以编程方式在iOS中读取根CA证书

12
以下代码读取 macOS 中的根证书。
我想知道在 iOS 中有哪些等效的代码?

https://github.com/HaxeFoundation/hxcpp/blob/7bd5ff3/src/hx/libs/ssl/SSL.cpp#L455-L491

CFMutableDictionaryRef search;
CFArrayRef result;
SecKeychainRef keychain;
SecCertificateRef item;
CFDataRef dat;
sslcert *chain = NULL;

// Load keychain
if( SecKeychainOpen("/System/Library/Keychains/SystemRootCertificates.keychain",&keychain) != errSecSuccess )
    return null();

// Search for certificates
search = CFDictionaryCreateMutable( NULL, 0, NULL, NULL );
CFDictionarySetValue( search, kSecClass, kSecClassCertificate );
CFDictionarySetValue( search, kSecMatchLimit, kSecMatchLimitAll );
CFDictionarySetValue( search, kSecReturnRef, kCFBooleanTrue );
CFDictionarySetValue( search, kSecMatchSearchList, CFArrayCreate(NULL, (const void **)&keychain, 1, NULL) );
if( SecItemCopyMatching( search, (CFTypeRef *)&result ) == errSecSuccess ){
    CFIndex n = CFArrayGetCount( result );
    for( CFIndex i = 0; i < n; i++ ){
        item = (SecCertificateRef)CFArrayGetValueAtIndex( result, i );

        // Get certificate in DER format
        dat = SecCertificateCopyData( item );
        if( dat ){
            if( chain == NULL ){
                chain = new sslcert();
                chain->create( NULL );
            }
            mbedtls_x509_crt_parse_der( chain->c, (unsigned char *)CFDataGetBytePtr(dat), CFDataGetLength(dat) );
            CFRelease( dat );
        }
    }
}
CFRelease(keychain);
if( chain != NULL )
    return chain;

由于你展示的代码是 用 cpp 编写 的,因此你仍然可以直接使用它,因为 cpp 中使用的所有关键字都来自于苹果的 Security.framework,你尝试使用相同的东西了吗? 你可以使用整个 SSL.cpp 文件。我认为这对你有用。 - iphonic
/System/Library/Keychains/SystemRootCertificates.keychain 在 iOS 上根本不存在。或者至少你无法读取它,因为一切都被沙盒化了。 - KevinResoL
2个回答

5
很抱歉,由于iOS应用程序生态系统是沙盒化的,因此无法进行等效操作。如果不知道您的目的,通常解决此问题的方法是从apple.com/certificateauthority下载苹果根证书,然后将其存储在您的应用程序中以供阅读。此外,可以参考此文章进行灵感启示。顺便说一句:如果iOS设备越狱,则有可能实现这一操作。

目的是在iOS中使用mbedtls(以前称为PolarSSL)。因为mbedtls需要根CA才能正常运行。发布的macOS代码就是做这件事的。 - KevinResoL
他们正在做类似的事情。这可能会给你一些启示。作为一个选项,你可以将它转换成DER格式以防万一。 - Ricowere
该示例仅从互联网上下载一个根证书(苹果公司的证书),或将其捆绑在应用程序中。因此,它与我的要求非常不同。(我需要所有根证书存储在设备本身中) - KevinResoL

4

Security.framework中获取存储在系统中的根证书的函数SecTrustCopyAnchorCertificates仅适用于macOS。有趣的是,它是一组相关函数中少数不适用于iOS的函数之一。谁知道这是否是故意的呢?


抱歉,我不太明白。我的代码没有使用SecTrustCopyAnchorCertificates,所以我不确定你为什么提到它。换句话说,你的意思是由于某些API在iOS上并不可用,因此我的原始问题根本没有解决方案吗? - KevinResoL
是的,在macOS上,有不同的方法可以检索系统中的根证书。由于iOS的沙盒限制,您问题中的代码片段在iOS上无法工作。SecTrustCopyAnchorCertificatesSecTrustSettingsCopyCertificates是两个函数,应该能够让您在iOS上检索根证书;但出于某种原因,它们在iOS上不可用。 - David H

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接