adding a certificate or symmetric key to the keychain

I fund several examples to store a generic password in the keychain. But I'm more interested to add a certificate or a symmetric key to the keychain. For the certificate I found a workarround to store the certifcate as NSData object in the "kSecValueData" attribute. But believe this is wrong if I try to set a SecCertificate I always get an error Code -50 in the call to the SecItemAdd method which means something is wrong with the attributes.

Replies

What platform are you working on?

What’s the goal in add a certificate? Are you trying to get your app (or the system as a whole) to trust that certificate?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I'm workin on iOS, Yes the goal is to add server side certificates (Root Certificate and server certificate) to the keychain to perform TLS authentication with the server.

I’m still not 100% sure I understand your goals but let me discuss the overall approach. You wrote:

I'm workin on iOS, Yes the goal is to add server side certificates (Root Certificate and server certificate) to the keychain to perform TLS authentication with the server.

I interpreted that to mean that your server uses a leaf certificates whose chain of trust ends in a root certificate that’s not trusted by iOS by default. If so, the keychain is not the droid you’re looking for. iOS does not store trusted root certificates in the keychain. Rather, it stores them in a separate database called the trust store. There is no API for the trust store.

If you want to customise TLS server trust evaluation, you should do that using the techniques described in Technote 2232 HTTPS Server Trust Evaluation.

However, my recommendation is that you not do this. In my experience there are three common cases where folks ask questions about this:

  • setting up a server for testing (A)

  • setting up a server in a managed environment, where it’s not appropriate to request a certificate from a standard certificate authority (CA) (B)

  • setting up a server for standard Internet use (C)

In case A you should create your own CA and have that issue your test certificates, then install that CA’s root certificate on your test devices. Technote 2326 Creating Certificates for TLS Testing explains how to do that.

For case B you should create a CA for your managed environment (most enterprises already run their own CA), have that CA issue your server certificate, and then install that CA’s root certificate on your device (typically via MDM).

For case C you should just bite the bullet and get a standard CA to issue you a certificate.

There are cases where overriding TLS server trust evaluation is your only option (for example, when using TLS in a peer-to-peer environment) but you should only do that when it’s your only choice. That’s because:

  • for HTTPS, overriding server trust evaluation requires you to opt out of App Transport Security

  • if you override TLS server trust evaluation incorrectly, you can introduce serious security vulnerabilities into your app

IMPORTANT Don’t underestimate this last point. Other developers have fallen into this trap. For example:

  • One well-used iOS HTTPS library had a bug that accidentally disabled HTTPS server trust evaluation completely.

  • I know of at least one well-used, and security-critical, iOS app that accidentally shipped to customers with their supposed-to-be-for-debug-only HTTPS server trust override code still enabled, effectively disabling HTTPS for their app.

Don’t be that guy!

All of the above applies to root certificates. For intermediate certificates the only correct approach (per the TLS RFCs) is to configured your server to return all intermediate certificates to your client as part of the TLS handshake. There are ways to work around this on the client side, but it’s both easier and safer to fix this on the server side.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"