Search code examples
iossecurityopensslcertificatekeychain

Accessing Apple's root certificate on iOS


I've found the following code: https://github.com/roddi/ValidateStoreReceipt/blob/master/validatereceipt.m which loads the root certificate ('Apple Root CA') on MacOS

and I'm trying to make it work on iOS as well.

Our code is written in C++ and uses OpenSSL for validating a remote peer when using SSL sockets.

On other platforms, we load the root certificate and add them to the context using X509_STORE_add_cert.

We then use SSL_get_peer_certificate and verify the hostname. These are NOT self-signed certificates which is why we want to use the root certificate of the device.

My question is how to get the root certificate on iOS devices?

EDIT:

I've tried the following query, but I keep getting -25300 (errSecItemNotFound).

NSDictionary* query=[NSDictionary dictionaryWithObjectsAndKeys:
                     (__bridge id)kSecClassCertificate,kSecClass,
                     kCFBooleanTrue,kSecReturnRef,
                     kSecMatchLimitAll,kSecMatchLimit,
                     kCFBooleanTrue,kSecMatchTrustedOnly,
                     nil];
SecItemCopyMatching((__bridge CFDictionaryRef)query,&ref);

Solution

  • You're going to want something along these lines:

    • Find the certificates using SecItemCopyMatching() with kSecMatchTrustedOnly set to kCFBooleanTrue. Remember, this will be a lot of certificates, not just one.
    • Then export them to DER format with SecCertificateCopyData().
    • Import them into OpenSSL
    • Profit

    Alternately, you can go the other way:

    • Convert certificate to DER using OpenSSL
    • Create a SecCertificateRef with SecCertificateCreateWithData()
    • Create a SecPolicyRef with SecPolicyCreateSSL()
    • Create a SecTrustRef with SecTrustCreateWithCertificates()
    • Evaluate with SecTrustEvaluate()
    • Profit

    Or of course you could also manage the SSL connection with NSURLConnection or with CFNetwork (available directly in C++) and the system would do everything for you automatically. Whenever possible, I recommend against using OpenSSL on iOS because it creates a lot of complexity. But the above should help you bridge if you need to.