Using node.js to verify a X509 certificate with CA cert

user826955 picture user826955 · Jan 22, 2018 · Viewed 12.1k times · Source

I am looking for a node.js way to verify a client certificate in X509 format with a CA certificate which was given to me (none of those are created/managed by me, my software only has to verify what is beeing sent to it).

I have found several modules for this job, however I am having issues with each of them:

  • X509 is able to do it using x509.verify(cert, CABundlePath, cb), however it needs to read the certificates from FS, and I am having them in memory already. This is cumbersome as it will be done with each web request which reaches my app.
  • It seems like PKI.js is able to do it, however their examples don't work for me but complain about missing files, so I can't even try it out.
  • I tried node-forge, but while I am unsure if I use it correctly (they don't have any API documentation) its throwing a forge.pki.BadCertificate error from forge.pki.verifyCertificateChain(caStore, [ cer ], cb).
  • When trying pem, using a simple pem.verifySigningChain(cer, [ ca ], cb) would throw some error complaining about loading a file from /var/.... Even if it would work, I would avoid using this lib as its relying on the openssl command line tool, which I would like to avoid

Now I feel pretty stupid because I failed to get this simple task done with any of the above modules. Could someone point me to a simple solution which will allow me to verify the signature/validity of a X509 certificate using a given CA certificate? :s

[edit] Basically I would need openssl verify -verbose -CAfile ca-crt.pem client1-crt.pem in Node.js but without dependencies to the openssl command line tool and without temporarily saving the certs to disk.

[edit2] Would it be possible to just use https://nodejs.org/api/crypto.html#crypto_verify_verify_object_signature_signatureformat?

Answer

user826955 picture user826955 · Jan 25, 2018

I finally managed to do it using node-forge. Heres a working code example:

let pki = require('node-forge').pki;
let fs = require('fs');

let caCert;
let caStore;

try {
    caCert = fs.readFileSync('path/to/ca-cert.pem').toString();
    caStore = pki.createCaStore([ caCert ]);
} catch (e) {
    log.error('Failed to load CA certificate (' + e + ')');
    return....;
}

try {
    pki.verifyCertificateChain(caStore, [ cert ]);
} catch (e) {
    return handleResponse(new Error('Failed to verify certificate (' + e.message || e + ')'));
}

Both certificates shall be given in base64 encoded PEM format/js string.

verifyCertificateChain checks the certifitate validity (notBefore/notAfter) as well as verifies the given CA chain.

I am not 100% sure if this is the best approach, or if this library is doing a good job, since their source code of verifyCertificateChain is full of #TODOs, so maybe this is not ready for production? But at least I have a somewhat working solution. Probably it would be better to create a node module which wraps the libssl c calls, but thats just a lot of effort for this small task.