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

213 lines (178 loc) 7.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _pvutils = require("pvutils"); var _bytestreamjs = require("bytestreamjs"); var _utils = require("./utils.js"); var _DigitallySigned = require("./DigitallySigned.js"); var _DigitallySigned2 = _interopRequireDefault(_DigitallySigned); var _LogEntryType = require("./LogEntryType.js"); var _LogEntryType2 = _interopRequireDefault(_LogEntryType); var _BaseClass = require("./BaseClass.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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 SignedCertificateTimestamp extends _BaseClass.BaseClass { //********************************************************************************** /** * Constructor for SignedCertificateTimestamp class * @param {Object} [parameters={}] * @property {Object} [schema] asn1js parsed value */ constructor(parameters = {}) { super(parameters); //region Internal properties of the object /** * @type {number} * @description version */ this.version = (0, _pvutils.getParametersValue)(parameters, "version", SignedCertificateTimestamp.constants("version")); /** * @type {ArrayBuffer} * @description logID */ this.logID = (0, _pvutils.getParametersValue)(parameters, "logID", SignedCertificateTimestamp.constants("logID")); /** * @type {Date} * @description timestamp */ this.timestamp = (0, _pvutils.getParametersValue)(parameters, "timestamp", SignedCertificateTimestamp.constants("timestamp")); /** * @type {ArrayBuffer} * @description extensions */ this.extensions = (0, _pvutils.getParametersValue)(parameters, "extensions", SignedCertificateTimestamp.constants("extensions")); /** * @type {DigitallySigned} * @description signature */ this.signature = (0, _pvutils.getParametersValue)(parameters, "signature", SignedCertificateTimestamp.constants("signature")); //endregion //region If input argument array contains "stream" if ("stream" in parameters) this.fromStream(parameters.stream); //endregion //region If input argument array contains "json" for this object if ("json" in parameters) this.fromJSON(parameters.json); //endregion } //********************************************************************************** /** * Return value for a constant by name * @param {string} name String name for a constant */ static constants(name) { switch (name) { case "version": return 0; case "logID": case "extensions": return new ArrayBuffer(0); case "timestamp": return new Date(0); case "signature": return new _DigitallySigned2.default(); default: throw new Error(`Invalid constant name for SignedCertificateTimestamp class: ${name}`); } } //********************************************************************************** /** * Convert SeqStream data into current class * @param {!SeqStream} stream */ fromStream(stream) { // struct { // Version sct_version; // LogID id; // uint64 timestamp; // CtExtensions extensions; // digitally-signed struct { // Version sct_version; // SignatureType signature_type = certificate_timestamp; // uint64 timestamp; // LogEntryType entry_type; // select(entry_type) { // case x509_entry: ASN.1Cert; // case precert_entry: PreCert; // } signed_entry; // CtExtensions extensions; // }; // } SignedCertificateTimestamp; const blockLength = stream.getUint16(); this.version = stream.getBlock(1)[0]; this.logID = new Uint8Array(stream.getBlock(32)).buffer.slice(0); this.timestamp = new Date(_utils.utils.getUint64(stream)); //region Extensions const extensionsLength = stream.getUint16(); this.extensions = new Uint8Array(stream.getBlock(extensionsLength)).buffer.slice(0); //endregion this.signature = new _DigitallySigned2.default({ stream }); if (blockLength !== 47 + extensionsLength + this.signature.signature.valueBeforeDecode.byteLength) throw new Error("Object's stream was not correct for SignedCertificateTimestamp"); } //********************************************************************************** /** * Convert JSON value into current object * @param {Object} json * @param {String} json.sct_version * @param {String} json.id * @param {String} json.timestamp * @param {String} json.extensions * @param {String} json.signature */ fromJSON(json) { this.version = json.sct_version; this.logID = (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.id)); this.timestamp = new Date(json.timestamp); this.extensions = (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.extensions)); this.signature = new _DigitallySigned2.default({ stream: new _bytestreamjs.SeqStream({ buffer: (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.signature)) }) }); } //********************************************************************************** /** * Convert current object to SeqStream data * @param {!SeqStream} stream * @returns {boolean} Result of the function */ toStream(stream) { stream.appendUint16(47 + this.extensions.byteLength + this.signature.valueBeforeDecode.byteLength); stream.appendChar(this.version); stream.appendView(new Uint8Array(this.logID)); _utils.utils.appendUint64(this.timestamp.valueOf(), stream); stream.appendUint16(this.extensions.byteLength); if (this.extensions.byteLength) stream.appendView(new Uint8Array(this.extensions)); this.signature.toStream(stream); return true; } //********************************************************************************** /** * Verify SignedCertificateTimestamp for specific input data * @param {ArrayBuffer} data Data to verify signature against. Could be encoded Certificate or encoded PreCert * @param {PublicKeyInfo} publicKey The PublicKeyInfo class from PKI.js having public key for the CT log * @param {Number} [dataType=x509_entry] Type = 0 (data is encoded Certificate), type = 1 (data is encoded PreCert) * @return {Promise<Boolean>} */ verify(data, publicKey, dataType = _LogEntryType2.default.constants("x509_entry")) { var _this = this; return _asyncToGenerator(function* () { const stream = new _bytestreamjs.SeqStream(); //region Initialize signed data block stream.appendChar(0x00); // sct_version stream.appendChar(0x00); // signature_type = certificate_timestamp _utils.utils.appendUint64(_this.timestamp.valueOf(), stream); stream.appendUint16(dataType); if (dataType === _LogEntryType2.default.constants("x509_entry")) stream.appendUint24(data.byteLength); stream.appendView(new Uint8Array(data)); stream.appendUint16(_this.extensions.byteLength); if (_this.extensions.byteLength !== 0) stream.appendView(new Uint8Array(_this.extensions)); //endregion return _this.signature.verify(stream.buffer, publicKey); })(); } //********************************************************************************** } exports.default = SignedCertificateTimestamp; //************************************************************************************** //# sourceMappingURL=SignedCertificateTimestamp.js.map