Programmatically read root CA certificates in iOS
Asked Answered
C

2

12

The following code reads out the root certificates in macOS.

I just wonder what are the equivalent code in 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;
Copyreader answered 24/2, 2017 at 6:50 Comment(2)
Since the code you shown is written in cpp you can still use that directly as all the keywords used in the cpp comes from Security.framework from Apple, have you tried using the same, you can use the whole SSL.cpp? I think it will work for you.Arsenate
/System/Library/Keychains/SystemRootCertificates.keychain simply doesn't exist on iOS. Or at least you can't read it because everything is sandboxed.Copyreader
B
5

I'm afraid it won't be possible to do an equivalent in iOS given the app ecosystem is sandboxed.

Without knowing your purposes, the usual approach for tackling this is downloading the apple root certificate from apple.com/certificateauthority and then storing it in your app for reading it.

Take a look this article for inspiring you as well.

PS: It might be possible to do this in an iOS device if it's jailbroken.

Bil answered 5/3, 2017 at 17:22 Comment(3)
The purpose is to use mbedtls (previously known as PolarSSL) in iOS. Because mbedtls needs the root CA to function. The posted macOS code does that exact thing.Copyreader
They are doing similar. It might inspire you. As an option you could convert it in DER format just in case.Bil
That example downloads only one root cert (the Apple one) from the internet, or bundled it inside the app. So it is quite different from my requirement. (I need all root certs stored in the device itself)Copyreader
H
4

The function SecTrustCopyAnchorCertificates from Security.framework that lets you retrieve root certificates stored in the system is only available on macOS. Curiously, it is one of the few functions (from set of related functions) that is not available on iOS. Deliberate, who knows?

Histogenesis answered 10/3, 2017 at 22:11 Comment(2)
Sorry, I don't quite get it. My code didn't use SecTrustCopyAnchorCertificates so I am not sure why you mentioned it. Or in other words, do you mean that there is simply no solution to my original question because there are some API simply just not available on iOS?Copyreader
Yes. On macOS, there are different ways to retrieve the root certificates in the system. The code snippet in your question won't work on iOS due to iOS's sandbox restrictions. SecTrustCopyAnchorCertificates and SecTrustSettingsCopyCertificates are the two functions that should give you the ability to retrieve root certificates on iOS; but for whatever reasons, they are not available on iOS.Histogenesis

© 2022 - 2024 — McMap. All rights reserved.