Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read expiration date and common name from SSL certificate using Node.js

In an https-enabled Node.js I have the certificate as a .pem file.

Now I would like to read some data from that file to have information about the certificate, such as its expiration date and the common name.

As I have seen neither Node's very own tls module nor modules such as ursa support this.

Of course I might call openssl as a child process and parse its output stream (I think this task should be doable using OpenSSL), but I'd prefer a solution without relying on the availability of an external program in the path.

How could I do this?

Update: Meanwhile, I found the pem module, and its readCertificateInfo provides the common name successfully, even using Node.js 0.8.18 (which is contrary to its docs who state that 0.7+ is not supported). Unfortunately, it does not return the expiration date.

Update 2: Internally, pem just calls out for the openssl command using a child process. Of course I can do this by myself, hence I am able to retrieve the information required from openssl directly. Anyway, if someone has a better idea (which, in this case means, a pure JavaScript / Node.js solution) I'd be happy about it :-)

like image 224
Golo Roden Avatar asked Jan 30 '13 08:01

Golo Roden


2 Answers

Meanwhile I found the answer: The PEM format is basically ASN.1 using a Base64 encryption.

Hence, you need to Base64 decode first, and then parse the result as ASN.1. The result is the data structure of the certificate with the appropriate values in it.

That's it :-)!

like image 92
Golo Roden Avatar answered Oct 30 '22 11:10

Golo Roden


If you're obtaining the certificate from something like tls.connect you can call getPeerCertificate() and you'll get back a structure that looks like this (connected to github.com):

{ subject: 
   { C: 'US',
     ST: 'California',
     L: 'San Francisco',
     O: 'GitHub, Inc.',
     CN: '*.github.com' },
  issuer: 
   { C: 'US',
     O: 'DigiCert Inc',
     OU: 'www.digicert.com',
     CN: 'DigiCert High Assurance CA-3' },
  subjectaltname: 'DNS:*.github.com, DNS:github.com',
  modulus: 'EF45CDFAEC13EF3E0CD38685530109CA9A3A4E5AF980CBC1BD51509C9944A8CDEB61EA951D4F3053C69FD6D355EDD13A3A43E96DD437C98813DA458E5C99F0811D7A0736EAB1DF0E3C600590A212DB3566D6E077A8A37951A653104F37BC46E38EDC101393990D6AB3101D8714DD78607B547B34A9F2E9E33B5F51B56AA76220BF9DE12A757D9424524A8DCD2D9B5C962FD8DFE8FD38BD80AC116061E7B3B7BF81AE8321C9EB7488F27D116603425FA755F4EC00ABF123BB5AABFBCA7C13AB288C0EC122F99424CA06A4D2A846D6D44618E5CF21B6B9D6D9518639506604A906600F1D6FA8A09B82AF7143645577A656B16D35EC7CAF48AD012E762D16E6D7C1',
  exponent: '10001',
  valid_from: 'Apr 30 00:00:00 2012 GMT',
  valid_to: 'Jul  9 12:00:00 2014 GMT',
  fingerprint: 'B1:4B:A1:6F:5C:EE:28:DA:C4:86:CD:D9:F2:80:8F:2E:A7:4A:51:F4',
  ext_key_usage: [ '1.3.6.1.5.5.7.3.1', '1.3.6.1.5.5.7.3.2' ] }

I haven't found a decent way to parse arbitrary local certs though, sorry.

like image 27
Paul Kehrer Avatar answered Oct 30 '22 10:10

Paul Kehrer