Need list of root certs on iOS

I need to get the list of trusted root certificates, but for some reason the function SecTrustCopyAnchorCertificates is not available on iOS. Is there any workaround?


We need the list because we have a large cross-platform codebase that uses the open-source mbedTLS library to run TLS connections. The mbedTLS API requires being given a list of root certs. It does not have a callback for evaluating the trust of a cert, so it's not feasible to plug SecTrust into it.


In an earlier thread on this topic it was suggested to copy Apple's published list of certs and paste it into the app. That's bad security: root certs can and do get revoked, and of course they expire and new ones can be added, so the root cert list has to be a dynamic entity that can be updated on the fly. Hardcoding a copy into an app puts that app developer on the hook for updating their app to fix security issues involving the global root cert list. Hardcoding it into a library (in our case) would put all of our users/customers in that situation.


I've never understood why SecTrustCopyAnchorCertificates wasn't added on iOS. These certs are public knowledge, so how can making them available be a security issue? I suspect it's done to keep people from using non-Apple cert/trust APIs, and ordinarily I do believe in using platform APIs, but when we have a large complex codebase that has to support everything from iOS to Android to Windows 10 to CentOS, that doesn't always work out.


--Jens

Accepted Reply

As often happens, soon after posting a question I discovered a solution. Specifically, mbedTLS does have a function that enables callback-based root cert lookup. It's called `mbedtls_ssl_conf_ca_cb()` — with a name like that I don't know why it didn't leap out at me earlier 🙄


So yes, using that function I can evaluate a cert passed to me by mbedTLS during the handshake, using the SecTrust API, and find and return the appropriate root cert. Problem solved!

Replies

I just took another look through the Security interfaces and didn't see an API on iOS to do this. If you are in need to check if a leaf can establish a chain of trust to a system installed root certificate, you could use SecCertificateCopyData and SecTrustCreateWithCertificates to create a SecTrust object. This was a technique mentioned on that referenced post and should allow you to check on a leaf by leaf basis. Obviously this is not what you are looking for, but if the other alternative is being non-functional, it would be a path to explore.



Matt Eaton

DTS Engineering, CoreOS

meaton3 at apple.com

As often happens, soon after posting a question I discovered a solution. Specifically, mbedTLS does have a function that enables callback-based root cert lookup. It's called `mbedtls_ssl_conf_ca_cb()` — with a name like that I don't know why it didn't leap out at me earlier 🙄


So yes, using that function I can evaluate a cert passed to me by mbedTLS during the handshake, using the SecTrust API, and find and return the appropriate root cert. Problem solved!