asn1-ts
Version:
ASN.1 encoding and decoding, including BER, CER, and DER.
41 lines (40 loc) • 1.99 kB
JavaScript
import External from "../../../types/External.mjs";
import { ASN1TagClass, ASN1UniversalType } from "../../../values.mjs";
import ASN1Element from "../../../asn1.mjs";
import * as errors from "../../../errors.mjs";
import decodeSequence from "../../der/decoders/decodeSequence.mjs";
export default function decodeExternal(value) {
const components = decodeSequence(value);
let i = 0;
const directReference = ((components[i]?.tagNumber === ASN1UniversalType.objectIdentifier)
&& (components[i].tagClass === ASN1TagClass.universal))
? components[i++].objectIdentifier
: undefined;
const indirectReference = ((components[i]?.tagNumber === ASN1UniversalType.integer)
&& (components[i].tagClass === ASN1TagClass.universal))
? components[i++].integer
: undefined;
const dataValueDescriptor = ((components[i]?.tagNumber === ASN1UniversalType.objectDescriptor)
&& (components[i].tagClass === ASN1TagClass.universal))
? components[i++].objectDescriptor
: undefined;
if (!directReference && !indirectReference) {
throw new errors.ASN1ConstructionError("EXTERNAL must have direct or indirect reference.");
}
const encodingElement = components[i];
if (!encodingElement || encodingElement.tagClass !== ASN1TagClass.context) {
throw new errors.ASN1ConstructionError("EXTERNAL missing 'encoding' component.");
}
const encoding = (() => {
switch (encodingElement.tagNumber) {
case (0): return encodingElement.inner;
case (1): return encodingElement.octetString;
case (2): return encodingElement.bitString;
default: {
throw new errors.ASN1UndefinedError("EXTERNAL does not know of an encoding option "
+ `having tag number ${encodingElement.tagNumber}.`);
}
}
})();
return new External(directReference, indirectReference, dataValueDescriptor, encoding);
}