Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 531
Chris Seymour Avatar asked Feb 07 '16 20:02

Chris Seymour


People also ask

How do I fix SSL error in Postman?

If certificate verification fails when sending a request, Postman displays an error message in the response pane. To fix the error, turn off SSL verification for the request: Open the request and select the Settings tab. Select Enable SSL certificate verification to turn off this setting.

How do I fix unable to get local issuer certificate?

When ssl certificate problem unable to get local issuer certificate error is caused by a self-signed certificate, the fix is to add the certificate to the trusted certificate store. Open the file ca-bundle. crt located in the directory above, then copy and paste the Git SSL certificate to the end of the file.


1 Answers

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);
    }
});
like image 64
Chris Seymour Avatar answered Oct 17 '22 07:10

Chris Seymour