12

I've been given an SSL cert to use for signing client requests, as well as the relevant CA certs. I can verify it using openssl:

$ openssl s_client -CAfile /etc/ssl/foo/ca-combined.pem -servername foo.co.in -connect foo.co.in:443 CONNECTED(00000003) ... snip ... Verify return code: 0 (ok) --- closed 

(I mashed the 2 CA certs into one file). But when I try to replicate it using node:

 var tls = require('tls'); var fs = require('fs'); var options = { host: 'foo.co.in', servername: 'foo.co.in', port: 443, key: fs.readFileSync('/etc/ssl/private/foo.key'), cert: fs.readFileSync('/etc/ssl/foo/cert.pem'), ca: [fs.readFileSync('/etc/ssl/foo/combined-ca.pem')] }; tls.connect(options, function(err) { done(err); }); 

I get an error:

Uncaught Error: unable to get local issuer certificate at Error (native) at TLSSocket.<anonymous> (_tls_wrap.js:1092:38) at TLSSocket._finishInit (_tls_wrap.js:610:8) at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:440:38) 

I found an answer on here, suggesting that I need to put each CA cert in a separate file:

ca: [fs.readFileSync('/etc/ssl/foo/ca.pem'), fs.readFileSync('/etc/ssl/foo/root-ca.pem')] 

but that still gave the same error. (I also tried reversing the order). I then tried putting the intermediate cert in with the client one, and just providing the root CA cert as ca (which seems to be what the docs suggest), same error. At this point I'm running out of ideas. The fact that openssl is happy suggests that I'm doing something wrong, any suggestions?

$ node --version v6.10.1 

(I realise I can set rejectUnauthorized to false, but I'd really rather not)

4
  • which backend server you are using? nginx, apache or something else? Commented Apr 5, 2017 at 11:22
  • that's out of my control. I gave them a CSR, and they generated a client cert for me, and gave me the CA certs Commented Apr 5, 2017 at 12:43
  • Refer this stackoverflow.com/questions/46968937/… Commented Oct 12, 2018 at 4:34
  • turning off verification isn't a good solution, in general Commented Oct 12, 2018 at 10:36

4 Answers 4

6

Turns out that I didn't need to supply the CA cert, as their CA was properly signed by a "known" authority. So I could just remove the ca field from my request.

Sign up to request clarification or add additional context in comments.

Comments

4

I created a root-ca and a intermediate-ca (signed by root-ca) certificates, then I created a server and a client certificates signed by intermediate-ca. To test it I've been implementing a server and client https with nodejs so a set it up with the certs and a get the following error on my client:

problem with request: unable to get local issuer certificate 

To solve it I need to put in my nodejs codes, at ca field, my root-ca and intermediate-ca certs. Like that:

key: fs.readFileSync('path/client.privkey.pem'), cert: fs.readFileSync('path/client.cert.pem'), ca: [ fs.readFileSync('path/intermed-ca.cert.pem'), fs.readFileSync('path/root-ca.cert.pem') ], 

it works for me.

1 Comment

how i can to create client certificates ?
4

To solve this generally for you system you have 2 different options:

The first is to export the variable NODE_EXTRA_CA_CERTS=$PATH_TO_YOUR_CUSTOM_CA_FILE.pem pointing to your custom CA_FILE

The second is to run node with the option --use-openssl-ca like:

node --use-openssl-ca main.js 

This assumes that you already configured your ssl certificates with something like:

wget -qP /usr/local/share/ca-certificates http://your_local_cert/local_ca.pem\ && update-ca-certificates 

See https://github.com/microsoft/vscode-remote-release/issues/5620

Comments

0

I've encountered the same issue when I had to use my custom SSL certificate and pass it in the ca field of the https.Agent.

The docs clearly state that if you're overriding this field, you lose all certificates that were there by default:

Mozilla's CAs are completely replaced when CAs are explicitly specified using this option.

So in my case, to resolve the issue I had to add default root certificates in the ca array like so:

import https from "https"; import tls from "tls"; import { getMyCustomCert } from "@some-namespace/internal-cert"; new https.Agent({ ca: [...tls.rootCertificates, getInternalCert()], }); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.