0

I am handling https authentication for server based on its name but i want to trust server based on a certificate which server gives me. how can i do this ,any help ??

- (void)connection:(NSURLConnection *)connection
    didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge.protectionSpace.authenticationMethod
     isEqualToString:NSURLAuthenticationMethodServerTrust])
{
    // we only trust our own domain
    if ([challenge.protectionSpace.host isEqualToString:@"www.serverpage.com"])
    {
        NSURLCredential *credential =
            [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
        [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
    }
}

[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

I searched web and found most of the answers are just accepting any server authentication without validating .

vishnuvarthan
  • 492
  • 1
  • 6
  • 23

2 Answers2

0

NSURLConnection has a builtin method for doing SSL with non trusted certs. See the SO answer here. Please make sure you do not use it in production code as it is vulnerable to MITM attacks.

Community
  • 1
  • 1
Dennis
  • 2,119
  • 20
  • 29
0

You need an encapsulate a server certificate inside your app. When your app starts, you need to extract a Public Key from an encapsulated server certificate. When run in delegate's callback URLSession:didReceiveChallenge:challenge:completionHandler you need to iterate through obtained certificates from supplied challenge.protectionSpace.serverTrust and do comparation with Public Key you extracted before.

Best thing - also do the same with an Issuer certificate - include original of it in your app, and investigate it with obtained one from challenge.protectionSpace.serverTrust

next code snippet is demonstrating an extraction of the Public Key from a certificate:

SecKeyRef getPKeyFromCert(SecCertificateRef cert) {
    SecTrustRef newtrust = NULL;
    CFMutableArrayRef certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    CFMutableArrayRef newPolicies = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    CFArrayAppendValue(certs, cert);

    if (SecTrustCreateWithCertificates(certs, newPolicies, &newtrust) == errSecSuccess) {
        return SecTrustCopyPublicKey(newtrust);
    }
    return NULL;
}

next code snippet is demonstrating an iteration through the certificates, supplied via the protectionSpace:

SecTrustRef trustRef = challenge.protectionSpace.serverTrust;
CFIndex count = SecTrustGetCertificateCount(trustRef);
CFIndex i = 0;
for (i = 0; i < count; i++) {
    SecCertificateRef certRef = SecTrustGetCertificateAtIndex(trustRef, i);
    SecKeyRef publicKey = getPKeyFromCert(certRef);
    // do the magic
}
A. Petrov
  • 910
  • 13
  • 18