• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 (mod) {
19    if (mod && mod.__esModule) return mod;
20    var result = {};
21    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22    __setModuleDefault(result, mod);
23    return result;
24};
25Object.defineProperty(exports, "__esModule", { value: true });
26exports.RFC3161Timestamp = void 0;
27/*
28Copyright 2023 The Sigstore Authors.
29
30Licensed under the Apache License, Version 2.0 (the "License");
31you may not use this file except in compliance with the License.
32You may obtain a copy of the License at
33
34    http://www.apache.org/licenses/LICENSE-2.0
35
36Unless required by applicable law or agreed to in writing, software
37distributed under the License is distributed on an "AS IS" BASIS,
38WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39See the License for the specific language governing permissions and
40limitations under the License.
41*/
42const asn1_1 = require("../asn1");
43const crypto = __importStar(require("../crypto"));
44const oid_1 = require("../oid");
45const error_1 = require("./error");
46const tstinfo_1 = require("./tstinfo");
47const OID_PKCS9_CONTENT_TYPE_SIGNED_DATA = '1.2.840.113549.1.7.2';
48const OID_PKCS9_CONTENT_TYPE_TSTINFO = '1.2.840.113549.1.9.16.1.4';
49const OID_PKCS9_MESSAGE_DIGEST_KEY = '1.2.840.113549.1.9.4';
50class RFC3161Timestamp {
51    constructor(asn1) {
52        this.root = asn1;
53    }
54    static parse(der) {
55        const asn1 = asn1_1.ASN1Obj.parseBuffer(der);
56        return new RFC3161Timestamp(asn1);
57    }
58    get status() {
59        return this.pkiStatusInfoObj.subs[0].toInteger();
60    }
61    get contentType() {
62        return this.contentTypeObj.toOID();
63    }
64    get eContentType() {
65        return this.eContentTypeObj.toOID();
66    }
67    get signingTime() {
68        return this.tstInfo.genTime;
69    }
70    get signerIssuer() {
71        return this.signerSidObj.subs[0].value;
72    }
73    get signerSerialNumber() {
74        return this.signerSidObj.subs[1].value;
75    }
76    get signerDigestAlgorithm() {
77        const oid = this.signerDigestAlgorithmObj.subs[0].toOID();
78        return oid_1.SHA2_HASH_ALGOS[oid];
79    }
80    get signatureAlgorithm() {
81        const oid = this.signatureAlgorithmObj.subs[0].toOID();
82        return oid_1.ECDSA_SIGNATURE_ALGOS[oid];
83    }
84    get signatureValue() {
85        return this.signatureValueObj.value;
86    }
87    get tstInfo() {
88        // Need to unpack tstInfo from an OCTET STRING
89        return new tstinfo_1.TSTInfo(this.eContentObj.subs[0].subs[0]);
90    }
91    verify(data, publicKey) {
92        if (!this.timeStampTokenObj) {
93            throw new error_1.RFC3161TimestampVerificationError('timeStampToken is missing');
94        }
95        // Check for expected ContentInfo content type
96        if (this.contentType !== OID_PKCS9_CONTENT_TYPE_SIGNED_DATA) {
97            throw new error_1.RFC3161TimestampVerificationError(`incorrect content type: ${this.contentType}`);
98        }
99        // Check for expected encapsulated content type
100        if (this.eContentType !== OID_PKCS9_CONTENT_TYPE_TSTINFO) {
101            throw new error_1.RFC3161TimestampVerificationError(`incorrect encapsulated content type: ${this.eContentType}`);
102        }
103        // Check that the tstInfo references the correct artifact
104        this.tstInfo.verify(data);
105        // Check that the signed message digest matches the tstInfo
106        this.verifyMessageDigest();
107        // Check that the signature is valid for the signed attributes
108        this.verifySignature(publicKey);
109    }
110    verifyMessageDigest() {
111        // Check that the tstInfo matches the signed data
112        const tstInfoDigest = crypto.digest(this.signerDigestAlgorithm, this.tstInfo.raw);
113        const expectedDigest = this.messageDigestAttributeObj.subs[1].subs[0].value;
114        if (!crypto.bufferEqual(tstInfoDigest, expectedDigest)) {
115            throw new error_1.RFC3161TimestampVerificationError('signed data does not match tstInfo');
116        }
117    }
118    verifySignature(key) {
119        // Encode the signed attributes for verification
120        const signedAttrs = this.signedAttrsObj.toDER();
121        signedAttrs[0] = 0x31; // Change context-specific tag to SET
122        // Check that the signature is valid for the signed attributes
123        const verified = crypto.verify(signedAttrs, key, this.signatureValue, this.signatureAlgorithm);
124        if (!verified) {
125            throw new error_1.RFC3161TimestampVerificationError('signature verification failed');
126        }
127    }
128    // https://www.rfc-editor.org/rfc/rfc3161#section-2.4.2
129    get pkiStatusInfoObj() {
130        // pkiStatusInfo is the first element of the timestamp response sequence
131        return this.root.subs[0];
132    }
133    // https://www.rfc-editor.org/rfc/rfc3161#section-2.4.2
134    get timeStampTokenObj() {
135        // timeStampToken is the first element of the timestamp response sequence
136        return this.root.subs[1];
137    }
138    // https://datatracker.ietf.org/doc/html/rfc5652#section-3
139    get contentTypeObj() {
140        return this.timeStampTokenObj.subs[0];
141    }
142    // https://www.rfc-editor.org/rfc/rfc5652#section-3
143    get signedDataObj() {
144        const obj = this.timeStampTokenObj.subs.find((sub) => sub.tag.isContextSpecific(0x00));
145        return obj.subs[0];
146    }
147    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.1
148    get encapContentInfoObj() {
149        return this.signedDataObj.subs[2];
150    }
151    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.1
152    get signerInfosObj() {
153        // SignerInfos is the last element of the signed data sequence
154        const sd = this.signedDataObj;
155        return sd.subs[sd.subs.length - 1];
156    }
157    // https://www.rfc-editor.org/rfc/rfc5652#section-5.1
158    get signerInfoObj() {
159        // Only supporting one signer
160        return this.signerInfosObj.subs[0];
161    }
162    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.2
163    get eContentTypeObj() {
164        return this.encapContentInfoObj.subs[0];
165    }
166    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.2
167    get eContentObj() {
168        return this.encapContentInfoObj.subs[1];
169    }
170    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
171    get signedAttrsObj() {
172        const signedAttrs = this.signerInfoObj.subs.find((sub) => sub.tag.isContextSpecific(0x00));
173        return signedAttrs;
174    }
175    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
176    get messageDigestAttributeObj() {
177        const messageDigest = this.signedAttrsObj.subs.find((sub) => sub.subs[0].tag.isOID() &&
178            sub.subs[0].toOID() === OID_PKCS9_MESSAGE_DIGEST_KEY);
179        return messageDigest;
180    }
181    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
182    get signerSidObj() {
183        return this.signerInfoObj.subs[1];
184    }
185    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
186    get signerDigestAlgorithmObj() {
187        // Signature is the 2nd element of the signerInfoObj object
188        return this.signerInfoObj.subs[2];
189    }
190    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
191    get signatureAlgorithmObj() {
192        // Signature is the 4th element of the signerInfoObj object
193        return this.signerInfoObj.subs[4];
194    }
195    // https://datatracker.ietf.org/doc/html/rfc5652#section-5.3
196    get signatureValueObj() {
197        // Signature is the 6th element of the signerInfoObj object
198        return this.signerInfoObj.subs[5];
199    }
200}
201exports.RFC3161Timestamp = RFC3161Timestamp;
202