Node.js: access client certificate

I am working on a Node.js application that we will call "Server A" where users have to provide a client certificate to access services.

Simplified example:

/** server setup **/
var serverOptions = {
    key: fs.readFileSync('certs/server.key'),
    cert: fs.readFileSync('certs/server.crt'),
    ca: [fs.readFileSync('certs/ca.crt'), fs.readFileSync('certs/bar.cer'), fs.readFileSync('certs/foo.cer')],
    requestCert: true
};

https.createServer(serverOptions, app).listen(SERVER_PORT, '', null, function () {
    var host = this.address().address;
    var port = this.address().port;

    console.log('listening at http://%s:%s', host, port);
});

      

Everything works as expected, the following code prints the details of the client certificate.

app.get('/', function (req, res) {

    /*** Dump ***/
    res.contentType('application/json');
    res.send(util.inspect(req.socket.getPeerCertificate(true), {colors: true}));

});

      

However, I would like to be able to use this client certificate obtained in serverA to request another server called "server B".

options = {
    hostname: 'localhost',
    port: '3010',
    path: '/',
    method: 'POST',
    headers: {
        'Content-Type': 'text/xml;charset=UTF-8',
        'Content-Length': serverResponse.length,
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 
    },
    cert: clientCertificate
};

var req = https.request(options, function (res) {

    console.log('statusCode: ', res.statusCode);
    console.log('headers: ', res.headers);

    res.on('data', function(d) {
        callback(d);
    });
});

      

The problem is that I haven't found a way to get the proper X509 certificate using the getPeerCertificate function, which returns a "custom" representation of the certificate object. As described in the official documentation, the cert parameter must be provided with the following details:

Open x509 certificate for use. The default is null.

Is there a way to get the client certificate in the correct format for this purpose?

+3


source to share


1 answer


I had the same problem and saw your question with no answers, so I come back to post my solution.

The certificate object has a field raw

that contains the certificate data you want in byte form. To get it in X509 format, just convert it to base64. So the code you are looking for is:



req.socket.getPeerCertificate(true).raw.toString('base64');

      

Hope it helps!

+2


source







All Articles