我需要打开一个CFStream套接字连接到具有不受信任的CA根的服务器。我有服务器的证书,我可以从中创建一个SecCertificateRef
结构。问题是如何设置流的属性。
我认为我应该将kCFStreamPropertySSLSettings
属性设置为CFDictionary
,而kCFStreamSSLCertificates
又包含SecCertificateRef
密钥。根据文档,这个键应该包含一个“SecCertificateRefs的CFArray,除了数组中的第一个元素,它是一个SecIdentityRef”。现在,我可以从我随应用程序提供的服务器证书中创建SecIdentityRef
,但是如何获取{{1}}?我想它应该是客户端身份,但我现在绝对不想要客户端身份验证。而且我找不到如何仅使用服务器证书来提供CFStream的方法。
注意,我不想将不受信任的证书添加到钥匙串,也不要在设置中禁用kCFStreamSSLValidatesCertificateChain。我需要接受服务器身份验证,只要它是基于我自己从磁盘加载的服务器证书数据,并且只在此CFStream上。
答案 0 :(得分:3)
我没有直接回答你的问题,但可能很少有指导原则:
为什么需要使用CFStream API而不是更直观的 NSURLConnection ? 从我在文档中可以找到的内容来看,它并不像Mac OS X中可用的所有关于CFStream API的内容都适用于iOS。所以想一想,看看你是否可以切换到NSURLConnection: - )
对于NSURLConnection,您可以使用 NSURLConnectionDelegate 方法获取SSL质询并自行验证证书。您可以查看我已实现这些功能的 wsdl2objc 项目:
现在关于你的问题:-)
我不知道如何在 kCFStreamPropertySSLSettings 中设置自定义(不受信任)的CA.我不确定是否可以使用 kCFStreamSSLCertificates 来完成,因为它用于设置客户端证书(因此要求具有索引0上的 SecIdentityRef ,基本上提供了私钥。)
当您说您不想将证书添加到钥匙串时,您的意思是手动还是编程?我想您不希望您的应用的用户必须手动执行此操作,但您可以使用 安全API 以编程方式导入证书。在这种情况下,您的证书将导入沙盒钥匙串,该钥匙串仅适用于您的应用程序。 (再次,不确定这是否有效,但值得尝试)
在我的应用程序中,我使用NSURLConnectionDelegate手动验证不受信任的证书。
的问候,
PECE
答案 1 :(得分:3)
基本上你必须:
kCFStreamSSLValidatesCertificateChain
kCFStreamPropertySSLPeerTrust
)一旦连接到流(但在发送任何数据之前,即在kCFStreamEventCanAcceptBytes
或kCFStreamEventHasBytesAvailable
事件上)kSecTrustResultRecoverableTrustFailure
)并检查结果是SecTrustEvaluate
还是kSecTrustResultProceed