我正在尝试在已建立的传输层上使用Apple's Secure Transport API,并使用我自己的根证书。我将我的根证书作为SecCertificateRef
,但我无法弄明白如何使其成为可信任的。
我已经检查了以下功能,每个功能看起来都非常接近我需要的功能:
SSLAddDistinguishedName()
未执行; SSLSetTrustedRoots()
已弃用; SSLSetCertificateAuthorities()
仅用于客户端身份验证。如果我可以覆盖SecTrustRef
中的SecContextRef
,那么SecTrustSetAnchorCertificates()
就可以完成这项工作。不幸的是,这条途径只让我SSLGetPeerSecTrust()
,这似乎是一个Apple私有API。
答案 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.
这似乎是您正在寻找的:
准备会话
调用SSLNewContext(在OS X中)或SSLCreateContext(在iOS和OS X中) 创建一个新的SSL会话上下文。
编写SSLWrite和SSLRead I / O函数并调用SSLSetIOFuncs 将它们传递给Secure Transport。
使用CFNetwork,BSD套接字或Open建立连接 运输。然后调用SSLSetConnection指定连接 SSL会话上下文适用于哪个。
调用SSLSetPeerDomainName以指定完全限定的域名 要连接的对等端(可选但非常高) 推荐)。
- 醇>
调用 SSLSetCertificate 指定要使用的证书 身份验证(服务器端需要,客户端可选)。
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/