iOS i SSL: nie można zweryfikować certyfikatu serwera z podpisem własnym


Jestem całkiem nowy w korzystaniu z usług internetowych przy użyciu kanału SSL. Po dość dobrym wyszukiwaniu znalazłem sposób na przeprowadzenie uwierzytelniania SSL / HTTPS przy użyciu interfejsów API delegowanych NSURLConnection. Poniżej znajduje się fragment kodu, który zawiera rzeczywistą rzecz uwierzytelniania:

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
[self printLogToConsole:@"Authenticating...."];
[self printLogToConsole:[NSString stringWithFormat:@"\n%@\n", [challenge description]]];
NSLog(@"\n\nserverTrust: %@\n", [[challenge protectionSpace] serverTrust]);

/* Extract the server certificate for trust validation
 */
NSURLProtectionSpace *protectionSpace = [challenge protectionSpace];
assert(protectionSpace);
SecTrustRef trust = [protectionSpace serverTrust];    
assert(trust);
CFRetain(trust); // Make sure this thing stays around until we're done with it
NSURLCredential *credential = [NSURLCredential credentialForTrust:trust];


/* On iOS 
 * we need to convert it to 'der' certificate. It can be done easily through Terminal as follows:
 * $ openssl x509 -in certificate.pem -outform der -out rootcert.der
 */
NSString *path = [[NSBundle mainBundle] pathForResource:@"rootcert" ofType:@"der"];
assert(path);
NSData *data = [NSData dataWithContentsOfFile:path];
assert(data);

/* Set up the array of certificates, we will authenticate against and create credentials */
SecCertificateRef rtCertificate = SecCertificateCreateWithData(NULL, CFBridgingRetain(data));
const void *array[1] = { rtCertificate };
trustedCerts = CFArrayCreate(NULL, array, 1, &kCFTypeArrayCallBacks);
CFRelease(rtCertificate); // for completeness, really does not matter

/* Build up the trust anchor using our root cert */
int err;
SecTrustResultType trustResult = 0;
err = SecTrustSetAnchorCertificates(trust, trustedCerts);
if (err == noErr) {
    err = SecTrustEvaluate(trust, &trustResult);
}
CFRelease(trust); // OK, now we're done with it

[self printLogToConsole:[NSString stringWithFormat:@"trustResult: %d\n", trustResult]];

/* http://developer.apple.com/library/mac/#qa/qa1360/_index.html
 */
BOOL trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultConfirm) || (trustResult == kSecTrustResultUnspecified));

// Return based on whether we decided to trust or not
if (trusted) {
    [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
    [self printLogToConsole:@"Success! Trust validation successful."];
} else {
    [self printLogToConsole:@"Failed! Trust evaluation failed for service root certificate.\n"];
    [[challenge sender] cancelAuthenticationChallenge:challenge];
}

}

Ale otrzymuję następujący błąd:

2012-06-11 17:10:12.541 SecureLogin[3424:f803] Error during connection: Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. (NSURLErrorDomain error -1012.)" UserInfo=0x682c790 {NSErrorFailingURLKey=https://staging.esecure.url/authentication/signin/merchants, NSErrorFailingURLStringKey=https://staging.esecure.url/authentication/signin/merchants}


Używam tego samego certyfikatu, który otrzymałem z serwera i przekonwertowałem go na format „der”. Buduję aplikację na iOS 5.x. Nie jestem pewien, czy czegoś brakuje. Daj mi znać o swoich sugestiach.

Dzięki.

EDYTOWAĆ Po sprawdzeniu certyfikatu tutaj, jak wygląda wyjście:


Daj mi znać, jeśli coś jest nie tak.

Dzięki.

questionAnswers(2)

yourAnswerToTheQuestion