How to select a certificate from a PEM file with multiple certificates

opensslsmimex509

Background info: I am working on an OS X server, and I need to use certificates from the key chain with openssl smime in order to encrypt messages in a bash script. In order to do so, I use the security find-certificate with the -e option to extract the certificates for a certain email address from the OS X key chain. This works well, however, the command extracts all certificates which are found for that email address to the PEM file. The file will even contain expired certificates.

When I use the PEM file for mail encryption with openssl smime, obviously only the first certificate in the PEM file is used.

So what needs to be done is to select the certificate with the highest expiration date from the PEM file, so I can use that one with openssl, but how can this can be done?

Best Answer

If any unexpired cert is acceptable:

$ # adjust filenames for your environment as desired 

$ cat <<\EOF >awkscript # only need to do this setup once
BEGIN{ cmd="openssl x509 <tempfile -checkend 0" }
/^-----BEGIN/ {f=1} 
f {print >"tempfile"} 
/^-----END/ {f=0; close("tempfile"); cmd | getline status;
  if( status ~ "not expire" ){ exit 0 }; close(cmd) }
END{ exit 1 }
EOF

$ if awk -f awkscript combinedpemfile
> then # use tempfile as cert for encryption
> else # no unexpired cert found 
> fi

If you need specifically need the last-expiring I don't see an easy way to automate the date comparison but this does the rest:

$ cat <<\EOF >awkscript # again only once
BEGIN{ cmd="openssl x509 -noout -enddate" }
/^------BEGIN/ {f=1; t=""} f {t=t $0 ORS} 
/^-----END/ {f=0; out="tempcert#"(++i); print t >out; 
  printf "%s: ",out; print t | cmd; close(cmd) }
EOF

$ awk -f awkscript combinedpemfile
tempcert#1: notAfter=(expiryfor1)
tempcert#2: notAfter=(expiryfor2)
tempcert#3: notAfter=(expiryfor3)
...
$ # pick the latest expiry and use the corresponding file (and clean up)