views:

177

answers:

3

I have just started working with X.509 certificates. Can any one tell me how to go about validating a certificate on linux? The use case is that my app had downloaded a certificate in a previous session and I have to check if it is still valid (i.e., not expired or revoked since it was stored) before starting a new session. I understand a full sample will not be possible here, but any pointers will be useful.

EDIT: Further investigation revealed another utility called Network Security Services (NSS). How does that compare to OpenSSL in terms of usability? Also, I am looking for programmatic solutions as I will not be able to launch command line utilities.

A: 

OCSP is a protocol to check revocation of certificates. Openssl provides certificate chain validation and signature verification APIs. It requires some amount of coding. So i would suggest you to look into Openssl Documentation.

You have to pass the certificate chain and validate it until you reach a root certificate which should be already saved on your machine. This is self signed certificate issued by entities called Root CAs(Certificate authority)

Apart from OCSP there is a outdated method where you have to fetch revocation list namely CRLs and parse that list for the certificate id.

EDIT: I forgot to mention the openssl command line utility which does the same functionality.

Praveen S
+2  A: 

openssl verify will do what you want, if you want a simple tool:

From running:

cd /usr/share/ca-certificates
find . -type f -exec openssl -verify {} \;

Here's a selection of the output:

./telesec.de/deutsche-telekom-root-ca-2.crt: OK
./brasil.gov.br/brasil.gov.br.crt: OK
./cacert.org/cacert.org.crt: OK
./spi-inc.org/spi-ca-2003.crt: /C=US/ST=Indiana/L=Indianapolis/O=Software in the Public Interest/OU=hostmaster/CN=Certification Authority/[email protected]
error 10 at 0 depth lookup:certificate has expired
OK
./spi-inc.org/spi-cacert-2008.crt: OK
./signet.pl/signet_ocspklasa3_pem.crt: /C=PL/O=TP Internet Sp. z o.o./CN=CC Signet - CA Klasa 3/serialNumber=Numer wpisu: 4
error 2 at 1 depth lookup:unable to get issuer certificate
./signet.pl/signet_ca3_pem.crt: /C=PL/O=TP Internet Sp. z o.o./CN=CC Signet - CA Klasa 3/serialNumber=Numer wpisu: 4
error 20 at 0 depth lookup:unable to get local issuer certificate

If you'd rather have the results in a larger program, perhaps the gnutls_x509_crt_verify(3), gnutls_x509_crt_get_key_usage(3), gnutls_x509_crt_check_revocation(3) interfaces are easier to use than OpenSSL. (I've never used gnutls, but I have used OpenSSL.)

sarnold
+1  A: 

Ok, let me begin.

As others mentioned, you can use openssl verify. According to the documentation, it checks the validity period too.

Programmatically, it means hours of searching for kinda bad (or missing) documentation, reading code examples all over the web, and maybe a headache.

In short, to validate if a certificate is signed by the CA, issuer, or someone's else certificate, you need to inform all the intermediary certificates, plus the revocation list (CRL), if you need it. To keep this answer short, let's assume the certificate was issued and signed by the CA.

Now, here is what you really need to do in terms of code (openssl):

  1. X509_STORE_new - Create a certificate store;
  2. X509_STORE_CTX_new - Create a store context;
  3. X509_STORE_add_cert - Add the CA (and all intermediary) certificate(s) to the trusted list of your certificate store (note: there's a function to lookup/load a list);
  4. X509_STORE_add_crl - Add the revoked certificates to the CRL of your certificate store (note: same as above);
  5. X509_STORE_CTX_init - Initialize your store context informing your certificate store;
  6. X509_STORE_CTX_set_purpose - Define the purpose if you need so;
  7. X509_STORE_CTX_set_cert- Tell the context which certificate you're going to validate;
  8. X509_verify_cert - Finally, validate it;
  9. X509_STORE_CTX_cleanup - If you want to reuse the context to validate another certificate, you clean it up and jump back to (5);
  10. Last but not least, deallocate (1) and (2);

I hope this helps many people, because I needed it recently, and took me a day of searching/reading/testing :-)

Okay, I assume. After I finished my code, I figured out everything I needed was right on the OpenSSL source-code. If you need an example, go straight to openssl-xxx/apps/verify.c.

jweyrich