通过阅读安全框架的源代码,我终于弄清楚了如何复制SecPolicyRef
:
SecPolicyCreateWithProperties
想要它所谓的“policyIdentifier”。它是一个常数,如kSecPolicyAppleIPsec
.
- 这不会由函数直接存储,它会比较值并调用专用的内部“初始化器”(如
SecPolicyCreateIPsec
)。
- 这些依次调用
SecPolicyCreate
(这是私有的)。它们最终传递了您传递给的相同标识符值SecPolicyCreateWithProperties
。
- 然后该值将按原样存储在该
_oid
字段中!
标识符实际上是 OID。您可以通过SecPolicyCopyProperties(policy)
(使用 key 存储在字典中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)
那么您突然会遇到以前不存在的异常并且可以更改评估结果!(我已经看到那些突然出现的异常导致评估结果为“继续”而不是“可恢复的信任失败”)。