node.jssslssl-certificatetls1.2requestjs

RequestJS - SSL connection is authorized but getPeerCertificate() returns null


I'm using the node package RequestJS v2.65.0 on node v4.1.2

I'm trying to read the SSL certificate from certain sites (eg. GitHub.com). This previously worked on node 0.12. On node 4.2.1, however, getPeerCertificate() returns null.

For example:

request({
  url: 'https://github.com'
}, function (err, res, body) {
  console.log('err:', err)
  console.log('peerCertificate:',res.req.connection.getPeerCertificate());
  console.log('authorized:',res.req.connection.authorized);
  console.log('authorizationError:',res.req.connection.authorizationError);
});

will print out

err: null
peerCertificate: null
authorized: true
authorizationError: null

i.e. the secure connection is established but the certificate is null.

From my (basic) understanding, if the connection is authorized, there should be a peer certificate.

I've tried with a number of SSL sites, and the result is the same. Is there an option in request, a bug with Node 4, or a misunderstanding on my part about how SSL/TLS works in node?


Solution

  • I think your problem is because the getPeerCertificate() will only output anything when the connection is in connected state, but when you receive your response, it's likely already too late.

    If you want getPeerCertificate to output, you should do it at the TLS level independently as such:

    const socket = require('tls').connect(443, "github.com", () => {
      console.log('client connected',
        socket.authorized ? 'authorized' : 'unauthorized');
      process.stdin.pipe(socket);
      process.stdin.resume();
    });
    

    Important! : Do not put the protocol in the URL. Rather, use require('url').parse(yourURL).hostname as the target.

    More info and example here: https://nodejs.org/api/tls.html#tls_tls_connect_port_host_options_callback