codekingpro/portable-devtools
114k
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.verifyRFC3161Timestamp = verifyRFC3161Timestamp;
4const core_1 = require("@sigstore/core");
5const error_1 = require("../error");
6const certificate_1 = require("../key/certificate");
7const trust_1 = require("../trust");
8function verifyRFC3161Timestamp(timestamp, data, timestampAuthorities) {
9 const signingTime = timestamp.signingTime;
10 // Filter for CAs which were valid at the time of signing
11 timestampAuthorities = (0, trust_1.filterCertAuthorities)(timestampAuthorities, signingTime);
12 // Filter for CAs which match serial and issuer embedded in the timestamp
13 timestampAuthorities = filterCAsBySerialAndIssuer(timestampAuthorities, {
14 serialNumber: timestamp.signerSerialNumber,
15 issuer: timestamp.signerIssuer,
16 });
17 // Check that we can verify the timestamp with AT LEAST ONE of the remaining
18 // CAs
19 const verified = timestampAuthorities.some((ca) => {
20 try {
21 verifyTimestampForCA(timestamp, data, ca);
22 return true;
23 }
24 catch (e) {
25 return false;
26 }
27 });
28 if (!verified) {
29 throw new error_1.VerificationError({
30 code: 'TIMESTAMP_ERROR',
31 message: 'timestamp could not be verified',
32 });
33 }
34}
35function verifyTimestampForCA(timestamp, data, ca) {
36 const [leaf, ...cas] = ca.certChain;
37 const signingKey = core_1.crypto.createPublicKey(leaf.publicKey);
38 const signingTime = timestamp.signingTime;
39 // Verify the certificate chain for the provided CA
40 try {
41 new certificate_1.CertificateChainVerifier({
42 untrustedCert: leaf,
43 trustedCerts: cas,
44 timestamp: signingTime,
45 }).verify();
46 }
47 catch (e) {
48 throw new error_1.VerificationError({
49 code: 'TIMESTAMP_ERROR',
50 message: 'invalid certificate chain',
51 });
52 }
53 // Check that the signing certificate's key can be used to verify the
54 // timestamp signature.
55 timestamp.verify(data, signingKey);
56}
57// Filters the list of CAs to those which have a leaf signing certificate which
58// matches the given serial number and issuer.
59function filterCAsBySerialAndIssuer(timestampAuthorities, criteria) {
60 return timestampAuthorities.filter((ca) => ca.certChain.length > 0 &&
61 core_1.crypto.bufferEqual(ca.certChain[0].serialNumber, criteria.serialNumber) &&
62 core_1.crypto.bufferEqual(ca.certChain[0].issuer, criteria.issuer));
63}
64 