cert-info.js/lib/cert-info.js

107 lines
3.1 KiB
JavaScript

// Copyright 2016-2018 AJ ONeal. All rights reserved
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
var certInfo = module.exports;
var ASN1 = require("./asn1-parser.js").ASN1;
var PEM = require("./asn1-parser.js").PEM;
var Enc = require("./asn1-parser.js").Enc;
Enc.hexToBuf = function (hex) {
return Buffer.from(hex, 'hex');
};
Enc.bufToUtf8 = function (u8) {
return Buffer.from(u8).toString('utf8');
};
certInfo.debug = certInfo.getCertInfo = function (pem) {
var bytes = PEM.parseBlock(pem).bytes;
return ASN1.parse(bytes);
};
certInfo.info = certInfo.getBasicInfo = function (pem) {
var c = certInfo.getCertInfo(pem);
// A cert has 3 parts: cert, signature meta, signature
if (c.children.length !== 3) {
throw new Error("doesn't look like a certificate: expected 3 parts of header");
}
c = c.children[0];
if (8 !== c.children.length) {
throw new Error("doesn't look like a certificate: expected 8 parts to certificate");
}
// 0:0 value 2
// 1 variable-length value
// 2:0 sha256 identifier 2:1 null
// 3 certificate of issuer C/O/OU/CN
// 4:0 notBefore 4:1 notAfter
var nbf = Enc.hexToBuf(c.children[4].children[0].value);
var exp = Enc.hexToBuf(c.children[4].children[1].value);
nbf = new Date(Date.UTC(
'20' + nbf.slice(0, 2)
, nbf.slice(2, 4) - 1
, nbf.slice(4, 6)
, nbf.slice(6, 8)
, nbf.slice(8, 10)
, nbf.slice(10, 12)
));
exp = new Date(Date.UTC(
'20' + exp.slice(0, 2)
, exp.slice(2, 4) - 1
, exp.slice(4, 6)
, exp.slice(6, 8)
, exp.slice(8, 10)
, exp.slice(10, 12)
));
// 5 the client C/O/OU/CN, etc
var sub = c.children[5].children.filter(function (set) {
if ('550403' === Enc.bufToHex(set.children[0].children[0].value)) {
return true;
}
}).map(function (set) {
return Enc.bufToUtf8(set.children[0].children[1].value);
})[0];
// 6 public key
// 7 extensions
var domains = c.children[7].children[0].children.filter(function (seq) {
if ('551d11' === Enc.bufToHex(seq.children[0].value)) {
return true;
}
}).map(function (seq) {
return seq.children[1].children[0].children.map(function (name) {
return Enc.bufToUtf8(name.value);
});
})[0];
return {
subject: sub
, altnames: domains
// for debugging during console.log
// do not expect these values to be here
, _issuedAt: nbf
, _expiresAt: exp
, issuedAt: nbf.valueOf()
, expiresAt: exp.valueOf()
};
};
certInfo.getCertInfoFromFile = function (pemFile) {
return require('fs').readFileSync(pemFile, 'ascii');
};
/*
certInfo.testGetCertInfo = function (pathname) {
var path = require('path');
var pemFile = pathname || path.join(__dirname, '..', 'tests', 'example.cert.pem');
return certInfo.getCertInfo(certInfo.getCertInfoFromFile(pemFile));
};
certInfo.testBasicCertInfo = function (pathname) {
var path = require('path');
var pemFile = pathname || path.join(__dirname, '..', 'tests', 'example.cert.pem');
return certInfo.getBasicInfo(certInfo.getCertInfoFromFile(pemFile));
};
*/