我有一个要评估自己的系统中的SecTrustRef
对象。只需致电SecTrustEvaluateAsync
就可以完成这项工作。问题是,我必须在不同的过程中对其进行评估,因为只有其他过程才可以访问存储CA证书的钥匙串,这可能导致评估成功。
这两个进程具有IPC链接,该链接允许我在它们之间交换任意字节数据,但是我看不到有任何方法可以轻松地将SecTrustRef
序列化为字节数据并将该数据反序列化为对象。其他过程。 SecTrustRef
似乎没有持久的存储机制。
那么我是不是在这里忽略了一些重要的事情,还是我真的必须获取所有证书(SecTrustGetCertificateAtIndex
)和所有策略(SecTrustCopyPolicies
)并自己对它们进行序列化?
如果是这样,我将如何序列化策略?
对于证书(SecCertificateRef
)很简单,我只需致电SecCertificateCopyData
,然后再致电SecCertificateCreateWithData
。
但是对于策略,我只能在一侧调用SecPolicyCopyProperties
,然后在SecPolicyCreateWithProperties
调用,但是后一种需要第二个参数,即policyIdentifier
,我看不出有什么办法现有政策的价值。我想念什么?
答案 0 :(得分:1)
通读source of the Security framework之后,我终于弄清楚了如何复制SecPolicyRef
:
SecPolicyCreateWithProperties
需要它所谓的“ policyIdentifier”。它像kSecPolicyAppleIPsec
这样的常量。SecPolicyCreateIPsec
)。SecPolicyCreate
(私有)。它们最终传递了与传递给SecPolicyCreateWithProperties
相同的标识符值。_oid
字段中!标识符实际上是OID。您可以通过SecPolicyCopyProperties(policy)
(使用键kSecPolicyOid
存储在字典中)或通过SecPolicyGetOID
来获取它(但这会带来不方便的CSSM_OID
返回)。其中一些专门的初始化程序还使用传递给SecPolicyCreateWithProperties
的属性字典中的值,这些值应该已经存在于复制的属性字典中。
所以这给了我们
序列化:
CFDictionaryRef createSerializedPolicy(SecPolicyRef policy) {
// Already contains all the information needed.
return SecPolicyCopyProperties(policy);
}
反序列化:
SecPolicyRef createDeserializedPolicy (CFDictionaryRef serialized) {
CFStringRef oid = CFDictionaryGetValue(serialized, kSecPolicyOid);
if (oid == NULL || CFGetTypeID(oid) != CFStringGetTypeID()) {
return NULL;
}
return SecPolicyCreateWithProperties(oid, serialized);
}
要尽可能地重现原始SecTrustRef,还需要复制锚点。有一个内部变量_anchorsOnly
,一旦设置锚点,该变量便设置为true
。不幸的是,无法查询此值,例如,我看到它是false
传递的信任中的NSURLSession
。尚不知道如何以公开方式获得此价值。
另一个有问题的例外是:如果_exceptions
为NULL,但您通过SecTrustCopyExceptions(trust)
查询它们,则确实会获得数据!而且,如果您通过SecTrustSetExceptions(trust, exceptions)
将其分配给反序列化信任,您突然会遇到以前从未出现过的异常,并且可以更改评估结果! (我已经看到那些突然出现的异常导致评估结果为“进行”,而不是“可恢复的信任失败”。)