From 8d29040b57de3738e5c57041a504408897b91a9c Mon Sep 17 00:00:00 2001 From: M_Viper Date: Thu, 22 Oct 2026 07:01:11 +0000 Subject: [PATCH] Upload via GUI (7543 Dateien) --- node_modules/@peculiar/asn1-schema/LICENSE | 21 + node_modules/@peculiar/asn1-schema/README.md | 45 ++ .../build/cjs/errors/schema_validation.js | 7 + .../@peculiar/asn1-schema/build/cjs/helper.js | 44 ++ .../@peculiar/asn1-schema/build/cjs/index.js | 22 + .../asn1-schema/build/cjs/objects.js | 17 + .../@peculiar/asn1-schema/build/cjs/parser.js | 313 +++++++++++ .../@peculiar/asn1-schema/build/cjs/schema.js | 165 ++++++ .../asn1-schema/build/cjs/serializer.js | 150 ++++++ .../asn1-schema/build/cjs/storage.js | 5 + .../@peculiar/asn1-schema/build/cjs/types.js | 2 + .../asn1-schema/build/cjs/types/bit_string.js | 71 +++ .../asn1-schema/build/cjs/types/index.js | 5 + .../build/cjs/types/octet_string.js | 45 ++ .../asn1-schema/build/es2015/convert.js | 20 + .../asn1-schema/build/es2015/converters.js | 143 ++++++ .../asn1-schema/build/es2015/decorators.js | 43 ++ .../asn1-schema/build/es2015/enums.js | 37 ++ .../asn1-schema/build/es2015/errors/index.js | 1 + .../build/es2015/errors/schema_validation.js | 3 + .../asn1-schema/build/es2015/helper.js | 39 ++ .../asn1-schema/build/es2015/index.js | 9 + .../asn1-schema/build/es2015/objects.js | 13 + .../asn1-schema/build/es2015/parser.js | 308 +++++++++++ .../asn1-schema/build/es2015/schema.js | 160 ++++++ .../asn1-schema/build/es2015/serializer.js | 145 ++++++ .../asn1-schema/build/es2015/storage.js | 2 + .../asn1-schema/build/es2015/types.js | 1 + .../build/es2015/types/bit_string.js | 66 +++ .../asn1-schema/build/es2015/types/index.js | 2 + .../build/es2015/types/octet_string.js | 40 ++ .../asn1-schema/build/types/convert.d.ts | 20 + .../asn1-schema/build/types/converters.d.ts | 117 +++++ .../asn1-schema/build/types/decorators.d.ts | 36 ++ .../asn1-schema/build/types/enums.d.ts | 41 ++ .../asn1-schema/build/types/errors/index.d.ts | 1 + .../build/types/errors/schema_validation.d.ts | 3 + .../asn1-schema/build/types/helper.d.ts | 5 + .../asn1-schema/build/types/index.d.ts | 10 + .../asn1-schema/build/types/objects.d.ts | 3 + .../asn1-schema/build/types/parser.d.ts | 72 +++ .../asn1-schema/build/types/schema.d.ts | 32 ++ .../asn1-schema/build/types/serializer.d.ts | 17 + .../asn1-schema/build/types/storage.d.ts | 2 + .../asn1-schema/build/types/types.d.ts | 42 ++ .../build/types/types/bit_string.d.ts | 15 + .../asn1-schema/build/types/types/index.d.ts | 2 + .../build/types/types/octet_string.d.ts | 15 + .../@peculiar/asn1-schema/package.json | 64 +++ .../@peculiar/json-schema/build/index.es.js | 484 ++++++++++++++++++ 50 files changed, 2925 insertions(+) create mode 100644 node_modules/@peculiar/asn1-schema/LICENSE create mode 100644 node_modules/@peculiar/asn1-schema/README.md create mode 100644 node_modules/@peculiar/asn1-schema/build/cjs/errors/schema_validation.js create mode 100644 node_modules/@peculiar/asn1-schema/build/cjs/helper.js create mode 100644 node_modules/@peculiar/asn1-schema/build/cjs/index.js create mode 100644 node_modules/@peculiar/asn1-schema/build/cjs/objects.js create mode 100644 node_modules/@peculiar/asn1-schema/build/cjs/parser.js create mode 100644 node_modules/@peculiar/asn1-schema/build/cjs/schema.js create mode 100644 node_modules/@peculiar/asn1-schema/build/cjs/serializer.js create mode 100644 node_modules/@peculiar/asn1-schema/build/cjs/storage.js create mode 100644 node_modules/@peculiar/asn1-schema/build/cjs/types.js create mode 100644 node_modules/@peculiar/asn1-schema/build/cjs/types/bit_string.js create mode 100644 node_modules/@peculiar/asn1-schema/build/cjs/types/index.js create mode 100644 node_modules/@peculiar/asn1-schema/build/cjs/types/octet_string.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/convert.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/converters.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/decorators.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/enums.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/errors/index.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/errors/schema_validation.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/helper.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/index.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/objects.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/parser.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/schema.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/serializer.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/storage.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/types.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/types/bit_string.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/types/index.js create mode 100644 node_modules/@peculiar/asn1-schema/build/es2015/types/octet_string.js create mode 100644 node_modules/@peculiar/asn1-schema/build/types/convert.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/converters.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/decorators.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/enums.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/errors/index.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/errors/schema_validation.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/helper.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/index.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/objects.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/parser.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/schema.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/serializer.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/storage.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/types.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/types/bit_string.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/types/index.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/build/types/types/octet_string.d.ts create mode 100644 node_modules/@peculiar/asn1-schema/package.json create mode 100644 node_modules/@peculiar/json-schema/build/index.es.js diff --git a/node_modules/@peculiar/asn1-schema/LICENSE b/node_modules/@peculiar/asn1-schema/LICENSE new file mode 100644 index 0000000..6f9ec13 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@peculiar/asn1-schema/README.md b/node_modules/@peculiar/asn1-schema/README.md new file mode 100644 index 0000000..d7858c2 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/README.md @@ -0,0 +1,45 @@ +# `@peculiar/asn1-schema` + +[![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://github.com/PeculiarVentures/asn1-schema/blob/master/packages/schema/LICENSE) +[![npm version](https://badge.fury.io/js/%40peculiar%2Fasn1-schema.svg)](https://badge.fury.io/js/%40peculiar%2Fasn1-schema) + +[![NPM](https://nodei.co/npm/@peculiar/asn1-schema.png)](https://nodei.co/npm/@peculiar/asn1-schema/) + +Decorators and helper APIs for declaring ASN.1 schemas in TypeScript. + +This is the core package used by the schema modules in this repository. It lets you describe DER structures with decorators and convert them with `AsnConvert`, `AsnParser`, and `AsnSerializer`. + +## Installation + +```bash +npm install @peculiar/asn1-schema +``` + +## Overview + +Abstract Syntax Notation One (ASN.1) is widely used across X.509, PKCS, CMS, OCSP, and related standards. This package keeps those mappings declarative and type-friendly by attaching schema metadata directly to classes. + +## TypeScript Example + +```ts +import { AsnConvert, AsnProp, AsnPropTypes, AsnType, AsnTypeTypes } from "@peculiar/asn1-schema"; + +@AsnType({ type: AsnTypeTypes.Sequence }) +class BasicConstraints { + @AsnProp({ type: AsnPropTypes.Boolean, defaultValue: false }) + public cA = false; +} + +const basicConstraints = new BasicConstraints(); +basicConstraints.cA = true; + +const encoded = AsnConvert.serialize(basicConstraints); +const decoded = AsnConvert.parse(encoded, BasicConstraints); + +console.log(decoded.cA); +``` + +## Related Links + +- [Decorators overview](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841) +- [ASN.1 playground](http://lapo.it/asn1js/) diff --git a/node_modules/@peculiar/asn1-schema/build/cjs/errors/schema_validation.js b/node_modules/@peculiar/asn1-schema/build/cjs/errors/schema_validation.js new file mode 100644 index 0000000..4ca0ed3 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/cjs/errors/schema_validation.js @@ -0,0 +1,7 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AsnSchemaValidationError = void 0; +class AsnSchemaValidationError extends Error { + schemas = []; +} +exports.AsnSchemaValidationError = AsnSchemaValidationError; diff --git a/node_modules/@peculiar/asn1-schema/build/cjs/helper.js b/node_modules/@peculiar/asn1-schema/build/cjs/helper.js new file mode 100644 index 0000000..bcc2f82 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/cjs/helper.js @@ -0,0 +1,44 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isConvertible = isConvertible; +exports.isTypeOfArray = isTypeOfArray; +exports.isArrayEqual = isArrayEqual; +function isConvertible(target) { + if (typeof target === "function" && target.prototype) { + if (target.prototype.toASN && target.prototype.fromASN) { + return true; + } + else { + return isConvertible(target.prototype); + } + } + else { + return !!(target && typeof target === "object" && "toASN" in target && "fromASN" in target); + } +} +function isTypeOfArray(target) { + if (target) { + const proto = Object.getPrototypeOf(target); + if (proto?.prototype?.constructor === Array) { + return true; + } + return isTypeOfArray(proto); + } + return false; +} +function isArrayEqual(bytes1, bytes2) { + if (!(bytes1 && bytes2)) { + return false; + } + if (bytes1.byteLength !== bytes2.byteLength) { + return false; + } + const b1 = new Uint8Array(bytes1); + const b2 = new Uint8Array(bytes2); + for (let i = 0; i < bytes1.byteLength; i++) { + if (b1[i] !== b2[i]) { + return false; + } + } + return true; +} diff --git a/node_modules/@peculiar/asn1-schema/build/cjs/index.js b/node_modules/@peculiar/asn1-schema/build/cjs/index.js new file mode 100644 index 0000000..9a04496 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/cjs/index.js @@ -0,0 +1,22 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AsnSerializer = exports.AsnParser = exports.AsnPropTypes = exports.AsnTypeTypes = exports.AsnSetType = exports.AsnSequenceType = exports.AsnChoiceType = exports.AsnType = exports.AsnProp = void 0; +const tslib_1 = require("tslib"); +tslib_1.__exportStar(require("./converters"), exports); +tslib_1.__exportStar(require("./types/index"), exports); +var decorators_1 = require("./decorators"); +Object.defineProperty(exports, "AsnProp", { enumerable: true, get: function () { return decorators_1.AsnProp; } }); +Object.defineProperty(exports, "AsnType", { enumerable: true, get: function () { return decorators_1.AsnType; } }); +Object.defineProperty(exports, "AsnChoiceType", { enumerable: true, get: function () { return decorators_1.AsnChoiceType; } }); +Object.defineProperty(exports, "AsnSequenceType", { enumerable: true, get: function () { return decorators_1.AsnSequenceType; } }); +Object.defineProperty(exports, "AsnSetType", { enumerable: true, get: function () { return decorators_1.AsnSetType; } }); +var enums_1 = require("./enums"); +Object.defineProperty(exports, "AsnTypeTypes", { enumerable: true, get: function () { return enums_1.AsnTypeTypes; } }); +Object.defineProperty(exports, "AsnPropTypes", { enumerable: true, get: function () { return enums_1.AsnPropTypes; } }); +var parser_1 = require("./parser"); +Object.defineProperty(exports, "AsnParser", { enumerable: true, get: function () { return parser_1.AsnParser; } }); +var serializer_1 = require("./serializer"); +Object.defineProperty(exports, "AsnSerializer", { enumerable: true, get: function () { return serializer_1.AsnSerializer; } }); +tslib_1.__exportStar(require("./errors"), exports); +tslib_1.__exportStar(require("./objects"), exports); +tslib_1.__exportStar(require("./convert"), exports); diff --git a/node_modules/@peculiar/asn1-schema/build/cjs/objects.js b/node_modules/@peculiar/asn1-schema/build/cjs/objects.js new file mode 100644 index 0000000..a787c28 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/cjs/objects.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AsnArray = void 0; +class AsnArray extends Array { + constructor(items = []) { + if (typeof items === "number") { + super(items); + } + else { + super(); + for (const item of items) { + this.push(item); + } + } + } +} +exports.AsnArray = AsnArray; diff --git a/node_modules/@peculiar/asn1-schema/build/cjs/parser.js b/node_modules/@peculiar/asn1-schema/build/cjs/parser.js new file mode 100644 index 0000000..62172fd --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/cjs/parser.js @@ -0,0 +1,313 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AsnParser = void 0; +const tslib_1 = require("tslib"); +const asn1js = tslib_1.__importStar(require("asn1js")); +const utils_1 = require("@peculiar/utils"); +const enums_1 = require("./enums"); +const converters = tslib_1.__importStar(require("./converters")); +const errors_1 = require("./errors"); +const helper_1 = require("./helper"); +const storage_1 = require("./storage"); +class AsnParser { + static parse(data, target, options) { + const asn1Parsed = asn1js.fromBER((0, utils_1.toArrayBuffer)(data), options?.berOptions); + if (asn1Parsed.result.error) { + throw new Error(asn1Parsed.result.error); + } + const res = this.fromASN(asn1Parsed.result, target, options); + return res; + } + static fromASN(asn1Schema, target, options) { + try { + if ((0, helper_1.isConvertible)(target)) { + const value = new target(); + return value.fromASN(asn1Schema); + } + const schema = storage_1.schemaStorage.get(target); + storage_1.schemaStorage.cache(target); + let targetSchema = schema.schema; + const choiceResult = this.handleChoiceTypes(asn1Schema, schema, target, targetSchema, options); + if (choiceResult?.result) { + return choiceResult.result; + } + if (choiceResult?.targetSchema) { + targetSchema = choiceResult.targetSchema; + } + const sequenceResult = this.handleSequenceTypes(asn1Schema, schema, target, targetSchema); + const res = new target(); + if ((0, helper_1.isTypeOfArray)(target)) { + return this.handleArrayTypes(asn1Schema, schema, target, options); + } + this.processSchemaItems(schema, sequenceResult, res, options); + return res; + } + catch (error) { + if (error instanceof errors_1.AsnSchemaValidationError) { + error.schemas.push(target.name); + } + throw error; + } + } + static handleChoiceTypes(asn1Schema, schema, target, targetSchema, options) { + if (asn1Schema.constructor === asn1js.Constructed && schema.type === enums_1.AsnTypeTypes.Choice && asn1Schema.idBlock.tagClass === 3) { + for (const key in schema.items) { + const schemaItem = schema.items[key]; + if (schemaItem.context === asn1Schema.idBlock.tagNumber && schemaItem.implicit) { + if (typeof schemaItem.type === "function" && storage_1.schemaStorage.has(schemaItem.type)) { + const fieldSchema = storage_1.schemaStorage.get(schemaItem.type); + if (fieldSchema && fieldSchema.type === enums_1.AsnTypeTypes.Sequence) { + const newSeq = new asn1js.Sequence(); + if ("value" in asn1Schema.valueBlock && Array.isArray(asn1Schema.valueBlock.value) && "value" in newSeq.valueBlock) { + newSeq.valueBlock.value = asn1Schema.valueBlock.value; + const fieldValue = this.fromASN(newSeq, schemaItem.type, options); + const res = new target(); + res[key] = fieldValue; + return { result: res }; + } + } + } + } + } + } + else if (asn1Schema.constructor === asn1js.Constructed && schema.type !== enums_1.AsnTypeTypes.Choice) { + const newTargetSchema = new asn1js.Constructed({ + idBlock: { + tagClass: 3, + tagNumber: asn1Schema.idBlock.tagNumber, + }, + value: schema.schema.valueBlock.value, + }); + for (const key in schema.items) { + delete asn1Schema[key]; + } + return { targetSchema: newTargetSchema }; + } + return null; + } + static handleSequenceTypes(asn1Schema, schema, target, targetSchema) { + if (schema.type === enums_1.AsnTypeTypes.Sequence) { + const asn1ComparedSchema = asn1js.compareSchema({}, asn1Schema, targetSchema); + if (!asn1ComparedSchema.verified) { + throw new errors_1.AsnSchemaValidationError(`Data does not match to ${target.name} ASN1 schema.${asn1ComparedSchema.result.error ? ` ${asn1ComparedSchema.result.error}` : ""}`); + } + return asn1ComparedSchema; + } + else { + const asn1ComparedSchema = asn1js.compareSchema({}, asn1Schema, targetSchema); + if (!asn1ComparedSchema.verified) { + throw new errors_1.AsnSchemaValidationError(`Data does not match to ${target.name} ASN1 schema.${asn1ComparedSchema.result.error ? ` ${asn1ComparedSchema.result.error}` : ""}`); + } + return asn1ComparedSchema; + } + } + static processRepeatedField(asn1Elements, asn1Index, schemaItem) { + let elementsToProcess = asn1Elements.slice(asn1Index); + if (elementsToProcess.length === 1 && elementsToProcess[0].constructor.name === "Sequence") { + const seq = elementsToProcess[0]; + if (seq.valueBlock && seq.valueBlock.value && Array.isArray(seq.valueBlock.value)) { + elementsToProcess = seq.valueBlock.value; + } + } + if (typeof schemaItem.type === "number") { + const converter = converters.defaultConverter(schemaItem.type); + if (!converter) + throw new Error(`No converter for ASN.1 type ${schemaItem.type}`); + return elementsToProcess + .filter((el) => el && el.valueBlock) + .map((el) => { + try { + return converter.fromASN(el); + } + catch { + return undefined; + } + }) + .filter((v) => v !== undefined); + } + else { + return elementsToProcess + .filter((el) => el && el.valueBlock) + .map((el) => { + try { + return this.fromASN(el, schemaItem.type); + } + catch { + return undefined; + } + }) + .filter((v) => v !== undefined); + } + } + static processPrimitiveField(asn1Element, schemaItem) { + const converter = converters.defaultConverter(schemaItem.type); + if (!converter) + throw new Error(`No converter for ASN.1 type ${schemaItem.type}`); + return converter.fromASN(asn1Element); + } + static isOptionalChoiceField(schemaItem) { + return (schemaItem.optional && + typeof schemaItem.type === "function" && + storage_1.schemaStorage.has(schemaItem.type) && + storage_1.schemaStorage.get(schemaItem.type).type === enums_1.AsnTypeTypes.Choice); + } + static processOptionalChoiceField(asn1Element, schemaItem) { + try { + const value = this.fromASN(asn1Element, schemaItem.type); + return { + processed: true, + value, + }; + } + catch (err) { + if (err instanceof errors_1.AsnSchemaValidationError && /Wrong values for Choice type/.test(err.message)) { + return { processed: false }; + } + throw err; + } + } + static handleArrayTypes(asn1Schema, schema, target, options) { + if (!("value" in asn1Schema.valueBlock && Array.isArray(asn1Schema.valueBlock.value))) { + throw new Error("Cannot get items from the ASN.1 parsed value. ASN.1 object is not constructed."); + } + const itemType = schema.itemType; + if (typeof itemType === "number") { + const converter = converters.defaultConverter(itemType); + if (!converter) { + throw new Error(`Cannot get default converter for array item of ${target.name} ASN1 schema`); + } + return target.from(asn1Schema.valueBlock.value, (element) => converter.fromASN(element)); + } + else { + return target.from(asn1Schema.valueBlock.value, (element) => this.fromASN(element, itemType, options)); + } + } + static processSchemaItems(schema, asn1ComparedSchema, res, options) { + for (const key in schema.items) { + const asn1SchemaValue = asn1ComparedSchema.result[key]; + if (!asn1SchemaValue) { + continue; + } + const schemaItem = schema.items[key]; + const schemaItemType = schemaItem.type; + let parsedValue; + if (typeof schemaItemType === "number" || (0, helper_1.isConvertible)(schemaItemType)) { + parsedValue = this.processPrimitiveSchemaItem(asn1SchemaValue, schemaItem, schemaItemType, options); + } + else { + parsedValue = this.processComplexSchemaItem(asn1SchemaValue, schemaItem, schemaItemType, options); + } + if (parsedValue && typeof parsedValue === "object" && "value" in parsedValue && "raw" in parsedValue) { + res[key] = parsedValue.value; + res[`${key}Raw`] = parsedValue.raw; + } + else { + res[key] = parsedValue; + } + } + } + static processPrimitiveSchemaItem(asn1SchemaValue, schemaItem, schemaItemType, options) { + const converter = schemaItem.converter ?? ((0, helper_1.isConvertible)(schemaItemType) ? new schemaItemType() : null); + if (!converter) { + throw new Error("Converter is empty"); + } + if (schemaItem.repeated) { + return this.processRepeatedPrimitiveItem(asn1SchemaValue, schemaItem, converter, options); + } + else { + return this.processSinglePrimitiveItem(asn1SchemaValue, schemaItem, schemaItemType, converter, options); + } + } + static processRepeatedPrimitiveItem(asn1SchemaValue, schemaItem, converter, options) { + if (schemaItem.implicit) { + const Container = schemaItem.repeated === "sequence" ? asn1js.Sequence : asn1js.Set; + const newItem = new Container(); + newItem.valueBlock = asn1SchemaValue.valueBlock; + const newItemAsn = asn1js.fromBER(newItem.toBER(false), options?.berOptions); + if (newItemAsn.offset === -1) { + throw new Error(`Cannot parse the child item. ${newItemAsn.result.error}`); + } + if (!("value" in newItemAsn.result.valueBlock && Array.isArray(newItemAsn.result.valueBlock.value))) { + throw new Error("Cannot get items from the ASN.1 parsed value. ASN.1 object is not constructed."); + } + const value = newItemAsn.result.valueBlock.value; + return Array.from(value, (element) => converter.fromASN(element)); + } + else { + return Array.from(asn1SchemaValue, (element) => converter.fromASN(element)); + } + } + static processSinglePrimitiveItem(asn1SchemaValue, schemaItem, schemaItemType, converter, options) { + let value = asn1SchemaValue; + if (schemaItem.implicit) { + let newItem; + if ((0, helper_1.isConvertible)(schemaItemType)) { + newItem = new schemaItemType().toSchema(""); + } + else { + const Asn1TypeName = enums_1.AsnPropTypes[schemaItemType]; + const Asn1Type = asn1js[Asn1TypeName]; + if (!Asn1Type) { + throw new Error(`Cannot get '${Asn1TypeName}' class from asn1js module`); + } + newItem = new Asn1Type(); + } + newItem.valueBlock = value.valueBlock; + value = asn1js.fromBER(newItem.toBER(false), options?.berOptions).result; + } + return converter.fromASN(value); + } + static processComplexSchemaItem(asn1SchemaValue, schemaItem, schemaItemType, options) { + if (schemaItem.repeated) { + if (!Array.isArray(asn1SchemaValue)) { + throw new Error("Cannot get list of items from the ASN.1 parsed value. ASN.1 value should be iterable."); + } + return Array.from(asn1SchemaValue, (element) => this.fromASN(element, schemaItemType, options)); + } + else { + const valueToProcess = this.handleImplicitTagging(asn1SchemaValue, schemaItem, schemaItemType); + if (this.isOptionalChoiceField(schemaItem)) { + try { + return this.fromASN(valueToProcess, schemaItemType, options); + } + catch (err) { + if (err instanceof errors_1.AsnSchemaValidationError && /Wrong values for Choice type/.test(err.message)) { + return undefined; + } + throw err; + } + } + else { + const parsedValue = this.fromASN(valueToProcess, schemaItemType, options); + if (schemaItem.raw) { + return { + value: parsedValue, + raw: asn1SchemaValue.valueBeforeDecodeView, + }; + } + return parsedValue; + } + } + } + static handleImplicitTagging(asn1SchemaValue, schemaItem, schemaItemType) { + if (schemaItem.implicit && typeof schemaItem.context === "number") { + const schema = storage_1.schemaStorage.get(schemaItemType); + if (schema.type === enums_1.AsnTypeTypes.Sequence) { + const newSeq = new asn1js.Sequence(); + if ("value" in asn1SchemaValue.valueBlock && Array.isArray(asn1SchemaValue.valueBlock.value) && "value" in newSeq.valueBlock) { + newSeq.valueBlock.value = asn1SchemaValue.valueBlock.value; + return newSeq; + } + } + else if (schema.type === enums_1.AsnTypeTypes.Set) { + const newSet = new asn1js.Set(); + if ("value" in asn1SchemaValue.valueBlock && Array.isArray(asn1SchemaValue.valueBlock.value) && "value" in newSet.valueBlock) { + newSet.valueBlock.value = asn1SchemaValue.valueBlock.value; + return newSet; + } + } + } + return asn1SchemaValue; + } +} +exports.AsnParser = AsnParser; diff --git a/node_modules/@peculiar/asn1-schema/build/cjs/schema.js b/node_modules/@peculiar/asn1-schema/build/cjs/schema.js new file mode 100644 index 0000000..151c81e --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/cjs/schema.js @@ -0,0 +1,165 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AsnSchemaStorage = void 0; +const tslib_1 = require("tslib"); +const asn1js = tslib_1.__importStar(require("asn1js")); +const enums_1 = require("./enums"); +const helper_1 = require("./helper"); +class AsnSchemaStorage { + items = new WeakMap(); + has(target) { + return this.items.has(target); + } + get(target, checkSchema = false) { + const schema = this.items.get(target); + if (!schema) { + throw new Error(`Cannot get schema for '${target.prototype.constructor.name}' target`); + } + if (checkSchema && !schema.schema) { + throw new Error(`Schema '${target.prototype.constructor.name}' doesn't contain ASN.1 schema. Call 'AsnSchemaStorage.cache'.`); + } + return schema; + } + cache(target) { + const schema = this.get(target); + if (!schema.schema) { + schema.schema = this.create(target, true); + } + } + createDefault(target) { + const schema = { + type: enums_1.AsnTypeTypes.Sequence, + items: {}, + }; + const parentSchema = this.findParentSchema(target); + if (parentSchema) { + Object.assign(schema, parentSchema); + schema.items = Object.assign({}, schema.items, parentSchema.items); + } + return schema; + } + create(target, useNames) { + const schema = this.items.get(target) || this.createDefault(target); + const asn1Value = []; + for (const key in schema.items) { + const item = schema.items[key]; + const name = useNames ? key : ""; + let asn1Item; + if (typeof item.type === "number") { + const Asn1TypeName = enums_1.AsnPropTypes[item.type]; + const Asn1Type = asn1js[Asn1TypeName]; + if (!Asn1Type) { + throw new Error(`Cannot get ASN1 class by name '${Asn1TypeName}'`); + } + asn1Item = new Asn1Type({ name }); + } + else if ((0, helper_1.isConvertible)(item.type)) { + const instance = new item.type(); + asn1Item = instance.toSchema(name); + } + else if (item.optional) { + const itemSchema = this.get(item.type); + if (itemSchema.type === enums_1.AsnTypeTypes.Choice) { + asn1Item = new asn1js.Any({ name }); + } + else { + asn1Item = this.create(item.type, false); + asn1Item.name = name; + } + } + else { + asn1Item = new asn1js.Any({ name }); + } + const optional = !!item.optional || item.defaultValue !== undefined; + if (item.repeated) { + asn1Item.name = ""; + const Container = item.repeated === "set" ? asn1js.Set : asn1js.Sequence; + asn1Item = new Container({ + name: "", + value: [ + new asn1js.Repeated({ + name, + value: asn1Item, + }), + ], + }); + } + if (item.context !== null && item.context !== undefined) { + if (item.implicit) { + if (typeof item.type === "number" || (0, helper_1.isConvertible)(item.type)) { + const Container = item.repeated ? asn1js.Constructed : asn1js.Primitive; + asn1Value.push(new Container({ + name, + optional, + idBlock: { + tagClass: 3, + tagNumber: item.context, + }, + })); + } + else { + this.cache(item.type); + const isRepeated = !!item.repeated; + let value = !isRepeated ? this.get(item.type, true).schema : asn1Item; + value = "valueBlock" in value ? value.valueBlock.value : value.value; + asn1Value.push(new asn1js.Constructed({ + name: !isRepeated ? name : "", + optional, + idBlock: { + tagClass: 3, + tagNumber: item.context, + }, + value: value, + })); + } + } + else { + asn1Value.push(new asn1js.Constructed({ + optional, + idBlock: { + tagClass: 3, + tagNumber: item.context, + }, + value: [asn1Item], + })); + } + } + else { + asn1Item.optional = optional; + asn1Value.push(asn1Item); + } + } + switch (schema.type) { + case enums_1.AsnTypeTypes.Sequence: + return new asn1js.Sequence({ + value: asn1Value, + name: "", + }); + case enums_1.AsnTypeTypes.Set: + return new asn1js.Set({ + value: asn1Value, + name: "", + }); + case enums_1.AsnTypeTypes.Choice: + return new asn1js.Choice({ + value: asn1Value, + name: "", + }); + default: + throw new Error("Unsupported ASN1 type in use"); + } + } + set(target, schema) { + this.items.set(target, schema); + return this; + } + findParentSchema(target) { + const parent = Object.getPrototypeOf(target); + if (parent) { + const schema = this.items.get(parent); + return schema || this.findParentSchema(parent); + } + return null; + } +} +exports.AsnSchemaStorage = AsnSchemaStorage; diff --git a/node_modules/@peculiar/asn1-schema/build/cjs/serializer.js b/node_modules/@peculiar/asn1-schema/build/cjs/serializer.js new file mode 100644 index 0000000..b8cac3e --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/cjs/serializer.js @@ -0,0 +1,150 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.AsnSerializer = void 0; +const tslib_1 = require("tslib"); +const asn1js = tslib_1.__importStar(require("asn1js")); +const utils_1 = require("@peculiar/utils"); +const converters = tslib_1.__importStar(require("./converters")); +const enums_1 = require("./enums"); +const helper_1 = require("./helper"); +const storage_1 = require("./storage"); +class AsnSerializer { + static serialize(obj) { + if (obj instanceof asn1js.BaseBlock) { + return obj.toBER(false); + } + return this.toASN(obj).toBER(false); + } + static toASN(obj) { + if (obj && typeof obj === "object" && (0, helper_1.isConvertible)(obj)) { + return obj.toASN(); + } + if (!(obj && typeof obj === "object")) { + throw new TypeError("Parameter 1 should be type of Object."); + } + const target = obj.constructor; + const schema = storage_1.schemaStorage.get(target); + storage_1.schemaStorage.cache(target); + let asn1Value = []; + if (schema.itemType) { + if (!Array.isArray(obj)) { + throw new TypeError("Parameter 1 should be type of Array."); + } + if (typeof schema.itemType === "number") { + const converter = converters.defaultConverter(schema.itemType); + if (!converter) { + throw new Error(`Cannot get default converter for array item of ${target.name} ASN1 schema`); + } + asn1Value = obj.map((o) => converter.toASN(o)); + } + else { + asn1Value = obj.map((o) => this.toAsnItem({ type: schema.itemType }, "[]", target, o)); + } + } + else { + for (const key in schema.items) { + const schemaItem = schema.items[key]; + const objProp = obj[key]; + if (objProp === undefined || + schemaItem.defaultValue === objProp || + (typeof schemaItem.defaultValue === "object" && typeof objProp === "object" && (0, helper_1.isArrayEqual)(this.serialize(schemaItem.defaultValue), this.serialize(objProp)))) { + continue; + } + const asn1Item = AsnSerializer.toAsnItem(schemaItem, key, target, objProp); + if (typeof schemaItem.context === "number") { + if (schemaItem.implicit) { + if (!schemaItem.repeated && (typeof schemaItem.type === "number" || (0, helper_1.isConvertible)(schemaItem.type))) { + const value = {}; + value.valueHex = asn1Item instanceof asn1js.Null ? (0, utils_1.toArrayBuffer)(asn1Item.valueBeforeDecodeView) : asn1Item.valueBlock.toBER(); + asn1Value.push(new asn1js.Primitive({ + optional: schemaItem.optional, + idBlock: { + tagClass: 3, + tagNumber: schemaItem.context, + }, + ...value, + })); + } + else { + asn1Value.push(new asn1js.Constructed({ + optional: schemaItem.optional, + idBlock: { + tagClass: 3, + tagNumber: schemaItem.context, + }, + value: asn1Item.valueBlock.value, + })); + } + } + else { + asn1Value.push(new asn1js.Constructed({ + optional: schemaItem.optional, + idBlock: { + tagClass: 3, + tagNumber: schemaItem.context, + }, + value: [asn1Item], + })); + } + } + else if (schemaItem.repeated) { + asn1Value = asn1Value.concat(asn1Item); + } + else { + asn1Value.push(asn1Item); + } + } + } + let asnSchema; + switch (schema.type) { + case enums_1.AsnTypeTypes.Sequence: + asnSchema = new asn1js.Sequence({ value: asn1Value }); + break; + case enums_1.AsnTypeTypes.Set: + asnSchema = new asn1js.Set({ value: asn1Value }); + break; + case enums_1.AsnTypeTypes.Choice: + if (!asn1Value[0]) { + throw new Error(`Schema '${target.name}' has wrong data. Choice cannot be empty.`); + } + asnSchema = asn1Value[0]; + break; + } + return asnSchema; + } + static toAsnItem(schemaItem, key, target, objProp) { + let asn1Item; + if (typeof schemaItem.type === "number") { + const converter = schemaItem.converter; + if (!converter) { + throw new Error(`Property '${key}' doesn't have converter for type ${enums_1.AsnPropTypes[schemaItem.type]} in schema '${target.name}'`); + } + if (schemaItem.repeated) { + if (!Array.isArray(objProp)) { + throw new TypeError("Parameter 'objProp' should be type of Array."); + } + const items = Array.from(objProp, (element) => converter.toASN(element)); + const Container = schemaItem.repeated === "sequence" ? asn1js.Sequence : asn1js.Set; + asn1Item = new Container({ value: items }); + } + else { + asn1Item = converter.toASN(objProp); + } + } + else { + if (schemaItem.repeated) { + if (!Array.isArray(objProp)) { + throw new TypeError("Parameter 'objProp' should be type of Array."); + } + const items = Array.from(objProp, (element) => this.toASN(element)); + const Container = schemaItem.repeated === "sequence" ? asn1js.Sequence : asn1js.Set; + asn1Item = new Container({ value: items }); + } + else { + asn1Item = this.toASN(objProp); + } + } + return asn1Item; + } +} +exports.AsnSerializer = AsnSerializer; diff --git a/node_modules/@peculiar/asn1-schema/build/cjs/storage.js b/node_modules/@peculiar/asn1-schema/build/cjs/storage.js new file mode 100644 index 0000000..368009e --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/cjs/storage.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.schemaStorage = void 0; +const schema_1 = require("./schema"); +exports.schemaStorage = new schema_1.AsnSchemaStorage(); diff --git a/node_modules/@peculiar/asn1-schema/build/cjs/types.js b/node_modules/@peculiar/asn1-schema/build/cjs/types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/cjs/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@peculiar/asn1-schema/build/cjs/types/bit_string.js b/node_modules/@peculiar/asn1-schema/build/cjs/types/bit_string.js new file mode 100644 index 0000000..ccbc18b --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/cjs/types/bit_string.js @@ -0,0 +1,71 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BitString = void 0; +const tslib_1 = require("tslib"); +const asn1js = tslib_1.__importStar(require("asn1js")); +const utils_1 = require("@peculiar/utils"); +class BitString { + unusedBits = 0; + value = new ArrayBuffer(0); + constructor(params, unusedBits = 0) { + if (params) { + if (typeof params === "number") { + this.fromNumber(params); + } + else if ((0, utils_1.isBufferSource)(params)) { + this.unusedBits = unusedBits; + this.value = (0, utils_1.toArrayBuffer)(params); + } + else { + throw TypeError("Unsupported type of 'params' argument for BitString"); + } + } + } + fromASN(asn) { + if (!(asn instanceof asn1js.BitString)) { + throw new TypeError("Argument 'asn' is not instance of ASN.1 BitString"); + } + this.unusedBits = asn.valueBlock.unusedBits; + this.value = (0, utils_1.toArrayBuffer)(asn.valueBlock.valueHex); + return this; + } + toASN() { + return new asn1js.BitString({ + unusedBits: this.unusedBits, + valueHex: this.value, + }); + } + toSchema(name) { + return new asn1js.BitString({ name }); + } + toNumber() { + let res = ""; + const uintArray = new Uint8Array(this.value); + for (const octet of uintArray) { + res += octet.toString(2).padStart(8, "0"); + } + res = res.split("").reverse().join(""); + if (this.unusedBits) { + res = res.slice(this.unusedBits).padStart(this.unusedBits, "0"); + } + return parseInt(res, 2); + } + fromNumber(value) { + let bits = value.toString(2); + const octetSize = (bits.length + 7) >> 3; + this.unusedBits = (octetSize << 3) - bits.length; + const octets = new Uint8Array(octetSize); + bits = bits + .padStart(octetSize << 3, "0") + .split("") + .reverse() + .join(""); + let index = 0; + while (index < octetSize) { + octets[index] = parseInt(bits.slice(index << 3, (index << 3) + 8), 2); + index++; + } + this.value = octets.buffer; + } +} +exports.BitString = BitString; diff --git a/node_modules/@peculiar/asn1-schema/build/cjs/types/index.js b/node_modules/@peculiar/asn1-schema/build/cjs/types/index.js new file mode 100644 index 0000000..cd5fccf --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/cjs/types/index.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const tslib_1 = require("tslib"); +tslib_1.__exportStar(require("./bit_string"), exports); +tslib_1.__exportStar(require("./octet_string"), exports); diff --git a/node_modules/@peculiar/asn1-schema/build/cjs/types/octet_string.js b/node_modules/@peculiar/asn1-schema/build/cjs/types/octet_string.js new file mode 100644 index 0000000..1a3b8b6 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/cjs/types/octet_string.js @@ -0,0 +1,45 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.OctetString = void 0; +const tslib_1 = require("tslib"); +const asn1js = tslib_1.__importStar(require("asn1js")); +const utils_1 = require("@peculiar/utils"); +class OctetString { + buffer; + get byteLength() { + return this.buffer.byteLength; + } + get byteOffset() { + return 0; + } + constructor(param) { + if (typeof param === "number") { + this.buffer = new ArrayBuffer(param); + } + else { + if ((0, utils_1.isBufferSource)(param)) { + this.buffer = (0, utils_1.toArrayBuffer)(param); + } + else if (Array.isArray(param)) { + this.buffer = new Uint8Array(param).buffer; + } + else { + this.buffer = new ArrayBuffer(0); + } + } + } + fromASN(asn) { + if (!(asn instanceof asn1js.OctetString)) { + throw new TypeError("Argument 'asn' is not instance of ASN.1 OctetString"); + } + this.buffer = (0, utils_1.toArrayBuffer)(asn.valueBlock.valueHex); + return this; + } + toASN() { + return new asn1js.OctetString({ valueHex: this.buffer }); + } + toSchema(name) { + return new asn1js.OctetString({ name }); + } +} +exports.OctetString = OctetString; diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/convert.js b/node_modules/@peculiar/asn1-schema/build/es2015/convert.js new file mode 100644 index 0000000..c34b2f4 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/convert.js @@ -0,0 +1,20 @@ +import * as asn1js from "asn1js"; +import { isBufferSource, toArrayBuffer } from "@peculiar/utils"; +import { AsnParser } from "./parser"; +import { AsnSerializer } from "./serializer"; +export class AsnConvert { + static serialize(obj) { + return AsnSerializer.serialize(obj); + } + static parse(data, target, options) { + return AsnParser.parse(data, target, options); + } + static toString(data, options) { + const buf = isBufferSource(data) ? toArrayBuffer(data) : AsnConvert.serialize(data); + const asn = asn1js.fromBER(buf, options?.berOptions); + if (asn.offset === -1) { + throw new Error(`Cannot decode ASN.1 data. ${asn.result.error}`); + } + return asn.result.toString(); + } +} diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/converters.js b/node_modules/@peculiar/asn1-schema/build/es2015/converters.js new file mode 100644 index 0000000..5bce359 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/converters.js @@ -0,0 +1,143 @@ +import * as asn1js from "asn1js"; +import { toArrayBuffer } from "@peculiar/utils"; +import { AsnPropTypes } from "./enums"; +import { OctetString } from "./types/index"; +export const AsnAnyConverter = { + fromASN: (value) => (value instanceof asn1js.Null ? null : toArrayBuffer(value.valueBeforeDecodeView)), + toASN: (value) => { + if (value === null) { + return new asn1js.Null(); + } + const schema = asn1js.fromBER(value, { maxDepth: Infinity, maxNodes: Infinity, maxContentLength: Infinity }); + if (schema.result.error) { + throw new Error(schema.result.error); + } + return schema.result; + }, +}; +export const AsnIntegerConverter = { + fromASN: (value) => value.valueBlock.valueHexView.byteLength >= 4 + ? value.valueBlock.toString() + : value.valueBlock.valueDec, + toASN: (value) => new asn1js.Integer({ value: +value }), +}; +export const AsnEnumeratedConverter = { + fromASN: (value) => value.valueBlock.valueDec, + toASN: (value) => new asn1js.Enumerated({ value }), +}; +export const AsnIntegerArrayBufferConverter = { + fromASN: (value) => toArrayBuffer(value.valueBlock.valueHexView), + toASN: (value) => new asn1js.Integer({ valueHex: value }), +}; +export const AsnIntegerBigIntConverter = { + fromASN: (value) => value.toBigInt(), + toASN: (value) => asn1js.Integer.fromBigInt(value), +}; +export const AsnBitStringConverter = { + fromASN: (value) => toArrayBuffer(value.valueBlock.valueHexView), + toASN: (value) => new asn1js.BitString({ valueHex: value }), +}; +export const AsnObjectIdentifierConverter = { + fromASN: (value) => value.valueBlock.toString(), + toASN: (value) => new asn1js.ObjectIdentifier({ value }), +}; +export const AsnRelativeObjectIdentifierConverter = { + fromASN: (value) => value.valueBlock.toString(), + toASN: (value) => new asn1js.RelativeObjectIdentifier({ value }), +}; +export const AsnBooleanConverter = { + fromASN: (value) => value.valueBlock.value, + toASN: (value) => new asn1js.Boolean({ value }), +}; +export const AsnOctetStringConverter = { + fromASN: (value) => toArrayBuffer(value.valueBlock.valueHexView), + toASN: (value) => new asn1js.OctetString({ valueHex: value }), +}; +export const AsnConstructedOctetStringConverter = { + fromASN: (value) => new OctetString(value.getValue()), + toASN: (value) => value.toASN(), +}; +function createStringConverter(Asn1Type) { + return { + fromASN: (value) => value.valueBlock.value, + toASN: (value) => new Asn1Type({ value }), + }; +} +export const AsnUtf8StringConverter = createStringConverter(asn1js.Utf8String); +export const AsnBmpStringConverter = createStringConverter(asn1js.BmpString); +export const AsnUniversalStringConverter = createStringConverter(asn1js.UniversalString); +export const AsnNumericStringConverter = createStringConverter(asn1js.NumericString); +export const AsnPrintableStringConverter = createStringConverter(asn1js.PrintableString); +export const AsnTeletexStringConverter = createStringConverter(asn1js.TeletexString); +export const AsnVideotexStringConverter = createStringConverter(asn1js.VideotexString); +export const AsnIA5StringConverter = createStringConverter(asn1js.IA5String); +export const AsnGraphicStringConverter = createStringConverter(asn1js.GraphicString); +export const AsnVisibleStringConverter = createStringConverter(asn1js.VisibleString); +export const AsnGeneralStringConverter = createStringConverter(asn1js.GeneralString); +export const AsnCharacterStringConverter = createStringConverter(asn1js.CharacterString); +export const AsnUTCTimeConverter = { + fromASN: (value) => value.toDate(), + toASN: (value) => new asn1js.UTCTime({ valueDate: value }), +}; +export const AsnGeneralizedTimeConverter = { + fromASN: (value) => value.toDate(), + toASN: (value) => new asn1js.GeneralizedTime({ valueDate: value }), +}; +export const AsnNullConverter = { + fromASN: () => null, + toASN: () => { + return new asn1js.Null(); + }, +}; +export function defaultConverter(type) { + switch (type) { + case AsnPropTypes.Any: + return AsnAnyConverter; + case AsnPropTypes.BitString: + return AsnBitStringConverter; + case AsnPropTypes.BmpString: + return AsnBmpStringConverter; + case AsnPropTypes.Boolean: + return AsnBooleanConverter; + case AsnPropTypes.CharacterString: + return AsnCharacterStringConverter; + case AsnPropTypes.Enumerated: + return AsnEnumeratedConverter; + case AsnPropTypes.GeneralString: + return AsnGeneralStringConverter; + case AsnPropTypes.GeneralizedTime: + return AsnGeneralizedTimeConverter; + case AsnPropTypes.GraphicString: + return AsnGraphicStringConverter; + case AsnPropTypes.IA5String: + return AsnIA5StringConverter; + case AsnPropTypes.Integer: + return AsnIntegerConverter; + case AsnPropTypes.Null: + return AsnNullConverter; + case AsnPropTypes.NumericString: + return AsnNumericStringConverter; + case AsnPropTypes.ObjectIdentifier: + return AsnObjectIdentifierConverter; + case AsnPropTypes.RelativeObjectIdentifier: + return AsnRelativeObjectIdentifierConverter; + case AsnPropTypes.OctetString: + return AsnOctetStringConverter; + case AsnPropTypes.PrintableString: + return AsnPrintableStringConverter; + case AsnPropTypes.TeletexString: + return AsnTeletexStringConverter; + case AsnPropTypes.UTCTime: + return AsnUTCTimeConverter; + case AsnPropTypes.UniversalString: + return AsnUniversalStringConverter; + case AsnPropTypes.Utf8String: + return AsnUtf8StringConverter; + case AsnPropTypes.VideotexString: + return AsnVideotexStringConverter; + case AsnPropTypes.VisibleString: + return AsnVisibleStringConverter; + default: + return null; + } +} diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/decorators.js b/node_modules/@peculiar/asn1-schema/build/es2015/decorators.js new file mode 100644 index 0000000..0749659 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/decorators.js @@ -0,0 +1,43 @@ +import * as converters from "./converters"; +import { AsnTypeTypes } from "./enums"; +import { schemaStorage } from "./storage"; +export const AsnType = (options) => (target) => { + let schema; + if (!schemaStorage.has(target)) { + schema = schemaStorage.createDefault(target); + schemaStorage.set(target, schema); + } + else { + schema = schemaStorage.get(target); + } + Object.assign(schema, options); +}; +export const AsnChoiceType = () => AsnType({ type: AsnTypeTypes.Choice }); +export const AsnSetType = (options) => AsnType({ + type: AsnTypeTypes.Set, + ...options, +}); +export const AsnSequenceType = (options) => AsnType({ + type: AsnTypeTypes.Sequence, + ...options, +}); +export const AsnProp = (options) => (target, propertyKey) => { + let schema; + if (!schemaStorage.has(target.constructor)) { + schema = schemaStorage.createDefault(target.constructor); + schemaStorage.set(target.constructor, schema); + } + else { + schema = schemaStorage.get(target.constructor); + } + const copyOptions = Object.assign({}, options); + if (typeof copyOptions.type === "number" && !copyOptions.converter) { + const defaultConverter = converters.defaultConverter(options.type); + if (!defaultConverter) { + throw new Error(`Cannot get default converter for property '${propertyKey}' of ${target.constructor.name}`); + } + copyOptions.converter = defaultConverter; + } + copyOptions.raw = options.raw; + schema.items[propertyKey] = copyOptions; +}; diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/enums.js b/node_modules/@peculiar/asn1-schema/build/es2015/enums.js new file mode 100644 index 0000000..39e8d54 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/enums.js @@ -0,0 +1,37 @@ +export var AsnTypeTypes; +(function (AsnTypeTypes) { + AsnTypeTypes[AsnTypeTypes["Sequence"] = 0] = "Sequence"; + AsnTypeTypes[AsnTypeTypes["Set"] = 1] = "Set"; + AsnTypeTypes[AsnTypeTypes["Choice"] = 2] = "Choice"; +})(AsnTypeTypes || (AsnTypeTypes = {})); +export var AsnPropTypes; +(function (AsnPropTypes) { + AsnPropTypes[AsnPropTypes["Any"] = 1] = "Any"; + AsnPropTypes[AsnPropTypes["Boolean"] = 2] = "Boolean"; + AsnPropTypes[AsnPropTypes["OctetString"] = 3] = "OctetString"; + AsnPropTypes[AsnPropTypes["BitString"] = 4] = "BitString"; + AsnPropTypes[AsnPropTypes["Integer"] = 5] = "Integer"; + AsnPropTypes[AsnPropTypes["Enumerated"] = 6] = "Enumerated"; + AsnPropTypes[AsnPropTypes["ObjectIdentifier"] = 7] = "ObjectIdentifier"; + AsnPropTypes[AsnPropTypes["Utf8String"] = 8] = "Utf8String"; + AsnPropTypes[AsnPropTypes["BmpString"] = 9] = "BmpString"; + AsnPropTypes[AsnPropTypes["UniversalString"] = 10] = "UniversalString"; + AsnPropTypes[AsnPropTypes["NumericString"] = 11] = "NumericString"; + AsnPropTypes[AsnPropTypes["PrintableString"] = 12] = "PrintableString"; + AsnPropTypes[AsnPropTypes["TeletexString"] = 13] = "TeletexString"; + AsnPropTypes[AsnPropTypes["VideotexString"] = 14] = "VideotexString"; + AsnPropTypes[AsnPropTypes["IA5String"] = 15] = "IA5String"; + AsnPropTypes[AsnPropTypes["GraphicString"] = 16] = "GraphicString"; + AsnPropTypes[AsnPropTypes["VisibleString"] = 17] = "VisibleString"; + AsnPropTypes[AsnPropTypes["GeneralString"] = 18] = "GeneralString"; + AsnPropTypes[AsnPropTypes["CharacterString"] = 19] = "CharacterString"; + AsnPropTypes[AsnPropTypes["UTCTime"] = 20] = "UTCTime"; + AsnPropTypes[AsnPropTypes["GeneralizedTime"] = 21] = "GeneralizedTime"; + AsnPropTypes[AsnPropTypes["DATE"] = 22] = "DATE"; + AsnPropTypes[AsnPropTypes["TimeOfDay"] = 23] = "TimeOfDay"; + AsnPropTypes[AsnPropTypes["DateTime"] = 24] = "DateTime"; + AsnPropTypes[AsnPropTypes["Duration"] = 25] = "Duration"; + AsnPropTypes[AsnPropTypes["TIME"] = 26] = "TIME"; + AsnPropTypes[AsnPropTypes["Null"] = 27] = "Null"; + AsnPropTypes[AsnPropTypes["RelativeObjectIdentifier"] = 28] = "RelativeObjectIdentifier"; +})(AsnPropTypes || (AsnPropTypes = {})); diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/errors/index.js b/node_modules/@peculiar/asn1-schema/build/es2015/errors/index.js new file mode 100644 index 0000000..6edc538 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/errors/index.js @@ -0,0 +1 @@ +export * from "./schema_validation"; diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/errors/schema_validation.js b/node_modules/@peculiar/asn1-schema/build/es2015/errors/schema_validation.js new file mode 100644 index 0000000..e56df85 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/errors/schema_validation.js @@ -0,0 +1,3 @@ +export class AsnSchemaValidationError extends Error { + schemas = []; +} diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/helper.js b/node_modules/@peculiar/asn1-schema/build/es2015/helper.js new file mode 100644 index 0000000..0916f24 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/helper.js @@ -0,0 +1,39 @@ +export function isConvertible(target) { + if (typeof target === "function" && target.prototype) { + if (target.prototype.toASN && target.prototype.fromASN) { + return true; + } + else { + return isConvertible(target.prototype); + } + } + else { + return !!(target && typeof target === "object" && "toASN" in target && "fromASN" in target); + } +} +export function isTypeOfArray(target) { + if (target) { + const proto = Object.getPrototypeOf(target); + if (proto?.prototype?.constructor === Array) { + return true; + } + return isTypeOfArray(proto); + } + return false; +} +export function isArrayEqual(bytes1, bytes2) { + if (!(bytes1 && bytes2)) { + return false; + } + if (bytes1.byteLength !== bytes2.byteLength) { + return false; + } + const b1 = new Uint8Array(bytes1); + const b2 = new Uint8Array(bytes2); + for (let i = 0; i < bytes1.byteLength; i++) { + if (b1[i] !== b2[i]) { + return false; + } + } + return true; +} diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/index.js b/node_modules/@peculiar/asn1-schema/build/es2015/index.js new file mode 100644 index 0000000..1c0049e --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/index.js @@ -0,0 +1,9 @@ +export * from "./converters"; +export * from "./types/index"; +export { AsnProp, AsnType, AsnChoiceType, AsnSequenceType, AsnSetType } from "./decorators"; +export { AsnTypeTypes, AsnPropTypes } from "./enums"; +export { AsnParser } from "./parser"; +export { AsnSerializer } from "./serializer"; +export * from "./errors"; +export * from "./objects"; +export * from "./convert"; diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/objects.js b/node_modules/@peculiar/asn1-schema/build/es2015/objects.js new file mode 100644 index 0000000..b858c74 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/objects.js @@ -0,0 +1,13 @@ +export class AsnArray extends Array { + constructor(items = []) { + if (typeof items === "number") { + super(items); + } + else { + super(); + for (const item of items) { + this.push(item); + } + } + } +} diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/parser.js b/node_modules/@peculiar/asn1-schema/build/es2015/parser.js new file mode 100644 index 0000000..0ab3d64 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/parser.js @@ -0,0 +1,308 @@ +import * as asn1js from "asn1js"; +import { toArrayBuffer } from "@peculiar/utils"; +import { AsnPropTypes, AsnTypeTypes } from "./enums"; +import * as converters from "./converters"; +import { AsnSchemaValidationError } from "./errors"; +import { isConvertible, isTypeOfArray } from "./helper"; +import { schemaStorage } from "./storage"; +export class AsnParser { + static parse(data, target, options) { + const asn1Parsed = asn1js.fromBER(toArrayBuffer(data), options?.berOptions); + if (asn1Parsed.result.error) { + throw new Error(asn1Parsed.result.error); + } + const res = this.fromASN(asn1Parsed.result, target, options); + return res; + } + static fromASN(asn1Schema, target, options) { + try { + if (isConvertible(target)) { + const value = new target(); + return value.fromASN(asn1Schema); + } + const schema = schemaStorage.get(target); + schemaStorage.cache(target); + let targetSchema = schema.schema; + const choiceResult = this.handleChoiceTypes(asn1Schema, schema, target, targetSchema, options); + if (choiceResult?.result) { + return choiceResult.result; + } + if (choiceResult?.targetSchema) { + targetSchema = choiceResult.targetSchema; + } + const sequenceResult = this.handleSequenceTypes(asn1Schema, schema, target, targetSchema); + const res = new target(); + if (isTypeOfArray(target)) { + return this.handleArrayTypes(asn1Schema, schema, target, options); + } + this.processSchemaItems(schema, sequenceResult, res, options); + return res; + } + catch (error) { + if (error instanceof AsnSchemaValidationError) { + error.schemas.push(target.name); + } + throw error; + } + } + static handleChoiceTypes(asn1Schema, schema, target, targetSchema, options) { + if (asn1Schema.constructor === asn1js.Constructed && schema.type === AsnTypeTypes.Choice && asn1Schema.idBlock.tagClass === 3) { + for (const key in schema.items) { + const schemaItem = schema.items[key]; + if (schemaItem.context === asn1Schema.idBlock.tagNumber && schemaItem.implicit) { + if (typeof schemaItem.type === "function" && schemaStorage.has(schemaItem.type)) { + const fieldSchema = schemaStorage.get(schemaItem.type); + if (fieldSchema && fieldSchema.type === AsnTypeTypes.Sequence) { + const newSeq = new asn1js.Sequence(); + if ("value" in asn1Schema.valueBlock && Array.isArray(asn1Schema.valueBlock.value) && "value" in newSeq.valueBlock) { + newSeq.valueBlock.value = asn1Schema.valueBlock.value; + const fieldValue = this.fromASN(newSeq, schemaItem.type, options); + const res = new target(); + res[key] = fieldValue; + return { result: res }; + } + } + } + } + } + } + else if (asn1Schema.constructor === asn1js.Constructed && schema.type !== AsnTypeTypes.Choice) { + const newTargetSchema = new asn1js.Constructed({ + idBlock: { + tagClass: 3, + tagNumber: asn1Schema.idBlock.tagNumber, + }, + value: schema.schema.valueBlock.value, + }); + for (const key in schema.items) { + delete asn1Schema[key]; + } + return { targetSchema: newTargetSchema }; + } + return null; + } + static handleSequenceTypes(asn1Schema, schema, target, targetSchema) { + if (schema.type === AsnTypeTypes.Sequence) { + const asn1ComparedSchema = asn1js.compareSchema({}, asn1Schema, targetSchema); + if (!asn1ComparedSchema.verified) { + throw new AsnSchemaValidationError(`Data does not match to ${target.name} ASN1 schema.${asn1ComparedSchema.result.error ? ` ${asn1ComparedSchema.result.error}` : ""}`); + } + return asn1ComparedSchema; + } + else { + const asn1ComparedSchema = asn1js.compareSchema({}, asn1Schema, targetSchema); + if (!asn1ComparedSchema.verified) { + throw new AsnSchemaValidationError(`Data does not match to ${target.name} ASN1 schema.${asn1ComparedSchema.result.error ? ` ${asn1ComparedSchema.result.error}` : ""}`); + } + return asn1ComparedSchema; + } + } + static processRepeatedField(asn1Elements, asn1Index, schemaItem) { + let elementsToProcess = asn1Elements.slice(asn1Index); + if (elementsToProcess.length === 1 && elementsToProcess[0].constructor.name === "Sequence") { + const seq = elementsToProcess[0]; + if (seq.valueBlock && seq.valueBlock.value && Array.isArray(seq.valueBlock.value)) { + elementsToProcess = seq.valueBlock.value; + } + } + if (typeof schemaItem.type === "number") { + const converter = converters.defaultConverter(schemaItem.type); + if (!converter) + throw new Error(`No converter for ASN.1 type ${schemaItem.type}`); + return elementsToProcess + .filter((el) => el && el.valueBlock) + .map((el) => { + try { + return converter.fromASN(el); + } + catch { + return undefined; + } + }) + .filter((v) => v !== undefined); + } + else { + return elementsToProcess + .filter((el) => el && el.valueBlock) + .map((el) => { + try { + return this.fromASN(el, schemaItem.type); + } + catch { + return undefined; + } + }) + .filter((v) => v !== undefined); + } + } + static processPrimitiveField(asn1Element, schemaItem) { + const converter = converters.defaultConverter(schemaItem.type); + if (!converter) + throw new Error(`No converter for ASN.1 type ${schemaItem.type}`); + return converter.fromASN(asn1Element); + } + static isOptionalChoiceField(schemaItem) { + return (schemaItem.optional && + typeof schemaItem.type === "function" && + schemaStorage.has(schemaItem.type) && + schemaStorage.get(schemaItem.type).type === AsnTypeTypes.Choice); + } + static processOptionalChoiceField(asn1Element, schemaItem) { + try { + const value = this.fromASN(asn1Element, schemaItem.type); + return { + processed: true, + value, + }; + } + catch (err) { + if (err instanceof AsnSchemaValidationError && /Wrong values for Choice type/.test(err.message)) { + return { processed: false }; + } + throw err; + } + } + static handleArrayTypes(asn1Schema, schema, target, options) { + if (!("value" in asn1Schema.valueBlock && Array.isArray(asn1Schema.valueBlock.value))) { + throw new Error("Cannot get items from the ASN.1 parsed value. ASN.1 object is not constructed."); + } + const itemType = schema.itemType; + if (typeof itemType === "number") { + const converter = converters.defaultConverter(itemType); + if (!converter) { + throw new Error(`Cannot get default converter for array item of ${target.name} ASN1 schema`); + } + return target.from(asn1Schema.valueBlock.value, (element) => converter.fromASN(element)); + } + else { + return target.from(asn1Schema.valueBlock.value, (element) => this.fromASN(element, itemType, options)); + } + } + static processSchemaItems(schema, asn1ComparedSchema, res, options) { + for (const key in schema.items) { + const asn1SchemaValue = asn1ComparedSchema.result[key]; + if (!asn1SchemaValue) { + continue; + } + const schemaItem = schema.items[key]; + const schemaItemType = schemaItem.type; + let parsedValue; + if (typeof schemaItemType === "number" || isConvertible(schemaItemType)) { + parsedValue = this.processPrimitiveSchemaItem(asn1SchemaValue, schemaItem, schemaItemType, options); + } + else { + parsedValue = this.processComplexSchemaItem(asn1SchemaValue, schemaItem, schemaItemType, options); + } + if (parsedValue && typeof parsedValue === "object" && "value" in parsedValue && "raw" in parsedValue) { + res[key] = parsedValue.value; + res[`${key}Raw`] = parsedValue.raw; + } + else { + res[key] = parsedValue; + } + } + } + static processPrimitiveSchemaItem(asn1SchemaValue, schemaItem, schemaItemType, options) { + const converter = schemaItem.converter ?? (isConvertible(schemaItemType) ? new schemaItemType() : null); + if (!converter) { + throw new Error("Converter is empty"); + } + if (schemaItem.repeated) { + return this.processRepeatedPrimitiveItem(asn1SchemaValue, schemaItem, converter, options); + } + else { + return this.processSinglePrimitiveItem(asn1SchemaValue, schemaItem, schemaItemType, converter, options); + } + } + static processRepeatedPrimitiveItem(asn1SchemaValue, schemaItem, converter, options) { + if (schemaItem.implicit) { + const Container = schemaItem.repeated === "sequence" ? asn1js.Sequence : asn1js.Set; + const newItem = new Container(); + newItem.valueBlock = asn1SchemaValue.valueBlock; + const newItemAsn = asn1js.fromBER(newItem.toBER(false), options?.berOptions); + if (newItemAsn.offset === -1) { + throw new Error(`Cannot parse the child item. ${newItemAsn.result.error}`); + } + if (!("value" in newItemAsn.result.valueBlock && Array.isArray(newItemAsn.result.valueBlock.value))) { + throw new Error("Cannot get items from the ASN.1 parsed value. ASN.1 object is not constructed."); + } + const value = newItemAsn.result.valueBlock.value; + return Array.from(value, (element) => converter.fromASN(element)); + } + else { + return Array.from(asn1SchemaValue, (element) => converter.fromASN(element)); + } + } + static processSinglePrimitiveItem(asn1SchemaValue, schemaItem, schemaItemType, converter, options) { + let value = asn1SchemaValue; + if (schemaItem.implicit) { + let newItem; + if (isConvertible(schemaItemType)) { + newItem = new schemaItemType().toSchema(""); + } + else { + const Asn1TypeName = AsnPropTypes[schemaItemType]; + const Asn1Type = asn1js[Asn1TypeName]; + if (!Asn1Type) { + throw new Error(`Cannot get '${Asn1TypeName}' class from asn1js module`); + } + newItem = new Asn1Type(); + } + newItem.valueBlock = value.valueBlock; + value = asn1js.fromBER(newItem.toBER(false), options?.berOptions).result; + } + return converter.fromASN(value); + } + static processComplexSchemaItem(asn1SchemaValue, schemaItem, schemaItemType, options) { + if (schemaItem.repeated) { + if (!Array.isArray(asn1SchemaValue)) { + throw new Error("Cannot get list of items from the ASN.1 parsed value. ASN.1 value should be iterable."); + } + return Array.from(asn1SchemaValue, (element) => this.fromASN(element, schemaItemType, options)); + } + else { + const valueToProcess = this.handleImplicitTagging(asn1SchemaValue, schemaItem, schemaItemType); + if (this.isOptionalChoiceField(schemaItem)) { + try { + return this.fromASN(valueToProcess, schemaItemType, options); + } + catch (err) { + if (err instanceof AsnSchemaValidationError && /Wrong values for Choice type/.test(err.message)) { + return undefined; + } + throw err; + } + } + else { + const parsedValue = this.fromASN(valueToProcess, schemaItemType, options); + if (schemaItem.raw) { + return { + value: parsedValue, + raw: asn1SchemaValue.valueBeforeDecodeView, + }; + } + return parsedValue; + } + } + } + static handleImplicitTagging(asn1SchemaValue, schemaItem, schemaItemType) { + if (schemaItem.implicit && typeof schemaItem.context === "number") { + const schema = schemaStorage.get(schemaItemType); + if (schema.type === AsnTypeTypes.Sequence) { + const newSeq = new asn1js.Sequence(); + if ("value" in asn1SchemaValue.valueBlock && Array.isArray(asn1SchemaValue.valueBlock.value) && "value" in newSeq.valueBlock) { + newSeq.valueBlock.value = asn1SchemaValue.valueBlock.value; + return newSeq; + } + } + else if (schema.type === AsnTypeTypes.Set) { + const newSet = new asn1js.Set(); + if ("value" in asn1SchemaValue.valueBlock && Array.isArray(asn1SchemaValue.valueBlock.value) && "value" in newSet.valueBlock) { + newSet.valueBlock.value = asn1SchemaValue.valueBlock.value; + return newSet; + } + } + } + return asn1SchemaValue; + } +} diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/schema.js b/node_modules/@peculiar/asn1-schema/build/es2015/schema.js new file mode 100644 index 0000000..08953f1 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/schema.js @@ -0,0 +1,160 @@ +import * as asn1js from "asn1js"; +import { AsnPropTypes, AsnTypeTypes } from "./enums"; +import { isConvertible } from "./helper"; +export class AsnSchemaStorage { + items = new WeakMap(); + has(target) { + return this.items.has(target); + } + get(target, checkSchema = false) { + const schema = this.items.get(target); + if (!schema) { + throw new Error(`Cannot get schema for '${target.prototype.constructor.name}' target`); + } + if (checkSchema && !schema.schema) { + throw new Error(`Schema '${target.prototype.constructor.name}' doesn't contain ASN.1 schema. Call 'AsnSchemaStorage.cache'.`); + } + return schema; + } + cache(target) { + const schema = this.get(target); + if (!schema.schema) { + schema.schema = this.create(target, true); + } + } + createDefault(target) { + const schema = { + type: AsnTypeTypes.Sequence, + items: {}, + }; + const parentSchema = this.findParentSchema(target); + if (parentSchema) { + Object.assign(schema, parentSchema); + schema.items = Object.assign({}, schema.items, parentSchema.items); + } + return schema; + } + create(target, useNames) { + const schema = this.items.get(target) || this.createDefault(target); + const asn1Value = []; + for (const key in schema.items) { + const item = schema.items[key]; + const name = useNames ? key : ""; + let asn1Item; + if (typeof item.type === "number") { + const Asn1TypeName = AsnPropTypes[item.type]; + const Asn1Type = asn1js[Asn1TypeName]; + if (!Asn1Type) { + throw new Error(`Cannot get ASN1 class by name '${Asn1TypeName}'`); + } + asn1Item = new Asn1Type({ name }); + } + else if (isConvertible(item.type)) { + const instance = new item.type(); + asn1Item = instance.toSchema(name); + } + else if (item.optional) { + const itemSchema = this.get(item.type); + if (itemSchema.type === AsnTypeTypes.Choice) { + asn1Item = new asn1js.Any({ name }); + } + else { + asn1Item = this.create(item.type, false); + asn1Item.name = name; + } + } + else { + asn1Item = new asn1js.Any({ name }); + } + const optional = !!item.optional || item.defaultValue !== undefined; + if (item.repeated) { + asn1Item.name = ""; + const Container = item.repeated === "set" ? asn1js.Set : asn1js.Sequence; + asn1Item = new Container({ + name: "", + value: [ + new asn1js.Repeated({ + name, + value: asn1Item, + }), + ], + }); + } + if (item.context !== null && item.context !== undefined) { + if (item.implicit) { + if (typeof item.type === "number" || isConvertible(item.type)) { + const Container = item.repeated ? asn1js.Constructed : asn1js.Primitive; + asn1Value.push(new Container({ + name, + optional, + idBlock: { + tagClass: 3, + tagNumber: item.context, + }, + })); + } + else { + this.cache(item.type); + const isRepeated = !!item.repeated; + let value = !isRepeated ? this.get(item.type, true).schema : asn1Item; + value = "valueBlock" in value ? value.valueBlock.value : value.value; + asn1Value.push(new asn1js.Constructed({ + name: !isRepeated ? name : "", + optional, + idBlock: { + tagClass: 3, + tagNumber: item.context, + }, + value: value, + })); + } + } + else { + asn1Value.push(new asn1js.Constructed({ + optional, + idBlock: { + tagClass: 3, + tagNumber: item.context, + }, + value: [asn1Item], + })); + } + } + else { + asn1Item.optional = optional; + asn1Value.push(asn1Item); + } + } + switch (schema.type) { + case AsnTypeTypes.Sequence: + return new asn1js.Sequence({ + value: asn1Value, + name: "", + }); + case AsnTypeTypes.Set: + return new asn1js.Set({ + value: asn1Value, + name: "", + }); + case AsnTypeTypes.Choice: + return new asn1js.Choice({ + value: asn1Value, + name: "", + }); + default: + throw new Error("Unsupported ASN1 type in use"); + } + } + set(target, schema) { + this.items.set(target, schema); + return this; + } + findParentSchema(target) { + const parent = Object.getPrototypeOf(target); + if (parent) { + const schema = this.items.get(parent); + return schema || this.findParentSchema(parent); + } + return null; + } +} diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/serializer.js b/node_modules/@peculiar/asn1-schema/build/es2015/serializer.js new file mode 100644 index 0000000..e38927f --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/serializer.js @@ -0,0 +1,145 @@ +import * as asn1js from "asn1js"; +import { toArrayBuffer } from "@peculiar/utils"; +import * as converters from "./converters"; +import { AsnPropTypes, AsnTypeTypes } from "./enums"; +import { isConvertible, isArrayEqual } from "./helper"; +import { schemaStorage } from "./storage"; +export class AsnSerializer { + static serialize(obj) { + if (obj instanceof asn1js.BaseBlock) { + return obj.toBER(false); + } + return this.toASN(obj).toBER(false); + } + static toASN(obj) { + if (obj && typeof obj === "object" && isConvertible(obj)) { + return obj.toASN(); + } + if (!(obj && typeof obj === "object")) { + throw new TypeError("Parameter 1 should be type of Object."); + } + const target = obj.constructor; + const schema = schemaStorage.get(target); + schemaStorage.cache(target); + let asn1Value = []; + if (schema.itemType) { + if (!Array.isArray(obj)) { + throw new TypeError("Parameter 1 should be type of Array."); + } + if (typeof schema.itemType === "number") { + const converter = converters.defaultConverter(schema.itemType); + if (!converter) { + throw new Error(`Cannot get default converter for array item of ${target.name} ASN1 schema`); + } + asn1Value = obj.map((o) => converter.toASN(o)); + } + else { + asn1Value = obj.map((o) => this.toAsnItem({ type: schema.itemType }, "[]", target, o)); + } + } + else { + for (const key in schema.items) { + const schemaItem = schema.items[key]; + const objProp = obj[key]; + if (objProp === undefined || + schemaItem.defaultValue === objProp || + (typeof schemaItem.defaultValue === "object" && typeof objProp === "object" && isArrayEqual(this.serialize(schemaItem.defaultValue), this.serialize(objProp)))) { + continue; + } + const asn1Item = AsnSerializer.toAsnItem(schemaItem, key, target, objProp); + if (typeof schemaItem.context === "number") { + if (schemaItem.implicit) { + if (!schemaItem.repeated && (typeof schemaItem.type === "number" || isConvertible(schemaItem.type))) { + const value = {}; + value.valueHex = asn1Item instanceof asn1js.Null ? toArrayBuffer(asn1Item.valueBeforeDecodeView) : asn1Item.valueBlock.toBER(); + asn1Value.push(new asn1js.Primitive({ + optional: schemaItem.optional, + idBlock: { + tagClass: 3, + tagNumber: schemaItem.context, + }, + ...value, + })); + } + else { + asn1Value.push(new asn1js.Constructed({ + optional: schemaItem.optional, + idBlock: { + tagClass: 3, + tagNumber: schemaItem.context, + }, + value: asn1Item.valueBlock.value, + })); + } + } + else { + asn1Value.push(new asn1js.Constructed({ + optional: schemaItem.optional, + idBlock: { + tagClass: 3, + tagNumber: schemaItem.context, + }, + value: [asn1Item], + })); + } + } + else if (schemaItem.repeated) { + asn1Value = asn1Value.concat(asn1Item); + } + else { + asn1Value.push(asn1Item); + } + } + } + let asnSchema; + switch (schema.type) { + case AsnTypeTypes.Sequence: + asnSchema = new asn1js.Sequence({ value: asn1Value }); + break; + case AsnTypeTypes.Set: + asnSchema = new asn1js.Set({ value: asn1Value }); + break; + case AsnTypeTypes.Choice: + if (!asn1Value[0]) { + throw new Error(`Schema '${target.name}' has wrong data. Choice cannot be empty.`); + } + asnSchema = asn1Value[0]; + break; + } + return asnSchema; + } + static toAsnItem(schemaItem, key, target, objProp) { + let asn1Item; + if (typeof schemaItem.type === "number") { + const converter = schemaItem.converter; + if (!converter) { + throw new Error(`Property '${key}' doesn't have converter for type ${AsnPropTypes[schemaItem.type]} in schema '${target.name}'`); + } + if (schemaItem.repeated) { + if (!Array.isArray(objProp)) { + throw new TypeError("Parameter 'objProp' should be type of Array."); + } + const items = Array.from(objProp, (element) => converter.toASN(element)); + const Container = schemaItem.repeated === "sequence" ? asn1js.Sequence : asn1js.Set; + asn1Item = new Container({ value: items }); + } + else { + asn1Item = converter.toASN(objProp); + } + } + else { + if (schemaItem.repeated) { + if (!Array.isArray(objProp)) { + throw new TypeError("Parameter 'objProp' should be type of Array."); + } + const items = Array.from(objProp, (element) => this.toASN(element)); + const Container = schemaItem.repeated === "sequence" ? asn1js.Sequence : asn1js.Set; + asn1Item = new Container({ value: items }); + } + else { + asn1Item = this.toASN(objProp); + } + } + return asn1Item; + } +} diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/storage.js b/node_modules/@peculiar/asn1-schema/build/es2015/storage.js new file mode 100644 index 0000000..5379efd --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/storage.js @@ -0,0 +1,2 @@ +import { AsnSchemaStorage } from "./schema"; +export const schemaStorage = new AsnSchemaStorage(); diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/types.js b/node_modules/@peculiar/asn1-schema/build/es2015/types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/types.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/types/bit_string.js b/node_modules/@peculiar/asn1-schema/build/es2015/types/bit_string.js new file mode 100644 index 0000000..fd1902d --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/types/bit_string.js @@ -0,0 +1,66 @@ +import * as asn1js from "asn1js"; +import { isBufferSource, toArrayBuffer } from "@peculiar/utils"; +export class BitString { + unusedBits = 0; + value = new ArrayBuffer(0); + constructor(params, unusedBits = 0) { + if (params) { + if (typeof params === "number") { + this.fromNumber(params); + } + else if (isBufferSource(params)) { + this.unusedBits = unusedBits; + this.value = toArrayBuffer(params); + } + else { + throw TypeError("Unsupported type of 'params' argument for BitString"); + } + } + } + fromASN(asn) { + if (!(asn instanceof asn1js.BitString)) { + throw new TypeError("Argument 'asn' is not instance of ASN.1 BitString"); + } + this.unusedBits = asn.valueBlock.unusedBits; + this.value = toArrayBuffer(asn.valueBlock.valueHex); + return this; + } + toASN() { + return new asn1js.BitString({ + unusedBits: this.unusedBits, + valueHex: this.value, + }); + } + toSchema(name) { + return new asn1js.BitString({ name }); + } + toNumber() { + let res = ""; + const uintArray = new Uint8Array(this.value); + for (const octet of uintArray) { + res += octet.toString(2).padStart(8, "0"); + } + res = res.split("").reverse().join(""); + if (this.unusedBits) { + res = res.slice(this.unusedBits).padStart(this.unusedBits, "0"); + } + return parseInt(res, 2); + } + fromNumber(value) { + let bits = value.toString(2); + const octetSize = (bits.length + 7) >> 3; + this.unusedBits = (octetSize << 3) - bits.length; + const octets = new Uint8Array(octetSize); + bits = bits + .padStart(octetSize << 3, "0") + .split("") + .reverse() + .join(""); + let index = 0; + while (index < octetSize) { + octets[index] = parseInt(bits.slice(index << 3, (index << 3) + 8), 2); + index++; + } + this.value = octets.buffer; + } +} diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/types/index.js b/node_modules/@peculiar/asn1-schema/build/es2015/types/index.js new file mode 100644 index 0000000..28ceb71 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/types/index.js @@ -0,0 +1,2 @@ +export * from "./bit_string"; +export * from "./octet_string"; diff --git a/node_modules/@peculiar/asn1-schema/build/es2015/types/octet_string.js b/node_modules/@peculiar/asn1-schema/build/es2015/types/octet_string.js new file mode 100644 index 0000000..2d04aa3 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/es2015/types/octet_string.js @@ -0,0 +1,40 @@ +import * as asn1js from "asn1js"; +import { isBufferSource, toArrayBuffer } from "@peculiar/utils"; +export class OctetString { + buffer; + get byteLength() { + return this.buffer.byteLength; + } + get byteOffset() { + return 0; + } + constructor(param) { + if (typeof param === "number") { + this.buffer = new ArrayBuffer(param); + } + else { + if (isBufferSource(param)) { + this.buffer = toArrayBuffer(param); + } + else if (Array.isArray(param)) { + this.buffer = new Uint8Array(param).buffer; + } + else { + this.buffer = new ArrayBuffer(0); + } + } + } + fromASN(asn) { + if (!(asn instanceof asn1js.OctetString)) { + throw new TypeError("Argument 'asn' is not instance of ASN.1 OctetString"); + } + this.buffer = toArrayBuffer(asn.valueBlock.valueHex); + return this; + } + toASN() { + return new asn1js.OctetString({ valueHex: this.buffer }); + } + toSchema(name) { + return new asn1js.OctetString({ name }); + } +} diff --git a/node_modules/@peculiar/asn1-schema/build/types/convert.d.ts b/node_modules/@peculiar/asn1-schema/build/types/convert.d.ts new file mode 100644 index 0000000..670ea0c --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/convert.d.ts @@ -0,0 +1,20 @@ +import { type BufferSourceLike } from "@peculiar/utils"; +import { IEmptyConstructor, IAsnParseOptions } from "./types"; +export declare class AsnConvert { + static serialize(obj: unknown): ArrayBuffer; + static parse(data: BufferSourceLike, target: IEmptyConstructor, options?: IAsnParseOptions): T; + /** + * Returns a string representation of an ASN.1 encoded data + * @param data ASN.1 encoded buffer source + * @param options Optional parsing options forwarded to `asn1js.fromBER` + * @returns String representation of ASN.1 structure + */ + static toString(data: BufferSourceLike, options?: IAsnParseOptions): string; + /** + * Returns a string representation of an ASN.1 schema + * @param obj Object which can be serialized to ASN.1 schema + * @param options Optional parsing options forwarded to `asn1js.fromBER` + * @returns String representation of ASN.1 structure + */ + static toString(obj: unknown, options?: IAsnParseOptions): string; +} diff --git a/node_modules/@peculiar/asn1-schema/build/types/converters.d.ts b/node_modules/@peculiar/asn1-schema/build/types/converters.d.ts new file mode 100644 index 0000000..6f487c5 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/converters.d.ts @@ -0,0 +1,117 @@ +import * as asn1js from "asn1js"; +import { AnyConverterType, IAsnConverter, IntegerConverterType } from "./types"; +import { AsnPropTypes } from "./enums"; +import { OctetString } from "./types/index"; +/** + * NOTE: Converter MUST have name AsnConverter. + * Asn1Prop decorator link custom converters by name of the Asn1PropType + */ +/** + * ASN.1 ANY converter + */ +export declare const AsnAnyConverter: IAsnConverter; +/** + * ASN.1 INTEGER to Number/String converter + */ +export declare const AsnIntegerConverter: IAsnConverter; +/** + * ASN.1 ENUMERATED converter + */ +export declare const AsnEnumeratedConverter: IAsnConverter; +/** + * ASN.1 INTEGER to ArrayBuffer converter + */ +export declare const AsnIntegerArrayBufferConverter: IAsnConverter; +/** + * ASN.1 INTEGER to BigInt converter + */ +export declare const AsnIntegerBigIntConverter: IAsnConverter; +/** + * ASN.1 BIT STRING converter + */ +export declare const AsnBitStringConverter: IAsnConverter; +/** + * ASN.1 OBJECT IDENTIFIER converter + */ +export declare const AsnObjectIdentifierConverter: IAsnConverter; +/** + * ASN.1 RELATIVE OBJECT IDENTIFIER converter + */ +export declare const AsnRelativeObjectIdentifierConverter: IAsnConverter; +/** + * ASN.1 BOOLEAN converter + */ +export declare const AsnBooleanConverter: IAsnConverter; +/** + * ASN.1 OCTET_STRING converter + */ +export declare const AsnOctetStringConverter: IAsnConverter; +/** + * ASN.1 OCTET_STRING converter to OctetString class + */ +export declare const AsnConstructedOctetStringConverter: IAsnConverter; +/** + * ASN.1 UTF8_STRING converter + */ +export declare const AsnUtf8StringConverter: IAsnConverter; +/** + * ASN.1 BPM STRING converter + */ +export declare const AsnBmpStringConverter: IAsnConverter; +/** + * ASN.1 UNIVERSAL STRING converter + */ +export declare const AsnUniversalStringConverter: IAsnConverter; +/** + * ASN.1 NUMERIC STRING converter + */ +export declare const AsnNumericStringConverter: IAsnConverter; +/** + * ASN.1 PRINTABLE STRING converter + */ +export declare const AsnPrintableStringConverter: IAsnConverter; +/** + * ASN.1 TELETEX STRING converter + */ +export declare const AsnTeletexStringConverter: IAsnConverter; +/** + * ASN.1 VIDEOTEX STRING converter + */ +export declare const AsnVideotexStringConverter: IAsnConverter; +/** + * ASN.1 IA5 STRING converter + */ +export declare const AsnIA5StringConverter: IAsnConverter; +/** + * ASN.1 GRAPHIC STRING converter + */ +export declare const AsnGraphicStringConverter: IAsnConverter; +/** + * ASN.1 VISIBLE STRING converter + */ +export declare const AsnVisibleStringConverter: IAsnConverter; +/** + * ASN.1 GENERAL STRING converter + */ +export declare const AsnGeneralStringConverter: IAsnConverter; +/** + * ASN.1 CHARACTER STRING converter + */ +export declare const AsnCharacterStringConverter: IAsnConverter; +/** + * ASN.1 UTCTime converter + */ +export declare const AsnUTCTimeConverter: IAsnConverter; +/** + * ASN.1 GeneralizedTime converter + */ +export declare const AsnGeneralizedTimeConverter: IAsnConverter; +/** + * ASN.1 ANY converter + */ +export declare const AsnNullConverter: IAsnConverter; +/** + * Returns default converter for specified type + * @param type + */ +export declare function defaultConverter(type: AsnPropTypes): IAsnConverter | null; diff --git a/node_modules/@peculiar/asn1-schema/build/types/decorators.d.ts b/node_modules/@peculiar/asn1-schema/build/types/decorators.d.ts new file mode 100644 index 0000000..b5193de --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/decorators.d.ts @@ -0,0 +1,36 @@ +import { AsnPropTypes, AsnTypeTypes } from "./enums"; +import { IAsnConverter, IEmptyConstructor } from "./types"; +export type AsnItemType = AsnPropTypes | IEmptyConstructor; +export interface IAsn1TypeOptions { + type: AsnTypeTypes; + itemType?: AsnItemType; +} +export type AsnRepeatTypeString = "sequence" | "set"; +export type AsnRepeatType = AsnRepeatTypeString; +export interface IAsn1PropOptions { + type: AsnItemType; + optional?: boolean; + defaultValue?: unknown; + context?: number; + implicit?: boolean; + converter?: IAsnConverter; + repeated?: AsnRepeatType; + /** + * If true, the raw ASN.1 encoded bytes of the property will be stored in a separate property + * with 'Raw' suffix. + */ + raw?: boolean; +} +export type AsnTypeDecorator = (target: IEmptyConstructor) => void; +export declare const AsnType: (options: IAsn1TypeOptions) => AsnTypeDecorator; +export declare const AsnChoiceType: () => AsnTypeDecorator; +export interface IAsn1SetOptions { + itemType: AsnItemType; +} +export declare const AsnSetType: (options: IAsn1SetOptions) => AsnTypeDecorator; +export interface IAsn1SequenceOptions { + itemType?: AsnItemType; +} +export declare const AsnSequenceType: (options: IAsn1SequenceOptions) => AsnTypeDecorator; +export type AsnPropDecorator = (target: object, propertyKey: string) => void; +export declare const AsnProp: (options: IAsn1PropOptions) => AsnPropDecorator; diff --git a/node_modules/@peculiar/asn1-schema/build/types/enums.d.ts b/node_modules/@peculiar/asn1-schema/build/types/enums.d.ts new file mode 100644 index 0000000..9cf3de6 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/enums.d.ts @@ -0,0 +1,41 @@ +/** + * ASN.1 types for classes + */ +export declare enum AsnTypeTypes { + Sequence = 0, + Set = 1, + Choice = 2 +} +/** + * ASN.1 types for properties + */ +export declare enum AsnPropTypes { + Any = 1, + Boolean = 2, + OctetString = 3, + BitString = 4, + Integer = 5, + Enumerated = 6, + ObjectIdentifier = 7, + Utf8String = 8, + BmpString = 9, + UniversalString = 10, + NumericString = 11, + PrintableString = 12, + TeletexString = 13, + VideotexString = 14, + IA5String = 15, + GraphicString = 16, + VisibleString = 17, + GeneralString = 18, + CharacterString = 19, + UTCTime = 20, + GeneralizedTime = 21, + DATE = 22, + TimeOfDay = 23, + DateTime = 24, + Duration = 25, + TIME = 26, + Null = 27, + RelativeObjectIdentifier = 28 +} diff --git a/node_modules/@peculiar/asn1-schema/build/types/errors/index.d.ts b/node_modules/@peculiar/asn1-schema/build/types/errors/index.d.ts new file mode 100644 index 0000000..6edc538 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/errors/index.d.ts @@ -0,0 +1 @@ +export * from "./schema_validation"; diff --git a/node_modules/@peculiar/asn1-schema/build/types/errors/schema_validation.d.ts b/node_modules/@peculiar/asn1-schema/build/types/errors/schema_validation.d.ts new file mode 100644 index 0000000..81de5ad --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/errors/schema_validation.d.ts @@ -0,0 +1,3 @@ +export declare class AsnSchemaValidationError extends Error { + schemas: string[]; +} diff --git a/node_modules/@peculiar/asn1-schema/build/types/helper.d.ts b/node_modules/@peculiar/asn1-schema/build/types/helper.d.ts new file mode 100644 index 0000000..4cf2baf --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/helper.d.ts @@ -0,0 +1,5 @@ +import { IAsnConvertible, IEmptyConstructor } from "./types"; +export declare function isConvertible(target: IEmptyConstructor): target is new () => IAsnConvertible; +export declare function isConvertible(target: unknown): target is IAsnConvertible; +export declare function isTypeOfArray(target: unknown): target is typeof Array; +export declare function isArrayEqual(bytes1: ArrayBuffer, bytes2: ArrayBuffer): boolean; diff --git a/node_modules/@peculiar/asn1-schema/build/types/index.d.ts b/node_modules/@peculiar/asn1-schema/build/types/index.d.ts new file mode 100644 index 0000000..5741fa2 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/index.d.ts @@ -0,0 +1,10 @@ +export * from "./converters"; +export * from "./types/index"; +export { AsnProp, AsnType, AsnChoiceType, AsnSequenceType, AsnSetType } from "./decorators"; +export { AsnTypeTypes, AsnPropTypes } from "./enums"; +export { AsnParser } from "./parser"; +export { AsnSerializer } from "./serializer"; +export { IAsnConverter, IAsnConvertible, IAsnParseOptions } from "./types"; +export * from "./errors"; +export * from "./objects"; +export * from "./convert"; diff --git a/node_modules/@peculiar/asn1-schema/build/types/objects.d.ts b/node_modules/@peculiar/asn1-schema/build/types/objects.d.ts new file mode 100644 index 0000000..f57d9f3 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/objects.d.ts @@ -0,0 +1,3 @@ +export declare abstract class AsnArray extends Array { + constructor(items?: T[]); +} diff --git a/node_modules/@peculiar/asn1-schema/build/types/parser.d.ts b/node_modules/@peculiar/asn1-schema/build/types/parser.d.ts new file mode 100644 index 0000000..fa82d7f --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/parser.d.ts @@ -0,0 +1,72 @@ +import * as asn1js from "asn1js"; +import { type BufferSourceLike } from "@peculiar/utils"; +import { IEmptyConstructor, IAsnParseOptions } from "./types"; +/** + * Deserializes objects from ASN.1 encoded data + */ +export declare class AsnParser { + /** + * Deserializes an object from the ASN.1 encoded buffer + * @param data ASN.1 encoded buffer + * @param target Target schema for object deserialization + */ + static parse(data: BufferSourceLike, target: IEmptyConstructor, options?: IAsnParseOptions): T; + /** + * Deserializes an object from the asn1js object + * @param asn1Schema asn1js object + * @param target Target schema for object deserialization + */ + static fromASN(asn1Schema: asn1js.AsnType, target: IEmptyConstructor, options?: IAsnParseOptions): T; + /** + * Handles Choice types with context tags (IMPLICIT) and IMPLICIT tagging + */ + private static handleChoiceTypes; + /** + * Handles SEQUENCE types with optional CHOICE fields and schema comparison + */ + private static handleSequenceTypes; + /** + * Processes repeated fields in manual mapping + */ + private static processRepeatedField; + /** + * Processes primitive fields in manual mapping + */ + private static processPrimitiveField; + /** + * Checks if a schema item is an optional CHOICE field + */ + private static isOptionalChoiceField; + /** + * Processes optional CHOICE fields in manual mapping + */ + private static processOptionalChoiceField; + /** + * Handles array types + */ + private static handleArrayTypes; + /** + * Processes all schema items + */ + private static processSchemaItems; + /** + * Processes primitive schema items + */ + private static processPrimitiveSchemaItem; + /** + * Processes repeated primitive items + */ + private static processRepeatedPrimitiveItem; + /** + * Processes single primitive items + */ + private static processSinglePrimitiveItem; + /** + * Processes complex schema items (SEQUENCE, SET, CHOICE) + */ + private static processComplexSchemaItem; + /** + * Handles IMPLICIT tagging for complex types + */ + private static handleImplicitTagging; +} diff --git a/node_modules/@peculiar/asn1-schema/build/types/schema.d.ts b/node_modules/@peculiar/asn1-schema/build/types/schema.d.ts new file mode 100644 index 0000000..d73c30d --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/schema.d.ts @@ -0,0 +1,32 @@ +import * as asn1js from "asn1js"; +import { AsnRepeatType } from "./decorators"; +import { AsnPropTypes, AsnTypeTypes } from "./enums"; +import { IAsnConverter, IEmptyConstructor } from "./types"; +export interface IAsnSchemaItem { + type: AsnPropTypes | IEmptyConstructor; + optional?: boolean; + defaultValue?: unknown; + context?: number; + implicit?: boolean; + converter?: IAsnConverter; + repeated?: AsnRepeatType; + raw?: boolean; +} +export interface IAsnSchema { + type: AsnTypeTypes; + itemType: AsnPropTypes | IEmptyConstructor; + items: Record; + schema?: AsnSchemaType; +} +export type AsnSchemaType = asn1js.Sequence | asn1js.Set | asn1js.Choice; +export declare class AsnSchemaStorage { + protected items: WeakMap; + has(target: object): boolean; + get(target: IEmptyConstructor, checkSchema: true): IAsnSchema & Required>; + get(target: IEmptyConstructor, checkSchema?: false): IAsnSchema; + cache(target: IEmptyConstructor): void; + createDefault(target: object): IAsnSchema; + create(target: object, useNames: boolean): AsnSchemaType; + set(target: object, schema: IAsnSchema): this; + protected findParentSchema(target: object): IAsnSchema | null; +} diff --git a/node_modules/@peculiar/asn1-schema/build/types/serializer.d.ts b/node_modules/@peculiar/asn1-schema/build/types/serializer.d.ts new file mode 100644 index 0000000..9405252 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/serializer.d.ts @@ -0,0 +1,17 @@ +import * as asn1js from "asn1js"; +/** + * Serializes objects into ASN.1 encoded data + */ +export declare class AsnSerializer { + /** + * Serializes an object to the ASN.1 encoded buffer + * @param obj The object to serialize + */ + static serialize(obj: unknown): ArrayBuffer; + /** + * Serialize an object to the asn1js object + * @param obj The object to serialize + */ + static toASN(obj: unknown): asn1js.AsnType; + private static toAsnItem; +} diff --git a/node_modules/@peculiar/asn1-schema/build/types/storage.d.ts b/node_modules/@peculiar/asn1-schema/build/types/storage.d.ts new file mode 100644 index 0000000..4be1aa4 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/storage.d.ts @@ -0,0 +1,2 @@ +import { AsnSchemaStorage } from "./schema"; +export declare const schemaStorage: AsnSchemaStorage; diff --git a/node_modules/@peculiar/asn1-schema/build/types/types.d.ts b/node_modules/@peculiar/asn1-schema/build/types/types.d.ts new file mode 100644 index 0000000..d5eae25 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/types.d.ts @@ -0,0 +1,42 @@ +/** + * ASN1 type + */ +import * as asn1js from "asn1js"; +export type IEmptyConstructor = new () => T; +/** + * Options for parsing ASN.1 encoded data + */ +export interface IAsnParseOptions { + /** + * Resource limits forwarded to `asn1js.fromBER` for untrusted input + * (`maxDepth`, `maxNodes`, `maxContentLength`). When omitted, the asn1js + * defaults apply (maxDepth: 100, maxNodes: 10000, maxContentLength: 16MB). + */ + berOptions?: asn1js.FromBerOptions; +} +/** + * Allows to convert ASN.1 object to JS value and back + */ +export interface IAsnConverter { + /** + * Returns JS value from ASN.1 object + * @param value ASN.1 object from asn1js module + */ + fromASN(value: AsnType): T; + /** + * Returns ASN.1 object from JS value + * @param value JS value + */ + toASN(value: T): AsnType; +} +export type IntegerConverterType = string | number; +export type AnyConverterType = ArrayBuffer | null; +/** + * Allows an object to control its own ASN.1 serialization and deserialization + */ +export interface IAsnConvertible { + fromASN(asn: T): this; + toASN(): T; + toSchema(name: string): asn1js.BaseBlock; +} +export type IAsnConvertibleConstructor = new () => IAsnConvertible; diff --git a/node_modules/@peculiar/asn1-schema/build/types/types/bit_string.d.ts b/node_modules/@peculiar/asn1-schema/build/types/types/bit_string.d.ts new file mode 100644 index 0000000..ddd5420 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/types/bit_string.d.ts @@ -0,0 +1,15 @@ +import * as asn1js from "asn1js"; +import { type BufferSourceLike } from "@peculiar/utils"; +import { IAsnConvertible } from "../types"; +export declare class BitString implements IAsnConvertible { + unusedBits: number; + value: ArrayBuffer; + constructor(); + constructor(value: T); + constructor(value: BufferSourceLike, unusedBits?: number); + fromASN(asn: asn1js.BitString): this; + toASN(): asn1js.BitString; + toSchema(name: string): asn1js.BitString; + toNumber(): T; + fromNumber(value: T): void; +} diff --git a/node_modules/@peculiar/asn1-schema/build/types/types/index.d.ts b/node_modules/@peculiar/asn1-schema/build/types/types/index.d.ts new file mode 100644 index 0000000..28ceb71 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/types/index.d.ts @@ -0,0 +1,2 @@ +export * from "./bit_string"; +export * from "./octet_string"; diff --git a/node_modules/@peculiar/asn1-schema/build/types/types/octet_string.d.ts b/node_modules/@peculiar/asn1-schema/build/types/types/octet_string.d.ts new file mode 100644 index 0000000..2a62ede --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/build/types/types/octet_string.d.ts @@ -0,0 +1,15 @@ +import * as asn1js from "asn1js"; +import { BufferSourceLike } from "@peculiar/utils"; +import { IAsnConvertible } from "../types"; +export declare class OctetString implements IAsnConvertible, ArrayBufferView { + buffer: ArrayBuffer; + get byteLength(): number; + get byteOffset(): number; + constructor(); + constructor(byteLength: number); + constructor(bytes: number[]); + constructor(bytes: BufferSourceLike); + fromASN(asn: asn1js.OctetString): this; + toASN(): asn1js.OctetString; + toSchema(name: string): asn1js.OctetString; +} diff --git a/node_modules/@peculiar/asn1-schema/package.json b/node_modules/@peculiar/asn1-schema/package.json new file mode 100644 index 0000000..6c93b65 --- /dev/null +++ b/node_modules/@peculiar/asn1-schema/package.json @@ -0,0 +1,64 @@ +{ + "name": "@peculiar/asn1-schema", + "version": "2.11.0", + "description": "Decorators and helper APIs for declaring ASN.1 schemas in TypeScript.", + "keywords": [ + "asn", + "asn1", + "schema", + "serialize", + "parse", + "decorator", + "der" + ], + "author": "PeculiarVentures, LLC", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "files": [ + "build/**/*.{js,d.ts}", + "LICENSE", + "README.md" + ], + "main": "build/cjs/index.js", + "module": "build/es2015/index.js", + "types": "build/types/index.d.ts", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/PeculiarVentures/asn1-schema", + "directory": "packages/schema" + }, + "bugs": { + "url": "https://github.com/PeculiarVentures/asn1-schema/issues" + }, + "homepage": "https://github.com/PeculiarVentures/asn1-schema/tree/master/packages/schema#readme", + "scripts": { + "clear": "rimraf build", + "build": "npm run build:module && npm run build:types", + "build:module": "npm run build:cjs && npm run build:es2015", + "build:cjs": "tsc -p tsconfig.compile.json --removeComments --module commonjs --outDir build/cjs", + "build:es2015": "tsc -p tsconfig.compile.json --removeComments --module ES2015 --outDir build/es2015", + "prebuild:types": "rimraf build/types", + "build:types": "tsc -p tsconfig.compile.json --outDir build/types --declaration --emitDeclarationOnly", + "rebuild": "npm run clear && npm run build" + }, + "dependencies": { + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + }, + "contributors": [ + { + "email": "rmh@unmitigatedrisk.com", + "name": "Ryan Hurst" + }, + { + "email": "microshine@mail.ru", + "name": "Miroshin Stepan" + } + ] +} diff --git a/node_modules/@peculiar/json-schema/build/index.es.js b/node_modules/@peculiar/json-schema/build/index.es.js new file mode 100644 index 0000000..5177313 --- /dev/null +++ b/node_modules/@peculiar/json-schema/build/index.es.js @@ -0,0 +1,484 @@ +/** + * Copyright (c) 2020, Peculiar Ventures, All rights reserved. + */ + +class JsonError extends Error { + constructor(message, innerError) { + super(innerError + ? `${message}. See the inner exception for more details.` + : message); + this.message = message; + this.innerError = innerError; + } +} + +class TransformError extends JsonError { + constructor(schema, message, innerError) { + super(message, innerError); + this.schema = schema; + } +} + +class ParserError extends TransformError { + constructor(schema, message, innerError) { + super(schema, `JSON doesn't match to '${schema.target.name}' schema. ${message}`, innerError); + } +} + +class ValidationError extends JsonError { +} + +class SerializerError extends JsonError { + constructor(schemaName, message, innerError) { + super(`Cannot serialize by '${schemaName}' schema. ${message}`, innerError); + this.schemaName = schemaName; + } +} + +class KeyError extends ParserError { + constructor(schema, keys, errors = {}) { + super(schema, "Some keys doesn't match to schema"); + this.keys = keys; + this.errors = errors; + } +} + +var JsonPropTypes; +(function (JsonPropTypes) { + JsonPropTypes[JsonPropTypes["Any"] = 0] = "Any"; + JsonPropTypes[JsonPropTypes["Boolean"] = 1] = "Boolean"; + JsonPropTypes[JsonPropTypes["Number"] = 2] = "Number"; + JsonPropTypes[JsonPropTypes["String"] = 3] = "String"; +})(JsonPropTypes || (JsonPropTypes = {})); + +function checkType(value, type) { + switch (type) { + case JsonPropTypes.Boolean: + return typeof value === "boolean"; + case JsonPropTypes.Number: + return typeof value === "number"; + case JsonPropTypes.String: + return typeof value === "string"; + } + return true; +} +function throwIfTypeIsWrong(value, type) { + if (!checkType(value, type)) { + throw new TypeError(`Value must be ${JsonPropTypes[type]}`); + } +} +function isConvertible(target) { + if (target && target.prototype) { + if (target.prototype.toJSON && target.prototype.fromJSON) { + return true; + } + else { + return isConvertible(target.prototype); + } + } + else { + return !!(target && target.toJSON && target.fromJSON); + } +} + +class JsonSchemaStorage { + constructor() { + this.items = new Map(); + } + has(target) { + return this.items.has(target) || !!this.findParentSchema(target); + } + get(target) { + const schema = this.items.get(target) || this.findParentSchema(target); + if (!schema) { + throw new Error("Cannot get schema for current target"); + } + return schema; + } + create(target) { + const schema = { names: {} }; + const parentSchema = this.findParentSchema(target); + if (parentSchema) { + Object.assign(schema, parentSchema); + schema.names = {}; + for (const name in parentSchema.names) { + schema.names[name] = Object.assign({}, parentSchema.names[name]); + } + } + schema.target = target; + return schema; + } + set(target, schema) { + this.items.set(target, schema); + return this; + } + findParentSchema(target) { + const parent = target.__proto__; + if (parent) { + const schema = this.items.get(parent); + return schema || this.findParentSchema(parent); + } + return null; + } +} + +const DEFAULT_SCHEMA = "default"; +const schemaStorage = new JsonSchemaStorage(); + +class PatternValidation { + constructor(pattern) { + this.pattern = new RegExp(pattern); + } + validate(value) { + const pattern = new RegExp(this.pattern.source, this.pattern.flags); + if (typeof value !== "string") { + throw new ValidationError("Incoming value must be string"); + } + if (!pattern.exec(value)) { + throw new ValidationError(`Value doesn't match to pattern '${pattern.toString()}'`); + } + } +} + +class InclusiveValidation { + constructor(min = Number.MIN_VALUE, max = Number.MAX_VALUE) { + this.min = min; + this.max = max; + } + validate(value) { + throwIfTypeIsWrong(value, JsonPropTypes.Number); + if (!(this.min <= value && value <= this.max)) { + const min = this.min === Number.MIN_VALUE ? "MIN" : this.min; + const max = this.max === Number.MAX_VALUE ? "MAX" : this.max; + throw new ValidationError(`Value doesn't match to diapason [${min},${max}]`); + } + } +} + +class ExclusiveValidation { + constructor(min = Number.MIN_VALUE, max = Number.MAX_VALUE) { + this.min = min; + this.max = max; + } + validate(value) { + throwIfTypeIsWrong(value, JsonPropTypes.Number); + if (!(this.min < value && value < this.max)) { + const min = this.min === Number.MIN_VALUE ? "MIN" : this.min; + const max = this.max === Number.MAX_VALUE ? "MAX" : this.max; + throw new ValidationError(`Value doesn't match to diapason (${min},${max})`); + } + } +} + +class LengthValidation { + constructor(length, minLength, maxLength) { + this.length = length; + this.minLength = minLength; + this.maxLength = maxLength; + } + validate(value) { + if (this.length !== undefined) { + if (value.length !== this.length) { + throw new ValidationError(`Value length must be exactly ${this.length}.`); + } + return; + } + if (this.minLength !== undefined) { + if (value.length < this.minLength) { + throw new ValidationError(`Value length must be more than ${this.minLength}.`); + } + } + if (this.maxLength !== undefined) { + if (value.length > this.maxLength) { + throw new ValidationError(`Value length must be less than ${this.maxLength}.`); + } + } + } +} + +class EnumerationValidation { + constructor(enumeration) { + this.enumeration = enumeration; + } + validate(value) { + throwIfTypeIsWrong(value, JsonPropTypes.String); + if (!this.enumeration.includes(value)) { + throw new ValidationError(`Value must be one of ${this.enumeration.map((v) => `'${v}'`).join(", ")}`); + } + } +} + +class JsonTransform { + static checkValues(data, schemaItem) { + const values = Array.isArray(data) ? data : [data]; + for (const value of values) { + for (const validation of schemaItem.validations) { + if (validation instanceof LengthValidation && schemaItem.repeated) { + validation.validate(data); + } + else { + validation.validate(value); + } + } + } + } + static checkTypes(value, schemaItem) { + if (schemaItem.repeated && !Array.isArray(value)) { + throw new TypeError("Value must be Array"); + } + if (typeof schemaItem.type === "number") { + const values = Array.isArray(value) ? value : [value]; + for (const v of values) { + throwIfTypeIsWrong(v, schemaItem.type); + } + } + } + static getSchemaByName(schema, name = DEFAULT_SCHEMA) { + return { ...schema.names[DEFAULT_SCHEMA], ...schema.names[name] }; + } +} + +class JsonSerializer extends JsonTransform { + static serialize(obj, options, replacer, space) { + const json = this.toJSON(obj, options); + return JSON.stringify(json, replacer, space); + } + static toJSON(obj, options = {}) { + let res; + let targetSchema = options.targetSchema; + const schemaName = options.schemaName || DEFAULT_SCHEMA; + if (isConvertible(obj)) { + return obj.toJSON(); + } + if (Array.isArray(obj)) { + res = []; + for (const item of obj) { + res.push(this.toJSON(item, options)); + } + } + else if (typeof obj === "object") { + if (targetSchema && !schemaStorage.has(targetSchema)) { + throw new JsonError("Cannot get schema for `targetSchema` param"); + } + targetSchema = (targetSchema || obj.constructor); + if (schemaStorage.has(targetSchema)) { + const schema = schemaStorage.get(targetSchema); + res = {}; + const namedSchema = this.getSchemaByName(schema, schemaName); + for (const key in namedSchema) { + try { + const item = namedSchema[key]; + const objItem = obj[key]; + let value; + if ((item.optional && objItem === undefined) + || (item.defaultValue !== undefined && objItem === item.defaultValue)) { + continue; + } + if (!item.optional && objItem === undefined) { + throw new SerializerError(targetSchema.name, `Property '${key}' is required.`); + } + if (typeof item.type === "number") { + if (item.converter) { + if (item.repeated) { + value = objItem.map((el) => item.converter.toJSON(el, obj)); + } + else { + value = item.converter.toJSON(objItem, obj); + } + } + else { + value = objItem; + } + } + else { + if (item.repeated) { + value = objItem.map((el) => this.toJSON(el, { schemaName })); + } + else { + value = this.toJSON(objItem, { schemaName }); + } + } + this.checkTypes(value, item); + this.checkValues(value, item); + res[item.name || key] = value; + } + catch (e) { + if (e instanceof SerializerError) { + throw e; + } + else { + throw new SerializerError(schema.target.name, `Property '${key}' is wrong. ${e.message}`, e); + } + } + } + } + else { + res = {}; + for (const key in obj) { + res[key] = this.toJSON(obj[key], { schemaName }); + } + } + } + else { + res = obj; + } + return res; + } +} + +class JsonParser extends JsonTransform { + static parse(data, options) { + const obj = JSON.parse(data); + return this.fromJSON(obj, options); + } + static fromJSON(target, options) { + const targetSchema = options.targetSchema; + const schemaName = options.schemaName || DEFAULT_SCHEMA; + const obj = new targetSchema(); + if (isConvertible(obj)) { + return obj.fromJSON(target); + } + const schema = schemaStorage.get(targetSchema); + const namedSchema = this.getSchemaByName(schema, schemaName); + const keyErrors = {}; + if (options.strictProperty && !Array.isArray(target)) { + JsonParser.checkStrictProperty(target, namedSchema, schema); + } + for (const key in namedSchema) { + try { + const item = namedSchema[key]; + const name = item.name || key; + const value = target[name]; + if (value === undefined && (item.optional || item.defaultValue !== undefined)) { + continue; + } + if (!item.optional && value === undefined) { + throw new ParserError(schema, `Property '${name}' is required.`); + } + this.checkTypes(value, item); + this.checkValues(value, item); + if (typeof (item.type) === "number") { + if (item.converter) { + if (item.repeated) { + obj[key] = value.map((el) => item.converter.fromJSON(el, obj)); + } + else { + obj[key] = item.converter.fromJSON(value, obj); + } + } + else { + obj[key] = value; + } + } + else { + const newOptions = { + ...options, + targetSchema: item.type, + schemaName, + }; + if (item.repeated) { + obj[key] = value.map((el) => this.fromJSON(el, newOptions)); + } + else { + obj[key] = this.fromJSON(value, newOptions); + } + } + } + catch (e) { + if (!(e instanceof ParserError)) { + e = new ParserError(schema, `Property '${key}' is wrong. ${e.message}`, e); + } + if (options.strictAllKeys) { + keyErrors[key] = e; + } + else { + throw e; + } + } + } + const keys = Object.keys(keyErrors); + if (keys.length) { + throw new KeyError(schema, keys, keyErrors); + } + return obj; + } + static checkStrictProperty(target, namedSchema, schema) { + const jsonProps = Object.keys(target); + const schemaProps = Object.keys(namedSchema); + const keys = []; + for (const key of jsonProps) { + if (schemaProps.indexOf(key) === -1) { + keys.push(key); + } + } + if (keys.length) { + throw new KeyError(schema, keys); + } + } +} + +function getValidations(item) { + const validations = []; + if (item.pattern) { + validations.push(new PatternValidation(item.pattern)); + } + if (item.type === JsonPropTypes.Number || item.type === JsonPropTypes.Any) { + if (item.minInclusive !== undefined || item.maxInclusive !== undefined) { + validations.push(new InclusiveValidation(item.minInclusive, item.maxInclusive)); + } + if (item.minExclusive !== undefined || item.maxExclusive !== undefined) { + validations.push(new ExclusiveValidation(item.minExclusive, item.maxExclusive)); + } + if (item.enumeration !== undefined) { + validations.push(new EnumerationValidation(item.enumeration)); + } + } + if (item.type === JsonPropTypes.String || item.repeated || item.type === JsonPropTypes.Any) { + if (item.length !== undefined || item.minLength !== undefined || item.maxLength !== undefined) { + validations.push(new LengthValidation(item.length, item.minLength, item.maxLength)); + } + } + return validations; +} +const JsonProp = (options = {}) => (target, propertyKey) => { + const errorMessage = `Cannot set type for ${propertyKey} property of ${target.constructor.name} schema`; + let schema; + if (!schemaStorage.has(target.constructor)) { + schema = schemaStorage.create(target.constructor); + schemaStorage.set(target.constructor, schema); + } + else { + schema = schemaStorage.get(target.constructor); + if (schema.target !== target.constructor) { + schema = schemaStorage.create(target.constructor); + schemaStorage.set(target.constructor, schema); + } + } + const defaultSchema = { + type: JsonPropTypes.Any, + validations: [], + }; + const copyOptions = Object.assign(defaultSchema, options); + copyOptions.validations = getValidations(copyOptions); + if (typeof copyOptions.type !== "number") { + if (!schemaStorage.has(copyOptions.type) && !isConvertible(copyOptions.type)) { + throw new Error(`${errorMessage}. Assigning type doesn't have schema.`); + } + } + let schemaNames; + if (Array.isArray(options.schema)) { + schemaNames = options.schema; + } + else { + schemaNames = [options.schema || DEFAULT_SCHEMA]; + } + for (const schemaName of schemaNames) { + if (!schema.names[schemaName]) { + schema.names[schemaName] = {}; + } + const namedSchema = schema.names[schemaName]; + namedSchema[propertyKey] = copyOptions; + } +}; + +export { JsonError, JsonParser, JsonProp, JsonPropTypes, JsonSerializer, KeyError, ParserError, SerializerError, TransformError, ValidationError };