title: How can I accept self-signed server certificates from a whitelist in iOS?
body: <p>I'm trying to accept self-signed certificates in a NSURLConnection, as many have before me.  The catch is that I only want to accept certs from a whitelist of certs I trust.  I'd settle for figuring out how to accept a single cert.  Here's the code I've got so far in my NSURLConnectionDelegate:</p>
  
  <pre><code>- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
      if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
          NSString *thePath = [[NSBundle mainBundle] pathForResource:@"trusted" ofType:@"der"];
          NSData *certData = [[NSData alloc] initWithContentsOfFile:thePath];
          CFDataRef myCertData = (__bridge_retained CFDataRef)certData;
          SecCertificateRef myCert = SecCertificateCreateWithData(NULL, myCertData);
          SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
          SecCertificateRef certArray[1] = { myCert };
          CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL);
          SecTrustRef myTrust;
          OSStatus status = SecTrustCreateWithCertificates(myCerts, myPolicy, &amp;myTrust);
  
          SecTrustResultType trustResult;
          if (status == noErr) {
              status = SecTrustEvaluate(myTrust, &amp;trustResult);
          }
          BOOL trusted = NO;
  
          if (trustResult == kSecTrustResultUnspecified) {
              // I never get here.  Instead, trustResult is always kSecTrustResultRecoverableTrustFailure
              trusted = YES; 
          }
  
          if (trusted) {
              [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]
                   forAuthenticationChallenge:challenge];
          } else {
              [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
          }
          CFRelease(myTrust);
          CFRelease(myCerts);
          CFRelease(myPolicy);
          CFRelease(myCert);
          CFRelease(myCertData);
      } else {
          [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
      }
  }
  </code></pre>
  
  <p>As you can see in the comment, I never actually get kSecTrustResultUnspecified, which is what I expect to get.  I verified that my cert is correct, and in the correct format (DER).</p>