我有两个X509格式的证书,我想将certificateA添加到锚证书列表中,并且仅针对证书A评估certificateB。我们也说certA - > certB在链中,因此CertA是受信任的根。
int len = i2d_X509(certificateA, &buf);
if (len > 0) {
/* Translate the data to a SecCertificateRef */
CFDataRef data = CFDataCreate(NULL, buf, len);
SecCertificateRef ref = SecCertificateCreateWithData(NULL, data);
CFRelease(data);
if (ref != NULL) {
/* Add the cert to the array */
[certs addObject:(__bridge_transfer id)(ref)];
}
} else {
return NULL;
}
OPENSSL_free(buf);
/* Get the reference */
CFArrayRef certsRef = (__bridge CFArrayRef)certs;
/* Get the Trust Refs */
NSString *refHostname = [NSString stringWithCString:hostname.c_str() encoding:[NSString defaultCStringEncoding]];
SecPolicyRef policy = SecPolicyCreateSSL(NO, (__bridge CFStringRef) refHostname);
SecTrustRef trustRefA;
OSStatus ret = SecTrustCreateWithCertificates(certsRef, policy, &trustRefA);
我为certA和certB执行此操作,它为我提供了两个trustRefs。然后将certificateA添加到Anchors列表中:
OSStatus ret = SecTrustSetAnchorCertificatesOnly(trustRefA, YES);
稍后,我想做:
OSStatus ret = SecTrustEvaluate(trustRefB, YES);
这不起作用。此外,有没有办法可以使用SecTrustEvaluate,并且只能对CertA锚点进行评估。
有没有办法将单个锚设置为要验证的默认证书?我很困惑,因为我认为这就是SecTrustSetAnchorCertificateOnly()所做的。
答案 0 :(得分:2)
以下是要添加到NSURLConnectionDelegate
' s connection:didReceiveAuthenticationChallenge:
的代码。它以DER格式加载CA,并针对该CA验证特定服务器。
if ([[[challenge protectionSpace] authenticationMethod] isEqualToString: NSURLAuthenticationMethodServerTrust])
{
do
{
SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
if(nil == serverTrust)
break; /* failed */
NSData* caCert = [NSData dataWithContentsOfFile:@"ca-rsa-cert.der"];
if(nil == caCert)
break; /* failed */
SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)caCert);
if(nil == caRef)
break; /* failed */
NSArray* caArray = [NSArray arrayWithObject:(__bridge id)(caRef)];
if(nil == caArray)
break; /* failed */
OSStatus status = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)caArray);
if(!(errSecSuccess == status))
break; /* failed */
SecTrustResultType result = -1;
status = SecTrustEvaluate(serverTrust, &result);
if(!(errSecSuccess == status))
break; /* failed */
/* https://developer.apple.com/library/ios/technotes/tn2232/_index.html */
/* https://developer.apple.com/library/mac/qa/qa1360/_index.html */
/* kSecTrustResultUnspecified and kSecTrustResultProceed are success */
if(result != kSecTrustResultUnspecified && result != kSecTrustResultProceed)
break; /* failed */
// The only good exit point
return [[challenge sender] useCredential: [NSURLCredential credentialForTrust: serverTrust]
forAuthenticationChallenge: challenge];
} while(0);
}
// Bad dog
return [[challenge sender] cancelAuthenticationChallenge: challenge];
如果您在错误路径上致电[connection cancel];
,则connection:didFailWithError:
将被调用