UNPKG

node-opcua-crypto

Version:

Crypto tools for Node-OPCUA

1,518 lines (1,491 loc) 133 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // source_nodejs/index.ts var source_nodejs_exports = {}; __export(source_nodejs_exports, { generatePrivateKeyFile: () => generatePrivateKeyFile, generatePrivateKeyFileAlternate: () => generatePrivateKeyFileAlternate, getCertificateStore: () => getCertificateStore, readCertificate: () => readCertificate, readCertificatePEM: () => readCertificatePEM, readCertificateRevocationList: () => readCertificateRevocationList, readCertificateSigningRequest: () => readCertificateSigningRequest, readPrivateKey: () => readPrivateKey, readPrivateKeyPEM: () => readPrivateKeyPEM, readPrivateRsaKey: () => readPrivateRsaKey, readPublicKey: () => readPublicKey, readPublicKeyPEM: () => readPublicKeyPEM, readPublicRsaKey: () => readPublicRsaKey, setCertificateStore: () => setCertificateStore }); module.exports = __toCommonJS(source_nodejs_exports); // source_nodejs/read.ts var import_assert5 = __toESM(require("assert")); var import_node_fs = __toESM(require("fs")); var import_node_path = __toESM(require("path")); var import_crypto = require("crypto"); // source/crypto_utils.ts var import_constants = __toESM(require("constants")); var import_assert4 = __toESM(require("assert")); var import_hexy = __toESM(require("hexy")); // source/buffer_utils.ts var createFastUninitializedBuffer = Buffer.allocUnsafe ? Buffer.allocUnsafe : (size) => { return new Buffer(size); }; // source/crypto_explore_certificate.ts var import_assert3 = __toESM(require("assert")); // source/asn1.ts var import_assert = __toESM(require("assert")); function readTag(buf, pos) { const start = pos; if (buf.length <= pos) { throw new Error("Invalid position : buf.length=" + buf.length + " pos =" + pos); } const tag = buf.readUInt8(pos); pos += 1; let length = buf.readUInt8(pos); pos += 1; if (length > 127) { const nbBytes = length & 127; length = 0; for (let i = 0; i < nbBytes; i++) { length = length * 256 + buf.readUInt8(pos); pos += 1; } } return { start, tag, position: pos, length }; } // source/directory_name.ts var import_assert2 = __toESM(require("assert")); // source/crypto_explore_certificate.ts function split_der(certificateChain) { const certificate_chain = []; do { const block_info = readTag(certificateChain, 0); const length = block_info.position + block_info.length; const der_certificate = certificateChain.subarray(0, length); certificate_chain.push(der_certificate); certificateChain = certificateChain.subarray(length); } while (certificateChain.length > 0); return certificate_chain; } function combine_der(certificates) { for (const cert of certificates) { const b = split_der(cert); let sum = 0; b.forEach((block) => { const block_info = readTag(block, 0); (0, import_assert3.default)(block_info.position + block_info.length === block.length); sum += block.length; }); (0, import_assert3.default)(sum === cert.length); } return Buffer.concat(certificates); } // source/crypto_utils.ts var import_jsrsasign = __toESM(require("jsrsasign")); var { hexy } = import_hexy.default; var PEM_REGEX = /^(-----BEGIN (.*)-----\r?\n([/+=a-zA-Z0-9\r\n]*)\r?\n-----END \2-----\r?\n?)/gm; var PEM_TYPE_REGEX = /^(-----BEGIN (.*)-----)/m; function identifyPemType(rawKey) { if (Buffer.isBuffer(rawKey)) { rawKey = rawKey.toString("utf8"); } const match = PEM_TYPE_REGEX.exec(rawKey); return !match ? void 0 : match[2]; } function removeTrailingLF(str) { const tmp = str.replace(/(\r|\n)+$/m, "").replace(/\r\n/gm, "\n"); return tmp; } function toPem(raw_key, pem) { (0, import_assert4.default)(raw_key, "expecting a key"); (0, import_assert4.default)(typeof pem === "string"); let pemType = identifyPemType(raw_key); if (pemType) { return Buffer.isBuffer(raw_key) ? removeTrailingLF(raw_key.toString("utf8")) : removeTrailingLF(raw_key); } else { pemType = pem; (0, import_assert4.default)(["CERTIFICATE REQUEST", "CERTIFICATE", "RSA PRIVATE KEY", "PUBLIC KEY", "X509 CRL"].indexOf(pemType) >= 0); let b = raw_key.toString("base64"); let str = "-----BEGIN " + pemType + "-----\n"; while (b.length) { str += b.substring(0, 64) + "\n"; b = b.substring(64); } str += "-----END " + pemType + "-----"; return str; } } function convertPEMtoDER(raw_key) { let match; let pemType; let base64str; const parts = []; PEM_REGEX.lastIndex = 0; while ((match = PEM_REGEX.exec(raw_key)) !== null) { pemType = match[2]; base64str = match[3]; base64str = base64str.replace(/\r?\n/g, ""); parts.push(Buffer.from(base64str, "base64")); } return combine_der(parts); } var RSA_PKCS1_OAEP_PADDING = import_constants.default.RSA_PKCS1_OAEP_PADDING; var RSA_PKCS1_PADDING = import_constants.default.RSA_PKCS1_PADDING; (0, import_assert4.default)(4 /* RSA_PKCS1_OAEP_PADDING */ === import_constants.default.RSA_PKCS1_OAEP_PADDING); (0, import_assert4.default)(1 /* RSA_PKCS1_PADDING */ === import_constants.default.RSA_PKCS1_PADDING); // source_nodejs/read.ts var import_sshpk = __toESM(require("sshpk")); function _readPemFile(filename) { (0, import_assert5.default)(typeof filename === "string"); return removeTrailingLF(import_node_fs.default.readFileSync(filename, "utf-8")); } function _readPemOrDerFileAsDER(filename) { if (filename.match(/.*\.der/)) { return import_node_fs.default.readFileSync(filename); } const raw_key = _readPemFile(filename); return convertPEMtoDER(raw_key); } function readCertificate(filename) { return _readPemOrDerFileAsDER(filename); } function readPublicKey(filename) { if (filename.match(/.*\.der/)) { const der = import_node_fs.default.readFileSync(filename); return (0, import_crypto.createPublicKey)(der); } else { const raw_key = _readPemFile(filename); return (0, import_crypto.createPublicKey)(raw_key); } } function myCreatePrivateKey(rawKey) { if (!import_crypto.createPrivateKey || process.env.NO_CREATE_PRIVATEKEY) { if (Buffer.isBuffer(rawKey)) { const pemKey = toPem(rawKey, "PRIVATE KEY"); (0, import_assert5.default)(["RSA PRIVATE KEY", "PRIVATE KEY"].indexOf(identifyPemType(pemKey)) >= 0); return { hidden: pemKey }; } return { hidden: ensureTrailingLF(rawKey) }; } const backup = process.env.OPENSSL_CONF; process.env.OPENSSL_CONF = "/dev/null"; const retValue = (0, import_crypto.createPrivateKey)(rawKey); process.env.OPENSSL_CONF = backup; return { hidden: retValue }; } function ensureTrailingLF(str) { return str.match(/\n$/) ? str : str + "\n"; } function readPrivateKey(filename) { if (filename.match(/.*\.der/)) { const der = import_node_fs.default.readFileSync(filename); return myCreatePrivateKey(der); } else { const raw_key = _readPemFile(filename); return myCreatePrivateKey(raw_key); } } function readCertificatePEM(filename) { return _readPemFile(filename); } function readPublicKeyPEM(filename) { return _readPemFile(filename); } function readPrivateKeyPEM(filename) { return _readPemFile(filename); } var _g_certificate_store = ""; function setCertificateStore(store) { const old_store = _g_certificate_store; _g_certificate_store = store; return old_store; } function getCertificateStore() { if (!_g_certificate_store) { _g_certificate_store = import_node_path.default.join(__dirname, "../../certificates/"); } return _g_certificate_store; } function readPrivateRsaKey(filename) { if (!import_crypto.createPrivateKey) { throw new Error("createPrivateKey is not supported in this environment"); } if (filename.substring(0, 1) !== "." && !import_node_fs.default.existsSync(filename)) { filename = import_node_path.default.join(getCertificateStore(), filename); } const content = import_node_fs.default.readFileSync(filename, "utf8"); const sshKey = import_sshpk.default.parsePrivateKey(content, "auto"); const key = sshKey.toString("pkcs1"); const hidden = (0, import_crypto.createPrivateKey)({ format: "pem", type: "pkcs1", key }); return { hidden }; } function readPublicRsaKey(filename) { if (filename.substring(0, 1) !== "." && !import_node_fs.default.existsSync(filename)) { filename = import_node_path.default.join(getCertificateStore(), filename); } const content = import_node_fs.default.readFileSync(filename, "utf-8"); const sshKey = import_sshpk.default.parseKey(content, "ssh"); const key = sshKey.toString("pkcs1"); return (0, import_crypto.createPublicKey)({ format: "pem", type: "pkcs1", key }); } // source_nodejs/read_certificate_revocation_list.ts var import_node_fs2 = __toESM(require("fs")); async function readCertificateRevocationList(filename) { const crl = await import_node_fs2.default.promises.readFile(filename); if (crl[0] === 48 && crl[1] === 130) { return crl; } const raw_crl = crl.toString(); return convertPEMtoDER(raw_crl); } // source_nodejs/read_certificate_signing_request.ts var import_node_fs3 = __toESM(require("fs")); async function readCertificateSigningRequest(filename) { const csr = await import_node_fs3.default.promises.readFile(filename); if (csr[0] === 48 && csr[1] === 130) { return csr; } const raw_crl = csr.toString(); return convertPEMtoDER(raw_crl); } // source_nodejs/generate_private_key_filename.ts var import_node_fs4 = __toESM(require("fs")); // source/explore_private_key.ts var doDebug = !!process.env.DEBUG; // source/common.ts var import_crypto2 = __toESM(require("crypto")); var KeyObjectOrig = import_crypto2.default.KeyObject; var { createPrivateKey: createPrivateKeyFromNodeJSCrypto } = import_crypto2.default; // source/crypto_utils2.ts var import_assert6 = __toESM(require("assert")); var import_jsrsasign2 = __toESM(require("jsrsasign")); // source/derived_keys.ts var import_assert8 = __toESM(require("assert")); // source/explore_certificate.ts var import_assert7 = __toESM(require("assert")); // source/x509/_crypto.ts var x509 = __toESM(require("@peculiar/x509")); var import_webcrypto = require("@peculiar/webcrypto"); var import_crypto3 = __toESM(require("crypto")); var x5092 = __toESM(require("@peculiar/x509")); var doDebug2 = false; var _crypto; var ignoreCrypto = process.env.IGNORE_SUBTLE_FROM_CRYPTO; if (typeof window === "undefined") { _crypto = import_crypto3.default; if (!_crypto?.subtle || ignoreCrypto) { _crypto = new import_webcrypto.Crypto(); doDebug2 && console.warn("using @peculiar/webcrypto"); } else { doDebug2 && console.warn("using nodejs crypto (native)"); } x509.cryptoProvider.set(_crypto); } else { doDebug2 && console.warn("using browser crypto (native)"); _crypto = crypto; x509.cryptoProvider.set(crypto); } function getCrypto() { return _crypto || crypto || require("crypto"); } // source/x509/create_key_pair.ts async function generateKeyPair(modulusLength = 2048) { const crypto3 = getCrypto(); const alg = { name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-256" }, publicExponent: new Uint8Array([1, 0, 1]), modulusLength }; const keys = await crypto3.subtle.generateKey(alg, true, ["sign", "verify"]); return keys; } async function privateKeyToPEM(privateKey) { const crypto3 = getCrypto(); const privDer = await crypto3.subtle.exportKey("pkcs8", privateKey); const privPem = x5092.PemConverter.encode(privDer, "PRIVATE KEY"); return { privPem, privDer }; } // source/x509/coerce_private_key.ts var crypto2 = getCrypto(); // source/x509/_get_attributes.ts var keyUsageApplication = x5092.KeyUsageFlags.keyEncipherment | x5092.KeyUsageFlags.nonRepudiation | x5092.KeyUsageFlags.dataEncipherment | x5092.KeyUsageFlags.keyCertSign | x5092.KeyUsageFlags.digitalSignature; var keyUsageCA = x5092.KeyUsageFlags.keyCertSign | x5092.KeyUsageFlags.cRLSign; // ../../node_modules/asn1js/build/index.es.js var index_es_exports = {}; __export(index_es_exports, { Any: () => Any, BaseBlock: () => BaseBlock, BaseStringBlock: () => BaseStringBlock, BitString: () => BitString, BmpString: () => BmpString, Boolean: () => Boolean, CharacterString: () => CharacterString, Choice: () => Choice, Constructed: () => Constructed, DATE: () => DATE, DateTime: () => DateTime, Duration: () => Duration, EndOfContent: () => EndOfContent, Enumerated: () => Enumerated, GeneralString: () => GeneralString, GeneralizedTime: () => GeneralizedTime, GraphicString: () => GraphicString, HexBlock: () => HexBlock, IA5String: () => IA5String, Integer: () => Integer, Null: () => Null, NumericString: () => NumericString, ObjectIdentifier: () => ObjectIdentifier, OctetString: () => OctetString, Primitive: () => Primitive, PrintableString: () => PrintableString, RawData: () => RawData, RelativeObjectIdentifier: () => RelativeObjectIdentifier, Repeated: () => Repeated, Sequence: () => Sequence, Set: () => Set, TIME: () => TIME, TeletexString: () => TeletexString, TimeOfDay: () => TimeOfDay, UTCTime: () => UTCTime, UniversalString: () => UniversalString, Utf8String: () => Utf8String, ValueBlock: () => ValueBlock, VideotexString: () => VideotexString, ViewWriter: () => ViewWriter, VisibleString: () => VisibleString, compareSchema: () => compareSchema, fromBER: () => fromBER, verifySchema: () => verifySchema }); // ../../node_modules/pvtsutils/build/index.es.js var ARRAY_BUFFER_NAME = "[object ArrayBuffer]"; var BufferSourceConverter = class _BufferSourceConverter { static isArrayBuffer(data) { return Object.prototype.toString.call(data) === ARRAY_BUFFER_NAME; } static toArrayBuffer(data) { if (this.isArrayBuffer(data)) { return data; } if (data.byteLength === data.buffer.byteLength) { return data.buffer; } if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) { return data.buffer; } return this.toUint8Array(data.buffer).slice(data.byteOffset, data.byteOffset + data.byteLength).buffer; } static toUint8Array(data) { return this.toView(data, Uint8Array); } static toView(data, type) { if (data.constructor === type) { return data; } if (this.isArrayBuffer(data)) { return new type(data); } if (this.isArrayBufferView(data)) { return new type(data.buffer, data.byteOffset, data.byteLength); } throw new TypeError("The provided value is not of type '(ArrayBuffer or ArrayBufferView)'"); } static isBufferSource(data) { return this.isArrayBufferView(data) || this.isArrayBuffer(data); } static isArrayBufferView(data) { return ArrayBuffer.isView(data) || data && this.isArrayBuffer(data.buffer); } static isEqual(a, b) { const aView = _BufferSourceConverter.toUint8Array(a); const bView = _BufferSourceConverter.toUint8Array(b); if (aView.length !== bView.byteLength) { return false; } for (let i = 0; i < aView.length; i++) { if (aView[i] !== bView[i]) { return false; } } return true; } static concat(...args) { let buffers; if (Array.isArray(args[0]) && !(args[1] instanceof Function)) { buffers = args[0]; } else if (Array.isArray(args[0]) && args[1] instanceof Function) { buffers = args[0]; } else { if (args[args.length - 1] instanceof Function) { buffers = args.slice(0, args.length - 1); } else { buffers = args; } } let size = 0; for (const buffer of buffers) { size += buffer.byteLength; } const res = new Uint8Array(size); let offset = 0; for (const buffer of buffers) { const view = this.toUint8Array(buffer); res.set(view, offset); offset += view.length; } if (args[args.length - 1] instanceof Function) { return this.toView(res, args[args.length - 1]); } return res.buffer; } }; var STRING_TYPE = "string"; var HEX_REGEX = /^[0-9a-f]+$/i; var BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/; var BASE64URL_REGEX = /^[a-zA-Z0-9-_]+$/; var Utf8Converter = class { static fromString(text) { const s = unescape(encodeURIComponent(text)); const uintArray = new Uint8Array(s.length); for (let i = 0; i < s.length; i++) { uintArray[i] = s.charCodeAt(i); } return uintArray.buffer; } static toString(buffer) { const buf = BufferSourceConverter.toUint8Array(buffer); let encodedString = ""; for (let i = 0; i < buf.length; i++) { encodedString += String.fromCharCode(buf[i]); } const decodedString = decodeURIComponent(escape(encodedString)); return decodedString; } }; var Utf16Converter = class { static toString(buffer, littleEndian = false) { const arrayBuffer = BufferSourceConverter.toArrayBuffer(buffer); const dataView = new DataView(arrayBuffer); let res = ""; for (let i = 0; i < arrayBuffer.byteLength; i += 2) { const code = dataView.getUint16(i, littleEndian); res += String.fromCharCode(code); } return res; } static fromString(text, littleEndian = false) { const res = new ArrayBuffer(text.length * 2); const dataView = new DataView(res); for (let i = 0; i < text.length; i++) { dataView.setUint16(i * 2, text.charCodeAt(i), littleEndian); } return res; } }; var Convert = class _Convert { static isHex(data) { return typeof data === STRING_TYPE && HEX_REGEX.test(data); } static isBase64(data) { return typeof data === STRING_TYPE && BASE64_REGEX.test(data); } static isBase64Url(data) { return typeof data === STRING_TYPE && BASE64URL_REGEX.test(data); } static ToString(buffer, enc = "utf8") { const buf = BufferSourceConverter.toUint8Array(buffer); switch (enc.toLowerCase()) { case "utf8": return this.ToUtf8String(buf); case "binary": return this.ToBinary(buf); case "hex": return this.ToHex(buf); case "base64": return this.ToBase64(buf); case "base64url": return this.ToBase64Url(buf); case "utf16le": return Utf16Converter.toString(buf, true); case "utf16": case "utf16be": return Utf16Converter.toString(buf); default: throw new Error(`Unknown type of encoding '${enc}'`); } } static FromString(str, enc = "utf8") { if (!str) { return new ArrayBuffer(0); } switch (enc.toLowerCase()) { case "utf8": return this.FromUtf8String(str); case "binary": return this.FromBinary(str); case "hex": return this.FromHex(str); case "base64": return this.FromBase64(str); case "base64url": return this.FromBase64Url(str); case "utf16le": return Utf16Converter.fromString(str, true); case "utf16": case "utf16be": return Utf16Converter.fromString(str); default: throw new Error(`Unknown type of encoding '${enc}'`); } } static ToBase64(buffer) { const buf = BufferSourceConverter.toUint8Array(buffer); if (typeof btoa !== "undefined") { const binary = this.ToString(buf, "binary"); return btoa(binary); } else { return Buffer.from(buf).toString("base64"); } } static FromBase64(base64) { const formatted = this.formatString(base64); if (!formatted) { return new ArrayBuffer(0); } if (!_Convert.isBase64(formatted)) { throw new TypeError("Argument 'base64Text' is not Base64 encoded"); } if (typeof atob !== "undefined") { return this.FromBinary(atob(formatted)); } else { return new Uint8Array(Buffer.from(formatted, "base64")).buffer; } } static FromBase64Url(base64url) { const formatted = this.formatString(base64url); if (!formatted) { return new ArrayBuffer(0); } if (!_Convert.isBase64Url(formatted)) { throw new TypeError("Argument 'base64url' is not Base64Url encoded"); } return this.FromBase64(this.Base64Padding(formatted.replace(/\-/g, "+").replace(/\_/g, "/"))); } static ToBase64Url(data) { return this.ToBase64(data).replace(/\+/g, "-").replace(/\//g, "_").replace(/\=/g, ""); } static FromUtf8String(text, encoding = _Convert.DEFAULT_UTF8_ENCODING) { switch (encoding) { case "ascii": return this.FromBinary(text); case "utf8": return Utf8Converter.fromString(text); case "utf16": case "utf16be": return Utf16Converter.fromString(text); case "utf16le": case "usc2": return Utf16Converter.fromString(text, true); default: throw new Error(`Unknown type of encoding '${encoding}'`); } } static ToUtf8String(buffer, encoding = _Convert.DEFAULT_UTF8_ENCODING) { switch (encoding) { case "ascii": return this.ToBinary(buffer); case "utf8": return Utf8Converter.toString(buffer); case "utf16": case "utf16be": return Utf16Converter.toString(buffer); case "utf16le": case "usc2": return Utf16Converter.toString(buffer, true); default: throw new Error(`Unknown type of encoding '${encoding}'`); } } static FromBinary(text) { const stringLength = text.length; const resultView = new Uint8Array(stringLength); for (let i = 0; i < stringLength; i++) { resultView[i] = text.charCodeAt(i); } return resultView.buffer; } static ToBinary(buffer) { const buf = BufferSourceConverter.toUint8Array(buffer); let res = ""; for (let i = 0; i < buf.length; i++) { res += String.fromCharCode(buf[i]); } return res; } static ToHex(buffer) { const buf = BufferSourceConverter.toUint8Array(buffer); let result = ""; const len = buf.length; for (let i = 0; i < len; i++) { const byte = buf[i]; if (byte < 16) { result += "0"; } result += byte.toString(16); } return result; } static FromHex(hexString) { let formatted = this.formatString(hexString); if (!formatted) { return new ArrayBuffer(0); } if (!_Convert.isHex(formatted)) { throw new TypeError("Argument 'hexString' is not HEX encoded"); } if (formatted.length % 2) { formatted = `0${formatted}`; } const res = new Uint8Array(formatted.length / 2); for (let i = 0; i < formatted.length; i = i + 2) { const c = formatted.slice(i, i + 2); res[i / 2] = parseInt(c, 16); } return res.buffer; } static ToUtf16String(buffer, littleEndian = false) { return Utf16Converter.toString(buffer, littleEndian); } static FromUtf16String(text, littleEndian = false) { return Utf16Converter.fromString(text, littleEndian); } static Base64Padding(base64) { const padCount = 4 - base64.length % 4; if (padCount < 4) { for (let i = 0; i < padCount; i++) { base64 += "="; } } return base64; } static formatString(data) { return (data === null || data === void 0 ? void 0 : data.replace(/[\n\r\t ]/g, "")) || ""; } }; Convert.DEFAULT_UTF8_ENCODING = "utf8"; // ../../node_modules/pvutils/build/utils.es.js function utilFromBase(inputBuffer, inputBase) { let result = 0; if (inputBuffer.length === 1) { return inputBuffer[0]; } for (let i = inputBuffer.length - 1; i >= 0; i--) { result += inputBuffer[inputBuffer.length - 1 - i] * Math.pow(2, inputBase * i); } return result; } function utilToBase(value, base, reserved = -1) { const internalReserved = reserved; let internalValue = value; let result = 0; let biggest = Math.pow(2, base); for (let i = 1; i < 8; i++) { if (value < biggest) { let retBuf; if (internalReserved < 0) { retBuf = new ArrayBuffer(i); result = i; } else { if (internalReserved < i) { return new ArrayBuffer(0); } retBuf = new ArrayBuffer(internalReserved); result = internalReserved; } const retView = new Uint8Array(retBuf); 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); } function utilConcatView(...views) { let outputLength = 0; let prevLength = 0; for (const view of views) { outputLength += view.length; } const retBuf = new ArrayBuffer(outputLength); const retView = new Uint8Array(retBuf); for (const view of views) { retView.set(view, prevLength); prevLength += view.length; } return retView; } function utilDecodeTC() { const buf = new Uint8Array(this.valueHex); if (this.valueHex.byteLength >= 2) { const condition1 = buf[0] === 255 && buf[1] & 128; const condition2 = buf[0] === 0 && (buf[1] & 128) === 0; if (condition1 || condition2) { this.warnings.push("Needlessly long format"); } } const bigIntBuffer = new ArrayBuffer(this.valueHex.byteLength); const bigIntView = new Uint8Array(bigIntBuffer); for (let i = 0; i < this.valueHex.byteLength; i++) { bigIntView[i] = 0; } bigIntView[0] = buf[0] & 128; const bigInt = utilFromBase(bigIntView, 8); const smallIntBuffer = new ArrayBuffer(this.valueHex.byteLength); const smallIntView = new Uint8Array(smallIntBuffer); for (let j = 0; j < this.valueHex.byteLength; j++) { smallIntView[j] = buf[j]; } smallIntView[0] &= 127; const smallInt = utilFromBase(smallIntView, 8); return smallInt - bigInt; } function utilEncodeTC(value) { const modValue = value < 0 ? value * -1 : value; let bigInt = 128; for (let i = 1; i < 8; i++) { if (modValue <= bigInt) { if (value < 0) { const smallInt = bigInt - modValue; const retBuf2 = utilToBase(smallInt, 8, i); const retView2 = new Uint8Array(retBuf2); retView2[0] |= 128; return retBuf2; } let retBuf = utilToBase(modValue, 8, i); let retView = new Uint8Array(retBuf); if (retView[0] & 128) { const tempBuf = retBuf.slice(0); const tempView = new Uint8Array(tempBuf); retBuf = new ArrayBuffer(retBuf.byteLength + 1); retView = new Uint8Array(retBuf); for (let k = 0; k < tempBuf.byteLength; k++) { retView[k + 1] = tempView[k]; } retView[0] = 0; } return retBuf; } bigInt *= Math.pow(2, 8); } return new ArrayBuffer(0); } function isEqualBuffer(inputBuffer1, inputBuffer2) { if (inputBuffer1.byteLength !== inputBuffer2.byteLength) { return false; } const view1 = new Uint8Array(inputBuffer1); const view2 = new Uint8Array(inputBuffer2); for (let i = 0; i < view1.length; i++) { if (view1[i] !== view2[i]) { return false; } } return true; } function padNumber(inputNumber, fullLength) { const str = inputNumber.toString(10); if (fullLength < str.length) { return ""; } const dif = fullLength - str.length; const padding = new Array(dif); for (let i = 0; i < dif; i++) { padding[i] = "0"; } const paddingString = padding.join(""); return paddingString.concat(str); } var log2 = Math.log(2); // ../../node_modules/asn1js/build/index.es.js function assertBigInt() { if (typeof BigInt === "undefined") { throw new Error("BigInt is not defined. Your environment doesn't implement BigInt."); } } function concat(buffers) { let outputLength = 0; let prevLength = 0; for (let i = 0; i < buffers.length; i++) { const buffer = buffers[i]; outputLength += buffer.byteLength; } const retView = new Uint8Array(outputLength); for (let i = 0; i < buffers.length; i++) { const buffer = buffers[i]; retView.set(new Uint8Array(buffer), prevLength); prevLength += buffer.byteLength; } return retView.buffer; } function checkBufferParams(baseBlock, inputBuffer, inputOffset, inputLength) { if (!(inputBuffer instanceof Uint8Array)) { baseBlock.error = "Wrong parameter: inputBuffer must be 'Uint8Array'"; return false; } if (!inputBuffer.byteLength) { baseBlock.error = "Wrong parameter: inputBuffer has zero length"; return false; } if (inputOffset < 0) { baseBlock.error = "Wrong parameter: inputOffset less than zero"; return false; } if (inputLength < 0) { baseBlock.error = "Wrong parameter: inputLength less than zero"; return false; } if (inputBuffer.byteLength - inputOffset - inputLength < 0) { baseBlock.error = "End of input reached before message was fully decoded (inconsistent offset and length values)"; return false; } return true; } var ViewWriter = class { constructor() { this.items = []; } write(buf) { this.items.push(buf); } final() { return concat(this.items); } }; var powers2 = [new Uint8Array([1])]; var digitsString = "0123456789"; var NAME = "name"; var VALUE_HEX_VIEW = "valueHexView"; var IS_HEX_ONLY = "isHexOnly"; var ID_BLOCK = "idBlock"; var TAG_CLASS = "tagClass"; var TAG_NUMBER = "tagNumber"; var IS_CONSTRUCTED = "isConstructed"; var FROM_BER = "fromBER"; var TO_BER = "toBER"; var LOCAL = "local"; var EMPTY_STRING = ""; var EMPTY_BUFFER = new ArrayBuffer(0); var EMPTY_VIEW = new Uint8Array(0); var END_OF_CONTENT_NAME = "EndOfContent"; var OCTET_STRING_NAME = "OCTET STRING"; var BIT_STRING_NAME = "BIT STRING"; function HexBlock(BaseClass) { var _a2; return _a2 = class Some extends BaseClass { constructor(...args) { var _a3; super(...args); const params = args[0] || {}; this.isHexOnly = (_a3 = params.isHexOnly) !== null && _a3 !== void 0 ? _a3 : false; this.valueHexView = params.valueHex ? BufferSourceConverter.toUint8Array(params.valueHex) : EMPTY_VIEW; } get valueHex() { return this.valueHexView.slice().buffer; } set valueHex(value) { this.valueHexView = new Uint8Array(value); } fromBER(inputBuffer, inputOffset, inputLength) { const view = inputBuffer instanceof ArrayBuffer ? new Uint8Array(inputBuffer) : inputBuffer; if (!checkBufferParams(this, view, inputOffset, inputLength)) { return -1; } const endLength = inputOffset + inputLength; this.valueHexView = view.subarray(inputOffset, endLength); if (!this.valueHexView.length) { this.warnings.push("Zero buffer length"); return inputOffset; } this.blockLength = inputLength; return endLength; } toBER(sizeOnly = false) { if (!this.isHexOnly) { this.error = "Flag 'isHexOnly' is not set, abort"; return EMPTY_BUFFER; } if (sizeOnly) { return new ArrayBuffer(this.valueHexView.byteLength); } return this.valueHexView.byteLength === this.valueHexView.buffer.byteLength ? this.valueHexView.buffer : this.valueHexView.slice().buffer; } toJSON() { return { ...super.toJSON(), isHexOnly: this.isHexOnly, valueHex: Convert.ToHex(this.valueHexView) }; } }, _a2.NAME = "hexBlock", _a2; } var LocalBaseBlock = class { constructor({ blockLength = 0, error = EMPTY_STRING, warnings = [], valueBeforeDecode = EMPTY_VIEW } = {}) { this.blockLength = blockLength; this.error = error; this.warnings = warnings; this.valueBeforeDecodeView = BufferSourceConverter.toUint8Array(valueBeforeDecode); } static blockName() { return this.NAME; } get valueBeforeDecode() { return this.valueBeforeDecodeView.slice().buffer; } set valueBeforeDecode(value) { this.valueBeforeDecodeView = new Uint8Array(value); } toJSON() { return { blockName: this.constructor.NAME, blockLength: this.blockLength, error: this.error, warnings: this.warnings, valueBeforeDecode: Convert.ToHex(this.valueBeforeDecodeView) }; } }; LocalBaseBlock.NAME = "baseBlock"; var ValueBlock = class extends LocalBaseBlock { fromBER(inputBuffer, inputOffset, inputLength) { throw TypeError("User need to make a specific function in a class which extends 'ValueBlock'"); } toBER(sizeOnly, writer) { throw TypeError("User need to make a specific function in a class which extends 'ValueBlock'"); } }; ValueBlock.NAME = "valueBlock"; var LocalIdentificationBlock = class extends HexBlock(LocalBaseBlock) { constructor({ idBlock = {} } = {}) { var _a2, _b, _c, _d; super(); if (idBlock) { this.isHexOnly = (_a2 = idBlock.isHexOnly) !== null && _a2 !== void 0 ? _a2 : false; this.valueHexView = idBlock.valueHex ? BufferSourceConverter.toUint8Array(idBlock.valueHex) : EMPTY_VIEW; this.tagClass = (_b = idBlock.tagClass) !== null && _b !== void 0 ? _b : -1; this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !== void 0 ? _c : -1; this.isConstructed = (_d = idBlock.isConstructed) !== null && _d !== void 0 ? _d : false; } else { this.tagClass = -1; this.tagNumber = -1; this.isConstructed = false; } } toBER(sizeOnly = false) { let firstOctet = 0; switch (this.tagClass) { case 1: firstOctet |= 0; break; case 2: firstOctet |= 64; break; case 3: firstOctet |= 128; break; case 4: firstOctet |= 192; break; default: this.error = "Unknown tag class"; return EMPTY_BUFFER; } if (this.isConstructed) firstOctet |= 32; if (this.tagNumber < 31 && !this.isHexOnly) { const retView2 = new Uint8Array(1); if (!sizeOnly) { let number = this.tagNumber; number &= 31; firstOctet |= number; retView2[0] = firstOctet; } return retView2.buffer; } if (!this.isHexOnly) { const encodedBuf = utilToBase(this.tagNumber, 7); const encodedView = new Uint8Array(encodedBuf); const size = encodedBuf.byteLength; const retView2 = new Uint8Array(size + 1); retView2[0] = firstOctet | 31; if (!sizeOnly) { for (let i = 0; i < size - 1; i++) retView2[i + 1] = encodedView[i] | 128; retView2[size] = encodedView[size - 1]; } return retView2.buffer; } const retView = new Uint8Array(this.valueHexView.byteLength + 1); retView[0] = firstOctet | 31; if (!sizeOnly) { const curView = this.valueHexView; for (let i = 0; i < curView.length - 1; i++) retView[i + 1] = curView[i] | 128; retView[this.valueHexView.byteLength] = curView[curView.length - 1]; } return retView.buffer; } fromBER(inputBuffer, inputOffset, inputLength) { const inputView = BufferSourceConverter.toUint8Array(inputBuffer); if (!checkBufferParams(this, inputView, inputOffset, inputLength)) { return -1; } const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength); if (intBuffer.length === 0) { this.error = "Zero buffer length"; return -1; } const tagClassMask = intBuffer[0] & 192; switch (tagClassMask) { case 0: this.tagClass = 1; break; case 64: this.tagClass = 2; break; case 128: this.tagClass = 3; break; case 192: this.tagClass = 4; break; default: this.error = "Unknown tag class"; return -1; } this.isConstructed = (intBuffer[0] & 32) === 32; this.isHexOnly = false; const tagNumberMask = intBuffer[0] & 31; if (tagNumberMask !== 31) { this.tagNumber = tagNumberMask; this.blockLength = 1; } else { let count = 1; let intTagNumberBuffer = this.valueHexView = new Uint8Array(255); let tagNumberBufferMaxLength = 255; while (intBuffer[count] & 128) { intTagNumberBuffer[count - 1] = intBuffer[count] & 127; count++; if (count >= intBuffer.length) { this.error = "End of input reached before message was fully decoded"; return -1; } if (count === tagNumberBufferMaxLength) { tagNumberBufferMaxLength += 255; const tempBufferView2 = new Uint8Array(tagNumberBufferMaxLength); for (let i = 0; i < intTagNumberBuffer.length; i++) tempBufferView2[i] = intTagNumberBuffer[i]; intTagNumberBuffer = this.valueHexView = new Uint8Array(tagNumberBufferMaxLength); } } this.blockLength = count + 1; intTagNumberBuffer[count - 1] = intBuffer[count] & 127; const tempBufferView = new Uint8Array(count); for (let i = 0; i < count; i++) tempBufferView[i] = intTagNumberBuffer[i]; intTagNumberBuffer = this.valueHexView = new Uint8Array(count); intTagNumberBuffer.set(tempBufferView); if (this.blockLength <= 9) this.tagNumber = utilFromBase(intTagNumberBuffer, 7); else { this.isHexOnly = true; this.warnings.push("Tag too long, represented as hex-coded"); } } if (this.tagClass === 1 && this.isConstructed) { switch (this.tagNumber) { case 1: case 2: case 5: case 6: case 9: case 13: case 14: case 23: case 24: case 31: case 32: case 33: case 34: this.error = "Constructed encoding used for primitive type"; return -1; } } return inputOffset + this.blockLength; } toJSON() { return { ...super.toJSON(), tagClass: this.tagClass, tagNumber: this.tagNumber, isConstructed: this.isConstructed }; } }; LocalIdentificationBlock.NAME = "identificationBlock"; var LocalLengthBlock = class extends LocalBaseBlock { constructor({ lenBlock = {} } = {}) { var _a2, _b, _c; super(); this.isIndefiniteForm = (_a2 = lenBlock.isIndefiniteForm) !== null && _a2 !== void 0 ? _a2 : false; this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !== void 0 ? _b : false; this.length = (_c = lenBlock.length) !== null && _c !== void 0 ? _c : 0; } fromBER(inputBuffer, inputOffset, inputLength) { const view = BufferSourceConverter.toUint8Array(inputBuffer); if (!checkBufferParams(this, view, inputOffset, inputLength)) { return -1; } const intBuffer = view.subarray(inputOffset, inputOffset + inputLength); if (intBuffer.length === 0) { this.error = "Zero buffer length"; return -1; } if (intBuffer[0] === 255) { this.error = "Length block 0xFF is reserved by standard"; return -1; } this.isIndefiniteForm = intBuffer[0] === 128; if (this.isIndefiniteForm) { this.blockLength = 1; return inputOffset + this.blockLength; } this.longFormUsed = !!(intBuffer[0] & 128); if (this.longFormUsed === false) { this.length = intBuffer[0]; this.blockLength = 1; return inputOffset + this.blockLength; } const count = intBuffer[0] & 127; if (count > 8) { 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 lenOffset = inputOffset + 1; const lengthBufferView = view.subarray(lenOffset, lenOffset + count); if (lengthBufferView[count - 1] === 0) this.warnings.push("Needlessly long encoded length"); this.length = utilFromBase(lengthBufferView, 8); if (this.longFormUsed && this.length <= 127) this.warnings.push("Unnecessary usage of long length form"); this.blockLength = count + 1; return inputOffset + this.blockLength; } toBER(sizeOnly = false) { let retBuf; let retView; if (this.length > 127) this.longFormUsed = true; if (this.isIndefiniteForm) { retBuf = new ArrayBuffer(1); if (sizeOnly === false) { retView = new Uint8Array(retBuf); retView[0] = 128; } return retBuf; } if (this.longFormUsed) { const encodedBuf = utilToBase(this.length, 8); if (encodedBuf.byteLength > 127) { this.error = "Too big length"; return EMPTY_BUFFER; } retBuf = new ArrayBuffer(encodedBuf.byteLength + 1); if (sizeOnly) return retBuf; const encodedView = new Uint8Array(encodedBuf); retView = new Uint8Array(retBuf); retView[0] = encodedBuf.byteLength | 128; 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; } toJSON() { return { ...super.toJSON(), isIndefiniteForm: this.isIndefiniteForm, longFormUsed: this.longFormUsed, length: this.length }; } }; LocalLengthBlock.NAME = "lengthBlock"; var typeStore = {}; var BaseBlock = class extends LocalBaseBlock { constructor({ name = EMPTY_STRING, optional = false, primitiveSchema, ...parameters } = {}, valueBlockType) { super(parameters); this.name = name; this.optional = optional; if (primitiveSchema) { this.primitiveSchema = primitiveSchema; } this.idBlock = new LocalIdentificationBlock(parameters); this.lenBlock = new LocalLengthBlock(parameters); this.valueBlock = valueBlockType ? new valueBlockType(parameters) : new ValueBlock(parameters); } fromBER(inputBuffer, inputOffset, inputLength) { const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm ? inputLength : this.lenBlock.length); if (resultOffset === -1) { this.error = this.valueBlock.error; return resultOffset; } if (!this.idBlock.error.length) this.blockLength += this.idBlock.blockLength; if (!this.lenBlock.error.length) this.blockLength += this.lenBlock.blockLength; if (!this.valueBlock.error.length) this.blockLength += this.valueBlock.blockLength; return resultOffset; } toBER(sizeOnly, writer) { const _writer = writer || new ViewWriter(); if (!writer) { prepareIndefiniteForm(this); } const idBlockBuf = this.idBlock.toBER(sizeOnly); _writer.write(idBlockBuf); if (this.lenBlock.isIndefiniteForm) { _writer.write(new Uint8Array([128]).buffer); this.valueBlock.toBER(sizeOnly, _writer); _writer.write(new ArrayBuffer(2)); } else { const valueBlockBuf = this.valueBlock.toBER(sizeOnly); this.lenBlock.length = valueBlockBuf.byteLength; const lenBlockBuf = this.lenBlock.toBER(sizeOnly); _writer.write(lenBlockBuf); _writer.write(valueBlockBuf); } if (!writer) { return _writer.final(); } return EMPTY_BUFFER; } toJSON() { const object = { ...super.toJSON(), idBlock: this.idBlock.toJSON(), lenBlock: this.lenBlock.toJSON(), valueBlock: this.valueBlock.toJSON(), name: this.name, optional: this.optional }; if (this.primitiveSchema) object.primitiveSchema = this.primitiveSchema.toJSON(); return object; } toString(encoding = "ascii") { if (encoding === "ascii") { return this.onAsciiEncoding(); } return Convert.ToHex(this.toBER()); } onAsciiEncoding() { return `${this.constructor.NAME} : ${Convert.ToHex(this.valueBlock.valueBeforeDecodeView)}`; } isEqual(other) { if (this === other) { return true; } if (!(other instanceof this.constructor)) { return false; } const thisRaw = this.toBER(); const otherRaw = other.toBER(); return isEqualBuffer(thisRaw, otherRaw); } }; BaseBlock.NAME = "BaseBlock"; function prepareIndefiniteForm(baseBlock) { if (baseBlock instanceof typeStore.Constructed) { for (const value of baseBlock.valueBlock.value) { if (prepareIndefiniteForm(value)) { baseBlock.lenBlock.isIndefiniteForm = true; } } } return !!baseBlock.lenBlock.isIndefiniteForm; } var BaseStringBlock = class extends BaseBlock { constructor({ value = EMPTY_STRING, ...parameters } = {}, stringValueBlockType) { super(parameters, stringValueBlockType); if (value) { this.fromString(value); } } getValue() { return this.valueBlock.value; } setValue(value) { this.valueBlock.value = value; } fromBER(inputBuffer, inputOffset, inputLength) { const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, this.lenBlock.isIndefiniteForm ? inputLength : this.lenBlock.length); if (resultOffset === -1) { this.error = this.valueBlock.error; return resultOffset; } this.fromBuffer(this.valueBlock.valueHexView); if (!this.idBlock.error.length) this.blockLength += this.idBlock.blockLength; if (!this.lenBlock.error.length) this.blockLength += this.lenBlock.blockLength; if (!this.valueBlock.error.length) this.blockLength += this.valueBlock.blockLength; return resultOffset; } onAsciiEncoding() { return `${this.constructor.NAME} : '${this.valueBlock.value}'`; } }; BaseStringBlock.NAME = "BaseStringBlock"; var LocalPrimitiveValueBlock = class extends HexBlock(ValueBlock) { constructor({ isHexOnly = true, ...parameters } = {}) { super(parameters); this.isHexOnly = isHexOnly; } }; LocalPrimitiveValueBlock.NAME = "PrimitiveValueBlock"; var _a$w; var Primitive = class extends BaseBlock { constructor(parameters = {}) { super(parameters, LocalPrimitiveValueBlock); this.idBlock.isConstructed = false; } }; _a$w = Primitive; (() => { typeStore.Primitive = _a$w; })(); Primitive.NAME = "PRIMITIVE"; 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; newObject.valueBeforeDecodeView = inputObject.valueBeforeDecodeView; return newObject; } function localFromBER(inputBuffer, inputOffset = 0, inputLength = inputBuffer.length) { const incomingOffset = inputOffset; let returnObject = new BaseBlock({}, ValueBlock); const baseBlock = new LocalBaseBlock(); if (!checkBufferParams(baseBlock, inputBuffer, inputOffset, inputLength)) { returnObject.error = baseBlock.error; return { offset: -1, result: returnObject }; } const intBuffer = inputBuffer.subarray(inputOffset, inputOffset + inputLength); if (!intBuffer.length) { returnObject.error = "Zero buffer length"; return { offset: -1, result: returnObject }; } let resultOffset = returnObject.idBlock.fromBER(inputBuffer, inputOffset, inputLength); if (returnObject.idBlock.warnings.length) { 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; resultOffset = returnObject.lenBlock.fromBER(inputBuffer, inputOffset, inputLength); if (returnObject.lenBlock.warnings.length) { 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; if (!returnObject.idBlock.isConstructed && returnObject.lenBlock.isIndefiniteForm) { returnObject.error = "Indefinite length form used for primitive encoding form"; return { offset: -1, result: returnObject }; } let newASN1Type = BaseBlock; switch (returnObject.idBlock.tagClass) { case 1: 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 }; } switch (returnObject.idBlock.tagNumber) { case 0: if (returnObject.idBlock.isConstructed && returnObject.lenBlock.length > 0) { returnObject.error = "Type [UNIVERSAL 0] is reserved"; return {