I'm building a SSL crawler application where user pass in the domain name and NodeJS use tls
library to retrieve the SSL certificate.
First, here is my codes:
server.js
const tls = require('tls');
var rootCas = require('ssl-root-cas/latest').create();
const fs = require('fs');
fs.readdirSync('./keys/intermediate_certs').forEach(file => {
rootCas.addFile('./keys/intermediate_certs/' + file)
});
var secureContext = tls.createSecureContext({
ca: rootCas
});
options = {
host: host, //domain like google.com
port: 443,
secureContext: secureContext,
ca: rootCas,
rejectUnauthorized: true
};
var tlsSocket = tls.connect(options, function () {
let rawCert = tlsSocket.getPeerCertificate()
console.log(rawCert)
})
tlsSocket.on('error', (error) => {
console.log(error)
// [ERR_TLS_CERT_ALTNAME_INVALID] Hostname/IP does not match certificate's altnames: Host: zdns.cn. is not in the cert's altnames: DNS:*.fkw.com, DNS:fkw.com
// unable to verify the first certificate or UNABLE_TO_VERIFY_LEAF_SIGNATURE
});
Problem is the nodejs application throwing error, according to the TLS
documentation, the errors were from OpenSSL, however, when browsing the website and view certificate
is showing all valid (even the common name matched exactly).
Here are some criteria:
- zdns.cn / www.zdns.cn is showing the error:
ERR_TLS_CERT_ALTNAME_INVALID
; When view cert from browser it show*.zdns.cn
- knet.cn / www.knet.cn is showing the error:
unable to verify the first certificate
; When view cert from browser it showwww.knet.cn
Note: I included latest root CA from ssl-root-cas
and also downloaded the intermediate certificate
manually from CA site.