文档说:“如果不是所有验证叶证书所需的证书都包含在信任管理对象中,那么 SecTrustEvaluate 在钥匙串搜索列表(请参阅 SecTrustSetKeychains)和系统的锚证书存储(请参阅 SecTrustSetAnchorCertificates)中搜索证书。”
但是,由于 SecTrustSetKeychains() 在 iOS 上不可用,尚不清楚此函数是否也会在应用程序的钥匙串中查找。
好像你发帖已经有一段时间了,所以我不确定你是否还需要答案。如果您的用例是“我遇到了connection:didReceiveAuthenticationChallenge:
,并且我想确保正在评估确切的证书,那么您可以使用 iOS 内置的信任方法或通过 Foundation API 做更多的工作: (请注意,此处没有专门调用 SecTrustEvaulate,但可以很容易地添加它)
#import <Security/Security.h>
#import <CommonCrypto/CommonDigest.h>
从那里,您可以迭代完整的证书数组,并将其与挑战服务器信任参考的 SHA1 之类的内容进行比较:
// 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
它现在写在文档中:
注意:虽然此函数会在用户的钥匙串(或 iOS 中的应用程序钥匙串)中搜索中间证书,但它不会在这些钥匙串中搜索锚(根)证书。要添加锚证书,您必须调用 SecTrustSetAnchorCertificates。
资料来源:SecTrustEvaluate 文档
Apple Devforums 的 eskimo1 回答了这个问题:
- SecTrustEvaluate() 是否在应用程序钥匙串中查找根证书?
默认情况下不是。但是,通过从钥匙串(或任何地方)中获取证书并使用 SecTrustSetAnchorCertificates 将它们应用于 SecTrust 对象,很容易做到这一点。
SecTrustEvaluation /will/ 在您的钥匙串中找到中间证书。