Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
timestamp.js213 linesDownload Raw Back to rfc3161
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.RFC3161Timestamp = 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 error_1 = require("./error");
56const tstinfo_1 = require("./tstinfo");
57const OID_PKCS9_CONTENT_TYPE_SIGNED_DATA = '1.2.840.113549.1.7.2';
58const OID_PKCS9_CONTENT_TYPE_TSTINFO = '1.2.840.113549.1.9.16.1.4';
59const OID_PKCS9_MESSAGE_DIGEST_KEY = '1.2.840.113549.1.9.4';
60class RFC3161Timestamp {
61    root;
62    constructor(asn1) {
63        this.root = asn1;
64    }
65    static parse(der) {
66        const asn1 = asn1_1.ASN1Obj.parseBuffer(der);
67        return new RFC3161Timestamp(asn1);
68    }
69    get status() {
70        return this.pkiStatusInfoObj.subs[0].toInteger();
71    }
72    get contentType() {
73        return this.contentTypeObj.toOID();
74    }
75    get eContentType() {
76        return this.eContentTypeObj.toOID();
77    }
78    get signingTime() {
79        return this.tstInfo.genTime;
80    }
81    get signerIssuer() {
82        return this.signerSidObj.subs[0].value;
83    }
84    get signerSerialNumber() {
85        return this.signerSidObj.subs[1].value;
86    }
87    get signerDigestAlgorithm() {
88        const oid = this.signerDigestAlgorithmObj.subs[0].toOID();
89        return oid_1.SHA2_HASH_ALGOS[oid];
90    }
91    get signatureAlgorithm() {
92        const oid = this.signatureAlgorithmObj.subs[0].toOID();
93        return oid_1.ECDSA_SIGNATURE_ALGOS[oid];
94    }
95    get signatureValue() {
96        return this.signatureValueObj.value;
97    }
98    get tstInfo() {
99        // Need to unpack tstInfo from an OCTET STRING
100        return new tstinfo_1.TSTInfo(this.eContentObj.subs[0].subs[0]);
101    }
102    verify(data, publicKey) {
103        if (!this.timeStampTokenObj) {
104            throw new error_1.RFC3161TimestampVerificationError('timeStampToken is missing');
105        }
106        // Check for expected ContentInfo content type
107        if (this.contentType !== OID_PKCS9_CONTENT_TYPE_SIGNED_DATA) {
108            throw new error_1.RFC3161TimestampVerificationError(`incorrect content type: ${this.contentType}`);
109        }
110        // Check for expected encapsulated content type
111        if (this.eContentType !== OID_PKCS9_CONTENT_TYPE_TSTINFO) {
112            throw new error_1.RFC3161TimestampVerificationError(`incorrect encapsulated content type: ${this.eContentType}`);
113        }
114        // Check that the tstInfo references the correct artifact
115        this.tstInfo.verify(data);
116        // Check that the signed message digest matches the tstInfo
117        this.verifyMessageDigest();
118        // Check that the signature is valid for the signed attributes
119        this.verifySignature(publicKey);
120    }
121    verifyMessageDigest() {
122        // Check that the tstInfo matches the signed data
123        const tstInfoDigest = crypto.digest(this.signerDigestAlgorithm, this.tstInfo.raw);
124        const expectedDigest = this.messageDigestAttributeObj.subs[1].subs[0].value;
125        if (!crypto.bufferEqual(tstInfoDigest, expectedDigest)) {
126            throw new error_1.RFC3161TimestampVerificationError('signed data does not match tstInfo');
127        }
128    }
129    verifySignature(key) {
130        // Encode the signed attributes for verification
131        const signedAttrs = this.signedAttrsObj.toDER();
132        signedAttrs[0] = 0x31; // Change context-specific tag to SET
133        // Check that the signature is valid for the signed attributes
134        const verified = crypto.verify(signedAttrs, key, this.signatureValue, this.signatureAlgorithm);
135        if (!verified) {
136            throw new error_1.RFC3161TimestampVerificationError('signature verification failed');
137        }
138    }
139    // https://www.rfc-editor.org/rfc/rfc3161#section-2.4.2
140    get pkiStatusInfoObj() {
141        // pkiStatusInfo is the first element of the timestamp response sequence
142        return this.root.subs[0];
143    }
144    // https://www.rfc-editor.org/rfc/rfc3161#section-2.4.2
145    get timeStampTokenObj() {
146        // timeStampToken is the first element of the timestamp response sequence
147        return this.root.subs[1];
148    }
149    // https://datatracker.ietf.org/doc/html/rfc5652#section-3
150    get contentTypeObj() {
151        return this.timeStampTokenObj.subs[0];
152    }
153    // https://www.rfc-editor.org/rfc/rfc5652#section-3
154    get signedDataObj() {
155        const obj = this.timeStampTokenObj.subs.find((sub) => sub.tag.isContextSpecific(0x00));
156        return obj.subs[0];
157    }
158    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.1
159    get encapContentInfoObj() {
160        return this.signedDataObj.subs[2];
161    }
162    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.1
163    get signerInfosObj() {
164        // SignerInfos is the last element of the signed data sequence
165        const sd = this.signedDataObj;
166        return sd.subs[sd.subs.length - 1];
167    }
168    // https://www.rfc-editor.org/rfc/rfc5652#section-5.1
169    get signerInfoObj() {
170        // Only supporting one signer
171        return this.signerInfosObj.subs[0];
172    }
173    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.2
174    get eContentTypeObj() {
175        return this.encapContentInfoObj.subs[0];
176    }
177    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.2
178    get eContentObj() {
179        return this.encapContentInfoObj.subs[1];
180    }
181    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
182    get signedAttrsObj() {
183        const signedAttrs = this.signerInfoObj.subs.find((sub) => sub.tag.isContextSpecific(0x00));
184        return signedAttrs;
185    }
186    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
187    get messageDigestAttributeObj() {
188        const messageDigest = this.signedAttrsObj.subs.find((sub) => sub.subs[0].tag.isOID() &&
189            sub.subs[0].toOID() === OID_PKCS9_MESSAGE_DIGEST_KEY);
190        return messageDigest;
191    }
192    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
193    get signerSidObj() {
194        return this.signerInfoObj.subs[1];
195    }
196    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
197    get signerDigestAlgorithmObj() {
198        // Signature is the 2nd element of the signerInfoObj object
199        return this.signerInfoObj.subs[2];
200    }
201    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
202    get signatureAlgorithmObj() {
203        // Signature is the 4th element of the signerInfoObj object
204        return this.signerInfoObj.subs[4];
205    }
206    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
207    get signatureValueObj() {
208        // Signature is the 6th element of the signerInfoObj object
209        return this.signerInfoObj.subs[5];
210    }
211}
212exports.RFC3161Timestamp = RFC3161Timestamp;
213 
codekingpro/portable-devtools · Team Ai