如何序列化 SecTrustRef 对象?

How to serialize a SecTrustRef object?

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

这两个进程有一个 IPC link,允许我在它们之间交换任意字节数据,但我没有看到任何方法可以轻松地将 SecTrustRef 序列化为字节数据并反序列化该数据回到另一个进程的对象。 SecTrustRef.

似乎没有持久存储机制

所以我是不是忽略了一些重要的东西,还是我真的必须获得所有证书 (SecTrustGetCertificateAtIndex) 和所有政策 (SecTrustCopyPolicies) 并自己序列化这些?

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

对于证书(SecCertificateRef),这很容易,我只是调用SecCertificateCopyData,然后调用SecCertificateCreateWithData

但是对于策略我只能在一侧调用 SecPolicyCopyProperties 然后在 SecPolicyCreateWithProperties 上调用,但是后者需要第二个参数,一个 policyIdentifier 我看不出有什么办法从现有策略中获取该值。我错过了什么?

通读 source of the Security framework,我终于弄明白了如何复制 SecPolicyRef:

  • SecPolicyCreateWithProperties 想要一个 "policyIdentifier"。它是一个常量,如 kSecPolicyAppleIPsec.
  • 这不会直接由函数存储,它比较值并调用专用内部 "initializers"(如 SecPolicyCreateIPsec)。
  • 这些依次调用 SecPolicyCreate(这是私有的)。他们最终传递的标识符值与您传递给 SecPolicyCreateWithProperties.
  • 的标识符值相同
  • 然后这个值按原样存储在 _oid 字段中!

标识符实际上是OID。您可以通过 SecPolicyCopyProperties(policy)(使用键 kSecPolicyOid 存储在字典中)或通过 SecPolicyGetOID(但 returns 不方便 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。不幸的是,没有办法查询这个值,例如,我看到它在 NSURLSession 传递的信任中是 false。还不知道如何以 public 的方式获得这个值。

另一个有问题的位是异常:如果 _exceptions 为 NULL 但您通过 SecTrustCopyExceptions(trust) 查询它们,您确实获得了数据!如果您通过 SecTrustSetExceptions(trust, exceptions) 将其分配给反序列化的信任,您突然会遇到以前不存在的异常,并且可以更改评估结果! (我已经看到那些突然出现的异常导致 "proceed" 而不是 "recoverable trust failure" 的评估结果)。