SecTrustEvaluate возвращает kSecTrustResultRecoverableTrustFailure в iOS 5

Работаю над обновлением приложения, которое у меня есть, до iOS5 после сообщений о том, что оно не работает с бета-версией. Проблема связана с тем, что наша пользовательская проверка SSL-сертификата больше не работает.

В разделе didReceiveAuthenticationChallenge получаем наши корневые сертификаты и вызываем SecTrustEvaluate. Это отлично работает на iOS4.

protectionSpace = [challenge protectionSpace];
    trust = [protectionSpace serverTrust];

    err = SecTrustEvaluate(trust, &trustResult);

    trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultUnspecified));

    if (!trusted) { 
        err = SecTrustSetAnchorCertificates(trust, (CFArrayRef)[EagleAccessAppDelegate getDelegate].rootCertificates);

        if (err == noErr) {
            err = SecTrustEvaluate(trust, &trustResult);
        }

        trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultUnspecified));
    }

    if (trusted) { 
        NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];
        [[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
    } else { 
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }

Сертификаты хранятся в формате DER как ресурсы, включенные в приложение.

// Load Certificates. 
NSString *devFilePath = [[NSBundle mainBundle] pathForResource:@"ipms-dev-ca.der" ofType:@"crt"];  
NSData *devRootCertificate = [[[NSData alloc] initWithContentsOfFile:devFilePath] autorelease];
SecCertificateRef devRoot = SecCertificateCreateWithData(NULL, (CFDataRef) devRootCertificate);

NSString *prodFilePath = [[NSBundle mainBundle] pathForResource:@"ipms-prod-ca.der" ofType:@"crt"];  
NSData *prodRootCertificate = [[[NSData alloc] initWithContentsOfFile:prodFilePath] autorelease];
SecCertificateRef prodRoot = SecCertificateCreateWithData(NULL, (CFDataRef) prodRootCertificate);

self.rootCertificates = [[NSArray alloc] initWithObjects:(id)devRoot, (id)prodRoot, nil];

По сути, у нас есть собственный сертификат CA, который мы используем для выдачи сертификатов для серверов, к которым подключается наше приложение.

Я могу воссоздать это, используя пример приложения AdvancedURLConnections.


person jr.    schedule 11.09.2011    source источник


Ответы (1)


Проблема заключалась в том, что сертификат был подписью MD5. Эти подписи больше не поддерживаются в iOS5.

person jr.    schedule 15.09.2011
comment
Спасибо за совет. Просто нужно было создать корневой сертификат с помощью openssl req -new -x509 -sha512... - person Luis; 05.03.2012
comment
Я пытаюсь сделать почти то же самое. Однако в моем случае якорный сертификат является сертификатом сервера (это его собственный корневой сертификат). Кроме того, мне не нужно проверять адрес сервера (он назначается динамически). Мой сертификат подписан SHA-1 RSA. Я что-то упускаю? Я все еще получаю сообщение об ошибке. - person Rick; 16.05.2013