I'm trying to connect to Apple's Push Notification service from an Ubuntu server for an app. I've successfully generated the combined .pem certificate required by the pyAPNS provider I'm using. However, when I try to verify the certificate with openssl verify
, I get error 20 at 0 depth lookup:unable to get local issuer certificate
. It works if I specify the certificate authority explicitly (openssl verify apns.pem -CAfile entrust_2048_ca.pem
), but I've already explicitly installed the Entrust certificate on the system as instructed here, under "Importing a Certificate into the System-Wide Certificate Authority Database", and as far as I understand this page, everything is as it should be (the certificate is in /usr/lib/ssl/certs and there is a symlink to it with the hash).
The same happens if I try connecting to the APNS itself with openssl s_client
: it seems to connect okay if I specify the CAfile explicitly, but otherwise not. PyAPNS tells me it can't connect to the APNS server, and I can only presume that's for the same reason.
How do I get OpenSSL to recognize the Entrust certificate authority by default, without explicitly specifying it every time? Am I missing a step somewhere?
OpenSSL use a hash of the certificate's Issuer DN to look up the file in the default directory where the CA certificates are installed.
See OpenSSL verify
documentation:
-CApath directory
A directory of trusted certificates. The certificates should have names of the form: hash.0 or have symbolic links to them of this form
(``hash'' is the hashed certificate subject name: see the -hash option
of the x509 utility). Under Unix the c_rehash script will
automatically create symbolic links to a directory of certificates.
These hash values will comes from the Subject DN of each CA certificate (since the aim is to look for a CA certificate with the subject matching the issuer of the certificate to verify). You can either use c_rehash
as documented, or get the Subject DN's hash using openssl x509 -subject_hash -noout -in cacert.pem
and rename the file/link accordingly.
The direct issuer of the certificate to verify might not be a root CA certificate: there might be an intermediate CA certificate in the chain. You also need to make sure that the intermediate certificates are used.
In addition, there are two distinct hash formats (there was a change since OpenSSL version 1.0), it's worth making a link using both -subject_hash_old
and -subject_hash
, although OpenSSL itself by default should only use its new format.