如何在iOS Secure Transport API中使用我自己的根证书?

时间:2015-05-05 18:14:39

标签: ios security ssl

我正在尝试在已建立的传输层上使用Apple's Secure Transport API,并使用我自己的根证书。我将我的根证书作为SecCertificateRef,但我无法弄明白如何使其成为可信任的。

我已经检查了以下功能,每个功能看起来都非常接近我需要的功能:

  • SSLAddDistinguishedName()未执行;
  • SSLSetTrustedRoots()已弃用;
  • SSLSetCertificateAuthorities()仅用于客户端身份验证。

如果我可以覆盖SecTrustRef中的SecContextRef,那么SecTrustSetAnchorCertificates()就可以完成这项工作。不幸的是,这条途径只让我SSLGetPeerSecTrust(),这似乎是一个Apple私有API。

2 个答案:

答案 0 :(得分:2)

我认为您想要的是以下内容:

OSStatus status = SSLSetSessionOption(sslContext, kSSLSessionOptionBreakOnServerAuth, true);

然后在握手期间

 OSStatus status = SSLHandshake(sslContext);
    if (status == errSSLPeerAuthCompleted)
    {
        SecTrustRef trust = NULL;
        status = SSLCopyPeerTrust(sslContext, &trust);

        // Perform your custom trust rules here.  e.g.
        BOOL bTrusted = NO;
        NSArray* anchor = [NSArray arrayWithObject:(id)pCACert];
        OSStatus result = SecTrustSetAnchorCertificates(trust, (CFArrayRef)anchor);
        /* Uncomment this to enable both system certs and the one we are supplying */
        //result = SecTrustSetAnchorCertificatesOnly(trust, NO);
        SecTrustResultType trustResult;
        result = SecTrustEvaluate(trust, &trustResult);
        if (result == errSecSuccess)
        {
          switch (trustResult)
          {
            case kSecTrustResultProceed:
            case kSecTrustResultUnspecified:
              bTrusted = YES;
              break;

            case kSecTrustResultInvalid:
            case kSecTrustResultDeny:
            case kSecTrustResultRecoverableTrustFailure:
            case kSecTrustResultFatalTrustFailure:
            case kSecTrustResultOtherError:
            default:
              break;
          }
        }

        // If trusted, continue the handshake
        if (bTrusted)
          status = SSLHandshake(sslContext);
        else 
        {
          /* Your trust failure handling here ~ disconnect */
        }
    }

其中pCAcert是您希望信任的根证书(SecCertificateRef)

答案 1 :(得分:1)

如果我理解这一点你正试图:

{您的应用} - [ssl会话] - > {您的服务器}

您的服务器正在使用由您自己的CA(root)签名的某些证书​​。您正在尝试使用手机发送CA证书,并将其用作受信任的CA而不是那里的全局CA.

这似乎是您正在寻找的:

  

准备会话

     
      
  1. 调用SSLNewContext(在OS X中)或SSLCreateContext(在iOS和OS X中)   创建一个新的SSL会话上下文。

  2.   
  3. 编写SSLWrite和SSLRead I / O函数并调用SSLSetIOFuncs   将它们传递给Secure Transport。

  4.   
  5. 使用CFNetwork,BSD套接字或Open建立连接   运输。然后调用SSLSetConnection指定连接   SSL会话上下文适用于哪个。

  6.   
  7. 调用SSLSetPeerDomainName以指定完全限定的域名   要连接的对等端(可选但非常高)   推荐)。

  8.   
  9. 调用 SSLSetCertificate 指定要使用的证书   身份验证(服务器端需要,客户端可选)。

  10.   
OSStatus SSLSetCertificate ( SSLContextRef context, CFArrayRef certRefs );

<强> certRefs
要设置的证书。此数组包含SecCertificateRef类型的项目,但certRefs [0]除外,其类型为SecIdentityRef。

  

讨论设置证书或证书是强制性的   服务器连接,但对于客户端是可选的。指定一个   客户端证书启用SSL客户端身份验证。您   必须在certRefs [0]中放置一个标识它的SecIdentityRef对象   叶证书及其对应的私钥。 指定根目录   证书是可选的; 如果未指定,则为根证书   验证此处指定的证书链必须存在于   系统范围内的可信锚证书。

来自:https://developer.apple.com/library/mac/documentation/Security/Reference/secureTransportRef/