@freedomofpress/sigstore-browser 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/conformance.yml +29 -0
- package/.github/workflows/publish.yml +45 -0
- package/README.md +10 -0
- package/dist/asn1/error.d.ts +5 -0
- package/dist/asn1/error.d.ts.map +1 -0
- package/dist/asn1/error.js +20 -0
- package/dist/asn1/error.js.map +1 -0
- package/dist/asn1/index.d.ts +2 -0
- package/dist/asn1/index.d.ts.map +1 -0
- package/dist/asn1/index.js +17 -0
- package/dist/asn1/index.js.map +1 -0
- package/dist/asn1/length.d.ts +4 -0
- package/dist/asn1/length.d.ts.map +1 -0
- package/dist/asn1/length.js +59 -0
- package/dist/asn1/length.js.map +1 -0
- package/dist/asn1/obj.d.ts +15 -0
- package/dist/asn1/obj.d.ts.map +1 -0
- package/dist/asn1/obj.js +153 -0
- package/dist/asn1/obj.js.map +1 -0
- package/dist/asn1/parse.d.ts +7 -0
- package/dist/asn1/parse.d.ts.map +1 -0
- package/dist/asn1/parse.js +118 -0
- package/dist/asn1/parse.js.map +1 -0
- package/dist/asn1/tag.d.ts +17 -0
- package/dist/asn1/tag.d.ts.map +1 -0
- package/dist/asn1/tag.js +86 -0
- package/dist/asn1/tag.js.map +1 -0
- package/dist/bundle.d.ts +87 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +2 -0
- package/dist/bundle.js.map +1 -0
- package/dist/canonicalize.d.ts +2 -0
- package/dist/canonicalize.d.ts.map +1 -0
- package/dist/canonicalize.js +64 -0
- package/dist/canonicalize.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +217 -0
- package/dist/cli.js.map +1 -0
- package/dist/crypto.d.ts +5 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +260 -0
- package/dist/crypto.js.map +1 -0
- package/dist/dsse.d.ts +2 -0
- package/dist/dsse.d.ts.map +1 -0
- package/dist/dsse.js +42 -0
- package/dist/dsse.js.map +1 -0
- package/dist/encoding.d.ts +17 -0
- package/dist/encoding.d.ts.map +1 -0
- package/dist/encoding.js +112 -0
- package/dist/encoding.js.map +1 -0
- package/dist/errors.d.ts +39 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +79 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces.d.ts +104 -0
- package/dist/interfaces.d.ts.map +1 -0
- package/dist/interfaces.js +26 -0
- package/dist/interfaces.js.map +1 -0
- package/dist/oid.d.ts +5 -0
- package/dist/oid.d.ts.map +1 -0
- package/dist/oid.js +25 -0
- package/dist/oid.js.map +1 -0
- package/dist/pem.d.ts +3 -0
- package/dist/pem.d.ts.map +1 -0
- package/dist/pem.js +41 -0
- package/dist/pem.js.map +1 -0
- package/dist/rfc3161/error.d.ts +3 -0
- package/dist/rfc3161/error.d.ts.map +1 -0
- package/dist/rfc3161/error.js +18 -0
- package/dist/rfc3161/error.js.map +1 -0
- package/dist/rfc3161/index.d.ts +2 -0
- package/dist/rfc3161/index.d.ts.map +1 -0
- package/dist/rfc3161/index.js +17 -0
- package/dist/rfc3161/index.js.map +1 -0
- package/dist/rfc3161/timestamp.d.ts +36 -0
- package/dist/rfc3161/timestamp.d.ts.map +1 -0
- package/dist/rfc3161/timestamp.js +203 -0
- package/dist/rfc3161/timestamp.js.map +1 -0
- package/dist/rfc3161/tstinfo.d.ts +13 -0
- package/dist/rfc3161/tstinfo.d.ts.map +1 -0
- package/dist/rfc3161/tstinfo.js +47 -0
- package/dist/rfc3161/tstinfo.js.map +1 -0
- package/dist/sigstore.d.ts +33 -0
- package/dist/sigstore.d.ts.map +1 -0
- package/dist/sigstore.js +531 -0
- package/dist/sigstore.js.map +1 -0
- package/dist/stream.d.ts +22 -0
- package/dist/stream.d.ts.map +1 -0
- package/dist/stream.js +114 -0
- package/dist/stream.js.map +1 -0
- package/dist/timestamp/tsa.d.ts +24 -0
- package/dist/timestamp/tsa.d.ts.map +1 -0
- package/dist/timestamp/tsa.js +150 -0
- package/dist/timestamp/tsa.js.map +1 -0
- package/dist/tlog/body.d.ts +8 -0
- package/dist/tlog/body.d.ts.map +1 -0
- package/dist/tlog/body.js +45 -0
- package/dist/tlog/body.js.map +1 -0
- package/dist/tlog/checkpoint.d.ts +23 -0
- package/dist/tlog/checkpoint.d.ts.map +1 -0
- package/dist/tlog/checkpoint.js +187 -0
- package/dist/tlog/checkpoint.js.map +1 -0
- package/dist/tlog/dsse.d.ts +4 -0
- package/dist/tlog/dsse.d.ts.map +1 -0
- package/dist/tlog/dsse.js +85 -0
- package/dist/tlog/dsse.js.map +1 -0
- package/dist/tlog/hashedrekord.d.ts +4 -0
- package/dist/tlog/hashedrekord.d.ts.map +1 -0
- package/dist/tlog/hashedrekord.js +63 -0
- package/dist/tlog/hashedrekord.js.map +1 -0
- package/dist/tlog/intoto.d.ts +4 -0
- package/dist/tlog/intoto.d.ts.map +1 -0
- package/dist/tlog/intoto.js +50 -0
- package/dist/tlog/intoto.js.map +1 -0
- package/dist/tlog/merkle.d.ts +3 -0
- package/dist/tlog/merkle.d.ts.map +1 -0
- package/dist/tlog/merkle.js +112 -0
- package/dist/tlog/merkle.js.map +1 -0
- package/dist/trust/tuf-root.json +1 -0
- package/dist/trust/tuf.d.ts +95 -0
- package/dist/trust/tuf.d.ts.map +1 -0
- package/dist/trust/tuf.js +150 -0
- package/dist/trust/tuf.js.map +1 -0
- package/dist/x509/cert.d.ts +52 -0
- package/dist/x509/cert.d.ts.map +1 -0
- package/dist/x509/cert.js +256 -0
- package/dist/x509/cert.js.map +1 -0
- package/dist/x509/chain.d.ts +20 -0
- package/dist/x509/chain.d.ts.map +1 -0
- package/dist/x509/chain.js +141 -0
- package/dist/x509/chain.js.map +1 -0
- package/dist/x509/ext.d.ts +48 -0
- package/dist/x509/ext.d.ts.map +1 -0
- package/dist/x509/ext.js +164 -0
- package/dist/x509/ext.js.map +1 -0
- package/dist/x509/index.d.ts +4 -0
- package/dist/x509/index.d.ts.map +1 -0
- package/dist/x509/index.js +19 -0
- package/dist/x509/index.js.map +1 -0
- package/dist/x509/sct.d.ts +25 -0
- package/dist/x509/sct.d.ts.map +1 -0
- package/dist/x509/sct.js +123 -0
- package/dist/x509/sct.js.map +1 -0
- package/eslint.config.mjs +31 -0
- package/package.json +39 -0
- package/src/asn1/error.ts +18 -0
- package/src/asn1/index.ts +16 -0
- package/src/asn1/length.ts +71 -0
- package/src/asn1/obj.ts +184 -0
- package/src/asn1/parse.ts +146 -0
- package/src/asn1/tag.ts +105 -0
- package/src/bundle.ts +99 -0
- package/src/canonicalize.ts +61 -0
- package/src/cli.ts +285 -0
- package/src/crypto.ts +310 -0
- package/src/dsse.ts +49 -0
- package/src/encoding.ts +141 -0
- package/src/errors.ts +82 -0
- package/src/index.browser.test.ts +219 -0
- package/src/index.ts +14 -0
- package/src/interfaces.ts +118 -0
- package/src/oid.ts +28 -0
- package/src/pem.ts +48 -0
- package/src/rfc3161/error.ts +16 -0
- package/src/rfc3161/index.ts +17 -0
- package/src/rfc3161/timestamp.ts +270 -0
- package/src/rfc3161/tstinfo.ts +80 -0
- package/src/sigstore.ts +728 -0
- package/src/stream.ts +141 -0
- package/src/timestamp/tsa.ts +205 -0
- package/src/tlog/body.ts +65 -0
- package/src/tlog/checkpoint.ts +248 -0
- package/src/tlog/dsse.ts +147 -0
- package/src/tlog/hashedrekord.ts +130 -0
- package/src/tlog/intoto.ts +102 -0
- package/src/tlog/merkle.ts +152 -0
- package/src/trust/README.md +38 -0
- package/src/trust/tuf-root.json +1 -0
- package/src/trust/tuf.ts +223 -0
- package/src/types/tuf-browser.d.ts +13 -0
- package/src/x509/cert.ts +319 -0
- package/src/x509/chain.ts +212 -0
- package/src/x509/ext.ts +212 -0
- package/src/x509/index.ts +19 -0
- package/src/x509/sct.ts +154 -0
- package/tsconfig.json +18 -0
- package/vite.config.playwright.ts +26 -0
- package/vite.config.ts +18 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { SigstoreBundle } from "./bundle.js";
|
|
2
|
+
import { CertAuthority, CTLog, RawCAs, RawLogs, RawTimestampAuthorities, RekorKeyInfo, TrustedRoot } from "./interfaces.js";
|
|
3
|
+
import { X509Certificate } from "./x509/index.js";
|
|
4
|
+
import { TrustedRootProvider } from "./trust/tuf.js";
|
|
5
|
+
export interface SigstoreVerifierOptions {
|
|
6
|
+
tlogThreshold?: number;
|
|
7
|
+
ctlogThreshold?: number;
|
|
8
|
+
tsaThreshold?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare class SigstoreVerifier {
|
|
11
|
+
private root;
|
|
12
|
+
private rawRoot;
|
|
13
|
+
private options;
|
|
14
|
+
constructor(options?: SigstoreVerifierOptions);
|
|
15
|
+
loadLog(frozenTimestamp: Date, logs: RawLogs): Promise<RekorKeyInfo | undefined>;
|
|
16
|
+
loadCTLogs(frozenTimestamp: Date, ctlogs: RawLogs): Promise<CTLog[]>;
|
|
17
|
+
verifyCertificateChain(timestamp: Date, leaf: X509Certificate, certificateAuthorities: CertAuthority[]): Promise<X509Certificate[]>;
|
|
18
|
+
loadTSA(frozenTimestamp: Date, tsas?: RawTimestampAuthorities): CertAuthority[];
|
|
19
|
+
loadCA(frozenTimestamp: Date, cas: RawCAs): CertAuthority[];
|
|
20
|
+
loadSigstoreRoot(rawRoot: TrustedRoot): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Load Sigstore trusted root via TUF
|
|
23
|
+
* Uses The Update Framework for secure, verified updates of trusted root metadata
|
|
24
|
+
*
|
|
25
|
+
* @param tufProvider Optional TrustedRootProvider instance. If not provided, uses default Sigstore TUF repository
|
|
26
|
+
*/
|
|
27
|
+
loadSigstoreRootWithTUF(tufProvider?: TrustedRootProvider): Promise<void>;
|
|
28
|
+
verifySCT(cert: X509Certificate, issuer: X509Certificate, ctlogs: CTLog[]): Promise<Uint8Array[]>;
|
|
29
|
+
verifyInclusionPromise(cert: X509Certificate, bundle: SigstoreBundle, rekor: RekorKeyInfo | undefined): Promise<boolean>;
|
|
30
|
+
verifyInclusionProof(bundle: SigstoreBundle): Promise<void>;
|
|
31
|
+
verifyArtifact(identity: string, issuer: string, bundle: SigstoreBundle, data: Uint8Array, isDigestOnly?: boolean): Promise<boolean>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=sigstore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sigstore.d.ts","sourceRoot":"","sources":["../src/sigstore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAY7C,OAAO,EACL,aAAa,EACb,KAAK,EAEL,MAAM,EACN,OAAO,EACP,uBAAuB,EACvB,YAAY,EAGZ,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAGL,eAAe,EAEhB,MAAM,iBAAiB,CAAC;AAKzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,WAAW,uBAAuB;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,OAAO,CAAoC;gBAEvC,OAAO,GAAE,uBAA4B;IAU3C,OAAO,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IA4BhF,UAAU,CAAC,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAuCpE,sBAAsB,CAC1B,SAAS,EAAE,IAAI,EACf,IAAI,EAAE,eAAe,EACrB,sBAAsB,EAAE,aAAa,EAAE,GACtC,OAAO,CAAC,eAAe,EAAE,CAAC;IA2B7B,OAAO,CACL,eAAe,EAAE,IAAI,EACrB,IAAI,CAAC,EAAE,uBAAuB,GAC7B,aAAa,EAAE;IAiClB,MAAM,CAAC,eAAe,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,aAAa,EAAE;IAwBrD,gBAAgB,CAAC,OAAO,EAAE,WAAW;IAe3C;;;;;OAKG;IACG,uBAAuB,CAAC,WAAW,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYzE,SAAS,CACb,IAAI,EAAE,eAAe,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,KAAK,EAAE,GACd,OAAO,CAAC,UAAU,EAAE,CAAC;IAqGlB,sBAAsB,CAC1B,IAAI,EAAE,eAAe,EACrB,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,YAAY,GAAG,SAAS,GAC9B,OAAO,CAAC,OAAO,CAAC;IA2Kb,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBpD,cAAc,CACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,UAAU,EAChB,YAAY,GAAE,OAAe,GAC5B,OAAO,CAAC,OAAO,CAAC;CA0KpB"}
|
package/dist/sigstore.js
ADDED
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
import { canonicalize } from "./canonicalize.js";
|
|
2
|
+
import { importKey, verifySignature, verifySignatureOverDigest } from "./crypto.js";
|
|
3
|
+
import { preAuthEncoding } from "./dsse.js";
|
|
4
|
+
import { base64ToUint8Array, stringToUint8Array, toArrayBuffer, uint8ArrayEqual, Uint8ArrayToHex, Uint8ArrayToString, } from "./encoding.js";
|
|
5
|
+
import { HashAlgorithms, SigstoreRoots, } from "./interfaces.js";
|
|
6
|
+
import { ByteStream } from "./stream.js";
|
|
7
|
+
import { CertificateChainVerifier, EXTENSION_OID_SCT, X509Certificate, X509SCTExtension, } from "./x509/index.js";
|
|
8
|
+
import { verifyMerkleInclusion } from "./tlog/merkle.js";
|
|
9
|
+
import { verifyCheckpoint } from "./tlog/checkpoint.js";
|
|
10
|
+
import { verifyTLogBody } from "./tlog/body.js";
|
|
11
|
+
import { verifyBundleTimestamp } from "./timestamp/tsa.js";
|
|
12
|
+
import { TrustedRootProvider } from "./trust/tuf.js";
|
|
13
|
+
export class SigstoreVerifier {
|
|
14
|
+
root;
|
|
15
|
+
rawRoot;
|
|
16
|
+
options;
|
|
17
|
+
constructor(options = {}) {
|
|
18
|
+
this.root = undefined;
|
|
19
|
+
this.rawRoot = undefined;
|
|
20
|
+
this.options = {
|
|
21
|
+
tlogThreshold: options.tlogThreshold ?? 1,
|
|
22
|
+
ctlogThreshold: options.ctlogThreshold ?? 1,
|
|
23
|
+
tsaThreshold: options.tsaThreshold ?? 0,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
async loadLog(frozenTimestamp, logs) {
|
|
27
|
+
// Load the first Rekor transparency log key that's valid at the frozen timestamp
|
|
28
|
+
// and store its log ID for verification. This matches sigstore-go's approach of
|
|
29
|
+
// looking up the verifier by log ID (verify/tlog.go:80-83).
|
|
30
|
+
for (const log of logs) {
|
|
31
|
+
// if start date is not in the future, and if an end doesn't exist or is in the future
|
|
32
|
+
if (frozenTimestamp > new Date(log.publicKey.validFor.start) &&
|
|
33
|
+
(!log.publicKey.validFor.end ||
|
|
34
|
+
new Date(log.publicKey.validFor.end) > frozenTimestamp)) {
|
|
35
|
+
return {
|
|
36
|
+
publicKey: await importKey(log.publicKey.keyDetails, log.publicKey.keyDetails, log.publicKey.rawBytes),
|
|
37
|
+
logId: base64ToUint8Array(log.logId.keyId),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Return undefined instead of throwing - some bundles don't need Rekor keys
|
|
42
|
+
// (e.g., v0.3 bundles with inclusion proofs)
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
async loadCTLogs(frozenTimestamp, ctlogs) {
|
|
46
|
+
const result = [];
|
|
47
|
+
for (const log of ctlogs) {
|
|
48
|
+
const start = new Date(log.publicKey.validFor.start);
|
|
49
|
+
const end = log.publicKey.validFor.end
|
|
50
|
+
? new Date(log.publicKey.validFor.end)
|
|
51
|
+
: new Date('9999-12-31'); // No expiry means valid forever
|
|
52
|
+
// Include logs that are valid (started before frozen timestamp)
|
|
53
|
+
// We keep all logs, even expired ones, for historical verification
|
|
54
|
+
if (start <= frozenTimestamp) {
|
|
55
|
+
const publicKey = await importKey(log.publicKey.keyDetails, log.publicKey.keyDetails, log.publicKey.rawBytes);
|
|
56
|
+
result.push({
|
|
57
|
+
logID: base64ToUint8Array(log.logId.keyId),
|
|
58
|
+
publicKey,
|
|
59
|
+
validFor: { start, end },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (result.length === 0) {
|
|
64
|
+
throw new Error("Could not find any valid CT logs in sigstore root.");
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
// Adapted from https://github.com/sigstore/sigstore-js/blob/main/packages/verify/src/key/certificate.ts#L22-L53
|
|
69
|
+
// Verifies that the leaf certificate chains to a trusted CA and is valid at the given timestamp.
|
|
70
|
+
// Differences from sigstore-js:
|
|
71
|
+
// - This is async (uses await) because our CertificateChainVerifier.verify() is async
|
|
72
|
+
// - sigstore-js filters CAs using filterCertAuthorities() before calling this function,
|
|
73
|
+
// we do the timestamp filtering inline within this function
|
|
74
|
+
async verifyCertificateChain(timestamp, leaf, certificateAuthorities) {
|
|
75
|
+
let lastError;
|
|
76
|
+
for (const ca of certificateAuthorities) {
|
|
77
|
+
// Check if this CA is valid for the given timestamp
|
|
78
|
+
if (timestamp < ca.validFor.start || timestamp > ca.validFor.end) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const verifier = new CertificateChainVerifier({
|
|
83
|
+
trustedCerts: ca.certChain,
|
|
84
|
+
untrustedCert: leaf,
|
|
85
|
+
timestamp,
|
|
86
|
+
});
|
|
87
|
+
return await verifier.verify();
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
lastError = err;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
throw new Error(`Failed to verify certificate chain: ${lastError?.message || 'No valid CAs found'}`);
|
|
94
|
+
}
|
|
95
|
+
// Load timestamp authorities that are valid at the frozen timestamp.
|
|
96
|
+
// Unlike sigstore-js which doesn't pre-load TSAs (it passes raw TSA data to timestamp verification),
|
|
97
|
+
// we parse and filter them at initialization time for consistency with how we handle CAs and other roots.
|
|
98
|
+
loadTSA(frozenTimestamp, tsas) {
|
|
99
|
+
if (!tsas || tsas.length === 0) {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
const result = [];
|
|
103
|
+
for (const tsa of tsas) {
|
|
104
|
+
const start = new Date(tsa.validFor.start);
|
|
105
|
+
const end = tsa.validFor.end ? new Date(tsa.validFor.end) : new Date(8640000000000000);
|
|
106
|
+
if (frozenTimestamp > start && frozenTimestamp < end) {
|
|
107
|
+
const certChain = tsa.certChain.certificates.map(cert => X509Certificate.parse(base64ToUint8Array(cert.rawBytes)));
|
|
108
|
+
if (certChain.length > 0) {
|
|
109
|
+
result.push({
|
|
110
|
+
certChain,
|
|
111
|
+
validFor: { start, end },
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
// Load certificate authorities (Fulcio CAs) that are valid at the frozen timestamp.
|
|
119
|
+
// Similar to sigstore-js's filterCertAuthorities() in trust/filter.ts, but we also
|
|
120
|
+
// parse the certificates at load time whereas sigstore-js keeps them in the trust material
|
|
121
|
+
// and parses them during verification. This pre-loading approach is consistent with our
|
|
122
|
+
// architecture of loading all trusted roots at initialization.
|
|
123
|
+
loadCA(frozenTimestamp, cas) {
|
|
124
|
+
const result = [];
|
|
125
|
+
for (const ca of cas) {
|
|
126
|
+
const start = new Date(ca.validFor.start);
|
|
127
|
+
const end = ca.validFor.end ? new Date(ca.validFor.end) : new Date(8640000000000000);
|
|
128
|
+
if (frozenTimestamp > start && frozenTimestamp < end) {
|
|
129
|
+
const certChain = ca.certChain.certificates.map(cert => X509Certificate.parse(base64ToUint8Array(cert.rawBytes)));
|
|
130
|
+
if (certChain.length > 0) {
|
|
131
|
+
result.push({
|
|
132
|
+
certChain,
|
|
133
|
+
validFor: { start, end },
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
async loadSigstoreRoot(rawRoot) {
|
|
141
|
+
const frozenTimestamp = new Date();
|
|
142
|
+
this.rawRoot = rawRoot;
|
|
143
|
+
this.root = {
|
|
144
|
+
rekor: await this.loadLog(frozenTimestamp, rawRoot[SigstoreRoots.tlogs]),
|
|
145
|
+
ctlogs: await this.loadCTLogs(frozenTimestamp, rawRoot[SigstoreRoots.ctlogs]),
|
|
146
|
+
certificateAuthorities: this.loadCA(frozenTimestamp, rawRoot[SigstoreRoots.certificateAuthorities]),
|
|
147
|
+
timestampAuthorities: this.loadTSA(frozenTimestamp, rawRoot.timestampAuthorities),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Load Sigstore trusted root via TUF
|
|
152
|
+
* Uses The Update Framework for secure, verified updates of trusted root metadata
|
|
153
|
+
*
|
|
154
|
+
* @param tufProvider Optional TrustedRootProvider instance. If not provided, uses default Sigstore TUF repository
|
|
155
|
+
*/
|
|
156
|
+
async loadSigstoreRootWithTUF(tufProvider) {
|
|
157
|
+
const provider = tufProvider || new TrustedRootProvider();
|
|
158
|
+
const trustedRoot = await provider.getTrustedRoot();
|
|
159
|
+
await this.loadSigstoreRoot(trustedRoot);
|
|
160
|
+
}
|
|
161
|
+
// Adapted from https://github.com/sigstore/sigstore-js/blob/main/packages/verify/src/key/sct.ts
|
|
162
|
+
// Key differences:
|
|
163
|
+
// - Adds duplicate SCT detection
|
|
164
|
+
// - Adds SCT timestamp validity checking
|
|
165
|
+
// - Inline CT log filtering by logID and validity period (reference uses filterTLogAuthorities)
|
|
166
|
+
// - Returns array of verified SCT logIDs for threshold checking (matches reference behavior)
|
|
167
|
+
async verifySCT(cert, issuer, ctlogs) {
|
|
168
|
+
let extSCT;
|
|
169
|
+
// Verifying the SCT requires that we remove the SCT extension and
|
|
170
|
+
// re-encode the TBS structure to DER -- this value is part of the data
|
|
171
|
+
// over which the signature is calculated. Since this is a destructive action
|
|
172
|
+
// we create a copy of the certificate so we can remove the SCT extension
|
|
173
|
+
// without affecting the original certificate.
|
|
174
|
+
const clone = cert.clone();
|
|
175
|
+
// Intentionally not using the findExtension method here because we want to
|
|
176
|
+
// remove the the SCT extension from the certificate before calculating the
|
|
177
|
+
// PreCert structure
|
|
178
|
+
for (let i = 0; i < clone.extensions.length; i++) {
|
|
179
|
+
const ext = clone.extensions[i];
|
|
180
|
+
if (ext.subs[0].toOID() === EXTENSION_OID_SCT) {
|
|
181
|
+
extSCT = new X509SCTExtension(ext);
|
|
182
|
+
// Remove the extension from the certificate
|
|
183
|
+
clone.extensions.splice(i, 1);
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// No SCT extension found - fail verification
|
|
188
|
+
if (!extSCT) {
|
|
189
|
+
throw new Error("Certificate is missing required SCT extension");
|
|
190
|
+
}
|
|
191
|
+
// Found an SCT extension but it has no SCTs - fail verification
|
|
192
|
+
if (extSCT.signedCertificateTimestamps.length === 0) {
|
|
193
|
+
throw new Error("SCT extension is present but contains no SCTs");
|
|
194
|
+
}
|
|
195
|
+
// Check for duplicate SCTs (same log ID)
|
|
196
|
+
const seenLogIds = new Set();
|
|
197
|
+
for (const sct of extSCT.signedCertificateTimestamps) {
|
|
198
|
+
const logIdHex = Uint8ArrayToHex(sct.logID);
|
|
199
|
+
if (seenLogIds.has(logIdHex)) {
|
|
200
|
+
throw new Error(`Duplicate SCT found for log ID: ${logIdHex}`);
|
|
201
|
+
}
|
|
202
|
+
seenLogIds.add(logIdHex);
|
|
203
|
+
}
|
|
204
|
+
// Construct the PreCert structure
|
|
205
|
+
// https://www.rfc-editor.org/rfc/rfc6962#section-3.2
|
|
206
|
+
const preCert = new ByteStream();
|
|
207
|
+
// Calculate hash of the issuer's public key
|
|
208
|
+
const issuerId = new Uint8Array(await crypto.subtle.digest(HashAlgorithms.SHA256, toArrayBuffer(issuer.publicKey)));
|
|
209
|
+
preCert.appendView(issuerId);
|
|
210
|
+
// Re-encodes the certificate to DER after removing the SCT extension
|
|
211
|
+
const tbs = clone.tbsCertificate.toDER();
|
|
212
|
+
preCert.appendUint24(tbs.length);
|
|
213
|
+
preCert.appendView(tbs);
|
|
214
|
+
// Collect all verified SCTs to check against threshold
|
|
215
|
+
const verifiedSCTs = [];
|
|
216
|
+
for (const sct of extSCT.signedCertificateTimestamps) {
|
|
217
|
+
// SCT should be within certificate validity period
|
|
218
|
+
if (sct.datetime < cert.notBefore || sct.datetime > cert.notAfter) {
|
|
219
|
+
continue; // Skip invalid SCT timestamp, don't fail yet
|
|
220
|
+
}
|
|
221
|
+
// Find the CT log that matches this SCT's log ID and is valid for the SCT datetime
|
|
222
|
+
const validCTLogs = ctlogs.filter((log) => {
|
|
223
|
+
// Check if log IDs match
|
|
224
|
+
if (log.logID.length !== sct.logID.length)
|
|
225
|
+
return false;
|
|
226
|
+
for (let i = 0; i < log.logID.length; i++) {
|
|
227
|
+
if (log.logID[i] !== sct.logID[i])
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
// Check that the SCT datetime is within the log's validity period
|
|
231
|
+
return log.validFor.start <= sct.datetime && sct.datetime <= log.validFor.end;
|
|
232
|
+
});
|
|
233
|
+
// Try to verify with any valid CT log
|
|
234
|
+
let verified = false;
|
|
235
|
+
for (const log of validCTLogs) {
|
|
236
|
+
try {
|
|
237
|
+
if (await sct.verify(preCert.buffer, log.publicKey)) {
|
|
238
|
+
verified = true;
|
|
239
|
+
break; // Found a valid log for this SCT
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
catch (e) {
|
|
243
|
+
// Continue trying other logs
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (verified) {
|
|
247
|
+
verifiedSCTs.push(sct.logID);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return verifiedSCTs;
|
|
251
|
+
}
|
|
252
|
+
async verifyInclusionPromise(cert, bundle, rekor) {
|
|
253
|
+
const entries = bundle.verificationMaterial.tlogEntries;
|
|
254
|
+
if (entries.length < 1) {
|
|
255
|
+
throw new Error("Failed to find a transparency log entry in the provided bundle.");
|
|
256
|
+
}
|
|
257
|
+
// Prevent DoS via excessive entries and threshold bypass via duplicates
|
|
258
|
+
// Matches sigstore-go limits (verify/tlog.go:46-57)
|
|
259
|
+
const MAX_TLOG_ENTRIES = 32;
|
|
260
|
+
if (entries.length > MAX_TLOG_ENTRIES) {
|
|
261
|
+
throw new Error(`Too many tlog entries: ${entries.length} > ${MAX_TLOG_ENTRIES}`);
|
|
262
|
+
}
|
|
263
|
+
for (let i = 0; i < entries.length; i++) {
|
|
264
|
+
for (let j = i + 1; j < entries.length; j++) {
|
|
265
|
+
const iLogId = Uint8ArrayToHex(base64ToUint8Array(entries[i].logId.keyId));
|
|
266
|
+
const jLogId = Uint8ArrayToHex(base64ToUint8Array(entries[j].logId.keyId));
|
|
267
|
+
if (iLogId === jLogId && entries[i].logIndex === entries[j].logIndex) {
|
|
268
|
+
throw new Error(`Duplicate tlog entry found: logID=${iLogId}, logIndex=${entries[i].logIndex}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
const entry = entries[0];
|
|
273
|
+
// Extract bundle version from mediaType
|
|
274
|
+
// e.g., "application/vnd.dev.sigstore.bundle+json;version=0.2"
|
|
275
|
+
const versionMatch = bundle.mediaType.match(/version=(\d+\.\d+)/);
|
|
276
|
+
const bundleVersion = versionMatch ? versionMatch[1] : "0.1";
|
|
277
|
+
const isV02OrLater = parseFloat(bundleVersion) >= 0.2;
|
|
278
|
+
// Bundle v0.2+ requires an inclusion proof
|
|
279
|
+
if (isV02OrLater && !entry.inclusionProof) {
|
|
280
|
+
throw new Error("Bundle v0.2+ requires an inclusion proof.");
|
|
281
|
+
}
|
|
282
|
+
// For rekor2/v0.3 bundles with inclusion proofs, the inclusion promise is optional
|
|
283
|
+
if (!entry.inclusionPromise?.signedEntryTimestamp) {
|
|
284
|
+
// If there's no inclusion promise, there must be an inclusion proof
|
|
285
|
+
if (!entry.inclusionProof) {
|
|
286
|
+
throw new Error("Bundle must have either an inclusion promise or an inclusion proof.");
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
// Verify the inclusion promise signature if present
|
|
291
|
+
// For v0.3 bundles that have both inclusion promise and proof,
|
|
292
|
+
// we can skip the promise verification if we don't have a Rekor key
|
|
293
|
+
// and there's a valid inclusion proof
|
|
294
|
+
if (!rekor && entry.inclusionProof) {
|
|
295
|
+
// Skip promise verification if we have an inclusion proof
|
|
296
|
+
// The inclusion proof will be verified later
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
if (!rekor) {
|
|
300
|
+
throw new Error("Rekor public key not found in trusted root");
|
|
301
|
+
}
|
|
302
|
+
// Verify the log ID matches (matches sigstore-go verify/tlog.go:80-83)
|
|
303
|
+
const entryLogId = base64ToUint8Array(entry.logId.keyId);
|
|
304
|
+
if (!uint8ArrayEqual(rekor.logId, entryLogId)) {
|
|
305
|
+
throw new Error(`Rekor log ID mismatch: bundle uses ${Uint8ArrayToHex(entryLogId)} but loaded key is for ${Uint8ArrayToHex(rekor.logId)}`);
|
|
306
|
+
}
|
|
307
|
+
const signature = base64ToUint8Array(entry.inclusionPromise.signedEntryTimestamp);
|
|
308
|
+
const keyId = Uint8ArrayToHex(entryLogId);
|
|
309
|
+
const integratedTime = Number(entry.integratedTime);
|
|
310
|
+
const signed = stringToUint8Array(canonicalize({
|
|
311
|
+
body: entry.canonicalizedBody,
|
|
312
|
+
integratedTime: integratedTime,
|
|
313
|
+
logIndex: Number(entry.logIndex),
|
|
314
|
+
logID: keyId,
|
|
315
|
+
}));
|
|
316
|
+
if (!(await verifySignature(rekor.publicKey, signed, signature))) {
|
|
317
|
+
throw new Error("Failed to verify the inclusion promise in the provided bundle.");
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
// Validate integrated time and logged certificate
|
|
322
|
+
// Note: Rekor v2 bundles don't have integrated time in the tlog entry
|
|
323
|
+
if (entry.integratedTime) {
|
|
324
|
+
const integratedTime = Number(entry.integratedTime);
|
|
325
|
+
const integratedDate = new Date(integratedTime * 1000);
|
|
326
|
+
if (!cert.validForDate(integratedDate)) {
|
|
327
|
+
throw new Error("Artifact signing was logged outside of the certificate validity.");
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
// Rekor v2 bundles (no integratedTime) require a timestamp for verification
|
|
332
|
+
if (!bundle.verificationMaterial.timestampVerificationData) {
|
|
333
|
+
throw new Error("Rekor v2 bundles require a timestamp for verification.");
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
// Verify that the certificate in the log matches the signing certificate
|
|
337
|
+
// The format depends on the entry type (hashedrekord vs dsse) and version
|
|
338
|
+
const bodyJson = JSON.parse(Uint8ArrayToString(base64ToUint8Array(entry.canonicalizedBody)));
|
|
339
|
+
if (bodyJson.kind === "hashedrekord") {
|
|
340
|
+
let loggedCertContent;
|
|
341
|
+
// Check for hashedRekordV002 structure (Rekor v2)
|
|
342
|
+
if (bodyJson.spec.hashedRekordV002) {
|
|
343
|
+
const verifier = bodyJson.spec.hashedRekordV002.signature.verifier;
|
|
344
|
+
if (verifier?.x509Certificate) {
|
|
345
|
+
loggedCertContent = verifier.x509Certificate.rawBytes;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
// Check for older hashedrekord structure
|
|
349
|
+
else if (bodyJson.spec.signature?.publicKey) {
|
|
350
|
+
loggedCertContent = bodyJson.spec.signature.publicKey.content;
|
|
351
|
+
}
|
|
352
|
+
if (loggedCertContent) {
|
|
353
|
+
// For hashedrekord v0.0.1, publicKey.content is base64-encoded PEM
|
|
354
|
+
// For hashedRekordV002, x509Certificate.rawBytes is base64-encoded DER
|
|
355
|
+
let loggedCert;
|
|
356
|
+
if (bodyJson.spec.hashedRekordV002) {
|
|
357
|
+
loggedCert = X509Certificate.parse(base64ToUint8Array(loggedCertContent));
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
const pemString = Uint8ArrayToString(base64ToUint8Array(loggedCertContent));
|
|
361
|
+
loggedCert = X509Certificate.parse(pemString);
|
|
362
|
+
}
|
|
363
|
+
if (!cert.equals(loggedCert)) {
|
|
364
|
+
throw new Error("Certificate in Rekor log does not match the signing certificate.");
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
else if (bodyJson.kind === "dsse") {
|
|
369
|
+
// DSSE entries store signatures differently
|
|
370
|
+
// The certificate is verified through the bundle's verification material
|
|
371
|
+
// No additional check needed here
|
|
372
|
+
}
|
|
373
|
+
else if (bodyJson.kind === "intoto") {
|
|
374
|
+
// Intoto entries are DSSE-based and don't store certificates in the tlog entry
|
|
375
|
+
// The certificate is part of the bundle's verification material which has already
|
|
376
|
+
// been verified against the CA root. The intoto verification in tlog/intoto.ts
|
|
377
|
+
// verifies the signature and payload hash match between the tlog and bundle.
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
// Unknown entry type - this should not happen with standard Sigstore bundles
|
|
381
|
+
throw new Error(`Unsupported tlog entry kind: ${bodyJson.kind}`);
|
|
382
|
+
}
|
|
383
|
+
return true;
|
|
384
|
+
}
|
|
385
|
+
async verifyInclusionProof(bundle) {
|
|
386
|
+
if (!this.rawRoot) {
|
|
387
|
+
throw new Error("Sigstore root is undefined");
|
|
388
|
+
}
|
|
389
|
+
if (bundle.verificationMaterial.tlogEntries.length < 1) {
|
|
390
|
+
throw new Error("No transparency log entries found in bundle");
|
|
391
|
+
}
|
|
392
|
+
const entry = bundle.verificationMaterial.tlogEntries[0];
|
|
393
|
+
// Only verify if there's an inclusion proof (v0.3/rekor2 bundles)
|
|
394
|
+
// v0.1 bundles use inclusion promises instead, verified in verifyInclusionPromise
|
|
395
|
+
if (entry.inclusionProof) {
|
|
396
|
+
await verifyMerkleInclusion(entry);
|
|
397
|
+
if (entry.inclusionProof.checkpoint) {
|
|
398
|
+
await verifyCheckpoint(entry, this.rawRoot.tlogs);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
async verifyArtifact(identity, issuer, bundle, data, isDigestOnly = false) {
|
|
403
|
+
// Quick checks first: does the signing certificate have the correct identity?
|
|
404
|
+
if (!this.root) {
|
|
405
|
+
throw new Error("Sigstore root is undefined");
|
|
406
|
+
}
|
|
407
|
+
const cert = bundle.verificationMaterial.certificate ||
|
|
408
|
+
bundle.verificationMaterial.x509CertificateChain?.certificates[0];
|
|
409
|
+
if (!cert) {
|
|
410
|
+
throw new Error("No certificate found in bundle");
|
|
411
|
+
}
|
|
412
|
+
const signingCert = X509Certificate.parse(base64ToUint8Array(cert.rawBytes));
|
|
413
|
+
// Handle both regular bundles (messageSignature) and DSSE bundles (dsseEnvelope)
|
|
414
|
+
let signature;
|
|
415
|
+
if (bundle.messageSignature) {
|
|
416
|
+
signature = base64ToUint8Array(bundle.messageSignature.signature);
|
|
417
|
+
}
|
|
418
|
+
else if (bundle.dsseEnvelope) {
|
|
419
|
+
if (!bundle.dsseEnvelope.signatures || bundle.dsseEnvelope.signatures.length === 0) {
|
|
420
|
+
throw new Error("DSSE envelope has no signatures");
|
|
421
|
+
}
|
|
422
|
+
signature = base64ToUint8Array(bundle.dsseEnvelope.signatures[0].sig);
|
|
423
|
+
}
|
|
424
|
+
else {
|
|
425
|
+
throw new Error("Bundle does not contain a message signature or DSSE envelope");
|
|
426
|
+
}
|
|
427
|
+
// # 1 Basic stuff
|
|
428
|
+
if (signingCert.subjectAltName !== identity) {
|
|
429
|
+
throw new Error("Certificate identity (subjectAltName) do not match the verifying one.");
|
|
430
|
+
}
|
|
431
|
+
// Check for issuer - try V2 first, fall back to V1 (like sigstore-js does)
|
|
432
|
+
const certIssuer = signingCert.extFulcioIssuerV2?.issuer || signingCert.extFulcioIssuerV1?.issuer;
|
|
433
|
+
if (certIssuer !== issuer) {
|
|
434
|
+
throw new Error("Identity issuer is not the verifying one.");
|
|
435
|
+
}
|
|
436
|
+
// # 2 Certificate validity - verify chain to trusted CA
|
|
437
|
+
// Similar to sigstore-js key/index.ts:59-64 which calls verifyCertificateChain()
|
|
438
|
+
// Returns the verified certificate path [leaf, intermediate(s), root]
|
|
439
|
+
const certPath = await this.verifyCertificateChain(signingCert.notBefore, signingCert, this.root.certificateAuthorities);
|
|
440
|
+
// # 3 To verify the SCT we need to build a preCert (because the cert was logged without the SCT)
|
|
441
|
+
// https://github.com/sigstore/sigstore-js/packages/verify/src/key/sct.ts#L45
|
|
442
|
+
// Similar to sigstore-js key/index.ts:67 which uses path[0] (leaf) and path[1] (issuer)
|
|
443
|
+
// for SCT verification. Handle edge case where path has only one cert (self-signed root).
|
|
444
|
+
const issuerCert = certPath.length > 1 ? certPath[1] : certPath[0];
|
|
445
|
+
const verifiedSCTs = await this.verifySCT(signingCert, issuerCert, this.root.ctlogs);
|
|
446
|
+
if (verifiedSCTs.length < this.options.ctlogThreshold) {
|
|
447
|
+
throw new Error(`Not enough valid SCTs: found ${verifiedSCTs.length}, required ${this.options.ctlogThreshold}`);
|
|
448
|
+
}
|
|
449
|
+
// # 4 Rekor inclusion promise
|
|
450
|
+
if (!(await this.verifyInclusionPromise(signingCert, bundle, this.root.rekor))) {
|
|
451
|
+
throw new Error("Inclusion promise validation failed.");
|
|
452
|
+
}
|
|
453
|
+
// # 5 Rekor inclusion proof (Merkle tree verification)
|
|
454
|
+
await this.verifyInclusionProof(bundle);
|
|
455
|
+
// # 5.1 Rekor body verification
|
|
456
|
+
if (bundle.verificationMaterial.tlogEntries.length > 0) {
|
|
457
|
+
await verifyTLogBody(bundle.verificationMaterial.tlogEntries[0], bundle);
|
|
458
|
+
}
|
|
459
|
+
// # 6 TSA Timestamp Verification (if present)
|
|
460
|
+
let verifiedTimestamp;
|
|
461
|
+
if (bundle.verificationMaterial.timestampVerificationData) {
|
|
462
|
+
// Verify TSA timestamps if present
|
|
463
|
+
verifiedTimestamp = await verifyBundleTimestamp(bundle.verificationMaterial.timestampVerificationData, signature, this.rawRoot?.timestampAuthorities || []);
|
|
464
|
+
// If we have a verified timestamp, check certificate validity at that time
|
|
465
|
+
if (verifiedTimestamp && !signingCert.validForDate(verifiedTimestamp)) {
|
|
466
|
+
throw new Error("Certificate was not valid at the time of timestamping");
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
// # 7 Revocation *skipping* not really a thing (unsurprisingly)
|
|
470
|
+
// # 8 verify the signed data
|
|
471
|
+
if (bundle.dsseEnvelope) {
|
|
472
|
+
// For DSSE bundles, verify the signature over the PAE
|
|
473
|
+
const payloadBytes = base64ToUint8Array(bundle.dsseEnvelope.payload);
|
|
474
|
+
const payload = JSON.parse(Uint8ArrayToString(payloadBytes));
|
|
475
|
+
// Verify the artifact digest matches a subject in the in-toto statement
|
|
476
|
+
if (!payload.subject || payload.subject.length === 0) {
|
|
477
|
+
throw new Error("DSSE payload has no subject");
|
|
478
|
+
}
|
|
479
|
+
// Compute or extract the artifact digest
|
|
480
|
+
let artifactDigest;
|
|
481
|
+
if (isDigestOnly) {
|
|
482
|
+
// data is already the digest bytes
|
|
483
|
+
artifactDigest = Uint8ArrayToHex(data);
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
// data is the file content, compute the digest
|
|
487
|
+
artifactDigest = Uint8ArrayToHex(new Uint8Array(await crypto.subtle.digest(HashAlgorithms.SHA256, toArrayBuffer(data))));
|
|
488
|
+
}
|
|
489
|
+
// Find matching subject by scanning all subjects (not just [0])
|
|
490
|
+
let matchedSubject = null;
|
|
491
|
+
for (const subject of payload.subject) {
|
|
492
|
+
const subjectDigest = subject.digest?.["sha256"];
|
|
493
|
+
if (subjectDigest && artifactDigest === subjectDigest.toLowerCase()) {
|
|
494
|
+
matchedSubject = subject;
|
|
495
|
+
break;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
if (!matchedSubject) {
|
|
499
|
+
throw new Error(`Artifact digest ${artifactDigest} does not match any subject in DSSE payload`);
|
|
500
|
+
}
|
|
501
|
+
// Create PAE (Pre-Authentication Encoding) for signature verification
|
|
502
|
+
const pae = preAuthEncoding(bundle.dsseEnvelope.payloadType, payloadBytes);
|
|
503
|
+
const publicKey = await signingCert.publicKeyObj;
|
|
504
|
+
const verified = await verifySignature(publicKey, pae, signature);
|
|
505
|
+
if (!verified) {
|
|
506
|
+
throw new Error("DSSE signature verification failed");
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
const publicKey = await signingCert.publicKeyObj;
|
|
511
|
+
if (isDigestOnly) {
|
|
512
|
+
// For hashedrekord bundles, verify signature over the digest directly.
|
|
513
|
+
// Uses the same elliptic.js workaround as sigstore-js conformance CLI.
|
|
514
|
+
const verified = await verifySignatureOverDigest(publicKey, data, signature);
|
|
515
|
+
if (!verified) {
|
|
516
|
+
throw new Error("Error verifying signature over digest");
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
// For regular bundles, verify the signature over the artifact data
|
|
521
|
+
const verified = await verifySignature(publicKey, data, signature);
|
|
522
|
+
if (!verified) {
|
|
523
|
+
const keyAlg = publicKey.algorithm.name || 'unknown';
|
|
524
|
+
throw new Error(`Error verifying artifact signature. Key algorithm: ${keyAlg}, Data length: ${data.length}, Signature length: ${signature.length}`);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
return true;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
//# sourceMappingURL=sigstore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sigstore.js","sourceRoot":"","sources":["../src/sigstore.ts"],"names":[],"mappings":"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"}
|
package/dist/stream.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare class ByteStream {
|
|
2
|
+
private static BLOCK_SIZE;
|
|
3
|
+
private buf;
|
|
4
|
+
private view;
|
|
5
|
+
private start;
|
|
6
|
+
constructor(buffer?: ArrayBuffer);
|
|
7
|
+
get buffer(): Uint8Array;
|
|
8
|
+
get length(): number;
|
|
9
|
+
get position(): number;
|
|
10
|
+
seek(position: number): void;
|
|
11
|
+
slice(start: number, len: number): Uint8Array;
|
|
12
|
+
appendChar(char: number): void;
|
|
13
|
+
appendUint16(num: number): void;
|
|
14
|
+
appendUint24(num: number): void;
|
|
15
|
+
appendView(view: Uint8Array): void;
|
|
16
|
+
getBlock(size: number): Uint8Array;
|
|
17
|
+
getUint8(): number;
|
|
18
|
+
getUint16(): number;
|
|
19
|
+
private ensureCapacity;
|
|
20
|
+
private realloc;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAiBA,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAQ;IAEjC,OAAO,CAAC,GAAG,CAAc;IACzB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,KAAK,CAAK;gBAEN,MAAM,CAAC,EAAE,WAAW;IAUhC,IAAI,MAAM,IAAI,UAAU,CAEvB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAEM,IAAI,CAAC,QAAQ,EAAE,MAAM;IAMrB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU;IAU7C,UAAU,CAAC,IAAI,EAAE,MAAM;IAMvB,YAAY,CAAC,GAAG,EAAE,MAAM;IAWxB,YAAY,CAAC,GAAG,EAAE,MAAM;IAYxB,UAAU,CAAC,IAAI,EAAE,UAAU;IAM3B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;IAelC,QAAQ,IAAI,MAAM;IAIlB,SAAS,IAAI,MAAM;IAM1B,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,OAAO;CAUhB"}
|