【问题标题】:How to serialize a SecTrustRef object?如何序列化 SecTrustRef 对象?
【发布时间】:2019-08-12 03:59:51
【问题描述】:

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

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

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

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

对于证书 (SecCertificateRef) 这很简单,我只需调用 SecCertificateCopyData 和稍后的 SecCertificateCreateWithData

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

【问题讨论】:

    标签: macos trust security-framework


    【解决方案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。不幸的是,没有办法查询这个值,例如,我在NSURLSession 传递的信任中看到它是false。尚不知道如何以公共方式获取此值。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-27
      • 1970-01-01
      • 2015-06-28
      • 2011-04-06
      • 1970-01-01
      • 1970-01-01
      • 2018-07-22
      相关资源
      最近更新 更多