12

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?

antialiasis
  • 831
  • 1
  • 8
  • 19
  • Just to clarify, how did you generate the hash values? Do they match what you get with `openssl x509 -subject_hash` on the CA cert, and what you get with `openssl x509 -issuer_hash` on the cert to verify? Is the `.0` extension present? – Bruno Aug 20 '12 at 17:31

1 Answers1

16

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.

Bruno
  • 119,590
  • 31
  • 270
  • 376
  • 2
    I've checked the hashes, and apparently the problem is there are intermediate CA certificates from Apple that the official instructions seem to fail to mention. I still have to look into those, but at least now I'm past this hurdle. Thanks immensely for a clear, helpful and accurate answer. – antialiasis Aug 21 '12 at 10:31