I figured it out, finally. Because our server has a dynamically-assigned IP address, and no hostname, we couldn't create a cert that matched. By default, iOS and OS X want to verify the hostname. The solution is to create a new SecTrustRef with a policy that does not check the hostname, and evaluate that. The final code is:
- (void) connection: (NSURLConnection*) inConnection willSendRequestForAuthenticationChallenge: (NSURLAuthenticationChallenge*) inChallenge { NSLogDebug(@"Connection challenged"); // Build a new trust based on the supplied trust, so that we can set the policy… NSURLProtectionSpace* protectionSpace = inChallenge.protectionSpace; SecTrustRef trust = protectionSpace.serverTrust; CFIndex numCerts = SecTrustGetCertificateCount(trust); NSMutableArray* certs = [NSMutableArray arrayWithCapacity: numCerts]; for (CFIndex idx = 0; idx < numCerts; ++idx) { SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust, idx); [certs addObject: CFBridgingRelease(cert)]; } // Create a policy that ignores the host name… SecPolicyRef policy = SecPolicyCreateSSL(true, NULL); OSStatus err = SecTrustCreateWithCertificates(CFBridgingRetain(certs), policy, &trust); CFRelease(policy); if (err != noErr) { NSLogDebug(@"Error creating trust: %d", err); [inChallenge.sender cancelAuthenticationChallenge: inChallenge]; return; } // Set the root cert and evaluate the trust… NSArray* rootCerts = @[ CFBridgingRelease(mRootCert) ]; err = SecTrustSetAnchorCertificates(trust, CFBridgingRetain(rootCerts)); if (err == noErr) { SecTrustResultType trustResult; err = SecTrustEvaluate(trust, &trustResult); CFRelease(trust); bool trusted = err == noErr; trusted = trusted && (trustResult == kSecTrustResultProceed || trustResult == kSecTrustResultUnspecified); if (trusted) { NSURLCredential* credential = [NSURLCredential credentialForTrust: trust]; [inChallenge.sender useCredential: credential forAuthenticationChallenge: inChallenge]; return; } } // An error occurred, or we don't trust the cert, so disallow it… [inChallenge.sender cancelAuthenticationChallenge: inChallenge]; } On May 16, 2013, at 12:46 , Jens Alfke <j...@mooseyard.com> wrote: > > On May 15, 2013, at 9:13 PM, Rick Mann <rm...@latencyzero.com> wrote: > >> I'm trying to validate our self-signed certificate in >> NSURLConnectionDelegate's >> -connection:willSendRequestForAuthenticationChallenge: using itself as the >> root cert. I'm not 100% sure I'm doing it right, but looking at the >> ridiculously, excessively complicated example code, I've come up with this: > > Ugh, yeah, I’ve had trouble with this too, but it was long enough ago that I > don’t remember the details. > One thing that might help is calling SecTrustGetResult to get detailed info > on the results of trust evaluation. The returned structure might have some > clues in it. > > You can also ask for help on the apple-cdsa list (which is for > security/crypto related topics). > > —Jens > _______________________________________________ > > Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) > > Please do not post admin requests or moderator comments to the list. > Contact the moderators at cocoa-dev-admins(at)lists.apple.com > > Help/Unsubscribe/Update your Subscription: > https://lists.apple.com/mailman/options/cocoa-dev/rmann%40latencyzero.com > > This email sent to rm...@latencyzero.com -- Rick _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com