如何序列化SecTrustRef对象?

时间:2019-03-21 10:11:07

标签: macos trust security-framework

我有一个要评估自己的系统中的SecTrustRef对象。只需致电SecTrustEvaluateAsync就可以完成这项工作。问题是,我必须在不同的过程中对其进行评估,因为只有其他过程才可以访问存储CA证书的钥匙串,这可能导致评估成功。

这两个进程具有IPC链接,该链接允许我在它们之间交换任意字节数据,但是我看不到有任何方法可以轻松地将SecTrustRef序列化为字节数据并将该数据反序列化为对象。其他过程。 SecTrustRef似乎没有持久的存储机制。

那么我是不是在这里忽略了一些重要的事情,还是我真的必须获取所有证书(SecTrustGetCertificateAtIndex)和所有策略(SecTrustCopyPolicies)并自己对它们进行序列化?

如果是这样,我将如何序列化策略?

对于证书(SecCertificateRef)很简单,我只需致电SecCertificateCopyData,然后再致电SecCertificateCreateWithData

但是对于策略,我只能在一侧调用SecPolicyCopyProperties,然后在SecPolicyCreateWithProperties调用,但是后一种需要第二个参数,即policyIdentifier,我看不出有什么办法现有政策的价值。我想念什么?

1 个答案:

答案 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)将其分配给反序列化信任,您突然会遇到以前从未出现过的异常,并且可以更改评估结果! (我已经看到那些突然出现的异常导致评估结果为“进行”,而不是“可恢复的信任失败”。)