I'm working on a Node.js app that we will call "server A" where users have to provide a client certificate in order 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 make a request to 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 have not found a way to get a proper X509 certificate with the getPeerCertificate function, which returns a "custom" object representation of the certificate. As described in the official documentation, the cert parameter must be provided with the following data :
Public x509 certificate to use. Default null.
Is there a way to get the client certificate in the correct format for that purpose?
I had the same problem and saw your question with no answers, so I'm coming back to post my solution.
The certificate object has a raw
field which contains the certificate data you want in byte form. To get it in X509 format, just convert it to base64. So the code you're looking for is:
req.socket.getPeerCertificate(true).raw.toString('base64');
Hope that helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With