Checking Certificates Meet Apple Requirements

Solution 1:

So it turns out there is an OS level tool, security

For example, I can test if a certificate ca.crt is valid like this:

security verify-cert -c ca.crt

Here's what a valid certificate will look like:

❯ security verify-cert -c ca.crt
...certificate verification successful.

And here's a certificate with a 10 year expiration that violates Apples rules, but is otherwise valid according to OpenSSH:

❯ security verify-cert -c ca.crt
Cert Verify Result: CSSMERR_TP_NOT_TRUSTED

Solution 2:

There are two possible ways using the CLI to check the validity of certificates:

  1. You have the certificate files somewhere accessible on your harddisk.
  2. You only have them installed, but not accessible on the harddisk.

Number one needs a bit more CLI work, number two can be done online and shows the complete certificate chain.

  1. You have the certificate files somewhere accessible on your harddisk. For checking the certificate file, we need to know in which format they are. Here is an example with a PEM format file:

    openssl x509 -in FILENAME -text

You can also choose the input format with

openssl x509 -inform PEM -in FILENAME -text

(PEM is default) That gives you a quite long text output on each certificate file and you have to validate the issuer, the CN, the expiration date manually by comparing it to the CA or root certificate. The second method will come in more handy:

  1. You only have them installed, but not accessible on the harddisk.

You can use the openssl s_client command to validate the complete chain.

openssl s_client -connect YOURSERVER:SSLPORT

You will immediately see the certificate AND the installed root chain and openssl is also telling you expiration dates and so on. Here is an example from my personal website:

openssl s_client -connect FQDN-DELETED:443
CONNECTED(00000005)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = FQDN-DELETED
verify return:1
---
Certificate chain
 0 s:/CN=FQDN-DELETED
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
...
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGUzCCBTugAwIBAgISA+Y4i63Ury6g85b3DghU9muyMA0GCSqGSIb3DQEBCwUA
...
-----END CERTIFICATE-----
subject=/CN=FQDN-DELETED
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
---
No client certificate CA names sent
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3742 bytes and written 322 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
...

There is much more output - just have a look. Send me back questions, if you have.