UNPKG

ctjs

Version:

CTjs is a full set of classes necessary to work with any kind of Certificate Transparency log (V1 as from RFC6962, or V2 as from RFC6962-bis). In CTjs you could find all necessary validation/verification functions for all related data shipped with full-fe

166 lines (142 loc) 6.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _asn1js = require("asn1js"); var asn1js = _interopRequireWildcard(_asn1js); var _pvutils = require("pvutils"); var _pkijs = require("pkijs"); var _BaseClass = require("./BaseClass.js"); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } //************************************************************************************** class PreCert extends _BaseClass.BaseClass { //********************************************************************************** /** * Constructor for PreCert class * @param {Object} [parameters={}] * @property {Object} [schema] asn1js parsed value */ constructor(parameters = {}) { super(parameters); //region Internal properties of the object /** * @type {ArrayBuffer} * @description issuerKeyHash */ this.issuerKeyHash = (0, _pvutils.getParametersValue)(parameters, "issuerKeyHash", PreCert.constants("issuerKeyHash")); /** * @type {Object} * @description tbsCertificate ASN1js parsed object representing TBS of certificate */ this.tbsCertificate = (0, _pvutils.getParametersValue)(parameters, "tbsCertificate", PreCert.constants("tbsCertificate")); //endregion //region If input argument array contains "stream" for this object if ("stream" in parameters) this.fromStream(parameters.stream); //endregion } //********************************************************************************** /** * Return value for a constant by name * @param {string} name String name for a constant */ static constants(name) { switch (name) { case "issuerKeyHash": return new ArrayBuffer(0); case "tbsCertificate": return new asn1js.Any(); default: throw new Error(`Invalid constant name for PreCert class: ${name}`); } } //********************************************************************************** /** * Convert SeqStream data into current class * @param {!SeqStream} stream */ fromStream(stream) { this.issuerKeyHash = new Uint8Array(stream.getBlock(32)).buffer.slice(0); const tbsLength = stream.getUint24(); const asn1 = asn1js.fromBER(new Uint8Array(stream.getBlock(tbsLength)).buffer.slice(0)); if (asn1.offset === -1) throw new Error("Object's stream was not correct for PreCert"); this.tbsCertificate = asn1.result; } //********************************************************************************** /** * Convert current object to SeqStream data * @param {!SeqStream} stream * @returns {boolean} Result of the function */ toStream(stream) { stream.appendView(new Uint8Array(this.issuerKeyHash)); const buffer = this.tbsCertificate.toBER(false); stream.appendUint24(buffer.byteLength); stream.appendView(new Uint8Array(buffer)); return true; } //********************************************************************************** /** * Convert end-entity certificate + issuer certificate into PreCert class * @param {!Object} parameters * @param {Certificate} parameters.certificate End-entity certificate * @param {Certificate} parameters.issuer Issuer's certificate for the end-entity certificate * @return {Promise<PreCert>} */ static fromCertificateAndIssuer(parameters) { return _asyncToGenerator(function* () { //region Initial variables const result = new PreCert(); //endregion //region Get a "crypto" extension const crypto = (0, _pkijs.getCrypto)(); if (typeof crypto === "undefined") return Promise.reject("Unable to create WebCrypto object"); //endregion //region Check input parameters if ("certificate" in parameters === false) throw new Error("Missing mandatory parameter: certificate"); if ("issuer" in parameters === false) throw new Error("Missing mandatory parameter: issuer"); //endregion //region Remove certificate extension for (let i = 0; i < parameters.certificate.extensions.length; i++) { switch (parameters.certificate.extensions[i].extnID) { case "1.3.6.1.4.1.11129.2.4.2": case "1.3.6.1.4.1.11129.2.4.3": parameters.certificate.extensions.splice(i, 1); break; default: } } //endregion //region Prepare modifier TBS value result.tbsCertificate = parameters.certificate.encodeTBS(); //endregion //region Initialize "issuer_key_hash" value result.issuerKeyHash = yield crypto.digest({ name: "SHA-256" }, new Uint8Array(parameters.issuer.subjectPublicKeyInfo.toSchema().toBER(false))); //endregion return result; })(); } //********************************************************************************** /** * Fictive X.509 Certificate made from existing PreCert. * * Could be interesting to get such certificate, encode it as a DER and then open the * data in UI like Windows - this would provide ability for easily checking PreCert values */ get certificate() { return new _pkijs.Certificate({ schema: new asn1js.Sequence({ value: [this.tbsCertificate, new _pkijs.AlgorithmIdentifier({ algorithmId: "1.2.840.113549.1.1.11", algorithmParams: new asn1js.Null() }).toSchema(), new asn1js.BitString({ valueHex: new ArrayBuffer(2), unusedBits: 0 })] }) }); } //********************************************************************************** } exports.default = PreCert; //************************************************************************************** //# sourceMappingURL=PreCert.js.map