mirror of
https://github.com/xuxiaobo-bobo/boda_jsEnv.git
synced 2025-04-23 08:29:24 +08:00
3129 lines
107 KiB
JavaScript
3129 lines
107 KiB
JavaScript
/*!
|
|
* Copyright (c) 2014, GMO GlobalSign
|
|
* Copyright (c) 2015-2022, Peculiar Ventures
|
|
* All rights reserved.
|
|
*
|
|
* Author 2014-2019, Yury Strozhevsky
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright notice, this
|
|
* list of conditions and the following disclaimer in the documentation and/or
|
|
* other materials provided with the distribution.
|
|
*
|
|
* * Neither the name of the copyright holder nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
import * as pvtsutils from 'pvtsutils';
|
|
import * as pvutils from 'pvutils';
|
|
|
|
function assertBigInt() {
|
|
if (typeof BigInt === "undefined") {
|
|
throw new Error("BigInt is not defined. Your environment doesn't implement BigInt.");
|
|
}
|
|
}
|
|
function concat(buffers) {
|
|
let outputLength = 0;
|
|
let prevLength = 0;
|
|
for (let i = 0; i < buffers.length; i++) {
|
|
const buffer = buffers[i];
|
|
outputLength += buffer.byteLength;
|
|
}
|
|
const retView = new Uint8Array(outputLength);
|
|
for (let i = 0; i < buffers.length; i++) {
|
|
const buffer = buffers[i];
|
|
retView.set(new Uint8Array(buffer), prevLength);
|
|
prevLength += buffer.byteLength;
|
|
}
|
|
return retView.buffer;
|
|
}
|
|
function checkBufferParams(baseBlock, inputBuffer, inputOffset, inputLength) {
|
|
if (!(inputBuffer instanceof Uint8Array)) {
|
|
baseBlock.error = "Wrong parameter: inputBuffer must be 'Uint8Array'";
|
|
return false;
|
|
}
|
|
if (!inputBuffer.byteLength) {
|
|
baseBlock.error = "Wrong parameter: inputBuffer has zero length";
|
|
return false;
|
|
}
|
|
if (inputOffset < 0) {
|
|
baseBlock.error = "Wrong parameter: inputOffset less than zero";
|
|
return false;
|
|
}
|
|
if (inputLength < 0) {
|
|
baseBlock.error = "Wrong parameter: inputLength less than zero";
|
|
return false;
|
|
}
|
|
if ((inputBuffer.byteLength - inputOffset - inputLength) < 0) {
|
|
baseBlock.error = "End of input reached before message was fully decoded (inconsistent offset and length values)";
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
class ViewWriter {
|
|
constructor() {
|
|
this.items = [];
|
|
}
|
|
write(buf) {
|
|
this.items.push(buf);
|
|
}
|
|
final() {
|
|
return concat(this.items);
|
|
}
|
|
}
|
|
|
|
const powers2 = [new Uint8Array([1])];
|
|
const digitsString = "0123456789";
|
|
const NAME = "name";
|
|
const VALUE_HEX_VIEW = "valueHexView";
|
|
const IS_HEX_ONLY = "isHexOnly";
|
|
const ID_BLOCK = "idBlock";
|
|
const TAG_CLASS = "tagClass";
|
|
const TAG_NUMBER = "tagNumber";
|
|
const IS_CONSTRUCTED = "isConstructed";
|
|
const FROM_BER = "fromBER";
|
|
const TO_BER = "toBER";
|
|
const LOCAL = "local";
|
|
const EMPTY_STRING = "";
|
|
const EMPTY_BUFFER = new ArrayBuffer(0);
|
|
const EMPTY_VIEW = new Uint8Array(0);
|
|
const END_OF_CONTENT_NAME = "EndOfContent";
|
|
const OCTET_STRING_NAME = "OCTET STRING";
|
|
const BIT_STRING_NAME = "BIT STRING";
|
|
|
|
function HexBlock(BaseClass) {
|
|
var _a;
|
|
return _a = class Some extends BaseClass {
|
|
constructor(...args) {
|
|
var _a;
|
|
super(...args);
|
|
const params = args[0] || {};
|
|
this.isHexOnly = (_a = params.isHexOnly) !== null && _a !== void 0 ? _a : false;
|
|
this.valueHexView = params.valueHex ? pvtsutils.BufferSourceConverter.toUint8Array(params.valueHex) : EMPTY_VIEW;
|
|
}
|
|
get valueHex() {
|
|
return this.valueHexView.slice().buffer;
|
|
}
|
|
set valueHex(value) {
|
|
this.valueHexView = new Uint8Array(value);
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
const view = inputBuffer instanceof ArrayBuffer ? new Uint8Array(inputBuffer) : inputBuffer;
|
|
if (!checkBufferParams(this, view, inputOffset, inputLength)) {
|
|
return -1;
|
|
}
|
|
const endLength = inputOffset + inputLength;
|
|
this.valueHexView = view.subarray(inputOffset, endLength);
|
|
if (!this.valueHexView.length) {
|
|
this.warnings.push("Zero buffer length");
|
|
return inputOffset;
|
|
}
|
|
this.blockLength = inputLength;
|
|
return endLength;
|
|
}
|
|
toBER(sizeOnly = false) {
|
|
if (!this.isHexOnly) {
|
|
this.error = "Flag 'isHexOnly' is not set, abort";
|
|
return EMPTY_BUFFER;
|
|
}
|
|
if (sizeOnly) {
|
|
return new ArrayBuffer(this.valueHexView.byteLength);
|
|
}
|
|
return (this.valueHexView.byteLength === this.valueHexView.buffer.byteLength)
|
|
? this.valueHexView.buffer
|
|
: this.valueHexView.slice().buffer;
|
|
}
|
|
toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
isHexOnly: this.isHexOnly,
|
|
valueHex: pvtsutils.Convert.ToHex(this.valueHexView),
|
|
};
|
|
}
|
|
},
|
|
_a.NAME = "hexBlock",
|
|
_a;
|
|
}
|
|
|
|
class LocalBaseBlock {
|
|
constructor({ blockLength = 0, error = EMPTY_STRING, warnings = [], valueBeforeDecode = EMPTY_VIEW, } = {}) {
|
|
this.blockLength = blockLength;
|
|
this.error = error;
|
|
this.warnings = warnings;
|
|
this.valueBeforeDecodeView = pvtsutils.BufferSourceConverter.toUint8Array(valueBeforeDecode);
|
|
}
|
|
static blockName() {
|
|
return this.NAME;
|
|
}
|
|
get valueBeforeDecode() {
|
|
return this.valueBeforeDecodeView.slice().buffer;
|
|
}
|
|
set valueBeforeDecode(value) {
|
|
this.valueBeforeDecodeView = new Uint8Array(value);
|
|
}
|
|
toJSON() {
|
|
return {
|
|
blockName: this.constructor.NAME,
|
|
blockLength: this.blockLength,
|
|
error: this.error,
|
|
warnings: this.warnings,
|
|
valueBeforeDecode: pvtsutils.Convert.ToHex(this.valueBeforeDecodeView),
|
|
};
|
|
}
|
|
}
|
|
LocalBaseBlock.NAME = "baseBlock";
|
|
|
|
class ValueBlock extends LocalBaseBlock {
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
throw TypeError("User need to make a specific function in a class which extends 'ValueBlock'");
|
|
}
|
|
toBER(sizeOnly, writer) {
|
|
throw TypeError("User need to make a specific function in a class which extends 'ValueBlock'");
|
|
}
|
|
}
|
|
ValueBlock.NAME = "valueBlock";
|
|
|
|
class LocalIdentificationBlock extends HexBlock(LocalBaseBlock) {
|
|
constructor({ idBlock = {}, } = {}) {
|
|
var _a, _b, _c, _d;
|
|
super();
|
|
if (idBlock) {
|
|
this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !== void 0 ? _a : false;
|
|
this.valueHexView = idBlock.valueHex ? pvtsutils.BufferSourceConverter.toUint8Array(idBlock.valueHex) : EMPTY_VIEW;
|
|
this.tagClass = (_b = idBlock.tagClass) !== null && _b !== void 0 ? _b : -1;
|
|
this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !== void 0 ? _c : -1;
|
|
this.isConstructed = (_d = idBlock.isConstructed) !== null && _d !== void 0 ? _d : false;
|
|
}
|
|
else {
|
|
this.tagClass = -1;
|
|
this.tagNumber = -1;
|
|
this.isConstructed = false;
|
|
}
|
|
}
|
|
toBER(sizeOnly = false) {
|
|
let firstOctet = 0;
|
|
switch (this.tagClass) {
|
|
case 1:
|
|
firstOctet |= 0x00;
|
|
break;
|
|
case 2:
|
|
firstOctet |= 0x40;
|
|
break;
|
|
case 3:
|
|
firstOctet |= 0x80;
|
|
break;
|
|
case 4:
|
|
firstOctet |= 0xC0;
|
|
break;
|
|
default:
|
|
this.error = "Unknown tag class";
|
|
return EMPTY_BUFFER;
|
|
}
|
|
if (this.isConstructed)
|
|
firstOctet |= 0x20;
|
|
if (this.tagNumber < 31 && !this.isHexOnly) {
|
|
const retView = new Uint8Array(1);
|
|
if (!sizeOnly) {
|
|
let number = this.tagNumber;
|
|
number &= 0x1F;
|
|
firstOctet |= number;
|
|
retView[0] = firstOctet;
|
|
}
|
|
return retView.buffer;
|
|
}
|
|
if (!this.isHexOnly) {
|
|
const encodedBuf = pvutils.utilToBase(this.tagNumber, 7);
|
|
const encodedView = new Uint8Array(encodedBuf);
|
|
const size = encodedBuf.byteLength;
|
|
const retView = new Uint8Array(size + 1);
|
|
retView[0] = (firstOctet | 0x1F);
|
|
if (!sizeOnly) {
|
|
for (let i = 0; i < (size - 1); i++)
|
|
retView[i + 1] = encodedView[i] | 0x80;
|
|
retView[size] = encodedView[size - 1];
|
|
}
|
|
return retView.buffer;
|
|
}
|
|
const retView = new Uint8Array(this.valueHexView.byteLength + 1);
|
|
retView[0] = (firstOctet | 0x1F);
|
|
if (!sizeOnly) {
|
|
const curView = this.valueHexView;
|
|
for (let i = 0; i < (curView.length - 1); i++)
|
|
retView[i + 1] = curView[i] | 0x80;
|
|
retView[this.valueHexView.byteLength] = curView[curView.length - 1];
|
|
}
|
|
return retView.buffer;
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer);
|
|
if (!checkBufferParams(this, inputView, inputOffset, inputLength)) {
|
|
return -1;
|
|
}
|
|
const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength);
|
|
if (intBuffer.length === 0) {
|
|
this.error = "Zero buffer length";
|
|
return -1;
|
|
}
|
|
const tagClassMask = intBuffer[0] & 0xC0;
|
|
switch (tagClassMask) {
|
|
case 0x00:
|
|
this.tagClass = (1);
|
|
break;
|
|
case 0x40:
|
|
this.tagClass = (2);
|
|
break;
|
|
case 0x80:
|
|
this.tagClass = (3);
|
|
break;
|
|
case 0xC0:
|
|
this.tagClass = (4);
|
|
break;
|
|
default:
|
|
this.error = "Unknown tag class";
|
|
return -1;
|
|
}
|
|
this.isConstructed = (intBuffer[0] & 0x20) === 0x20;
|
|
this.isHexOnly = false;
|
|
const tagNumberMask = intBuffer[0] & 0x1F;
|
|
if (tagNumberMask !== 0x1F) {
|
|
this.tagNumber = (tagNumberMask);
|
|
this.blockLength = 1;
|
|
}
|
|
else {
|
|
let count = 1;
|
|
let intTagNumberBuffer = this.valueHexView = new Uint8Array(255);
|
|
let tagNumberBufferMaxLength = 255;
|
|
while (intBuffer[count] & 0x80) {
|
|
intTagNumberBuffer[count - 1] = intBuffer[count] & 0x7F;
|
|
count++;
|
|
if (count >= intBuffer.length) {
|
|
this.error = "End of input reached before message was fully decoded";
|
|
return -1;
|
|
}
|
|
if (count === tagNumberBufferMaxLength) {
|
|
tagNumberBufferMaxLength += 255;
|
|
const tempBufferView = new Uint8Array(tagNumberBufferMaxLength);
|
|
for (let i = 0; i < intTagNumberBuffer.length; i++)
|
|
tempBufferView[i] = intTagNumberBuffer[i];
|
|
intTagNumberBuffer = this.valueHexView = new Uint8Array(tagNumberBufferMaxLength);
|
|
}
|
|
}
|
|
this.blockLength = (count + 1);
|
|
intTagNumberBuffer[count - 1] = intBuffer[count] & 0x7F;
|
|
const tempBufferView = new Uint8Array(count);
|
|
for (let i = 0; i < count; i++)
|
|
tempBufferView[i] = intTagNumberBuffer[i];
|
|
intTagNumberBuffer = this.valueHexView = new Uint8Array(count);
|
|
intTagNumberBuffer.set(tempBufferView);
|
|
if (this.blockLength <= 9)
|
|
this.tagNumber = pvutils.utilFromBase(intTagNumberBuffer, 7);
|
|
else {
|
|
this.isHexOnly = true;
|
|
this.warnings.push("Tag too long, represented as hex-coded");
|
|
}
|
|
}
|
|
if (((this.tagClass === 1)) &&
|
|
(this.isConstructed)) {
|
|
switch (this.tagNumber) {
|
|
case 1:
|
|
case 2:
|
|
case 5:
|
|
case 6:
|
|
case 9:
|
|
case 13:
|
|
case 14:
|
|
case 23:
|
|
case 24:
|
|
case 31:
|
|
case 32:
|
|
case 33:
|
|
case 34:
|
|
this.error = "Constructed encoding used for primitive type";
|
|
return -1;
|
|
}
|
|
}
|
|
return (inputOffset + this.blockLength);
|
|
}
|
|
toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
tagClass: this.tagClass,
|
|
tagNumber: this.tagNumber,
|
|
isConstructed: this.isConstructed,
|
|
};
|
|
}
|
|
}
|
|
LocalIdentificationBlock.NAME = "identificationBlock";
|
|
|
|
class LocalLengthBlock extends LocalBaseBlock {
|
|
constructor({ lenBlock = {}, } = {}) {
|
|
var _a, _b, _c;
|
|
super();
|
|
this.isIndefiniteForm = (_a = lenBlock.isIndefiniteForm) !== null && _a !== void 0 ? _a : false;
|
|
this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !== void 0 ? _b : false;
|
|
this.length = (_c = lenBlock.length) !== null && _c !== void 0 ? _c : 0;
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
const view = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer);
|
|
if (!checkBufferParams(this, view, inputOffset, inputLength)) {
|
|
return -1;
|
|
}
|
|
const intBuffer = view.subarray(inputOffset, inputOffset + inputLength);
|
|
if (intBuffer.length === 0) {
|
|
this.error = "Zero buffer length";
|
|
return -1;
|
|
}
|
|
if (intBuffer[0] === 0xFF) {
|
|
this.error = "Length block 0xFF is reserved by standard";
|
|
return -1;
|
|
}
|
|
this.isIndefiniteForm = intBuffer[0] === 0x80;
|
|
if (this.isIndefiniteForm) {
|
|
this.blockLength = 1;
|
|
return (inputOffset + this.blockLength);
|
|
}
|
|
this.longFormUsed = !!(intBuffer[0] & 0x80);
|
|
if (this.longFormUsed === false) {
|
|
this.length = (intBuffer[0]);
|
|
this.blockLength = 1;
|
|
return (inputOffset + this.blockLength);
|
|
}
|
|
const count = intBuffer[0] & 0x7F;
|
|
if (count > 8) {
|
|
this.error = "Too big integer";
|
|
return -1;
|
|
}
|
|
if ((count + 1) > intBuffer.length) {
|
|
this.error = "End of input reached before message was fully decoded";
|
|
return -1;
|
|
}
|
|
const lenOffset = inputOffset + 1;
|
|
const lengthBufferView = view.subarray(lenOffset, lenOffset + count);
|
|
if (lengthBufferView[count - 1] === 0x00)
|
|
this.warnings.push("Needlessly long encoded length");
|
|
this.length = pvutils.utilFromBase(lengthBufferView, 8);
|
|
if (this.longFormUsed && (this.length <= 127))
|
|
this.warnings.push("Unnecessary usage of long length form");
|
|
this.blockLength = count + 1;
|
|
return (inputOffset + this.blockLength);
|
|
}
|
|
toBER(sizeOnly = false) {
|
|
let retBuf;
|
|
let retView;
|
|
if (this.length > 127)
|
|
this.longFormUsed = true;
|
|
if (this.isIndefiniteForm) {
|
|
retBuf = new ArrayBuffer(1);
|
|
if (sizeOnly === false) {
|
|
retView = new Uint8Array(retBuf);
|
|
retView[0] = 0x80;
|
|
}
|
|
return retBuf;
|
|
}
|
|
if (this.longFormUsed) {
|
|
const encodedBuf = pvutils.utilToBase(this.length, 8);
|
|
if (encodedBuf.byteLength > 127) {
|
|
this.error = "Too big length";
|
|
return (EMPTY_BUFFER);
|
|
}
|
|
retBuf = new ArrayBuffer(encodedBuf.byteLength + 1);
|
|
if (sizeOnly)
|
|
return retBuf;
|
|
const encodedView = new Uint8Array(encodedBuf);
|
|
retView = new Uint8Array(retBuf);
|
|
retView[0] = encodedBuf.byteLength | 0x80;
|
|
for (let i = 0; i < encodedBuf.byteLength; i++)
|
|
retView[i + 1] = encodedView[i];
|
|
return retBuf;
|
|
}
|
|
retBuf = new ArrayBuffer(1);
|
|
if (sizeOnly === false) {
|
|
retView = new Uint8Array(retBuf);
|
|
retView[0] = this.length;
|
|
}
|
|
return retBuf;
|
|
}
|
|
toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
isIndefiniteForm: this.isIndefiniteForm,
|
|
longFormUsed: this.longFormUsed,
|
|
length: this.length,
|
|
};
|
|
}
|
|
}
|
|
LocalLengthBlock.NAME = "lengthBlock";
|
|
|
|
const typeStore = {};
|
|
|
|
class BaseBlock extends LocalBaseBlock {
|
|
constructor({ name = EMPTY_STRING, optional = false, primitiveSchema, ...parameters } = {}, valueBlockType) {
|
|
super(parameters);
|
|
this.name = name;
|
|
this.optional = optional;
|
|
if (primitiveSchema) {
|
|
this.primitiveSchema = primitiveSchema;
|
|
}
|
|
this.idBlock = new LocalIdentificationBlock(parameters);
|
|
this.lenBlock = new LocalLengthBlock(parameters);
|
|
this.valueBlock = valueBlockType ? new valueBlockType(parameters) : new ValueBlock(parameters);
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, (this.lenBlock.isIndefiniteForm) ? inputLength : this.lenBlock.length);
|
|
if (resultOffset === -1) {
|
|
this.error = this.valueBlock.error;
|
|
return resultOffset;
|
|
}
|
|
if (!this.idBlock.error.length)
|
|
this.blockLength += this.idBlock.blockLength;
|
|
if (!this.lenBlock.error.length)
|
|
this.blockLength += this.lenBlock.blockLength;
|
|
if (!this.valueBlock.error.length)
|
|
this.blockLength += this.valueBlock.blockLength;
|
|
return resultOffset;
|
|
}
|
|
toBER(sizeOnly, writer) {
|
|
const _writer = writer || new ViewWriter();
|
|
if (!writer) {
|
|
prepareIndefiniteForm(this);
|
|
}
|
|
const idBlockBuf = this.idBlock.toBER(sizeOnly);
|
|
_writer.write(idBlockBuf);
|
|
if (this.lenBlock.isIndefiniteForm) {
|
|
_writer.write(new Uint8Array([0x80]).buffer);
|
|
this.valueBlock.toBER(sizeOnly, _writer);
|
|
_writer.write(new ArrayBuffer(2));
|
|
}
|
|
else {
|
|
const valueBlockBuf = this.valueBlock.toBER(sizeOnly);
|
|
this.lenBlock.length = valueBlockBuf.byteLength;
|
|
const lenBlockBuf = this.lenBlock.toBER(sizeOnly);
|
|
_writer.write(lenBlockBuf);
|
|
_writer.write(valueBlockBuf);
|
|
}
|
|
if (!writer) {
|
|
return _writer.final();
|
|
}
|
|
return EMPTY_BUFFER;
|
|
}
|
|
toJSON() {
|
|
const object = {
|
|
...super.toJSON(),
|
|
idBlock: this.idBlock.toJSON(),
|
|
lenBlock: this.lenBlock.toJSON(),
|
|
valueBlock: this.valueBlock.toJSON(),
|
|
name: this.name,
|
|
optional: this.optional,
|
|
};
|
|
if (this.primitiveSchema)
|
|
object.primitiveSchema = this.primitiveSchema.toJSON();
|
|
return object;
|
|
}
|
|
toString(encoding = "ascii") {
|
|
if (encoding === "ascii") {
|
|
return this.onAsciiEncoding();
|
|
}
|
|
return pvtsutils.Convert.ToHex(this.toBER());
|
|
}
|
|
onAsciiEncoding() {
|
|
return `${this.constructor.NAME} : ${pvtsutils.Convert.ToHex(this.valueBlock.valueBeforeDecodeView)}`;
|
|
}
|
|
isEqual(other) {
|
|
if (this === other) {
|
|
return true;
|
|
}
|
|
if (!(other instanceof this.constructor)) {
|
|
return false;
|
|
}
|
|
const thisRaw = this.toBER();
|
|
const otherRaw = other.toBER();
|
|
return pvutils.isEqualBuffer(thisRaw, otherRaw);
|
|
}
|
|
}
|
|
BaseBlock.NAME = "BaseBlock";
|
|
function prepareIndefiniteForm(baseBlock) {
|
|
if (baseBlock instanceof typeStore.Constructed) {
|
|
for (const value of baseBlock.valueBlock.value) {
|
|
if (prepareIndefiniteForm(value)) {
|
|
baseBlock.lenBlock.isIndefiniteForm = true;
|
|
}
|
|
}
|
|
}
|
|
return !!baseBlock.lenBlock.isIndefiniteForm;
|
|
}
|
|
|
|
class BaseStringBlock extends BaseBlock {
|
|
constructor({ value = EMPTY_STRING, ...parameters } = {}, stringValueBlockType) {
|
|
super(parameters, stringValueBlockType);
|
|
if (value) {
|
|
this.fromString(value);
|
|
}
|
|
}
|
|
getValue() {
|
|
return this.valueBlock.value;
|
|
}
|
|
setValue(value) {
|
|
this.valueBlock.value = value;
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, (this.lenBlock.isIndefiniteForm) ? inputLength : this.lenBlock.length);
|
|
if (resultOffset === -1) {
|
|
this.error = this.valueBlock.error;
|
|
return resultOffset;
|
|
}
|
|
this.fromBuffer(this.valueBlock.valueHexView);
|
|
if (!this.idBlock.error.length)
|
|
this.blockLength += this.idBlock.blockLength;
|
|
if (!this.lenBlock.error.length)
|
|
this.blockLength += this.lenBlock.blockLength;
|
|
if (!this.valueBlock.error.length)
|
|
this.blockLength += this.valueBlock.blockLength;
|
|
return resultOffset;
|
|
}
|
|
onAsciiEncoding() {
|
|
return `${this.constructor.NAME} : '${this.valueBlock.value}'`;
|
|
}
|
|
}
|
|
BaseStringBlock.NAME = "BaseStringBlock";
|
|
|
|
class LocalPrimitiveValueBlock extends HexBlock(ValueBlock) {
|
|
constructor({ isHexOnly = true, ...parameters } = {}) {
|
|
super(parameters);
|
|
this.isHexOnly = isHexOnly;
|
|
}
|
|
}
|
|
LocalPrimitiveValueBlock.NAME = "PrimitiveValueBlock";
|
|
|
|
var _a$w;
|
|
class Primitive extends BaseBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters, LocalPrimitiveValueBlock);
|
|
this.idBlock.isConstructed = false;
|
|
}
|
|
}
|
|
_a$w = Primitive;
|
|
(() => {
|
|
typeStore.Primitive = _a$w;
|
|
})();
|
|
Primitive.NAME = "PRIMITIVE";
|
|
|
|
function localChangeType(inputObject, newType) {
|
|
if (inputObject instanceof newType) {
|
|
return inputObject;
|
|
}
|
|
const newObject = new newType();
|
|
newObject.idBlock = inputObject.idBlock;
|
|
newObject.lenBlock = inputObject.lenBlock;
|
|
newObject.warnings = inputObject.warnings;
|
|
newObject.valueBeforeDecodeView = inputObject.valueBeforeDecodeView;
|
|
return newObject;
|
|
}
|
|
function localFromBER(inputBuffer, inputOffset = 0, inputLength = inputBuffer.length) {
|
|
const incomingOffset = inputOffset;
|
|
let returnObject = new BaseBlock({}, ValueBlock);
|
|
const baseBlock = new LocalBaseBlock();
|
|
if (!checkBufferParams(baseBlock, inputBuffer, inputOffset, inputLength)) {
|
|
returnObject.error = baseBlock.error;
|
|
return {
|
|
offset: -1,
|
|
result: returnObject
|
|
};
|
|
}
|
|
const intBuffer = inputBuffer.subarray(inputOffset, inputOffset + inputLength);
|
|
if (!intBuffer.length) {
|
|
returnObject.error = "Zero buffer length";
|
|
return {
|
|
offset: -1,
|
|
result: returnObject
|
|
};
|
|
}
|
|
let resultOffset = returnObject.idBlock.fromBER(inputBuffer, inputOffset, inputLength);
|
|
if (returnObject.idBlock.warnings.length) {
|
|
returnObject.warnings.concat(returnObject.idBlock.warnings);
|
|
}
|
|
if (resultOffset === -1) {
|
|
returnObject.error = returnObject.idBlock.error;
|
|
return {
|
|
offset: -1,
|
|
result: returnObject
|
|
};
|
|
}
|
|
inputOffset = resultOffset;
|
|
inputLength -= returnObject.idBlock.blockLength;
|
|
resultOffset = returnObject.lenBlock.fromBER(inputBuffer, inputOffset, inputLength);
|
|
if (returnObject.lenBlock.warnings.length) {
|
|
returnObject.warnings.concat(returnObject.lenBlock.warnings);
|
|
}
|
|
if (resultOffset === -1) {
|
|
returnObject.error = returnObject.lenBlock.error;
|
|
return {
|
|
offset: -1,
|
|
result: returnObject
|
|
};
|
|
}
|
|
inputOffset = resultOffset;
|
|
inputLength -= returnObject.lenBlock.blockLength;
|
|
if (!returnObject.idBlock.isConstructed &&
|
|
returnObject.lenBlock.isIndefiniteForm) {
|
|
returnObject.error = "Indefinite length form used for primitive encoding form";
|
|
return {
|
|
offset: -1,
|
|
result: returnObject
|
|
};
|
|
}
|
|
let newASN1Type = BaseBlock;
|
|
switch (returnObject.idBlock.tagClass) {
|
|
case 1:
|
|
if ((returnObject.idBlock.tagNumber >= 37) &&
|
|
(returnObject.idBlock.isHexOnly === false)) {
|
|
returnObject.error = "UNIVERSAL 37 and upper tags are reserved by ASN.1 standard";
|
|
return {
|
|
offset: -1,
|
|
result: returnObject
|
|
};
|
|
}
|
|
switch (returnObject.idBlock.tagNumber) {
|
|
case 0:
|
|
if ((returnObject.idBlock.isConstructed) &&
|
|
(returnObject.lenBlock.length > 0)) {
|
|
returnObject.error = "Type [UNIVERSAL 0] is reserved";
|
|
return {
|
|
offset: -1,
|
|
result: returnObject
|
|
};
|
|
}
|
|
newASN1Type = typeStore.EndOfContent;
|
|
break;
|
|
case 1:
|
|
newASN1Type = typeStore.Boolean;
|
|
break;
|
|
case 2:
|
|
newASN1Type = typeStore.Integer;
|
|
break;
|
|
case 3:
|
|
newASN1Type = typeStore.BitString;
|
|
break;
|
|
case 4:
|
|
newASN1Type = typeStore.OctetString;
|
|
break;
|
|
case 5:
|
|
newASN1Type = typeStore.Null;
|
|
break;
|
|
case 6:
|
|
newASN1Type = typeStore.ObjectIdentifier;
|
|
break;
|
|
case 10:
|
|
newASN1Type = typeStore.Enumerated;
|
|
break;
|
|
case 12:
|
|
newASN1Type = typeStore.Utf8String;
|
|
break;
|
|
case 13:
|
|
newASN1Type = typeStore.RelativeObjectIdentifier;
|
|
break;
|
|
case 14:
|
|
newASN1Type = typeStore.TIME;
|
|
break;
|
|
case 15:
|
|
returnObject.error = "[UNIVERSAL 15] is reserved by ASN.1 standard";
|
|
return {
|
|
offset: -1,
|
|
result: returnObject
|
|
};
|
|
case 16:
|
|
newASN1Type = typeStore.Sequence;
|
|
break;
|
|
case 17:
|
|
newASN1Type = typeStore.Set;
|
|
break;
|
|
case 18:
|
|
newASN1Type = typeStore.NumericString;
|
|
break;
|
|
case 19:
|
|
newASN1Type = typeStore.PrintableString;
|
|
break;
|
|
case 20:
|
|
newASN1Type = typeStore.TeletexString;
|
|
break;
|
|
case 21:
|
|
newASN1Type = typeStore.VideotexString;
|
|
break;
|
|
case 22:
|
|
newASN1Type = typeStore.IA5String;
|
|
break;
|
|
case 23:
|
|
newASN1Type = typeStore.UTCTime;
|
|
break;
|
|
case 24:
|
|
newASN1Type = typeStore.GeneralizedTime;
|
|
break;
|
|
case 25:
|
|
newASN1Type = typeStore.GraphicString;
|
|
break;
|
|
case 26:
|
|
newASN1Type = typeStore.VisibleString;
|
|
break;
|
|
case 27:
|
|
newASN1Type = typeStore.GeneralString;
|
|
break;
|
|
case 28:
|
|
newASN1Type = typeStore.UniversalString;
|
|
break;
|
|
case 29:
|
|
newASN1Type = typeStore.CharacterString;
|
|
break;
|
|
case 30:
|
|
newASN1Type = typeStore.BmpString;
|
|
break;
|
|
case 31:
|
|
newASN1Type = typeStore.DATE;
|
|
break;
|
|
case 32:
|
|
newASN1Type = typeStore.TimeOfDay;
|
|
break;
|
|
case 33:
|
|
newASN1Type = typeStore.DateTime;
|
|
break;
|
|
case 34:
|
|
newASN1Type = typeStore.Duration;
|
|
break;
|
|
default: {
|
|
const newObject = returnObject.idBlock.isConstructed
|
|
? new typeStore.Constructed()
|
|
: new typeStore.Primitive();
|
|
newObject.idBlock = returnObject.idBlock;
|
|
newObject.lenBlock = returnObject.lenBlock;
|
|
newObject.warnings = returnObject.warnings;
|
|
returnObject = newObject;
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
default: {
|
|
newASN1Type = returnObject.idBlock.isConstructed
|
|
? typeStore.Constructed
|
|
: typeStore.Primitive;
|
|
}
|
|
}
|
|
returnObject = localChangeType(returnObject, newASN1Type);
|
|
resultOffset = returnObject.fromBER(inputBuffer, inputOffset, returnObject.lenBlock.isIndefiniteForm ? inputLength : returnObject.lenBlock.length);
|
|
returnObject.valueBeforeDecodeView = inputBuffer.subarray(incomingOffset, incomingOffset + returnObject.blockLength);
|
|
return {
|
|
offset: resultOffset,
|
|
result: returnObject
|
|
};
|
|
}
|
|
function fromBER(inputBuffer) {
|
|
if (!inputBuffer.byteLength) {
|
|
const result = new BaseBlock({}, ValueBlock);
|
|
result.error = "Input buffer has zero length";
|
|
return {
|
|
offset: -1,
|
|
result
|
|
};
|
|
}
|
|
return localFromBER(pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer).slice(), 0, inputBuffer.byteLength);
|
|
}
|
|
|
|
function checkLen(indefiniteLength, length) {
|
|
if (indefiniteLength) {
|
|
return 1;
|
|
}
|
|
return length;
|
|
}
|
|
class LocalConstructedValueBlock extends ValueBlock {
|
|
constructor({ value = [], isIndefiniteForm = false, ...parameters } = {}) {
|
|
super(parameters);
|
|
this.value = value;
|
|
this.isIndefiniteForm = isIndefiniteForm;
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
const view = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer);
|
|
if (!checkBufferParams(this, view, inputOffset, inputLength)) {
|
|
return -1;
|
|
}
|
|
this.valueBeforeDecodeView = view.subarray(inputOffset, inputOffset + inputLength);
|
|
if (this.valueBeforeDecodeView.length === 0) {
|
|
this.warnings.push("Zero buffer length");
|
|
return inputOffset;
|
|
}
|
|
let currentOffset = inputOffset;
|
|
while (checkLen(this.isIndefiniteForm, inputLength) > 0) {
|
|
const returnObject = localFromBER(view, currentOffset, inputLength);
|
|
if (returnObject.offset === -1) {
|
|
this.error = returnObject.result.error;
|
|
this.warnings.concat(returnObject.result.warnings);
|
|
return -1;
|
|
}
|
|
currentOffset = returnObject.offset;
|
|
this.blockLength += returnObject.result.blockLength;
|
|
inputLength -= returnObject.result.blockLength;
|
|
this.value.push(returnObject.result);
|
|
if (this.isIndefiniteForm && returnObject.result.constructor.NAME === END_OF_CONTENT_NAME) {
|
|
break;
|
|
}
|
|
}
|
|
if (this.isIndefiniteForm) {
|
|
if (this.value[this.value.length - 1].constructor.NAME === END_OF_CONTENT_NAME) {
|
|
this.value.pop();
|
|
}
|
|
else {
|
|
this.warnings.push("No EndOfContent block encoded");
|
|
}
|
|
}
|
|
return currentOffset;
|
|
}
|
|
toBER(sizeOnly, writer) {
|
|
const _writer = writer || new ViewWriter();
|
|
for (let i = 0; i < this.value.length; i++) {
|
|
this.value[i].toBER(sizeOnly, _writer);
|
|
}
|
|
if (!writer) {
|
|
return _writer.final();
|
|
}
|
|
return EMPTY_BUFFER;
|
|
}
|
|
toJSON() {
|
|
const object = {
|
|
...super.toJSON(),
|
|
isIndefiniteForm: this.isIndefiniteForm,
|
|
value: [],
|
|
};
|
|
for (const value of this.value) {
|
|
object.value.push(value.toJSON());
|
|
}
|
|
return object;
|
|
}
|
|
}
|
|
LocalConstructedValueBlock.NAME = "ConstructedValueBlock";
|
|
|
|
var _a$v;
|
|
class Constructed extends BaseBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters, LocalConstructedValueBlock);
|
|
this.idBlock.isConstructed = true;
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm;
|
|
const resultOffset = this.valueBlock.fromBER(inputBuffer, inputOffset, (this.lenBlock.isIndefiniteForm) ? inputLength : this.lenBlock.length);
|
|
if (resultOffset === -1) {
|
|
this.error = this.valueBlock.error;
|
|
return resultOffset;
|
|
}
|
|
if (!this.idBlock.error.length)
|
|
this.blockLength += this.idBlock.blockLength;
|
|
if (!this.lenBlock.error.length)
|
|
this.blockLength += this.lenBlock.blockLength;
|
|
if (!this.valueBlock.error.length)
|
|
this.blockLength += this.valueBlock.blockLength;
|
|
return resultOffset;
|
|
}
|
|
onAsciiEncoding() {
|
|
const values = [];
|
|
for (const value of this.valueBlock.value) {
|
|
values.push(value.toString("ascii").split("\n").map(o => ` ${o}`).join("\n"));
|
|
}
|
|
const blockName = this.idBlock.tagClass === 3
|
|
? `[${this.idBlock.tagNumber}]`
|
|
: this.constructor.NAME;
|
|
return values.length
|
|
? `${blockName} :\n${values.join("\n")}`
|
|
: `${blockName} :`;
|
|
}
|
|
}
|
|
_a$v = Constructed;
|
|
(() => {
|
|
typeStore.Constructed = _a$v;
|
|
})();
|
|
Constructed.NAME = "CONSTRUCTED";
|
|
|
|
class LocalEndOfContentValueBlock extends ValueBlock {
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
return inputOffset;
|
|
}
|
|
toBER(sizeOnly) {
|
|
return EMPTY_BUFFER;
|
|
}
|
|
}
|
|
LocalEndOfContentValueBlock.override = "EndOfContentValueBlock";
|
|
|
|
var _a$u;
|
|
class EndOfContent extends BaseBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters, LocalEndOfContentValueBlock);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 0;
|
|
}
|
|
}
|
|
_a$u = EndOfContent;
|
|
(() => {
|
|
typeStore.EndOfContent = _a$u;
|
|
})();
|
|
EndOfContent.NAME = END_OF_CONTENT_NAME;
|
|
|
|
var _a$t;
|
|
class Null extends BaseBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters, ValueBlock);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 5;
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
if (this.lenBlock.length > 0)
|
|
this.warnings.push("Non-zero length of value block for Null type");
|
|
if (!this.idBlock.error.length)
|
|
this.blockLength += this.idBlock.blockLength;
|
|
if (!this.lenBlock.error.length)
|
|
this.blockLength += this.lenBlock.blockLength;
|
|
this.blockLength += inputLength;
|
|
if ((inputOffset + inputLength) > inputBuffer.byteLength) {
|
|
this.error = "End of input reached before message was fully decoded (inconsistent offset and length values)";
|
|
return -1;
|
|
}
|
|
return (inputOffset + inputLength);
|
|
}
|
|
toBER(sizeOnly, writer) {
|
|
const retBuf = new ArrayBuffer(2);
|
|
if (!sizeOnly) {
|
|
const retView = new Uint8Array(retBuf);
|
|
retView[0] = 0x05;
|
|
retView[1] = 0x00;
|
|
}
|
|
if (writer) {
|
|
writer.write(retBuf);
|
|
}
|
|
return retBuf;
|
|
}
|
|
onAsciiEncoding() {
|
|
return `${this.constructor.NAME}`;
|
|
}
|
|
}
|
|
_a$t = Null;
|
|
(() => {
|
|
typeStore.Null = _a$t;
|
|
})();
|
|
Null.NAME = "NULL";
|
|
|
|
class LocalBooleanValueBlock extends HexBlock(ValueBlock) {
|
|
constructor({ value, ...parameters } = {}) {
|
|
super(parameters);
|
|
if (parameters.valueHex) {
|
|
this.valueHexView = pvtsutils.BufferSourceConverter.toUint8Array(parameters.valueHex);
|
|
}
|
|
else {
|
|
this.valueHexView = new Uint8Array(1);
|
|
}
|
|
if (value) {
|
|
this.value = value;
|
|
}
|
|
}
|
|
get value() {
|
|
for (const octet of this.valueHexView) {
|
|
if (octet > 0) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
set value(value) {
|
|
this.valueHexView[0] = value ? 0xFF : 0x00;
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer);
|
|
if (!checkBufferParams(this, inputView, inputOffset, inputLength)) {
|
|
return -1;
|
|
}
|
|
this.valueHexView = inputView.subarray(inputOffset, inputOffset + inputLength);
|
|
if (inputLength > 1)
|
|
this.warnings.push("Boolean value encoded in more then 1 octet");
|
|
this.isHexOnly = true;
|
|
pvutils.utilDecodeTC.call(this);
|
|
this.blockLength = inputLength;
|
|
return (inputOffset + inputLength);
|
|
}
|
|
toBER() {
|
|
return this.valueHexView.slice();
|
|
}
|
|
toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
value: this.value,
|
|
};
|
|
}
|
|
}
|
|
LocalBooleanValueBlock.NAME = "BooleanValueBlock";
|
|
|
|
var _a$s;
|
|
class Boolean extends BaseBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters, LocalBooleanValueBlock);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 1;
|
|
}
|
|
getValue() {
|
|
return this.valueBlock.value;
|
|
}
|
|
setValue(value) {
|
|
this.valueBlock.value = value;
|
|
}
|
|
onAsciiEncoding() {
|
|
return `${this.constructor.NAME} : ${this.getValue}`;
|
|
}
|
|
}
|
|
_a$s = Boolean;
|
|
(() => {
|
|
typeStore.Boolean = _a$s;
|
|
})();
|
|
Boolean.NAME = "BOOLEAN";
|
|
|
|
class LocalOctetStringValueBlock extends HexBlock(LocalConstructedValueBlock) {
|
|
constructor({ isConstructed = false, ...parameters } = {}) {
|
|
super(parameters);
|
|
this.isConstructed = isConstructed;
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
let resultOffset = 0;
|
|
if (this.isConstructed) {
|
|
this.isHexOnly = false;
|
|
resultOffset = LocalConstructedValueBlock.prototype.fromBER.call(this, inputBuffer, inputOffset, inputLength);
|
|
if (resultOffset === -1)
|
|
return resultOffset;
|
|
for (let i = 0; i < this.value.length; i++) {
|
|
const currentBlockName = this.value[i].constructor.NAME;
|
|
if (currentBlockName === END_OF_CONTENT_NAME) {
|
|
if (this.isIndefiniteForm)
|
|
break;
|
|
else {
|
|
this.error = "EndOfContent is unexpected, OCTET STRING may consists of OCTET STRINGs only";
|
|
return -1;
|
|
}
|
|
}
|
|
if (currentBlockName !== OCTET_STRING_NAME) {
|
|
this.error = "OCTET STRING may consists of OCTET STRINGs only";
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
this.isHexOnly = true;
|
|
resultOffset = super.fromBER(inputBuffer, inputOffset, inputLength);
|
|
this.blockLength = inputLength;
|
|
}
|
|
return resultOffset;
|
|
}
|
|
toBER(sizeOnly, writer) {
|
|
if (this.isConstructed)
|
|
return LocalConstructedValueBlock.prototype.toBER.call(this, sizeOnly, writer);
|
|
return sizeOnly
|
|
? new ArrayBuffer(this.valueHexView.byteLength)
|
|
: this.valueHexView.slice().buffer;
|
|
}
|
|
toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
isConstructed: this.isConstructed,
|
|
};
|
|
}
|
|
}
|
|
LocalOctetStringValueBlock.NAME = "OctetStringValueBlock";
|
|
|
|
var _a$r;
|
|
class OctetString extends BaseBlock {
|
|
constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
|
|
var _b, _c;
|
|
(_b = parameters.isConstructed) !== null && _b !== void 0 ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === void 0 ? void 0 : _c.length));
|
|
super({
|
|
idBlock: {
|
|
isConstructed: parameters.isConstructed,
|
|
...idBlock,
|
|
},
|
|
lenBlock: {
|
|
...lenBlock,
|
|
isIndefiniteForm: !!parameters.isIndefiniteForm,
|
|
},
|
|
...parameters,
|
|
}, LocalOctetStringValueBlock);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 4;
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
this.valueBlock.isConstructed = this.idBlock.isConstructed;
|
|
this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm;
|
|
if (inputLength === 0) {
|
|
if (this.idBlock.error.length === 0)
|
|
this.blockLength += this.idBlock.blockLength;
|
|
if (this.lenBlock.error.length === 0)
|
|
this.blockLength += this.lenBlock.blockLength;
|
|
return inputOffset;
|
|
}
|
|
if (!this.valueBlock.isConstructed) {
|
|
const view = inputBuffer instanceof ArrayBuffer ? new Uint8Array(inputBuffer) : inputBuffer;
|
|
const buf = view.subarray(inputOffset, inputOffset + inputLength);
|
|
try {
|
|
if (buf.byteLength) {
|
|
const asn = localFromBER(buf, 0, buf.byteLength);
|
|
if (asn.offset !== -1 && asn.offset === inputLength) {
|
|
this.valueBlock.value = [asn.result];
|
|
}
|
|
}
|
|
}
|
|
catch (e) {
|
|
}
|
|
}
|
|
return super.fromBER(inputBuffer, inputOffset, inputLength);
|
|
}
|
|
onAsciiEncoding() {
|
|
if (this.valueBlock.isConstructed || (this.valueBlock.value && this.valueBlock.value.length)) {
|
|
return Constructed.prototype.onAsciiEncoding.call(this);
|
|
}
|
|
return `${this.constructor.NAME} : ${pvtsutils.Convert.ToHex(this.valueBlock.valueHexView)}`;
|
|
}
|
|
getValue() {
|
|
if (!this.idBlock.isConstructed) {
|
|
return this.valueBlock.valueHexView.slice().buffer;
|
|
}
|
|
const array = [];
|
|
for (const content of this.valueBlock.value) {
|
|
if (content instanceof OctetString) {
|
|
array.push(content.valueBlock.valueHexView);
|
|
}
|
|
}
|
|
return pvtsutils.BufferSourceConverter.concat(array);
|
|
}
|
|
}
|
|
_a$r = OctetString;
|
|
(() => {
|
|
typeStore.OctetString = _a$r;
|
|
})();
|
|
OctetString.NAME = OCTET_STRING_NAME;
|
|
|
|
class LocalBitStringValueBlock extends HexBlock(LocalConstructedValueBlock) {
|
|
constructor({ unusedBits = 0, isConstructed = false, ...parameters } = {}) {
|
|
super(parameters);
|
|
this.unusedBits = unusedBits;
|
|
this.isConstructed = isConstructed;
|
|
this.blockLength = this.valueHexView.byteLength;
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
if (!inputLength) {
|
|
return inputOffset;
|
|
}
|
|
let resultOffset = -1;
|
|
if (this.isConstructed) {
|
|
resultOffset = LocalConstructedValueBlock.prototype.fromBER.call(this, inputBuffer, inputOffset, inputLength);
|
|
if (resultOffset === -1)
|
|
return resultOffset;
|
|
for (const value of this.value) {
|
|
const currentBlockName = value.constructor.NAME;
|
|
if (currentBlockName === END_OF_CONTENT_NAME) {
|
|
if (this.isIndefiniteForm)
|
|
break;
|
|
else {
|
|
this.error = "EndOfContent is unexpected, BIT STRING may consists of BIT STRINGs only";
|
|
return -1;
|
|
}
|
|
}
|
|
if (currentBlockName !== BIT_STRING_NAME) {
|
|
this.error = "BIT STRING may consists of BIT STRINGs only";
|
|
return -1;
|
|
}
|
|
const valueBlock = value.valueBlock;
|
|
if ((this.unusedBits > 0) && (valueBlock.unusedBits > 0)) {
|
|
this.error = "Using of \"unused bits\" inside constructive BIT STRING allowed for least one only";
|
|
return -1;
|
|
}
|
|
this.unusedBits = valueBlock.unusedBits;
|
|
}
|
|
return resultOffset;
|
|
}
|
|
const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer);
|
|
if (!checkBufferParams(this, inputView, inputOffset, inputLength)) {
|
|
return -1;
|
|
}
|
|
const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength);
|
|
this.unusedBits = intBuffer[0];
|
|
if (this.unusedBits > 7) {
|
|
this.error = "Unused bits for BitString must be in range 0-7";
|
|
return -1;
|
|
}
|
|
if (!this.unusedBits) {
|
|
const buf = intBuffer.subarray(1);
|
|
try {
|
|
if (buf.byteLength) {
|
|
const asn = localFromBER(buf, 0, buf.byteLength);
|
|
if (asn.offset !== -1 && asn.offset === (inputLength - 1)) {
|
|
this.value = [asn.result];
|
|
}
|
|
}
|
|
}
|
|
catch (e) {
|
|
}
|
|
}
|
|
this.valueHexView = intBuffer.subarray(1);
|
|
this.blockLength = intBuffer.length;
|
|
return (inputOffset + inputLength);
|
|
}
|
|
toBER(sizeOnly, writer) {
|
|
if (this.isConstructed) {
|
|
return LocalConstructedValueBlock.prototype.toBER.call(this, sizeOnly, writer);
|
|
}
|
|
if (sizeOnly) {
|
|
return new ArrayBuffer(this.valueHexView.byteLength + 1);
|
|
}
|
|
if (!this.valueHexView.byteLength) {
|
|
return EMPTY_BUFFER;
|
|
}
|
|
const retView = new Uint8Array(this.valueHexView.length + 1);
|
|
retView[0] = this.unusedBits;
|
|
retView.set(this.valueHexView, 1);
|
|
return retView.buffer;
|
|
}
|
|
toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
unusedBits: this.unusedBits,
|
|
isConstructed: this.isConstructed,
|
|
};
|
|
}
|
|
}
|
|
LocalBitStringValueBlock.NAME = "BitStringValueBlock";
|
|
|
|
var _a$q;
|
|
class BitString extends BaseBlock {
|
|
constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
|
|
var _b, _c;
|
|
(_b = parameters.isConstructed) !== null && _b !== void 0 ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === void 0 ? void 0 : _c.length));
|
|
super({
|
|
idBlock: {
|
|
isConstructed: parameters.isConstructed,
|
|
...idBlock,
|
|
},
|
|
lenBlock: {
|
|
...lenBlock,
|
|
isIndefiniteForm: !!parameters.isIndefiniteForm,
|
|
},
|
|
...parameters,
|
|
}, LocalBitStringValueBlock);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 3;
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
this.valueBlock.isConstructed = this.idBlock.isConstructed;
|
|
this.valueBlock.isIndefiniteForm = this.lenBlock.isIndefiniteForm;
|
|
return super.fromBER(inputBuffer, inputOffset, inputLength);
|
|
}
|
|
onAsciiEncoding() {
|
|
if (this.valueBlock.isConstructed || (this.valueBlock.value && this.valueBlock.value.length)) {
|
|
return Constructed.prototype.onAsciiEncoding.call(this);
|
|
}
|
|
else {
|
|
const bits = [];
|
|
const valueHex = this.valueBlock.valueHexView;
|
|
for (const byte of valueHex) {
|
|
bits.push(byte.toString(2).padStart(8, "0"));
|
|
}
|
|
const bitsStr = bits.join("");
|
|
return `${this.constructor.NAME} : ${bitsStr.substring(0, bitsStr.length - this.valueBlock.unusedBits)}`;
|
|
}
|
|
}
|
|
}
|
|
_a$q = BitString;
|
|
(() => {
|
|
typeStore.BitString = _a$q;
|
|
})();
|
|
BitString.NAME = BIT_STRING_NAME;
|
|
|
|
var _a$p;
|
|
function viewAdd(first, second) {
|
|
const c = new Uint8Array([0]);
|
|
const firstView = new Uint8Array(first);
|
|
const secondView = new Uint8Array(second);
|
|
let firstViewCopy = firstView.slice(0);
|
|
const firstViewCopyLength = firstViewCopy.length - 1;
|
|
const secondViewCopy = secondView.slice(0);
|
|
const secondViewCopyLength = secondViewCopy.length - 1;
|
|
let value = 0;
|
|
const max = (secondViewCopyLength < firstViewCopyLength) ? firstViewCopyLength : secondViewCopyLength;
|
|
let counter = 0;
|
|
for (let i = max; i >= 0; i--, counter++) {
|
|
switch (true) {
|
|
case (counter < secondViewCopy.length):
|
|
value = firstViewCopy[firstViewCopyLength - counter] + secondViewCopy[secondViewCopyLength - counter] + c[0];
|
|
break;
|
|
default:
|
|
value = firstViewCopy[firstViewCopyLength - counter] + c[0];
|
|
}
|
|
c[0] = value / 10;
|
|
switch (true) {
|
|
case (counter >= firstViewCopy.length):
|
|
firstViewCopy = pvutils.utilConcatView(new Uint8Array([value % 10]), firstViewCopy);
|
|
break;
|
|
default:
|
|
firstViewCopy[firstViewCopyLength - counter] = value % 10;
|
|
}
|
|
}
|
|
if (c[0] > 0)
|
|
firstViewCopy = pvutils.utilConcatView(c, firstViewCopy);
|
|
return firstViewCopy;
|
|
}
|
|
function power2(n) {
|
|
if (n >= powers2.length) {
|
|
for (let p = powers2.length; p <= n; p++) {
|
|
const c = new Uint8Array([0]);
|
|
let digits = (powers2[p - 1]).slice(0);
|
|
for (let i = (digits.length - 1); i >= 0; i--) {
|
|
const newValue = new Uint8Array([(digits[i] << 1) + c[0]]);
|
|
c[0] = newValue[0] / 10;
|
|
digits[i] = newValue[0] % 10;
|
|
}
|
|
if (c[0] > 0)
|
|
digits = pvutils.utilConcatView(c, digits);
|
|
powers2.push(digits);
|
|
}
|
|
}
|
|
return powers2[n];
|
|
}
|
|
function viewSub(first, second) {
|
|
let b = 0;
|
|
const firstView = new Uint8Array(first);
|
|
const secondView = new Uint8Array(second);
|
|
const firstViewCopy = firstView.slice(0);
|
|
const firstViewCopyLength = firstViewCopy.length - 1;
|
|
const secondViewCopy = secondView.slice(0);
|
|
const secondViewCopyLength = secondViewCopy.length - 1;
|
|
let value;
|
|
let counter = 0;
|
|
for (let i = secondViewCopyLength; i >= 0; i--, counter++) {
|
|
value = firstViewCopy[firstViewCopyLength - counter] - secondViewCopy[secondViewCopyLength - counter] - b;
|
|
switch (true) {
|
|
case (value < 0):
|
|
b = 1;
|
|
firstViewCopy[firstViewCopyLength - counter] = value + 10;
|
|
break;
|
|
default:
|
|
b = 0;
|
|
firstViewCopy[firstViewCopyLength - counter] = value;
|
|
}
|
|
}
|
|
if (b > 0) {
|
|
for (let i = (firstViewCopyLength - secondViewCopyLength + 1); i >= 0; i--, counter++) {
|
|
value = firstViewCopy[firstViewCopyLength - counter] - b;
|
|
if (value < 0) {
|
|
b = 1;
|
|
firstViewCopy[firstViewCopyLength - counter] = value + 10;
|
|
}
|
|
else {
|
|
b = 0;
|
|
firstViewCopy[firstViewCopyLength - counter] = value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return firstViewCopy.slice();
|
|
}
|
|
class LocalIntegerValueBlock extends HexBlock(ValueBlock) {
|
|
constructor({ value, ...parameters } = {}) {
|
|
super(parameters);
|
|
this._valueDec = 0;
|
|
if (parameters.valueHex) {
|
|
this.setValueHex();
|
|
}
|
|
if (value !== undefined) {
|
|
this.valueDec = value;
|
|
}
|
|
}
|
|
setValueHex() {
|
|
if (this.valueHexView.length >= 4) {
|
|
this.warnings.push("Too big Integer for decoding, hex only");
|
|
this.isHexOnly = true;
|
|
this._valueDec = 0;
|
|
}
|
|
else {
|
|
this.isHexOnly = false;
|
|
if (this.valueHexView.length > 0) {
|
|
this._valueDec = pvutils.utilDecodeTC.call(this);
|
|
}
|
|
}
|
|
}
|
|
set valueDec(v) {
|
|
this._valueDec = v;
|
|
this.isHexOnly = false;
|
|
this.valueHexView = new Uint8Array(pvutils.utilEncodeTC(v));
|
|
}
|
|
get valueDec() {
|
|
return this._valueDec;
|
|
}
|
|
fromDER(inputBuffer, inputOffset, inputLength, expectedLength = 0) {
|
|
const offset = this.fromBER(inputBuffer, inputOffset, inputLength);
|
|
if (offset === -1)
|
|
return offset;
|
|
const view = this.valueHexView;
|
|
if ((view[0] === 0x00) && ((view[1] & 0x80) !== 0)) {
|
|
this.valueHexView = view.subarray(1);
|
|
}
|
|
else {
|
|
if (expectedLength !== 0) {
|
|
if (view.length < expectedLength) {
|
|
if ((expectedLength - view.length) > 1)
|
|
expectedLength = view.length + 1;
|
|
this.valueHexView = view.subarray(expectedLength - view.length);
|
|
}
|
|
}
|
|
}
|
|
return offset;
|
|
}
|
|
toDER(sizeOnly = false) {
|
|
const view = this.valueHexView;
|
|
switch (true) {
|
|
case ((view[0] & 0x80) !== 0):
|
|
{
|
|
const updatedView = new Uint8Array(this.valueHexView.length + 1);
|
|
updatedView[0] = 0x00;
|
|
updatedView.set(view, 1);
|
|
this.valueHexView = updatedView;
|
|
}
|
|
break;
|
|
case ((view[0] === 0x00) && ((view[1] & 0x80) === 0)):
|
|
{
|
|
this.valueHexView = this.valueHexView.subarray(1);
|
|
}
|
|
break;
|
|
}
|
|
return this.toBER(sizeOnly);
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
const resultOffset = super.fromBER(inputBuffer, inputOffset, inputLength);
|
|
if (resultOffset === -1) {
|
|
return resultOffset;
|
|
}
|
|
this.setValueHex();
|
|
return resultOffset;
|
|
}
|
|
toBER(sizeOnly) {
|
|
return sizeOnly
|
|
? new ArrayBuffer(this.valueHexView.length)
|
|
: this.valueHexView.slice().buffer;
|
|
}
|
|
toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
valueDec: this.valueDec,
|
|
};
|
|
}
|
|
toString() {
|
|
const firstBit = (this.valueHexView.length * 8) - 1;
|
|
let digits = new Uint8Array((this.valueHexView.length * 8) / 3);
|
|
let bitNumber = 0;
|
|
let currentByte;
|
|
const asn1View = this.valueHexView;
|
|
let result = "";
|
|
let flag = false;
|
|
for (let byteNumber = (asn1View.byteLength - 1); byteNumber >= 0; byteNumber--) {
|
|
currentByte = asn1View[byteNumber];
|
|
for (let i = 0; i < 8; i++) {
|
|
if ((currentByte & 1) === 1) {
|
|
switch (bitNumber) {
|
|
case firstBit:
|
|
digits = viewSub(power2(bitNumber), digits);
|
|
result = "-";
|
|
break;
|
|
default:
|
|
digits = viewAdd(digits, power2(bitNumber));
|
|
}
|
|
}
|
|
bitNumber++;
|
|
currentByte >>= 1;
|
|
}
|
|
}
|
|
for (let i = 0; i < digits.length; i++) {
|
|
if (digits[i])
|
|
flag = true;
|
|
if (flag)
|
|
result += digitsString.charAt(digits[i]);
|
|
}
|
|
if (flag === false)
|
|
result += digitsString.charAt(0);
|
|
return result;
|
|
}
|
|
}
|
|
_a$p = LocalIntegerValueBlock;
|
|
LocalIntegerValueBlock.NAME = "IntegerValueBlock";
|
|
(() => {
|
|
Object.defineProperty(_a$p.prototype, "valueHex", {
|
|
set: function (v) {
|
|
this.valueHexView = new Uint8Array(v);
|
|
this.setValueHex();
|
|
},
|
|
get: function () {
|
|
return this.valueHexView.slice().buffer;
|
|
},
|
|
});
|
|
})();
|
|
|
|
var _a$o;
|
|
class Integer extends BaseBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters, LocalIntegerValueBlock);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 2;
|
|
}
|
|
toBigInt() {
|
|
assertBigInt();
|
|
return BigInt(this.valueBlock.toString());
|
|
}
|
|
static fromBigInt(value) {
|
|
assertBigInt();
|
|
const bigIntValue = BigInt(value);
|
|
const writer = new ViewWriter();
|
|
const hex = bigIntValue.toString(16).replace(/^-/, "");
|
|
const view = new Uint8Array(pvtsutils.Convert.FromHex(hex));
|
|
if (bigIntValue < 0) {
|
|
const first = new Uint8Array(view.length + (view[0] & 0x80 ? 1 : 0));
|
|
first[0] |= 0x80;
|
|
const firstInt = BigInt(`0x${pvtsutils.Convert.ToHex(first)}`);
|
|
const secondInt = firstInt + bigIntValue;
|
|
const second = pvtsutils.BufferSourceConverter.toUint8Array(pvtsutils.Convert.FromHex(secondInt.toString(16)));
|
|
second[0] |= 0x80;
|
|
writer.write(second);
|
|
}
|
|
else {
|
|
if (view[0] & 0x80) {
|
|
writer.write(new Uint8Array([0]));
|
|
}
|
|
writer.write(view);
|
|
}
|
|
const res = new Integer({
|
|
valueHex: writer.final(),
|
|
});
|
|
return res;
|
|
}
|
|
convertToDER() {
|
|
const integer = new Integer({ valueHex: this.valueBlock.valueHexView });
|
|
integer.valueBlock.toDER();
|
|
return integer;
|
|
}
|
|
convertFromDER() {
|
|
return new Integer({
|
|
valueHex: this.valueBlock.valueHexView[0] === 0
|
|
? this.valueBlock.valueHexView.subarray(1)
|
|
: this.valueBlock.valueHexView,
|
|
});
|
|
}
|
|
onAsciiEncoding() {
|
|
return `${this.constructor.NAME} : ${this.valueBlock.toString()}`;
|
|
}
|
|
}
|
|
_a$o = Integer;
|
|
(() => {
|
|
typeStore.Integer = _a$o;
|
|
})();
|
|
Integer.NAME = "INTEGER";
|
|
|
|
var _a$n;
|
|
class Enumerated extends Integer {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 10;
|
|
}
|
|
}
|
|
_a$n = Enumerated;
|
|
(() => {
|
|
typeStore.Enumerated = _a$n;
|
|
})();
|
|
Enumerated.NAME = "ENUMERATED";
|
|
|
|
class LocalSidValueBlock extends HexBlock(ValueBlock) {
|
|
constructor({ valueDec = -1, isFirstSid = false, ...parameters } = {}) {
|
|
super(parameters);
|
|
this.valueDec = valueDec;
|
|
this.isFirstSid = isFirstSid;
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
if (!inputLength) {
|
|
return inputOffset;
|
|
}
|
|
const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer);
|
|
if (!checkBufferParams(this, inputView, inputOffset, inputLength)) {
|
|
return -1;
|
|
}
|
|
const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength);
|
|
this.valueHexView = new Uint8Array(inputLength);
|
|
for (let i = 0; i < inputLength; i++) {
|
|
this.valueHexView[i] = intBuffer[i] & 0x7F;
|
|
this.blockLength++;
|
|
if ((intBuffer[i] & 0x80) === 0x00)
|
|
break;
|
|
}
|
|
const tempView = new Uint8Array(this.blockLength);
|
|
for (let i = 0; i < this.blockLength; i++) {
|
|
tempView[i] = this.valueHexView[i];
|
|
}
|
|
this.valueHexView = tempView;
|
|
if ((intBuffer[this.blockLength - 1] & 0x80) !== 0x00) {
|
|
this.error = "End of input reached before message was fully decoded";
|
|
return -1;
|
|
}
|
|
if (this.valueHexView[0] === 0x00)
|
|
this.warnings.push("Needlessly long format of SID encoding");
|
|
if (this.blockLength <= 8)
|
|
this.valueDec = pvutils.utilFromBase(this.valueHexView, 7);
|
|
else {
|
|
this.isHexOnly = true;
|
|
this.warnings.push("Too big SID for decoding, hex only");
|
|
}
|
|
return (inputOffset + this.blockLength);
|
|
}
|
|
set valueBigInt(value) {
|
|
assertBigInt();
|
|
let bits = BigInt(value).toString(2);
|
|
while (bits.length % 7) {
|
|
bits = "0" + bits;
|
|
}
|
|
const bytes = new Uint8Array(bits.length / 7);
|
|
for (let i = 0; i < bytes.length; i++) {
|
|
bytes[i] = parseInt(bits.slice(i * 7, i * 7 + 7), 2) + (i + 1 < bytes.length ? 0x80 : 0);
|
|
}
|
|
this.fromBER(bytes.buffer, 0, bytes.length);
|
|
}
|
|
toBER(sizeOnly) {
|
|
if (this.isHexOnly) {
|
|
if (sizeOnly)
|
|
return (new ArrayBuffer(this.valueHexView.byteLength));
|
|
const curView = this.valueHexView;
|
|
const retView = new Uint8Array(this.blockLength);
|
|
for (let i = 0; i < (this.blockLength - 1); i++)
|
|
retView[i] = curView[i] | 0x80;
|
|
retView[this.blockLength - 1] = curView[this.blockLength - 1];
|
|
return retView.buffer;
|
|
}
|
|
const encodedBuf = pvutils.utilToBase(this.valueDec, 7);
|
|
if (encodedBuf.byteLength === 0) {
|
|
this.error = "Error during encoding SID value";
|
|
return EMPTY_BUFFER;
|
|
}
|
|
const retView = new Uint8Array(encodedBuf.byteLength);
|
|
if (!sizeOnly) {
|
|
const encodedView = new Uint8Array(encodedBuf);
|
|
const len = encodedBuf.byteLength - 1;
|
|
for (let i = 0; i < len; i++)
|
|
retView[i] = encodedView[i] | 0x80;
|
|
retView[len] = encodedView[len];
|
|
}
|
|
return retView;
|
|
}
|
|
toString() {
|
|
let result = "";
|
|
if (this.isHexOnly)
|
|
result = pvtsutils.Convert.ToHex(this.valueHexView);
|
|
else {
|
|
if (this.isFirstSid) {
|
|
let sidValue = this.valueDec;
|
|
if (this.valueDec <= 39)
|
|
result = "0.";
|
|
else {
|
|
if (this.valueDec <= 79) {
|
|
result = "1.";
|
|
sidValue -= 40;
|
|
}
|
|
else {
|
|
result = "2.";
|
|
sidValue -= 80;
|
|
}
|
|
}
|
|
result += sidValue.toString();
|
|
}
|
|
else
|
|
result = this.valueDec.toString();
|
|
}
|
|
return result;
|
|
}
|
|
toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
valueDec: this.valueDec,
|
|
isFirstSid: this.isFirstSid,
|
|
};
|
|
}
|
|
}
|
|
LocalSidValueBlock.NAME = "sidBlock";
|
|
|
|
class LocalObjectIdentifierValueBlock extends ValueBlock {
|
|
constructor({ value = EMPTY_STRING, ...parameters } = {}) {
|
|
super(parameters);
|
|
this.value = [];
|
|
if (value) {
|
|
this.fromString(value);
|
|
}
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
let resultOffset = inputOffset;
|
|
while (inputLength > 0) {
|
|
const sidBlock = new LocalSidValueBlock();
|
|
resultOffset = sidBlock.fromBER(inputBuffer, resultOffset, inputLength);
|
|
if (resultOffset === -1) {
|
|
this.blockLength = 0;
|
|
this.error = sidBlock.error;
|
|
return resultOffset;
|
|
}
|
|
if (this.value.length === 0)
|
|
sidBlock.isFirstSid = true;
|
|
this.blockLength += sidBlock.blockLength;
|
|
inputLength -= sidBlock.blockLength;
|
|
this.value.push(sidBlock);
|
|
}
|
|
return resultOffset;
|
|
}
|
|
toBER(sizeOnly) {
|
|
const retBuffers = [];
|
|
for (let i = 0; i < this.value.length; i++) {
|
|
const valueBuf = this.value[i].toBER(sizeOnly);
|
|
if (valueBuf.byteLength === 0) {
|
|
this.error = this.value[i].error;
|
|
return EMPTY_BUFFER;
|
|
}
|
|
retBuffers.push(valueBuf);
|
|
}
|
|
return concat(retBuffers);
|
|
}
|
|
fromString(string) {
|
|
this.value = [];
|
|
let pos1 = 0;
|
|
let pos2 = 0;
|
|
let sid = "";
|
|
let flag = false;
|
|
do {
|
|
pos2 = string.indexOf(".", pos1);
|
|
if (pos2 === -1)
|
|
sid = string.substring(pos1);
|
|
else
|
|
sid = string.substring(pos1, pos2);
|
|
pos1 = pos2 + 1;
|
|
if (flag) {
|
|
const sidBlock = this.value[0];
|
|
let plus = 0;
|
|
switch (sidBlock.valueDec) {
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
plus = 40;
|
|
break;
|
|
case 2:
|
|
plus = 80;
|
|
break;
|
|
default:
|
|
this.value = [];
|
|
return;
|
|
}
|
|
const parsedSID = parseInt(sid, 10);
|
|
if (isNaN(parsedSID))
|
|
return;
|
|
sidBlock.valueDec = parsedSID + plus;
|
|
flag = false;
|
|
}
|
|
else {
|
|
const sidBlock = new LocalSidValueBlock();
|
|
if (sid > Number.MAX_SAFE_INTEGER) {
|
|
assertBigInt();
|
|
const sidValue = BigInt(sid);
|
|
sidBlock.valueBigInt = sidValue;
|
|
}
|
|
else {
|
|
sidBlock.valueDec = parseInt(sid, 10);
|
|
if (isNaN(sidBlock.valueDec))
|
|
return;
|
|
}
|
|
if (!this.value.length) {
|
|
sidBlock.isFirstSid = true;
|
|
flag = true;
|
|
}
|
|
this.value.push(sidBlock);
|
|
}
|
|
} while (pos2 !== -1);
|
|
}
|
|
toString() {
|
|
let result = "";
|
|
let isHexOnly = false;
|
|
for (let i = 0; i < this.value.length; i++) {
|
|
isHexOnly = this.value[i].isHexOnly;
|
|
let sidStr = this.value[i].toString();
|
|
if (i !== 0)
|
|
result = `${result}.`;
|
|
if (isHexOnly) {
|
|
sidStr = `{${sidStr}}`;
|
|
if (this.value[i].isFirstSid)
|
|
result = `2.{${sidStr} - 80}`;
|
|
else
|
|
result += sidStr;
|
|
}
|
|
else
|
|
result += sidStr;
|
|
}
|
|
return result;
|
|
}
|
|
toJSON() {
|
|
const object = {
|
|
...super.toJSON(),
|
|
value: this.toString(),
|
|
sidArray: [],
|
|
};
|
|
for (let i = 0; i < this.value.length; i++) {
|
|
object.sidArray.push(this.value[i].toJSON());
|
|
}
|
|
return object;
|
|
}
|
|
}
|
|
LocalObjectIdentifierValueBlock.NAME = "ObjectIdentifierValueBlock";
|
|
|
|
var _a$m;
|
|
class ObjectIdentifier extends BaseBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters, LocalObjectIdentifierValueBlock);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 6;
|
|
}
|
|
getValue() {
|
|
return this.valueBlock.toString();
|
|
}
|
|
setValue(value) {
|
|
this.valueBlock.fromString(value);
|
|
}
|
|
onAsciiEncoding() {
|
|
return `${this.constructor.NAME} : ${this.valueBlock.toString() || "empty"}`;
|
|
}
|
|
toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
value: this.getValue(),
|
|
};
|
|
}
|
|
}
|
|
_a$m = ObjectIdentifier;
|
|
(() => {
|
|
typeStore.ObjectIdentifier = _a$m;
|
|
})();
|
|
ObjectIdentifier.NAME = "OBJECT IDENTIFIER";
|
|
|
|
class LocalRelativeSidValueBlock extends HexBlock(LocalBaseBlock) {
|
|
constructor({ valueDec = 0, ...parameters } = {}) {
|
|
super(parameters);
|
|
this.valueDec = valueDec;
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
if (inputLength === 0)
|
|
return inputOffset;
|
|
const inputView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer);
|
|
if (!checkBufferParams(this, inputView, inputOffset, inputLength))
|
|
return -1;
|
|
const intBuffer = inputView.subarray(inputOffset, inputOffset + inputLength);
|
|
this.valueHexView = new Uint8Array(inputLength);
|
|
for (let i = 0; i < inputLength; i++) {
|
|
this.valueHexView[i] = intBuffer[i] & 0x7F;
|
|
this.blockLength++;
|
|
if ((intBuffer[i] & 0x80) === 0x00)
|
|
break;
|
|
}
|
|
const tempView = new Uint8Array(this.blockLength);
|
|
for (let i = 0; i < this.blockLength; i++)
|
|
tempView[i] = this.valueHexView[i];
|
|
this.valueHexView = tempView;
|
|
if ((intBuffer[this.blockLength - 1] & 0x80) !== 0x00) {
|
|
this.error = "End of input reached before message was fully decoded";
|
|
return -1;
|
|
}
|
|
if (this.valueHexView[0] === 0x00)
|
|
this.warnings.push("Needlessly long format of SID encoding");
|
|
if (this.blockLength <= 8)
|
|
this.valueDec = pvutils.utilFromBase(this.valueHexView, 7);
|
|
else {
|
|
this.isHexOnly = true;
|
|
this.warnings.push("Too big SID for decoding, hex only");
|
|
}
|
|
return (inputOffset + this.blockLength);
|
|
}
|
|
toBER(sizeOnly) {
|
|
if (this.isHexOnly) {
|
|
if (sizeOnly)
|
|
return (new ArrayBuffer(this.valueHexView.byteLength));
|
|
const curView = this.valueHexView;
|
|
const retView = new Uint8Array(this.blockLength);
|
|
for (let i = 0; i < (this.blockLength - 1); i++)
|
|
retView[i] = curView[i] | 0x80;
|
|
retView[this.blockLength - 1] = curView[this.blockLength - 1];
|
|
return retView.buffer;
|
|
}
|
|
const encodedBuf = pvutils.utilToBase(this.valueDec, 7);
|
|
if (encodedBuf.byteLength === 0) {
|
|
this.error = "Error during encoding SID value";
|
|
return EMPTY_BUFFER;
|
|
}
|
|
const retView = new Uint8Array(encodedBuf.byteLength);
|
|
if (!sizeOnly) {
|
|
const encodedView = new Uint8Array(encodedBuf);
|
|
const len = encodedBuf.byteLength - 1;
|
|
for (let i = 0; i < len; i++)
|
|
retView[i] = encodedView[i] | 0x80;
|
|
retView[len] = encodedView[len];
|
|
}
|
|
return retView.buffer;
|
|
}
|
|
toString() {
|
|
let result = "";
|
|
if (this.isHexOnly)
|
|
result = pvtsutils.Convert.ToHex(this.valueHexView);
|
|
else {
|
|
result = this.valueDec.toString();
|
|
}
|
|
return result;
|
|
}
|
|
toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
valueDec: this.valueDec,
|
|
};
|
|
}
|
|
}
|
|
LocalRelativeSidValueBlock.NAME = "relativeSidBlock";
|
|
|
|
class LocalRelativeObjectIdentifierValueBlock extends ValueBlock {
|
|
constructor({ value = EMPTY_STRING, ...parameters } = {}) {
|
|
super(parameters);
|
|
this.value = [];
|
|
if (value) {
|
|
this.fromString(value);
|
|
}
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
let resultOffset = inputOffset;
|
|
while (inputLength > 0) {
|
|
const sidBlock = new LocalRelativeSidValueBlock();
|
|
resultOffset = sidBlock.fromBER(inputBuffer, resultOffset, inputLength);
|
|
if (resultOffset === -1) {
|
|
this.blockLength = 0;
|
|
this.error = sidBlock.error;
|
|
return resultOffset;
|
|
}
|
|
this.blockLength += sidBlock.blockLength;
|
|
inputLength -= sidBlock.blockLength;
|
|
this.value.push(sidBlock);
|
|
}
|
|
return resultOffset;
|
|
}
|
|
toBER(sizeOnly, writer) {
|
|
const retBuffers = [];
|
|
for (let i = 0; i < this.value.length; i++) {
|
|
const valueBuf = this.value[i].toBER(sizeOnly);
|
|
if (valueBuf.byteLength === 0) {
|
|
this.error = this.value[i].error;
|
|
return EMPTY_BUFFER;
|
|
}
|
|
retBuffers.push(valueBuf);
|
|
}
|
|
return concat(retBuffers);
|
|
}
|
|
fromString(string) {
|
|
this.value = [];
|
|
let pos1 = 0;
|
|
let pos2 = 0;
|
|
let sid = "";
|
|
do {
|
|
pos2 = string.indexOf(".", pos1);
|
|
if (pos2 === -1)
|
|
sid = string.substring(pos1);
|
|
else
|
|
sid = string.substring(pos1, pos2);
|
|
pos1 = pos2 + 1;
|
|
const sidBlock = new LocalRelativeSidValueBlock();
|
|
sidBlock.valueDec = parseInt(sid, 10);
|
|
if (isNaN(sidBlock.valueDec))
|
|
return true;
|
|
this.value.push(sidBlock);
|
|
} while (pos2 !== -1);
|
|
return true;
|
|
}
|
|
toString() {
|
|
let result = "";
|
|
let isHexOnly = false;
|
|
for (let i = 0; i < this.value.length; i++) {
|
|
isHexOnly = this.value[i].isHexOnly;
|
|
let sidStr = this.value[i].toString();
|
|
if (i !== 0)
|
|
result = `${result}.`;
|
|
if (isHexOnly) {
|
|
sidStr = `{${sidStr}}`;
|
|
result += sidStr;
|
|
}
|
|
else
|
|
result += sidStr;
|
|
}
|
|
return result;
|
|
}
|
|
toJSON() {
|
|
const object = {
|
|
...super.toJSON(),
|
|
value: this.toString(),
|
|
sidArray: [],
|
|
};
|
|
for (let i = 0; i < this.value.length; i++)
|
|
object.sidArray.push(this.value[i].toJSON());
|
|
return object;
|
|
}
|
|
}
|
|
LocalRelativeObjectIdentifierValueBlock.NAME = "RelativeObjectIdentifierValueBlock";
|
|
|
|
var _a$l;
|
|
class RelativeObjectIdentifier extends BaseBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters, LocalRelativeObjectIdentifierValueBlock);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 13;
|
|
}
|
|
getValue() {
|
|
return this.valueBlock.toString();
|
|
}
|
|
setValue(value) {
|
|
this.valueBlock.fromString(value);
|
|
}
|
|
onAsciiEncoding() {
|
|
return `${this.constructor.NAME} : ${this.valueBlock.toString() || "empty"}`;
|
|
}
|
|
toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
value: this.getValue(),
|
|
};
|
|
}
|
|
}
|
|
_a$l = RelativeObjectIdentifier;
|
|
(() => {
|
|
typeStore.RelativeObjectIdentifier = _a$l;
|
|
})();
|
|
RelativeObjectIdentifier.NAME = "RelativeObjectIdentifier";
|
|
|
|
var _a$k;
|
|
class Sequence extends Constructed {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 16;
|
|
}
|
|
}
|
|
_a$k = Sequence;
|
|
(() => {
|
|
typeStore.Sequence = _a$k;
|
|
})();
|
|
Sequence.NAME = "SEQUENCE";
|
|
|
|
var _a$j;
|
|
class Set extends Constructed {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 17;
|
|
}
|
|
}
|
|
_a$j = Set;
|
|
(() => {
|
|
typeStore.Set = _a$j;
|
|
})();
|
|
Set.NAME = "SET";
|
|
|
|
class LocalStringValueBlock extends HexBlock(ValueBlock) {
|
|
constructor({ ...parameters } = {}) {
|
|
super(parameters);
|
|
this.isHexOnly = true;
|
|
this.value = EMPTY_STRING;
|
|
}
|
|
toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
value: this.value,
|
|
};
|
|
}
|
|
}
|
|
LocalStringValueBlock.NAME = "StringValueBlock";
|
|
|
|
class LocalSimpleStringValueBlock extends LocalStringValueBlock {
|
|
}
|
|
LocalSimpleStringValueBlock.NAME = "SimpleStringValueBlock";
|
|
|
|
class LocalSimpleStringBlock extends BaseStringBlock {
|
|
constructor({ ...parameters } = {}) {
|
|
super(parameters, LocalSimpleStringValueBlock);
|
|
}
|
|
fromBuffer(inputBuffer) {
|
|
this.valueBlock.value = String.fromCharCode.apply(null, pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer));
|
|
}
|
|
fromString(inputString) {
|
|
const strLen = inputString.length;
|
|
const view = this.valueBlock.valueHexView = new Uint8Array(strLen);
|
|
for (let i = 0; i < strLen; i++)
|
|
view[i] = inputString.charCodeAt(i);
|
|
this.valueBlock.value = inputString;
|
|
}
|
|
}
|
|
LocalSimpleStringBlock.NAME = "SIMPLE STRING";
|
|
|
|
class LocalUtf8StringValueBlock extends LocalSimpleStringBlock {
|
|
fromBuffer(inputBuffer) {
|
|
this.valueBlock.valueHexView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer);
|
|
try {
|
|
this.valueBlock.value = pvtsutils.Convert.ToUtf8String(inputBuffer);
|
|
}
|
|
catch (ex) {
|
|
this.warnings.push(`Error during "decodeURIComponent": ${ex}, using raw string`);
|
|
this.valueBlock.value = pvtsutils.Convert.ToBinary(inputBuffer);
|
|
}
|
|
}
|
|
fromString(inputString) {
|
|
this.valueBlock.valueHexView = new Uint8Array(pvtsutils.Convert.FromUtf8String(inputString));
|
|
this.valueBlock.value = inputString;
|
|
}
|
|
}
|
|
LocalUtf8StringValueBlock.NAME = "Utf8StringValueBlock";
|
|
|
|
var _a$i;
|
|
class Utf8String extends LocalUtf8StringValueBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 12;
|
|
}
|
|
}
|
|
_a$i = Utf8String;
|
|
(() => {
|
|
typeStore.Utf8String = _a$i;
|
|
})();
|
|
Utf8String.NAME = "UTF8String";
|
|
|
|
class LocalBmpStringValueBlock extends LocalSimpleStringBlock {
|
|
fromBuffer(inputBuffer) {
|
|
this.valueBlock.value = pvtsutils.Convert.ToUtf16String(inputBuffer);
|
|
this.valueBlock.valueHexView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer);
|
|
}
|
|
fromString(inputString) {
|
|
this.valueBlock.value = inputString;
|
|
this.valueBlock.valueHexView = new Uint8Array(pvtsutils.Convert.FromUtf16String(inputString));
|
|
}
|
|
}
|
|
LocalBmpStringValueBlock.NAME = "BmpStringValueBlock";
|
|
|
|
var _a$h;
|
|
class BmpString extends LocalBmpStringValueBlock {
|
|
constructor({ ...parameters } = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 30;
|
|
}
|
|
}
|
|
_a$h = BmpString;
|
|
(() => {
|
|
typeStore.BmpString = _a$h;
|
|
})();
|
|
BmpString.NAME = "BMPString";
|
|
|
|
class LocalUniversalStringValueBlock extends LocalSimpleStringBlock {
|
|
fromBuffer(inputBuffer) {
|
|
const copyBuffer = ArrayBuffer.isView(inputBuffer) ? inputBuffer.slice().buffer : inputBuffer.slice(0);
|
|
const valueView = new Uint8Array(copyBuffer);
|
|
for (let i = 0; i < valueView.length; i += 4) {
|
|
valueView[i] = valueView[i + 3];
|
|
valueView[i + 1] = valueView[i + 2];
|
|
valueView[i + 2] = 0x00;
|
|
valueView[i + 3] = 0x00;
|
|
}
|
|
this.valueBlock.value = String.fromCharCode.apply(null, new Uint32Array(copyBuffer));
|
|
}
|
|
fromString(inputString) {
|
|
const strLength = inputString.length;
|
|
const valueHexView = this.valueBlock.valueHexView = new Uint8Array(strLength * 4);
|
|
for (let i = 0; i < strLength; i++) {
|
|
const codeBuf = pvutils.utilToBase(inputString.charCodeAt(i), 8);
|
|
const codeView = new Uint8Array(codeBuf);
|
|
if (codeView.length > 4)
|
|
continue;
|
|
const dif = 4 - codeView.length;
|
|
for (let j = (codeView.length - 1); j >= 0; j--)
|
|
valueHexView[i * 4 + j + dif] = codeView[j];
|
|
}
|
|
this.valueBlock.value = inputString;
|
|
}
|
|
}
|
|
LocalUniversalStringValueBlock.NAME = "UniversalStringValueBlock";
|
|
|
|
var _a$g;
|
|
class UniversalString extends LocalUniversalStringValueBlock {
|
|
constructor({ ...parameters } = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 28;
|
|
}
|
|
}
|
|
_a$g = UniversalString;
|
|
(() => {
|
|
typeStore.UniversalString = _a$g;
|
|
})();
|
|
UniversalString.NAME = "UniversalString";
|
|
|
|
var _a$f;
|
|
class NumericString extends LocalSimpleStringBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 18;
|
|
}
|
|
}
|
|
_a$f = NumericString;
|
|
(() => {
|
|
typeStore.NumericString = _a$f;
|
|
})();
|
|
NumericString.NAME = "NumericString";
|
|
|
|
var _a$e;
|
|
class PrintableString extends LocalSimpleStringBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 19;
|
|
}
|
|
}
|
|
_a$e = PrintableString;
|
|
(() => {
|
|
typeStore.PrintableString = _a$e;
|
|
})();
|
|
PrintableString.NAME = "PrintableString";
|
|
|
|
var _a$d;
|
|
class TeletexString extends LocalSimpleStringBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 20;
|
|
}
|
|
}
|
|
_a$d = TeletexString;
|
|
(() => {
|
|
typeStore.TeletexString = _a$d;
|
|
})();
|
|
TeletexString.NAME = "TeletexString";
|
|
|
|
var _a$c;
|
|
class VideotexString extends LocalSimpleStringBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 21;
|
|
}
|
|
}
|
|
_a$c = VideotexString;
|
|
(() => {
|
|
typeStore.VideotexString = _a$c;
|
|
})();
|
|
VideotexString.NAME = "VideotexString";
|
|
|
|
var _a$b;
|
|
class IA5String extends LocalSimpleStringBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 22;
|
|
}
|
|
}
|
|
_a$b = IA5String;
|
|
(() => {
|
|
typeStore.IA5String = _a$b;
|
|
})();
|
|
IA5String.NAME = "IA5String";
|
|
|
|
var _a$a;
|
|
class GraphicString extends LocalSimpleStringBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 25;
|
|
}
|
|
}
|
|
_a$a = GraphicString;
|
|
(() => {
|
|
typeStore.GraphicString = _a$a;
|
|
})();
|
|
GraphicString.NAME = "GraphicString";
|
|
|
|
var _a$9;
|
|
class VisibleString extends LocalSimpleStringBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 26;
|
|
}
|
|
}
|
|
_a$9 = VisibleString;
|
|
(() => {
|
|
typeStore.VisibleString = _a$9;
|
|
})();
|
|
VisibleString.NAME = "VisibleString";
|
|
|
|
var _a$8;
|
|
class GeneralString extends LocalSimpleStringBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 27;
|
|
}
|
|
}
|
|
_a$8 = GeneralString;
|
|
(() => {
|
|
typeStore.GeneralString = _a$8;
|
|
})();
|
|
GeneralString.NAME = "GeneralString";
|
|
|
|
var _a$7;
|
|
class CharacterString extends LocalSimpleStringBlock {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 29;
|
|
}
|
|
}
|
|
_a$7 = CharacterString;
|
|
(() => {
|
|
typeStore.CharacterString = _a$7;
|
|
})();
|
|
CharacterString.NAME = "CharacterString";
|
|
|
|
var _a$6;
|
|
class UTCTime extends VisibleString {
|
|
constructor({ value, valueDate, ...parameters } = {}) {
|
|
super(parameters);
|
|
this.year = 0;
|
|
this.month = 0;
|
|
this.day = 0;
|
|
this.hour = 0;
|
|
this.minute = 0;
|
|
this.second = 0;
|
|
if (value) {
|
|
this.fromString(value);
|
|
this.valueBlock.valueHexView = new Uint8Array(value.length);
|
|
for (let i = 0; i < value.length; i++)
|
|
this.valueBlock.valueHexView[i] = value.charCodeAt(i);
|
|
}
|
|
if (valueDate) {
|
|
this.fromDate(valueDate);
|
|
this.valueBlock.valueHexView = new Uint8Array(this.toBuffer());
|
|
}
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 23;
|
|
}
|
|
fromBuffer(inputBuffer) {
|
|
this.fromString(String.fromCharCode.apply(null, pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer)));
|
|
}
|
|
toBuffer() {
|
|
const str = this.toString();
|
|
const buffer = new ArrayBuffer(str.length);
|
|
const view = new Uint8Array(buffer);
|
|
for (let i = 0; i < str.length; i++)
|
|
view[i] = str.charCodeAt(i);
|
|
return buffer;
|
|
}
|
|
fromDate(inputDate) {
|
|
this.year = inputDate.getUTCFullYear();
|
|
this.month = inputDate.getUTCMonth() + 1;
|
|
this.day = inputDate.getUTCDate();
|
|
this.hour = inputDate.getUTCHours();
|
|
this.minute = inputDate.getUTCMinutes();
|
|
this.second = inputDate.getUTCSeconds();
|
|
}
|
|
toDate() {
|
|
return (new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second)));
|
|
}
|
|
fromString(inputString) {
|
|
const parser = /(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z/ig;
|
|
const parserArray = parser.exec(inputString);
|
|
if (parserArray === null) {
|
|
this.error = "Wrong input string for conversion";
|
|
return;
|
|
}
|
|
const year = parseInt(parserArray[1], 10);
|
|
if (year >= 50)
|
|
this.year = 1900 + year;
|
|
else
|
|
this.year = 2000 + year;
|
|
this.month = parseInt(parserArray[2], 10);
|
|
this.day = parseInt(parserArray[3], 10);
|
|
this.hour = parseInt(parserArray[4], 10);
|
|
this.minute = parseInt(parserArray[5], 10);
|
|
this.second = parseInt(parserArray[6], 10);
|
|
}
|
|
toString(encoding = "iso") {
|
|
if (encoding === "iso") {
|
|
const outputArray = new Array(7);
|
|
outputArray[0] = pvutils.padNumber(((this.year < 2000) ? (this.year - 1900) : (this.year - 2000)), 2);
|
|
outputArray[1] = pvutils.padNumber(this.month, 2);
|
|
outputArray[2] = pvutils.padNumber(this.day, 2);
|
|
outputArray[3] = pvutils.padNumber(this.hour, 2);
|
|
outputArray[4] = pvutils.padNumber(this.minute, 2);
|
|
outputArray[5] = pvutils.padNumber(this.second, 2);
|
|
outputArray[6] = "Z";
|
|
return outputArray.join("");
|
|
}
|
|
return super.toString(encoding);
|
|
}
|
|
onAsciiEncoding() {
|
|
return `${this.constructor.NAME} : ${this.toDate().toISOString()}`;
|
|
}
|
|
toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
year: this.year,
|
|
month: this.month,
|
|
day: this.day,
|
|
hour: this.hour,
|
|
minute: this.minute,
|
|
second: this.second,
|
|
};
|
|
}
|
|
}
|
|
_a$6 = UTCTime;
|
|
(() => {
|
|
typeStore.UTCTime = _a$6;
|
|
})();
|
|
UTCTime.NAME = "UTCTime";
|
|
|
|
var _a$5;
|
|
class GeneralizedTime extends UTCTime {
|
|
constructor(parameters = {}) {
|
|
var _b;
|
|
super(parameters);
|
|
(_b = this.millisecond) !== null && _b !== void 0 ? _b : (this.millisecond = 0);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 24;
|
|
}
|
|
fromDate(inputDate) {
|
|
super.fromDate(inputDate);
|
|
this.millisecond = inputDate.getUTCMilliseconds();
|
|
}
|
|
toDate() {
|
|
return (new Date(Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second, this.millisecond)));
|
|
}
|
|
fromString(inputString) {
|
|
let isUTC = false;
|
|
let timeString = "";
|
|
let dateTimeString = "";
|
|
let fractionPart = 0;
|
|
let parser;
|
|
let hourDifference = 0;
|
|
let minuteDifference = 0;
|
|
if (inputString[inputString.length - 1] === "Z") {
|
|
timeString = inputString.substring(0, inputString.length - 1);
|
|
isUTC = true;
|
|
}
|
|
else {
|
|
const number = new Number(inputString[inputString.length - 1]);
|
|
if (isNaN(number.valueOf()))
|
|
throw new Error("Wrong input string for conversion");
|
|
timeString = inputString;
|
|
}
|
|
if (isUTC) {
|
|
if (timeString.indexOf("+") !== -1)
|
|
throw new Error("Wrong input string for conversion");
|
|
if (timeString.indexOf("-") !== -1)
|
|
throw new Error("Wrong input string for conversion");
|
|
}
|
|
else {
|
|
let multiplier = 1;
|
|
let differencePosition = timeString.indexOf("+");
|
|
let differenceString = "";
|
|
if (differencePosition === -1) {
|
|
differencePosition = timeString.indexOf("-");
|
|
multiplier = -1;
|
|
}
|
|
if (differencePosition !== -1) {
|
|
differenceString = timeString.substring(differencePosition + 1);
|
|
timeString = timeString.substring(0, differencePosition);
|
|
if ((differenceString.length !== 2) && (differenceString.length !== 4))
|
|
throw new Error("Wrong input string for conversion");
|
|
let number = parseInt(differenceString.substring(0, 2), 10);
|
|
if (isNaN(number.valueOf()))
|
|
throw new Error("Wrong input string for conversion");
|
|
hourDifference = multiplier * number;
|
|
if (differenceString.length === 4) {
|
|
number = parseInt(differenceString.substring(2, 4), 10);
|
|
if (isNaN(number.valueOf()))
|
|
throw new Error("Wrong input string for conversion");
|
|
minuteDifference = multiplier * number;
|
|
}
|
|
}
|
|
}
|
|
let fractionPointPosition = timeString.indexOf(".");
|
|
if (fractionPointPosition === -1)
|
|
fractionPointPosition = timeString.indexOf(",");
|
|
if (fractionPointPosition !== -1) {
|
|
const fractionPartCheck = new Number(`0${timeString.substring(fractionPointPosition)}`);
|
|
if (isNaN(fractionPartCheck.valueOf()))
|
|
throw new Error("Wrong input string for conversion");
|
|
fractionPart = fractionPartCheck.valueOf();
|
|
dateTimeString = timeString.substring(0, fractionPointPosition);
|
|
}
|
|
else
|
|
dateTimeString = timeString;
|
|
switch (true) {
|
|
case (dateTimeString.length === 8):
|
|
parser = /(\d{4})(\d{2})(\d{2})/ig;
|
|
if (fractionPointPosition !== -1)
|
|
throw new Error("Wrong input string for conversion");
|
|
break;
|
|
case (dateTimeString.length === 10):
|
|
parser = /(\d{4})(\d{2})(\d{2})(\d{2})/ig;
|
|
if (fractionPointPosition !== -1) {
|
|
let fractionResult = 60 * fractionPart;
|
|
this.minute = Math.floor(fractionResult);
|
|
fractionResult = 60 * (fractionResult - this.minute);
|
|
this.second = Math.floor(fractionResult);
|
|
fractionResult = 1000 * (fractionResult - this.second);
|
|
this.millisecond = Math.floor(fractionResult);
|
|
}
|
|
break;
|
|
case (dateTimeString.length === 12):
|
|
parser = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})/ig;
|
|
if (fractionPointPosition !== -1) {
|
|
let fractionResult = 60 * fractionPart;
|
|
this.second = Math.floor(fractionResult);
|
|
fractionResult = 1000 * (fractionResult - this.second);
|
|
this.millisecond = Math.floor(fractionResult);
|
|
}
|
|
break;
|
|
case (dateTimeString.length === 14):
|
|
parser = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/ig;
|
|
if (fractionPointPosition !== -1) {
|
|
const fractionResult = 1000 * fractionPart;
|
|
this.millisecond = Math.floor(fractionResult);
|
|
}
|
|
break;
|
|
default:
|
|
throw new Error("Wrong input string for conversion");
|
|
}
|
|
const parserArray = parser.exec(dateTimeString);
|
|
if (parserArray === null)
|
|
throw new Error("Wrong input string for conversion");
|
|
for (let j = 1; j < parserArray.length; j++) {
|
|
switch (j) {
|
|
case 1:
|
|
this.year = parseInt(parserArray[j], 10);
|
|
break;
|
|
case 2:
|
|
this.month = parseInt(parserArray[j], 10);
|
|
break;
|
|
case 3:
|
|
this.day = parseInt(parserArray[j], 10);
|
|
break;
|
|
case 4:
|
|
this.hour = parseInt(parserArray[j], 10) + hourDifference;
|
|
break;
|
|
case 5:
|
|
this.minute = parseInt(parserArray[j], 10) + minuteDifference;
|
|
break;
|
|
case 6:
|
|
this.second = parseInt(parserArray[j], 10);
|
|
break;
|
|
default:
|
|
throw new Error("Wrong input string for conversion");
|
|
}
|
|
}
|
|
if (isUTC === false) {
|
|
const tempDate = new Date(this.year, this.month, this.day, this.hour, this.minute, this.second, this.millisecond);
|
|
this.year = tempDate.getUTCFullYear();
|
|
this.month = tempDate.getUTCMonth();
|
|
this.day = tempDate.getUTCDay();
|
|
this.hour = tempDate.getUTCHours();
|
|
this.minute = tempDate.getUTCMinutes();
|
|
this.second = tempDate.getUTCSeconds();
|
|
this.millisecond = tempDate.getUTCMilliseconds();
|
|
}
|
|
}
|
|
toString(encoding = "iso") {
|
|
if (encoding === "iso") {
|
|
const outputArray = [];
|
|
outputArray.push(pvutils.padNumber(this.year, 4));
|
|
outputArray.push(pvutils.padNumber(this.month, 2));
|
|
outputArray.push(pvutils.padNumber(this.day, 2));
|
|
outputArray.push(pvutils.padNumber(this.hour, 2));
|
|
outputArray.push(pvutils.padNumber(this.minute, 2));
|
|
outputArray.push(pvutils.padNumber(this.second, 2));
|
|
if (this.millisecond !== 0) {
|
|
outputArray.push(".");
|
|
outputArray.push(pvutils.padNumber(this.millisecond, 3));
|
|
}
|
|
outputArray.push("Z");
|
|
return outputArray.join("");
|
|
}
|
|
return super.toString(encoding);
|
|
}
|
|
toJSON() {
|
|
return {
|
|
...super.toJSON(),
|
|
millisecond: this.millisecond,
|
|
};
|
|
}
|
|
}
|
|
_a$5 = GeneralizedTime;
|
|
(() => {
|
|
typeStore.GeneralizedTime = _a$5;
|
|
})();
|
|
GeneralizedTime.NAME = "GeneralizedTime";
|
|
|
|
var _a$4;
|
|
class DATE extends Utf8String {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 31;
|
|
}
|
|
}
|
|
_a$4 = DATE;
|
|
(() => {
|
|
typeStore.DATE = _a$4;
|
|
})();
|
|
DATE.NAME = "DATE";
|
|
|
|
var _a$3;
|
|
class TimeOfDay extends Utf8String {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 32;
|
|
}
|
|
}
|
|
_a$3 = TimeOfDay;
|
|
(() => {
|
|
typeStore.TimeOfDay = _a$3;
|
|
})();
|
|
TimeOfDay.NAME = "TimeOfDay";
|
|
|
|
var _a$2;
|
|
class DateTime extends Utf8String {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 33;
|
|
}
|
|
}
|
|
_a$2 = DateTime;
|
|
(() => {
|
|
typeStore.DateTime = _a$2;
|
|
})();
|
|
DateTime.NAME = "DateTime";
|
|
|
|
var _a$1;
|
|
class Duration extends Utf8String {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 34;
|
|
}
|
|
}
|
|
_a$1 = Duration;
|
|
(() => {
|
|
typeStore.Duration = _a$1;
|
|
})();
|
|
Duration.NAME = "Duration";
|
|
|
|
var _a;
|
|
class TIME extends Utf8String {
|
|
constructor(parameters = {}) {
|
|
super(parameters);
|
|
this.idBlock.tagClass = 1;
|
|
this.idBlock.tagNumber = 14;
|
|
}
|
|
}
|
|
_a = TIME;
|
|
(() => {
|
|
typeStore.TIME = _a;
|
|
})();
|
|
TIME.NAME = "TIME";
|
|
|
|
class Any {
|
|
constructor({ name = EMPTY_STRING, optional = false, } = {}) {
|
|
this.name = name;
|
|
this.optional = optional;
|
|
}
|
|
}
|
|
|
|
class Choice extends Any {
|
|
constructor({ value = [], ...parameters } = {}) {
|
|
super(parameters);
|
|
this.value = value;
|
|
}
|
|
}
|
|
|
|
class Repeated extends Any {
|
|
constructor({ value = new Any(), local = false, ...parameters } = {}) {
|
|
super(parameters);
|
|
this.value = value;
|
|
this.local = local;
|
|
}
|
|
}
|
|
|
|
class RawData {
|
|
constructor({ data = EMPTY_VIEW } = {}) {
|
|
this.dataView = pvtsutils.BufferSourceConverter.toUint8Array(data);
|
|
}
|
|
get data() {
|
|
return this.dataView.slice().buffer;
|
|
}
|
|
set data(value) {
|
|
this.dataView = pvtsutils.BufferSourceConverter.toUint8Array(value);
|
|
}
|
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
|
const endLength = inputOffset + inputLength;
|
|
this.dataView = pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer).subarray(inputOffset, endLength);
|
|
return endLength;
|
|
}
|
|
toBER(sizeOnly) {
|
|
return this.dataView.slice().buffer;
|
|
}
|
|
}
|
|
|
|
function compareSchema(root, inputData, inputSchema) {
|
|
if (inputSchema instanceof Choice) {
|
|
for (let j = 0; j < inputSchema.value.length; j++) {
|
|
const result = compareSchema(root, inputData, inputSchema.value[j]);
|
|
if (result.verified) {
|
|
return {
|
|
verified: true,
|
|
result: root
|
|
};
|
|
}
|
|
}
|
|
{
|
|
const _result = {
|
|
verified: false,
|
|
result: {
|
|
error: "Wrong values for Choice type"
|
|
},
|
|
};
|
|
if (inputSchema.hasOwnProperty(NAME))
|
|
_result.name = inputSchema.name;
|
|
return _result;
|
|
}
|
|
}
|
|
if (inputSchema instanceof Any) {
|
|
if (inputSchema.hasOwnProperty(NAME))
|
|
root[inputSchema.name] = inputData;
|
|
return {
|
|
verified: true,
|
|
result: root
|
|
};
|
|
}
|
|
if ((root instanceof Object) === false) {
|
|
return {
|
|
verified: false,
|
|
result: { error: "Wrong root object" }
|
|
};
|
|
}
|
|
if ((inputData instanceof Object) === false) {
|
|
return {
|
|
verified: false,
|
|
result: { error: "Wrong ASN.1 data" }
|
|
};
|
|
}
|
|
if ((inputSchema instanceof Object) === false) {
|
|
return {
|
|
verified: false,
|
|
result: { error: "Wrong ASN.1 schema" }
|
|
};
|
|
}
|
|
if ((ID_BLOCK in inputSchema) === false) {
|
|
return {
|
|
verified: false,
|
|
result: { error: "Wrong ASN.1 schema" }
|
|
};
|
|
}
|
|
if ((FROM_BER in inputSchema.idBlock) === false) {
|
|
return {
|
|
verified: false,
|
|
result: { error: "Wrong ASN.1 schema" }
|
|
};
|
|
}
|
|
if ((TO_BER in inputSchema.idBlock) === false) {
|
|
return {
|
|
verified: false,
|
|
result: { error: "Wrong ASN.1 schema" }
|
|
};
|
|
}
|
|
const encodedId = inputSchema.idBlock.toBER(false);
|
|
if (encodedId.byteLength === 0) {
|
|
return {
|
|
verified: false,
|
|
result: { error: "Error encoding idBlock for ASN.1 schema" }
|
|
};
|
|
}
|
|
const decodedOffset = inputSchema.idBlock.fromBER(encodedId, 0, encodedId.byteLength);
|
|
if (decodedOffset === -1) {
|
|
return {
|
|
verified: false,
|
|
result: { error: "Error decoding idBlock for ASN.1 schema" }
|
|
};
|
|
}
|
|
if (inputSchema.idBlock.hasOwnProperty(TAG_CLASS) === false) {
|
|
return {
|
|
verified: false,
|
|
result: { error: "Wrong ASN.1 schema" }
|
|
};
|
|
}
|
|
if (inputSchema.idBlock.tagClass !== inputData.idBlock.tagClass) {
|
|
return {
|
|
verified: false,
|
|
result: root
|
|
};
|
|
}
|
|
if (inputSchema.idBlock.hasOwnProperty(TAG_NUMBER) === false) {
|
|
return {
|
|
verified: false,
|
|
result: { error: "Wrong ASN.1 schema" }
|
|
};
|
|
}
|
|
if (inputSchema.idBlock.tagNumber !== inputData.idBlock.tagNumber) {
|
|
return {
|
|
verified: false,
|
|
result: root
|
|
};
|
|
}
|
|
if (inputSchema.idBlock.hasOwnProperty(IS_CONSTRUCTED) === false) {
|
|
return {
|
|
verified: false,
|
|
result: { error: "Wrong ASN.1 schema" }
|
|
};
|
|
}
|
|
if (inputSchema.idBlock.isConstructed !== inputData.idBlock.isConstructed) {
|
|
return {
|
|
verified: false,
|
|
result: root
|
|
};
|
|
}
|
|
if (!(IS_HEX_ONLY in inputSchema.idBlock)) {
|
|
return {
|
|
verified: false,
|
|
result: { error: "Wrong ASN.1 schema" }
|
|
};
|
|
}
|
|
if (inputSchema.idBlock.isHexOnly !== inputData.idBlock.isHexOnly) {
|
|
return {
|
|
verified: false,
|
|
result: root
|
|
};
|
|
}
|
|
if (inputSchema.idBlock.isHexOnly) {
|
|
if ((VALUE_HEX_VIEW in inputSchema.idBlock) === false) {
|
|
return {
|
|
verified: false,
|
|
result: { error: "Wrong ASN.1 schema" }
|
|
};
|
|
}
|
|
const schemaView = inputSchema.idBlock.valueHexView;
|
|
const asn1View = inputData.idBlock.valueHexView;
|
|
if (schemaView.length !== asn1View.length) {
|
|
return {
|
|
verified: false,
|
|
result: root
|
|
};
|
|
}
|
|
for (let i = 0; i < schemaView.length; i++) {
|
|
if (schemaView[i] !== asn1View[1]) {
|
|
return {
|
|
verified: false,
|
|
result: root
|
|
};
|
|
}
|
|
}
|
|
}
|
|
if (inputSchema.name) {
|
|
inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING);
|
|
if (inputSchema.name)
|
|
root[inputSchema.name] = inputData;
|
|
}
|
|
if (inputSchema instanceof typeStore.Constructed) {
|
|
let admission = 0;
|
|
let result = {
|
|
verified: false,
|
|
result: {
|
|
error: "Unknown error",
|
|
}
|
|
};
|
|
let maxLength = inputSchema.valueBlock.value.length;
|
|
if (maxLength > 0) {
|
|
if (inputSchema.valueBlock.value[0] instanceof Repeated) {
|
|
maxLength = inputData.valueBlock.value.length;
|
|
}
|
|
}
|
|
if (maxLength === 0) {
|
|
return {
|
|
verified: true,
|
|
result: root
|
|
};
|
|
}
|
|
if ((inputData.valueBlock.value.length === 0) &&
|
|
(inputSchema.valueBlock.value.length !== 0)) {
|
|
let _optional = true;
|
|
for (let i = 0; i < inputSchema.valueBlock.value.length; i++)
|
|
_optional = _optional && (inputSchema.valueBlock.value[i].optional || false);
|
|
if (_optional) {
|
|
return {
|
|
verified: true,
|
|
result: root
|
|
};
|
|
}
|
|
if (inputSchema.name) {
|
|
inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING);
|
|
if (inputSchema.name)
|
|
delete root[inputSchema.name];
|
|
}
|
|
root.error = "Inconsistent object length";
|
|
return {
|
|
verified: false,
|
|
result: root
|
|
};
|
|
}
|
|
for (let i = 0; i < maxLength; i++) {
|
|
if ((i - admission) >= inputData.valueBlock.value.length) {
|
|
if (inputSchema.valueBlock.value[i].optional === false) {
|
|
const _result = {
|
|
verified: false,
|
|
result: root
|
|
};
|
|
root.error = "Inconsistent length between ASN.1 data and schema";
|
|
if (inputSchema.name) {
|
|
inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING);
|
|
if (inputSchema.name) {
|
|
delete root[inputSchema.name];
|
|
_result.name = inputSchema.name;
|
|
}
|
|
}
|
|
return _result;
|
|
}
|
|
}
|
|
else {
|
|
if (inputSchema.valueBlock.value[0] instanceof Repeated) {
|
|
result = compareSchema(root, inputData.valueBlock.value[i], inputSchema.valueBlock.value[0].value);
|
|
if (result.verified === false) {
|
|
if (inputSchema.valueBlock.value[0].optional)
|
|
admission++;
|
|
else {
|
|
if (inputSchema.name) {
|
|
inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING);
|
|
if (inputSchema.name)
|
|
delete root[inputSchema.name];
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
if ((NAME in inputSchema.valueBlock.value[0]) && (inputSchema.valueBlock.value[0].name.length > 0)) {
|
|
let arrayRoot = {};
|
|
if ((LOCAL in inputSchema.valueBlock.value[0]) && (inputSchema.valueBlock.value[0].local))
|
|
arrayRoot = inputData;
|
|
else
|
|
arrayRoot = root;
|
|
if (typeof arrayRoot[inputSchema.valueBlock.value[0].name] === "undefined")
|
|
arrayRoot[inputSchema.valueBlock.value[0].name] = [];
|
|
arrayRoot[inputSchema.valueBlock.value[0].name].push(inputData.valueBlock.value[i]);
|
|
}
|
|
}
|
|
else {
|
|
result = compareSchema(root, inputData.valueBlock.value[i - admission], inputSchema.valueBlock.value[i]);
|
|
if (result.verified === false) {
|
|
if (inputSchema.valueBlock.value[i].optional)
|
|
admission++;
|
|
else {
|
|
if (inputSchema.name) {
|
|
inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING);
|
|
if (inputSchema.name)
|
|
delete root[inputSchema.name];
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (result.verified === false) {
|
|
const _result = {
|
|
verified: false,
|
|
result: root
|
|
};
|
|
if (inputSchema.name) {
|
|
inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING);
|
|
if (inputSchema.name) {
|
|
delete root[inputSchema.name];
|
|
_result.name = inputSchema.name;
|
|
}
|
|
}
|
|
return _result;
|
|
}
|
|
return {
|
|
verified: true,
|
|
result: root
|
|
};
|
|
}
|
|
if (inputSchema.primitiveSchema &&
|
|
(VALUE_HEX_VIEW in inputData.valueBlock)) {
|
|
const asn1 = localFromBER(inputData.valueBlock.valueHexView);
|
|
if (asn1.offset === -1) {
|
|
const _result = {
|
|
verified: false,
|
|
result: asn1.result
|
|
};
|
|
if (inputSchema.name) {
|
|
inputSchema.name = inputSchema.name.replace(/^\s+|\s+$/g, EMPTY_STRING);
|
|
if (inputSchema.name) {
|
|
delete root[inputSchema.name];
|
|
_result.name = inputSchema.name;
|
|
}
|
|
}
|
|
return _result;
|
|
}
|
|
return compareSchema(root, asn1.result, inputSchema.primitiveSchema);
|
|
}
|
|
return {
|
|
verified: true,
|
|
result: root
|
|
};
|
|
}
|
|
function verifySchema(inputBuffer, inputSchema) {
|
|
if ((inputSchema instanceof Object) === false) {
|
|
return {
|
|
verified: false,
|
|
result: { error: "Wrong ASN.1 schema type" }
|
|
};
|
|
}
|
|
const asn1 = localFromBER(pvtsutils.BufferSourceConverter.toUint8Array(inputBuffer));
|
|
if (asn1.offset === -1) {
|
|
return {
|
|
verified: false,
|
|
result: asn1.result
|
|
};
|
|
}
|
|
return compareSchema(asn1.result, asn1.result, inputSchema);
|
|
}
|
|
|
|
export { Any, BaseBlock, BaseStringBlock, BitString, BmpString, Boolean, CharacterString, Choice, Constructed, DATE, DateTime, Duration, EndOfContent, Enumerated, GeneralString, GeneralizedTime, GraphicString, HexBlock, IA5String, Integer, Null, NumericString, ObjectIdentifier, OctetString, Primitive, PrintableString, RawData, RelativeObjectIdentifier, Repeated, Sequence, Set, TIME, TeletexString, TimeOfDay, UTCTime, UniversalString, Utf8String, ValueBlock, VideotexString, ViewWriter, VisibleString, compareSchema, fromBER, verifySchema };
|