Reputation: 85785
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
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
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