Chris Seymour
Chris Seymour

Reputation: 85785

Unable to verify the first certificate

I have a directory containing a certificate bundle, a Python script and a Node script. Both scripts make a GET request to the same URL and are provided with the same certificate bundle. The Python script makes the request as expected however the node script throws this error:

{ [Error: unable to verify the first certificate] code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' }

The Python script (Python 3.4.3 and the requests library):

import requests
print(requests.get(url, verify='/tmp/cert/cacert.pem'))

The node script (Node 4.2.6 and the request library):

var fs = require('fs');
var request = require('request');

request.get({
    url: url,
    agentOptions: {
        ca: fs.readFileSync('/tmp/cert/cacert.pem')
    }
}, function (error, response, body) {
    if (error) {
        console.log(error);
    } else {
        console.log(body);
    }
});

Both are using the same OpenSSL version:

$ python -c 'import ssl; print(ssl.OPENSSL_VERSION)'
OpenSSL 1.0.2e-fips 3 Dec 2015

$ node -pe process.versions.openssl 
1.0.2e

I don't believe the problem to be with the certificate bundle and I don't want to turn off host verification in Node.

Does anybody know why Node is throwing this error?

Upvotes: 7

Views: 3752

Answers (2)

Chris Seymour
Chris Seymour

Reputation: 85785

The documentation describes the ca option as follows:

ca: A string, Buffer or array of strings or Buffers of trusted certificates in PEM format. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections.

So it doesn't expect a CA bundle. The fix is simple however, just split the bundle like so:

var fs = require('fs');
var request = require('request');

var certs = fs.readFileSync('/tmp/cert/cacert.pem').toString().split("\n\n"); 

request.get({
    url: url,
    agentOptions: {
        ca: certs
    }
}, function (error, response, body) {
    if (error) {
        console.log(error);
    } else {
        console.log(body);
    }
});

Upvotes: 3

Alex Palcuie
Alex Palcuie

Reputation: 4974

Maybe you can use this module that fixes the problem, by downloading certificates usually used by browsers.

https://www.npmjs.com/package/ssl-root-cas

Upvotes: 0

Related Questions