Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Procedure/Mechanism for using System's cacerts instead of Node's? #7608

Open
docwhat opened this Issue · 3 comments

4 participants

Christian Höltje Fedor Indutny Timothy J Fontaine Trevor Norris
Christian Höltje

I would like Node to be able to use my system's CA Certificates instead of the ones built in.

This is because I run software in a controlled environment that manages the CA Certs tightly (we have a group that vets them) and we have our own site-specific CA Certs that Node needs to know about.

All the solutions so far involve turning off strict-ssl either per request or globally (ack!). Or a convoluted bit of code that reads in the CA Certs and parses them and feeds them in as options (which means we have to modify 3rd party software or force load our own code that sets global options before their code runs).

Instead, it would be nice if there was a procedure or mechanism for telling Node to use our certificates. We can provide them in a "cert directory" format (one file per cert) or in a single file format.

Traditionally, with OpenSSL, you'd use something like the environment variables SSL_CERT_FILE or SSL_CERT_DIR for this. I'm not a fan of using environment variables, but it would at least be a good start.

This would solve problems with people not having trusted CA Certs and "working around it" by turning off strict-ssl in various ways (see all the Stack Overflows for example).

Ciao!

Trevor Norris trevnorris added the crypto label
Fedor Indutny
Owner

Hello, thanks for sharing this!

Does ca option work for you? I'm ok with loading certificates from env variable, but would like to see if the ca works for you first.

Cheers,
Fedor.

Christian Höltje

Caveat: I'm not an experienced node programmer...

Here's my code:

var https = require('https');
var fs = require('fs');
var i, url;

var cas = [
  fs.readFileSync('/path/to/caintermediatecert.pem', 'utf8'),
  fs.readFileSync('/path/to/carootcert.pem', 'utf8')
];
https.globalAgent.options.ca = cas;

var urls = [
  'https://google.com/',
  'https://gitlab.bigdatalab.ibm.com/',
  'https://internal.example.com/'
];

function fetcher(url) {
  console.log('Fetching: ' + url);

  https.get(url, function(result) {
    result.setEncoding('utf8');

    result.on('data', function() {});
    result.on('end', function() {
      console.log('Success:  %s', url);
    });
  }).on('error', function(err) {
    console.log('Error:    %s -- %s', url, err);
  });
}

for (i in urls) {
  url = urls[i];
  fetcher(url);
}

I get this output:

Fetching: https://google.com/
Fetching: https://internal.example.com/
Success:  https://internal.example.com/
Error:    https://google.com/ -- Error: CERT_UNTRUSTED

To make this work for both URLs, I need a way to add to https.globalAgent.options.ca instead of replacing it. But https.globalAgent.options.ca seems to be undefined by default, so I assume the real ca is someplace else.

And to make this "easy" for users, I would need a way to tell node to use my ca cert bundle. e.g. on my Mac with Homebrew installed, I would want it to use /usr/local/etc/openssl/osx_cert.pem. Ideally, this would be a compile time option with the ability to override it via environmental variables.

Ciao!

PS: If you're wondering how I got into this its because our hubot can't fetch URLs from internal sites. :-)

Timothy J Fontaine
Owner

see also #7148

We will be adding a mechanism to do this and contributions are welcome, but it doesn't exist yet -- for now either doing it programmatically or at build time is the only solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.