Does SecTrustEvaluate() look for root certificates in the application keychain?

后端 未结 3 2113
逝去的感伤
逝去的感伤 2021-01-03 13:45

The docs say: “If not all the certificates needed to verify the leaf certificate are included in the trust management object, then SecTrustEvaluate searches for certificates

3条回答
  •  执笔经年
    2021-01-03 13:50

    Seems like it's been a while since you posted so I'm not sure if you still need the answer. If your use case is "I'm getting hit with connection:didReceiveAuthenticationChallenge:, and I'd like to make sure that exact certificate is being evaluated, then you can either use iOS built-in trust methods or do a bit more work via the Foundation APIs: (note that SecTrustEvaulate is not being called specifically here, but it could be added in quite easily)

    #import 
    #import 
    

    From there, you can iterate the full array of certs, and compare it to something like a SHA1 of the challenge's server trust reference:

    // way #1 - iOS built-in ================================================ //
    SecTrustRef trust = challenge.protectionSpace.serverTrust;
    CFIndex cnt = SecTrustGetCertificateCount(trust);
    
    // way #2 - build it in yourself from a file ============================ //
    OSErr err;
    NSString *path = [[NSBundle mainBundle] pathForResource:@"my.cert" 
                                                     ofType:@"der"];
    NSData *derData = [NSData dataWithContentsOfFile:path];
    
    SecCertificateRef myCert = 
        SecCertificateCreateWithData(NULL, (CFDataRef)derData);
    
    CFMutableArrayRef array = CFArrayCreateMutable(NULL, 1, NULL);
    CFArrayInsertValueAtIndex(array, 0, myCert);
    
    err = SecTrustSetAnchorCertificates(trust, array);
    if (err != errSecSuccess) {
        // do something smarter here, obviously, logging would be a start
        abort();
    }
    CFArrayRef certs = NULL;
    err = SecTrustCopyCustomAnchorCertificates(trust, &certs);
    if (err != errSecSuccess) {
        // again, better choices needed
        abort();
    }
    CFIndex cnt = CFArrayGetCount(certs);
    
    // loop and compare 'em
    for (int i = 0; i < cnt; i++) {
        SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust, i);
    
        CFDataRef cdata = SecCertificateCopyData(cert);
        NSData *data = [[NSData alloc] initWithData:(NSData *)cdata];
    
        unsigned char digest_result[CC_SHA1_DIGEST_LENGTH];
    
        CC_SHA1(data.bytes, data.length, digest_result);
        // compare each byte with your in-code SHA1 bytes
        if (allBytesMatch) {
            NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];
            [challenge.sender useCredential:cred 
                 forAuthenticationChallenge:challenge];
        }
    }
    // don't forget to release & CFRelease all the alloc'ed stuff from above
    

提交回复
热议问题