Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
cert.js246 linesDownload Raw Back to x509
1"use strict";
2var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3    if (k2 === undefined) k2 = k;
4    var desc = Object.getOwnPropertyDescriptor(m, k);
5    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6      desc = { enumerable: true, get: function() { return m[k]; } };
7    }
8    Object.defineProperty(o, k2, desc);
9}) : (function(o, m, k, k2) {
10    if (k2 === undefined) k2 = k;
11    o[k2] = m[k];
12}));
13var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14    Object.defineProperty(o, "default", { enumerable: true, value: v });
15}) : function(o, v) {
16    o["default"] = v;
17});
18var __importStar = (this && this.__importStar) || (function () {
19    var ownKeys = function(o) {
20        ownKeys = Object.getOwnPropertyNames || function (o) {
21            var ar = [];
22            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23            return ar;
24        };
25        return ownKeys(o);
26    };
27    return function (mod) {
28        if (mod && mod.__esModule) return mod;
29        var result = {};
30        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31        __setModuleDefault(result, mod);
32        return result;
33    };
34})();
35Object.defineProperty(exports, "__esModule", { value: true });
36exports.X509Certificate = exports.EXTENSION_OID_SCT = void 0;
37/*
38Copyright 2023 The Sigstore Authors.
39
40Licensed under the Apache License, Version 2.0 (the "License");
41you may not use this file except in compliance with the License.
42You may obtain a copy of the License at
43
44    http://www.apache.org/licenses/LICENSE-2.0
45
46Unless required by applicable law or agreed to in writing, software
47distributed under the License is distributed on an "AS IS" BASIS,
48WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
49See the License for the specific language governing permissions and
50limitations under the License.
51*/
52const asn1_1 = require("../asn1");
53const crypto = __importStar(require("../crypto"));
54const oid_1 = require("../oid");
55const pem = __importStar(require("../pem"));
56const ext_1 = require("./ext");
57const EXTENSION_OID_SUBJECT_KEY_ID = '2.5.29.14';
58const EXTENSION_OID_KEY_USAGE = '2.5.29.15';
59const EXTENSION_OID_SUBJECT_ALT_NAME = '2.5.29.17';
60const EXTENSION_OID_BASIC_CONSTRAINTS = '2.5.29.19';
61const EXTENSION_OID_AUTHORITY_KEY_ID = '2.5.29.35';
62exports.EXTENSION_OID_SCT = '1.3.6.1.4.1.11129.2.4.2';
63class X509Certificate {
64    root;
65    constructor(asn1) {
66        this.root = asn1;
67    }
68    static parse(cert) {
69        const der = typeof cert === 'string' ? pem.toDER(cert) : cert;
70        const asn1 = asn1_1.ASN1Obj.parseBuffer(der);
71        return new X509Certificate(asn1);
72    }
73    get tbsCertificate() {
74        return this.tbsCertificateObj;
75    }
76    get version() {
77        // version number is the first element of the version context specific tag
78        const ver = this.versionObj.subs[0].toInteger();
79        return `v${(ver + BigInt(1)).toString()}`;
80    }
81    get serialNumber() {
82        return this.serialNumberObj.value;
83    }
84    get notBefore() {
85        // notBefore is the first element of the validity sequence
86        return this.validityObj.subs[0].toDate();
87    }
88    get notAfter() {
89        // notAfter is the second element of the validity sequence
90        return this.validityObj.subs[1].toDate();
91    }
92    get issuer() {
93        return this.issuerObj.value;
94    }
95    get subject() {
96        return this.subjectObj.value;
97    }
98    get publicKey() {
99        return this.subjectPublicKeyInfoObj.toDER();
100    }
101    get signatureAlgorithm() {
102        const oid = this.signatureAlgorithmObj.subs[0].toOID();
103        if (oid_1.RSA_SIGNATURE_ALGOS[oid]) {
104            return oid_1.RSA_SIGNATURE_ALGOS[oid];
105        }
106        return oid_1.ECDSA_SIGNATURE_ALGOS[oid];
107    }
108    get signatureValue() {
109        // Signature value is a bit string, so we need to skip the first byte
110        return this.signatureValueObj.value.subarray(1);
111    }
112    get subjectAltName() {
113        const ext = this.extSubjectAltName;
114        return ext?.uri || /* istanbul ignore next */ ext?.rfc822Name;
115    }
116    get extensions() {
117        // The extension list is the first (and only) element of the extensions
118        // context specific tag
119        /* istanbul ignore next */
120        const extSeq = this.extensionsObj?.subs[0];
121        /* istanbul ignore next */
122        return extSeq?.subs || [];
123    }
124    get extKeyUsage() {
125        const ext = this.findExtension(EXTENSION_OID_KEY_USAGE);
126        return ext ? new ext_1.X509KeyUsageExtension(ext) : undefined;
127    }
128    get extBasicConstraints() {
129        const ext = this.findExtension(EXTENSION_OID_BASIC_CONSTRAINTS);
130        return ext ? new ext_1.X509BasicConstraintsExtension(ext) : undefined;
131    }
132    get extSubjectAltName() {
133        const ext = this.findExtension(EXTENSION_OID_SUBJECT_ALT_NAME);
134        return ext ? new ext_1.X509SubjectAlternativeNameExtension(ext) : undefined;
135    }
136    get extAuthorityKeyID() {
137        const ext = this.findExtension(EXTENSION_OID_AUTHORITY_KEY_ID);
138        return ext ? new ext_1.X509AuthorityKeyIDExtension(ext) : undefined;
139    }
140    get extSubjectKeyID() {
141        const ext = this.findExtension(EXTENSION_OID_SUBJECT_KEY_ID);
142        return ext
143            ? new ext_1.X509SubjectKeyIDExtension(ext)
144            : /* istanbul ignore next */ undefined;
145    }
146    get extSCT() {
147        const ext = this.findExtension(exports.EXTENSION_OID_SCT);
148        return ext ? new ext_1.X509SCTExtension(ext) : undefined;
149    }
150    get isCA() {
151        const ca = this.extBasicConstraints?.isCA || false;
152        // If the KeyUsage extension is present, keyCertSign must be set
153        /* istanbul ignore else */
154        if (this.extKeyUsage) {
155            return ca && this.extKeyUsage.keyCertSign;
156        }
157        // TODO: test coverage for this case
158        /* istanbul ignore next */
159        return ca;
160    }
161    extension(oid) {
162        const ext = this.findExtension(oid);
163        return ext ? new ext_1.X509Extension(ext) : undefined;
164    }
165    verify(issuerCertificate) {
166        // Use the issuer's public key if provided, otherwise use the subject's
167        const publicKey = issuerCertificate?.publicKey || this.publicKey;
168        const key = crypto.createPublicKey(publicKey);
169        return crypto.verify(this.tbsCertificate.toDER(), key, this.signatureValue, this.signatureAlgorithm);
170    }
171    validForDate(date) {
172        return this.notBefore <= date && date <= this.notAfter;
173    }
174    equals(other) {
175        return this.root.toDER().equals(other.root.toDER());
176    }
177    // Creates a copy of the certificate with a new buffer
178    clone() {
179        const der = this.root.toDER();
180        const clone = Buffer.alloc(der.length);
181        der.copy(clone);
182        return X509Certificate.parse(clone);
183    }
184    findExtension(oid) {
185        // Find the extension with the given OID. The OID will always be the first
186        // element of the extension sequence
187        return this.extensions.find((ext) => ext.subs[0].toOID() === oid);
188    }
189    /////////////////////////////////////////////////////////////////////////////
190    // The following properties use the documented x509 structure to locate the
191    // desired ASN.1 object
192    // https://www.rfc-editor.org/rfc/rfc5280#section-4.1
193    // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.1.1
194    get tbsCertificateObj() {
195        // tbsCertificate is the first element of the certificate sequence
196        return this.root.subs[0];
197    }
198    // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.1.2
199    get signatureAlgorithmObj() {
200        // signatureAlgorithm is the second element of the certificate sequence
201        return this.root.subs[1];
202    }
203    // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.1.3
204    get signatureValueObj() {
205        // signatureValue is the third element of the certificate sequence
206        return this.root.subs[2];
207    }
208    // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.1
209    get versionObj() {
210        // version is the first element of the tbsCertificate sequence
211        return this.tbsCertificateObj.subs[0];
212    }
213    // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.2
214    get serialNumberObj() {
215        // serialNumber is the second element of the tbsCertificate sequence
216        return this.tbsCertificateObj.subs[1];
217    }
218    // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.4
219    get issuerObj() {
220        // issuer is the fourth element of the tbsCertificate sequence
221        return this.tbsCertificateObj.subs[3];
222    }
223    // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.5
224    get validityObj() {
225        // version is the fifth element of the tbsCertificate sequence
226        return this.tbsCertificateObj.subs[4];
227    }
228    // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.6
229    get subjectObj() {
230        // subject is the sixth element of the tbsCertificate sequence
231        return this.tbsCertificateObj.subs[5];
232    }
233    // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.7
234    get subjectPublicKeyInfoObj() {
235        // subjectPublicKeyInfo is the seventh element of the tbsCertificate sequence
236        return this.tbsCertificateObj.subs[6];
237    }
238    // Extensions can't be located by index because their position varies. Instead,
239    // we need to find the extensions context specific tag
240    // https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.9
241    get extensionsObj() {
242        return this.tbsCertificateObj.subs.find((sub) => sub.tag.isContextSpecific(0x03));
243    }
244}
245exports.X509Certificate = X509Certificate;
246 
codekingpro/portable-devtools · Team Ai