Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 根据自定义锚证书验证证书_Ios_Ssl_Openssl_Core Foundation - Fatal编程技术网

Ios 根据自定义锚证书验证证书

Ios 根据自定义锚证书验证证书,ios,ssl,openssl,core-foundation,Ios,Ssl,Openssl,Core Foundation,我有两个X509格式的证书,我想将certificateA添加到锚证书列表中,并仅根据certificateA评估certificateB。我们也可以在链中使用certA->certB,因此certA是受信任的根 int len = i2d_X509(certificateA, &buf); if (len > 0) { /* Translate the data to a SecCertificateRef */ CFDataRef data = CFDataCreate

我有两个X509格式的证书,我想将certificateA添加到锚证书列表中,并仅根据certificateA评估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都这样做,这给了我两个信任。然后,要将certificateA添加到锚列表中,我需要:

  OSStatus ret = SecTrustSetAnchorCertificatesOnly(trustRefA, YES);
稍后,我想做:

  OSStatus ret = SecTrustEvaluate(trustRefB, YES);
这不管用。还有,有没有一种方法我可以使用SecTrustEvaluate,并且只对CertA锚进行评估


有没有办法将单个锚点设置为要验证的默认证书?我相当困惑,因为我认为SecTrustSetAnchorCertificateOnly()就是这么做的。

以下是要添加到
NSURLConnectionLegate
连接: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];

如果您调用
[连接取消]
在错误路径上,则不会调用
连接:didFailWithError:

我认为您应该使用
SecTrustSetAnchorCertificates
,而不是
SecTrustSetAnchorCertificates Only
。看,如果我使用SecTrustSetAnchorCertificates,anchorChain会是什么?我会使用SecTrustSetAnchorCertificates(certA,NULL)吗?在pseudo中,我相信它的
SecTrustSetAnchorCertificates(certA,certB)