Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
obj.js156 linesDownload Raw Back to asn1
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.ASN1Obj = void 0;
4/*
5Copyright 2023 The Sigstore Authors.
6
7Licensed under the Apache License, Version 2.0 (the "License");
8you may not use this file except in compliance with the License.
9You may obtain a copy of the License at
10
11    http://www.apache.org/licenses/LICENSE-2.0
12
13Unless required by applicable law or agreed to in writing, software
14distributed under the License is distributed on an "AS IS" BASIS,
15WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16See the License for the specific language governing permissions and
17limitations under the License.
18*/
19const stream_1 = require("../stream");
20const error_1 = require("./error");
21const length_1 = require("./length");
22const parse_1 = require("./parse");
23const tag_1 = require("./tag");
24class ASN1Obj {
25    tag;
26    subs;
27    value;
28    constructor(tag, value, subs) {
29        this.tag = tag;
30        this.value = value;
31        this.subs = subs;
32    }
33    // Constructs an ASN.1 object from a Buffer of DER-encoded bytes.
34    static parseBuffer(buf) {
35        return parseStream(new stream_1.ByteStream(buf));
36    }
37    toDER() {
38        const valueStream = new stream_1.ByteStream();
39        if (this.subs.length > 0) {
40            for (const sub of this.subs) {
41                valueStream.appendView(sub.toDER());
42            }
43        }
44        else {
45            valueStream.appendView(this.value);
46        }
47        const value = valueStream.buffer;
48        // Concat tag/length/value
49        const obj = new stream_1.ByteStream();
50        obj.appendChar(this.tag.toDER());
51        obj.appendView((0, length_1.encodeLength)(value.length));
52        obj.appendView(value);
53        return obj.buffer;
54    }
55    /////////////////////////////////////////////////////////////////////////////
56    // Convenience methods for parsing ASN.1 primitives into JS types
57    // Returns the ASN.1 object's value as a boolean. Throws an error if the
58    // object is not a boolean.
59    toBoolean() {
60        if (!this.tag.isBoolean()) {
61            throw new error_1.ASN1TypeError('not a boolean');
62        }
63        return (0, parse_1.parseBoolean)(this.value);
64    }
65    // Returns the ASN.1 object's value as a BigInt. Throws an error if the
66    // object is not an integer.
67    toInteger() {
68        if (!this.tag.isInteger()) {
69            throw new error_1.ASN1TypeError('not an integer');
70        }
71        return (0, parse_1.parseInteger)(this.value);
72    }
73    // Returns the ASN.1 object's value as an OID string. Throws an error if the
74    // object is not an OID.
75    toOID() {
76        if (!this.tag.isOID()) {
77            throw new error_1.ASN1TypeError('not an OID');
78        }
79        return (0, parse_1.parseOID)(this.value);
80    }
81    // Returns the ASN.1 object's value as a Date. Throws an error if the object
82    // is not either a UTCTime or a GeneralizedTime.
83    toDate() {
84        switch (true) {
85            case this.tag.isUTCTime():
86                return (0, parse_1.parseTime)(this.value, true);
87            case this.tag.isGeneralizedTime():
88                return (0, parse_1.parseTime)(this.value, false);
89            default:
90                throw new error_1.ASN1TypeError('not a date');
91        }
92    }
93    // Returns the ASN.1 object's value as a number[] where each number is the
94    // value of a bit in the bit string. Throws an error if the object is not a
95    // bit string.
96    toBitString() {
97        if (!this.tag.isBitString()) {
98            throw new error_1.ASN1TypeError('not a bit string');
99        }
100        return (0, parse_1.parseBitString)(this.value);
101    }
102}
103exports.ASN1Obj = ASN1Obj;
104/////////////////////////////////////////////////////////////////////////////
105// Internal stream parsing functions
106function parseStream(stream) {
107    // Parse tag, length, and value from stream
108    const tag = new tag_1.ASN1Tag(stream.getUint8());
109    const len = (0, length_1.decodeLength)(stream);
110    const value = stream.slice(stream.position, len);
111    const start = stream.position;
112    let subs = [];
113    // If the object is constructed, parse its children. Sometimes, children
114    // are embedded in OCTESTRING objects, so we need to check those
115    // for children as well.
116    if (tag.constructed) {
117        subs = collectSubs(stream, len);
118    }
119    else if (tag.isOctetString()) {
120        // Attempt to parse children of OCTETSTRING objects. If anything fails,
121        // assume the object is not constructed and treat as primitive.
122        try {
123            subs = collectSubs(stream, len);
124        }
125        catch (e) {
126            // Fail silently and treat as primitive
127        }
128    }
129    // If there are no children, move stream cursor to the end of the object
130    if (subs.length === 0) {
131        stream.seek(start + len);
132    }
133    return new ASN1Obj(tag, value, subs);
134}
135function collectSubs(stream, len) {
136    // Calculate end of object content
137    const end = stream.position + len;
138    // Make sure there are enough bytes left in the stream. This should never
139    // happen, cause it'll get caught when the stream is sliced in parseStream.
140    // Leaving as an extra check just in case.
141    /* istanbul ignore if */
142    if (end > stream.length) {
143        throw new error_1.ASN1ParseError('invalid length');
144    }
145    // Parse all children
146    const subs = [];
147    while (stream.position < end) {
148        subs.push(parseStream(stream));
149    }
150    // When we're done parsing children, we should be at the end of the object
151    if (stream.position !== end) {
152        throw new error_1.ASN1ParseError('invalid length');
153    }
154    return subs;
155}
156 
codekingpro/portable-devtools · Team Ai