Read critical extensions from https certificate

1.1k views Asked by At

I want to do custom validation for node https certificate verification. So, in https options I have set rejectUnauthorized property to false.

var httpsOptions = {
    ...
    rejectUnauthorized: false,
    ... 
};

Now even if certificate verification internally fails, request won't fail. I want to handle that part manually. I wanted to handle unhandled critical extension error. My code to do so is,

var req = https.request(httpsOptions, (res) => { 
  var data = '';
  res.on('data', (chunk) => { 
      data += chunk;
  }); 
  res.on('end', () => {
    console.log(data);
  });
});

req.on("socket", function () {
  req.socket.on('secureConnect', () => {
    if(!req.socket.authorized){
      if(req.socket.authorizationError === 'unhandled critical extension'){
        // Place to verify extensions
      }
      process.nextTick(() => {req.abort();});      
    }
  });
});

req.write(JSON.stringify(requestObj));
req.end();

The above code works as expected. I can say when unhandled critical extension error occurs. Inside the if condition(Place to verify extensions), I want to see what are all critical extensions that are unhandled. If it didn't match the list I have, I want to abort the request. req.socket has so many properties, so I could not paste here. There is no field in it, which holds those unhandled critical extensions. How to extract the unhandled critical extensions which caused the error?

Note: I have seen some npm packages which could parse ssl certificates like x509 and PKIjs. It gives lots of confusion and I could not find any working example which can solve my problem.

EDIT:

req.socket.getPeerCertificate().raw gives the DER certificate in Buffer format. How to decode it and view those extensions?

1

There are 1 answers

0
RaR On

First we need to get the server certificate. We can use req.socket.getPeerCertificate() to get it. It returns a JSON object but it won't have extensions section. But, it will be having the entire certificate in buffer format in its raw property.

var certInBuf = req.socket.getPeerCertificate().raw;

There are a lot of packages available to convert this buffer format to pem format. One of them is pemtools

var certInPem = pemtools(certInBuf, 'CERTIFICATE').toString();

Then we can use node-forge to parse the certificate and extract the extensions.

var pki = require('node-forge').pki;
var extensions = pki.certificateFromPem(certInPem).extensions;

Then we can validate the extensions. If not satisfied we can abort the request by calling req.abort()