codekingpro/portable-devtools
114k
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 