From 2aa4a82499d4becd2284cdb482213d541b8804dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 16:29:10 +0200 Subject: Adding upstream version 86.0.1. Signed-off-by: Daniel Baumann --- .../certviewer/content/vendor/pkijs_bundle.js | 47423 +++++++++++++++++++ 1 file changed, 47423 insertions(+) create mode 100644 toolkit/components/certviewer/content/vendor/pkijs_bundle.js (limited to 'toolkit/components/certviewer/content/vendor/pkijs_bundle.js') diff --git a/toolkit/components/certviewer/content/vendor/pkijs_bundle.js b/toolkit/components/certviewer/content/vendor/pkijs_bundle.js new file mode 100644 index 0000000000..09e4db9932 --- /dev/null +++ b/toolkit/components/certviewer/content/vendor/pkijs_bundle.js @@ -0,0 +1,47423 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.pkijs = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i. + * + */ +//************************************************************************************** +class ByteStream { + //********************************************************************************** + // noinspection FunctionWithMultipleLoopsJS + /** + * Constructor for ByteStream class + * @param {{[length]: number, [stub]: number, [view]: Uint8Array, [buffer]: ArrayBuffer, [string]: string, [hexstring]: string}} parameters + */ + constructor(parameters = {}) { + this.clear(); + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = Object.keys(parameters)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + const key = _step.value; + + switch (key) { + case "length": + this.length = parameters.length; + break; + case "stub": + // noinspection NonBlockStatementBodyJS + for (let i = 0; i < this._view.length; i++) this._view[i] = parameters.stub; + break; + case "view": + this.fromUint8Array(parameters.view); + break; + case "buffer": + this.fromArrayBuffer(parameters.buffer); + break; + case "string": + this.fromString(parameters.string); + break; + case "hexstring": + this.fromHexString(parameters.hexstring); + break; + default: + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + //********************************************************************************** + /** + * Setter for "buffer" + * @param {ArrayBuffer} value + */ + set buffer(value) { + this._buffer = value.slice(0); + this._view = new Uint8Array(this._buffer); + } + //********************************************************************************** + /** + * Getter for "buffer" + * @returns {ArrayBuffer} + */ + get buffer() { + return this._buffer; + } + //********************************************************************************** + /** + * Setter for "view" + * @param {Uint8Array} value + */ + set view(value) { + this._buffer = new ArrayBuffer(value.length); + this._view = new Uint8Array(this._buffer); + + this._view.set(value); + } + //********************************************************************************** + /** + * Getter for "view" + * @returns {Uint8Array} + */ + get view() { + return this._view; + } + //********************************************************************************** + /** + * Getter for "length" + * @returns {number} + */ + get length() { + return this._buffer.byteLength; + } + //********************************************************************************** + /** + * Setter for "length" + * @param {number} value + */ + set length(value) { + this._buffer = new ArrayBuffer(value); + this._view = new Uint8Array(this._buffer); + } + //********************************************************************************** + /** + * Clear existing stream + */ + clear() { + this._buffer = new ArrayBuffer(0); + this._view = new Uint8Array(this._buffer); + } + //********************************************************************************** + /** + * Initialize "Stream" object from existing "ArrayBuffer" + * @param {!ArrayBuffer} array The ArrayBuffer to copy from + */ + fromArrayBuffer(array) { + this.buffer = array; + } + //********************************************************************************** + // noinspection FunctionNamingConventionJS + /** + * Initialize "Stream" object from existing "Uint8Array" + * @param {!Uint8Array} array The Uint8Array to copy from + */ + fromUint8Array(array) { + this._buffer = new ArrayBuffer(array.length); + this._view = new Uint8Array(this._buffer); + + this._view.set(array); + } + //********************************************************************************** + /** + * Initialize "Stream" object from existing string + * @param {string} string The string to initialize from + */ + fromString(string) { + const stringLength = string.length; + + this.length = stringLength; + + // noinspection NonBlockStatementBodyJS + for (let i = 0; i < stringLength; i++) this.view[i] = string.charCodeAt(i); + } + //********************************************************************************** + /** + * Represent "Stream" object content as a string + * @param {number} [start] Start position to convert to string + * @param {number} [length] Length of array to convert to string + * @returns {string} + */ + toString(start = 0, length = this.view.length - start) { + //region Initial variables + let result = ""; + //endregion + + //region Check input parameters + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start >= this.view.length || start < 0) { + // noinspection AssignmentToFunctionParameterJS + start = 0; + } + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length >= this.view.length || length < 0) { + // noinspection AssignmentToFunctionParameterJS + length = this.view.length - start; + } + //endregion + + //region Convert array of bytes to string + // noinspection NonBlockStatementBodyJS + for (let i = start; i < start + length; i++) result += String.fromCharCode(this.view[i]); + //endregion + + return result; + } + //********************************************************************************** + // noinspection FunctionTooLongJS + /** + * Initialize "Stream" object from existing hexdecimal string + * @param {string} hexString String to initialize from + */ + fromHexString(hexString) { + //region Initial variables + const stringLength = hexString.length; + + this.buffer = new ArrayBuffer(stringLength >> 1); + this.view = new Uint8Array(this.buffer); + + const hexMap = new Map(); + + // noinspection MagicNumberJS + hexMap.set("0", 0x00); + // noinspection MagicNumberJS + hexMap.set("1", 0x01); + // noinspection MagicNumberJS + hexMap.set("2", 0x02); + // noinspection MagicNumberJS + hexMap.set("3", 0x03); + // noinspection MagicNumberJS + hexMap.set("4", 0x04); + // noinspection MagicNumberJS + hexMap.set("5", 0x05); + // noinspection MagicNumberJS + hexMap.set("6", 0x06); + // noinspection MagicNumberJS + hexMap.set("7", 0x07); + // noinspection MagicNumberJS + hexMap.set("8", 0x08); + // noinspection MagicNumberJS + hexMap.set("9", 0x09); + // noinspection MagicNumberJS + hexMap.set("A", 0x0A); + // noinspection MagicNumberJS + hexMap.set("a", 0x0A); + // noinspection MagicNumberJS + hexMap.set("B", 0x0B); + // noinspection MagicNumberJS + hexMap.set("b", 0x0B); + // noinspection MagicNumberJS + hexMap.set("C", 0x0C); + // noinspection MagicNumberJS + hexMap.set("c", 0x0C); + // noinspection MagicNumberJS + hexMap.set("D", 0x0D); + // noinspection MagicNumberJS + hexMap.set("d", 0x0D); + // noinspection MagicNumberJS + hexMap.set("E", 0x0E); + // noinspection MagicNumberJS + hexMap.set("e", 0x0E); + // noinspection MagicNumberJS + hexMap.set("F", 0x0F); + // noinspection MagicNumberJS + hexMap.set("f", 0x0F); + + let j = 0; + // noinspection MagicNumberJS + let temp = 0x00; + //endregion + + //region Convert char-by-char + for (let i = 0; i < stringLength; i++) { + // noinspection NegatedIfStatementJS + if (!(i % 2)) { + // noinspection NestedFunctionCallJS + temp = hexMap.get(hexString.charAt(i)) << 4; + } else { + // noinspection NestedFunctionCallJS + temp |= hexMap.get(hexString.charAt(i)); + + this.view[j] = temp; + j++; + } + } + //endregion + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Represent "Stream" object content as a hexdecimal string + * @param {number} [start=0] Start position to convert to string + * @param {number} [length=(this.view.length - start)] Length of array to convert to string + * @returns {string} + */ + toHexString(start = 0, length = this.view.length - start) { + //region Initial variables + let result = ""; + //endregion + + //region Check input parameters + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start >= this.view.length || start < 0) { + // noinspection AssignmentToFunctionParameterJS + start = 0; + } + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length >= this.view.length || length < 0) { + // noinspection AssignmentToFunctionParameterJS + length = this.view.length - start; + } + //endregion + + for (let i = start; i < start + length; i++) { + // noinspection ChainedFunctionCallJS + const str = this.view[i].toString(16).toUpperCase(); + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, ConditionalExpressionJS, EqualityComparisonWithCoercionJS + result = result + (str.length == 1 ? "0" : "") + str; + } + + return result; + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS + /** + * Return copy of existing "Stream" + * @param {number} [start=0] Start position of the copy + * @param {number} [length=this.view.length] Length of the copy + * @returns {ByteStream} + */ + copy(start = 0, length = this._buffer.byteLength - start) { + //region Check input parameters + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (start === 0 && this._buffer.byteLength === 0) return new ByteStream(); + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (start < 0 || start > this._buffer.byteLength - 1) throw new Error(`Wrong start position: ${start}`); + //endregion + + const stream = new ByteStream(); + + stream._buffer = this._buffer.slice(start, start + length); + stream._view = new Uint8Array(stream._buffer); + + return stream; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS + /** + * Return slice of existing "Stream" + * @param {number} [start=0] Start position of the slice + * @param {number} [end=this._buffer.byteLength] End position of the slice + * @returns {ByteStream} + */ + slice(start = 0, end = this._buffer.byteLength) { + //region Check input parameters + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (start === 0 && this._buffer.byteLength === 0) return new ByteStream(); + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (start < 0 || start > this._buffer.byteLength - 1) throw new Error(`Wrong start position: ${start}`); + //endregion + + const stream = new ByteStream(); + + stream._buffer = this._buffer.slice(start, end); + stream._view = new Uint8Array(stream._buffer); + + return stream; + } + //********************************************************************************** + /** + * Change size of existing "Stream" + * @param {!number} size Size for new "Stream" + */ + realloc(size) { + //region Initial variables + const buffer = new ArrayBuffer(size); + const view = new Uint8Array(buffer); + //endregion + + //region Create a new ArrayBuffer content + // noinspection NonBlockStatementBodyJS + if (size > this._view.length) view.set(this._view);else { + // noinspection NestedFunctionCallJS + view.set(new Uint8Array(this._buffer, 0, size)); + } + //endregion + + //region Initialize "Stream" with new "ArrayBuffer" + this._buffer = buffer.slice(0); + this._view = new Uint8Array(this._buffer); + //endregion + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Append a new "Stream" content to the current "Stream" + * @param {ByteStream} stream A new "stream" to append to current "stream" + */ + append(stream) { + //region Initial variables + const initialSize = this._buffer.byteLength; + const streamViewLength = stream._buffer.byteLength; + + const copyView = stream._view.slice(); + //endregion + + //region Re-allocate current internal buffer + this.realloc(initialSize + streamViewLength); + //endregion + + //region Copy input stream content to a new place + this._view.set(copyView, initialSize); + //endregion + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS + /** + * Insert "Stream" content to the current "Stream" at specific position + * @param {ByteStream} stream A new "stream" to insert to current "stream" + * @param {number} [start=0] Start position to insert to + * @param {number} [length] + * @returns {boolean} + */ + insert(stream, start = 0, length = this._buffer.byteLength - start) { + //region Initial variables + // noinspection NonBlockStatementBodyJS + if (start > this._buffer.byteLength - 1) return false; + + if (length > this._buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = this._buffer.byteLength - start; + } + //endregion + + //region Check input variables + if (length > stream._buffer.byteLength) { + // noinspection AssignmentToFunctionParameterJS + length = stream._buffer.byteLength; + } + //endregion + + //region Update content of the current stream + // noinspection NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (length == stream._buffer.byteLength) this._view.set(stream._view, start);else { + // noinspection NestedFunctionCallJS + this._view.set(stream._view.slice(0, length), start); + } + //endregion + + return true; + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS + /** + * Check that two "Stream" objects has equal content + * @param {ByteStream} stream Stream to compare with + * @returns {boolean} + */ + isEqual(stream) { + //region Check length of both buffers + // noinspection NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (this._buffer.byteLength != stream._buffer.byteLength) return false; + //endregion + + //region Compare each byte of both buffers + for (let i = 0; i < stream._buffer.byteLength; i++) { + // noinspection NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (this.view[i] != stream.view[i]) return false; + } + //endregion + + return true; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS + /** + * Check that current "Stream" objects has equal content with input "Uint8Array" + * @param {Uint8Array} view View to compare with + * @returns {boolean} + */ + isEqualView(view) { + //region Check length of both buffers + // noinspection NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (view.length != this.view.length) return false; + //endregion + + //region Compare each byte of both buffers + for (let i = 0; i < view.length; i++) { + // noinspection NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (this.view[i] != view[i]) return false; + } + //endregion + + return true; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleLoopsJS, FunctionWithMultipleReturnPointsJS, OverlyComplexFunctionJS, FunctionTooLongJS + /** + * Find any byte pattern in "Stream" + * @param {ByteStream} pattern Stream having pattern value + * @param {?number} [start] Start position to search from + * @param {?number} [length] Length of byte block to search at + * @param {boolean} [backward] Flag to search in backward order + * @returns {number} + */ + findPattern(pattern, start = null, length = null, backward = false) { + //region Check input variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS, ConditionalExpressionJS + start = backward ? this.buffer.byteLength : 0; + } + + if (start > this.buffer.byteLength) { + // noinspection AssignmentToFunctionParameterJS + start = this.buffer.byteLength; + } + + if (backward) { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = start; + } + + if (length > start) { + // noinspection AssignmentToFunctionParameterJS + length = start; + } + } else { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + if (length > this.buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + } + //endregion + + //region Initial variables + const patternLength = pattern.buffer.byteLength; + // noinspection NonBlockStatementBodyJS + if (patternLength > length) return -1; + //endregion + + //region Make a "pre-read" array for pattern + const patternArray = []; + // noinspection NonBlockStatementBodyJS + for (let i = 0; i < patternLength; i++) patternArray.push(pattern.view[i]); + //endregion + + //region Search for pattern + for (let i = 0; i <= length - patternLength; i++) { + let equal = true; + // noinspection ConditionalExpressionJS + const equalStart = backward ? start - patternLength - i : start + i; + + for (let j = 0; j < patternLength; j++) { + // noinspection EqualityComparisonWithCoercionJS + if (this.view[j + equalStart] != patternArray[j]) { + equal = false; + // noinspection BreakStatementJS + break; + } + } + + if (equal) { + // noinspection ConditionalExpressionJS + return backward ? start - patternLength - i : start + patternLength + i; // Position after the pattern found + } + } + //endregion + + return -1; + } + //********************************************************************************** + // noinspection OverlyComplexFunctionJS + /** + * Find first position of any pattern from input array + * @param {Array.} patterns Array with patterns which should be found + * @param {?number} [start] Start position to search from + * @param {?number} [length] Length of byte block to search at + * @param {boolean} [backward=false] Flag to search in backward order + * @returns {{id: number, position: number}} + */ + findFirstIn(patterns, start = null, length = null, backward = false) { + //region Initial variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS, ConditionalExpressionJS + start = backward ? this.buffer.byteLength : 0; + } + + if (start > this.buffer.byteLength) { + // noinspection AssignmentToFunctionParameterJS + start = this.buffer.byteLength; + } + + if (backward) { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = start; + } + + if (length > start) { + // noinspection AssignmentToFunctionParameterJS + length = start; + } + } else { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + if (length > this.buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + } + + // noinspection ConditionalExpressionJS + const result = { + id: -1, + position: backward ? 0 : start + length, + length: 0 + }; + //endregion + + for (let i = 0; i < patterns.length; i++) { + const position = this.findPattern(patterns[i], start, length, backward); + // noinspection EqualityComparisonWithCoercionJS + if (position != -1) { + let valid = false; + const patternLength = patterns[i].length; + + if (backward) { + // noinspection NonBlockStatementBodyJS + if (position - patternLength >= result.position - result.length) valid = true; + } else { + // noinspection NonBlockStatementBodyJS + if (position - patternLength <= result.position - result.length) valid = true; + } + + if (valid) { + result.position = position; + result.id = i; + result.length = patternLength; + } + } + } + + return result; + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS + /** + * Find all positions of any pattern from input array + * @param {Array.} patterns Array with patterns which should be found + * @param {?number} [start] Start position to search from + * @param {?number} [length] Length of byte block to search at + * @returns {Array} + */ + findAllIn(patterns, start = 0, length = this.buffer.byteLength - start) { + //region Initial variables + const result = []; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS + start = 0; + } + + // noinspection NonBlockStatementBodyJS + if (start > this.buffer.byteLength - 1) return result; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + if (length > this.buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + let patternFound = { + id: -1, + position: start + }; + //endregion + + //region Find all accurences of patterns + do { + const position = patternFound.position; + + patternFound = this.findFirstIn(patterns, patternFound.position, length); + + // noinspection EqualityComparisonWithCoercionJS + if (patternFound.id == -1) { + // noinspection BreakStatementJS + break; + } + + // noinspection AssignmentToFunctionParameterJS + length -= patternFound.position - position; + + result.push({ + id: patternFound.id, + position: patternFound.position + }); + } while (true); // eslint-disable-line + //endregion + + return result; + } + //********************************************************************************** + // noinspection FunctionWithMultipleLoopsJS, FunctionWithMultipleReturnPointsJS + /** + * Find all positions of a pattern + * @param {ByteStream} pattern Stream having pattern value + * @param {?number} [start] Start position to search from + * @param {?number} [length] Length of byte block to search at + * @returns {Array|number} Array with all pattern positions or (-1) if failed + */ + findAllPatternIn(pattern, start = 0, length = this.buffer.byteLength - start) { + //region Check input variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS + start = 0; + } + + if (start > this.buffer.byteLength) { + // noinspection AssignmentToFunctionParameterJS + start = this.buffer.byteLength; + } + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + if (length > this.buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + //endregion + + //region Initial variables + const result = []; + + const patternLength = pattern.buffer.byteLength; + // noinspection NonBlockStatementBodyJS + if (patternLength > length) return -1; + //endregion + + //region Make a "pre-read" array for pattern + const patternArray = Array.from(pattern.view); + //endregion + + //region Search for pattern + for (let i = 0; i <= length - patternLength; i++) { + let equal = true; + const equalStart = start + i; + + for (let j = 0; j < patternLength; j++) { + // noinspection EqualityComparisonWithCoercionJS + if (this.view[j + equalStart] != patternArray[j]) { + equal = false; + // noinspection BreakStatementJS + break; + } + } + + if (equal) { + result.push(start + patternLength + i); // Position after the pattern found + i += patternLength - 1; // On next step of "for" we will have "i++" + } + } + //endregion + + return result; + } + //********************************************************************************** + // noinspection OverlyComplexFunctionJS, FunctionTooLongJS + /** + * Find first position of data, not included in patterns from input array + * @param {Array.} patterns Array with patterns which should be ommited + * @param {?number} [start] Start position to search from + * @param {?number} [length] Length of byte block to search at + * @param {boolean} [backward=false] Flag to search in backward order + * @returns {{left: {id: number, position: *}, right: {id: number, position: number}, value: ByteStream}} + */ + findFirstNotIn(patterns, start = null, length = null, backward = false) { + //region Initial variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS, ConditionalExpressionJS + start = backward ? this.buffer.byteLength : 0; + } + + if (start > this.buffer.byteLength) { + // noinspection AssignmentToFunctionParameterJS + start = this.buffer.byteLength; + } + + if (backward) { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = start; + } + + if (length > start) { + // noinspection AssignmentToFunctionParameterJS + length = start; + } + } else { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + if (length > this.buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + } + + const result = { + left: { + id: -1, + position: start + }, + right: { + id: -1, + position: 0 + }, + value: new ByteStream() + }; + + let currentLength = length; + //endregion + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + while (currentLength > 0) { + //region Search for nearest "pattern" + // noinspection ConditionalExpressionJS + result.right = this.findFirstIn(patterns, backward ? start - length + currentLength : start + length - currentLength, currentLength, backward); + //endregion + + //region No pattern at all + // noinspection EqualityComparisonWithCoercionJS + if (result.right.id == -1) { + // noinspection AssignmentToFunctionParameterJS + length = currentLength; + + if (backward) { + // noinspection AssignmentToFunctionParameterJS + start -= length; + } else { + // noinspection AssignmentToFunctionParameterJS + start = result.left.position; + } + + result.value = new ByteStream(); + + result.value._buffer = this._buffer.slice(start, start + length); + result.value._view = new Uint8Array(result.value._buffer); + + // noinspection BreakStatementJS + break; + } + //endregion + + //region Check distance between two patterns + // noinspection ConditionalExpressionJS, EqualityComparisonWithCoercionJS + if (result.right.position != (backward ? result.left.position - patterns[result.right.id].buffer.byteLength : result.left.position + patterns[result.right.id].buffer.byteLength)) { + if (backward) { + // noinspection AssignmentToFunctionParameterJS + start = result.right.position + patterns[result.right.id].buffer.byteLength; + // noinspection AssignmentToFunctionParameterJS + length = result.left.position - result.right.position - patterns[result.right.id].buffer.byteLength; + } else { + // noinspection AssignmentToFunctionParameterJS + start = result.left.position; + // noinspection AssignmentToFunctionParameterJS + length = result.right.position - result.left.position - patterns[result.right.id].buffer.byteLength; + } + + result.value = new ByteStream(); + + result.value._buffer = this._buffer.slice(start, start + length); + result.value._view = new Uint8Array(result.value._buffer); + + // noinspection BreakStatementJS + break; + } + //endregion + + //region Store information about previous pattern + result.left = result.right; + //endregion + + //region Change current length + currentLength -= patterns[result.right.id]._buffer.byteLength; + //endregion + } + + //region Swap "patterns" in case of backward order + if (backward) { + const temp = result.right; + result.right = result.left; + result.left = temp; + } + //endregion + + return result; + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS + /** + * Find all positions of data, not included in patterns from input array + * @param {Array.} patterns Array with patterns which should be ommited + * @param {?number} [start] Start position to search from + * @param {?number} [length] Length of byte block to search at + * @returns {Array} + */ + findAllNotIn(patterns, start = null, length = null) { + //region Initial variables + const result = []; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS + start = 0; + } + + // noinspection NonBlockStatementBodyJS + if (start > this.buffer.byteLength - 1) return result; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + if (length > this.buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + let patternFound = { + left: { + id: -1, + position: start + }, + right: { + id: -1, + position: start + }, + value: new ByteStream() + }; + //endregion + + //region Find all accurences of patterns + // noinspection EqualityComparisonWithCoercionJS + do { + const position = patternFound.right.position; + + patternFound = this.findFirstNotIn(patterns, patternFound.right.position, length); + + // noinspection AssignmentToFunctionParameterJS + length -= patternFound.right.position - position; + + result.push({ + left: { + id: patternFound.left.id, + position: patternFound.left.position + }, + right: { + id: patternFound.right.id, + position: patternFound.right.position + }, + value: patternFound.value + }); + } while (patternFound.right.id != -1); + //endregion + + return result; + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS, OverlyComplexFunctionJS + /** + * Find position of a sequence of any patterns from input array + * @param {Array.} patterns Array of pattern to look for + * @param {?number} [start] Start position to search from + * @param {?number} [length] Length of byte block to search at + * @param {boolean} [backward=false] Flag to search in backward order + * @returns {*} + */ + findFirstSequence(patterns, start = null, length = null, backward = false) { + //region Initial variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS, ConditionalExpressionJS + start = backward ? this.buffer.byteLength : 0; + } + + if (start > this.buffer.byteLength) { + // noinspection AssignmentToFunctionParameterJS + start = this.buffer.byteLength; + } + + if (backward) { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = start; + } + + if (length > start) { + // noinspection AssignmentToFunctionParameterJS + length = start; + } + } else { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + if (length > this.buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + } + //endregion + + //region Find first byte from sequence + const firstIn = this.skipNotPatterns(patterns, start, length, backward); + // noinspection EqualityComparisonWithCoercionJS + if (firstIn == -1) { + return { + position: -1, + value: new ByteStream() + }; + } + //endregion + + //region Find first byte not in sequence + // noinspection ConditionalExpressionJS + const firstNotIn = this.skipPatterns(patterns, firstIn, length - (backward ? start - firstIn : firstIn - start), backward); + //endregion + + //region Make output value + if (backward) { + // noinspection AssignmentToFunctionParameterJS + start = firstNotIn; + // noinspection AssignmentToFunctionParameterJS + length = firstIn - firstNotIn; + } else { + // noinspection AssignmentToFunctionParameterJS + start = firstIn; + // noinspection AssignmentToFunctionParameterJS + length = firstNotIn - firstIn; + } + + const value = new ByteStream(); + + value._buffer = this._buffer.slice(start, start + length); + value._view = new Uint8Array(value._buffer); + //endregion + + return { + position: firstNotIn, + value + }; + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS + /** + * Find all positions of a sequence of any patterns from input array + * @param {Array.} patterns Array of patterns to search for + * @param {?number} [start] Start position to search from + * @param {?number} [length] Length of byte block to search at + * @returns {Array} + */ + findAllSequences(patterns, start = null, length = null) { + //region Initial variables + const result = []; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS + start = 0; + } + + // noinspection NonBlockStatementBodyJS + if (start > this.buffer.byteLength - 1) return result; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + if (length > this.buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + let patternFound = { + position: start, + value: new ByteStream() + }; + //endregion + + //region Find all accurences of patterns + // noinspection EqualityComparisonWithCoercionJS + do { + const position = patternFound.position; + + patternFound = this.findFirstSequence(patterns, patternFound.position, length); + + // noinspection EqualityComparisonWithCoercionJS + if (patternFound.position != -1) { + // noinspection AssignmentToFunctionParameterJS + length -= patternFound.position - position; + + result.push({ + position: patternFound.position, + value: patternFound.value + }); + } + } while (patternFound.position != -1); + //endregion + + return result; + } + //********************************************************************************** + // noinspection FunctionWithMultipleLoopsJS, FunctionWithMultipleReturnPointsJS, OverlyComplexFunctionJS, FunctionTooLongJS + /** + * Find all paired patterns in the stream + * @param {ByteStream} leftPattern Left pattern to search for + * @param {ByteStream} rightPattern Right pattern to search for + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @returns {Array} + */ + findPairedPatterns(leftPattern, rightPattern, start = null, length = null) { + //region Initial variables + const result = []; + + // noinspection NonBlockStatementBodyJS + if (leftPattern.isEqual(rightPattern)) return result; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS + start = 0; + } + + // noinspection NonBlockStatementBodyJS + if (start > this.buffer.byteLength - 1) return result; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + if (length > this.buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + let currentPositionLeft = 0; + //endregion + + //region Find all "left patterns" as sorted array + const leftPatterns = this.findAllPatternIn(leftPattern, start, length); + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (leftPatterns.length == 0) return result; + //endregion + + //region Find all "right patterns" as sorted array + const rightPatterns = this.findAllPatternIn(rightPattern, start, length); + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (rightPatterns.length == 0) return result; + //endregion + + //region Combine patterns + while (currentPositionLeft < leftPatterns.length) { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, EqualityComparisonWithCoercionJS + if (rightPatterns.length == 0) { + // noinspection BreakStatementJS + break; + } + + // noinspection EqualityComparisonWithCoercionJS + if (leftPatterns[0] == rightPatterns[0]) { + // Possible situation when one pattern is a part of another + // For example "stream" and "endstream" + // In case when we have only "endstream" in fact "stream" will be also found at the same position + // (position of the pattern is an index AFTER the pattern) + + result.push({ + left: leftPatterns[0], + right: rightPatterns[0] + }); + + leftPatterns.splice(0, 1); + rightPatterns.splice(0, 1); + + // noinspection ContinueStatementJS + continue; + } + + if (leftPatterns[currentPositionLeft] > rightPatterns[0]) { + // noinspection BreakStatementJS + break; + } + + while (leftPatterns[currentPositionLeft] < rightPatterns[0]) { + currentPositionLeft++; + + if (currentPositionLeft >= leftPatterns.length) { + // noinspection BreakStatementJS + break; + } + } + + result.push({ + left: leftPatterns[currentPositionLeft - 1], + right: rightPatterns[0] + }); + + leftPatterns.splice(currentPositionLeft - 1, 1); + rightPatterns.splice(0, 1); + + currentPositionLeft = 0; + } + //endregion + + //region Sort result + result.sort((a, b) => a.left - b.left); + //endregion + + return result; + } + //********************************************************************************** + // noinspection FunctionWithMultipleLoopsJS, FunctionWithMultipleReturnPointsJS, OverlyComplexFunctionJS, FunctionTooLongJS + /** + * Find all paired patterns in the stream + * @param {Array.} inputLeftPatterns Array of left patterns to search for + * @param {Array.} inputRightPatterns Array of right patterns to search for + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @returns {Array} + */ + findPairedArrays(inputLeftPatterns, inputRightPatterns, start = null, length = null) { + //region Initial variables + const result = []; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS + start = 0; + } + + // noinspection NonBlockStatementBodyJS + if (start > this.buffer.byteLength - 1) return result; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + if (length > this.buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + let currentPositionLeft = 0; + //endregion + + //region Find all "left patterns" as sorted array + const leftPatterns = this.findAllIn(inputLeftPatterns, start, length); + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (leftPatterns.length == 0) return result; + //endregion + + //region Find all "right patterns" as sorted array + const rightPatterns = this.findAllIn(inputRightPatterns, start, length); + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (rightPatterns.length == 0) return result; + //endregion + + //region Combine patterns + while (currentPositionLeft < leftPatterns.length) { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, EqualityComparisonWithCoercionJS + if (rightPatterns.length == 0) { + // noinspection BreakStatementJS + break; + } + + // noinspection EqualityComparisonWithCoercionJS + if (leftPatterns[0].position == rightPatterns[0].position) { + // Possible situation when one pattern is a part of another + // For example "stream" and "endstream" + // In case when we have only "endstream" in fact "stream" will be also found at the same position + // (position of the pattern is an index AFTER the pattern) + + result.push({ + left: leftPatterns[0], + right: rightPatterns[0] + }); + + leftPatterns.splice(0, 1); + rightPatterns.splice(0, 1); + + // noinspection ContinueStatementJS + continue; + } + + if (leftPatterns[currentPositionLeft].position > rightPatterns[0].position) { + // noinspection BreakStatementJS + break; + } + + while (leftPatterns[currentPositionLeft].position < rightPatterns[0].position) { + currentPositionLeft++; + + if (currentPositionLeft >= leftPatterns.length) { + // noinspection BreakStatementJS + break; + } + } + + result.push({ + left: leftPatterns[currentPositionLeft - 1], + right: rightPatterns[0] + }); + + leftPatterns.splice(currentPositionLeft - 1, 1); + rightPatterns.splice(0, 1); + + currentPositionLeft = 0; + } + //endregion + + //region Sort result + result.sort((a, b) => a.left.position - b.left.position); + //endregion + + return result; + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS, FunctionTooLongJS + /** + * Replace one patter with other + * @param {ByteStream} searchPattern The pattern to search for + * @param {ByteStream} replacePattern The pattern to replace initial pattern + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @param {Array|null} [findAllResult=null] Pre-calculated results of "findAllIn" + * @returns {*} + */ + replacePattern(searchPattern, replacePattern, start = null, length = null, findAllResult = null) { + //region Initial variables + let result; + + let i; + const output = { + status: -1, + searchPatternPositions: [], + replacePatternPositions: [] + }; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS + start = 0; + } + + // noinspection NonBlockStatementBodyJS + if (start > this.buffer.byteLength - 1) return false; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + if (length > this.buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + //endregion + + //region Find a pattern to search for + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (findAllResult == null) { + result = this.findAllIn([searchPattern], start, length); + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (result.length == 0) return output; + } else result = findAllResult; + + // noinspection NestedFunctionCallJS + output.searchPatternPositions.push(...Array.from(result, element => element.position)); + //endregion + + //region Variables for new buffer initialization + const patternDifference = searchPattern.buffer.byteLength - replacePattern.buffer.byteLength; + + const changedBuffer = new ArrayBuffer(this.view.length - result.length * patternDifference); + const changedView = new Uint8Array(changedBuffer); + //endregion + + //region Copy data from 0 to start + // noinspection NestedFunctionCallJS + changedView.set(new Uint8Array(this.buffer, 0, start)); + //endregion + + //region Replace pattern + for (i = 0; i < result.length; i++) { + //region Initial variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, ConditionalExpressionJS, EqualityComparisonWithCoercionJS + const currentPosition = i == 0 ? start : result[i - 1].position; + //endregion + + //region Copy bytes other then search pattern + // noinspection NestedFunctionCallJS + changedView.set(new Uint8Array(this.buffer, currentPosition, result[i].position - searchPattern.buffer.byteLength - currentPosition), currentPosition - i * patternDifference); + //endregion + + //region Put replace pattern in a new buffer + changedView.set(replacePattern.view, result[i].position - searchPattern.buffer.byteLength - i * patternDifference); + + output.replacePatternPositions.push(result[i].position - searchPattern.buffer.byteLength - i * patternDifference); + //endregion + } + //endregion + + //region Copy data from the end of old buffer + i--; + // noinspection NestedFunctionCallJS + changedView.set(new Uint8Array(this.buffer, result[i].position, this.buffer.byteLength - result[i].position), result[i].position - searchPattern.buffer.byteLength + replacePattern.buffer.byteLength - i * patternDifference); + //endregion + + //region Re-initialize existing buffer + this.buffer = changedBuffer; + this.view = new Uint8Array(this.buffer); + //endregion + + output.status = 1; + + return output; + } + //********************************************************************************** + // noinspection FunctionWithMultipleLoopsJS, FunctionWithMultipleReturnPointsJS, OverlyComplexFunctionJS, FunctionTooLongJS + /** + * Skip any pattern from input array + * @param {Array.} patterns Array with patterns which should be ommited + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @param {boolean} [backward=false] Flag to search in backward order + * @returns {*} + */ + skipPatterns(patterns, start = null, length = null, backward = false) { + //region Initial variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS, ConditionalExpressionJS + start = backward ? this.buffer.byteLength : 0; + } + + if (start > this.buffer.byteLength) { + // noinspection AssignmentToFunctionParameterJS + start = this.buffer.byteLength; + } + + if (backward) { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = start; + } + + if (length > start) { + // noinspection AssignmentToFunctionParameterJS + length = start; + } + } else { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + if (length > this.buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + } + + let result = start; + //endregion + + //region Search for pattern + for (let k = 0; k < patterns.length; k++) { + const patternLength = patterns[k].buffer.byteLength; + // noinspection ConditionalExpressionJS + const equalStart = backward ? result - patternLength : result; + let equal = true; + + for (let j = 0; j < patternLength; j++) { + // noinspection EqualityComparisonWithCoercionJS + if (this.view[j + equalStart] != patterns[k].view[j]) { + equal = false; + // noinspection BreakStatementJS + break; + } + } + + if (equal) { + k = -1; + + if (backward) { + result -= patternLength; + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (result <= 0) return result; + } else { + result += patternLength; + // noinspection NonBlockStatementBodyJS + if (result >= start + length) return result; + } + } + } + //endregion + + return result; + } + //********************************************************************************** + // noinspection FunctionWithMultipleLoopsJS, OverlyComplexFunctionJS, FunctionTooLongJS + /** + * Skip any pattern not from input array + * @param {Array.} patterns Array with patterns which should not be ommited + * @param start + * @param length + * @param backward + * @returns {number} + */ + skipNotPatterns(patterns, start = null, length = null, backward = false) { + //region Initial variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS, ConditionalExpressionJS + start = backward ? this.buffer.byteLength : 0; + } + + if (start > this.buffer.byteLength) { + // noinspection AssignmentToFunctionParameterJS + start = this.buffer.byteLength; + } + + if (backward) { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = start; + } + + if (length > start) { + // noinspection AssignmentToFunctionParameterJS + length = start; + } + } else { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + + if (length > this.buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = this.buffer.byteLength - start; + } + } + + let result = -1; + //endregion + + //region Search for pattern + for (let i = 0; i < length; i++) { + for (let k = 0; k < patterns.length; k++) { + const patternLength = patterns[k].buffer.byteLength; + // noinspection ConditionalExpressionJS + const equalStart = backward ? start - i - patternLength : start + i; + let equal = true; + + for (let j = 0; j < patternLength; j++) { + // noinspection EqualityComparisonWithCoercionJS + if (this.view[j + equalStart] != patterns[k].view[j]) { + equal = false; + // noinspection BreakStatementJS + break; + } + } + + if (equal) { + // noinspection ConditionalExpressionJS + result = backward ? start - i : start + i; // Exact position of pattern found + // noinspection BreakStatementJS + break; + } + } + + // noinspection EqualityComparisonWithCoercionJS + if (result != -1) { + // noinspection BreakStatementJS + break; + } + } + //endregion + + return result; + } + //********************************************************************************** +} +exports.ByteStream = ByteStream; //************************************************************************************** + +class SeqStream { + //********************************************************************************** + /** + * Constructor for "SeqStream" class + * @param {{[stream]: ByteStream, [length]: number, [backward]: boolean, [start]: number, [appendBlock]: number}} parameters + */ + constructor(parameters = {}) { + /** + * Major stream + * @type {ByteStream} + */ + this.stream = new ByteStream(); + /** + * Length of the major stream + * @type {number} + */ + this._length = 0; + /** + * Flag to search in backward direction + * @type {boolean} + */ + this.backward = false; + /** + * Start position to search + * @type {number} + */ + this._start = 0; + /** + * Length of a block when append information to major stream + * @type {number} + */ + this.appendBlock = 0; + + this.prevLength = 0; + this.prevStart = 0; + + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = Object.keys(parameters)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + const key = _step2.value; + + switch (key) { + case "stream": + this.stream = parameters.stream; + break; + case "backward": + this.backward = parameters.backward; + // noinspection JSUnusedGlobalSymbols + this._start = this.stream.buffer.byteLength; + break; + case "length": + // noinspection JSUnusedGlobalSymbols + this._length = parameters.length; + break; + case "start": + // noinspection JSUnusedGlobalSymbols + this._start = parameters.start; + break; + case "appendBlock": + this.appendBlock = parameters.appendBlock; + break; + case "view": + this.stream = new ByteStream({ view: parameters.view }); + break; + case "buffer": + this.stream = new ByteStream({ buffer: parameters.buffer }); + break; + case "string": + this.stream = new ByteStream({ string: parameters.string }); + break; + case "hexstring": + this.stream = new ByteStream({ hexstring: parameters.hexstring }); + break; + default: + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + } + //********************************************************************************** + /** + * Setter for "stream" property + * @param {ByteStream} value + */ + set stream(value) { + this._stream = value; + + this.prevLength = this._length; + // noinspection JSUnusedGlobalSymbols + this._length = value._buffer.byteLength; + + this.prevStart = this._start; + // noinspection JSUnusedGlobalSymbols + this._start = 0; + } + //********************************************************************************** + /** + * Getter for "stream" property + * @returns {ByteStream} + */ + get stream() { + return this._stream; + } + //********************************************************************************** + /** + * Setter for "length" property + * @param {number} value + */ + set length(value) { + this.prevLength = this._length; + // noinspection JSUnusedGlobalSymbols + this._length = value; + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS + /** + * Getter for "length" property + * @returns {number} + */ + get length() { + // noinspection NonBlockStatementBodyJS + if (this.appendBlock) return this.start; + + return this._length; + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS + /** + * Setter for "start" property + * @param {number} value + */ + set start(value) { + // noinspection NonBlockStatementBodyJS + if (value > this.stream.buffer.byteLength) return; + + //region Initialization of "prev" internal variables + this.prevStart = this._start; + this.prevLength = this._length; + //endregion + + // noinspection JSUnusedGlobalSymbols, ConditionalExpressionJS + this._length -= this.backward ? this._start - value : value - this._start; + // noinspection JSUnusedGlobalSymbols + this._start = value; + } + //********************************************************************************** + /** + * Getter for "start" property + * @returns {number} + */ + get start() { + return this._start; + } + //********************************************************************************** + /** + * Return ArrayBuffer with having value of existing SeqStream length + * @return {ArrayBuffer} + */ + get buffer() { + return this._stream._buffer.slice(0, this._length); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Reset current position of the "SeqStream" + */ + resetPosition() { + // noinspection JSUnusedGlobalSymbols + this._start = this.prevStart; + // noinspection JSUnusedGlobalSymbols + this._length = this.prevLength; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS + /** + * Find any byte pattern in "ByteStream" + * @param {ByteStream} pattern Stream having pattern value + * @param {?number} [gap] Maximum gap between start position and position of nearest object + * @returns {number} + */ + findPattern(pattern, gap = null) { + //region Initial variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (gap == null || gap > this.length) { + // noinspection AssignmentToFunctionParameterJS + gap = this.length; + } + //endregion + + //region Find pattern + const result = this.stream.findPattern(pattern, this.start, this.length, this.backward); + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (result == -1) return result; + + if (this.backward) { + // noinspection NonBlockStatementBodyJS + if (result < this.start - pattern.buffer.byteLength - gap) return -1; + } else { + // noinspection NonBlockStatementBodyJS + if (result > this.start + pattern.buffer.byteLength + gap) return -1; + } + //endregion + + //region Create new values + this.start = result; + //endregion ; + + return result; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS + /** + * Find first position of any pattern from input array + * @param {Array.} patterns Array with patterns which should be found + * @param {?number} [gap] Maximum gap between start position and position of nearest object + * @returns {{id: number, position: number}} + */ + findFirstIn(patterns, gap = null) { + //region Initial variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (gap == null || gap > this.length) { + // noinspection AssignmentToFunctionParameterJS + gap = this.length; + } + //endregion + + //region Search for patterns + const result = this.stream.findFirstIn(patterns, this.start, this.length, this.backward); + // noinspection NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (result.id == -1) return result; + + if (this.backward) { + if (result.position < this.start - patterns[result.id].buffer.byteLength - gap) { + // noinspection ConditionalExpressionJS + return { + id: -1, + position: this.backward ? 0 : this.start + this.length + }; + } + } else { + if (result.position > this.start + patterns[result.id].buffer.byteLength + gap) { + // noinspection ConditionalExpressionJS + return { + id: -1, + position: this.backward ? 0 : this.start + this.length + }; + } + } + //endregion + + //region Create new values + this.start = result.position; + //endregion ; + + return result; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Find all positions of any pattern from input array + * @param {Array.} patterns Array with patterns which should be found + * @returns {Array} + */ + findAllIn(patterns) { + // In case of "backward order" the start position is at the end on stream. + // In case of "normal order" the start position is at the begging of the stream. + // But in fact for search for all patterns we need to have start position in "normal order". + // noinspection ConditionalExpressionJS + const start = this.backward ? this.start - this.length : this.start; + + return this.stream.findAllIn(patterns, start, this.length); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS, OverlyComplexFunctionJS + /** + * Find first position of data, not included in patterns from input array + * @param {Array.} patterns Array with patterns which should be ommited + * @param {?number} gap Maximum gap between start position and position of nearest object + * @returns {*} + */ + findFirstNotIn(patterns, gap = null) { + //region Initial variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (gap == null || gap > this._length) { + // noinspection AssignmentToFunctionParameterJS + gap = this._length; + } + //endregion + + //region Search for patterns + const result = this._stream.findFirstNotIn(patterns, this._start, this._length, this.backward); + // noinspection NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (result.left.id == -1 && result.right.id == -1) return result; + + if (this.backward) { + // noinspection EqualityComparisonWithCoercionJS + if (result.right.id != -1) { + if (result.right.position < this._start - patterns[result.right.id]._buffer.byteLength - gap) { + return { + left: { + id: -1, + position: this._start + }, + right: { + id: -1, + position: 0 + }, + value: new ByteStream() + }; + } + } + } else { + // noinspection EqualityComparisonWithCoercionJS + if (result.left.id != -1) { + if (result.left.position > this._start + patterns[result.left.id]._buffer.byteLength + gap) { + return { + left: { + id: -1, + position: this._start + }, + right: { + id: -1, + position: 0 + }, + value: new ByteStream() + }; + } + } + } + //endregion + + //region Create new values + if (this.backward) { + // noinspection NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (result.left.id == -1) this.start = 0;else this.start = result.left.position; + } else { + // noinspection NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (result.right.id == -1) this.start = this._start + this._length;else this.start = result.right.position; + } + //endregion ; + + return result; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Find all positions of data, not included in patterns from input array + * @param {Array.} patterns Array with patterns which should be ommited + * @returns {Array} + */ + findAllNotIn(patterns) { + // In case of "backward order" the start position is at the end on stream. + // In case of "normal order" the start position is at the begging of the stream. + // But in fact for search for all patterns we need to have start position in "normal order". + // noinspection ConditionalExpressionJS + const start = this.backward ? this._start - this._length : this._start; + + return this._stream.findAllNotIn(patterns, start, this._length); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS + /** + * Find position of a sequence of any patterns from input array + * @param {Array.} patterns Array with patterns which should be ommited + * @param {?number} [length] Length to search sequence for + * @param {?number} [gap] Maximum gap between start position and position of nearest object + * @returns {*} + */ + findFirstSequence(patterns, length = null, gap = null) { + //region Initial variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null || length > this._length) { + // noinspection AssignmentToFunctionParameterJS + length = this._length; + } + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (gap == null || gap > length) { + // noinspection AssignmentToFunctionParameterJS + gap = length; + } + //endregion + + //region Search for sequence + const result = this._stream.findFirstSequence(patterns, this._start, length, this.backward); + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (result.value.buffer.byteLength == 0) return result; + + if (this.backward) { + if (result.position < this._start - result.value._buffer.byteLength - gap) { + return { + position: -1, + value: new ByteStream() + }; + } + } else { + if (result.position > this._start + result.value._buffer.byteLength + gap) { + return { + position: -1, + value: new ByteStream() + }; + } + } + //endregion + + //region Create new values + this.start = result.position; + //endregion ; + + return result; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Find position of a sequence of any patterns from input array + * @param {Array.} patterns Array with patterns which should be found + * @returns {Array} + */ + findAllSequences(patterns) { + // In case of "backward order" the start position is at the end on stream. + // In case of "normal order" the start position is at the begging of the stream. + // But in fact for search for all patterns we need to have start position in "normal order". + // noinspection ConditionalExpressionJS + const start = this.backward ? this.start - this.length : this.start; + + return this.stream.findAllSequences(patterns, start, this.length); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS + /** + * Find all paired patterns in the stream + * @param {ByteStream} leftPattern Left pattern to search for + * @param {ByteStream} rightPattern Right pattern to search for + * @param {?number} [gap] Maximum gap between start position and position of nearest object + * @returns {Array} + */ + findPairedPatterns(leftPattern, rightPattern, gap = null) { + //region Initial variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (gap == null || gap > this.length) { + // noinspection AssignmentToFunctionParameterJS + gap = this.length; + } + //endregion + + // In case of "backward order" the start position is at the end on stream. + // In case of "normal order" the start position is at the begging of the stream. + // But in fact for search for all patterns we need to have start position in "normal order". + // noinspection ConditionalExpressionJS + const start = this.backward ? this.start - this.length : this.start; + + //region Search for patterns + const result = this.stream.findPairedPatterns(leftPattern, rightPattern, start, this.length); + if (result.length) { + if (this.backward) { + // noinspection NonBlockStatementBodyJS + if (result[0].right < this.start - rightPattern.buffer.byteLength - gap) return []; + } else { + // noinspection NonBlockStatementBodyJS + if (result[0].left > this.start + leftPattern.buffer.byteLength + gap) return []; + } + } + //endregion + + return result; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS + /** + * Find all paired patterns in the stream + * @param {Array.} leftPatterns Array of left patterns to search for + * @param {Array.} rightPatterns Array of right patterns to search for + * @param {?number} [gap] Maximum gap between start position and position of nearest object + * @returns {Array} + */ + findPairedArrays(leftPatterns, rightPatterns, gap = null) { + //region Initial variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (gap == null || gap > this.length) { + // noinspection AssignmentToFunctionParameterJS + gap = this.length; + } + //endregion + + // In case of "backward order" the start position is at the end on stream. + // In case of "normal order" the start position is at the begging of the stream. + // But in fact for search for all patterns we need to have start position in "normal order". + // noinspection ConditionalExpressionJS + const start = this.backward ? this.start - this.length : this.start; + + //region Search for patterns + const result = this.stream.findPairedArrays(leftPatterns, rightPatterns, start, this.length); + if (result.length) { + if (this.backward) { + // noinspection NonBlockStatementBodyJS + if (result[0].right.position < this.start - rightPatterns[result[0].right.id].buffer.byteLength - gap) return []; + } else { + // noinspection NonBlockStatementBodyJS + if (result[0].left.position > this.start + leftPatterns[result[0].left.id].buffer.byteLength + gap) return []; + } + } + //endregion + + return result; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Replace one patter with other + * @param {ByteStream} searchPattern The pattern to search for + * @param {ByteStream} replacePattern The pattern to replace initial pattern + * @returns {*} + */ + replacePattern(searchPattern, replacePattern) { + // In case of "backward order" the start position is at the end on stream. + // In case of "normal order" the start position is at the begging of the stream. + // But in fact for search for all patterns we need to have start position in "normal order". + // noinspection ConditionalExpressionJS + const start = this.backward ? this.start - this.length : this.start; + + return this.stream.replacePattern(searchPattern, replacePattern, start, this.length); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Skip of any pattern from input array + * @param {Array.} patterns Array with patterns which should be ommited + * @returns {*} + */ + skipPatterns(patterns) { + const result = this.stream.skipPatterns(patterns, this.start, this.length, this.backward); + + //region Create new values + this.start = result; + //endregion ; + + return result; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS + /** + * Skip of any pattern from input array + * @param {Array.} patterns Array with patterns which should be ommited + * @returns {number} + */ + skipNotPatterns(patterns) { + const result = this.stream.skipNotPatterns(patterns, this.start, this.length, this.backward); + // noinspection NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (result == -1) return -1; + + //region Create new values + this.start = result; + //endregion ; + + return result; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Append a new "Stream" content to the current "Stream" + * @param {ByteStream} stream A new "stream" to append to current "stream" + */ + append(stream) { + if (this._start + stream._buffer.byteLength > this._stream._buffer.byteLength) { + if (stream._buffer.byteLength > this.appendBlock) { + // noinspection MagicNumberJS + this.appendBlock = stream._buffer.byteLength + 1000; + } + + this._stream.realloc(this._stream._buffer.byteLength + this.appendBlock); + } + + this._stream._view.set(stream._view, this._start); + + this._length += stream._buffer.byteLength * 2; + this.start = this._start + stream._buffer.byteLength; + this.prevLength -= stream._buffer.byteLength * 2; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Append a "view" content to the current "Stream" + * @param {Uint8Array} view A new "view" to append to current "stream" + */ + appendView(view) { + if (this._start + view.length > this._stream._buffer.byteLength) { + if (view.length > this.appendBlock) { + // noinspection MagicNumberJS + this.appendBlock = view.length + 1000; + } + + this._stream.realloc(this._stream._buffer.byteLength + this.appendBlock); + } + + this._stream._view.set(view, this._start); + + this._length += view.length * 2; + this.start = this._start + view.length; + this.prevLength -= view.length * 2; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Append a new char to the current "Stream" + * @param {number} char A new char to append to current "stream" + */ + appendChar(char) { + if (this._start + 1 > this._stream._buffer.byteLength) { + // noinspection ConstantOnLefSideOfComparisonJS + if (1 > this.appendBlock) { + // noinspection MagicNumberJS + this.appendBlock = 1000; + } + + this._stream.realloc(this._stream._buffer.byteLength + this.appendBlock); + } + + this._stream._view[this._start] = char; + + this._length += 2; + this.start = this._start + 1; + this.prevLength -= 2; + } + //********************************************************************************** + // noinspection FunctionNamingConventionJS + /** + * Append a new number to the current "Stream" + * @param {number} number A new unsigned 16-bit integer to append to current "stream" + */ + appendUint16(number) { + if (this._start + 2 > this._stream._buffer.byteLength) { + // noinspection ConstantOnLefSideOfComparisonJS + if (2 > this.appendBlock) { + // noinspection MagicNumberJS + this.appendBlock = 1000; + } + + this._stream.realloc(this._stream._buffer.byteLength + this.appendBlock); + } + + const value = new Uint16Array([number]); + const view = new Uint8Array(value.buffer); + + this._stream._view[this._start] = view[1]; + this._stream._view[this._start + 1] = view[0]; + + this._length += 4; + this.start = this._start + 2; + this.prevLength -= 4; + } + //********************************************************************************** + // noinspection FunctionNamingConventionJS + /** + * Append a new number to the current "Stream" + * @param {number} number A new unsigned 24-bit integer to append to current "stream" + */ + appendUint24(number) { + if (this._start + 3 > this._stream._buffer.byteLength) { + // noinspection ConstantOnLefSideOfComparisonJS + if (3 > this.appendBlock) { + // noinspection MagicNumberJS + this.appendBlock = 1000; + } + + this._stream.realloc(this._stream._buffer.byteLength + this.appendBlock); + } + + const value = new Uint32Array([number]); + const view = new Uint8Array(value.buffer); + + this._stream._view[this._start] = view[2]; + this._stream._view[this._start + 1] = view[1]; + this._stream._view[this._start + 2] = view[0]; + + this._length += 6; + this.start = this._start + 3; + this.prevLength -= 6; + } + //********************************************************************************** + // noinspection FunctionNamingConventionJS + /** + * Append a new number to the current "Stream" + * @param {number} number A new unsigned 32-bit integer to append to current "stream" + */ + appendUint32(number) { + if (this._start + 4 > this._stream._buffer.byteLength) { + // noinspection ConstantOnLefSideOfComparisonJS + if (4 > this.appendBlock) { + // noinspection MagicNumberJS + this.appendBlock = 1000; + } + + this._stream.realloc(this._stream._buffer.byteLength + this.appendBlock); + } + + const value = new Uint32Array([number]); + const view = new Uint8Array(value.buffer); + + this._stream._view[this._start] = view[3]; + this._stream._view[this._start + 1] = view[2]; + this._stream._view[this._start + 2] = view[1]; + this._stream._view[this._start + 3] = view[0]; + + this._length += 8; + this.start = this._start + 4; + this.prevLength -= 8; + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS + /** + * Get a block of data + * @param {number} size Size of the data block to get + * @param {boolean} [changeLength=true] Should we change "length" and "start" value after reading the data block + * @returns {Array} + */ + getBlock(size, changeLength = true) { + //region Check input parameters + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (this._length <= 0) return []; + + if (this._length < size) { + // noinspection AssignmentToFunctionParameterJS + size = this._length; + } + //endregion + + //region Initial variables + let result; + //endregion + + //region Getting result depends on "backward" flag + if (this.backward) { + const buffer = this._stream._buffer.slice(this._length - size, this._length); + const view = new Uint8Array(buffer); + + result = new Array(size); + + // noinspection NonBlockStatementBodyJS + for (let i = 0; i < size; i++) result[size - 1 - i] = view[i]; + } else { + const buffer = this._stream._buffer.slice(this._start, this._start + size); + + // noinspection NestedFunctionCallJS + result = Array.from(new Uint8Array(buffer)); + } + //endregion + + //region Change "length" value if needed + if (changeLength) { + // noinspection ConditionalExpressionJS + this.start += this.backward ? -1 * size : size; + } + //endregion + + return result; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS, FunctionNamingConventionJS + /** + * Get 2-byte unsigned integer value + * @param {boolean} [changeLength=true] Should we change "length" and "start" value after reading the data block + * @returns {number} + */ + getUint16(changeLength = true) { + const block = this.getBlock(2, changeLength); + + //region Check posibility for convertion + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (block.length < 2) return 0; + //endregion + + //region Convert byte array to "Uint16Array" value + const value = new Uint16Array(1); + const view = new Uint8Array(value.buffer); + + view[0] = block[1]; + view[1] = block[0]; + //endregion + + return value[0]; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS, FunctionNamingConventionJS + /** + * Get 2-byte signed integer value + * @param {boolean} [changeLength=true] Should we change "length" and "start" value after reading the data block + * @returns {number} + */ + getInt16(changeLength = true) { + const block = this.getBlock(2, changeLength); + + //region Check posibility for convertion + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (block.length < 2) return 0; + //endregion + + //region Convert byte array to "Int16Array" value + const value = new Int16Array(1); + const view = new Uint8Array(value.buffer); + + view[0] = block[1]; + view[1] = block[0]; + //endregion + + return value[0]; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS, FunctionNamingConventionJS + /** + * Get 3-byte unsigned integer value + * @param {boolean} [changeLength=true] Should we change "length" and "start" value after reading the data block + * @returns {number} + */ + getUint24(changeLength = true) { + const block = this.getBlock(3, changeLength); + + //region Check posibility for convertion + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (block.length < 3) return 0; + //endregion + + //region Convert byte array to "Uint32Array" value + const value = new Uint32Array(1); + const view = new Uint8Array(value.buffer); + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + for (let i = 3; i >= 1; i--) view[3 - i] = block[i - 1]; + //endregion + + return value[0]; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS, FunctionNamingConventionJS + /** + * Get 4-byte unsigned integer value + * @param {boolean} [changeLength=true] Should we change "length" and "start" value after reading the data block + * @returns {number} + */ + getUint32(changeLength = true) { + const block = this.getBlock(4, changeLength); + + //region Check posibility for convertion + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (block.length < 4) return 0; + //endregion + + //region Convert byte array to "Uint32Array" value + const value = new Uint32Array(1); + const view = new Uint8Array(value.buffer); + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + for (let i = 3; i >= 0; i--) view[3 - i] = block[i]; + //endregion + + return value[0]; + } + //********************************************************************************** + /** + * Get 4-byte signed integer value + * @param {boolean} [changeLength=true] Should we change "length" and "start" value after reading the data block + * @returns {number} + */ + getInt32(changeLength = true) { + const block = this.getBlock(4, changeLength); + + //region Check posibility for convertion + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (block.length < 4) return 0; + //endregion + + //region Convert byte array to "Int32Array" value + const value = new Int32Array(1); + const view = new Uint8Array(value.buffer); + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + for (let i = 3; i >= 0; i--) view[3 - i] = block[i]; + //endregion + + return value[0]; + } + //********************************************************************************** +} +exports.SeqStream = SeqStream; //************************************************************************************** +// noinspection FunctionWithMultipleLoopsJS, FunctionWithMultipleReturnPointsJS, OverlyComplexFunctionJS, FunctionTooLongJS +/** + * Get parsed values from "byte map" + * @param {ByteStream} stream Stream to parse data from + * @param {Object} map Object with information how to parse "byte map" + * @param {number} elements Number of elements in parsing byte map + * @param {?number} [start=null] Start position to parse from + * @param {?number} [length=null] Length of byte block to parse from + * @returns {*} + */ + +function parseByteMap(stream, map, elements, start = null, length = null) { + /* + Map example: + + let map = [ + { + type: "string", + name: "type", + minlength: 1, + maxlength: 1, + func: function(array) + { + let result = { + status: (-1), + length: 1 + }; + + switch(array[0]) + { + case 0x6E: // "n" + result.value = "n"; + break; + case 0x66: // "f" + result.value = "f"; + break; + default: + return result; + } + + result.status = 1; + + return result; + } + }, + { + type: "check", + minlength: 1, + maxlength: 2, + func: function(array) + { + let position = (-1); + + if(array[0] == 0x0A) + position = 1; + if(array[1] == 0x0A) + position = 2; + + return { + status: (position > 0) ? 1 : (-1), + length: position + }; + } + } + ]; + */ + + //region Initial variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start === null) { + // noinspection AssignmentToFunctionParameterJS + start = 0; + } + + // noinspection NonBlockStatementBodyJS + if (start > stream.buffer.byteLength - 1) return false; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length === null) { + // noinspection AssignmentToFunctionParameterJS + length = stream.buffer.byteLength - start; + } + + if (length > stream.buffer.byteLength - start) { + // noinspection AssignmentToFunctionParameterJS + length = stream.buffer.byteLength - start; + } + + let dataView; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, EqualityComparisonWithCoercionJS, NonBlockStatementBodyJS + if (start == 0 && length == stream.buffer.byteLength) dataView = stream.view;else dataView = new Uint8Array(stream.buffer, start, length); + + const resultArray = new Array(elements); + let elementsCount = 0; + + let count = 0; + const mapLength = map.length; + //endregion + + //region Parse all byte, structure by structure + while (count < length) { + let structureLength = 0; + + resultArray[elementsCount] = {}; + + for (let i = 0; i < mapLength; i++) { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, JSUnresolvedVariable, EqualityComparisonWithCoercionJS + if (map[i].maxlength == 0) { + // noinspection NonBlockStatementBodyJS + if ("defaultValue" in map[i]) resultArray[elementsCount][map[i].name] = map[i].defaultValue; + + // noinspection ContinueStatementJS + continue; + } + + // noinspection JSUnresolvedVariable + const array = new Array(map[i].maxlength); + + // noinspection JSUnresolvedVariable + for (let j = 0; j < map[i].maxlength; j++) { + // noinspection IncrementDecrementResultUsedJS + array[j] = dataView[count++]; + } + + // noinspection JSUnresolvedVariable + const result = map[i].func(array); + // noinspection EqualityComparisonWithCoercionJS, NonBlockStatementBodyJS + if (result.status == -1) { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS, EqualityComparisonWithCoercionJS + if (resultArray.length == 1) return []; + + return resultArray.slice(0, resultArray.length - 1); + } + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, EqualityComparisonWithCoercionJS, NonBlockStatementBodyJS + if (map[i].type != "check") resultArray[elementsCount][map[i].name] = result.value; + + // noinspection JSUnresolvedVariable + count -= map[i].maxlength - result.length; + structureLength += result.length; + } + + // noinspection IncrementDecrementResultUsedJS + resultArray[elementsCount++].structureLength = structureLength; + } + //endregion + + return resultArray; +} +//************************************************************************************** +//region "Bits-to-string" array +const bitsToStringArray = ["00000000", "00000001", "00000010", "00000011", "00000100", "00000101", "00000110", "00000111", "00001000", "00001001", "00001010", "00001011", "00001100", "00001101", "00001110", "00001111", "00010000", "00010001", "00010010", "00010011", "00010100", "00010101", "00010110", "00010111", "00011000", "00011001", "00011010", "00011011", "00011100", "00011101", "00011110", "00011111", "00100000", "00100001", "00100010", "00100011", "00100100", "00100101", "00100110", "00100111", "00101000", "00101001", "00101010", "00101011", "00101100", "00101101", "00101110", "00101111", "00110000", "00110001", "00110010", "00110011", "00110100", "00110101", "00110110", "00110111", "00111000", "00111001", "00111010", "00111011", "00111100", "00111101", "00111110", "00111111", "01000000", "01000001", "01000010", "01000011", "01000100", "01000101", "01000110", "01000111", "01001000", "01001001", "01001010", "01001011", "01001100", "01001101", "01001110", "01001111", "01010000", "01010001", "01010010", "01010011", "01010100", "01010101", "01010110", "01010111", "01011000", "01011001", "01011010", "01011011", "01011100", "01011101", "01011110", "01011111", "01100000", "01100001", "01100010", "01100011", "01100100", "01100101", "01100110", "01100111", "01101000", "01101001", "01101010", "01101011", "01101100", "01101101", "01101110", "01101111", "01110000", "01110001", "01110010", "01110011", "01110100", "01110101", "01110110", "01110111", "01111000", "01111001", "01111010", "01111011", "01111100", "01111101", "01111110", "01111111", "10000000", "10000001", "10000010", "10000011", "10000100", "10000101", "10000110", "10000111", "10001000", "10001001", "10001010", "10001011", "10001100", "10001101", "10001110", "10001111", "10010000", "10010001", "10010010", "10010011", "10010100", "10010101", "10010110", "10010111", "10011000", "10011001", "10011010", "10011011", "10011100", "10011101", "10011110", "10011111", "10100000", "10100001", "10100010", "10100011", "10100100", "10100101", "10100110", "10100111", "10101000", "10101001", "10101010", "10101011", "10101100", "10101101", "10101110", "10101111", "10110000", "10110001", "10110010", "10110011", "10110100", "10110101", "10110110", "10110111", "10111000", "10111001", "10111010", "10111011", "10111100", "10111101", "10111110", "10111111", "11000000", "11000001", "11000010", "11000011", "11000100", "11000101", "11000110", "11000111", "11001000", "11001001", "11001010", "11001011", "11001100", "11001101", "11001110", "11001111", "11010000", "11010001", "11010010", "11010011", "11010100", "11010101", "11010110", "11010111", "11011000", "11011001", "11011010", "11011011", "11011100", "11011101", "11011110", "11011111", "11100000", "11100001", "11100010", "11100011", "11100100", "11100101", "11100110", "11100111", "11101000", "11101001", "11101010", "11101011", "11101100", "11101101", "11101110", "11101111", "11110000", "11110001", "11110010", "11110011", "11110100", "11110101", "11110110", "11110111", "11111000", "11111001", "11111010", "11111011", "11111100", "11111101", "11111110", "11111111"]; +//endregion +//************************************************************************************** +class BitStream { + //********************************************************************************** + /** + * Constructor for "BitStream" class + * @param {{[byteStream]: ByteStream, [view]: Uint8Array, [buffer]: ArrayBuffer, [string]: string, [bitsCount]: number}} parameters + */ + constructor(parameters = {}) { + this.buffer = new ArrayBuffer(0); + this.view = new Uint8Array(this.buffer); + + this.bitsCount = 0; // Number of bits stored in current "BitStream" + + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = Object.keys(parameters)[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + const key = _step3.value; + + switch (key) { + case "byteStream": + this.fromByteStream(parameters.byteStream); + break; + case "view": + this.fromUint8Array(parameters.view); + break; + case "buffer": + this.fromArrayBuffer(parameters.buffer); + break; + case "string": + this.fromString(parameters.string); + break; + case "uint32": + this.fromUint32(parameters.uint32); + break; + case "bitsCount": + this.bitsCount = parameters.bitsCount; + break; + default: + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3.return) { + _iterator3.return(); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + } + //********************************************************************************** + /** + * Clear existing stream + */ + clear() { + this.buffer = new ArrayBuffer(0); + this.view = new Uint8Array(this.buffer); + + this.bitsCount = 0; + } + //********************************************************************************** + /** + * Initialize "BitStream" by data from existing "ByteStream" + * @param {ByteStream} stream + */ + fromByteStream(stream) { + this.buffer = stream.buffer.slice(0); + this.view = new Uint8Array(this.buffer); + + this.bitsCount = this.view.length << 3; + } + //********************************************************************************** + /** + * Initialize "BitStream" object from existing "ArrayBuffer" + * @param {ArrayBuffer} array The ArrayBuffer to copy from + */ + fromArrayBuffer(array) { + this.buffer = array.slice(0); + this.view = new Uint8Array(this.buffer); + + this.bitsCount = this.view.length << 3; + } + //********************************************************************************** + // noinspection FunctionNamingConventionJS + /** + * Initialize "BitStream" object from existing "Uint8Array" + * @param {Uint8Array} array The Uint8Array to copy from + */ + fromUint8Array(array) { + this.buffer = new ArrayBuffer(array.length); + this.view = new Uint8Array(this.buffer); + + this.view.set(array); + + this.bitsCount = this.view.length << 3; + } + //********************************************************************************** + /** + * Initialize "BitStream" object from existing bit string + * @param {string} string The string to initialize from + */ + fromString(string) { + //region Initial variables + const stringLength = string.length; + + // noinspection ConditionalExpressionJS + this.buffer = new ArrayBuffer((stringLength >> 3) + (stringLength % 8 ? 1 : 0)); + this.view = new Uint8Array(this.buffer); + + this.bitsCount = (stringLength >> 3) + 1 << 3; // In order to handle correct shifting + + let byteIndex = 0; + //endregion + + //region Convert from "bit string" to bytes + for (let i = 0; i < stringLength; i++) { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, EqualityComparisonWithCoercionJS, NonBlockStatementBodyJS + if (string[i] == "1") this.view[byteIndex] |= 1 << 7 - i % 8; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, EqualityComparisonWithCoercionJS, NonBlockStatementBodyJS + if (i && (i + 1) % 8 == 0) byteIndex++; + } + //endregion + + //region Shift "BitStream" into correct position + // noinspection NonBlockStatementBodyJS + if (stringLength % 8) this.shiftRight(8 - stringLength % 8); + //endregion + + //region Change "bitsCount" + this.bitsCount = stringLength; + //endregion + } + //********************************************************************************** + /** + * Initialize "BitStream" object from existing uint32 number + * @param {Number} number The string to initialize from + */ + fromUint32(uint32) { + this.buffer = new ArrayBuffer(4); + this.view = new Uint8Array(this.buffer); + + const value = new Uint32Array([uint32]); + const view = new Uint8Array(value.buffer); + + for (let i = 3; i >= 0; i--) this.view[i] = view[3 - i]; + + this.bitsCount = 32; + } + //********************************************************************************** + /** + * Represent "BitStream" object content as a string + * @param {?number} [start=null] Start number to convert to string from + * @param {?number} [length=null] Length of BitStream to convert to string + * @returns {string} + */ + toString(start = null, length = null) { + //region Check input parameters + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS + start = 0; + } + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start >= this.view.length || start < 0) { + // noinspection AssignmentToFunctionParameterJS + start = 0; + } + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length == null) { + // noinspection AssignmentToFunctionParameterJS + length = this.view.length - start; + } + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length >= this.view.length || length < 0) { + // noinspection AssignmentToFunctionParameterJS + length = this.view.length - start; + } + //endregion + + //region Initial variables + const result = []; + //endregion + + //region Convert from bytes to "bit string" + // noinspection NonBlockStatementBodyJS + for (let i = start; i < start + length; i++) result.push(bitsToStringArray[this.view[i]]); + //endregion + + // noinspection ChainedFunctionCallJS + return result.join("").slice((this.view.length << 3) - this.bitsCount); + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS + /** + * Shift entire "BitStream" value right to number of bits + * @param {number} shift Number of bits to shift value + * @param {boolean} [needShrink=true] Need to shrink result or not + */ + shiftRight(shift, needShrink = true) { + //region Check parameters + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, EqualityComparisonWithCoercionJS, NonBlockStatementBodyJS + if (this.view.length == 0) return; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (shift < 0 || shift > 8) throw new Error("The \"shift\" parameter must be in range 0-8"); + + // noinspection NonBlockStatementBodyJS + if (shift > this.bitsCount) throw new Error("The \"shift\" parameter can not be bigger than \"this.bitsCount\""); + //endregion + + //region Initial variables + // noinspection MagicNumberJS + const shiftMask = 0xFF >> 8 - shift; + this.view[this.view.length - 1] >>= shift; + //endregion + + //region Shift value + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + for (let i = this.view.length - 2; i >= 0; i--) { + // noinspection NonShortCircuitBooleanExpressionJS + this.view[i + 1] |= (this.view[i] & shiftMask) << 8 - shift; + this.view[i] >>= shift; + } + //endregion + + //region Decrease number of bits stored into value + this.bitsCount -= shift; + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, EqualityComparisonWithCoercionJS, NonBlockStatementBodyJS + if (this.bitsCount == 0) this.clear(); + //endregion + + //region Change stream size if needed + // noinspection NonBlockStatementBodyJS + if (needShrink) this.shrink(); + //endregion + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS + /** + * Shift entire "BitStream" value left to number of bits + * @param {number} shift Number of bits to shift value + */ + shiftLeft(shift) { + /* + NOTE: We do not really shift value because of internal structure of "BitStream": + all bytes inside "BitStream" are aligned to right position. So, even if we will + really shift value to left after that we will need again shift it right to the + same number of bits. Thus all that we do here is hiding of left bits and descresing + the "bitsCount" number. + */ + + //region Check parameters + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, EqualityComparisonWithCoercionJS, NonBlockStatementBodyJS + if (this.view.length == 0) return; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (shift < 0 || shift > 8) throw new Error("The \"shift\" parameter must be in range 0-8"); + + // noinspection NonBlockStatementBodyJS + if (shift > this.bitsCount) throw new Error("The \"shift\" parameter can not be bigger than \"this.bitsCount\""); + //endregion + + //region Remove shifted bits + // noinspection MagicNumberJS, NonShortCircuitBooleanExpressionJS + const bitsOffset = this.bitsCount & 0x07; + if (bitsOffset > shift) { + // noinspection MagicNumberJS + this.view[0] &= 0xFF >> bitsOffset + shift; + } else { + //region Change size of buffer + const buffer = new ArrayBuffer(this.buffer.byteLength - 1); + const view = new Uint8Array(buffer); + + // noinspection NestedFunctionCallJS + view.set(new Uint8Array(this.buffer, 1, this.buffer.byteLength - 1)); + //endregion + + //region Mask item with index 0 + // noinspection MagicNumberJS + view[0] &= 0xFF >> shift - bitsOffset; + //endregion + + //region Store final array into current stream + this.buffer = buffer.slice(0); + this.view = new Uint8Array(this.buffer); + //endregion + } + //endregion + + //region Decrease number of bits stored into value + this.bitsCount -= shift; + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, EqualityComparisonWithCoercionJS, NonBlockStatementBodyJS + if (this.bitsCount == 0) this.clear(); + //endregion + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS, FunctionTooLongJS + /** + * Return slice of existing "BitStream" + * @param {?number} [start=null] Start position of the slice (in bits) + * @param {?number} [end=null] End position of the slice (in bits) + * @returns {BitStream} + */ + slice(start = null, end = null) { + //region Make ability to pass non-value bits + let valueShift = 0; + // noinspection NonBlockStatementBodyJS + if (this.bitsCount % 8) valueShift = 8 - this.bitsCount % 8; + + // noinspection AssignmentToFunctionParameterJS + start += valueShift; + // noinspection AssignmentToFunctionParameterJS + end += valueShift; + //endregion + + //region Initial variables + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (start == null) { + // noinspection AssignmentToFunctionParameterJS + start = 0; + } + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (start < 0 || start > (this.view.length << 3) - 1) return new BitStream(); //("Wrong start position: " + start); + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (end == null) { + // noinspection AssignmentToFunctionParameterJS + end = (this.view.length << 3) - 1; + } + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (end < 0 || end > (this.view.length << 3) - 1) return new BitStream(); //("Wrong end position: " + end); + + // noinspection NonBlockStatementBodyJS + if (end - start + 1 > this.bitsCount) return new BitStream(); //("Maximum length is " + this.bitsCount); + + const startIndex = start >> 3; + // noinspection MagicNumberJS, NonShortCircuitBooleanExpressionJS + const startOffset = start & 0x07; + + const endIndex = end >> 3; + // noinspection MagicNumberJS, NonShortCircuitBooleanExpressionJS + const endOffset = end & 0x07; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, ConditionalExpressionJS, EqualityComparisonWithCoercionJS + const bitsLength = endIndex - startIndex == 0 ? 1 : endIndex - startIndex + 1; + + const result = new BitStream(); + //endregion + + //region Store "primary bytes" + result.buffer = new ArrayBuffer(bitsLength); + result.view = new Uint8Array(result.buffer); + result.bitsCount = bitsLength << 3; + + // noinspection NestedFunctionCallJS + result.view.set(new Uint8Array(this.buffer, startIndex, bitsLength)); + //endregion + + //region Change "start byte" + // noinspection MagicNumberJS + result.view[0] &= 0xFF >> startOffset; + //endregion + + //region Change "end byte" + // noinspection MagicNumberJS + result.view[bitsLength] &= 0xFF << 7 - endOffset; + //endregion + + //region Shift result array to right + // noinspection NonBlockStatementBodyJS + if (7 - endOffset) result.shiftRight(7 - endOffset, false); + //endregion + + //region Set final number of bits + result.bitsCount = end - start + 1; + //endregion + + //region Cut unnecessary bytes from result + result.shrink(); + //endregion + + return result; + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS + /** + * Return copy of existing "BitStream" + * @param {?number} [start=null] Start position of the copy (in bits) + * @param {?number} [length=null] Length of the copy (in bits) + * @returns {BitStream} + */ + copy(start = null, length = null) { + //region Check input parameters + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (start < 0 || start > (this.view.length << 3) - 1) return new BitStream(); //("Wrong start position: " + start); + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS + if (length === null) { + // noinspection AssignmentToFunctionParameterJS + length = (this.view.length << 3) - start - 1; + } + + // noinspection NonBlockStatementBodyJS + if (length > this.bitsCount) return new BitStream(); //("Maximum length is " + this.bitsCount); + //endregion + + return this.slice(start, start + length - 1); + } + //********************************************************************************** + /** + * Shrink unnecessary bytes in current stream accordingly to "bitsCount" value + */ + shrink() { + // noinspection ConditionalExpressionJS + const currentLength = (this.bitsCount >> 3) + (this.bitsCount % 8 ? 1 : 0); + if (currentLength < this.buffer.byteLength) { + //region Change size of buffer + const buffer = new ArrayBuffer(currentLength); + const view = new Uint8Array(buffer); + + // noinspection NestedFunctionCallJS + view.set(new Uint8Array(this.buffer, this.buffer.byteLength - currentLength, currentLength)); + //endregion + + //region Store final array into current stream + this.buffer = buffer.slice(0); + this.view = new Uint8Array(this.buffer); + //endregion + } + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Reverse bits order in each byte in the stream + * Got it from here: http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits + */ + reverseBytes() { + //region Reverse bits order in each byte in the stream + for (let i = 0; i < this.view.length; i++) { + // noinspection MagicNumberJS, NonShortCircuitBooleanExpressionJS + this.view[i] = (this.view[i] * 0x0802 & 0x22110 | this.view[i] * 0x8020 & 0x88440) * 0x10101 >> 16; + } + //endregion + + //region Shift "most significant" byte + if (this.bitsCount % 8) { + // noinspection ConditionalExpressionJS + const currentLength = (this.bitsCount >> 3) + (this.bitsCount % 8 ? 1 : 0); + // noinspection MagicNumberJS, NonShortCircuitBooleanExpressionJS + this.view[this.view.length - currentLength] >>= 8 - (this.bitsCount & 0x07); + } + //endregion + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Reverse all bits in entire "BitStream" + */ + reverseValue() { + const initialValue = this.toString(); + const initialValueLength = initialValue.length; + + const reversedValue = new Array(initialValueLength); + + // noinspection NonBlockStatementBodyJS + for (let i = 0; i < initialValueLength; i++) reversedValue[initialValueLength - 1 - i] = initialValue[i]; + + // noinspection NestedFunctionCallJS + this.fromString(reversedValue.join("")); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS + /** + * Trying to represent entire "BitStream" as an unsigned integer. + * @return {number} + */ + getNumberValue() { + //region Initial variables + const byteLength = this.buffer.byteLength - 1; + //endregion + + //region Check posibility for convertion + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + if (byteLength > 3) return -1; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, EqualityComparisonWithCoercionJS, NonBlockStatementBodyJS + if (byteLength == -1) return 0; + //endregion + + //region Convert byte array to "Uint32Array" value + const value = new Uint32Array(1); + const view = new Uint8Array(value.buffer); + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, NonBlockStatementBodyJS + for (let i = byteLength; i >= 0; i--) view[byteLength - i] = this.view[i]; + //endregion + + return value[0]; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Find any bit pattern in "BitStream" + * @param {BitStream} pattern Stream having pattern value + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @param {boolean} [backward=false] Flag to search in backward order + * @returns {number} + */ + findPattern(pattern, start = null, length = null, backward = false) { + //region Convert "BitStream" values to "ByteStream" + const stringStream = new ByteStream({ + string: this.toString() + }); + const stringPattern = new ByteStream({ + string: pattern.toString() + }); + //endregion + + return stringStream.findPattern(stringPattern, start, length, backward); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Find first position of any pattern from input array + * @param {Array.} patterns Array with patterns which should be found + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @param {boolean} [backward=false] Flag to search in backward order + * @returns {{id: number, position: number}} + */ + findFirstIn(patterns, start = null, length = null, backward = false) { + //region Convert "BitStream" values to "ByteStream" + const stringStream = new ByteStream({ + string: this.toString() + }); + + const stringPatterns = new Array(patterns.length); + + for (let i = 0; i < patterns.length; i++) { + stringPatterns[i] = new ByteStream({ + string: patterns[i].toString() + }); + } + //endregion + + return stringStream.findFirstIn(stringPatterns, start, length, backward); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Find all positions of any pattern from input array + * @param {Array.} patterns Array with patterns which should be found + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @returns {Array} + */ + findAllIn(patterns, start = null, length = null) { + //region Convert "BitStream" values to "ByteStream" + const stringStream = new ByteStream({ + string: this.toString() + }); + + const stringPatterns = new Array(patterns.length); + + for (let i = 0; i < patterns.length; i++) { + stringPatterns[i] = new ByteStream({ + string: patterns[i].toString() + }); + } + //endregion + + return stringStream.findAllIn(stringPatterns, start, length); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Find all positions of a pattern + * @param {BitStream} pattern Stream having pattern value + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @returns {Array|number} + */ + findAllPatternIn(pattern, start = null, length = null) { + //region Convert "BitStream" values to "ByteStream" + const stringStream = new ByteStream({ + string: this.toString() + }); + const stringPattern = new ByteStream({ + string: pattern.toString() + }); + //endregion + + return stringStream.findAllPatternIn(stringPattern, start, length); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Find first position of data, not included in patterns from input array + * @param {Array.} patterns Array with patterns which should be found + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @param {boolean} [backward=false] Flag to search in backward order + * @returns {{left: {id: number, position: *}, right: {id: number, position: number}, value: ByteStream}} + */ + findFirstNotIn(patterns, start = null, length = null, backward = false) { + //region Convert "BitStream" values to "ByteStream" + const stringStream = new ByteStream({ + string: this.toString() + }); + + const stringPatterns = new Array(patterns.length); + + for (let i = 0; i < patterns.length; i++) { + stringPatterns[i] = new ByteStream({ + string: patterns[i].toString() + }); + } + //endregion + + return stringStream.findFirstNotIn(stringPatterns, start, length, backward); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Find all positions of data, not included in patterns from input array + * @param {Array.} patterns Array with patterns which should be found + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @returns {Array} + */ + findAllNotIn(patterns, start = null, length = null) { + //region Convert "BitStream" values to "ByteStream" + const stringStream = new ByteStream({ + string: this.toString() + }); + + const stringPatterns = new Array(patterns.length); + + for (let i = 0; i < patterns.length; i++) { + stringPatterns[i] = new ByteStream({ + string: patterns[i].toString() + }); + } + //endregion + + return stringStream.findAllNotIn(stringPatterns, start, length); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Find position of a sequence of any patterns from input array + * @param {Array.} patterns Array with patterns which should be found + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @param {boolean} [backward=false] Flag to search in backward order + * @returns {{position, value}|*} + */ + findFirstSequence(patterns, start = null, length = null, backward = false) { + //region Convert "BitStream" values to "ByteStream" + const stringStream = new ByteStream({ + string: this.toString() + }); + + const stringPatterns = new Array(patterns.length); + + for (let i = 0; i < patterns.length; i++) { + stringPatterns[i] = new ByteStream({ + string: patterns[i].toString() + }); + } + //endregion + + return stringStream.findFirstSequence(stringPatterns, start, length, backward); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Find position of a sequence of any patterns from input array + * @param {Array.} patterns Array with patterns which should be found + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @returns {Array} + */ + findAllSequences(patterns, start, length) { + //region Convert "BitStream" values to "ByteStream" + const stringStream = new ByteStream({ + string: this.toString() + }); + + const stringPatterns = new Array(patterns.length); + + for (let i = 0; i < patterns.length; i++) { + stringPatterns[i] = new ByteStream({ + string: patterns[i].toString() + }); + } + //endregion + + return stringStream.findAllSequences(stringPatterns, start, length); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Find all paired patterns in the stream + * @param {BitStream} leftPattern Left pattern to search for + * @param {BitStream} rightPattern Right pattern to search for + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @returns {Array} + */ + findPairedPatterns(leftPattern, rightPattern, start = null, length = null) { + //region Convert "BitStream" values to "ByteStream" + const stringStream = new ByteStream({ + string: this.toString() + }); + const stringLeftPattern = new ByteStream({ + string: leftPattern.toString() + }); + const stringRightPattern = new ByteStream({ + string: rightPattern.toString() + }); + //endregion + + return stringStream.findPairedPatterns(stringLeftPattern, stringRightPattern, start, length); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleLoopsJS + /** + * Find all paired patterns in the stream + * @param {Array.} inputLeftPatterns Array of left patterns to search for + * @param {Array.} inputRightPatterns Array of right patterns to search for + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @returns {Array} + */ + findPairedArrays(inputLeftPatterns, inputRightPatterns, start = null, length = null) { + //region Convert "BitStream" values to "ByteStream" + const stringStream = new ByteStream({ + string: this.toString() + }); + + const stringLeftPatterns = new Array(inputLeftPatterns.length); + + for (let i = 0; i < inputLeftPatterns.length; i++) { + stringLeftPatterns[i] = new ByteStream({ + string: inputLeftPatterns[i].toString() + }); + } + + const stringRightPatterns = new Array(inputRightPatterns.length); + + for (let i = 0; i < inputRightPatterns.length; i++) { + stringRightPatterns[i] = new ByteStream({ + string: inputRightPatterns[i].toString() + }); + } + //endregion + + return stringStream.findPairedArrays(stringLeftPatterns, stringRightPatterns, start, length); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleReturnPointsJS + /** + * Replace one pattern with other + * @param {BitStream} searchPattern The pattern to search for + * @param {BitStream} replacePattern The pattern to replace initial pattern + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @returns {boolean} + */ + replacePattern(searchPattern, replacePattern, start = null, length = null) { + //region Convert "BitStream" values to "ByteStream" + const stringStream = new ByteStream({ + string: this.toString() + }); + const stringSearchPattern = new ByteStream({ + string: searchPattern.toString() + }); + const stringReplacePattern = new ByteStream({ + string: replacePattern.toString() + }); + //endregion + + //region Re-initialize existing data + if (stringStream.findPairedPatterns(stringSearchPattern, stringReplacePattern, start, length)) { + // noinspection NestedFunctionCallJS + this.fromString(stringStream.toString()); + return true; + } + //endregion + + return false; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Skip any pattern from input array + * @param {Array.} patterns Array with patterns which should be ommited + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @param {boolean} [backward=false] Flag to search in backward order + * @returns {*} + */ + skipPatterns(patterns, start, length, backward) { + //region Convert "BitStream" values to "ByteStream" + const stringStream = new ByteStream({ + string: this.toString() + }); + + const stringPatterns = new Array(patterns.length); + + for (let i = 0; i < patterns.length; i++) { + stringPatterns[i] = new ByteStream({ + string: patterns[i].toString() + }); + } + //endregion + + return stringStream.skipPatterns(stringPatterns, start, length, backward); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Skip any pattern not from input array + * @param {Array.} patterns Array with patterns which should be ommited + * @param {?number} [start=null] Start position to search from + * @param {?number} [length=null] Length of byte block to search at + * @param {boolean} [backward=false] Flag to search in backward order + * @returns {number} + */ + skipNotPatterns(patterns, start, length, backward) { + //region Convert "BitStream" values to "ByteStream" + const stringStream = new ByteStream({ + string: this.toString() + }); + + const stringPatterns = new Array(patterns.length); + + for (let i = 0; i < patterns.length; i++) { + stringPatterns[i] = new ByteStream({ + string: patterns[i].toString() + }); + } + //endregion + + return stringStream.skipNotPatterns(stringPatterns, start, length, backward); + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Append a new "BitStream" content to the current "BitStream" + * @param {BitStream} stream A new "stream" to append to current "stream" + */ + append(stream) { + //region Initialize current stream with new data + // noinspection NestedFunctionCallJS + this.fromString([this.toString(), stream.toString()].join("")); + //endregion + } + //********************************************************************************** +} +exports.BitStream = BitStream; //************************************************************************************** + +class SeqBitStream { + //********************************************************************************** + constructor(parameters = {}) { + //region Internal variables + this.stream = new BitStream(); + + this._start = 0; + this._length = this.stream.bitsCount; + + this.backward = false; + + this.appendBlock = 0; + //endregion + + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = Object.keys(parameters)[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + const key = _step4.value; + + switch (key) { + case "stream": + case "start": + case "length": + case "backward": + case "appendBlock": + this[key] = parameters[key]; + break; + default: + } + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4.return) { + _iterator4.return(); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS + set start(value) { + // noinspection NonBlockStatementBodyJS + if (value > this.stream.bitsCount) return; + + // noinspection ConditionalExpressionJS + this._length -= this.backward ? this._start - value : value - this._start; + this._start = value; + + //region Initialization of "prev" internal variables + // noinspection JSUnusedGlobalSymbols + this.prevStart = this._start; + // noinspection JSUnusedGlobalSymbols + this.prevLength = this._length; + //endregion + } + //********************************************************************************** + get start() { + return this._start; + } + //********************************************************************************** + // noinspection FunctionWithMultipleReturnPointsJS + set length(value) { + // noinspection NonBlockStatementBodyJS + if (value > this.stream.bitsCount) return; + + // noinspection JSUnusedGlobalSymbols + this.prevLength = this._length; + this._length = value; + } + //********************************************************************************** + get length() { + return this._length; + } + //********************************************************************************** + set stream(value) { + this._stream = value; + + // noinspection JSUnusedGlobalSymbols + this.prevLength = this._length; + this._length = value.bitsCount; + + // noinspection JSUnusedGlobalSymbols + this.prevStart = this._start; + // noinspection ConditionalExpressionJS + this._start = this.backward ? this.length : 0; + } + //********************************************************************************** + get stream() { + return this._stream; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols + /** + * Get next "length" bits from the stream + * @param {number} length Number of bits to read + * @returns {*} + */ + getBits(length) { + //region Check input parameters + if (this.start + length > this.stream.bitsCount) { + // noinspection AssignmentToFunctionParameterJS + length = this.stream.bitsCount - this.start; + } + //endregion + + //region Initial variables + let result; + //endregion + + //region Copy necessary length of bits + if (this.backward) { + result = this.stream.copy(this.start - length, length); + this.start -= result.bitsCount; + } else { + result = this.stream.copy(this.start, length); + this.start += result.bitsCount; + } + //endregion + + return result; + } + //********************************************************************************** + // noinspection FunctionTooLongJS + /** + * Get string representation for the next "length" bits from the stream + * @param {number} length Number of bits to read + * @returns {string} + */ + getBitsString(length) { + //region Check input parameters + if (this.start + length > this.stream.bitsCount) { + // noinspection AssignmentToFunctionParameterJS + length = this.stream.bitsCount - this.start; + } + //endregion + + //region Initial variables + let result = []; + + let start; + + // noinspection NonBlockStatementBodyJS + if (this.backward) start = this.start - length;else start = this.start; + + let end = this.start + length - 1; + + //region Make ability to pass non-value bits + let valueShift = 0; + // noinspection NonBlockStatementBodyJS + if (this.stream.bitsCount % 8) valueShift = 8 - this.stream.bitsCount % 8; + + start += valueShift; + end += valueShift; + //endregion + + const startIndex = start >> 3; + // noinspection MagicNumberJS, NonShortCircuitBooleanExpressionJS + const startOffset = start & 0x07; + + const endIndex = end >> 3; + // noinspection MagicNumberJS, NonShortCircuitBooleanExpressionJS + const endOffset = end & 0x07; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, ConditionalExpressionJS, EqualityComparisonWithCoercionJS + const bitsLengthIndex = startIndex + (endIndex - startIndex == 0 ? 1 : endIndex - startIndex + 1); + //endregion + + //region Get string representation of bits + for (let i = startIndex; i < bitsLengthIndex; i++) { + let value = bitsToStringArray[this.stream.view[i]]; + + // noinspection EqualityComparisonWithCoercionJS, NonBlockStatementBodyJS + if (i == startIndex) value = value.slice(startOffset); + + // noinspection EqualityComparisonWithCoercionJS, NonBlockStatementBodyJS + if (i == bitsLengthIndex - 1) value = value.slice(0, endOffset - 7 + value.length); + + result.push(value); + } + + result = result.join(""); + //endregion + + //region Change internal values + // noinspection NonBlockStatementBodyJS + if (this.backward) this.start -= result.length;else this.start += result.length; + //endregion + + return result; + } + //********************************************************************************** + // noinspection JSUnusedGlobalSymbols, FunctionWithMultipleLoopsJS, FunctionWithMultipleReturnPointsJS + /** + * Get number value representation of the next "length" bits from the stream, preliminary reversed + * @param {number} length Number of bits to read + * @returns {*} + */ + getBitsReversedValue(length) { + //region Initial variables + const initialValue = this.getBitsString(length); + const initialValueLength = initialValue.length; + + let byteIndex; + + const initialOffset = 8 - initialValueLength % 8; + + const reversedValue = new Array(initialValueLength); + + const value = new Uint32Array(1); + const valueView = new Uint8Array(value.buffer, 0, 4); + + let i; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, MagicNumberJS, NonBlockStatementBodyJS + if (initialValueLength > 32) return -1; + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, MagicNumberJS, EqualityComparisonWithCoercionJS, NonBlockStatementBodyJS + if (length == 32) byteIndex = 3;else byteIndex = initialValueLength - 1 >> 3; + //endregion + + //region Reverse value + // noinspection NonBlockStatementBodyJS + for (i = 0; i < initialValueLength; i++) reversedValue[initialValueLength - 1 - i] = initialValue[i]; + //endregion + + //region Convert byte array to "Uint32Array" value + for (i = initialOffset; i < initialOffset + initialValueLength; i++) { + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, EqualityComparisonWithCoercionJS + if (reversedValue[i - initialOffset] == "1") { + // noinspection MagicNumberJS + valueView[byteIndex] |= 0x01 << 7 - i % 8; + } + + // noinspection ConstantOnRightSideOfComparisonJS, ConstantOnLeftSideOfComparisonJS, EqualityComparisonWithCoercionJS, NonBlockStatementBodyJS + if (i && (i + 1) % 8 == 0) byteIndex--; + } + //endregion + + return value[0]; + } + //********************************************************************************** + /** + * Represent remaining bits in "BitStream" as a string + * @return {string} + */ + toString() { + const streamToDisplay = this.stream.copy(this.start, this.length); + return streamToDisplay.toString(); + } + //********************************************************************************** +} +exports.SeqBitStream = SeqBitStream; //************************************************************************************** + +},{}],2:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _GeneralName = _interopRequireDefault(require("./GeneralName.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class AccessDescription { + //********************************************************************************** + + /** + * Constructor for AccessDescription class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc The type and format of the information are specified by the accessMethod field. This profile defines two accessMethod OIDs: id-ad-caIssuers and id-ad-ocsp + */ + this.accessMethod = (0, _pvutils.getParametersValue)(parameters, "accessMethod", AccessDescription.defaultValues("accessMethod")); + /** + * @type {GeneralName} + * @desc The accessLocation field specifies the location of the information + */ + + this.accessLocation = (0, _pvutils.getParametersValue)(parameters, "accessLocation", AccessDescription.defaultValues("accessLocation")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "accessMethod": + return ""; + + case "accessLocation": + return new _GeneralName.default(); + + default: + throw new Error(`Invalid member name for AccessDescription class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * AccessDescription ::= SEQUENCE { + * accessMethod OBJECT IDENTIFIER, + * accessLocation GeneralName } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [accessMethod] + * @property {string} [accessLocation] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.accessMethod || "" + }), _GeneralName.default.schema(names.accessLocation || {})] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["accessMethod", "accessLocation"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, AccessDescription.schema({ + names: { + accessMethod: "accessMethod", + accessLocation: { + names: { + blockName: "accessLocation" + } + } + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for AccessDescription"); //endregion + //region Get internal properties from parsed schema + + this.accessMethod = asn1.result.accessMethod.valueBlock.toString(); + this.accessLocation = new _GeneralName.default({ + schema: asn1.result.accessLocation + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [new asn1js.ObjectIdentifier({ + value: this.accessMethod + }), this.accessLocation.toSchema()] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + accessMethod: this.accessMethod, + accessLocation: this.accessLocation.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = AccessDescription; + +},{"./GeneralName.js":40,"asn1js":112,"pvutils":113}],3:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC3161. Accuracy represents the time deviation around the UTC time contained in GeneralizedTime. + */ +class Accuracy { + //********************************************************************************** + + /** + * Constructor for Accuracy class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + if ("seconds" in parameters) + /** + * @type {number} + * @desc seconds + */ + this.seconds = (0, _pvutils.getParametersValue)(parameters, "seconds", Accuracy.defaultValues("seconds")); + if ("millis" in parameters) + /** + * @type {number} + * @desc millis + */ + this.millis = (0, _pvutils.getParametersValue)(parameters, "millis", Accuracy.defaultValues("millis")); + if ("micros" in parameters) + /** + * @type {number} + * @desc micros + */ + this.micros = (0, _pvutils.getParametersValue)(parameters, "micros", Accuracy.defaultValues("micros")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "seconds": + case "millis": + case "micros": + return 0; + + default: + throw new Error(`Invalid member name for Accuracy class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "seconds": + case "millis": + case "micros": + return memberValue === Accuracy.defaultValues(memberName); + + default: + throw new Error(`Invalid member name for Accuracy class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * Accuracy ::= SEQUENCE { + * seconds INTEGER OPTIONAL, + * millis [0] INTEGER (1..999) OPTIONAL, + * micros [1] INTEGER (1..999) OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [seconds] + * @property {string} [millis] + * @property {string} [micros] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + optional: true, + value: [new asn1js.Integer({ + optional: true, + name: names.seconds || "" + }), new asn1js.Primitive({ + name: names.millis || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + } + }), new asn1js.Primitive({ + name: names.micros || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + } + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["seconds", "millis", "micros"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, Accuracy.schema({ + names: { + seconds: "seconds", + millis: "millis", + micros: "micros" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for Accuracy"); //endregion + //region Get internal properties from parsed schema + + if ("seconds" in asn1.result) this.seconds = asn1.result.seconds.valueBlock.valueDec; + + if ("millis" in asn1.result) { + const intMillis = new asn1js.Integer({ + valueHex: asn1.result.millis.valueBlock.valueHex + }); + this.millis = intMillis.valueBlock.valueDec; + } + + if ("micros" in asn1.result) { + const intMicros = new asn1js.Integer({ + valueHex: asn1.result.micros.valueBlock.valueHex + }); + this.micros = intMicros.valueBlock.valueDec; + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array of output sequence + const outputArray = []; + if ("seconds" in this) outputArray.push(new asn1js.Integer({ + value: this.seconds + })); + + if ("millis" in this) { + const intMillis = new asn1js.Integer({ + value: this.millis + }); + outputArray.push(new asn1js.Primitive({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + valueHex: intMillis.valueBlock.valueHex + })); + } + + if ("micros" in this) { + const intMicros = new asn1js.Integer({ + value: this.micros + }); + outputArray.push(new asn1js.Primitive({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + valueHex: intMicros.valueBlock.valueHex + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = {}; + if ("seconds" in this) _object.seconds = this.seconds; + if ("millis" in this) _object.millis = this.millis; + if ("micros" in this) _object.micros = this.micros; + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = Accuracy; + +},{"asn1js":112,"pvutils":113}],4:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class AlgorithmIdentifier { + //********************************************************************************** + + /** + * Constructor for AlgorithmIdentifier class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + * @property {string} [algorithmId] ObjectIdentifier for algorithm (string representation) + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc ObjectIdentifier for algorithm (string representation) + */ + this.algorithmId = (0, _pvutils.getParametersValue)(parameters, "algorithmId", AlgorithmIdentifier.defaultValues("algorithmId")); + if ("algorithmParams" in parameters) + /** + * @type {Object} + * @desc Any algorithm parameters + */ + this.algorithmParams = (0, _pvutils.getParametersValue)(parameters, "algorithmParams", AlgorithmIdentifier.defaultValues("algorithmParams")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "algorithmId": + return ""; + + case "algorithmParams": + return new asn1js.Any(); + + default: + throw new Error(`Invalid member name for AlgorithmIdentifier class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "algorithmId": + return memberValue === ""; + + case "algorithmParams": + return memberValue instanceof asn1js.Any; + + default: + throw new Error(`Invalid member name for AlgorithmIdentifier class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * AlgorithmIdentifier ::= Sequence { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} algorithmIdentifier ObjectIdentifier for the algorithm + * @property {string} algorithmParams Any algorithm parameters + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + optional: names.optional || false, + value: [new asn1js.ObjectIdentifier({ + name: names.algorithmIdentifier || "" + }), new asn1js.Any({ + name: names.algorithmParams || "", + optional: true + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["algorithm", "params"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, AlgorithmIdentifier.schema({ + names: { + algorithmIdentifier: "algorithm", + algorithmParams: "params" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for AlgorithmIdentifier"); //endregion + //region Get internal properties from parsed schema + + this.algorithmId = asn1.result.algorithm.valueBlock.toString(); + if ("params" in asn1.result) this.algorithmParams = asn1.result.params; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(new asn1js.ObjectIdentifier({ + value: this.algorithmId + })); + if ("algorithmParams" in this && this.algorithmParams instanceof asn1js.Any === false) outputArray.push(this.algorithmParams); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = { + algorithmId: this.algorithmId + }; + if ("algorithmParams" in this && this.algorithmParams instanceof asn1js.Any === false) object.algorithmParams = this.algorithmParams.toJSON(); + return object; + } //********************************************************************************** + + /** + * Check that two "AlgorithmIdentifiers" are equal + * @param {AlgorithmIdentifier} algorithmIdentifier + * @returns {boolean} + */ + + + isEqual(algorithmIdentifier) { + //region Check input type + if (algorithmIdentifier instanceof AlgorithmIdentifier === false) return false; //endregion + //region Check "algorithm_id" + + if (this.algorithmId !== algorithmIdentifier.algorithmId) return false; //endregion + //region Check "algorithm_params" + + if ("algorithmParams" in this) { + if ("algorithmParams" in algorithmIdentifier) return JSON.stringify(this.algorithmParams) === JSON.stringify(algorithmIdentifier.algorithmParams); + return false; + } + + if ("algorithmParams" in algorithmIdentifier) return false; //endregion + + return true; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = AlgorithmIdentifier; + +},{"asn1js":112,"pvutils":113}],5:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _GeneralName = _interopRequireDefault(require("./GeneralName.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class AltName { + //********************************************************************************** + + /** + * Constructor for AltName class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc Array of alternative names in GeneralName type + */ + this.altNames = (0, _pvutils.getParametersValue)(parameters, "altNames", AltName.defaultValues("altNames")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "altNames": + return []; + + default: + throw new Error(`Invalid member name for AltName class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * AltName ::= GeneralNames + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [altNames] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.altNames || "", + value: _GeneralName.default.schema() + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["altNames"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, AltName.schema({ + names: { + altNames: "altNames" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for AltName"); //endregion + //region Get internal properties from parsed schema + + if ("altNames" in asn1.result) this.altNames = Array.from(asn1.result.altNames, element => new _GeneralName.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: Array.from(this.altNames, element => element.toSchema()) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + altNames: Array.from(this.altNames, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = AltName; + +},{"./GeneralName.js":40,"asn1js":112,"pvutils":113}],6:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC2986 + */ +class Attribute { + //********************************************************************************** + + /** + * Constructor for Attribute class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc ObjectIdentifier for attribute (string representation) + */ + this.type = (0, _pvutils.getParametersValue)(parameters, "type", Attribute.defaultValues("type")); + /** + * @type {Array} + * @desc Any attribute values + */ + + this.values = (0, _pvutils.getParametersValue)(parameters, "values", Attribute.defaultValues("values")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "type": + return ""; + + case "values": + return []; + + default: + throw new Error(`Invalid member name for Attribute class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "type": + return memberValue === ""; + + case "values": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for Attribute class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE { + * type ATTRIBUTE.&id({IOSet}), + * values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type}) + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [type] + * @property {string} [setName] + * @property {string} [values] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.type || "" + }), new asn1js.Set({ + name: names.setName || "", + value: [new asn1js.Repeated({ + name: names.values || "", + value: new asn1js.Any() + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["type", "values"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, Attribute.schema({ + names: { + type: "type", + values: "values" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for Attribute"); //endregion + //region Get internal properties from parsed schema + + this.type = asn1.result.type.valueBlock.toString(); + this.values = asn1.result.values; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [new asn1js.ObjectIdentifier({ + value: this.type + }), new asn1js.Set({ + value: this.values + })] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + type: this.type, + values: Array.from(this.values, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = Attribute; + +},{"asn1js":112,"pvutils":113}],7:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AttributeCertificateInfoV1 = exports.IssuerSerial = exports.AttCertValidityPeriod = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _GeneralNames = _interopRequireDefault(require("./GeneralNames.js")); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _Attribute = _interopRequireDefault(require("./Attribute.js")); + +var _Extensions = _interopRequireDefault(require("./Extensions.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5755 + */ +class AttCertValidityPeriod { + //********************************************************************************** + + /** + * Constructor for AttCertValidityPeriod class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {GeneralizedTime} + * @desc notBeforeTime + */ + this.notBeforeTime = (0, _pvutils.getParametersValue)(parameters, "notBeforeTime", AttCertValidityPeriod.defaultValues("notBeforeTime")); + /** + * @type {GeneralizedTime} + * @desc notAfterTime + */ + + this.notAfterTime = (0, _pvutils.getParametersValue)(parameters, "notAfterTime", AttCertValidityPeriod.defaultValues("notAfterTime")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "notBeforeTime": + case "notAfterTime": + return new Date(0, 0, 0); + + default: + throw new Error(`Invalid member name for AttCertValidityPeriod class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * AttCertValidityPeriod ::= SEQUENCE { + * notBeforeTime GeneralizedTime, + * notAfterTime GeneralizedTime + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [notBeforeTime] + * @property {string} [notAfterTime] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.GeneralizedTime({ + name: names.notBeforeTime || "" + }), new asn1js.GeneralizedTime({ + name: names.notAfterTime || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["notBeforeTime", "notAfterTime"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, AttCertValidityPeriod.schema({ + names: { + notBeforeTime: "notBeforeTime", + notAfterTime: "notAfterTime" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for AttCertValidityPeriod"); //endregion + //region Get internal properties from parsed schema + + this.notBeforeTime = asn1.result.notBeforeTime.toDate(); + this.notAfterTime = asn1.result.notAfterTime.toDate(); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [new asn1js.GeneralizedTime({ + valueDate: this.notBeforeTime + }), new asn1js.GeneralizedTime({ + valueDate: this.notAfterTime + })] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + notBeforeTime: this.notBeforeTime, + notAfterTime: this.notAfterTime + }; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * Class from RFC5755 + */ + + +exports.AttCertValidityPeriod = AttCertValidityPeriod; + +class IssuerSerial { + //********************************************************************************** + + /** + * Constructor for IssuerSerial class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {RelativeDistinguishedNames} + * @desc issuer + */ + this.issuer = (0, _pvutils.getParametersValue)(parameters, "issuer", IssuerSerial.defaultValues("issuer")); + /** + * @type {Integer} + * @desc serialNumber + */ + + this.serialNumber = (0, _pvutils.getParametersValue)(parameters, "serialNumber", IssuerSerial.defaultValues("serialNumber")); + if ("issuerUID" in parameters) + /** + * @type {BitString} + * @desc issuerUID + */ + this.issuerUID = (0, _pvutils.getParametersValue)(parameters, "issuerUID", IssuerSerial.defaultValues("issuerUID")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "issuer": + return new _GeneralNames.default(); + + case "serialNumber": + return new asn1js.Integer(); + + case "issuerUID": + return new asn1js.BitString(); + + default: + throw new Error(`Invalid member name for IssuerSerial class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * IssuerSerial ::= SEQUENCE { + * issuer GeneralNames, + * serial CertificateSerialNumber, + * issuerUID UniqueIdentifier OPTIONAL + * } + * + * CertificateSerialNumber ::= INTEGER + * UniqueIdentifier ::= BIT STRING + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [issuer] + * @property {string} [serialNumber] + * @property {string} [issuerUID] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_GeneralNames.default.schema(names.issuer || {}), new asn1js.Integer({ + name: names.serialNumber || "" + }), new asn1js.BitString({ + optional: true, + name: names.issuerUID || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["issuer", "serialNumber", "issuerUID"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, IssuerSerial.schema({ + names: { + issuer: { + names: { + blockName: "issuer" + } + }, + serialNumber: "serialNumber", + issuerUID: "issuerUID" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for IssuerSerial"); //endregion + //region Get internal properties from parsed schema + + this.issuer = new _GeneralNames.default({ + schema: asn1.result.issuer + }); + this.serialNumber = asn1.result.serialNumber; + if ("issuerUID" in asn1.result) this.issuerUID = asn1.result.issuerUID; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + const result = new asn1js.Sequence({ + value: [this.issuer.toSchema(), this.serialNumber] + }); + if ("issuerUID" in this) result.valueBlock.value.push(this.issuerUID); //region Construct and return new ASN.1 schema for this object + + return result; //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const result = { + issuer: this.issuer.toJSON(), + serialNumber: this.serialNumber.toJSON() + }; + if ("issuerUID" in this) result.issuerUID = this.issuerUID.toJSON(); + return result; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * Class from RFC5755 + */ + + +exports.IssuerSerial = IssuerSerial; + +class AttributeCertificateInfoV1 { + //********************************************************************************** + + /** + * Constructor for AttributeCertificateInfoV1 class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", AttributeCertificateInfoV1.defaultValues("version")); + if ("baseCertificateID" in parameters) + /** + * @type {IssuerSerial} + * @desc baseCertificateID + */ + this.baseCertificateID = (0, _pvutils.getParametersValue)(parameters, "baseCertificateID", AttributeCertificateInfoV1.defaultValues("baseCertificateID")); + if ("subjectName" in parameters) + /** + * @type {GeneralNames} + * @desc subjectName + */ + this.subjectName = (0, _pvutils.getParametersValue)(parameters, "subjectName", AttributeCertificateInfoV1.defaultValues("subjectName")); + /** + * @type {GeneralNames} + * @desc issuer + */ + + this.issuer = (0, _pvutils.getParametersValue)(parameters, "issuer", AttributeCertificateInfoV1.defaultValues("issuer")); + /** + * @type {AlgorithmIdentifier} + * @desc signature + */ + + this.signature = (0, _pvutils.getParametersValue)(parameters, "signature", AttributeCertificateInfoV1.defaultValues("signature")); + /** + * @type {Integer} + * @desc serialNumber + */ + + this.serialNumber = (0, _pvutils.getParametersValue)(parameters, "serialNumber", AttributeCertificateInfoV1.defaultValues("serialNumber")); + /** + * @type {AttCertValidityPeriod} + * @desc attrCertValidityPeriod + */ + + this.attrCertValidityPeriod = (0, _pvutils.getParametersValue)(parameters, "attrCertValidityPeriod", AttributeCertificateInfoV1.defaultValues("attrCertValidityPeriod")); + /** + * @type {Array.} + * @desc attributes + */ + + this.attributes = (0, _pvutils.getParametersValue)(parameters, "attributes", AttributeCertificateInfoV1.defaultValues("attributes")); + if ("issuerUniqueID" in parameters) + /** + * @type {BitString} + * @desc issuerUniqueID + */ + this.issuerUniqueID = (0, _pvutils.getParametersValue)(parameters, "issuerUniqueID", AttributeCertificateInfoV1.defaultValues("issuerUniqueID")); + if ("extensions" in parameters) + /** + * @type {Extensions} + * @desc extensions + */ + this.extensions = (0, _pvutils.getParametersValue)(parameters, "extensions", AttributeCertificateInfoV1.defaultValues("extensions")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 0; + + case "baseCertificateID": + return new IssuerSerial(); + + case "subjectName": + return new _GeneralNames.default(); + + case "issuer": + return {}; + + case "signature": + return new _AlgorithmIdentifier.default(); + + case "serialNumber": + return new asn1js.Integer(); + + case "attrCertValidityPeriod": + return new AttCertValidityPeriod(); + + case "attributes": + return []; + + case "issuerUniqueID": + return new asn1js.BitString(); + + case "extensions": + return new _Extensions.default(); + + default: + throw new Error(`Invalid member name for AttributeCertificateInfoV1 class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * AttributeCertificateInfo ::= SEQUENCE { + * version Version DEFAULT v1, + * subject CHOICE { + * baseCertificateID [0] IssuerSerial, -- associated with a Public Key Certificate + * subjectName [1] GeneralNames }, -- associated with a name + * issuer GeneralNames, -- CA issuing the attribute certificate + * signature AlgorithmIdentifier, + * serialNumber CertificateSerialNumber, + * attrCertValidityPeriod AttCertValidityPeriod, + * attributes SEQUENCE OF Attribute, + * issuerUniqueID UniqueIdentifier OPTIONAL, + * extensions Extensions OPTIONAL + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [issuer] + * @property {string} [serialNumber] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.version || "" + }), new asn1js.Choice({ + value: [new asn1js.Constructed({ + name: names.baseCertificateID || "", + idBlock: { + tagClass: 3, + tagNumber: 0 // [0] + + }, + value: IssuerSerial.schema().valueBlock.value + }), new asn1js.Constructed({ + name: names.subjectName || "", + idBlock: { + tagClass: 3, + tagNumber: 1 // [2] + + }, + value: _GeneralNames.default.schema().valueBlock.value + })] + }), _GeneralNames.default.schema({ + names: { + blockName: names.issuer || "" + } + }), _AlgorithmIdentifier.default.schema(names.signature || {}), new asn1js.Integer({ + name: names.serialNumber || "" + }), AttCertValidityPeriod.schema(names.attrCertValidityPeriod || {}), new asn1js.Sequence({ + name: names.attributes || "", + value: [new asn1js.Repeated({ + value: _Attribute.default.schema() + })] + }), new asn1js.BitString({ + optional: true, + name: names.issuerUniqueID || "" + }), _Extensions.default.schema(names.extensions || {}, true)] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["version", "baseCertificateID", "subjectName", "issuer", "signature", "serialNumber", "attrCertValidityPeriod", "attributes", "issuerUniqueID", "extensions"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, AttributeCertificateInfoV1.schema({ + names: { + version: "version", + baseCertificateID: "baseCertificateID", + subjectName: "subjectName", + issuer: "issuer", + signature: { + names: { + blockName: "signature" + } + }, + serialNumber: "serialNumber", + attrCertValidityPeriod: { + names: { + blockName: "attrCertValidityPeriod" + } + }, + attributes: "attributes", + issuerUniqueID: "issuerUniqueID", + extensions: { + names: { + blockName: "extensions" + } + } + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for AttributeCertificateInfoV1"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result.version.valueBlock.valueDec; + + if ("baseCertificateID" in asn1.result) { + this.baseCertificateID = new IssuerSerial({ + schema: new asn1js.Sequence({ + value: asn1.result.baseCertificateID.valueBlock.value + }) + }); + } + + if ("subjectName" in asn1.result) { + this.subjectName = new _GeneralNames.default({ + schema: new asn1js.Sequence({ + value: asn1.result.subjectName.valueBlock.value + }) + }); + } + + this.issuer = asn1.result.issuer; + this.signature = new _AlgorithmIdentifier.default({ + schema: asn1.result.signature + }); + this.serialNumber = asn1.result.serialNumber; + this.attrCertValidityPeriod = new AttCertValidityPeriod({ + schema: asn1.result.attrCertValidityPeriod + }); + this.attributes = Array.from(asn1.result.attributes.valueBlock.value, element => new _Attribute.default({ + schema: element + })); + if ("issuerUniqueID" in asn1.result) this.issuerUniqueID = asn1.result.issuerUniqueID; + if ("extensions" in asn1.result) this.extensions = new _Extensions.default({ + schema: asn1.result.extensions + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + const result = new asn1js.Sequence({ + value: [new asn1js.Integer({ + value: this.version + })] + }); + + if ("baseCertificateID" in this) { + result.valueBlock.value.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + tagNumber: 0 // [0] + + }, + value: this.baseCertificateID.toSchema().valueBlock.value + })); + } + + if ("subjectName" in this) { + result.valueBlock.value.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + tagNumber: 1 // [1] + + }, + value: this.subjectName.toSchema().valueBlock.value + })); + } + + result.valueBlock.value.push(this.issuer.toSchema()); + result.valueBlock.value.push(this.signature.toSchema()); + result.valueBlock.value.push(this.serialNumber); + result.valueBlock.value.push(this.attrCertValidityPeriod.toSchema()); + result.valueBlock.value.push(new asn1js.Sequence({ + value: Array.from(this.attributes, element => element.toSchema()) + })); + if ("issuerUniqueID" in this) result.valueBlock.value.push(this.issuerUniqueID); + if ("extensions" in this) result.valueBlock.value.push(this.extensions.toSchema()); + return result; + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const result = { + version: this.version + }; + if ("baseCertificateID" in this) result.baseCertificateID = this.baseCertificateID.toJSON(); + if ("subjectName" in this) result.subjectName = this.subjectName.toJSON(); + result.issuer = this.issuer.toJSON(); + result.signature = this.signature.toJSON(); + result.serialNumber = this.serialNumber.toJSON(); + result.attrCertValidityPeriod = this.attrCertValidityPeriod.toJSON(); + result.attributes = Array.from(this.attributes, element => element.toJSON()); + if ("issuerUniqueID" in this) result.issuerUniqueID = this.issuerUniqueID.toJSON(); + if ("extensions" in this) result.extensions = this.extensions.toJSON(); + return result; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * Class from X.509:1997 + */ + + +exports.AttributeCertificateInfoV1 = AttributeCertificateInfoV1; + +class AttributeCertificateV1 { + //********************************************************************************** + + /** + * Constructor for AttributeCertificateV1 class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {AttributeCertificateInfoV1} + * @desc acinfo + */ + this.acinfo = (0, _pvutils.getParametersValue)(parameters, "acinfo", AttributeCertificateV1.defaultValues("acinfo")); + /** + * @type {AlgorithmIdentifier} + * @desc signatureAlgorithm + */ + + this.signatureAlgorithm = (0, _pvutils.getParametersValue)(parameters, "signatureAlgorithm", AttributeCertificateV1.defaultValues("signatureAlgorithm")); + /** + * @type {BitString} + * @desc signatureValue + */ + + this.signatureValue = (0, _pvutils.getParametersValue)(parameters, "signatureValue", AttributeCertificateV1.defaultValues("signatureValue")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "acinfo": + return new AttributeCertificateInfoV1(); + + case "signatureAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "signatureValue": + return new asn1js.BitString(); + + default: + throw new Error(`Invalid member name for AttributeCertificateV1 class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * AttributeCertificate ::= SEQUENCE { + * acinfo AttributeCertificateInfoV1, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {Object} [acinfo] + * @property {Object} [signatureAlgorithm] + * @property {string} [signatureValue] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [AttributeCertificateInfoV1.schema(names.acinfo || {}), _AlgorithmIdentifier.default.schema(names.signatureAlgorithm || {}), new asn1js.BitString({ + name: names.signatureValue || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["acinfo", "signatureValue", "signatureAlgorithm"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, AttributeCertificateV1.schema({ + names: { + acinfo: { + names: { + blockName: "acinfo" + } + }, + signatureAlgorithm: { + names: { + blockName: "signatureAlgorithm" + } + }, + signatureValue: "signatureValue" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for AttributeCertificateV1"); //endregion + //region Get internal properties from parsed schema + + this.acinfo = new AttributeCertificateInfoV1({ + schema: asn1.result.acinfo + }); + this.signatureAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.signatureAlgorithm + }); + this.signatureValue = asn1.result.signatureValue; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + return new asn1js.Sequence({ + value: [this.acinfo.toSchema(), this.signatureAlgorithm.toSchema(), this.signatureValue] + }); + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + acinfo: this.acinfo.toJSON(), + signatureAlgorithm: this.signatureAlgorithm.toJSON(), + signatureValue: this.signatureValue.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = AttributeCertificateV1; + +},{"./AlgorithmIdentifier.js":4,"./Attribute.js":6,"./Extensions.js":39,"./GeneralNames.js":41,"asn1js":112,"pvutils":113}],8:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AttributeCertificateInfoV2 = exports.Holder = exports.V2Form = exports.ObjectDigestInfo = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _GeneralNames = _interopRequireDefault(require("./GeneralNames.js")); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _Attribute = _interopRequireDefault(require("./Attribute.js")); + +var _Extensions = _interopRequireDefault(require("./Extensions.js")); + +var _AttributeCertificateV = require("./AttributeCertificateV1.js"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5755 + */ +class ObjectDigestInfo { + //********************************************************************************** + + /** + * Constructor for ObjectDigestInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Enumerated} + * @desc digestedObjectType + */ + this.digestedObjectType = (0, _pvutils.getParametersValue)(parameters, "digestedObjectType", ObjectDigestInfo.defaultValues("digestedObjectType")); + if ("otherObjectTypeID" in parameters) + /** + * @type {ObjectIdentifier} + * @desc otherObjectTypeID + */ + this.otherObjectTypeID = (0, _pvutils.getParametersValue)(parameters, "otherObjectTypeID", ObjectDigestInfo.defaultValues("otherObjectTypeID")); + /** + * @type {AlgorithmIdentifier} + * @desc digestAlgorithm + */ + + this.digestAlgorithm = (0, _pvutils.getParametersValue)(parameters, "digestAlgorithm", ObjectDigestInfo.defaultValues("digestAlgorithm")); + /** + * @type {BitString} + * @desc objectDigest + */ + + this.objectDigest = (0, _pvutils.getParametersValue)(parameters, "objectDigest", ObjectDigestInfo.defaultValues("objectDigest")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "digestedObjectType": + return new asn1js.Enumerated(); + + case "otherObjectTypeID": + return new asn1js.ObjectIdentifier(); + + case "digestAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "objectDigest": + return new asn1js.BitString(); + + default: + throw new Error(`Invalid member name for ObjectDigestInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * ObjectDigestInfo ::= SEQUENCE { + * digestedObjectType ENUMERATED { + * publicKey (0), + * publicKeyCert (1), + * otherObjectTypes (2) }, + * -- otherObjectTypes MUST NOT + * -- be used in this profile + * otherObjectTypeID OBJECT IDENTIFIER OPTIONAL, + * digestAlgorithm AlgorithmIdentifier, + * objectDigest BIT STRING + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [digestedObjectType] + * @property {string} [otherObjectTypeID] + * @property {string} [digestAlgorithm] + * @property {string} [objectDigest] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Enumerated({ + name: names.digestedObjectType || "" + }), new asn1js.ObjectIdentifier({ + optional: true, + name: names.otherObjectTypeID || "" + }), _AlgorithmIdentifier.default.schema(names.digestAlgorithm || {}), new asn1js.BitString({ + name: names.objectDigest || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["digestedObjectType", "otherObjectTypeID", "digestAlgorithm", "objectDigest"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, ObjectDigestInfo.schema({ + names: { + digestedObjectType: "digestedObjectType", + otherObjectTypeID: "otherObjectTypeID", + digestAlgorithm: { + names: { + blockName: "digestAlgorithm" + } + }, + objectDigest: "objectDigest" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for ObjectDigestInfo"); //endregion + //region Get internal properties from parsed schema + + this.digestedObjectType = asn1.result.digestedObjectType; + if ("otherObjectTypeID" in asn1.result) this.otherObjectTypeID = asn1.result.otherObjectTypeID; + this.digestAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.digestAlgorithm + }); + this.objectDigest = asn1.result.objectDigest; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + const result = new asn1js.Sequence({ + value: [this.digestedObjectType] + }); + if ("otherObjectTypeID" in this) result.value.push(this.otherObjectTypeID); + result.value.push(this.digestAlgorithm.toSchema()); + result.value.push(this.objectDigest); + return result; + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const result = { + digestedObjectType: this.digestedObjectType.toJSON() + }; + if ("otherObjectTypeID" in this) result.otherObjectTypeID = this.otherObjectTypeID.toJSON(); + result.digestAlgorithm = this.digestAlgorithm.toJSON(); + result.objectDigest = this.objectDigest.toJSON(); + return result; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * Class from RFC5755 + */ + + +exports.ObjectDigestInfo = ObjectDigestInfo; + +class V2Form { + //********************************************************************************** + + /** + * Constructor for V2Form class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + if ("issuerName" in parameters) + /** + * @type {GeneralNames} + * @desc issuerName + */ + this.issuerName = (0, _pvutils.getParametersValue)(parameters, "issuerName", V2Form.defaultValues("issuerName")); + if ("baseCertificateID" in parameters) + /** + * @type {IssuerSerial} + * @desc baseCertificateID + */ + this.baseCertificateID = (0, _pvutils.getParametersValue)(parameters, "baseCertificateID", V2Form.defaultValues("baseCertificateID")); + if ("objectDigestInfo" in parameters) + /** + * @type {ObjectDigestInfo} + * @desc objectDigestInfo + */ + this.objectDigestInfo = (0, _pvutils.getParametersValue)(parameters, "objectDigestInfo", V2Form.defaultValues("objectDigestInfo")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "issuerName": + return new _GeneralNames.default(); + + case "baseCertificateID": + return new _AttributeCertificateV.IssuerSerial(); + + case "objectDigestInfo": + return new ObjectDigestInfo(); + + default: + throw new Error(`Invalid member name for V2Form class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * V2Form ::= SEQUENCE { + * issuerName GeneralNames OPTIONAL, + * baseCertificateID [0] IssuerSerial OPTIONAL, + * objectDigestInfo [1] ObjectDigestInfo OPTIONAL + * -- issuerName MUST be present in this profile + * -- baseCertificateID and objectDigestInfo MUST NOT + * -- be present in this profile + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [issuerName] + * @property {string} [baseCertificateID] + * @property {string} [objectDigestInfo] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_GeneralNames.default.schema({ + names: { + blockName: names.issuerName + } + }, true), new asn1js.Constructed({ + optional: true, + name: names.baseCertificateID || "", + idBlock: { + tagClass: 3, + tagNumber: 0 // [0] + + }, + value: _AttributeCertificateV.IssuerSerial.schema().valueBlock.value + }), new asn1js.Constructed({ + optional: true, + name: names.objectDigestInfo || "", + idBlock: { + tagClass: 3, + tagNumber: 1 // [1] + + }, + value: ObjectDigestInfo.schema().valueBlock.value + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["issuerName", "baseCertificateID", "objectDigestInfo"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, V2Form.schema({ + names: { + issuerName: "issuerName", + baseCertificateID: "baseCertificateID", + objectDigestInfo: "objectDigestInfo" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for V2Form"); //endregion + //region Get internal properties from parsed schema + + if ("issuerName" in asn1.result) this.issuerName = new _GeneralNames.default({ + schema: asn1.result.issuerName + }); + + if ("baseCertificateID" in asn1.result) { + this.baseCertificateID = new _AttributeCertificateV.IssuerSerial({ + schema: new asn1js.Sequence({ + value: asn1.result.baseCertificateID.valueBlock.value + }) + }); + } + + if ("objectDigestInfo" in asn1.result) { + this.objectDigestInfo = new ObjectDigestInfo({ + schema: new asn1js.Sequence({ + value: asn1.result.objectDigestInfo.valueBlock.value + }) + }); + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + const result = new asn1js.Sequence(); + if ("issuerName" in this) result.valueBlock.value.push(this.issuerName.toSchema()); + + if ("baseCertificateID" in this) { + result.valueBlock.value.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + tagNumber: 0 // [0] + + }, + value: this.baseCertificateID.toSchema().valueBlock.value + })); + } + + if ("objectDigestInfo" in this) { + result.valueBlock.value.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + tagNumber: 1 // [1] + + }, + value: this.objectDigestInfo.toSchema().valueBlock.value + })); + } //region Construct and return new ASN.1 schema for this object + + + return result; //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const result = {}; + if ("issuerName" in this) result.issuerName = this.issuerName.toJSON(); + if ("baseCertificateID" in this) result.baseCertificateID = this.baseCertificateID.toJSON(); + if ("objectDigestInfo" in this) result.objectDigestInfo = this.objectDigestInfo.toJSON(); + return result; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * Class from RFC5755 + */ + + +exports.V2Form = V2Form; + +class Holder { + //********************************************************************************** + + /** + * Constructor for Holder class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + if ("baseCertificateID" in parameters) + /** + * @type {IssuerSerial} + * @desc baseCertificateID + */ + this.baseCertificateID = (0, _pvutils.getParametersValue)(parameters, "baseCertificateID", Holder.defaultValues("baseCertificateID")); + if ("entityName" in parameters) + /** + * @type {GeneralNames} + * @desc entityName + */ + this.entityName = (0, _pvutils.getParametersValue)(parameters, "entityName", Holder.defaultValues("entityName")); + if ("objectDigestInfo" in parameters) + /** + * @type {ObjectDigestInfo} + * @desc objectDigestInfo + */ + this.objectDigestInfo = (0, _pvutils.getParametersValue)(parameters, "objectDigestInfo", Holder.defaultValues("objectDigestInfo")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "baseCertificateID": + return new _AttributeCertificateV.IssuerSerial(); + + case "entityName": + return new _GeneralNames.default(); + + case "objectDigestInfo": + return new ObjectDigestInfo(); + + default: + throw new Error(`Invalid member name for Holder class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * Holder ::= SEQUENCE { + * baseCertificateID [0] IssuerSerial OPTIONAL, + * -- the issuer and serial number of + * -- the holder's Public Key Certificate + * entityName [1] GeneralNames OPTIONAL, + * -- the name of the claimant or role + * objectDigestInfo [2] ObjectDigestInfo OPTIONAL + * -- used to directly authenticate the holder, + * -- for example, an executable + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [baseCertificateID] + * @property {string} [entityName] + * @property {string} [objectDigestInfo] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Constructed({ + optional: true, + name: names.baseCertificateID || "", + idBlock: { + tagClass: 3, + tagNumber: 0 // [0] + + }, + value: _AttributeCertificateV.IssuerSerial.schema().valueBlock.value + }), new asn1js.Constructed({ + optional: true, + name: names.entityName || "", + idBlock: { + tagClass: 3, + tagNumber: 1 // [2] + + }, + value: _GeneralNames.default.schema().valueBlock.value + }), new asn1js.Constructed({ + optional: true, + name: names.objectDigestInfo || "", + idBlock: { + tagClass: 3, + tagNumber: 2 // [2] + + }, + value: ObjectDigestInfo.schema().valueBlock.value + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["baseCertificateID", "entityName", "objectDigestInfo"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, Holder.schema({ + names: { + baseCertificateID: "baseCertificateID", + entityName: "entityName", + objectDigestInfo: "objectDigestInfo" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for Holder"); //endregion + //region Get internal properties from parsed schema + + if ("baseCertificateID" in asn1.result) { + this.baseCertificateID = new _AttributeCertificateV.IssuerSerial({ + schema: new asn1js.Sequence({ + value: asn1.result.baseCertificateID.valueBlock.value + }) + }); + } + + if ("entityName" in asn1.result) { + this.entityName = new _GeneralNames.default({ + schema: new asn1js.Sequence({ + value: asn1.result.entityName.valueBlock.value + }) + }); + } + + if ("objectDigestInfo" in asn1.result) { + this.objectDigestInfo = new ObjectDigestInfo({ + schema: new asn1js.Sequence({ + value: asn1.result.objectDigestInfo.valueBlock.value + }) + }); + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + const result = new asn1js.Sequence(); + + if ("baseCertificateID" in this) { + result.valueBlock.value.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + tagNumber: 0 // [0] + + }, + value: this.baseCertificateID.toSchema().valueBlock.value + })); + } + + if ("entityName" in this) { + result.valueBlock.value.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + tagNumber: 1 // [1] + + }, + value: this.entityName.toSchema().valueBlock.value + })); + } + + if ("objectDigestInfo" in this) { + result.valueBlock.value.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + tagNumber: 2 // [2] + + }, + value: this.objectDigestInfo.toSchema().valueBlock.value + })); + } + + return result; + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const result = {}; + if ("baseCertificateID" in this) result.baseCertificateID = this.baseCertificateID.toJSON(); + if ("entityName" in this) result.entityName = this.entityName.toJSON(); + if ("objectDigestInfo" in this) result.objectDigestInfo = this.objectDigestInfo.toJSON(); + return result; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * Class from RFC5755 + */ + + +exports.Holder = Holder; + +class AttributeCertificateInfoV2 { + //********************************************************************************** + + /** + * Constructor for AttributeCertificateInfoV2 class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", AttributeCertificateInfoV2.defaultValues("version")); + /** + * @type {Holder} + * @desc holder + */ + + this.holder = (0, _pvutils.getParametersValue)(parameters, "holder", AttributeCertificateInfoV2.defaultValues("holder")); + /** + * @type {GeneralNames|V2Form} + * @desc issuer + */ + + this.issuer = (0, _pvutils.getParametersValue)(parameters, "issuer", AttributeCertificateInfoV2.defaultValues("issuer")); + /** + * @type {AlgorithmIdentifier} + * @desc signature + */ + + this.signature = (0, _pvutils.getParametersValue)(parameters, "signature", AttributeCertificateInfoV2.defaultValues("signature")); + /** + * @type {Integer} + * @desc serialNumber + */ + + this.serialNumber = (0, _pvutils.getParametersValue)(parameters, "serialNumber", AttributeCertificateInfoV2.defaultValues("serialNumber")); + /** + * @type {AttCertValidityPeriod} + * @desc attrCertValidityPeriod + */ + + this.attrCertValidityPeriod = (0, _pvutils.getParametersValue)(parameters, "attrCertValidityPeriod", AttributeCertificateInfoV2.defaultValues("attrCertValidityPeriod")); + /** + * @type {Array.} + * @desc attributes + */ + + this.attributes = (0, _pvutils.getParametersValue)(parameters, "attributes", AttributeCertificateInfoV2.defaultValues("attributes")); + if ("issuerUniqueID" in parameters) + /** + * @type {BitString} + * @desc issuerUniqueID + */ + this.issuerUniqueID = (0, _pvutils.getParametersValue)(parameters, "issuerUniqueID", AttributeCertificateInfoV2.defaultValues("issuerUniqueID")); + if ("extensions" in parameters) + /** + * @type {Extensions} + * @desc extensions + */ + this.extensions = (0, _pvutils.getParametersValue)(parameters, "extensions", AttributeCertificateInfoV2.defaultValues("extensions")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 1; + + case "holder": + return new Holder(); + + case "issuer": + return {}; + + case "signature": + return new _AlgorithmIdentifier.default(); + + case "serialNumber": + return new asn1js.Integer(); + + case "attrCertValidityPeriod": + return new _AttributeCertificateV.AttCertValidityPeriod(); + + case "attributes": + return []; + + case "issuerUniqueID": + return new asn1js.BitString(); + + case "extensions": + return new _Extensions.default(); + + default: + throw new Error(`Invalid member name for AttributeCertificateInfoV2 class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * AttributeCertificateInfoV2 ::= SEQUENCE { + * version AttCertVersion, -- version is v2 + * holder Holder, + * issuer AttCertIssuer, + * signature AlgorithmIdentifier, + * serialNumber CertificateSerialNumber, + * attrCertValidityPeriod AttCertValidityPeriod, + * attributes SEQUENCE OF Attribute, + * issuerUniqueID UniqueIdentifier OPTIONAL, + * extensions Extensions OPTIONAL + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [issuer] + * @property {string} [serialNumber] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.version || "" + }), Holder.schema(names.holder || {}), new asn1js.Choice({ + value: [_GeneralNames.default.schema({ + names: { + blockName: names.issuer || "" + } + }), new asn1js.Constructed({ + name: names.issuer || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: V2Form.schema().valueBlock.value + })] + }), _AlgorithmIdentifier.default.schema(names.signature || {}), new asn1js.Integer({ + name: names.serialNumber || "" + }), _AttributeCertificateV.AttCertValidityPeriod.schema(names.attrCertValidityPeriod || {}), new asn1js.Sequence({ + name: names.attributes || "", + value: [new asn1js.Repeated({ + value: _Attribute.default.schema() + })] + }), new asn1js.BitString({ + optional: true, + name: names.issuerUniqueID || "" + }), _Extensions.default.schema(names.extensions || {}, true)] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["version", "holder", "issuer", "signature", "serialNumber", "attrCertValidityPeriod", "attributes", "issuerUniqueID", "extensions"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, AttributeCertificateInfoV2.schema({ + names: { + version: "version", + holder: { + names: { + blockName: "holder" + } + }, + issuer: "issuer", + signature: { + names: { + blockName: "signature" + } + }, + serialNumber: "serialNumber", + attrCertValidityPeriod: { + names: { + blockName: "attrCertValidityPeriod" + } + }, + attributes: "attributes", + issuerUniqueID: "issuerUniqueID", + extensions: { + names: { + blockName: "extensions" + } + } + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for AttributeCertificateInfoV2"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result.version.valueBlock.valueDec; + this.holder = new Holder({ + schema: asn1.result.holder + }); + + switch (asn1.result.issuer.idBlock.tagClass) { + case 3: + // V2Form + this.issuer = new V2Form({ + schema: new asn1js.Sequence({ + value: asn1.result.issuer.valueBlock.value + }) + }); + break; + + case 1: // GeneralNames (should not be used) + + default: + throw new Error("Incorect value for 'issuer' in AttributeCertificateInfoV2"); + } + + this.signature = new _AlgorithmIdentifier.default({ + schema: asn1.result.signature + }); + this.serialNumber = asn1.result.serialNumber; + this.attrCertValidityPeriod = new _AttributeCertificateV.AttCertValidityPeriod({ + schema: asn1.result.attrCertValidityPeriod + }); + this.attributes = Array.from(asn1.result.attributes.valueBlock.value, element => new _Attribute.default({ + schema: element + })); + if ("issuerUniqueID" in asn1.result) this.issuerUniqueID = asn1.result.issuerUniqueID; + if ("extensions" in asn1.result) this.extensions = new _Extensions.default({ + schema: asn1.result.extensions + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + const result = new asn1js.Sequence({ + value: [new asn1js.Integer({ + value: this.version + }), this.holder.toSchema(), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: this.issuer.toSchema().valueBlock.value + }), this.signature.toSchema(), this.serialNumber, this.attrCertValidityPeriod.toSchema(), new asn1js.Sequence({ + value: Array.from(this.attributes, element => element.toSchema()) + })] + }); + if ("issuerUniqueID" in this) result.valueBlock.value.push(this.issuerUniqueID); + if ("extensions" in this) result.valueBlock.value.push(this.extensions.toSchema()); + return result; + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const result = { + version: this.version, + holder: this.holder.toJSON(), + issuer: this.issuer.toJSON(), + signature: this.signature.toJSON(), + serialNumber: this.serialNumber.toJSON(), + attrCertValidityPeriod: this.attrCertValidityPeriod.toJSON(), + attributes: Array.from(this.attributes, element => element.toJSON()) + }; + if ("issuerUniqueID" in this) result.issuerUniqueID = this.issuerUniqueID.toJSON(); + if ("extensions" in this) result.extensions = this.extensions.toJSON(); + return result; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * Class from RFC5755 + */ + + +exports.AttributeCertificateInfoV2 = AttributeCertificateInfoV2; + +class AttributeCertificateV2 { + //********************************************************************************** + + /** + * Constructor for AttributeCertificateV2 class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {AttributeCertificateInfoV2} + * @desc acinfo + */ + this.acinfo = (0, _pvutils.getParametersValue)(parameters, "acinfo", AttributeCertificateV2.defaultValues("acinfo")); + /** + * @type {AlgorithmIdentifier} + * @desc signatureAlgorithm + */ + + this.signatureAlgorithm = (0, _pvutils.getParametersValue)(parameters, "signatureAlgorithm", AttributeCertificateV2.defaultValues("signatureAlgorithm")); + /** + * @type {BitString} + * @desc signatureValue + */ + + this.signatureValue = (0, _pvutils.getParametersValue)(parameters, "signatureValue", AttributeCertificateV2.defaultValues("signatureValue")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "acinfo": + return new AttributeCertificateInfoV2(); + + case "signatureAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "signatureValue": + return new asn1js.BitString(); + + default: + throw new Error(`Invalid member name for AttributeCertificateV2 class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * AttributeCertificate ::= SEQUENCE { + * acinfo AttributeCertificateInfoV2, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {Object} [acinfo] + * @property {Object} [signatureAlgorithm] + * @property {string} [signatureValue] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [AttributeCertificateInfoV2.schema(names.acinfo || {}), _AlgorithmIdentifier.default.schema(names.signatureAlgorithm || {}), new asn1js.BitString({ + name: names.signatureValue || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["acinfo", "signatureAlgorithm", "signatureValue"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, AttributeCertificateV2.schema({ + names: { + acinfo: { + names: { + blockName: "acinfo" + } + }, + signatureAlgorithm: { + names: { + blockName: "signatureAlgorithm" + } + }, + signatureValue: "signatureValue" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for AttributeCertificateV2"); //endregion + //region Get internal properties from parsed schema + + this.acinfo = new AttributeCertificateInfoV2({ + schema: asn1.result.acinfo + }); + this.signatureAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.signatureAlgorithm + }); + this.signatureValue = asn1.result.signatureValue; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + return new asn1js.Sequence({ + value: [this.acinfo.toSchema(), this.signatureAlgorithm.toSchema(), this.signatureValue] + }); + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + acinfo: this.acinfo.toJSON(), + signatureAlgorithm: this.signatureAlgorithm.toJSON(), + signatureValue: this.signatureValue.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = AttributeCertificateV2; + +},{"./AlgorithmIdentifier.js":4,"./Attribute.js":6,"./AttributeCertificateV1.js":7,"./Extensions.js":39,"./GeneralNames.js":41,"asn1js":112,"pvutils":113}],9:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _common = require("./common.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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class AttributeTypeAndValue { + //********************************************************************************** + + /** + * Constructor for AttributeTypeAndValue class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc type + */ + this.type = (0, _pvutils.getParametersValue)(parameters, "type", AttributeTypeAndValue.defaultValues("type")); + /** + * @type {Object} + * @desc Value of the AttributeTypeAndValue class + */ + + this.value = (0, _pvutils.getParametersValue)(parameters, "value", AttributeTypeAndValue.defaultValues("value")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "type": + return ""; + + case "value": + return {}; + + default: + throw new Error(`Invalid member name for AttributeTypeAndValue class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * AttributeTypeAndValue ::= Sequence { + * type AttributeType, + * value AttributeValue } + * + * AttributeType ::= OBJECT IDENTIFIER + * + * AttributeValue ::= ANY -- DEFINED BY AttributeType + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] Name for entire block + * @property {string} [type] Name for "type" element + * @property {string} [value] Name for "value" element + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.type || "" + }), new asn1js.Any({ + name: names.value || "" + })] + }); + } //********************************************************************************** + + + static blockName() { + return "AttributeTypeAndValue"; + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["type", "typeValue"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, AttributeTypeAndValue.schema({ + names: { + type: "type", + value: "typeValue" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for AttributeTypeAndValue"); //endregion + //region Get internal properties from parsed schema + + this.type = asn1.result.type.valueBlock.toString(); // noinspection JSUnresolvedVariable + + this.value = asn1.result.typeValue; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [new asn1js.ObjectIdentifier({ + value: this.type + }), this.value] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + type: this.type + }; + if (Object.keys(this.value).length !== 0) _object.value = this.value.toJSON();else _object.value = this.value; + return _object; + } //********************************************************************************** + + /** + * Compare two AttributeTypeAndValue values, or AttributeTypeAndValue with ArrayBuffer value + * @param {(AttributeTypeAndValue|ArrayBuffer)} compareTo The value compare to current + * @returns {boolean} + */ + + + isEqual(compareTo) { + const stringBlockNames = [asn1js.Utf8String.blockName(), asn1js.BmpString.blockName(), asn1js.UniversalString.blockName(), asn1js.NumericString.blockName(), asn1js.PrintableString.blockName(), asn1js.TeletexString.blockName(), asn1js.VideotexString.blockName(), asn1js.IA5String.blockName(), asn1js.GraphicString.blockName(), asn1js.VisibleString.blockName(), asn1js.GeneralString.blockName(), asn1js.CharacterString.blockName()]; + + if (compareTo.constructor.blockName() === AttributeTypeAndValue.blockName()) { + if (this.type !== compareTo.type) return false; //region Check we do have both strings + + let isString = false; + const thisName = this.value.constructor.blockName(); + + if (thisName === compareTo.value.constructor.blockName()) { + for (var _i = 0, _stringBlockNames = stringBlockNames; _i < _stringBlockNames.length; _i++) { + const name = _stringBlockNames[_i]; + + if (thisName === name) { + isString = true; + break; + } + } + } //endregion + + + if (isString) { + const value1 = (0, _common.stringPrep)(this.value.valueBlock.value); + const value2 = (0, _common.stringPrep)(compareTo.value.valueBlock.value); + if (value1.localeCompare(value2) !== 0) return false; + } else // Comparing as two ArrayBuffers + { + if ((0, _pvutils.isEqualBuffer)(this.value.valueBeforeDecode, compareTo.value.valueBeforeDecode) === false) return false; + } + + return true; + } + + if (compareTo instanceof ArrayBuffer) return (0, _pvutils.isEqualBuffer)(this.value.valueBeforeDecode, compareTo); + return false; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = AttributeTypeAndValue; + +},{"./common.js":110,"asn1js":112,"pvutils":113}],10:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _ContentInfo = _interopRequireDefault(require("./ContentInfo.js")); + +var _SafeContents = _interopRequireDefault(require("./SafeContents.js")); + +var _EnvelopedData = _interopRequireDefault(require("./EnvelopedData.js")); + +var _EncryptedData = _interopRequireDefault(require("./EncryptedData.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } + +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } + +function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } + +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } + +//************************************************************************************** + +/** + * Class from RFC7292 + */ +class AuthenticatedSafe { + //********************************************************************************** + + /** + * Constructor for AuthenticatedSafe class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc safeContents + */ + this.safeContents = (0, _pvutils.getParametersValue)(parameters, "safeContents", AuthenticatedSafe.defaultValues("safeContents")); + if ("parsedValue" in parameters) + /** + * @type {*} + * @desc parsedValue + */ + this.parsedValue = (0, _pvutils.getParametersValue)(parameters, "parsedValue", AuthenticatedSafe.defaultValues("parsedValue")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "safeContents": + return []; + + case "parsedValue": + return {}; + + default: + throw new Error(`Invalid member name for AuthenticatedSafe class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "safeContents": + return memberValue.length === 0; + + case "parsedValue": + return memberValue instanceof Object && Object.keys(memberValue).length === 0; + + default: + throw new Error(`Invalid member name for AuthenticatedSafe class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * AuthenticatedSafe ::= SEQUENCE OF ContentInfo + * -- Data if unencrypted + * -- EncryptedData if password-encrypted + * -- EnvelopedData if public key-encrypted + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [contentInfos] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.contentInfos || "", + value: _ContentInfo.default.schema() + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["contentInfos"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, AuthenticatedSafe.schema({ + names: { + contentInfos: "contentInfos" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for AuthenticatedSafe"); //endregion + //region Get internal properties from parsed schema + + this.safeContents = Array.from(asn1.result.contentInfos, element => new _ContentInfo.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: Array.from(this.safeContents, element => element.toSchema()) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + safeContents: Array.from(this.safeContents, element => element.toJSON()) + }; + } //********************************************************************************** + + + parseInternalValues(parameters) { + //region Check input data from "parameters" + if (parameters instanceof Object === false) return Promise.reject("The \"parameters\" must has \"Object\" type"); + if ("safeContents" in parameters === false) return Promise.reject("Absent mandatory parameter \"safeContents\""); + if (parameters.safeContents instanceof Array === false) return Promise.reject("The \"parameters.safeContents\" must has \"Array\" type"); + if (parameters.safeContents.length !== this.safeContents.length) return Promise.reject("Length of \"parameters.safeContents\" must be equal to \"this.safeContents.length\""); //endregion + //region Initial variables + + let sequence = Promise.resolve(); //endregion + //region Create value for "this.parsedValue.authenticatedSafe" + + this.parsedValue = { + safeContents: [] + }; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.safeContents.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + const _step$value = _slicedToArray(_step.value, 2), + index = _step$value[0], + content = _step$value[1]; + + switch (content.contentType) { + //region data + case "1.2.840.113549.1.7.1": + { + //region Check that we do have OCTETSTRING as "content" + if (content.content instanceof asn1js.OctetString === false) return Promise.reject("Wrong type of \"this.safeContents[j].content\""); //endregion + //region Check we have "constructive encoding" for AuthSafe content + + let authSafeContent = new ArrayBuffer(0); + + if (content.content.valueBlock.isConstructed) { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = content.content.valueBlock.value[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + const contentValue = _step2.value; + authSafeContent = (0, _pvutils.utilConcatBuf)(authSafeContent, contentValue.valueBlock.valueHex); + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return != null) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + } else authSafeContent = content.content.valueBlock.valueHex; //endregion + //region Parse internal ASN.1 data + + + const asn1 = asn1js.fromBER(authSafeContent); + if (asn1.offset === -1) return Promise.reject("Error during parsing of ASN.1 data inside \"content.content\""); //endregion + //region Finilly initialize initial values of "SafeContents" type + + this.parsedValue.safeContents.push({ + privacyMode: 0, + // No privacy, clear data + value: new _SafeContents.default({ + schema: asn1.result + }) + }); //endregion + } + break; + //endregion + //region envelopedData + + case "1.2.840.113549.1.7.3": + { + //region Initial variables + const cmsEnveloped = new _EnvelopedData.default({ + schema: content.content + }); //endregion + //region Check mandatory parameters + + if ("recipientCertificate" in parameters.safeContents[index] === false) return Promise.reject("Absent mandatory parameter \"recipientCertificate\" in \"parameters.safeContents[j]\""); + const recipientCertificate = parameters.safeContents[index].recipientCertificate; + if ("recipientKey" in parameters.safeContents[index] === false) return Promise.reject("Absent mandatory parameter \"recipientKey\" in \"parameters.safeContents[j]\""); // noinspection JSUnresolvedVariable + + const recipientKey = parameters.safeContents[index].recipientKey; //endregion + //region Decrypt CMS EnvelopedData using first recipient information + + sequence = sequence.then(() => cmsEnveloped.decrypt(0, { + recipientCertificate, + recipientPrivateKey: recipientKey + })); + sequence = sequence.then( + /** + * @param {ArrayBuffer} result + */ + result => { + const asn1 = asn1js.fromBER(result); + if (asn1.offset === -1) return Promise.reject("Error during parsing of decrypted data"); + this.parsedValue.safeContents.push({ + privacyMode: 2, + // Public-key privacy mode + value: new _SafeContents.default({ + schema: asn1.result + }) + }); + return Promise.resolve(); + }); //endregion + } + break; + //endregion + //region encryptedData + + case "1.2.840.113549.1.7.6": + { + //region Initial variables + const cmsEncrypted = new _EncryptedData.default({ + schema: content.content + }); //endregion + //region Check mandatory parameters + + if ("password" in parameters.safeContents[index] === false) return Promise.reject("Absent mandatory parameter \"password\" in \"parameters.safeContents[j]\""); + const password = parameters.safeContents[index].password; //endregion + //region Decrypt CMS EncryptedData using password + + sequence = sequence.then(() => cmsEncrypted.decrypt({ + password + }), error => Promise.reject(error)); //endregion + //region Initialize internal data + + sequence = sequence.then( + /** + * @param {ArrayBuffer} result + */ + result => { + const asn1 = asn1js.fromBER(result); + if (asn1.offset === -1) return Promise.reject("Error during parsing of decrypted data"); + this.parsedValue.safeContents.push({ + privacyMode: 1, + // Password-based privacy mode + value: new _SafeContents.default({ + schema: asn1.result + }) + }); + return Promise.resolve(); + }, error => Promise.reject(error)); //endregion + } + break; + //endregion + //region default + + default: + throw new Error(`Unknown "contentType" for AuthenticatedSafe: " ${content.contentType}`); + //endregion + } + } //endregion + + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return sequence; + } //********************************************************************************** + + + makeInternalValues(parameters) { + //region Check data in "parsedValue" + if ("parsedValue" in this === false) return Promise.reject("Please run \"parseValues\" first or add \"parsedValue\" manually"); + if (this.parsedValue instanceof Object === false) return Promise.reject("The \"this.parsedValue\" must has \"Object\" type"); + if (this.parsedValue.safeContents instanceof Array === false) return Promise.reject("The \"this.parsedValue.safeContents\" must has \"Array\" type"); //endregion + //region Check input data from "parameters" + + if (parameters instanceof Object === false) return Promise.reject("The \"parameters\" must has \"Object\" type"); + if ("safeContents" in parameters === false) return Promise.reject("Absent mandatory parameter \"safeContents\""); + if (parameters.safeContents instanceof Array === false) return Promise.reject("The \"parameters.safeContents\" must has \"Array\" type"); + if (parameters.safeContents.length !== this.parsedValue.safeContents.length) return Promise.reject("Length of \"parameters.safeContents\" must be equal to \"this.parsedValue.safeContents\""); //endregion + //region Initial variables + + let sequence = Promise.resolve(); //endregion + //region Create internal values from already parsed values + + this.safeContents = []; + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.parsedValue.safeContents.entries()[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + const _step3$value = _slicedToArray(_step3.value, 2), + index = _step3$value[0], + content = _step3$value[1]; + + //region Check current "content" value + if ("privacyMode" in content === false) return Promise.reject("The \"privacyMode\" is a mandatory parameter for \"content\""); + if ("value" in content === false) return Promise.reject("The \"value\" is a mandatory parameter for \"content\""); + if (content.value instanceof _SafeContents.default === false) return Promise.reject("The \"content.value\" must has \"SafeContents\" type"); //endregion + + switch (content.privacyMode) { + //region No privacy + case 0: + { + const contentBuffer = content.value.toSchema().toBER(false); + sequence = sequence.then(() => { + this.safeContents.push(new _ContentInfo.default({ + contentType: "1.2.840.113549.1.7.1", + content: new asn1js.OctetString({ + valueHex: contentBuffer + }) + })); + }); + } + break; + //endregion + //region Privacy with password + + case 1: + { + //region Initial variables + const cmsEncrypted = new _EncryptedData.default(); + const currentParameters = parameters.safeContents[index]; + currentParameters.contentToEncrypt = content.value.toSchema().toBER(false); //endregion + //region Encrypt CMS EncryptedData using password + + sequence = sequence.then(() => cmsEncrypted.encrypt(currentParameters), error => Promise.reject(error)); //endregion + //region Store result content in CMS_CONTENT_INFO type + + sequence = sequence.then(() => { + this.safeContents.push(new _ContentInfo.default({ + contentType: "1.2.840.113549.1.7.6", + content: cmsEncrypted.toSchema() + })); + }, error => Promise.reject(error)); //endregion + } + break; + //endregion + //region Privacy with public key + + case 2: + { + //region Initial variables + const cmsEnveloped = new _EnvelopedData.default(); + const contentToEncrypt = content.value.toSchema().toBER(false); //endregion + //region Check mandatory parameters + + if ("encryptingCertificate" in parameters.safeContents[index] === false) return Promise.reject("Absent mandatory parameter \"encryptingCertificate\" in \"parameters.safeContents[i]\""); + if ("encryptionAlgorithm" in parameters.safeContents[index] === false) return Promise.reject("Absent mandatory parameter \"encryptionAlgorithm\" in \"parameters.safeContents[i]\""); + + switch (true) { + case parameters.safeContents[index].encryptionAlgorithm.name.toLowerCase() === "aes-cbc": + case parameters.safeContents[index].encryptionAlgorithm.name.toLowerCase() === "aes-gcm": + break; + + default: + return Promise.reject(`Incorrect parameter "encryptionAlgorithm" in "parameters.safeContents[i]": ${parameters.safeContents[index].encryptionAlgorithm}`); + } + + switch (true) { + case parameters.safeContents[index].encryptionAlgorithm.length === 128: + case parameters.safeContents[index].encryptionAlgorithm.length === 192: + case parameters.safeContents[index].encryptionAlgorithm.length === 256: + break; + + default: + return Promise.reject(`Incorrect parameter "encryptionAlgorithm.length" in "parameters.safeContents[i]": ${parameters.safeContents[index].encryptionAlgorithm.length}`); + } //endregion + //region Making correct "encryptionAlgorithm" variable + + + const encryptionAlgorithm = parameters.safeContents[index].encryptionAlgorithm; //endregion + //region Append recipient for enveloped data + + cmsEnveloped.addRecipientByCertificate(parameters.safeContents[index].encryptingCertificate); //endregion + //region Making encryption + + sequence = sequence.then(() => cmsEnveloped.encrypt(encryptionAlgorithm, contentToEncrypt)); + sequence = sequence.then(() => { + this.safeContents.push(new _ContentInfo.default({ + contentType: "1.2.840.113549.1.7.3", + content: cmsEnveloped.toSchema() + })); + }); //endregion + } + break; + //endregion + //region default + + default: + return Promise.reject(`Incorrect value for "content.privacyMode": ${content.privacyMode}`); + //endregion + } + } //endregion + //region Return result of the function + + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3.return != null) { + _iterator3.return(); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return sequence.then(() => this, error => Promise.reject(`Error during parsing: ${error}`)); //endregion + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = AuthenticatedSafe; + +},{"./ContentInfo.js":26,"./EncryptedData.js":35,"./EnvelopedData.js":36,"./SafeContents.js":96,"asn1js":112,"pvutils":113}],11:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _GeneralName = _interopRequireDefault(require("./GeneralName.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class AuthorityKeyIdentifier { + //********************************************************************************** + + /** + * Constructor for AuthorityKeyIdentifier class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + if ("keyIdentifier" in parameters) + /** + * @type {OctetString} + * @desc keyIdentifier + */ + this.keyIdentifier = (0, _pvutils.getParametersValue)(parameters, "keyIdentifier", AuthorityKeyIdentifier.defaultValues("keyIdentifier")); + if ("authorityCertIssuer" in parameters) + /** + * @type {Array.} + * @desc authorityCertIssuer + */ + this.authorityCertIssuer = (0, _pvutils.getParametersValue)(parameters, "authorityCertIssuer", AuthorityKeyIdentifier.defaultValues("authorityCertIssuer")); + if ("authorityCertSerialNumber" in parameters) + /** + * @type {Integer} + * @desc authorityCertIssuer + */ + this.authorityCertSerialNumber = (0, _pvutils.getParametersValue)(parameters, "authorityCertSerialNumber", AuthorityKeyIdentifier.defaultValues("authorityCertSerialNumber")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "keyIdentifier": + return new asn1js.OctetString(); + + case "authorityCertIssuer": + return []; + + case "authorityCertSerialNumber": + return new asn1js.Integer(); + + default: + throw new Error(`Invalid member name for AuthorityKeyIdentifier class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * AuthorityKeyIdentifier OID ::= 2.5.29.35 + * + * AuthorityKeyIdentifier ::= SEQUENCE { + * keyIdentifier [0] KeyIdentifier OPTIONAL, + * authorityCertIssuer [1] GeneralNames OPTIONAL, + * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } + * + * KeyIdentifier ::= OCTET STRING + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [keyIdentifier] + * @property {string} [authorityCertIssuer] + * @property {string} [authorityCertSerialNumber] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Primitive({ + name: names.keyIdentifier || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + } + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [new asn1js.Repeated({ + name: names.authorityCertIssuer || "", + value: _GeneralName.default.schema() + })] + }), new asn1js.Primitive({ + name: names.authorityCertSerialNumber || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + } + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["keyIdentifier", "authorityCertIssuer", "authorityCertSerialNumber"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, AuthorityKeyIdentifier.schema({ + names: { + keyIdentifier: "keyIdentifier", + authorityCertIssuer: "authorityCertIssuer", + authorityCertSerialNumber: "authorityCertSerialNumber" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for AuthorityKeyIdentifier"); //endregion + //region Get internal properties from parsed schema + + if ("keyIdentifier" in asn1.result) this.keyIdentifier = new asn1js.OctetString({ + valueHex: asn1.result.keyIdentifier.valueBlock.valueHex + }); + if ("authorityCertIssuer" in asn1.result) this.authorityCertIssuer = Array.from(asn1.result.authorityCertIssuer, element => new _GeneralName.default({ + schema: element + })); + if ("authorityCertSerialNumber" in asn1.result) this.authorityCertSerialNumber = new asn1js.Integer({ + valueHex: asn1.result.authorityCertSerialNumber.valueBlock.valueHex + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + + if ("keyIdentifier" in this) { + outputArray.push(new asn1js.Primitive({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + valueHex: this.keyIdentifier.valueBlock.valueHex + })); + } + + if ("authorityCertIssuer" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: Array.from(this.authorityCertIssuer, element => element.toSchema()) + })); + } + + if ("authorityCertSerialNumber" in this) { + outputArray.push(new asn1js.Primitive({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + valueHex: this.authorityCertSerialNumber.valueBlock.valueHex + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = {}; + if ("keyIdentifier" in this) object.keyIdentifier = this.keyIdentifier.toJSON(); + if ("authorityCertIssuer" in this) object.authorityCertIssuer = Array.from(this.authorityCertIssuer, element => element.toJSON()); + if ("authorityCertSerialNumber" in this) object.authorityCertSerialNumber = this.authorityCertSerialNumber.toJSON(); + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = AuthorityKeyIdentifier; + +},{"./GeneralName.js":40,"asn1js":112,"pvutils":113}],12:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class BasicConstraints { + //********************************************************************************** + + /** + * Constructor for BasicConstraints class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + * @property {Object} [cA] + * @property {Object} [pathLenConstraint] + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {boolean} + * @desc cA + */ + this.cA = (0, _pvutils.getParametersValue)(parameters, "cA", false); + if ("pathLenConstraint" in parameters) + /** + * @type {number|Integer} + * @desc pathLenConstraint + */ + this.pathLenConstraint = (0, _pvutils.getParametersValue)(parameters, "pathLenConstraint", 0); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "cA": + return false; + + default: + throw new Error(`Invalid member name for BasicConstraints class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * BasicConstraints ::= SEQUENCE { + * cA BOOLEAN DEFAULT FALSE, + * pathLenConstraint INTEGER (0..MAX) OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [cA] + * @property {string} [pathLenConstraint] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Boolean({ + optional: true, + name: names.cA || "" + }), new asn1js.Integer({ + optional: true, + name: names.pathLenConstraint || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["cA", "pathLenConstraint"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, BasicConstraints.schema({ + names: { + cA: "cA", + pathLenConstraint: "pathLenConstraint" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for BasicConstraints"); //endregion + //region Get internal properties from parsed schema + + if ("cA" in asn1.result) this.cA = asn1.result.cA.valueBlock.value; + + if ("pathLenConstraint" in asn1.result) { + if (asn1.result.pathLenConstraint.valueBlock.isHexOnly) this.pathLenConstraint = asn1.result.pathLenConstraint;else this.pathLenConstraint = asn1.result.pathLenConstraint.valueBlock.valueDec; + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + if (this.cA !== BasicConstraints.defaultValues("cA")) outputArray.push(new asn1js.Boolean({ + value: this.cA + })); + + if ("pathLenConstraint" in this) { + if (this.pathLenConstraint instanceof asn1js.Integer) outputArray.push(this.pathLenConstraint);else outputArray.push(new asn1js.Integer({ + value: this.pathLenConstraint + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = {}; + if (this.cA !== BasicConstraints.defaultValues("cA")) object.cA = this.cA; + + if ("pathLenConstraint" in this) { + if (this.pathLenConstraint instanceof asn1js.Integer) object.pathLenConstraint = this.pathLenConstraint.toJSON();else object.pathLenConstraint = this.pathLenConstraint; + } + + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = BasicConstraints; + +},{"asn1js":112,"pvutils":113}],13:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _common = require("./common.js"); + +var _ResponseData = _interopRequireDefault(require("./ResponseData.js")); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _Certificate = _interopRequireDefault(require("./Certificate.js")); + +var _CertID = _interopRequireDefault(require("./CertID.js")); + +var _RelativeDistinguishedNames = _interopRequireDefault(require("./RelativeDistinguishedNames.js")); + +var _CertificateChainValidationEngine = _interopRequireDefault(require("./CertificateChainValidationEngine.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } + +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } + +function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } + +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } + +//************************************************************************************** + +/** + * Class from RFC6960 + */ +class BasicOCSPResponse { + //********************************************************************************** + + /** + * Constructor for BasicOCSPResponse class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {ResponseData} + * @desc tbsResponseData + */ + this.tbsResponseData = (0, _pvutils.getParametersValue)(parameters, "tbsResponseData", BasicOCSPResponse.defaultValues("tbsResponseData")); + /** + * @type {AlgorithmIdentifier} + * @desc signatureAlgorithm + */ + + this.signatureAlgorithm = (0, _pvutils.getParametersValue)(parameters, "signatureAlgorithm", BasicOCSPResponse.defaultValues("signatureAlgorithm")); + /** + * @type {BitString} + * @desc signature + */ + + this.signature = (0, _pvutils.getParametersValue)(parameters, "signature", BasicOCSPResponse.defaultValues("signature")); + if ("certs" in parameters) + /** + * @type {Array.} + * @desc certs + */ + this.certs = (0, _pvutils.getParametersValue)(parameters, "certs", BasicOCSPResponse.defaultValues("certs")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "tbsResponseData": + return new _ResponseData.default(); + + case "signatureAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "signature": + return new asn1js.BitString(); + + case "certs": + return []; + + default: + throw new Error(`Invalid member name for BasicOCSPResponse class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "type": + { + // noinspection OverlyComplexBooleanExpressionJS + let comparisonResult = _ResponseData.default.compareWithDefault("tbs", memberValue.tbs) && _ResponseData.default.compareWithDefault("responderID", memberValue.responderID) && _ResponseData.default.compareWithDefault("producedAt", memberValue.producedAt) && _ResponseData.default.compareWithDefault("responses", memberValue.responses); + + if ("responseExtensions" in memberValue) comparisonResult = comparisonResult && _ResponseData.default.compareWithDefault("responseExtensions", memberValue.responseExtensions); + return comparisonResult; + } + + case "signatureAlgorithm": + return memberValue.algorithmId === "" && "algorithmParams" in memberValue === false; + + case "signature": + return memberValue.isEqual(BasicOCSPResponse.defaultValues(memberName)); + + case "certs": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for BasicOCSPResponse class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * BasicOCSPResponse ::= SEQUENCE { + * tbsResponseData ResponseData, + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [tbsResponseData] + * @property {string} [signatureAlgorithm] + * @property {string} [signature] + * @property {string} [certs] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "BasicOCSPResponse", + value: [_ResponseData.default.schema(names.tbsResponseData || { + names: { + blockName: "BasicOCSPResponse.tbsResponseData" + } + }), _AlgorithmIdentifier.default.schema(names.signatureAlgorithm || { + names: { + blockName: "BasicOCSPResponse.signatureAlgorithm" + } + }), new asn1js.BitString({ + name: names.signature || "BasicOCSPResponse.signature" + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Sequence({ + value: [new asn1js.Repeated({ + name: "BasicOCSPResponse.certs", + value: _Certificate.default.schema(names.certs || {}) + })] + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["BasicOCSPResponse.tbsResponseData", "BasicOCSPResponse.signatureAlgorithm", "BasicOCSPResponse.signature", "BasicOCSPResponse.certs"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, BasicOCSPResponse.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for BasicOCSPResponse"); //endregion + //region Get internal properties from parsed schema + + this.tbsResponseData = new _ResponseData.default({ + schema: asn1.result["BasicOCSPResponse.tbsResponseData"] + }); + this.signatureAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result["BasicOCSPResponse.signatureAlgorithm"] + }); + this.signature = asn1.result["BasicOCSPResponse.signature"]; + if ("BasicOCSPResponse.certs" in asn1.result) this.certs = Array.from(asn1.result["BasicOCSPResponse.certs"], element => new _Certificate.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(this.tbsResponseData.toSchema()); + outputArray.push(this.signatureAlgorithm.toSchema()); + outputArray.push(this.signature); //region Create array of certificates + + if ("certs" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Sequence({ + value: Array.from(this.certs, element => element.toSchema()) + })] + })); + } //endregion + //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + tbsResponseData: this.tbsResponseData.toJSON(), + signatureAlgorithm: this.signatureAlgorithm.toJSON(), + signature: this.signature.toJSON() + }; + if ("certs" in this) _object.certs = Array.from(this.certs, element => element.toJSON()); + return _object; + } //********************************************************************************** + + /** + * Get OCSP response status for specific certificate + * @param {Certificate} certificate Certificate to be checked + * @param {Certificate} issuerCertificate Certificate of issuer for certificate to be checked + * @returns {Promise} + */ + + + getCertificateStatus(certificate, issuerCertificate) { + //region Initial variables + let sequence = Promise.resolve(); + const result = { + isForCertificate: false, + status: 2 // 0 = good, 1 = revoked, 2 = unknown + + }; + const hashesObject = {}; + const certIDs = []; + const certIDPromises = []; //endregion + //region Create all "certIDs" for input certificates + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.tbsResponseData.responses[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + const response = _step.value; + const hashAlgorithm = (0, _common.getAlgorithmByOID)(response.certID.hashAlgorithm.algorithmId); + if ("name" in hashAlgorithm === false) return Promise.reject(`Wrong CertID hashing algorithm: ${response.certID.hashAlgorithm.algorithmId}`); + + if (hashAlgorithm.name in hashesObject === false) { + hashesObject[hashAlgorithm.name] = 1; + const certID = new _CertID.default(); + certIDs.push(certID); + certIDPromises.push(certID.createForCertificate(certificate, { + hashAlgorithm: hashAlgorithm.name, + issuerCertificate + })); + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + sequence = sequence.then(() => Promise.all(certIDPromises)); //endregion + //region Compare all response's "certIDs" with identifiers for input certificate + + sequence = sequence.then(() => { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.tbsResponseData.responses[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + const response = _step2.value; + + for (var _i = 0, _certIDs = certIDs; _i < _certIDs.length; _i++) { + const id = _certIDs[_i]; + + if (response.certID.isEqual(id)) { + result.isForCertificate = true; + + try { + switch (response.certStatus.idBlock.isConstructed) { + case true: + if (response.certStatus.idBlock.tagNumber === 1) result.status = 1; // revoked + + break; + + case false: + switch (response.certStatus.idBlock.tagNumber) { + case 0: + // good + result.status = 0; + break; + + case 2: + // unknown + result.status = 2; + break; + + default: + } + + break; + + default: + } + } catch (ex) {} + + return result; + } + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return != null) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + return result; + }); //endregion + + return sequence; + } //********************************************************************************** + + /** + * Make signature for current OCSP Basic Response + * @param {Object} privateKey Private key for "subjectPublicKeyInfo" structure + * @param {string} [hashAlgorithm="SHA-1"] Hashing algorithm. Default SHA-1 + * @returns {Promise} + */ + + + sign(privateKey, hashAlgorithm = "SHA-1") { + //region Initial checking + //region Get a private key from function parameter + if (typeof privateKey === "undefined") return Promise.reject("Need to provide a private key for signing"); //endregion + //endregion + //region Initial variables + + let sequence = Promise.resolve(); + let parameters; + const engine = (0, _common.getEngine)(); //endregion + //region Get a "default parameters" for current algorithm and set correct signature algorithm + + sequence = sequence.then(() => engine.subtle.getSignatureParameters(privateKey, hashAlgorithm)); + sequence = sequence.then(result => { + parameters = result.parameters; + this.signatureAlgorithm = result.signatureAlgorithm; + }); //endregion + //region Create TBS data for signing + + sequence = sequence.then(() => { + this.tbsResponseData.tbs = this.tbsResponseData.toSchema(true).toBER(false); + }); //endregion + //region Signing TBS data on provided private key + + sequence = sequence.then(() => engine.subtle.signWithPrivateKey(this.tbsResponseData.tbs, privateKey, parameters)); + sequence = sequence.then(result => { + this.signature = new asn1js.BitString({ + valueHex: result + }); + }); //endregion + + return sequence; + } //********************************************************************************** + + /** + * Verify existing OCSP Basic Response + * @param {Object} parameters Additional parameters + * @returns {Promise} + */ + + + verify(parameters = {}) { + //region Initial variables + let signerCert = null; + let certIndex = -1; + let sequence = Promise.resolve(); + let trustedCerts = []; + + const _this = this; + + const engine = (0, _common.getEngine)(); //endregion + //region Check amount of certificates + + if ("certs" in this === false) return Promise.reject("No certificates attached to the BasicOCSPResponce"); //endregion + //region Get input values + + if ("trustedCerts" in parameters) trustedCerts = parameters.trustedCerts; //endregion + //region Aux functions + + /** + * Check CA flag for the certificate + * @param {Certificate} cert Certificate to find CA flag for + * @returns {*} + */ + + function checkCA(cert) { + //region Do not include signer's certificate + if (cert.issuer.isEqual(signerCert.issuer) === true && cert.serialNumber.isEqual(signerCert.serialNumber) === true) return null; //endregion + + let isCA = false; + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = cert.extensions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + const extension = _step3.value; + + if (extension.extnID === "2.5.29.19") // BasicConstraints + { + if ("cA" in extension.parsedValue) { + if (extension.parsedValue.cA === true) isCA = true; + } + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3.return != null) { + _iterator3.return(); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + if (isCA) return cert; + return null; + } //endregion + //region Get a "crypto" extension + + + const crypto = (0, _common.getCrypto)(); + if (typeof crypto === "undefined") return Promise.reject("Unable to create WebCrypto object"); //endregion + //region Find correct value for "responderID" + + switch (true) { + case this.tbsResponseData.responderID instanceof _RelativeDistinguishedNames.default: + // [1] Name + sequence = sequence.then(() => { + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = _this.certs.entries()[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + const _step4$value = _slicedToArray(_step4.value, 2), + index = _step4$value[0], + certificate = _step4$value[1]; + + if (certificate.subject.isEqual(_this.tbsResponseData.responderID)) { + certIndex = index; + break; + } + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4.return != null) { + _iterator4.return(); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + }); + break; + + case this.tbsResponseData.responderID instanceof asn1js.OctetString: + // [2] KeyHash + sequence = sequence.then(() => Promise.all(Array.from(_this.certs, element => crypto.digest({ + name: "sha-1" + }, new Uint8Array(element.subjectPublicKeyInfo.subjectPublicKey.valueBlock.valueHex)))).then(results => { + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = _this.certs.entries()[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + const _step5$value = _slicedToArray(_step5.value, 1), + index = _step5$value[0]; + + if ((0, _pvutils.isEqualBuffer)(results[index], _this.tbsResponseData.responderID.valueBlock.valueHex)) { + certIndex = index; + break; + } + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5.return != null) { + _iterator5.return(); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + })); + break; + + default: + return Promise.reject("Wrong value for responderID"); + } //endregion + //region Make additional verification for signer's certificate + + + sequence = sequence.then(() => { + if (certIndex === -1) return Promise.reject("Correct certificate was not found in OCSP response"); + signerCert = this.certs[certIndex]; + return Promise.all(Array.from(_this.certs, element => checkCA(element))).then(promiseResults => { + const additionalCerts = []; + additionalCerts.push(signerCert); + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; + + try { + for (var _iterator6 = promiseResults[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + const promiseResult = _step6.value; + if (promiseResult !== null) additionalCerts.push(promiseResult); + } + } catch (err) { + _didIteratorError6 = true; + _iteratorError6 = err; + } finally { + try { + if (!_iteratorNormalCompletion6 && _iterator6.return != null) { + _iterator6.return(); + } + } finally { + if (_didIteratorError6) { + throw _iteratorError6; + } + } + } + + const certChain = new _CertificateChainValidationEngine.default({ + certs: additionalCerts, + trustedCerts + }); + return certChain.verify().then(verificationResult => { + if (verificationResult.result === true) return Promise.resolve(); + return Promise.reject("Validation of signer's certificate failed"); + }, error => Promise.reject(`Validation of signer's certificate failed with error: ${error instanceof Object ? error.resultMessage : error}`)); + }, promiseError => Promise.reject(`Error during checking certificates for CA flag: ${promiseError}`)); + }); //endregion + + sequence = sequence.then(() => engine.subtle.verifyWithPublicKey(this.tbsResponseData.tbs, this.signature, this.certs[certIndex].subjectPublicKeyInfo, this.signatureAlgorithm)); + return sequence; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = BasicOCSPResponse; + +},{"./AlgorithmIdentifier.js":4,"./CertID.js":18,"./Certificate.js":19,"./CertificateChainValidationEngine.js":20,"./RelativeDistinguishedNames.js":89,"./ResponseData.js":92,"./common.js":110,"asn1js":112,"pvutils":113}],14:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from https://docs.microsoft.com/en-us/windows/desktop/seccrypto/certification-authority-renewal + */ +class CAVersion { + //********************************************************************************** + + /** + * Constructor for CAVersion class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc certificateIndex + */ + this.certificateIndex = (0, _pvutils.getParametersValue)(parameters, "certificateIndex", CAVersion.defaultValues("certificateIndex")); + /** + * @type {number} + * @desc keyIndex + */ + + this.keyIndex = (0, _pvutils.getParametersValue)(parameters, "keyIndex", CAVersion.defaultValues("keyIndex")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "certificateIndex": + case "keyIndex": + return 0; + + default: + throw new Error(`Invalid member name for CAVersion class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * CAVersion ::= INTEGER + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + return new asn1js.Integer(); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Check the schema is valid + if (schema.constructor.blockName() !== asn1js.Integer.blockName()) throw new Error("Object's schema was not verified against input data for CAVersion"); //endregion + //region Check length of the input value and correct it if needed + + let value = schema.valueBlock.valueHex.slice(0); + const valueView = new Uint8Array(value); + + switch (true) { + case value.byteLength < 4: + { + const tempValue = new ArrayBuffer(4); + const tempValueView = new Uint8Array(tempValue); + tempValueView.set(valueView, 4 - value.byteLength); + value = tempValue.slice(0); + } + break; + + case value.byteLength > 4: + { + const tempValue = new ArrayBuffer(4); + const tempValueView = new Uint8Array(tempValue); + tempValueView.set(valueView.slice(0, 4)); + value = tempValue.slice(0); + } + break; + + default: + } //endregion + //region Get internal properties from parsed schema + + + const keyIndexBuffer = value.slice(0, 2); + const keyIndexView8 = new Uint8Array(keyIndexBuffer); + let temp = keyIndexView8[0]; + keyIndexView8[0] = keyIndexView8[1]; + keyIndexView8[1] = temp; + const keyIndexView16 = new Uint16Array(keyIndexBuffer); + this.keyIndex = keyIndexView16[0]; + const certificateIndexBuffer = value.slice(2); + const certificateIndexView8 = new Uint8Array(certificateIndexBuffer); + temp = certificateIndexView8[0]; + certificateIndexView8[0] = certificateIndexView8[1]; + certificateIndexView8[1] = temp; + const certificateIndexView16 = new Uint16Array(certificateIndexBuffer); + this.certificateIndex = certificateIndexView16[0]; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create raw values + const certificateIndexBuffer = new ArrayBuffer(2); + const certificateIndexView = new Uint16Array(certificateIndexBuffer); + certificateIndexView[0] = this.certificateIndex; + const certificateIndexView8 = new Uint8Array(certificateIndexBuffer); + let temp = certificateIndexView8[0]; + certificateIndexView8[0] = certificateIndexView8[1]; + certificateIndexView8[1] = temp; + const keyIndexBuffer = new ArrayBuffer(2); + const keyIndexView = new Uint16Array(keyIndexBuffer); + keyIndexView[0] = this.keyIndex; + const keyIndexView8 = new Uint8Array(keyIndexBuffer); + temp = keyIndexView8[0]; + keyIndexView8[0] = keyIndexView8[1]; + keyIndexView8[1] = temp; //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Integer({ + valueHex: (0, _pvutils.utilConcatBuf)(keyIndexBuffer, certificateIndexBuffer) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + certificateIndex: this.certificateIndex, + keyIndex: this.keyIndex + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = CAVersion; + +},{"asn1js":112,"pvutils":113}],15:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _CertificateRevocationList = _interopRequireDefault(require("./CertificateRevocationList.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC7292 + */ +class CRLBag { + //********************************************************************************** + + /** + * Constructor for CRLBag class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc crlId + */ + this.crlId = (0, _pvutils.getParametersValue)(parameters, "crlId", CRLBag.defaultValues("crlId")); + /** + * @type {*} + * @desc crlValue + */ + + this.crlValue = (0, _pvutils.getParametersValue)(parameters, "crlValue", CRLBag.defaultValues("crlValue")); + if ("parsedValue" in parameters) + /** + * @type {*} + * @desc parsedValue + */ + this.parsedValue = (0, _pvutils.getParametersValue)(parameters, "parsedValue", CRLBag.defaultValues("parsedValue")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "crlId": + return ""; + + case "crlValue": + return new asn1js.Any(); + + case "parsedValue": + return {}; + + default: + throw new Error(`Invalid member name for CRLBag class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "crlId": + return memberValue === ""; + + case "crlValue": + return memberValue instanceof asn1js.Any; + + case "parsedValue": + return memberValue instanceof Object && Object.keys(memberValue).length === 0; + + default: + throw new Error(`Invalid member name for CRLBag class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * CRLBag ::= SEQUENCE { + * crlId BAG-TYPE.&id ({CRLTypes}), + * crlValue [0] EXPLICIT BAG-TYPE.&Type ({CRLTypes}{@crlId}) + *} + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [id] + * @property {string} [value] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.id || "id" + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Any({ + name: names.value || "value" + })] // EXPLICIT ANY value + + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["crlId", "crlValue"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, CRLBag.schema({ + names: { + id: "crlId", + value: "crlValue" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for CRLBag"); //endregion + //region Get internal properties from parsed schema + + this.crlId = asn1.result.crlId.valueBlock.toString(); + this.crlValue = asn1.result.crlValue; + + switch (this.crlId) { + case "1.2.840.113549.1.9.23.1": + // x509CRL + { + const asn1Inner = asn1js.fromBER(this.certValue.valueBlock.valueHex); + this.parsedValue = new _CertificateRevocationList.default({ + schema: asn1Inner.result + }); + } + break; + + default: + throw new Error(`Incorrect "crlId" value in CRLBag: ${this.crlId}`); + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + if ("parsedValue" in this) { + this.certId = "1.2.840.113549.1.9.23.1"; + this.certValue = new asn1js.OctetString({ + valueHex: this.parsedValue.toSchema().toBER(false) + }); + } + + return new asn1js.Sequence({ + value: [new asn1js.ObjectIdentifier({ + value: this.crlId + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [this.crlValue.toSchema()] + })] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + crlId: this.crlId, + crlValue: this.crlValue.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = CRLBag; + +},{"./CertificateRevocationList.js":22,"asn1js":112,"pvutils":113}],16:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _DistributionPoint = _interopRequireDefault(require("./DistributionPoint.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class CRLDistributionPoints { + //********************************************************************************** + + /** + * Constructor for CRLDistributionPoints class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc distributionPoints + */ + this.distributionPoints = (0, _pvutils.getParametersValue)(parameters, "distributionPoints", CRLDistributionPoints.defaultValues("distributionPoints")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "distributionPoints": + return []; + + default: + throw new Error(`Invalid member name for CRLDistributionPoints class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [distributionPoints] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.distributionPoints || "", + value: _DistributionPoint.default.schema() + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["distributionPoints"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, CRLDistributionPoints.schema({ + names: { + distributionPoints: "distributionPoints" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for CRLDistributionPoints"); //endregion + //region Get internal properties from parsed schema + + this.distributionPoints = Array.from(asn1.result.distributionPoints, element => new _DistributionPoint.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: Array.from(this.distributionPoints, element => element.toSchema()) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + distributionPoints: Array.from(this.distributionPoints, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = CRLDistributionPoints; + +},{"./DistributionPoint.js":29,"asn1js":112,"pvutils":113}],17:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _Certificate = _interopRequireDefault(require("./Certificate.js")); + +var _AttributeCertificateV = _interopRequireDefault(require("./AttributeCertificateV2.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC7292 + */ +class CertBag { + //********************************************************************************** + + /** + * Constructor for CertBag class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc certId + */ + this.certId = (0, _pvutils.getParametersValue)(parameters, "certId", CertBag.defaultValues("certId")); + /** + * @type {*} + * @desc certValue + */ + + this.certValue = (0, _pvutils.getParametersValue)(parameters, "certValue", CertBag.defaultValues("certValue")); + if ("parsedValue" in parameters) + /** + * @type {*} + * @desc parsedValue + */ + this.parsedValue = (0, _pvutils.getParametersValue)(parameters, "parsedValue", CertBag.defaultValues("parsedValue")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "certId": + return ""; + + case "certValue": + return new asn1js.Any(); + + case "parsedValue": + return {}; + + default: + throw new Error(`Invalid member name for CertBag class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "certId": + return memberValue === ""; + + case "certValue": + return memberValue instanceof asn1js.Any; + + case "parsedValue": + return memberValue instanceof Object && Object.keys(memberValue).length === 0; + + default: + throw new Error(`Invalid member name for CertBag class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * CertBag ::= SEQUENCE { + * certId BAG-TYPE.&id ({CertTypes}), + * certValue [0] EXPLICIT BAG-TYPE.&Type ({CertTypes}{@certId}) + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [id] + * @property {string} [value] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.id || "id" + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Any({ + name: names.value || "value" + })] // EXPLICIT ANY value + + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["certId", "certValue"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, CertBag.schema({ + names: { + id: "certId", + value: "certValue" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for CertBag"); //endregion + //region Get internal properties from parsed schema + + this.certId = asn1.result.certId.valueBlock.toString(); + this.certValue = asn1.result.certValue; + + switch (this.certId) { + case "1.2.840.113549.1.9.22.1": + // x509Certificate + { + const asn1Inner = asn1js.fromBER(this.certValue.valueBlock.valueHex); + + try { + this.parsedValue = new _Certificate.default({ + schema: asn1Inner.result + }); + } catch (ex) // In some realizations the same OID used for attribute certificates + { + this.parsedValue = new _AttributeCertificateV.default({ + schema: asn1Inner.result + }); + } + } + break; + + case "1.2.840.113549.1.9.22.3": + // attributeCertificate - (!!!) THIS OID IS SUBJECT FOR CHANGE IN FUTURE (!!!) + { + const asn1Inner = asn1js.fromBER(this.certValue.valueBlock.valueHex); + this.parsedValue = new _AttributeCertificateV.default({ + schema: asn1Inner.result + }); + } + break; + + case "1.2.840.113549.1.9.22.2": // sdsiCertificate + + default: + throw new Error(`Incorrect "certId" value in CertBag: ${this.certId}`); + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + if ("parsedValue" in this) { + if ("acinfo" in this.parsedValue) // attributeCertificate + this.certId = "1.2.840.113549.1.9.22.3";else // x509Certificate + this.certId = "1.2.840.113549.1.9.22.1"; + this.certValue = new asn1js.OctetString({ + valueHex: this.parsedValue.toSchema().toBER(false) + }); + } + + return new asn1js.Sequence({ + value: [new asn1js.ObjectIdentifier({ + value: this.certId + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: ["toSchema" in this.certValue ? this.certValue.toSchema() : this.certValue] + })] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + certId: this.certId, + certValue: this.certValue.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = CertBag; + +},{"./AttributeCertificateV2.js":8,"./Certificate.js":19,"asn1js":112,"pvutils":113}],18:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _common = require("./common.js"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC6960 + */ +class CertID { + //********************************************************************************** + + /** + * Constructor for CertID class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {AlgorithmIdentifier} + * @desc hashAlgorithm + */ + this.hashAlgorithm = (0, _pvutils.getParametersValue)(parameters, "hashAlgorithm", CertID.defaultValues("hashAlgorithm")); + /** + * @type {OctetString} + * @desc issuerNameHash + */ + + this.issuerNameHash = (0, _pvutils.getParametersValue)(parameters, "issuerNameHash", CertID.defaultValues("issuerNameHash")); + /** + * @type {OctetString} + * @desc issuerKeyHash + */ + + this.issuerKeyHash = (0, _pvutils.getParametersValue)(parameters, "issuerKeyHash", CertID.defaultValues("issuerKeyHash")); + /** + * @type {Integer} + * @desc serialNumber + */ + + this.serialNumber = (0, _pvutils.getParametersValue)(parameters, "serialNumber", CertID.defaultValues("serialNumber")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "hashAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "issuerNameHash": + case "issuerKeyHash": + return new asn1js.OctetString(); + + case "serialNumber": + return new asn1js.Integer(); + + default: + throw new Error(`Invalid member name for CertID class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "hashAlgorithm": + return memberValue.algorithmId === "" && "algorithmParams" in memberValue === false; + + case "issuerNameHash": + case "issuerKeyHash": + case "serialNumber": + return memberValue.isEqual(CertID.defaultValues(memberName)); + + default: + throw new Error(`Invalid member name for CertID class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * CertID ::= SEQUENCE { + * hashAlgorithm AlgorithmIdentifier, + * issuerNameHash OCTET STRING, -- Hash of issuer's DN + * issuerKeyHash OCTET STRING, -- Hash of issuer's public key + * serialNumber CertificateSerialNumber } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [hashAlgorithm] + * @property {string} [hashAlgorithmObject] + * @property {string} [issuerNameHash] + * @property {string} [issuerKeyHash] + * @property {string} [serialNumber] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_AlgorithmIdentifier.default.schema(names.hashAlgorithmObject || { + names: { + blockName: names.hashAlgorithm || "" + } + }), new asn1js.OctetString({ + name: names.issuerNameHash || "" + }), new asn1js.OctetString({ + name: names.issuerKeyHash || "" + }), new asn1js.Integer({ + name: names.serialNumber || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["hashAlgorithm", "issuerNameHash", "issuerKeyHash", "serialNumber"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, CertID.schema({ + names: { + hashAlgorithm: "hashAlgorithm", + issuerNameHash: "issuerNameHash", + issuerKeyHash: "issuerKeyHash", + serialNumber: "serialNumber" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for CertID"); //endregion + //region Get internal properties from parsed schema + + this.hashAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.hashAlgorithm + }); + this.issuerNameHash = asn1.result.issuerNameHash; + this.issuerKeyHash = asn1.result.issuerKeyHash; + this.serialNumber = asn1.result.serialNumber; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [this.hashAlgorithm.toSchema(), this.issuerNameHash, this.issuerKeyHash, this.serialNumber] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + hashAlgorithm: this.hashAlgorithm.toJSON(), + issuerNameHash: this.issuerNameHash.toJSON(), + issuerKeyHash: this.issuerKeyHash.toJSON(), + serialNumber: this.serialNumber.toJSON() + }; + } //********************************************************************************** + + /** + * Check that two "CertIDs" are equal + * @param {CertID} certificateID Identifier of the certificate to be checked + * @returns {boolean} + */ + + + isEqual(certificateID) { + //region Check "hashAlgorithm" + if (!this.hashAlgorithm.algorithmId === certificateID.hashAlgorithm.algorithmId) return false; //endregion + //region Check "issuerNameHash" + + if ((0, _pvutils.isEqualBuffer)(this.issuerNameHash.valueBlock.valueHex, certificateID.issuerNameHash.valueBlock.valueHex) === false) return false; //endregion + //region Check "issuerKeyHash" + + if ((0, _pvutils.isEqualBuffer)(this.issuerKeyHash.valueBlock.valueHex, certificateID.issuerKeyHash.valueBlock.valueHex) === false) return false; //endregion + //region Check "serialNumber" + + if (!this.serialNumber.isEqual(certificateID.serialNumber)) return false; //endregion + + return true; + } //********************************************************************************** + + /** + * Making OCSP certificate identifier for specific certificate + * @param {Certificate} certificate Certificate making OCSP Request for + * @param {Object} parameters Additional parameters + * @returns {Promise} + */ + + + createForCertificate(certificate, parameters) { + //region Initial variables + let sequence = Promise.resolve(); + let issuerCertificate; //endregion + //region Get a "crypto" extension + + const crypto = (0, _common.getCrypto)(); + if (typeof crypto === "undefined") return Promise.reject("Unable to create WebCrypto object"); //endregion + //region Check input parameters + + if ("hashAlgorithm" in parameters === false) return Promise.reject("Parameter \"hashAlgorithm\" is mandatory for \"OCSP_REQUEST.createForCertificate\""); + const hashOID = (0, _common.getOIDByAlgorithm)({ + name: parameters.hashAlgorithm + }); + if (hashOID === "") return Promise.reject(`Incorrect "hashAlgorithm": ${this.hashAlgorithm}`); + this.hashAlgorithm = new _AlgorithmIdentifier.default({ + algorithmId: hashOID, + algorithmParams: new asn1js.Null() + }); + if ("issuerCertificate" in parameters) issuerCertificate = parameters.issuerCertificate;else return Promise.reject("Parameter \"issuerCertificate\" is mandatory for \"OCSP_REQUEST.createForCertificate\""); //endregion + //region Initialize "serialNumber" field + + this.serialNumber = certificate.serialNumber; //endregion + //region Create "issuerNameHash" + + sequence = sequence.then(() => crypto.digest({ + name: parameters.hashAlgorithm + }, issuerCertificate.subject.toSchema().toBER(false)), error => Promise.reject(error)); //endregion + //region Create "issuerKeyHash" + + sequence = sequence.then(result => { + this.issuerNameHash = new asn1js.OctetString({ + valueHex: result + }); + const issuerKeyBuffer = issuerCertificate.subjectPublicKeyInfo.subjectPublicKey.valueBlock.valueHex; + return crypto.digest({ + name: parameters.hashAlgorithm + }, issuerKeyBuffer); + }, error => Promise.reject(error)).then(result => { + this.issuerKeyHash = new asn1js.OctetString({ + valueHex: result + }); + }, error => Promise.reject(error)); //endregion + + return sequence; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = CertID; + +},{"./AlgorithmIdentifier.js":4,"./common.js":110,"asn1js":112,"pvutils":113}],19:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _common = require("./common.js"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _RelativeDistinguishedNames = _interopRequireDefault(require("./RelativeDistinguishedNames.js")); + +var _Time = _interopRequireDefault(require("./Time.js")); + +var _PublicKeyInfo = _interopRequireDefault(require("./PublicKeyInfo.js")); + +var _Extension = _interopRequireDefault(require("./Extension.js")); + +var _Extensions = _interopRequireDefault(require("./Extensions.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** +function tbsCertificate(parameters = {}) { + //TBSCertificate ::= SEQUENCE { + // version [0] EXPLICIT Version DEFAULT v1, + // serialNumber CertificateSerialNumber, + // signature AlgorithmIdentifier, + // issuer Name, + // validity Validity, + // subject Name, + // subjectPublicKeyInfo SubjectPublicKeyInfo, + // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + // -- If present, version MUST be v2 or v3 + // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + // -- If present, version MUST be v2 or v3 + // extensions [3] EXPLICIT Extensions OPTIONAL + // -- If present, version MUST be v3 + //} + + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [tbsCertificateVersion] + * @property {string} [tbsCertificateSerialNumber] + * @property {string} [signature] + * @property {string} [issuer] + * @property {string} [tbsCertificateValidity] + * @property {string} [notBefore] + * @property {string} [notAfter] + * @property {string} [subject] + * @property {string} [subjectPublicKeyInfo] + * @property {string} [tbsCertificateIssuerUniqueID] + * @property {string} [tbsCertificateSubjectUniqueID] + * @property {string} [extensions] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "tbsCertificate", + value: [new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Integer({ + name: names.tbsCertificateVersion || "tbsCertificate.version" + }) // EXPLICIT integer value + ] + }), new asn1js.Integer({ + name: names.tbsCertificateSerialNumber || "tbsCertificate.serialNumber" + }), _AlgorithmIdentifier.default.schema(names.signature || { + names: { + blockName: "tbsCertificate.signature" + } + }), _RelativeDistinguishedNames.default.schema(names.issuer || { + names: { + blockName: "tbsCertificate.issuer" + } + }), new asn1js.Sequence({ + name: names.tbsCertificateValidity || "tbsCertificate.validity", + value: [_Time.default.schema(names.notBefore || { + names: { + utcTimeName: "tbsCertificate.notBefore", + generalTimeName: "tbsCertificate.notBefore" + } + }), _Time.default.schema(names.notAfter || { + names: { + utcTimeName: "tbsCertificate.notAfter", + generalTimeName: "tbsCertificate.notAfter" + } + })] + }), _RelativeDistinguishedNames.default.schema(names.subject || { + names: { + blockName: "tbsCertificate.subject" + } + }), _PublicKeyInfo.default.schema(names.subjectPublicKeyInfo || { + names: { + blockName: "tbsCertificate.subjectPublicKeyInfo" + } + }), new asn1js.Primitive({ + name: names.tbsCertificateIssuerUniqueID || "tbsCertificate.issuerUniqueID", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + } + }), // IMPLICIT bistring value + new asn1js.Primitive({ + name: names.tbsCertificateSubjectUniqueID || "tbsCertificate.subjectUniqueID", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + } + }), // IMPLICIT bistring value + new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 3 // [3] + + }, + value: [_Extensions.default.schema(names.extensions || { + names: { + blockName: "tbsCertificate.extensions" + } + })] + }) // EXPLICIT SEQUENCE value + ] + }); +} //************************************************************************************** + +/** + * Class from RFC5280 + */ + + +class Certificate { + //********************************************************************************** + + /** + * Constructor for Certificate class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {ArrayBuffer} + * @desc ToBeSigned (TBS) part of the certificate + */ + this.tbs = (0, _pvutils.getParametersValue)(parameters, "tbs", Certificate.defaultValues("tbs")); + /** + * @type {number} + * @desc Version number + */ + + this.version = (0, _pvutils.getParametersValue)(parameters, "version", Certificate.defaultValues("version")); + /** + * @type {Integer} + * @desc Serial number of the certificate + */ + + this.serialNumber = (0, _pvutils.getParametersValue)(parameters, "serialNumber", Certificate.defaultValues("serialNumber")); + /** + * @type {AlgorithmIdentifier} + * @desc This field contains the algorithm identifier for the algorithm used by the CA to sign the certificate + */ + + this.signature = (0, _pvutils.getParametersValue)(parameters, "signature", Certificate.defaultValues("signature")); + /** + * @type {RelativeDistinguishedNames} + * @desc The issuer field identifies the entity that has signed and issued the certificate + */ + + this.issuer = (0, _pvutils.getParametersValue)(parameters, "issuer", Certificate.defaultValues("issuer")); + /** + * @type {Time} + * @desc The date on which the certificate validity period begins + */ + + this.notBefore = (0, _pvutils.getParametersValue)(parameters, "notBefore", Certificate.defaultValues("notBefore")); + /** + * @type {Time} + * @desc The date on which the certificate validity period ends + */ + + this.notAfter = (0, _pvutils.getParametersValue)(parameters, "notAfter", Certificate.defaultValues("notAfter")); + /** + * @type {RelativeDistinguishedNames} + * @desc The subject field identifies the entity associated with the public key stored in the subject public key field + */ + + this.subject = (0, _pvutils.getParametersValue)(parameters, "subject", Certificate.defaultValues("subject")); + /** + * @type {PublicKeyInfo} + * @desc This field is used to carry the public key and identify the algorithm with which the key is used + */ + + this.subjectPublicKeyInfo = (0, _pvutils.getParametersValue)(parameters, "subjectPublicKeyInfo", Certificate.defaultValues("subjectPublicKeyInfo")); + if ("issuerUniqueID" in parameters) + /** + * @type {ArrayBuffer} + * @desc The subject and issuer unique identifiers are present in the certificate to handle the possibility of reuse of subject and/or issuer names over time + */ + this.issuerUniqueID = (0, _pvutils.getParametersValue)(parameters, "issuerUniqueID", Certificate.defaultValues("issuerUniqueID")); + if ("subjectUniqueID" in parameters) + /** + * @type {ArrayBuffer} + * @desc The subject and issuer unique identifiers are present in the certificate to handle the possibility of reuse of subject and/or issuer names over time + */ + this.subjectUniqueID = (0, _pvutils.getParametersValue)(parameters, "subjectUniqueID", Certificate.defaultValues("subjectUniqueID")); + if ("extensions" in parameters) + /** + * @type {Array} + * @desc If present, this field is a SEQUENCE of one or more certificate extensions + */ + this.extensions = (0, _pvutils.getParametersValue)(parameters, "extensions", Certificate.defaultValues("extensions")); + /** + * @type {AlgorithmIdentifier} + * @desc The signatureAlgorithm field contains the identifier for the cryptographic algorithm used by the CA to sign this certificate + */ + + this.signatureAlgorithm = (0, _pvutils.getParametersValue)(parameters, "signatureAlgorithm", Certificate.defaultValues("signatureAlgorithm")); + /** + * @type {BitString} + * @desc The signatureValue field contains a digital signature computed upon the ASN.1 DER encoded tbsCertificate + */ + + this.signatureValue = (0, _pvutils.getParametersValue)(parameters, "signatureValue", Certificate.defaultValues("signatureValue")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "tbs": + return new ArrayBuffer(0); + + case "version": + return 0; + + case "serialNumber": + return new asn1js.Integer(); + + case "signature": + return new _AlgorithmIdentifier.default(); + + case "issuer": + return new _RelativeDistinguishedNames.default(); + + case "notBefore": + return new _Time.default(); + + case "notAfter": + return new _Time.default(); + + case "subject": + return new _RelativeDistinguishedNames.default(); + + case "subjectPublicKeyInfo": + return new _PublicKeyInfo.default(); + + case "issuerUniqueID": + return new ArrayBuffer(0); + + case "subjectUniqueID": + return new ArrayBuffer(0); + + case "extensions": + return []; + + case "signatureAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "signatureValue": + return new asn1js.BitString(); + + default: + throw new Error(`Invalid member name for Certificate class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * Certificate ::= SEQUENCE { + * tbsCertificate TBSCertificate, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [tbsCertificate] + * @property {string} [signatureAlgorithm] + * @property {string} [signatureValue] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [tbsCertificate(names.tbsCertificate), _AlgorithmIdentifier.default.schema(names.signatureAlgorithm || { + names: { + blockName: "signatureAlgorithm" + } + }), new asn1js.BitString({ + name: names.signatureValue || "signatureValue" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["tbsCertificate", "tbsCertificate.extensions", "tbsCertificate.version", "tbsCertificate.serialNumber", "tbsCertificate.signature", "tbsCertificate.issuer", "tbsCertificate.notBefore", "tbsCertificate.notAfter", "tbsCertificate.subject", "tbsCertificate.subjectPublicKeyInfo", "tbsCertificate.issuerUniqueID", "tbsCertificate.subjectUniqueID", "signatureAlgorithm", "signatureValue"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, Certificate.schema({ + names: { + tbsCertificate: { + names: { + extensions: { + names: { + extensions: "tbsCertificate.extensions" + } + } + } + } + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for Certificate"); //endregion + //region Get internal properties from parsed schema + + this.tbs = asn1.result.tbsCertificate.valueBeforeDecode; + if ("tbsCertificate.version" in asn1.result) this.version = asn1.result["tbsCertificate.version"].valueBlock.valueDec; + this.serialNumber = asn1.result["tbsCertificate.serialNumber"]; + this.signature = new _AlgorithmIdentifier.default({ + schema: asn1.result["tbsCertificate.signature"] + }); + this.issuer = new _RelativeDistinguishedNames.default({ + schema: asn1.result["tbsCertificate.issuer"] + }); + this.notBefore = new _Time.default({ + schema: asn1.result["tbsCertificate.notBefore"] + }); + this.notAfter = new _Time.default({ + schema: asn1.result["tbsCertificate.notAfter"] + }); + this.subject = new _RelativeDistinguishedNames.default({ + schema: asn1.result["tbsCertificate.subject"] + }); + this.subjectPublicKeyInfo = new _PublicKeyInfo.default({ + schema: asn1.result["tbsCertificate.subjectPublicKeyInfo"] + }); + if ("tbsCertificate.issuerUniqueID" in asn1.result) this.issuerUniqueID = asn1.result["tbsCertificate.issuerUniqueID"].valueBlock.valueHex; + if ("tbsCertificate.subjectUniqueID" in asn1.result) this.subjectUniqueID = asn1.result["tbsCertificate.subjectUniqueID"].valueBlock.valueHex; + if ("tbsCertificate.extensions" in asn1.result) this.extensions = Array.from(asn1.result["tbsCertificate.extensions"], element => new _Extension.default({ + schema: element + })); + this.signatureAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.signatureAlgorithm + }); + this.signatureValue = asn1.result.signatureValue; //endregion + } //********************************************************************************** + + /** + * Create ASN.1 schema for existing values of TBS part for the certificate + */ + + + encodeTBS() { + //region Create array for output sequence + const outputArray = []; + + if ("version" in this && this.version !== Certificate.defaultValues("version")) { + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Integer({ + value: this.version + }) // EXPLICIT integer value + ] + })); + } + + outputArray.push(this.serialNumber); + outputArray.push(this.signature.toSchema()); + outputArray.push(this.issuer.toSchema()); + outputArray.push(new asn1js.Sequence({ + value: [this.notBefore.toSchema(), this.notAfter.toSchema()] + })); + outputArray.push(this.subject.toSchema()); + outputArray.push(this.subjectPublicKeyInfo.toSchema()); + + if ("issuerUniqueID" in this) { + outputArray.push(new asn1js.Primitive({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + valueHex: this.issuerUniqueID + })); + } + + if ("subjectUniqueID" in this) { + outputArray.push(new asn1js.Primitive({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + valueHex: this.subjectUniqueID + })); + } + + if ("extensions" in this) { + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 3 // [3] + + }, + value: [new asn1js.Sequence({ + value: Array.from(this.extensions, element => element.toSchema()) + })] + })); + } //endregion + //region Create and return output sequence + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema(encodeFlag = false) { + let tbsSchema = {}; //region Decode stored TBS value + + if (encodeFlag === false) { + if (this.tbs.length === 0) // No stored certificate TBS part + return Certificate.schema().value[0]; + tbsSchema = asn1js.fromBER(this.tbs).result; + } //endregion + //region Create TBS schema via assembling from TBS parts + else tbsSchema = this.encodeTBS(); //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: [tbsSchema, this.signatureAlgorithm.toSchema(), this.signatureValue] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = { + tbs: (0, _pvutils.bufferToHexCodes)(this.tbs, 0, this.tbs.byteLength), + serialNumber: this.serialNumber.toJSON(), + signature: this.signature.toJSON(), + issuer: this.issuer.toJSON(), + notBefore: this.notBefore.toJSON(), + notAfter: this.notAfter.toJSON(), + subject: this.subject.toJSON(), + subjectPublicKeyInfo: this.subjectPublicKeyInfo.toJSON(), + signatureAlgorithm: this.signatureAlgorithm.toJSON(), + signatureValue: this.signatureValue.toJSON() + }; + if ("version" in this && this.version !== Certificate.defaultValues("version")) object.version = this.version; + if ("issuerUniqueID" in this) object.issuerUniqueID = (0, _pvutils.bufferToHexCodes)(this.issuerUniqueID, 0, this.issuerUniqueID.byteLength); + if ("subjectUniqueID" in this) object.subjectUniqueID = (0, _pvutils.bufferToHexCodes)(this.subjectUniqueID, 0, this.subjectUniqueID.byteLength); + if ("extensions" in this) object.extensions = Array.from(this.extensions, element => element.toJSON()); + return object; + } //********************************************************************************** + + /** + * Importing public key for current certificate + */ + + + getPublicKey(parameters = null) { + return (0, _common.getEngine)().subtle.getPublicKey(this.subjectPublicKeyInfo, this.signatureAlgorithm, parameters); + } //********************************************************************************** + + /** + * Get hash value for subject public key (default SHA-1) + * @param {String} [hashAlgorithm=SHA-1] Hashing algorithm name + */ + + + getKeyHash(hashAlgorithm = "SHA-1") { + //region Get a "crypto" extension + const crypto = (0, _common.getCrypto)(); + if (typeof crypto === "undefined") return Promise.reject("Unable to create WebCrypto object"); //endregion + + return crypto.digest({ + name: hashAlgorithm + }, new Uint8Array(this.subjectPublicKeyInfo.subjectPublicKey.valueBlock.valueHex)); + } //********************************************************************************** + + /** + * Make a signature for current value from TBS section + * @param {Object} privateKey Private key for "subjectPublicKeyInfo" structure + * @param {string} [hashAlgorithm="SHA-1"] Hashing algorithm + */ + + + sign(privateKey, hashAlgorithm = "SHA-1") { + //region Initial checking + //region Check private key + if (typeof privateKey === "undefined") return Promise.reject("Need to provide a private key for signing"); //endregion + //endregion + //region Initial variables + + let sequence = Promise.resolve(); + let parameters; + const engine = (0, _common.getEngine)(); //endregion + //region Get a "default parameters" for current algorithm and set correct signature algorithm + + sequence = sequence.then(() => engine.subtle.getSignatureParameters(privateKey, hashAlgorithm)); + sequence = sequence.then(result => { + parameters = result.parameters; + this.signature = result.signatureAlgorithm; + this.signatureAlgorithm = result.signatureAlgorithm; + }); //endregion + //region Create TBS data for signing + + sequence = sequence.then(() => { + this.tbs = this.encodeTBS().toBER(false); + }); //endregion + //region Signing TBS data on provided private key + + sequence = sequence.then(() => engine.subtle.signWithPrivateKey(this.tbs, privateKey, parameters)); + sequence = sequence.then(result => { + this.signatureValue = new asn1js.BitString({ + valueHex: result + }); + }); //endregion + + return sequence; + } //********************************************************************************** + + + verify(issuerCertificate = null) { + //region Global variables + let subjectPublicKeyInfo = {}; //endregion + //region Set correct "subjectPublicKeyInfo" value + + if (issuerCertificate !== null) subjectPublicKeyInfo = issuerCertificate.subjectPublicKeyInfo;else { + if (this.issuer.isEqual(this.subject)) // Self-signed certificate + subjectPublicKeyInfo = this.subjectPublicKeyInfo; + } + if (subjectPublicKeyInfo instanceof _PublicKeyInfo.default === false) return Promise.reject("Please provide issuer certificate as a parameter"); //endregion + + return (0, _common.getEngine)().subtle.verifyWithPublicKey(this.tbs, this.signatureValue, subjectPublicKeyInfo, this.signatureAlgorithm); + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = Certificate; + +},{"./AlgorithmIdentifier.js":4,"./Extension.js":38,"./Extensions.js":39,"./PublicKeyInfo.js":78,"./RelativeDistinguishedNames.js":89,"./Time.js":107,"./common.js":110,"asn1js":112,"pvutils":113}],20:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _pvutils = require("pvutils"); + +var _common = require("./common.js"); + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +//************************************************************************************** +class CertificateChainValidationEngine { + //********************************************************************************** + + /** + * Constructor for CertificateChainValidationEngine class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc Array of pre-defined trusted (by user) certificates + */ + this.trustedCerts = (0, _pvutils.getParametersValue)(parameters, "trustedCerts", this.defaultValues("trustedCerts")); + /** + * @type {Array.} + * @desc Array with certificate chain. Could be only one end-user certificate in there! + */ + + this.certs = (0, _pvutils.getParametersValue)(parameters, "certs", this.defaultValues("certs")); + /** + * @type {Array.} + * @desc Array of all CRLs for all certificates from certificate chain + */ + + this.crls = (0, _pvutils.getParametersValue)(parameters, "crls", this.defaultValues("crls")); + /** + * @type {Array} + * @desc Array of all OCSP responses + */ + + this.ocsps = (0, _pvutils.getParametersValue)(parameters, "ocsps", this.defaultValues("ocsps")); + /** + * @type {Date} + * @desc The date at which the check would be + */ + + this.checkDate = (0, _pvutils.getParametersValue)(parameters, "checkDate", this.defaultValues("checkDate")); + /** + * @type {Function} + * @desc The date at which the check would be + */ + + this.findOrigin = (0, _pvutils.getParametersValue)(parameters, "findOrigin", this.defaultValues("findOrigin")); + /** + * @type {Function} + * @desc The date at which the check would be + */ + + this.findIssuer = (0, _pvutils.getParametersValue)(parameters, "findIssuer", this.defaultValues("findIssuer")); //endregion + } //********************************************************************************** + + + static defaultFindOrigin(certificate, validationEngine) { + //region Firstly encode TBS for certificate + if (certificate.tbs.byteLength === 0) certificate.tbs = certificate.encodeTBS(); //endregion + //region Search in Intermediate Certificates + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = validationEngine.certs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + const localCert = _step.value; + //region Firstly encode TBS for certificate + if (localCert.tbs.byteLength === 0) localCert.tbs = localCert.encodeTBS(); //endregion + + if ((0, _pvutils.isEqualBuffer)(certificate.tbs, localCert.tbs)) return "Intermediate Certificates"; + } //endregion + //region Search in Trusted Certificates + + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = validationEngine.trustedCerts[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + const trustedCert = _step2.value; + //region Firstly encode TBS for certificate + if (trustedCert.tbs.byteLength === 0) trustedCert.tbs = trustedCert.encodeTBS(); //endregion + + if ((0, _pvutils.isEqualBuffer)(certificate.tbs, trustedCert.tbs)) return "Trusted Certificates"; + } //endregion + + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return != null) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + return "Unknown"; + } //********************************************************************************** + + + defaultFindIssuer(certificate, validationEngine) { + return _asyncToGenerator(function* () { + //region Initial variables + let result = []; + let keyIdentifier = null; + let authorityCertIssuer = null; + let authorityCertSerialNumber = null; //endregion + //region Speed-up searching in case of self-signed certificates + + if (certificate.subject.isEqual(certificate.issuer)) { + try { + const verificationResult = yield certificate.verify(); + if (verificationResult === true) return [certificate]; + } catch (ex) {} + } //endregion + //region Find values to speed-up search + + + if ("extensions" in certificate) { + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = certificate.extensions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + const extension = _step3.value; + + if (extension.extnID === "2.5.29.35") // AuthorityKeyIdentifier + { + if ("keyIdentifier" in extension.parsedValue) keyIdentifier = extension.parsedValue.keyIdentifier;else { + if ("authorityCertIssuer" in extension.parsedValue) authorityCertIssuer = extension.parsedValue.authorityCertIssuer; + if ("authorityCertSerialNumber" in extension.parsedValue) authorityCertSerialNumber = extension.parsedValue.authorityCertSerialNumber; + } + break; + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3.return != null) { + _iterator3.return(); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + } //endregion + //region Aux function + + + function checkCertificate(possibleIssuer) { + //region Firstly search for appropriate extensions + if (keyIdentifier !== null) { + if ("extensions" in possibleIssuer) { + let extensionFound = false; + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = possibleIssuer.extensions[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + const extension = _step4.value; + + if (extension.extnID === "2.5.29.14") // SubjectKeyIdentifier + { + extensionFound = true; + if ((0, _pvutils.isEqualBuffer)(extension.parsedValue.valueBlock.valueHex, keyIdentifier.valueBlock.valueHex)) result.push(possibleIssuer); + break; + } + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4.return != null) { + _iterator4.return(); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + if (extensionFound) return; + } + } //endregion + //region Now search for authorityCertSerialNumber + + + let authorityCertSerialNumberEqual = false; + if (authorityCertSerialNumber !== null) authorityCertSerialNumberEqual = possibleIssuer.serialNumber.isEqual(authorityCertSerialNumber); //endregion + //region And at least search for Issuer data + + if (authorityCertIssuer !== null) { + if (possibleIssuer.subject.isEqual(authorityCertIssuer)) { + if (authorityCertSerialNumberEqual) result.push(possibleIssuer); + } + } else { + if (certificate.issuer.isEqual(possibleIssuer.subject)) result.push(possibleIssuer); + } //endregion + + } //endregion + //region Search in Trusted Certificates + + + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = validationEngine.trustedCerts[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + const trustedCert = _step5.value; + checkCertificate(trustedCert); + } //endregion + //region Search in Intermediate Certificates + + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5.return != null) { + _iterator5.return(); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; + + try { + for (var _iterator6 = validationEngine.certs[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + const intermediateCert = _step6.value; + checkCertificate(intermediateCert); + } //endregion + //region Now perform certificate verification checking + + } catch (err) { + _didIteratorError6 = true; + _iteratorError6 = err; + } finally { + try { + if (!_iteratorNormalCompletion6 && _iterator6.return != null) { + _iterator6.return(); + } + } finally { + if (_didIteratorError6) { + throw _iteratorError6; + } + } + } + + for (let i = 0; i < result.length; i++) { + try { + const verificationResult = yield certificate.verify(result[i]); + if (verificationResult === false) result.splice(i, 1); + } catch (ex) { + result.splice(i, 1); // Something wrong, remove the certificate + } + } //endregion + + + return result; + })(); + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + defaultValues(memberName) { + switch (memberName) { + case "trustedCerts": + return []; + + case "certs": + return []; + + case "crls": + return []; + + case "ocsps": + return []; + + case "checkDate": + return new Date(); + + case "findOrigin": + return CertificateChainValidationEngine.defaultFindOrigin; + + case "findIssuer": + return this.defaultFindIssuer; + + default: + throw new Error(`Invalid member name for CertificateChainValidationEngine class: ${memberName}`); + } + } //********************************************************************************** + + + sort(passedWhenNotRevValues = false) { + var _this2 = this; + + return _asyncToGenerator(function* () { + //region Initial variables + const localCerts = []; + const _this = _this2; //endregion + //region Building certificate path + + function buildPath(_x) { + return _buildPath.apply(this, arguments); + } //endregion + //region Find CRL for specific certificate + + + function _buildPath() { + _buildPath = _asyncToGenerator(function* (certificate) { + const result = []; //region Aux function checking array for unique elements + + function checkUnique(array) { + let unique = true; + + for (let i = 0; i < array.length; i++) { + for (let j = 0; j < array.length; j++) { + if (j === i) continue; + + if (array[i] === array[j]) { + unique = false; + break; + } + } + + if (!unique) break; + } + + return unique; + } //endregion + + + const findIssuerResult = yield _this.findIssuer(certificate, _this); + if (findIssuerResult.length === 0) throw new Error("No valid certificate paths found"); + + for (let i = 0; i < findIssuerResult.length; i++) { + if ((0, _pvutils.isEqualBuffer)(findIssuerResult[i].tbs, certificate.tbs)) { + result.push([findIssuerResult[i]]); + continue; + } + + const buildPathResult = yield buildPath(findIssuerResult[i]); + + for (let j = 0; j < buildPathResult.length; j++) { + const copy = buildPathResult[j].slice(); + copy.splice(0, 0, findIssuerResult[i]); + if (checkUnique(copy)) result.push(copy);else result.push(buildPathResult[j]); + } + } + + return result; + }); + return _buildPath.apply(this, arguments); + } + + function findCRL(_x2) { + return _findCRL.apply(this, arguments); + } //endregion + //region Find OCSP for specific certificate + + + function _findCRL() { + _findCRL = _asyncToGenerator(function* (certificate) { + //region Initial variables + const issuerCertificates = []; + const crls = []; + const crlsAndCertificates = []; //endregion + //region Find all possible CRL issuers + + issuerCertificates.push(...localCerts.filter(element => certificate.issuer.isEqual(element.subject))); + + if (issuerCertificates.length === 0) { + return { + status: 1, + statusMessage: "No certificate's issuers" + }; + } //endregion + //region Find all CRLs for certificate's issuer + + + crls.push(..._this.crls.filter(element => element.issuer.isEqual(certificate.issuer))); + + if (crls.length === 0) { + return { + status: 2, + statusMessage: "No CRLs for specific certificate issuer" + }; + } //endregion + //region Find specific certificate of issuer for each CRL + + + for (let i = 0; i < crls.length; i++) { + //region Check "nextUpdate" for the CRL + // The "nextUpdate" is older than "checkDate". + // Thus we should do have another, updated CRL. + // Thus the CRL assumed to be invalid. + if (crls[i].nextUpdate.value < _this.checkDate) continue; //endregion + + for (let j = 0; j < issuerCertificates.length; j++) { + try { + const result = yield crls[i].verify({ + issuerCertificate: issuerCertificates[j] + }); + + if (result) { + crlsAndCertificates.push({ + crl: crls[i], + certificate: issuerCertificates[j] + }); + break; + } + } catch (ex) {} + } + } //endregion + + + if (crlsAndCertificates.length) { + return { + status: 0, + statusMessage: "", + result: crlsAndCertificates + }; + } + + return { + status: 3, + statusMessage: "No valid CRLs found" + }; + }); + return _findCRL.apply(this, arguments); + } + + function findOCSP(_x3, _x4) { + return _findOCSP.apply(this, arguments); + } //endregion + //region Check for certificate to be CA + + + function _findOCSP() { + _findOCSP = _asyncToGenerator(function* (certificate, issuerCertificate) { + //region Get hash algorithm from certificate + const hashAlgorithm = (0, _common.getAlgorithmByOID)(certificate.signatureAlgorithm.algorithmId); + if ("name" in hashAlgorithm === false) return 1; + if ("hash" in hashAlgorithm === false) return 1; //endregion + //region Search for OCSP response for the certificate + + for (let i = 0; i < _this.ocsps.length; i++) { + const result = yield _this.ocsps[i].getCertificateStatus(certificate, issuerCertificate); + + if (result.isForCertificate) { + if (result.status === 0) return 0; + return 1; + } + } //endregion + + + return 2; + }); + return _findOCSP.apply(this, arguments); + } + + function checkForCA(_x5) { + return _checkForCA.apply(this, arguments); + } //endregion + //region Basic check for certificate path + + + function _checkForCA() { + _checkForCA = _asyncToGenerator(function* (certificate, needToCheckCRL = false) { + //region Initial variables + let isCA = false; + let mustBeCA = false; + let keyUsagePresent = false; + let cRLSign = false; //endregion + + if ("extensions" in certificate) { + for (let j = 0; j < certificate.extensions.length; j++) { + if (certificate.extensions[j].critical === true && "parsedValue" in certificate.extensions[j] === false) { + return { + result: false, + resultCode: 6, + resultMessage: `Unable to parse critical certificate extension: ${certificate.extensions[j].extnID}` + }; + } + + if (certificate.extensions[j].extnID === "2.5.29.15") // KeyUsage + { + keyUsagePresent = true; + const view = new Uint8Array(certificate.extensions[j].parsedValue.valueBlock.valueHex); + if ((view[0] & 0x04) === 0x04) // Set flag "keyCertSign" + mustBeCA = true; + if ((view[0] & 0x02) === 0x02) // Set flag "cRLSign" + cRLSign = true; + } + + if (certificate.extensions[j].extnID === "2.5.29.19") // BasicConstraints + { + if ("cA" in certificate.extensions[j].parsedValue) { + if (certificate.extensions[j].parsedValue.cA === true) isCA = true; + } + } + } + + if (mustBeCA === true && isCA === false) { + return { + result: false, + resultCode: 3, + resultMessage: "Unable to build certificate chain - using \"keyCertSign\" flag set without BasicConstaints" + }; + } + + if (keyUsagePresent === true && isCA === true && mustBeCA === false) { + return { + result: false, + resultCode: 4, + resultMessage: "Unable to build certificate chain - \"keyCertSign\" flag was not set" + }; + } // noinspection OverlyComplexBooleanExpressionJS + + + if (isCA === true && keyUsagePresent === true && needToCheckCRL && cRLSign === false) { + return { + result: false, + resultCode: 5, + resultMessage: "Unable to build certificate chain - intermediate certificate must have \"cRLSign\" key usage flag" + }; + } + } + + if (isCA === false) { + return { + result: false, + resultCode: 7, + resultMessage: "Unable to build certificate chain - more than one possible end-user certificate" + }; + } + + return { + result: true, + resultCode: 0, + resultMessage: "" + }; + }); + return _checkForCA.apply(this, arguments); + } + + function basicCheck(_x6, _x7) { + return _basicCheck.apply(this, arguments); + } //endregion + //region Do main work + //region Initialize "localCerts" by value of "_this.certs" + "_this.trustedCerts" arrays + + + function _basicCheck() { + _basicCheck = _asyncToGenerator(function* (path, checkDate) { + //region Check that all dates are valid + for (let i = 0; i < path.length; i++) { + if (path[i].notBefore.value > checkDate || path[i].notAfter.value < checkDate) { + return { + result: false, + resultCode: 8, + resultMessage: "The certificate is either not yet valid or expired" + }; + } + } //endregion + //region Check certificate name chain + // We should have at least two certificates: end entity and trusted root + + + if (path.length < 2) { + return { + result: false, + resultCode: 9, + resultMessage: "Too short certificate path" + }; + } + + for (let i = path.length - 2; i >= 0; i--) { + //region Check that we do not have a "self-signed" certificate + if (path[i].issuer.isEqual(path[i].subject) === false) { + if (path[i].issuer.isEqual(path[i + 1].subject) === false) { + return { + result: false, + resultCode: 10, + resultMessage: "Incorrect name chaining" + }; + } + } //endregion + + } //endregion + //region Check each certificate (except "trusted root") to be non-revoked + + + if (_this.crls.length !== 0 || _this.ocsps.length !== 0) // If CRLs and OCSPs are empty then we consider all certificates to be valid + { + for (let i = 0; i < path.length - 1; i++) { + //region Initial variables + let ocspResult = 2; + let crlResult = { + status: 0, + statusMessage: "" + }; //endregion + //region Check OCSPs first + + if (_this.ocsps.length !== 0) { + ocspResult = yield findOCSP(path[i], path[i + 1]); + + switch (ocspResult) { + case 0: + continue; + + case 1: + return { + result: false, + resultCode: 12, + resultMessage: "One of certificates was revoked via OCSP response" + }; + + case 2: + // continue to check the certificate with CRL + break; + + default: + } + } //endregion + //region Check CRLs + + + if (_this.crls.length !== 0) { + crlResult = yield findCRL(path[i]); + + if (crlResult.status === 0) { + for (let j = 0; j < crlResult.result.length; j++) { + //region Check that the CRL issuer certificate have not been revoked + const isCertificateRevoked = crlResult.result[j].crl.isCertificateRevoked(path[i]); + + if (isCertificateRevoked) { + return { + result: false, + resultCode: 12, + resultMessage: "One of certificates had been revoked" + }; + } //endregion + //region Check that the CRL issuer certificate is a CA certificate + + + const isCertificateCA = yield checkForCA(crlResult.result[j].certificate, true); + + if (isCertificateCA.result === false) { + return { + result: false, + resultCode: 13, + resultMessage: "CRL issuer certificate is not a CA certificate or does not have crlSign flag" + }; + } //endregion + + } + } else { + if (passedWhenNotRevValues === false) { + throw { + result: false, + resultCode: 11, + resultMessage: `No revocation values found for one of certificates: ${crlResult.statusMessage}` + }; + } + } + } else { + if (ocspResult === 2) { + return { + result: false, + resultCode: 11, + resultMessage: "No revocation values found for one of certificates" + }; + } + } //endregion + //region Check we do have links to revocation values inside issuer's certificate + + + if (ocspResult === 2 && crlResult.status === 2 && passedWhenNotRevValues) { + const issuerCertificate = path[i + 1]; + let extensionFound = false; + + if ("extensions" in issuerCertificate) { + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; + + try { + for (var _iterator7 = issuerCertificate.extensions[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + const extension = _step7.value; + + switch (extension.extnID) { + case "2.5.29.31": // CRLDistributionPoints + + case "2.5.29.46": // FreshestCRL + + case "1.3.6.1.5.5.7.1.1": + // AuthorityInfoAccess + extensionFound = true; + break; + + default: + } + } + } catch (err) { + _didIteratorError7 = true; + _iteratorError7 = err; + } finally { + try { + if (!_iteratorNormalCompletion7 && _iterator7.return != null) { + _iterator7.return(); + } + } finally { + if (_didIteratorError7) { + throw _iteratorError7; + } + } + } + } + + if (extensionFound) { + throw { + result: false, + resultCode: 11, + resultMessage: `No revocation values found for one of certificates: ${crlResult.statusMessage}` + }; + } + } //endregion + + } + } //endregion + //region Check each certificate (except "end entity") in the path to be a CA certificate + + + for (let i = 1; i < path.length; i++) { + const result = yield checkForCA(path[i]); + + if (result.result === false) { + return { + result: false, + resultCode: 14, + resultMessage: "One of intermediate certificates is not a CA certificate" + }; + } + } //endregion + + + return { + result: true + }; + }); + return _basicCheck.apply(this, arguments); + } + + localCerts.push(..._this.trustedCerts); + localCerts.push(..._this.certs); //endregion + //region Check all certificates for been unique + + for (let i = 0; i < localCerts.length; i++) { + for (let j = 0; j < localCerts.length; j++) { + if (i === j) continue; + + if ((0, _pvutils.isEqualBuffer)(localCerts[i].tbs, localCerts[j].tbs)) { + localCerts.splice(j, 1); + i = 0; + break; + } + } + } //endregion + //region Initial variables + + + let result; + const certificatePath = [localCerts[localCerts.length - 1]]; // The "end entity" certificate must be the least in "certs" array + //endregion + //region Build path for "end entity" certificate + + result = yield buildPath(localCerts[localCerts.length - 1]); + + if (result.length === 0) { + return { + result: false, + resultCode: 60, + resultMessage: "Unable to find certificate path" + }; + } //endregion + //region Exclude certificate paths not ended with "trusted roots" + + + for (let i = 0; i < result.length; i++) { + let found = false; + + for (let j = 0; j < result[i].length; j++) { + const certificate = result[i][j]; + + for (let k = 0; k < _this.trustedCerts.length; k++) { + if ((0, _pvutils.isEqualBuffer)(certificate.tbs, _this.trustedCerts[k].tbs)) { + found = true; + break; + } + } + + if (found) break; + } + + if (!found) { + result.splice(i, 1); + i = 0; + } + } + + if (result.length === 0) { + throw { + result: false, + resultCode: 97, + resultMessage: "No valid certificate paths found" + }; + } //endregion + //region Find shortest certificate path (for the moment it is the only criteria) + + + let shortestLength = result[0].length; + let shortestIndex = 0; + + for (let i = 0; i < result.length; i++) { + if (result[i].length < shortestLength) { + shortestLength = result[i].length; + shortestIndex = i; + } + } //endregion + //region Create certificate path for basic check + + + for (let i = 0; i < result[shortestIndex].length; i++) certificatePath.push(result[shortestIndex][i]); //endregion + //region Perform basic checking for all certificates in the path + + + result = yield basicCheck(certificatePath, _this.checkDate); + if (result.result === false) throw result; //endregion + + return certificatePath; //endregion + })(); + } //********************************************************************************** + + /** + * Major verification function for certificate chain. + * @param {{initialPolicySet, initialExplicitPolicy, initialPolicyMappingInhibit, initialInhibitPolicy, initialPermittedSubtreesSet, initialExcludedSubtreesSet, initialRequiredNameForms}} [parameters] + * @returns {Promise} + */ + + + verify(parameters = {}) { + var _this3 = this; + + return _asyncToGenerator(function* () { + //region Auxiliary functions for name constraints checking + function compareDNSName(name, constraint) { + /// Compare two dNSName values + /// DNS from name + /// Constraint for DNS from name + /// Boolean result - valid or invalid the "name" against the "constraint" + //region Make a "string preparation" for both name and constrain + const namePrepared = (0, _common.stringPrep)(name); + const constraintPrepared = (0, _common.stringPrep)(constraint); //endregion + //region Make a "splitted" versions of "constraint" and "name" + + const nameSplitted = namePrepared.split("."); + const constraintSplitted = constraintPrepared.split("."); //endregion + //region Length calculation and additional check + + const nameLen = nameSplitted.length; + const constrLen = constraintSplitted.length; + if (nameLen === 0 || constrLen === 0 || nameLen < constrLen) return false; //endregion + //region Check that no part of "name" has zero length + + for (let i = 0; i < nameLen; i++) { + if (nameSplitted[i].length === 0) return false; + } //endregion + //region Check that no part of "constraint" has zero length + + + for (let i = 0; i < constrLen; i++) { + if (constraintSplitted[i].length === 0) { + if (i === 0) { + if (constrLen === 1) return false; + continue; + } + + return false; + } + } //endregion + //region Check that "name" has a tail as "constraint" + + + for (let i = 0; i < constrLen; i++) { + if (constraintSplitted[constrLen - 1 - i].length === 0) continue; + if (nameSplitted[nameLen - 1 - i].localeCompare(constraintSplitted[constrLen - 1 - i]) !== 0) return false; + } //endregion + + + return true; + } + + function compareRFC822Name(name, constraint) { + /// Compare two rfc822Name values + /// E-mail address from name + /// Constraint for e-mail address from name + /// Boolean result - valid or invalid the "name" against the "constraint" + //region Make a "string preparation" for both name and constrain + const namePrepared = (0, _common.stringPrep)(name); + const constraintPrepared = (0, _common.stringPrep)(constraint); //endregion + //region Make a "splitted" versions of "constraint" and "name" + + const nameSplitted = namePrepared.split("@"); + const constraintSplitted = constraintPrepared.split("@"); //endregion + //region Splitted array length checking + + if (nameSplitted.length === 0 || constraintSplitted.length === 0 || nameSplitted.length < constraintSplitted.length) return false; //endregion + + if (constraintSplitted.length === 1) { + const result = compareDNSName(nameSplitted[1], constraintSplitted[0]); + + if (result) { + //region Make a "splitted" versions of domain name from "constraint" and "name" + const ns = nameSplitted[1].split("."); + const cs = constraintSplitted[0].split("."); //endregion + + if (cs[0].length === 0) return true; + return ns.length === cs.length; + } + + return false; + } + + return namePrepared.localeCompare(constraintPrepared) === 0; + } + + function compareUniformResourceIdentifier(name, constraint) { + /// Compare two uniformResourceIdentifier values + /// uniformResourceIdentifier from name + /// Constraint for uniformResourceIdentifier from name + /// Boolean result - valid or invalid the "name" against the "constraint" + //region Make a "string preparation" for both name and constrain + let namePrepared = (0, _common.stringPrep)(name); + const constraintPrepared = (0, _common.stringPrep)(constraint); //endregion + //region Find out a major URI part to compare with + + const ns = namePrepared.split("/"); + const cs = constraintPrepared.split("/"); + if (cs.length > 1) // Malformed constraint + return false; + + if (ns.length > 1) // Full URI string + { + for (let i = 0; i < ns.length; i++) { + if (ns[i].length > 0 && ns[i].charAt(ns[i].length - 1) !== ":") { + const nsPort = ns[i].split(":"); + namePrepared = nsPort[0]; + break; + } + } + } //endregion + + + const result = compareDNSName(namePrepared, constraintPrepared); + + if (result) { + //region Make a "splitted" versions of "constraint" and "name" + const nameSplitted = namePrepared.split("."); + const constraintSplitted = constraintPrepared.split("."); //endregion + + if (constraintSplitted[0].length === 0) return true; + return nameSplitted.length === constraintSplitted.length; + } + + return false; + } + + function compareIPAddress(name, constraint) { + /// Compare two iPAddress values + /// iPAddress from name + /// Constraint for iPAddress from name + /// Boolean result - valid or invalid the "name" against the "constraint" + //region Common variables + const nameView = new Uint8Array(name.valueBlock.valueHex); + const constraintView = new Uint8Array(constraint.valueBlock.valueHex); //endregion + //region Work with IPv4 addresses + + if (nameView.length === 4 && constraintView.length === 8) { + for (let i = 0; i < 4; i++) { + if ((nameView[i] ^ constraintView[i]) & constraintView[i + 4]) return false; + } + + return true; + } //endregion + //region Work with IPv6 addresses + + + if (nameView.length === 16 && constraintView.length === 32) { + for (let i = 0; i < 16; i++) { + if ((nameView[i] ^ constraintView[i]) & constraintView[i + 16]) return false; + } + + return true; + } //endregion + + + return false; + } + + function compareDirectoryName(name, constraint) { + /// Compare two directoryName values + /// directoryName from name + /// Constraint for directoryName from name + /// Boolean flag - should be comparision interrupted after first match or we need to match all "constraints" parts + /// Boolean result - valid or invalid the "name" against the "constraint" + //region Initial check + if (name.typesAndValues.length === 0 || constraint.typesAndValues.length === 0) return true; + if (name.typesAndValues.length < constraint.typesAndValues.length) return false; //endregion + //region Initial variables + + let result = true; + let nameStart = 0; //endregion + + for (let i = 0; i < constraint.typesAndValues.length; i++) { + let localResult = false; + + for (let j = nameStart; j < name.typesAndValues.length; j++) { + localResult = name.typesAndValues[j].isEqual(constraint.typesAndValues[i]); + if (name.typesAndValues[j].type === constraint.typesAndValues[i].type) result = result && localResult; + + if (localResult === true) { + if (nameStart === 0 || nameStart === j) { + nameStart = j + 1; + break; + } else // Structure of "name" must be the same with "constraint" + return false; + } + } + + if (localResult === false) return false; + } + + return nameStart === 0 ? false : result; + } //endregion + + + try { + //region Initial checks + if (_this3.certs.length === 0) throw "Empty certificate array"; //endregion + //region Get input variables + + let passedWhenNotRevValues = false; + if ("passedWhenNotRevValues" in parameters) passedWhenNotRevValues = parameters.passedWhenNotRevValues; + let initialPolicySet = []; + initialPolicySet.push("2.5.29.32.0"); // "anyPolicy" + + let initialExplicitPolicy = false; + let initialPolicyMappingInhibit = false; + let initialInhibitPolicy = false; + let initialPermittedSubtreesSet = []; // Array of "simpl.x509.GeneralSubtree" + + let initialExcludedSubtreesSet = []; // Array of "simpl.x509.GeneralSubtree" + + let initialRequiredNameForms = []; // Array of "simpl.x509.GeneralSubtree" + + if ("initialPolicySet" in parameters) initialPolicySet = parameters.initialPolicySet; + if ("initialExplicitPolicy" in parameters) initialExplicitPolicy = parameters.initialExplicitPolicy; + if ("initialPolicyMappingInhibit" in parameters) initialPolicyMappingInhibit = parameters.initialPolicyMappingInhibit; + if ("initialInhibitPolicy" in parameters) initialInhibitPolicy = parameters.initialInhibitPolicy; + if ("initialPermittedSubtreesSet" in parameters) initialPermittedSubtreesSet = parameters.initialPermittedSubtreesSet; + if ("initialExcludedSubtreesSet" in parameters) initialExcludedSubtreesSet = parameters.initialExcludedSubtreesSet; + if ("initialRequiredNameForms" in parameters) initialRequiredNameForms = parameters.initialRequiredNameForms; + let explicitPolicyIndicator = initialExplicitPolicy; + let policyMappingInhibitIndicator = initialPolicyMappingInhibit; + let inhibitAnyPolicyIndicator = initialInhibitPolicy; + const pendingConstraints = new Array(3); + pendingConstraints[0] = false; // For "explicitPolicyPending" + + pendingConstraints[1] = false; // For "policyMappingInhibitPending" + + pendingConstraints[2] = false; // For "inhibitAnyPolicyPending" + + let explicitPolicyPending = 0; + let policyMappingInhibitPending = 0; + let inhibitAnyPolicyPending = 0; + let permittedSubtrees = initialPermittedSubtreesSet; + let excludedSubtrees = initialExcludedSubtreesSet; + const requiredNameForms = initialRequiredNameForms; + let pathDepth = 1; //endregion + //region Sorting certificates in the chain array + + _this3.certs = yield _this3.sort(passedWhenNotRevValues); //endregion + //region Work with policies + //region Support variables + + const allPolicies = []; // Array of all policies (string values) + + allPolicies.push("2.5.29.32.0"); // Put "anyPolicy" at first place + + const policiesAndCerts = []; // In fact "array of array" where rows are for each specific policy, column for each certificate and value is "true/false" + + const anyPolicyArray = new Array(_this3.certs.length - 1); // Minus "trusted anchor" + + for (let ii = 0; ii < _this3.certs.length - 1; ii++) anyPolicyArray[ii] = true; + + policiesAndCerts.push(anyPolicyArray); + const policyMappings = new Array(_this3.certs.length - 1); // Array of "PolicyMappings" for each certificate + + const certPolicies = new Array(_this3.certs.length - 1); // Array of "CertificatePolicies" for each certificate + + let explicitPolicyStart = explicitPolicyIndicator ? _this3.certs.length - 1 : -1; //endregion + //region Gather all neccessary information from certificate chain + + for (let i = _this3.certs.length - 2; i >= 0; i--, pathDepth++) { + if ("extensions" in _this3.certs[i]) { + //region Get information about certificate extensions + for (let j = 0; j < _this3.certs[i].extensions.length; j++) { + //region CertificatePolicies + if (_this3.certs[i].extensions[j].extnID === "2.5.29.32") { + certPolicies[i] = _this3.certs[i].extensions[j].parsedValue; //region Remove entry from "anyPolicies" for the certificate + + for (let s = 0; s < allPolicies.length; s++) { + if (allPolicies[s] === "2.5.29.32.0") { + delete policiesAndCerts[s][i]; + break; + } + } //endregion + + + for (let k = 0; k < _this3.certs[i].extensions[j].parsedValue.certificatePolicies.length; k++) { + let policyIndex = -1; //region Try to find extension in "allPolicies" array + + for (let s = 0; s < allPolicies.length; s++) { + if (_this3.certs[i].extensions[j].parsedValue.certificatePolicies[k].policyIdentifier === allPolicies[s]) { + policyIndex = s; + break; + } + } //endregion + + + if (policyIndex === -1) { + allPolicies.push(_this3.certs[i].extensions[j].parsedValue.certificatePolicies[k].policyIdentifier); + const certArray = new Array(_this3.certs.length - 1); + certArray[i] = true; + policiesAndCerts.push(certArray); + } else policiesAndCerts[policyIndex][i] = true; + } + } //endregion + //region PolicyMappings + + + if (_this3.certs[i].extensions[j].extnID === "2.5.29.33") { + if (policyMappingInhibitIndicator) { + return { + result: false, + resultCode: 98, + resultMessage: "Policy mapping prohibited" + }; + } + + policyMappings[i] = _this3.certs[i].extensions[j].parsedValue; + } //endregion + //region PolicyConstraints + + + if (_this3.certs[i].extensions[j].extnID === "2.5.29.36") { + if (explicitPolicyIndicator === false) { + //region requireExplicitPolicy + if (_this3.certs[i].extensions[j].parsedValue.requireExplicitPolicy === 0) { + explicitPolicyIndicator = true; + explicitPolicyStart = i; + } else { + if (pendingConstraints[0] === false) { + pendingConstraints[0] = true; + explicitPolicyPending = _this3.certs[i].extensions[j].parsedValue.requireExplicitPolicy; + } else explicitPolicyPending = explicitPolicyPending > _this3.certs[i].extensions[j].parsedValue.requireExplicitPolicy ? _this3.certs[i].extensions[j].parsedValue.requireExplicitPolicy : explicitPolicyPending; + } //endregion + //region inhibitPolicyMapping + + + if (_this3.certs[i].extensions[j].parsedValue.inhibitPolicyMapping === 0) policyMappingInhibitIndicator = true;else { + if (pendingConstraints[1] === false) { + pendingConstraints[1] = true; + policyMappingInhibitPending = _this3.certs[i].extensions[j].parsedValue.inhibitPolicyMapping + 1; + } else policyMappingInhibitPending = policyMappingInhibitPending > _this3.certs[i].extensions[j].parsedValue.inhibitPolicyMapping + 1 ? _this3.certs[i].extensions[j].parsedValue.inhibitPolicyMapping + 1 : policyMappingInhibitPending; + } //endregion + } + } //endregion + //region InhibitAnyPolicy + + + if (_this3.certs[i].extensions[j].extnID === "2.5.29.54") { + if (inhibitAnyPolicyIndicator === false) { + if (_this3.certs[i].extensions[j].parsedValue.valueBlock.valueDec === 0) inhibitAnyPolicyIndicator = true;else { + if (pendingConstraints[2] === false) { + pendingConstraints[2] = true; + inhibitAnyPolicyPending = _this3.certs[i].extensions[j].parsedValue.valueBlock.valueDec; + } else inhibitAnyPolicyPending = inhibitAnyPolicyPending > _this3.certs[i].extensions[j].parsedValue.valueBlock.valueDec ? _this3.certs[i].extensions[j].parsedValue.valueBlock.valueDec : inhibitAnyPolicyPending; + } + } + } //endregion + + } //endregion + //region Check "inhibitAnyPolicyIndicator" + + + if (inhibitAnyPolicyIndicator === true) { + let policyIndex = -1; //region Find "anyPolicy" index + + for (let searchAnyPolicy = 0; searchAnyPolicy < allPolicies.length; searchAnyPolicy++) { + if (allPolicies[searchAnyPolicy] === "2.5.29.32.0") { + policyIndex = searchAnyPolicy; + break; + } + } //endregion + + + if (policyIndex !== -1) delete policiesAndCerts[0][i]; // Unset value to "undefined" for "anyPolicies" value for current certificate + } //endregion + //region Process with "pending constraints" + + + if (explicitPolicyIndicator === false) { + if (pendingConstraints[0] === true) { + explicitPolicyPending--; + + if (explicitPolicyPending === 0) { + explicitPolicyIndicator = true; + explicitPolicyStart = i; + pendingConstraints[0] = false; + } + } + } + + if (policyMappingInhibitIndicator === false) { + if (pendingConstraints[1] === true) { + policyMappingInhibitPending--; + + if (policyMappingInhibitPending === 0) { + policyMappingInhibitIndicator = true; + pendingConstraints[1] = false; + } + } + } + + if (inhibitAnyPolicyIndicator === false) { + if (pendingConstraints[2] === true) { + inhibitAnyPolicyPending--; + + if (inhibitAnyPolicyPending === 0) { + inhibitAnyPolicyIndicator = true; + pendingConstraints[2] = false; + } + } + } //endregion + + } + } //endregion + //region Working with policy mappings + + + for (let i = 0; i < _this3.certs.length - 1; i++) { + //region Check that there is "policy mapping" for level "i + 1" + if (i < _this3.certs.length - 2 && typeof policyMappings[i + 1] !== "undefined") { + for (let k = 0; k < policyMappings[i + 1].mappings.length; k++) { + //region Check that we do not have "anyPolicy" in current mapping + if (policyMappings[i + 1].mappings[k].issuerDomainPolicy === "2.5.29.32.0" || policyMappings[i + 1].mappings[k].subjectDomainPolicy === "2.5.29.32.0") { + return { + result: false, + resultCode: 99, + resultMessage: "The \"anyPolicy\" should not be a part of policy mapping scheme" + }; + } //endregion + //region Initial variables + + + let issuerDomainPolicyIndex = -1; + let subjectDomainPolicyIndex = -1; //endregion + //region Search for index of policies indedes + + for (let n = 0; n < allPolicies.length; n++) { + if (allPolicies[n] === policyMappings[i + 1].mappings[k].issuerDomainPolicy) issuerDomainPolicyIndex = n; + if (allPolicies[n] === policyMappings[i + 1].mappings[k].subjectDomainPolicy) subjectDomainPolicyIndex = n; + } //endregion + //region Delete existing "issuerDomainPolicy" because on the level we mapped the policy to another one + + + if (typeof policiesAndCerts[issuerDomainPolicyIndex][i] !== "undefined") delete policiesAndCerts[issuerDomainPolicyIndex][i]; //endregion + //region Check all policies for the certificate + + for (let j = 0; j < certPolicies[i].certificatePolicies.length; j++) { + if (policyMappings[i + 1].mappings[k].subjectDomainPolicy === certPolicies[i].certificatePolicies[j].policyIdentifier) { + //region Set mapped policy for current certificate + if (issuerDomainPolicyIndex !== -1 && subjectDomainPolicyIndex !== -1) { + for (let m = 0; m <= i; m++) { + if (typeof policiesAndCerts[subjectDomainPolicyIndex][m] !== "undefined") { + policiesAndCerts[issuerDomainPolicyIndex][m] = true; + delete policiesAndCerts[subjectDomainPolicyIndex][m]; + } + } + } //endregion + + } + } //endregion + + } + } //endregion + + } //endregion + //region Working with "explicitPolicyIndicator" and "anyPolicy" + + + for (let i = 0; i < allPolicies.length; i++) { + if (allPolicies[i] === "2.5.29.32.0") { + for (let j = 0; j < explicitPolicyStart; j++) delete policiesAndCerts[i][j]; + } + } //endregion + //region Create "set of authorities-constrained policies" + + + const authConstrPolicies = []; + + for (let i = 0; i < policiesAndCerts.length; i++) { + let found = true; + + for (let j = 0; j < _this3.certs.length - 1; j++) { + let anyPolicyFound = false; + + if (j < explicitPolicyStart && allPolicies[i] === "2.5.29.32.0" && allPolicies.length > 1) { + found = false; + break; + } + + if (typeof policiesAndCerts[i][j] === "undefined") { + if (j >= explicitPolicyStart) { + //region Search for "anyPolicy" in the policy set + for (let k = 0; k < allPolicies.length; k++) { + if (allPolicies[k] === "2.5.29.32.0") { + if (policiesAndCerts[k][j] === true) anyPolicyFound = true; + break; + } + } //endregion + + } + + if (!anyPolicyFound) { + found = false; + break; + } + } + } + + if (found === true) authConstrPolicies.push(allPolicies[i]); + } //endregion + //region Create "set of user-constrained policies" + + + let userConstrPolicies = []; + if (initialPolicySet.length === 1 && initialPolicySet[0] === "2.5.29.32.0" && explicitPolicyIndicator === false) userConstrPolicies = initialPolicySet;else { + if (authConstrPolicies.length === 1 && authConstrPolicies[0] === "2.5.29.32.0") userConstrPolicies = initialPolicySet;else { + for (let i = 0; i < authConstrPolicies.length; i++) { + for (let j = 0; j < initialPolicySet.length; j++) { + if (initialPolicySet[j] === authConstrPolicies[i] || initialPolicySet[j] === "2.5.29.32.0") { + userConstrPolicies.push(authConstrPolicies[i]); + break; + } + } + } + } + } //endregion + //region Combine output object + + const policyResult = { + result: userConstrPolicies.length > 0, + resultCode: 0, + resultMessage: userConstrPolicies.length > 0 ? "" : "Zero \"userConstrPolicies\" array, no intersections with \"authConstrPolicies\"", + authConstrPolicies, + userConstrPolicies, + explicitPolicyIndicator, + policyMappings, + certificatePath: _this3.certs + }; + if (userConstrPolicies.length === 0) return policyResult; //endregion + //endregion + //region Work with name constraints + //region Check a result from "policy checking" part + + if (policyResult.result === false) return policyResult; //endregion + //region Check all certificates, excluding "trust anchor" + + pathDepth = 1; + + for (let i = _this3.certs.length - 2; i >= 0; i--, pathDepth++) { + //region Support variables + let subjectAltNames = []; + let certPermittedSubtrees = []; + let certExcludedSubtrees = []; //endregion + + if ("extensions" in _this3.certs[i]) { + for (let j = 0; j < _this3.certs[i].extensions.length; j++) { + //region NameConstraints + if (_this3.certs[i].extensions[j].extnID === "2.5.29.30") { + if ("permittedSubtrees" in _this3.certs[i].extensions[j].parsedValue) certPermittedSubtrees = certPermittedSubtrees.concat(_this3.certs[i].extensions[j].parsedValue.permittedSubtrees); + if ("excludedSubtrees" in _this3.certs[i].extensions[j].parsedValue) certExcludedSubtrees = certExcludedSubtrees.concat(_this3.certs[i].extensions[j].parsedValue.excludedSubtrees); + } //endregion + //region SubjectAltName + + + if (_this3.certs[i].extensions[j].extnID === "2.5.29.17") subjectAltNames = subjectAltNames.concat(_this3.certs[i].extensions[j].parsedValue.altNames); //endregion + } + } //region Checking for "required name forms" + + + let formFound = requiredNameForms.length <= 0; + + for (let j = 0; j < requiredNameForms.length; j++) { + switch (requiredNameForms[j].base.type) { + case 4: + // directoryName + { + if (requiredNameForms[j].base.value.typesAndValues.length !== _this3.certs[i].subject.typesAndValues.length) continue; + formFound = true; + + for (let k = 0; k < _this3.certs[i].subject.typesAndValues.length; k++) { + if (_this3.certs[i].subject.typesAndValues[k].type !== requiredNameForms[j].base.value.typesAndValues[k].type) { + formFound = false; + break; + } + } + + if (formFound === true) break; + } + break; + + default: // ??? Probably here we should reject the certificate ??? + + } + } + + if (formFound === false) { + policyResult.result = false; + policyResult.resultCode = 21; + policyResult.resultMessage = "No neccessary name form found"; + throw policyResult; + } //endregion + //region Checking for "permited sub-trees" + //region Make groups for all types of constraints + + + const constrGroups = []; // Array of array for groupped constraints + + constrGroups[0] = []; // rfc822Name + + constrGroups[1] = []; // dNSName + + constrGroups[2] = []; // directoryName + + constrGroups[3] = []; // uniformResourceIdentifier + + constrGroups[4] = []; // iPAddress + + for (let j = 0; j < permittedSubtrees.length; j++) { + switch (permittedSubtrees[j].base.type) { + //region rfc822Name + case 1: + constrGroups[0].push(permittedSubtrees[j]); + break; + //endregion + //region dNSName + + case 2: + constrGroups[1].push(permittedSubtrees[j]); + break; + //endregion + //region directoryName + + case 4: + constrGroups[2].push(permittedSubtrees[j]); + break; + //endregion + //region uniformResourceIdentifier + + case 6: + constrGroups[3].push(permittedSubtrees[j]); + break; + //endregion + //region iPAddress + + case 7: + constrGroups[4].push(permittedSubtrees[j]); + break; + //endregion + //region default + + default: //endregion + + } + } //endregion + //region Check name constraints groupped by type, one-by-one + + + for (let p = 0; p < 5; p++) { + let groupPermitted = false; + let valueExists = false; + const group = constrGroups[p]; + + for (let j = 0; j < group.length; j++) { + switch (p) { + //region rfc822Name + case 0: + if (subjectAltNames.length > 0) { + for (let k = 0; k < subjectAltNames.length; k++) { + if (subjectAltNames[k].type === 1) // rfc822Name + { + valueExists = true; + groupPermitted = groupPermitted || compareRFC822Name(subjectAltNames[k].value, group[j].base.value); + } + } + } else // Try to find out "emailAddress" inside "subject" + { + for (let k = 0; k < _this3.certs[i].subject.typesAndValues.length; k++) { + if (_this3.certs[i].subject.typesAndValues[k].type === "1.2.840.113549.1.9.1" || // PKCS#9 e-mail address + _this3.certs[i].subject.typesAndValues[k].type === "0.9.2342.19200300.100.1.3") // RFC1274 "rfc822Mailbox" e-mail address + { + valueExists = true; + groupPermitted = groupPermitted || compareRFC822Name(_this3.certs[i].subject.typesAndValues[k].value.valueBlock.value, group[j].base.value); + } + } + } + + break; + //endregion + //region dNSName + + case 1: + if (subjectAltNames.length > 0) { + for (let k = 0; k < subjectAltNames.length; k++) { + if (subjectAltNames[k].type === 2) // dNSName + { + valueExists = true; + groupPermitted = groupPermitted || compareDNSName(subjectAltNames[k].value, group[j].base.value); + } + } + } + + break; + //endregion + //region directoryName + + case 2: + valueExists = true; + groupPermitted = compareDirectoryName(_this3.certs[i].subject, group[j].base.value); + break; + //endregion + //region uniformResourceIdentifier + + case 3: + if (subjectAltNames.length > 0) { + for (let k = 0; k < subjectAltNames.length; k++) { + if (subjectAltNames[k].type === 6) // uniformResourceIdentifier + { + valueExists = true; + groupPermitted = groupPermitted || compareUniformResourceIdentifier(subjectAltNames[k].value, group[j].base.value); + } + } + } + + break; + //endregion + //region iPAddress + + case 4: + if (subjectAltNames.length > 0) { + for (let k = 0; k < subjectAltNames.length; k++) { + if (subjectAltNames[k].type === 7) // iPAddress + { + valueExists = true; + groupPermitted = groupPermitted || compareIPAddress(subjectAltNames[k].value, group[j].base.value); + } + } + } + + break; + //endregion + //region default + + default: //endregion + + } + + if (groupPermitted) break; + } + + if (groupPermitted === false && group.length > 0 && valueExists) { + policyResult.result = false; + policyResult.resultCode = 41; + policyResult.resultMessage = "Failed to meet \"permitted sub-trees\" name constraint"; + throw policyResult; + } + } //endregion + //endregion + //region Checking for "excluded sub-trees" + + + let excluded = false; + + for (let j = 0; j < excludedSubtrees.length; j++) { + switch (excludedSubtrees[j].base.type) { + //region rfc822Name + case 1: + if (subjectAltNames.length >= 0) { + for (let k = 0; k < subjectAltNames.length; k++) { + if (subjectAltNames[k].type === 1) // rfc822Name + excluded = excluded || compareRFC822Name(subjectAltNames[k].value, excludedSubtrees[j].base.value); + } + } else // Try to find out "emailAddress" inside "subject" + { + for (let k = 0; k < _this3.certs[i].subject.typesAndValues.length; k++) { + if (_this3.certs[i].subject.typesAndValues[k].type === "1.2.840.113549.1.9.1" || // PKCS#9 e-mail address + _this3.certs[i].subject.typesAndValues[k].type === "0.9.2342.19200300.100.1.3") // RFC1274 "rfc822Mailbox" e-mail address + excluded = excluded || compareRFC822Name(_this3.certs[i].subject.typesAndValues[k].value.valueBlock.value, excludedSubtrees[j].base.value); + } + } + + break; + //endregion + //region dNSName + + case 2: + if (subjectAltNames.length > 0) { + for (let k = 0; k < subjectAltNames.length; k++) { + if (subjectAltNames[k].type === 2) // dNSName + excluded = excluded || compareDNSName(subjectAltNames[k].value, excludedSubtrees[j].base.value); + } + } + + break; + //endregion + //region directoryName + + case 4: + excluded = excluded || compareDirectoryName(_this3.certs[i].subject, excludedSubtrees[j].base.value); + break; + //endregion + //region uniformResourceIdentifier + + case 6: + if (subjectAltNames.length > 0) { + for (let k = 0; k < subjectAltNames.length; k++) { + if (subjectAltNames[k].type === 6) // uniformResourceIdentifier + excluded = excluded || compareUniformResourceIdentifier(subjectAltNames[k].value, excludedSubtrees[j].base.value); + } + } + + break; + //endregion + //region iPAddress + + case 7: + if (subjectAltNames.length > 0) { + for (let k = 0; k < subjectAltNames.length; k++) { + if (subjectAltNames[k].type === 7) // iPAddress + excluded = excluded || compareIPAddress(subjectAltNames[k].value, excludedSubtrees[j].base.value); + } + } + + break; + //endregion + //region default + + default: // No action, but probably here we need to create a warning for "malformed constraint" + //endregion + + } + + if (excluded) break; + } + + if (excluded === true) { + policyResult.result = false; + policyResult.resultCode = 42; + policyResult.resultMessage = "Failed to meet \"excluded sub-trees\" name constraint"; + throw policyResult; + } //endregion + //region Append "cert_..._subtrees" to "..._subtrees" + + + permittedSubtrees = permittedSubtrees.concat(certPermittedSubtrees); + excludedSubtrees = excludedSubtrees.concat(certExcludedSubtrees); //endregion + } //endregion + + + return policyResult; //endregion + } catch (error) { + if (error instanceof Object) { + if ("resultMessage" in error) return error; + + if ("message" in error) { + return { + result: false, + resultCode: -1, + resultMessage: error.message + }; + } + } + + return { + result: false, + resultCode: -1, + resultMessage: error + }; + } + })(); + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = CertificateChainValidationEngine; + +},{"./common.js":110,"pvutils":113}],21:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _PolicyInformation = _interopRequireDefault(require("./PolicyInformation.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class CertificatePolicies { + //********************************************************************************** + + /** + * Constructor for CertificatePolicies class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc certificatePolicies + */ + this.certificatePolicies = (0, _pvutils.getParametersValue)(parameters, "certificatePolicies", CertificatePolicies.defaultValues("certificatePolicies")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "certificatePolicies": + return []; + + default: + throw new Error(`Invalid member name for CertificatePolicies class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [certificatePolicies] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.certificatePolicies || "", + value: _PolicyInformation.default.schema() + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["certificatePolicies"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, CertificatePolicies.schema({ + names: { + certificatePolicies: "certificatePolicies" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for CertificatePolicies"); //endregion + //region Get internal properties from parsed schema + + this.certificatePolicies = Array.from(asn1.result.certificatePolicies, element => new _PolicyInformation.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: Array.from(this.certificatePolicies, element => element.toSchema()) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + certificatePolicies: Array.from(this.certificatePolicies, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = CertificatePolicies; + +},{"./PolicyInformation.js":72,"asn1js":112,"pvutils":113}],22:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _common = require("./common.js"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _RelativeDistinguishedNames = _interopRequireDefault(require("./RelativeDistinguishedNames.js")); + +var _Time = _interopRequireDefault(require("./Time.js")); + +var _RevokedCertificate = _interopRequireDefault(require("./RevokedCertificate.js")); + +var _Extensions = _interopRequireDefault(require("./Extensions.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** +function tbsCertList(parameters = {}) { + //TBSCertList ::= SEQUENCE { + // version Version OPTIONAL, + // -- if present, MUST be v2 + // signature AlgorithmIdentifier, + // issuer Name, + // thisUpdate Time, + // nextUpdate Time OPTIONAL, + // revokedCertificates SEQUENCE OF SEQUENCE { + // userCertificate CertificateSerialNumber, + // revocationDate Time, + // crlEntryExtensions Extensions OPTIONAL + // -- if present, version MUST be v2 + // } OPTIONAL, + // crlExtensions [0] EXPLICIT Extensions OPTIONAL + // -- if present, version MUST be v2 + //} + + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [tbsCertListVersion] + * @property {string} [signature] + * @property {string} [issuer] + * @property {string} [tbsCertListThisUpdate] + * @property {string} [tbsCertListNextUpdate] + * @property {string} [tbsCertListRevokedCertificates] + * @property {string} [crlExtensions] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "tbsCertList", + value: [new asn1js.Integer({ + optional: true, + name: names.tbsCertListVersion || "tbsCertList.version", + value: 2 + }), // EXPLICIT integer value (v2) + _AlgorithmIdentifier.default.schema(names.signature || { + names: { + blockName: "tbsCertList.signature" + } + }), _RelativeDistinguishedNames.default.schema(names.issuer || { + names: { + blockName: "tbsCertList.issuer" + } + }), _Time.default.schema(names.tbsCertListThisUpdate || { + names: { + utcTimeName: "tbsCertList.thisUpdate", + generalTimeName: "tbsCertList.thisUpdate" + } + }), _Time.default.schema(names.tbsCertListNextUpdate || { + names: { + utcTimeName: "tbsCertList.nextUpdate", + generalTimeName: "tbsCertList.nextUpdate" + } + }, true), new asn1js.Sequence({ + optional: true, + value: [new asn1js.Repeated({ + name: names.tbsCertListRevokedCertificates || "tbsCertList.revokedCertificates", + value: new asn1js.Sequence({ + value: [new asn1js.Integer(), _Time.default.schema(), _Extensions.default.schema({}, true)] + }) + })] + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [_Extensions.default.schema(names.crlExtensions || { + names: { + blockName: "tbsCertList.extensions" + } + })] + }) // EXPLICIT SEQUENCE value + ] + }); +} //************************************************************************************** + +/** + * Class from RFC5280 + */ + + +class CertificateRevocationList { + //********************************************************************************** + + /** + * Constructor for Attribute class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {ArrayBuffer} + * @desc tbs + */ + this.tbs = (0, _pvutils.getParametersValue)(parameters, "tbs", CertificateRevocationList.defaultValues("tbs")); + /** + * @type {number} + * @desc version + */ + + this.version = (0, _pvutils.getParametersValue)(parameters, "version", CertificateRevocationList.defaultValues("version")); + /** + * @type {AlgorithmIdentifier} + * @desc signature + */ + + this.signature = (0, _pvutils.getParametersValue)(parameters, "signature", CertificateRevocationList.defaultValues("signature")); + /** + * @type {RelativeDistinguishedNames} + * @desc issuer + */ + + this.issuer = (0, _pvutils.getParametersValue)(parameters, "issuer", CertificateRevocationList.defaultValues("issuer")); + /** + * @type {Time} + * @desc thisUpdate + */ + + this.thisUpdate = (0, _pvutils.getParametersValue)(parameters, "thisUpdate", CertificateRevocationList.defaultValues("thisUpdate")); + if ("nextUpdate" in parameters) + /** + * @type {Time} + * @desc nextUpdate + */ + this.nextUpdate = (0, _pvutils.getParametersValue)(parameters, "nextUpdate", CertificateRevocationList.defaultValues("nextUpdate")); + if ("revokedCertificates" in parameters) + /** + * @type {Array.} + * @desc revokedCertificates + */ + this.revokedCertificates = (0, _pvutils.getParametersValue)(parameters, "revokedCertificates", CertificateRevocationList.defaultValues("revokedCertificates")); + if ("crlExtensions" in parameters) + /** + * @type {Extensions} + * @desc crlExtensions + */ + this.crlExtensions = (0, _pvutils.getParametersValue)(parameters, "crlExtensions", CertificateRevocationList.defaultValues("crlExtensions")); + /** + * @type {AlgorithmIdentifier} + * @desc signatureAlgorithm + */ + + this.signatureAlgorithm = (0, _pvutils.getParametersValue)(parameters, "signatureAlgorithm", CertificateRevocationList.defaultValues("signatureAlgorithm")); + /** + * @type {BitString} + * @desc signatureValue + */ + + this.signatureValue = (0, _pvutils.getParametersValue)(parameters, "signatureValue", CertificateRevocationList.defaultValues("signatureValue")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "tbs": + return new ArrayBuffer(0); + + case "version": + return 1; + + case "signature": + return new _AlgorithmIdentifier.default(); + + case "issuer": + return new _RelativeDistinguishedNames.default(); + + case "thisUpdate": + return new _Time.default(); + + case "nextUpdate": + return new _Time.default(); + + case "revokedCertificates": + return []; + + case "crlExtensions": + return new _Extensions.default(); + + case "signatureAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "signatureValue": + return new asn1js.BitString(); + + default: + throw new Error(`Invalid member name for CertificateRevocationList class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * CertificateList ::= SEQUENCE { + * tbsCertList TBSCertList, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [signatureAlgorithm] + * @property {string} [signatureValue] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "CertificateList", + value: [tbsCertList(parameters), _AlgorithmIdentifier.default.schema(names.signatureAlgorithm || { + names: { + blockName: "signatureAlgorithm" + } + }), new asn1js.BitString({ + name: names.signatureValue || "signatureValue" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["tbsCertList", "tbsCertList.version", "tbsCertList.signature", "tbsCertList.issuer", "tbsCertList.thisUpdate", "tbsCertList.nextUpdate", "tbsCertList.revokedCertificates", "tbsCertList.extensions", "signatureAlgorithm", "signatureValue"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, CertificateRevocationList.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for CertificateRevocationList"); //endregion + //region Get internal properties from parsed schema + // noinspection JSUnresolvedVariable + + this.tbs = asn1.result.tbsCertList.valueBeforeDecode; + if ("tbsCertList.version" in asn1.result) this.version = asn1.result["tbsCertList.version"].valueBlock.valueDec; + this.signature = new _AlgorithmIdentifier.default({ + schema: asn1.result["tbsCertList.signature"] + }); + this.issuer = new _RelativeDistinguishedNames.default({ + schema: asn1.result["tbsCertList.issuer"] + }); + this.thisUpdate = new _Time.default({ + schema: asn1.result["tbsCertList.thisUpdate"] + }); + if ("tbsCertList.nextUpdate" in asn1.result) this.nextUpdate = new _Time.default({ + schema: asn1.result["tbsCertList.nextUpdate"] + }); + if ("tbsCertList.revokedCertificates" in asn1.result) this.revokedCertificates = Array.from(asn1.result["tbsCertList.revokedCertificates"], element => new _RevokedCertificate.default({ + schema: element + })); + if ("tbsCertList.extensions" in asn1.result) this.crlExtensions = new _Extensions.default({ + schema: asn1.result["tbsCertList.extensions"] + }); + this.signatureAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.signatureAlgorithm + }); + this.signatureValue = asn1.result.signatureValue; //endregion + } //********************************************************************************** + + + encodeTBS() { + //region Create array for output sequence + const outputArray = []; + if (this.version !== CertificateRevocationList.defaultValues("version")) outputArray.push(new asn1js.Integer({ + value: this.version + })); + outputArray.push(this.signature.toSchema()); + outputArray.push(this.issuer.toSchema()); + outputArray.push(this.thisUpdate.toSchema()); + if ("nextUpdate" in this) outputArray.push(this.nextUpdate.toSchema()); + + if ("revokedCertificates" in this) { + outputArray.push(new asn1js.Sequence({ + value: Array.from(this.revokedCertificates, element => element.toSchema()) + })); + } + + if ("crlExtensions" in this) { + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [this.crlExtensions.toSchema()] + })); + } //endregion + + + return new asn1js.Sequence({ + value: outputArray + }); + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema(encodeFlag = false) { + //region Decode stored TBS value + let tbsSchema; + + if (encodeFlag === false) { + if (this.tbs.length === 0) // No stored TBS part + return CertificateRevocationList.schema(); + tbsSchema = asn1js.fromBER(this.tbs).result; + } //endregion + //region Create TBS schema via assembling from TBS parts + else tbsSchema = this.encodeTBS(); //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: [tbsSchema, this.signatureAlgorithm.toSchema(), this.signatureValue] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = { + tbs: (0, _pvutils.bufferToHexCodes)(this.tbs, 0, this.tbs.byteLength), + signature: this.signature.toJSON(), + issuer: this.issuer.toJSON(), + thisUpdate: this.thisUpdate.toJSON(), + signatureAlgorithm: this.signatureAlgorithm.toJSON(), + signatureValue: this.signatureValue.toJSON() + }; + if (this.version !== CertificateRevocationList.defaultValues("version")) object.version = this.version; + if ("nextUpdate" in this) object.nextUpdate = this.nextUpdate.toJSON(); + if ("revokedCertificates" in this) object.revokedCertificates = Array.from(this.revokedCertificates, element => element.toJSON()); + if ("crlExtensions" in this) object.crlExtensions = this.crlExtensions.toJSON(); + return object; + } //********************************************************************************** + + + isCertificateRevoked(certificate) { + //region Check that issuer of the input certificate is the same with issuer of this CRL + if (this.issuer.isEqual(certificate.issuer) === false) return false; //endregion + //region Check that there are revoked certificates in this CRL + + if ("revokedCertificates" in this === false) return false; //endregion + //region Search for input certificate in revoked certificates array + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.revokedCertificates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + const revokedCertificate = _step.value; + if (revokedCertificate.userCertificate.isEqual(certificate.serialNumber)) return true; + } //endregion + + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return false; + } //********************************************************************************** + + /** + * Make a signature for existing CRL data + * @param {Object} privateKey Private key for "subjectPublicKeyInfo" structure + * @param {string} [hashAlgorithm] Hashing algorithm. Default SHA-1 + */ + + + sign(privateKey, hashAlgorithm = "SHA-1") { + //region Initial checking + //region Get a private key from function parameter + if (typeof privateKey === "undefined") return Promise.reject("Need to provide a private key for signing"); //endregion + //endregion + //region Initial variables + + let sequence = Promise.resolve(); + let parameters; + const engine = (0, _common.getEngine)(); //endregion + //region Get a "default parameters" for current algorithm and set correct signature algorithm + + sequence = sequence.then(() => engine.subtle.getSignatureParameters(privateKey, hashAlgorithm)); + sequence = sequence.then(result => { + parameters = result.parameters; + this.signature = result.signatureAlgorithm; + this.signatureAlgorithm = result.signatureAlgorithm; + }); //endregion + //region Create TBS data for signing + + sequence = sequence.then(() => { + this.tbs = this.encodeTBS().toBER(false); + }); //endregion + //region Signing TBS data on provided private key + + sequence = sequence.then(() => engine.subtle.signWithPrivateKey(this.tbs, privateKey, parameters)); + sequence = sequence.then(result => { + this.signatureValue = new asn1js.BitString({ + valueHex: result + }); + }); //endregion + + return sequence; + } //********************************************************************************** + + /** + * Verify existing signature + * @param {{[issuerCertificate]: Object, [publicKeyInfo]: Object}} parameters + * @returns {*} + */ + + + verify(parameters = {}) { + //region Global variables + let sequence = Promise.resolve(); + let subjectPublicKeyInfo = -1; + const engine = (0, _common.getEngine)(); //endregion + //region Get information about CRL issuer certificate + + if ("issuerCertificate" in parameters) // "issuerCertificate" must be of type "Certificate" + { + subjectPublicKeyInfo = parameters.issuerCertificate.subjectPublicKeyInfo; // The CRL issuer name and "issuerCertificate" subject name are not equal + + if (this.issuer.isEqual(parameters.issuerCertificate.subject) === false) return Promise.resolve(false); + } //region In case if there is only public key during verification + + + if ("publicKeyInfo" in parameters) subjectPublicKeyInfo = parameters.publicKeyInfo; // Must be of type "PublicKeyInfo" + //endregion + + if ("subjectPublicKey" in subjectPublicKeyInfo === false) return Promise.reject("Issuer's certificate must be provided as an input parameter"); //endregion + //region Check the CRL for unknown critical extensions + + if ("crlExtensions" in this) { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.crlExtensions.extensions[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + const extension = _step2.value; + + if (extension.critical) { + // We can not be sure that unknown extension has no value for CRL signature + if ("parsedValue" in extension === false) return Promise.resolve(false); + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return != null) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + } //endregion + + + sequence = sequence.then(() => engine.subtle.verifyWithPublicKey(this.tbs, this.signatureValue, subjectPublicKeyInfo, this.signatureAlgorithm)); + return sequence; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = CertificateRevocationList; + +},{"./AlgorithmIdentifier.js":4,"./Extensions.js":39,"./RelativeDistinguishedNames.js":89,"./RevokedCertificate.js":94,"./Time.js":107,"./common.js":110,"asn1js":112,"pvutils":113}],23:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _Certificate = _interopRequireDefault(require("./Certificate.js")); + +var _AttributeCertificateV = _interopRequireDefault(require("./AttributeCertificateV1.js")); + +var _AttributeCertificateV2 = _interopRequireDefault(require("./AttributeCertificateV2.js")); + +var _OtherCertificateFormat = _interopRequireDefault(require("./OtherCertificateFormat.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class CertificateSet { + //********************************************************************************** + + /** + * Constructor for CertificateSet class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array} + * @desc certificates + */ + this.certificates = (0, _pvutils.getParametersValue)(parameters, "certificates", CertificateSet.defaultValues("certificates")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "certificates": + return []; + + default: + throw new Error(`Invalid member name for Attribute class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * CertificateSet ::= SET OF CertificateChoices + * + * CertificateChoices ::= CHOICE { + * certificate Certificate, + * extendedCertificate [0] IMPLICIT ExtendedCertificate, -- Obsolete + * v1AttrCert [1] IMPLICIT AttributeCertificateV1, -- Obsolete + * v2AttrCert [2] IMPLICIT AttributeCertificateV2, + * other [3] IMPLICIT OtherCertificateFormat } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Set({ + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.certificates || "certificates", + value: new asn1js.Choice({ + value: [_Certificate.default.schema(), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Any()] + }), // JUST A STUB + new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: _AttributeCertificateV.default.schema().valueBlock.value + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + value: _AttributeCertificateV2.default.schema().valueBlock.value + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 3 // [3] + + }, + value: _OtherCertificateFormat.default.schema().valueBlock.value + })] + }) + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["certificates"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, CertificateSet.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for CertificateSet"); //endregion + //region Get internal properties from parsed schema + + this.certificates = Array.from(asn1.result.certificates || [], element => { + const initialTagNumber = element.idBlock.tagNumber; + if (element.idBlock.tagClass === 1) return new _Certificate.default({ + schema: element + }); //region Making "Sequence" from "Constructed" value + + const elementSequence = new asn1js.Sequence({ + value: element.valueBlock.value + }); //endregion + + switch (initialTagNumber) { + case 1: + return new _AttributeCertificateV.default({ + schema: elementSequence + }); + + case 2: + return new _AttributeCertificateV2.default({ + schema: elementSequence + }); + + case 3: + return new _OtherCertificateFormat.default({ + schema: elementSequence + }); + + case 0: + default: + } + + return element; + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Set({ + value: Array.from(this.certificates, element => { + switch (true) { + case element instanceof _Certificate.default: + return element.toSchema(); + + case element instanceof _AttributeCertificateV.default: + return new asn1js.Constructed({ + idBlock: { + tagClass: 3, + tagNumber: 1 // [1] + + }, + value: element.toSchema().valueBlock.value + }); + + case element instanceof _AttributeCertificateV2.default: + return new asn1js.Constructed({ + idBlock: { + tagClass: 3, + tagNumber: 2 // [2] + + }, + value: element.toSchema().valueBlock.value + }); + + case element instanceof _OtherCertificateFormat.default: + return new asn1js.Constructed({ + idBlock: { + tagClass: 3, + tagNumber: 3 // [3] + + }, + value: element.toSchema().valueBlock.value + }); + + default: + } + + return element; + }) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + certificates: Array.from(this.certificates, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = CertificateSet; + +},{"./AttributeCertificateV1.js":7,"./AttributeCertificateV2.js":8,"./Certificate.js":19,"./OtherCertificateFormat.js":60,"asn1js":112,"pvutils":113}],24:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from "[MS-WCCE]: Windows Client Certificate Enrollment Protocol" + */ +class CertificateTemplate { + //********************************************************************************** + + /** + * Constructor for CertificateTemplate class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc templateID + */ + this.templateID = (0, _pvutils.getParametersValue)(parameters, "templateID", CertificateTemplate.defaultValues("templateID")); + if ("templateMajorVersion" in parameters) + /** + * @type {number} + * @desc templateMajorVersion + */ + this.templateMajorVersion = (0, _pvutils.getParametersValue)(parameters, "templateMajorVersion", CertificateTemplate.defaultValues("templateMajorVersion")); + if ("templateMinorVersion" in parameters) + /** + * @type {number} + * @desc templateMinorVersion + */ + this.templateMinorVersion = (0, _pvutils.getParametersValue)(parameters, "templateMinorVersion", CertificateTemplate.defaultValues("templateMinorVersion")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "templateID": + return ""; + + case "templateMajorVersion": + case "templateMinorVersion": + return 0; + + default: + throw new Error(`Invalid member name for CertificateTemplate class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * CertificateTemplateOID ::= SEQUENCE { + * templateID OBJECT IDENTIFIER, + * templateMajorVersion INTEGER (0..4294967295) OPTIONAL, + * templateMinorVersion INTEGER (0..4294967295) OPTIONAL + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [templateID] + * @property {string} [templateMajorVersion] + * @property {string} [templateMinorVersion] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.templateID || "" + }), new asn1js.Integer({ + name: names.templateMajorVersion || "", + optional: true + }), new asn1js.Integer({ + name: names.templateMinorVersion || "", + optional: true + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["templateID", "templateMajorVersion", "templateMinorVersion"]); //endregion + //region Check the schema is valid + + let asn1 = asn1js.compareSchema(schema, schema, CertificateTemplate.schema({ + names: { + templateID: "templateID", + templateMajorVersion: "templateMajorVersion", + templateMinorVersion: "templateMinorVersion" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for CertificateTemplate"); //endregion + //region Get internal properties from parsed schema + + this.templateID = asn1.result.templateID.valueBlock.toString(); + if ("templateMajorVersion" in asn1.result) this.templateMajorVersion = asn1.result.templateMajorVersion.valueBlock.valueDec; + if ("templateMinorVersion" in asn1.result) this.templateMinorVersion = asn1.result.templateMinorVersion.valueBlock.valueDec; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(new asn1js.ObjectIdentifier({ + value: this.templateID + })); + if ("templateMajorVersion" in this) outputArray.push(new asn1js.Integer({ + value: this.templateMajorVersion + })); + if ("templateMinorVersion" in this) outputArray.push(new asn1js.Integer({ + value: this.templateMinorVersion + })); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = { + extnID: this.templateID + }; + if ("templateMajorVersion" in this) object.templateMajorVersion = this.templateMajorVersion; + if ("templateMinorVersion" in this) object.templateMinorVersion = this.templateMinorVersion; + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = CertificateTemplate; + +},{"asn1js":112,"pvutils":113}],25:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _common = require("./common.js"); + +var _PublicKeyInfo = _interopRequireDefault(require("./PublicKeyInfo.js")); + +var _RelativeDistinguishedNames = _interopRequireDefault(require("./RelativeDistinguishedNames.js")); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _Attribute = _interopRequireDefault(require("./Attribute.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** +function CertificationRequestInfo(parameters = {}) { + //CertificationRequestInfo ::= SEQUENCE { + // version INTEGER { v1(0) } (v1,...), + // subject Name, + // subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, + // attributes [0] Attributes{{ CRIAttributes }} + //} + + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [CertificationRequestInfo] + * @property {string} [CertificationRequestInfoVersion] + * @property {string} [subject] + * @property {string} [CertificationRequestInfoAttributes] + * @property {string} [attributes] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.CertificationRequestInfo || "CertificationRequestInfo", + value: [new asn1js.Integer({ + name: names.CertificationRequestInfoVersion || "CertificationRequestInfo.version" + }), _RelativeDistinguishedNames.default.schema(names.subject || { + names: { + blockName: "CertificationRequestInfo.subject" + } + }), _PublicKeyInfo.default.schema({ + names: { + blockName: "CertificationRequestInfo.subjectPublicKeyInfo" + } + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Repeated({ + optional: true, + // Because OpenSSL makes wrong "attributes" field + name: names.CertificationRequestInfoAttributes || "CertificationRequestInfo.attributes", + value: _Attribute.default.schema(names.attributes || {}) + })] + })] + }); +} //************************************************************************************** + +/** + * Class from RFC2986 + */ + + +class CertificationRequest { + //********************************************************************************** + + /** + * Constructor for Attribute class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {ArrayBuffer} + * @desc tbs + */ + this.tbs = (0, _pvutils.getParametersValue)(parameters, "tbs", CertificationRequest.defaultValues("tbs")); + /** + * @type {number} + * @desc version + */ + + this.version = (0, _pvutils.getParametersValue)(parameters, "version", CertificationRequest.defaultValues("version")); + /** + * @type {RelativeDistinguishedNames} + * @desc subject + */ + + this.subject = (0, _pvutils.getParametersValue)(parameters, "subject", CertificationRequest.defaultValues("subject")); + /** + * @type {PublicKeyInfo} + * @desc subjectPublicKeyInfo + */ + + this.subjectPublicKeyInfo = (0, _pvutils.getParametersValue)(parameters, "subjectPublicKeyInfo", CertificationRequest.defaultValues("subjectPublicKeyInfo")); + if ("attributes" in parameters) + /** + * @type {Array.} + * @desc attributes + */ + this.attributes = (0, _pvutils.getParametersValue)(parameters, "attributes", CertificationRequest.defaultValues("attributes")); + /** + * @type {AlgorithmIdentifier} + * @desc signatureAlgorithm + */ + + this.signatureAlgorithm = (0, _pvutils.getParametersValue)(parameters, "signatureAlgorithm", CertificationRequest.defaultValues("signatureAlgorithm")); + /** + * @type {BitString} + * @desc signatureAlgorithm + */ + + this.signatureValue = (0, _pvutils.getParametersValue)(parameters, "signatureValue", CertificationRequest.defaultValues("signatureValue")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "tbs": + return new ArrayBuffer(0); + + case "version": + return 0; + + case "subject": + return new _RelativeDistinguishedNames.default(); + + case "subjectPublicKeyInfo": + return new _PublicKeyInfo.default(); + + case "attributes": + return []; + + case "signatureAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "signatureValue": + return new asn1js.BitString(); + + default: + throw new Error(`Invalid member name for CertificationRequest class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * CertificationRequest ::= SEQUENCE { + * certificationRequestInfo CertificationRequestInfo, + * signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }}, + * signature BIT STRING + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [certificationRequestInfo] + * @property {string} [signatureAlgorithm] + * @property {string} [signatureValue] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + value: [CertificationRequestInfo(names.certificationRequestInfo || {}), new asn1js.Sequence({ + name: names.signatureAlgorithm || "signatureAlgorithm", + value: [new asn1js.ObjectIdentifier(), new asn1js.Any({ + optional: true + })] + }), new asn1js.BitString({ + name: names.signatureValue || "signatureValue" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["CertificationRequestInfo", "CertificationRequestInfo.version", "CertificationRequestInfo.subject", "CertificationRequestInfo.subjectPublicKeyInfo", "CertificationRequestInfo.attributes", "signatureAlgorithm", "signatureValue"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, CertificationRequest.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for CertificationRequest"); //endregion + //region Get internal properties from parsed schema + + this.tbs = asn1.result.CertificationRequestInfo.valueBeforeDecode; + this.version = asn1.result["CertificationRequestInfo.version"].valueBlock.valueDec; + this.subject = new _RelativeDistinguishedNames.default({ + schema: asn1.result["CertificationRequestInfo.subject"] + }); + this.subjectPublicKeyInfo = new _PublicKeyInfo.default({ + schema: asn1.result["CertificationRequestInfo.subjectPublicKeyInfo"] + }); + if ("CertificationRequestInfo.attributes" in asn1.result) this.attributes = Array.from(asn1.result["CertificationRequestInfo.attributes"], element => new _Attribute.default({ + schema: element + })); + this.signatureAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.signatureAlgorithm + }); + this.signatureValue = asn1.result.signatureValue; //endregion + } //********************************************************************************** + + /** + * Aux function making ASN1js Sequence from current TBS + * @returns {Sequence} + */ + + + encodeTBS() { + //region Create array for output sequence + const outputArray = [new asn1js.Integer({ + value: this.version + }), this.subject.toSchema(), this.subjectPublicKeyInfo.toSchema()]; + + if ("attributes" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: Array.from(this.attributes, element => element.toSchema()) + })); + } //endregion + + + return new asn1js.Sequence({ + value: outputArray + }); + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema(encodeFlag = false) { + //region Decode stored TBS value + let tbsSchema; + + if (encodeFlag === false) { + if (this.tbs.byteLength === 0) // No stored TBS part + return CertificationRequest.schema(); + tbsSchema = asn1js.fromBER(this.tbs).result; + } //endregion + //region Create TBS schema via assembling from TBS parts + else tbsSchema = this.encodeTBS(); //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: [tbsSchema, this.signatureAlgorithm.toSchema(), this.signatureValue] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = { + tbs: (0, _pvutils.bufferToHexCodes)(this.tbs, 0, this.tbs.byteLength), + version: this.version, + subject: this.subject.toJSON(), + subjectPublicKeyInfo: this.subjectPublicKeyInfo.toJSON(), + signatureAlgorithm: this.signatureAlgorithm.toJSON(), + signatureValue: this.signatureValue.toJSON() + }; + if ("attributes" in this) object.attributes = Array.from(this.attributes, element => element.toJSON()); + return object; + } //********************************************************************************** + + /** + * Makes signature for currect certification request + * @param {Object} privateKey WebCrypto private key + * @param {string} [hashAlgorithm=SHA-1] String representing current hashing algorithm + */ + + + sign(privateKey, hashAlgorithm = "SHA-1") { + //region Initial checking + //region Get a private key from function parameter + if (typeof privateKey === "undefined") return Promise.reject("Need to provide a private key for signing"); //endregion + //endregion + //region Initial variables + + let sequence = Promise.resolve(); + let parameters; + const engine = (0, _common.getEngine)(); //endregion + //region Get a "default parameters" for current algorithm and set correct signature algorithm + + sequence = sequence.then(() => engine.subtle.getSignatureParameters(privateKey, hashAlgorithm)); + sequence = sequence.then(result => { + parameters = result.parameters; + this.signatureAlgorithm = result.signatureAlgorithm; + }); //endregion + //region Create TBS data for signing + + sequence = sequence.then(() => { + this.tbs = this.encodeTBS().toBER(false); + }); //endregion + //region Signing TBS data on provided private key + + sequence = sequence.then(() => engine.subtle.signWithPrivateKey(this.tbs, privateKey, parameters)); + sequence = sequence.then(result => { + this.signatureValue = new asn1js.BitString({ + valueHex: result + }); + }); //endregion + + return sequence; + } //********************************************************************************** + + /** + * Verify existing certification request signature + * @returns {*} + */ + + + verify() { + return (0, _common.getEngine)().subtle.verifyWithPublicKey(this.tbs, this.signatureValue, this.subjectPublicKeyInfo, this.signatureAlgorithm); + } //********************************************************************************** + + /** + * Importing public key for current certificate request + */ + + + getPublicKey(parameters = null) { + return (0, _common.getEngine)().getPublicKey(this.subjectPublicKeyInfo, this.signatureAlgorithm, parameters); + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = CertificationRequest; + +},{"./AlgorithmIdentifier.js":4,"./Attribute.js":6,"./PublicKeyInfo.js":78,"./RelativeDistinguishedNames.js":89,"./common.js":110,"asn1js":112,"pvutils":113}],26:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class ContentInfo { + //********************************************************************************** + + /** + * Constructor for ContentInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc contentType + */ + this.contentType = (0, _pvutils.getParametersValue)(parameters, "contentType", ContentInfo.defaultValues("contentType")); + /** + * @type {Any} + * @desc content + */ + + this.content = (0, _pvutils.getParametersValue)(parameters, "content", ContentInfo.defaultValues("content")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "contentType": + return ""; + + case "content": + return new asn1js.Any(); + + default: + throw new Error(`Invalid member name for ContentInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "contentType": + return memberValue === ""; + + case "content": + return memberValue instanceof asn1js.Any; + + default: + throw new Error(`Invalid member name for ContentInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * ContentInfo ::= SEQUENCE { + * contentType ContentType, + * content [0] EXPLICIT ANY DEFINED BY contentType } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [contentType] + * @property {string} [content] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + if ("optional" in names === false) names.optional = false; + return new asn1js.Sequence({ + name: names.blockName || "ContentInfo", + optional: names.optional, + value: [new asn1js.ObjectIdentifier({ + name: names.contentType || "contentType" + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Any({ + name: names.content || "content" + })] // EXPLICIT ANY value + + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["contentType", "content"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, ContentInfo.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for ContentInfo"); //endregion + //region Get internal properties from parsed schema + + this.contentType = asn1.result.contentType.valueBlock.toString(); + this.content = asn1.result.content; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [new asn1js.ObjectIdentifier({ + value: this.contentType + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [this.content] // EXPLICIT ANY value + + })] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = { + contentType: this.contentType + }; + if (!(this.content instanceof asn1js.Any)) object.content = this.content.toJSON(); + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = ContentInfo; + +},{"asn1js":112,"pvutils":113}],27:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _common = require("./common.js"); + +var _PublicKeyInfo = _interopRequireDefault(require("./PublicKeyInfo.js")); + +var _PrivateKeyInfo = _interopRequireDefault(require("./PrivateKeyInfo.js")); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _EncryptedContentInfo = _interopRequireDefault(require("./EncryptedContentInfo.js")); + +var _RSASSAPSSParams = _interopRequireDefault(require("./RSASSAPSSParams.js")); + +var _PBKDF2Params = _interopRequireDefault(require("./PBKDF2Params.js")); + +var _PBES2Params = _interopRequireDefault(require("./PBES2Params.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Making MAC key using algorithm described in B.2 of PKCS#12 standard. + */ +function makePKCS12B2Key(cryptoEngine, hashAlgorithm, keyLength, password, salt, iterationCount) { + //region Initial variables + let u; + let v; + const result = []; //endregion + //region Get "u" and "v" values + + switch (hashAlgorithm.toUpperCase()) { + case "SHA-1": + u = 20; // 160 + + v = 64; // 512 + + break; + + case "SHA-256": + u = 32; // 256 + + v = 64; // 512 + + break; + + case "SHA-384": + u = 48; // 384 + + v = 128; // 1024 + + break; + + case "SHA-512": + u = 64; // 512 + + v = 128; // 1024 + + break; + + default: + throw new Error("Unsupported hashing algorithm"); + } //endregion + //region Main algorithm making key + //region Transform password to UTF-8 like string + + + const passwordViewInitial = new Uint8Array(password); + const passwordTransformed = new ArrayBuffer(password.byteLength * 2 + 2); + const passwordTransformedView = new Uint8Array(passwordTransformed); + + for (let i = 0; i < passwordViewInitial.length; i++) { + passwordTransformedView[i * 2] = 0x00; + passwordTransformedView[i * 2 + 1] = passwordViewInitial[i]; + } + + passwordTransformedView[passwordTransformedView.length - 2] = 0x00; + passwordTransformedView[passwordTransformedView.length - 1] = 0x00; + password = passwordTransformed.slice(0); //endregion + //region Construct a string D (the "diversifier") by concatenating v/8 copies of ID + + const D = new ArrayBuffer(v); + const dView = new Uint8Array(D); + + for (let i = 0; i < D.byteLength; i++) dView[i] = 3; // The ID value equal to "3" for MACing (see B.3 of standard) + //endregion + //region Concatenate copies of the salt together to create a string S of length v * ceil(s / v) bytes (the final copy of the salt may be trunacted to create S) + + + const saltLength = salt.byteLength; + const sLen = v * Math.ceil(saltLength / v); + const S = new ArrayBuffer(sLen); + const sView = new Uint8Array(S); + const saltView = new Uint8Array(salt); + + for (let i = 0; i < sLen; i++) sView[i] = saltView[i % saltLength]; //endregion + //region Concatenate copies of the password together to create a string P of length v * ceil(p / v) bytes (the final copy of the password may be truncated to create P) + + + const passwordLength = password.byteLength; + const pLen = v * Math.ceil(passwordLength / v); + const P = new ArrayBuffer(pLen); + const pView = new Uint8Array(P); + const passwordView = new Uint8Array(password); + + for (let i = 0; i < pLen; i++) pView[i] = passwordView[i % passwordLength]; //endregion + //region Set I=S||P to be the concatenation of S and P + + + const sPlusPLength = S.byteLength + P.byteLength; + let I = new ArrayBuffer(sPlusPLength); + let iView = new Uint8Array(I); + iView.set(sView); + iView.set(pView, sView.length); //endregion + //region Set c=ceil(n / u) + + const c = Math.ceil((keyLength >> 3) / u); //endregion + //region Initial variables + + let internalSequence = Promise.resolve(I); //endregion + //region For i=1, 2, ..., c, do the following: + + for (let i = 0; i <= c; i++) { + internalSequence = internalSequence.then(_I => { + //region Create contecanetion of D and I + const dAndI = new ArrayBuffer(D.byteLength + _I.byteLength); + const dAndIView = new Uint8Array(dAndI); + dAndIView.set(dView); + dAndIView.set(iView, dView.length); //endregion + + return dAndI; + }); //region Make "iterationCount" rounds of hashing + + for (let j = 0; j < iterationCount; j++) internalSequence = internalSequence.then(roundBuffer => cryptoEngine.digest({ + name: hashAlgorithm + }, new Uint8Array(roundBuffer))); //endregion + + + internalSequence = internalSequence.then(roundBuffer => { + //region Concatenate copies of Ai to create a string B of length v bits (the final copy of Ai may be truncated to create B) + const B = new ArrayBuffer(v); + const bView = new Uint8Array(B); + + for (let j = 0; j < B.byteLength; j++) bView[j] = roundBuffer[j % roundBuffer.length]; //endregion + //region Make new I value + + + const k = Math.ceil(saltLength / v) + Math.ceil(passwordLength / v); + const iRound = []; + let sliceStart = 0; + let sliceLength = v; + + for (let j = 0; j < k; j++) { + const chunk = Array.from(new Uint8Array(I.slice(sliceStart, sliceStart + sliceLength))); + sliceStart += v; + if (sliceStart + v > I.byteLength) sliceLength = I.byteLength - sliceStart; + let x = 0x1ff; + + for (let l = B.byteLength - 1; l >= 0; l--) { + x >>= 8; + x += bView[l] + chunk[l]; + chunk[l] = x & 0xff; + } + + iRound.push(...chunk); + } + + I = new ArrayBuffer(iRound.length); + iView = new Uint8Array(I); + iView.set(iRound); //endregion + + result.push(...new Uint8Array(roundBuffer)); + return I; + }); + } //endregion + //region Initialize final key + + + internalSequence = internalSequence.then(() => { + const resultBuffer = new ArrayBuffer(keyLength >> 3); + const resultView = new Uint8Array(resultBuffer); + resultView.set(new Uint8Array(result).slice(0, keyLength >> 3)); + return resultBuffer; + }); //endregion + //endregion + + return internalSequence; +} //************************************************************************************** + +/** + * Default cryptographic engine for Web Cryptography API + */ + + +class CryptoEngine { + //********************************************************************************** + + /** + * Constructor for CryptoEngine class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Object} + * @desc Usually here we are expecting "window.crypto" or an equivalent from custom "crypto engine" + */ + this.crypto = (0, _pvutils.getParametersValue)(parameters, "crypto", {}); + /** + * @type {Object} + * @desc Usually here we are expecting "window.crypto.subtle" or an equivalent from custom "crypto engine" + */ + + this.subtle = (0, _pvutils.getParametersValue)(parameters, "subtle", {}); + /** + * @type {string} + * @desc Name of the "crypto engine" + */ + + this.name = (0, _pvutils.getParametersValue)(parameters, "name", ""); //endregion + } //********************************************************************************** + + /** + * Import WebCrypto keys from different formats + * @param {string} format + * @param {ArrayBuffer|Uint8Array} keyData + * @param {Object} algorithm + * @param {boolean} extractable + * @param {Array} keyUsages + * @returns {Promise} + */ + + + importKey(format, keyData, algorithm, extractable, keyUsages) { + //region Initial variables + let jwk = {}; //endregion + //region Change "keyData" type if needed + + if (keyData instanceof Uint8Array) keyData = keyData.buffer; //endregion + + switch (format.toLowerCase()) { + case "raw": + return this.subtle.importKey("raw", keyData, algorithm, extractable, keyUsages); + + case "spki": + { + const asn1 = asn1js.fromBER(keyData); + if (asn1.offset === -1) return Promise.reject("Incorrect keyData"); + const publicKeyInfo = new _PublicKeyInfo.default(); + + try { + publicKeyInfo.fromSchema(asn1.result); + } catch (ex) { + return Promise.reject("Incorrect keyData"); + } // noinspection FallThroughInSwitchStatementJS + + + switch (algorithm.name.toUpperCase()) { + case "RSA-PSS": + { + //region Get information about used hash function + switch (algorithm.hash.name.toUpperCase()) { + case "SHA-1": + jwk.alg = "PS1"; + break; + + case "SHA-256": + jwk.alg = "PS256"; + break; + + case "SHA-384": + jwk.alg = "PS384"; + break; + + case "SHA-512": + jwk.alg = "PS512"; + break; + + default: + return Promise.reject(`Incorrect hash algorithm: ${algorithm.hash.name.toUpperCase()}`); + } //endregion + + } + // break omitted + + case "RSASSA-PKCS1-V1_5": + { + keyUsages = ["verify"]; // Override existing keyUsages value since the key is a public key + + jwk.kty = "RSA"; + jwk.ext = extractable; + jwk.key_ops = keyUsages; + if (publicKeyInfo.algorithm.algorithmId !== "1.2.840.113549.1.1.1") return Promise.reject(`Incorrect public key algorithm: ${publicKeyInfo.algorithm.algorithmId}`); //region Get information about used hash function + + if ("alg" in jwk === false) { + switch (algorithm.hash.name.toUpperCase()) { + case "SHA-1": + jwk.alg = "RS1"; + break; + + case "SHA-256": + jwk.alg = "RS256"; + break; + + case "SHA-384": + jwk.alg = "RS384"; + break; + + case "SHA-512": + jwk.alg = "RS512"; + break; + + default: + return Promise.reject(`Incorrect public key algorithm: ${publicKeyInfo.algorithm.algorithmId}`); + } + } //endregion + //region Create RSA Public Key elements + + + const publicKeyJSON = publicKeyInfo.toJSON(); + + for (var _i = 0, _Object$keys = Object.keys(publicKeyJSON); _i < _Object$keys.length; _i++) { + const key = _Object$keys[_i]; + jwk[key] = publicKeyJSON[key]; + } //endregion + + } + break; + + case "ECDSA": + keyUsages = ["verify"]; + // Override existing keyUsages value since the key is a public key + // break omitted + + case "ECDH": + { + //region Initial variables + jwk = { + kty: "EC", + ext: extractable, + key_ops: keyUsages + }; //endregion + //region Get information about algorithm + + if (publicKeyInfo.algorithm.algorithmId !== "1.2.840.10045.2.1") return Promise.reject(`Incorrect public key algorithm: ${publicKeyInfo.algorithm.algorithmId}`); //endregion + //region Create ECDSA Public Key elements + + const publicKeyJSON = publicKeyInfo.toJSON(); + + for (var _i2 = 0, _Object$keys2 = Object.keys(publicKeyJSON); _i2 < _Object$keys2.length; _i2++) { + const key = _Object$keys2[_i2]; + jwk[key] = publicKeyJSON[key]; + } //endregion + + } + break; + + case "RSA-OAEP": + { + jwk.kty = "RSA"; + jwk.ext = extractable; + jwk.key_ops = keyUsages; + if (this.name.toLowerCase() === "safari") jwk.alg = "RSA-OAEP";else { + switch (algorithm.hash.name.toUpperCase()) { + case "SHA-1": + jwk.alg = "RSA-OAEP"; + break; + + case "SHA-256": + jwk.alg = "RSA-OAEP-256"; + break; + + case "SHA-384": + jwk.alg = "RSA-OAEP-384"; + break; + + case "SHA-512": + jwk.alg = "RSA-OAEP-512"; + break; + + default: + return Promise.reject(`Incorrect public key algorithm: ${publicKeyInfo.algorithm.algorithmId}`); + } + } //region Create ECDSA Public Key elements + + const publicKeyJSON = publicKeyInfo.toJSON(); + + for (var _i3 = 0, _Object$keys3 = Object.keys(publicKeyJSON); _i3 < _Object$keys3.length; _i3++) { + const key = _Object$keys3[_i3]; + jwk[key] = publicKeyJSON[key]; + } //endregion + + } + break; + + default: + return Promise.reject(`Incorrect algorithm name: ${algorithm.name.toUpperCase()}`); + } + } + break; + + case "pkcs8": + { + const privateKeyInfo = new _PrivateKeyInfo.default(); //region Parse "PrivateKeyInfo" object + + const asn1 = asn1js.fromBER(keyData); + if (asn1.offset === -1) return Promise.reject("Incorrect keyData"); + + try { + privateKeyInfo.fromSchema(asn1.result); + } catch (ex) { + return Promise.reject("Incorrect keyData"); + } + + if ("parsedKey" in privateKeyInfo === false) return Promise.reject("Incorrect keyData"); //endregion + // noinspection FallThroughInSwitchStatementJS + // noinspection FallThroughInSwitchStatementJS + + switch (algorithm.name.toUpperCase()) { + case "RSA-PSS": + { + //region Get information about used hash function + switch (algorithm.hash.name.toUpperCase()) { + case "SHA-1": + jwk.alg = "PS1"; + break; + + case "SHA-256": + jwk.alg = "PS256"; + break; + + case "SHA-384": + jwk.alg = "PS384"; + break; + + case "SHA-512": + jwk.alg = "PS512"; + break; + + default: + return Promise.reject(`Incorrect hash algorithm: ${algorithm.hash.name.toUpperCase()}`); + } //endregion + + } + // break omitted + + case "RSASSA-PKCS1-V1_5": + { + keyUsages = ["sign"]; // Override existing keyUsages value since the key is a private key + + jwk.kty = "RSA"; + jwk.ext = extractable; + jwk.key_ops = keyUsages; //region Get information about used hash function + + if (privateKeyInfo.privateKeyAlgorithm.algorithmId !== "1.2.840.113549.1.1.1") return Promise.reject(`Incorrect private key algorithm: ${privateKeyInfo.privateKeyAlgorithm.algorithmId}`); //endregion + //region Get information about used hash function + + if ("alg" in jwk === false) { + switch (algorithm.hash.name.toUpperCase()) { + case "SHA-1": + jwk.alg = "RS1"; + break; + + case "SHA-256": + jwk.alg = "RS256"; + break; + + case "SHA-384": + jwk.alg = "RS384"; + break; + + case "SHA-512": + jwk.alg = "RS512"; + break; + + default: + return Promise.reject(`Incorrect hash algorithm: ${algorithm.hash.name.toUpperCase()}`); + } + } //endregion + //region Create RSA Private Key elements + + + const privateKeyJSON = privateKeyInfo.toJSON(); + + for (var _i4 = 0, _Object$keys4 = Object.keys(privateKeyJSON); _i4 < _Object$keys4.length; _i4++) { + const key = _Object$keys4[_i4]; + jwk[key] = privateKeyJSON[key]; + } //endregion + + } + break; + + case "ECDSA": + keyUsages = ["sign"]; + // Override existing keyUsages value since the key is a private key + // break omitted + + case "ECDH": + { + //region Initial variables + jwk = { + kty: "EC", + ext: extractable, + key_ops: keyUsages + }; //endregion + //region Get information about used hash function + + if (privateKeyInfo.privateKeyAlgorithm.algorithmId !== "1.2.840.10045.2.1") return Promise.reject(`Incorrect algorithm: ${privateKeyInfo.privateKeyAlgorithm.algorithmId}`); //endregion + //region Create ECDSA Private Key elements + + const privateKeyJSON = privateKeyInfo.toJSON(); + + for (var _i5 = 0, _Object$keys5 = Object.keys(privateKeyJSON); _i5 < _Object$keys5.length; _i5++) { + const key = _Object$keys5[_i5]; + jwk[key] = privateKeyJSON[key]; + } //endregion + + } + break; + + case "RSA-OAEP": + { + jwk.kty = "RSA"; + jwk.ext = extractable; + jwk.key_ops = keyUsages; //region Get information about used hash function + + if (this.name.toLowerCase() === "safari") jwk.alg = "RSA-OAEP";else { + switch (algorithm.hash.name.toUpperCase()) { + case "SHA-1": + jwk.alg = "RSA-OAEP"; + break; + + case "SHA-256": + jwk.alg = "RSA-OAEP-256"; + break; + + case "SHA-384": + jwk.alg = "RSA-OAEP-384"; + break; + + case "SHA-512": + jwk.alg = "RSA-OAEP-512"; + break; + + default: + return Promise.reject(`Incorrect hash algorithm: ${algorithm.hash.name.toUpperCase()}`); + } + } //endregion + //region Create RSA Private Key elements + + const privateKeyJSON = privateKeyInfo.toJSON(); + + for (var _i6 = 0, _Object$keys6 = Object.keys(privateKeyJSON); _i6 < _Object$keys6.length; _i6++) { + const key = _Object$keys6[_i6]; + jwk[key] = privateKeyJSON[key]; + } //endregion + + } + break; + + default: + return Promise.reject(`Incorrect algorithm name: ${algorithm.name.toUpperCase()}`); + } + } + break; + + case "jwk": + jwk = keyData; + break; + + default: + return Promise.reject(`Incorrect format: ${format}`); + } //region Special case for Safari browser (since its acting not as WebCrypto standard describes) + + + if (this.name.toLowerCase() === "safari") { + // Try to use both ways - import using ArrayBuffer and pure JWK (for Safari Technology Preview) + return Promise.resolve().then(() => this.subtle.importKey("jwk", (0, _pvutils.stringToArrayBuffer)(JSON.stringify(jwk)), algorithm, extractable, keyUsages)).then(result => result, () => this.subtle.importKey("jwk", jwk, algorithm, extractable, keyUsages)); + } //endregion + + + return this.subtle.importKey("jwk", jwk, algorithm, extractable, keyUsages); + } //********************************************************************************** + + /** + * Export WebCrypto keys to different formats + * @param {string} format + * @param {Object} key + * @returns {Promise} + */ + + + exportKey(format, key) { + let sequence = this.subtle.exportKey("jwk", key); //region Currently Safari returns ArrayBuffer as JWK thus we need an additional transformation + + if (this.name.toLowerCase() === "safari") { + sequence = sequence.then(result => { + // Some additional checks for Safari Technology Preview + if (result instanceof ArrayBuffer) return JSON.parse((0, _pvutils.arrayBufferToString)(result)); + return result; + }); + } //endregion + + + switch (format.toLowerCase()) { + case "raw": + return this.subtle.exportKey("raw", key); + + case "spki": + sequence = sequence.then(result => { + const publicKeyInfo = new _PublicKeyInfo.default(); + + try { + publicKeyInfo.fromJSON(result); + } catch (ex) { + return Promise.reject("Incorrect key data"); + } + + return publicKeyInfo.toSchema().toBER(false); + }); + break; + + case "pkcs8": + sequence = sequence.then(result => { + const privateKeyInfo = new _PrivateKeyInfo.default(); + + try { + privateKeyInfo.fromJSON(result); + } catch (ex) { + return Promise.reject("Incorrect key data"); + } + + return privateKeyInfo.toSchema().toBER(false); + }); + break; + + case "jwk": + break; + + default: + return Promise.reject(`Incorrect format: ${format}`); + } + + return sequence; + } //********************************************************************************** + + /** + * Convert WebCrypto keys between different export formats + * @param {string} inputFormat + * @param {string} outputFormat + * @param {ArrayBuffer|Object} keyData + * @param {Object} algorithm + * @param {boolean} extractable + * @param {Array} keyUsages + * @returns {Promise} + */ + + + convert(inputFormat, outputFormat, keyData, algorithm, extractable, keyUsages) { + switch (inputFormat.toLowerCase()) { + case "raw": + switch (outputFormat.toLowerCase()) { + case "raw": + return Promise.resolve(keyData); + + case "spki": + return Promise.resolve().then(() => this.importKey("raw", keyData, algorithm, extractable, keyUsages)).then(result => this.exportKey("spki", result)); + + case "pkcs8": + return Promise.resolve().then(() => this.importKey("raw", keyData, algorithm, extractable, keyUsages)).then(result => this.exportKey("pkcs8", result)); + + case "jwk": + return Promise.resolve().then(() => this.importKey("raw", keyData, algorithm, extractable, keyUsages)).then(result => this.exportKey("jwk", result)); + + default: + return Promise.reject(`Incorrect outputFormat: ${outputFormat}`); + } + + case "spki": + switch (outputFormat.toLowerCase()) { + case "raw": + return Promise.resolve().then(() => this.importKey("spki", keyData, algorithm, extractable, keyUsages)).then(result => this.exportKey("raw", result)); + + case "spki": + return Promise.resolve(keyData); + + case "pkcs8": + return Promise.reject("Impossible to convert between SPKI/PKCS8"); + + case "jwk": + return Promise.resolve().then(() => this.importKey("spki", keyData, algorithm, extractable, keyUsages)).then(result => this.exportKey("jwk", result)); + + default: + return Promise.reject(`Incorrect outputFormat: ${outputFormat}`); + } + + case "pkcs8": + switch (outputFormat.toLowerCase()) { + case "raw": + return Promise.resolve().then(() => this.importKey("pkcs8", keyData, algorithm, extractable, keyUsages)).then(result => this.exportKey("raw", result)); + + case "spki": + return Promise.reject("Impossible to convert between SPKI/PKCS8"); + + case "pkcs8": + return Promise.resolve(keyData); + + case "jwk": + return Promise.resolve().then(() => this.importKey("pkcs8", keyData, algorithm, extractable, keyUsages)).then(result => this.exportKey("jwk", result)); + + default: + return Promise.reject(`Incorrect outputFormat: ${outputFormat}`); + } + + case "jwk": + switch (outputFormat.toLowerCase()) { + case "raw": + return Promise.resolve().then(() => this.importKey("jwk", keyData, algorithm, extractable, keyUsages)).then(result => this.exportKey("raw", result)); + + case "spki": + return Promise.resolve().then(() => this.importKey("jwk", keyData, algorithm, extractable, keyUsages)).then(result => this.exportKey("spki", result)); + + case "pkcs8": + return Promise.resolve().then(() => this.importKey("jwk", keyData, algorithm, extractable, keyUsages)).then(result => this.exportKey("pkcs8", result)); + + case "jwk": + return Promise.resolve(keyData); + + default: + return Promise.reject(`Incorrect outputFormat: ${outputFormat}`); + } + + default: + return Promise.reject(`Incorrect inputFormat: ${inputFormat}`); + } + } //********************************************************************************** + + /** + * Wrapper for standard function "encrypt" + * @param args + * @returns {Promise} + */ + + + encrypt(...args) { + return this.subtle.encrypt(...args); + } //********************************************************************************** + + /** + * Wrapper for standard function "decrypt" + * @param args + * @returns {Promise} + */ + + + decrypt(...args) { + return this.subtle.decrypt(...args); + } //********************************************************************************** + + /** + * Wrapper for standard function "sign" + * @param args + * @returns {Promise} + */ + + + sign(...args) { + return this.subtle.sign(...args); + } //********************************************************************************** + + /** + * Wrapper for standard function "verify" + * @param args + * @returns {Promise} + */ + + + verify(...args) { + return this.subtle.verify(...args); + } //********************************************************************************** + + /** + * Wrapper for standard function "digest" + * @param args + * @returns {Promise} + */ + + + digest(...args) { + return this.subtle.digest(...args); + } //********************************************************************************** + + /** + * Wrapper for standard function "generateKey" + * @param args + * @returns {Promise} + */ + + + generateKey(...args) { + return this.subtle.generateKey(...args); + } //********************************************************************************** + + /** + * Wrapper for standard function "deriveKey" + * @param args + * @returns {Promise} + */ + + + deriveKey(...args) { + return this.subtle.deriveKey(...args); + } //********************************************************************************** + + /** + * Wrapper for standard function "deriveBits" + * @param args + * @returns {Promise} + */ + + + deriveBits(...args) { + return this.subtle.deriveBits(...args); + } //********************************************************************************** + + /** + * Wrapper for standard function "wrapKey" + * @param args + * @returns {Promise} + */ + + + wrapKey(...args) { + return this.subtle.wrapKey(...args); + } //********************************************************************************** + + /** + * Wrapper for standard function "unwrapKey" + * @param args + * @returns {Promise} + */ + + + unwrapKey(...args) { + return this.subtle.unwrapKey(...args); + } //********************************************************************************** + + /** + * Initialize input Uint8Array by random values (with help from current "crypto engine") + * @param {!Uint8Array} view + * @returns {*} + */ + + + getRandomValues(view) { + if ("getRandomValues" in this.crypto === false) throw new Error("No support for getRandomValues"); + return this.crypto.getRandomValues(view); + } //********************************************************************************** + + /** + * Get WebCrypto algorithm by wel-known OID + * @param {string} oid well-known OID to search for + * @returns {Object} + */ + + + getAlgorithmByOID(oid) { + switch (oid) { + case "1.2.840.113549.1.1.1": + case "1.2.840.113549.1.1.5": + return { + name: "RSASSA-PKCS1-v1_5", + hash: { + name: "SHA-1" + } + }; + + case "1.2.840.113549.1.1.11": + return { + name: "RSASSA-PKCS1-v1_5", + hash: { + name: "SHA-256" + } + }; + + case "1.2.840.113549.1.1.12": + return { + name: "RSASSA-PKCS1-v1_5", + hash: { + name: "SHA-384" + } + }; + + case "1.2.840.113549.1.1.13": + return { + name: "RSASSA-PKCS1-v1_5", + hash: { + name: "SHA-512" + } + }; + + case "1.2.840.113549.1.1.10": + return { + name: "RSA-PSS" + }; + + case "1.2.840.113549.1.1.7": + return { + name: "RSA-OAEP" + }; + + case "1.2.840.10045.2.1": + case "1.2.840.10045.4.1": + return { + name: "ECDSA", + hash: { + name: "SHA-1" + } + }; + + case "1.2.840.10045.4.3.2": + return { + name: "ECDSA", + hash: { + name: "SHA-256" + } + }; + + case "1.2.840.10045.4.3.3": + return { + name: "ECDSA", + hash: { + name: "SHA-384" + } + }; + + case "1.2.840.10045.4.3.4": + return { + name: "ECDSA", + hash: { + name: "SHA-512" + } + }; + + case "1.3.133.16.840.63.0.2": + return { + name: "ECDH", + kdf: "SHA-1" + }; + + case "1.3.132.1.11.1": + return { + name: "ECDH", + kdf: "SHA-256" + }; + + case "1.3.132.1.11.2": + return { + name: "ECDH", + kdf: "SHA-384" + }; + + case "1.3.132.1.11.3": + return { + name: "ECDH", + kdf: "SHA-512" + }; + + case "2.16.840.1.101.3.4.1.2": + return { + name: "AES-CBC", + length: 128 + }; + + case "2.16.840.1.101.3.4.1.22": + return { + name: "AES-CBC", + length: 192 + }; + + case "2.16.840.1.101.3.4.1.42": + return { + name: "AES-CBC", + length: 256 + }; + + case "2.16.840.1.101.3.4.1.6": + return { + name: "AES-GCM", + length: 128 + }; + + case "2.16.840.1.101.3.4.1.26": + return { + name: "AES-GCM", + length: 192 + }; + + case "2.16.840.1.101.3.4.1.46": + return { + name: "AES-GCM", + length: 256 + }; + + case "2.16.840.1.101.3.4.1.4": + return { + name: "AES-CFB", + length: 128 + }; + + case "2.16.840.1.101.3.4.1.24": + return { + name: "AES-CFB", + length: 192 + }; + + case "2.16.840.1.101.3.4.1.44": + return { + name: "AES-CFB", + length: 256 + }; + + case "2.16.840.1.101.3.4.1.5": + return { + name: "AES-KW", + length: 128 + }; + + case "2.16.840.1.101.3.4.1.25": + return { + name: "AES-KW", + length: 192 + }; + + case "2.16.840.1.101.3.4.1.45": + return { + name: "AES-KW", + length: 256 + }; + + case "1.2.840.113549.2.7": + return { + name: "HMAC", + hash: { + name: "SHA-1" + } + }; + + case "1.2.840.113549.2.9": + return { + name: "HMAC", + hash: { + name: "SHA-256" + } + }; + + case "1.2.840.113549.2.10": + return { + name: "HMAC", + hash: { + name: "SHA-384" + } + }; + + case "1.2.840.113549.2.11": + return { + name: "HMAC", + hash: { + name: "SHA-512" + } + }; + + case "1.2.840.113549.1.9.16.3.5": + return { + name: "DH" + }; + + case "1.3.14.3.2.26": + return { + name: "SHA-1" + }; + + case "2.16.840.1.101.3.4.2.1": + return { + name: "SHA-256" + }; + + case "2.16.840.1.101.3.4.2.2": + return { + name: "SHA-384" + }; + + case "2.16.840.1.101.3.4.2.3": + return { + name: "SHA-512" + }; + + case "1.2.840.113549.1.5.12": + return { + name: "PBKDF2" + }; + //region Special case - OIDs for ECC curves + + case "1.2.840.10045.3.1.7": + return { + name: "P-256" + }; + + case "1.3.132.0.34": + return { + name: "P-384" + }; + + case "1.3.132.0.35": + return { + name: "P-521" + }; + //endregion + + default: + } + + return {}; + } //********************************************************************************** + + /** + * Get OID for each specific algorithm + * @param {Object} algorithm + * @returns {string} + */ + + + getOIDByAlgorithm(algorithm) { + let result = ""; + + switch (algorithm.name.toUpperCase()) { + case "RSASSA-PKCS1-V1_5": + switch (algorithm.hash.name.toUpperCase()) { + case "SHA-1": + result = "1.2.840.113549.1.1.5"; + break; + + case "SHA-256": + result = "1.2.840.113549.1.1.11"; + break; + + case "SHA-384": + result = "1.2.840.113549.1.1.12"; + break; + + case "SHA-512": + result = "1.2.840.113549.1.1.13"; + break; + + default: + } + + break; + + case "RSA-PSS": + result = "1.2.840.113549.1.1.10"; + break; + + case "RSA-OAEP": + result = "1.2.840.113549.1.1.7"; + break; + + case "ECDSA": + switch (algorithm.hash.name.toUpperCase()) { + case "SHA-1": + result = "1.2.840.10045.4.1"; + break; + + case "SHA-256": + result = "1.2.840.10045.4.3.2"; + break; + + case "SHA-384": + result = "1.2.840.10045.4.3.3"; + break; + + case "SHA-512": + result = "1.2.840.10045.4.3.4"; + break; + + default: + } + + break; + + case "ECDH": + switch (algorithm.kdf.toUpperCase()) { + // Non-standard addition - hash algorithm of KDF function + case "SHA-1": + result = "1.3.133.16.840.63.0.2"; // dhSinglePass-stdDH-sha1kdf-scheme + + break; + + case "SHA-256": + result = "1.3.132.1.11.1"; // dhSinglePass-stdDH-sha256kdf-scheme + + break; + + case "SHA-384": + result = "1.3.132.1.11.2"; // dhSinglePass-stdDH-sha384kdf-scheme + + break; + + case "SHA-512": + result = "1.3.132.1.11.3"; // dhSinglePass-stdDH-sha512kdf-scheme + + break; + + default: + } + + break; + + case "AES-CTR": + break; + + case "AES-CBC": + switch (algorithm.length) { + case 128: + result = "2.16.840.1.101.3.4.1.2"; + break; + + case 192: + result = "2.16.840.1.101.3.4.1.22"; + break; + + case 256: + result = "2.16.840.1.101.3.4.1.42"; + break; + + default: + } + + break; + + case "AES-CMAC": + break; + + case "AES-GCM": + switch (algorithm.length) { + case 128: + result = "2.16.840.1.101.3.4.1.6"; + break; + + case 192: + result = "2.16.840.1.101.3.4.1.26"; + break; + + case 256: + result = "2.16.840.1.101.3.4.1.46"; + break; + + default: + } + + break; + + case "AES-CFB": + switch (algorithm.length) { + case 128: + result = "2.16.840.1.101.3.4.1.4"; + break; + + case 192: + result = "2.16.840.1.101.3.4.1.24"; + break; + + case 256: + result = "2.16.840.1.101.3.4.1.44"; + break; + + default: + } + + break; + + case "AES-KW": + switch (algorithm.length) { + case 128: + result = "2.16.840.1.101.3.4.1.5"; + break; + + case 192: + result = "2.16.840.1.101.3.4.1.25"; + break; + + case 256: + result = "2.16.840.1.101.3.4.1.45"; + break; + + default: + } + + break; + + case "HMAC": + switch (algorithm.hash.name.toUpperCase()) { + case "SHA-1": + result = "1.2.840.113549.2.7"; + break; + + case "SHA-256": + result = "1.2.840.113549.2.9"; + break; + + case "SHA-384": + result = "1.2.840.113549.2.10"; + break; + + case "SHA-512": + result = "1.2.840.113549.2.11"; + break; + + default: + } + + break; + + case "DH": + result = "1.2.840.113549.1.9.16.3.5"; + break; + + case "SHA-1": + result = "1.3.14.3.2.26"; + break; + + case "SHA-256": + result = "2.16.840.1.101.3.4.2.1"; + break; + + case "SHA-384": + result = "2.16.840.1.101.3.4.2.2"; + break; + + case "SHA-512": + result = "2.16.840.1.101.3.4.2.3"; + break; + + case "CONCAT": + break; + + case "HKDF": + break; + + case "PBKDF2": + result = "1.2.840.113549.1.5.12"; + break; + //region Special case - OIDs for ECC curves + + case "P-256": + result = "1.2.840.10045.3.1.7"; + break; + + case "P-384": + result = "1.3.132.0.34"; + break; + + case "P-521": + result = "1.3.132.0.35"; + break; + //endregion + + default: + } + + return result; + } //********************************************************************************** + + /** + * Get default algorithm parameters for each kind of operation + * @param {string} algorithmName Algorithm name to get common parameters for + * @param {string} operation Kind of operation: "sign", "encrypt", "generatekey", "importkey", "exportkey", "verify" + * @returns {*} + */ + + + getAlgorithmParameters(algorithmName, operation) { + let result = { + algorithm: {}, + usages: [] + }; + + switch (algorithmName.toUpperCase()) { + case "RSASSA-PKCS1-V1_5": + switch (operation.toLowerCase()) { + case "generatekey": + result = { + algorithm: { + name: "RSASSA-PKCS1-v1_5", + modulusLength: 2048, + publicExponent: new Uint8Array([0x01, 0x00, 0x01]), + hash: { + name: "SHA-256" + } + }, + usages: ["sign", "verify"] + }; + break; + + case "verify": + case "sign": + case "importkey": + result = { + algorithm: { + name: "RSASSA-PKCS1-v1_5", + hash: { + name: "SHA-256" + } + }, + usages: ["verify"] // For importKey("pkcs8") usage must be "sign" only + + }; + break; + + case "exportkey": + default: + return { + algorithm: { + name: "RSASSA-PKCS1-v1_5" + }, + usages: [] + }; + } + + break; + + case "RSA-PSS": + switch (operation.toLowerCase()) { + case "sign": + case "verify": + result = { + algorithm: { + name: "RSA-PSS", + hash: { + name: "SHA-1" + }, + saltLength: 20 + }, + usages: ["sign", "verify"] + }; + break; + + case "generatekey": + result = { + algorithm: { + name: "RSA-PSS", + modulusLength: 2048, + publicExponent: new Uint8Array([0x01, 0x00, 0x01]), + hash: { + name: "SHA-1" + } + }, + usages: ["sign", "verify"] + }; + break; + + case "importkey": + result = { + algorithm: { + name: "RSA-PSS", + hash: { + name: "SHA-1" + } + }, + usages: ["verify"] // For importKey("pkcs8") usage must be "sign" only + + }; + break; + + case "exportkey": + default: + return { + algorithm: { + name: "RSA-PSS" + }, + usages: [] + }; + } + + break; + + case "RSA-OAEP": + switch (operation.toLowerCase()) { + case "encrypt": + case "decrypt": + result = { + algorithm: { + name: "RSA-OAEP" + }, + usages: ["encrypt", "decrypt"] + }; + break; + + case "generatekey": + result = { + algorithm: { + name: "RSA-OAEP", + modulusLength: 2048, + publicExponent: new Uint8Array([0x01, 0x00, 0x01]), + hash: { + name: "SHA-256" + } + }, + usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"] + }; + break; + + case "importkey": + result = { + algorithm: { + name: "RSA-OAEP", + hash: { + name: "SHA-256" + } + }, + usages: ["encrypt"] // encrypt for "spki" and decrypt for "pkcs8" + + }; + break; + + case "exportkey": + default: + return { + algorithm: { + name: "RSA-OAEP" + }, + usages: [] + }; + } + + break; + + case "ECDSA": + switch (operation.toLowerCase()) { + case "generatekey": + result = { + algorithm: { + name: "ECDSA", + namedCurve: "P-256" + }, + usages: ["sign", "verify"] + }; + break; + + case "importkey": + result = { + algorithm: { + name: "ECDSA", + namedCurve: "P-256" + }, + usages: ["verify"] // "sign" for "pkcs8" + + }; + break; + + case "verify": + case "sign": + result = { + algorithm: { + name: "ECDSA", + hash: { + name: "SHA-256" + } + }, + usages: ["sign"] + }; + break; + + default: + return { + algorithm: { + name: "ECDSA" + }, + usages: [] + }; + } + + break; + + case "ECDH": + switch (operation.toLowerCase()) { + case "exportkey": + case "importkey": + case "generatekey": + result = { + algorithm: { + name: "ECDH", + namedCurve: "P-256" + }, + usages: ["deriveKey", "deriveBits"] + }; + break; + + case "derivekey": + case "derivebits": + result = { + algorithm: { + name: "ECDH", + namedCurve: "P-256", + public: [] // Must be a "publicKey" + + }, + usages: ["encrypt", "decrypt"] + }; + break; + + default: + return { + algorithm: { + name: "ECDH" + }, + usages: [] + }; + } + + break; + + case "AES-CTR": + switch (operation.toLowerCase()) { + case "importkey": + case "exportkey": + case "generatekey": + result = { + algorithm: { + name: "AES-CTR", + length: 256 + }, + usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"] + }; + break; + + case "decrypt": + case "encrypt": + result = { + algorithm: { + name: "AES-CTR", + counter: new Uint8Array(16), + length: 10 + }, + usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"] + }; + break; + + default: + return { + algorithm: { + name: "AES-CTR" + }, + usages: [] + }; + } + + break; + + case "AES-CBC": + switch (operation.toLowerCase()) { + case "importkey": + case "exportkey": + case "generatekey": + result = { + algorithm: { + name: "AES-CBC", + length: 256 + }, + usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"] + }; + break; + + case "decrypt": + case "encrypt": + result = { + algorithm: { + name: "AES-CBC", + iv: this.getRandomValues(new Uint8Array(16)) // For "decrypt" the value should be replaced with value got on "encrypt" step + + }, + usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"] + }; + break; + + default: + return { + algorithm: { + name: "AES-CBC" + }, + usages: [] + }; + } + + break; + + case "AES-GCM": + switch (operation.toLowerCase()) { + case "importkey": + case "exportkey": + case "generatekey": + result = { + algorithm: { + name: "AES-GCM", + length: 256 + }, + usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"] + }; + break; + + case "decrypt": + case "encrypt": + result = { + algorithm: { + name: "AES-GCM", + iv: this.getRandomValues(new Uint8Array(16)) // For "decrypt" the value should be replaced with value got on "encrypt" step + + }, + usages: ["encrypt", "decrypt", "wrapKey", "unwrapKey"] + }; + break; + + default: + return { + algorithm: { + name: "AES-GCM" + }, + usages: [] + }; + } + + break; + + case "AES-KW": + switch (operation.toLowerCase()) { + case "importkey": + case "exportkey": + case "generatekey": + case "wrapkey": + case "unwrapkey": + result = { + algorithm: { + name: "AES-KW", + length: 256 + }, + usages: ["wrapKey", "unwrapKey"] + }; + break; + + default: + return { + algorithm: { + name: "AES-KW" + }, + usages: [] + }; + } + + break; + + case "HMAC": + switch (operation.toLowerCase()) { + case "sign": + case "verify": + result = { + algorithm: { + name: "HMAC" + }, + usages: ["sign", "verify"] + }; + break; + + case "importkey": + case "exportkey": + case "generatekey": + result = { + algorithm: { + name: "HMAC", + length: 32, + hash: { + name: "SHA-256" + } + }, + usages: ["sign", "verify"] + }; + break; + + default: + return { + algorithm: { + name: "HMAC" + }, + usages: [] + }; + } + + break; + + case "HKDF": + switch (operation.toLowerCase()) { + case "derivekey": + result = { + algorithm: { + name: "HKDF", + hash: "SHA-256", + salt: new Uint8Array([]), + info: new Uint8Array([]) + }, + usages: ["encrypt", "decrypt"] + }; + break; + + default: + return { + algorithm: { + name: "HKDF" + }, + usages: [] + }; + } + + break; + + case "PBKDF2": + switch (operation.toLowerCase()) { + case "derivekey": + result = { + algorithm: { + name: "PBKDF2", + hash: { + name: "SHA-256" + }, + salt: new Uint8Array([]), + iterations: 10000 + }, + usages: ["encrypt", "decrypt"] + }; + break; + + default: + return { + algorithm: { + name: "PBKDF2" + }, + usages: [] + }; + } + + break; + + default: + } + + return result; + } //********************************************************************************** + + /** + * Getting hash algorithm by signature algorithm + * @param {AlgorithmIdentifier} signatureAlgorithm Signature algorithm + * @returns {string} + */ + + + getHashAlgorithm(signatureAlgorithm) { + let result = ""; + + switch (signatureAlgorithm.algorithmId) { + case "1.2.840.10045.4.1": // ecdsa-with-SHA1 + + case "1.2.840.113549.1.1.5": + result = "SHA-1"; + break; + + case "1.2.840.10045.4.3.2": // ecdsa-with-SHA256 + + case "1.2.840.113549.1.1.11": + result = "SHA-256"; + break; + + case "1.2.840.10045.4.3.3": // ecdsa-with-SHA384 + + case "1.2.840.113549.1.1.12": + result = "SHA-384"; + break; + + case "1.2.840.10045.4.3.4": // ecdsa-with-SHA512 + + case "1.2.840.113549.1.1.13": + result = "SHA-512"; + break; + + case "1.2.840.113549.1.1.10": + // RSA-PSS + { + try { + const params = new _RSASSAPSSParams.default({ + schema: signatureAlgorithm.algorithmParams + }); + + if ("hashAlgorithm" in params) { + const algorithm = this.getAlgorithmByOID(params.hashAlgorithm.algorithmId); + if ("name" in algorithm === false) return ""; + result = algorithm.name; + } else result = "SHA-1"; + } catch (ex) {} + } + break; + + default: + } + + return result; + } //********************************************************************************** + + /** + * Specialized function encrypting "EncryptedContentInfo" object using parameters + * @param {Object} parameters + * @returns {Promise} + */ + + + encryptEncryptedContentInfo(parameters) { + //region Check for input parameters + if (parameters instanceof Object === false) return Promise.reject("Parameters must have type \"Object\""); + if ("password" in parameters === false) return Promise.reject("Absent mandatory parameter \"password\""); + if ("contentEncryptionAlgorithm" in parameters === false) return Promise.reject("Absent mandatory parameter \"contentEncryptionAlgorithm\""); + if ("hmacHashAlgorithm" in parameters === false) return Promise.reject("Absent mandatory parameter \"hmacHashAlgorithm\""); + if ("iterationCount" in parameters === false) return Promise.reject("Absent mandatory parameter \"iterationCount\""); + if ("contentToEncrypt" in parameters === false) return Promise.reject("Absent mandatory parameter \"contentToEncrypt\""); + if ("contentType" in parameters === false) return Promise.reject("Absent mandatory parameter \"contentType\""); + const contentEncryptionOID = this.getOIDByAlgorithm(parameters.contentEncryptionAlgorithm); + if (contentEncryptionOID === "") return Promise.reject("Wrong \"contentEncryptionAlgorithm\" value"); + const pbkdf2OID = this.getOIDByAlgorithm({ + name: "PBKDF2" + }); + if (pbkdf2OID === "") return Promise.reject("Can not find OID for PBKDF2"); + const hmacOID = this.getOIDByAlgorithm({ + name: "HMAC", + hash: { + name: parameters.hmacHashAlgorithm + } + }); + if (hmacOID === "") return Promise.reject(`Incorrect value for "hmacHashAlgorithm": ${parameters.hmacHashAlgorithm}`); //endregion + //region Initial variables + + let sequence = Promise.resolve(); + const ivBuffer = new ArrayBuffer(16); // For AES we need IV 16 bytes long + + const ivView = new Uint8Array(ivBuffer); + this.getRandomValues(ivView); + const saltBuffer = new ArrayBuffer(64); + const saltView = new Uint8Array(saltBuffer); + this.getRandomValues(saltView); + const contentView = new Uint8Array(parameters.contentToEncrypt); + const pbkdf2Params = new _PBKDF2Params.default({ + salt: new asn1js.OctetString({ + valueHex: saltBuffer + }), + iterationCount: parameters.iterationCount, + prf: new _AlgorithmIdentifier.default({ + algorithmId: hmacOID, + algorithmParams: new asn1js.Null() + }) + }); //endregion + //region Derive PBKDF2 key from "password" buffer + + sequence = sequence.then(() => { + const passwordView = new Uint8Array(parameters.password); + return this.importKey("raw", passwordView, "PBKDF2", false, ["deriveKey"]); + }, error => Promise.reject(error)); //endregion + //region Derive key for "contentEncryptionAlgorithm" + + sequence = sequence.then(result => this.deriveKey({ + name: "PBKDF2", + hash: { + name: parameters.hmacHashAlgorithm + }, + salt: saltView, + iterations: parameters.iterationCount + }, result, parameters.contentEncryptionAlgorithm, false, ["encrypt"]), error => Promise.reject(error)); //endregion + //region Encrypt content + + sequence = sequence.then(result => this.encrypt({ + name: parameters.contentEncryptionAlgorithm.name, + iv: ivView + }, result, contentView), error => Promise.reject(error)); //endregion + //region Store all parameters in EncryptedData object + + sequence = sequence.then(result => { + const pbes2Parameters = new _PBES2Params.default({ + keyDerivationFunc: new _AlgorithmIdentifier.default({ + algorithmId: pbkdf2OID, + algorithmParams: pbkdf2Params.toSchema() + }), + encryptionScheme: new _AlgorithmIdentifier.default({ + algorithmId: contentEncryptionOID, + algorithmParams: new asn1js.OctetString({ + valueHex: ivBuffer + }) + }) + }); + return new _EncryptedContentInfo.default({ + contentType: parameters.contentType, + contentEncryptionAlgorithm: new _AlgorithmIdentifier.default({ + algorithmId: "1.2.840.113549.1.5.13", + // pkcs5PBES2 + algorithmParams: pbes2Parameters.toSchema() + }), + encryptedContent: new asn1js.OctetString({ + valueHex: result + }) + }); + }, error => Promise.reject(error)); //endregion + + return sequence; + } //********************************************************************************** + + /** + * Decrypt data stored in "EncryptedContentInfo" object using parameters + * @param parameters + * @return {Promise} + */ + + + decryptEncryptedContentInfo(parameters) { + //region Check for input parameters + if (parameters instanceof Object === false) return Promise.reject("Parameters must have type \"Object\""); + if ("password" in parameters === false) return Promise.reject("Absent mandatory parameter \"password\""); + if ("encryptedContentInfo" in parameters === false) return Promise.reject("Absent mandatory parameter \"encryptedContentInfo\""); + if (parameters.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId !== "1.2.840.113549.1.5.13") // pkcs5PBES2 + return Promise.reject(`Unknown "contentEncryptionAlgorithm": ${parameters.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId}`); //endregion + //region Initial variables + + let sequence = Promise.resolve(); + let pbes2Parameters; + + try { + pbes2Parameters = new _PBES2Params.default({ + schema: parameters.encryptedContentInfo.contentEncryptionAlgorithm.algorithmParams + }); + } catch (ex) { + return Promise.reject("Incorrectly encoded \"pbes2Parameters\""); + } + + let pbkdf2Params; + + try { + pbkdf2Params = new _PBKDF2Params.default({ + schema: pbes2Parameters.keyDerivationFunc.algorithmParams + }); + } catch (ex) { + return Promise.reject("Incorrectly encoded \"pbkdf2Params\""); + } + + const contentEncryptionAlgorithm = this.getAlgorithmByOID(pbes2Parameters.encryptionScheme.algorithmId); + if ("name" in contentEncryptionAlgorithm === false) return Promise.reject(`Incorrect OID for "contentEncryptionAlgorithm": ${pbes2Parameters.encryptionScheme.algorithmId}`); + const ivBuffer = pbes2Parameters.encryptionScheme.algorithmParams.valueBlock.valueHex; + const ivView = new Uint8Array(ivBuffer); + const saltBuffer = pbkdf2Params.salt.valueBlock.valueHex; + const saltView = new Uint8Array(saltBuffer); + const iterationCount = pbkdf2Params.iterationCount; + let hmacHashAlgorithm = "SHA-1"; + + if ("prf" in pbkdf2Params) { + const algorithm = this.getAlgorithmByOID(pbkdf2Params.prf.algorithmId); + if ("name" in algorithm === false) return Promise.reject("Incorrect OID for HMAC hash algorithm"); + hmacHashAlgorithm = algorithm.hash.name; + } //endregion + //region Derive PBKDF2 key from "password" buffer + + + sequence = sequence.then(() => this.importKey("raw", parameters.password, "PBKDF2", false, ["deriveKey"]), error => Promise.reject(error)); //endregion + //region Derive key for "contentEncryptionAlgorithm" + + sequence = sequence.then(result => this.deriveKey({ + name: "PBKDF2", + hash: { + name: hmacHashAlgorithm + }, + salt: saltView, + iterations: iterationCount + }, result, contentEncryptionAlgorithm, false, ["decrypt"]), error => Promise.reject(error)); //endregion + //region Decrypt internal content using derived key + + sequence = sequence.then(result => { + //region Create correct data block for decryption + let dataBuffer = new ArrayBuffer(0); + if (parameters.encryptedContentInfo.encryptedContent.idBlock.isConstructed === false) dataBuffer = parameters.encryptedContentInfo.encryptedContent.valueBlock.valueHex;else { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = parameters.encryptedContentInfo.encryptedContent.valueBlock.value[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + const content = _step.value; + dataBuffer = (0, _pvutils.utilConcatBuf)(dataBuffer, content.valueBlock.valueHex); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } //endregion + + return this.decrypt({ + name: contentEncryptionAlgorithm.name, + iv: ivView + }, result, dataBuffer); + }, error => Promise.reject(error)); //endregion + + return sequence; + } //********************************************************************************** + + /** + * Stamping (signing) data using algorithm simular to HMAC + * @param {Object} parameters + * @return {Promise.|Promise} + */ + + + stampDataWithPassword(parameters) { + //region Check for input parameters + if (parameters instanceof Object === false) return Promise.reject("Parameters must have type \"Object\""); + if ("password" in parameters === false) return Promise.reject("Absent mandatory parameter \"password\""); + if ("hashAlgorithm" in parameters === false) return Promise.reject("Absent mandatory parameter \"hashAlgorithm\""); + if ("salt" in parameters === false) return Promise.reject("Absent mandatory parameter \"iterationCount\""); + if ("iterationCount" in parameters === false) return Promise.reject("Absent mandatory parameter \"salt\""); + if ("contentToStamp" in parameters === false) return Promise.reject("Absent mandatory parameter \"contentToStamp\""); //endregion + //region Choose correct length for HMAC key + + let length; + + switch (parameters.hashAlgorithm.toLowerCase()) { + case "sha-1": + length = 160; + break; + + case "sha-256": + length = 256; + break; + + case "sha-384": + length = 384; + break; + + case "sha-512": + length = 512; + break; + + default: + return Promise.reject(`Incorrect "parameters.hashAlgorithm" parameter: ${parameters.hashAlgorithm}`); + } //endregion + //region Initial variables + + + let sequence = Promise.resolve(); + const hmacAlgorithm = { + name: "HMAC", + length, + hash: { + name: parameters.hashAlgorithm + } + }; //endregion + //region Create PKCS#12 key for integrity checking + + sequence = sequence.then(() => makePKCS12B2Key(this, parameters.hashAlgorithm, length, parameters.password, parameters.salt, parameters.iterationCount)); //endregion + //region Import HMAC key + // noinspection JSCheckFunctionSignatures + + sequence = sequence.then(result => this.importKey("raw", new Uint8Array(result), hmacAlgorithm, false, ["sign"])); //endregion + //region Make signed HMAC value + + sequence = sequence.then(result => this.sign(hmacAlgorithm, result, new Uint8Array(parameters.contentToStamp)), error => Promise.reject(error)); //endregion + + return sequence; + } //********************************************************************************** + + + verifyDataStampedWithPassword(parameters) { + //region Check for input parameters + if (parameters instanceof Object === false) return Promise.reject("Parameters must have type \"Object\""); + if ("password" in parameters === false) return Promise.reject("Absent mandatory parameter \"password\""); + if ("hashAlgorithm" in parameters === false) return Promise.reject("Absent mandatory parameter \"hashAlgorithm\""); + if ("salt" in parameters === false) return Promise.reject("Absent mandatory parameter \"iterationCount\""); + if ("iterationCount" in parameters === false) return Promise.reject("Absent mandatory parameter \"salt\""); + if ("contentToVerify" in parameters === false) return Promise.reject("Absent mandatory parameter \"contentToVerify\""); + if ("signatureToVerify" in parameters === false) return Promise.reject("Absent mandatory parameter \"signatureToVerify\""); //endregion + //region Choose correct length for HMAC key + + let length; + + switch (parameters.hashAlgorithm.toLowerCase()) { + case "sha-1": + length = 160; + break; + + case "sha-256": + length = 256; + break; + + case "sha-384": + length = 384; + break; + + case "sha-512": + length = 512; + break; + + default: + return Promise.reject(`Incorrect "parameters.hashAlgorithm" parameter: ${parameters.hashAlgorithm}`); + } //endregion + //region Initial variables + + + let sequence = Promise.resolve(); + const hmacAlgorithm = { + name: "HMAC", + length, + hash: { + name: parameters.hashAlgorithm + } + }; //endregion + //region Create PKCS#12 key for integrity checking + + sequence = sequence.then(() => makePKCS12B2Key(this, parameters.hashAlgorithm, length, parameters.password, parameters.salt, parameters.iterationCount)); //endregion + //region Import HMAC key + // noinspection JSCheckFunctionSignatures + + sequence = sequence.then(result => this.importKey("raw", new Uint8Array(result), hmacAlgorithm, false, ["verify"])); //endregion + //region Make signed HMAC value + + sequence = sequence.then(result => this.verify(hmacAlgorithm, result, new Uint8Array(parameters.signatureToVerify), new Uint8Array(parameters.contentToVerify)), error => Promise.reject(error)); //endregion + + return sequence; + } //********************************************************************************** + + /** + * Get signature parameters by analyzing private key algorithm + * @param {Object} privateKey The private key user would like to use + * @param {string} [hashAlgorithm="SHA-1"] Hash algorithm user would like to use + * @return {Promise.|Promise} + */ + + + getSignatureParameters(privateKey, hashAlgorithm = "SHA-1") { + //region Check hashing algorithm + const oid = this.getOIDByAlgorithm({ + name: hashAlgorithm + }); + if (oid === "") return Promise.reject(`Unsupported hash algorithm: ${hashAlgorithm}`); //endregion + //region Initial variables + + const signatureAlgorithm = new _AlgorithmIdentifier.default(); //endregion + //region Get a "default parameters" for current algorithm + + const parameters = this.getAlgorithmParameters(privateKey.algorithm.name, "sign"); + parameters.algorithm.hash.name = hashAlgorithm; //endregion + //region Fill internal structures base on "privateKey" and "hashAlgorithm" + + switch (privateKey.algorithm.name.toUpperCase()) { + case "RSASSA-PKCS1-V1_5": + case "ECDSA": + signatureAlgorithm.algorithmId = this.getOIDByAlgorithm(parameters.algorithm); + break; + + case "RSA-PSS": + { + //region Set "saltLength" as a length (in octets) of hash function result + switch (hashAlgorithm.toUpperCase()) { + case "SHA-256": + parameters.algorithm.saltLength = 32; + break; + + case "SHA-384": + parameters.algorithm.saltLength = 48; + break; + + case "SHA-512": + parameters.algorithm.saltLength = 64; + break; + + default: + } //endregion + //region Fill "RSASSA_PSS_params" object + + + const paramsObject = {}; + + if (hashAlgorithm.toUpperCase() !== "SHA-1") { + const hashAlgorithmOID = this.getOIDByAlgorithm({ + name: hashAlgorithm + }); + if (hashAlgorithmOID === "") return Promise.reject(`Unsupported hash algorithm: ${hashAlgorithm}`); + paramsObject.hashAlgorithm = new _AlgorithmIdentifier.default({ + algorithmId: hashAlgorithmOID, + algorithmParams: new asn1js.Null() + }); + paramsObject.maskGenAlgorithm = new _AlgorithmIdentifier.default({ + algorithmId: "1.2.840.113549.1.1.8", + // MGF1 + algorithmParams: paramsObject.hashAlgorithm.toSchema() + }); + } + + if (parameters.algorithm.saltLength !== 20) paramsObject.saltLength = parameters.algorithm.saltLength; + const pssParameters = new _RSASSAPSSParams.default(paramsObject); //endregion + //region Automatically set signature algorithm + + signatureAlgorithm.algorithmId = "1.2.840.113549.1.1.10"; + signatureAlgorithm.algorithmParams = pssParameters.toSchema(); //endregion + } + break; + + default: + return Promise.reject(`Unsupported signature algorithm: ${privateKey.algorithm.name}`); + } //endregion + + + return Promise.resolve().then(() => ({ + signatureAlgorithm, + parameters + })); + } //********************************************************************************** + + /** + * Sign data with pre-defined private key + * @param {ArrayBuffer} data Data to be signed + * @param {Object} privateKey Private key to use + * @param {Object} parameters Parameters for used algorithm + * @return {Promise.|Promise} + */ + + + signWithPrivateKey(data, privateKey, parameters) { + return this.sign(parameters.algorithm, privateKey, new Uint8Array(data)).then(result => { + //region Special case for ECDSA algorithm + if (parameters.algorithm.name === "ECDSA") result = (0, _common.createCMSECDSASignature)(result); //endregion + + return result; + }, error => Promise.reject(`Signing error: ${error}`)); + } //********************************************************************************** + + + fillPublicKeyParameters(publicKeyInfo, signatureAlgorithm) { + const parameters = {}; //region Find signer's hashing algorithm + + const shaAlgorithm = this.getHashAlgorithm(signatureAlgorithm); + if (shaAlgorithm === "") return Promise.reject(`Unsupported signature algorithm: ${signatureAlgorithm.algorithmId}`); //endregion + //region Get information about public key algorithm and default parameters for import + + let algorithmId; + if (signatureAlgorithm.algorithmId === "1.2.840.113549.1.1.10") algorithmId = signatureAlgorithm.algorithmId;else algorithmId = publicKeyInfo.algorithm.algorithmId; + const algorithmObject = this.getAlgorithmByOID(algorithmId); + if ("name" in algorithmObject === "") return Promise.reject(`Unsupported public key algorithm: ${signatureAlgorithm.algorithmId}`); + parameters.algorithm = this.getAlgorithmParameters(algorithmObject.name, "importkey"); + if ("hash" in parameters.algorithm.algorithm) parameters.algorithm.algorithm.hash.name = shaAlgorithm; //region Special case for ECDSA + + if (algorithmObject.name === "ECDSA") { + //region Get information about named curve + let algorithmParamsChecked = false; + + if ("algorithmParams" in publicKeyInfo.algorithm === true) { + if ("idBlock" in publicKeyInfo.algorithm.algorithmParams) { + if (publicKeyInfo.algorithm.algorithmParams.idBlock.tagClass === 1 && publicKeyInfo.algorithm.algorithmParams.idBlock.tagNumber === 6) algorithmParamsChecked = true; + } + } + + if (algorithmParamsChecked === false) return Promise.reject("Incorrect type for ECDSA public key parameters"); + const curveObject = this.getAlgorithmByOID(publicKeyInfo.algorithm.algorithmParams.valueBlock.toString()); + if ("name" in curveObject === false) return Promise.reject(`Unsupported named curve algorithm: ${publicKeyInfo.algorithm.algorithmParams.valueBlock.toString()}`); //endregion + + parameters.algorithm.algorithm.namedCurve = curveObject.name; + } //endregion + //endregion + + + return parameters; + } //********************************************************************************** + + + getPublicKey(publicKeyInfo, signatureAlgorithm, parameters = null) { + if (parameters === null) parameters = this.fillPublicKeyParameters(publicKeyInfo, signatureAlgorithm); + const publicKeyInfoSchema = publicKeyInfo.toSchema(); + const publicKeyInfoBuffer = publicKeyInfoSchema.toBER(false); + const publicKeyInfoView = new Uint8Array(publicKeyInfoBuffer); + return this.importKey("spki", publicKeyInfoView, parameters.algorithm.algorithm, true, parameters.algorithm.usages); + } //********************************************************************************** + + + verifyWithPublicKey(data, signature, publicKeyInfo, signatureAlgorithm, shaAlgorithm = null) { + //region Initial variables + let sequence = Promise.resolve(); //endregion + //region Find signer's hashing algorithm + + if (shaAlgorithm === null) { + shaAlgorithm = this.getHashAlgorithm(signatureAlgorithm); + if (shaAlgorithm === "") return Promise.reject(`Unsupported signature algorithm: ${signatureAlgorithm.algorithmId}`); //region Import public key + + sequence = sequence.then(() => this.getPublicKey(publicKeyInfo, signatureAlgorithm)); //endregion + } else { + const parameters = {}; //region Get information about public key algorithm and default parameters for import + + let algorithmId; + if (signatureAlgorithm.algorithmId === "1.2.840.113549.1.1.10") algorithmId = signatureAlgorithm.algorithmId;else algorithmId = publicKeyInfo.algorithm.algorithmId; + const algorithmObject = this.getAlgorithmByOID(algorithmId); + if ("name" in algorithmObject === "") return Promise.reject(`Unsupported public key algorithm: ${signatureAlgorithm.algorithmId}`); + parameters.algorithm = this.getAlgorithmParameters(algorithmObject.name, "importkey"); + if ("hash" in parameters.algorithm.algorithm) parameters.algorithm.algorithm.hash.name = shaAlgorithm; //region Special case for ECDSA + + if (algorithmObject.name === "ECDSA") { + //region Get information about named curve + let algorithmParamsChecked = false; + + if ("algorithmParams" in publicKeyInfo.algorithm === true) { + if ("idBlock" in publicKeyInfo.algorithm.algorithmParams) { + if (publicKeyInfo.algorithm.algorithmParams.idBlock.tagClass === 1 && publicKeyInfo.algorithm.algorithmParams.idBlock.tagNumber === 6) algorithmParamsChecked = true; + } + } + + if (algorithmParamsChecked === false) return Promise.reject("Incorrect type for ECDSA public key parameters"); + const curveObject = this.getAlgorithmByOID(publicKeyInfo.algorithm.algorithmParams.valueBlock.toString()); + if ("name" in curveObject === false) return Promise.reject(`Unsupported named curve algorithm: ${publicKeyInfo.algorithm.algorithmParams.valueBlock.toString()}`); //endregion + + parameters.algorithm.algorithm.namedCurve = curveObject.name; + } //endregion + //endregion + //region Import public key + + + sequence = sequence.then(() => this.getPublicKey(publicKeyInfo, null, parameters)); //endregion + } //endregion + //region Verify signature + + + sequence = sequence.then(publicKey => { + //region Get default algorithm parameters for verification + const algorithm = this.getAlgorithmParameters(publicKey.algorithm.name, "verify"); + if ("hash" in algorithm.algorithm) algorithm.algorithm.hash.name = shaAlgorithm; //endregion + //region Special case for ECDSA signatures + + let signatureValue = signature.valueBlock.valueHex; + + if (publicKey.algorithm.name === "ECDSA") { + const asn1 = asn1js.fromBER(signatureValue); // noinspection JSCheckFunctionSignatures + + signatureValue = (0, _common.createECDSASignatureFromCMS)(asn1.result); + } //endregion + //region Special case for RSA-PSS + + + if (publicKey.algorithm.name === "RSA-PSS") { + let pssParameters; + + try { + pssParameters = new _RSASSAPSSParams.default({ + schema: signatureAlgorithm.algorithmParams + }); + } catch (ex) { + return Promise.reject(ex); + } + + if ("saltLength" in pssParameters) algorithm.algorithm.saltLength = pssParameters.saltLength;else algorithm.algorithm.saltLength = 20; + let hashAlgo = "SHA-1"; + + if ("hashAlgorithm" in pssParameters) { + const hashAlgorithm = this.getAlgorithmByOID(pssParameters.hashAlgorithm.algorithmId); + if ("name" in hashAlgorithm === false) return Promise.reject(`Unrecognized hash algorithm: ${pssParameters.hashAlgorithm.algorithmId}`); + hashAlgo = hashAlgorithm.name; + } + + algorithm.algorithm.hash.name = hashAlgo; + } //endregion + + + return this.verify(algorithm.algorithm, publicKey, new Uint8Array(signatureValue), new Uint8Array(data)); + }); //endregion + + return sequence; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = CryptoEngine; + +},{"./AlgorithmIdentifier.js":4,"./EncryptedContentInfo.js":34,"./PBES2Params.js":65,"./PBKDF2Params.js":66,"./PrivateKeyInfo.js":76,"./PublicKeyInfo.js":78,"./RSASSAPSSParams.js":83,"./common.js":110,"asn1js":112,"pvutils":113}],28:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC3447 + */ +class DigestInfo { + //********************************************************************************** + + /** + * Constructor for DigestInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {AlgorithmIdentifier} + * @desc digestAlgorithm + */ + this.digestAlgorithm = (0, _pvutils.getParametersValue)(parameters, "digestAlgorithm", DigestInfo.defaultValues("digestAlgorithm")); + /** + * @type {OctetString} + * @desc digest + */ + + this.digest = (0, _pvutils.getParametersValue)(parameters, "digest", DigestInfo.defaultValues("digest")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "digestAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "digest": + return new asn1js.OctetString(); + + default: + throw new Error(`Invalid member name for DigestInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "digestAlgorithm": + return _AlgorithmIdentifier.default.compareWithDefault("algorithmId", memberValue.algorithmId) && "algorithmParams" in memberValue === false; + + case "digest": + return memberValue.isEqual(DigestInfo.defaultValues(memberName)); + + default: + throw new Error(`Invalid member name for DigestInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * DigestInfo ::= SEQUENCE { + * digestAlgorithm DigestAlgorithmIdentifier, + * digest Digest } + * + * Digest ::= OCTET STRING + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [type] + * @property {string} [setName] + * @property {string} [values] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_AlgorithmIdentifier.default.schema(names.digestAlgorithm || { + names: { + blockName: "digestAlgorithm" + } + }), new asn1js.OctetString({ + name: names.digest || "digest" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["digestAlgorithm", "digest"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, DigestInfo.schema({ + names: { + digestAlgorithm: { + names: { + blockName: "digestAlgorithm" + } + }, + digest: "digest" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for DigestInfo"); //endregion + //region Get internal properties from parsed schema + + this.digestAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.digestAlgorithm + }); + this.digest = asn1.result.digest; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [this.digestAlgorithm.toSchema(), this.digest] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + digestAlgorithm: this.digestAlgorithm.toJSON(), + digest: this.digest.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = DigestInfo; + +},{"./AlgorithmIdentifier.js":4,"asn1js":112,"pvutils":113}],29:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _GeneralName = _interopRequireDefault(require("./GeneralName.js")); + +var _RelativeDistinguishedNames = _interopRequireDefault(require("./RelativeDistinguishedNames.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class DistributionPoint { + //********************************************************************************** + + /** + * Constructor for DistributionPoint class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + * @property {Object} [distributionPoint] + * @property {Object} [reasons] + * @property {Object} [cRLIssuer] + */ + constructor(parameters = {}) { + //region Internal properties of the object + if ("distributionPoint" in parameters) + /** + * @type {Array.} + * @desc distributionPoint + */ + this.distributionPoint = (0, _pvutils.getParametersValue)(parameters, "distributionPoint", DistributionPoint.defaultValues("distributionPoint")); + if ("reasons" in parameters) + /** + * @type {BitString} + * @desc values + */ + this.reasons = (0, _pvutils.getParametersValue)(parameters, "reasons", DistributionPoint.defaultValues("reasons")); + if ("cRLIssuer" in parameters) + /** + * @type {Array.} + * @desc cRLIssuer + */ + this.cRLIssuer = (0, _pvutils.getParametersValue)(parameters, "cRLIssuer", DistributionPoint.defaultValues("cRLIssuer")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "distributionPoint": + return []; + + case "reasons": + return new asn1js.BitString(); + + case "cRLIssuer": + return []; + + default: + throw new Error(`Invalid member name for DistributionPoint class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * DistributionPoint ::= SEQUENCE { + * distributionPoint [0] DistributionPointName OPTIONAL, + * reasons [1] ReasonFlags OPTIONAL, + * cRLIssuer [2] GeneralNames OPTIONAL } + * + * DistributionPointName ::= CHOICE { + * fullName [0] GeneralNames, + * nameRelativeToCRLIssuer [1] RelativeDistinguishedName } + * + * ReasonFlags ::= BIT STRING { + * unused (0), + * keyCompromise (1), + * cACompromise (2), + * affiliationChanged (3), + * superseded (4), + * cessationOfOperation (5), + * certificateHold (6), + * privilegeWithdrawn (7), + * aACompromise (8) } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [distributionPoint] + * @property {string} [distributionPointNames] + * @property {string} [reasons] + * @property {string} [cRLIssuer] + * @property {string} [cRLIssuerNames] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Choice({ + value: [new asn1js.Constructed({ + name: names.distributionPoint || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Repeated({ + name: names.distributionPointNames || "", + value: _GeneralName.default.schema() + })] + }), new asn1js.Constructed({ + name: names.distributionPoint || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: _RelativeDistinguishedNames.default.schema().valueBlock.value + })] + })] + }), new asn1js.Primitive({ + name: names.reasons || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + } + }), // IMPLICIT bitstring value + new asn1js.Constructed({ + name: names.cRLIssuer || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + value: [new asn1js.Repeated({ + name: names.cRLIssuerNames || "", + value: _GeneralName.default.schema() + })] + }) // IMPLICIT bitstring value + ] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["distributionPoint", "distributionPointNames", "reasons", "cRLIssuer", "cRLIssuerNames"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, DistributionPoint.schema({ + names: { + distributionPoint: "distributionPoint", + distributionPointNames: "distributionPointNames", + reasons: "reasons", + cRLIssuer: "cRLIssuer", + cRLIssuerNames: "cRLIssuerNames" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for DistributionPoint"); //endregion + //region Get internal properties from parsed schema + + if ("distributionPoint" in asn1.result) { + if (asn1.result.distributionPoint.idBlock.tagNumber === 0) // GENERAL_NAMES variant + this.distributionPoint = Array.from(asn1.result.distributionPointNames, element => new _GeneralName.default({ + schema: element + })); + + if (asn1.result.distributionPoint.idBlock.tagNumber === 1) // RDN variant + { + this.distributionPoint = new _RelativeDistinguishedNames.default({ + schema: new asn1js.Sequence({ + value: asn1.result.distributionPoint.valueBlock.value + }) + }); + } + } + + if ("reasons" in asn1.result) this.reasons = new asn1js.BitString({ + valueHex: asn1.result.reasons.valueBlock.valueHex + }); + if ("cRLIssuer" in asn1.result) this.cRLIssuer = Array.from(asn1.result.cRLIssuerNames, element => new _GeneralName.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + + if ("distributionPoint" in this) { + let internalValue; + + if (this.distributionPoint instanceof Array) { + internalValue = new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: Array.from(this.distributionPoint, element => element.toSchema()) + }); + } else { + internalValue = new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [this.distributionPoint.toSchema()] + }); + } + + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [internalValue] + })); + } + + if ("reasons" in this) { + outputArray.push(new asn1js.Primitive({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + valueHex: this.reasons.valueBlock.valueHex + })); + } + + if ("cRLIssuer" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + value: Array.from(this.cRLIssuer, element => element.toSchema()) + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = {}; + + if ("distributionPoint" in this) { + if (this.distributionPoint instanceof Array) object.distributionPoint = Array.from(this.distributionPoint, element => element.toJSON());else object.distributionPoint = this.distributionPoint.toJSON(); + } + + if ("reasons" in this) object.reasons = this.reasons.toJSON(); + if ("cRLIssuer" in this) object.cRLIssuer = Array.from(this.cRLIssuer, element => element.toJSON()); + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = DistributionPoint; + +},{"./GeneralName.js":40,"./RelativeDistinguishedNames.js":89,"asn1js":112,"pvutils":113}],30:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC6318 + */ +class ECCCMSSharedInfo { + //********************************************************************************** + + /** + * Constructor for ECCCMSSharedInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {AlgorithmIdentifier} + * @desc keyInfo + */ + this.keyInfo = (0, _pvutils.getParametersValue)(parameters, "keyInfo", ECCCMSSharedInfo.defaultValues("keyInfo")); + if ("entityUInfo" in parameters) + /** + * @type {OctetString} + * @desc entityUInfo + */ + this.entityUInfo = (0, _pvutils.getParametersValue)(parameters, "entityUInfo", ECCCMSSharedInfo.defaultValues("entityUInfo")); + /** + * @type {OctetString} + * @desc suppPubInfo + */ + + this.suppPubInfo = (0, _pvutils.getParametersValue)(parameters, "suppPubInfo", ECCCMSSharedInfo.defaultValues("suppPubInfo")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "keyInfo": + return new _AlgorithmIdentifier.default(); + + case "entityUInfo": + return new asn1js.OctetString(); + + case "suppPubInfo": + return new asn1js.OctetString(); + + default: + throw new Error(`Invalid member name for ECCCMSSharedInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "keyInfo": + case "entityUInfo": + case "suppPubInfo": + return memberValue.isEqual(ECCCMSSharedInfo.defaultValues(memberName)); + + default: + throw new Error(`Invalid member name for ECCCMSSharedInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * ECC-CMS-SharedInfo ::= SEQUENCE { + * keyInfo AlgorithmIdentifier, + * entityUInfo [0] EXPLICIT OCTET STRING OPTIONAL, + * suppPubInfo [2] EXPLICIT OCTET STRING } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [keyInfo] + * @property {string} [entityUInfo] + * @property {string} [suppPubInfo] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_AlgorithmIdentifier.default.schema(names.keyInfo || {}), new asn1js.Constructed({ + name: names.entityUInfo || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + optional: true, + value: [new asn1js.OctetString()] + }), new asn1js.Constructed({ + name: names.suppPubInfo || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + value: [new asn1js.OctetString()] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["keyInfo", "entityUInfo", "suppPubInfo"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, ECCCMSSharedInfo.schema({ + names: { + keyInfo: { + names: { + blockName: "keyInfo" + } + }, + entityUInfo: "entityUInfo", + suppPubInfo: "suppPubInfo" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for ECCCMSSharedInfo"); //endregion + //region Get internal properties from parsed schema + + this.keyInfo = new _AlgorithmIdentifier.default({ + schema: asn1.result.keyInfo + }); + if ("entityUInfo" in asn1.result) this.entityUInfo = asn1.result.entityUInfo.valueBlock.value[0]; + this.suppPubInfo = asn1.result.suppPubInfo.valueBlock.value[0]; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create output array for sequence + const outputArray = []; + outputArray.push(this.keyInfo.toSchema()); + + if ("entityUInfo" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [this.entityUInfo] + })); + } + + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + value: [this.suppPubInfo] + })); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + keyInfo: this.keyInfo.toJSON() + }; + if ("entityUInfo" in this) _object.entityUInfo = this.entityUInfo.toJSON(); + _object.suppPubInfo = this.suppPubInfo.toJSON(); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = ECCCMSSharedInfo; + +},{"./AlgorithmIdentifier.js":4,"asn1js":112,"pvutils":113}],31:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _ECPublicKey = _interopRequireDefault(require("./ECPublicKey.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5915 + */ +class ECPrivateKey { + //********************************************************************************** + + /** + * Constructor for ECPrivateKey class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", ECPrivateKey.defaultValues("version")); + /** + * @type {OctetString} + * @desc privateKey + */ + + this.privateKey = (0, _pvutils.getParametersValue)(parameters, "privateKey", ECPrivateKey.defaultValues("privateKey")); + if ("namedCurve" in parameters) + /** + * @type {string} + * @desc namedCurve + */ + this.namedCurve = (0, _pvutils.getParametersValue)(parameters, "namedCurve", ECPrivateKey.defaultValues("namedCurve")); + if ("publicKey" in parameters) + /** + * @type {ECPublicKey} + * @desc publicKey + */ + this.publicKey = (0, _pvutils.getParametersValue)(parameters, "publicKey", ECPrivateKey.defaultValues("publicKey")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + //region If input argument array contains "json" for this object + + if ("json" in parameters) this.fromJSON(parameters.json); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 1; + + case "privateKey": + return new asn1js.OctetString(); + + case "namedCurve": + return ""; + + case "publicKey": + return new _ECPublicKey.default(); + + default: + throw new Error(`Invalid member name for ECCPrivateKey class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "version": + return memberValue === ECPrivateKey.defaultValues(memberName); + + case "privateKey": + return memberValue.isEqual(ECPrivateKey.defaultValues(memberName)); + + case "namedCurve": + return memberValue === ""; + + case "publicKey": + return _ECPublicKey.default.compareWithDefault("namedCurve", memberValue.namedCurve) && _ECPublicKey.default.compareWithDefault("x", memberValue.x) && _ECPublicKey.default.compareWithDefault("y", memberValue.y); + + default: + throw new Error(`Invalid member name for ECCPrivateKey class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * ECPrivateKey ::= SEQUENCE { + * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + * privateKey OCTET STRING, + * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + * publicKey [1] BIT STRING OPTIONAL + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [version] + * @property {string} [privateKey] + * @property {string} [namedCurve] + * @property {string} [publicKey] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.version || "" + }), new asn1js.OctetString({ + name: names.privateKey || "" + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.ObjectIdentifier({ + name: names.namedCurve || "" + })] + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [new asn1js.BitString({ + name: names.publicKey || "" + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["version", "privateKey", "namedCurve", "publicKey"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, ECPrivateKey.schema({ + names: { + version: "version", + privateKey: "privateKey", + namedCurve: "namedCurve", + publicKey: "publicKey" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for ECPrivateKey"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result.version.valueBlock.valueDec; + this.privateKey = asn1.result.privateKey; + if ("namedCurve" in asn1.result) this.namedCurve = asn1.result.namedCurve.valueBlock.toString(); + + if ("publicKey" in asn1.result) { + const publicKeyData = { + schema: asn1.result.publicKey.valueBlock.valueHex + }; + if ("namedCurve" in this) publicKeyData.namedCurve = this.namedCurve; + this.publicKey = new _ECPublicKey.default(publicKeyData); + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + const outputArray = [new asn1js.Integer({ + value: this.version + }), this.privateKey]; + + if ("namedCurve" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.ObjectIdentifier({ + value: this.namedCurve + })] + })); + } + + if ("publicKey" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [new asn1js.BitString({ + valueHex: this.publicKey.toSchema().toBER(false) + })] + })); + } + + return new asn1js.Sequence({ + value: outputArray + }); + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + if ("namedCurve" in this === false || ECPrivateKey.compareWithDefault("namedCurve", this.namedCurve)) throw new Error("Not enough information for making JSON: absent \"namedCurve\" value"); + let crvName = ""; + + switch (this.namedCurve) { + case "1.2.840.10045.3.1.7": + // P-256 + crvName = "P-256"; + break; + + case "1.3.132.0.34": + // P-384 + crvName = "P-384"; + break; + + case "1.3.132.0.35": + // P-521 + crvName = "P-521"; + break; + + default: + } + + const privateKeyJSON = { + crv: crvName, + d: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.privateKey.valueBlock.valueHex), true, true, false) + }; + + if ("publicKey" in this) { + const publicKeyJSON = this.publicKey.toJSON(); + privateKeyJSON.x = publicKeyJSON.x; + privateKeyJSON.y = publicKeyJSON.y; + } + + return privateKeyJSON; + } //********************************************************************************** + + /** + * Convert JSON value into current object + * @param {Object} json + */ + + + fromJSON(json) { + let coodinateLength = 0; + + if ("crv" in json) { + switch (json.crv.toUpperCase()) { + case "P-256": + this.namedCurve = "1.2.840.10045.3.1.7"; + coodinateLength = 32; + break; + + case "P-384": + this.namedCurve = "1.3.132.0.34"; + coodinateLength = 48; + break; + + case "P-521": + this.namedCurve = "1.3.132.0.35"; + coodinateLength = 66; + break; + + default: + } + } else throw new Error("Absent mandatory parameter \"crv\""); + + if ("d" in json) { + const convertBuffer = (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.d, true)); + + if (convertBuffer.byteLength < coodinateLength) { + const buffer = new ArrayBuffer(coodinateLength); + const view = new Uint8Array(buffer); + const convertBufferView = new Uint8Array(convertBuffer); + view.set(convertBufferView, 1); + this.privateKey = new asn1js.OctetString({ + valueHex: buffer + }); + } else this.privateKey = new asn1js.OctetString({ + valueHex: convertBuffer.slice(0, coodinateLength) + }); + } else throw new Error("Absent mandatory parameter \"d\""); + + if ("x" in json && "y" in json) this.publicKey = new _ECPublicKey.default({ + json + }); + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = ECPrivateKey; + +},{"./ECPublicKey.js":32,"asn1js":112,"pvutils":113}],32:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5480 + */ +class ECPublicKey { + //********************************************************************************** + + /** + * Constructor for ECCPublicKey class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {ArrayBuffer} + * @desc type + */ + this.x = (0, _pvutils.getParametersValue)(parameters, "x", ECPublicKey.defaultValues("x")); + /** + * @type {ArrayBuffer} + * @desc values + */ + + this.y = (0, _pvutils.getParametersValue)(parameters, "y", ECPublicKey.defaultValues("y")); + /** + * @type {string} + * @desc namedCurve + */ + + this.namedCurve = (0, _pvutils.getParametersValue)(parameters, "namedCurve", ECPublicKey.defaultValues("namedCurve")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + //region If input argument array contains "json" for this object + + if ("json" in parameters) this.fromJSON(parameters.json); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "x": + case "y": + return new ArrayBuffer(0); + + case "namedCurve": + return ""; + + default: + throw new Error(`Invalid member name for ECCPublicKey class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "x": + case "y": + return (0, _pvutils.isEqualBuffer)(memberValue, ECPublicKey.defaultValues(memberName)); + + case "namedCurve": + return memberValue === ""; + + default: + throw new Error(`Invalid member name for ECCPublicKey class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + return new asn1js.RawData(); + } //********************************************************************************** + + /** + * Convert ArrayBuffer into current class + * @param {!ArrayBuffer} schema Special case: schema is an ArrayBuffer + */ + + + fromSchema(schema) { + //region Check the schema is valid + if (schema instanceof ArrayBuffer === false) throw new Error("Object's schema was not verified against input data for ECPublicKey"); + const view = new Uint8Array(schema); + if (view[0] !== 0x04) throw new Error("Object's schema was not verified against input data for ECPublicKey"); //endregion + //region Get internal properties from parsed schema + + let coordinateLength; + + switch (this.namedCurve) { + case "1.2.840.10045.3.1.7": + // P-256 + coordinateLength = 32; + break; + + case "1.3.132.0.34": + // P-384 + coordinateLength = 48; + break; + + case "1.3.132.0.35": + // P-521 + coordinateLength = 66; + break; + + default: + throw new Error(`Incorrect curve OID: ${this.namedCurve}`); + } + + if (schema.byteLength !== coordinateLength * 2 + 1) throw new Error("Object's schema was not verified against input data for ECPublicKey"); + this.x = schema.slice(1, coordinateLength + 1); + this.y = schema.slice(1 + coordinateLength, coordinateLength * 2 + 1); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + return new asn1js.RawData({ + data: (0, _pvutils.utilConcatBuf)(new Uint8Array([0x04]).buffer, this.x, this.y) + }); + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + let crvName = ""; + + switch (this.namedCurve) { + case "1.2.840.10045.3.1.7": + // P-256 + crvName = "P-256"; + break; + + case "1.3.132.0.34": + // P-384 + crvName = "P-384"; + break; + + case "1.3.132.0.35": + // P-521 + crvName = "P-521"; + break; + + default: + } + + return { + crv: crvName, + x: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.x), true, true, false), + y: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.y), true, true, false) + }; + } //********************************************************************************** + + /** + * Convert JSON value into current object + * @param {Object} json + */ + + + fromJSON(json) { + let coodinateLength = 0; + + if ("crv" in json) { + switch (json.crv.toUpperCase()) { + case "P-256": + this.namedCurve = "1.2.840.10045.3.1.7"; + coodinateLength = 32; + break; + + case "P-384": + this.namedCurve = "1.3.132.0.34"; + coodinateLength = 48; + break; + + case "P-521": + this.namedCurve = "1.3.132.0.35"; + coodinateLength = 66; + break; + + default: + } + } else throw new Error("Absent mandatory parameter \"crv\""); + + if ("x" in json) { + const convertBuffer = (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.x, true)); + + if (convertBuffer.byteLength < coodinateLength) { + this.x = new ArrayBuffer(coodinateLength); + const view = new Uint8Array(this.x); + const convertBufferView = new Uint8Array(convertBuffer); + view.set(convertBufferView, 1); + } else this.x = convertBuffer.slice(0, coodinateLength); + } else throw new Error("Absent mandatory parameter \"x\""); + + if ("y" in json) { + const convertBuffer = (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.y, true)); + + if (convertBuffer.byteLength < coodinateLength) { + this.y = new ArrayBuffer(coodinateLength); + const view = new Uint8Array(this.y); + const convertBufferView = new Uint8Array(convertBuffer); + view.set(convertBufferView, 1); + } else this.y = convertBuffer.slice(0, coodinateLength); + } else throw new Error("Absent mandatory parameter \"y\""); + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = ECPublicKey; + +},{"asn1js":112,"pvutils":113}],33:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class EncapsulatedContentInfo { + //********************************************************************************** + + /** + * Constructor for EncapsulatedContentInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc eContentType + */ + this.eContentType = (0, _pvutils.getParametersValue)(parameters, "eContentType", EncapsulatedContentInfo.defaultValues("eContentType")); + + if ("eContent" in parameters) { + /** + * @type {OctetString} + * @desc eContent + */ + this.eContent = (0, _pvutils.getParametersValue)(parameters, "eContent", EncapsulatedContentInfo.defaultValues("eContent")); + + if (this.eContent.idBlock.tagClass === 1 && this.eContent.idBlock.tagNumber === 4) { + //region Divide OCTETSTRING value down to small pieces + if (this.eContent.idBlock.isConstructed === false) { + const constrString = new asn1js.OctetString({ + idBlock: { + isConstructed: true + }, + isConstructed: true + }); + let offset = 0; + let length = this.eContent.valueBlock.valueHex.byteLength; + + while (length > 0) { + const pieceView = new Uint8Array(this.eContent.valueBlock.valueHex, offset, offset + 65536 > this.eContent.valueBlock.valueHex.byteLength ? this.eContent.valueBlock.valueHex.byteLength - offset : 65536); + + const _array = new ArrayBuffer(pieceView.length); + + const _view = new Uint8Array(_array); + + for (let i = 0; i < _view.length; i++) _view[i] = pieceView[i]; + + constrString.valueBlock.value.push(new asn1js.OctetString({ + valueHex: _array + })); + length -= pieceView.length; + offset += pieceView.length; + } + + this.eContent = constrString; + } //endregion + + } + } //endregion + //region If input argument array contains "schema" for this object + + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "eContentType": + return ""; + + case "eContent": + return new asn1js.OctetString(); + + default: + throw new Error(`Invalid member name for EncapsulatedContentInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "eContentType": + return memberValue === ""; + + case "eContent": + { + if (memberValue.idBlock.tagClass === 1 && memberValue.idBlock.tagNumber === 4) return memberValue.isEqual(EncapsulatedContentInfo.defaultValues("eContent")); + return false; + } + + default: + throw new Error(`Invalid member name for EncapsulatedContentInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * EncapsulatedContentInfo ::= SEQUENCE { + * eContentType ContentType, + * eContent [0] EXPLICIT OCTET STRING OPTIONAL } * Changed it to ANY, as in PKCS#7 + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [type] + * @property {string} [setName] + * @property {string} [values] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.eContentType || "" + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Any({ + name: names.eContent || "" + }) // In order to aling this with PKCS#7 and CMS as well + ] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["eContentType", "eContent"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, EncapsulatedContentInfo.schema({ + names: { + eContentType: "eContentType", + eContent: "eContent" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for EncapsulatedContentInfo"); //endregion + //region Get internal properties from parsed schema + + this.eContentType = asn1.result.eContentType.valueBlock.toString(); + if ("eContent" in asn1.result) this.eContent = asn1.result.eContent; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(new asn1js.ObjectIdentifier({ + value: this.eContentType + })); + + if ("eContent" in this) { + if (EncapsulatedContentInfo.compareWithDefault("eContent", this.eContent) === false) { + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [this.eContent] + })); + } + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + eContentType: this.eContentType + }; + + if ("eContent" in this) { + if (EncapsulatedContentInfo.compareWithDefault("eContent", this.eContent) === false) _object.eContent = this.eContent.toJSON(); + } + + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = EncapsulatedContentInfo; + +},{"asn1js":112,"pvutils":113}],34:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class EncryptedContentInfo { + //********************************************************************************** + + /** + * Constructor for EncryptedContentInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc contentType + */ + this.contentType = (0, _pvutils.getParametersValue)(parameters, "contentType", EncryptedContentInfo.defaultValues("contentType")); + /** + * @type {AlgorithmIdentifier} + * @desc contentEncryptionAlgorithm + */ + + this.contentEncryptionAlgorithm = (0, _pvutils.getParametersValue)(parameters, "contentEncryptionAlgorithm", EncryptedContentInfo.defaultValues("contentEncryptionAlgorithm")); + + if ("encryptedContent" in parameters) { + /** + * @type {OctetString} + * @desc encryptedContent (!!!) could be contructive or primitive value (!!!) + */ + this.encryptedContent = parameters.encryptedContent; + + if (this.encryptedContent.idBlock.tagClass === 1 && this.encryptedContent.idBlock.tagNumber === 4) { + //region Divide OCTETSTRING value down to small pieces + if (this.encryptedContent.idBlock.isConstructed === false) { + const constrString = new asn1js.OctetString({ + idBlock: { + isConstructed: true + }, + isConstructed: true + }); + let offset = 0; + let length = this.encryptedContent.valueBlock.valueHex.byteLength; + + while (length > 0) { + const pieceView = new Uint8Array(this.encryptedContent.valueBlock.valueHex, offset, offset + 1024 > this.encryptedContent.valueBlock.valueHex.byteLength ? this.encryptedContent.valueBlock.valueHex.byteLength - offset : 1024); + + const _array = new ArrayBuffer(pieceView.length); + + const _view = new Uint8Array(_array); + + for (let i = 0; i < _view.length; i++) _view[i] = pieceView[i]; + + constrString.valueBlock.value.push(new asn1js.OctetString({ + valueHex: _array + })); + length -= pieceView.length; + offset += pieceView.length; + } + + this.encryptedContent = constrString; + } //endregion + + } + } //endregion + //region If input argument array contains "schema" for this object + + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "contentType": + return ""; + + case "contentEncryptionAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "encryptedContent": + return new asn1js.OctetString(); + + default: + throw new Error(`Invalid member name for EncryptedContentInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "contentType": + return memberValue === ""; + + case "contentEncryptionAlgorithm": + return memberValue.algorithmId === "" && "algorithmParams" in memberValue === false; + + case "encryptedContent": + return memberValue.isEqual(EncryptedContentInfo.defaultValues(memberName)); + + default: + throw new Error(`Invalid member name for EncryptedContentInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * EncryptedContentInfo ::= SEQUENCE { + * contentType ContentType, + * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, + * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL } + * + * Comment: Strange, but modern crypto engines create "encryptedContent" as "[0] EXPLICIT EncryptedContent" + * + * EncryptedContent ::= OCTET STRING + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [contentType] + * @property {string} [contentEncryptionAlgorithm] + * @property {string} [encryptedContent] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.contentType || "" + }), _AlgorithmIdentifier.default.schema(names.contentEncryptionAlgorithm || {}), // The CHOICE we need because "EncryptedContent" could have either "constructive" + // or "primitive" form of encoding and we need to handle both variants + new asn1js.Choice({ + value: [new asn1js.Constructed({ + name: names.encryptedContent || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Repeated({ + value: new asn1js.OctetString() + })] + }), new asn1js.Primitive({ + name: names.encryptedContent || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + } + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["contentType", "contentEncryptionAlgorithm", "encryptedContent"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, EncryptedContentInfo.schema({ + names: { + contentType: "contentType", + contentEncryptionAlgorithm: { + names: { + blockName: "contentEncryptionAlgorithm" + } + }, + encryptedContent: "encryptedContent" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for EncryptedContentInfo"); //endregion + //region Get internal properties from parsed schema + + this.contentType = asn1.result.contentType.valueBlock.toString(); + this.contentEncryptionAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.contentEncryptionAlgorithm + }); + + if ("encryptedContent" in asn1.result) { + this.encryptedContent = asn1.result.encryptedContent; + this.encryptedContent.idBlock.tagClass = 1; // UNIVERSAL + + this.encryptedContent.idBlock.tagNumber = 4; // OCTETSTRING (!!!) The value still has instance of "in_window.org.pkijs.asn1.ASN1_CONSTRUCTED / ASN1_PRIMITIVE" + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const sequenceLengthBlock = { + isIndefiniteForm: false + }; + const outputArray = []; + outputArray.push(new asn1js.ObjectIdentifier({ + value: this.contentType + })); + outputArray.push(this.contentEncryptionAlgorithm.toSchema()); + + if ("encryptedContent" in this) { + sequenceLengthBlock.isIndefiniteForm = this.encryptedContent.idBlock.isConstructed; + const encryptedValue = this.encryptedContent; + encryptedValue.idBlock.tagClass = 3; // CONTEXT-SPECIFIC + + encryptedValue.idBlock.tagNumber = 0; // [0] + + encryptedValue.lenBlock.isIndefiniteForm = this.encryptedContent.idBlock.isConstructed; + outputArray.push(encryptedValue); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + lenBlock: sequenceLengthBlock, + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + contentType: this.contentType, + contentEncryptionAlgorithm: this.contentEncryptionAlgorithm.toJSON() + }; + if ("encryptedContent" in this) _object.encryptedContent = this.encryptedContent.toJSON(); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = EncryptedContentInfo; + +},{"./AlgorithmIdentifier.js":4,"asn1js":112,"pvutils":113}],35:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _common = require("./common.js"); + +var _EncryptedContentInfo = _interopRequireDefault(require("./EncryptedContentInfo.js")); + +var _Attribute = _interopRequireDefault(require("./Attribute.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class EncryptedData { + //********************************************************************************** + + /** + * Constructor for EncryptedData class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", EncryptedData.defaultValues("version")); + /** + * @type {EncryptedContentInfo} + * @desc encryptedContentInfo + */ + + this.encryptedContentInfo = (0, _pvutils.getParametersValue)(parameters, "encryptedContentInfo", EncryptedData.defaultValues("encryptedContentInfo")); + if ("unprotectedAttrs" in parameters) + /** + * @type {Array.} + * @desc unprotectedAttrs + */ + this.unprotectedAttrs = (0, _pvutils.getParametersValue)(parameters, "unprotectedAttrs", EncryptedData.defaultValues("unprotectedAttrs")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 0; + + case "encryptedContentInfo": + return new _EncryptedContentInfo.default(); + + case "unprotectedAttrs": + return []; + + default: + throw new Error(`Invalid member name for EncryptedData class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "version": + return memberValue === 0; + + case "encryptedContentInfo": + return _EncryptedContentInfo.default.compareWithDefault("contentType", memberValue.contentType) && _EncryptedContentInfo.default.compareWithDefault("contentEncryptionAlgorithm", memberValue.contentEncryptionAlgorithm) && _EncryptedContentInfo.default.compareWithDefault("encryptedContent", memberValue.encryptedContent); + + case "unprotectedAttrs": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for EncryptedData class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * EncryptedData ::= SEQUENCE { + * version CMSVersion, + * encryptedContentInfo EncryptedContentInfo, + * unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [version] + * @property {string} [encryptedContentInfo] + * @property {string} [unprotectedAttrs] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.version || "" + }), _EncryptedContentInfo.default.schema(names.encryptedContentInfo || {}), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [new asn1js.Repeated({ + name: names.unprotectedAttrs || "", + value: _Attribute.default.schema() + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["version", "encryptedContentInfo", "unprotectedAttrs"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, EncryptedData.schema({ + names: { + version: "version", + encryptedContentInfo: { + names: { + blockName: "encryptedContentInfo" + } + }, + unprotectedAttrs: "unprotectedAttrs" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for EncryptedData"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result.version.valueBlock.valueDec; + this.encryptedContentInfo = new _EncryptedContentInfo.default({ + schema: asn1.result.encryptedContentInfo + }); + if ("unprotectedAttrs" in asn1.result) this.unprotectedAttrs = Array.from(asn1.result.unprotectedAttrs, element => new _Attribute.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(new asn1js.Integer({ + value: this.version + })); + outputArray.push(this.encryptedContentInfo.toSchema()); + + if ("unprotectedAttrs" in this) { + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: Array.from(this.unprotectedAttrs, element => element.toSchema()) + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + version: this.version, + encryptedContentInfo: this.encryptedContentInfo.toJSON() + }; + if ("unprotectedAttrs" in this) _object.unprotectedAttrs = Array.from(this.unprotectedAttrs, element => element.toJSON()); + return _object; + } //********************************************************************************** + + /** + * Create a new CMS Encrypted Data content + * @param {Object} parameters Parameters neccessary for encryption + * @returns {Promise} + */ + + + encrypt(parameters) { + //region Check for input parameters + if (parameters instanceof Object === false) return Promise.reject("Parameters must have type \"Object\""); //endregion + //region Get cryptographic engine + + const engine = (0, _common.getEngine)(); + if (typeof engine === "undefined") return Promise.reject("Unable to initialize cryptographic engine"); //endregion + //region Set "contentType" parameter + + parameters.contentType = "1.2.840.113549.1.7.1"; // "data" + //endregion + + if ("encryptEncryptedContentInfo" in engine.subtle) { + return engine.subtle.encryptEncryptedContentInfo(parameters).then(result => { + this.encryptedContentInfo = result; + }); + } + + return Promise.reject(`No support for "encryptEncryptedContentInfo" in current crypto engine ${engine.name}`); + } //********************************************************************************** + + /** + * Create a new CMS Encrypted Data content + * @param {Object} parameters Parameters neccessary for encryption + */ + + + decrypt(parameters) { + //region Check for input parameters + if (parameters instanceof Object === false) return Promise.reject("Parameters must have type \"Object\""); //endregion + //region Get cryptographic engine + + const engine = (0, _common.getEngine)(); + if (typeof engine === "undefined") return Promise.reject("Unable to initialize cryptographic engine"); //endregion + //region Set "encryptedContentInfo" value + + parameters.encryptedContentInfo = this.encryptedContentInfo; //endregion + + if ("decryptEncryptedContentInfo" in engine.subtle) return engine.subtle.decryptEncryptedContentInfo(parameters); + return Promise.reject(`No support for "decryptEncryptedContentInfo" in current crypto engine ${engine.name}`); + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = EncryptedData; + +},{"./Attribute.js":6,"./EncryptedContentInfo.js":34,"./common.js":110,"asn1js":112,"pvutils":113}],36:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _common = require("./common.js"); + +var _OriginatorInfo = _interopRequireDefault(require("./OriginatorInfo.js")); + +var _RecipientInfo = _interopRequireDefault(require("./RecipientInfo.js")); + +var _EncryptedContentInfo = _interopRequireDefault(require("./EncryptedContentInfo.js")); + +var _Attribute = _interopRequireDefault(require("./Attribute.js")); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _RSAESOAEPParams = _interopRequireDefault(require("./RSAESOAEPParams.js")); + +var _KeyTransRecipientInfo = _interopRequireDefault(require("./KeyTransRecipientInfo.js")); + +var _IssuerAndSerialNumber = _interopRequireDefault(require("./IssuerAndSerialNumber.js")); + +var _RecipientEncryptedKey = _interopRequireDefault(require("./RecipientEncryptedKey.js")); + +var _KeyAgreeRecipientIdentifier = _interopRequireDefault(require("./KeyAgreeRecipientIdentifier.js")); + +var _KeyAgreeRecipientInfo = _interopRequireDefault(require("./KeyAgreeRecipientInfo.js")); + +var _RecipientEncryptedKeys = _interopRequireDefault(require("./RecipientEncryptedKeys.js")); + +var _KEKRecipientInfo = _interopRequireDefault(require("./KEKRecipientInfo.js")); + +var _KEKIdentifier = _interopRequireDefault(require("./KEKIdentifier.js")); + +var _PBKDF2Params = _interopRequireDefault(require("./PBKDF2Params.js")); + +var _PasswordRecipientinfo = _interopRequireDefault(require("./PasswordRecipientinfo.js")); + +var _ECCCMSSharedInfo = _interopRequireDefault(require("./ECCCMSSharedInfo.js")); + +var _OriginatorIdentifierOrKey = _interopRequireDefault(require("./OriginatorIdentifierOrKey.js")); + +var _OriginatorPublicKey = _interopRequireDefault(require("./OriginatorPublicKey.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class EnvelopedData { + //********************************************************************************** + + /** + * Constructor for EnvelopedData class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", EnvelopedData.defaultValues("version")); + if ("originatorInfo" in parameters) + /** + * @type {OriginatorInfo} + * @desc originatorInfo + */ + this.originatorInfo = (0, _pvutils.getParametersValue)(parameters, "originatorInfo", EnvelopedData.defaultValues("originatorInfo")); + /** + * @type {Array.} + * @desc recipientInfos + */ + + this.recipientInfos = (0, _pvutils.getParametersValue)(parameters, "recipientInfos", EnvelopedData.defaultValues("recipientInfos")); + /** + * @type {EncryptedContentInfo} + * @desc encryptedContentInfo + */ + + this.encryptedContentInfo = (0, _pvutils.getParametersValue)(parameters, "encryptedContentInfo", EnvelopedData.defaultValues("encryptedContentInfo")); + if ("unprotectedAttrs" in parameters) + /** + * @type {Array.} + * @desc unprotectedAttrs + */ + this.unprotectedAttrs = (0, _pvutils.getParametersValue)(parameters, "unprotectedAttrs", EnvelopedData.defaultValues("unprotectedAttrs")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 0; + + case "originatorInfo": + return new _OriginatorInfo.default(); + + case "recipientInfos": + return []; + + case "encryptedContentInfo": + return new _EncryptedContentInfo.default(); + + case "unprotectedAttrs": + return []; + + default: + throw new Error(`Invalid member name for EnvelopedData class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "version": + return memberValue === EnvelopedData.defaultValues(memberName); + + case "originatorInfo": + return memberValue.certs.certificates.length === 0 && memberValue.crls.crls.length === 0; + + case "recipientInfos": + case "unprotectedAttrs": + return memberValue.length === 0; + + case "encryptedContentInfo": + return _EncryptedContentInfo.default.compareWithDefault("contentType", memberValue.contentType) && _EncryptedContentInfo.default.compareWithDefault("contentEncryptionAlgorithm", memberValue.contentEncryptionAlgorithm) && _EncryptedContentInfo.default.compareWithDefault("encryptedContent", memberValue.encryptedContent); + + default: + throw new Error(`Invalid member name for EnvelopedData class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * EnvelopedData ::= SEQUENCE { + * version CMSVersion, + * originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL, + * recipientInfos RecipientInfos, + * encryptedContentInfo EncryptedContentInfo, + * unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [version] + * @property {string} [originatorInfo] + * @property {string} [recipientInfos] + * @property {string} [encryptedContentInfo] + * @property {string} [unprotectedAttrs] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.version || "" + }), new asn1js.Constructed({ + name: names.originatorInfo || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: _OriginatorInfo.default.schema().valueBlock.value + }), new asn1js.Set({ + value: [new asn1js.Repeated({ + name: names.recipientInfos || "", + value: _RecipientInfo.default.schema() + })] + }), _EncryptedContentInfo.default.schema(names.encryptedContentInfo || {}), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [new asn1js.Repeated({ + name: names.unprotectedAttrs || "", + value: _Attribute.default.schema() + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["version", "originatorInfo", "recipientInfos", "encryptedContentInfo", "unprotectedAttrs"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, EnvelopedData.schema({ + names: { + version: "version", + originatorInfo: "originatorInfo", + recipientInfos: "recipientInfos", + encryptedContentInfo: { + names: { + blockName: "encryptedContentInfo" + } + }, + unprotectedAttrs: "unprotectedAttrs" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for EnvelopedData"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result.version.valueBlock.valueDec; + + if ("originatorInfo" in asn1.result) { + this.originatorInfo = new _OriginatorInfo.default({ + schema: new asn1js.Sequence({ + value: asn1.result.originatorInfo.valueBlock.value + }) + }); + } + + this.recipientInfos = Array.from(asn1.result.recipientInfos, element => new _RecipientInfo.default({ + schema: element + })); + this.encryptedContentInfo = new _EncryptedContentInfo.default({ + schema: asn1.result.encryptedContentInfo + }); + if ("unprotectedAttrs" in asn1.result) this.unprotectedAttrs = Array.from(asn1.result.unprotectedAttrs, element => new _Attribute.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(new asn1js.Integer({ + value: this.version + })); + + if ("originatorInfo" in this) { + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: this.originatorInfo.toSchema().valueBlock.value + })); + } + + outputArray.push(new asn1js.Set({ + value: Array.from(this.recipientInfos, element => element.toSchema()) + })); + outputArray.push(this.encryptedContentInfo.toSchema()); + + if ("unprotectedAttrs" in this) { + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: Array.from(this.unprotectedAttrs, element => element.toSchema()) + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + version: this.version + }; + if ("originatorInfo" in this) _object.originatorInfo = this.originatorInfo.toJSON(); + _object.recipientInfos = Array.from(this.recipientInfos, element => element.toJSON()); + _object.encryptedContentInfo = this.encryptedContentInfo.toJSON(); + if ("unprotectedAttrs" in this) _object.unprotectedAttrs = Array.from(this.unprotectedAttrs, element => element.toJSON()); + return _object; + } //********************************************************************************** + + /** + * Helpers function for filling "RecipientInfo" based on recipient's certificate. + * Problem with WebCrypto is that for RSA certificates we have only one option - "key transport" and + * for ECC certificates we also have one option - "key agreement". As soon as Google will implement + * DH algorithm it would be possible to use "key agreement" also for RSA certificates. + * @param {Certificate} [certificate] Recipient's certificate + * @param {Object} [parameters] Additional parameters neccessary for "fine tunning" of encryption process + * @param {number} [variant] Variant = 1 is for "key transport", variant = 2 is for "key agreement". In fact the "variant" is unneccessary now because Google has no DH algorithm implementation. Thus key encryption scheme would be choosen by certificate type only: "key transport" for RSA and "key agreement" for ECC certificates. + */ + + + addRecipientByCertificate(certificate, parameters, variant) { + //region Initial variables + const encryptionParameters = parameters || {}; //endregion + //region Check type of certificate + + if (certificate.subjectPublicKeyInfo.algorithm.algorithmId.indexOf("1.2.840.113549") !== -1) variant = 1; // For the moment it is the only variant for RSA-based certificates + else { + if (certificate.subjectPublicKeyInfo.algorithm.algorithmId.indexOf("1.2.840.10045") !== -1) variant = 2; // For the moment it is the only variant for ECC-based certificates + else throw new Error(`Unknown type of certificate's public key: ${certificate.subjectPublicKeyInfo.algorithm.algorithmId}`); + } //endregion + //region Initialize encryption parameters + + if ("oaepHashAlgorithm" in encryptionParameters === false) encryptionParameters.oaepHashAlgorithm = "SHA-512"; + if ("kdfAlgorithm" in encryptionParameters === false) encryptionParameters.kdfAlgorithm = "SHA-512"; + if ("kekEncryptionLength" in encryptionParameters === false) encryptionParameters.kekEncryptionLength = 256; //endregion + //region Add new "recipient" depends on "variant" and certificate type + + switch (variant) { + case 1: + // Key transport scheme + { + //region keyEncryptionAlgorithm + const oaepOID = (0, _common.getOIDByAlgorithm)({ + name: "RSA-OAEP" + }); + if (oaepOID === "") throw new Error("Can not find OID for OAEP"); //endregion + //region RSAES-OAEP-params + + const hashOID = (0, _common.getOIDByAlgorithm)({ + name: encryptionParameters.oaepHashAlgorithm + }); + if (hashOID === "") throw new Error(`Unknown OAEP hash algorithm: ${encryptionParameters.oaepHashAlgorithm}`); + const hashAlgorithm = new _AlgorithmIdentifier.default({ + algorithmId: hashOID, + algorithmParams: new asn1js.Null() + }); + const rsaOAEPParams = new _RSAESOAEPParams.default({ + hashAlgorithm, + maskGenAlgorithm: new _AlgorithmIdentifier.default({ + algorithmId: "1.2.840.113549.1.1.8", + // id-mgf1 + algorithmParams: hashAlgorithm.toSchema() + }) + }); //endregion + //region KeyTransRecipientInfo + + const keyInfo = new _KeyTransRecipientInfo.default({ + version: 0, + rid: new _IssuerAndSerialNumber.default({ + issuer: certificate.issuer, + serialNumber: certificate.serialNumber + }), + keyEncryptionAlgorithm: new _AlgorithmIdentifier.default({ + algorithmId: oaepOID, + algorithmParams: rsaOAEPParams.toSchema() + }), + recipientCertificate: certificate // "encryptedKey" will be calculated in "encrypt" function + + }); //endregion + //region Final values for "CMS_ENVELOPED_DATA" + + this.recipientInfos.push(new _RecipientInfo.default({ + variant: 1, + value: keyInfo + })); //endregion + } + break; + + case 2: + // Key agreement scheme + { + //region RecipientEncryptedKey + const encryptedKey = new _RecipientEncryptedKey.default({ + rid: new _KeyAgreeRecipientIdentifier.default({ + variant: 1, + value: new _IssuerAndSerialNumber.default({ + issuer: certificate.issuer, + serialNumber: certificate.serialNumber + }) + }) // "encryptedKey" will be calculated in "encrypt" function + + }); //endregion + //region keyEncryptionAlgorithm + + const aesKWoid = (0, _common.getOIDByAlgorithm)({ + name: "AES-KW", + length: encryptionParameters.kekEncryptionLength + }); + if (aesKWoid === "") throw new Error(`Unknown length for key encryption algorithm: ${encryptionParameters.kekEncryptionLength}`); + const aesKW = new _AlgorithmIdentifier.default({ + algorithmId: aesKWoid, + algorithmParams: new asn1js.Null() + }); //endregion + //region KeyAgreeRecipientInfo + + const ecdhOID = (0, _common.getOIDByAlgorithm)({ + name: "ECDH", + kdf: encryptionParameters.kdfAlgorithm + }); + if (ecdhOID === "") throw new Error(`Unknown KDF algorithm: ${encryptionParameters.kdfAlgorithm}`); // In fact there is no need in so long UKM, but RFC2631 + // has requirement that "UserKeyMaterial" must be 512 bits long + + const ukmBuffer = new ArrayBuffer(64); + const ukmView = new Uint8Array(ukmBuffer); + (0, _common.getRandomValues)(ukmView); // Generate random values in 64 bytes long buffer + + const keyInfo = new _KeyAgreeRecipientInfo.default({ + version: 3, + // "originator" will be calculated in "encrypt" function because ephemeral key would be generated there + ukm: new asn1js.OctetString({ + valueHex: ukmBuffer + }), + keyEncryptionAlgorithm: new _AlgorithmIdentifier.default({ + algorithmId: ecdhOID, + algorithmParams: aesKW.toSchema() + }), + recipientEncryptedKeys: new _RecipientEncryptedKeys.default({ + encryptedKeys: [encryptedKey] + }), + recipientCertificate: certificate + }); //endregion + //region Final values for "CMS_ENVELOPED_DATA" + + this.recipientInfos.push(new _RecipientInfo.default({ + variant: 2, + value: keyInfo + })); //endregion + } + break; + + default: + throw new Error(`Unknown "variant" value: ${variant}`); + } //endregion + + + return true; + } //********************************************************************************** + + /** + * Add recipient based on pre-defined data like password or KEK + * @param {ArrayBuffer} preDefinedData ArrayBuffer with pre-defined data + * @param {Object} parameters Additional parameters neccessary for "fine tunning" of encryption process + * @param {number} variant Variant = 1 for pre-defined "key encryption key" (KEK). Variant = 2 for password-based encryption. + */ + + + addRecipientByPreDefinedData(preDefinedData, parameters, variant) { + //region Initial variables + const encryptionParameters = parameters || {}; //endregion + //region Check initial parameters + + if (preDefinedData instanceof ArrayBuffer === false) throw new Error("Please pass \"preDefinedData\" in ArrayBuffer type"); + if (preDefinedData.byteLength === 0) throw new Error("Pre-defined data could have zero length"); //endregion + //region Initialize encryption parameters + + if ("keyIdentifier" in encryptionParameters === false) { + const keyIdentifierBuffer = new ArrayBuffer(16); + const keyIdentifierView = new Uint8Array(keyIdentifierBuffer); + (0, _common.getRandomValues)(keyIdentifierView); + encryptionParameters.keyIdentifier = keyIdentifierBuffer; + } + + if ("hmacHashAlgorithm" in encryptionParameters === false) encryptionParameters.hmacHashAlgorithm = "SHA-512"; + if ("iterationCount" in encryptionParameters === false) encryptionParameters.iterationCount = 2048; + + if ("keyEncryptionAlgorithm" in encryptionParameters === false) { + encryptionParameters.keyEncryptionAlgorithm = { + name: "AES-KW", + length: 256 + }; + } + + if ("keyEncryptionAlgorithmParams" in encryptionParameters === false) encryptionParameters.keyEncryptionAlgorithmParams = new asn1js.Null(); //endregion + //region Add new recipient based on passed variant + + switch (variant) { + case 1: + // KEKRecipientInfo + { + //region keyEncryptionAlgorithm + const kekOID = (0, _common.getOIDByAlgorithm)(encryptionParameters.keyEncryptionAlgorithm); + if (kekOID === "") throw new Error("Incorrect value for \"keyEncryptionAlgorithm\""); //endregion + //region KEKRecipientInfo + + const keyInfo = new _KEKRecipientInfo.default({ + version: 4, + kekid: new _KEKIdentifier.default({ + keyIdentifier: new asn1js.OctetString({ + valueHex: encryptionParameters.keyIdentifier + }) + }), + keyEncryptionAlgorithm: new _AlgorithmIdentifier.default({ + algorithmId: kekOID, + + /* + For AES-KW params are NULL, but for other algorithm could another situation. + */ + algorithmParams: encryptionParameters.keyEncryptionAlgorithmParams + }), + preDefinedKEK: preDefinedData // "encryptedKey" would be set in "ecrypt" function + + }); //endregion + //region Final values for "CMS_ENVELOPED_DATA" + + this.recipientInfos.push(new _RecipientInfo.default({ + variant: 3, + value: keyInfo + })); //endregion + } + break; + + case 2: + // PasswordRecipientinfo + { + //region keyDerivationAlgorithm + const pbkdf2OID = (0, _common.getOIDByAlgorithm)({ + name: "PBKDF2" + }); + if (pbkdf2OID === "") throw new Error("Can not find OID for PBKDF2"); //endregion + //region Salt + + const saltBuffer = new ArrayBuffer(64); + const saltView = new Uint8Array(saltBuffer); + (0, _common.getRandomValues)(saltView); //endregion + //region HMAC-based algorithm + + const hmacOID = (0, _common.getOIDByAlgorithm)({ + name: "HMAC", + hash: { + name: encryptionParameters.hmacHashAlgorithm + } + }); + if (hmacOID === "") throw new Error(`Incorrect value for "hmacHashAlgorithm": ${encryptionParameters.hmacHashAlgorithm}`); //endregion + //region PBKDF2-params + + const pbkdf2Params = new _PBKDF2Params.default({ + salt: new asn1js.OctetString({ + valueHex: saltBuffer + }), + iterationCount: encryptionParameters.iterationCount, + prf: new _AlgorithmIdentifier.default({ + algorithmId: hmacOID, + algorithmParams: new asn1js.Null() + }) + }); //endregion + //region keyEncryptionAlgorithm + + const kekOID = (0, _common.getOIDByAlgorithm)(encryptionParameters.keyEncryptionAlgorithm); + if (kekOID === "") throw new Error("Incorrect value for \"keyEncryptionAlgorithm\""); //endregion + //region PasswordRecipientinfo + + const keyInfo = new _PasswordRecipientinfo.default({ + version: 0, + keyDerivationAlgorithm: new _AlgorithmIdentifier.default({ + algorithmId: pbkdf2OID, + algorithmParams: pbkdf2Params.toSchema() + }), + keyEncryptionAlgorithm: new _AlgorithmIdentifier.default({ + algorithmId: kekOID, + + /* + For AES-KW params are NULL, but for other algorithm could be another situation. + */ + algorithmParams: encryptionParameters.keyEncryptionAlgorithmParams + }), + password: preDefinedData // "encryptedKey" would be set in "ecrypt" function + + }); //endregion + //region Final values for "CMS_ENVELOPED_DATA" + + this.recipientInfos.push(new _RecipientInfo.default({ + variant: 4, + value: keyInfo + })); //endregion + } + break; + + default: + throw new Error(`Unknown value for "variant": ${variant}`); + } //endregion + + } //********************************************************************************** + + /** + * Create a new CMS Enveloped Data content with encrypted data + * @param {Object} contentEncryptionAlgorithm WebCrypto algorithm. For the moment here could be only "AES-CBC" or "AES-GCM" algorithms. + * @param {ArrayBuffer} contentToEncrypt Content to encrypt + * @returns {Promise} + */ + + + encrypt(contentEncryptionAlgorithm, contentToEncrypt) { + //region Initial variables + let sequence = Promise.resolve(); + const ivBuffer = new ArrayBuffer(16); // For AES we need IV 16 bytes long + + const ivView = new Uint8Array(ivBuffer); + (0, _common.getRandomValues)(ivView); + const contentView = new Uint8Array(contentToEncrypt); + let sessionKey; + let encryptedContent; + let exportedSessionKey; + const recipientsPromises = []; + + const _this = this; //endregion + //region Check for input parameters + + + const contentEncryptionOID = (0, _common.getOIDByAlgorithm)(contentEncryptionAlgorithm); + if (contentEncryptionOID === "") return Promise.reject("Wrong \"contentEncryptionAlgorithm\" value"); //endregion + //region Get a "crypto" extension + + const crypto = (0, _common.getCrypto)(); + if (typeof crypto === "undefined") return Promise.reject("Unable to create WebCrypto object"); //endregion + //region Generate new content encryption key + + sequence = sequence.then(() => crypto.generateKey(contentEncryptionAlgorithm, true, ["encrypt"])); //endregion + //region Encrypt content + + sequence = sequence.then(result => { + sessionKey = result; + return crypto.encrypt({ + name: contentEncryptionAlgorithm.name, + iv: ivView + }, sessionKey, contentView); + }, error => Promise.reject(error)); //endregion + //region Export raw content of content encryption key + + sequence = sequence.then(result => { + //region Create output OCTETSTRING with encrypted content + encryptedContent = result; //endregion + + return crypto.exportKey("raw", sessionKey); + }, error => Promise.reject(error)).then(result => { + exportedSessionKey = result; + return true; + }, error => Promise.reject(error)); //endregion + //region Append common information to CMS_ENVELOPED_DATA + + sequence = sequence.then(() => { + this.version = 2; + this.encryptedContentInfo = new _EncryptedContentInfo.default({ + contentType: "1.2.840.113549.1.7.1", + // "data" + contentEncryptionAlgorithm: new _AlgorithmIdentifier.default({ + algorithmId: contentEncryptionOID, + algorithmParams: new asn1js.OctetString({ + valueHex: ivBuffer + }) + }), + encryptedContent: new asn1js.OctetString({ + valueHex: encryptedContent + }) + }); + }, error => Promise.reject(error)); //endregion + //region Special sub-functions to work with each recipient's type + + function SubKeyAgreeRecipientInfo(index) { + //region Initial variables + let currentSequence = Promise.resolve(); + let ecdhPublicKey; + let ecdhPrivateKey; + let recipientCurve; + let recipientCurveLength; + let exportedECDHPublicKey; //endregion + //region Get "namedCurve" parameter from recipient's certificate + + currentSequence = currentSequence.then(() => { + const curveObject = _this.recipientInfos[index].value.recipientCertificate.subjectPublicKeyInfo.algorithm.algorithmParams; + if (curveObject instanceof asn1js.ObjectIdentifier === false) return Promise.reject(`Incorrect "recipientCertificate" for index ${index}`); + const curveOID = curveObject.valueBlock.toString(); + + switch (curveOID) { + case "1.2.840.10045.3.1.7": + recipientCurve = "P-256"; + recipientCurveLength = 256; + break; + + case "1.3.132.0.34": + recipientCurve = "P-384"; + recipientCurveLength = 384; + break; + + case "1.3.132.0.35": + recipientCurve = "P-521"; + recipientCurveLength = 528; + break; + + default: + return Promise.reject(`Incorrect curve OID for index ${index}`); + } + + return recipientCurve; + }, error => Promise.reject(error)); //endregion + //region Generate ephemeral ECDH key + + currentSequence = currentSequence.then(result => crypto.generateKey({ + name: "ECDH", + namedCurve: result + }, true, ["deriveBits"]), error => Promise.reject(error)); //endregion + //region Export public key of ephemeral ECDH key pair + + currentSequence = currentSequence.then(result => { + ecdhPublicKey = result.publicKey; + ecdhPrivateKey = result.privateKey; + return crypto.exportKey("spki", ecdhPublicKey); + }, error => Promise.reject(error)); //endregion + //region Import recipient's public key + + currentSequence = currentSequence.then(result => { + exportedECDHPublicKey = result; + return _this.recipientInfos[index].value.recipientCertificate.getPublicKey({ + algorithm: { + algorithm: { + name: "ECDH", + namedCurve: recipientCurve + }, + usages: [] + } + }); + }, error => Promise.reject(error)); //endregion + //region Create shared secret + + currentSequence = currentSequence.then(result => crypto.deriveBits({ + name: "ECDH", + public: result + }, ecdhPrivateKey, recipientCurveLength), error => Promise.reject(error)); //endregion + //region Apply KDF function to shared secret + + currentSequence = currentSequence.then( + /** + * @param {ArrayBuffer} result + */ + result => { + //region Get length of used AES-KW algorithm + const aesKWAlgorithm = new _AlgorithmIdentifier.default({ + schema: _this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmParams + }); + const KWalgorithm = (0, _common.getAlgorithmByOID)(aesKWAlgorithm.algorithmId); + if ("name" in KWalgorithm === false) return Promise.reject(`Incorrect OID for key encryption algorithm: ${aesKWAlgorithm.algorithmId}`); //endregion + //region Translate AES-KW length to ArrayBuffer + + let kwLength = KWalgorithm.length; + const kwLengthBuffer = new ArrayBuffer(4); + const kwLengthView = new Uint8Array(kwLengthBuffer); + + for (let j = 3; j >= 0; j--) { + kwLengthView[j] = kwLength; + kwLength >>= 8; + } //endregion + //region Create and encode "ECC-CMS-SharedInfo" structure + + + const eccInfo = new _ECCCMSSharedInfo.default({ + keyInfo: new _AlgorithmIdentifier.default({ + algorithmId: aesKWAlgorithm.algorithmId, + + /* + Initially RFC5753 says that AES algorithms have absent parameters. + But since early implementations all put NULL here. Thus, in order to be + "backward compatible", index also put NULL here. + */ + algorithmParams: new asn1js.Null() + }), + entityUInfo: _this.recipientInfos[index].value.ukm, + suppPubInfo: new asn1js.OctetString({ + valueHex: kwLengthBuffer + }) + }); + const encodedInfo = eccInfo.toSchema().toBER(false); //endregion + //region Get SHA algorithm used together with ECDH + + const ecdhAlgorithm = (0, _common.getAlgorithmByOID)(_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmId); + if ("name" in ecdhAlgorithm === false) return Promise.reject(`Incorrect OID for key encryption algorithm: ${_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmId}`); //endregion + + return (0, _common.kdf)(ecdhAlgorithm.kdf, result, KWalgorithm.length, encodedInfo); + }, error => Promise.reject(error)); //endregion + //region Import AES-KW key from result of KDF function + + currentSequence = currentSequence.then(result => crypto.importKey("raw", result, { + name: "AES-KW" + }, true, ["wrapKey"]), error => Promise.reject(error)); //endregion + //region Finally wrap session key by using AES-KW algorithm + + currentSequence = currentSequence.then(result => crypto.wrapKey("raw", sessionKey, result, { + name: "AES-KW" + }), error => Promise.reject(error)); //endregion + //region Append all neccessary data to current CMS_RECIPIENT_INFO object + + currentSequence = currentSequence.then(result => { + //region OriginatorIdentifierOrKey + const asn1 = asn1js.fromBER(exportedECDHPublicKey); + const originator = new _OriginatorIdentifierOrKey.default(); + originator.variant = 3; + originator.value = new _OriginatorPublicKey.default({ + schema: asn1.result + }); // There is option when we can stay with ECParameters, but here index prefer to avoid the params + + if ("algorithmParams" in originator.value.algorithm) delete originator.value.algorithm.algorithmParams; + _this.recipientInfos[index].value.originator = originator; //endregion + //region RecipientEncryptedKey + + /* + We will not support using of same ephemeral key for many recipients + */ + + _this.recipientInfos[index].value.recipientEncryptedKeys.encryptedKeys[0].encryptedKey = new asn1js.OctetString({ + valueHex: result + }); //endregion + }, error => Promise.reject(error)); //endregion + + return currentSequence; + } + + function SubKeyTransRecipientInfo(index) { + //region Initial variables + let currentSequence = Promise.resolve(); //endregion + //region Get recipient's public key + + currentSequence = currentSequence.then(() => { + //region Get current used SHA algorithm + const schema = _this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmParams; + const rsaOAEPParams = new _RSAESOAEPParams.default({ + schema + }); + const hashAlgorithm = (0, _common.getAlgorithmByOID)(rsaOAEPParams.hashAlgorithm.algorithmId); + if ("name" in hashAlgorithm === false) return Promise.reject(`Incorrect OID for hash algorithm: ${rsaOAEPParams.hashAlgorithm.algorithmId}`); //endregion + + return _this.recipientInfos[index].value.recipientCertificate.getPublicKey({ + algorithm: { + algorithm: { + name: "RSA-OAEP", + hash: { + name: hashAlgorithm.name + } + }, + usages: ["encrypt", "wrapKey"] + } + }); + }, error => Promise.reject(error)); //endregion + //region Encrypt early exported session key on recipient's public key + + currentSequence = currentSequence.then(result => crypto.encrypt(result.algorithm, result, exportedSessionKey), error => Promise.reject(error)); //endregion + //region Append all neccessary data to current CMS_RECIPIENT_INFO object + + currentSequence = currentSequence.then(result => { + //region RecipientEncryptedKey + _this.recipientInfos[index].value.encryptedKey = new asn1js.OctetString({ + valueHex: result + }); //endregion + }, error => Promise.reject(error)); //endregion + + return currentSequence; + } + + function SubKEKRecipientInfo(index) { + //region Initial variables + let currentSequence = Promise.resolve(); + let kekAlgorithm; //endregion + //region Import KEK from pre-defined data + + currentSequence = currentSequence.then(() => { + //region Get WebCrypto form of "keyEncryptionAlgorithm" + kekAlgorithm = (0, _common.getAlgorithmByOID)(_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmId); + if ("name" in kekAlgorithm === false) return Promise.reject(`Incorrect OID for "keyEncryptionAlgorithm": ${_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmId}`); //endregion + + return crypto.importKey("raw", new Uint8Array(_this.recipientInfos[index].value.preDefinedKEK), kekAlgorithm, true, ["wrapKey"]); // Too specific for AES-KW + }, error => Promise.reject(error)); //endregion + //region Wrap previously exported session key + + currentSequence = currentSequence.then(result => crypto.wrapKey("raw", sessionKey, result, kekAlgorithm), error => Promise.reject(error)); //endregion + //region Append all neccessary data to current CMS_RECIPIENT_INFO object + + currentSequence = currentSequence.then(result => { + //region RecipientEncryptedKey + _this.recipientInfos[index].value.encryptedKey = new asn1js.OctetString({ + valueHex: result + }); //endregion + }, error => Promise.reject(error)); //endregion + + return currentSequence; + } + + function SubPasswordRecipientinfo(index) { + //region Initial variables + let currentSequence = Promise.resolve(); + let pbkdf2Params; + let kekAlgorithm; //endregion + //region Check that we have encoded "keyDerivationAlgorithm" plus "PBKDF2_params" in there + + currentSequence = currentSequence.then(() => { + if ("keyDerivationAlgorithm" in _this.recipientInfos[index].value === false) return Promise.reject("Please append encoded \"keyDerivationAlgorithm\""); + if ("algorithmParams" in _this.recipientInfos[index].value.keyDerivationAlgorithm === false) return Promise.reject("Incorrectly encoded \"keyDerivationAlgorithm\""); + + try { + pbkdf2Params = new _PBKDF2Params.default({ + schema: _this.recipientInfos[index].value.keyDerivationAlgorithm.algorithmParams + }); + } catch (ex) { + return Promise.reject("Incorrectly encoded \"keyDerivationAlgorithm\""); + } + + return Promise.resolve(); + }, error => Promise.reject(error)); //endregion + //region Derive PBKDF2 key from "password" buffer + + currentSequence = currentSequence.then(() => { + const passwordView = new Uint8Array(_this.recipientInfos[index].value.password); + return crypto.importKey("raw", passwordView, "PBKDF2", false, ["deriveKey"]); + }, error => Promise.reject(error)); //endregion + //region Derive key for "keyEncryptionAlgorithm" + + currentSequence = currentSequence.then(result => { + //region Get WebCrypto form of "keyEncryptionAlgorithm" + kekAlgorithm = (0, _common.getAlgorithmByOID)(_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmId); + if ("name" in kekAlgorithm === false) return Promise.reject(`Incorrect OID for "keyEncryptionAlgorithm": ${_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmId}`); //endregion + //region Get HMAC hash algorithm + + let hmacHashAlgorithm = "SHA-1"; + + if ("prf" in pbkdf2Params) { + const algorithm = (0, _common.getAlgorithmByOID)(pbkdf2Params.prf.algorithmId); + if ("name" in algorithm === false) return Promise.reject("Incorrect OID for HMAC hash algorithm"); + hmacHashAlgorithm = algorithm.hash.name; + } //endregion + //region Get PBKDF2 "salt" value + + + const saltView = new Uint8Array(pbkdf2Params.salt.valueBlock.valueHex); //endregion + //region Get PBKDF2 iterations count + + const iterations = pbkdf2Params.iterationCount; //endregion + + return crypto.deriveKey({ + name: "PBKDF2", + hash: { + name: hmacHashAlgorithm + }, + salt: saltView, + iterations + }, result, kekAlgorithm, true, ["wrapKey"]); // Usages are too specific for KEK algorithm + }, error => Promise.reject(error)); //endregion + //region Wrap previously exported session key (Also too specific for KEK algorithm) + + currentSequence = currentSequence.then(result => crypto.wrapKey("raw", sessionKey, result, kekAlgorithm), error => Promise.reject(error)); //endregion + //region Append all neccessary data to current CMS_RECIPIENT_INFO object + + currentSequence = currentSequence.then(result => { + //region RecipientEncryptedKey + _this.recipientInfos[index].value.encryptedKey = new asn1js.OctetString({ + valueHex: result + }); //endregion + }, error => Promise.reject(error)); //endregion + + return currentSequence; + } //endregion + //region Create special routines for each "recipient" + + + sequence = sequence.then(() => { + for (let i = 0; i < this.recipientInfos.length; i++) { + //region Initial variables + let currentSequence = Promise.resolve(); //endregion + + switch (this.recipientInfos[i].variant) { + case 1: + // KeyTransRecipientInfo + currentSequence = SubKeyTransRecipientInfo(i); + break; + + case 2: + // KeyAgreeRecipientInfo + currentSequence = SubKeyAgreeRecipientInfo(i); + break; + + case 3: + // KEKRecipientInfo + currentSequence = SubKEKRecipientInfo(i); + break; + + case 4: + // PasswordRecipientinfo + currentSequence = SubPasswordRecipientinfo(i); + break; + + default: + return Promise.reject(`Uknown recipient type in array with index ${i}`); + } + + recipientsPromises.push(currentSequence); + } + + return Promise.all(recipientsPromises); + }, error => Promise.reject(error)); //endregion + + return sequence; + } //********************************************************************************** + + /** + * Decrypt existing CMS Enveloped Data content + * @param {number} recipientIndex Index of recipient + * @param {Object} parameters Additional parameters + * @returns {Promise} + */ + + + decrypt(recipientIndex, parameters) { + //region Initial variables + let sequence = Promise.resolve(); + const decryptionParameters = parameters || {}; + + const _this = this; //endregion + //region Check for input parameters + + + if (recipientIndex + 1 > this.recipientInfos.length) return Promise.reject(`Maximum value for "index" is: ${this.recipientInfos.length - 1}`); //endregion + //region Get a "crypto" extension + + const crypto = (0, _common.getCrypto)(); + if (typeof crypto === "undefined") return Promise.reject("Unable to create WebCrypto object"); //endregion + //region Special sub-functions to work with each recipient's type + + function SubKeyAgreeRecipientInfo(index) { + //region Initial variables + let currentSequence = Promise.resolve(); + let recipientCurve; + let recipientCurveLength; + let curveOID; + let ecdhPrivateKey; //endregion + //region Get "namedCurve" parameter from recipient's certificate + + currentSequence = currentSequence.then(() => { + if ("recipientCertificate" in decryptionParameters === false) return Promise.reject("Parameter \"recipientCertificate\" is mandatory for \"KeyAgreeRecipientInfo\""); + if ("recipientPrivateKey" in decryptionParameters === false) return Promise.reject("Parameter \"recipientPrivateKey\" is mandatory for \"KeyAgreeRecipientInfo\""); + const curveObject = decryptionParameters.recipientCertificate.subjectPublicKeyInfo.algorithm.algorithmParams; + if (curveObject instanceof asn1js.ObjectIdentifier === false) return Promise.reject(`Incorrect "recipientCertificate" for index ${index}`); + curveOID = curveObject.valueBlock.toString(); + + switch (curveOID) { + case "1.2.840.10045.3.1.7": + recipientCurve = "P-256"; + recipientCurveLength = 256; + break; + + case "1.3.132.0.34": + recipientCurve = "P-384"; + recipientCurveLength = 384; + break; + + case "1.3.132.0.35": + recipientCurve = "P-521"; + recipientCurveLength = 528; + break; + + default: + return Promise.reject(`Incorrect curve OID for index ${index}`); + } + + return crypto.importKey("pkcs8", decryptionParameters.recipientPrivateKey, { + name: "ECDH", + namedCurve: recipientCurve + }, true, ["deriveBits"]); + }, error => Promise.reject(error)); //endregion + //region Import sender's ephemeral public key + + currentSequence = currentSequence.then(result => { + ecdhPrivateKey = result; //region Change "OriginatorPublicKey" if "curve" parameter absent + + if ("algorithmParams" in _this.recipientInfos[index].value.originator.value.algorithm === false) _this.recipientInfos[index].value.originator.value.algorithm.algorithmParams = new asn1js.ObjectIdentifier({ + value: curveOID + }); //endregion + //region Create ArrayBuffer with sender's public key + + const buffer = _this.recipientInfos[index].value.originator.value.toSchema().toBER(false); //endregion + + + return crypto.importKey("spki", buffer, { + name: "ECDH", + namedCurve: recipientCurve + }, true, []); + }, error => Promise.reject(error)); //endregion + //region Create shared secret + + currentSequence = currentSequence.then(result => crypto.deriveBits({ + name: "ECDH", + public: result + }, ecdhPrivateKey, recipientCurveLength), error => Promise.reject(error)); //endregion + //region Apply KDF function to shared secret + + currentSequence = currentSequence.then( + /** + * @param {ArrayBuffer} result + */ + result => { + //region Get length of used AES-KW algorithm + const aesKWAlgorithm = new _AlgorithmIdentifier.default({ + schema: _this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmParams + }); + const KWalgorithm = (0, _common.getAlgorithmByOID)(aesKWAlgorithm.algorithmId); + if ("name" in KWalgorithm === false) return Promise.reject(`Incorrect OID for key encryption algorithm: ${aesKWAlgorithm.algorithmId}`); //endregion + //region Translate AES-KW length to ArrayBuffer + + let kwLength = KWalgorithm.length; + const kwLengthBuffer = new ArrayBuffer(4); + const kwLengthView = new Uint8Array(kwLengthBuffer); + + for (let j = 3; j >= 0; j--) { + kwLengthView[j] = kwLength; + kwLength >>= 8; + } //endregion + //region Create and encode "ECC-CMS-SharedInfo" structure + + + const eccInfo = new _ECCCMSSharedInfo.default({ + keyInfo: new _AlgorithmIdentifier.default({ + algorithmId: aesKWAlgorithm.algorithmId, + + /* + Initially RFC5753 says that AES algorithms have absent parameters. + But since early implementations all put NULL here. Thus, in order to be + "backward compatible", index also put NULL here. + */ + algorithmParams: new asn1js.Null() + }), + entityUInfo: _this.recipientInfos[index].value.ukm, + suppPubInfo: new asn1js.OctetString({ + valueHex: kwLengthBuffer + }) + }); + const encodedInfo = eccInfo.toSchema().toBER(false); //endregion + //region Get SHA algorithm used together with ECDH + + const ecdhAlgorithm = (0, _common.getAlgorithmByOID)(_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmId); + if ("name" in ecdhAlgorithm === false) return Promise.reject(`Incorrect OID for key encryption algorithm: ${_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmId}`); //endregion + + return (0, _common.kdf)(ecdhAlgorithm.kdf, result, KWalgorithm.length, encodedInfo); + }, error => Promise.reject(error)); //endregion + //region Import AES-KW key from result of KDF function + + currentSequence = currentSequence.then(result => crypto.importKey("raw", result, { + name: "AES-KW" + }, true, ["unwrapKey"]), error => Promise.reject(error)); //endregion + //region Finally unwrap session key + + currentSequence = currentSequence.then(result => { + //region Get WebCrypto form of content encryption algorithm + const contentEncryptionAlgorithm = (0, _common.getAlgorithmByOID)(_this.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId); + if ("name" in contentEncryptionAlgorithm === false) return Promise.reject(`Incorrect "contentEncryptionAlgorithm": ${_this.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId}`); //endregion + + return crypto.unwrapKey("raw", _this.recipientInfos[index].value.recipientEncryptedKeys.encryptedKeys[0].encryptedKey.valueBlock.valueHex, result, { + name: "AES-KW" + }, contentEncryptionAlgorithm, true, ["decrypt"]); + }, error => Promise.reject(error)); //endregion + + return currentSequence; + } + + function SubKeyTransRecipientInfo(index) { + //region Initial variables + let currentSequence = Promise.resolve(); //endregion + //region Import recipient's private key + + currentSequence = currentSequence.then(() => { + if ("recipientPrivateKey" in decryptionParameters === false) return Promise.reject("Parameter \"recipientPrivateKey\" is mandatory for \"KeyTransRecipientInfo\""); //region Get current used SHA algorithm + + const schema = _this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmParams; + const rsaOAEPParams = new _RSAESOAEPParams.default({ + schema + }); + const hashAlgorithm = (0, _common.getAlgorithmByOID)(rsaOAEPParams.hashAlgorithm.algorithmId); + if ("name" in hashAlgorithm === false) return Promise.reject(`Incorrect OID for hash algorithm: ${rsaOAEPParams.hashAlgorithm.algorithmId}`); //endregion + + return crypto.importKey("pkcs8", decryptionParameters.recipientPrivateKey, { + name: "RSA-OAEP", + hash: { + name: hashAlgorithm.name + } + }, true, ["decrypt"]); + }, error => Promise.reject(error)); //endregion + //region Decrypt encrypted session key + + currentSequence = currentSequence.then(result => crypto.decrypt(result.algorithm, result, _this.recipientInfos[index].value.encryptedKey.valueBlock.valueHex), error => Promise.reject(error)); //endregion + //region Import decrypted session key + + currentSequence = currentSequence.then(result => { + //region Get WebCrypto form of content encryption algorithm + const contentEncryptionAlgorithm = (0, _common.getAlgorithmByOID)(_this.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId); + if ("name" in contentEncryptionAlgorithm === false) return Promise.reject(`Incorrect "contentEncryptionAlgorithm": ${_this.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId}`); //endregion + + return crypto.importKey("raw", result, contentEncryptionAlgorithm, true, ["decrypt"]); + }, error => Promise.reject(error)); //endregion + + return currentSequence; + } + + function SubKEKRecipientInfo(index) { + //region Initial variables + let currentSequence = Promise.resolve(); + let kekAlgorithm; //endregion + //region Import KEK from pre-defined data + + currentSequence = currentSequence.then(() => { + if ("preDefinedData" in decryptionParameters === false) return Promise.reject("Parameter \"preDefinedData\" is mandatory for \"KEKRecipientInfo\""); //region Get WebCrypto form of "keyEncryptionAlgorithm" + + kekAlgorithm = (0, _common.getAlgorithmByOID)(_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmId); + if ("name" in kekAlgorithm === false) return Promise.reject(`Incorrect OID for "keyEncryptionAlgorithm": ${_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmId}`); //endregion + + return crypto.importKey("raw", decryptionParameters.preDefinedData, kekAlgorithm, true, ["unwrapKey"]); // Too specific for AES-KW + }, error => Promise.reject(error)); //endregion + //region Unwrap previously exported session key + + currentSequence = currentSequence.then(result => { + //region Get WebCrypto form of content encryption algorithm + const contentEncryptionAlgorithm = (0, _common.getAlgorithmByOID)(_this.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId); + if ("name" in contentEncryptionAlgorithm === false) return Promise.reject(`Incorrect "contentEncryptionAlgorithm": ${_this.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId}`); //endregion + + return crypto.unwrapKey("raw", _this.recipientInfos[index].value.encryptedKey.valueBlock.valueHex, result, kekAlgorithm, contentEncryptionAlgorithm, true, ["decrypt"]); + }, error => Promise.reject(error)); //endregion + + return currentSequence; + } + + function SubPasswordRecipientinfo(index) { + //region Initial variables + let currentSequence = Promise.resolve(); + let pbkdf2Params; + let kekAlgorithm; //endregion + //region Derive PBKDF2 key from "password" buffer + + currentSequence = currentSequence.then(() => { + if ("preDefinedData" in decryptionParameters === false) return Promise.reject("Parameter \"preDefinedData\" is mandatory for \"KEKRecipientInfo\""); + if ("keyDerivationAlgorithm" in _this.recipientInfos[index].value === false) return Promise.reject("Please append encoded \"keyDerivationAlgorithm\""); + if ("algorithmParams" in _this.recipientInfos[index].value.keyDerivationAlgorithm === false) return Promise.reject("Incorrectly encoded \"keyDerivationAlgorithm\""); + + try { + pbkdf2Params = new _PBKDF2Params.default({ + schema: _this.recipientInfos[index].value.keyDerivationAlgorithm.algorithmParams + }); + } catch (ex) { + return Promise.reject("Incorrectly encoded \"keyDerivationAlgorithm\""); + } + + return crypto.importKey("raw", decryptionParameters.preDefinedData, "PBKDF2", false, ["deriveKey"]); + }, error => Promise.reject(error)); //endregion + //region Derive key for "keyEncryptionAlgorithm" + + currentSequence = currentSequence.then(result => { + //region Get WebCrypto form of "keyEncryptionAlgorithm" + kekAlgorithm = (0, _common.getAlgorithmByOID)(_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmId); + if ("name" in kekAlgorithm === false) return Promise.reject(`Incorrect OID for "keyEncryptionAlgorithm": ${_this.recipientInfos[index].value.keyEncryptionAlgorithm.algorithmId}`); //endregion + //region Get HMAC hash algorithm + + let hmacHashAlgorithm = "SHA-1"; + + if ("prf" in pbkdf2Params) { + const algorithm = (0, _common.getAlgorithmByOID)(pbkdf2Params.prf.algorithmId); + if ("name" in algorithm === false) return Promise.reject("Incorrect OID for HMAC hash algorithm"); + hmacHashAlgorithm = algorithm.hash.name; + } //endregion + //region Get PBKDF2 "salt" value + + + const saltView = new Uint8Array(pbkdf2Params.salt.valueBlock.valueHex); //endregion + //region Get PBKDF2 iterations count + + const iterations = pbkdf2Params.iterationCount; //endregion + + return crypto.deriveKey({ + name: "PBKDF2", + hash: { + name: hmacHashAlgorithm + }, + salt: saltView, + iterations + }, result, kekAlgorithm, true, ["unwrapKey"]); // Usages are too specific for KEK algorithm + }, error => Promise.reject(error)); //endregion + //region Unwrap previously exported session key + + currentSequence = currentSequence.then(result => { + //region Get WebCrypto form of content encryption algorithm + const contentEncryptionAlgorithm = (0, _common.getAlgorithmByOID)(_this.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId); + if ("name" in contentEncryptionAlgorithm === false) return Promise.reject(`Incorrect "contentEncryptionAlgorithm": ${_this.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId}`); //endregion + + return crypto.unwrapKey("raw", _this.recipientInfos[index].value.encryptedKey.valueBlock.valueHex, result, kekAlgorithm, contentEncryptionAlgorithm, true, ["decrypt"]); + }, error => Promise.reject(error)); //endregion + + return currentSequence; + } //endregion + //region Perform steps, specific to each type of session key encryption + + + sequence = sequence.then(() => { + //region Initial variables + let currentSequence = Promise.resolve(); //endregion + + switch (this.recipientInfos[recipientIndex].variant) { + case 1: + // KeyTransRecipientInfo + currentSequence = SubKeyTransRecipientInfo(recipientIndex); + break; + + case 2: + // KeyAgreeRecipientInfo + currentSequence = SubKeyAgreeRecipientInfo(recipientIndex); + break; + + case 3: + // KEKRecipientInfo + currentSequence = SubKEKRecipientInfo(recipientIndex); + break; + + case 4: + // PasswordRecipientinfo + currentSequence = SubPasswordRecipientinfo(recipientIndex); + break; + + default: + return Promise.reject(`Uknown recipient type in array with index ${recipientIndex}`); + } + + return currentSequence; + }, error => Promise.reject(error)); //endregion + //region Finally decrypt data by session key + + sequence = sequence.then(result => { + //region Get WebCrypto form of content encryption algorithm + const contentEncryptionAlgorithm = (0, _common.getAlgorithmByOID)(this.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId); + if ("name" in contentEncryptionAlgorithm === false) return Promise.reject(`Incorrect "contentEncryptionAlgorithm": ${this.encryptedContentInfo.contentEncryptionAlgorithm.algorithmId}`); //endregion + //region Get "intialization vector" for content encryption algorithm + + const ivBuffer = this.encryptedContentInfo.contentEncryptionAlgorithm.algorithmParams.valueBlock.valueHex; + const ivView = new Uint8Array(ivBuffer); //endregion + //region Create correct data block for decryption + + let dataBuffer = new ArrayBuffer(0); + if (this.encryptedContentInfo.encryptedContent.idBlock.isConstructed === false) dataBuffer = this.encryptedContentInfo.encryptedContent.valueBlock.valueHex;else { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.encryptedContentInfo.encryptedContent.valueBlock.value[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + const content = _step.value; + dataBuffer = (0, _pvutils.utilConcatBuf)(dataBuffer, content.valueBlock.valueHex); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } //endregion + + return crypto.decrypt({ + name: contentEncryptionAlgorithm.name, + iv: ivView + }, result, dataBuffer); + }, error => Promise.reject(error)); //endregion + + return sequence; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = EnvelopedData; + +},{"./AlgorithmIdentifier.js":4,"./Attribute.js":6,"./ECCCMSSharedInfo.js":30,"./EncryptedContentInfo.js":34,"./IssuerAndSerialNumber.js":44,"./KEKIdentifier.js":46,"./KEKRecipientInfo.js":47,"./KeyAgreeRecipientIdentifier.js":48,"./KeyAgreeRecipientInfo.js":49,"./KeyTransRecipientInfo.js":51,"./OriginatorIdentifierOrKey.js":57,"./OriginatorInfo.js":58,"./OriginatorPublicKey.js":59,"./PBKDF2Params.js":66,"./PasswordRecipientinfo.js":70,"./RSAESOAEPParams.js":80,"./RecipientEncryptedKey.js":84,"./RecipientEncryptedKeys.js":85,"./RecipientInfo.js":87,"./common.js":110,"asn1js":112,"pvutils":113}],37:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class ExtKeyUsage { + //********************************************************************************** + + /** + * Constructor for ExtKeyUsage class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc keyPurposes + */ + this.keyPurposes = (0, _pvutils.getParametersValue)(parameters, "keyPurposes", ExtKeyUsage.defaultValues("keyPurposes")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "keyPurposes": + return []; + + default: + throw new Error(`Invalid member name for ExtKeyUsage class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * ExtKeyUsage ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId + * + * KeyPurposeId ::= OBJECT IDENTIFIER + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [keyPurposes] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.keyPurposes || "", + value: new asn1js.ObjectIdentifier() + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["keyPurposes"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, ExtKeyUsage.schema({ + names: { + keyPurposes: "keyPurposes" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for ExtKeyUsage"); //endregion + //region Get internal properties from parsed schema + + this.keyPurposes = Array.from(asn1.result.keyPurposes, element => element.valueBlock.toString()); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: Array.from(this.keyPurposes, element => new asn1js.ObjectIdentifier({ + value: element + })) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + keyPurposes: Array.from(this.keyPurposes) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = ExtKeyUsage; + +},{"asn1js":112,"pvutils":113}],38:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _SubjectDirectoryAttributes = _interopRequireDefault(require("./SubjectDirectoryAttributes.js")); + +var _PrivateKeyUsagePeriod = _interopRequireDefault(require("./PrivateKeyUsagePeriod.js")); + +var _AltName = _interopRequireDefault(require("./AltName.js")); + +var _BasicConstraints = _interopRequireDefault(require("./BasicConstraints.js")); + +var _IssuingDistributionPoint = _interopRequireDefault(require("./IssuingDistributionPoint.js")); + +var _GeneralNames = _interopRequireDefault(require("./GeneralNames.js")); + +var _NameConstraints = _interopRequireDefault(require("./NameConstraints.js")); + +var _CRLDistributionPoints = _interopRequireDefault(require("./CRLDistributionPoints.js")); + +var _CertificatePolicies = _interopRequireDefault(require("./CertificatePolicies.js")); + +var _PolicyMappings = _interopRequireDefault(require("./PolicyMappings.js")); + +var _AuthorityKeyIdentifier = _interopRequireDefault(require("./AuthorityKeyIdentifier.js")); + +var _PolicyConstraints = _interopRequireDefault(require("./PolicyConstraints.js")); + +var _ExtKeyUsage = _interopRequireDefault(require("./ExtKeyUsage.js")); + +var _InfoAccess = _interopRequireDefault(require("./InfoAccess.js")); + +var _SignedCertificateTimestampList = _interopRequireDefault(require("./SignedCertificateTimestampList.js")); + +var _CertificateTemplate = _interopRequireDefault(require("./CertificateTemplate.js")); + +var _CAVersion = _interopRequireDefault(require("./CAVersion.js")); + +var _QCStatements = _interopRequireDefault(require("./QCStatements.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class Extension { + //********************************************************************************** + + /** + * Constructor for Extension class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc extnID + */ + this.extnID = (0, _pvutils.getParametersValue)(parameters, "extnID", Extension.defaultValues("extnID")); + /** + * @type {boolean} + * @desc critical + */ + + this.critical = (0, _pvutils.getParametersValue)(parameters, "critical", Extension.defaultValues("critical")); + /** + * @type {OctetString} + * @desc extnValue + */ + + if ("extnValue" in parameters) this.extnValue = new asn1js.OctetString({ + valueHex: parameters.extnValue + });else this.extnValue = Extension.defaultValues("extnValue"); + if ("parsedValue" in parameters) + /** + * @type {Object} + * @desc parsedValue + */ + this.parsedValue = (0, _pvutils.getParametersValue)(parameters, "parsedValue", Extension.defaultValues("parsedValue")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "extnID": + return ""; + + case "critical": + return false; + + case "extnValue": + return new asn1js.OctetString(); + + case "parsedValue": + return {}; + + default: + throw new Error(`Invalid member name for Extension class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [extnID] + * @property {string} [critical] + * @property {string} [extnValue] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.extnID || "" + }), new asn1js.Boolean({ + name: names.critical || "", + optional: true + }), new asn1js.OctetString({ + name: names.extnValue || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["extnID", "critical", "extnValue"]); //endregion + //region Check the schema is valid + + let asn1 = asn1js.compareSchema(schema, schema, Extension.schema({ + names: { + extnID: "extnID", + critical: "critical", + extnValue: "extnValue" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for Extension"); //endregion + //region Get internal properties from parsed schema + + this.extnID = asn1.result.extnID.valueBlock.toString(); + if ("critical" in asn1.result) this.critical = asn1.result.critical.valueBlock.value; + this.extnValue = asn1.result.extnValue; //region Get "parsedValue" for well-known extensions + + asn1 = asn1js.fromBER(this.extnValue.valueBlock.valueHex); + if (asn1.offset === -1) return; + + switch (this.extnID) { + case "2.5.29.9": + // SubjectDirectoryAttributes + try { + this.parsedValue = new _SubjectDirectoryAttributes.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _SubjectDirectoryAttributes.default(); + this.parsedValue.parsingError = "Incorrectly formated SubjectDirectoryAttributes"; + } + + break; + + case "2.5.29.14": + // SubjectKeyIdentifier + this.parsedValue = asn1.result; // Should be just a simple OCTETSTRING + + break; + + case "2.5.29.15": + // KeyUsage + this.parsedValue = asn1.result; // Should be just a simple BITSTRING + + break; + + case "2.5.29.16": + // PrivateKeyUsagePeriod + try { + this.parsedValue = new _PrivateKeyUsagePeriod.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _PrivateKeyUsagePeriod.default(); + this.parsedValue.parsingError = "Incorrectly formated PrivateKeyUsagePeriod"; + } + + break; + + case "2.5.29.17": // SubjectAltName + + case "2.5.29.18": + // IssuerAltName + try { + this.parsedValue = new _AltName.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _AltName.default(); + this.parsedValue.parsingError = "Incorrectly formated AltName"; + } + + break; + + case "2.5.29.19": + // BasicConstraints + try { + this.parsedValue = new _BasicConstraints.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _BasicConstraints.default(); + this.parsedValue.parsingError = "Incorrectly formated BasicConstraints"; + } + + break; + + case "2.5.29.20": // CRLNumber + + case "2.5.29.27": + // BaseCRLNumber (delta CRL indicator) + this.parsedValue = asn1.result; // Should be just a simple INTEGER + + break; + + case "2.5.29.21": + // CRLReason + this.parsedValue = asn1.result; // Should be just a simple ENUMERATED + + break; + + case "2.5.29.24": + // InvalidityDate + this.parsedValue = asn1.result; // Should be just a simple GeneralizedTime + + break; + + case "2.5.29.28": + // IssuingDistributionPoint + try { + this.parsedValue = new _IssuingDistributionPoint.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _IssuingDistributionPoint.default(); + this.parsedValue.parsingError = "Incorrectly formated IssuingDistributionPoint"; + } + + break; + + case "2.5.29.29": + // CertificateIssuer + try { + this.parsedValue = new _GeneralNames.default({ + schema: asn1.result + }); // Should be just a simple + } catch (ex) { + this.parsedValue = new _GeneralNames.default(); + this.parsedValue.parsingError = "Incorrectly formated GeneralNames"; + } + + break; + + case "2.5.29.30": + // NameConstraints + try { + this.parsedValue = new _NameConstraints.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _NameConstraints.default(); + this.parsedValue.parsingError = "Incorrectly formated NameConstraints"; + } + + break; + + case "2.5.29.31": // CRLDistributionPoints + + case "2.5.29.46": + // FreshestCRL + try { + this.parsedValue = new _CRLDistributionPoints.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _CRLDistributionPoints.default(); + this.parsedValue.parsingError = "Incorrectly formated CRLDistributionPoints"; + } + + break; + + case "2.5.29.32": // CertificatePolicies + + case "1.3.6.1.4.1.311.21.10": + // szOID_APPLICATION_CERT_POLICIES - Microsoft-specific OID + try { + this.parsedValue = new _CertificatePolicies.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _CertificatePolicies.default(); + this.parsedValue.parsingError = "Incorrectly formated CertificatePolicies"; + } + + break; + + case "2.5.29.33": + // PolicyMappings + try { + this.parsedValue = new _PolicyMappings.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _PolicyMappings.default(); + this.parsedValue.parsingError = "Incorrectly formated CertificatePolicies"; + } + + break; + + case "2.5.29.35": + // AuthorityKeyIdentifier + try { + this.parsedValue = new _AuthorityKeyIdentifier.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _AuthorityKeyIdentifier.default(); + this.parsedValue.parsingError = "Incorrectly formated AuthorityKeyIdentifier"; + } + + break; + + case "2.5.29.36": + // PolicyConstraints + try { + this.parsedValue = new _PolicyConstraints.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _PolicyConstraints.default(); + this.parsedValue.parsingError = "Incorrectly formated PolicyConstraints"; + } + + break; + + case "2.5.29.37": + // ExtKeyUsage + try { + this.parsedValue = new _ExtKeyUsage.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _ExtKeyUsage.default(); + this.parsedValue.parsingError = "Incorrectly formated ExtKeyUsage"; + } + + break; + + case "2.5.29.54": + // InhibitAnyPolicy + this.parsedValue = asn1.result; // Should be just a simple INTEGER + + break; + + case "1.3.6.1.5.5.7.1.1": // AuthorityInfoAccess + + case "1.3.6.1.5.5.7.1.11": + // SubjectInfoAccess + try { + this.parsedValue = new _InfoAccess.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _InfoAccess.default(); + this.parsedValue.parsingError = "Incorrectly formated InfoAccess"; + } + + break; + + case "1.3.6.1.4.1.11129.2.4.2": + // SignedCertificateTimestampList + try { + this.parsedValue = new _SignedCertificateTimestampList.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _SignedCertificateTimestampList.default(); + this.parsedValue.parsingError = "Incorrectly formated SignedCertificateTimestampList"; + } + + break; + + case "1.3.6.1.4.1.311.20.2": + // szOID_ENROLL_CERTTYPE_EXTENSION - Microsoft-specific extension + this.parsedValue = asn1.result; // Used to be simple Unicode string + + break; + + case "1.3.6.1.4.1.311.21.2": + // szOID_CERTSRV_PREVIOUS_CERT_HASH - Microsoft-specific extension + this.parsedValue = asn1.result; // Used to be simple OctetString + + break; + + case "1.3.6.1.4.1.311.21.7": + // szOID_CERTIFICATE_TEMPLATE - Microsoft-specific extension + try { + this.parsedValue = new _CertificateTemplate.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _CertificateTemplate.default(); + this.parsedValue.parsingError = "Incorrectly formated CertificateTemplate"; + } + + break; + + case "1.3.6.1.4.1.311.21.1": + // szOID_CERTSRV_CA_VERSION - Microsoft-specific extension + try { + this.parsedValue = new _CAVersion.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _CAVersion.default(); + this.parsedValue.parsingError = "Incorrectly formated CAVersion"; + } + + break; + + case "1.3.6.1.5.5.7.1.3": + // QCStatements + try { + this.parsedValue = new _QCStatements.default({ + schema: asn1.result + }); + } catch (ex) { + this.parsedValue = new _QCStatements.default(); + this.parsedValue.parsingError = "Incorrectly formated QCStatements"; + } + + break; + + default: + } //endregion + //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(new asn1js.ObjectIdentifier({ + value: this.extnID + })); + if (this.critical !== Extension.defaultValues("critical")) outputArray.push(new asn1js.Boolean({ + value: this.critical + })); + outputArray.push(this.extnValue); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = { + extnID: this.extnID, + extnValue: this.extnValue.toJSON() + }; + if (this.critical !== Extension.defaultValues("critical")) object.critical = this.critical; + + if ("parsedValue" in this) { + if ("toJSON" in this.parsedValue) object.parsedValue = this.parsedValue.toJSON(); + } + + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = Extension; + +},{"./AltName.js":5,"./AuthorityKeyIdentifier.js":11,"./BasicConstraints.js":12,"./CAVersion.js":14,"./CRLDistributionPoints.js":16,"./CertificatePolicies.js":21,"./CertificateTemplate.js":24,"./ExtKeyUsage.js":37,"./GeneralNames.js":41,"./InfoAccess.js":43,"./IssuingDistributionPoint.js":45,"./NameConstraints.js":54,"./PolicyConstraints.js":71,"./PolicyMappings.js":74,"./PrivateKeyUsagePeriod.js":77,"./QCStatements.js":79,"./SignedCertificateTimestampList.js":100,"./SubjectDirectoryAttributes.js":104,"asn1js":112,"pvutils":113}],39:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _Extension = _interopRequireDefault(require("./Extension.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class Extensions { + //********************************************************************************** + + /** + * Constructor for Extensions class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc type + */ + this.extensions = (0, _pvutils.getParametersValue)(parameters, "extensions", Extensions.defaultValues("extensions")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "extensions": + return []; + + default: + throw new Error(`Invalid member name for Extensions class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @param {boolean} optional Flag that current schema should be optional + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}, optional = false) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [extensions] + * @property {string} [extension] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + optional, + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.extensions || "", + value: _Extension.default.schema(names.extension || {}) + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["extensions"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, Extensions.schema({ + names: { + extensions: "extensions" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for Extensions"); //endregion + //region Get internal properties from parsed schema + + this.extensions = Array.from(asn1.result.extensions, element => new _Extension.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: Array.from(this.extensions, element => element.toSchema()) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + extensions: Array.from(this.extensions, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = Extensions; + +},{"./Extension.js":38,"asn1js":112,"pvutils":113}],40:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _RelativeDistinguishedNames = _interopRequireDefault(require("./RelativeDistinguishedNames.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** +//region Additional asn1js schema elements existing inside GeneralName schema +//************************************************************************************** + +/** + * Schema for "builtInStandardAttributes" of "ORAddress" + * @param {Object} parameters + * @property {Object} [names] + * @param {boolean} optional + * @returns {Sequence} + */ +function builtInStandardAttributes(parameters = {}, optional = false) { + //builtInStandardAttributes ::= Sequence { + // country-name CountryName OPTIONAL, + // administration-domain-name AdministrationDomainName OPTIONAL, + // network-address [0] IMPLICIT NetworkAddress OPTIONAL, + // terminal-identifier [1] IMPLICIT TerminalIdentifier OPTIONAL, + // private-domain-name [2] PrivateDomainName OPTIONAL, + // organization-name [3] IMPLICIT OrganizationName OPTIONAL, + // numeric-user-identifier [4] IMPLICIT NumericUserIdentifier OPTIONAL, + // personal-name [5] IMPLICIT PersonalName OPTIONAL, + // organizational-unit-names [6] IMPLICIT OrganizationalUnitNames OPTIONAL } + + /** + * @type {Object} + * @property {string} [country_name] + * @property {string} [administration_domain_name] + * @property {string} [network_address] + * @property {string} [terminal_identifier] + * @property {string} [private_domain_name] + * @property {string} [organization_name] + * @property {string} [numeric_user_identifier] + * @property {string} [personal_name] + * @property {string} [organizational_unit_names] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + optional, + value: [new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 2, + // APPLICATION-SPECIFIC + tagNumber: 1 // [1] + + }, + name: names.country_name || "", + value: [new asn1js.Choice({ + value: [new asn1js.NumericString(), new asn1js.PrintableString()] + })] + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 2, + // APPLICATION-SPECIFIC + tagNumber: 2 // [2] + + }, + name: names.administration_domain_name || "", + value: [new asn1js.Choice({ + value: [new asn1js.NumericString(), new asn1js.PrintableString()] + })] + }), new asn1js.Primitive({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + name: names.network_address || "", + isHexOnly: true + }), new asn1js.Primitive({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + name: names.terminal_identifier || "", + isHexOnly: true + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + name: names.private_domain_name || "", + value: [new asn1js.Choice({ + value: [new asn1js.NumericString(), new asn1js.PrintableString()] + })] + }), new asn1js.Primitive({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 3 // [3] + + }, + name: names.organization_name || "", + isHexOnly: true + }), new asn1js.Primitive({ + optional: true, + name: names.numeric_user_identifier || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 4 // [4] + + }, + isHexOnly: true + }), new asn1js.Constructed({ + optional: true, + name: names.personal_name || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 5 // [5] + + }, + value: [new asn1js.Primitive({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + isHexOnly: true + }), new asn1js.Primitive({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + isHexOnly: true + }), new asn1js.Primitive({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + isHexOnly: true + }), new asn1js.Primitive({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 3 // [3] + + }, + isHexOnly: true + })] + }), new asn1js.Constructed({ + optional: true, + name: names.organizational_unit_names || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 6 // [6] + + }, + value: [new asn1js.Repeated({ + value: new asn1js.PrintableString() + })] + })] + }); +} //************************************************************************************** + +/** + * Schema for "builtInDomainDefinedAttributes" of "ORAddress" + * @param {boolean} optional + * @returns {Sequence} + */ + + +function builtInDomainDefinedAttributes(optional = false) { + return new asn1js.Sequence({ + optional, + value: [new asn1js.PrintableString(), new asn1js.PrintableString()] + }); +} //************************************************************************************** + +/** + * Schema for "builtInDomainDefinedAttributes" of "ORAddress" + * @param {boolean} optional + * @returns {Set} + */ + + +function extensionAttributes(optional = false) { + return new asn1js.Set({ + optional, + value: [new asn1js.Primitive({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + isHexOnly: true + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [new asn1js.Any()] + })] + }); +} //************************************************************************************** +//endregion +//************************************************************************************** + +/** + * Class from RFC5280 + */ + + +class GeneralName { + //********************************************************************************** + + /** + * Constructor for GeneralName class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + * @property {number} [type] value type - from a tagged value (0 for "otherName", 1 for "rfc822Name" etc.) + * @property {Object} [value] asn1js object having GeneralName value (type depends on "type" value) + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc value type - from a tagged value (0 for "otherName", 1 for "rfc822Name" etc.) + */ + this.type = (0, _pvutils.getParametersValue)(parameters, "type", GeneralName.defaultValues("type")); + /** + * @type {Object} + * @desc asn1js object having GeneralName value (type depends on "type" value) + */ + + this.value = (0, _pvutils.getParametersValue)(parameters, "value", GeneralName.defaultValues("value")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "type": + return 9; + + case "value": + return {}; + + default: + throw new Error(`Invalid member name for GeneralName class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "type": + return memberValue === GeneralName.defaultValues(memberName); + + case "value": + return Object.keys(memberValue).length === 0; + + default: + throw new Error(`Invalid member name for GeneralName class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * GeneralName ::= Choice { + * otherName [0] OtherName, + * rfc822Name [1] IA5String, + * dNSName [2] IA5String, + * x400Address [3] ORAddress, + * directoryName [4] value, + * ediPartyName [5] EDIPartyName, + * uniformResourceIdentifier [6] IA5String, + * iPAddress [7] OCTET STRING, + * registeredID [8] OBJECT IDENTIFIER } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {Object} [directoryName] + * @property {Object} [builtInStandardAttributes] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Choice({ + value: [new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier(), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Any()] + })] + }), new asn1js.Primitive({ + name: names.blockName || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + } + }), new asn1js.Primitive({ + name: names.blockName || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + } + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 3 // [3] + + }, + name: names.blockName || "", + value: [builtInStandardAttributes(names.builtInStandardAttributes || {}, false), builtInDomainDefinedAttributes(true), extensionAttributes(true)] + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 4 // [4] + + }, + name: names.blockName || "", + value: [_RelativeDistinguishedNames.default.schema(names.directoryName || {})] + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 5 // [5] + + }, + name: names.blockName || "", + value: [new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Choice({ + value: [new asn1js.TeletexString(), new asn1js.PrintableString(), new asn1js.UniversalString(), new asn1js.Utf8String(), new asn1js.BmpString()] + })] + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [new asn1js.Choice({ + value: [new asn1js.TeletexString(), new asn1js.PrintableString(), new asn1js.UniversalString(), new asn1js.Utf8String(), new asn1js.BmpString()] + })] + })] + }), new asn1js.Primitive({ + name: names.blockName || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 6 // [6] + + } + }), new asn1js.Primitive({ + name: names.blockName || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 7 // [7] + + } + }), new asn1js.Primitive({ + name: names.blockName || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 8 // [8] + + } + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["blockName", "otherName", "rfc822Name", "dNSName", "x400Address", "directoryName", "ediPartyName", "uniformResourceIdentifier", "iPAddress", "registeredID"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, GeneralName.schema({ + names: { + blockName: "blockName", + otherName: "otherName", + rfc822Name: "rfc822Name", + dNSName: "dNSName", + x400Address: "x400Address", + directoryName: { + names: { + blockName: "directoryName" + } + }, + ediPartyName: "ediPartyName", + uniformResourceIdentifier: "uniformResourceIdentifier", + iPAddress: "iPAddress", + registeredID: "registeredID" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for GeneralName"); //endregion + //region Get internal properties from parsed schema + + this.type = asn1.result.blockName.idBlock.tagNumber; + + switch (this.type) { + case 0: + // otherName + this.value = asn1.result.blockName; + break; + + case 1: // rfc822Name + dNSName + uniformResourceIdentifier + + case 2: + case 6: + { + const value = asn1.result.blockName; + value.idBlock.tagClass = 1; // UNIVERSAL + + value.idBlock.tagNumber = 22; // IA5STRING + + const valueBER = value.toBER(false); + this.value = asn1js.fromBER(valueBER).result.valueBlock.value; + } + break; + + case 3: + // x400Address + this.value = asn1.result.blockName; + break; + + case 4: + // directoryName + this.value = new _RelativeDistinguishedNames.default({ + schema: asn1.result.directoryName + }); + break; + + case 5: + // ediPartyName + this.value = asn1.result.ediPartyName; + break; + + case 7: + // iPAddress + this.value = new asn1js.OctetString({ + valueHex: asn1.result.blockName.valueBlock.valueHex + }); + break; + + case 8: + // registeredID + { + const value = asn1.result.blockName; + value.idBlock.tagClass = 1; // UNIVERSAL + + value.idBlock.tagNumber = 6; // ObjectIdentifier + + const valueBER = value.toBER(false); + this.value = asn1js.fromBER(valueBER).result.valueBlock.toString(); // Getting a string representation of the ObjectIdentifier + } + break; + + default: + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + switch (this.type) { + case 0: + case 3: + case 5: + return new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: this.type + }, + value: [this.value] + }); + + case 1: + case 2: + case 6: + { + const value = new asn1js.IA5String({ + value: this.value + }); + value.idBlock.tagClass = 3; + value.idBlock.tagNumber = this.type; + return value; + } + + case 4: + return new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 4 + }, + value: [this.value.toSchema()] + }); + + case 7: + { + const value = this.value; + value.idBlock.tagClass = 3; + value.idBlock.tagNumber = this.type; + return value; + } + + case 8: + { + const value = new asn1js.ObjectIdentifier({ + value: this.value + }); + value.idBlock.tagClass = 3; + value.idBlock.tagNumber = this.type; + return value; + } + + default: + return GeneralName.schema(); + } //endregion + + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + type: this.type, + value: "" + }; + if (typeof this.value === "string") _object.value = this.value;else { + try { + _object.value = this.value.toJSON(); + } catch (ex) {} + } + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = GeneralName; + +},{"./RelativeDistinguishedNames.js":89,"asn1js":112,"pvutils":113}],41:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _GeneralName = _interopRequireDefault(require("./GeneralName.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class GeneralNames { + //********************************************************************************** + + /** + * Constructor for GeneralNames class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc Array of "general names" + */ + this.names = (0, _pvutils.getParametersValue)(parameters, "names", GeneralNames.defaultValues("names")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "names": + return []; + + default: + throw new Error(`Invalid member name for GeneralNames class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @param {boolean} [optional=false] Flag would be element optional or not + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}, optional = false) { + /** + * @type {Object} + * @property {string} utcTimeName Name for "utcTimeName" choice + * @property {string} generalTimeName Name for "generalTimeName" choice + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + optional, + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.generalNames || "", + value: _GeneralName.default.schema() + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["names", "generalNames"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, GeneralNames.schema({ + names: { + blockName: "names", + generalNames: "generalNames" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for GeneralNames"); //endregion + //region Get internal properties from parsed schema + + this.names = Array.from(asn1.result.generalNames, element => new _GeneralName.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: Array.from(this.names, element => element.toSchema()) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + names: Array.from(this.names, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = GeneralNames; + +},{"./GeneralName.js":40,"asn1js":112,"pvutils":113}],42:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _GeneralName = _interopRequireDefault(require("./GeneralName.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class GeneralSubtree { + //********************************************************************************** + + /** + * Constructor for GeneralSubtree class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {GeneralName} + * @desc base + */ + this.base = (0, _pvutils.getParametersValue)(parameters, "base", GeneralSubtree.defaultValues("base")); + /** + * @type {number|Integer} + * @desc base + */ + + this.minimum = (0, _pvutils.getParametersValue)(parameters, "minimum", GeneralSubtree.defaultValues("minimum")); + if ("maximum" in parameters) + /** + * @type {number|Integer} + * @desc minimum + */ + this.maximum = (0, _pvutils.getParametersValue)(parameters, "maximum", GeneralSubtree.defaultValues("maximum")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "base": + return new _GeneralName.default(); + + case "minimum": + return 0; + + case "maximum": + return 0; + + default: + throw new Error(`Invalid member name for GeneralSubtree class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * GeneralSubtree ::= SEQUENCE { + * base GeneralName, + * minimum [0] BaseDistance DEFAULT 0, + * maximum [1] BaseDistance OPTIONAL } + * + * BaseDistance ::= INTEGER (0..MAX) + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [base] + * @property {string} [minimum] + * @property {string} [maximum] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_GeneralName.default.schema(names.base || {}), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Integer({ + name: names.minimum || "" + })] + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [new asn1js.Integer({ + name: names.maximum || "" + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["base", "minimum", "maximum"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, GeneralSubtree.schema({ + names: { + base: { + names: { + blockName: "base" + } + }, + minimum: "minimum", + maximum: "maximum" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for GeneralSubtree"); //endregion + //region Get internal properties from parsed schema + + this.base = new _GeneralName.default({ + schema: asn1.result.base + }); + + if ("minimum" in asn1.result) { + if (asn1.result.minimum.valueBlock.isHexOnly) this.minimum = asn1.result.minimum;else this.minimum = asn1.result.minimum.valueBlock.valueDec; + } + + if ("maximum" in asn1.result) { + if (asn1.result.maximum.valueBlock.isHexOnly) this.maximum = asn1.result.maximum;else this.maximum = asn1.result.maximum.valueBlock.valueDec; + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(this.base.toSchema()); + + if (this.minimum !== 0) { + let valueMinimum = 0; + if (this.minimum instanceof asn1js.Integer) valueMinimum = this.minimum;else valueMinimum = new asn1js.Integer({ + value: this.minimum + }); + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [valueMinimum] + })); + } + + if ("maximum" in this) { + let valueMaximum = 0; + if (this.maximum instanceof asn1js.Integer) valueMaximum = this.maximum;else valueMaximum = new asn1js.Integer({ + value: this.maximum + }); + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [valueMaximum] + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = { + base: this.base.toJSON() + }; + + if (this.minimum !== 0) { + if (typeof this.minimum === "number") object.minimum = this.minimum;else object.minimum = this.minimum.toJSON(); + } + + if ("maximum" in this) { + if (typeof this.maximum === "number") object.maximum = this.maximum;else object.maximum = this.maximum.toJSON(); + } + + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = GeneralSubtree; + +},{"./GeneralName.js":40,"asn1js":112,"pvutils":113}],43:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AccessDescription = _interopRequireDefault(require("./AccessDescription.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class InfoAccess { + //********************************************************************************** + + /** + * Constructor for InfoAccess class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc accessDescriptions + */ + this.accessDescriptions = (0, _pvutils.getParametersValue)(parameters, "accessDescriptions", InfoAccess.defaultValues("accessDescriptions")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "accessDescriptions": + return []; + + default: + throw new Error(`Invalid member name for InfoAccess class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * AuthorityInfoAccessSyntax ::= + * SEQUENCE SIZE (1..MAX) OF AccessDescription + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [accessDescriptions] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.accessDescriptions || "", + value: _AccessDescription.default.schema() + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["accessDescriptions"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, InfoAccess.schema({ + names: { + accessDescriptions: "accessDescriptions" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for InfoAccess"); //endregion + //region Get internal properties from parsed schema + + this.accessDescriptions = Array.from(asn1.result.accessDescriptions, element => new _AccessDescription.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: Array.from(this.accessDescriptions, element => element.toSchema()) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + accessDescriptions: Array.from(this.accessDescriptions, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = InfoAccess; + +},{"./AccessDescription.js":2,"asn1js":112,"pvutils":113}],44:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _RelativeDistinguishedNames = _interopRequireDefault(require("./RelativeDistinguishedNames.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class IssuerAndSerialNumber { + //********************************************************************************** + + /** + * Constructor for IssuerAndSerialNumber class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {RelativeDistinguishedNames} + * @desc issuer + */ + this.issuer = (0, _pvutils.getParametersValue)(parameters, "issuer", IssuerAndSerialNumber.defaultValues("issuer")); + /** + * @type {Integer} + * @desc serialNumber + */ + + this.serialNumber = (0, _pvutils.getParametersValue)(parameters, "serialNumber", IssuerAndSerialNumber.defaultValues("serialNumber")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "issuer": + return new _RelativeDistinguishedNames.default(); + + case "serialNumber": + return new asn1js.Integer(); + + default: + throw new Error(`Invalid member name for IssuerAndSerialNumber class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * IssuerAndSerialNumber ::= SEQUENCE { + * issuer Name, + * serialNumber CertificateSerialNumber } + * + * CertificateSerialNumber ::= INTEGER + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [issuer] + * @property {string} [serialNumber] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_RelativeDistinguishedNames.default.schema(names.issuer || {}), new asn1js.Integer({ + name: names.serialNumber || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["issuer", "serialNumber"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, IssuerAndSerialNumber.schema({ + names: { + issuer: { + names: { + blockName: "issuer" + } + }, + serialNumber: "serialNumber" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for IssuerAndSerialNumber"); //endregion + //region Get internal properties from parsed schema + + this.issuer = new _RelativeDistinguishedNames.default({ + schema: asn1.result.issuer + }); + this.serialNumber = asn1.result.serialNumber; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [this.issuer.toSchema(), this.serialNumber] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + issuer: this.issuer.toJSON(), + serialNumber: this.serialNumber.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = IssuerAndSerialNumber; + +},{"./RelativeDistinguishedNames.js":89,"asn1js":112,"pvutils":113}],45:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _GeneralName = _interopRequireDefault(require("./GeneralName.js")); + +var _RelativeDistinguishedNames = _interopRequireDefault(require("./RelativeDistinguishedNames.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class IssuingDistributionPoint { + //********************************************************************************** + + /** + * Constructor for IssuingDistributionPoint class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + if ("distributionPoint" in parameters) + /** + * @type {Array.|RelativeDistinguishedNames} + * @desc distributionPoint + */ + this.distributionPoint = (0, _pvutils.getParametersValue)(parameters, "distributionPoint", IssuingDistributionPoint.defaultValues("distributionPoint")); + /** + * @type {boolean} + * @desc onlyContainsUserCerts + */ + + this.onlyContainsUserCerts = (0, _pvutils.getParametersValue)(parameters, "onlyContainsUserCerts", IssuingDistributionPoint.defaultValues("onlyContainsUserCerts")); + /** + * @type {boolean} + * @desc onlyContainsCACerts + */ + + this.onlyContainsCACerts = (0, _pvutils.getParametersValue)(parameters, "onlyContainsCACerts", IssuingDistributionPoint.defaultValues("onlyContainsCACerts")); + if ("onlySomeReasons" in parameters) + /** + * @type {number} + * @desc onlySomeReasons + */ + this.onlySomeReasons = (0, _pvutils.getParametersValue)(parameters, "onlySomeReasons", IssuingDistributionPoint.defaultValues("onlySomeReasons")); + /** + * @type {boolean} + * @desc indirectCRL + */ + + this.indirectCRL = (0, _pvutils.getParametersValue)(parameters, "indirectCRL", IssuingDistributionPoint.defaultValues("indirectCRL")); + /** + * @type {boolean} + * @desc onlyContainsAttributeCerts + */ + + this.onlyContainsAttributeCerts = (0, _pvutils.getParametersValue)(parameters, "onlyContainsAttributeCerts", IssuingDistributionPoint.defaultValues("onlyContainsAttributeCerts")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "distributionPoint": + return []; + + case "onlyContainsUserCerts": + return false; + + case "onlyContainsCACerts": + return false; + + case "onlySomeReasons": + return 0; + + case "indirectCRL": + return false; + + case "onlyContainsAttributeCerts": + return false; + + default: + throw new Error(`Invalid member name for IssuingDistributionPoint class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * IssuingDistributionPoint ::= SEQUENCE { + * distributionPoint [0] DistributionPointName OPTIONAL, + * onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE, + * onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE, + * onlySomeReasons [3] ReasonFlags OPTIONAL, + * indirectCRL [4] BOOLEAN DEFAULT FALSE, + * onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE } + * + * ReasonFlags ::= BIT STRING { + * unused (0), + * keyCompromise (1), + * cACompromise (2), + * affiliationChanged (3), + * superseded (4), + * cessationOfOperation (5), + * certificateHold (6), + * privilegeWithdrawn (7), + * aACompromise (8) } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [distributionPoint] + * @property {string} [distributionPointNames] + * @property {string} [onlyContainsUserCerts] + * @property {string} [onlyContainsCACerts] + * @property {string} [onlySomeReasons] + * @property {string} [indirectCRL] + * @property {string} [onlyContainsAttributeCerts] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Choice({ + value: [new asn1js.Constructed({ + name: names.distributionPoint || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Repeated({ + name: names.distributionPointNames || "", + value: _GeneralName.default.schema() + })] + }), new asn1js.Constructed({ + name: names.distributionPoint || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: _RelativeDistinguishedNames.default.schema().valueBlock.value + })] + })] + }), new asn1js.Primitive({ + name: names.onlyContainsUserCerts || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + } + }), // IMPLICIT boolean value + new asn1js.Primitive({ + name: names.onlyContainsCACerts || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + } + }), // IMPLICIT boolean value + new asn1js.Primitive({ + name: names.onlySomeReasons || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 3 // [3] + + } + }), // IMPLICIT bitstring value + new asn1js.Primitive({ + name: names.indirectCRL || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 4 // [4] + + } + }), // IMPLICIT boolean value + new asn1js.Primitive({ + name: names.onlyContainsAttributeCerts || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 5 // [5] + + } + }) // IMPLICIT boolean value + ] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["distributionPoint", "distributionPointNames", "onlyContainsUserCerts", "onlyContainsCACerts", "onlySomeReasons", "indirectCRL", "onlyContainsAttributeCerts"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, IssuingDistributionPoint.schema({ + names: { + distributionPoint: "distributionPoint", + distributionPointNames: "distributionPointNames", + onlyContainsUserCerts: "onlyContainsUserCerts", + onlyContainsCACerts: "onlyContainsCACerts", + onlySomeReasons: "onlySomeReasons", + indirectCRL: "indirectCRL", + onlyContainsAttributeCerts: "onlyContainsAttributeCerts" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for IssuingDistributionPoint"); //endregion + //region Get internal properties from parsed schema + + if ("distributionPoint" in asn1.result) { + switch (true) { + case asn1.result.distributionPoint.idBlock.tagNumber === 0: + // GENERAL_NAMES variant + this.distributionPoint = Array.from(asn1.result.distributionPointNames, element => new _GeneralName.default({ + schema: element + })); + break; + + case asn1.result.distributionPoint.idBlock.tagNumber === 1: + // RDN variant + { + this.distributionPoint = new _RelativeDistinguishedNames.default({ + schema: new asn1js.Sequence({ + value: asn1.result.distributionPoint.valueBlock.value + }) + }); + } + break; + + default: + throw new Error("Unknown tagNumber for distributionPoint: {$asn1.result.distributionPoint.idBlock.tagNumber}"); + } + } + + if ("onlyContainsUserCerts" in asn1.result) { + const view = new Uint8Array(asn1.result.onlyContainsUserCerts.valueBlock.valueHex); + this.onlyContainsUserCerts = view[0] !== 0x00; + } + + if ("onlyContainsCACerts" in asn1.result) { + const view = new Uint8Array(asn1.result.onlyContainsCACerts.valueBlock.valueHex); + this.onlyContainsCACerts = view[0] !== 0x00; + } + + if ("onlySomeReasons" in asn1.result) { + const view = new Uint8Array(asn1.result.onlySomeReasons.valueBlock.valueHex); + this.onlySomeReasons = view[0]; + } + + if ("indirectCRL" in asn1.result) { + const view = new Uint8Array(asn1.result.indirectCRL.valueBlock.valueHex); + this.indirectCRL = view[0] !== 0x00; + } + + if ("onlyContainsAttributeCerts" in asn1.result) { + const view = new Uint8Array(asn1.result.onlyContainsAttributeCerts.valueBlock.valueHex); + this.onlyContainsAttributeCerts = view[0] !== 0x00; + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + + if ("distributionPoint" in this) { + let value; + + if (this.distributionPoint instanceof Array) { + value = new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: Array.from(this.distributionPoint, element => element.toSchema()) + }); + } else { + value = this.distributionPoint.toSchema(); + value.idBlock.tagClass = 3; // CONTEXT - SPECIFIC + + value.idBlock.tagNumber = 1; // [1] + } + + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [value] + })); + } + + if (this.onlyContainsUserCerts !== IssuingDistributionPoint.defaultValues("onlyContainsUserCerts")) { + outputArray.push(new asn1js.Primitive({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + valueHex: new Uint8Array([0xFF]).buffer + })); + } + + if (this.onlyContainsCACerts !== IssuingDistributionPoint.defaultValues("onlyContainsCACerts")) { + outputArray.push(new asn1js.Primitive({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + valueHex: new Uint8Array([0xFF]).buffer + })); + } + + if ("onlySomeReasons" in this) { + const buffer = new ArrayBuffer(1); + const view = new Uint8Array(buffer); + view[0] = this.onlySomeReasons; + outputArray.push(new asn1js.Primitive({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 3 // [3] + + }, + valueHex: buffer + })); + } + + if (this.indirectCRL !== IssuingDistributionPoint.defaultValues("indirectCRL")) { + outputArray.push(new asn1js.Primitive({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 4 // [4] + + }, + valueHex: new Uint8Array([0xFF]).buffer + })); + } + + if (this.onlyContainsAttributeCerts !== IssuingDistributionPoint.defaultValues("onlyContainsAttributeCerts")) { + outputArray.push(new asn1js.Primitive({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 5 // [5] + + }, + valueHex: new Uint8Array([0xFF]).buffer + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = {}; + + if ("distributionPoint" in this) { + if (this.distributionPoint instanceof Array) object.distributionPoint = Array.from(this.distributionPoint, element => element.toJSON());else object.distributionPoint = this.distributionPoint.toJSON(); + } + + if (this.onlyContainsUserCerts !== IssuingDistributionPoint.defaultValues("onlyContainsUserCerts")) object.onlyContainsUserCerts = this.onlyContainsUserCerts; + if (this.onlyContainsCACerts !== IssuingDistributionPoint.defaultValues("onlyContainsCACerts")) object.onlyContainsCACerts = this.onlyContainsCACerts; + if ("onlySomeReasons" in this) object.onlySomeReasons = this.onlySomeReasons; + if (this.indirectCRL !== IssuingDistributionPoint.defaultValues("indirectCRL")) object.indirectCRL = this.indirectCRL; + if (this.onlyContainsAttributeCerts !== IssuingDistributionPoint.defaultValues("onlyContainsAttributeCerts")) object.onlyContainsAttributeCerts = this.onlyContainsAttributeCerts; + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = IssuingDistributionPoint; + +},{"./GeneralName.js":40,"./RelativeDistinguishedNames.js":89,"asn1js":112,"pvutils":113}],46:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _OtherKeyAttribute = _interopRequireDefault(require("./OtherKeyAttribute.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class KEKIdentifier { + //********************************************************************************** + + /** + * Constructor for KEKIdentifier class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {OctetString} + * @desc keyIdentifier + */ + this.keyIdentifier = (0, _pvutils.getParametersValue)(parameters, "keyIdentifier", KEKIdentifier.defaultValues("keyIdentifier")); + if ("date" in parameters) + /** + * @type {GeneralizedTime} + * @desc date + */ + this.date = (0, _pvutils.getParametersValue)(parameters, "date", KEKIdentifier.defaultValues("date")); + if ("other" in parameters) + /** + * @type {OtherKeyAttribute} + * @desc other + */ + this.other = (0, _pvutils.getParametersValue)(parameters, "other", KEKIdentifier.defaultValues("other")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "keyIdentifier": + return new asn1js.OctetString(); + + case "date": + return new asn1js.GeneralizedTime(); + + case "other": + return new _OtherKeyAttribute.default(); + + default: + throw new Error(`Invalid member name for KEKIdentifier class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "keyIdentifier": + return memberValue.isEqual(KEKIdentifier.defaultValues("keyIdentifier")); + + case "date": + // noinspection OverlyComplexBooleanExpressionJS + return memberValue.year === 0 && memberValue.month === 0 && memberValue.day === 0 && memberValue.hour === 0 && memberValue.minute === 0 && memberValue.second === 0 && memberValue.millisecond === 0; + + case "other": + return memberValue.compareWithDefault("keyAttrId", memberValue.keyAttrId) && "keyAttr" in memberValue === false; + + default: + throw new Error(`Invalid member name for KEKIdentifier class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * KEKIdentifier ::= SEQUENCE { + * keyIdentifier OCTET STRING, + * date GeneralizedTime OPTIONAL, + * other OtherKeyAttribute OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [keyIdentifier] + * @property {string} [date] + * @property {string} [other] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.OctetString({ + name: names.keyIdentifier || "" + }), new asn1js.GeneralizedTime({ + optional: true, + name: names.date || "" + }), _OtherKeyAttribute.default.schema(names.other || {})] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["keyIdentifier", "date", "other"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, KEKIdentifier.schema({ + names: { + keyIdentifier: "keyIdentifier", + date: "date", + other: { + names: { + blockName: "other" + } + } + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for KEKIdentifier"); //endregion + //region Get internal properties from parsed schema + + this.keyIdentifier = asn1.result.keyIdentifier; + if ("date" in asn1.result) this.date = asn1.result.date; + if ("other" in asn1.result) this.other = new _OtherKeyAttribute.default({ + schema: asn1.result.other + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(this.keyIdentifier); + if ("date" in this) outputArray.push(this.date); + if ("other" in this) outputArray.push(this.other.toSchema()); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + keyIdentifier: this.keyIdentifier.toJSON() + }; + if ("date" in this) _object.date = this.date; + if ("other" in this) _object.other = this.other.toJSON(); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = KEKIdentifier; + +},{"./OtherKeyAttribute.js":61,"asn1js":112,"pvutils":113}],47:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _KEKIdentifier = _interopRequireDefault(require("./KEKIdentifier.js")); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class KEKRecipientInfo { + //********************************************************************************** + + /** + * Constructor for KEKRecipientInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", KEKRecipientInfo.defaultValues("version")); + /** + * @type {KEKIdentifier} + * @desc kekid + */ + + this.kekid = (0, _pvutils.getParametersValue)(parameters, "kekid", KEKRecipientInfo.defaultValues("kekid")); + /** + * @type {AlgorithmIdentifier} + * @desc keyEncryptionAlgorithm + */ + + this.keyEncryptionAlgorithm = (0, _pvutils.getParametersValue)(parameters, "keyEncryptionAlgorithm", KEKRecipientInfo.defaultValues("keyEncryptionAlgorithm")); + /** + * @type {OctetString} + * @desc encryptedKey + */ + + this.encryptedKey = (0, _pvutils.getParametersValue)(parameters, "encryptedKey", KEKRecipientInfo.defaultValues("encryptedKey")); + /** + * @type {ArrayBuffer} + * @desc preDefinedKEK KEK using to encrypt CEK + */ + + this.preDefinedKEK = (0, _pvutils.getParametersValue)(parameters, "preDefinedKEK", KEKRecipientInfo.defaultValues("preDefinedKEK")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 0; + + case "kekid": + return new _KEKIdentifier.default(); + + case "keyEncryptionAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "encryptedKey": + return new asn1js.OctetString(); + + case "preDefinedKEK": + return new ArrayBuffer(0); + + default: + throw new Error(`Invalid member name for KEKRecipientInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "KEKRecipientInfo": + return memberValue === KEKRecipientInfo.defaultValues("version"); + + case "kekid": + return memberValue.compareWithDefault("keyIdentifier", memberValue.keyIdentifier) && "date" in memberValue === false && "other" in memberValue === false; + + case "keyEncryptionAlgorithm": + return memberValue.algorithmId === "" && "algorithmParams" in memberValue === false; + + case "encryptedKey": + return memberValue.isEqual(KEKRecipientInfo.defaultValues("encryptedKey")); + + case "preDefinedKEK": + return memberValue.byteLength === 0; + + default: + throw new Error(`Invalid member name for KEKRecipientInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * KEKRecipientInfo ::= SEQUENCE { + * version CMSVersion, -- always set to 4 + * kekid KEKIdentifier, + * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, + * encryptedKey EncryptedKey } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [version] + * @property {string} [kekid] + * @property {string} [keyEncryptionAlgorithm] + * @property {string} [encryptedKey] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.version || "" + }), _KEKIdentifier.default.schema(names.kekid || {}), _AlgorithmIdentifier.default.schema(names.keyEncryptionAlgorithm || {}), new asn1js.OctetString({ + name: names.encryptedKey || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["version", "kekid", "keyEncryptionAlgorithm", "encryptedKey"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, KEKRecipientInfo.schema({ + names: { + version: "version", + kekid: { + names: { + blockName: "kekid" + } + }, + keyEncryptionAlgorithm: { + names: { + blockName: "keyEncryptionAlgorithm" + } + }, + encryptedKey: "encryptedKey" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for KEKRecipientInfo"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result.version.valueBlock.valueDec; + this.kekid = new _KEKIdentifier.default({ + schema: asn1.result.kekid + }); + this.keyEncryptionAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.keyEncryptionAlgorithm + }); + this.encryptedKey = asn1.result.encryptedKey; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [new asn1js.Integer({ + value: this.version + }), this.kekid.toSchema(), this.keyEncryptionAlgorithm.toSchema(), this.encryptedKey] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + version: this.version, + kekid: this.kekid.toJSON(), + keyEncryptionAlgorithm: this.keyEncryptionAlgorithm.toJSON(), + encryptedKey: this.encryptedKey.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = KEKRecipientInfo; + +},{"./AlgorithmIdentifier.js":4,"./KEKIdentifier.js":46,"asn1js":112,"pvutils":113}],48:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _IssuerAndSerialNumber = _interopRequireDefault(require("./IssuerAndSerialNumber.js")); + +var _RecipientKeyIdentifier = _interopRequireDefault(require("./RecipientKeyIdentifier.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class KeyAgreeRecipientIdentifier { + //********************************************************************************** + + /** + * Constructor for KeyAgreeRecipientIdentifier class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc variant + */ + this.variant = (0, _pvutils.getParametersValue)(parameters, "variant", KeyAgreeRecipientIdentifier.defaultValues("variant")); + /** + * @type {*} + * @desc values + */ + + this.value = (0, _pvutils.getParametersValue)(parameters, "value", KeyAgreeRecipientIdentifier.defaultValues("value")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "variant": + return -1; + + case "value": + return {}; + + default: + throw new Error(`Invalid member name for KeyAgreeRecipientIdentifier class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "variant": + return memberValue === -1; + + case "value": + return Object.keys(memberValue).length === 0; + + default: + throw new Error(`Invalid member name for KeyAgreeRecipientIdentifier class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * KeyAgreeRecipientIdentifier ::= CHOICE { + * issuerAndSerialNumber IssuerAndSerialNumber, + * rKeyId [0] IMPLICIT RecipientKeyIdentifier } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [issuerAndSerialNumber] + * @property {string} [rKeyId] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Choice({ + value: [_IssuerAndSerialNumber.default.schema(names.issuerAndSerialNumber || { + names: { + blockName: names.blockName || "" + } + }), new asn1js.Constructed({ + name: names.blockName || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: _RecipientKeyIdentifier.default.schema(names.rKeyId || { + names: { + blockName: names.blockName || "" + } + }).valueBlock.value + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["blockName"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, KeyAgreeRecipientIdentifier.schema({ + names: { + blockName: "blockName" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for KeyAgreeRecipientIdentifier"); //endregion + //region Get internal properties from parsed schema + + if (asn1.result.blockName.idBlock.tagClass === 1) { + this.variant = 1; + this.value = new _IssuerAndSerialNumber.default({ + schema: asn1.result.blockName + }); + } else { + this.variant = 2; + this.value = new _RecipientKeyIdentifier.default({ + schema: new asn1js.Sequence({ + value: asn1.result.blockName.valueBlock.value + }) + }); + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + switch (this.variant) { + case 1: + return this.value.toSchema(); + + case 2: + return new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: this.value.toSchema().valueBlock.value + }); + + default: + return new asn1js.Any(); + } //endregion + + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + variant: this.variant + }; + if (this.variant === 1 || this.variant === 2) _object.value = this.value.toJSON(); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = KeyAgreeRecipientIdentifier; + +},{"./IssuerAndSerialNumber.js":44,"./RecipientKeyIdentifier.js":88,"asn1js":112,"pvutils":113}],49:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _OriginatorIdentifierOrKey = _interopRequireDefault(require("./OriginatorIdentifierOrKey.js")); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _RecipientEncryptedKeys = _interopRequireDefault(require("./RecipientEncryptedKeys.js")); + +var _Certificate = _interopRequireDefault(require("./Certificate.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class KeyAgreeRecipientInfo { + //********************************************************************************** + + /** + * Constructor for KeyAgreeRecipientInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", KeyAgreeRecipientInfo.defaultValues("version")); + /** + * @type {OriginatorIdentifierOrKey} + * @desc originator + */ + + this.originator = (0, _pvutils.getParametersValue)(parameters, "originator", KeyAgreeRecipientInfo.defaultValues("originator")); + if ("ukm" in parameters) + /** + * @type {OctetString} + * @desc ukm + */ + this.ukm = (0, _pvutils.getParametersValue)(parameters, "ukm", KeyAgreeRecipientInfo.defaultValues("ukm")); + /** + * @type {AlgorithmIdentifier} + * @desc keyEncryptionAlgorithm + */ + + this.keyEncryptionAlgorithm = (0, _pvutils.getParametersValue)(parameters, "keyEncryptionAlgorithm", KeyAgreeRecipientInfo.defaultValues("keyEncryptionAlgorithm")); + /** + * @type {RecipientEncryptedKeys} + * @desc recipientEncryptedKeys + */ + + this.recipientEncryptedKeys = (0, _pvutils.getParametersValue)(parameters, "recipientEncryptedKeys", KeyAgreeRecipientInfo.defaultValues("recipientEncryptedKeys")); + /** + * @type {Certificate} + * @desc recipientCertificate For some reasons we need to store recipient's certificate here + */ + + this.recipientCertificate = (0, _pvutils.getParametersValue)(parameters, "recipientCertificate", KeyAgreeRecipientInfo.defaultValues("recipientCertificate")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 0; + + case "originator": + return new _OriginatorIdentifierOrKey.default(); + + case "ukm": + return new asn1js.OctetString(); + + case "keyEncryptionAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "recipientEncryptedKeys": + return new _RecipientEncryptedKeys.default(); + + case "recipientCertificate": + return new _Certificate.default(); + + default: + throw new Error(`Invalid member name for KeyAgreeRecipientInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "version": + return memberValue === 0; + + case "originator": + return memberValue.variant === -1 && "value" in memberValue === false; + + case "ukm": + return memberValue.isEqual(KeyAgreeRecipientInfo.defaultValues("ukm")); + + case "keyEncryptionAlgorithm": + return memberValue.algorithmId === "" && "algorithmParams" in memberValue === false; + + case "recipientEncryptedKeys": + return memberValue.encryptedKeys.length === 0; + + case "recipientCertificate": + return false; + // For now leave it as is + + default: + throw new Error(`Invalid member name for KeyAgreeRecipientInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * KeyAgreeRecipientInfo ::= SEQUENCE { + * version CMSVersion, -- always set to 3 + * originator [0] EXPLICIT OriginatorIdentifierOrKey, + * ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL, + * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, + * recipientEncryptedKeys RecipientEncryptedKeys } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [version] + * @property {string} [originator] + * @property {string} [ukm] + * @property {string} [keyEncryptionAlgorithm] + * @property {string} [recipientEncryptedKeys] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.version || "" + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [_OriginatorIdentifierOrKey.default.schema(names.originator || {})] + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [new asn1js.OctetString({ + name: names.ukm || "" + })] + }), _AlgorithmIdentifier.default.schema(names.keyEncryptionAlgorithm || {}), _RecipientEncryptedKeys.default.schema(names.recipientEncryptedKeys || {})] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["version", "originator", "ukm", "keyEncryptionAlgorithm", "recipientEncryptedKeys"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, KeyAgreeRecipientInfo.schema({ + names: { + version: "version", + originator: { + names: { + blockName: "originator" + } + }, + ukm: "ukm", + keyEncryptionAlgorithm: { + names: { + blockName: "keyEncryptionAlgorithm" + } + }, + recipientEncryptedKeys: { + names: { + blockName: "recipientEncryptedKeys" + } + } + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for KeyAgreeRecipientInfo"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result.version.valueBlock.valueDec; + this.originator = new _OriginatorIdentifierOrKey.default({ + schema: asn1.result.originator + }); + if ("ukm" in asn1.result) this.ukm = asn1.result.ukm; + this.keyEncryptionAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.keyEncryptionAlgorithm + }); + this.recipientEncryptedKeys = new _RecipientEncryptedKeys.default({ + schema: asn1.result.recipientEncryptedKeys + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for final sequence + const outputArray = []; + outputArray.push(new asn1js.Integer({ + value: this.version + })); + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [this.originator.toSchema()] + })); + + if ("ukm" in this) { + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [this.ukm] + })); + } + + outputArray.push(this.keyEncryptionAlgorithm.toSchema()); + outputArray.push(this.recipientEncryptedKeys.toSchema()); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + version: this.version, + originator: this.originator.toJSON() + }; + if ("ukm" in this) _object.ukm = this.ukm.toJSON(); + _object.keyEncryptionAlgorithm = this.keyEncryptionAlgorithm.toJSON(); + _object.recipientEncryptedKeys = this.recipientEncryptedKeys.toJSON(); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = KeyAgreeRecipientInfo; + +},{"./AlgorithmIdentifier.js":4,"./Certificate.js":19,"./OriginatorIdentifierOrKey.js":57,"./RecipientEncryptedKeys.js":85,"asn1js":112,"pvutils":113}],50:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _PrivateKeyInfo = _interopRequireDefault(require("./PrivateKeyInfo.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +//************************************************************************************** + +/** + * Class from RFC5208 + */ +class KeyBag extends _PrivateKeyInfo.default { + //********************************************************************************** + + /** + * Constructor for Attribute class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + super(parameters); + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = KeyBag; + +},{"./PrivateKeyInfo.js":76}],51:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _Certificate = _interopRequireDefault(require("./Certificate.js")); + +var _RecipientIdentifier = _interopRequireDefault(require("./RecipientIdentifier.js")); + +var _IssuerAndSerialNumber = _interopRequireDefault(require("./IssuerAndSerialNumber.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class KeyTransRecipientInfo { + //********************************************************************************** + + /** + * Constructor for KeyTransRecipientInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", KeyTransRecipientInfo.defaultValues("version")); + /** + * @type {RecipientIdentifier} + * @desc rid + */ + + this.rid = (0, _pvutils.getParametersValue)(parameters, "rid", KeyTransRecipientInfo.defaultValues("rid")); + /** + * @type {AlgorithmIdentifier} + * @desc keyEncryptionAlgorithm + */ + + this.keyEncryptionAlgorithm = (0, _pvutils.getParametersValue)(parameters, "keyEncryptionAlgorithm", KeyTransRecipientInfo.defaultValues("keyEncryptionAlgorithm")); + /** + * @type {OctetString} + * @desc encryptedKey + */ + + this.encryptedKey = (0, _pvutils.getParametersValue)(parameters, "encryptedKey", KeyTransRecipientInfo.defaultValues("encryptedKey")); + /** + * @type {Certificate} + * @desc recipientCertificate For some reasons we need to store recipient's certificate here + */ + + this.recipientCertificate = (0, _pvutils.getParametersValue)(parameters, "recipientCertificate", KeyTransRecipientInfo.defaultValues("recipientCertificate")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return -1; + + case "rid": + return {}; + + case "keyEncryptionAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "encryptedKey": + return new asn1js.OctetString(); + + case "recipientCertificate": + return new _Certificate.default(); + + default: + throw new Error(`Invalid member name for KeyTransRecipientInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "version": + return memberValue === KeyTransRecipientInfo.defaultValues("version"); + + case "rid": + return Object.keys(memberValue).length === 0; + + case "keyEncryptionAlgorithm": + case "encryptedKey": + return memberValue.isEqual(KeyTransRecipientInfo.defaultValues(memberName)); + + case "recipientCertificate": + return false; + // For now we do not need to compare any values with the "recipientCertificate" + + default: + throw new Error(`Invalid member name for KeyTransRecipientInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * KeyTransRecipientInfo ::= SEQUENCE { + * version CMSVersion, -- always set to 0 or 2 + * rid RecipientIdentifier, + * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, + * encryptedKey EncryptedKey } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [version] + * @property {string} [rid] + * @property {string} [keyEncryptionAlgorithm] + * @property {string} [encryptedKey] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.version || "" + }), _RecipientIdentifier.default.schema(names.rid || {}), _AlgorithmIdentifier.default.schema(names.keyEncryptionAlgorithm || {}), new asn1js.OctetString({ + name: names.encryptedKey || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["version", "rid", "keyEncryptionAlgorithm", "encryptedKey"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, KeyTransRecipientInfo.schema({ + names: { + version: "version", + rid: { + names: { + blockName: "rid" + } + }, + keyEncryptionAlgorithm: { + names: { + blockName: "keyEncryptionAlgorithm" + } + }, + encryptedKey: "encryptedKey" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for KeyTransRecipientInfo"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result.version.valueBlock.valueDec; + if (asn1.result.rid.idBlock.tagClass === 3) this.rid = asn1.result.rid.valueBlock.value[0]; // SubjectKeyIdentifier + else this.rid = new _IssuerAndSerialNumber.default({ + schema: asn1.result.rid + }); + this.keyEncryptionAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.keyEncryptionAlgorithm + }); + this.encryptedKey = asn1.result.encryptedKey; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + + if (this.rid instanceof _IssuerAndSerialNumber.default) { + this.version = 0; + outputArray.push(new asn1js.Integer({ + value: this.version + })); + outputArray.push(this.rid.toSchema()); + } else { + this.version = 2; + outputArray.push(new asn1js.Integer({ + value: this.version + })); + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [this.rid] + })); + } + + outputArray.push(this.keyEncryptionAlgorithm.toSchema()); + outputArray.push(this.encryptedKey); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + version: this.version, + rid: this.rid.toJSON(), + keyEncryptionAlgorithm: this.keyEncryptionAlgorithm.toJSON(), + encryptedKey: this.encryptedKey.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = KeyTransRecipientInfo; + +},{"./AlgorithmIdentifier.js":4,"./Certificate.js":19,"./IssuerAndSerialNumber.js":44,"./RecipientIdentifier.js":86,"asn1js":112,"pvutils":113}],52:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _DigestInfo = _interopRequireDefault(require("./DigestInfo.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC7292 + */ +class MacData { + //********************************************************************************** + + /** + * Constructor for MacData class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {DigestInfo} + * @desc mac + */ + this.mac = (0, _pvutils.getParametersValue)(parameters, "mac", MacData.defaultValues("mac")); + /** + * @type {OctetString} + * @desc macSalt + */ + + this.macSalt = (0, _pvutils.getParametersValue)(parameters, "macSalt", MacData.defaultValues("macSalt")); + if ("iterations" in parameters) + /** + * @type {number} + * @desc iterations + */ + this.iterations = (0, _pvutils.getParametersValue)(parameters, "iterations", MacData.defaultValues("iterations")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "mac": + return new _DigestInfo.default(); + + case "macSalt": + return new asn1js.OctetString(); + + case "iterations": + return 1; + + default: + throw new Error(`Invalid member name for MacData class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "mac": + return _DigestInfo.default.compareWithDefault("digestAlgorithm", memberValue.digestAlgorithm) && _DigestInfo.default.compareWithDefault("digest", memberValue.digest); + + case "macSalt": + return memberValue.isEqual(MacData.defaultValues(memberName)); + + case "iterations": + return memberValue === MacData.defaultValues(memberName); + + default: + throw new Error(`Invalid member name for MacData class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * MacData ::= SEQUENCE { + * mac DigestInfo, + * macSalt OCTET STRING, + * iterations INTEGER DEFAULT 1 + * -- Note: The default is for historical reasons and its use is + * -- deprecated. A higher value, like 1024 is recommended. + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [optional] + * @property {string} [mac] + * @property {string} [macSalt] + * @property {string} [iterations] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + optional: names.optional || true, + value: [_DigestInfo.default.schema(names.mac || { + names: { + blockName: "mac" + } + }), new asn1js.OctetString({ + name: names.macSalt || "macSalt" + }), new asn1js.Integer({ + optional: true, + name: names.iterations || "iterations" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["mac", "macSalt", "iterations"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, MacData.schema({ + names: { + mac: { + names: { + blockName: "mac" + } + }, + macSalt: "macSalt", + iterations: "iterations" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for MacData"); //endregion + //region Get internal properties from parsed schema + + this.mac = new _DigestInfo.default({ + schema: asn1.result.mac + }); + this.macSalt = asn1.result.macSalt; + if ("iterations" in asn1.result) this.iterations = asn1.result.iterations.valueBlock.valueDec; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + const outputArray = [this.mac.toSchema(), this.macSalt]; + if ("iterations" in this) outputArray.push(new asn1js.Integer({ + value: this.iterations + })); + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const output = { + mac: this.mac.toJSON(), + macSalt: this.macSalt.toJSON() + }; + if ("iterations" in this) output.iterations = this.iterations.toJSON(); + return output; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = MacData; + +},{"./DigestInfo.js":28,"asn1js":112,"pvutils":113}],53:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC3161 + */ +class MessageImprint { + //********************************************************************************** + + /** + * Constructor for MessageImprint class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {AlgorithmIdentifier} + * @desc hashAlgorithm + */ + this.hashAlgorithm = (0, _pvutils.getParametersValue)(parameters, "hashAlgorithm", MessageImprint.defaultValues("hashAlgorithm")); + /** + * @type {OctetString} + * @desc hashedMessage + */ + + this.hashedMessage = (0, _pvutils.getParametersValue)(parameters, "hashedMessage", MessageImprint.defaultValues("hashedMessage")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "hashAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "hashedMessage": + return new asn1js.OctetString(); + + default: + throw new Error(`Invalid member name for MessageImprint class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "hashAlgorithm": + return memberValue.algorithmId === "" && "algorithmParams" in memberValue === false; + + case "hashedMessage": + return memberValue.isEqual(MessageImprint.defaultValues(memberName)) === 0; + + default: + throw new Error(`Invalid member name for MessageImprint class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * MessageImprint ::= SEQUENCE { + * hashAlgorithm AlgorithmIdentifier, + * hashedMessage OCTET STRING } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [hashAlgorithm] + * @property {string} [hashedMessage] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_AlgorithmIdentifier.default.schema(names.hashAlgorithm || {}), new asn1js.OctetString({ + name: names.hashedMessage || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["hashAlgorithm", "hashedMessage"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, MessageImprint.schema({ + names: { + hashAlgorithm: { + names: { + blockName: "hashAlgorithm" + } + }, + hashedMessage: "hashedMessage" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for MessageImprint"); //endregion + //region Get internal properties from parsed schema + + this.hashAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.hashAlgorithm + }); + this.hashedMessage = asn1.result.hashedMessage; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [this.hashAlgorithm.toSchema(), this.hashedMessage] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + hashAlgorithm: this.hashAlgorithm.toJSON(), + hashedMessage: this.hashedMessage.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = MessageImprint; + +},{"./AlgorithmIdentifier.js":4,"asn1js":112,"pvutils":113}],54:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _GeneralSubtree = _interopRequireDefault(require("./GeneralSubtree.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class NameConstraints { + //********************************************************************************** + + /** + * Constructor for NameConstraints class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + if ("permittedSubtrees" in parameters) + /** + * @type {Array.} + * @desc permittedSubtrees + */ + this.permittedSubtrees = (0, _pvutils.getParametersValue)(parameters, "permittedSubtrees", NameConstraints.defaultValues("permittedSubtrees")); + if ("excludedSubtrees" in parameters) + /** + * @type {Array.} + * @desc excludedSubtrees + */ + this.excludedSubtrees = (0, _pvutils.getParametersValue)(parameters, "excludedSubtrees", NameConstraints.defaultValues("excludedSubtrees")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "permittedSubtrees": + return []; + + case "excludedSubtrees": + return []; + + default: + throw new Error(`Invalid member name for NameConstraints class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * NameConstraints ::= SEQUENCE { + * permittedSubtrees [0] GeneralSubtrees OPTIONAL, + * excludedSubtrees [1] GeneralSubtrees OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [permittedSubtrees] + * @property {string} [excludedSubtrees] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Repeated({ + name: names.permittedSubtrees || "", + value: _GeneralSubtree.default.schema() + })] + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [new asn1js.Repeated({ + name: names.excludedSubtrees || "", + value: _GeneralSubtree.default.schema() + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["permittedSubtrees", "excludedSubtrees"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, NameConstraints.schema({ + names: { + permittedSubtrees: "permittedSubtrees", + excludedSubtrees: "excludedSubtrees" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for NameConstraints"); //endregion + //region Get internal properties from parsed schema + + if ("permittedSubtrees" in asn1.result) this.permittedSubtrees = Array.from(asn1.result.permittedSubtrees, element => new _GeneralSubtree.default({ + schema: element + })); + if ("excludedSubtrees" in asn1.result) this.excludedSubtrees = Array.from(asn1.result.excludedSubtrees, element => new _GeneralSubtree.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + + if ("permittedSubtrees" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: Array.from(this.permittedSubtrees, element => element.toSchema()) + })); + } + + if ("excludedSubtrees" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: Array.from(this.excludedSubtrees, element => element.toSchema()) + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = {}; + if ("permittedSubtrees" in this) object.permittedSubtrees = Array.from(this.permittedSubtrees, element => element.toJSON()); + if ("excludedSubtrees" in this) object.excludedSubtrees = Array.from(this.excludedSubtrees, element => element.toJSON()); + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = NameConstraints; + +},{"./GeneralSubtree.js":42,"asn1js":112,"pvutils":113}],55:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _common = require("./common.js"); + +var _TBSRequest = _interopRequireDefault(require("./TBSRequest.js")); + +var _Signature = _interopRequireDefault(require("./Signature.js")); + +var _Request = _interopRequireDefault(require("./Request.js")); + +var _CertID = _interopRequireDefault(require("./CertID.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC6960 + */ +class OCSPRequest { + //********************************************************************************** + + /** + * Constructor for OCSPRequest class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {TBSRequest} + * @desc tbsRequest + */ + this.tbsRequest = (0, _pvutils.getParametersValue)(parameters, "tbsRequest", OCSPRequest.defaultValues("tbsRequest")); + if ("optionalSignature" in parameters) + /** + * @type {Signature} + * @desc optionalSignature + */ + this.optionalSignature = (0, _pvutils.getParametersValue)(parameters, "optionalSignature", OCSPRequest.defaultValues("optionalSignature")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "tbsRequest": + return new _TBSRequest.default(); + + case "optionalSignature": + return new _Signature.default(); + + default: + throw new Error(`Invalid member name for OCSPRequest class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "tbsRequest": + // noinspection OverlyComplexBooleanExpressionJS + return _TBSRequest.default.compareWithDefault("tbs", memberValue.tbs) && _TBSRequest.default.compareWithDefault("version", memberValue.version) && _TBSRequest.default.compareWithDefault("requestorName", memberValue.requestorName) && _TBSRequest.default.compareWithDefault("requestList", memberValue.requestList) && _TBSRequest.default.compareWithDefault("requestExtensions", memberValue.requestExtensions); + + case "optionalSignature": + return _Signature.default.compareWithDefault("signatureAlgorithm", memberValue.signatureAlgorithm) && _Signature.default.compareWithDefault("signature", memberValue.signature) && _Signature.default.compareWithDefault("certs", memberValue.certs); + + default: + throw new Error(`Invalid member name for OCSPRequest class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * OCSPRequest ::= SEQUENCE { + * tbsRequest TBSRequest, + * optionalSignature [0] EXPLICIT Signature OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [tbsRequest] + * @property {string} [optionalSignature] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "OCSPRequest", + value: [_TBSRequest.default.schema(names.tbsRequest || { + names: { + blockName: "tbsRequest" + } + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [_Signature.default.schema(names.optionalSignature || { + names: { + blockName: "optionalSignature" + } + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["tbsRequest", "optionalSignature"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, OCSPRequest.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for OCSPRequest"); //endregion + //region Get internal properties from parsed schema + + this.tbsRequest = new _TBSRequest.default({ + schema: asn1.result.tbsRequest + }); + if ("optionalSignature" in asn1.result) this.optionalSignature = new _Signature.default({ + schema: asn1.result.optionalSignature + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @param {boolean} encodeFlag If param equal to false then create TBS schema via decoding stored value. In othe case create TBS schema via assembling from TBS parts. + * @returns {Object} asn1js object + */ + + + toSchema(encodeFlag = false) { + //region Create array for output sequence + const outputArray = []; + outputArray.push(this.tbsRequest.toSchema(encodeFlag)); + if ("optionalSignature" in this) outputArray.push(this.optionalSignature.toSchema()); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + tbsRequest: this.tbsRequest.toJSON() + }; + if ("optionalSignature" in this) _object.optionalSignature = this.optionalSignature.toJSON(); + return _object; + } //********************************************************************************** + + /** + * Making OCSP Request for specific certificate + * @param {Certificate} certificate Certificate making OCSP Request for + * @param {Object} parameters Additional parameters + * @returns {Promise} + */ + + + createForCertificate(certificate, parameters) { + //region Initial variables + let sequence = Promise.resolve(); + const certID = new _CertID.default(); //endregion + //region Create OCSP certificate identifier for the certificate + + sequence = sequence.then(() => certID.createForCertificate(certificate, parameters)); //endregion + //region Make final request data + + sequence = sequence.then(() => { + this.tbsRequest = new _TBSRequest.default({ + requestList: [new _Request.default({ + reqCert: certID + })] + }); + }, error => Promise.reject(error)); //endregion + + return sequence; + } //********************************************************************************** + + /** + * Make signature for current OCSP Request + * @param {Object} privateKey Private key for "subjectPublicKeyInfo" structure + * @param {string} [hashAlgorithm] Hashing algorithm. Default SHA-1 + * @returns {Promise} + */ + + + sign(privateKey, hashAlgorithm = "SHA-1") { + //region Initial checking + //region Check private key + if (typeof privateKey === "undefined") return Promise.reject("Need to provide a private key for signing"); //endregion + //region Check that "optionalSignature" exists in the current request + + if ("optionalSignature" in this === false) return Promise.reject("Need to create \"optionalSignature\" field before signing"); //endregion + //endregion + //region Initial variables + + let sequence = Promise.resolve(); + let parameters; + let tbs; + const engine = (0, _common.getEngine)(); //endregion + //region Get a "default parameters" for current algorithm and set correct signature algorithm + + sequence = sequence.then(() => engine.subtle.getSignatureParameters(privateKey, hashAlgorithm)); + sequence = sequence.then(result => { + parameters = result.parameters; + this.optionalSignature.signatureAlgorithm = result.signatureAlgorithm; + }); //endregion + //region Create TBS data for signing + + sequence = sequence.then(() => { + tbs = this.tbsRequest.toSchema(true).toBER(false); + }); //endregion + //region Signing TBS data on provided private key + + sequence = sequence.then(() => engine.subtle.signWithPrivateKey(tbs, privateKey, parameters)); + sequence = sequence.then(result => { + this.optionalSignature.signature = new asn1js.BitString({ + valueHex: result + }); + }); //endregion + + return sequence; + } //********************************************************************************** + + + verify() {} // TODO: Create the function + //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = OCSPRequest; + +},{"./CertID.js":18,"./Request.js":90,"./Signature.js":98,"./TBSRequest.js":105,"./common.js":110,"asn1js":112,"pvutils":113}],56:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _ResponseBytes = _interopRequireDefault(require("./ResponseBytes.js")); + +var _BasicOCSPResponse = _interopRequireDefault(require("./BasicOCSPResponse.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC6960 + */ +class OCSPResponse { + //********************************************************************************** + + /** + * Constructor for OCSPResponse class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Enumerated} + * @desc responseStatus + */ + this.responseStatus = (0, _pvutils.getParametersValue)(parameters, "responseStatus", OCSPResponse.defaultValues("responseStatus")); + if ("responseBytes" in parameters) + /** + * @type {ResponseBytes} + * @desc responseBytes + */ + this.responseBytes = (0, _pvutils.getParametersValue)(parameters, "responseBytes", OCSPResponse.defaultValues("responseBytes")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "responseStatus": + return new asn1js.Enumerated(); + + case "responseBytes": + return new _ResponseBytes.default(); + + default: + throw new Error(`Invalid member name for OCSPResponse class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "responseStatus": + return memberValue.isEqual(OCSPResponse.defaultValues(memberName)); + + case "responseBytes": + return _ResponseBytes.default.compareWithDefault("responseType", memberValue.responseType) && _ResponseBytes.default.compareWithDefault("response", memberValue.response); + + default: + throw new Error(`Invalid member name for OCSPResponse class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * OCSPResponse ::= SEQUENCE { + * responseStatus OCSPResponseStatus, + * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } + * + * OCSPResponseStatus ::= ENUMERATED { + * successful (0), -- Response has valid confirmations + * malformedRequest (1), -- Illegal confirmation request + * internalError (2), -- Internal error in issuer + * tryLater (3), -- Try again later + * -- (4) is not used + * sigRequired (5), -- Must sign the request + * unauthorized (6) -- Request unauthorized + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [responseStatus] + * @property {string} [responseBytes] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "OCSPResponse", + value: [new asn1js.Enumerated({ + name: names.responseStatus || "responseStatus" + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [_ResponseBytes.default.schema(names.responseBytes || { + names: { + blockName: "responseBytes" + } + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["responseStatus", "responseBytes"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, OCSPResponse.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for OCSPResponse"); //endregion + //region Get internal properties from parsed schema + + this.responseStatus = asn1.result.responseStatus; + if ("responseBytes" in asn1.result) this.responseBytes = new _ResponseBytes.default({ + schema: asn1.result.responseBytes + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(this.responseStatus); + + if ("responseBytes" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [this.responseBytes.toSchema()] + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + responseStatus: this.responseStatus.toJSON() + }; + if ("responseBytes" in this) _object.responseBytes = this.responseBytes.toJSON(); + return _object; + } //********************************************************************************** + + /** + * Get OCSP response status for specific certificate + * @param {Certificate} certificate + * @param {Certificate} issuerCertificate + * @returns {*} + */ + + + getCertificateStatus(certificate, issuerCertificate) { + //region Initial variables + let basicResponse; + const result = { + isForCertificate: false, + status: 2 // 0 = good, 1 = revoked, 2 = unknown + + }; //endregion + //region Check that "ResponseBytes" contain "OCSP_BASIC_RESPONSE" + + if ("responseBytes" in this === false) return result; + if (this.responseBytes.responseType !== "1.3.6.1.5.5.7.48.1.1") // id-pkix-ocsp-basic + return result; + + try { + const asn1Basic = asn1js.fromBER(this.responseBytes.response.valueBlock.valueHex); + basicResponse = new _BasicOCSPResponse.default({ + schema: asn1Basic.result + }); + } catch (ex) { + return result; + } //endregion + + + return basicResponse.getCertificateStatus(certificate, issuerCertificate); + } //********************************************************************************** + + /** + * Make a signature for current OCSP Response + * @param {Object} privateKey Private key for "subjectPublicKeyInfo" structure + * @param {string} [hashAlgorithm] Hashing algorithm. Default SHA-1 + * @returns {Promise} + */ + + + sign(privateKey, hashAlgorithm) { + //region Check that ResponseData has type BasicOCSPResponse and sign it + if (this.responseBytes.responseType === "1.3.6.1.5.5.7.48.1.1") { + const asn1 = asn1js.fromBER(this.responseBytes.response.valueBlock.valueHex); + const basicResponse = new _BasicOCSPResponse.default({ + schema: asn1.result + }); + return basicResponse.sign(privateKey, hashAlgorithm); + } + + return Promise.reject(`Unknown ResponseBytes type: ${this.responseBytes.responseType}`); //endregion + } //********************************************************************************** + + /** + * Verify current OCSP Response + * @param {Certificate|null} issuerCertificate In order to decrease size of resp issuer cert could be ommited. In such case you need manually provide it. + * @returns {Promise} + */ + + + verify(issuerCertificate = null) { + //region Check that ResponseBytes exists in the object + if ("responseBytes" in this === false) return Promise.reject("Empty ResponseBytes field"); //endregion + //region Check that ResponceData has type BasicOCSPResponse and verify it + + if (this.responseBytes.responseType === "1.3.6.1.5.5.7.48.1.1") { + const asn1 = asn1js.fromBER(this.responseBytes.response.valueBlock.valueHex); + const basicResponse = new _BasicOCSPResponse.default({ + schema: asn1.result + }); + + if (issuerCertificate !== null) { + if ("certs" in basicResponse === false) basicResponse.certs = []; + basicResponse.certs.push(issuerCertificate); + } + + return basicResponse.verify(); + } + + return Promise.reject(`Unknown ResponseBytes type: ${this.responseBytes.responseType}`); //endregion + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = OCSPResponse; + +},{"./BasicOCSPResponse.js":13,"./ResponseBytes.js":91,"asn1js":112,"pvutils":113}],57:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _IssuerAndSerialNumber = _interopRequireDefault(require("./IssuerAndSerialNumber.js")); + +var _OriginatorPublicKey = _interopRequireDefault(require("./OriginatorPublicKey.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class OriginatorIdentifierOrKey { + //********************************************************************************** + + /** + * Constructor for OriginatorIdentifierOrKey class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc variant + */ + this.variant = (0, _pvutils.getParametersValue)(parameters, "variant", OriginatorIdentifierOrKey.defaultValues("variant")); + if ("value" in parameters) + /** + * @type {IssuerAndSerialNumber|OctetString|OriginatorPublicKey} + * @desc value + */ + this.value = (0, _pvutils.getParametersValue)(parameters, "value", OriginatorIdentifierOrKey.defaultValues("value")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "variant": + return -1; + + case "value": + return {}; + + default: + throw new Error(`Invalid member name for OriginatorIdentifierOrKey class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "variant": + return memberValue === -1; + + case "value": + return Object.keys(memberValue).length === 0; + + default: + throw new Error(`Invalid member name for OriginatorIdentifierOrKey class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * OriginatorIdentifierOrKey ::= CHOICE { + * issuerAndSerialNumber IssuerAndSerialNumber, + * subjectKeyIdentifier [0] SubjectKeyIdentifier, + * originatorKey [1] OriginatorPublicKey } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Choice({ + value: [_IssuerAndSerialNumber.default.schema({ + names: { + blockName: names.blockName || "" + } + }), new asn1js.Primitive({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + name: names.blockName || "" + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + name: names.blockName || "", + value: _OriginatorPublicKey.default.schema().valueBlock.value + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["blockName"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, OriginatorIdentifierOrKey.schema({ + names: { + blockName: "blockName" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for OriginatorIdentifierOrKey"); //endregion + //region Get internal properties from parsed schema + + if (asn1.result.blockName.idBlock.tagClass === 1) { + this.variant = 1; + this.value = new _IssuerAndSerialNumber.default({ + schema: asn1.result.blockName + }); + } else { + if (asn1.result.blockName.idBlock.tagNumber === 0) { + //region Create "OCTETSTRING" from "ASN1_PRIMITIVE" + asn1.result.blockName.idBlock.tagClass = 1; // UNIVERSAL + + asn1.result.blockName.idBlock.tagNumber = 4; // OCTETSTRING + //endregion + + this.variant = 2; + this.value = asn1.result.blockName; + } else { + this.variant = 3; + this.value = new _OriginatorPublicKey.default({ + schema: new asn1js.Sequence({ + value: asn1.result.blockName.valueBlock.value + }) + }); + } + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + switch (this.variant) { + case 1: + return this.value.toSchema(); + + case 2: + this.value.idBlock.tagClass = 3; // CONTEXT-SPECIFIC + + this.value.idBlock.tagNumber = 0; // [0] + + return this.value; + + case 3: + { + const _schema = this.value.toSchema(); + + _schema.idBlock.tagClass = 3; // CONTEXT-SPECIFIC + + _schema.idBlock.tagNumber = 1; // [1] + + return _schema; + } + + default: + return new asn1js.Any(); + } //endregion + + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + variant: this.variant + }; + if (this.variant === 1 || this.variant === 2 || this.variant === 3) _object.value = this.value.toJSON(); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = OriginatorIdentifierOrKey; + +},{"./IssuerAndSerialNumber.js":44,"./OriginatorPublicKey.js":59,"asn1js":112,"pvutils":113}],58:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _CertificateSet = _interopRequireDefault(require("./CertificateSet.js")); + +var _RevocationInfoChoices = _interopRequireDefault(require("./RevocationInfoChoices.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class OriginatorInfo { + //********************************************************************************** + + /** + * Constructor for OriginatorInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + if ("certs" in parameters) + /** + * @type {CertificateSet} + * @desc certs + */ + this.certs = (0, _pvutils.getParametersValue)(parameters, "certs", OriginatorInfo.defaultValues("certs")); + if ("crls" in parameters) + /** + * @type {RevocationInfoChoices} + * @desc crls + */ + this.crls = (0, _pvutils.getParametersValue)(parameters, "crls", OriginatorInfo.defaultValues("crls")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "certs": + return new _CertificateSet.default(); + + case "crls": + return new _RevocationInfoChoices.default(); + + default: + throw new Error(`Invalid member name for OriginatorInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "certs": + return memberValue.certificates.length === 0; + + case "crls": + return memberValue.crls.length === 0 && memberValue.otherRevocationInfos.length === 0; + + default: + throw new Error(`Invalid member name for OriginatorInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * OriginatorInfo ::= SEQUENCE { + * certs [0] IMPLICIT CertificateSet OPTIONAL, + * crls [1] IMPLICIT RevocationInfoChoices OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [certs] + * @property {string} [crls] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Constructed({ + name: names.certs || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: _CertificateSet.default.schema().valueBlock.value + }), new asn1js.Constructed({ + name: names.crls || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: _RevocationInfoChoices.default.schema().valueBlock.value + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["certs", "crls"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, OriginatorInfo.schema({ + names: { + certs: "certs", + crls: "crls" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for OriginatorInfo"); //endregion + //region Get internal properties from parsed schema + + if ("certs" in asn1.result) { + this.certs = new _CertificateSet.default({ + schema: new asn1js.Set({ + value: asn1.result.certs.valueBlock.value + }) + }); + } + + if ("crls" in asn1.result) { + this.crls = new _RevocationInfoChoices.default({ + schema: new asn1js.Set({ + value: asn1.result.crls.valueBlock.value + }) + }); + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + const sequenceValue = []; + + if ("certs" in this) { + sequenceValue.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: this.certs.toSchema().valueBlock.value + })); + } + + if ("crls" in this) { + sequenceValue.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: this.crls.toSchema().valueBlock.value + })); + } //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: sequenceValue + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = {}; + if ("certs" in this) object.certs = this.certs.toJSON(); + if ("crls" in this) object.crls = this.crls.toJSON(); + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = OriginatorInfo; + +},{"./CertificateSet.js":23,"./RevocationInfoChoices.js":93,"asn1js":112,"pvutils":113}],59:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class OriginatorPublicKey { + //********************************************************************************** + + /** + * Constructor for OriginatorPublicKey class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {AlgorithmIdentifier} + * @desc algorithm + */ + this.algorithm = (0, _pvutils.getParametersValue)(parameters, "algorithm", OriginatorPublicKey.defaultValues("algorithm")); + /** + * @type {BitString} + * @desc publicKey + */ + + this.publicKey = (0, _pvutils.getParametersValue)(parameters, "publicKey", OriginatorPublicKey.defaultValues("publicKey")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "algorithm": + return new _AlgorithmIdentifier.default(); + + case "publicKey": + return new asn1js.BitString(); + + default: + throw new Error(`Invalid member name for OriginatorPublicKey class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "algorithm": + case "publicKey": + return memberValue.isEqual(OriginatorPublicKey.defaultValues(memberName)); + + default: + throw new Error(`Invalid member name for OriginatorPublicKey class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * OriginatorPublicKey ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * publicKey BIT STRING } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [algorithm] + * @property {string} [publicKey] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_AlgorithmIdentifier.default.schema(names.algorithm || {}), new asn1js.BitString({ + name: names.publicKey || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["algorithm", "publicKey"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, OriginatorPublicKey.schema({ + names: { + algorithm: { + names: { + blockName: "algorithm" + } + }, + publicKey: "publicKey" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for OriginatorPublicKey"); //endregion + //region Get internal properties from parsed schema + + this.algorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.algorithm + }); + this.publicKey = asn1.result.publicKey; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [this.algorithm.toSchema(), this.publicKey] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + algorithm: this.algorithm.toJSON(), + publicKey: this.publicKey.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = OriginatorPublicKey; + +},{"./AlgorithmIdentifier.js":4,"asn1js":112,"pvutils":113}],60:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class OtherCertificateFormat { + //********************************************************************************** + + /** + * Constructor for OtherCertificateFormat class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc otherCertFormat + */ + this.otherCertFormat = (0, _pvutils.getParametersValue)(parameters, "otherCertFormat", OtherCertificateFormat.defaultValues("otherCertFormat")); + /** + * @type {Any} + * @desc otherCert + */ + + this.otherCert = (0, _pvutils.getParametersValue)(parameters, "otherCert", OtherCertificateFormat.defaultValues("otherCert")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "otherCertFormat": + return ""; + + case "otherCert": + return new asn1js.Any(); + + default: + throw new Error(`Invalid member name for OtherCertificateFormat class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * OtherCertificateFormat ::= SEQUENCE { + * otherCertFormat OBJECT IDENTIFIER, + * otherCert ANY DEFINED BY otherCertFormat } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [otherCertFormat] + * @property {string} [otherCert] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.otherCertFormat || "otherCertFormat" + }), new asn1js.Any({ + name: names.otherCert || "otherCert" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["otherCertFormat", "otherCert"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, OtherCertificateFormat.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for OtherCertificateFormat"); //endregion + //region Get internal properties from parsed schema + + this.otherCertFormat = asn1.result.otherCertFormat.valueBlock.toString(); + this.otherCert = asn1.result.otherCert; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [new asn1js.ObjectIdentifier({ + value: this.otherCertFormat + }), this.otherCert] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = { + otherCertFormat: this.otherCertFormat + }; + if (!(this.otherCert instanceof asn1js.Any)) object.otherCert = this.otherCert.toJSON(); + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = OtherCertificateFormat; + +},{"asn1js":112,"pvutils":113}],61:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class OtherKeyAttribute { + //********************************************************************************** + + /** + * Constructor for OtherKeyAttribute class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc keyAttrId + */ + this.keyAttrId = (0, _pvutils.getParametersValue)(parameters, "keyAttrId", OtherKeyAttribute.defaultValues("keyAttrId")); + if ("keyAttr" in parameters) + /** + * @type {*} + * @desc keyAttr + */ + this.keyAttr = (0, _pvutils.getParametersValue)(parameters, "keyAttr", OtherKeyAttribute.defaultValues("keyAttr")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "keyAttrId": + return ""; + + case "keyAttr": + return {}; + + default: + throw new Error(`Invalid member name for OtherKeyAttribute class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "keyAttrId": + return memberValue === ""; + + case "keyAttr": + return Object.keys(memberValue).length === 0; + + default: + throw new Error(`Invalid member name for OtherKeyAttribute class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * OtherKeyAttribute ::= SEQUENCE { + * keyAttrId OBJECT IDENTIFIER, + * keyAttr ANY DEFINED BY keyAttrId OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [optional] + * @property {string} [keyAttrId] + * @property {string} [keyAttr] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + optional: names.optional || true, + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.keyAttrId || "" + }), new asn1js.Any({ + optional: true, + name: names.keyAttr || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["keyAttrId", "keyAttr"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, OtherKeyAttribute.schema({ + names: { + keyAttrId: "keyAttrId", + keyAttr: "keyAttr" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for OtherKeyAttribute"); //endregion + //region Get internal properties from parsed schema + + this.keyAttrId = asn1.result.keyAttrId.valueBlock.toString(); + if ("keyAttr" in asn1.result) this.keyAttr = asn1.result.keyAttr; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(new asn1js.ObjectIdentifier({ + value: this.keyAttrId + })); + if ("keyAttr" in this) outputArray.push(this.keyAttr); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + keyAttrId: this.keyAttrId + }; + if ("keyAttr" in this) _object.keyAttr = this.keyAttr.toJSON(); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = OtherKeyAttribute; + +},{"asn1js":112,"pvutils":113}],62:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC3447 + */ +class OtherPrimeInfo { + //********************************************************************************** + + /** + * Constructor for OtherPrimeInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Integer} + * @desc prime + */ + this.prime = (0, _pvutils.getParametersValue)(parameters, "prime", OtherPrimeInfo.defaultValues("prime")); + /** + * @type {Integer} + * @desc exponent + */ + + this.exponent = (0, _pvutils.getParametersValue)(parameters, "exponent", OtherPrimeInfo.defaultValues("exponent")); + /** + * @type {Integer} + * @desc coefficient + */ + + this.coefficient = (0, _pvutils.getParametersValue)(parameters, "coefficient", OtherPrimeInfo.defaultValues("coefficient")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + //region If input argument array contains "json" for this object + + if ("json" in parameters) this.fromJSON(parameters.json); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "prime": + return new asn1js.Integer(); + + case "exponent": + return new asn1js.Integer(); + + case "coefficient": + return new asn1js.Integer(); + + default: + throw new Error(`Invalid member name for OtherPrimeInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * OtherPrimeInfo ::= Sequence { + * prime Integer, -- ri + * exponent Integer, -- di + * coefficient Integer -- ti + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} prime + * @property {string} exponent + * @property {string} coefficient + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.prime || "" + }), new asn1js.Integer({ + name: names.exponent || "" + }), new asn1js.Integer({ + name: names.coefficient || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["prime", "exponent", "coefficient"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, OtherPrimeInfo.schema({ + names: { + prime: "prime", + exponent: "exponent", + coefficient: "coefficient" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for OtherPrimeInfo"); //endregion + //region Get internal properties from parsed schema + + this.prime = asn1.result.prime.convertFromDER(); + this.exponent = asn1.result.exponent.convertFromDER(); + this.coefficient = asn1.result.coefficient.convertFromDER(); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [this.prime.convertToDER(), this.exponent.convertToDER(), this.coefficient.convertToDER()] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + r: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.prime.valueBlock.valueHex), true, true), + d: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.exponent.valueBlock.valueHex), true, true), + t: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.coefficient.valueBlock.valueHex), true, true) + }; + } //********************************************************************************** + + /** + * Convert JSON value into current object + * @param {Object} json + */ + + + fromJSON(json) { + if ("r" in json) this.prime = new asn1js.Integer({ + valueHex: (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.r, true)) + });else throw new Error("Absent mandatory parameter \"r\""); + if ("d" in json) this.exponent = new asn1js.Integer({ + valueHex: (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.d, true)) + });else throw new Error("Absent mandatory parameter \"d\""); + if ("t" in json) this.coefficient = new asn1js.Integer({ + valueHex: (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.t, true)) + });else throw new Error("Absent mandatory parameter \"t\""); + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = OtherPrimeInfo; + +},{"asn1js":112,"pvutils":113}],63:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class OtherRecipientInfo { + //********************************************************************************** + + /** + * Constructor for OtherRecipientInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc oriType + */ + this.oriType = (0, _pvutils.getParametersValue)(parameters, "oriType", OtherRecipientInfo.defaultValues("oriType")); + /** + * @type {*} + * @desc oriValue + */ + + this.oriValue = (0, _pvutils.getParametersValue)(parameters, "oriValue", OtherRecipientInfo.defaultValues("oriValue")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "oriType": + return ""; + + case "oriValue": + return {}; + + default: + throw new Error(`Invalid member name for OtherRecipientInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "oriType": + return memberValue === ""; + + case "oriValue": + return Object.keys(memberValue).length === 0; + + default: + throw new Error(`Invalid member name for OtherRecipientInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * OtherRecipientInfo ::= SEQUENCE { + * oriType OBJECT IDENTIFIER, + * oriValue ANY DEFINED BY oriType } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [oriType] + * @property {string} [oriValue] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.oriType || "" + }), new asn1js.Any({ + name: names.oriValue || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["oriType", "oriValue"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, OtherRecipientInfo.schema({ + names: { + oriType: "oriType", + oriValue: "oriValue" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for OtherRecipientInfo"); //endregion + //region Get internal properties from parsed schema + + this.oriType = asn1.result.oriType.valueBlock.toString(); + this.oriValue = asn1.result.oriValue; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [new asn1js.ObjectIdentifier({ + value: this.oriType + }), this.oriValue] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + oriType: this.oriType + }; + if (OtherRecipientInfo.compareWithDefault("oriValue", this.oriValue) === false) _object.oriValue = this.oriValue.toJSON(); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = OtherRecipientInfo; + +},{"asn1js":112,"pvutils":113}],64:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class OtherRevocationInfoFormat { + //********************************************************************************** + + /** + * Constructor for OtherRevocationInfoFormat class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc otherRevInfoFormat + */ + this.otherRevInfoFormat = (0, _pvutils.getParametersValue)(parameters, "otherRevInfoFormat", OtherRevocationInfoFormat.defaultValues("otherRevInfoFormat")); + /** + * @type {Any} + * @desc otherRevInfo + */ + + this.otherRevInfo = (0, _pvutils.getParametersValue)(parameters, "otherRevInfo", OtherRevocationInfoFormat.defaultValues("otherRevInfo")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "otherRevInfoFormat": + return ""; + + case "otherRevInfo": + return new asn1js.Any(); + + default: + throw new Error(`Invalid member name for OtherRevocationInfoFormat class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * OtherCertificateFormat ::= SEQUENCE { + * otherRevInfoFormat OBJECT IDENTIFIER, + * otherRevInfo ANY DEFINED BY otherCertFormat } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [otherRevInfoFormat] + * @property {string} [otherRevInfo] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.otherRevInfoFormat || "otherRevInfoFormat" + }), new asn1js.Any({ + name: names.otherRevInfo || "otherRevInfo" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["otherRevInfoFormat", "otherRevInfo"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, OtherRevocationInfoFormat.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for OtherRevocationInfoFormat"); //endregion + //region Get internal properties from parsed schema + + this.otherRevInfoFormat = asn1.result.otherRevInfoFormat.valueBlock.toString(); + this.otherRevInfo = asn1.result.otherRevInfo; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [new asn1js.ObjectIdentifier({ + value: this.otherRevInfoFormat + }), this.otherRevInfo] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = { + otherRevInfoFormat: this.otherRevInfoFormat + }; + if (!(this.otherRevInfo instanceof asn1js.Any)) object.otherRevInfo = this.otherRevInfo.toJSON(); + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = OtherRevocationInfoFormat; + +},{"asn1js":112,"pvutils":113}],65:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC2898 + */ +class PBES2Params { + //********************************************************************************** + + /** + * Constructor for PBES2Params class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {AlgorithmIdentifier} + * @desc keyDerivationFunc + */ + this.keyDerivationFunc = (0, _pvutils.getParametersValue)(parameters, "keyDerivationFunc", PBES2Params.defaultValues("keyDerivationFunc")); + /** + * @type {AlgorithmIdentifier} + * @desc encryptionScheme + */ + + this.encryptionScheme = (0, _pvutils.getParametersValue)(parameters, "encryptionScheme", PBES2Params.defaultValues("encryptionScheme")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "keyDerivationFunc": + return new _AlgorithmIdentifier.default(); + + case "encryptionScheme": + return new _AlgorithmIdentifier.default(); + + default: + throw new Error(`Invalid member name for PBES2Params class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * PBES2-params ::= SEQUENCE { + * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, + * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [keyDerivationFunc] + * @property {string} [encryptionScheme] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_AlgorithmIdentifier.default.schema(names.keyDerivationFunc || {}), _AlgorithmIdentifier.default.schema(names.encryptionScheme || {})] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["keyDerivationFunc", "encryptionScheme"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, PBES2Params.schema({ + names: { + keyDerivationFunc: { + names: { + blockName: "keyDerivationFunc" + } + }, + encryptionScheme: { + names: { + blockName: "encryptionScheme" + } + } + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for PBES2Params"); //endregion + //region Get internal properties from parsed schema + + this.keyDerivationFunc = new _AlgorithmIdentifier.default({ + schema: asn1.result.keyDerivationFunc + }); + this.encryptionScheme = new _AlgorithmIdentifier.default({ + schema: asn1.result.encryptionScheme + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [this.keyDerivationFunc.toSchema(), this.encryptionScheme.toSchema()] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + keyDerivationFunc: this.keyDerivationFunc.toJSON(), + encryptionScheme: this.encryptionScheme.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = PBES2Params; + +},{"./AlgorithmIdentifier.js":4,"asn1js":112,"pvutils":113}],66:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC2898 + */ +class PBKDF2Params { + //********************************************************************************** + + /** + * Constructor for PBKDF2Params class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Object} + * @desc salt + */ + this.salt = (0, _pvutils.getParametersValue)(parameters, "salt", PBKDF2Params.defaultValues("salt")); + /** + * @type {number} + * @desc iterationCount + */ + + this.iterationCount = (0, _pvutils.getParametersValue)(parameters, "iterationCount", PBKDF2Params.defaultValues("iterationCount")); + if ("keyLength" in parameters) + /** + * @type {number} + * @desc keyLength + */ + this.keyLength = (0, _pvutils.getParametersValue)(parameters, "keyLength", PBKDF2Params.defaultValues("keyLength")); + if ("prf" in parameters) + /** + * @type {AlgorithmIdentifier} + * @desc prf + */ + this.prf = (0, _pvutils.getParametersValue)(parameters, "prf", PBKDF2Params.defaultValues("prf")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "salt": + return {}; + + case "iterationCount": + return -1; + + case "keyLength": + return 0; + + case "prf": + return new _AlgorithmIdentifier.default({ + algorithmId: "1.3.14.3.2.26", + // SHA-1 + algorithmParams: new asn1js.Null() + }); + + default: + throw new Error(`Invalid member name for PBKDF2Params class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * PBKDF2-params ::= SEQUENCE { + * salt CHOICE { + * specified OCTET STRING, + * otherSource AlgorithmIdentifier }, + * iterationCount INTEGER (1..MAX), + * keyLength INTEGER (1..MAX) OPTIONAL, + * prf AlgorithmIdentifier + * DEFAULT { algorithm hMAC-SHA1, parameters NULL } } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [saltPrimitive] + * @property {string} [saltConstructed] + * @property {string} [iterationCount] + * @property {string} [keyLength] + * @property {string} [prf] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Choice({ + value: [new asn1js.OctetString({ + name: names.saltPrimitive || "" + }), _AlgorithmIdentifier.default.schema(names.saltConstructed || {})] + }), new asn1js.Integer({ + name: names.iterationCount || "" + }), new asn1js.Integer({ + name: names.keyLength || "", + optional: true + }), _AlgorithmIdentifier.default.schema(names.prf || { + names: { + optional: true + } + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["salt", "iterationCount", "keyLength", "prf"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, PBKDF2Params.schema({ + names: { + saltPrimitive: "salt", + saltConstructed: { + names: { + blockName: "salt" + } + }, + iterationCount: "iterationCount", + keyLength: "keyLength", + prf: { + names: { + blockName: "prf", + optional: true + } + } + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for PBKDF2Params"); //endregion + //region Get internal properties from parsed schema + + this.salt = asn1.result.salt; + this.iterationCount = asn1.result.iterationCount.valueBlock.valueDec; + if ("keyLength" in asn1.result) this.keyLength = asn1.result.keyLength.valueBlock.valueDec; + if ("prf" in asn1.result) this.prf = new _AlgorithmIdentifier.default({ + schema: asn1.result.prf + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(this.salt); + outputArray.push(new asn1js.Integer({ + value: this.iterationCount + })); + + if ("keyLength" in this) { + if (PBKDF2Params.defaultValues("keyLength") !== this.keyLength) outputArray.push(new asn1js.Integer({ + value: this.keyLength + })); + } + + if ("prf" in this) { + if (PBKDF2Params.defaultValues("prf").isEqual(this.prf) === false) outputArray.push(this.prf.toSchema()); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + salt: this.salt.toJSON(), + iterationCount: this.iterationCount + }; + + if ("keyLength" in this) { + if (PBKDF2Params.defaultValues("keyLength") !== this.keyLength) _object.keyLength = this.keyLength; + } + + if ("prf" in this) { + if (PBKDF2Params.defaultValues("prf").isEqual(this.prf) === false) _object.prf = this.prf.toJSON(); + } + + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = PBKDF2Params; + +},{"./AlgorithmIdentifier.js":4,"asn1js":112,"pvutils":113}],67:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _common = require("./common.js"); + +var _ContentInfo = _interopRequireDefault(require("./ContentInfo.js")); + +var _MacData = _interopRequireDefault(require("./MacData.js")); + +var _DigestInfo = _interopRequireDefault(require("./DigestInfo.js")); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _SignedData = _interopRequireDefault(require("./SignedData.js")); + +var _EncapsulatedContentInfo = _interopRequireDefault(require("./EncapsulatedContentInfo.js")); + +var _Attribute = _interopRequireDefault(require("./Attribute.js")); + +var _SignerInfo = _interopRequireDefault(require("./SignerInfo.js")); + +var _IssuerAndSerialNumber = _interopRequireDefault(require("./IssuerAndSerialNumber.js")); + +var _SignedAndUnsignedAttributes = _interopRequireDefault(require("./SignedAndUnsignedAttributes.js")); + +var _AuthenticatedSafe = _interopRequireDefault(require("./AuthenticatedSafe.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC7292 + */ +class PFX { + //********************************************************************************** + + /** + * Constructor for PFX class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", PFX.defaultValues("version")); + /** + * @type {ContentInfo} + * @desc authSafe + */ + + this.authSafe = (0, _pvutils.getParametersValue)(parameters, "authSafe", PFX.defaultValues("authSafe")); + if ("macData" in parameters) + /** + * @type {MacData} + * @desc macData + */ + this.macData = (0, _pvutils.getParametersValue)(parameters, "macData", PFX.defaultValues("macData")); + if ("parsedValue" in parameters) + /** + * @type {*} + * @desc parsedValue + */ + this.parsedValue = (0, _pvutils.getParametersValue)(parameters, "parsedValue", PFX.defaultValues("parsedValue")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 3; + + case "authSafe": + return new _ContentInfo.default(); + + case "macData": + return new _MacData.default(); + + case "parsedValue": + return {}; + + default: + throw new Error(`Invalid member name for PFX class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "version": + return memberValue === PFX.defaultValues(memberName); + + case "authSafe": + return _ContentInfo.default.compareWithDefault("contentType", memberValue.contentType) && _ContentInfo.default.compareWithDefault("content", memberValue.content); + + case "macData": + return _MacData.default.compareWithDefault("mac", memberValue.mac) && _MacData.default.compareWithDefault("macSalt", memberValue.macSalt) && _MacData.default.compareWithDefault("iterations", memberValue.iterations); + + case "parsedValue": + return memberValue instanceof Object && Object.keys(memberValue).length === 0; + + default: + throw new Error(`Invalid member name for PFX class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * PFX ::= SEQUENCE { + * version INTEGER {v3(3)}(v3,...), + * authSafe ContentInfo, + * macData MacData OPTIONAL + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [version] + * @property {string} [authSafe] + * @property {string} [macData] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.version || "version" + }), _ContentInfo.default.schema(names.authSafe || { + names: { + blockName: "authSafe" + } + }), _MacData.default.schema(names.macData || { + names: { + blockName: "macData", + optional: true + } + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["version", "authSafe", "macData"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, PFX.schema({ + names: { + version: "version", + authSafe: { + names: { + blockName: "authSafe" + } + }, + macData: { + names: { + blockName: "macData" + } + } + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for PFX"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result.version.valueBlock.valueDec; + this.authSafe = new _ContentInfo.default({ + schema: asn1.result.authSafe + }); + if ("macData" in asn1.result) this.macData = new _MacData.default({ + schema: asn1.result.macData + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + const outputArray = [new asn1js.Integer({ + value: this.version + }), this.authSafe.toSchema()]; + if ("macData" in this) outputArray.push(this.macData.toSchema()); + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const output = { + version: this.version, + authSafe: this.authSafe.toJSON() + }; + if ("macData" in this) output.macData = this.macData.toJSON(); + return output; + } //********************************************************************************** + + /** + * Making ContentInfo from "parsedValue" object + * @param {Object} parameters Parameters, specific to each "integrity mode" + */ + + + makeInternalValues(parameters = {}) { + //region Check mandatory parameter + if (parameters instanceof Object === false) return Promise.reject("The \"parameters\" must has \"Object\" type"); + if ("parsedValue" in this === false) return Promise.reject("Please call \"parseValues\" function first in order to make \"parsedValue\" data"); + if ("integrityMode" in this.parsedValue === false) return Promise.reject("Absent mandatory parameter \"integrityMode\" inside \"parsedValue\""); //endregion + //region Initial variables + + let sequence = Promise.resolve(); //endregion + //region Get a "crypto" extension + + const crypto = (0, _common.getCrypto)(); + if (typeof crypto === "undefined") return Promise.reject("Unable to create WebCrypto object"); //endregion + //region Makes values for each particular integrity mode + //region Check that we do have neccessary fields in "parsedValue" object + + if ("authenticatedSafe" in this.parsedValue === false) return Promise.reject("Absent mandatory parameter \"authenticatedSafe\" in \"parsedValue\""); //endregion + + switch (this.parsedValue.integrityMode) { + //region HMAC-based integrity + case 0: + { + //region Check additional mandatory parameters + if ("iterations" in parameters === false) return Promise.reject("Absent mandatory parameter \"iterations\""); + if ("pbkdf2HashAlgorithm" in parameters === false) return Promise.reject("Absent mandatory parameter \"pbkdf2HashAlgorithm\""); + if ("hmacHashAlgorithm" in parameters === false) return Promise.reject("Absent mandatory parameter \"hmacHashAlgorithm\""); + if ("password" in parameters === false) return Promise.reject("Absent mandatory parameter \"password\""); //endregion + //region Initial variables + + const saltBuffer = new ArrayBuffer(64); + const saltView = new Uint8Array(saltBuffer); + (0, _common.getRandomValues)(saltView); + const data = this.parsedValue.authenticatedSafe.toSchema().toBER(false); + this.authSafe = new _ContentInfo.default({ + contentType: "1.2.840.113549.1.7.1", + content: new asn1js.OctetString({ + valueHex: data + }) + }); //endregion + //region Call current crypto engine for making HMAC-based data stamp + + const engine = (0, _common.getEngine)(); + if ("stampDataWithPassword" in engine.subtle === false) return Promise.reject(`No support for "stampDataWithPassword" in current engine "${engine.name}"`); + sequence = sequence.then(() => engine.subtle.stampDataWithPassword({ + password: parameters.password, + hashAlgorithm: parameters.hmacHashAlgorithm, + salt: saltBuffer, + iterationCount: parameters.iterations, + contentToStamp: data + })); //endregion + //region Make "MacData" values + + sequence = sequence.then(result => { + this.macData = new _MacData.default({ + mac: new _DigestInfo.default({ + digestAlgorithm: new _AlgorithmIdentifier.default({ + algorithmId: (0, _common.getOIDByAlgorithm)({ + name: parameters.hmacHashAlgorithm + }) + }), + digest: new asn1js.OctetString({ + valueHex: result + }) + }), + macSalt: new asn1js.OctetString({ + valueHex: saltBuffer + }), + iterations: parameters.iterations + }); + }, error => Promise.reject(error)); //endregion + //endregion + } + break; + //endregion + //region publicKey-based integrity + + case 1: + { + //region Check additional mandatory parameters + if ("signingCertificate" in parameters === false) return Promise.reject("Absent mandatory parameter \"signingCertificate\""); + if ("privateKey" in parameters === false) return Promise.reject("Absent mandatory parameter \"privateKey\""); + if ("hashAlgorithm" in parameters === false) return Promise.reject("Absent mandatory parameter \"hashAlgorithm\""); //endregion + //region Making data to be signed + // NOTE: all internal data for "authenticatedSafe" must be already prepared. + // Thus user must call "makeValues" for all internal "SafeContent" value with appropriate parameters. + // Or user can choose to use values from initial parsing of existing PKCS#12 data. + + const toBeSigned = this.parsedValue.authenticatedSafe.toSchema().toBER(false); //endregion + //region Initial variables + + const cmsSigned = new _SignedData.default({ + version: 1, + encapContentInfo: new _EncapsulatedContentInfo.default({ + eContentType: "1.2.840.113549.1.7.1", + // "data" content type + eContent: new asn1js.OctetString({ + valueHex: toBeSigned + }) + }), + certificates: [parameters.signingCertificate] + }); //endregion + //region Making additional attributes for CMS Signed Data + //region Create a message digest + + sequence = sequence.then(() => crypto.digest({ + name: parameters.hashAlgorithm + }, new Uint8Array(toBeSigned))); //endregion + //region Combine all signed extensions + + sequence = sequence.then(result => { + //region Initial variables + const signedAttr = []; //endregion + //region contentType + + signedAttr.push(new _Attribute.default({ + type: "1.2.840.113549.1.9.3", + values: [new asn1js.ObjectIdentifier({ + value: "1.2.840.113549.1.7.1" + })] + })); //endregion + //region signingTime + + signedAttr.push(new _Attribute.default({ + type: "1.2.840.113549.1.9.5", + values: [new asn1js.UTCTime({ + valueDate: new Date() + })] + })); //endregion + //region messageDigest + + signedAttr.push(new _Attribute.default({ + type: "1.2.840.113549.1.9.4", + values: [new asn1js.OctetString({ + valueHex: result + })] + })); //endregion + //region Making final value for "SignerInfo" type + + cmsSigned.signerInfos.push(new _SignerInfo.default({ + version: 1, + sid: new _IssuerAndSerialNumber.default({ + issuer: parameters.signingCertificate.issuer, + serialNumber: parameters.signingCertificate.serialNumber + }), + signedAttrs: new _SignedAndUnsignedAttributes.default({ + type: 0, + attributes: signedAttr + }) + })); //endregion + }, error => Promise.reject(`Error during making digest for message: ${error}`)); //endregion + //endregion + //region Signing CMS Signed Data + + sequence = sequence.then(() => cmsSigned.sign(parameters.privateKey, 0, parameters.hashAlgorithm)); //endregion + //region Making final CMS_CONTENT_INFO type + + sequence = sequence.then(() => { + this.authSafe = new _ContentInfo.default({ + contentType: "1.2.840.113549.1.7.2", + content: cmsSigned.toSchema(true) + }); + }, error => Promise.reject(`Error during making signature: ${error}`)); //endregion + } + break; + //endregion + //region default + + default: + return Promise.reject(`Parameter "integrityMode" has unknown value: ${parameters.integrityMode}`); + //endregion + } //endregion + + + return sequence; + } //********************************************************************************** + + + parseInternalValues(parameters) { + //region Check input data from "parameters" + if (parameters instanceof Object === false) return Promise.reject("The \"parameters\" must has \"Object\" type"); + if ("checkIntegrity" in parameters === false) parameters.checkIntegrity = true; //endregion + //region Initial variables + + let sequence = Promise.resolve(); //endregion + //region Get a "crypto" extension + + const crypto = (0, _common.getCrypto)(); + if (typeof crypto === "undefined") return Promise.reject("Unable to create WebCrypto object"); //endregion + //region Create value for "this.parsedValue.authenticatedSafe" and check integrity + + this.parsedValue = {}; + + switch (this.authSafe.contentType) { + //region data + case "1.2.840.113549.1.7.1": + { + //region Check additional mandatory parameters + if ("password" in parameters === false) return Promise.reject("Absent mandatory parameter \"password\""); //endregion + //region Integrity based on HMAC + + this.parsedValue.integrityMode = 0; //endregion + //region Check that we do have OCTETSTRING as "content" + + if (this.authSafe.content instanceof asn1js.OctetString === false) return Promise.reject("Wrong type of \"this.authSafe.content\""); //endregion + //region Check we have "constructive encoding" for AuthSafe content + + let authSafeContent = new ArrayBuffer(0); + + if (this.authSafe.content.valueBlock.isConstructed) { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.authSafe.content.valueBlock.value[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + const contentValue = _step.value; + authSafeContent = (0, _pvutils.utilConcatBuf)(authSafeContent, contentValue.valueBlock.valueHex); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } else authSafeContent = this.authSafe.content.valueBlock.valueHex; //endregion + //region Parse internal ASN.1 data + + + const asn1 = asn1js.fromBER(authSafeContent); + if (asn1.offset === -1) return Promise.reject("Error during parsing of ASN.1 data inside \"this.authSafe.content\""); //endregion + //region Set "authenticatedSafe" value + + this.parsedValue.authenticatedSafe = new _AuthenticatedSafe.default({ + schema: asn1.result + }); //endregion + //region Check integrity + + if (parameters.checkIntegrity) { + //region Check that "MacData" exists + if ("macData" in this === false) return Promise.reject("Absent \"macData\" value, can not check PKCS#12 data integrity"); //endregion + //region Initial variables + + const hashAlgorithm = (0, _common.getAlgorithmByOID)(this.macData.mac.digestAlgorithm.algorithmId); + if ("name" in hashAlgorithm === false) return Promise.reject(`Unsupported digest algorithm: ${this.macData.mac.digestAlgorithm.algorithmId}`); //endregion + //region Call current crypto engine for verifying HMAC-based data stamp + + const engine = (0, _common.getEngine)(); + sequence = sequence.then(() => engine.subtle.verifyDataStampedWithPassword({ + password: parameters.password, + hashAlgorithm: hashAlgorithm.name, + salt: this.macData.macSalt.valueBlock.valueHex, + iterationCount: this.macData.iterations, + contentToVerify: authSafeContent, + signatureToVerify: this.macData.mac.digest.valueBlock.valueHex + })); //endregion + //region Verify HMAC signature + + sequence = sequence.then(result => { + if (result === false) return Promise.reject("Integrity for the PKCS#12 data is broken!"); + return Promise.resolve(); + }, error => Promise.reject(error)); //endregion + } //endregion + + } + break; + //endregion + //region signedData + + case "1.2.840.113549.1.7.2": + { + //region Integrity based on signature using public key + this.parsedValue.integrityMode = 1; //endregion + //region Parse CMS Signed Data + + const cmsSigned = new _SignedData.default({ + schema: this.authSafe.content + }); //endregion + //region Check that we do have OCTETSTRING as "content" + + if ("eContent" in cmsSigned.encapContentInfo === false) return Promise.reject("Absent of attached data in \"cmsSigned.encapContentInfo\""); + if (cmsSigned.encapContentInfo.eContent instanceof asn1js.OctetString === false) return Promise.reject("Wrong type of \"cmsSigned.encapContentInfo.eContent\""); //endregion + //region Create correct data block for verification + + let data = new ArrayBuffer(0); + if (cmsSigned.encapContentInfo.eContent.idBlock.isConstructed === false) data = cmsSigned.encapContentInfo.eContent.valueBlock.valueHex;else { + for (let i = 0; i < cmsSigned.encapContentInfo.eContent.valueBlock.value.length; i++) data = (0, _pvutils.utilConcatBuf)(data, cmsSigned.encapContentInfo.eContent.valueBlock.value[i].valueBlock.valueHex); + } //endregion + //region Parse internal ASN.1 data + + const asn1 = asn1js.fromBER(data); + if (asn1.offset === -1) return Promise.reject("Error during parsing of ASN.1 data inside \"this.authSafe.content\""); //endregion + //region Set "authenticatedSafe" value + + this.parsedValue.authenticatedSafe = new _AuthenticatedSafe.default({ + schema: asn1.result + }); //endregion + //region Check integrity + + sequence = sequence.then(() => cmsSigned.verify({ + signer: 0, + checkChain: false + })).then(result => { + if (result === false) return Promise.reject("Integrity for the PKCS#12 data is broken!"); + return Promise.resolve(); + }, error => Promise.reject(`Error during integrity verification: ${error}`)); //endregion + } + break; + //endregion + //region default + + default: + return Promise.reject(`Incorrect value for "this.authSafe.contentType": ${this.authSafe.contentType}`); + //endregion + } //endregion + //region Return result of the function + + + return sequence.then(() => this, error => Promise.reject(`Error during parsing: ${error}`)); //endregion + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = PFX; + +},{"./AlgorithmIdentifier.js":4,"./Attribute.js":6,"./AuthenticatedSafe.js":10,"./ContentInfo.js":26,"./DigestInfo.js":28,"./EncapsulatedContentInfo.js":33,"./IssuerAndSerialNumber.js":44,"./MacData.js":52,"./SignedAndUnsignedAttributes.js":99,"./SignedData.js":101,"./SignerInfo.js":102,"./common.js":110,"asn1js":112,"pvutils":113}],68:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _EncryptedData = _interopRequireDefault(require("./EncryptedData.js")); + +var _EncryptedContentInfo = _interopRequireDefault(require("./EncryptedContentInfo.js")); + +var _PrivateKeyInfo = _interopRequireDefault(require("./PrivateKeyInfo.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC7292 + */ +class PKCS8ShroudedKeyBag { + //********************************************************************************** + + /** + * Constructor for PKCS8ShroudedKeyBag class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {AlgorithmIdentifier} + * @desc encryptionAlgorithm + */ + this.encryptionAlgorithm = (0, _pvutils.getParametersValue)(parameters, "encryptionAlgorithm", PKCS8ShroudedKeyBag.defaultValues("encryptionAlgorithm")); + /** + * @type {OctetString} + * @desc encryptedData + */ + + this.encryptedData = (0, _pvutils.getParametersValue)(parameters, "encryptedData", PKCS8ShroudedKeyBag.defaultValues("encryptedData")); + if ("parsedValue" in parameters) + /** + * @type {*} + * @desc parsedValue + */ + this.parsedValue = (0, _pvutils.getParametersValue)(parameters, "parsedValue", PKCS8ShroudedKeyBag.defaultValues("parsedValue")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "encryptionAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "encryptedData": + return new asn1js.OctetString(); + + case "parsedValue": + return {}; + + default: + throw new Error(`Invalid member name for PKCS8ShroudedKeyBag class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "encryptionAlgorithm": + return _AlgorithmIdentifier.default.compareWithDefault("algorithmId", memberValue.algorithmId) && "algorithmParams" in memberValue === false; + + case "encryptedData": + return memberValue.isEqual(PKCS8ShroudedKeyBag.defaultValues(memberName)); + + case "parsedValue": + return memberValue instanceof Object && Object.keys(memberValue).length === 0; + + default: + throw new Error(`Invalid member name for PKCS8ShroudedKeyBag class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * PKCS8ShroudedKeyBag ::= EncryptedPrivateKeyInfo + * + * EncryptedPrivateKeyInfo ::= SEQUENCE { + * encryptionAlgorithm AlgorithmIdentifier {{KeyEncryptionAlgorithms}}, + * encryptedData EncryptedData + * } + * + * EncryptedData ::= OCTET STRING + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [encryptionAlgorithm] + * @property {string} [encryptedData] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_AlgorithmIdentifier.default.schema(names.encryptionAlgorithm || { + names: { + blockName: "encryptionAlgorithm" + } + }), new asn1js.Choice({ + value: [new asn1js.OctetString({ + name: names.encryptedData || "encryptedData" + }), new asn1js.OctetString({ + idBlock: { + isConstructed: true + }, + name: names.encryptedData || "encryptedData" + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["encryptionAlgorithm", "encryptedData"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, PKCS8ShroudedKeyBag.schema({ + names: { + encryptionAlgorithm: { + names: { + blockName: "encryptionAlgorithm" + } + }, + encryptedData: "encryptedData" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for PKCS8ShroudedKeyBag"); //endregion + //region Get internal properties from parsed schema + + this.encryptionAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.encryptionAlgorithm + }); + this.encryptedData = asn1.result.encryptedData; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [this.encryptionAlgorithm.toSchema(), this.encryptedData] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + encryptionAlgorithm: this.encryptionAlgorithm.toJSON(), + encryptedData: this.encryptedData.toJSON() + }; + } //********************************************************************************** + + + parseInternalValues(parameters) { + //region Initial variables + let sequence = Promise.resolve(); + const cmsEncrypted = new _EncryptedData.default({ + encryptedContentInfo: new _EncryptedContentInfo.default({ + contentEncryptionAlgorithm: this.encryptionAlgorithm, + encryptedContent: this.encryptedData + }) + }); //endregion + //region Decrypt internal data + + sequence = sequence.then(() => cmsEncrypted.decrypt(parameters), error => Promise.reject(error)); //endregion + //region Initialize "parsedValue" with decrypted PKCS#8 private key + + sequence = sequence.then( + /** + * @param {ArrayBuffer} result + */ + result => { + const asn1 = asn1js.fromBER(result); + if (asn1.offset === -1) return Promise.reject("Error during parsing ASN.1 data"); + this.parsedValue = new _PrivateKeyInfo.default({ + schema: asn1.result + }); + return Promise.resolve(); + }, error => Promise.reject(error)); //endregion + + return sequence; + } //********************************************************************************** + + + makeInternalValues(parameters) { + //region Check that we do have "parsedValue" + if ("parsedValue" in this === false) return Promise.reject("Please initialize \"parsedValue\" first"); //endregion + //region Initial variables + + let sequence = Promise.resolve(); + const cmsEncrypted = new _EncryptedData.default(); //endregion + //region Encrypt internal data + + sequence = sequence.then(() => { + parameters.contentToEncrypt = this.parsedValue.toSchema().toBER(false); + return cmsEncrypted.encrypt(parameters); + }, error => Promise.reject(error)); //endregion + //region Initialize internal values + + sequence = sequence.then(() => { + this.encryptionAlgorithm = cmsEncrypted.encryptedContentInfo.contentEncryptionAlgorithm; + this.encryptedData = cmsEncrypted.encryptedContentInfo.encryptedContent; + }); //endregion + + return sequence; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = PKCS8ShroudedKeyBag; + +},{"./AlgorithmIdentifier.js":4,"./EncryptedContentInfo.js":34,"./EncryptedData.js":35,"./PrivateKeyInfo.js":76,"asn1js":112,"pvutils":113}],69:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC3161 + */ +class PKIStatusInfo { + //********************************************************************************** + + /** + * Constructor for PKIStatusInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc status + */ + this.status = (0, _pvutils.getParametersValue)(parameters, "status", PKIStatusInfo.defaultValues("status")); + if ("statusStrings" in parameters) + /** + * @type {Array.} + * @desc statusStrings + */ + this.statusStrings = (0, _pvutils.getParametersValue)(parameters, "statusStrings", PKIStatusInfo.defaultValues("statusStrings")); + if ("failInfo" in parameters) + /** + * @type {BitString} + * @desc failInfo + */ + this.failInfo = (0, _pvutils.getParametersValue)(parameters, "failInfo", PKIStatusInfo.defaultValues("failInfo")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "status": + return 2; + + case "statusStrings": + return []; + + case "failInfo": + return new asn1js.BitString(); + + default: + throw new Error(`Invalid member name for PKIStatusInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "status": + return memberValue === PKIStatusInfo.defaultValues(memberName); + + case "statusStrings": + return memberValue.length === 0; + + case "failInfo": + return memberValue.isEqual(PKIStatusInfo.defaultValues(memberName)); + + default: + throw new Error(`Invalid member name for PKIStatusInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * PKIStatusInfo ::= SEQUENCE { + * status PKIStatus, + * statusString PKIFreeText OPTIONAL, + * failInfo PKIFailureInfo OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [status] + * @property {string} [statusStrings] + * @property {string} [failInfo] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.status || "" + }), new asn1js.Sequence({ + optional: true, + value: [new asn1js.Repeated({ + name: names.statusStrings || "", + value: new asn1js.Utf8String() + })] + }), new asn1js.BitString({ + name: names.failInfo || "", + optional: true + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["status", "statusStrings", "failInfo"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, PKIStatusInfo.schema({ + names: { + status: "status", + statusStrings: "statusStrings", + failInfo: "failInfo" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for PKIStatusInfo"); //endregion + //region Get internal properties from parsed schema + + const _status = asn1.result.status; + if (_status.valueBlock.isHexOnly === true || _status.valueBlock.valueDec < 0 || _status.valueBlock.valueDec > 5) throw new Error("PKIStatusInfo \"status\" has invalid value"); + this.status = _status.valueBlock.valueDec; + if ("statusStrings" in asn1.result) this.statusStrings = asn1.result.statusStrings; + if ("failInfo" in asn1.result) this.failInfo = asn1.result.failInfo; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array of output sequence + const outputArray = []; + outputArray.push(new asn1js.Integer({ + value: this.status + })); + + if ("statusStrings" in this) { + outputArray.push(new asn1js.Sequence({ + optional: true, + value: this.statusStrings + })); + } + + if ("failInfo" in this) outputArray.push(this.failInfo); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + status: this.status + }; + if ("statusStrings" in this) _object.statusStrings = Array.from(this.statusStrings, element => element.toJSON()); + if ("failInfo" in this) _object.failInfo = this.failInfo.toJSON(); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = PKIStatusInfo; + +},{"asn1js":112,"pvutils":113}],70:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class PasswordRecipientinfo { + //********************************************************************************** + + /** + * Constructor for PasswordRecipientinfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", PasswordRecipientinfo.defaultValues("version")); + if ("keyDerivationAlgorithm" in parameters) + /** + * @type {AlgorithmIdentifier} + * @desc keyDerivationAlgorithm + */ + this.keyDerivationAlgorithm = (0, _pvutils.getParametersValue)(parameters, "keyDerivationAlgorithm", PasswordRecipientinfo.defaultValues("keyDerivationAlgorithm")); + /** + * @type {AlgorithmIdentifier} + * @desc keyEncryptionAlgorithm + */ + + this.keyEncryptionAlgorithm = (0, _pvutils.getParametersValue)(parameters, "keyEncryptionAlgorithm", PasswordRecipientinfo.defaultValues("keyEncryptionAlgorithm")); + /** + * @type {OctetString} + * @desc encryptedKey + */ + + this.encryptedKey = (0, _pvutils.getParametersValue)(parameters, "encryptedKey", PasswordRecipientinfo.defaultValues("encryptedKey")); + /** + * @type {ArrayBuffer} + * @desc password Password to derive key from + */ + + this.password = (0, _pvutils.getParametersValue)(parameters, "password", PasswordRecipientinfo.defaultValues("password")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return -1; + + case "keyDerivationAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "keyEncryptionAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "encryptedKey": + return new asn1js.OctetString(); + + case "password": + return new ArrayBuffer(0); + + default: + throw new Error(`Invalid member name for PasswordRecipientinfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "version": + return memberValue === -1; + + case "keyDerivationAlgorithm": + case "keyEncryptionAlgorithm": + return memberValue.algorithmId === "" && "algorithmParams" in memberValue === false; + + case "encryptedKey": + return memberValue.isEqual(PasswordRecipientinfo.defaultValues("encryptedKey")); + + case "password": + return memberValue.byteLength === 0; + + default: + throw new Error(`Invalid member name for PasswordRecipientinfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * PasswordRecipientInfo ::= SEQUENCE { + * version CMSVersion, -- Always set to 0 + * keyDerivationAlgorithm [0] KeyDerivationAlgorithmIdentifier OPTIONAL, + * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, + * encryptedKey EncryptedKey } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [keyDerivationAlgorithm] + * @property {string} [keyEncryptionAlgorithm] + * @property {string} [encryptedKey] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.version || "" + }), new asn1js.Constructed({ + name: names.keyDerivationAlgorithm || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: _AlgorithmIdentifier.default.schema().valueBlock.value + }), _AlgorithmIdentifier.default.schema(names.keyEncryptionAlgorithm || {}), new asn1js.OctetString({ + name: names.encryptedKey || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["version", "keyDerivationAlgorithm", "keyEncryptionAlgorithm", "encryptedKey"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, PasswordRecipientinfo.schema({ + names: { + version: "version", + keyDerivationAlgorithm: "keyDerivationAlgorithm", + keyEncryptionAlgorithm: { + names: { + blockName: "keyEncryptionAlgorithm" + } + }, + encryptedKey: "encryptedKey" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for PasswordRecipientinfo"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result.version.valueBlock.valueDec; + + if ("keyDerivationAlgorithm" in asn1.result) { + this.keyDerivationAlgorithm = new _AlgorithmIdentifier.default({ + schema: new asn1js.Sequence({ + value: asn1.result.keyDerivationAlgorithm.valueBlock.value + }) + }); + } + + this.keyEncryptionAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.keyEncryptionAlgorithm + }); + this.encryptedKey = asn1.result.encryptedKey; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create output array for sequence + const outputArray = []; + outputArray.push(new asn1js.Integer({ + value: this.version + })); + + if ("keyDerivationAlgorithm" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: this.keyDerivationAlgorithm.toSchema().valueBlock.value + })); + } + + outputArray.push(this.keyEncryptionAlgorithm.toSchema()); + outputArray.push(this.encryptedKey); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + version: this.version, + keyDerivationAlgorithm: this.keyDerivationAlgorithm.toJSON(), + keyEncryptionAlgorithm: this.keyEncryptionAlgorithm.toJSON(), + encryptedKey: this.encryptedKey.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = PasswordRecipientinfo; + +},{"./AlgorithmIdentifier.js":4,"asn1js":112,"pvutils":113}],71:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class PolicyConstraints { + //********************************************************************************** + + /** + * Constructor for PolicyConstraints class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + if ("requireExplicitPolicy" in parameters) + /** + * @type {number} + * @desc requireExplicitPolicy + */ + this.requireExplicitPolicy = (0, _pvutils.getParametersValue)(parameters, "requireExplicitPolicy", PolicyConstraints.defaultValues("requireExplicitPolicy")); + if ("inhibitPolicyMapping" in parameters) + /** + * @type {number} + * @desc Value of the TIME class + */ + this.inhibitPolicyMapping = (0, _pvutils.getParametersValue)(parameters, "inhibitPolicyMapping", PolicyConstraints.defaultValues("inhibitPolicyMapping")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "requireExplicitPolicy": + return 0; + + case "inhibitPolicyMapping": + return 0; + + default: + throw new Error(`Invalid member name for PolicyConstraints class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * PolicyConstraints ::= SEQUENCE { + * requireExplicitPolicy [0] SkipCerts OPTIONAL, + * inhibitPolicyMapping [1] SkipCerts OPTIONAL } + * + * SkipCerts ::= INTEGER (0..MAX) + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [requireExplicitPolicy] + * @property {string} [inhibitPolicyMapping] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Primitive({ + name: names.requireExplicitPolicy || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + } + }), // IMPLICIT integer value + new asn1js.Primitive({ + name: names.inhibitPolicyMapping || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + } + }) // IMPLICIT integer value + ] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["requireExplicitPolicy", "inhibitPolicyMapping"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, PolicyConstraints.schema({ + names: { + requireExplicitPolicy: "requireExplicitPolicy", + inhibitPolicyMapping: "inhibitPolicyMapping" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for PolicyConstraints"); //endregion + //region Get internal properties from parsed schema + + if ("requireExplicitPolicy" in asn1.result) { + const field1 = asn1.result.requireExplicitPolicy; + field1.idBlock.tagClass = 1; // UNIVERSAL + + field1.idBlock.tagNumber = 2; // INTEGER + + const ber1 = field1.toBER(false); + const int1 = asn1js.fromBER(ber1); + this.requireExplicitPolicy = int1.result.valueBlock.valueDec; + } + + if ("inhibitPolicyMapping" in asn1.result) { + const field2 = asn1.result.inhibitPolicyMapping; + field2.idBlock.tagClass = 1; // UNIVERSAL + + field2.idBlock.tagNumber = 2; // INTEGER + + const ber2 = field2.toBER(false); + const int2 = asn1js.fromBER(ber2); + this.inhibitPolicyMapping = int2.result.valueBlock.valueDec; + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create correct values for output sequence + const outputArray = []; + + if ("requireExplicitPolicy" in this) { + const int1 = new asn1js.Integer({ + value: this.requireExplicitPolicy + }); + int1.idBlock.tagClass = 3; // CONTEXT-SPECIFIC + + int1.idBlock.tagNumber = 0; // [0] + + outputArray.push(int1); + } + + if ("inhibitPolicyMapping" in this) { + const int2 = new asn1js.Integer({ + value: this.inhibitPolicyMapping + }); + int2.idBlock.tagClass = 3; // CONTEXT-SPECIFIC + + int2.idBlock.tagNumber = 1; // [1] + + outputArray.push(int2); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = {}; + if ("requireExplicitPolicy" in this) object.requireExplicitPolicy = this.requireExplicitPolicy; + if ("inhibitPolicyMapping" in this) object.inhibitPolicyMapping = this.inhibitPolicyMapping; + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = PolicyConstraints; + +},{"asn1js":112,"pvutils":113}],72:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _PolicyQualifierInfo = _interopRequireDefault(require("./PolicyQualifierInfo.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class PolicyInformation { + //********************************************************************************** + + /** + * Constructor for PolicyInformation class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc policyIdentifier + */ + this.policyIdentifier = (0, _pvutils.getParametersValue)(parameters, "policyIdentifier", PolicyInformation.defaultValues("policyIdentifier")); + if ("policyQualifiers" in parameters) + /** + * @type {Array.} + * @desc Value of the TIME class + */ + this.policyQualifiers = (0, _pvutils.getParametersValue)(parameters, "policyQualifiers", PolicyInformation.defaultValues("policyQualifiers")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "policyIdentifier": + return ""; + + case "policyQualifiers": + return []; + + default: + throw new Error(`Invalid member name for PolicyInformation class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * PolicyInformation ::= SEQUENCE { + * policyIdentifier CertPolicyId, + * policyQualifiers SEQUENCE SIZE (1..MAX) OF + * PolicyQualifierInfo OPTIONAL } + * + * CertPolicyId ::= OBJECT IDENTIFIER + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [policyIdentifier] + * @property {string} [policyQualifiers] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.policyIdentifier || "" + }), new asn1js.Sequence({ + optional: true, + value: [new asn1js.Repeated({ + name: names.policyQualifiers || "", + value: _PolicyQualifierInfo.default.schema() + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["policyIdentifier", "policyQualifiers"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, PolicyInformation.schema({ + names: { + policyIdentifier: "policyIdentifier", + policyQualifiers: "policyQualifiers" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for PolicyInformation"); //endregion + //region Get internal properties from parsed schema + + this.policyIdentifier = asn1.result.policyIdentifier.valueBlock.toString(); + if ("policyQualifiers" in asn1.result) this.policyQualifiers = Array.from(asn1.result.policyQualifiers, element => new _PolicyQualifierInfo.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(new asn1js.ObjectIdentifier({ + value: this.policyIdentifier + })); + + if ("policyQualifiers" in this) { + outputArray.push(new asn1js.Sequence({ + value: Array.from(this.policyQualifiers, element => element.toSchema()) + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = { + policyIdentifier: this.policyIdentifier + }; + if ("policyQualifiers" in this) object.policyQualifiers = Array.from(this.policyQualifiers, element => element.toJSON()); + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = PolicyInformation; + +},{"./PolicyQualifierInfo.js":75,"asn1js":112,"pvutils":113}],73:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class PolicyMapping { + //********************************************************************************** + + /** + * Constructor for PolicyMapping class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc issuerDomainPolicy + */ + this.issuerDomainPolicy = (0, _pvutils.getParametersValue)(parameters, "issuerDomainPolicy", PolicyMapping.defaultValues("issuerDomainPolicy")); + /** + * @type {string} + * @desc subjectDomainPolicy + */ + + this.subjectDomainPolicy = (0, _pvutils.getParametersValue)(parameters, "subjectDomainPolicy", PolicyMapping.defaultValues("subjectDomainPolicy")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "issuerDomainPolicy": + return ""; + + case "subjectDomainPolicy": + return ""; + + default: + throw new Error(`Invalid member name for PolicyMapping class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * PolicyMapping ::= SEQUENCE { + * issuerDomainPolicy CertPolicyId, + * subjectDomainPolicy CertPolicyId } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [issuerDomainPolicy] + * @property {string} [subjectDomainPolicy] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.issuerDomainPolicy || "" + }), new asn1js.ObjectIdentifier({ + name: names.subjectDomainPolicy || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["issuerDomainPolicy", "subjectDomainPolicy"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, PolicyMapping.schema({ + names: { + issuerDomainPolicy: "issuerDomainPolicy", + subjectDomainPolicy: "subjectDomainPolicy" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for PolicyMapping"); //endregion + //region Get internal properties from parsed schema + + this.issuerDomainPolicy = asn1.result.issuerDomainPolicy.valueBlock.toString(); + this.subjectDomainPolicy = asn1.result.subjectDomainPolicy.valueBlock.toString(); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [new asn1js.ObjectIdentifier({ + value: this.issuerDomainPolicy + }), new asn1js.ObjectIdentifier({ + value: this.subjectDomainPolicy + })] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + issuerDomainPolicy: this.issuerDomainPolicy, + subjectDomainPolicy: this.subjectDomainPolicy + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = PolicyMapping; + +},{"asn1js":112,"pvutils":113}],74:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _PolicyMapping = _interopRequireDefault(require("./PolicyMapping.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class PolicyMappings { + //********************************************************************************** + + /** + * Constructor for PolicyMappings class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc mappings + */ + this.mappings = (0, _pvutils.getParametersValue)(parameters, "mappings", PolicyMappings.defaultValues("mappings")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "mappings": + return []; + + default: + throw new Error(`Invalid member name for PolicyMappings class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF PolicyMapping + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [utcTimeName] Name for "utcTimeName" choice + * @property {string} [generalTimeName] Name for "generalTimeName" choice + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.mappings || "", + value: _PolicyMapping.default.schema() + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["mappings"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, PolicyMappings.schema({ + names: { + mappings: "mappings" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for PolicyMappings"); //endregion + //region Get internal properties from parsed schema + + this.mappings = Array.from(asn1.result.mappings, element => new _PolicyMapping.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: Array.from(this.mappings, element => element.toSchema()) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + mappings: Array.from(this.mappings, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = PolicyMappings; + +},{"./PolicyMapping.js":73,"asn1js":112,"pvutils":113}],75:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class PolicyQualifierInfo { + //********************************************************************************** + + /** + * Constructor for PolicyQualifierInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc policyQualifierId + */ + this.policyQualifierId = (0, _pvutils.getParametersValue)(parameters, "policyQualifierId", PolicyQualifierInfo.defaultValues("policyQualifierId")); + /** + * @type {Object} + * @desc qualifier + */ + + this.qualifier = (0, _pvutils.getParametersValue)(parameters, "qualifier", PolicyQualifierInfo.defaultValues("qualifier")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "policyQualifierId": + return ""; + + case "qualifier": + return new asn1js.Any(); + + default: + throw new Error(`Invalid member name for PolicyQualifierInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * PolicyQualifierInfo ::= SEQUENCE { + * policyQualifierId PolicyQualifierId, + * qualifier ANY DEFINED BY policyQualifierId } + * + * id-qt OBJECT IDENTIFIER ::= { id-pkix 2 } + * id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 } + * id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 } + * + * PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice ) + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [policyQualifierId] + * @property {string} [qualifier] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.policyQualifierId || "" + }), new asn1js.Any({ + name: names.qualifier || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["policyQualifierId", "qualifier"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, PolicyQualifierInfo.schema({ + names: { + policyQualifierId: "policyQualifierId", + qualifier: "qualifier" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for PolicyQualifierInfo"); //endregion + //region Get internal properties from parsed schema + + this.policyQualifierId = asn1.result.policyQualifierId.valueBlock.toString(); + this.qualifier = asn1.result.qualifier; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [new asn1js.ObjectIdentifier({ + value: this.policyQualifierId + }), this.qualifier] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + policyQualifierId: this.policyQualifierId, + qualifier: this.qualifier.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = PolicyQualifierInfo; + +},{"asn1js":112,"pvutils":113}],76:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _Attribute = _interopRequireDefault(require("./Attribute.js")); + +var _ECPrivateKey = _interopRequireDefault(require("./ECPrivateKey.js")); + +var _RSAPrivateKey = _interopRequireDefault(require("./RSAPrivateKey.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5208 + */ +class PrivateKeyInfo { + //********************************************************************************** + + /** + * Constructor for PrivateKeyInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", PrivateKeyInfo.defaultValues("version")); + /** + * @type {AlgorithmIdentifier} + * @desc privateKeyAlgorithm + */ + + this.privateKeyAlgorithm = (0, _pvutils.getParametersValue)(parameters, "privateKeyAlgorithm", PrivateKeyInfo.defaultValues("privateKeyAlgorithm")); + /** + * @type {OctetString} + * @desc privateKey + */ + + this.privateKey = (0, _pvutils.getParametersValue)(parameters, "privateKey", PrivateKeyInfo.defaultValues("privateKey")); + if ("attributes" in parameters) + /** + * @type {Array.} + * @desc attributes + */ + this.attributes = (0, _pvutils.getParametersValue)(parameters, "attributes", PrivateKeyInfo.defaultValues("attributes")); + if ("parsedKey" in parameters) + /** + * @type {ECPrivateKey|RSAPrivateKey} + * @desc Parsed public key value + */ + this.parsedKey = (0, _pvutils.getParametersValue)(parameters, "parsedKey", PrivateKeyInfo.defaultValues("parsedKey")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + //region If input argument array contains "json" for this object + + if ("json" in parameters) this.fromJSON(parameters.json); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 0; + + case "privateKeyAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "privateKey": + return new asn1js.OctetString(); + + case "attributes": + return []; + + case "parsedKey": + return {}; + + default: + throw new Error(`Invalid member name for PrivateKeyInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * PrivateKeyInfo ::= SEQUENCE { + * version Version, + * privateKeyAlgorithm AlgorithmIdentifier {{PrivateKeyAlgorithms}}, + * privateKey PrivateKey, + * attributes [0] Attributes OPTIONAL } + * + * Version ::= INTEGER {v1(0)} (v1,...) + * + * PrivateKey ::= OCTET STRING + * + * Attributes ::= SET OF Attribute + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [version] + * @property {string} [privateKeyAlgorithm] + * @property {string} [privateKey] + * @property {string} [attributes] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.version || "" + }), _AlgorithmIdentifier.default.schema(names.privateKeyAlgorithm || {}), new asn1js.OctetString({ + name: names.privateKey || "" + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Repeated({ + name: names.attributes || "", + value: _Attribute.default.schema() + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["version", "privateKeyAlgorithm", "privateKey", "attributes"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, PrivateKeyInfo.schema({ + names: { + version: "version", + privateKeyAlgorithm: { + names: { + blockName: "privateKeyAlgorithm" + } + }, + privateKey: "privateKey", + attributes: "attributes" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for PrivateKeyInfo"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result.version.valueBlock.valueDec; + this.privateKeyAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.privateKeyAlgorithm + }); + this.privateKey = asn1.result.privateKey; + if ("attributes" in asn1.result) this.attributes = Array.from(asn1.result.attributes, element => new _Attribute.default({ + schema: element + })); + + switch (this.privateKeyAlgorithm.algorithmId) { + case "1.2.840.113549.1.1.1": + // RSA + { + const privateKeyASN1 = asn1js.fromBER(this.privateKey.valueBlock.valueHex); + if (privateKeyASN1.offset !== -1) this.parsedKey = new _RSAPrivateKey.default({ + schema: privateKeyASN1.result + }); + } + break; + + case "1.2.840.10045.2.1": + // ECDSA + if ("algorithmParams" in this.privateKeyAlgorithm) { + if (this.privateKeyAlgorithm.algorithmParams instanceof asn1js.ObjectIdentifier) { + const privateKeyASN1 = asn1js.fromBER(this.privateKey.valueBlock.valueHex); + + if (privateKeyASN1.offset !== -1) { + this.parsedKey = new _ECPrivateKey.default({ + namedCurve: this.privateKeyAlgorithm.algorithmParams.valueBlock.toString(), + schema: privateKeyASN1.result + }); + } + } + } + + break; + + default: + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = [new asn1js.Integer({ + value: this.version + }), this.privateKeyAlgorithm.toSchema(), this.privateKey]; + + if ("attributes" in this) { + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: Array.from(this.attributes, element => element.toSchema()) + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + //region Return common value in case we do not have enough info fo making JWK + if ("parsedKey" in this === false) { + const object = { + version: this.version, + privateKeyAlgorithm: this.privateKeyAlgorithm.toJSON(), + privateKey: this.privateKey.toJSON() + }; + if ("attributes" in this) object.attributes = Array.from(this.attributes, element => element.toJSON()); + return object; + } //endregion + //region Making JWK + + + const jwk = {}; + + switch (this.privateKeyAlgorithm.algorithmId) { + case "1.2.840.10045.2.1": + // ECDSA + jwk.kty = "EC"; + break; + + case "1.2.840.113549.1.1.1": + // RSA + jwk.kty = "RSA"; + break; + + default: + } + + const publicKeyJWK = this.parsedKey.toJSON(); + + for (var _i = 0, _Object$keys = Object.keys(publicKeyJWK); _i < _Object$keys.length; _i++) { + const key = _Object$keys[_i]; + jwk[key] = publicKeyJWK[key]; + } + + return jwk; //endregion + } //********************************************************************************** + + /** + * Convert JSON value into current object + * @param {Object} json + */ + + + fromJSON(json) { + if ("kty" in json) { + switch (json.kty.toUpperCase()) { + case "EC": + this.parsedKey = new _ECPrivateKey.default({ + json + }); + this.privateKeyAlgorithm = new _AlgorithmIdentifier.default({ + algorithmId: "1.2.840.10045.2.1", + algorithmParams: new asn1js.ObjectIdentifier({ + value: this.parsedKey.namedCurve + }) + }); + break; + + case "RSA": + this.parsedKey = new _RSAPrivateKey.default({ + json + }); + this.privateKeyAlgorithm = new _AlgorithmIdentifier.default({ + algorithmId: "1.2.840.113549.1.1.1", + algorithmParams: new asn1js.Null() + }); + break; + + default: + throw new Error(`Invalid value for "kty" parameter: ${json.kty}`); + } + + this.privateKey = new asn1js.OctetString({ + valueHex: this.parsedKey.toSchema().toBER(false) + }); + } + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = PrivateKeyInfo; + +},{"./AlgorithmIdentifier.js":4,"./Attribute.js":6,"./ECPrivateKey.js":31,"./RSAPrivateKey.js":81,"asn1js":112,"pvutils":113}],77:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class PrivateKeyUsagePeriod { + //********************************************************************************** + + /** + * Constructor for PrivateKeyUsagePeriod class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + if ("notBefore" in parameters) + /** + * @type {Date} + * @desc notBefore + */ + this.notBefore = (0, _pvutils.getParametersValue)(parameters, "notBefore", PrivateKeyUsagePeriod.defaultValues("notBefore")); + if ("notAfter" in parameters) + /** + * @type {Date} + * @desc notAfter + */ + this.notAfter = (0, _pvutils.getParametersValue)(parameters, "notAfter", PrivateKeyUsagePeriod.defaultValues("notAfter")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "notBefore": + return new Date(); + + case "notAfter": + return new Date(); + + default: + throw new Error(`Invalid member name for PrivateKeyUsagePeriod class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * PrivateKeyUsagePeriod OID ::= 2.5.29.16 + * + * PrivateKeyUsagePeriod ::= SEQUENCE { + * notBefore [0] GeneralizedTime OPTIONAL, + * notAfter [1] GeneralizedTime OPTIONAL } + * -- either notBefore or notAfter MUST be present + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [notBefore] + * @property {string} [notAfter] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Primitive({ + name: names.notBefore || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + } + }), new asn1js.Primitive({ + name: names.notAfter || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + } + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["notBefore", "notAfter"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, PrivateKeyUsagePeriod.schema({ + names: { + notBefore: "notBefore", + notAfter: "notAfter" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for PrivateKeyUsagePeriod"); //endregion + //region Get internal properties from parsed schema + + if ("notBefore" in asn1.result) { + const localNotBefore = new asn1js.GeneralizedTime(); + localNotBefore.fromBuffer(asn1.result.notBefore.valueBlock.valueHex); + this.notBefore = localNotBefore.toDate(); + } + + if ("notAfter" in asn1.result) { + const localNotAfter = new asn1js.GeneralizedTime({ + valueHex: asn1.result.notAfter.valueBlock.valueHex + }); + localNotAfter.fromBuffer(asn1.result.notAfter.valueBlock.valueHex); + this.notAfter = localNotAfter.toDate(); + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + + if ("notBefore" in this) { + outputArray.push(new asn1js.Primitive({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + valueHex: new asn1js.GeneralizedTime({ + valueDate: this.notBefore + }).valueBlock.valueHex + })); + } + + if ("notAfter" in this) { + outputArray.push(new asn1js.Primitive({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + valueHex: new asn1js.GeneralizedTime({ + valueDate: this.notAfter + }).valueBlock.valueHex + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = {}; + if ("notBefore" in this) object.notBefore = this.notBefore; + if ("notAfter" in this) object.notAfter = this.notAfter; + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = PrivateKeyUsagePeriod; + +},{"asn1js":112,"pvutils":113}],78:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _common = require("./common.js"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _ECPublicKey = _interopRequireDefault(require("./ECPublicKey.js")); + +var _RSAPublicKey = _interopRequireDefault(require("./RSAPublicKey.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class PublicKeyInfo { + //********************************************************************************** + + /** + * Constructor for PublicKeyInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {AlgorithmIdentifier} + * @desc Algorithm identifier + */ + this.algorithm = (0, _pvutils.getParametersValue)(parameters, "algorithm", PublicKeyInfo.defaultValues("algorithm")); + /** + * @type {BitString} + * @desc Subject public key value + */ + + this.subjectPublicKey = (0, _pvutils.getParametersValue)(parameters, "subjectPublicKey", PublicKeyInfo.defaultValues("subjectPublicKey")); + if ("parsedKey" in parameters) + /** + * @type {ECPublicKey|RSAPublicKey} + * @desc Parsed public key value + */ + this.parsedKey = (0, _pvutils.getParametersValue)(parameters, "parsedKey", PublicKeyInfo.defaultValues("parsedKey")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + //region If input argument array contains "json" for this object + + if ("json" in parameters) this.fromJSON(parameters.json); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "algorithm": + return new _AlgorithmIdentifier.default(); + + case "subjectPublicKey": + return new asn1js.BitString(); + + default: + throw new Error(`Invalid member name for PublicKeyInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * SubjectPublicKeyInfo ::= Sequence { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [algorithm] + * @property {string} [subjectPublicKey] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_AlgorithmIdentifier.default.schema(names.algorithm || {}), new asn1js.BitString({ + name: names.subjectPublicKey || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["algorithm", "subjectPublicKey"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, PublicKeyInfo.schema({ + names: { + algorithm: { + names: { + blockName: "algorithm" + } + }, + subjectPublicKey: "subjectPublicKey" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for PublicKeyInfo"); //endregion + //region Get internal properties from parsed schema + + this.algorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.algorithm + }); + this.subjectPublicKey = asn1.result.subjectPublicKey; + + switch (this.algorithm.algorithmId) { + case "1.2.840.10045.2.1": + // ECDSA + if ("algorithmParams" in this.algorithm) { + if (this.algorithm.algorithmParams.constructor.blockName() === asn1js.ObjectIdentifier.blockName()) { + try { + this.parsedKey = new _ECPublicKey.default({ + namedCurve: this.algorithm.algorithmParams.valueBlock.toString(), + schema: this.subjectPublicKey.valueBlock.valueHex + }); + } catch (ex) {} // Could be a problems during recognision of internal public key data here. Let's ignore them. + + } + } + + break; + + case "1.2.840.113549.1.1.1": + // RSA + { + const publicKeyASN1 = asn1js.fromBER(this.subjectPublicKey.valueBlock.valueHex); + + if (publicKeyASN1.offset !== -1) { + try { + this.parsedKey = new _RSAPublicKey.default({ + schema: publicKeyASN1.result + }); + } catch (ex) {} // Could be a problems during recognision of internal public key data here. Let's ignore them. + + } + } + break; + + default: + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [this.algorithm.toSchema(), this.subjectPublicKey] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + //region Return common value in case we do not have enough info fo making JWK + if ("parsedKey" in this === false) { + return { + algorithm: this.algorithm.toJSON(), + subjectPublicKey: this.subjectPublicKey.toJSON() + }; + } //endregion + //region Making JWK + + + const jwk = {}; + + switch (this.algorithm.algorithmId) { + case "1.2.840.10045.2.1": + // ECDSA + jwk.kty = "EC"; + break; + + case "1.2.840.113549.1.1.1": + // RSA + jwk.kty = "RSA"; + break; + + default: + } + + const publicKeyJWK = this.parsedKey.toJSON(); + + for (var _i = 0, _Object$keys = Object.keys(publicKeyJWK); _i < _Object$keys.length; _i++) { + const key = _Object$keys[_i]; + jwk[key] = publicKeyJWK[key]; + } + + return jwk; //endregion + } //********************************************************************************** + + /** + * Convert JSON value into current object + * @param {Object} json + */ + + + fromJSON(json) { + if ("kty" in json) { + switch (json.kty.toUpperCase()) { + case "EC": + this.parsedKey = new _ECPublicKey.default({ + json + }); + this.algorithm = new _AlgorithmIdentifier.default({ + algorithmId: "1.2.840.10045.2.1", + algorithmParams: new asn1js.ObjectIdentifier({ + value: this.parsedKey.namedCurve + }) + }); + break; + + case "RSA": + this.parsedKey = new _RSAPublicKey.default({ + json + }); + this.algorithm = new _AlgorithmIdentifier.default({ + algorithmId: "1.2.840.113549.1.1.1", + algorithmParams: new asn1js.Null() + }); + break; + + default: + throw new Error(`Invalid value for "kty" parameter: ${json.kty}`); + } + + this.subjectPublicKey = new asn1js.BitString({ + valueHex: this.parsedKey.toSchema().toBER(false) + }); + } + } //********************************************************************************** + + + importKey(publicKey) { + //region Initial variables + let sequence = Promise.resolve(); + + const _this = this; //endregion + //region Initial check + + + if (typeof publicKey === "undefined") return Promise.reject("Need to provide publicKey input parameter"); //endregion + //region Get a "crypto" extension + + const crypto = (0, _common.getCrypto)(); + if (typeof crypto === "undefined") return Promise.reject("Unable to create WebCrypto object"); //endregion + //region Export public key + + sequence = sequence.then(() => crypto.exportKey("spki", publicKey)); //endregion + //region Initialize internal variables by parsing exported value + + sequence = sequence.then( + /** + * @param {ArrayBuffer} exportedKey + */ + exportedKey => { + const asn1 = asn1js.fromBER(exportedKey); + + try { + _this.fromSchema(asn1.result); + } catch (exception) { + return Promise.reject("Error during initializing object from schema"); + } + + return undefined; + }, error => Promise.reject(`Error during exporting public key: ${error}`)); //endregion + + return sequence; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = PublicKeyInfo; + +},{"./AlgorithmIdentifier.js":4,"./ECPublicKey.js":32,"./RSAPublicKey.js":82,"./common.js":110,"asn1js":112,"pvutils":113}],79:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.QCStatement = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC3739 + */ +class QCStatement { + //********************************************************************************** + + /** + * Constructor for QCStatement class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + */ + this.id = (0, _pvutils.getParametersValue)(parameters, "id", QCStatement.defaultValues("id")); + + if ("type" in parameters) { + /** + * @type {*} Any data described by "id" + */ + this.type = (0, _pvutils.getParametersValue)(parameters, "type", QCStatement.defaultValues("type")); + } //endregion + //region If input argument array contains "schema" for this object + + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "id": + return ""; + + case "type": + return new asn1js.Null(); + + default: + throw new Error(`Invalid member name for QCStatement class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "id": + return memberValue === ""; + + case "type": + return memberValue instanceof asn1js.Null; + + default: + throw new Error(`Invalid member name for QCStatement class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * QCStatement ::= SEQUENCE { + * statementId QC-STATEMENT.&id({SupportedStatements}), + * statementInfo QC-STATEMENT.&Type({SupportedStatements}{@statementId}) OPTIONAL + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [id] + * @property {string} [type] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.id || "" + }), new asn1js.Any({ + name: names.type || "", + optional: true + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["id", "type"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, QCStatement.schema({ + names: { + id: "id", + type: "type" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for QCStatement"); //endregion + //region Get internal properties from parsed schema + + this.id = asn1.result.id.valueBlock.toString(); + if ("type" in asn1.result) this.type = asn1.result.type; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + const value = [new asn1js.ObjectIdentifier({ + value: this.id + })]; + if ("type" in this) value.push(this.type); //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = { + id: this.id + }; + if ("type" in this) object.type = this.type.toJSON(); + return object; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * Class from RFC3739 + */ + + +exports.QCStatement = QCStatement; + +class QCStatements { + //********************************************************************************** + + /** + * Constructor for QCStatements class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array} + */ + this.values = (0, _pvutils.getParametersValue)(parameters, "values", QCStatements.defaultValues("values")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "values": + return []; + + default: + throw new Error(`Invalid member name for QCStatements class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "values": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for QCStatements class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * QCStatements ::= SEQUENCE OF QCStatement + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [values] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.values || "", + value: QCStatement.schema(names.value || {}) + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["values"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, QCStatements.schema({ + names: { + values: "values" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for QCStatements"); //endregion + //region Get internal properties from parsed schema + + this.values = Array.from(asn1.result.values, element => new QCStatement({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: Array.from(this.values, element => element.toSchema()) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + extensions: Array.from(this.values, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = QCStatements; + +},{"asn1js":112,"pvutils":113}],80:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC3447 + */ +class RSAESOAEPParams { + //********************************************************************************** + + /** + * Constructor for RSAESOAEPParams class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {AlgorithmIdentifier} + * @desc hashAlgorithm + */ + this.hashAlgorithm = (0, _pvutils.getParametersValue)(parameters, "hashAlgorithm", RSAESOAEPParams.defaultValues("hashAlgorithm")); + /** + * @type {AlgorithmIdentifier} + * @desc maskGenAlgorithm + */ + + this.maskGenAlgorithm = (0, _pvutils.getParametersValue)(parameters, "maskGenAlgorithm", RSAESOAEPParams.defaultValues("maskGenAlgorithm")); + /** + * @type {AlgorithmIdentifier} + * @desc pSourceAlgorithm + */ + + this.pSourceAlgorithm = (0, _pvutils.getParametersValue)(parameters, "pSourceAlgorithm", RSAESOAEPParams.defaultValues("pSourceAlgorithm")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "hashAlgorithm": + return new _AlgorithmIdentifier.default({ + algorithmId: "1.3.14.3.2.26", + // SHA-1 + algorithmParams: new asn1js.Null() + }); + + case "maskGenAlgorithm": + return new _AlgorithmIdentifier.default({ + algorithmId: "1.2.840.113549.1.1.8", + // MGF1 + algorithmParams: new _AlgorithmIdentifier.default({ + algorithmId: "1.3.14.3.2.26", + // SHA-1 + algorithmParams: new asn1js.Null() + }).toSchema() + }); + + case "pSourceAlgorithm": + return new _AlgorithmIdentifier.default({ + algorithmId: "1.2.840.113549.1.1.9", + // id-pSpecified + algorithmParams: new asn1js.OctetString({ + valueHex: new Uint8Array([0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09]).buffer + }) // SHA-1 hash of empty string + + }); + + default: + throw new Error(`Invalid member name for RSAESOAEPParams class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * RSAES-OAEP-params ::= SEQUENCE { + * hashAlgorithm [0] HashAlgorithm DEFAULT sha1, + * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1, + * pSourceAlgorithm [2] PSourceAlgorithm DEFAULT pSpecifiedEmpty + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [hashAlgorithm] + * @property {string} [maskGenAlgorithm] + * @property {string} [pSourceAlgorithm] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + optional: true, + value: [_AlgorithmIdentifier.default.schema(names.hashAlgorithm || {})] + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + optional: true, + value: [_AlgorithmIdentifier.default.schema(names.maskGenAlgorithm || {})] + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + optional: true, + value: [_AlgorithmIdentifier.default.schema(names.pSourceAlgorithm || {})] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["hashAlgorithm", "maskGenAlgorithm", "pSourceAlgorithm"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, RSAESOAEPParams.schema({ + names: { + hashAlgorithm: { + names: { + blockName: "hashAlgorithm" + } + }, + maskGenAlgorithm: { + names: { + blockName: "maskGenAlgorithm" + } + }, + pSourceAlgorithm: { + names: { + blockName: "pSourceAlgorithm" + } + } + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for RSAESOAEPParams"); //endregion + //region Get internal properties from parsed schema + + if ("hashAlgorithm" in asn1.result) this.hashAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.hashAlgorithm + }); + if ("maskGenAlgorithm" in asn1.result) this.maskGenAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.maskGenAlgorithm + }); + if ("pSourceAlgorithm" in asn1.result) this.pSourceAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.pSourceAlgorithm + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + + if (!this.hashAlgorithm.isEqual(RSAESOAEPParams.defaultValues("hashAlgorithm"))) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [this.hashAlgorithm.toSchema()] + })); + } + + if (!this.maskGenAlgorithm.isEqual(RSAESOAEPParams.defaultValues("maskGenAlgorithm"))) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [this.maskGenAlgorithm.toSchema()] + })); + } + + if (!this.pSourceAlgorithm.isEqual(RSAESOAEPParams.defaultValues("pSourceAlgorithm"))) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + value: [this.pSourceAlgorithm.toSchema()] + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = {}; + if (!this.hashAlgorithm.isEqual(RSAESOAEPParams.defaultValues("hashAlgorithm"))) object.hashAlgorithm = this.hashAlgorithm.toJSON(); + if (!this.maskGenAlgorithm.isEqual(RSAESOAEPParams.defaultValues("maskGenAlgorithm"))) object.maskGenAlgorithm = this.maskGenAlgorithm.toJSON(); + if (!this.pSourceAlgorithm.isEqual(RSAESOAEPParams.defaultValues("pSourceAlgorithm"))) object.pSourceAlgorithm = this.pSourceAlgorithm.toJSON(); + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = RSAESOAEPParams; + +},{"./AlgorithmIdentifier.js":4,"asn1js":112,"pvutils":113}],81:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _OtherPrimeInfo = _interopRequireDefault(require("./OtherPrimeInfo.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC3447 + */ +class RSAPrivateKey { + //********************************************************************************** + + /** + * Constructor for RSAPrivateKey class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", RSAPrivateKey.defaultValues("version")); + /** + * @type {Integer} + * @desc modulus + */ + + this.modulus = (0, _pvutils.getParametersValue)(parameters, "modulus", RSAPrivateKey.defaultValues("modulus")); + /** + * @type {Integer} + * @desc publicExponent + */ + + this.publicExponent = (0, _pvutils.getParametersValue)(parameters, "publicExponent", RSAPrivateKey.defaultValues("publicExponent")); + /** + * @type {Integer} + * @desc privateExponent + */ + + this.privateExponent = (0, _pvutils.getParametersValue)(parameters, "privateExponent", RSAPrivateKey.defaultValues("privateExponent")); + /** + * @type {Integer} + * @desc prime1 + */ + + this.prime1 = (0, _pvutils.getParametersValue)(parameters, "prime1", RSAPrivateKey.defaultValues("prime1")); + /** + * @type {Integer} + * @desc prime2 + */ + + this.prime2 = (0, _pvutils.getParametersValue)(parameters, "prime2", RSAPrivateKey.defaultValues("prime2")); + /** + * @type {Integer} + * @desc exponent1 + */ + + this.exponent1 = (0, _pvutils.getParametersValue)(parameters, "exponent1", RSAPrivateKey.defaultValues("exponent1")); + /** + * @type {Integer} + * @desc exponent2 + */ + + this.exponent2 = (0, _pvutils.getParametersValue)(parameters, "exponent2", RSAPrivateKey.defaultValues("exponent2")); + /** + * @type {Integer} + * @desc coefficient + */ + + this.coefficient = (0, _pvutils.getParametersValue)(parameters, "coefficient", RSAPrivateKey.defaultValues("coefficient")); + if ("otherPrimeInfos" in parameters) + /** + * @type {Array.} + * @desc otherPrimeInfos + */ + this.otherPrimeInfos = (0, _pvutils.getParametersValue)(parameters, "otherPrimeInfos", RSAPrivateKey.defaultValues("otherPrimeInfos")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + //region If input argument array contains "json" for this object + + if ("json" in parameters) this.fromJSON(parameters.json); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 0; + + case "modulus": + return new asn1js.Integer(); + + case "publicExponent": + return new asn1js.Integer(); + + case "privateExponent": + return new asn1js.Integer(); + + case "prime1": + return new asn1js.Integer(); + + case "prime2": + return new asn1js.Integer(); + + case "exponent1": + return new asn1js.Integer(); + + case "exponent2": + return new asn1js.Integer(); + + case "coefficient": + return new asn1js.Integer(); + + case "otherPrimeInfos": + return []; + + default: + throw new Error(`Invalid member name for RSAPrivateKey class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * RSAPrivateKey ::= Sequence { + * version Version, + * modulus Integer, -- n + * publicExponent Integer, -- e + * privateExponent Integer, -- d + * prime1 Integer, -- p + * prime2 Integer, -- q + * exponent1 Integer, -- d mod (p-1) + * exponent2 Integer, -- d mod (q-1) + * coefficient Integer, -- (inverse of q) mod p + * otherPrimeInfos OtherPrimeInfos OPTIONAL + * } + * + * OtherPrimeInfos ::= Sequence SIZE(1..MAX) OF OtherPrimeInfo + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [version] + * @property {string} [modulus] + * @property {string} [publicExponent] + * @property {string} [privateExponent] + * @property {string} [prime1] + * @property {string} [prime2] + * @property {string} [exponent1] + * @property {string} [exponent2] + * @property {string} [coefficient] + * @property {string} [otherPrimeInfosName] + * @property {Object} [otherPrimeInfo] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.version || "" + }), new asn1js.Integer({ + name: names.modulus || "" + }), new asn1js.Integer({ + name: names.publicExponent || "" + }), new asn1js.Integer({ + name: names.privateExponent || "" + }), new asn1js.Integer({ + name: names.prime1 || "" + }), new asn1js.Integer({ + name: names.prime2 || "" + }), new asn1js.Integer({ + name: names.exponent1 || "" + }), new asn1js.Integer({ + name: names.exponent2 || "" + }), new asn1js.Integer({ + name: names.coefficient || "" + }), new asn1js.Sequence({ + optional: true, + value: [new asn1js.Repeated({ + name: names.otherPrimeInfosName || "", + value: _OtherPrimeInfo.default.schema(names.otherPrimeInfo || {}) + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["version", "modulus", "publicExponent", "privateExponent", "prime1", "prime2", "exponent1", "exponent2", "coefficient", "otherPrimeInfos"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, RSAPrivateKey.schema({ + names: { + version: "version", + modulus: "modulus", + publicExponent: "publicExponent", + privateExponent: "privateExponent", + prime1: "prime1", + prime2: "prime2", + exponent1: "exponent1", + exponent2: "exponent2", + coefficient: "coefficient", + otherPrimeInfo: { + names: { + blockName: "otherPrimeInfos" + } + } + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for RSAPrivateKey"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result.version.valueBlock.valueDec; + this.modulus = asn1.result.modulus.convertFromDER(256); + this.publicExponent = asn1.result.publicExponent; + this.privateExponent = asn1.result.privateExponent.convertFromDER(256); + this.prime1 = asn1.result.prime1.convertFromDER(128); + this.prime2 = asn1.result.prime2.convertFromDER(128); + this.exponent1 = asn1.result.exponent1.convertFromDER(128); + this.exponent2 = asn1.result.exponent2.convertFromDER(128); + this.coefficient = asn1.result.coefficient.convertFromDER(128); + if ("otherPrimeInfos" in asn1.result) this.otherPrimeInfos = Array.from(asn1.result.otherPrimeInfos, element => new _OtherPrimeInfo.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(new asn1js.Integer({ + value: this.version + })); + outputArray.push(this.modulus.convertToDER()); + outputArray.push(this.publicExponent); + outputArray.push(this.privateExponent.convertToDER()); + outputArray.push(this.prime1.convertToDER()); + outputArray.push(this.prime2.convertToDER()); + outputArray.push(this.exponent1.convertToDER()); + outputArray.push(this.exponent2.convertToDER()); + outputArray.push(this.coefficient.convertToDER()); + + if ("otherPrimeInfos" in this) { + outputArray.push(new asn1js.Sequence({ + value: Array.from(this.otherPrimeInfos, element => element.toSchema()) + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const jwk = { + n: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.modulus.valueBlock.valueHex), true, true, true), + e: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.publicExponent.valueBlock.valueHex), true, true, true), + d: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.privateExponent.valueBlock.valueHex), true, true, true), + p: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.prime1.valueBlock.valueHex), true, true, true), + q: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.prime2.valueBlock.valueHex), true, true, true), + dp: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.exponent1.valueBlock.valueHex), true, true, true), + dq: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.exponent2.valueBlock.valueHex), true, true, true), + qi: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.coefficient.valueBlock.valueHex), true, true, true) + }; + if ("otherPrimeInfos" in this) jwk.oth = Array.from(this.otherPrimeInfos, element => element.toJSON()); + return jwk; + } //********************************************************************************** + + /** + * Convert JSON value into current object + * @param {Object} json + */ + + + fromJSON(json) { + if ("n" in json) this.modulus = new asn1js.Integer({ + valueHex: (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.n, true, true)) + });else throw new Error("Absent mandatory parameter \"n\""); + if ("e" in json) this.publicExponent = new asn1js.Integer({ + valueHex: (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.e, true, true)) + });else throw new Error("Absent mandatory parameter \"e\""); + if ("d" in json) this.privateExponent = new asn1js.Integer({ + valueHex: (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.d, true, true)) + });else throw new Error("Absent mandatory parameter \"d\""); + if ("p" in json) this.prime1 = new asn1js.Integer({ + valueHex: (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.p, true, true)) + });else throw new Error("Absent mandatory parameter \"p\""); + if ("q" in json) this.prime2 = new asn1js.Integer({ + valueHex: (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.q, true, true)) + });else throw new Error("Absent mandatory parameter \"q\""); + if ("dp" in json) this.exponent1 = new asn1js.Integer({ + valueHex: (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.dp, true, true)) + });else throw new Error("Absent mandatory parameter \"dp\""); + if ("dq" in json) this.exponent2 = new asn1js.Integer({ + valueHex: (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.dq, true, true)) + });else throw new Error("Absent mandatory parameter \"dq\""); + if ("qi" in json) this.coefficient = new asn1js.Integer({ + valueHex: (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.qi, true, true)) + });else throw new Error("Absent mandatory parameter \"qi\""); + if ("oth" in json) this.otherPrimeInfos = Array.from(json.oth, element => new _OtherPrimeInfo.default({ + json: element + })); + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = RSAPrivateKey; + +},{"./OtherPrimeInfo.js":62,"asn1js":112,"pvutils":113}],82:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC3447 + */ +class RSAPublicKey { + //********************************************************************************** + + /** + * Constructor for RSAPublicKey class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + * @property {Integer} [modulus] + * @property {Integer} [publicExponent] + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Integer} + * @desc Modulus part of RSA public key + */ + this.modulus = (0, _pvutils.getParametersValue)(parameters, "modulus", RSAPublicKey.defaultValues("modulus")); + /** + * @type {Integer} + * @desc Public exponent of RSA public key + */ + + this.publicExponent = (0, _pvutils.getParametersValue)(parameters, "publicExponent", RSAPublicKey.defaultValues("publicExponent")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + //region If input argument array contains "json" for this object + + if ("json" in parameters) this.fromJSON(parameters.json); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "modulus": + return new asn1js.Integer(); + + case "publicExponent": + return new asn1js.Integer(); + + default: + throw new Error(`Invalid member name for RSAPublicKey class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * RSAPublicKey ::= Sequence { + * modulus Integer, -- n + * publicExponent Integer -- e + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} utcTimeName Name for "utcTimeName" choice + * @property {string} generalTimeName Name for "generalTimeName" choice + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.modulus || "" + }), new asn1js.Integer({ + name: names.publicExponent || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["modulus", "publicExponent"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, RSAPublicKey.schema({ + names: { + modulus: "modulus", + publicExponent: "publicExponent" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for RSAPublicKey"); //endregion + //region Get internal properties from parsed schema + + this.modulus = asn1.result.modulus.convertFromDER(256); + this.publicExponent = asn1.result.publicExponent; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [this.modulus.convertToDER(), this.publicExponent] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + n: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.modulus.valueBlock.valueHex), true, true, true), + e: (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(this.publicExponent.valueBlock.valueHex), true, true, true) + }; + } //********************************************************************************** + + /** + * Convert JSON value into current object + * @param {Object} json + */ + + + fromJSON(json) { + if ("n" in json) { + const array = (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.n, true)); + this.modulus = new asn1js.Integer({ + valueHex: array.slice(0, Math.pow(2, (0, _pvutils.nearestPowerOf2)(array.byteLength))) + }); + } else throw new Error("Absent mandatory parameter \"n\""); + + if ("e" in json) this.publicExponent = new asn1js.Integer({ + valueHex: (0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(json.e, true)).slice(0, 3) + });else throw new Error("Absent mandatory parameter \"e\""); + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = RSAPublicKey; + +},{"asn1js":112,"pvutils":113}],83:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC4055 + */ +class RSASSAPSSParams { + //********************************************************************************** + + /** + * Constructor for RSASSAPSSParams class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {AlgorithmIdentifier} + * @desc Algorithms of hashing (DEFAULT sha1) + */ + this.hashAlgorithm = (0, _pvutils.getParametersValue)(parameters, "hashAlgorithm", RSASSAPSSParams.defaultValues("hashAlgorithm")); + /** + * @type {AlgorithmIdentifier} + * @desc Algorithm of "mask generaion function (MGF)" (DEFAULT mgf1SHA1) + */ + + this.maskGenAlgorithm = (0, _pvutils.getParametersValue)(parameters, "maskGenAlgorithm", RSASSAPSSParams.defaultValues("maskGenAlgorithm")); + /** + * @type {number} + * @desc Salt length (DEFAULT 20) + */ + + this.saltLength = (0, _pvutils.getParametersValue)(parameters, "saltLength", RSASSAPSSParams.defaultValues("saltLength")); + /** + * @type {number} + * @desc (DEFAULT 1) + */ + + this.trailerField = (0, _pvutils.getParametersValue)(parameters, "trailerField", RSASSAPSSParams.defaultValues("trailerField")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "hashAlgorithm": + return new _AlgorithmIdentifier.default({ + algorithmId: "1.3.14.3.2.26", + // SHA-1 + algorithmParams: new asn1js.Null() + }); + + case "maskGenAlgorithm": + return new _AlgorithmIdentifier.default({ + algorithmId: "1.2.840.113549.1.1.8", + // MGF1 + algorithmParams: new _AlgorithmIdentifier.default({ + algorithmId: "1.3.14.3.2.26", + // SHA-1 + algorithmParams: new asn1js.Null() + }).toSchema() + }); + + case "saltLength": + return 20; + + case "trailerField": + return 1; + + default: + throw new Error(`Invalid member name for RSASSAPSSParams class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * RSASSA-PSS-params ::= Sequence { + * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier, + * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier, + * saltLength [2] Integer DEFAULT 20, + * trailerField [3] Integer DEFAULT 1 } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [hashAlgorithm] + * @property {string} [maskGenAlgorithm] + * @property {string} [saltLength] + * @property {string} [trailerField] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + optional: true, + value: [_AlgorithmIdentifier.default.schema(names.hashAlgorithm || {})] + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + optional: true, + value: [_AlgorithmIdentifier.default.schema(names.maskGenAlgorithm || {})] + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + optional: true, + value: [new asn1js.Integer({ + name: names.saltLength || "" + })] + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 3 // [3] + + }, + optional: true, + value: [new asn1js.Integer({ + name: names.trailerField || "" + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["hashAlgorithm", "maskGenAlgorithm", "saltLength", "trailerField"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, RSASSAPSSParams.schema({ + names: { + hashAlgorithm: { + names: { + blockName: "hashAlgorithm" + } + }, + maskGenAlgorithm: { + names: { + blockName: "maskGenAlgorithm" + } + }, + saltLength: "saltLength", + trailerField: "trailerField" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for RSASSAPSSParams"); //endregion + //region Get internal properties from parsed schema + + if ("hashAlgorithm" in asn1.result) this.hashAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.hashAlgorithm + }); + if ("maskGenAlgorithm" in asn1.result) this.maskGenAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.maskGenAlgorithm + }); + if ("saltLength" in asn1.result) this.saltLength = asn1.result.saltLength.valueBlock.valueDec; + if ("trailerField" in asn1.result) this.trailerField = asn1.result.trailerField.valueBlock.valueDec; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + + if (!this.hashAlgorithm.isEqual(RSASSAPSSParams.defaultValues("hashAlgorithm"))) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [this.hashAlgorithm.toSchema()] + })); + } + + if (!this.maskGenAlgorithm.isEqual(RSASSAPSSParams.defaultValues("maskGenAlgorithm"))) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [this.maskGenAlgorithm.toSchema()] + })); + } + + if (this.saltLength !== RSASSAPSSParams.defaultValues("saltLength")) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + value: [new asn1js.Integer({ + value: this.saltLength + })] + })); + } + + if (this.trailerField !== RSASSAPSSParams.defaultValues("trailerField")) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 3 // [3] + + }, + value: [new asn1js.Integer({ + value: this.trailerField + })] + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = {}; + if (!this.hashAlgorithm.isEqual(RSASSAPSSParams.defaultValues("hashAlgorithm"))) object.hashAlgorithm = this.hashAlgorithm.toJSON(); + if (!this.maskGenAlgorithm.isEqual(RSASSAPSSParams.defaultValues("maskGenAlgorithm"))) object.maskGenAlgorithm = this.maskGenAlgorithm.toJSON(); + if (this.saltLength !== RSASSAPSSParams.defaultValues("saltLength")) object.saltLength = this.saltLength; + if (this.trailerField !== RSASSAPSSParams.defaultValues("trailerField")) object.trailerField = this.trailerField; + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = RSASSAPSSParams; + +},{"./AlgorithmIdentifier.js":4,"asn1js":112,"pvutils":113}],84:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _KeyAgreeRecipientIdentifier = _interopRequireDefault(require("./KeyAgreeRecipientIdentifier.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class RecipientEncryptedKey { + //********************************************************************************** + + /** + * Constructor for RecipientEncryptedKey class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {KeyAgreeRecipientIdentifier} + * @desc rid + */ + this.rid = (0, _pvutils.getParametersValue)(parameters, "rid", RecipientEncryptedKey.defaultValues("rid")); + /** + * @type {OctetString} + * @desc encryptedKey + */ + + this.encryptedKey = (0, _pvutils.getParametersValue)(parameters, "encryptedKey", RecipientEncryptedKey.defaultValues("encryptedKey")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "rid": + return new _KeyAgreeRecipientIdentifier.default(); + + case "encryptedKey": + return new asn1js.OctetString(); + + default: + throw new Error(`Invalid member name for RecipientEncryptedKey class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "rid": + return memberValue.variant === -1 && "value" in memberValue === false; + + case "encryptedKey": + return memberValue.isEqual(RecipientEncryptedKey.defaultValues("encryptedKey")); + + default: + throw new Error(`Invalid member name for RecipientEncryptedKey class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * RecipientEncryptedKey ::= SEQUENCE { + * rid KeyAgreeRecipientIdentifier, + * encryptedKey EncryptedKey } + * + * EncryptedKey ::= OCTET STRING + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [rid] + * @property {string} [encryptedKey] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_KeyAgreeRecipientIdentifier.default.schema(names.rid || {}), new asn1js.OctetString({ + name: names.encryptedKey || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["rid", "encryptedKey"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, RecipientEncryptedKey.schema({ + names: { + rid: { + names: { + blockName: "rid" + } + }, + encryptedKey: "encryptedKey" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for RecipientEncryptedKey"); //endregion + //region Get internal properties from parsed schema + + this.rid = new _KeyAgreeRecipientIdentifier.default({ + schema: asn1.result.rid + }); + this.encryptedKey = asn1.result.encryptedKey; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [this.rid.toSchema(), this.encryptedKey] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + rid: this.rid.toJSON(), + encryptedKey: this.encryptedKey.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = RecipientEncryptedKey; + +},{"./KeyAgreeRecipientIdentifier.js":48,"asn1js":112,"pvutils":113}],85:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _RecipientEncryptedKey = _interopRequireDefault(require("./RecipientEncryptedKey.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class RecipientEncryptedKeys { + //********************************************************************************** + + /** + * Constructor for RecipientEncryptedKeys class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc encryptedKeys + */ + this.encryptedKeys = (0, _pvutils.getParametersValue)(parameters, "encryptedKeys", RecipientEncryptedKeys.defaultValues("encryptedKeys")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "encryptedKeys": + return []; + + default: + throw new Error(`Invalid member name for RecipientEncryptedKeys class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "encryptedKeys": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for RecipientEncryptedKeys class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * RecipientEncryptedKeys ::= SEQUENCE OF RecipientEncryptedKey + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [RecipientEncryptedKeys] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.RecipientEncryptedKeys || "", + value: _RecipientEncryptedKey.default.schema() + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["RecipientEncryptedKeys"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, RecipientEncryptedKeys.schema({ + names: { + RecipientEncryptedKeys: "RecipientEncryptedKeys" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for RecipientEncryptedKeys"); //endregion + //region Get internal properties from parsed schema + + this.encryptedKeys = Array.from(asn1.result.RecipientEncryptedKeys, element => new _RecipientEncryptedKey.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: Array.from(this.encryptedKeys, element => element.toSchema()) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + encryptedKeys: Array.from(this.encryptedKeys, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = RecipientEncryptedKeys; + +},{"./RecipientEncryptedKey.js":84,"asn1js":112,"pvutils":113}],86:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _IssuerAndSerialNumber = _interopRequireDefault(require("./IssuerAndSerialNumber.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class RecipientIdentifier { + //********************************************************************************** + + /** + * Constructor for RecipientIdentifier class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc variant + */ + this.variant = (0, _pvutils.getParametersValue)(parameters, "variant", RecipientIdentifier.defaultValues("variant")); + if ("value" in parameters) + /** + * @type {*} + * @desc value + */ + this.value = (0, _pvutils.getParametersValue)(parameters, "value", RecipientIdentifier.defaultValues("value")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "variant": + return -1; + + case "value": + return {}; + + default: + throw new Error(`Invalid member name for RecipientIdentifier class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "variant": + return memberValue === -1; + + case "values": + return Object.keys(memberValue).length === 0; + + default: + throw new Error(`Invalid member name for RecipientIdentifier class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * RecipientIdentifier ::= CHOICE { + * issuerAndSerialNumber IssuerAndSerialNumber, + * subjectKeyIdentifier [0] SubjectKeyIdentifier } + * + * SubjectKeyIdentifier ::= OCTET STRING + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Choice({ + value: [_IssuerAndSerialNumber.default.schema({ + names: { + blockName: names.blockName || "" + } + }), new asn1js.Constructed({ + name: names.blockName || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.OctetString()] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["blockName"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, RecipientIdentifier.schema({ + names: { + blockName: "blockName" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for RecipientIdentifier"); //endregion + //region Get internal properties from parsed schema + + if (asn1.result.blockName.idBlock.tagClass === 1) { + this.variant = 1; + this.value = new _IssuerAndSerialNumber.default({ + schema: asn1.result.blockName + }); + } else { + this.variant = 2; + this.value = asn1.result.blockName.valueBlock.value[0]; + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + switch (this.variant) { + case 1: + return this.value.toSchema(); + + case 2: + return new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [this.value] + }); + + default: + return new asn1js.Any(); + } //endregion + + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + variant: this.variant + }; + if (this.variant === 1 || this.variant === 2) _object.value = this.value.toJSON(); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = RecipientIdentifier; + +},{"./IssuerAndSerialNumber.js":44,"asn1js":112,"pvutils":113}],87:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _KeyTransRecipientInfo = _interopRequireDefault(require("./KeyTransRecipientInfo.js")); + +var _KeyAgreeRecipientInfo = _interopRequireDefault(require("./KeyAgreeRecipientInfo.js")); + +var _KEKRecipientInfo = _interopRequireDefault(require("./KEKRecipientInfo.js")); + +var _PasswordRecipientinfo = _interopRequireDefault(require("./PasswordRecipientinfo.js")); + +var _OtherRecipientInfo = _interopRequireDefault(require("./OtherRecipientInfo.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class RecipientInfo { + //********************************************************************************** + + /** + * Constructor for RecipientInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc variant + */ + this.variant = (0, _pvutils.getParametersValue)(parameters, "variant", RecipientInfo.defaultValues("variant")); + if ("value" in parameters) + /** + * @type {*} + * @desc value + */ + this.value = (0, _pvutils.getParametersValue)(parameters, "value", RecipientInfo.defaultValues("value")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "variant": + return -1; + + case "value": + return {}; + + default: + throw new Error(`Invalid member name for RecipientInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "variant": + return memberValue === RecipientInfo.defaultValues(memberName); + + case "value": + return Object.keys(memberValue).length === 0; + + default: + throw new Error(`Invalid member name for RecipientInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * RecipientInfo ::= CHOICE { + * ktri KeyTransRecipientInfo, + * kari [1] KeyAgreeRecipientInfo, + * kekri [2] KEKRecipientInfo, + * pwri [3] PasswordRecipientinfo, + * ori [4] OtherRecipientInfo } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [type] + * @property {string} [setName] + * @property {string} [values] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Choice({ + value: [_KeyTransRecipientInfo.default.schema({ + names: { + blockName: names.blockName || "" + } + }), new asn1js.Constructed({ + name: names.blockName || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: _KeyAgreeRecipientInfo.default.schema().valueBlock.value + }), new asn1js.Constructed({ + name: names.blockName || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + value: _KEKRecipientInfo.default.schema().valueBlock.value + }), new asn1js.Constructed({ + name: names.blockName || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 3 // [3] + + }, + value: _PasswordRecipientinfo.default.schema().valueBlock.value + }), new asn1js.Constructed({ + name: names.blockName || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 4 // [4] + + }, + value: _OtherRecipientInfo.default.schema().valueBlock.value + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["blockName"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, RecipientInfo.schema({ + names: { + blockName: "blockName" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for RecipientInfo"); //endregion + //region Get internal properties from parsed schema + + if (asn1.result.blockName.idBlock.tagClass === 1) { + this.variant = 1; + this.value = new _KeyTransRecipientInfo.default({ + schema: asn1.result.blockName + }); + } else { + //region Create "SEQUENCE" from "ASN1_CONSTRUCTED" + const blockSequence = new asn1js.Sequence({ + value: asn1.result.blockName.valueBlock.value + }); //endregion + + switch (asn1.result.blockName.idBlock.tagNumber) { + case 1: + this.variant = 2; + this.value = new _KeyAgreeRecipientInfo.default({ + schema: blockSequence + }); + break; + + case 2: + this.variant = 3; + this.value = new _KEKRecipientInfo.default({ + schema: blockSequence + }); + break; + + case 3: + this.variant = 4; + this.value = new _PasswordRecipientinfo.default({ + schema: blockSequence + }); + break; + + case 4: + this.variant = 5; + this.value = new _OtherRecipientInfo.default({ + schema: blockSequence + }); + break; + + default: + throw new Error("Incorrect structure of RecipientInfo block"); + } + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + const _schema = this.value.toSchema(); + + switch (this.variant) { + case 1: + return _schema; + + case 2: + case 3: + case 4: + //region Create "ASN1_CONSTRUCTED" from "SEQUENCE" + _schema.idBlock.tagClass = 3; // CONTEXT-SPECIFIC + + _schema.idBlock.tagNumber = this.variant - 1; //endregion + + return _schema; + + default: + return new asn1js.Any(); + } //endregion + + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + variant: this.variant + }; + if (this.variant >= 1 && this.variant <= 4) _object.value = this.value.toJSON(); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = RecipientInfo; + +},{"./KEKRecipientInfo.js":47,"./KeyAgreeRecipientInfo.js":49,"./KeyTransRecipientInfo.js":51,"./OtherRecipientInfo.js":63,"./PasswordRecipientinfo.js":70,"asn1js":112,"pvutils":113}],88:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _OtherKeyAttribute = _interopRequireDefault(require("./OtherKeyAttribute.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class RecipientKeyIdentifier { + //********************************************************************************** + + /** + * Constructor for RecipientKeyIdentifier class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {OctetString} + * @desc subjectKeyIdentifier + */ + this.subjectKeyIdentifier = (0, _pvutils.getParametersValue)(parameters, "subjectKeyIdentifier", RecipientKeyIdentifier.defaultValues("subjectKeyIdentifier")); + if ("date" in parameters) + /** + * @type {GeneralizedTime} + * @desc date + */ + this.date = (0, _pvutils.getParametersValue)(parameters, "date", RecipientKeyIdentifier.defaultValues("date")); + if ("other" in parameters) + /** + * @type {OtherKeyAttribute} + * @desc other + */ + this.other = (0, _pvutils.getParametersValue)(parameters, "other", RecipientKeyIdentifier.defaultValues("other")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "subjectKeyIdentifier": + return new asn1js.OctetString(); + + case "date": + return new asn1js.GeneralizedTime(); + + case "other": + return new _OtherKeyAttribute.default(); + + default: + throw new Error(`Invalid member name for RecipientKeyIdentifier class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "subjectKeyIdentifier": + return memberValue.isEqual(RecipientKeyIdentifier.defaultValues("subjectKeyIdentifier")); + + case "date": + // noinspection OverlyComplexBooleanExpressionJS + return memberValue.year === 0 && memberValue.month === 0 && memberValue.day === 0 && memberValue.hour === 0 && memberValue.minute === 0 && memberValue.second === 0 && memberValue.millisecond === 0; + + case "other": + return memberValue.keyAttrId === "" && "keyAttr" in memberValue === false; + + default: + throw new Error(`Invalid member name for RecipientKeyIdentifier class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * RecipientKeyIdentifier ::= SEQUENCE { + * subjectKeyIdentifier SubjectKeyIdentifier, + * date GeneralizedTime OPTIONAL, + * other OtherKeyAttribute OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [type] + * @property {string} [setName] + * @property {string} [values] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.OctetString({ + name: names.subjectKeyIdentifier || "" + }), new asn1js.GeneralizedTime({ + optional: true, + name: names.date || "" + }), _OtherKeyAttribute.default.schema(names.other || {})] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["subjectKeyIdentifier", "date", "other"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, RecipientKeyIdentifier.schema({ + names: { + subjectKeyIdentifier: "subjectKeyIdentifier", + date: "date", + other: { + names: { + blockName: "other" + } + } + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for RecipientKeyIdentifier"); //endregion + //region Get internal properties from parsed schema + + this.subjectKeyIdentifier = asn1.result.subjectKeyIdentifier; + if ("date" in asn1.result) this.date = asn1.result.date; + if ("other" in asn1.result) this.other = new _OtherKeyAttribute.default({ + schema: asn1.result.other + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(this.subjectKeyIdentifier); + if ("date" in this) outputArray.push(this.date); + if ("other" in this) outputArray.push(this.other.toSchema()); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + subjectKeyIdentifier: this.subjectKeyIdentifier.toJSON() + }; + if ("date" in this) _object.date = this.date; + if ("other" in this) _object.other = this.other.toJSON(); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = RecipientKeyIdentifier; + +},{"./OtherKeyAttribute.js":61,"asn1js":112,"pvutils":113}],89:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AttributeTypeAndValue = _interopRequireDefault(require("./AttributeTypeAndValue.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } + +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } + +function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } + +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class RelativeDistinguishedNames { + //********************************************************************************** + + /** + * Constructor for RelativeDistinguishedNames class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + * @property {Array.} [typesAndValues] Array of "type and value" objects + * @property {ArrayBuffer} [valueBeforeDecode] Value of the RDN before decoding from schema + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc Array of "type and value" objects + */ + this.typesAndValues = (0, _pvutils.getParametersValue)(parameters, "typesAndValues", RelativeDistinguishedNames.defaultValues("typesAndValues")); + /** + * @type {ArrayBuffer} + * @desc Value of the RDN before decoding from schema + */ + + this.valueBeforeDecode = (0, _pvutils.getParametersValue)(parameters, "valueBeforeDecode", RelativeDistinguishedNames.defaultValues("valueBeforeDecode")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "typesAndValues": + return []; + + case "valueBeforeDecode": + return new ArrayBuffer(0); + + default: + throw new Error(`Invalid member name for RelativeDistinguishedNames class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "typesAndValues": + return memberValue.length === 0; + + case "valueBeforeDecode": + return memberValue.byteLength === 0; + + default: + throw new Error(`Invalid member name for RelativeDistinguishedNames class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * RDNSequence ::= Sequence OF RelativeDistinguishedName + * + * RelativeDistinguishedName ::= + * SET SIZE (1..MAX) OF AttributeTypeAndValue + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] Name for entire block + * @property {string} [repeatedSequence] Name for "repeatedSequence" block + * @property {string} [repeatedSet] Name for "repeatedSet" block + * @property {string} [typeAndValue] Name for "typeAndValue" block + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.repeatedSequence || "", + value: new asn1js.Set({ + value: [new asn1js.Repeated({ + name: names.repeatedSet || "", + value: _AttributeTypeAndValue.default.schema(names.typeAndValue || {}) + })] + }) + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["RDN", "typesAndValues"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, RelativeDistinguishedNames.schema({ + names: { + blockName: "RDN", + repeatedSet: "typesAndValues" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for RelativeDistinguishedNames"); //endregion + //region Get internal properties from parsed schema + + if ("typesAndValues" in asn1.result) // Could be a case when there is no "types and values" + this.typesAndValues = Array.from(asn1.result.typesAndValues, element => new _AttributeTypeAndValue.default({ + schema: element + })); // noinspection JSUnresolvedVariable + + this.valueBeforeDecode = asn1.result.RDN.valueBeforeDecode; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Decode stored TBS value + if (this.valueBeforeDecode.byteLength === 0) // No stored encoded array, create "from scratch" + { + return new asn1js.Sequence({ + value: [new asn1js.Set({ + value: Array.from(this.typesAndValues, element => element.toSchema()) + })] + }); + } + + const asn1 = asn1js.fromBER(this.valueBeforeDecode); //endregion + //region Construct and return new ASN.1 schema for this object + + return asn1.result; //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + typesAndValues: Array.from(this.typesAndValues, element => element.toJSON()) + }; + } //********************************************************************************** + + /** + * Compare two RDN values, or RDN with ArrayBuffer value + * @param {(RelativeDistinguishedNames|ArrayBuffer)} compareTo The value compare to current + * @returns {boolean} + */ + + + isEqual(compareTo) { + if (compareTo instanceof RelativeDistinguishedNames) { + if (this.typesAndValues.length !== compareTo.typesAndValues.length) return false; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.typesAndValues.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + const _step$value = _slicedToArray(_step.value, 2), + index = _step$value[0], + typeAndValue = _step$value[1]; + + if (typeAndValue.isEqual(compareTo.typesAndValues[index]) === false) return false; + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return true; + } + + if (compareTo instanceof ArrayBuffer) return (0, _pvutils.isEqualBuffer)(this.valueBeforeDecode, compareTo); + return false; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = RelativeDistinguishedNames; + +},{"./AttributeTypeAndValue.js":9,"asn1js":112,"pvutils":113}],90:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _CertID = _interopRequireDefault(require("./CertID.js")); + +var _Extension = _interopRequireDefault(require("./Extension.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC6960 + */ +class Request { + //********************************************************************************** + + /** + * Constructor for Request class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {CertID} + * @desc reqCert + */ + this.reqCert = (0, _pvutils.getParametersValue)(parameters, "reqCert", Request.defaultValues("reqCert")); + if ("singleRequestExtensions" in parameters) + /** + * @type {Array.} + * @desc singleRequestExtensions + */ + this.singleRequestExtensions = (0, _pvutils.getParametersValue)(parameters, "singleRequestExtensions", Request.defaultValues("singleRequestExtensions")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "reqCert": + return new _CertID.default(); + + case "singleRequestExtensions": + return []; + + default: + throw new Error(`Invalid member name for Request class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "reqCert": + return memberValue.isEqual(Request.defaultValues(memberName)); + + case "singleRequestExtensions": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for Request class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * Request ::= SEQUENCE { + * reqCert CertID, + * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [reqCert] + * @property {string} [extensions] + * @property {string} [singleRequestExtensions] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_CertID.default.schema(names.reqCert || {}), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [_Extension.default.schema(names.extensions || { + names: { + blockName: names.singleRequestExtensions || "" + } + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["reqCert", "singleRequestExtensions"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, Request.schema({ + names: { + reqCert: { + names: { + blockName: "reqCert" + } + }, + singleRequestExtensions: { + names: { + blockName: "singleRequestExtensions" + } + } + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for Request"); //endregion + //region Get internal properties from parsed schema + + this.reqCert = new _CertID.default({ + schema: asn1.result.reqCert + }); + if ("singleRequestExtensions" in asn1.result) this.singleRequestExtensions = Array.from(asn1.result.singleRequestExtensions.valueBlock.value, element => new _Extension.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(this.reqCert.toSchema()); + + if ("singleRequestExtensions" in this) { + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Sequence({ + value: Array.from(this.singleRequestExtensions, element => element.toSchema()) + })] + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + reqCert: this.reqCert.toJSON() + }; + if ("singleRequestExtensions" in this) _object.singleRequestExtensions = Array.from(this.singleRequestExtensions, element => element.toJSON()); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = Request; + +},{"./CertID.js":18,"./Extension.js":38,"asn1js":112,"pvutils":113}],91:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC6960 + */ +class ResponseBytes { + //********************************************************************************** + + /** + * Constructor for ResponseBytes class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc responseType + */ + this.responseType = (0, _pvutils.getParametersValue)(parameters, "responseType", ResponseBytes.defaultValues("responseType")); + /** + * @type {OctetString} + * @desc response + */ + + this.response = (0, _pvutils.getParametersValue)(parameters, "response", ResponseBytes.defaultValues("response")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "responseType": + return ""; + + case "response": + return new asn1js.OctetString(); + + default: + throw new Error(`Invalid member name for ResponseBytes class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "responseType": + return memberValue === ""; + + case "response": + return memberValue.isEqual(ResponseBytes.defaultValues(memberName)); + + default: + throw new Error(`Invalid member name for ResponseBytes class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * ResponseBytes ::= SEQUENCE { + * responseType OBJECT IDENTIFIER, + * response OCTET STRING } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [responseType] + * @property {string} [response] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.responseType || "" + }), new asn1js.OctetString({ + name: names.response || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["responseType", "response"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, ResponseBytes.schema({ + names: { + responseType: "responseType", + response: "response" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for ResponseBytes"); //endregion + //region Get internal properties from parsed schema + + this.responseType = asn1.result.responseType.valueBlock.toString(); + this.response = asn1.result.response; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [new asn1js.ObjectIdentifier({ + value: this.responseType + }), this.response] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + responseType: this.responseType, + response: this.response.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = ResponseBytes; + +},{"asn1js":112,"pvutils":113}],92:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _RelativeDistinguishedNames = _interopRequireDefault(require("./RelativeDistinguishedNames.js")); + +var _SingleResponse = _interopRequireDefault(require("./SingleResponse.js")); + +var _Extension = _interopRequireDefault(require("./Extension.js")); + +var _Extensions = _interopRequireDefault(require("./Extensions.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC6960 + */ +class ResponseData { + //********************************************************************************** + + /** + * Constructor for ResponseData class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {ArrayBuffer} + * @desc tbs + */ + this.tbs = (0, _pvutils.getParametersValue)(parameters, "tbs", ResponseData.defaultValues("tbs")); + /** + * @type {Object} + * @desc responderID + */ + + this.responderID = (0, _pvutils.getParametersValue)(parameters, "responderID", ResponseData.defaultValues("responderID")); + /** + * @type {Date} + * @desc producedAt + */ + + this.producedAt = (0, _pvutils.getParametersValue)(parameters, "producedAt", ResponseData.defaultValues("producedAt")); + /** + * @type {Array.} + * @desc responses + */ + + this.responses = (0, _pvutils.getParametersValue)(parameters, "responses", ResponseData.defaultValues("responses")); + if ("responseExtensions" in parameters) + /** + * @type {Array.} + * @desc responseExtensions + */ + this.responseExtensions = (0, _pvutils.getParametersValue)(parameters, "responseExtensions", ResponseData.defaultValues("responseExtensions")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "tbs": + return new ArrayBuffer(0); + + case "responderID": + return {}; + + case "producedAt": + return new Date(0, 0, 0); + + case "responses": + case "responseExtensions": + return []; + + default: + throw new Error(`Invalid member name for ResponseData class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "tbs": + return memberValue.byteLength === 0; + + case "responderID": + return Object.keys(memberValue).length === 0; + + case "producedAt": + return memberValue === ResponseData.defaultValues(memberName); + + case "responses": + case "responseExtensions": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for ResponseData class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * ResponseData ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * responderID ResponderID, + * producedAt GeneralizedTime, + * responses SEQUENCE OF SingleResponse, + * responseExtensions [1] EXPLICIT Extensions OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [version] + * @property {string} [ResponseDataByName] + * @property {string} [ResponseDataByKey] + * @property {string} [producedAt] + * @property {string} [response] + * @property {string} [extensions] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "ResponseData", + value: [new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Integer({ + name: names.version || "ResponseData.version" + })] + }), new asn1js.Choice({ + value: [new asn1js.Constructed({ + name: names.responderID || "ResponseData.responderID", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [_RelativeDistinguishedNames.default.schema(names.ResponseDataByName || { + names: { + blockName: "ResponseData.byName" + } + })] + }), new asn1js.Constructed({ + name: names.responderID || "ResponseData.responderID", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + value: [new asn1js.OctetString({ + name: names.ResponseDataByKey || "ResponseData.byKey" + })] + })] + }), new asn1js.GeneralizedTime({ + name: names.producedAt || "ResponseData.producedAt" + }), new asn1js.Sequence({ + value: [new asn1js.Repeated({ + name: "ResponseData.responses", + value: _SingleResponse.default.schema(names.response || {}) + })] + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [_Extensions.default.schema(names.extensions || { + names: { + blockName: "ResponseData.responseExtensions" + } + })] + }) // EXPLICIT SEQUENCE value + ] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["ResponseData", "ResponseData.version", "ResponseData.responderID", "ResponseData.producedAt", "ResponseData.responses", "ResponseData.responseExtensions"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, ResponseData.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for ResponseData"); //endregion + //region Get internal properties from parsed schema + + this.tbs = asn1.result.ResponseData.valueBeforeDecode; + if ("ResponseData.version" in asn1.result) this.version = asn1.result["ResponseData.version"].valueBlock.valueDec; + if (asn1.result["ResponseData.responderID"].idBlock.tagNumber === 1) this.responderID = new _RelativeDistinguishedNames.default({ + schema: asn1.result["ResponseData.responderID"].valueBlock.value[0] + });else this.responderID = asn1.result["ResponseData.responderID"].valueBlock.value[0]; // OCTETSTRING + + this.producedAt = asn1.result["ResponseData.producedAt"].toDate(); + this.responses = Array.from(asn1.result["ResponseData.responses"], element => new _SingleResponse.default({ + schema: element + })); + if ("ResponseData.responseExtensions" in asn1.result) this.responseExtensions = Array.from(asn1.result["ResponseData.responseExtensions"].valueBlock.value, element => new _Extension.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @param {boolean} encodeFlag If param equal to false then create TBS schema via decoding stored value. In othe case create TBS schema via assembling from TBS parts. + * @returns {Object} asn1js object + */ + + + toSchema(encodeFlag = false) { + //region Decode stored TBS value + let tbsSchema; + + if (encodeFlag === false) { + if (this.tbs.length === 0) // No stored certificate TBS part + return ResponseData.schema(); + tbsSchema = asn1js.fromBER(this.tbs).result; + } //endregion + //region Create TBS schema via assembling from TBS parts + else { + const outputArray = []; + + if ("version" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Integer({ + value: this.version + })] + })); + } + + if (this.responderID instanceof _RelativeDistinguishedNames.default) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [this.responderID.toSchema()] + })); + } else { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + value: [this.responderID] + })); + } + + outputArray.push(new asn1js.GeneralizedTime({ + valueDate: this.producedAt + })); + outputArray.push(new asn1js.Sequence({ + value: Array.from(this.responses, element => element.toSchema()) + })); + + if ("responseExtensions" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [new asn1js.Sequence({ + value: Array.from(this.responseExtensions, element => element.toSchema()) + })] + })); + } + + tbsSchema = new asn1js.Sequence({ + value: outputArray + }); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return tbsSchema; //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = {}; + if ("version" in this) _object.version = this.version; + if ("responderID" in this) _object.responderID = this.responderID; + if ("producedAt" in this) _object.producedAt = this.producedAt; + if ("responses" in this) _object.responses = Array.from(this.responses, element => element.toJSON()); + if ("responseExtensions" in this) _object.responseExtensions = Array.from(this.responseExtensions, element => element.toJSON()); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = ResponseData; + +},{"./Extension.js":38,"./Extensions.js":39,"./RelativeDistinguishedNames.js":89,"./SingleResponse.js":103,"asn1js":112,"pvutils":113}],93:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _CertificateRevocationList = _interopRequireDefault(require("./CertificateRevocationList.js")); + +var _OtherRevocationInfoFormat = _interopRequireDefault(require("./OtherRevocationInfoFormat.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class RevocationInfoChoices { + //********************************************************************************** + + /** + * Constructor for RevocationInfoChoices class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc crls + */ + this.crls = (0, _pvutils.getParametersValue)(parameters, "crls", RevocationInfoChoices.defaultValues("crls")); + /** + * @type {Array.} + * @desc otherRevocationInfos + */ + + this.otherRevocationInfos = (0, _pvutils.getParametersValue)(parameters, "otherRevocationInfos", RevocationInfoChoices.defaultValues("otherRevocationInfos")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "crls": + return []; + + case "otherRevocationInfos": + return []; + + default: + throw new Error(`Invalid member name for RevocationInfoChoices class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * RevocationInfoChoices ::= SET OF RevocationInfoChoice + * + * RevocationInfoChoice ::= CHOICE { + * crl CertificateList, + * other [1] IMPLICIT OtherRevocationInfoFormat } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [crls] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Set({ + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.crls || "", + value: new asn1js.Choice({ + value: [_CertificateRevocationList.default.schema(), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [new asn1js.ObjectIdentifier(), new asn1js.Any()] + })] + }) + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["crls"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, RevocationInfoChoices.schema({ + names: { + crls: "crls" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for RevocationInfoChoices"); //endregion + //region Get internal properties from parsed schema + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = asn1.result.crls[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + const element = _step.value; + if (element.idBlock.tagClass === 1) this.crls.push(new _CertificateRevocationList.default({ + schema: element + }));else this.otherRevocationInfos.push(new _OtherRevocationInfoFormat.default({ + schema: element + })); + } //endregion + + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output set + const outputArray = []; + outputArray.push(...Array.from(this.crls, element => element.toSchema())); + outputArray.push(...Array.from(this.otherRevocationInfos, element => { + const schema = element.toSchema(); + schema.idBlock.tagClass = 3; + schema.idBlock.tagNumber = 1; + return schema; + })); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Set({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + crls: Array.from(this.crls, element => element.toJSON()), + otherRevocationInfos: Array.from(this.otherRevocationInfos, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = RevocationInfoChoices; + +},{"./CertificateRevocationList.js":22,"./OtherRevocationInfoFormat.js":64,"asn1js":112,"pvutils":113}],94:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _Time = _interopRequireDefault(require("./Time.js")); + +var _Extensions = _interopRequireDefault(require("./Extensions.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class RevokedCertificate { + //********************************************************************************** + + /** + * Constructor for RevokedCertificate class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Integer} + * @desc userCertificate + */ + this.userCertificate = (0, _pvutils.getParametersValue)(parameters, "userCertificate", RevokedCertificate.defaultValues("userCertificate")); + /** + * @type {Time} + * @desc revocationDate + */ + + this.revocationDate = (0, _pvutils.getParametersValue)(parameters, "revocationDate", RevokedCertificate.defaultValues("revocationDate")); + if ("crlEntryExtensions" in parameters) + /** + * @type {Extensions} + * @desc crlEntryExtensions + */ + this.crlEntryExtensions = (0, _pvutils.getParametersValue)(parameters, "crlEntryExtensions", RevokedCertificate.defaultValues("crlEntryExtensions")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "userCertificate": + return new asn1js.Integer(); + + case "revocationDate": + return new _Time.default(); + + case "crlEntryExtensions": + return new _Extensions.default(); + + default: + throw new Error(`Invalid member name for RevokedCertificate class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * revokedCertificates SEQUENCE OF SEQUENCE { + * userCertificate CertificateSerialNumber, + * revocationDate Time, + * crlEntryExtensions Extensions OPTIONAL + * -- if present, version MUST be v2 + * } OPTIONAL, + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [userCertificate] + * @property {string} [revocationDate] + * @property {string} [crlEntryExtensions] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Integer({ + name: names.userCertificate || "userCertificate" + }), _Time.default.schema({ + names: { + utcTimeName: names.revocationDate || "revocationDate", + generalTimeName: names.revocationDate || "revocationDate" + } + }), _Extensions.default.schema({ + names: { + blockName: names.crlEntryExtensions || "crlEntryExtensions" + } + }, true)] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["userCertificate", "revocationDate", "crlEntryExtensions"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, RevokedCertificate.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for RevokedCertificate"); //endregion + //region Get internal properties from parsed schema + + this.userCertificate = asn1.result.userCertificate; + this.revocationDate = new _Time.default({ + schema: asn1.result.revocationDate + }); + if ("crlEntryExtensions" in asn1.result) this.crlEntryExtensions = new _Extensions.default({ + schema: asn1.result.crlEntryExtensions + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = [this.userCertificate, this.revocationDate.toSchema()]; + if ("crlEntryExtensions" in this) outputArray.push(this.crlEntryExtensions.toSchema()); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const object = { + userCertificate: this.userCertificate.toJSON(), + revocationDate: this.revocationDate.toJSON + }; + if ("crlEntryExtensions" in this) object.crlEntryExtensions = this.crlEntryExtensions.toJSON(); + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = RevokedCertificate; + +},{"./Extensions.js":39,"./Time.js":107,"asn1js":112,"pvutils":113}],95:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _Attribute = _interopRequireDefault(require("./Attribute.js")); + +var _PrivateKeyInfo = _interopRequireDefault(require("./PrivateKeyInfo.js")); + +var _PKCS8ShroudedKeyBag = _interopRequireDefault(require("./PKCS8ShroudedKeyBag.js")); + +var _CertBag = _interopRequireDefault(require("./CertBag.js")); + +var _CRLBag = _interopRequireDefault(require("./CRLBag.js")); + +var _SecretBag = _interopRequireDefault(require("./SecretBag.js")); + +var _SafeContents = _interopRequireDefault(require("./SafeContents.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC7292 + */ +class SafeBag { + //********************************************************************************** + + /** + * Constructor for SafeBag class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc bagId + */ + this.bagId = (0, _pvutils.getParametersValue)(parameters, "bagId", SafeBag.defaultValues("bagId")); + /** + * @type {*} + * @desc bagValue + */ + + this.bagValue = (0, _pvutils.getParametersValue)(parameters, "bagValue", SafeBag.defaultValues("bagValue")); + if ("bagAttributes" in parameters) + /** + * @type {Array.} + * @desc bagAttributes + */ + this.bagAttributes = (0, _pvutils.getParametersValue)(parameters, "bagAttributes", SafeBag.defaultValues("bagAttributes")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "bagId": + return ""; + + case "bagValue": + return new asn1js.Any(); + + case "bagAttributes": + return []; + + default: + throw new Error(`Invalid member name for SafeBag class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "bagId": + return memberValue === ""; + + case "bagValue": + return memberValue instanceof asn1js.Any; + + case "bagAttributes": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for SafeBag class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * SafeBag ::= SEQUENCE { + * bagId BAG-TYPE.&id ({PKCS12BagSet}), + * bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}), + * bagAttributes SET OF PKCS12Attribute OPTIONAL + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [bagId] + * @property {string} [bagValue] + * @property {string} [bagAttributes] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.bagId || "bagId" + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Any({ + name: names.bagValue || "bagValue" + })] // EXPLICIT ANY value + + }), new asn1js.Set({ + optional: true, + value: [new asn1js.Repeated({ + name: names.bagAttributes || "bagAttributes", + value: _Attribute.default.schema() + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["bagId", "bagValue", "bagAttributes"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, SafeBag.schema({ + names: { + bagId: "bagId", + bagValue: "bagValue", + bagAttributes: "bagAttributes" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for SafeBag"); //endregion + //region Get internal properties from parsed schema + + this.bagId = asn1.result.bagId.valueBlock.toString(); + + switch (this.bagId) { + case "1.2.840.113549.1.12.10.1.1": + // keyBag + this.bagValue = new _PrivateKeyInfo.default({ + schema: asn1.result.bagValue + }); + break; + + case "1.2.840.113549.1.12.10.1.2": + // pkcs8ShroudedKeyBag + this.bagValue = new _PKCS8ShroudedKeyBag.default({ + schema: asn1.result.bagValue + }); + break; + + case "1.2.840.113549.1.12.10.1.3": + // certBag + this.bagValue = new _CertBag.default({ + schema: asn1.result.bagValue + }); + break; + + case "1.2.840.113549.1.12.10.1.4": + // crlBag + this.bagValue = new _CRLBag.default({ + schema: asn1.result.bagValue + }); + break; + + case "1.2.840.113549.1.12.10.1.5": + // secretBag + this.bagValue = new _SecretBag.default({ + schema: asn1.result.bagValue + }); + break; + + case "1.2.840.113549.1.12.10.1.6": + // safeContentsBag + this.bagValue = new _SafeContents.default({ + schema: asn1.result.bagValue + }); + break; + + default: + throw new Error(`Invalid "bagId" for SafeBag: ${this.bagId}`); + } + + if ("bagAttributes" in asn1.result) this.bagAttributes = Array.from(asn1.result.bagAttributes, element => new _Attribute.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + const outputArray = [new asn1js.ObjectIdentifier({ + value: this.bagId + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [this.bagValue.toSchema()] + })]; + + if ("bagAttributes" in this) { + outputArray.push(new asn1js.Set({ + value: Array.from(this.bagAttributes, element => element.toSchema()) + })); + } + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const output = { + bagId: this.bagId, + bagValue: this.bagValue.toJSON() + }; + if ("bagAttributes" in this) output.bagAttributes = Array.from(this.bagAttributes, element => element.toJSON()); + return output; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = SafeBag; + +},{"./Attribute.js":6,"./CRLBag.js":15,"./CertBag.js":17,"./PKCS8ShroudedKeyBag.js":68,"./PrivateKeyInfo.js":76,"./SafeContents.js":96,"./SecretBag.js":97,"asn1js":112,"pvutils":113}],96:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _SafeBag = _interopRequireDefault(require("./SafeBag.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC7292 + */ +class SafeContents { + //********************************************************************************** + + /** + * Constructor for SafeContents class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc safeBags + */ + this.safeBags = (0, _pvutils.getParametersValue)(parameters, "safeBags", SafeContents.defaultValues("safeBags")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "safeBags": + return []; + + default: + throw new Error(`Invalid member name for SafeContents class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "safeBags": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for SafeContents class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * SafeContents ::= SEQUENCE OF SafeBag + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [safeBags] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.safeBags || "", + value: _SafeBag.default.schema() + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["safeBags"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, SafeContents.schema({ + names: { + safeBags: "safeBags" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for SafeContents"); //endregion + //region Get internal properties from parsed schema + + this.safeBags = Array.from(asn1.result.safeBags, element => new _SafeBag.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: Array.from(this.safeBags, element => element.toSchema()) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + safeBags: Array.from(this.safeBags, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = SafeContents; + +},{"./SafeBag.js":95,"asn1js":112,"pvutils":113}],97:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC7292 + */ +class SecretBag { + //********************************************************************************** + + /** + * Constructor for SecretBag class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc secretTypeId + */ + this.secretTypeId = (0, _pvutils.getParametersValue)(parameters, "secretTypeId", SecretBag.defaultValues("secretTypeId")); + /** + * @type {*} + * @desc secretValue + */ + + this.secretValue = (0, _pvutils.getParametersValue)(parameters, "secretValue", SecretBag.defaultValues("secretValue")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "secretTypeId": + return ""; + + case "secretValue": + return new asn1js.Any(); + + default: + throw new Error(`Invalid member name for SecretBag class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "secretTypeId": + return memberValue === ""; + + case "secretValue": + return memberValue instanceof asn1js.Any; + + default: + throw new Error(`Invalid member name for SecretBag class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * SecretBag ::= SEQUENCE { + * secretTypeId BAG-TYPE.&id ({SecretTypes}), + * secretValue [0] EXPLICIT BAG-TYPE.&Type ({SecretTypes}{@secretTypeId}) + * } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [id] + * @property {string} [value] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.ObjectIdentifier({ + name: names.id || "id" + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Any({ + name: names.value || "value" + })] // EXPLICIT ANY value + + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["secretTypeId", "secretValue"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, SecretBag.schema({ + names: { + id: "secretTypeId", + value: "secretValue" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for SecretBag"); //endregion + //region Get internal properties from parsed schema + + this.secretTypeId = asn1.result.secretTypeId.valueBlock.toString(); + this.secretValue = asn1.result.secretValue; //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: [new asn1js.ObjectIdentifier({ + value: this.secretTypeId + }), new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [this.secretValue.toSchema()] + })] + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + secretTypeId: this.secretTypeId, + secretValue: this.secretValue.toJSON() + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = SecretBag; + +},{"asn1js":112,"pvutils":113}],98:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _Certificate = _interopRequireDefault(require("./Certificate.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC6960 + */ +class Signature { + //********************************************************************************** + + /** + * Constructor for Signature class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {AlgorithmIdentifier} + * @desc signatureAlgorithm + */ + this.signatureAlgorithm = (0, _pvutils.getParametersValue)(parameters, "signatureAlgorithm", Signature.defaultValues("signatureAlgorithm")); + /** + * @type {BitString} + * @desc signature + */ + + this.signature = (0, _pvutils.getParametersValue)(parameters, "signature", Signature.defaultValues("signature")); + if ("certs" in parameters) + /** + * @type {Array.} + * @desc certs + */ + this.certs = (0, _pvutils.getParametersValue)(parameters, "certs", Signature.defaultValues("certs")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "signatureAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "signature": + return new asn1js.BitString(); + + case "certs": + return []; + + default: + throw new Error(`Invalid member name for Signature class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "signatureAlgorithm": + return memberValue.algorithmId === "" && "algorithmParams" in memberValue === false; + + case "signature": + return memberValue.isEqual(Signature.defaultValues(memberName)); + + case "certs": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for Signature class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * Signature ::= SEQUENCE { + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [signatureAlgorithm] + * @property {string} [signature] + * @property {string} [certs] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_AlgorithmIdentifier.default.schema(names.signatureAlgorithm || {}), new asn1js.BitString({ + name: names.signature || "" + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Sequence({ + value: [new asn1js.Repeated({ + name: names.certs || "", + value: _Certificate.default.schema(names.certs || {}) + })] + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["signatureAlgorithm", "signature", "certs"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, Signature.schema({ + names: { + signatureAlgorithm: { + names: { + blockName: "signatureAlgorithm" + } + }, + signature: "signature", + certs: "certs" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for Signature"); //endregion + //region Get internal properties from parsed schema + + this.signatureAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result.signatureAlgorithm + }); + this.signature = asn1.result.signature; + if ("certs" in asn1.result) this.certs = Array.from(asn1.result.certs, element => new _Certificate.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array of output sequence + const outputArray = []; + outputArray.push(this.signatureAlgorithm.toSchema()); + outputArray.push(this.signature); + + if ("certs" in this) { + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Sequence({ + value: Array.from(this.certs, element => element.toSchema()) + })] + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + signatureAlgorithm: this.signatureAlgorithm.toJSON(), + signature: this.signature.toJSON() + }; + if ("certs" in this) _object.certs = Array.from(this.certs, element => element.toJSON()); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = Signature; + +},{"./AlgorithmIdentifier.js":4,"./Certificate.js":19,"asn1js":112,"pvutils":113}],99:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _Attribute = _interopRequireDefault(require("./Attribute.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class SignedAndUnsignedAttributes { + //********************************************************************************** + + /** + * Constructor for SignedAndUnsignedAttributes class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc type + */ + this.type = (0, _pvutils.getParametersValue)(parameters, "type", SignedAndUnsignedAttributes.defaultValues("type")); + /** + * @type {Array} + * @desc attributes + */ + + this.attributes = (0, _pvutils.getParametersValue)(parameters, "attributes", SignedAndUnsignedAttributes.defaultValues("attributes")); + /** + * @type {ArrayBuffer} + * @desc encodedValue Need to have it in order to successfully process with signature verification + */ + + this.encodedValue = (0, _pvutils.getParametersValue)(parameters, "encodedValue", SignedAndUnsignedAttributes.defaultValues("encodedValue")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "type": + return -1; + + case "attributes": + return []; + + case "encodedValue": + return new ArrayBuffer(0); + + default: + throw new Error(`Invalid member name for SignedAndUnsignedAttributes class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "type": + return memberValue === SignedAndUnsignedAttributes.defaultValues("type"); + + case "attributes": + return memberValue.length === 0; + + case "encodedValue": + return memberValue.byteLength === 0; + + default: + throw new Error(`Invalid member name for SignedAndUnsignedAttributes class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * SignedAttributes ::= SET SIZE (1..MAX) OF Attribute + * + * UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {number} [tagNumber] + * @property {string} [attributes] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Constructed({ + name: names.blockName || "", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: names.tagNumber // "SignedAttributes" = 0, "UnsignedAttributes" = 1 + + }, + value: [new asn1js.Repeated({ + name: names.attributes || "", + value: _Attribute.default.schema() + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["attributes"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, SignedAndUnsignedAttributes.schema({ + names: { + tagNumber: this.type, + attributes: "attributes" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for SignedAndUnsignedAttributes"); //endregion + //region Get internal properties from parsed schema + + this.type = asn1.result.idBlock.tagNumber; + this.encodedValue = asn1.result.valueBeforeDecode; //region Change type from "[0]" to "SET" accordingly to standard + + const encodedView = new Uint8Array(this.encodedValue); + encodedView[0] = 0x31; //endregion + + if ("attributes" in asn1.result === false) { + if (this.type === 0) throw new Error("Wrong structure of SignedUnsignedAttributes");else return; // Not so important in case of "UnsignedAttributes" + } + + this.attributes = Array.from(asn1.result.attributes, element => new _Attribute.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + if (SignedAndUnsignedAttributes.compareWithDefault("type", this.type) || SignedAndUnsignedAttributes.compareWithDefault("attributes", this.attributes)) throw new Error("Incorrectly initialized \"SignedAndUnsignedAttributes\" class"); //region Construct and return new ASN.1 schema for this object + + return new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: this.type // "SignedAttributes" = 0, "UnsignedAttributes" = 1 + + }, + value: Array.from(this.attributes, element => element.toSchema()) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + if (SignedAndUnsignedAttributes.compareWithDefault("type", this.type) || SignedAndUnsignedAttributes.compareWithDefault("attributes", this.attributes)) throw new Error("Incorrectly initialized \"SignedAndUnsignedAttributes\" class"); + return { + type: this.type, + attributes: Array.from(this.attributes, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = SignedAndUnsignedAttributes; + +},{"./Attribute.js":6,"asn1js":112,"pvutils":113}],100:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.verifySCTsForCertificate = verifySCTsForCertificate; +exports.default = exports.SignedCertificateTimestamp = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _bytestreamjs = require("bytestreamjs"); + +var _common = require("./common.js"); + +var _PublicKeyInfo = _interopRequireDefault(require("./PublicKeyInfo.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +//************************************************************************************** +class SignedCertificateTimestamp { + //********************************************************************************** + + /** + * Constructor for SignedCertificateTimestamp class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", SignedCertificateTimestamp.defaultValues("version")); + /** + * @type {ArrayBuffer} + * @desc logID + */ + + this.logID = (0, _pvutils.getParametersValue)(parameters, "logID", SignedCertificateTimestamp.defaultValues("logID")); + /** + * @type {Date} + * @desc timestamp + */ + + this.timestamp = (0, _pvutils.getParametersValue)(parameters, "timestamp", SignedCertificateTimestamp.defaultValues("timestamp")); + /** + * @type {ArrayBuffer} + * @desc extensions + */ + + this.extensions = (0, _pvutils.getParametersValue)(parameters, "extensions", SignedCertificateTimestamp.defaultValues("extensions")); + /** + * @type {string} + * @desc hashAlgorithm + */ + + this.hashAlgorithm = (0, _pvutils.getParametersValue)(parameters, "hashAlgorithm", SignedCertificateTimestamp.defaultValues("hashAlgorithm")); + /** + * @type {string} + * @desc signatureAlgorithm + */ + + this.signatureAlgorithm = (0, _pvutils.getParametersValue)(parameters, "signatureAlgorithm", SignedCertificateTimestamp.defaultValues("signatureAlgorithm")); + /** + * @type {Object} + * @desc signature + */ + + this.signature = (0, _pvutils.getParametersValue)(parameters, "signature", SignedCertificateTimestamp.defaultValues("signature")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + //region If input argument array contains "stream" + + if ("stream" in parameters) this.fromStream(parameters.stream); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 0; + + case "logID": + case "extensions": + return new ArrayBuffer(0); + + case "timestamp": + return new Date(0); + + case "hashAlgorithm": + case "signatureAlgorithm": + return ""; + + case "signature": + return new asn1js.Any(); + + default: + throw new Error(`Invalid member name for SignedCertificateTimestamp class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + if (schema instanceof asn1js.RawData === false) throw new Error("Object's schema was not verified against input data for SignedCertificateTimestamp"); + const seqStream = new _bytestreamjs.SeqStream({ + stream: new _bytestreamjs.ByteStream({ + buffer: schema.data + }) + }); + this.fromStream(seqStream); + } //********************************************************************************** + + /** + * Convert SeqStream data into current class + * @param {!SeqStream} stream + */ + + + fromStream(stream) { + const blockLength = stream.getUint16(); + this.version = stream.getBlock(1)[0]; + + if (this.version === 0) { + this.logID = new Uint8Array(stream.getBlock(32)).buffer.slice(0); + this.timestamp = new Date((0, _pvutils.utilFromBase)(new Uint8Array(stream.getBlock(8)), 8)); //region Extensions + + const extensionsLength = stream.getUint16(); + this.extensions = new Uint8Array(stream.getBlock(extensionsLength)).buffer.slice(0); //endregion + //region Hash algorithm + + switch (stream.getBlock(1)[0]) { + case 0: + this.hashAlgorithm = "none"; + break; + + case 1: + this.hashAlgorithm = "md5"; + break; + + case 2: + this.hashAlgorithm = "sha1"; + break; + + case 3: + this.hashAlgorithm = "sha224"; + break; + + case 4: + this.hashAlgorithm = "sha256"; + break; + + case 5: + this.hashAlgorithm = "sha384"; + break; + + case 6: + this.hashAlgorithm = "sha512"; + break; + + default: + throw new Error("Object's stream was not correct for SignedCertificateTimestamp"); + } //endregion + //region Signature algorithm + + + switch (stream.getBlock(1)[0]) { + case 0: + this.signatureAlgorithm = "anonymous"; + break; + + case 1: + this.signatureAlgorithm = "rsa"; + break; + + case 2: + this.signatureAlgorithm = "dsa"; + break; + + case 3: + this.signatureAlgorithm = "ecdsa"; + break; + + default: + throw new Error("Object's stream was not correct for SignedCertificateTimestamp"); + } //endregion + //region Signature + + + const signatureLength = stream.getUint16(); + const signatureData = new Uint8Array(stream.getBlock(signatureLength)).buffer.slice(0); + const asn1 = asn1js.fromBER(signatureData); + if (asn1.offset === -1) throw new Error("Object's stream was not correct for SignedCertificateTimestamp"); + this.signature = asn1.result; //endregion + + if (blockLength !== 47 + extensionsLength + signatureLength) throw new Error("Object's stream was not correct for SignedCertificateTimestamp"); + } + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + const stream = this.toStream(); + return new asn1js.RawData({ + data: stream.stream.buffer + }); + } //********************************************************************************** + + /** + * Convert current object to SeqStream data + * @returns {SeqStream} SeqStream object + */ + + + toStream() { + const stream = new _bytestreamjs.SeqStream(); + stream.appendUint16(47 + this.extensions.byteLength + this.signature.valueBeforeDecode.byteLength); + stream.appendChar(this.version); + stream.appendView(new Uint8Array(this.logID)); + const timeBuffer = new ArrayBuffer(8); + const timeView = new Uint8Array(timeBuffer); + const baseArray = (0, _pvutils.utilToBase)(this.timestamp.valueOf(), 8); + timeView.set(new Uint8Array(baseArray), 8 - baseArray.byteLength); + stream.appendView(timeView); + stream.appendUint16(this.extensions.byteLength); + if (this.extensions.byteLength) stream.appendView(new Uint8Array(this.extensions)); + + let _hashAlgorithm; + + switch (this.hashAlgorithm.toLowerCase()) { + case "none": + _hashAlgorithm = 0; + break; + + case "md5": + _hashAlgorithm = 1; + break; + + case "sha1": + _hashAlgorithm = 2; + break; + + case "sha224": + _hashAlgorithm = 3; + break; + + case "sha256": + _hashAlgorithm = 4; + break; + + case "sha384": + _hashAlgorithm = 5; + break; + + case "sha512": + _hashAlgorithm = 6; + break; + + default: + throw new Error(`Incorrect data for hashAlgorithm: ${this.hashAlgorithm}`); + } + + stream.appendChar(_hashAlgorithm); + + let _signatureAlgorithm; + + switch (this.signatureAlgorithm.toLowerCase()) { + case "anonymous": + _signatureAlgorithm = 0; + break; + + case "rsa": + _signatureAlgorithm = 1; + break; + + case "dsa": + _signatureAlgorithm = 2; + break; + + case "ecdsa": + _signatureAlgorithm = 3; + break; + + default: + throw new Error(`Incorrect data for signatureAlgorithm: ${this.signatureAlgorithm}`); + } + + stream.appendChar(_signatureAlgorithm); + + const _signature = this.signature.toBER(false); + + stream.appendUint16(_signature.byteLength); + stream.appendView(new Uint8Array(_signature)); + return stream; + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + version: this.version, + logID: (0, _pvutils.bufferToHexCodes)(this.logID), + timestamp: this.timestamp, + extensions: (0, _pvutils.bufferToHexCodes)(this.extensions), + hashAlgorithm: this.hashAlgorithm, + signatureAlgorithm: this.signatureAlgorithm, + signature: this.signature.toJSON() + }; + } //********************************************************************************** + + /** + * Verify SignedCertificateTimestamp for specific input data + * @param {Object[]} logs Array of objects with information about each CT Log (like here: https://ct.grahamedgecombe.com/logs.json) + * @param {String} logs.log_id Identifier of the CT Log encoded in BASE-64 format + * @param {String} logs.key Public key of the CT Log encoded in BASE-64 format + * @param {ArrayBuffer} data Data to verify signature against. Could be encoded Certificate or encoded PreCert + * @param {Number} [dataType=0] Type = 0 (data is encoded Certificate), type = 1 (data is encoded PreCert) + * @return {Promise} + */ + + + verify(logs, data, dataType = 0) { + var _this = this; + + return _asyncToGenerator(function* () { + //region Initial variables + let logId = (0, _pvutils.toBase64)((0, _pvutils.arrayBufferToString)(_this.logID)); + let publicKeyBase64 = null; + let publicKeyInfo; + let stream = new _bytestreamjs.SeqStream(); //endregion + //region Found and init public key + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = logs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + const log = _step.value; + + if (log.log_id === logId) { + publicKeyBase64 = log.key; + break; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + if (publicKeyBase64 === null) throw new Error(`Public key not found for CT with logId: ${logId}`); + const asn1 = asn1js.fromBER((0, _pvutils.stringToArrayBuffer)((0, _pvutils.fromBase64)(publicKeyBase64))); + if (asn1.offset === -1) throw new Error(`Incorrect key value for CT Log with logId: ${logId}`); + publicKeyInfo = new _PublicKeyInfo.default({ + schema: asn1.result + }); //endregion + //region Initialize signed data block + + stream.appendChar(0x00); // sct_version + + stream.appendChar(0x00); // signature_type = certificate_timestamp + + const timeBuffer = new ArrayBuffer(8); + const timeView = new Uint8Array(timeBuffer); + const baseArray = (0, _pvutils.utilToBase)(_this.timestamp.valueOf(), 8); + timeView.set(new Uint8Array(baseArray), 8 - baseArray.byteLength); + stream.appendView(timeView); + stream.appendUint16(dataType); + if (dataType === 0) 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 + //region Perform verification + + return (0, _common.getEngine)().subtle.verifyWithPublicKey(stream._stream._buffer.slice(0, stream._length), { + valueBlock: { + valueHex: _this.signature.toBER(false) + } + }, publicKeyInfo, { + algorithmId: "" + }, "SHA-256"); //endregion + })(); + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * Class from RFC6962 + */ + + +exports.SignedCertificateTimestamp = SignedCertificateTimestamp; + +class SignedCertificateTimestampList { + //********************************************************************************** + + /** + * Constructor for SignedCertificateTimestampList class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc timestamps + */ + this.timestamps = (0, _pvutils.getParametersValue)(parameters, "timestamps", SignedCertificateTimestampList.defaultValues("timestamps")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "timestamps": + return []; + + default: + throw new Error(`Invalid member name for SignedCertificateTimestampList class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "timestamps": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for SignedCertificateTimestampList class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * SignedCertificateTimestampList ::= OCTET STRING + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [optional] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + if ("optional" in names === false) names.optional = false; + return new asn1js.OctetString({ + name: names.blockName || "SignedCertificateTimestampList", + optional: names.optional + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Check the schema is valid + if (schema instanceof asn1js.OctetString === false) throw new Error("Object's schema was not verified against input data for SignedCertificateTimestampList"); //endregion + //region Get internal properties from parsed schema + + const seqStream = new _bytestreamjs.SeqStream({ + stream: new _bytestreamjs.ByteStream({ + buffer: schema.valueBlock.valueHex + }) + }); + let dataLength = seqStream.getUint16(); + if (dataLength !== seqStream.length) throw new Error("Object's schema was not verified against input data for SignedCertificateTimestampList"); + + while (seqStream.length) this.timestamps.push(new SignedCertificateTimestamp({ + stream: seqStream + })); //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Initial variables + const stream = new _bytestreamjs.SeqStream(); + let overallLength = 0; + const timestampsData = []; //endregion + //region Get overall length + + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.timestamps[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + const timestamp = _step2.value; + const timestampStream = timestamp.toStream(); + timestampsData.push(timestampStream); + overallLength += timestampStream.stream.buffer.byteLength; + } //endregion + + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return != null) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + stream.appendUint16(overallLength); //region Set data from all timestamps + + for (var _i = 0, _timestampsData = timestampsData; _i < _timestampsData.length; _i++) { + const timestamp = _timestampsData[_i]; + stream.appendView(timestamp.stream.view); + } //endregion + + + return new asn1js.OctetString({ + valueHex: stream.stream.buffer.slice(0) + }); + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + timestamps: Array.from(this.timestamps, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * Verify SignedCertificateTimestamp for specific certificate content + * @param {Certificate} certificate Certificate for which verification would be performed + * @param {Certificate} issuerCertificate Certificate of the issuer of target certificate + * @param {Object[]} logs Array of objects with information about each CT Log (like here: https://ct.grahamedgecombe.com/logs.json) + * @param {String} logs.log_id Identifier of the CT Log encoded in BASE-64 format + * @param {String} logs.key Public key of the CT Log encoded in BASE-64 format + * @param {Number} [index=-1] Index of SignedCertificateTimestamp inside SignedCertificateTimestampList (for -1 would verify all) + * @return {Array} Array of verification results + */ + + +exports.default = SignedCertificateTimestampList; + +function verifySCTsForCertificate(_x, _x2, _x3) { + return _verifySCTsForCertificate.apply(this, arguments); +} //********************************************************************************** + + +function _verifySCTsForCertificate() { + _verifySCTsForCertificate = _asyncToGenerator(function* (certificate, issuerCertificate, logs, index = -1) { + //region Initial variables + let parsedValue = null; + let tbs; + let issuerId; + const stream = new _bytestreamjs.SeqStream(); + let preCert; //endregion + //region Get a "crypto" extension + + const crypto = (0, _common.getCrypto)(); + if (typeof crypto === "undefined") return Promise.reject("Unable to create WebCrypto object"); //endregion + //region Remove certificate extension + + for (let i = 0; i < certificate.extensions.length; i++) { + switch (certificate.extensions[i].extnID) { + case "1.3.6.1.4.1.11129.2.4.2": + { + parsedValue = certificate.extensions[i].parsedValue; + if (parsedValue.timestamps.length === 0) throw new Error("Nothing to verify in the certificate"); + certificate.extensions.splice(i, 1); + } + break; + + default: + } + } //endregion + //region Check we do have what to verify + + + if (parsedValue === null) throw new Error("No SignedCertificateTimestampList extension in the specified certificate"); //endregion + //region Prepare modifier TBS value + + tbs = certificate.encodeTBS().toBER(false); //endregion + //region Initialize "issuer_key_hash" value + + issuerId = yield crypto.digest({ + name: "SHA-256" + }, new Uint8Array(issuerCertificate.subjectPublicKeyInfo.toSchema().toBER(false))); //endregion + //region Make final "PreCert" value + + stream.appendView(new Uint8Array(issuerId)); + stream.appendUint24(tbs.byteLength); + stream.appendView(new Uint8Array(tbs)); + preCert = stream._stream._buffer.slice(0, stream._length); //endregion + //region Call verification function for specified index + + if (index === -1) { + const verifyArray = []; + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = parsedValue.timestamps[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + const timestamp = _step3.value; + const verifyResult = yield timestamp.verify(logs, preCert, 1); + verifyArray.push(verifyResult); + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3.return != null) { + _iterator3.return(); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return verifyArray; + } + + if (index >= parsedValue.timestamps.length) index = parsedValue.timestamps.length - 1; + return [yield parsedValue.timestamps[index].verify(logs, preCert, 1)]; //endregion + }); + return _verifySCTsForCertificate.apply(this, arguments); +} + +},{"./PublicKeyInfo.js":78,"./common.js":110,"asn1js":112,"bytestreamjs":1,"pvutils":113}],101:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _common = require("./common.js"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _EncapsulatedContentInfo = _interopRequireDefault(require("./EncapsulatedContentInfo.js")); + +var _Certificate = _interopRequireDefault(require("./Certificate.js")); + +var _CertificateRevocationList = _interopRequireDefault(require("./CertificateRevocationList.js")); + +var _OtherRevocationInfoFormat = _interopRequireDefault(require("./OtherRevocationInfoFormat.js")); + +var _SignerInfo = _interopRequireDefault(require("./SignerInfo.js")); + +var _CertificateSet = _interopRequireDefault(require("./CertificateSet.js")); + +var _RevocationInfoChoices = _interopRequireDefault(require("./RevocationInfoChoices.js")); + +var _IssuerAndSerialNumber = _interopRequireDefault(require("./IssuerAndSerialNumber.js")); + +var _TSTInfo = _interopRequireDefault(require("./TSTInfo.js")); + +var _CertificateChainValidationEngine = _interopRequireDefault(require("./CertificateChainValidationEngine.js")); + +var _BasicOCSPResponse = _interopRequireDefault(require("./BasicOCSPResponse.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } + +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } + +function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } + +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class SignedData { + //********************************************************************************** + + /** + * Constructor for SignedData class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", SignedData.defaultValues("version")); + /** + * @type {Array.} + * @desc digestAlgorithms + */ + + this.digestAlgorithms = (0, _pvutils.getParametersValue)(parameters, "digestAlgorithms", SignedData.defaultValues("digestAlgorithms")); + /** + * @type {EncapsulatedContentInfo} + * @desc encapContentInfo + */ + + this.encapContentInfo = (0, _pvutils.getParametersValue)(parameters, "encapContentInfo", SignedData.defaultValues("encapContentInfo")); + if ("certificates" in parameters) + /** + * @type {Array.} + * @desc certificates + */ + this.certificates = (0, _pvutils.getParametersValue)(parameters, "certificates", SignedData.defaultValues("certificates")); + if ("crls" in parameters) + /** + * @type {Array.} + * @desc crls + */ + this.crls = (0, _pvutils.getParametersValue)(parameters, "crls", SignedData.defaultValues("crls")); + if ("ocsps" in parameters) + /** + * @type {Array.} + * @desc crls + */ + this.ocsps = (0, _pvutils.getParametersValue)(parameters, "ocsps", SignedData.defaultValues("ocsps")); + /** + * @type {Array.} + * @desc signerInfos + */ + + this.signerInfos = (0, _pvutils.getParametersValue)(parameters, "signerInfos", SignedData.defaultValues("signerInfos")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 0; + + case "digestAlgorithms": + return []; + + case "encapContentInfo": + return new _EncapsulatedContentInfo.default(); + + case "certificates": + return []; + + case "crls": + return []; + + case "ocsps": + return []; + + case "signerInfos": + return []; + + default: + throw new Error(`Invalid member name for SignedData class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "version": + return memberValue === SignedData.defaultValues("version"); + + case "encapContentInfo": + return new _EncapsulatedContentInfo.default(); + + case "digestAlgorithms": + case "certificates": + case "crls": + case "ocsps": + case "signerInfos": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for SignedData class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * SignedData ::= SEQUENCE { + * version CMSVersion, + * digestAlgorithms DigestAlgorithmIdentifiers, + * encapContentInfo EncapsulatedContentInfo, + * certificates [0] IMPLICIT CertificateSet OPTIONAL, + * crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, + * signerInfos SignerInfos } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [optional] + * @property {string} [digestAlgorithms] + * @property {string} [encapContentInfo] + * @property {string} [certificates] + * @property {string} [crls] + * @property {string} [signerInfos] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + if ("optional" in names === false) names.optional = false; + return new asn1js.Sequence({ + name: names.blockName || "SignedData", + optional: names.optional, + value: [new asn1js.Integer({ + name: names.version || "SignedData.version" + }), new asn1js.Set({ + value: [new asn1js.Repeated({ + name: names.digestAlgorithms || "SignedData.digestAlgorithms", + value: _AlgorithmIdentifier.default.schema() + })] + }), _EncapsulatedContentInfo.default.schema(names.encapContentInfo || { + names: { + blockName: "SignedData.encapContentInfo" + } + }), new asn1js.Constructed({ + name: names.certificates || "SignedData.certificates", + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: _CertificateSet.default.schema().valueBlock.value + }), // IMPLICIT CertificateSet + new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: _RevocationInfoChoices.default.schema(names.crls || { + names: { + crls: "SignedData.crls" + } + }).valueBlock.value + }), // IMPLICIT RevocationInfoChoices + new asn1js.Set({ + value: [new asn1js.Repeated({ + name: names.signerInfos || "SignedData.signerInfos", + value: _SignerInfo.default.schema() + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["SignedData.version", "SignedData.digestAlgorithms", "SignedData.encapContentInfo", "SignedData.certificates", "SignedData.crls", "SignedData.signerInfos"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, SignedData.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for SignedData"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result["SignedData.version"].valueBlock.valueDec; + if ("SignedData.digestAlgorithms" in asn1.result) // Could be empty SET of digest algorithms + this.digestAlgorithms = Array.from(asn1.result["SignedData.digestAlgorithms"], algorithm => new _AlgorithmIdentifier.default({ + schema: algorithm + })); + this.encapContentInfo = new _EncapsulatedContentInfo.default({ + schema: asn1.result["SignedData.encapContentInfo"] + }); + + if ("SignedData.certificates" in asn1.result) { + const certificateSet = new _CertificateSet.default({ + schema: new asn1js.Set({ + value: asn1.result["SignedData.certificates"].valueBlock.value + }) + }); + this.certificates = certificateSet.certificates.slice(0); // Copy all just for making comfortable access + } + + if ("SignedData.crls" in asn1.result) { + this.crls = Array.from(asn1.result["SignedData.crls"], crl => { + if (crl.idBlock.tagClass === 1) return new _CertificateRevocationList.default({ + schema: crl + }); //region Create SEQUENCE from [1] + + crl.idBlock.tagClass = 1; // UNIVERSAL + + crl.idBlock.tagNumber = 16; // SEQUENCE + //endregion + + return new _OtherRevocationInfoFormat.default({ + schema: crl + }); + }); + } + + if ("SignedData.signerInfos" in asn1.result) // Could be empty SET SignerInfos + this.signerInfos = Array.from(asn1.result["SignedData.signerInfos"], signerInfoSchema => new _SignerInfo.default({ + schema: signerInfoSchema + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema(encodeFlag = false) { + //region Create array for output sequence + const outputArray = []; + outputArray.push(new asn1js.Integer({ + value: this.version + })); //region Create array of digest algorithms + + outputArray.push(new asn1js.Set({ + value: Array.from(this.digestAlgorithms, algorithm => algorithm.toSchema(encodeFlag)) + })); //endregion + + outputArray.push(this.encapContentInfo.toSchema()); + + if ("certificates" in this) { + const certificateSet = new _CertificateSet.default({ + certificates: this.certificates + }); + const certificateSetSchema = certificateSet.toSchema(); + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + tagNumber: 0 + }, + value: certificateSetSchema.valueBlock.value + })); + } + + if ("crls" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: Array.from(this.crls, crl => { + if (crl instanceof _OtherRevocationInfoFormat.default) { + const crlSchema = crl.toSchema(encodeFlag); + crlSchema.idBlock.tagClass = 3; + crlSchema.idBlock.tagNumber = 1; + return crlSchema; + } + + return crl.toSchema(encodeFlag); + }) + })); + } //region Create array of signer infos + + + outputArray.push(new asn1js.Set({ + value: Array.from(this.signerInfos, signerInfo => signerInfo.toSchema(encodeFlag)) + })); //endregion + //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + version: this.version, + digestAlgorithms: Array.from(this.digestAlgorithms, algorithm => algorithm.toJSON()), + encapContentInfo: this.encapContentInfo.toJSON() + }; + if ("certificates" in this) _object.certificates = Array.from(this.certificates, certificate => certificate.toJSON()); + if ("crls" in this) _object.crls = Array.from(this.crls, crl => crl.toJSON()); + _object.signerInfos = Array.from(this.signerInfos, signerInfo => signerInfo.toJSON()); + return _object; + } //********************************************************************************** + + /** + * Verify current SignedData value + * @param {Object} [param={}] + * @param {Number} [param.signer = -1] Index of the signer which information we need to verify + * @param {ArrayBuffer} [param.data=new ArrayBuffer(0)] + * @param {Array.} [param.trustedCerts=[]] + * @param {Date} [param.checkDate=new Date()] + * @param {Boolean} [param.checkChain=false] + * @param {Boolean} [param.extendedMode=false] + * @param {?Function} [findOrigin=null] + * @param {?Function} [findIssuer=null] + */ + + + verify({ + signer = -1, + data = new ArrayBuffer(0), + trustedCerts = [], + checkDate = new Date(), + checkChain = false, + extendedMode = false, + passedWhenNotRevValues = false, + findOrigin = null, + findIssuer = null + } = {}) { + //region Global variables + let sequence = Promise.resolve(); + let messageDigestValue = new ArrayBuffer(0); + let shaAlgorithm = ""; + let signerCertificate = {}; + let timestampSerial = null; + let certificatePath = []; + const engine = (0, _common.getEngine)(); //endregion + //region Get a "crypto" extension + + const crypto = (0, _common.getCrypto)(); + if (typeof crypto === "undefined") return Promise.reject("Unable to create WebCrypto object"); //endregion + //region Get a signer number + + if (signer === -1) { + if (extendedMode) { + return Promise.reject({ + date: checkDate, + code: 1, + message: "Unable to get signer index from input parameters", + signatureVerified: null, + signerCertificate: null, + signerCertificateVerified: null + }); + } + + return Promise.reject("Unable to get signer index from input parameters"); + } //endregion + //region Check that certificates field was included in signed data + + + if ("certificates" in this === false) { + if (extendedMode) { + return Promise.reject({ + date: checkDate, + code: 2, + message: "No certificates attached to this signed data", + signatureVerified: null, + signerCertificate: null, + signerCertificateVerified: null + }); + } + + return Promise.reject("No certificates attached to this signed data"); + } //endregion + //region Find a certificate for specified signer + + + if (this.signerInfos[signer].sid instanceof _IssuerAndSerialNumber.default) { + sequence = sequence.then(() => { + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.certificates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + const certificate = _step.value; + if (certificate instanceof _Certificate.default === false) continue; + + if (certificate.issuer.isEqual(this.signerInfos[signer].sid.issuer) && certificate.serialNumber.isEqual(this.signerInfos[signer].sid.serialNumber)) { + signerCertificate = certificate; + return Promise.resolve(); + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + if (extendedMode) { + return Promise.reject({ + date: checkDate, + code: 3, + message: "Unable to find signer certificate", + signatureVerified: null, + signerCertificate: null, + signerCertificateVerified: null + }); + } + + return Promise.reject("Unable to find signer certificate"); + }); + } else // Find by SubjectKeyIdentifier + { + sequence = sequence.then(() => Promise.all(Array.from(this.certificates.filter(certificate => certificate instanceof _Certificate.default), certificate => crypto.digest({ + name: "sha-1" + }, new Uint8Array(certificate.subjectPublicKeyInfo.subjectPublicKey.valueBlock.valueHex)))).then(results => { + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.certificates.entries()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + const _step2$value = _slicedToArray(_step2.value, 2), + index = _step2$value[0], + certificate = _step2$value[1]; + + if (certificate instanceof _Certificate.default === false) continue; + + if ((0, _pvutils.isEqualBuffer)(results[index], this.signerInfos[signer].sid.valueBlock.valueHex)) { + signerCertificate = certificate; + return Promise.resolve(); + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return != null) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + if (extendedMode) { + return Promise.reject({ + date: checkDate, + code: 3, + message: "Unable to find signer certificate", + signatureVerified: null, + signerCertificate: null, + signerCertificateVerified: null + }); + } + + return Promise.reject("Unable to find signer certificate"); + }, () => { + if (extendedMode) { + return Promise.reject({ + date: checkDate, + code: 3, + message: "Unable to find signer certificate", + signatureVerified: null, + signerCertificate: null, + signerCertificateVerified: null + }); + } + + return Promise.reject("Unable to find signer certificate"); + })); + } //endregion + //region Verify internal digest in case of "tSTInfo" content type + + + sequence = sequence.then(() => { + if (this.encapContentInfo.eContentType === "1.2.840.113549.1.9.16.1.4") { + //region Check "eContent" precense + if ("eContent" in this.encapContentInfo === false) return false; //endregion + //region Initialize TST_INFO value + + const asn1 = asn1js.fromBER(this.encapContentInfo.eContent.valueBlock.valueHex); + let tstInfo; + + try { + tstInfo = new _TSTInfo.default({ + schema: asn1.result + }); + } catch (ex) { + return false; + } //endregion + //region Change "checkDate" and append "timestampSerial" + + + checkDate = tstInfo.genTime; + timestampSerial = tstInfo.serialNumber.valueBlock.valueHex; //endregion + //region Check that we do have detached data content + + if (data.byteLength === 0) { + if (extendedMode) { + return Promise.reject({ + date: checkDate, + code: 4, + message: "Missed detached data input array", + signatureVerified: null, + signerCertificate, + signerCertificateVerified: null + }); + } + + return Promise.reject("Missed detached data input array"); + } //endregion + + + return tstInfo.verify({ + data + }); + } + + return true; + }); //endregion + //region Make additional verification for signer's certificate + + function checkCA(cert) { + /// Certificate to find CA flag for + //region Do not include signer's certificate + if (cert.issuer.isEqual(signerCertificate.issuer) === true && cert.serialNumber.isEqual(signerCertificate.serialNumber) === true) return null; //endregion + + let isCA = false; + + if ("extensions" in cert) { + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = cert.extensions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + const extension = _step3.value; + + if (extension.extnID === "2.5.29.19") // BasicConstraints + { + if ("cA" in extension.parsedValue) { + if (extension.parsedValue.cA === true) isCA = true; + } + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3.return != null) { + _iterator3.return(); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + } + + if (isCA) return cert; + return null; + } + + if (checkChain) { + sequence = sequence.then(result => { + //region Verify result of previous operation + if (result === false) return false; //endregion + + const promiseResults = Array.from(this.certificates.filter(certificate => certificate instanceof _Certificate.default), certificate => checkCA(certificate)); + const certificateChainValidationEngineParameters = { + checkDate, + certs: Array.from(promiseResults.filter(_result => _result !== null)), + trustedCerts + }; + if (findIssuer !== null) certificateChainValidationEngineParameters.findIssuer = findIssuer; + if (findOrigin !== null) certificateChainValidationEngineParameters.findOrigin = findOrigin; + const certificateChainEngine = new _CertificateChainValidationEngine.default(certificateChainValidationEngineParameters); + certificateChainEngine.certs.push(signerCertificate); + + if ("crls" in this) { + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = this.crls[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + const crl = _step4.value; + if ("thisUpdate" in crl) certificateChainEngine.crls.push(crl);else // Assumed "revocation value" has "OtherRevocationInfoFormat" + { + if (crl.otherRevInfoFormat === "1.3.6.1.5.5.7.48.1.1") // Basic OCSP response + certificateChainEngine.ocsps.push(new _BasicOCSPResponse.default({ + schema: crl.otherRevInfo + })); + } + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4.return != null) { + _iterator4.return(); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + } + + if ("ocsps" in this) certificateChainEngine.ocsps.push(...this.ocsps); + return certificateChainEngine.verify({ + passedWhenNotRevValues + }).then(verificationResult => { + if ("certificatePath" in verificationResult) certificatePath = verificationResult.certificatePath; + if (verificationResult.result === true) return Promise.resolve(true); + + if (extendedMode) { + return Promise.reject({ + date: checkDate, + code: 5, + message: `Validation of signer's certificate failed: ${verificationResult.resultMessage}`, + signatureVerified: null, + signerCertificate, + signerCertificateVerified: false + }); + } + + return Promise.reject("Validation of signer's certificate failed"); + }, error => { + if (extendedMode) { + return Promise.reject({ + date: checkDate, + code: 5, + message: `Validation of signer's certificate failed with error: ${error instanceof Object ? error.resultMessage : error}`, + signatureVerified: null, + signerCertificate, + signerCertificateVerified: false + }); + } + + return Promise.reject(`Validation of signer's certificate failed with error: ${error instanceof Object ? error.resultMessage : error}`); + }); + }); + } //endregion + //region Find signer's hashing algorithm + + + sequence = sequence.then(result => { + //region Verify result of previous operation + if (result === false) return false; //endregion + + const signerInfoHashAlgorithm = (0, _common.getAlgorithmByOID)(this.signerInfos[signer].digestAlgorithm.algorithmId); + + if ("name" in signerInfoHashAlgorithm === false) { + if (extendedMode) { + return Promise.reject({ + date: checkDate, + code: 7, + message: `Unsupported signature algorithm: ${this.signerInfos[signer].digestAlgorithm.algorithmId}`, + signatureVerified: null, + signerCertificate, + signerCertificateVerified: true + }); + } + + return Promise.reject(`Unsupported signature algorithm: ${this.signerInfos[signer].digestAlgorithm.algorithmId}`); + } + + shaAlgorithm = signerInfoHashAlgorithm.name; + return true; + }); //endregion + //region Create correct data block for verification + + sequence = sequence.then(result => { + //region Verify result of previous operation + if (result === false) return false; //endregion + + if ("eContent" in this.encapContentInfo) // Attached data + { + if (this.encapContentInfo.eContent.idBlock.tagClass === 1 && this.encapContentInfo.eContent.idBlock.tagNumber === 4) { + if (this.encapContentInfo.eContent.idBlock.isConstructed === false) data = this.encapContentInfo.eContent.valueBlock.valueHex;else { + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = this.encapContentInfo.eContent.valueBlock.value[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + const contentValue = _step5.value; + data = (0, _pvutils.utilConcatBuf)(data, contentValue.valueBlock.valueHex); + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5.return != null) { + _iterator5.return(); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + } + } else data = this.encapContentInfo.eContent.valueBlock.valueBeforeDecode; + } else // Detached data + { + if (data.byteLength === 0) // Check that "data" already provided by function parameter + { + if (extendedMode) { + return Promise.reject({ + date: checkDate, + code: 8, + message: "Missed detached data input array", + signatureVerified: null, + signerCertificate, + signerCertificateVerified: true + }); + } + + return Promise.reject("Missed detached data input array"); + } + } + + if ("signedAttrs" in this.signerInfos[signer]) { + //region Check mandatory attributes + let foundContentType = false; + let foundMessageDigest = false; + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; + + try { + for (var _iterator6 = this.signerInfos[signer].signedAttrs.attributes[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + const attribute = _step6.value; + //region Check that "content-type" attribute exists + if (attribute.type === "1.2.840.113549.1.9.3") foundContentType = true; //endregion + //region Check that "message-digest" attribute exists + + if (attribute.type === "1.2.840.113549.1.9.4") { + foundMessageDigest = true; + messageDigestValue = attribute.values[0].valueBlock.valueHex; + } //endregion + //region Speed-up searching + + + if (foundContentType && foundMessageDigest) break; //endregion + } + } catch (err) { + _didIteratorError6 = true; + _iteratorError6 = err; + } finally { + try { + if (!_iteratorNormalCompletion6 && _iterator6.return != null) { + _iterator6.return(); + } + } finally { + if (_didIteratorError6) { + throw _iteratorError6; + } + } + } + + if (foundContentType === false) { + if (extendedMode) { + return Promise.reject({ + date: checkDate, + code: 9, + message: "Attribute \"content-type\" is a mandatory attribute for \"signed attributes\"", + signatureVerified: null, + signerCertificate, + signerCertificateVerified: true + }); + } + + return Promise.reject("Attribute \"content-type\" is a mandatory attribute for \"signed attributes\""); + } + + if (foundMessageDigest === false) { + if (extendedMode) { + return Promise.reject({ + date: checkDate, + code: 10, + message: "Attribute \"message-digest\" is a mandatory attribute for \"signed attributes\"", + signatureVerified: null, + signerCertificate, + signerCertificateVerified: true + }); + } + + return Promise.reject("Attribute \"message-digest\" is a mandatory attribute for \"signed attributes\""); + } //endregion + + } + + return true; + }); //endregion + //region Verify "message-digest" attribute in case of "signedAttrs" + + sequence = sequence.then(result => { + //region Verify result of previous operation + if (result === false) return false; //endregion + + if ("signedAttrs" in this.signerInfos[signer]) return crypto.digest(shaAlgorithm, new Uint8Array(data)); + return true; + }).then( + /** + * @param {ArrayBuffer} result + */ + result => { + //region Verify result of previous operation + if (result === false) return false; //endregion + + if ("signedAttrs" in this.signerInfos[signer]) { + if ((0, _pvutils.isEqualBuffer)(result, messageDigestValue)) { + data = this.signerInfos[signer].signedAttrs.encodedValue; + return true; + } + + return false; + } + + return true; + }); //endregion + + sequence = sequence.then(result => { + //region Verify result of previous operation + if (result === false) return false; //endregion + + return engine.subtle.verifyWithPublicKey(data, this.signerInfos[signer].signature, signerCertificate.subjectPublicKeyInfo, signerCertificate.signatureAlgorithm, shaAlgorithm); + }); //region Make a final result + + sequence = sequence.then(result => { + if (extendedMode) { + return { + date: checkDate, + code: 14, + message: "", + signatureVerified: result, + signerCertificate, + timestampSerial, + signerCertificateVerified: true, + certificatePath + }; + } + + return result; + }, error => { + if (extendedMode) { + if ("code" in error) return Promise.reject(error); + return Promise.reject({ + date: checkDate, + code: 15, + message: `Error during verification: ${error.message}`, + signatureVerified: null, + signerCertificate, + timestampSerial, + signerCertificateVerified: true + }); + } + + return Promise.reject(error); + }); //endregion + + return sequence; + } //********************************************************************************** + + /** + * Signing current SignedData + * @param {key} privateKey Private key for "subjectPublicKeyInfo" structure + * @param {number} signerIndex Index number (starting from 0) of signer index to make signature for + * @param {string} [hashAlgorithm="SHA-1"] Hashing algorithm. Default SHA-1 + * @param {ArrayBuffer} [data] Detached data + * @returns {*} + */ + + + sign(privateKey, signerIndex, hashAlgorithm = "SHA-1", data = new ArrayBuffer(0)) { + //region Initial checking + if (typeof privateKey === "undefined") return Promise.reject("Need to provide a private key for signing"); //endregion + //region Initial variables + + let sequence = Promise.resolve(); + let parameters; + const engine = (0, _common.getEngine)(); //endregion + //region Simple check for supported algorithm + + const hashAlgorithmOID = (0, _common.getOIDByAlgorithm)({ + name: hashAlgorithm + }); + if (hashAlgorithmOID === "") return Promise.reject(`Unsupported hash algorithm: ${hashAlgorithm}`); //endregion + //region Append information about hash algorithm + + if (this.digestAlgorithms.filter(algorithm => algorithm.algorithmId === hashAlgorithmOID).length === 0) { + this.digestAlgorithms.push(new _AlgorithmIdentifier.default({ + algorithmId: hashAlgorithmOID, + algorithmParams: new asn1js.Null() + })); + } + + this.signerInfos[signerIndex].digestAlgorithm = new _AlgorithmIdentifier.default({ + algorithmId: hashAlgorithmOID, + algorithmParams: new asn1js.Null() + }); //endregion + //region Get a "default parameters" for current algorithm and set correct signature algorithm + + sequence = sequence.then(() => engine.subtle.getSignatureParameters(privateKey, hashAlgorithm)); + sequence = sequence.then(result => { + parameters = result.parameters; + this.signerInfos[signerIndex].signatureAlgorithm = result.signatureAlgorithm; + }); //endregion + //region Create TBS data for signing + + sequence = sequence.then(() => { + if ("signedAttrs" in this.signerInfos[signerIndex]) { + if (this.signerInfos[signerIndex].signedAttrs.encodedValue.byteLength !== 0) data = this.signerInfos[signerIndex].signedAttrs.encodedValue;else { + data = this.signerInfos[signerIndex].signedAttrs.toSchema(true).toBER(false); //region Change type from "[0]" to "SET" acordingly to standard + + const view = new Uint8Array(data); + view[0] = 0x31; //endregion + } + } else { + if ("eContent" in this.encapContentInfo) // Attached data + { + if (this.encapContentInfo.eContent.idBlock.tagClass === 1 && this.encapContentInfo.eContent.idBlock.tagNumber === 4) { + if (this.encapContentInfo.eContent.idBlock.isConstructed === false) data = this.encapContentInfo.eContent.valueBlock.valueHex;else { + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; + + try { + for (var _iterator7 = this.encapContentInfo.eContent.valueBlock.value[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + const content = _step7.value; + data = (0, _pvutils.utilConcatBuf)(data, content.valueBlock.valueHex); + } + } catch (err) { + _didIteratorError7 = true; + _iteratorError7 = err; + } finally { + try { + if (!_iteratorNormalCompletion7 && _iterator7.return != null) { + _iterator7.return(); + } + } finally { + if (_didIteratorError7) { + throw _iteratorError7; + } + } + } + } + } else data = this.encapContentInfo.eContent.valueBlock.valueBeforeDecode; + } else // Detached data + { + if (data.byteLength === 0) // Check that "data" already provided by function parameter + return Promise.reject("Missed detached data input array"); + } + } + + return Promise.resolve(); + }); //endregion + //region Signing TBS data on provided private key + + sequence = sequence.then(() => engine.subtle.signWithPrivateKey(data, privateKey, parameters)); + sequence = sequence.then(result => { + this.signerInfos[signerIndex].signature = new asn1js.OctetString({ + valueHex: result + }); + return result; + }); //endregion + + return sequence; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = SignedData; + +},{"./AlgorithmIdentifier.js":4,"./BasicOCSPResponse.js":13,"./Certificate.js":19,"./CertificateChainValidationEngine.js":20,"./CertificateRevocationList.js":22,"./CertificateSet.js":23,"./EncapsulatedContentInfo.js":33,"./IssuerAndSerialNumber.js":44,"./OtherRevocationInfoFormat.js":64,"./RevocationInfoChoices.js":93,"./SignerInfo.js":102,"./TSTInfo.js":106,"./common.js":110,"asn1js":112,"pvutils":113}],102:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _SignedAndUnsignedAttributes = _interopRequireDefault(require("./SignedAndUnsignedAttributes.js")); + +var _IssuerAndSerialNumber = _interopRequireDefault(require("./IssuerAndSerialNumber.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5652 + */ +class SignerInfo { + //********************************************************************************** + + /** + * Constructor for SignerInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {string} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", SignerInfo.defaultValues("version")); + /** + * @type {Object} + * @desc sid + */ + + this.sid = (0, _pvutils.getParametersValue)(parameters, "sid", SignerInfo.defaultValues("sid")); + /** + * @type {AlgorithmIdentifier} + * @desc digestAlgorithm + */ + + this.digestAlgorithm = (0, _pvutils.getParametersValue)(parameters, "digestAlgorithm", SignerInfo.defaultValues("digestAlgorithm")); + if ("signedAttrs" in parameters) + /** + * @type {SignedAndUnsignedAttributes} + * @desc signedAttrs + */ + this.signedAttrs = (0, _pvutils.getParametersValue)(parameters, "signedAttrs", SignerInfo.defaultValues("signedAttrs")); + /** + * @type {AlgorithmIdentifier} + * @desc digestAlgorithm + */ + + this.signatureAlgorithm = (0, _pvutils.getParametersValue)(parameters, "signatureAlgorithm", SignerInfo.defaultValues("signatureAlgorithm")); + /** + * @type {OctetString} + * @desc signature + */ + + this.signature = (0, _pvutils.getParametersValue)(parameters, "signature", SignerInfo.defaultValues("signature")); + if ("unsignedAttrs" in parameters) + /** + * @type {SignedAndUnsignedAttributes} + * @desc unsignedAttrs + */ + this.unsignedAttrs = (0, _pvutils.getParametersValue)(parameters, "unsignedAttrs", SignerInfo.defaultValues("unsignedAttrs")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 0; + + case "sid": + return new asn1js.Any(); + + case "digestAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "signedAttrs": + return new _SignedAndUnsignedAttributes.default({ + type: 0 + }); + + case "signatureAlgorithm": + return new _AlgorithmIdentifier.default(); + + case "signature": + return new asn1js.OctetString(); + + case "unsignedAttrs": + return new _SignedAndUnsignedAttributes.default({ + type: 1 + }); + + default: + throw new Error(`Invalid member name for SignerInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "version": + return SignerInfo.defaultValues("version") === memberValue; + + case "sid": + return memberValue instanceof asn1js.Any; + + case "digestAlgorithm": + if (memberValue instanceof _AlgorithmIdentifier.default === false) return false; + return memberValue.isEqual(SignerInfo.defaultValues("digestAlgorithm")); + + case "signedAttrs": + return _SignedAndUnsignedAttributes.default.compareWithDefault("type", memberValue.type) && _SignedAndUnsignedAttributes.default.compareWithDefault("attributes", memberValue.attributes) && _SignedAndUnsignedAttributes.default.compareWithDefault("encodedValue", memberValue.encodedValue); + + case "signatureAlgorithm": + if (memberValue instanceof _AlgorithmIdentifier.default === false) return false; + return memberValue.isEqual(SignerInfo.defaultValues("signatureAlgorithm")); + + case "signature": + case "unsignedAttrs": + return _SignedAndUnsignedAttributes.default.compareWithDefault("type", memberValue.type) && _SignedAndUnsignedAttributes.default.compareWithDefault("attributes", memberValue.attributes) && _SignedAndUnsignedAttributes.default.compareWithDefault("encodedValue", memberValue.encodedValue); + + default: + throw new Error(`Invalid member name for SignerInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * SignerInfo ::= SEQUENCE { + * version CMSVersion, + * sid SignerIdentifier, + * digestAlgorithm DigestAlgorithmIdentifier, + * signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, + * signatureAlgorithm SignatureAlgorithmIdentifier, + * signature SignatureValue, + * unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL } + * + * SignerIdentifier ::= CHOICE { + * issuerAndSerialNumber IssuerAndSerialNumber, + * subjectKeyIdentifier [0] SubjectKeyIdentifier } + * + * SubjectKeyIdentifier ::= OCTET STRING + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [version] + * @property {string} [sid] + * @property {string} [digestAlgorithm] + * @property {string} [signedAttrs] + * @property {string} [signatureAlgorithm] + * @property {string} [signature] + * @property {string} [unsignedAttrs] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: "SignerInfo", + value: [new asn1js.Integer({ + name: names.version || "SignerInfo.version" + }), new asn1js.Choice({ + value: [_IssuerAndSerialNumber.default.schema(names.sid || { + names: { + blockName: "SignerInfo.sid" + } + }), new asn1js.Constructed({ + optional: true, + name: names.sid || "SignerInfo.sid", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.OctetString()] + })] + }), _AlgorithmIdentifier.default.schema(names.digestAlgorithm || { + names: { + blockName: "SignerInfo.digestAlgorithm" + } + }), _SignedAndUnsignedAttributes.default.schema(names.signedAttrs || { + names: { + blockName: "SignerInfo.signedAttrs", + tagNumber: 0 + } + }), _AlgorithmIdentifier.default.schema(names.signatureAlgorithm || { + names: { + blockName: "SignerInfo.signatureAlgorithm" + } + }), new asn1js.OctetString({ + name: names.signature || "SignerInfo.signature" + }), _SignedAndUnsignedAttributes.default.schema(names.unsignedAttrs || { + names: { + blockName: "SignerInfo.unsignedAttrs", + tagNumber: 1 + } + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["SignerInfo.version", "SignerInfo.sid", "SignerInfo.digestAlgorithm", "SignerInfo.signedAttrs", "SignerInfo.signatureAlgorithm", "SignerInfo.signature", "SignerInfo.unsignedAttrs"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, SignerInfo.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for SignerInfo"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result["SignerInfo.version"].valueBlock.valueDec; + const currentSid = asn1.result["SignerInfo.sid"]; + if (currentSid.idBlock.tagClass === 1) this.sid = new _IssuerAndSerialNumber.default({ + schema: currentSid + });else this.sid = currentSid; + this.digestAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result["SignerInfo.digestAlgorithm"] + }); + if ("SignerInfo.signedAttrs" in asn1.result) this.signedAttrs = new _SignedAndUnsignedAttributes.default({ + type: 0, + schema: asn1.result["SignerInfo.signedAttrs"] + }); + this.signatureAlgorithm = new _AlgorithmIdentifier.default({ + schema: asn1.result["SignerInfo.signatureAlgorithm"] + }); + this.signature = asn1.result["SignerInfo.signature"]; + if ("SignerInfo.unsignedAttrs" in asn1.result) this.unsignedAttrs = new _SignedAndUnsignedAttributes.default({ + type: 1, + schema: asn1.result["SignerInfo.unsignedAttrs"] + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + if (SignerInfo.compareWithDefault("sid", this.sid)) throw new Error("Incorrectly initialized \"SignerInfo\" class"); //region Create array for output sequence + + const outputArray = []; + outputArray.push(new asn1js.Integer({ + value: this.version + })); + if (this.sid instanceof _IssuerAndSerialNumber.default) outputArray.push(this.sid.toSchema());else outputArray.push(this.sid); + outputArray.push(this.digestAlgorithm.toSchema()); + + if ("signedAttrs" in this) { + if (SignerInfo.compareWithDefault("signedAttrs", this.signedAttrs) === false) outputArray.push(this.signedAttrs.toSchema()); + } + + outputArray.push(this.signatureAlgorithm.toSchema()); + outputArray.push(this.signature); + + if ("unsignedAttrs" in this) { + if (SignerInfo.compareWithDefault("unsignedAttrs", this.unsignedAttrs) === false) outputArray.push(this.unsignedAttrs.toSchema()); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + if (SignerInfo.compareWithDefault("sid", this.sid)) throw new Error("Incorrectly initialized \"SignerInfo\" class"); + const _object = { + version: this.version + }; + if (!(this.sid instanceof asn1js.Any)) _object.sid = this.sid.toJSON(); + _object.digestAlgorithm = this.digestAlgorithm.toJSON(); + if (SignerInfo.compareWithDefault("signedAttrs", this.signedAttrs) === false) _object.signedAttrs = this.signedAttrs.toJSON(); + _object.signatureAlgorithm = this.signatureAlgorithm.toJSON(); + _object.signature = this.signature.toJSON(); + if (SignerInfo.compareWithDefault("unsignedAttrs", this.unsignedAttrs) === false) _object.unsignedAttrs = this.unsignedAttrs.toJSON(); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = SignerInfo; + +},{"./AlgorithmIdentifier.js":4,"./IssuerAndSerialNumber.js":44,"./SignedAndUnsignedAttributes.js":99,"asn1js":112,"pvutils":113}],103:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _CertID = _interopRequireDefault(require("./CertID.js")); + +var _Extension = _interopRequireDefault(require("./Extension.js")); + +var _Extensions = _interopRequireDefault(require("./Extensions.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC6960 + */ +class SingleResponse { + //********************************************************************************** + + /** + * Constructor for SingleResponse class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {CertID} + * @desc certID + */ + this.certID = (0, _pvutils.getParametersValue)(parameters, "certID", SingleResponse.defaultValues("certID")); + /** + * @type {Object} + * @desc certStatus + */ + + this.certStatus = (0, _pvutils.getParametersValue)(parameters, "certStatus", SingleResponse.defaultValues("certStatus")); + /** + * @type {Date} + * @desc thisUpdate + */ + + this.thisUpdate = (0, _pvutils.getParametersValue)(parameters, "thisUpdate", SingleResponse.defaultValues("thisUpdate")); + if ("nextUpdate" in parameters) + /** + * @type {Date} + * @desc nextUpdate + */ + this.nextUpdate = (0, _pvutils.getParametersValue)(parameters, "nextUpdate", SingleResponse.defaultValues("nextUpdate")); + if ("singleExtensions" in parameters) + /** + * @type {Array.} + * @desc singleExtensions + */ + this.singleExtensions = (0, _pvutils.getParametersValue)(parameters, "singleExtensions", SingleResponse.defaultValues("singleExtensions")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "certID": + return new _CertID.default(); + + case "certStatus": + return {}; + + case "thisUpdate": + case "nextUpdate": + return new Date(0, 0, 0); + + case "singleExtensions": + return []; + + default: + throw new Error(`Invalid member name for SingleResponse class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "certID": + // noinspection OverlyComplexBooleanExpressionJS + return _CertID.default.compareWithDefault("hashAlgorithm", memberValue.hashAlgorithm) && _CertID.default.compareWithDefault("issuerNameHash", memberValue.issuerNameHash) && _CertID.default.compareWithDefault("issuerKeyHash", memberValue.issuerKeyHash) && _CertID.default.compareWithDefault("serialNumber", memberValue.serialNumber); + + case "certStatus": + return Object.keys(memberValue).length === 0; + + case "thisUpdate": + case "nextUpdate": + return memberValue === SingleResponse.defaultValues(memberName); + + default: + throw new Error(`Invalid member name for SingleResponse class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * SingleResponse ::= SEQUENCE { + * certID CertID, + * certStatus CertStatus, + * thisUpdate GeneralizedTime, + * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, + * singleExtensions [1] EXPLICIT Extensions OPTIONAL } + * + * CertStatus ::= CHOICE { + * good [0] IMPLICIT NULL, + * revoked [1] IMPLICIT RevokedInfo, + * unknown [2] IMPLICIT UnknownInfo } + * + * RevokedInfo ::= SEQUENCE { + * revocationTime GeneralizedTime, + * revocationReason [0] EXPLICIT CRLReason OPTIONAL } + * + * UnknownInfo ::= NULL + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [certID] + * @property {string} [certStatus] + * @property {string} [thisUpdate] + * @property {string} [nextUpdate] + * @property {string} [singleExtensions] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [_CertID.default.schema(names.certID || {}), new asn1js.Choice({ + value: [new asn1js.Primitive({ + name: names.certStatus || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + lenBlockLength: 1 // The length contains one byte 0x00 + + }), // IMPLICIT NULL (no "valueBlock") + new asn1js.Constructed({ + name: names.certStatus || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [new asn1js.GeneralizedTime(), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Enumerated()] + })] + }), new asn1js.Primitive({ + name: names.certStatus || "", + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + lenBlock: { + length: 1 + } + }) // IMPLICIT NULL (no "valueBlock") + ] + }), new asn1js.GeneralizedTime({ + name: names.thisUpdate || "" + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.GeneralizedTime({ + name: names.nextUpdate || "" + })] + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [_Extensions.default.schema(names.singleExtensions || {})] + }) // EXPLICIT SEQUENCE value + ] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["certID", "certStatus", "thisUpdate", "nextUpdate", "singleExtensions"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, SingleResponse.schema({ + names: { + certID: { + names: { + blockName: "certID" + } + }, + certStatus: "certStatus", + thisUpdate: "thisUpdate", + nextUpdate: "nextUpdate", + singleExtensions: { + names: { + blockName: "singleExtensions" + } + } + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for SingleResponse"); //endregion + //region Get internal properties from parsed schema + + this.certID = new _CertID.default({ + schema: asn1.result.certID + }); + this.certStatus = asn1.result.certStatus; + this.thisUpdate = asn1.result.thisUpdate.toDate(); + if ("nextUpdate" in asn1.result) this.nextUpdate = asn1.result.nextUpdate.toDate(); + if ("singleExtensions" in asn1.result) this.singleExtensions = Array.from(asn1.result.singleExtensions.valueBlock.value, element => new _Extension.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create value array for output sequence + const outputArray = []; + outputArray.push(this.certID.toSchema()); + outputArray.push(this.certStatus); + outputArray.push(new asn1js.GeneralizedTime({ + valueDate: this.thisUpdate + })); + + if ("nextUpdate" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.GeneralizedTime({ + valueDate: this.nextUpdate + })] + })); + } + + if ("singleExtensions" in this) { + outputArray.push(new asn1js.Sequence({ + value: Array.from(this.singleExtensions, element => element.toSchema()) + })); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + certID: this.certID.toJSON(), + certStatus: this.certStatus.toJSON(), + thisUpdate: this.thisUpdate + }; + if ("nextUpdate" in this) _object.nextUpdate = this.nextUpdate; + if ("singleExtensions" in this) _object.singleExtensions = Array.from(this.singleExtensions, element => element.toJSON()); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = SingleResponse; + +},{"./CertID.js":18,"./Extension.js":38,"./Extensions.js":39,"asn1js":112,"pvutils":113}],104:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _Attribute = _interopRequireDefault(require("./Attribute.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class SubjectDirectoryAttributes { + //********************************************************************************** + + /** + * Constructor for SubjectDirectoryAttributes class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {Array.} + * @desc attributes + */ + this.attributes = (0, _pvutils.getParametersValue)(parameters, "attributes", SubjectDirectoryAttributes.defaultValues("attributes")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "attributes": + return []; + + default: + throw new Error(`Invalid member name for SubjectDirectoryAttributes class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [utcTimeName] Name for "utcTimeName" choice + * @property {string} [generalTimeName] Name for "generalTimeName" choice + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "", + value: [new asn1js.Repeated({ + name: names.attributes || "", + value: _Attribute.default.schema() + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["attributes"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, SubjectDirectoryAttributes.schema({ + names: { + attributes: "attributes" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for SubjectDirectoryAttributes"); //endregion + //region Get internal properties from parsed schema + + this.attributes = Array.from(asn1.result.attributes, element => new _Attribute.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + return new asn1js.Sequence({ + value: Array.from(this.attributes, element => element.toSchema()) + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + attributes: Array.from(this.attributes, element => element.toJSON()) + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = SubjectDirectoryAttributes; + +},{"./Attribute.js":6,"asn1js":112,"pvutils":113}],105:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _GeneralName = _interopRequireDefault(require("./GeneralName.js")); + +var _Request = _interopRequireDefault(require("./Request.js")); + +var _Extension = _interopRequireDefault(require("./Extension.js")); + +var _Extensions = _interopRequireDefault(require("./Extensions.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC6960 + */ +class TBSRequest { + //********************************************************************************** + + /** + * Constructor for TBSRequest class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {ArrayBuffer} + * @desc tbs + */ + this.tbs = (0, _pvutils.getParametersValue)(parameters, "tbs", TBSRequest.defaultValues("tbs")); + if ("version" in parameters) + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", TBSRequest.defaultValues("version")); + if ("requestorName" in parameters) + /** + * @type {GeneralName} + * @desc requestorName + */ + this.requestorName = (0, _pvutils.getParametersValue)(parameters, "requestorName", TBSRequest.defaultValues("requestorName")); + /** + * @type {Array.} + * @desc requestList + */ + + this.requestList = (0, _pvutils.getParametersValue)(parameters, "requestList", TBSRequest.defaultValues("requestList")); + if ("requestExtensions" in parameters) + /** + * @type {Array.} + * @desc requestExtensions + */ + this.requestExtensions = (0, _pvutils.getParametersValue)(parameters, "requestExtensions", TBSRequest.defaultValues("requestExtensions")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "tbs": + return new ArrayBuffer(0); + + case "version": + return 0; + + case "requestorName": + return new _GeneralName.default(); + + case "requestList": + case "requestExtensions": + return []; + + default: + throw new Error(`Invalid member name for TBSRequest class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "tbs": + return memberValue.byteLength === 0; + + case "version": + return memberValue === TBSRequest.defaultValues(memberName); + + case "requestorName": + return memberValue.type === _GeneralName.default.defaultValues("type") && Object.keys(memberValue.value).length === 0; + + case "requestList": + case "requestExtensions": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for TBSRequest class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * TBSRequest ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * requestorName [1] EXPLICIT GeneralName OPTIONAL, + * requestList SEQUENCE OF Request, + * requestExtensions [2] EXPLICIT Extensions OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [TBSRequestVersion] + * @property {string} [requestorName] + * @property {string} [requestList] + * @property {string} [requests] + * @property {string} [requestNames] + * @property {string} [extensions] + * @property {string} [requestExtensions] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "TBSRequest", + value: [new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Integer({ + name: names.TBSRequestVersion || "TBSRequest.version" + })] + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [_GeneralName.default.schema(names.requestorName || { + names: { + blockName: "TBSRequest.requestorName" + } + })] + }), new asn1js.Sequence({ + name: names.requestList || "TBSRequest.requestList", + value: [new asn1js.Repeated({ + name: names.requests || "TBSRequest.requests", + value: _Request.default.schema(names.requestNames || {}) + })] + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + value: [_Extensions.default.schema(names.extensions || { + names: { + blockName: names.requestExtensions || "TBSRequest.requestExtensions" + } + })] + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["TBSRequest", "TBSRequest.version", "TBSRequest.requestorName", "TBSRequest.requests", "TBSRequest.requestExtensions"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, TBSRequest.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for TBSRequest"); //endregion + //region Get internal properties from parsed schema + + this.tbs = asn1.result.TBSRequest.valueBeforeDecode; + if ("TBSRequest.version" in asn1.result) this.version = asn1.result["TBSRequest.version"].valueBlock.valueDec; + if ("TBSRequest.requestorName" in asn1.result) this.requestorName = new _GeneralName.default({ + schema: asn1.result["TBSRequest.requestorName"] + }); + this.requestList = Array.from(asn1.result["TBSRequest.requests"], element => new _Request.default({ + schema: element + })); + if ("TBSRequest.requestExtensions" in asn1.result) this.requestExtensions = Array.from(asn1.result["TBSRequest.requestExtensions"].valueBlock.value, element => new _Extension.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @param {boolean} encodeFlag If param equal to false then create TBS schema via decoding stored value. In othe case create TBS schema via assembling from TBS parts. + * @returns {Object} asn1js object + */ + + + toSchema(encodeFlag = false) { + //region Decode stored TBS value + let tbsSchema; + + if (encodeFlag === false) { + if (this.tbs.byteLength === 0) // No stored TBS part + return TBSRequest.schema(); + tbsSchema = asn1js.fromBER(this.tbs).result; + } //endregion + //region Create TBS schema via assembling from TBS parts + else { + const outputArray = []; + + if ("version" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Integer({ + value: this.version + })] + })); + } + + if ("requestorName" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [this.requestorName.toSchema()] + })); + } + + outputArray.push(new asn1js.Sequence({ + value: Array.from(this.requestList, element => element.toSchema()) + })); + + if ("requestExtensions" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 2 // [2] + + }, + value: [new asn1js.Sequence({ + value: Array.from(this.requestExtensions, element => element.toSchema()) + })] + })); + } + + tbsSchema = new asn1js.Sequence({ + value: outputArray + }); + } //endregion + //region Construct and return new ASN.1 schema for this object + + + return tbsSchema; //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = {}; + if ("version" in this) _object.version = this.version; + if ("requestorName" in this) _object.requestorName = this.requestorName.toJSON(); + _object.requestList = Array.from(this.requestList, element => element.toJSON()); + if ("requestExtensions" in this) _object.requestExtensions = Array.from(this.requestExtensions, element => element.toJSON()); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = TBSRequest; + +},{"./Extension.js":38,"./Extensions.js":39,"./GeneralName.js":40,"./Request.js":90,"asn1js":112,"pvutils":113}],106:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _common = require("./common.js"); + +var _MessageImprint = _interopRequireDefault(require("./MessageImprint.js")); + +var _Accuracy = _interopRequireDefault(require("./Accuracy.js")); + +var _GeneralName = _interopRequireDefault(require("./GeneralName.js")); + +var _Extension = _interopRequireDefault(require("./Extension.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC3161 + */ +class TSTInfo { + //********************************************************************************** + + /** + * Constructor for TSTInfo class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", TSTInfo.defaultValues("version")); + /** + * @type {string} + * @desc policy + */ + + this.policy = (0, _pvutils.getParametersValue)(parameters, "policy", TSTInfo.defaultValues("policy")); + /** + * @type {MessageImprint} + * @desc messageImprint + */ + + this.messageImprint = (0, _pvutils.getParametersValue)(parameters, "messageImprint", TSTInfo.defaultValues("messageImprint")); + /** + * @type {Integer} + * @desc serialNumber + */ + + this.serialNumber = (0, _pvutils.getParametersValue)(parameters, "serialNumber", TSTInfo.defaultValues("serialNumber")); + /** + * @type {Date} + * @desc genTime + */ + + this.genTime = (0, _pvutils.getParametersValue)(parameters, "genTime", TSTInfo.defaultValues("genTime")); + if ("accuracy" in parameters) + /** + * @type {Accuracy} + * @desc accuracy + */ + this.accuracy = (0, _pvutils.getParametersValue)(parameters, "accuracy", TSTInfo.defaultValues("accuracy")); + if ("ordering" in parameters) + /** + * @type {boolean} + * @desc ordering + */ + this.ordering = (0, _pvutils.getParametersValue)(parameters, "ordering", TSTInfo.defaultValues("ordering")); + if ("nonce" in parameters) + /** + * @type {Integer} + * @desc nonce + */ + this.nonce = (0, _pvutils.getParametersValue)(parameters, "nonce", TSTInfo.defaultValues("nonce")); + if ("tsa" in parameters) + /** + * @type {GeneralName} + * @desc tsa + */ + this.tsa = (0, _pvutils.getParametersValue)(parameters, "tsa", TSTInfo.defaultValues("tsa")); + if ("extensions" in parameters) + /** + * @type {Array.} + * @desc extensions + */ + this.extensions = (0, _pvutils.getParametersValue)(parameters, "extensions", TSTInfo.defaultValues("extensions")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 0; + + case "policy": + return ""; + + case "messageImprint": + return new _MessageImprint.default(); + + case "serialNumber": + return new asn1js.Integer(); + + case "genTime": + return new Date(0, 0, 0); + + case "accuracy": + return new _Accuracy.default(); + + case "ordering": + return false; + + case "nonce": + return new asn1js.Integer(); + + case "tsa": + return new _GeneralName.default(); + + case "extensions": + return []; + + default: + throw new Error(`Invalid member name for TSTInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "version": + case "policy": + case "genTime": + case "ordering": + return memberValue === TSTInfo.defaultValues(memberName); + + case "messageImprint": + return _MessageImprint.default.compareWithDefault("hashAlgorithm", memberValue.hashAlgorithm) && _MessageImprint.default.compareWithDefault("hashedMessage", memberValue.hashedMessage); + + case "serialNumber": + case "nonce": + return memberValue.isEqual(TSTInfo.defaultValues(memberName)); + + case "accuracy": + return _Accuracy.default.compareWithDefault("seconds", memberValue.seconds) && _Accuracy.default.compareWithDefault("millis", memberValue.millis) && _Accuracy.default.compareWithDefault("micros", memberValue.micros); + + case "tsa": + return _GeneralName.default.compareWithDefault("type", memberValue.type) && _GeneralName.default.compareWithDefault("value", memberValue.value); + + case "extensions": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for TSTInfo class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * TSTInfo ::= SEQUENCE { + * version INTEGER { v1(1) }, + * policy TSAPolicyId, + * messageImprint MessageImprint, + * serialNumber INTEGER, + * genTime GeneralizedTime, + * accuracy Accuracy OPTIONAL, + * ordering BOOLEAN DEFAULT FALSE, + * nonce INTEGER OPTIONAL, + * tsa [0] GeneralName OPTIONAL, + * extensions [1] IMPLICIT Extensions OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [version] + * @property {string} [policy] + * @property {string} [messageImprint] + * @property {string} [serialNumber] + * @property {string} [genTime] + * @property {string} [accuracy] + * @property {string} [ordering] + * @property {string} [nonce] + * @property {string} [tsa] + * @property {string} [extensions] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "TSTInfo", + value: [new asn1js.Integer({ + name: names.version || "TSTInfo.version" + }), new asn1js.ObjectIdentifier({ + name: names.policy || "TSTInfo.policy" + }), _MessageImprint.default.schema(names.messageImprint || { + names: { + blockName: "TSTInfo.messageImprint" + } + }), new asn1js.Integer({ + name: names.serialNumber || "TSTInfo.serialNumber" + }), new asn1js.GeneralizedTime({ + name: names.genTime || "TSTInfo.genTime" + }), _Accuracy.default.schema(names.accuracy || { + names: { + blockName: "TSTInfo.accuracy" + } + }), new asn1js.Boolean({ + name: names.ordering || "TSTInfo.ordering", + optional: true + }), new asn1js.Integer({ + name: names.nonce || "TSTInfo.nonce", + optional: true + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [_GeneralName.default.schema(names.tsa || { + names: { + blockName: "TSTInfo.tsa" + } + })] + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: [new asn1js.Repeated({ + name: names.extensions || "TSTInfo.extensions", + value: _Extension.default.schema(names.extension || {}) + })] + }) // IMPLICIT Extensions + ] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["TSTInfo.version", "TSTInfo.policy", "TSTInfo.messageImprint", "TSTInfo.serialNumber", "TSTInfo.genTime", "TSTInfo.accuracy", "TSTInfo.ordering", "TSTInfo.nonce", "TSTInfo.tsa", "TSTInfo.extensions"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, TSTInfo.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for TSTInfo"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result["TSTInfo.version"].valueBlock.valueDec; + this.policy = asn1.result["TSTInfo.policy"].valueBlock.toString(); + this.messageImprint = new _MessageImprint.default({ + schema: asn1.result["TSTInfo.messageImprint"] + }); + this.serialNumber = asn1.result["TSTInfo.serialNumber"]; + this.genTime = asn1.result["TSTInfo.genTime"].toDate(); + if ("TSTInfo.accuracy" in asn1.result) this.accuracy = new _Accuracy.default({ + schema: asn1.result["TSTInfo.accuracy"] + }); + if ("TSTInfo.ordering" in asn1.result) this.ordering = asn1.result["TSTInfo.ordering"].valueBlock.value; + if ("TSTInfo.nonce" in asn1.result) this.nonce = asn1.result["TSTInfo.nonce"]; + if ("TSTInfo.tsa" in asn1.result) this.tsa = new _GeneralName.default({ + schema: asn1.result["TSTInfo.tsa"] + }); + if ("TSTInfo.extensions" in asn1.result) this.extensions = Array.from(asn1.result["TSTInfo.extensions"], element => new _Extension.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(new asn1js.Integer({ + value: this.version + })); + outputArray.push(new asn1js.ObjectIdentifier({ + value: this.policy + })); + outputArray.push(this.messageImprint.toSchema()); + outputArray.push(this.serialNumber); + outputArray.push(new asn1js.GeneralizedTime({ + valueDate: this.genTime + })); + if ("accuracy" in this) outputArray.push(this.accuracy.toSchema()); + if ("ordering" in this) outputArray.push(new asn1js.Boolean({ + value: this.ordering + })); + if ("nonce" in this) outputArray.push(this.nonce); + + if ("tsa" in this) { + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [this.tsa.toSchema()] + })); + } //region Create array of extensions + + + if ("extensions" in this) { + outputArray.push(new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 1 // [1] + + }, + value: Array.from(this.extensions, element => element.toSchema()) + })); + } //endregion + //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + version: this.version, + policy: this.policy, + messageImprint: this.messageImprint.toJSON(), + serialNumber: this.serialNumber.toJSON(), + genTime: this.genTime + }; + if ("accuracy" in this) _object.accuracy = this.accuracy.toJSON(); + if ("ordering" in this) _object.ordering = this.ordering; + if ("nonce" in this) _object.nonce = this.nonce.toJSON(); + if ("tsa" in this) _object.tsa = this.tsa.toJSON(); + if ("extensions" in this) _object.extensions = Array.from(this.extensions, element => element.toJSON()); + return _object; + } //********************************************************************************** + + /** + * Verify current TST Info value + * @param {{data: ArrayBuffer, notBefore: Date, notAfter: Date}} parameters Input parameters + * @returns {Promise} + */ + + + verify(parameters = {}) { + //region Initial variables + let sequence = Promise.resolve(); + let data; + let notBefore = null; + let notAfter = null; //endregion + //region Get a "crypto" extension + + const crypto = (0, _common.getCrypto)(); + if (typeof crypto === "undefined") return Promise.reject("Unable to create WebCrypto object"); //endregion + //region Get initial parameters + + if ("data" in parameters) data = parameters.data;else return Promise.reject("\"data\" is a mandatory attribute for TST_INFO verification"); + if ("notBefore" in parameters) notBefore = parameters.notBefore; + if ("notAfter" in parameters) notAfter = parameters.notAfter; //endregion + //region Check date + + if (notBefore !== null) { + if (this.genTime < notBefore) return Promise.reject("Generation time for TSTInfo object is less than notBefore value"); + } + + if (notAfter !== null) { + if (this.genTime > notAfter) return Promise.reject("Generation time for TSTInfo object is more than notAfter value"); + } //endregion + //region Find hashing algorithm + + + const shaAlgorithm = (0, _common.getAlgorithmByOID)(this.messageImprint.hashAlgorithm.algorithmId); + if ("name" in shaAlgorithm === false) return Promise.reject(`Unsupported signature algorithm: ${this.messageImprint.hashAlgorithm.algorithmId}`); //endregion + //region Calculate message digest for input "data" buffer + // noinspection JSCheckFunctionSignatures + + sequence = sequence.then(() => crypto.digest(shaAlgorithm.name, new Uint8Array(data))).then(result => (0, _pvutils.isEqualBuffer)(result, this.messageImprint.hashedMessage.valueBlock.valueHex)); //endregion + + return sequence; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = TSTInfo; + +},{"./Accuracy.js":3,"./Extension.js":38,"./GeneralName.js":40,"./MessageImprint.js":53,"./common.js":110,"asn1js":112,"pvutils":113}],107:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC5280 + */ +class Time { + //********************************************************************************** + + /** + * Constructor for Time class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + * @property {number} [type] 0 - UTCTime; 1 - GeneralizedTime; 2 - empty value + * @property {Date} [value] Value of the TIME class + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc 0 - UTCTime; 1 - GeneralizedTime; 2 - empty value + */ + this.type = (0, _pvutils.getParametersValue)(parameters, "type", Time.defaultValues("type")); + /** + * @type {Date} + * @desc Value of the TIME class + */ + + this.value = (0, _pvutils.getParametersValue)(parameters, "value", Time.defaultValues("value")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "type": + return 0; + + case "value": + return new Date(0, 0, 0); + + default: + throw new Error(`Invalid member name for Time class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * Time ::= CHOICE { + * utcTime UTCTime, + * generalTime GeneralizedTime } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @param {boolean} optional Flag that current schema should be optional + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}, optional = false) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [utcTimeName] Name for "utcTimeName" choice + * @property {string} [generalTimeName] Name for "generalTimeName" choice + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Choice({ + optional, + value: [new asn1js.UTCTime({ + name: names.utcTimeName || "" + }), new asn1js.GeneralizedTime({ + name: names.generalTimeName || "" + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["utcTimeName", "generalTimeName"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, Time.schema({ + names: { + utcTimeName: "utcTimeName", + generalTimeName: "generalTimeName" + } + })); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for Time"); //endregion + //region Get internal properties from parsed schema + + if ("utcTimeName" in asn1.result) { + this.type = 0; + this.value = asn1.result.utcTimeName.toDate(); + } + + if ("generalTimeName" in asn1.result) { + this.type = 1; + this.value = asn1.result.generalTimeName.toDate(); + } //endregion + + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Construct and return new ASN.1 schema for this object + let result = {}; + if (this.type === 0) result = new asn1js.UTCTime({ + valueDate: this.value + }); + if (this.type === 1) result = new asn1js.GeneralizedTime({ + valueDate: this.value + }); + return result; //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + return { + type: this.type, + value: this.value + }; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = Time; + +},{"asn1js":112,"pvutils":113}],108:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _MessageImprint = _interopRequireDefault(require("./MessageImprint.js")); + +var _Extension = _interopRequireDefault(require("./Extension.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC3161 + */ +class TimeStampReq { + //********************************************************************************** + + /** + * Constructor for TimeStampReq class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {number} + * @desc version + */ + this.version = (0, _pvutils.getParametersValue)(parameters, "version", TimeStampReq.defaultValues("version")); + /** + * @type {MessageImprint} + * @desc messageImprint + */ + + this.messageImprint = (0, _pvutils.getParametersValue)(parameters, "messageImprint", TimeStampReq.defaultValues("messageImprint")); + if ("reqPolicy" in parameters) + /** + * @type {string} + * @desc reqPolicy + */ + this.reqPolicy = (0, _pvutils.getParametersValue)(parameters, "reqPolicy", TimeStampReq.defaultValues("reqPolicy")); + if ("nonce" in parameters) + /** + * @type {Integer} + * @desc nonce + */ + this.nonce = (0, _pvutils.getParametersValue)(parameters, "nonce", TimeStampReq.defaultValues("nonce")); + if ("certReq" in parameters) + /** + * @type {boolean} + * @desc certReq + */ + this.certReq = (0, _pvutils.getParametersValue)(parameters, "certReq", TimeStampReq.defaultValues("certReq")); + if ("extensions" in parameters) + /** + * @type {Array.} + * @desc extensions + */ + this.extensions = (0, _pvutils.getParametersValue)(parameters, "extensions", TimeStampReq.defaultValues("extensions")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "version": + return 0; + + case "messageImprint": + return new _MessageImprint.default(); + + case "reqPolicy": + return ""; + + case "nonce": + return new asn1js.Integer(); + + case "certReq": + return false; + + case "extensions": + return []; + + default: + throw new Error(`Invalid member name for TimeStampReq class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "version": + case "reqPolicy": + case "certReq": + return memberValue === TimeStampReq.defaultValues(memberName); + + case "messageImprint": + return _MessageImprint.default.compareWithDefault("hashAlgorithm", memberValue.hashAlgorithm) && _MessageImprint.default.compareWithDefault("hashedMessage", memberValue.hashedMessage); + + case "nonce": + return memberValue.isEqual(TimeStampReq.defaultValues(memberName)); + + case "extensions": + return memberValue.length === 0; + + default: + throw new Error(`Invalid member name for TimeStampReq class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * TimeStampReq ::= SEQUENCE { + * version INTEGER { v1(1) }, + * messageImprint MessageImprint, + * reqPolicy TSAPolicyId OPTIONAL, + * nonce INTEGER OPTIONAL, + * certReq BOOLEAN DEFAULT FALSE, + * extensions [0] IMPLICIT Extensions OPTIONAL } + * + * TSAPolicyId ::= OBJECT IDENTIFIER + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [type] + * @property {string} [setName] + * @property {string} [values] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "TimeStampReq", + value: [new asn1js.Integer({ + name: names.version || "TimeStampReq.version" + }), _MessageImprint.default.schema(names.messageImprint || { + names: { + blockName: "TimeStampReq.messageImprint" + } + }), new asn1js.ObjectIdentifier({ + name: names.reqPolicy || "TimeStampReq.reqPolicy", + optional: true + }), new asn1js.Integer({ + name: names.nonce || "TimeStampReq.nonce", + optional: true + }), new asn1js.Boolean({ + name: names.certReq || "TimeStampReq.certReq", + optional: true + }), new asn1js.Constructed({ + optional: true, + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: [new asn1js.Repeated({ + name: names.extensions || "TimeStampReq.extensions", + value: _Extension.default.schema() + })] + }) // IMPLICIT SEQUENCE value + ] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["TimeStampReq.version", "TimeStampReq.messageImprint", "TimeStampReq.reqPolicy", "TimeStampReq.nonce", "TimeStampReq.certReq", "TimeStampReq.extensions"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, TimeStampReq.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for TimeStampReq"); //endregion + //region Get internal properties from parsed schema + + this.version = asn1.result["TimeStampReq.version"].valueBlock.valueDec; + this.messageImprint = new _MessageImprint.default({ + schema: asn1.result["TimeStampReq.messageImprint"] + }); + if ("TimeStampReq.reqPolicy" in asn1.result) this.reqPolicy = asn1.result["TimeStampReq.reqPolicy"].valueBlock.toString(); + if ("TimeStampReq.nonce" in asn1.result) this.nonce = asn1.result["TimeStampReq.nonce"]; + if ("TimeStampReq.certReq" in asn1.result) this.certReq = asn1.result["TimeStampReq.certReq"].valueBlock.value; + if ("TimeStampReq.extensions" in asn1.result) this.extensions = Array.from(asn1.result["TimeStampReq.extensions"], element => new _Extension.default({ + schema: element + })); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(new asn1js.Integer({ + value: this.version + })); + outputArray.push(this.messageImprint.toSchema()); + if ("reqPolicy" in this) outputArray.push(new asn1js.ObjectIdentifier({ + value: this.reqPolicy + })); + if ("nonce" in this) outputArray.push(this.nonce); + if ("certReq" in this && TimeStampReq.compareWithDefault("certReq", this.certReq) === false) outputArray.push(new asn1js.Boolean({ + value: this.certReq + })); //region Create array of extensions + + if ("extensions" in this) { + outputArray.push(new asn1js.Constructed({ + idBlock: { + tagClass: 3, + // CONTEXT-SPECIFIC + tagNumber: 0 // [0] + + }, + value: Array.from(this.extensions, element => element.toSchema()) + })); + } //endregion + //endregion + //region Construct and return new ASN.1 schema for this object + + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + version: this.version, + messageImprint: this.messageImprint.toJSON() + }; + if ("reqPolicy" in this) _object.reqPolicy = this.reqPolicy; + if ("nonce" in this) _object.nonce = this.nonce.toJSON(); + if ("certReq" in this && TimeStampReq.compareWithDefault("certReq", this.certReq) === false) _object.certReq = this.certReq; + if ("extensions" in this) _object.extensions = Array.from(this.extensions, element => element.toJSON()); + return _object; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = TimeStampReq; + +},{"./Extension.js":38,"./MessageImprint.js":53,"asn1js":112,"pvutils":113}],109:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _PKIStatusInfo = _interopRequireDefault(require("./PKIStatusInfo.js")); + +var _ContentInfo = _interopRequireDefault(require("./ContentInfo.js")); + +var _SignedData = _interopRequireDefault(require("./SignedData.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** + +/** + * Class from RFC3161 + */ +class TimeStampResp { + //********************************************************************************** + + /** + * Constructor for TimeStampResp class + * @param {Object} [parameters={}] + * @param {Object} [parameters.schema] asn1js parsed value to initialize the class from + */ + constructor(parameters = {}) { + //region Internal properties of the object + + /** + * @type {PKIStatusInfo} + * @desc status + */ + this.status = (0, _pvutils.getParametersValue)(parameters, "status", TimeStampResp.defaultValues("status")); + if ("timeStampToken" in parameters) + /** + * @type {ContentInfo} + * @desc timeStampToken + */ + this.timeStampToken = (0, _pvutils.getParametersValue)(parameters, "timeStampToken", TimeStampResp.defaultValues("timeStampToken")); //endregion + //region If input argument array contains "schema" for this object + + if ("schema" in parameters) this.fromSchema(parameters.schema); //endregion + } //********************************************************************************** + + /** + * Return default values for all class members + * @param {string} memberName String name for a class member + */ + + + static defaultValues(memberName) { + switch (memberName) { + case "status": + return new _PKIStatusInfo.default(); + + case "timeStampToken": + return new _ContentInfo.default(); + + default: + throw new Error(`Invalid member name for TimeStampResp class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Compare values with default values for all class members + * @param {string} memberName String name for a class member + * @param {*} memberValue Value to compare with default value + */ + + + static compareWithDefault(memberName, memberValue) { + switch (memberName) { + case "status": + return _PKIStatusInfo.default.compareWithDefault("status", memberValue.status) && "statusStrings" in memberValue === false && "failInfo" in memberValue === false; + + case "timeStampToken": + return memberValue.contentType === "" && memberValue.content instanceof asn1js.Any; + + default: + throw new Error(`Invalid member name for TimeStampResp class: ${memberName}`); + } + } //********************************************************************************** + + /** + * Return value of pre-defined ASN.1 schema for current class + * + * ASN.1 schema: + * ```asn1 + * TimeStampResp ::= SEQUENCE { + * status PKIStatusInfo, + * timeStampToken TimeStampToken OPTIONAL } + * ``` + * + * @param {Object} parameters Input parameters for the schema + * @returns {Object} asn1js schema object + */ + + + static schema(parameters = {}) { + /** + * @type {Object} + * @property {string} [blockName] + * @property {string} [status] + * @property {string} [timeStampToken] + */ + const names = (0, _pvutils.getParametersValue)(parameters, "names", {}); + return new asn1js.Sequence({ + name: names.blockName || "TimeStampResp", + value: [_PKIStatusInfo.default.schema(names.status || { + names: { + blockName: "TimeStampResp.status" + } + }), _ContentInfo.default.schema(names.timeStampToken || { + names: { + blockName: "TimeStampResp.timeStampToken", + optional: true + } + })] + }); + } //********************************************************************************** + + /** + * Convert parsed asn1js object into current class + * @param {!Object} schema + */ + + + fromSchema(schema) { + //region Clear input data first + (0, _pvutils.clearProps)(schema, ["TimeStampResp.status", "TimeStampResp.timeStampToken"]); //endregion + //region Check the schema is valid + + const asn1 = asn1js.compareSchema(schema, schema, TimeStampResp.schema()); + if (asn1.verified === false) throw new Error("Object's schema was not verified against input data for TimeStampResp"); //endregion + //region Get internal properties from parsed schema + + this.status = new _PKIStatusInfo.default({ + schema: asn1.result["TimeStampResp.status"] + }); + if ("TimeStampResp.timeStampToken" in asn1.result) this.timeStampToken = new _ContentInfo.default({ + schema: asn1.result["TimeStampResp.timeStampToken"] + }); //endregion + } //********************************************************************************** + + /** + * Convert current object to asn1js object and set correct values + * @returns {Object} asn1js object + */ + + + toSchema() { + //region Create array for output sequence + const outputArray = []; + outputArray.push(this.status.toSchema()); + if ("timeStampToken" in this) outputArray.push(this.timeStampToken.toSchema()); //endregion + //region Construct and return new ASN.1 schema for this object + + return new asn1js.Sequence({ + value: outputArray + }); //endregion + } //********************************************************************************** + + /** + * Convertion for the class to JSON object + * @returns {Object} + */ + + + toJSON() { + const _object = { + status: this.status + }; + if ("timeStampToken" in this) _object.timeStampToken = this.timeStampToken.toJSON(); + return _object; + } //********************************************************************************** + + /** + * Sign current TSP Response + * @param {Object} privateKey Private key for "subjectPublicKeyInfo" structure + * @param {string} [hashAlgorithm] Hashing algorithm. Default SHA-1 + * @returns {Promise} + */ + + + sign(privateKey, hashAlgorithm) { + //region Check that "timeStampToken" exists + if ("timeStampToken" in this === false) return Promise.reject("timeStampToken is absent in TSP response"); //endregion + //region Check that "timeStampToken" has a right internal format + + if (this.timeStampToken.contentType !== "1.2.840.113549.1.7.2") // Must be a CMS signed data + return Promise.reject(`Wrong format of timeStampToken: ${this.timeStampToken.contentType}`); //endregion + //region Sign internal signed data value + + const signed = new _ContentInfo.default({ + schema: this.timeStampToken.content + }); + return signed.sign(privateKey, 0, hashAlgorithm); //endregion + } //********************************************************************************** + + /** + * Verify current TSP Response + * @param {Object} verificationParameters Input parameters for verification + * @returns {Promise} + */ + + + verify(verificationParameters = { + signer: 0, + trustedCerts: [], + data: new ArrayBuffer(0) + }) { + //region Check that "timeStampToken" exists + if ("timeStampToken" in this === false) return Promise.reject("timeStampToken is absent in TSP response"); //endregion + //region Check that "timeStampToken" has a right internal format + + if (this.timeStampToken.contentType !== "1.2.840.113549.1.7.2") // Must be a CMS signed data + return Promise.reject(`Wrong format of timeStampToken: ${this.timeStampToken.contentType}`); //endregion + //region Verify internal signed data value + + const signed = new _SignedData.default({ + schema: this.timeStampToken.content + }); + return signed.verify(verificationParameters); //endregion + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.default = TimeStampResp; + +},{"./ContentInfo.js":26,"./PKIStatusInfo.js":69,"./SignedData.js":101,"asn1js":112,"pvutils":113}],110:[function(require,module,exports){ +(function (process,global){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.setEngine = setEngine; +exports.getEngine = getEngine; +exports.getCrypto = getCrypto; +exports.getRandomValues = getRandomValues; +exports.getOIDByAlgorithm = getOIDByAlgorithm; +exports.getAlgorithmParameters = getAlgorithmParameters; +exports.createCMSECDSASignature = createCMSECDSASignature; +exports.stringPrep = stringPrep; +exports.createECDSASignatureFromCMS = createECDSASignatureFromCMS; +exports.getAlgorithmByOID = getAlgorithmByOID; +exports.getHashAlgorithm = getHashAlgorithm; +exports.kdfWithCounter = kdfWithCounter; +exports.kdf = kdf; + +var asn1js = _interopRequireWildcard(require("asn1js")); + +var _pvutils = require("pvutils"); + +var _CryptoEngine = _interopRequireDefault(require("./CryptoEngine.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +//************************************************************************************** +//region Crypto engine related function +//************************************************************************************** +let engine = { + name: "none", + crypto: null, + subtle: null +}; //************************************************************************************** + +function setEngine(name, crypto, subtle) { + //region We are in Node + // noinspection JSUnresolvedVariable + if (typeof process !== "undefined" && "pid" in process && typeof global !== "undefined" && typeof window === "undefined") { + // noinspection ES6ModulesDependencies, JSUnresolvedVariable + if (typeof global[process.pid] === "undefined") { + // noinspection JSUnresolvedVariable + global[process.pid] = {}; + } else { + // noinspection JSUnresolvedVariable + if (typeof global[process.pid] !== "object") { + // noinspection JSUnresolvedVariable + throw new Error(`Name global.${process.pid} already exists and it is not an object`); + } + } // noinspection JSUnresolvedVariable + + + if (typeof global[process.pid].pkijs === "undefined") { + // noinspection JSUnresolvedVariable + global[process.pid].pkijs = {}; + } else { + // noinspection JSUnresolvedVariable + if (typeof global[process.pid].pkijs !== "object") { + // noinspection JSUnresolvedVariable + throw new Error(`Name global.${process.pid}.pkijs already exists and it is not an object`); + } + } // noinspection JSUnresolvedVariable + + + global[process.pid].pkijs.engine = { + name: name, + crypto: crypto, + subtle: subtle + }; + } //endregion + //region We are in browser + else { + engine = { + name: name, + crypto: crypto, + subtle: subtle + }; + } //endregion + +} //************************************************************************************** + + +function getEngine() { + //region We are in Node + // noinspection JSUnresolvedVariable + if (typeof process !== "undefined" && "pid" in process && typeof global !== "undefined" && typeof window === "undefined") { + let _engine; + + try { + // noinspection JSUnresolvedVariable + _engine = global[process.pid].pkijs.engine; + } catch (ex) { + throw new Error("Please call \"setEngine\" before call to \"getEngine\""); + } + + return _engine; + } //endregion + + + return engine; +} //************************************************************************************** + + +(function initCryptoEngine() { + if (typeof self !== "undefined") { + if ("crypto" in self) { + let engineName = "webcrypto"; + /** + * Standard crypto object + * @type {Object} + * @property {Object} [webkitSubtle] Subtle object from Apple + */ + + const cryptoObject = self.crypto; + let subtleObject; // Apple Safari support + + if ("webkitSubtle" in self.crypto) { + try { + subtleObject = self.crypto.webkitSubtle; + } catch (ex) { + subtleObject = self.crypto.subtle; + } + + engineName = "safari"; + } + + if ("subtle" in self.crypto) subtleObject = self.crypto.subtle; + + if (typeof subtleObject === "undefined") { + engine = { + name: engineName, + crypto: cryptoObject, + subtle: null + }; + } else { + engine = { + name: engineName, + crypto: cryptoObject, + subtle: new _CryptoEngine.default({ + name: engineName, + crypto: self.crypto, + subtle: subtleObject + }) + }; + } + } + } + + setEngine(engine.name, engine.crypto, engine.subtle); +})(); //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of common functions +//************************************************************************************** + +/** + * Get crypto subtle from current "crypto engine" or "undefined" + * @returns {({decrypt, deriveKey, digest, encrypt, exportKey, generateKey, importKey, sign, unwrapKey, verify, wrapKey}|null)} + */ + + +function getCrypto() { + const _engine = getEngine(); + + if (_engine.subtle !== null) return _engine.subtle; + return undefined; +} //************************************************************************************** + +/** + * Initialize input Uint8Array by random values (with help from current "crypto engine") + * @param {!Uint8Array} view + * @returns {*} + */ + + +function getRandomValues(view) { + return getEngine().subtle.getRandomValues(view); +} //************************************************************************************** + +/** + * Get OID for each specific algorithm + * @param {Object} algorithm + * @returns {string} + */ + + +function getOIDByAlgorithm(algorithm) { + return getEngine().subtle.getOIDByAlgorithm(algorithm); +} //************************************************************************************** + +/** + * Get default algorithm parameters for each kind of operation + * @param {string} algorithmName Algorithm name to get common parameters for + * @param {string} operation Kind of operation: "sign", "encrypt", "generatekey", "importkey", "exportkey", "verify" + * @returns {*} + */ + + +function getAlgorithmParameters(algorithmName, operation) { + return getEngine().subtle.getAlgorithmParameters(algorithmName, operation); +} //************************************************************************************** + +/** + * Create CMS ECDSA signature from WebCrypto ECDSA signature + * @param {ArrayBuffer} signatureBuffer WebCrypto result of "sign" function + * @returns {ArrayBuffer} + */ + + +function createCMSECDSASignature(signatureBuffer) { + //region Initial check for correct length + if (signatureBuffer.byteLength % 2 !== 0) return new ArrayBuffer(0); //endregion + //region Initial variables + + const length = signatureBuffer.byteLength / 2; // There are two equal parts inside incoming ArrayBuffer + + const rBuffer = new ArrayBuffer(length); + const rView = new Uint8Array(rBuffer); + rView.set(new Uint8Array(signatureBuffer, 0, length)); + const rInteger = new asn1js.Integer({ + valueHex: rBuffer + }); + const sBuffer = new ArrayBuffer(length); + const sView = new Uint8Array(sBuffer); + sView.set(new Uint8Array(signatureBuffer, length, length)); + const sInteger = new asn1js.Integer({ + valueHex: sBuffer + }); //endregion + + return new asn1js.Sequence({ + value: [rInteger.convertToDER(), sInteger.convertToDER()] + }).toBER(false); +} //************************************************************************************** + +/** + * String preparation function. In a future here will be realization of algorithm from RFC4518 + * @param {string} inputString JavaScript string. As soon as for each ASN.1 string type we have a specific transformation function here we will work with pure JavaScript string + * @returns {string} Formated string + */ + + +function stringPrep(inputString) { + //region Initial variables + let isSpace = false; + let cuttedResult = ""; //endregion + + const result = inputString.trim(); // Trim input string + //region Change all sequence of SPACE down to SPACE char + + for (let i = 0; i < result.length; i++) { + if (result.charCodeAt(i) === 32) { + if (isSpace === false) isSpace = true; + } else { + if (isSpace) { + cuttedResult += " "; + isSpace = false; + } + + cuttedResult += result[i]; + } + } //endregion + + + return cuttedResult.toLowerCase(); +} //************************************************************************************** + +/** + * Create a single ArrayBuffer from CMS ECDSA signature + * @param {Sequence} cmsSignature ASN.1 SEQUENCE contains CMS ECDSA signature + * @returns {ArrayBuffer} + */ + + +function createECDSASignatureFromCMS(cmsSignature) { + //region Check input variables + if (cmsSignature instanceof asn1js.Sequence === false) return new ArrayBuffer(0); + if (cmsSignature.valueBlock.value.length !== 2) return new ArrayBuffer(0); + if (cmsSignature.valueBlock.value[0] instanceof asn1js.Integer === false) return new ArrayBuffer(0); + if (cmsSignature.valueBlock.value[1] instanceof asn1js.Integer === false) return new ArrayBuffer(0); //endregion + + const rValue = cmsSignature.valueBlock.value[0].convertFromDER(); + const sValue = cmsSignature.valueBlock.value[1].convertFromDER(); //region Check the lengths of two parts are equal + + switch (true) { + case rValue.valueBlock.valueHex.byteLength < sValue.valueBlock.valueHex.byteLength: + { + if (sValue.valueBlock.valueHex.byteLength - rValue.valueBlock.valueHex.byteLength !== 1) throw new Error("Incorrect DER integer decoding"); + const correctedLength = sValue.valueBlock.valueHex.byteLength; + const rValueView = new Uint8Array(rValue.valueBlock.valueHex); + const rValueBufferCorrected = new ArrayBuffer(correctedLength); + const rValueViewCorrected = new Uint8Array(rValueBufferCorrected); + rValueViewCorrected.set(rValueView, 1); + rValueViewCorrected[0] = 0x00; // In order to be sure we do not have any garbage here + + return (0, _pvutils.utilConcatBuf)(rValueBufferCorrected, sValue.valueBlock.valueHex); + } + + case rValue.valueBlock.valueHex.byteLength > sValue.valueBlock.valueHex.byteLength: + { + if (rValue.valueBlock.valueHex.byteLength - sValue.valueBlock.valueHex.byteLength !== 1) throw new Error("Incorrect DER integer decoding"); + const correctedLength = rValue.valueBlock.valueHex.byteLength; + const sValueView = new Uint8Array(sValue.valueBlock.valueHex); + const sValueBufferCorrected = new ArrayBuffer(correctedLength); + const sValueViewCorrected = new Uint8Array(sValueBufferCorrected); + sValueViewCorrected.set(sValueView, 1); + sValueViewCorrected[0] = 0x00; // In order to be sure we do not have any garbage here + + return (0, _pvutils.utilConcatBuf)(rValue.valueBlock.valueHex, sValueBufferCorrected); + } + + default: + { + //region In case we have equal length and the length is not even with 2 + if (rValue.valueBlock.valueHex.byteLength % 2) { + const correctedLength = rValue.valueBlock.valueHex.byteLength + 1; + const rValueView = new Uint8Array(rValue.valueBlock.valueHex); + const rValueBufferCorrected = new ArrayBuffer(correctedLength); + const rValueViewCorrected = new Uint8Array(rValueBufferCorrected); + rValueViewCorrected.set(rValueView, 1); + rValueViewCorrected[0] = 0x00; // In order to be sure we do not have any garbage here + + const sValueView = new Uint8Array(sValue.valueBlock.valueHex); + const sValueBufferCorrected = new ArrayBuffer(correctedLength); + const sValueViewCorrected = new Uint8Array(sValueBufferCorrected); + sValueViewCorrected.set(sValueView, 1); + sValueViewCorrected[0] = 0x00; // In order to be sure we do not have any garbage here + + return (0, _pvutils.utilConcatBuf)(rValueBufferCorrected, sValueBufferCorrected); + } //endregion + + } + } //endregion + + + return (0, _pvutils.utilConcatBuf)(rValue.valueBlock.valueHex, sValue.valueBlock.valueHex); +} //************************************************************************************** + +/** + * Get WebCrypto algorithm by wel-known OID + * @param {string} oid well-known OID to search for + * @returns {Object} + */ + + +function getAlgorithmByOID(oid) { + return getEngine().subtle.getAlgorithmByOID(oid); +} //************************************************************************************** + +/** + * Getting hash algorithm by signature algorithm + * @param {AlgorithmIdentifier} signatureAlgorithm Signature algorithm + * @returns {string} + */ + + +function getHashAlgorithm(signatureAlgorithm) { + return getEngine().subtle.getHashAlgorithm(signatureAlgorithm); +} //************************************************************************************** + +/** + * ANS X9.63 Key Derivation Function having a "Counter" as a parameter + * @param {string} hashFunction Used hash function + * @param {ArrayBuffer} Zbuffer ArrayBuffer containing ECDH shared secret to derive from + * @param {number} Counter + * @param {ArrayBuffer} SharedInfo Usually DER encoded "ECC_CMS_SharedInfo" structure + */ + + +function kdfWithCounter(hashFunction, Zbuffer, Counter, SharedInfo) { + //region Check of input parameters + switch (hashFunction.toUpperCase()) { + case "SHA-1": + case "SHA-256": + case "SHA-384": + case "SHA-512": + break; + + default: + return Promise.reject(`Unknown hash function: ${hashFunction}`); + } + + if (Zbuffer instanceof ArrayBuffer === false) return Promise.reject("Please set \"Zbuffer\" as \"ArrayBuffer\""); + if (Zbuffer.byteLength === 0) return Promise.reject("\"Zbuffer\" has zero length, error"); + if (SharedInfo instanceof ArrayBuffer === false) return Promise.reject("Please set \"SharedInfo\" as \"ArrayBuffer\""); + if (Counter > 255) return Promise.reject("Please set \"Counter\" variable to value less or equal to 255"); //endregion + //region Initial variables + + const counterBuffer = new ArrayBuffer(4); + const counterView = new Uint8Array(counterBuffer); + counterView[0] = 0x00; + counterView[1] = 0x00; + counterView[2] = 0x00; + counterView[3] = Counter; + let combinedBuffer = new ArrayBuffer(0); //endregion + //region Get a "crypto" extension + + const crypto = getCrypto(); + if (typeof crypto === "undefined") return Promise.reject("Unable to create WebCrypto object"); //endregion + //region Create a combined ArrayBuffer for digesting + + combinedBuffer = (0, _pvutils.utilConcatBuf)(combinedBuffer, Zbuffer); + combinedBuffer = (0, _pvutils.utilConcatBuf)(combinedBuffer, counterBuffer); + combinedBuffer = (0, _pvutils.utilConcatBuf)(combinedBuffer, SharedInfo); //endregion + //region Return digest of combined ArrayBuffer and information about current counter + + return crypto.digest({ + name: hashFunction + }, combinedBuffer).then(result => ({ + counter: Counter, + result + })); //endregion +} //************************************************************************************** + +/** + * ANS X9.63 Key Derivation Function + * @param {string} hashFunction Used hash function + * @param {ArrayBuffer} Zbuffer ArrayBuffer containing ECDH shared secret to derive from + * @param {number} keydatalen Length (!!! in BITS !!!) of used kew derivation function + * @param {ArrayBuffer} SharedInfo Usually DER encoded "ECC_CMS_SharedInfo" structure + */ + + +function kdf(hashFunction, Zbuffer, keydatalen, SharedInfo) { + //region Initial variables + let hashLength = 0; + let maxCounter = 1; + const kdfArray = []; //endregion + //region Check of input parameters + + switch (hashFunction.toUpperCase()) { + case "SHA-1": + hashLength = 160; // In bits + + break; + + case "SHA-256": + hashLength = 256; // In bits + + break; + + case "SHA-384": + hashLength = 384; // In bits + + break; + + case "SHA-512": + hashLength = 512; // In bits + + break; + + default: + return Promise.reject(`Unknown hash function: ${hashFunction}`); + } + + if (Zbuffer instanceof ArrayBuffer === false) return Promise.reject("Please set \"Zbuffer\" as \"ArrayBuffer\""); + if (Zbuffer.byteLength === 0) return Promise.reject("\"Zbuffer\" has zero length, error"); + if (SharedInfo instanceof ArrayBuffer === false) return Promise.reject("Please set \"SharedInfo\" as \"ArrayBuffer\""); //endregion + //region Calculated maximum value of "Counter" variable + + const quotient = keydatalen / hashLength; + + if (Math.floor(quotient) > 0) { + maxCounter = Math.floor(quotient); + if (quotient - maxCounter > 0) maxCounter++; + } //endregion + //region Create an array of "kdfWithCounter" + + + for (let i = 1; i <= maxCounter; i++) kdfArray.push(kdfWithCounter(hashFunction, Zbuffer, i, SharedInfo)); //endregion + //region Return combined digest with specified length + + + return Promise.all(kdfArray).then(incomingResult => { + //region Initial variables + let combinedBuffer = new ArrayBuffer(0); + let currentCounter = 1; + let found = true; //endregion + //region Combine all buffer together + + while (found) { + found = false; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = incomingResult[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + const result = _step.value; + + if (result.counter === currentCounter) { + combinedBuffer = (0, _pvutils.utilConcatBuf)(combinedBuffer, result.result); + found = true; + break; + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return != null) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + currentCounter++; + } //endregion + //region Create output buffer with specified length + + + keydatalen >>= 3; // Divide by 8 since "keydatalen" is in bits + + if (combinedBuffer.byteLength > keydatalen) { + const newBuffer = new ArrayBuffer(keydatalen); + const newView = new Uint8Array(newBuffer); + const combinedView = new Uint8Array(combinedBuffer); + + for (let i = 0; i < keydatalen; i++) newView[i] = combinedView[i]; + + return newBuffer; + } + + return combinedBuffer; // Since the situation when "combinedBuffer.byteLength < keydatalen" here we have only "combinedBuffer.byteLength === keydatalen" + //endregion + }); //endregion +} //************************************************************************************** +//endregion +//************************************************************************************** + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./CryptoEngine.js":27,"_process":114,"asn1js":112,"pvutils":113}],111:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "setEngine", { + enumerable: true, + get: function get() { + return _common.setEngine; + } +}); +Object.defineProperty(exports, "getEngine", { + enumerable: true, + get: function get() { + return _common.getEngine; + } +}); +Object.defineProperty(exports, "getCrypto", { + enumerable: true, + get: function get() { + return _common.getCrypto; + } +}); +Object.defineProperty(exports, "getRandomValues", { + enumerable: true, + get: function get() { + return _common.getRandomValues; + } +}); +Object.defineProperty(exports, "getOIDByAlgorithm", { + enumerable: true, + get: function get() { + return _common.getOIDByAlgorithm; + } +}); +Object.defineProperty(exports, "getAlgorithmParameters", { + enumerable: true, + get: function get() { + return _common.getAlgorithmParameters; + } +}); +Object.defineProperty(exports, "createCMSECDSASignature", { + enumerable: true, + get: function get() { + return _common.createCMSECDSASignature; + } +}); +Object.defineProperty(exports, "stringPrep", { + enumerable: true, + get: function get() { + return _common.stringPrep; + } +}); +Object.defineProperty(exports, "createECDSASignatureFromCMS", { + enumerable: true, + get: function get() { + return _common.createECDSASignatureFromCMS; + } +}); +Object.defineProperty(exports, "getAlgorithmByOID", { + enumerable: true, + get: function get() { + return _common.getAlgorithmByOID; + } +}); +Object.defineProperty(exports, "getHashAlgorithm", { + enumerable: true, + get: function get() { + return _common.getHashAlgorithm; + } +}); +Object.defineProperty(exports, "kdfWithCounter", { + enumerable: true, + get: function get() { + return _common.kdfWithCounter; + } +}); +Object.defineProperty(exports, "kdf", { + enumerable: true, + get: function get() { + return _common.kdf; + } +}); +Object.defineProperty(exports, "AccessDescription", { + enumerable: true, + get: function get() { + return _AccessDescription.default; + } +}); +Object.defineProperty(exports, "Accuracy", { + enumerable: true, + get: function get() { + return _Accuracy.default; + } +}); +Object.defineProperty(exports, "AlgorithmIdentifier", { + enumerable: true, + get: function get() { + return _AlgorithmIdentifier.default; + } +}); +Object.defineProperty(exports, "AltName", { + enumerable: true, + get: function get() { + return _AltName.default; + } +}); +Object.defineProperty(exports, "Attribute", { + enumerable: true, + get: function get() { + return _Attribute.default; + } +}); +Object.defineProperty(exports, "AttributeTypeAndValue", { + enumerable: true, + get: function get() { + return _AttributeTypeAndValue.default; + } +}); +Object.defineProperty(exports, "AuthenticatedSafe", { + enumerable: true, + get: function get() { + return _AuthenticatedSafe.default; + } +}); +Object.defineProperty(exports, "AuthorityKeyIdentifier", { + enumerable: true, + get: function get() { + return _AuthorityKeyIdentifier.default; + } +}); +Object.defineProperty(exports, "BasicConstraints", { + enumerable: true, + get: function get() { + return _BasicConstraints.default; + } +}); +Object.defineProperty(exports, "BasicOCSPResponse", { + enumerable: true, + get: function get() { + return _BasicOCSPResponse.default; + } +}); +Object.defineProperty(exports, "CRLBag", { + enumerable: true, + get: function get() { + return _CRLBag.default; + } +}); +Object.defineProperty(exports, "CRLDistributionPoints", { + enumerable: true, + get: function get() { + return _CRLDistributionPoints.default; + } +}); +Object.defineProperty(exports, "CertBag", { + enumerable: true, + get: function get() { + return _CertBag.default; + } +}); +Object.defineProperty(exports, "CertID", { + enumerable: true, + get: function get() { + return _CertID.default; + } +}); +Object.defineProperty(exports, "Certificate", { + enumerable: true, + get: function get() { + return _Certificate.default; + } +}); +Object.defineProperty(exports, "CertificateChainValidationEngine", { + enumerable: true, + get: function get() { + return _CertificateChainValidationEngine.default; + } +}); +Object.defineProperty(exports, "CertificatePolicies", { + enumerable: true, + get: function get() { + return _CertificatePolicies.default; + } +}); +Object.defineProperty(exports, "CertificateRevocationList", { + enumerable: true, + get: function get() { + return _CertificateRevocationList.default; + } +}); +Object.defineProperty(exports, "CertificateSet", { + enumerable: true, + get: function get() { + return _CertificateSet.default; + } +}); +Object.defineProperty(exports, "CertificationRequest", { + enumerable: true, + get: function get() { + return _CertificationRequest.default; + } +}); +Object.defineProperty(exports, "ContentInfo", { + enumerable: true, + get: function get() { + return _ContentInfo.default; + } +}); +Object.defineProperty(exports, "CryptoEngine", { + enumerable: true, + get: function get() { + return _CryptoEngine.default; + } +}); +Object.defineProperty(exports, "DigestInfo", { + enumerable: true, + get: function get() { + return _DigestInfo.default; + } +}); +Object.defineProperty(exports, "DistributionPoint", { + enumerable: true, + get: function get() { + return _DistributionPoint.default; + } +}); +Object.defineProperty(exports, "ECCCMSSharedInfo", { + enumerable: true, + get: function get() { + return _ECCCMSSharedInfo.default; + } +}); +Object.defineProperty(exports, "ECPrivateKey", { + enumerable: true, + get: function get() { + return _ECPrivateKey.default; + } +}); +Object.defineProperty(exports, "ECPublicKey", { + enumerable: true, + get: function get() { + return _ECPublicKey.default; + } +}); +Object.defineProperty(exports, "EncapsulatedContentInfo", { + enumerable: true, + get: function get() { + return _EncapsulatedContentInfo.default; + } +}); +Object.defineProperty(exports, "EncryptedContentInfo", { + enumerable: true, + get: function get() { + return _EncryptedContentInfo.default; + } +}); +Object.defineProperty(exports, "EncryptedData", { + enumerable: true, + get: function get() { + return _EncryptedData.default; + } +}); +Object.defineProperty(exports, "EnvelopedData", { + enumerable: true, + get: function get() { + return _EnvelopedData.default; + } +}); +Object.defineProperty(exports, "ExtKeyUsage", { + enumerable: true, + get: function get() { + return _ExtKeyUsage.default; + } +}); +Object.defineProperty(exports, "Extension", { + enumerable: true, + get: function get() { + return _Extension.default; + } +}); +Object.defineProperty(exports, "Extensions", { + enumerable: true, + get: function get() { + return _Extensions.default; + } +}); +Object.defineProperty(exports, "GeneralName", { + enumerable: true, + get: function get() { + return _GeneralName.default; + } +}); +Object.defineProperty(exports, "GeneralNames", { + enumerable: true, + get: function get() { + return _GeneralNames.default; + } +}); +Object.defineProperty(exports, "GeneralSubtree", { + enumerable: true, + get: function get() { + return _GeneralSubtree.default; + } +}); +Object.defineProperty(exports, "InfoAccess", { + enumerable: true, + get: function get() { + return _InfoAccess.default; + } +}); +Object.defineProperty(exports, "IssuerAndSerialNumber", { + enumerable: true, + get: function get() { + return _IssuerAndSerialNumber.default; + } +}); +Object.defineProperty(exports, "IssuingDistributionPoint", { + enumerable: true, + get: function get() { + return _IssuingDistributionPoint.default; + } +}); +Object.defineProperty(exports, "KEKIdentifier", { + enumerable: true, + get: function get() { + return _KEKIdentifier.default; + } +}); +Object.defineProperty(exports, "KEKRecipientInfo", { + enumerable: true, + get: function get() { + return _KEKRecipientInfo.default; + } +}); +Object.defineProperty(exports, "KeyAgreeRecipientIdentifier", { + enumerable: true, + get: function get() { + return _KeyAgreeRecipientIdentifier.default; + } +}); +Object.defineProperty(exports, "KeyAgreeRecipientInfo", { + enumerable: true, + get: function get() { + return _KeyAgreeRecipientInfo.default; + } +}); +Object.defineProperty(exports, "KeyBag", { + enumerable: true, + get: function get() { + return _KeyBag.default; + } +}); +Object.defineProperty(exports, "KeyTransRecipientInfo", { + enumerable: true, + get: function get() { + return _KeyTransRecipientInfo.default; + } +}); +Object.defineProperty(exports, "MacData", { + enumerable: true, + get: function get() { + return _MacData.default; + } +}); +Object.defineProperty(exports, "MessageImprint", { + enumerable: true, + get: function get() { + return _MessageImprint.default; + } +}); +Object.defineProperty(exports, "NameConstraints", { + enumerable: true, + get: function get() { + return _NameConstraints.default; + } +}); +Object.defineProperty(exports, "OCSPRequest", { + enumerable: true, + get: function get() { + return _OCSPRequest.default; + } +}); +Object.defineProperty(exports, "OCSPResponse", { + enumerable: true, + get: function get() { + return _OCSPResponse.default; + } +}); +Object.defineProperty(exports, "OriginatorIdentifierOrKey", { + enumerable: true, + get: function get() { + return _OriginatorIdentifierOrKey.default; + } +}); +Object.defineProperty(exports, "OriginatorInfo", { + enumerable: true, + get: function get() { + return _OriginatorInfo.default; + } +}); +Object.defineProperty(exports, "OriginatorPublicKey", { + enumerable: true, + get: function get() { + return _OriginatorPublicKey.default; + } +}); +Object.defineProperty(exports, "OtherCertificateFormat", { + enumerable: true, + get: function get() { + return _OtherCertificateFormat.default; + } +}); +Object.defineProperty(exports, "OtherKeyAttribute", { + enumerable: true, + get: function get() { + return _OtherKeyAttribute.default; + } +}); +Object.defineProperty(exports, "OtherPrimeInfo", { + enumerable: true, + get: function get() { + return _OtherPrimeInfo.default; + } +}); +Object.defineProperty(exports, "OtherRecipientInfo", { + enumerable: true, + get: function get() { + return _OtherRecipientInfo.default; + } +}); +Object.defineProperty(exports, "OtherRevocationInfoFormat", { + enumerable: true, + get: function get() { + return _OtherRevocationInfoFormat.default; + } +}); +Object.defineProperty(exports, "PBES2Params", { + enumerable: true, + get: function get() { + return _PBES2Params.default; + } +}); +Object.defineProperty(exports, "PBKDF2Params", { + enumerable: true, + get: function get() { + return _PBKDF2Params.default; + } +}); +Object.defineProperty(exports, "PFX", { + enumerable: true, + get: function get() { + return _PFX.default; + } +}); +Object.defineProperty(exports, "PKCS8ShroudedKeyBag", { + enumerable: true, + get: function get() { + return _PKCS8ShroudedKeyBag.default; + } +}); +Object.defineProperty(exports, "PKIStatusInfo", { + enumerable: true, + get: function get() { + return _PKIStatusInfo.default; + } +}); +Object.defineProperty(exports, "PasswordRecipientinfo", { + enumerable: true, + get: function get() { + return _PasswordRecipientinfo.default; + } +}); +Object.defineProperty(exports, "PolicyConstraints", { + enumerable: true, + get: function get() { + return _PolicyConstraints.default; + } +}); +Object.defineProperty(exports, "PolicyInformation", { + enumerable: true, + get: function get() { + return _PolicyInformation.default; + } +}); +Object.defineProperty(exports, "PolicyMapping", { + enumerable: true, + get: function get() { + return _PolicyMapping.default; + } +}); +Object.defineProperty(exports, "PolicyMappings", { + enumerable: true, + get: function get() { + return _PolicyMappings.default; + } +}); +Object.defineProperty(exports, "PolicyQualifierInfo", { + enumerable: true, + get: function get() { + return _PolicyQualifierInfo.default; + } +}); +Object.defineProperty(exports, "PrivateKeyInfo", { + enumerable: true, + get: function get() { + return _PrivateKeyInfo.default; + } +}); +Object.defineProperty(exports, "PrivateKeyUsagePeriod", { + enumerable: true, + get: function get() { + return _PrivateKeyUsagePeriod.default; + } +}); +Object.defineProperty(exports, "PublicKeyInfo", { + enumerable: true, + get: function get() { + return _PublicKeyInfo.default; + } +}); +Object.defineProperty(exports, "RSAESOAEPParams", { + enumerable: true, + get: function get() { + return _RSAESOAEPParams.default; + } +}); +Object.defineProperty(exports, "RSAPrivateKey", { + enumerable: true, + get: function get() { + return _RSAPrivateKey.default; + } +}); +Object.defineProperty(exports, "RSAPublicKey", { + enumerable: true, + get: function get() { + return _RSAPublicKey.default; + } +}); +Object.defineProperty(exports, "RSASSAPSSParams", { + enumerable: true, + get: function get() { + return _RSASSAPSSParams.default; + } +}); +Object.defineProperty(exports, "RecipientEncryptedKey", { + enumerable: true, + get: function get() { + return _RecipientEncryptedKey.default; + } +}); +Object.defineProperty(exports, "RecipientEncryptedKeys", { + enumerable: true, + get: function get() { + return _RecipientEncryptedKeys.default; + } +}); +Object.defineProperty(exports, "RecipientIdentifier", { + enumerable: true, + get: function get() { + return _RecipientIdentifier.default; + } +}); +Object.defineProperty(exports, "RecipientInfo", { + enumerable: true, + get: function get() { + return _RecipientInfo.default; + } +}); +Object.defineProperty(exports, "RecipientKeyIdentifier", { + enumerable: true, + get: function get() { + return _RecipientKeyIdentifier.default; + } +}); +Object.defineProperty(exports, "RelativeDistinguishedNames", { + enumerable: true, + get: function get() { + return _RelativeDistinguishedNames.default; + } +}); +Object.defineProperty(exports, "Request", { + enumerable: true, + get: function get() { + return _Request.default; + } +}); +Object.defineProperty(exports, "ResponseBytes", { + enumerable: true, + get: function get() { + return _ResponseBytes.default; + } +}); +Object.defineProperty(exports, "ResponseData", { + enumerable: true, + get: function get() { + return _ResponseData.default; + } +}); +Object.defineProperty(exports, "RevocationInfoChoices", { + enumerable: true, + get: function get() { + return _RevocationInfoChoices.default; + } +}); +Object.defineProperty(exports, "RevokedCertificate", { + enumerable: true, + get: function get() { + return _RevokedCertificate.default; + } +}); +Object.defineProperty(exports, "SafeBag", { + enumerable: true, + get: function get() { + return _SafeBag.default; + } +}); +Object.defineProperty(exports, "SafeContents", { + enumerable: true, + get: function get() { + return _SafeContents.default; + } +}); +Object.defineProperty(exports, "SecretBag", { + enumerable: true, + get: function get() { + return _SecretBag.default; + } +}); +Object.defineProperty(exports, "Signature", { + enumerable: true, + get: function get() { + return _Signature.default; + } +}); +Object.defineProperty(exports, "SignedAndUnsignedAttributes", { + enumerable: true, + get: function get() { + return _SignedAndUnsignedAttributes.default; + } +}); +Object.defineProperty(exports, "SignedData", { + enumerable: true, + get: function get() { + return _SignedData.default; + } +}); +Object.defineProperty(exports, "SignerInfo", { + enumerable: true, + get: function get() { + return _SignerInfo.default; + } +}); +Object.defineProperty(exports, "SingleResponse", { + enumerable: true, + get: function get() { + return _SingleResponse.default; + } +}); +Object.defineProperty(exports, "SubjectDirectoryAttributes", { + enumerable: true, + get: function get() { + return _SubjectDirectoryAttributes.default; + } +}); +Object.defineProperty(exports, "TBSRequest", { + enumerable: true, + get: function get() { + return _TBSRequest.default; + } +}); +Object.defineProperty(exports, "TSTInfo", { + enumerable: true, + get: function get() { + return _TSTInfo.default; + } +}); +Object.defineProperty(exports, "Time", { + enumerable: true, + get: function get() { + return _Time.default; + } +}); +Object.defineProperty(exports, "TimeStampReq", { + enumerable: true, + get: function get() { + return _TimeStampReq.default; + } +}); +Object.defineProperty(exports, "TimeStampResp", { + enumerable: true, + get: function get() { + return _TimeStampResp.default; + } +}); +Object.defineProperty(exports, "SignedCertificateTimestampList", { + enumerable: true, + get: function get() { + return _SignedCertificateTimestampList.default; + } +}); +Object.defineProperty(exports, "SignedCertificateTimestamp", { + enumerable: true, + get: function get() { + return _SignedCertificateTimestampList.SignedCertificateTimestamp; + } +}); +Object.defineProperty(exports, "verifySCTsForCertificate", { + enumerable: true, + get: function get() { + return _SignedCertificateTimestampList.verifySCTsForCertificate; + } +}); +Object.defineProperty(exports, "CertificateTemplate", { + enumerable: true, + get: function get() { + return _CertificateTemplate.default; + } +}); +Object.defineProperty(exports, "CAVersion", { + enumerable: true, + get: function get() { + return _CAVersion.default; + } +}); +Object.defineProperty(exports, "QCStatements", { + enumerable: true, + get: function get() { + return _CAVersion.default; + } +}); +Object.defineProperty(exports, "QCStatement", { + enumerable: true, + get: function get() { + return _QCStatements.QCStatement; + } +}); + +var _common = require("./common.js"); + +var _AccessDescription = _interopRequireDefault(require("./AccessDescription.js")); + +var _Accuracy = _interopRequireDefault(require("./Accuracy.js")); + +var _AlgorithmIdentifier = _interopRequireDefault(require("./AlgorithmIdentifier.js")); + +var _AltName = _interopRequireDefault(require("./AltName.js")); + +var _Attribute = _interopRequireDefault(require("./Attribute.js")); + +var _AttributeTypeAndValue = _interopRequireDefault(require("./AttributeTypeAndValue.js")); + +var _AuthenticatedSafe = _interopRequireDefault(require("./AuthenticatedSafe.js")); + +var _AuthorityKeyIdentifier = _interopRequireDefault(require("./AuthorityKeyIdentifier.js")); + +var _BasicConstraints = _interopRequireDefault(require("./BasicConstraints.js")); + +var _BasicOCSPResponse = _interopRequireDefault(require("./BasicOCSPResponse.js")); + +var _CRLBag = _interopRequireDefault(require("./CRLBag.js")); + +var _CRLDistributionPoints = _interopRequireDefault(require("./CRLDistributionPoints.js")); + +var _CertBag = _interopRequireDefault(require("./CertBag.js")); + +var _CertID = _interopRequireDefault(require("./CertID.js")); + +var _Certificate = _interopRequireDefault(require("./Certificate.js")); + +var _CertificateChainValidationEngine = _interopRequireDefault(require("./CertificateChainValidationEngine.js")); + +var _CertificatePolicies = _interopRequireDefault(require("./CertificatePolicies.js")); + +var _CertificateRevocationList = _interopRequireDefault(require("./CertificateRevocationList.js")); + +var _CertificateSet = _interopRequireDefault(require("./CertificateSet.js")); + +var _CertificationRequest = _interopRequireDefault(require("./CertificationRequest.js")); + +var _ContentInfo = _interopRequireDefault(require("./ContentInfo.js")); + +var _CryptoEngine = _interopRequireDefault(require("./CryptoEngine.js")); + +var _DigestInfo = _interopRequireDefault(require("./DigestInfo.js")); + +var _DistributionPoint = _interopRequireDefault(require("./DistributionPoint.js")); + +var _ECCCMSSharedInfo = _interopRequireDefault(require("./ECCCMSSharedInfo.js")); + +var _ECPrivateKey = _interopRequireDefault(require("./ECPrivateKey.js")); + +var _ECPublicKey = _interopRequireDefault(require("./ECPublicKey.js")); + +var _EncapsulatedContentInfo = _interopRequireDefault(require("./EncapsulatedContentInfo.js")); + +var _EncryptedContentInfo = _interopRequireDefault(require("./EncryptedContentInfo.js")); + +var _EncryptedData = _interopRequireDefault(require("./EncryptedData.js")); + +var _EnvelopedData = _interopRequireDefault(require("./EnvelopedData.js")); + +var _ExtKeyUsage = _interopRequireDefault(require("./ExtKeyUsage.js")); + +var _Extension = _interopRequireDefault(require("./Extension.js")); + +var _Extensions = _interopRequireDefault(require("./Extensions.js")); + +var _GeneralName = _interopRequireDefault(require("./GeneralName.js")); + +var _GeneralNames = _interopRequireDefault(require("./GeneralNames.js")); + +var _GeneralSubtree = _interopRequireDefault(require("./GeneralSubtree.js")); + +var _InfoAccess = _interopRequireDefault(require("./InfoAccess.js")); + +var _IssuerAndSerialNumber = _interopRequireDefault(require("./IssuerAndSerialNumber.js")); + +var _IssuingDistributionPoint = _interopRequireDefault(require("./IssuingDistributionPoint.js")); + +var _KEKIdentifier = _interopRequireDefault(require("./KEKIdentifier.js")); + +var _KEKRecipientInfo = _interopRequireDefault(require("./KEKRecipientInfo.js")); + +var _KeyAgreeRecipientIdentifier = _interopRequireDefault(require("./KeyAgreeRecipientIdentifier.js")); + +var _KeyAgreeRecipientInfo = _interopRequireDefault(require("./KeyAgreeRecipientInfo.js")); + +var _KeyBag = _interopRequireDefault(require("./KeyBag.js")); + +var _KeyTransRecipientInfo = _interopRequireDefault(require("./KeyTransRecipientInfo.js")); + +var _MacData = _interopRequireDefault(require("./MacData.js")); + +var _MessageImprint = _interopRequireDefault(require("./MessageImprint.js")); + +var _NameConstraints = _interopRequireDefault(require("./NameConstraints.js")); + +var _OCSPRequest = _interopRequireDefault(require("./OCSPRequest.js")); + +var _OCSPResponse = _interopRequireDefault(require("./OCSPResponse.js")); + +var _OriginatorIdentifierOrKey = _interopRequireDefault(require("./OriginatorIdentifierOrKey.js")); + +var _OriginatorInfo = _interopRequireDefault(require("./OriginatorInfo.js")); + +var _OriginatorPublicKey = _interopRequireDefault(require("./OriginatorPublicKey.js")); + +var _OtherCertificateFormat = _interopRequireDefault(require("./OtherCertificateFormat.js")); + +var _OtherKeyAttribute = _interopRequireDefault(require("./OtherKeyAttribute.js")); + +var _OtherPrimeInfo = _interopRequireDefault(require("./OtherPrimeInfo.js")); + +var _OtherRecipientInfo = _interopRequireDefault(require("./OtherRecipientInfo.js")); + +var _OtherRevocationInfoFormat = _interopRequireDefault(require("./OtherRevocationInfoFormat.js")); + +var _PBES2Params = _interopRequireDefault(require("./PBES2Params.js")); + +var _PBKDF2Params = _interopRequireDefault(require("./PBKDF2Params.js")); + +var _PFX = _interopRequireDefault(require("./PFX.js")); + +var _PKCS8ShroudedKeyBag = _interopRequireDefault(require("./PKCS8ShroudedKeyBag.js")); + +var _PKIStatusInfo = _interopRequireDefault(require("./PKIStatusInfo.js")); + +var _PasswordRecipientinfo = _interopRequireDefault(require("./PasswordRecipientinfo.js")); + +var _PolicyConstraints = _interopRequireDefault(require("./PolicyConstraints.js")); + +var _PolicyInformation = _interopRequireDefault(require("./PolicyInformation.js")); + +var _PolicyMapping = _interopRequireDefault(require("./PolicyMapping.js")); + +var _PolicyMappings = _interopRequireDefault(require("./PolicyMappings.js")); + +var _PolicyQualifierInfo = _interopRequireDefault(require("./PolicyQualifierInfo.js")); + +var _PrivateKeyInfo = _interopRequireDefault(require("./PrivateKeyInfo.js")); + +var _PrivateKeyUsagePeriod = _interopRequireDefault(require("./PrivateKeyUsagePeriod.js")); + +var _PublicKeyInfo = _interopRequireDefault(require("./PublicKeyInfo.js")); + +var _RSAESOAEPParams = _interopRequireDefault(require("./RSAESOAEPParams.js")); + +var _RSAPrivateKey = _interopRequireDefault(require("./RSAPrivateKey.js")); + +var _RSAPublicKey = _interopRequireDefault(require("./RSAPublicKey.js")); + +var _RSASSAPSSParams = _interopRequireDefault(require("./RSASSAPSSParams.js")); + +var _RecipientEncryptedKey = _interopRequireDefault(require("./RecipientEncryptedKey.js")); + +var _RecipientEncryptedKeys = _interopRequireDefault(require("./RecipientEncryptedKeys.js")); + +var _RecipientIdentifier = _interopRequireDefault(require("./RecipientIdentifier.js")); + +var _RecipientInfo = _interopRequireDefault(require("./RecipientInfo.js")); + +var _RecipientKeyIdentifier = _interopRequireDefault(require("./RecipientKeyIdentifier.js")); + +var _RelativeDistinguishedNames = _interopRequireDefault(require("./RelativeDistinguishedNames.js")); + +var _Request = _interopRequireDefault(require("./Request.js")); + +var _ResponseBytes = _interopRequireDefault(require("./ResponseBytes.js")); + +var _ResponseData = _interopRequireDefault(require("./ResponseData.js")); + +var _RevocationInfoChoices = _interopRequireDefault(require("./RevocationInfoChoices.js")); + +var _RevokedCertificate = _interopRequireDefault(require("./RevokedCertificate.js")); + +var _SafeBag = _interopRequireDefault(require("./SafeBag.js")); + +var _SafeContents = _interopRequireDefault(require("./SafeContents.js")); + +var _SecretBag = _interopRequireDefault(require("./SecretBag.js")); + +var _Signature = _interopRequireDefault(require("./Signature.js")); + +var _SignedAndUnsignedAttributes = _interopRequireDefault(require("./SignedAndUnsignedAttributes.js")); + +var _SignedData = _interopRequireDefault(require("./SignedData.js")); + +var _SignerInfo = _interopRequireDefault(require("./SignerInfo.js")); + +var _SingleResponse = _interopRequireDefault(require("./SingleResponse.js")); + +var _SubjectDirectoryAttributes = _interopRequireDefault(require("./SubjectDirectoryAttributes.js")); + +var _TBSRequest = _interopRequireDefault(require("./TBSRequest.js")); + +var _TSTInfo = _interopRequireDefault(require("./TSTInfo.js")); + +var _Time = _interopRequireDefault(require("./Time.js")); + +var _TimeStampReq = _interopRequireDefault(require("./TimeStampReq.js")); + +var _TimeStampResp = _interopRequireDefault(require("./TimeStampResp.js")); + +var _SignedCertificateTimestampList = _interopRequireWildcard(require("./SignedCertificateTimestampList.js")); + +var _CertificateTemplate = _interopRequireDefault(require("./CertificateTemplate.js")); + +var _CAVersion = _interopRequireDefault(require("./CAVersion.js")); + +var _QCStatements = require("./QCStatements.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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +},{"./AccessDescription.js":2,"./Accuracy.js":3,"./AlgorithmIdentifier.js":4,"./AltName.js":5,"./Attribute.js":6,"./AttributeTypeAndValue.js":9,"./AuthenticatedSafe.js":10,"./AuthorityKeyIdentifier.js":11,"./BasicConstraints.js":12,"./BasicOCSPResponse.js":13,"./CAVersion.js":14,"./CRLBag.js":15,"./CRLDistributionPoints.js":16,"./CertBag.js":17,"./CertID.js":18,"./Certificate.js":19,"./CertificateChainValidationEngine.js":20,"./CertificatePolicies.js":21,"./CertificateRevocationList.js":22,"./CertificateSet.js":23,"./CertificateTemplate.js":24,"./CertificationRequest.js":25,"./ContentInfo.js":26,"./CryptoEngine.js":27,"./DigestInfo.js":28,"./DistributionPoint.js":29,"./ECCCMSSharedInfo.js":30,"./ECPrivateKey.js":31,"./ECPublicKey.js":32,"./EncapsulatedContentInfo.js":33,"./EncryptedContentInfo.js":34,"./EncryptedData.js":35,"./EnvelopedData.js":36,"./ExtKeyUsage.js":37,"./Extension.js":38,"./Extensions.js":39,"./GeneralName.js":40,"./GeneralNames.js":41,"./GeneralSubtree.js":42,"./InfoAccess.js":43,"./IssuerAndSerialNumber.js":44,"./IssuingDistributionPoint.js":45,"./KEKIdentifier.js":46,"./KEKRecipientInfo.js":47,"./KeyAgreeRecipientIdentifier.js":48,"./KeyAgreeRecipientInfo.js":49,"./KeyBag.js":50,"./KeyTransRecipientInfo.js":51,"./MacData.js":52,"./MessageImprint.js":53,"./NameConstraints.js":54,"./OCSPRequest.js":55,"./OCSPResponse.js":56,"./OriginatorIdentifierOrKey.js":57,"./OriginatorInfo.js":58,"./OriginatorPublicKey.js":59,"./OtherCertificateFormat.js":60,"./OtherKeyAttribute.js":61,"./OtherPrimeInfo.js":62,"./OtherRecipientInfo.js":63,"./OtherRevocationInfoFormat.js":64,"./PBES2Params.js":65,"./PBKDF2Params.js":66,"./PFX.js":67,"./PKCS8ShroudedKeyBag.js":68,"./PKIStatusInfo.js":69,"./PasswordRecipientinfo.js":70,"./PolicyConstraints.js":71,"./PolicyInformation.js":72,"./PolicyMapping.js":73,"./PolicyMappings.js":74,"./PolicyQualifierInfo.js":75,"./PrivateKeyInfo.js":76,"./PrivateKeyUsagePeriod.js":77,"./PublicKeyInfo.js":78,"./QCStatements.js":79,"./RSAESOAEPParams.js":80,"./RSAPrivateKey.js":81,"./RSAPublicKey.js":82,"./RSASSAPSSParams.js":83,"./RecipientEncryptedKey.js":84,"./RecipientEncryptedKeys.js":85,"./RecipientIdentifier.js":86,"./RecipientInfo.js":87,"./RecipientKeyIdentifier.js":88,"./RelativeDistinguishedNames.js":89,"./Request.js":90,"./ResponseBytes.js":91,"./ResponseData.js":92,"./RevocationInfoChoices.js":93,"./RevokedCertificate.js":94,"./SafeBag.js":95,"./SafeContents.js":96,"./SecretBag.js":97,"./Signature.js":98,"./SignedAndUnsignedAttributes.js":99,"./SignedCertificateTimestampList.js":100,"./SignedData.js":101,"./SignerInfo.js":102,"./SingleResponse.js":103,"./SubjectDirectoryAttributes.js":104,"./TBSRequest.js":105,"./TSTInfo.js":106,"./Time.js":107,"./TimeStampReq.js":108,"./TimeStampResp.js":109,"./common.js":110}],112:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.fromBER = fromBER; +exports.compareSchema = compareSchema; +exports.verifySchema = verifySchema; +exports.fromJSON = fromJSON; +exports.RawData = exports.Repeated = exports.Any = exports.Choice = exports.TIME = exports.Duration = exports.DateTime = exports.TimeOfDay = exports.DATE = exports.GeneralizedTime = exports.UTCTime = exports.CharacterString = exports.GeneralString = exports.VisibleString = exports.GraphicString = exports.IA5String = exports.VideotexString = exports.TeletexString = exports.PrintableString = exports.NumericString = exports.UniversalString = exports.BmpString = exports.RelativeObjectIdentifier = exports.Utf8String = exports.ObjectIdentifier = exports.Enumerated = exports.Integer = exports.BitString = exports.OctetString = exports.Null = exports.Set = exports.Sequence = exports.Boolean = exports.EndOfContent = exports.Constructed = exports.Primitive = exports.BaseBlock = exports.ValueBlock = exports.HexBlock = void 0; + +var _pvutils = require("pvutils"); + +/* eslint-disable indent */ + +/* + * Copyright (c) 2016-2018, Peculiar Ventures + * All rights reserved. + * + * Author 2016-2018, Yury Strozhevsky . + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ +//************************************************************************************** +//************************************************************************************** +//region Declaration of global variables +//************************************************************************************** +const powers2 = [new Uint8Array([1])]; +const digitsString = "0123456789"; //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration for "LocalBaseBlock" class +//************************************************************************************** + +/** + * Class used as a base block for all remaining ASN.1 classes + * @typedef LocalBaseBlock + * @interface + * @property {number} blockLength + * @property {string} error + * @property {Array.} warnings + * @property {ArrayBuffer} valueBeforeDecode + */ + +class LocalBaseBlock { + //********************************************************************************** + + /** + * Constructor for "LocalBaseBlock" class + * @param {Object} [parameters={}] + * @property {ArrayBuffer} [valueBeforeDecode] + */ + constructor(parameters = {}) { + /** + * @type {number} blockLength + */ + this.blockLength = (0, _pvutils.getParametersValue)(parameters, "blockLength", 0); + /** + * @type {string} error + */ + + this.error = (0, _pvutils.getParametersValue)(parameters, "error", ""); + /** + * @type {Array.} warnings + */ + + this.warnings = (0, _pvutils.getParametersValue)(parameters, "warnings", []); //noinspection JSCheckFunctionSignatures + + /** + * @type {ArrayBuffer} valueBeforeDecode + */ + + if ("valueBeforeDecode" in parameters) this.valueBeforeDecode = parameters.valueBeforeDecode.slice(0);else this.valueBeforeDecode = new ArrayBuffer(0); + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "baseBlock"; + } //********************************************************************************** + + /** + * Convertion for the block to JSON object + * @returns {{blockName: string, blockLength: number, error: string, warnings: Array., valueBeforeDecode: string}} + */ + + + toJSON() { + return { + blockName: this.constructor.blockName(), + blockLength: this.blockLength, + error: this.error, + warnings: this.warnings, + valueBeforeDecode: (0, _pvutils.bufferToHexCodes)(this.valueBeforeDecode, 0, this.valueBeforeDecode.byteLength) + }; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Description for "HexBlock" class +//************************************************************************************** + +/** + * Class used as a base block for all remaining ASN.1 classes + * @extends LocalBaseBlock + * @typedef HexBlock + * @property {number} blockLength + * @property {string} error + * @property {Array.} warnings + * @property {ArrayBuffer} valueBeforeDecode + * @property {boolean} isHexOnly + * @property {ArrayBuffer} valueHex + */ +//noinspection JSUnusedLocalSymbols + + +const HexBlock = BaseClass => class LocalHexBlockMixin extends BaseClass { + //********************************************************************************** + //noinspection JSUnusedGlobalSymbols + + /** + * Constructor for "HexBlock" class + * @param {Object} [parameters={}] + * @property {ArrayBuffer} [valueHex] + */ + constructor(parameters = {}) { + super(parameters); + /** + * @type {boolean} + */ + + this.isHexOnly = (0, _pvutils.getParametersValue)(parameters, "isHexOnly", false); + /** + * @type {ArrayBuffer} + */ + + if ("valueHex" in parameters) this.valueHex = parameters.valueHex.slice(0);else this.valueHex = new ArrayBuffer(0); + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "hexBlock"; + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + //region Basic check for parameters + //noinspection JSCheckFunctionSignatures + if ((0, _pvutils.checkBufferParams)(this, inputBuffer, inputOffset, inputLength) === false) return -1; //endregion + //region Getting Uint8Array from ArrayBuffer + + const intBuffer = new Uint8Array(inputBuffer, inputOffset, inputLength); //endregion + //region Initial checks + + if (intBuffer.length === 0) { + this.warnings.push("Zero buffer length"); + return inputOffset; + } //endregion + //region Copy input buffer to internal buffer + + + this.valueHex = inputBuffer.slice(inputOffset, inputOffset + inputLength); //endregion + + this.blockLength = inputLength; + return inputOffset + inputLength; + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + if (this.isHexOnly !== true) { + this.error = "Flag \"isHexOnly\" is not set, abort"; + return new ArrayBuffer(0); + } + + if (sizeOnly === true) return new ArrayBuffer(this.valueHex.byteLength); //noinspection JSCheckFunctionSignatures + + return this.valueHex.slice(0); + } //********************************************************************************** + + /** + * Convertion for the block to JSON object + * @returns {Object} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.blockName = this.constructor.blockName(); + object.isHexOnly = this.isHexOnly; + object.valueHex = (0, _pvutils.bufferToHexCodes)(this.valueHex, 0, this.valueHex.byteLength); + return object; + } //********************************************************************************** + + +}; //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of identification block class +//************************************************************************************** + + +exports.HexBlock = HexBlock; + +class LocalIdentificationBlock extends HexBlock(LocalBaseBlock) { + //********************************************************************************** + + /** + * Constructor for "LocalBaseBlock" class + * @param {Object} [parameters={}] + * @property {Object} [idBlock] + */ + constructor(parameters = {}) { + super(); + + if ("idBlock" in parameters) { + //region Properties from hexBlock class + this.isHexOnly = (0, _pvutils.getParametersValue)(parameters.idBlock, "isHexOnly", false); + this.valueHex = (0, _pvutils.getParametersValue)(parameters.idBlock, "valueHex", new ArrayBuffer(0)); //endregion + + this.tagClass = (0, _pvutils.getParametersValue)(parameters.idBlock, "tagClass", -1); + this.tagNumber = (0, _pvutils.getParametersValue)(parameters.idBlock, "tagNumber", -1); + this.isConstructed = (0, _pvutils.getParametersValue)(parameters.idBlock, "isConstructed", false); + } else { + this.tagClass = -1; + this.tagNumber = -1; + this.isConstructed = false; + } + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "identificationBlock"; + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + //region Initial variables + let firstOctet = 0; + let retBuf; + let retView; //endregion + + switch (this.tagClass) { + case 1: + firstOctet |= 0x00; // UNIVERSAL + + break; + + case 2: + firstOctet |= 0x40; // APPLICATION + + break; + + case 3: + firstOctet |= 0x80; // CONTEXT-SPECIFIC + + break; + + case 4: + firstOctet |= 0xC0; // PRIVATE + + break; + + default: + this.error = "Unknown tag class"; + return new ArrayBuffer(0); + } + + if (this.isConstructed) firstOctet |= 0x20; + + if (this.tagNumber < 31 && !this.isHexOnly) { + retBuf = new ArrayBuffer(1); + retView = new Uint8Array(retBuf); + + if (!sizeOnly) { + let number = this.tagNumber; + number &= 0x1F; + firstOctet |= number; + retView[0] = firstOctet; + } + + return retBuf; + } + + if (this.isHexOnly === false) { + const encodedBuf = (0, _pvutils.utilToBase)(this.tagNumber, 7); + const encodedView = new Uint8Array(encodedBuf); + const size = encodedBuf.byteLength; + retBuf = new ArrayBuffer(size + 1); + retView = new Uint8Array(retBuf); + retView[0] = firstOctet | 0x1F; + + if (!sizeOnly) { + for (let i = 0; i < size - 1; i++) retView[i + 1] = encodedView[i] | 0x80; + + retView[size] = encodedView[size - 1]; + } + + return retBuf; + } + + retBuf = new ArrayBuffer(this.valueHex.byteLength + 1); + retView = new Uint8Array(retBuf); + retView[0] = firstOctet | 0x1F; + + if (sizeOnly === false) { + const curView = new Uint8Array(this.valueHex); + + for (let i = 0; i < curView.length - 1; i++) retView[i + 1] = curView[i] | 0x80; + + retView[this.valueHex.byteLength] = curView[curView.length - 1]; + } + + return retBuf; + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + //region Basic check for parameters + //noinspection JSCheckFunctionSignatures + if ((0, _pvutils.checkBufferParams)(this, inputBuffer, inputOffset, inputLength) === false) return -1; //endregion + //region Getting Uint8Array from ArrayBuffer + + const intBuffer = new Uint8Array(inputBuffer, inputOffset, inputLength); //endregion + //region Initial checks + + if (intBuffer.length === 0) { + this.error = "Zero buffer length"; + return -1; + } //endregion + //region Find tag class + + + const tagClassMask = intBuffer[0] & 0xC0; + + switch (tagClassMask) { + case 0x00: + this.tagClass = 1; // UNIVERSAL + + break; + + case 0x40: + this.tagClass = 2; // APPLICATION + + break; + + case 0x80: + this.tagClass = 3; // CONTEXT-SPECIFIC + + break; + + case 0xC0: + this.tagClass = 4; // PRIVATE + + break; + + default: + this.error = "Unknown tag class"; + return -1; + } //endregion + //region Find it's constructed or not + + + this.isConstructed = (intBuffer[0] & 0x20) === 0x20; //endregion + //region Find tag number + + this.isHexOnly = false; + const tagNumberMask = intBuffer[0] & 0x1F; //region Simple case (tag number < 31) + + if (tagNumberMask !== 0x1F) { + this.tagNumber = tagNumberMask; + this.blockLength = 1; + } //endregion + //region Tag number bigger or equal to 31 + else { + let count = 1; + this.valueHex = new ArrayBuffer(255); + let tagNumberBufferMaxLength = 255; + let intTagNumberBuffer = new Uint8Array(this.valueHex); //noinspection JSBitwiseOperatorUsage + + while (intBuffer[count] & 0x80) { + intTagNumberBuffer[count - 1] = intBuffer[count] & 0x7F; + count++; + + if (count >= intBuffer.length) { + this.error = "End of input reached before message was fully decoded"; + return -1; + } //region In case if tag number length is greater than 255 bytes (rare but possible case) + + + if (count === tagNumberBufferMaxLength) { + tagNumberBufferMaxLength += 255; + const tempBuffer = new ArrayBuffer(tagNumberBufferMaxLength); + const tempBufferView = new Uint8Array(tempBuffer); + + for (let i = 0; i < intTagNumberBuffer.length; i++) tempBufferView[i] = intTagNumberBuffer[i]; + + this.valueHex = new ArrayBuffer(tagNumberBufferMaxLength); + intTagNumberBuffer = new Uint8Array(this.valueHex); + } //endregion + + } + + this.blockLength = count + 1; + intTagNumberBuffer[count - 1] = intBuffer[count] & 0x7F; // Write last byte to buffer + //region Cut buffer + + const tempBuffer = new ArrayBuffer(count); + const tempBufferView = new Uint8Array(tempBuffer); + + for (let i = 0; i < count; i++) tempBufferView[i] = intTagNumberBuffer[i]; + + this.valueHex = new ArrayBuffer(count); + intTagNumberBuffer = new Uint8Array(this.valueHex); + intTagNumberBuffer.set(tempBufferView); //endregion + //region Try to convert long tag number to short form + + if (this.blockLength <= 9) this.tagNumber = (0, _pvutils.utilFromBase)(intTagNumberBuffer, 7);else { + this.isHexOnly = true; + this.warnings.push("Tag too long, represented as hex-coded"); + } //endregion + } //endregion + //endregion + //region Check if constructed encoding was using for primitive type + + + if (this.tagClass === 1 && this.isConstructed) { + switch (this.tagNumber) { + case 1: // Boolean + + case 2: // REAL + + case 5: // Null + + case 6: // OBJECT IDENTIFIER + + case 9: // REAL + + case 13: // RELATIVE OBJECT IDENTIFIER + + case 14: // Time + + case 23: + case 24: + case 31: + case 32: + case 33: + case 34: + this.error = "Constructed encoding used for primitive type"; + return -1; + + default: + } + } //endregion + + + return inputOffset + this.blockLength; // Return current offset in input buffer + } //********************************************************************************** + + /** + * Convertion for the block to JSON object + * @returns {{blockName: string, + * tagClass: number, + * tagNumber: number, + * isConstructed: boolean, + * isHexOnly: boolean, + * valueHex: ArrayBuffer, + * blockLength: number, + * error: string, warnings: Array., + * valueBeforeDecode: string}} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.blockName = this.constructor.blockName(); + object.tagClass = this.tagClass; + object.tagNumber = this.tagNumber; + object.isConstructed = this.isConstructed; + return object; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of length block class +//************************************************************************************** + + +class LocalLengthBlock extends LocalBaseBlock { + //********************************************************************************** + + /** + * Constructor for "LocalLengthBlock" class + * @param {Object} [parameters={}] + * @property {Object} [lenBlock] + */ + constructor(parameters = {}) { + super(); + + if ("lenBlock" in parameters) { + this.isIndefiniteForm = (0, _pvutils.getParametersValue)(parameters.lenBlock, "isIndefiniteForm", false); + this.longFormUsed = (0, _pvutils.getParametersValue)(parameters.lenBlock, "longFormUsed", false); + this.length = (0, _pvutils.getParametersValue)(parameters.lenBlock, "length", 0); + } else { + this.isIndefiniteForm = false; + this.longFormUsed = false; + this.length = 0; + } + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "lengthBlock"; + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + //region Basic check for parameters + //noinspection JSCheckFunctionSignatures + if ((0, _pvutils.checkBufferParams)(this, inputBuffer, inputOffset, inputLength) === false) return -1; //endregion + //region Getting Uint8Array from ArrayBuffer + + const intBuffer = new Uint8Array(inputBuffer, inputOffset, inputLength); //endregion + //region Initial checks + + if (intBuffer.length === 0) { + this.error = "Zero buffer length"; + return -1; + } + + if (intBuffer[0] === 0xFF) { + this.error = "Length block 0xFF is reserved by standard"; + return -1; + } //endregion + //region Check for length form type + + + this.isIndefiniteForm = intBuffer[0] === 0x80; //endregion + //region Stop working in case of indefinite length form + + if (this.isIndefiniteForm === true) { + this.blockLength = 1; + return inputOffset + this.blockLength; + } //endregion + //region Check is long form of length encoding using + + + this.longFormUsed = !!(intBuffer[0] & 0x80); //endregion + //region Stop working in case of short form of length value + + if (this.longFormUsed === false) { + this.length = intBuffer[0]; + this.blockLength = 1; + return inputOffset + this.blockLength; + } //endregion + //region Calculate length value in case of long form + + + const count = intBuffer[0] & 0x7F; + + if (count > 8) // Too big length value + { + this.error = "Too big integer"; + return -1; + } + + if (count + 1 > intBuffer.length) { + this.error = "End of input reached before message was fully decoded"; + return -1; + } + + const lengthBufferView = new Uint8Array(count); + + for (let i = 0; i < count; i++) lengthBufferView[i] = intBuffer[i + 1]; + + if (lengthBufferView[count - 1] === 0x00) this.warnings.push("Needlessly long encoded length"); + this.length = (0, _pvutils.utilFromBase)(lengthBufferView, 8); + if (this.longFormUsed && this.length <= 127) this.warnings.push("Unneccesary usage of long length form"); + this.blockLength = count + 1; //endregion + + return inputOffset + this.blockLength; // Return current offset in input buffer + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + //region Initial variables + let retBuf; + let retView; //endregion + + if (this.length > 127) this.longFormUsed = true; + + if (this.isIndefiniteForm) { + retBuf = new ArrayBuffer(1); + + if (sizeOnly === false) { + retView = new Uint8Array(retBuf); + retView[0] = 0x80; + } + + return retBuf; + } + + if (this.longFormUsed === true) { + const encodedBuf = (0, _pvutils.utilToBase)(this.length, 8); + + if (encodedBuf.byteLength > 127) { + this.error = "Too big length"; + return new ArrayBuffer(0); + } + + retBuf = new ArrayBuffer(encodedBuf.byteLength + 1); + if (sizeOnly === true) return retBuf; + const encodedView = new Uint8Array(encodedBuf); + retView = new Uint8Array(retBuf); + retView[0] = encodedBuf.byteLength | 0x80; + + for (let i = 0; i < encodedBuf.byteLength; i++) retView[i + 1] = encodedView[i]; + + return retBuf; + } + + retBuf = new ArrayBuffer(1); + + if (sizeOnly === false) { + retView = new Uint8Array(retBuf); + retView[0] = this.length; + } + + return retBuf; + } //********************************************************************************** + + /** + * Convertion for the block to JSON object + * @returns {{blockName, blockLength, error, warnings, valueBeforeDecode}|{blockName: string, blockLength: number, error: string, warnings: Array., valueBeforeDecode: string}} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.blockName = this.constructor.blockName(); + object.isIndefiniteForm = this.isIndefiniteForm; + object.longFormUsed = this.longFormUsed; + object.length = this.length; + return object; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of value block class +//************************************************************************************** + + +class ValueBlock extends LocalBaseBlock { + //********************************************************************************** + + /** + * Constructor for "ValueBlock" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "valueBlock"; + } //********************************************************************************** + //noinspection JSUnusedLocalSymbols,JSUnusedLocalSymbols,JSUnusedLocalSymbols + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + //region Throw an exception for a function which needs to be specified in extended classes + throw TypeError("User need to make a specific function in a class which extends \"ValueBlock\""); //endregion + } //********************************************************************************** + //noinspection JSUnusedLocalSymbols + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + //region Throw an exception for a function which needs to be specified in extended classes + throw TypeError("User need to make a specific function in a class which extends \"ValueBlock\""); //endregion + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of basic ASN.1 block class +//************************************************************************************** + + +exports.ValueBlock = ValueBlock; + +class BaseBlock extends LocalBaseBlock { + //********************************************************************************** + + /** + * Constructor for "BaseBlock" class + * @param {Object} [parameters={}] + * @property {Object} [primitiveSchema] + * @property {string} [name] + * @property {boolean} [optional] + * @param valueBlockType Type of value block + */ + constructor(parameters = {}, valueBlockType = ValueBlock) { + super(parameters); + if ("name" in parameters) this.name = parameters.name; + if ("optional" in parameters) this.optional = parameters.optional; + if ("primitiveSchema" in parameters) this.primitiveSchema = parameters.primitiveSchema; + this.idBlock = new LocalIdentificationBlock(parameters); + this.lenBlock = new LocalLengthBlock(parameters); + this.valueBlock = new valueBlockType(parameters); + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "BaseBlock"; + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm === true ? inputLength : this.lenBlock.length); + + if (resultOffset === -1) { + this.error = this.valueBlock.error; + return resultOffset; + } + + if (this.idBlock.error.length === 0) this.blockLength += this.idBlock.blockLength; + if (this.lenBlock.error.length === 0) this.blockLength += this.lenBlock.blockLength; + if (this.valueBlock.error.length === 0) this.blockLength += this.valueBlock.blockLength; + return resultOffset; + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + let retBuf; + const idBlockBuf = this.idBlock.toBER(sizeOnly); + const valueBlockSizeBuf = this.valueBlock.toBER(true); + this.lenBlock.length = valueBlockSizeBuf.byteLength; + const lenBlockBuf = this.lenBlock.toBER(sizeOnly); + retBuf = (0, _pvutils.utilConcatBuf)(idBlockBuf, lenBlockBuf); + let valueBlockBuf; + if (sizeOnly === false) valueBlockBuf = this.valueBlock.toBER(sizeOnly);else valueBlockBuf = new ArrayBuffer(this.lenBlock.length); + retBuf = (0, _pvutils.utilConcatBuf)(retBuf, valueBlockBuf); + + if (this.lenBlock.isIndefiniteForm === true) { + const indefBuf = new ArrayBuffer(2); + + if (sizeOnly === false) { + const indefView = new Uint8Array(indefBuf); + indefView[0] = 0x00; + indefView[1] = 0x00; + } + + retBuf = (0, _pvutils.utilConcatBuf)(retBuf, indefBuf); + } + + return retBuf; + } //********************************************************************************** + + /** + * Convertion for the block to JSON object + * @returns {{blockName, blockLength, error, warnings, valueBeforeDecode}|{blockName: string, blockLength: number, error: string, warnings: Array., valueBeforeDecode: string}} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.idBlock = this.idBlock.toJSON(); + object.lenBlock = this.lenBlock.toJSON(); + object.valueBlock = this.valueBlock.toJSON(); + if ("name" in this) object.name = this.name; + if ("optional" in this) object.optional = this.optional; + if ("primitiveSchema" in this) object.primitiveSchema = this.primitiveSchema.toJSON(); + return object; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of basic block for all PRIMITIVE types +//************************************************************************************** + + +exports.BaseBlock = BaseBlock; + +class LocalPrimitiveValueBlock extends ValueBlock { + //********************************************************************************** + + /** + * Constructor for "LocalPrimitiveValueBlock" class + * @param {Object} [parameters={}] + * @property {ArrayBuffer} [valueBeforeDecode] + */ + constructor(parameters = {}) { + super(parameters); //region Variables from "hexBlock" class + + if ("valueHex" in parameters) this.valueHex = parameters.valueHex.slice(0);else this.valueHex = new ArrayBuffer(0); + this.isHexOnly = (0, _pvutils.getParametersValue)(parameters, "isHexOnly", true); //endregion + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + //region Basic check for parameters + //noinspection JSCheckFunctionSignatures + if ((0, _pvutils.checkBufferParams)(this, inputBuffer, inputOffset, inputLength) === false) return -1; //endregion + //region Getting Uint8Array from ArrayBuffer + + const intBuffer = new Uint8Array(inputBuffer, inputOffset, inputLength); //endregion + //region Initial checks + + if (intBuffer.length === 0) { + this.warnings.push("Zero buffer length"); + return inputOffset; + } //endregion + //region Copy input buffer into internal buffer + + + this.valueHex = new ArrayBuffer(intBuffer.length); + const valueHexView = new Uint8Array(this.valueHex); + + for (let i = 0; i < intBuffer.length; i++) valueHexView[i] = intBuffer[i]; //endregion + + + this.blockLength = inputLength; + return inputOffset + inputLength; + } //********************************************************************************** + //noinspection JSUnusedLocalSymbols + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + return this.valueHex.slice(0); + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "PrimitiveValueBlock"; + } //********************************************************************************** + + /** + * Convertion for the block to JSON object + * @returns {{blockName, blockLength, error, warnings, valueBeforeDecode}|{blockName: string, blockLength: number, error: string, warnings: Array., valueBeforeDecode: string}} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.valueHex = (0, _pvutils.bufferToHexCodes)(this.valueHex, 0, this.valueHex.byteLength); + object.isHexOnly = this.isHexOnly; + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +class Primitive extends BaseBlock { + //********************************************************************************** + + /** + * Constructor for "Primitive" class + * @param {Object} [parameters={}] + * @property {ArrayBuffer} [valueHex] + */ + constructor(parameters = {}) { + super(parameters, LocalPrimitiveValueBlock); + this.idBlock.isConstructed = false; + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "PRIMITIVE"; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of basic block for all CONSTRUCTED types +//************************************************************************************** + + +exports.Primitive = Primitive; + +class LocalConstructedValueBlock extends ValueBlock { + //********************************************************************************** + + /** + * Constructor for "LocalConstructedValueBlock" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.value = (0, _pvutils.getParametersValue)(parameters, "value", []); + this.isIndefiniteForm = (0, _pvutils.getParametersValue)(parameters, "isIndefiniteForm", false); + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + //region Store initial offset and length + const initialOffset = inputOffset; + const initialLength = inputLength; //endregion + //region Basic check for parameters + //noinspection JSCheckFunctionSignatures + + if ((0, _pvutils.checkBufferParams)(this, inputBuffer, inputOffset, inputLength) === false) return -1; //endregion + //region Getting Uint8Array from ArrayBuffer + + const intBuffer = new Uint8Array(inputBuffer, inputOffset, inputLength); //endregion + //region Initial checks + + if (intBuffer.length === 0) { + this.warnings.push("Zero buffer length"); + return inputOffset; + } //endregion + //region Aux function + + + function checkLen(indefiniteLength, length) { + if (indefiniteLength === true) return 1; + return length; + } //endregion + + + let currentOffset = inputOffset; + + while (checkLen(this.isIndefiniteForm, inputLength) > 0) { + const returnObject = LocalFromBER(inputBuffer, currentOffset, inputLength); + + if (returnObject.offset === -1) { + this.error = returnObject.result.error; + this.warnings.concat(returnObject.result.warnings); + return -1; + } + + currentOffset = returnObject.offset; + this.blockLength += returnObject.result.blockLength; + inputLength -= returnObject.result.blockLength; + this.value.push(returnObject.result); + if (this.isIndefiniteForm === true && returnObject.result.constructor.blockName() === EndOfContent.blockName()) break; + } + + if (this.isIndefiniteForm === true) { + if (this.value[this.value.length - 1].constructor.blockName() === EndOfContent.blockName()) this.value.pop();else this.warnings.push("No EndOfContent block encoded"); + } //region Copy "inputBuffer" to "valueBeforeDecode" + + + this.valueBeforeDecode = inputBuffer.slice(initialOffset, initialOffset + initialLength); //endregion + + return currentOffset; + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + let retBuf = new ArrayBuffer(0); + + for (let i = 0; i < this.value.length; i++) { + const valueBuf = this.value[i].toBER(sizeOnly); + retBuf = (0, _pvutils.utilConcatBuf)(retBuf, valueBuf); + } + + return retBuf; + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "ConstructedValueBlock"; + } //********************************************************************************** + + /** + * Convertion for the block to JSON object + * @returns {{blockName, blockLength, error, warnings, valueBeforeDecode}|{blockName: string, blockLength: number, error: string, warnings: Array., valueBeforeDecode: string}} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.isIndefiniteForm = this.isIndefiniteForm; + object.value = []; + + for (let i = 0; i < this.value.length; i++) object.value.push(this.value[i].toJSON()); + + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +class Constructed extends BaseBlock { + //********************************************************************************** + + /** + * Constructor for "Constructed" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters, LocalConstructedValueBlock); + this.idBlock.isConstructed = true; + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "CONSTRUCTED"; + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm; + const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm === true ? inputLength : this.lenBlock.length); + + if (resultOffset === -1) { + this.error = this.valueBlock.error; + return resultOffset; + } + + if (this.idBlock.error.length === 0) this.blockLength += this.idBlock.blockLength; + if (this.lenBlock.error.length === 0) this.blockLength += this.lenBlock.blockLength; + if (this.valueBlock.error.length === 0) this.blockLength += this.valueBlock.blockLength; + return resultOffset; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of ASN.1 EndOfContent type class +//************************************************************************************** + + +exports.Constructed = Constructed; + +class LocalEndOfContentValueBlock extends ValueBlock { + //********************************************************************************** + + /** + * Constructor for "LocalEndOfContentValueBlock" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + } //********************************************************************************** + //noinspection JSUnusedLocalSymbols,JSUnusedLocalSymbols + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + //region There is no "value block" for EndOfContent type and we need to return the same offset + return inputOffset; //endregion + } //********************************************************************************** + //noinspection JSUnusedLocalSymbols + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + return new ArrayBuffer(0); + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "EndOfContentValueBlock"; + } //********************************************************************************** + + +} //************************************************************************************** + + +class EndOfContent extends BaseBlock { + //********************************************************************************** + constructor(paramaters = {}) { + super(paramaters, LocalEndOfContentValueBlock); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 0; // EndOfContent + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "EndOfContent"; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of ASN.1 Boolean type class +//************************************************************************************** + + +exports.EndOfContent = EndOfContent; + +class LocalBooleanValueBlock extends ValueBlock { + //********************************************************************************** + + /** + * Constructor for "LocalBooleanValueBlock" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.value = (0, _pvutils.getParametersValue)(parameters, "value", false); + this.isHexOnly = (0, _pvutils.getParametersValue)(parameters, "isHexOnly", false); + if ("valueHex" in parameters) this.valueHex = parameters.valueHex.slice(0);else { + this.valueHex = new ArrayBuffer(1); + + if (this.value === true) { + const view = new Uint8Array(this.valueHex); + view[0] = 0xFF; + } + } + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + //region Basic check for parameters + //noinspection JSCheckFunctionSignatures + if ((0, _pvutils.checkBufferParams)(this, inputBuffer, inputOffset, inputLength) === false) return -1; //endregion + //region Getting Uint8Array from ArrayBuffer + + const intBuffer = new Uint8Array(inputBuffer, inputOffset, inputLength); //endregion + + if (inputLength > 1) this.warnings.push("Boolean value encoded in more then 1 octet"); + this.isHexOnly = true; //region Copy input buffer to internal array + + this.valueHex = new ArrayBuffer(intBuffer.length); + const view = new Uint8Array(this.valueHex); + + for (let i = 0; i < intBuffer.length; i++) view[i] = intBuffer[i]; //endregion + + + if (_pvutils.utilDecodeTC.call(this) !== 0) this.value = true;else this.value = false; + this.blockLength = inputLength; + return inputOffset + inputLength; + } //********************************************************************************** + //noinspection JSUnusedLocalSymbols + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + return this.valueHex; + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "BooleanValueBlock"; + } //********************************************************************************** + + /** + * Convertion for the block to JSON object + * @returns {{blockName, blockLength, error, warnings, valueBeforeDecode}|{blockName: string, blockLength: number, error: string, warnings: Array., valueBeforeDecode: string}} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.value = this.value; + object.isHexOnly = this.isHexOnly; + object.valueHex = (0, _pvutils.bufferToHexCodes)(this.valueHex, 0, this.valueHex.byteLength); + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +class Boolean extends BaseBlock { + //********************************************************************************** + + /** + * Constructor for "Boolean" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters, LocalBooleanValueBlock); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 1; // Boolean + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "Boolean"; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of ASN.1 Sequence and Set type classes +//************************************************************************************** + + +exports.Boolean = Boolean; + +class Sequence extends Constructed { + //********************************************************************************** + + /** + * Constructor for "Sequence" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 16; // Sequence + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "Sequence"; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.Sequence = Sequence; + +class Set extends Constructed { + //********************************************************************************** + + /** + * Constructor for "Set" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 17; // Set + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "Set"; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of ASN.1 Null type class +//************************************************************************************** + + +exports.Set = Set; + +class Null extends BaseBlock { + //********************************************************************************** + + /** + * Constructor for "Null" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters, LocalBaseBlock); // We will not have a call to "Null value block" because of specified "fromBER" and "toBER" functions + + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 5; // Null + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "Null"; + } //********************************************************************************** + //noinspection JSUnusedLocalSymbols + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + if (this.lenBlock.length > 0) this.warnings.push("Non-zero length of value block for Null type"); + if (this.idBlock.error.length === 0) this.blockLength += this.idBlock.blockLength; + if (this.lenBlock.error.length === 0) this.blockLength += this.lenBlock.blockLength; + this.blockLength += inputLength; + + if (inputOffset + inputLength > inputBuffer.byteLength) { + this.error = "End of input reached before message was fully decoded (inconsistent offset and length values)"; + return -1; + } + + return inputOffset + inputLength; + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + const retBuf = new ArrayBuffer(2); + if (sizeOnly === true) return retBuf; + const retView = new Uint8Array(retBuf); + retView[0] = 0x05; + retView[1] = 0x00; + return retBuf; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of ASN.1 OctetString type class +//************************************************************************************** + + +exports.Null = Null; + +class LocalOctetStringValueBlock extends HexBlock(LocalConstructedValueBlock) { + //********************************************************************************** + + /** + * Constructor for "LocalOctetStringValueBlock" class + * @param {Object} [parameters={}] + * @property {ArrayBuffer} [valueHex] + */ + constructor(parameters = {}) { + super(parameters); + this.isConstructed = (0, _pvutils.getParametersValue)(parameters, "isConstructed", false); + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + let resultOffset = 0; + + if (this.isConstructed === true) { + this.isHexOnly = false; + resultOffset = LocalConstructedValueBlock.prototype.fromBER.call(this, inputBuffer, inputOffset, inputLength); + if (resultOffset === -1) return resultOffset; + + for (let i = 0; i < this.value.length; i++) { + const currentBlockName = this.value[i].constructor.blockName(); + + if (currentBlockName === EndOfContent.blockName()) { + if (this.isIndefiniteForm === true) break;else { + this.error = "EndOfContent is unexpected, OCTET STRING may consists of OCTET STRINGs only"; + return -1; + } + } + + if (currentBlockName !== OctetString.blockName()) { + this.error = "OCTET STRING may consists of OCTET STRINGs only"; + return -1; + } + } + } else { + this.isHexOnly = true; + resultOffset = super.fromBER(inputBuffer, inputOffset, inputLength); + this.blockLength = inputLength; + } + + return resultOffset; + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + if (this.isConstructed === true) return LocalConstructedValueBlock.prototype.toBER.call(this, sizeOnly); + let retBuf = new ArrayBuffer(this.valueHex.byteLength); + if (sizeOnly === true) return retBuf; + if (this.valueHex.byteLength === 0) return retBuf; + retBuf = this.valueHex.slice(0); + return retBuf; + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "OctetStringValueBlock"; + } //********************************************************************************** + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.isConstructed = this.isConstructed; + object.isHexOnly = this.isHexOnly; + object.valueHex = (0, _pvutils.bufferToHexCodes)(this.valueHex, 0, this.valueHex.byteLength); + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +class OctetString extends BaseBlock { + //********************************************************************************** + + /** + * Constructor for "OctetString" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters, LocalOctetStringValueBlock); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 4; // OctetString + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + this.valueBlock.isConstructed = this.idBlock.isConstructed; + this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm; //region Ability to encode empty OCTET STRING + + if (inputLength === 0) { + if (this.idBlock.error.length === 0) this.blockLength += this.idBlock.blockLength; + if (this.lenBlock.error.length === 0) this.blockLength += this.lenBlock.blockLength; + return inputOffset; + } //endregion + + + return super.fromBER(inputBuffer, inputOffset, inputLength); + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "OctetString"; + } //********************************************************************************** + //noinspection JSUnusedGlobalSymbols + + /** + * Checking that two OCTETSTRINGs are equal + * @param {OctetString} octetString + */ + + + isEqual(octetString) { + //region Check input type + if (octetString instanceof OctetString === false) return false; //endregion + //region Compare two JSON strings + + if (JSON.stringify(this) !== JSON.stringify(octetString)) return false; //endregion + + return true; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of ASN.1 BitString type class +//************************************************************************************** + + +exports.OctetString = OctetString; + +class LocalBitStringValueBlock extends HexBlock(LocalConstructedValueBlock) { + //********************************************************************************** + + /** + * Constructor for "LocalBitStringValueBlock" class + * @param {Object} [parameters={}] + * @property {ArrayBuffer} [valueHex] + */ + constructor(parameters = {}) { + super(parameters); + this.unusedBits = (0, _pvutils.getParametersValue)(parameters, "unusedBits", 0); + this.isConstructed = (0, _pvutils.getParametersValue)(parameters, "isConstructed", false); + this.blockLength = this.valueHex.byteLength; + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + //region Ability to decode zero-length BitString value + if (inputLength === 0) return inputOffset; //endregion + + let resultOffset = -1; //region If the BISTRING supposed to be a constructed value + + if (this.isConstructed === true) { + resultOffset = LocalConstructedValueBlock.prototype.fromBER.call(this, inputBuffer, inputOffset, inputLength); + if (resultOffset === -1) return resultOffset; + + for (let i = 0; i < this.value.length; i++) { + const currentBlockName = this.value[i].constructor.blockName(); + + if (currentBlockName === EndOfContent.blockName()) { + if (this.isIndefiniteForm === true) break;else { + this.error = "EndOfContent is unexpected, BIT STRING may consists of BIT STRINGs only"; + return -1; + } + } + + if (currentBlockName !== BitString.blockName()) { + this.error = "BIT STRING may consists of BIT STRINGs only"; + return -1; + } + + if (this.unusedBits > 0 && this.value[i].valueBlock.unusedBits > 0) { + this.error = "Usign of \"unused bits\" inside constructive BIT STRING allowed for least one only"; + return -1; + } + + this.unusedBits = this.value[i].valueBlock.unusedBits; + + if (this.unusedBits > 7) { + this.error = "Unused bits for BitString must be in range 0-7"; + return -1; + } + } + + return resultOffset; + } //endregion + //region If the BitString supposed to be a primitive value + //region Basic check for parameters + //noinspection JSCheckFunctionSignatures + + + if ((0, _pvutils.checkBufferParams)(this, inputBuffer, inputOffset, inputLength) === false) return -1; //endregion + + const intBuffer = new Uint8Array(inputBuffer, inputOffset, inputLength); + this.unusedBits = intBuffer[0]; + + if (this.unusedBits > 7) { + this.error = "Unused bits for BitString must be in range 0-7"; + return -1; + } //region Copy input buffer to internal buffer + + + this.valueHex = new ArrayBuffer(intBuffer.length - 1); + const view = new Uint8Array(this.valueHex); + + for (let i = 0; i < inputLength - 1; i++) view[i] = intBuffer[i + 1]; //endregion + + + this.blockLength = intBuffer.length; + return inputOffset + inputLength; //endregion + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + if (this.isConstructed === true) return LocalConstructedValueBlock.prototype.toBER.call(this, sizeOnly); + if (sizeOnly === true) return new ArrayBuffer(this.valueHex.byteLength + 1); + if (this.valueHex.byteLength === 0) return new ArrayBuffer(0); + const curView = new Uint8Array(this.valueHex); + const retBuf = new ArrayBuffer(this.valueHex.byteLength + 1); + const retView = new Uint8Array(retBuf); + retView[0] = this.unusedBits; + + for (let i = 0; i < this.valueHex.byteLength; i++) retView[i + 1] = curView[i]; + + return retBuf; + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "BitStringValueBlock"; + } //********************************************************************************** + + /** + * Convertion for the block to JSON object + * @returns {{blockName, blockLength, error, warnings, valueBeforeDecode}|{blockName: string, blockLength: number, error: string, warnings: Array., valueBeforeDecode: string}} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.unusedBits = this.unusedBits; + object.isConstructed = this.isConstructed; + object.isHexOnly = this.isHexOnly; + object.valueHex = (0, _pvutils.bufferToHexCodes)(this.valueHex, 0, this.valueHex.byteLength); + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +class BitString extends BaseBlock { + //********************************************************************************** + + /** + * Constructor for "BitString" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters, LocalBitStringValueBlock); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 3; // BitString + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "BitString"; + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + //region Ability to encode empty BitString + if (inputLength === 0) return inputOffset; //endregion + + this.valueBlock.isConstructed = this.idBlock.isConstructed; + this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm; + return super.fromBER(inputBuffer, inputOffset, inputLength); + } //********************************************************************************** + + /** + * Checking that two BITSTRINGs are equal + * @param {BitString} bitString + */ + + + isEqual(bitString) { + //region Check input type + if (bitString instanceof BitString === false) return false; //endregion + //region Compare two JSON strings + + if (JSON.stringify(this) !== JSON.stringify(bitString)) return false; //endregion + + return true; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of ASN.1 Integer type class +//************************************************************************************** + +/** + * @extends ValueBlock + */ + + +exports.BitString = BitString; + +class LocalIntegerValueBlock extends HexBlock(ValueBlock) { + //********************************************************************************** + + /** + * Constructor for "LocalIntegerValueBlock" class + * @param {Object} [parameters={}] + * @property {ArrayBuffer} [valueHex] + */ + constructor(parameters = {}) { + super(parameters); + if ("value" in parameters) this.valueDec = parameters.value; + } //********************************************************************************** + + /** + * Setter for "valueHex" + * @param {ArrayBuffer} _value + */ + + + set valueHex(_value) { + this._valueHex = _value.slice(0); + + if (_value.byteLength >= 4) { + this.warnings.push("Too big Integer for decoding, hex only"); + this.isHexOnly = true; + this._valueDec = 0; + } else { + this.isHexOnly = false; + if (_value.byteLength > 0) this._valueDec = _pvutils.utilDecodeTC.call(this); + } + } //********************************************************************************** + + /** + * Getter for "valueHex" + * @returns {ArrayBuffer} + */ + + + get valueHex() { + return this._valueHex; + } //********************************************************************************** + + /** + * Getter for "valueDec" + * @param {number} _value + */ + + + set valueDec(_value) { + this._valueDec = _value; + this.isHexOnly = false; + this._valueHex = (0, _pvutils.utilEncodeTC)(_value); + } //********************************************************************************** + + /** + * Getter for "valueDec" + * @returns {number} + */ + + + get valueDec() { + return this._valueDec; + } //********************************************************************************** + + /** + * Base function for converting block from DER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 DER encoded array + * @param {!number} inputOffset Offset in ASN.1 DER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @param {number} [expectedLength=0] Expected length of converted "valueHex" buffer + * @returns {number} Offset after least decoded byte + */ + + + fromDER(inputBuffer, inputOffset, inputLength, expectedLength = 0) { + const offset = this.fromBER(inputBuffer, inputOffset, inputLength); + if (offset === -1) return offset; + const view = new Uint8Array(this._valueHex); + + if (view[0] === 0x00 && (view[1] & 0x80) !== 0) { + const updatedValueHex = new ArrayBuffer(this._valueHex.byteLength - 1); + const updatedView = new Uint8Array(updatedValueHex); + updatedView.set(new Uint8Array(this._valueHex, 1, this._valueHex.byteLength - 1)); + this._valueHex = updatedValueHex.slice(0); + } else { + if (expectedLength !== 0) { + if (this._valueHex.byteLength < expectedLength) { + if (expectedLength - this._valueHex.byteLength > 1) expectedLength = this._valueHex.byteLength + 1; + const updatedValueHex = new ArrayBuffer(expectedLength); + const updatedView = new Uint8Array(updatedValueHex); + updatedView.set(view, expectedLength - this._valueHex.byteLength); + this._valueHex = updatedValueHex.slice(0); + } + } + } + + return offset; + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (DER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toDER(sizeOnly = false) { + const view = new Uint8Array(this._valueHex); + + switch (true) { + case (view[0] & 0x80) !== 0: + { + const updatedValueHex = new ArrayBuffer(this._valueHex.byteLength + 1); + const updatedView = new Uint8Array(updatedValueHex); + updatedView[0] = 0x00; + updatedView.set(view, 1); + this._valueHex = updatedValueHex.slice(0); + } + break; + + case view[0] === 0x00 && (view[1] & 0x80) === 0: + { + const updatedValueHex = new ArrayBuffer(this._valueHex.byteLength - 1); + const updatedView = new Uint8Array(updatedValueHex); + updatedView.set(new Uint8Array(this._valueHex, 1, this._valueHex.byteLength - 1)); + this._valueHex = updatedValueHex.slice(0); + } + break; + + default: + } + + return this.toBER(sizeOnly); + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + const resultOffset = super.fromBER(inputBuffer, inputOffset, inputLength); + if (resultOffset === -1) return resultOffset; + this.blockLength = inputLength; + return inputOffset + inputLength; + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + //noinspection JSCheckFunctionSignatures + return this.valueHex.slice(0); + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "IntegerValueBlock"; + } //********************************************************************************** + //noinspection JSUnusedGlobalSymbols + + /** + * Convertion for the block to JSON object + * @returns {Object} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.valueDec = this.valueDec; + return object; + } //********************************************************************************** + + /** + * Convert current value to decimal string representation + */ + + + toString() { + //region Aux functions + function viewAdd(first, second) { + //region Initial variables + const c = new Uint8Array([0]); + let firstView = new Uint8Array(first); + let secondView = new Uint8Array(second); + let firstViewCopy = firstView.slice(0); + const firstViewCopyLength = firstViewCopy.length - 1; + let secondViewCopy = secondView.slice(0); + const secondViewCopyLength = secondViewCopy.length - 1; + let value = 0; + const max = secondViewCopyLength < firstViewCopyLength ? firstViewCopyLength : secondViewCopyLength; + let counter = 0; //endregion + + for (let i = max; i >= 0; i--, counter++) { + switch (true) { + case counter < secondViewCopy.length: + value = firstViewCopy[firstViewCopyLength - counter] + secondViewCopy[secondViewCopyLength - counter] + c[0]; + break; + + default: + value = firstViewCopy[firstViewCopyLength - counter] + c[0]; + } + + c[0] = value / 10; + + switch (true) { + case counter >= firstViewCopy.length: + firstViewCopy = (0, _pvutils.utilConcatView)(new Uint8Array([value % 10]), firstViewCopy); + break; + + default: + firstViewCopy[firstViewCopyLength - counter] = value % 10; + } + } + + if (c[0] > 0) firstViewCopy = (0, _pvutils.utilConcatView)(c, firstViewCopy); + return firstViewCopy.slice(0); + } + + function power2(n) { + if (n >= powers2.length) { + for (let p = powers2.length; p <= n; p++) { + const c = new Uint8Array([0]); + let digits = powers2[p - 1].slice(0); + + for (let i = digits.length - 1; i >= 0; i--) { + const newValue = new Uint8Array([(digits[i] << 1) + c[0]]); + c[0] = newValue[0] / 10; + digits[i] = newValue[0] % 10; + } + + if (c[0] > 0) digits = (0, _pvutils.utilConcatView)(c, digits); + powers2.push(digits); + } + } + + return powers2[n]; + } + + function viewSub(first, second) { + //region Initial variables + let b = 0; + let firstView = new Uint8Array(first); + let secondView = new Uint8Array(second); + let firstViewCopy = firstView.slice(0); + const firstViewCopyLength = firstViewCopy.length - 1; + let secondViewCopy = secondView.slice(0); + const secondViewCopyLength = secondViewCopy.length - 1; + let value; + let counter = 0; //endregion + + for (let i = secondViewCopyLength; i >= 0; i--, counter++) { + value = firstViewCopy[firstViewCopyLength - counter] - secondViewCopy[secondViewCopyLength - counter] - b; + + switch (true) { + case value < 0: + b = 1; + firstViewCopy[firstViewCopyLength - counter] = value + 10; + break; + + default: + b = 0; + firstViewCopy[firstViewCopyLength - counter] = value; + } + } + + if (b > 0) { + for (let i = firstViewCopyLength - secondViewCopyLength + 1; i >= 0; i--, counter++) { + value = firstViewCopy[firstViewCopyLength - counter] - b; + + if (value < 0) { + b = 1; + firstViewCopy[firstViewCopyLength - counter] = value + 10; + } else { + b = 0; + firstViewCopy[firstViewCopyLength - counter] = value; + break; + } + } + } + + return firstViewCopy.slice(); + } //endregion + //region Initial variables + + + const firstBit = this._valueHex.byteLength * 8 - 1; + let digits = new Uint8Array(this._valueHex.byteLength * 8 / 3); + let bitNumber = 0; + let currentByte; + const asn1View = new Uint8Array(this._valueHex); + let result = ""; + let flag = false; //endregion + //region Calculate number + + for (let byteNumber = this._valueHex.byteLength - 1; byteNumber >= 0; byteNumber--) { + currentByte = asn1View[byteNumber]; + + for (let i = 0; i < 8; i++) { + if ((currentByte & 1) === 1) { + switch (bitNumber) { + case firstBit: + digits = viewSub(power2(bitNumber), digits); + result = "-"; + break; + + default: + digits = viewAdd(digits, power2(bitNumber)); + } + } + + bitNumber++; + currentByte >>= 1; + } + } //endregion + //region Print number + + + for (let i = 0; i < digits.length; i++) { + if (digits[i]) flag = true; + if (flag) result += digitsString.charAt(digits[i]); + } + + if (flag === false) result += digitsString.charAt(0); //endregion + + return result; + } //********************************************************************************** + + +} //************************************************************************************** + + +class Integer extends BaseBlock { + //********************************************************************************** + + /** + * Constructor for "Integer" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters, LocalIntegerValueBlock); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 2; // Integer + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "Integer"; + } //********************************************************************************** + //noinspection JSUnusedGlobalSymbols + + /** + * Compare two Integer object, or Integer and ArrayBuffer objects + * @param {!Integer|ArrayBuffer} otherValue + * @returns {boolean} + */ + + + isEqual(otherValue) { + if (otherValue instanceof Integer) { + if (this.valueBlock.isHexOnly && otherValue.valueBlock.isHexOnly) // Compare two ArrayBuffers + return (0, _pvutils.isEqualBuffer)(this.valueBlock.valueHex, otherValue.valueBlock.valueHex); + if (this.valueBlock.isHexOnly === otherValue.valueBlock.isHexOnly) return this.valueBlock.valueDec === otherValue.valueBlock.valueDec; + return false; + } + + if (otherValue instanceof ArrayBuffer) return (0, _pvutils.isEqualBuffer)(this.valueBlock.valueHex, otherValue); + return false; + } //********************************************************************************** + + /** + * Convert current Integer value from BER into DER format + * @returns {Integer} + */ + + + convertToDER() { + const integer = new Integer({ + valueHex: this.valueBlock.valueHex + }); + integer.valueBlock.toDER(); + return integer; + } //********************************************************************************** + + /** + * Convert current Integer value from DER to BER format + * @returns {Integer} + */ + + + convertFromDER() { + const expectedLength = this.valueBlock.valueHex.byteLength % 2 ? this.valueBlock.valueHex.byteLength + 1 : this.valueBlock.valueHex.byteLength; + const integer = new Integer({ + valueHex: this.valueBlock.valueHex + }); + integer.valueBlock.fromDER(integer.valueBlock.valueHex, 0, integer.valueBlock.valueHex.byteLength, expectedLength); + return integer; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of ASN.1 Enumerated type class +//************************************************************************************** + + +exports.Integer = Integer; + +class Enumerated extends Integer { + //********************************************************************************** + + /** + * Constructor for "Enumerated" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 10; // Enumerated + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "Enumerated"; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of ASN.1 ObjectIdentifier type class +//************************************************************************************** + + +exports.Enumerated = Enumerated; + +class LocalSidValueBlock extends HexBlock(LocalBaseBlock) { + //********************************************************************************** + + /** + * Constructor for "LocalSidValueBlock" class + * @param {Object} [parameters={}] + * @property {number} [valueDec] + * @property {boolean} [isFirstSid] + */ + constructor(parameters = {}) { + super(parameters); + this.valueDec = (0, _pvutils.getParametersValue)(parameters, "valueDec", -1); + this.isFirstSid = (0, _pvutils.getParametersValue)(parameters, "isFirstSid", false); + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "sidBlock"; + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + if (inputLength === 0) return inputOffset; //region Basic check for parameters + //noinspection JSCheckFunctionSignatures + + if ((0, _pvutils.checkBufferParams)(this, inputBuffer, inputOffset, inputLength) === false) return -1; //endregion + + const intBuffer = new Uint8Array(inputBuffer, inputOffset, inputLength); + this.valueHex = new ArrayBuffer(inputLength); + let view = new Uint8Array(this.valueHex); + + for (let i = 0; i < inputLength; i++) { + view[i] = intBuffer[i] & 0x7F; + this.blockLength++; + if ((intBuffer[i] & 0x80) === 0x00) break; + } //region Ajust size of valueHex buffer + + + const tempValueHex = new ArrayBuffer(this.blockLength); + const tempView = new Uint8Array(tempValueHex); + + for (let i = 0; i < this.blockLength; i++) tempView[i] = view[i]; //noinspection JSCheckFunctionSignatures + + + this.valueHex = tempValueHex.slice(0); + view = new Uint8Array(this.valueHex); //endregion + + if ((intBuffer[this.blockLength - 1] & 0x80) !== 0x00) { + this.error = "End of input reached before message was fully decoded"; + return -1; + } + + if (view[0] === 0x00) this.warnings.push("Needlessly long format of SID encoding"); + if (this.blockLength <= 8) this.valueDec = (0, _pvutils.utilFromBase)(view, 7);else { + this.isHexOnly = true; + this.warnings.push("Too big SID for decoding, hex only"); + } + return inputOffset + this.blockLength; + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + //region Initial variables + let retBuf; + let retView; //endregion + + if (this.isHexOnly) { + if (sizeOnly === true) return new ArrayBuffer(this.valueHex.byteLength); + const curView = new Uint8Array(this.valueHex); + retBuf = new ArrayBuffer(this.blockLength); + retView = new Uint8Array(retBuf); + + for (let i = 0; i < this.blockLength - 1; i++) retView[i] = curView[i] | 0x80; + + retView[this.blockLength - 1] = curView[this.blockLength - 1]; + return retBuf; + } + + const encodedBuf = (0, _pvutils.utilToBase)(this.valueDec, 7); + + if (encodedBuf.byteLength === 0) { + this.error = "Error during encoding SID value"; + return new ArrayBuffer(0); + } + + retBuf = new ArrayBuffer(encodedBuf.byteLength); + + if (sizeOnly === false) { + const encodedView = new Uint8Array(encodedBuf); + retView = new Uint8Array(retBuf); + + for (let i = 0; i < encodedBuf.byteLength - 1; i++) retView[i] = encodedView[i] | 0x80; + + retView[encodedBuf.byteLength - 1] = encodedView[encodedBuf.byteLength - 1]; + } + + return retBuf; + } //********************************************************************************** + + /** + * Create string representation of current SID block + * @returns {string} + */ + + + toString() { + let result = ""; + if (this.isHexOnly === true) result = (0, _pvutils.bufferToHexCodes)(this.valueHex, 0, this.valueHex.byteLength);else { + if (this.isFirstSid) { + let sidValue = this.valueDec; + if (this.valueDec <= 39) result = "0.";else { + if (this.valueDec <= 79) { + result = "1."; + sidValue -= 40; + } else { + result = "2."; + sidValue -= 80; + } + } + result += sidValue.toString(); + } else result = this.valueDec.toString(); + } + return result; + } //********************************************************************************** + //noinspection JSUnusedGlobalSymbols + + /** + * Convertion for the block to JSON object + * @returns {Object} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.valueDec = this.valueDec; + object.isFirstSid = this.isFirstSid; + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +class LocalObjectIdentifierValueBlock extends ValueBlock { + //********************************************************************************** + + /** + * Constructor for "LocalObjectIdentifierValueBlock" class + * @param {Object} [parameters={}] + * @property {ArrayBuffer} [valueHex] + */ + constructor(parameters = {}) { + super(parameters); + this.fromString((0, _pvutils.getParametersValue)(parameters, "value", "")); + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + let resultOffset = inputOffset; + + while (inputLength > 0) { + const sidBlock = new LocalSidValueBlock(); + resultOffset = sidBlock.fromBER(inputBuffer, resultOffset, inputLength); + + if (resultOffset === -1) { + this.blockLength = 0; + this.error = sidBlock.error; + return resultOffset; + } + + if (this.value.length === 0) sidBlock.isFirstSid = true; + this.blockLength += sidBlock.blockLength; + inputLength -= sidBlock.blockLength; + this.value.push(sidBlock); + } + + return resultOffset; + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + let retBuf = new ArrayBuffer(0); + + for (let i = 0; i < this.value.length; i++) { + const valueBuf = this.value[i].toBER(sizeOnly); + + if (valueBuf.byteLength === 0) { + this.error = this.value[i].error; + return new ArrayBuffer(0); + } + + retBuf = (0, _pvutils.utilConcatBuf)(retBuf, valueBuf); + } + + return retBuf; + } //********************************************************************************** + + /** + * Create "LocalObjectIdentifierValueBlock" class from string + * @param {string} string Input string to convert from + * @returns {boolean} + */ + + + fromString(string) { + this.value = []; // Clear existing SID values + + let pos1 = 0; + let pos2 = 0; + let sid = ""; + let flag = false; + + do { + pos2 = string.indexOf(".", pos1); + if (pos2 === -1) sid = string.substr(pos1);else sid = string.substr(pos1, pos2 - pos1); + pos1 = pos2 + 1; + + if (flag) { + const sidBlock = this.value[0]; + let plus = 0; + + switch (sidBlock.valueDec) { + case 0: + break; + + case 1: + plus = 40; + break; + + case 2: + plus = 80; + break; + + default: + this.value = []; // clear SID array + + return false; + // ??? + } + + const parsedSID = parseInt(sid, 10); + if (isNaN(parsedSID)) return true; + sidBlock.valueDec = parsedSID + plus; + flag = false; + } else { + const sidBlock = new LocalSidValueBlock(); + sidBlock.valueDec = parseInt(sid, 10); + if (isNaN(sidBlock.valueDec)) return true; + + if (this.value.length === 0) { + sidBlock.isFirstSid = true; + flag = true; + } + + this.value.push(sidBlock); + } + } while (pos2 !== -1); + + return true; + } //********************************************************************************** + + /** + * Converts "LocalObjectIdentifierValueBlock" class to string + * @returns {string} + */ + + + toString() { + let result = ""; + let isHexOnly = false; + + for (let i = 0; i < this.value.length; i++) { + isHexOnly = this.value[i].isHexOnly; + let sidStr = this.value[i].toString(); + if (i !== 0) result = `${result}.`; + + if (isHexOnly) { + sidStr = `{${sidStr}}`; + if (this.value[i].isFirstSid) result = `2.{${sidStr} - 80}`;else result += sidStr; + } else result += sidStr; + } + + return result; + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "ObjectIdentifierValueBlock"; + } //********************************************************************************** + + /** + * Convertion for the block to JSON object + * @returns {Object} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.value = this.toString(); + object.sidArray = []; + + for (let i = 0; i < this.value.length; i++) object.sidArray.push(this.value[i].toJSON()); + + return object; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends BaseBlock + */ + + +class ObjectIdentifier extends BaseBlock { + //********************************************************************************** + + /** + * Constructor for "ObjectIdentifier" class + * @param {Object} [parameters={}] + * @property {ArrayBuffer} [valueHex] + */ + constructor(parameters = {}) { + super(parameters, LocalObjectIdentifierValueBlock); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 6; // OBJECT IDENTIFIER + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "ObjectIdentifier"; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of all string's classes +//************************************************************************************** + + +exports.ObjectIdentifier = ObjectIdentifier; + +class LocalUtf8StringValueBlock extends HexBlock(LocalBaseBlock) { + //********************************************************************************** + //noinspection JSUnusedGlobalSymbols + + /** + * Constructor for "LocalUtf8StringValueBlock" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.isHexOnly = true; + this.value = ""; // String representation of decoded ArrayBuffer + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "Utf8StringValueBlock"; + } //********************************************************************************** + //noinspection JSUnusedGlobalSymbols + + /** + * Convertion for the block to JSON object + * @returns {Object} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.value = this.value; + return object; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends BaseBlock + */ + + +class Utf8String extends BaseBlock { + //********************************************************************************** + + /** + * Constructor for "Utf8String" class + * @param {Object} [parameters={}] + * @property {ArrayBuffer} [valueHex] + */ + constructor(parameters = {}) { + super(parameters, LocalUtf8StringValueBlock); + if ("value" in parameters) this.fromString(parameters.value); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 12; // Utf8String + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "Utf8String"; + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm === true ? inputLength : this.lenBlock.length); + + if (resultOffset === -1) { + this.error = this.valueBlock.error; + return resultOffset; + } + + this.fromBuffer(this.valueBlock.valueHex); + if (this.idBlock.error.length === 0) this.blockLength += this.idBlock.blockLength; + if (this.lenBlock.error.length === 0) this.blockLength += this.lenBlock.blockLength; + if (this.valueBlock.error.length === 0) this.blockLength += this.valueBlock.blockLength; + return resultOffset; + } //********************************************************************************** + + /** + * Function converting ArrayBuffer into ASN.1 internal string + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + */ + + + fromBuffer(inputBuffer) { + this.valueBlock.value = String.fromCharCode.apply(null, new Uint8Array(inputBuffer)); + + try { + //noinspection JSDeprecatedSymbols + this.valueBlock.value = decodeURIComponent(escape(this.valueBlock.value)); + } catch (ex) { + this.warnings.push(`Error during "decodeURIComponent": ${ex}, using raw string`); + } + } //********************************************************************************** + + /** + * Function converting JavaScript string into ASN.1 internal class + * @param {!string} inputString ASN.1 BER encoded array + */ + + + fromString(inputString) { + //noinspection JSDeprecatedSymbols + const str = unescape(encodeURIComponent(inputString)); + const strLen = str.length; + this.valueBlock.valueHex = new ArrayBuffer(strLen); + const view = new Uint8Array(this.valueBlock.valueHex); + + for (let i = 0; i < strLen; i++) view[i] = str.charCodeAt(i); + + this.valueBlock.value = inputString; + } //********************************************************************************** + + +} //************************************************************************************** +//region Declaration of ASN.1 RelativeObjectIdentifier type class +//************************************************************************************** + + +exports.Utf8String = Utf8String; + +class LocalRelativeSidValueBlock extends HexBlock(LocalBaseBlock) { + //********************************************************************************** + + /** + * Constructor for "LocalRelativeSidValueBlock" class + * @param {Object} [parameters={}] + * @property {number} [valueDec] + */ + constructor(parameters = {}) { + super(parameters); + this.valueDec = (0, _pvutils.getParametersValue)(parameters, "valueDec", -1); + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "relativeSidBlock"; + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + if (inputLength === 0) return inputOffset; //region Basic check for parameters + //noinspection JSCheckFunctionSignatures + + if ((0, _pvutils.checkBufferParams)(this, inputBuffer, inputOffset, inputLength) === false) return -1; //endregion + + const intBuffer = new Uint8Array(inputBuffer, inputOffset, inputLength); + this.valueHex = new ArrayBuffer(inputLength); + let view = new Uint8Array(this.valueHex); + + for (let i = 0; i < inputLength; i++) { + view[i] = intBuffer[i] & 0x7F; + this.blockLength++; + if ((intBuffer[i] & 0x80) === 0x00) break; + } //region Ajust size of valueHex buffer + + + const tempValueHex = new ArrayBuffer(this.blockLength); + const tempView = new Uint8Array(tempValueHex); + + for (let i = 0; i < this.blockLength; i++) tempView[i] = view[i]; //noinspection JSCheckFunctionSignatures + + + this.valueHex = tempValueHex.slice(0); + view = new Uint8Array(this.valueHex); //endregion + + if ((intBuffer[this.blockLength - 1] & 0x80) !== 0x00) { + this.error = "End of input reached before message was fully decoded"; + return -1; + } + + if (view[0] === 0x00) this.warnings.push("Needlessly long format of SID encoding"); + if (this.blockLength <= 8) this.valueDec = (0, _pvutils.utilFromBase)(view, 7);else { + this.isHexOnly = true; + this.warnings.push("Too big SID for decoding, hex only"); + } + return inputOffset + this.blockLength; + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + //region Initial variables + let retBuf; + let retView; //endregion + + if (this.isHexOnly) { + if (sizeOnly === true) return new ArrayBuffer(this.valueHex.byteLength); + const curView = new Uint8Array(this.valueHex); + retBuf = new ArrayBuffer(this.blockLength); + retView = new Uint8Array(retBuf); + + for (let i = 0; i < this.blockLength - 1; i++) retView[i] = curView[i] | 0x80; + + retView[this.blockLength - 1] = curView[this.blockLength - 1]; + return retBuf; + } + + const encodedBuf = (0, _pvutils.utilToBase)(this.valueDec, 7); + + if (encodedBuf.byteLength === 0) { + this.error = "Error during encoding SID value"; + return new ArrayBuffer(0); + } + + retBuf = new ArrayBuffer(encodedBuf.byteLength); + + if (sizeOnly === false) { + const encodedView = new Uint8Array(encodedBuf); + retView = new Uint8Array(retBuf); + + for (let i = 0; i < encodedBuf.byteLength - 1; i++) retView[i] = encodedView[i] | 0x80; + + retView[encodedBuf.byteLength - 1] = encodedView[encodedBuf.byteLength - 1]; + } + + return retBuf; + } //********************************************************************************** + + /** + * Create string representation of current SID block + * @returns {string} + */ + + + toString() { + let result = ""; + if (this.isHexOnly === true) result = (0, _pvutils.bufferToHexCodes)(this.valueHex, 0, this.valueHex.byteLength);else { + result = this.valueDec.toString(); + } + return result; + } //********************************************************************************** + //noinspection JSUnusedGlobalSymbols + + /** + * Convertion for the block to JSON object + * @returns {Object} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.valueDec = this.valueDec; + return object; + } //********************************************************************************** + + +} //************************************************************************************** + + +class LocalRelativeObjectIdentifierValueBlock extends ValueBlock { + //********************************************************************************** + + /** + * Constructor for "LocalRelativeObjectIdentifierValueBlock" class + * @param {Object} [parameters={}] + * @property {ArrayBuffer} [valueHex] + */ + constructor(parameters = {}) { + super(parameters); + this.fromString((0, _pvutils.getParametersValue)(parameters, "value", "")); + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + let resultOffset = inputOffset; + + while (inputLength > 0) { + const sidBlock = new LocalRelativeSidValueBlock(); + resultOffset = sidBlock.fromBER(inputBuffer, resultOffset, inputLength); + + if (resultOffset === -1) { + this.blockLength = 0; + this.error = sidBlock.error; + return resultOffset; + } + + this.blockLength += sidBlock.blockLength; + inputLength -= sidBlock.blockLength; + this.value.push(sidBlock); + } + + return resultOffset; + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + let retBuf = new ArrayBuffer(0); + + for (let i = 0; i < this.value.length; i++) { + const valueBuf = this.value[i].toBER(sizeOnly); + + if (valueBuf.byteLength === 0) { + this.error = this.value[i].error; + return new ArrayBuffer(0); + } + + retBuf = (0, _pvutils.utilConcatBuf)(retBuf, valueBuf); + } + + return retBuf; + } //********************************************************************************** + + /** + * Create "LocalRelativeObjectIdentifierValueBlock" class from string + * @param {string} string Input string to convert from + * @returns {boolean} + */ + + + fromString(string) { + this.value = []; // Clear existing SID values + + let pos1 = 0; + let pos2 = 0; + let sid = ""; + + do { + pos2 = string.indexOf(".", pos1); + if (pos2 === -1) sid = string.substr(pos1);else sid = string.substr(pos1, pos2 - pos1); + pos1 = pos2 + 1; + const sidBlock = new LocalRelativeSidValueBlock(); + sidBlock.valueDec = parseInt(sid, 10); + if (isNaN(sidBlock.valueDec)) return true; + this.value.push(sidBlock); + } while (pos2 !== -1); + + return true; + } //********************************************************************************** + + /** + * Converts "LocalRelativeObjectIdentifierValueBlock" class to string + * @returns {string} + */ + + + toString() { + let result = ""; + let isHexOnly = false; + + for (let i = 0; i < this.value.length; i++) { + isHexOnly = this.value[i].isHexOnly; + let sidStr = this.value[i].toString(); + if (i !== 0) result = `${result}.`; + + if (isHexOnly) { + sidStr = `{${sidStr}}`; + result += sidStr; + } else result += sidStr; + } + + return result; + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "RelativeObjectIdentifierValueBlock"; + } //********************************************************************************** + + /** + * Convertion for the block to JSON object + * @returns {Object} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.value = this.toString(); + object.sidArray = []; + + for (let i = 0; i < this.value.length; i++) object.sidArray.push(this.value[i].toJSON()); + + return object; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends BaseBlock + */ + + +class RelativeObjectIdentifier extends BaseBlock { + //********************************************************************************** + + /** + * Constructor for "RelativeObjectIdentifier" class + * @param {Object} [parameters={}] + * @property {ArrayBuffer} [valueHex] + */ + constructor(parameters = {}) { + super(parameters, LocalRelativeObjectIdentifierValueBlock); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 13; // RELATIVE OBJECT IDENTIFIER + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "RelativeObjectIdentifier"; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** + +/** + * @extends LocalBaseBlock + * @extends HexBlock + */ + + +exports.RelativeObjectIdentifier = RelativeObjectIdentifier; + +class LocalBmpStringValueBlock extends HexBlock(LocalBaseBlock) { + //********************************************************************************** + + /** + * Constructor for "LocalBmpStringValueBlock" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.isHexOnly = true; + this.value = ""; + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "BmpStringValueBlock"; + } //********************************************************************************** + //noinspection JSUnusedGlobalSymbols + + /** + * Convertion for the block to JSON object + * @returns {Object} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.value = this.value; + return object; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends BaseBlock + */ + + +class BmpString extends BaseBlock { + //********************************************************************************** + + /** + * Constructor for "BmpString" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters, LocalBmpStringValueBlock); + if ("value" in parameters) this.fromString(parameters.value); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 30; // BmpString + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "BmpString"; + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm === true ? inputLength : this.lenBlock.length); + + if (resultOffset === -1) { + this.error = this.valueBlock.error; + return resultOffset; + } + + this.fromBuffer(this.valueBlock.valueHex); + if (this.idBlock.error.length === 0) this.blockLength += this.idBlock.blockLength; + if (this.lenBlock.error.length === 0) this.blockLength += this.lenBlock.blockLength; + if (this.valueBlock.error.length === 0) this.blockLength += this.valueBlock.blockLength; + return resultOffset; + } //********************************************************************************** + + /** + * Function converting ArrayBuffer into ASN.1 internal string + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + */ + + + fromBuffer(inputBuffer) { + //noinspection JSCheckFunctionSignatures + const copyBuffer = inputBuffer.slice(0); + const valueView = new Uint8Array(copyBuffer); + + for (let i = 0; i < valueView.length; i += 2) { + const temp = valueView[i]; + valueView[i] = valueView[i + 1]; + valueView[i + 1] = temp; + } + + this.valueBlock.value = String.fromCharCode.apply(null, new Uint16Array(copyBuffer)); + } //********************************************************************************** + + /** + * Function converting JavaScript string into ASN.1 internal class + * @param {!string} inputString ASN.1 BER encoded array + */ + + + fromString(inputString) { + const strLength = inputString.length; + this.valueBlock.valueHex = new ArrayBuffer(strLength * 2); + const valueHexView = new Uint8Array(this.valueBlock.valueHex); + + for (let i = 0; i < strLength; i++) { + const codeBuf = (0, _pvutils.utilToBase)(inputString.charCodeAt(i), 8); + const codeView = new Uint8Array(codeBuf); + if (codeView.length > 2) continue; + const dif = 2 - codeView.length; + + for (let j = codeView.length - 1; j >= 0; j--) valueHexView[i * 2 + j + dif] = codeView[j]; + } + + this.valueBlock.value = inputString; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.BmpString = BmpString; + +class LocalUniversalStringValueBlock extends HexBlock(LocalBaseBlock) { + //********************************************************************************** + + /** + * Constructor for "LocalUniversalStringValueBlock" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.isHexOnly = true; + this.value = ""; + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "UniversalStringValueBlock"; + } //********************************************************************************** + //noinspection JSUnusedGlobalSymbols + + /** + * Convertion for the block to JSON object + * @returns {Object} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.value = this.value; + return object; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends BaseBlock + */ + + +class UniversalString extends BaseBlock { + //********************************************************************************** + + /** + * Constructor for "UniversalString" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters, LocalUniversalStringValueBlock); + if ("value" in parameters) this.fromString(parameters.value); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 28; // UniversalString + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "UniversalString"; + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm === true ? inputLength : this.lenBlock.length); + + if (resultOffset === -1) { + this.error = this.valueBlock.error; + return resultOffset; + } + + this.fromBuffer(this.valueBlock.valueHex); + if (this.idBlock.error.length === 0) this.blockLength += this.idBlock.blockLength; + if (this.lenBlock.error.length === 0) this.blockLength += this.lenBlock.blockLength; + if (this.valueBlock.error.length === 0) this.blockLength += this.valueBlock.blockLength; + return resultOffset; + } //********************************************************************************** + + /** + * Function converting ArrayBuffer into ASN.1 internal string + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + */ + + + fromBuffer(inputBuffer) { + //noinspection JSCheckFunctionSignatures + const copyBuffer = inputBuffer.slice(0); + const valueView = new Uint8Array(copyBuffer); + + for (let i = 0; i < valueView.length; i += 4) { + valueView[i] = valueView[i + 3]; + valueView[i + 1] = valueView[i + 2]; + valueView[i + 2] = 0x00; + valueView[i + 3] = 0x00; + } + + this.valueBlock.value = String.fromCharCode.apply(null, new Uint32Array(copyBuffer)); + } //********************************************************************************** + + /** + * Function converting JavaScript string into ASN.1 internal class + * @param {!string} inputString ASN.1 BER encoded array + */ + + + fromString(inputString) { + const strLength = inputString.length; + this.valueBlock.valueHex = new ArrayBuffer(strLength * 4); + const valueHexView = new Uint8Array(this.valueBlock.valueHex); + + for (let i = 0; i < strLength; i++) { + const codeBuf = (0, _pvutils.utilToBase)(inputString.charCodeAt(i), 8); + const codeView = new Uint8Array(codeBuf); + if (codeView.length > 4) continue; + const dif = 4 - codeView.length; + + for (let j = codeView.length - 1; j >= 0; j--) valueHexView[i * 4 + j + dif] = codeView[j]; + } + + this.valueBlock.value = inputString; + } //********************************************************************************** + + +} //************************************************************************************** + + +exports.UniversalString = UniversalString; + +class LocalSimpleStringValueBlock extends HexBlock(LocalBaseBlock) { + //********************************************************************************** + + /** + * Constructor for "LocalSimpleStringValueBlock" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.value = ""; + this.isHexOnly = true; + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "SimpleStringValueBlock"; + } //********************************************************************************** + //noinspection JSUnusedGlobalSymbols + + /** + * Convertion for the block to JSON object + * @returns {Object} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.value = this.value; + return object; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends BaseBlock + */ + + +class LocalSimpleStringBlock extends BaseBlock { + //********************************************************************************** + + /** + * Constructor for "LocalSimpleStringBlock" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters, LocalSimpleStringValueBlock); + if ("value" in parameters) this.fromString(parameters.value); + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "SIMPLESTRING"; + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm === true ? inputLength : this.lenBlock.length); + + if (resultOffset === -1) { + this.error = this.valueBlock.error; + return resultOffset; + } + + this.fromBuffer(this.valueBlock.valueHex); + if (this.idBlock.error.length === 0) this.blockLength += this.idBlock.blockLength; + if (this.lenBlock.error.length === 0) this.blockLength += this.lenBlock.blockLength; + if (this.valueBlock.error.length === 0) this.blockLength += this.valueBlock.blockLength; + return resultOffset; + } //********************************************************************************** + + /** + * Function converting ArrayBuffer into ASN.1 internal string + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + */ + + + fromBuffer(inputBuffer) { + this.valueBlock.value = String.fromCharCode.apply(null, new Uint8Array(inputBuffer)); + } //********************************************************************************** + + /** + * Function converting JavaScript string into ASN.1 internal class + * @param {!string} inputString ASN.1 BER encoded array + */ + + + fromString(inputString) { + const strLen = inputString.length; + this.valueBlock.valueHex = new ArrayBuffer(strLen); + const view = new Uint8Array(this.valueBlock.valueHex); + + for (let i = 0; i < strLen; i++) view[i] = inputString.charCodeAt(i); + + this.valueBlock.value = inputString; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends LocalSimpleStringBlock + */ + + +class NumericString extends LocalSimpleStringBlock { + //********************************************************************************** + + /** + * Constructor for "NumericString" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 18; // NumericString + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "NumericString"; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends LocalSimpleStringBlock + */ + + +exports.NumericString = NumericString; + +class PrintableString extends LocalSimpleStringBlock { + //********************************************************************************** + + /** + * Constructor for "PrintableString" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 19; // PrintableString + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "PrintableString"; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends LocalSimpleStringBlock + */ + + +exports.PrintableString = PrintableString; + +class TeletexString extends LocalSimpleStringBlock { + //********************************************************************************** + + /** + * Constructor for "TeletexString" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 20; // TeletexString + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "TeletexString"; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends LocalSimpleStringBlock + */ + + +exports.TeletexString = TeletexString; + +class VideotexString extends LocalSimpleStringBlock { + //********************************************************************************** + + /** + * Constructor for "VideotexString" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 21; // VideotexString + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "VideotexString"; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends LocalSimpleStringBlock + */ + + +exports.VideotexString = VideotexString; + +class IA5String extends LocalSimpleStringBlock { + //********************************************************************************** + + /** + * Constructor for "IA5String" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 22; // IA5String + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "IA5String"; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends LocalSimpleStringBlock + */ + + +exports.IA5String = IA5String; + +class GraphicString extends LocalSimpleStringBlock { + //********************************************************************************** + + /** + * Constructor for "GraphicString" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 25; // GraphicString + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "GraphicString"; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends LocalSimpleStringBlock + */ + + +exports.GraphicString = GraphicString; + +class VisibleString extends LocalSimpleStringBlock { + //********************************************************************************** + + /** + * Constructor for "VisibleString" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 26; // VisibleString + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "VisibleString"; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends LocalSimpleStringBlock + */ + + +exports.VisibleString = VisibleString; + +class GeneralString extends LocalSimpleStringBlock { + //********************************************************************************** + + /** + * Constructor for "GeneralString" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 27; // GeneralString + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "GeneralString"; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends LocalSimpleStringBlock + */ + + +exports.GeneralString = GeneralString; + +class CharacterString extends LocalSimpleStringBlock { + //********************************************************************************** + + /** + * Constructor for "CharacterString" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 29; // CharacterString + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "CharacterString"; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of all date and time classes +//************************************************************************************** + +/** + * @extends VisibleString + */ + + +exports.CharacterString = CharacterString; + +class UTCTime extends VisibleString { + //********************************************************************************** + + /** + * Constructor for "UTCTime" class + * @param {Object} [parameters={}] + * @property {string} [value] String representatio of the date + * @property {Date} [valueDate] JavaScript "Date" object + */ + constructor(parameters = {}) { + super(parameters); + this.year = 0; + this.month = 0; + this.day = 0; + this.hour = 0; + this.minute = 0; + this.second = 0; //region Create UTCTime from ASN.1 UTC string value + + if ("value" in parameters) { + this.fromString(parameters.value); + this.valueBlock.valueHex = new ArrayBuffer(parameters.value.length); + const view = new Uint8Array(this.valueBlock.valueHex); + + for (let i = 0; i < parameters.value.length; i++) view[i] = parameters.value.charCodeAt(i); + } //endregion + //region Create GeneralizedTime from JavaScript Date type + + + if ("valueDate" in parameters) { + this.fromDate(parameters.valueDate); + this.valueBlock.valueHex = this.toBuffer(); + } //endregion + + + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 23; // UTCTime + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm === true ? inputLength : this.lenBlock.length); + + if (resultOffset === -1) { + this.error = this.valueBlock.error; + return resultOffset; + } + + this.fromBuffer(this.valueBlock.valueHex); + if (this.idBlock.error.length === 0) this.blockLength += this.idBlock.blockLength; + if (this.lenBlock.error.length === 0) this.blockLength += this.lenBlock.blockLength; + if (this.valueBlock.error.length === 0) this.blockLength += this.valueBlock.blockLength; + return resultOffset; + } //********************************************************************************** + + /** + * Function converting ArrayBuffer into ASN.1 internal string + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + */ + + + fromBuffer(inputBuffer) { + this.fromString(String.fromCharCode.apply(null, new Uint8Array(inputBuffer))); + } //********************************************************************************** + + /** + * Function converting ASN.1 internal string into ArrayBuffer + * @returns {ArrayBuffer} + */ + + + toBuffer() { + const str = this.toString(); + const buffer = new ArrayBuffer(str.length); + const view = new Uint8Array(buffer); + + for (let i = 0; i < str.length; i++) view[i] = str.charCodeAt(i); + + return buffer; + } //********************************************************************************** + + /** + * Function converting "Date" object into ASN.1 internal string + * @param {!Date} inputDate JavaScript "Date" object + */ + + + fromDate(inputDate) { + this.year = inputDate.getUTCFullYear(); + this.month = inputDate.getUTCMonth() + 1; + this.day = inputDate.getUTCDate(); + this.hour = inputDate.getUTCHours(); + this.minute = inputDate.getUTCMinutes(); + this.second = inputDate.getUTCSeconds(); + } //********************************************************************************** + //noinspection JSUnusedGlobalSymbols + + /** + * Function converting ASN.1 internal string into "Date" object + * @returns {Date} + */ + + + toDate() { + return new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second)); + } //********************************************************************************** + + /** + * Function converting JavaScript string into ASN.1 internal class + * @param {!string} inputString ASN.1 BER encoded array + */ + + + fromString(inputString) { + //region Parse input string + const parser = /(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z/ig; + const parserArray = parser.exec(inputString); + + if (parserArray === null) { + this.error = "Wrong input string for convertion"; + return; + } //endregion + //region Store parsed values + + + const year = parseInt(parserArray[1], 10); + if (year >= 50) this.year = 1900 + year;else this.year = 2000 + year; + this.month = parseInt(parserArray[2], 10); + this.day = parseInt(parserArray[3], 10); + this.hour = parseInt(parserArray[4], 10); + this.minute = parseInt(parserArray[5], 10); + this.second = parseInt(parserArray[6], 10); //endregion + } //********************************************************************************** + + /** + * Function converting ASN.1 internal class into JavaScript string + * @returns {string} + */ + + + toString() { + const outputArray = new Array(7); + outputArray[0] = (0, _pvutils.padNumber)(this.year < 2000 ? this.year - 1900 : this.year - 2000, 2); + outputArray[1] = (0, _pvutils.padNumber)(this.month, 2); + outputArray[2] = (0, _pvutils.padNumber)(this.day, 2); + outputArray[3] = (0, _pvutils.padNumber)(this.hour, 2); + outputArray[4] = (0, _pvutils.padNumber)(this.minute, 2); + outputArray[5] = (0, _pvutils.padNumber)(this.second, 2); + outputArray[6] = "Z"; + return outputArray.join(""); + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "UTCTime"; + } //********************************************************************************** + + /** + * Convertion for the block to JSON object + * @returns {Object} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.year = this.year; + object.month = this.month; + object.day = this.day; + object.hour = this.hour; + object.minute = this.minute; + object.second = this.second; + return object; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends VisibleString + */ + + +exports.UTCTime = UTCTime; + +class GeneralizedTime extends VisibleString { + //********************************************************************************** + + /** + * Constructor for "GeneralizedTime" class + * @param {Object} [parameters={}] + * @property {string} [value] String representatio of the date + * @property {Date} [valueDate] JavaScript "Date" object + */ + constructor(parameters = {}) { + super(parameters); + this.year = 0; + this.month = 0; + this.day = 0; + this.hour = 0; + this.minute = 0; + this.second = 0; + this.millisecond = 0; //region Create UTCTime from ASN.1 UTC string value + + if ("value" in parameters) { + this.fromString(parameters.value); + this.valueBlock.valueHex = new ArrayBuffer(parameters.value.length); + const view = new Uint8Array(this.valueBlock.valueHex); + + for (let i = 0; i < parameters.value.length; i++) view[i] = parameters.value.charCodeAt(i); + } //endregion + //region Create GeneralizedTime from JavaScript Date type + + + if ("valueDate" in parameters) { + this.fromDate(parameters.valueDate); + this.valueBlock.valueHex = this.toBuffer(); + } //endregion + + + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 24; // GeneralizedTime + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm === true ? inputLength : this.lenBlock.length); + + if (resultOffset === -1) { + this.error = this.valueBlock.error; + return resultOffset; + } + + this.fromBuffer(this.valueBlock.valueHex); + if (this.idBlock.error.length === 0) this.blockLength += this.idBlock.blockLength; + if (this.lenBlock.error.length === 0) this.blockLength += this.lenBlock.blockLength; + if (this.valueBlock.error.length === 0) this.blockLength += this.valueBlock.blockLength; + return resultOffset; + } //********************************************************************************** + + /** + * Function converting ArrayBuffer into ASN.1 internal string + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + */ + + + fromBuffer(inputBuffer) { + this.fromString(String.fromCharCode.apply(null, new Uint8Array(inputBuffer))); + } //********************************************************************************** + + /** + * Function converting ASN.1 internal string into ArrayBuffer + * @returns {ArrayBuffer} + */ + + + toBuffer() { + const str = this.toString(); + const buffer = new ArrayBuffer(str.length); + const view = new Uint8Array(buffer); + + for (let i = 0; i < str.length; i++) view[i] = str.charCodeAt(i); + + return buffer; + } //********************************************************************************** + + /** + * Function converting "Date" object into ASN.1 internal string + * @param {!Date} inputDate JavaScript "Date" object + */ + + + fromDate(inputDate) { + this.year = inputDate.getUTCFullYear(); + this.month = inputDate.getUTCMonth() + 1; + this.day = inputDate.getUTCDate(); + this.hour = inputDate.getUTCHours(); + this.minute = inputDate.getUTCMinutes(); + this.second = inputDate.getUTCSeconds(); + this.millisecond = inputDate.getUTCMilliseconds(); + } //********************************************************************************** + //noinspection JSUnusedGlobalSymbols + + /** + * Function converting ASN.1 internal string into "Date" object + * @returns {Date} + */ + + + toDate() { + return new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second, this.millisecond)); + } //********************************************************************************** + + /** + * Function converting JavaScript string into ASN.1 internal class + * @param {!string} inputString ASN.1 BER encoded array + */ + + + fromString(inputString) { + //region Initial variables + let isUTC = false; + let timeString = ""; + let dateTimeString = ""; + let fractionPart = 0; + let parser; + let hourDifference = 0; + let minuteDifference = 0; //endregion + //region Convert as UTC time + + if (inputString[inputString.length - 1] === "Z") { + timeString = inputString.substr(0, inputString.length - 1); + isUTC = true; + } //endregion + //region Convert as local time + else { + //noinspection JSPrimitiveTypeWrapperUsage + const number = new Number(inputString[inputString.length - 1]); + if (isNaN(number.valueOf())) throw new Error("Wrong input string for convertion"); + timeString = inputString; + } //endregion + //region Check that we do not have a "+" and "-" symbols inside UTC time + + + if (isUTC) { + if (timeString.indexOf("+") !== -1) throw new Error("Wrong input string for convertion"); + if (timeString.indexOf("-") !== -1) throw new Error("Wrong input string for convertion"); + } //endregion + //region Get "UTC time difference" in case of local time + else { + let multiplier = 1; + let differencePosition = timeString.indexOf("+"); + let differenceString = ""; + + if (differencePosition === -1) { + differencePosition = timeString.indexOf("-"); + multiplier = -1; + } + + if (differencePosition !== -1) { + differenceString = timeString.substr(differencePosition + 1); + timeString = timeString.substr(0, differencePosition); + if (differenceString.length !== 2 && differenceString.length !== 4) throw new Error("Wrong input string for convertion"); //noinspection JSPrimitiveTypeWrapperUsage + + let number = new Number(differenceString.substr(0, 2)); + if (isNaN(number.valueOf())) throw new Error("Wrong input string for convertion"); + hourDifference = multiplier * number; + + if (differenceString.length === 4) { + //noinspection JSPrimitiveTypeWrapperUsage + number = new Number(differenceString.substr(2, 2)); + if (isNaN(number.valueOf())) throw new Error("Wrong input string for convertion"); + minuteDifference = multiplier * number; + } + } + } //endregion + //region Get position of fraction point + + + let fractionPointPosition = timeString.indexOf("."); // Check for "full stop" symbol + + if (fractionPointPosition === -1) fractionPointPosition = timeString.indexOf(","); // Check for "comma" symbol + //endregion + //region Get fraction part + + if (fractionPointPosition !== -1) { + //noinspection JSPrimitiveTypeWrapperUsage + const fractionPartCheck = new Number(`0${timeString.substr(fractionPointPosition)}`); + if (isNaN(fractionPartCheck.valueOf())) throw new Error("Wrong input string for convertion"); + fractionPart = fractionPartCheck.valueOf(); + dateTimeString = timeString.substr(0, fractionPointPosition); + } else dateTimeString = timeString; //endregion + //region Parse internal date + + + switch (true) { + case dateTimeString.length === 8: + // "YYYYMMDD" + parser = /(\d{4})(\d{2})(\d{2})/ig; + if (fractionPointPosition !== -1) throw new Error("Wrong input string for convertion"); // Here we should not have a "fraction point" + + break; + + case dateTimeString.length === 10: + // "YYYYMMDDHH" + parser = /(\d{4})(\d{2})(\d{2})(\d{2})/ig; + + if (fractionPointPosition !== -1) { + let fractionResult = 60 * fractionPart; + this.minute = Math.floor(fractionResult); + fractionResult = 60 * (fractionResult - this.minute); + this.second = Math.floor(fractionResult); + fractionResult = 1000 * (fractionResult - this.second); + this.millisecond = Math.floor(fractionResult); + } + + break; + + case dateTimeString.length === 12: + // "YYYYMMDDHHMM" + parser = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})/ig; + + if (fractionPointPosition !== -1) { + let fractionResult = 60 * fractionPart; + this.second = Math.floor(fractionResult); + fractionResult = 1000 * (fractionResult - this.second); + this.millisecond = Math.floor(fractionResult); + } + + break; + + case dateTimeString.length === 14: + // "YYYYMMDDHHMMSS" + parser = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/ig; + + if (fractionPointPosition !== -1) { + const fractionResult = 1000 * fractionPart; + this.millisecond = Math.floor(fractionResult); + } + + break; + + default: + throw new Error("Wrong input string for convertion"); + } //endregion + //region Put parsed values at right places + + + const parserArray = parser.exec(dateTimeString); + if (parserArray === null) throw new Error("Wrong input string for convertion"); + + for (let j = 1; j < parserArray.length; j++) { + switch (j) { + case 1: + this.year = parseInt(parserArray[j], 10); + break; + + case 2: + this.month = parseInt(parserArray[j], 10); + break; + + case 3: + this.day = parseInt(parserArray[j], 10); + break; + + case 4: + this.hour = parseInt(parserArray[j], 10) + hourDifference; + break; + + case 5: + this.minute = parseInt(parserArray[j], 10) + minuteDifference; + break; + + case 6: + this.second = parseInt(parserArray[j], 10); + break; + + default: + throw new Error("Wrong input string for convertion"); + } + } //endregion + //region Get final date + + + if (isUTC === false) { + const tempDate = new Date(this.year, this.month, this.day, this.hour, this.minute, this.second, this.millisecond); + this.year = tempDate.getUTCFullYear(); + this.month = tempDate.getUTCMonth(); + this.day = tempDate.getUTCDay(); + this.hour = tempDate.getUTCHours(); + this.minute = tempDate.getUTCMinutes(); + this.second = tempDate.getUTCSeconds(); + this.millisecond = tempDate.getUTCMilliseconds(); + } //endregion + + } //********************************************************************************** + + /** + * Function converting ASN.1 internal class into JavaScript string + * @returns {string} + */ + + + toString() { + const outputArray = []; + outputArray.push((0, _pvutils.padNumber)(this.year, 4)); + outputArray.push((0, _pvutils.padNumber)(this.month, 2)); + outputArray.push((0, _pvutils.padNumber)(this.day, 2)); + outputArray.push((0, _pvutils.padNumber)(this.hour, 2)); + outputArray.push((0, _pvutils.padNumber)(this.minute, 2)); + outputArray.push((0, _pvutils.padNumber)(this.second, 2)); + + if (this.millisecond !== 0) { + outputArray.push("."); + outputArray.push((0, _pvutils.padNumber)(this.millisecond, 3)); + } + + outputArray.push("Z"); + return outputArray.join(""); + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "GeneralizedTime"; + } //********************************************************************************** + + /** + * Convertion for the block to JSON object + * @returns {Object} + */ + + + toJSON() { + let object = {}; //region Seems at the moment (Sep 2016) there is no way how to check method is supported in "super" object + + try { + object = super.toJSON(); + } catch (ex) {} //endregion + + + object.year = this.year; + object.month = this.month; + object.day = this.day; + object.hour = this.hour; + object.minute = this.minute; + object.second = this.second; + object.millisecond = this.millisecond; + return object; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends Utf8String + */ + + +exports.GeneralizedTime = GeneralizedTime; + +class DATE extends Utf8String { + //********************************************************************************** + + /** + * Constructor for "DATE" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 31; // DATE + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "DATE"; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends Utf8String + */ + + +exports.DATE = DATE; + +class TimeOfDay extends Utf8String { + //********************************************************************************** + + /** + * Constructor for "TimeOfDay" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 32; // TimeOfDay + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "TimeOfDay"; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends Utf8String + */ + + +exports.TimeOfDay = TimeOfDay; + +class DateTime extends Utf8String { + //********************************************************************************** + + /** + * Constructor for "DateTime" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 33; // DateTime + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "DateTime"; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends Utf8String + */ + + +exports.DateTime = DateTime; + +class Duration extends Utf8String { + //********************************************************************************** + + /** + * Constructor for "Duration" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 34; // Duration + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "Duration"; + } //********************************************************************************** + + +} //************************************************************************************** + +/** + * @extends Utf8String + */ + + +exports.Duration = Duration; + +class TIME extends Utf8String { + //********************************************************************************** + + /** + * Constructor for "Time" class + * @param {Object} [parameters={}] + */ + constructor(parameters = {}) { + super(parameters); + this.idBlock.tagClass = 1; // UNIVERSAL + + this.idBlock.tagNumber = 14; // Time + } //********************************************************************************** + + /** + * Aux function, need to get a block name. Need to have it here for inhiritence + * @returns {string} + */ + + + static blockName() { + return "TIME"; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of special ASN.1 schema type Choice +//************************************************************************************** + + +exports.TIME = TIME; + +class Choice { + //********************************************************************************** + + /** + * Constructor for "Choice" class + * @param {Object} [parameters={}] + * @property {Array} [value] Array of ASN.1 types for make a choice from + * @property {boolean} [optional] + */ + constructor(parameters = {}) { + this.value = (0, _pvutils.getParametersValue)(parameters, "value", []); + this.optional = (0, _pvutils.getParametersValue)(parameters, "optional", false); + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of special ASN.1 schema type Any +//************************************************************************************** + + +exports.Choice = Choice; + +class Any { + //********************************************************************************** + + /** + * Constructor for "Any" class + * @param {Object} [parameters={}] + * @property {string} [name] + * @property {boolean} [optional] + */ + constructor(parameters = {}) { + this.name = (0, _pvutils.getParametersValue)(parameters, "name", ""); + this.optional = (0, _pvutils.getParametersValue)(parameters, "optional", false); + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of special ASN.1 schema type Repeated +//************************************************************************************** + + +exports.Any = Any; + +class Repeated { + //********************************************************************************** + + /** + * Constructor for "Repeated" class + * @param {Object} [parameters={}] + * @property {string} [name] + * @property {boolean} [optional] + */ + constructor(parameters = {}) { + this.name = (0, _pvutils.getParametersValue)(parameters, "name", ""); + this.optional = (0, _pvutils.getParametersValue)(parameters, "optional", false); + this.value = (0, _pvutils.getParametersValue)(parameters, "value", new Any()); + this.local = (0, _pvutils.getParametersValue)(parameters, "local", false); // Could local or global array to store elements + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Declaration of special ASN.1 schema type RawData +//************************************************************************************** + +/** + * @description Special class providing ability to have "toBER/fromBER" for raw ArrayBuffer + */ + + +exports.Repeated = Repeated; + +class RawData { + //********************************************************************************** + + /** + * Constructor for "Repeated" class + * @param {Object} [parameters={}] + * @property {string} [name] + * @property {boolean} [optional] + */ + constructor(parameters = {}) { + this.data = (0, _pvutils.getParametersValue)(parameters, "data", new ArrayBuffer(0)); + } //********************************************************************************** + + /** + * Base function for converting block from BER encoded array of bytes + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {number} Offset after least decoded byte + */ + + + fromBER(inputBuffer, inputOffset, inputLength) { + this.data = inputBuffer.slice(inputOffset, inputLength); + return inputOffset + inputLength; + } //********************************************************************************** + + /** + * Encoding of current ASN.1 block into ASN.1 encoded array (BER rules) + * @param {boolean} [sizeOnly=false] Flag that we need only a size of encoding, not a real array of bytes + * @returns {ArrayBuffer} + */ + + + toBER(sizeOnly = false) { + return this.data; + } //********************************************************************************** + + +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Major ASN.1 BER decoding function +//************************************************************************************** + +/** + * Internal library function for decoding ASN.1 BER + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array + * @param {!number} inputOffset Offset in ASN.1 BER encoded array where decoding should be started + * @param {!number} inputLength Maximum length of array of bytes which can be using in this function + * @returns {{offset: number, result: Object}} + */ + + +exports.RawData = RawData; + +function LocalFromBER(inputBuffer, inputOffset, inputLength) { + const incomingOffset = inputOffset; // Need to store initial offset since "inputOffset" is changing in the function + //region Local function changing a type for ASN.1 classes + + function localChangeType(inputObject, newType) { + if (inputObject instanceof newType) return inputObject; + const newObject = new newType(); + newObject.idBlock = inputObject.idBlock; + newObject.lenBlock = inputObject.lenBlock; + newObject.warnings = inputObject.warnings; //noinspection JSCheckFunctionSignatures + + newObject.valueBeforeDecode = inputObject.valueBeforeDecode.slice(0); + return newObject; + } //endregion + //region Create a basic ASN.1 type since we need to return errors and warnings from the function + + + let returnObject = new BaseBlock({}, Object); //endregion + //region Basic check for parameters + + const baseBlock = new LocalBaseBlock(); + + if ((0, _pvutils.checkBufferParams)(baseBlock, inputBuffer, inputOffset, inputLength) === false) { + returnObject.error = baseBlock.error; + return { + offset: -1, + result: returnObject + }; + } //endregion + //region Getting Uint8Array from ArrayBuffer + + + const intBuffer = new Uint8Array(inputBuffer, inputOffset, inputLength); //endregion + //region Initial checks + + if (intBuffer.length === 0) { + this.error = "Zero buffer length"; + return { + offset: -1, + result: returnObject + }; + } //endregion + //region Decode indentifcation block of ASN.1 BER structure + + + let resultOffset = returnObject.idBlock.fromBER(inputBuffer, inputOffset, inputLength); + returnObject.warnings.concat(returnObject.idBlock.warnings); + + if (resultOffset === -1) { + returnObject.error = returnObject.idBlock.error; + return { + offset: -1, + result: returnObject + }; + } + + inputOffset = resultOffset; + inputLength -= returnObject.idBlock.blockLength; //endregion + //region Decode length block of ASN.1 BER structure + + resultOffset = returnObject.lenBlock.fromBER(inputBuffer, inputOffset, inputLength); + returnObject.warnings.concat(returnObject.lenBlock.warnings); + + if (resultOffset === -1) { + returnObject.error = returnObject.lenBlock.error; + return { + offset: -1, + result: returnObject + }; + } + + inputOffset = resultOffset; + inputLength -= returnObject.lenBlock.blockLength; //endregion + //region Check for usign indefinite length form in encoding for primitive types + + if (returnObject.idBlock.isConstructed === false && returnObject.lenBlock.isIndefiniteForm === true) { + returnObject.error = "Indefinite length form used for primitive encoding form"; + return { + offset: -1, + result: returnObject + }; + } //endregion + //region Switch ASN.1 block type + + + let newASN1Type = BaseBlock; + + switch (returnObject.idBlock.tagClass) { + //region UNIVERSAL + case 1: + //region Check for reserved tag numbers + if (returnObject.idBlock.tagNumber >= 37 && returnObject.idBlock.isHexOnly === false) { + returnObject.error = "UNIVERSAL 37 and upper tags are reserved by ASN.1 standard"; + return { + offset: -1, + result: returnObject + }; + } //endregion + + + switch (returnObject.idBlock.tagNumber) { + //region EndOfContent type + case 0: + //region Check for EndOfContent type + if (returnObject.idBlock.isConstructed === true && returnObject.lenBlock.length > 0) { + returnObject.error = "Type [UNIVERSAL 0] is reserved"; + return { + offset: -1, + result: returnObject + }; + } //endregion + + + newASN1Type = EndOfContent; + break; + //endregion + //region Boolean type + + case 1: + newASN1Type = Boolean; + break; + //endregion + //region Integer type + + case 2: + newASN1Type = Integer; + break; + //endregion + //region BitString type + + case 3: + newASN1Type = BitString; + break; + //endregion + //region OctetString type + + case 4: + newASN1Type = OctetString; + break; + //endregion + //region Null type + + case 5: + newASN1Type = Null; + break; + //endregion + //region OBJECT IDENTIFIER type + + case 6: + newASN1Type = ObjectIdentifier; + break; + //endregion + //region Enumerated type + + case 10: + newASN1Type = Enumerated; + break; + //endregion + //region Utf8String type + + case 12: + newASN1Type = Utf8String; + break; + //endregion + //region Time type + //region RELATIVE OBJECT IDENTIFIER type + + case 13: + newASN1Type = RelativeObjectIdentifier; + break; + //endregion + + case 14: + newASN1Type = TIME; + break; + //endregion + //region ASN.1 reserved type + + case 15: + returnObject.error = "[UNIVERSAL 15] is reserved by ASN.1 standard"; + return { + offset: -1, + result: returnObject + }; + //endregion + //region Sequence type + + case 16: + newASN1Type = Sequence; + break; + //endregion + //region Set type + + case 17: + newASN1Type = Set; + break; + //endregion + //region NumericString type + + case 18: + newASN1Type = NumericString; + break; + //endregion + //region PrintableString type + + case 19: + newASN1Type = PrintableString; + break; + //endregion + //region TeletexString type + + case 20: + newASN1Type = TeletexString; + break; + //endregion + //region VideotexString type + + case 21: + newASN1Type = VideotexString; + break; + //endregion + //region IA5String type + + case 22: + newASN1Type = IA5String; + break; + //endregion + //region UTCTime type + + case 23: + newASN1Type = UTCTime; + break; + //endregion + //region GeneralizedTime type + + case 24: + newASN1Type = GeneralizedTime; + break; + //endregion + //region GraphicString type + + case 25: + newASN1Type = GraphicString; + break; + //endregion + //region VisibleString type + + case 26: + newASN1Type = VisibleString; + break; + //endregion + //region GeneralString type + + case 27: + newASN1Type = GeneralString; + break; + //endregion + //region UniversalString type + + case 28: + newASN1Type = UniversalString; + break; + //endregion + //region CharacterString type + + case 29: + newASN1Type = CharacterString; + break; + //endregion + //region BmpString type + + case 30: + newASN1Type = BmpString; + break; + //endregion + //region DATE type + + case 31: + newASN1Type = DATE; + break; + //endregion + //region TimeOfDay type + + case 32: + newASN1Type = TimeOfDay; + break; + //endregion + //region Date-Time type + + case 33: + newASN1Type = DateTime; + break; + //endregion + //region Duration type + + case 34: + newASN1Type = Duration; + break; + //endregion + //region default + + default: + { + let newObject; + if (returnObject.idBlock.isConstructed === true) newObject = new Constructed();else newObject = new Primitive(); + newObject.idBlock = returnObject.idBlock; + newObject.lenBlock = returnObject.lenBlock; + newObject.warnings = returnObject.warnings; + returnObject = newObject; + resultOffset = returnObject.fromBER(inputBuffer, inputOffset, inputLength); + } + //endregion + } + + break; + //endregion + //region All other tag classes + + case 2: // APPLICATION + + case 3: // CONTEXT-SPECIFIC + + case 4: // PRIVATE + + default: + { + if (returnObject.idBlock.isConstructed === true) newASN1Type = Constructed;else newASN1Type = Primitive; + } + //endregion + } //endregion + //region Change type and perform BER decoding + + + returnObject = localChangeType(returnObject, newASN1Type); + resultOffset = returnObject.fromBER(inputBuffer, inputOffset, returnObject.lenBlock.isIndefiniteForm === true ? inputLength : returnObject.lenBlock.length); //endregion + //region Coping incoming buffer for entire ASN.1 block + + returnObject.valueBeforeDecode = inputBuffer.slice(incomingOffset, incomingOffset + returnObject.blockLength); //endregion + + return { + offset: resultOffset, + result: returnObject + }; +} //************************************************************************************** + +/** + * Major function for decoding ASN.1 BER array into internal library structuries + * @param {!ArrayBuffer} inputBuffer ASN.1 BER encoded array of bytes + */ + + +function fromBER(inputBuffer) { + if (inputBuffer.byteLength === 0) { + const result = new BaseBlock({}, Object); + result.error = "Input buffer has zero length"; + return { + offset: -1, + result + }; + } + + return LocalFromBER(inputBuffer, 0, inputBuffer.byteLength); +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Major scheme verification function +//************************************************************************************** + +/** + * Compare of two ASN.1 object trees + * @param {!Object} root Root of input ASN.1 object tree + * @param {!Object} inputData Input ASN.1 object tree + * @param {!Object} inputSchema Input ASN.1 schema to compare with + * @return {{verified: boolean}|{verified:boolean, result: Object}} + */ + + +function compareSchema(root, inputData, inputSchema) { + //region Special case for Choice schema element type + if (inputSchema instanceof Choice) { + const choiceResult = false; + + for (let j = 0; j < inputSchema.value.length; j++) { + const result = compareSchema(root, inputData, inputSchema.value[j]); + + if (result.verified === true) { + return { + verified: true, + result: root + }; + } + } + + if (choiceResult === false) { + const _result = { + verified: false, + result: { + error: "Wrong values for Choice type" + } + }; + if (inputSchema.hasOwnProperty("name")) _result.name = inputSchema.name; + return _result; + } + } //endregion + //region Special case for Any schema element type + + + if (inputSchema instanceof Any) { + //region Add named component of ASN.1 schema + if (inputSchema.hasOwnProperty("name")) root[inputSchema.name] = inputData; //endregion + + return { + verified: true, + result: root + }; + } //endregion + //region Initial check + + + if (root instanceof Object === false) { + return { + verified: false, + result: { + error: "Wrong root object" + } + }; + } + + if (inputData instanceof Object === false) { + return { + verified: false, + result: { + error: "Wrong ASN.1 data" + } + }; + } + + if (inputSchema instanceof Object === false) { + return { + verified: false, + result: { + error: "Wrong ASN.1 schema" + } + }; + } + + if ("idBlock" in inputSchema === false) { + return { + verified: false, + result: { + error: "Wrong ASN.1 schema" + } + }; + } //endregion + //region Comparing idBlock properties in ASN.1 data and ASN.1 schema + //region Encode and decode ASN.1 schema idBlock + /// This encoding/decoding is neccessary because could be an errors in schema definition + + + if ("fromBER" in inputSchema.idBlock === false) { + return { + verified: false, + result: { + error: "Wrong ASN.1 schema" + } + }; + } + + if ("toBER" in inputSchema.idBlock === false) { + return { + verified: false, + result: { + error: "Wrong ASN.1 schema" + } + }; + } + + const encodedId = inputSchema.idBlock.toBER(false); + + if (encodedId.byteLength === 0) { + return { + verified: false, + result: { + error: "Error encoding idBlock for ASN.1 schema" + } + }; + } + + const decodedOffset = inputSchema.idBlock.fromBER(encodedId, 0, encodedId.byteLength); + + if (decodedOffset === -1) { + return { + verified: false, + result: { + error: "Error decoding idBlock for ASN.1 schema" + } + }; + } //endregion + //region tagClass + + + if (inputSchema.idBlock.hasOwnProperty("tagClass") === false) { + return { + verified: false, + result: { + error: "Wrong ASN.1 schema" + } + }; + } + + if (inputSchema.idBlock.tagClass !== inputData.idBlock.tagClass) { + return { + verified: false, + result: root + }; + } //endregion + //region tagNumber + + + if (inputSchema.idBlock.hasOwnProperty("tagNumber") === false) { + return { + verified: false, + result: { + error: "Wrong ASN.1 schema" + } + }; + } + + if (inputSchema.idBlock.tagNumber !== inputData.idBlock.tagNumber) { + return { + verified: false, + result: root + }; + } //endregion + //region isConstructed + + + if (inputSchema.idBlock.hasOwnProperty("isConstructed") === false) { + return { + verified: false, + result: { + error: "Wrong ASN.1 schema" + } + }; + } + + if (inputSchema.idBlock.isConstructed !== inputData.idBlock.isConstructed) { + return { + verified: false, + result: root + }; + } //endregion + //region isHexOnly + + + if ("isHexOnly" in inputSchema.idBlock === false) // Since 'isHexOnly' is an inhirited property + { + return { + verified: false, + result: { + error: "Wrong ASN.1 schema" + } + }; + } + + if (inputSchema.idBlock.isHexOnly !== inputData.idBlock.isHexOnly) { + return { + verified: false, + result: root + }; + } //endregion + //region valueHex + + + if (inputSchema.idBlock.isHexOnly === true) { + if ("valueHex" in inputSchema.idBlock === false) // Since 'valueHex' is an inhirited property + { + return { + verified: false, + result: { + error: "Wrong ASN.1 schema" + } + }; + } + + const schemaView = new Uint8Array(inputSchema.idBlock.valueHex); + const asn1View = new Uint8Array(inputData.idBlock.valueHex); + + if (schemaView.length !== asn1View.length) { + return { + verified: false, + result: root + }; + } + + for (let i = 0; i < schemaView.length; i++) { + if (schemaView[i] !== asn1View[1]) { + return { + verified: false, + result: root + }; + } + } + } //endregion + //endregion + //region Add named component of ASN.1 schema + + + if (inputSchema.hasOwnProperty("name")) { + inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, ""); + if (inputSchema.name !== "") root[inputSchema.name] = inputData; + } //endregion + //region Getting next ASN.1 block for comparition + + + if (inputSchema.idBlock.isConstructed === true) { + let admission = 0; + let result = { + verified: false + }; + let maxLength = inputSchema.valueBlock.value.length; + + if (maxLength > 0) { + if (inputSchema.valueBlock.value[0] instanceof Repeated) maxLength = inputData.valueBlock.value.length; + } //region Special case when constructive value has no elements + + + if (maxLength === 0) { + return { + verified: true, + result: root + }; + } //endregion + //region Special case when "inputData" has no values and "inputSchema" has all optional values + + + if (inputData.valueBlock.value.length === 0 && inputSchema.valueBlock.value.length !== 0) { + let _optional = true; + + for (let i = 0; i < inputSchema.valueBlock.value.length; i++) _optional = _optional && (inputSchema.valueBlock.value[i].optional || false); + + if (_optional === true) { + return { + verified: true, + result: root + }; + } //region Delete early added name of block + + + if (inputSchema.hasOwnProperty("name")) { + inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, ""); + if (inputSchema.name !== "") delete root[inputSchema.name]; + } //endregion + + + root.error = "Inconsistent object length"; + return { + verified: false, + result: root + }; + } //endregion + + + for (let i = 0; i < maxLength; i++) { + //region Special case when there is an "optional" element of ASN.1 schema at the end + if (i - admission >= inputData.valueBlock.value.length) { + if (inputSchema.valueBlock.value[i].optional === false) { + const _result = { + verified: false, + result: root + }; + root.error = "Inconsistent length between ASN.1 data and schema"; //region Delete early added name of block + + if (inputSchema.hasOwnProperty("name")) { + inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, ""); + + if (inputSchema.name !== "") { + delete root[inputSchema.name]; + _result.name = inputSchema.name; + } + } //endregion + + + return _result; + } + } //endregion + else { + //region Special case for Repeated type of ASN.1 schema element + if (inputSchema.valueBlock.value[0] instanceof Repeated) { + result = compareSchema(root, inputData.valueBlock.value[i], inputSchema.valueBlock.value[0].value); + + if (result.verified === false) { + if (inputSchema.valueBlock.value[0].optional === true) admission++;else { + //region Delete early added name of block + if (inputSchema.hasOwnProperty("name")) { + inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, ""); + if (inputSchema.name !== "") delete root[inputSchema.name]; + } //endregion + + + return result; + } + } + + if ("name" in inputSchema.valueBlock.value[0] && inputSchema.valueBlock.value[0].name.length > 0) { + let arrayRoot = {}; + if ("local" in inputSchema.valueBlock.value[0] && inputSchema.valueBlock.value[0].local === true) arrayRoot = inputData;else arrayRoot = root; + if (typeof arrayRoot[inputSchema.valueBlock.value[0].name] === "undefined") arrayRoot[inputSchema.valueBlock.value[0].name] = []; + arrayRoot[inputSchema.valueBlock.value[0].name].push(inputData.valueBlock.value[i]); + } + } //endregion + else { + result = compareSchema(root, inputData.valueBlock.value[i - admission], inputSchema.valueBlock.value[i]); + + if (result.verified === false) { + if (inputSchema.valueBlock.value[i].optional === true) admission++;else { + //region Delete early added name of block + if (inputSchema.hasOwnProperty("name")) { + inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, ""); + if (inputSchema.name !== "") delete root[inputSchema.name]; + } //endregion + + + return result; + } + } + } + } + } + + if (result.verified === false) // The situation may take place if last element is "optional" and verification failed + { + const _result = { + verified: false, + result: root + }; //region Delete early added name of block + + if (inputSchema.hasOwnProperty("name")) { + inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, ""); + + if (inputSchema.name !== "") { + delete root[inputSchema.name]; + _result.name = inputSchema.name; + } + } //endregion + + + return _result; + } + + return { + verified: true, + result: root + }; + } //endregion + //region Ability to parse internal value for primitive-encoded value (value of OctetString, for example) + + + if ("primitiveSchema" in inputSchema && "valueHex" in inputData.valueBlock) { + //region Decoding of raw ASN.1 data + const asn1 = fromBER(inputData.valueBlock.valueHex); + + if (asn1.offset === -1) { + const _result = { + verified: false, + result: asn1.result + }; //region Delete early added name of block + + if (inputSchema.hasOwnProperty("name")) { + inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, ""); + + if (inputSchema.name !== "") { + delete root[inputSchema.name]; + _result.name = inputSchema.name; + } + } //endregion + + + return _result; + } //endregion + + + return compareSchema(root, asn1.result, inputSchema.primitiveSchema); + } + + return { + verified: true, + result: root + }; //endregion +} //************************************************************************************** +//noinspection JSUnusedGlobalSymbols + +/** + * ASN.1 schema verification for ArrayBuffer data + * @param {!ArrayBuffer} inputBuffer Input BER-encoded ASN.1 data + * @param {!Object} inputSchema Input ASN.1 schema to verify against to + * @return {{verified: boolean}|{verified:boolean, result: Object}} + */ + + +function verifySchema(inputBuffer, inputSchema) { + //region Initial check + if (inputSchema instanceof Object === false) { + return { + verified: false, + result: { + error: "Wrong ASN.1 schema type" + } + }; + } //endregion + //region Decoding of raw ASN.1 data + + + const asn1 = fromBER(inputBuffer); + + if (asn1.offset === -1) { + return { + verified: false, + result: asn1.result + }; + } //endregion + //region Compare ASN.1 struct with input schema + + + return compareSchema(asn1.result, asn1.result, inputSchema); //endregion +} //************************************************************************************** +//endregion +//************************************************************************************** +//region Major function converting JSON to ASN.1 objects +//************************************************************************************** +//noinspection JSUnusedGlobalSymbols + +/** + * Converting from JSON to ASN.1 objects + * @param {string|Object} json JSON string or object to convert to ASN.1 objects + */ + + +function fromJSON(json) {} // TODO Implement +//************************************************************************************** +//endregion +//************************************************************************************** + +},{"pvutils":113}],113:[function(require,module,exports){ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getUTCDate = getUTCDate; +exports.getParametersValue = getParametersValue; +exports.bufferToHexCodes = bufferToHexCodes; +exports.checkBufferParams = checkBufferParams; +exports.utilFromBase = utilFromBase; +exports.utilToBase = utilToBase; +exports.utilConcatBuf = utilConcatBuf; +exports.utilConcatView = utilConcatView; +exports.utilDecodeTC = utilDecodeTC; +exports.utilEncodeTC = utilEncodeTC; +exports.isEqualBuffer = isEqualBuffer; +exports.padNumber = padNumber; +exports.toBase64 = toBase64; +exports.fromBase64 = fromBase64; +exports.arrayBufferToString = arrayBufferToString; +exports.stringToArrayBuffer = stringToArrayBuffer; +exports.nearestPowerOf2 = nearestPowerOf2; +exports.clearProps = clearProps; +//************************************************************************************** +/** + * Making UTC date from local date + * @param {Date} date Date to convert from + * @returns {Date} + */ +function getUTCDate(date) { + // noinspection NestedFunctionCallJS, MagicNumberJS + return new Date(date.getTime() + date.getTimezoneOffset() * 60000); +} +//************************************************************************************** +// noinspection FunctionWithMultipleReturnPointsJS +/** + * Get value for input parameters, or set a default value + * @param {Object} parameters + * @param {string} name + * @param defaultValue + */ +function getParametersValue(parameters, name, defaultValue) { + // noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS + if (parameters instanceof Object === false) return defaultValue; + + // noinspection NonBlockStatementBodyJS + if (name in parameters) return parameters[name]; + + return defaultValue; +} +//************************************************************************************** +/** + * Converts "ArrayBuffer" into a hexdecimal string + * @param {ArrayBuffer} inputBuffer + * @param {number} [inputOffset=0] + * @param {number} [inputLength=inputBuffer.byteLength] + * @param {boolean} [insertSpace=false] + * @returns {string} + */ +function bufferToHexCodes(inputBuffer, inputOffset = 0, inputLength = inputBuffer.byteLength - inputOffset, insertSpace = false) { + let result = ""; + + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = new Uint8Array(inputBuffer, inputOffset, inputLength)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + const item = _step.value; + + // noinspection ChainedFunctionCallJS + const str = item.toString(16).toUpperCase(); + + // noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS + if (str.length === 1) result += "0"; + + result += str; + + // noinspection NonBlockStatementBodyJS + if (insertSpace) result += " "; + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return result.trim(); +} +//************************************************************************************** +// noinspection JSValidateJSDoc, FunctionWithMultipleReturnPointsJS +/** + * Check input "ArrayBuffer" for common functions + * @param {LocalBaseBlock} baseBlock + * @param {ArrayBuffer} inputBuffer + * @param {number} inputOffset + * @param {number} inputLength + * @returns {boolean} + */ +function checkBufferParams(baseBlock, inputBuffer, inputOffset, inputLength) { + // noinspection ConstantOnRightSideOfComparisonJS + if (inputBuffer instanceof ArrayBuffer === false) { + // noinspection JSUndefinedPropertyAssignment + baseBlock.error = "Wrong parameter: inputBuffer must be \"ArrayBuffer\""; + return false; + } + + // noinspection ConstantOnRightSideOfComparisonJS + if (inputBuffer.byteLength === 0) { + // noinspection JSUndefinedPropertyAssignment + baseBlock.error = "Wrong parameter: inputBuffer has zero length"; + return false; + } + + // noinspection ConstantOnRightSideOfComparisonJS + if (inputOffset < 0) { + // noinspection JSUndefinedPropertyAssignment + baseBlock.error = "Wrong parameter: inputOffset less than zero"; + return false; + } + + // noinspection ConstantOnRightSideOfComparisonJS + if (inputLength < 0) { + // noinspection JSUndefinedPropertyAssignment + baseBlock.error = "Wrong parameter: inputLength less than zero"; + return false; + } + + // noinspection ConstantOnRightSideOfComparisonJS + if (inputBuffer.byteLength - inputOffset - inputLength < 0) { + // noinspection JSUndefinedPropertyAssignment + baseBlock.error = "End of input reached before message was fully decoded (inconsistent offset and length values)"; + return false; + } + + return true; +} +//************************************************************************************** +// noinspection FunctionWithMultipleReturnPointsJS +/** + * Convert number from 2^base to 2^10 + * @param {Uint8Array} inputBuffer + * @param {number} inputBase + * @returns {number} + */ +function utilFromBase(inputBuffer, inputBase) { + let result = 0; + + // noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS + if (inputBuffer.length === 1) return inputBuffer[0]; + + // noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS + for (let i = inputBuffer.length - 1; i >= 0; i--) result += inputBuffer[inputBuffer.length - 1 - i] * Math.pow(2, inputBase * i); + + return result; +} +//************************************************************************************** +// noinspection FunctionWithMultipleLoopsJS, FunctionWithMultipleReturnPointsJS +/** + * Convert number from 2^10 to 2^base + * @param {!number} value The number to convert + * @param {!number} base The base for 2^base + * @param {number} [reserved=0] Pre-defined number of bytes in output array (-1 = limited by function itself) + * @returns {ArrayBuffer} + */ +function utilToBase(value, base, reserved = -1) { + const internalReserved = reserved; + let internalValue = value; + + let result = 0; + let biggest = Math.pow(2, base); + + // noinspection ConstantOnRightSideOfComparisonJS + for (let i = 1; i < 8; i++) { + if (value < biggest) { + let retBuf; + + // noinspection ConstantOnRightSideOfComparisonJS + if (internalReserved < 0) { + retBuf = new ArrayBuffer(i); + result = i; + } else { + // noinspection NonBlockStatementBodyJS + if (internalReserved < i) return new ArrayBuffer(0); + + retBuf = new ArrayBuffer(internalReserved); + + result = internalReserved; + } + + const retView = new Uint8Array(retBuf); + + // noinspection ConstantOnRightSideOfComparisonJS + for (let j = i - 1; j >= 0; j--) { + const basis = Math.pow(2, j * base); + + retView[result - j - 1] = Math.floor(internalValue / basis); + internalValue -= retView[result - j - 1] * basis; + } + + return retBuf; + } + + biggest *= Math.pow(2, base); + } + + return new ArrayBuffer(0); +} +//************************************************************************************** +// noinspection FunctionWithMultipleLoopsJS +/** + * Concatenate two ArrayBuffers + * @param {...ArrayBuffer} buffers Set of ArrayBuffer + */ +function utilConcatBuf(...buffers) { + //region Initial variables + let outputLength = 0; + let prevLength = 0; + //endregion + + //region Calculate output length + + // noinspection NonBlockStatementBodyJS + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = buffers[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + const buffer = _step2.value; + + outputLength += buffer.byteLength; + } //endregion + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + const retBuf = new ArrayBuffer(outputLength); + const retView = new Uint8Array(retBuf); + + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = buffers[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + const buffer = _step3.value; + + // noinspection NestedFunctionCallJS + retView.set(new Uint8Array(buffer), prevLength); + prevLength += buffer.byteLength; + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3.return) { + _iterator3.return(); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + return retBuf; +} +//************************************************************************************** +// noinspection FunctionWithMultipleLoopsJS +/** + * Concatenate two Uint8Array + * @param {...Uint8Array} views Set of Uint8Array + */ +function utilConcatView(...views) { + //region Initial variables + let outputLength = 0; + let prevLength = 0; + //endregion + + //region Calculate output length + // noinspection NonBlockStatementBodyJS + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = views[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + const view = _step4.value; + + outputLength += view.length; + } //endregion + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4.return) { + _iterator4.return(); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + + const retBuf = new ArrayBuffer(outputLength); + const retView = new Uint8Array(retBuf); + + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = views[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + const view = _step5.value; + + retView.set(view, prevLength); + prevLength += view.length; + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5.return) { + _iterator5.return(); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + + return retView; +} +//************************************************************************************** +// noinspection FunctionWithMultipleLoopsJS +/** + * Decoding of "two complement" values + * The function must be called in scope of instance of "hexBlock" class ("valueHex" and "warnings" properties must be present) + * @returns {number} + */ +function utilDecodeTC() { + const buf = new Uint8Array(this.valueHex); + + // noinspection ConstantOnRightSideOfComparisonJS + if (this.valueHex.byteLength >= 2) { + //noinspection JSBitwiseOperatorUsage, ConstantOnRightSideOfComparisonJS, LocalVariableNamingConventionJS, MagicNumberJS, NonShortCircuitBooleanExpressionJS + const condition1 = buf[0] === 0xFF && buf[1] & 0x80; + // noinspection ConstantOnRightSideOfComparisonJS, LocalVariableNamingConventionJS, MagicNumberJS, NonShortCircuitBooleanExpressionJS + const condition2 = buf[0] === 0x00 && (buf[1] & 0x80) === 0x00; + + // noinspection NonBlockStatementBodyJS + if (condition1 || condition2) this.warnings.push("Needlessly long format"); + } + + //region Create big part of the integer + const bigIntBuffer = new ArrayBuffer(this.valueHex.byteLength); + const bigIntView = new Uint8Array(bigIntBuffer); + // noinspection NonBlockStatementBodyJS + for (let i = 0; i < this.valueHex.byteLength; i++) bigIntView[i] = 0; + + // noinspection MagicNumberJS, NonShortCircuitBooleanExpressionJS + bigIntView[0] = buf[0] & 0x80; // mask only the biggest bit + + const bigInt = utilFromBase(bigIntView, 8); + //endregion + + //region Create small part of the integer + const smallIntBuffer = new ArrayBuffer(this.valueHex.byteLength); + const smallIntView = new Uint8Array(smallIntBuffer); + // noinspection NonBlockStatementBodyJS + for (let j = 0; j < this.valueHex.byteLength; j++) smallIntView[j] = buf[j]; + + // noinspection MagicNumberJS + smallIntView[0] &= 0x7F; // mask biggest bit + + const smallInt = utilFromBase(smallIntView, 8); + //endregion + + return smallInt - bigInt; +} +//************************************************************************************** +// noinspection FunctionWithMultipleLoopsJS, FunctionWithMultipleReturnPointsJS +/** + * Encode integer value to "two complement" format + * @param {number} value Value to encode + * @returns {ArrayBuffer} + */ +function utilEncodeTC(value) { + // noinspection ConstantOnRightSideOfComparisonJS, ConditionalExpressionJS + const modValue = value < 0 ? value * -1 : value; + let bigInt = 128; + + // noinspection ConstantOnRightSideOfComparisonJS + for (let i = 1; i < 8; i++) { + if (modValue <= bigInt) { + // noinspection ConstantOnRightSideOfComparisonJS + if (value < 0) { + const smallInt = bigInt - modValue; + + const retBuf = utilToBase(smallInt, 8, i); + const retView = new Uint8Array(retBuf); + + // noinspection MagicNumberJS + retView[0] |= 0x80; + + return retBuf; + } + + let retBuf = utilToBase(modValue, 8, i); + let retView = new Uint8Array(retBuf); + + //noinspection JSBitwiseOperatorUsage, MagicNumberJS, NonShortCircuitBooleanExpressionJS + if (retView[0] & 0x80) { + //noinspection JSCheckFunctionSignatures + const tempBuf = retBuf.slice(0); + const tempView = new Uint8Array(tempBuf); + + retBuf = new ArrayBuffer(retBuf.byteLength + 1); + // noinspection ReuseOfLocalVariableJS + retView = new Uint8Array(retBuf); + + // noinspection NonBlockStatementBodyJS + for (let k = 0; k < tempBuf.byteLength; k++) retView[k + 1] = tempView[k]; + + // noinspection MagicNumberJS + retView[0] = 0x00; + } + + return retBuf; + } + + bigInt *= Math.pow(2, 8); + } + + return new ArrayBuffer(0); +} +//************************************************************************************** +// noinspection FunctionWithMultipleReturnPointsJS, ParameterNamingConventionJS +/** + * Compare two array buffers + * @param {!ArrayBuffer} inputBuffer1 + * @param {!ArrayBuffer} inputBuffer2 + * @returns {boolean} + */ +function isEqualBuffer(inputBuffer1, inputBuffer2) { + // noinspection NonBlockStatementBodyJS + if (inputBuffer1.byteLength !== inputBuffer2.byteLength) return false; + + // noinspection LocalVariableNamingConventionJS + const view1 = new Uint8Array(inputBuffer1); + // noinspection LocalVariableNamingConventionJS + const view2 = new Uint8Array(inputBuffer2); + + for (let i = 0; i < view1.length; i++) { + // noinspection NonBlockStatementBodyJS + if (view1[i] !== view2[i]) return false; + } + + return true; +} +//************************************************************************************** +// noinspection FunctionWithMultipleReturnPointsJS +/** + * Pad input number with leade "0" if needed + * @returns {string} + * @param {number} inputNumber + * @param {number} fullLength + */ +function padNumber(inputNumber, fullLength) { + const str = inputNumber.toString(10); + + // noinspection NonBlockStatementBodyJS + if (fullLength < str.length) return ""; + + const dif = fullLength - str.length; + + const padding = new Array(dif); + // noinspection NonBlockStatementBodyJS + for (let i = 0; i < dif; i++) padding[i] = "0"; + + const paddingString = padding.join(""); + + return paddingString.concat(str); +} +//************************************************************************************** +const base64Template = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; +const base64UrlTemplate = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_="; +//************************************************************************************** +// noinspection FunctionWithMultipleLoopsJS, OverlyComplexFunctionJS, FunctionTooLongJS, FunctionNamingConventionJS +/** + * Encode string into BASE64 (or "base64url") + * @param {string} input + * @param {boolean} useUrlTemplate If "true" then output would be encoded using "base64url" + * @param {boolean} skipPadding Skip BASE-64 padding or not + * @param {boolean} skipLeadingZeros Skip leading zeros in input data or not + * @returns {string} + */ +function toBase64(input, useUrlTemplate = false, skipPadding = false, skipLeadingZeros = false) { + let i = 0; + + // noinspection LocalVariableNamingConventionJS + let flag1 = 0; + // noinspection LocalVariableNamingConventionJS + let flag2 = 0; + + let output = ""; + + // noinspection ConditionalExpressionJS + const template = useUrlTemplate ? base64UrlTemplate : base64Template; + + if (skipLeadingZeros) { + let nonZeroPosition = 0; + + for (let i = 0; i < input.length; i++) { + // noinspection ConstantOnRightSideOfComparisonJS + if (input.charCodeAt(i) !== 0) { + nonZeroPosition = i; + // noinspection BreakStatementJS + break; + } + } + + // noinspection AssignmentToFunctionParameterJS + input = input.slice(nonZeroPosition); + } + + while (i < input.length) { + // noinspection LocalVariableNamingConventionJS, IncrementDecrementResultUsedJS + const chr1 = input.charCodeAt(i++); + // noinspection NonBlockStatementBodyJS + if (i >= input.length) flag1 = 1; + // noinspection LocalVariableNamingConventionJS, IncrementDecrementResultUsedJS + const chr2 = input.charCodeAt(i++); + // noinspection NonBlockStatementBodyJS + if (i >= input.length) flag2 = 1; + // noinspection LocalVariableNamingConventionJS, IncrementDecrementResultUsedJS + const chr3 = input.charCodeAt(i++); + + // noinspection LocalVariableNamingConventionJS + const enc1 = chr1 >> 2; + // noinspection LocalVariableNamingConventionJS, MagicNumberJS, NonShortCircuitBooleanExpressionJS + const enc2 = (chr1 & 0x03) << 4 | chr2 >> 4; + // noinspection LocalVariableNamingConventionJS, MagicNumberJS, NonShortCircuitBooleanExpressionJS + let enc3 = (chr2 & 0x0F) << 2 | chr3 >> 6; + // noinspection LocalVariableNamingConventionJS, MagicNumberJS, NonShortCircuitBooleanExpressionJS + let enc4 = chr3 & 0x3F; + + // noinspection ConstantOnRightSideOfComparisonJS + if (flag1 === 1) { + // noinspection NestedAssignmentJS, AssignmentResultUsedJS, MagicNumberJS + enc3 = enc4 = 64; + } else { + // noinspection ConstantOnRightSideOfComparisonJS + if (flag2 === 1) { + // noinspection MagicNumberJS + enc4 = 64; + } + } + + // noinspection NonBlockStatementBodyJS + if (skipPadding) { + // noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS, MagicNumberJS + if (enc3 === 64) output += `${template.charAt(enc1)}${template.charAt(enc2)}`;else { + // noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS, MagicNumberJS + if (enc4 === 64) output += `${template.charAt(enc1)}${template.charAt(enc2)}${template.charAt(enc3)}`;else output += `${template.charAt(enc1)}${template.charAt(enc2)}${template.charAt(enc3)}${template.charAt(enc4)}`; + } + } else output += `${template.charAt(enc1)}${template.charAt(enc2)}${template.charAt(enc3)}${template.charAt(enc4)}`; + } + + return output; +} +//************************************************************************************** +// noinspection FunctionWithMoreThanThreeNegationsJS, FunctionWithMultipleLoopsJS, OverlyComplexFunctionJS, FunctionNamingConventionJS +/** + * Decode string from BASE64 (or "base64url") + * @param {string} input + * @param {boolean} [useUrlTemplate=false] If "true" then output would be encoded using "base64url" + * @param {boolean} [cutTailZeros=false] If "true" then cut tailing zeroz from function result + * @returns {string} + */ +function fromBase64(input, useUrlTemplate = false, cutTailZeros = false) { + // noinspection ConditionalExpressionJS + const template = useUrlTemplate ? base64UrlTemplate : base64Template; + + //region Aux functions + // noinspection FunctionWithMultipleReturnPointsJS, NestedFunctionJS + function indexof(toSearch) { + // noinspection ConstantOnRightSideOfComparisonJS, MagicNumberJS + for (let i = 0; i < 64; i++) { + // noinspection NonBlockStatementBodyJS + if (template.charAt(i) === toSearch) return i; + } + + // noinspection MagicNumberJS + return 64; + } + + // noinspection NestedFunctionJS + function test(incoming) { + // noinspection ConstantOnRightSideOfComparisonJS, ConditionalExpressionJS, MagicNumberJS + return incoming === 64 ? 0x00 : incoming; + } + //endregion + + let i = 0; + + let output = ""; + + while (i < input.length) { + // noinspection NestedFunctionCallJS, LocalVariableNamingConventionJS, IncrementDecrementResultUsedJS + const enc1 = indexof(input.charAt(i++)); + // noinspection NestedFunctionCallJS, LocalVariableNamingConventionJS, ConditionalExpressionJS, MagicNumberJS, IncrementDecrementResultUsedJS + const enc2 = i >= input.length ? 0x00 : indexof(input.charAt(i++)); + // noinspection NestedFunctionCallJS, LocalVariableNamingConventionJS, ConditionalExpressionJS, MagicNumberJS, IncrementDecrementResultUsedJS + const enc3 = i >= input.length ? 0x00 : indexof(input.charAt(i++)); + // noinspection NestedFunctionCallJS, LocalVariableNamingConventionJS, ConditionalExpressionJS, MagicNumberJS, IncrementDecrementResultUsedJS + const enc4 = i >= input.length ? 0x00 : indexof(input.charAt(i++)); + + // noinspection LocalVariableNamingConventionJS, NonShortCircuitBooleanExpressionJS + const chr1 = test(enc1) << 2 | test(enc2) >> 4; + // noinspection LocalVariableNamingConventionJS, MagicNumberJS, NonShortCircuitBooleanExpressionJS + const chr2 = (test(enc2) & 0x0F) << 4 | test(enc3) >> 2; + // noinspection LocalVariableNamingConventionJS, MagicNumberJS, NonShortCircuitBooleanExpressionJS + const chr3 = (test(enc3) & 0x03) << 6 | test(enc4); + + output += String.fromCharCode(chr1); + + // noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS, MagicNumberJS + if (enc3 !== 64) output += String.fromCharCode(chr2); + + // noinspection ConstantOnRightSideOfComparisonJS, NonBlockStatementBodyJS, MagicNumberJS + if (enc4 !== 64) output += String.fromCharCode(chr3); + } + + if (cutTailZeros) { + const outputLength = output.length; + let nonZeroStart = -1; + + // noinspection ConstantOnRightSideOfComparisonJS + for (let i = outputLength - 1; i >= 0; i--) { + // noinspection ConstantOnRightSideOfComparisonJS + if (output.charCodeAt(i) !== 0) { + nonZeroStart = i; + // noinspection BreakStatementJS + break; + } + } + + // noinspection NonBlockStatementBodyJS, NegatedIfStatementJS + if (nonZeroStart !== -1) output = output.slice(0, nonZeroStart + 1);else output = ""; + } + + return output; +} +//************************************************************************************** +function arrayBufferToString(buffer) { + let resultString = ""; + const view = new Uint8Array(buffer); + + // noinspection NonBlockStatementBodyJS + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; + + try { + for (var _iterator6 = view[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + const element = _step6.value; + + resultString += String.fromCharCode(element); + } + } catch (err) { + _didIteratorError6 = true; + _iteratorError6 = err; + } finally { + try { + if (!_iteratorNormalCompletion6 && _iterator6.return) { + _iterator6.return(); + } + } finally { + if (_didIteratorError6) { + throw _iteratorError6; + } + } + } + + return resultString; +} +//************************************************************************************** +function stringToArrayBuffer(str) { + const stringLength = str.length; + + const resultBuffer = new ArrayBuffer(stringLength); + const resultView = new Uint8Array(resultBuffer); + + // noinspection NonBlockStatementBodyJS + for (let i = 0; i < stringLength; i++) resultView[i] = str.charCodeAt(i); + + return resultBuffer; +} +//************************************************************************************** +const log2 = Math.log(2); +//************************************************************************************** +// noinspection FunctionNamingConventionJS +/** + * Get nearest to input length power of 2 + * @param {number} length Current length of existing array + * @returns {number} + */ +function nearestPowerOf2(length) { + const base = Math.log(length) / log2; + + const floor = Math.floor(base); + const round = Math.round(base); + + // noinspection ConditionalExpressionJS + return floor === round ? floor : round; +} +//************************************************************************************** +/** + * Delete properties by name from specified object + * @param {Object} object Object to delete properties from + * @param {Array.} propsArray Array of properties names + */ +function clearProps(object, propsArray) { + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; + + try { + for (var _iterator7 = propsArray[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + const prop = _step7.value; + + delete object[prop]; + } + } catch (err) { + _didIteratorError7 = true; + _iteratorError7 = err; + } finally { + try { + if (!_iteratorNormalCompletion7 && _iterator7.return) { + _iterator7.return(); + } + } finally { + if (_didIteratorError7) { + throw _iteratorError7; + } + } + } +} +//************************************************************************************** + +},{}],114:[function(require,module,exports){ +// shim for using process in browser +var process = module.exports = {}; + +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. + +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; +process.prependListener = noop; +process.prependOnceListener = noop; + +process.listeners = function (name) { return [] } + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],115:[function(require,module,exports){ +/* 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/. */ + +const pkijs = require("pkijs"); // version 2.1.78 + +module.exports = { + pkijs, +}; + +},{"pkijs":111}]},{},[115])(115) +}); -- cgit v1.2.3