cert-info.js
3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// 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));
};
*/