How do I make Safari automatically use a particular client certificate for an entire site?

Solution 1:

Safari's client certificates and related preferences are stored in Keychain Manager with a kind of certificate.

When you select a certificate to use with a web site, it stores another entry in the Keychain Manager with a kind of identity preference. Unfortunately, by default it stores it only for the exact page you were on. Both the name and location are set to the URL of the page.

To fix this, you can just edit one of the identity preference entries and change the where section to the base URL, like https://somesslsite.com/ (the trailing slash is important!). I also update the name to the same thing to prevent confusion. You can then delete all of the other identity preference entries for that site.

If you have a certificate that expired and you've had to add a new one, I would recommend that you delete the old certificate entries and all of the related identity preference entries.

To find certificate and identity preference entries, open Keychain Manager, make sure All Items is selected, and search for the partial URL and/or certificate name as appropriate. You probably don't have many, so if that doesn't work just sort the list by kind and you should be able to find them easily.

NOTE: I'm answer this myself since I figured it out but wanted to persist the knowledge for myself and others.

Solution 2:

Partial paths and wildcards are now supported in more recent versions of OS X. So you can use the Keychain Manager to create an identity preference for an entire web site and/or domain.

Partial path example (note that the trailing slash is required!):

https://server.mydomain.com/

Wildcard example:

*.mydomain.com

Full details here (from 'man security' page):

Prior to 10.5.4, identity preferences for SSL/TLS client authentication could only be set on a per-URL basis. The URL being visited had to match the service name exactly for the preference to be in effect.

In 10.5.4, it became possible to specify identity preferences on a per-server basis, by using a service name with a partial path URL to match more specific paths on the same server. For example, if an identity preference for "https://www.apache-ssl.org/" exists, it will be in effect for "https://www.apache-ssl.org/cgi/cert-export", and so on. Note that partial path URLs must end with a trailing slash character.

Starting with 10.6, it is possible to specify identity preferences on a per-domain basis, by using the wildcard character * as the leftmost component of the service name. Unlike SSL wildcards, an identity preference wildcard can match more than one subdomain. For example, an identity preference for the name *.army.mil will match server1.subdomain1.army.mil or server2.subdomain2.army.mil. Likewise, a preference for *.mil will match both server.army.mil and server.navy.mil.

Solution 3:

I've been struggling with this myself and the above answer made me realize what was going on.

If you had a certificate for a website and it expired, what you should do is remove the old certificate. Then also remove the identity preference type items for that website. These old items are just as much expired as the certificate is. After you remove them, any new identity preference will be stored and used correctly.

So:

  1. Remove old certificate
  2. Remove old certificate's identity preference items
  3. Add new certificate

Then you can browse to the website, select the new certificate from the list, this will be remembered for that specific web address. Currently we are at Safari 5.1.3 and this version will not use any wildcards for preferences, you will have to add the preference for each change in web address... Hope this helps someone, just putting it out there because I didn't find any complete answer.