When using Client Certificate Authentication, why do I keep getting NSURLErrorDomain Code=-1206?

寵の児 提交于 2019-12-07 12:36:43

问题


The following code is me using code from previous posts about ios client certificate authentication. Every says this works, however why does it work for me?!?!

I keep getting the following error:

connection didFailWithError: Error Domain=NSURLErrorDomain Code=-1206 "The server “www.mywebsite.com” requires a client certificate.

I've followed at least 4 posts about this same topic on stackoverflow and 2 on other similar sites. They all say the same thing, except it isn't working.

I know my PKCS12 file works because i emailed it to my ipad, where i installed it on the ipad keychain and i'm able to access and authorize with the certificate identity using Safari. It is just when i'm trying to do it using a NSURLConnection in a 3rd party app, it refuses to allow me to do it.

Any suggestions are welcome, I feel like i've exhausted my options.


    // Download PKCS12 Cert from my FTP server.

    NSString *stringURL = @"ftp://user:password@myipaddress/myclientId.p12";        
    NSString* webStringURL = [stringURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSURL  *url = [NSURL URLWithString:webStringURL];
    NSData *p12Data = [NSData dataWithContentsOfURL:url];


    if ( p12Data )
    {   
        CFDataRef inP12data = (__bridge CFDataRef)p12Data;

        SecIdentityRef myIdentity;
        SecTrustRef myTrust;
        OSStatus errMsg = NULL;

        // This is the same function that has been reposted in all the other posts about ios client certification authentication.  So i'm not going to repost that.
        errMsg = extractIdentityAndTrust(inP12data, &myIdentity, &myTrust);

        SecCertificateRef myCertificate;
        SecIdentityCopyCertificate(myIdentity, &myCertificate);

        const void *certs[] = { myCertificate };

        CFArrayRef certsArray = CFArrayCreate(NULL, certs, 1, NULL);

        NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:(__bridge NSArray*)certsArray persistence:NSURLCredentialPersistenceNone];

        [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];

回答1:


Error was on this line. Second parameter needs to be set to "nil"

    NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:(__bridge NSArray*)certsArray persistence:NSURLCredentialPersistenceNone];

Changed to:

    NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:nil persistence:NSURLCredentialPersistenceNone];



回答2:


Chances are your .p12 contains intermediate certs AND your server required those intermediate certs.

You can verified with wireshark that you code will send in duplicated certificate of the identity but no intermediate certificate in the client certificate response.

If there is the case, you are to also extract the certificate from p12 and pass to create the NSURLCredentials:

int count = SecTrustGetCertificateCount(myTrust);
NSMutableArray* myCertificates = nil;
if (count > 1) {
    myCertificates = [NSMutableArray arrayWithCapacity:SecTrustGetCertificateCount(myTrust)];
    for (int i = 1; i < count; ++i) {  // remove the leaf cert
         [certs addObject:(id)SecTrustGetCertificateAtIndex(myTrust, i)];
    }
}
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:myCertificates persistence:NSURLCredentialPersistenceNone];

Also, passing nil to NSURLCredential should not break any code. see Apple's sample: https://developer.apple.com/library/ios/documentation/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html. But passing empty array @[] to NSURLCredential will crash.



来源:https://stackoverflow.com/questions/16371066/when-using-client-certificate-authentication-why-do-i-keep-getting-nsurlerrordo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!