NSUrlConnection sendAsynchronousRequest and self-signed certificates

I am writing some kind of API code that processes http requests, and I used [NSUrlConnection: sendAsynchronousRequest: queue: completionHandler] for calls, since it is quite easy to write simple handlers, and also so that I don't have to have different classes with different delegates for every call.

The problem I am facing is that it seems that the only way to accept self-signed certificates is to have a delegate that implements several functions that say the certificate is ok. Is there a way to do this using an asynchronous method that uses blocks?

+6
source share
1 answer

No, but delegate calls are not so difficult. This is the code you need:

1) Make this file static

static CFArrayRef certs; 

2) Do this during initialization:

  // I had a crt certificate, needed a der one, so found this site: // http://fixunix.com/openssl/537621-re-der-crt-file-conversion.html // and did this from Terminal: openssl x509 -in crt.crt -outform der -out crt.der NSString *path = [[NSBundle mainBundle] pathForResource:@"<your name>" ofType:@"der"]; assert(path); NSData *data = [NSData dataWithContentsOfFile:path]; assert(data); SecCertificateRef rootcert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)data); if(rootcert) { const void *array[1] = { rootcert }; certs = CFArrayCreate(NULL, array, 1, &kCFTypeArrayCallBacks); CFRelease(rootcert); // for completeness, really does not matter } else { NSLog(@"BIG TROUBLE - ROOT CERTIFICATE FAILED!"); } 

3) Then add this method:

 - (void)connection:(NSURLConnection *)conn didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { #pragma unused(conn) // NSLog(@"didReceiveAuthenticationChallenge %@ FAILURES=%zd", [[challenge protectionSpace] authenticationMethod], (ssize_t)[challenge previousFailureCount]); /* Setup */ NSURLProtectionSpace *protectionSpace = [challenge protectionSpace]; assert(protectionSpace); SecTrustRef trust = [protectionSpace serverTrust]; assert(trust); CFRetain(trust); // Don't know when ARC might release protectionSpace NSURLCredential *credential = [NSURLCredential credentialForTrust:trust]; BOOL trusted = NO; OSStatus err; SecTrustResultType trustResult = 0; err = SecTrustSetAnchorCertificates(trust, certs); if (err == noErr) { err = SecTrustEvaluate(trust, &trustResult); if(err == noErr) { // http://developer.apple.com/library/mac/#qa/qa1360/_index.html switch(trustResult) { case kSecTrustResultProceed: case kSecTrustResultConfirm: case kSecTrustResultUnspecified: trusted = YES; break; } } } CFRelease(trust); // Return based on whether we decided to trust or not if (trusted) { [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; } else { NSLog(@"Trust evaluation failed"); [[challenge sender] cancelAuthenticationChallenge:challenge]; } } 
+3
source

Source: https://habr.com/ru/post/921141/


All Articles