Deployed the page to Github Pages.

This commit is contained in:
Batuhan Berk Başoğlu 2024-11-03 21:30:09 -05:00
parent 1d79754e93
commit 2c89899458
Signed by: batuhan-basoglu
SSH key fingerprint: SHA256:kEsnuHX+qbwhxSAXPUQ4ox535wFHu/hIRaa53FzxRpo
62797 changed files with 6551425 additions and 15279 deletions

14
node_modules/@sigstore/verify/dist/bundle/dsse.d.ts generated vendored Normal file
View file

@ -0,0 +1,14 @@
/// <reference types="node" />
/// <reference types="node" />
import { crypto } from '@sigstore/core';
import type { Envelope } from '@sigstore/bundle';
import type { SignatureContent } from '../shared.types';
export declare class DSSESignatureContent implements SignatureContent {
private readonly env;
constructor(env: Envelope);
compareDigest(digest: Buffer): boolean;
compareSignature(signature: Buffer): boolean;
verifySignature(key: crypto.KeyObject): boolean;
get signature(): Buffer;
private get preAuthEncoding();
}

43
node_modules/@sigstore/verify/dist/bundle/dsse.js generated vendored Normal file
View file

@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DSSESignatureContent = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const core_1 = require("@sigstore/core");
class DSSESignatureContent {
constructor(env) {
this.env = env;
}
compareDigest(digest) {
return core_1.crypto.bufferEqual(digest, core_1.crypto.hash(this.env.payload));
}
compareSignature(signature) {
return core_1.crypto.bufferEqual(signature, this.signature);
}
verifySignature(key) {
return core_1.crypto.verify(this.preAuthEncoding, key, this.signature);
}
get signature() {
return this.env.signatures.length > 0
? this.env.signatures[0].sig
: Buffer.from('');
}
// DSSE Pre-Authentication Encoding
get preAuthEncoding() {
return core_1.dsse.preAuthEncoding(this.env.payloadType, this.env.payload);
}
}
exports.DSSESignatureContent = DSSESignatureContent;

5
node_modules/@sigstore/verify/dist/bundle/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,5 @@
/// <reference types="node" />
import { Bundle } from '@sigstore/bundle';
import type { SignatureContent, SignedEntity } from '../shared.types';
export declare function toSignedEntity(bundle: Bundle, artifact?: Buffer): SignedEntity;
export declare function signatureContent(bundle: Bundle, artifact?: Buffer): SignatureContent;

58
node_modules/@sigstore/verify/dist/bundle/index.js generated vendored Normal file
View file

@ -0,0 +1,58 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.signatureContent = exports.toSignedEntity = void 0;
const core_1 = require("@sigstore/core");
const dsse_1 = require("./dsse");
const message_1 = require("./message");
function toSignedEntity(bundle, artifact) {
const { tlogEntries, timestampVerificationData } = bundle.verificationMaterial;
const timestamps = [];
for (const entry of tlogEntries) {
timestamps.push({
$case: 'transparency-log',
tlogEntry: entry,
});
}
for (const ts of timestampVerificationData?.rfc3161Timestamps ?? []) {
timestamps.push({
$case: 'timestamp-authority',
timestamp: core_1.RFC3161Timestamp.parse(ts.signedTimestamp),
});
}
return {
signature: signatureContent(bundle, artifact),
key: key(bundle),
tlogEntries,
timestamps,
};
}
exports.toSignedEntity = toSignedEntity;
function signatureContent(bundle, artifact) {
switch (bundle.content.$case) {
case 'dsseEnvelope':
return new dsse_1.DSSESignatureContent(bundle.content.dsseEnvelope);
case 'messageSignature':
return new message_1.MessageSignatureContent(bundle.content.messageSignature, artifact);
}
}
exports.signatureContent = signatureContent;
function key(bundle) {
switch (bundle.verificationMaterial.content.$case) {
case 'publicKey':
return {
$case: 'public-key',
hint: bundle.verificationMaterial.content.publicKey.hint,
};
case 'x509CertificateChain':
return {
$case: 'certificate',
certificate: core_1.X509Certificate.parse(bundle.verificationMaterial.content.x509CertificateChain
.certificates[0].rawBytes),
};
case 'certificate':
return {
$case: 'certificate',
certificate: core_1.X509Certificate.parse(bundle.verificationMaterial.content.certificate.rawBytes),
};
}
}

14
node_modules/@sigstore/verify/dist/bundle/message.d.ts generated vendored Normal file
View file

@ -0,0 +1,14 @@
/// <reference types="node" />
/// <reference types="node" />
import { crypto } from '@sigstore/core';
import type { MessageSignature } from '@sigstore/bundle';
import type { SignatureContent } from '../shared.types';
export declare class MessageSignatureContent implements SignatureContent {
readonly signature: Buffer;
private readonly messageDigest;
private readonly artifact;
constructor(messageSignature: MessageSignature, artifact: Buffer);
compareSignature(signature: Buffer): boolean;
compareDigest(digest: Buffer): boolean;
verifySignature(key: crypto.KeyObject): boolean;
}

36
node_modules/@sigstore/verify/dist/bundle/message.js generated vendored Normal file
View file

@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageSignatureContent = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const core_1 = require("@sigstore/core");
class MessageSignatureContent {
constructor(messageSignature, artifact) {
this.signature = messageSignature.signature;
this.messageDigest = messageSignature.messageDigest.digest;
this.artifact = artifact;
}
compareSignature(signature) {
return core_1.crypto.bufferEqual(signature, this.signature);
}
compareDigest(digest) {
return core_1.crypto.bufferEqual(digest, this.messageDigest);
}
verifySignature(key) {
return core_1.crypto.verify(this.artifact, key, this.signature);
}
}
exports.MessageSignatureContent = MessageSignatureContent;

16
node_modules/@sigstore/verify/dist/error.d.ts generated vendored Normal file
View file

@ -0,0 +1,16 @@
declare class BaseError<T extends string> extends Error {
code: T;
cause: any;
constructor({ code, message, cause, }: {
code: T;
message: string;
cause?: any;
});
}
type VerificationErrorCode = 'NOT_IMPLEMENTED_ERROR' | 'TLOG_INCLUSION_PROOF_ERROR' | 'TLOG_INCLUSION_PROMISE_ERROR' | 'TLOG_MISSING_INCLUSION_ERROR' | 'TLOG_BODY_ERROR' | 'CERTIFICATE_ERROR' | 'PUBLIC_KEY_ERROR' | 'SIGNATURE_ERROR' | 'TIMESTAMP_ERROR';
export declare class VerificationError extends BaseError<VerificationErrorCode> {
}
type PolicyErrorCode = 'UNTRUSTED_SIGNER_ERROR';
export declare class PolicyError extends BaseError<PolicyErrorCode> {
}
export {};

32
node_modules/@sigstore/verify/dist/error.js generated vendored Normal file
View file

@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PolicyError = exports.VerificationError = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
class BaseError extends Error {
constructor({ code, message, cause, }) {
super(message);
this.code = code;
this.cause = cause;
this.name = this.constructor.name;
}
}
class VerificationError extends BaseError {
}
exports.VerificationError = VerificationError;
class PolicyError extends BaseError {
}
exports.PolicyError = PolicyError;

5
node_modules/@sigstore/verify/dist/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,5 @@
export { toSignedEntity } from './bundle';
export { PolicyError, VerificationError } from './error';
export { KeyFinderFunc, TrustMaterial, toTrustMaterial } from './trust';
export { Verifier, VerifierOptions } from './verifier';
export type { SignedEntity, Signer, VerificationPolicy } from './shared.types';

28
node_modules/@sigstore/verify/dist/index.js generated vendored Normal file
View file

@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Verifier = exports.toTrustMaterial = exports.VerificationError = exports.PolicyError = exports.toSignedEntity = void 0;
/* istanbul ignore file */
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var bundle_1 = require("./bundle");
Object.defineProperty(exports, "toSignedEntity", { enumerable: true, get: function () { return bundle_1.toSignedEntity; } });
var error_1 = require("./error");
Object.defineProperty(exports, "PolicyError", { enumerable: true, get: function () { return error_1.PolicyError; } });
Object.defineProperty(exports, "VerificationError", { enumerable: true, get: function () { return error_1.VerificationError; } });
var trust_1 = require("./trust");
Object.defineProperty(exports, "toTrustMaterial", { enumerable: true, get: function () { return trust_1.toTrustMaterial; } });
var verifier_1 = require("./verifier");
Object.defineProperty(exports, "Verifier", { enumerable: true, get: function () { return verifier_1.Verifier; } });

View file

@ -0,0 +1,19 @@
import { X509Certificate } from '@sigstore/core';
import { CertAuthority } from '../trust';
export declare function verifyCertificateChain(leaf: X509Certificate, certificateAuthorities: CertAuthority[]): X509Certificate[];
interface CertificateChainVerifierOptions {
trustedCerts: X509Certificate[];
untrustedCert: X509Certificate;
}
export declare class CertificateChainVerifier {
private untrustedCert;
private trustedCerts;
private localCerts;
constructor(opts: CertificateChainVerifierOptions);
verify(): X509Certificate[];
private sort;
private buildPaths;
private findIssuer;
private checkPath;
}
export {};

205
node_modules/@sigstore/verify/dist/key/certificate.js generated vendored Normal file
View file

@ -0,0 +1,205 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CertificateChainVerifier = exports.verifyCertificateChain = void 0;
const error_1 = require("../error");
const trust_1 = require("../trust");
function verifyCertificateChain(leaf, certificateAuthorities) {
// Filter list of trusted CAs to those which are valid for the given
// leaf certificate.
const cas = (0, trust_1.filterCertAuthorities)(certificateAuthorities, {
start: leaf.notBefore,
end: leaf.notAfter,
});
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
let error;
for (const ca of cas) {
try {
const verifier = new CertificateChainVerifier({
trustedCerts: ca.certChain,
untrustedCert: leaf,
});
return verifier.verify();
}
catch (err) {
error = err;
}
}
// If we failed to verify the certificate chain for all of the trusted
// CAs, throw the last error we encountered.
throw new error_1.VerificationError({
code: 'CERTIFICATE_ERROR',
message: 'Failed to verify certificate chain',
cause: error,
});
}
exports.verifyCertificateChain = verifyCertificateChain;
class CertificateChainVerifier {
constructor(opts) {
this.untrustedCert = opts.untrustedCert;
this.trustedCerts = opts.trustedCerts;
this.localCerts = dedupeCertificates([
...opts.trustedCerts,
opts.untrustedCert,
]);
}
verify() {
// Construct certificate path from leaf to root
const certificatePath = this.sort();
// Perform validation checks on each certificate in the path
this.checkPath(certificatePath);
// Return verified certificate path
return certificatePath;
}
sort() {
const leafCert = this.untrustedCert;
// Construct all possible paths from the leaf
let paths = this.buildPaths(leafCert);
// Filter for paths which contain a trusted certificate
paths = paths.filter((path) => path.some((cert) => this.trustedCerts.includes(cert)));
if (paths.length === 0) {
throw new error_1.VerificationError({
code: 'CERTIFICATE_ERROR',
message: 'no trusted certificate path found',
});
}
// Find the shortest of possible paths
/* istanbul ignore next */
const path = paths.reduce((prev, curr) => prev.length < curr.length ? prev : curr);
// Construct chain from shortest path
// Removes the last certificate in the path, which will be a second copy
// of the root certificate given that the root is self-signed.
return [leafCert, ...path].slice(0, -1);
}
// Recursively build all possible paths from the leaf to the root
buildPaths(certificate) {
const paths = [];
const issuers = this.findIssuer(certificate);
if (issuers.length === 0) {
throw new error_1.VerificationError({
code: 'CERTIFICATE_ERROR',
message: 'no valid certificate path found',
});
}
for (let i = 0; i < issuers.length; i++) {
const issuer = issuers[i];
// Base case - issuer is self
if (issuer.equals(certificate)) {
paths.push([certificate]);
continue;
}
// Recursively build path for the issuer
const subPaths = this.buildPaths(issuer);
// Construct paths by appending the issuer to each subpath
for (let j = 0; j < subPaths.length; j++) {
paths.push([issuer, ...subPaths[j]]);
}
}
return paths;
}
// Return all possible issuers for the given certificate
findIssuer(certificate) {
let issuers = [];
let keyIdentifier;
// Exit early if the certificate is self-signed
if (certificate.subject.equals(certificate.issuer)) {
if (certificate.verify()) {
return [certificate];
}
}
// If the certificate has an authority key identifier, use that
// to find the issuer
if (certificate.extAuthorityKeyID) {
keyIdentifier = certificate.extAuthorityKeyID.keyIdentifier;
// TODO: Add support for authorityCertIssuer/authorityCertSerialNumber
// though Fulcio doesn't appear to use these
}
// Find possible issuers by comparing the authorityKeyID/subjectKeyID
// or issuer/subject. Potential issuers are added to the result array.
this.localCerts.forEach((possibleIssuer) => {
if (keyIdentifier) {
if (possibleIssuer.extSubjectKeyID) {
if (possibleIssuer.extSubjectKeyID.keyIdentifier.equals(keyIdentifier)) {
issuers.push(possibleIssuer);
}
return;
}
}
// Fallback to comparing certificate issuer and subject if
// subjectKey/authorityKey extensions are not present
if (possibleIssuer.subject.equals(certificate.issuer)) {
issuers.push(possibleIssuer);
}
});
// Remove any issuers which fail to verify the certificate
issuers = issuers.filter((issuer) => {
try {
return certificate.verify(issuer);
}
catch (ex) {
/* istanbul ignore next - should never error */
return false;
}
});
return issuers;
}
checkPath(path) {
/* istanbul ignore if */
if (path.length < 1) {
throw new error_1.VerificationError({
code: 'CERTIFICATE_ERROR',
message: 'certificate chain must contain at least one certificate',
});
}
// Ensure that all certificates beyond the leaf are CAs
const validCAs = path.slice(1).every((cert) => cert.isCA);
if (!validCAs) {
throw new error_1.VerificationError({
code: 'CERTIFICATE_ERROR',
message: 'intermediate certificate is not a CA',
});
}
// Certificate's issuer must match the subject of the next certificate
// in the chain
for (let i = path.length - 2; i >= 0; i--) {
/* istanbul ignore if */
if (!path[i].issuer.equals(path[i + 1].subject)) {
throw new error_1.VerificationError({
code: 'CERTIFICATE_ERROR',
message: 'incorrect certificate name chaining',
});
}
}
// Check pathlength constraints
for (let i = 0; i < path.length; i++) {
const cert = path[i];
// If the certificate is a CA, check the path length
if (cert.extBasicConstraints?.isCA) {
const pathLength = cert.extBasicConstraints.pathLenConstraint;
// The path length, if set, indicates how many intermediate
// certificates (NOT including the leaf) are allowed to follow. The
// pathLength constraint of any intermediate CA certificate MUST be
// greater than or equal to it's own depth in the chain (with an
// adjustment for the leaf certificate)
if (pathLength !== undefined && pathLength < i - 1) {
throw new error_1.VerificationError({
code: 'CERTIFICATE_ERROR',
message: 'path length constraint exceeded',
});
}
}
}
}
}
exports.CertificateChainVerifier = CertificateChainVerifier;
// Remove duplicate certificates from the array
function dedupeCertificates(certs) {
for (let i = 0; i < certs.length; i++) {
for (let j = i + 1; j < certs.length; j++) {
if (certs[i].equals(certs[j])) {
certs.splice(j, 1);
j--;
}
}
}
return certs;
}

10
node_modules/@sigstore/verify/dist/key/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,10 @@
import { X509Certificate } from '@sigstore/core';
import { VerifiedSCTProvider } from './sct';
import type { Signer } from '../shared.types';
import type { TrustMaterial } from '../trust';
export type CertificateVerificationResult = {
signer: Signer;
scts: VerifiedSCTProvider[];
};
export declare function verifyPublicKey(hint: string, timestamps: Date[], trustMaterial: TrustMaterial): Signer;
export declare function verifyCertificate(leaf: X509Certificate, timestamps: Date[], trustMaterial: TrustMaterial): CertificateVerificationResult;

72
node_modules/@sigstore/verify/dist/key/index.js generated vendored Normal file
View file

@ -0,0 +1,72 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyCertificate = exports.verifyPublicKey = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const core_1 = require("@sigstore/core");
const error_1 = require("../error");
const certificate_1 = require("./certificate");
const sct_1 = require("./sct");
const OID_FULCIO_ISSUER_V1 = '1.3.6.1.4.1.57264.1.1';
const OID_FULCIO_ISSUER_V2 = '1.3.6.1.4.1.57264.1.8';
function verifyPublicKey(hint, timestamps, trustMaterial) {
const key = trustMaterial.publicKey(hint);
timestamps.forEach((timestamp) => {
if (!key.validFor(timestamp)) {
throw new error_1.VerificationError({
code: 'PUBLIC_KEY_ERROR',
message: `Public key is not valid for timestamp: ${timestamp.toISOString()}`,
});
}
});
return { key: key.publicKey };
}
exports.verifyPublicKey = verifyPublicKey;
function verifyCertificate(leaf, timestamps, trustMaterial) {
// Check that leaf certificate chains to a trusted CA
const path = (0, certificate_1.verifyCertificateChain)(leaf, trustMaterial.certificateAuthorities);
// Check that ALL certificates are valid for ALL of the timestamps
const validForDate = timestamps.every((timestamp) => path.every((cert) => cert.validForDate(timestamp)));
if (!validForDate) {
throw new error_1.VerificationError({
code: 'CERTIFICATE_ERROR',
message: 'certificate is not valid or expired at the specified date',
});
}
return {
scts: (0, sct_1.verifySCTs)(path[0], path[1], trustMaterial.ctlogs),
signer: getSigner(path[0]),
};
}
exports.verifyCertificate = verifyCertificate;
function getSigner(cert) {
let issuer;
const issuerExtension = cert.extension(OID_FULCIO_ISSUER_V2);
if (issuerExtension) {
issuer = issuerExtension.valueObj.subs?.[0]?.value.toString('ascii');
}
else {
issuer = cert.extension(OID_FULCIO_ISSUER_V1)?.value.toString('ascii');
}
const identity = {
extensions: { issuer },
subjectAlternativeName: cert.subjectAltName,
};
return {
key: core_1.crypto.createPublicKey(cert.publicKey),
identity,
};
}

5
node_modules/@sigstore/verify/dist/key/sct.d.ts generated vendored Normal file
View file

@ -0,0 +1,5 @@
/// <reference types="node" />
import { X509Certificate } from '@sigstore/core';
import type { TLogAuthority } from '../trust';
export type VerifiedSCTProvider = Buffer;
export declare function verifySCTs(cert: X509Certificate, issuer: X509Certificate, ctlogs: TLogAuthority[]): VerifiedSCTProvider[];

79
node_modules/@sigstore/verify/dist/key/sct.js generated vendored Normal file
View file

@ -0,0 +1,79 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifySCTs = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const core_1 = require("@sigstore/core");
const error_1 = require("../error");
const trust_1 = require("../trust");
function verifySCTs(cert, issuer, ctlogs) {
let extSCT;
// Verifying the SCT requires that we remove the SCT extension and
// re-encode the TBS structure to DER -- this value is part of the data
// over which the signature is calculated. Since this is a destructive action
// we create a copy of the certificate so we can remove the SCT extension
// without affecting the original certificate.
const clone = cert.clone();
// Intentionally not using the findExtension method here because we want to
// remove the the SCT extension from the certificate before calculating the
// PreCert structure
for (let i = 0; i < clone.extensions.length; i++) {
const ext = clone.extensions[i];
if (ext.subs[0].toOID() === core_1.EXTENSION_OID_SCT) {
extSCT = new core_1.X509SCTExtension(ext);
// Remove the extension from the certificate
clone.extensions.splice(i, 1);
break;
}
}
// No SCT extension found to verify
if (!extSCT) {
return [];
}
// Found an SCT extension but it has no SCTs
/* istanbul ignore if -- too difficult to fabricate test case for this */
if (extSCT.signedCertificateTimestamps.length === 0) {
return [];
}
// Construct the PreCert structure
// https://www.rfc-editor.org/rfc/rfc6962#section-3.2
const preCert = new core_1.ByteStream();
// Calculate hash of the issuer's public key
const issuerId = core_1.crypto.hash(issuer.publicKey);
preCert.appendView(issuerId);
// Re-encodes the certificate to DER after removing the SCT extension
const tbs = clone.tbsCertificate.toDER();
preCert.appendUint24(tbs.length);
preCert.appendView(tbs);
// Calculate and return the verification results for each SCT
return extSCT.signedCertificateTimestamps.map((sct) => {
// Find the ctlog instance that corresponds to the SCT's logID
const validCTLogs = (0, trust_1.filterTLogAuthorities)(ctlogs, {
logID: sct.logID,
targetDate: sct.datetime,
});
// See if the SCT is valid for any of the CT logs
const verified = validCTLogs.some((log) => sct.verify(preCert.buffer, log.publicKey));
if (!verified) {
throw new error_1.VerificationError({
code: 'CERTIFICATE_ERROR',
message: 'SCT verification failed',
});
}
return sct.logID;
});
}
exports.verifySCTs = verifySCTs;

3
node_modules/@sigstore/verify/dist/policy.d.ts generated vendored Normal file
View file

@ -0,0 +1,3 @@
import { CertificateExtensions } from './shared.types';
export declare function verifySubjectAlternativeName(policyIdentity: string, signerIdentity: string | undefined): void;
export declare function verifyExtensions(policyExtensions: CertificateExtensions, signerExtensions?: CertificateExtensions): void;

25
node_modules/@sigstore/verify/dist/policy.js generated vendored Normal file
View file

@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyExtensions = exports.verifySubjectAlternativeName = void 0;
const error_1 = require("./error");
function verifySubjectAlternativeName(policyIdentity, signerIdentity) {
if (signerIdentity === undefined || !signerIdentity.match(policyIdentity)) {
throw new error_1.PolicyError({
code: 'UNTRUSTED_SIGNER_ERROR',
message: `certificate identity error - expected ${policyIdentity}, got ${signerIdentity}`,
});
}
}
exports.verifySubjectAlternativeName = verifySubjectAlternativeName;
function verifyExtensions(policyExtensions, signerExtensions = {}) {
let key;
for (key in policyExtensions) {
if (signerExtensions[key] !== policyExtensions[key]) {
throw new error_1.PolicyError({
code: 'UNTRUSTED_SIGNER_ERROR',
message: `invalid certificate extension - expected ${key}=${policyExtensions[key]}, got ${key}=${signerExtensions[key]}`,
});
}
}
}
exports.verifyExtensions = verifyExtensions;

50
node_modules/@sigstore/verify/dist/shared.types.d.ts generated vendored Normal file
View file

@ -0,0 +1,50 @@
/// <reference types="node" />
/// <reference types="node" />
import type { TransparencyLogEntry } from '@sigstore/bundle';
import type { RFC3161Timestamp, X509Certificate, crypto } from '@sigstore/core';
export type CertificateExtensionName = 'issuer';
export type CertificateExtensions = {
[key in CertificateExtensionName]?: string;
};
export type CertificateIdentity = {
subjectAlternativeName?: string;
extensions?: CertificateExtensions;
};
export type VerificationPolicy = CertificateIdentity;
export type Signer = {
key: crypto.KeyObject;
identity?: CertificateIdentity;
};
export type Timestamp = {
$case: 'timestamp-authority';
timestamp: RFC3161Timestamp;
} | {
$case: 'transparency-log';
tlogEntry: TransparencyLogEntry;
};
export type VerificationKey = {
$case: 'public-key';
hint: string;
} | {
$case: 'certificate';
certificate: X509Certificate;
};
export type SignatureContent = {
signature: Buffer;
compareSignature(signature: Buffer): boolean;
compareDigest(digest: Buffer): boolean;
verifySignature(key: crypto.KeyObject): boolean;
};
export type TimestampProvider = {
timestamps: Timestamp[];
};
export type SignatureProvider = {
signature: SignatureContent;
};
export type KeyProvider = {
key: VerificationKey;
};
export type TLogEntryProvider = {
tlogEntries: TransparencyLogEntry[];
};
export type SignedEntity = SignatureProvider & KeyProvider & TimestampProvider & TLogEntryProvider;

2
node_modules/@sigstore/verify/dist/shared.types.js generated vendored Normal file
View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View file

@ -0,0 +1,3 @@
import { TLogAuthority } from '../trust';
import type { TLogEntryWithInclusionProof } from '@sigstore/bundle';
export declare function verifyCheckpoint(entry: TLogEntryWithInclusionProof, tlogs: TLogAuthority[]): void;

View file

@ -0,0 +1,158 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyCheckpoint = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const core_1 = require("@sigstore/core");
const error_1 = require("../error");
const trust_1 = require("../trust");
// Separator between the note and the signatures in a checkpoint
const CHECKPOINT_SEPARATOR = '\n\n';
// Checkpoint signatures are of the following form:
// " <identity> <key_hint+signature_bytes>\n"
// where:
// - the prefix is an emdash (U+2014).
// - <identity> gives a human-readable representation of the signing ID.
// - <key_hint+signature_bytes> is the first 4 bytes of the SHA256 hash of the
// associated public key followed by the signature bytes.
const SIGNATURE_REGEX = /\u2014 (\S+) (\S+)\n/g;
// Verifies the checkpoint value in the given tlog entry. There are two steps
// to the verification:
// 1. Verify that all signatures in the checkpoint can be verified against a
// trusted public key
// 2. Verify that the root hash in the checkpoint matches the root hash in the
// inclusion proof
// See: https://github.com/transparency-dev/formats/blob/main/log/README.md
function verifyCheckpoint(entry, tlogs) {
// Filter tlog instances to just those which were valid at the time of the
// entry
const validTLogs = (0, trust_1.filterTLogAuthorities)(tlogs, {
targetDate: new Date(Number(entry.integratedTime) * 1000),
});
const inclusionProof = entry.inclusionProof;
const signedNote = SignedNote.fromString(inclusionProof.checkpoint.envelope);
const checkpoint = LogCheckpoint.fromString(signedNote.note);
// Verify that the signatures in the checkpoint are all valid
if (!verifySignedNote(signedNote, validTLogs)) {
throw new error_1.VerificationError({
code: 'TLOG_INCLUSION_PROOF_ERROR',
message: 'invalid checkpoint signature',
});
}
// Verify that the root hash from the checkpoint matches the root hash in the
// inclusion proof
if (!core_1.crypto.bufferEqual(checkpoint.logHash, inclusionProof.rootHash)) {
throw new error_1.VerificationError({
code: 'TLOG_INCLUSION_PROOF_ERROR',
message: 'root hash mismatch',
});
}
}
exports.verifyCheckpoint = verifyCheckpoint;
// Verifies the signatures in the SignedNote. For each signature, the
// corresponding transparency log is looked up by the key hint and the
// signature is verified against the public key in the transparency log.
// Throws an error if any of the signatures are invalid.
function verifySignedNote(signedNote, tlogs) {
const data = Buffer.from(signedNote.note, 'utf-8');
return signedNote.signatures.every((signature) => {
// Find the transparency log instance with the matching key hint
const tlog = tlogs.find((tlog) => core_1.crypto.bufferEqual(tlog.logID.subarray(0, 4), signature.keyHint));
if (!tlog) {
return false;
}
return core_1.crypto.verify(data, tlog.publicKey, signature.signature);
});
}
// SignedNote represents a signed note from a transparency log checkpoint. Consists
// of a body (or note) and one more signatures calculated over the body. See
// https://github.com/transparency-dev/formats/blob/main/log/README.md#signed-envelope
class SignedNote {
constructor(note, signatures) {
this.note = note;
this.signatures = signatures;
}
// Deserialize a SignedNote from a string
static fromString(envelope) {
if (!envelope.includes(CHECKPOINT_SEPARATOR)) {
throw new error_1.VerificationError({
code: 'TLOG_INCLUSION_PROOF_ERROR',
message: 'missing checkpoint separator',
});
}
// Split the note into the header and the data portions at the separator
const split = envelope.indexOf(CHECKPOINT_SEPARATOR);
const header = envelope.slice(0, split + 1);
const data = envelope.slice(split + CHECKPOINT_SEPARATOR.length);
// Find all the signature lines in the data portion
const matches = data.matchAll(SIGNATURE_REGEX);
// Parse each of the matched signature lines into the name and signature.
// The first four bytes of the signature are the key hint (should match the
// first four bytes of the log ID), and the rest is the signature itself.
const signatures = Array.from(matches, (match) => {
const [, name, signature] = match;
const sigBytes = Buffer.from(signature, 'base64');
if (sigBytes.length < 5) {
throw new error_1.VerificationError({
code: 'TLOG_INCLUSION_PROOF_ERROR',
message: 'malformed checkpoint signature',
});
}
return {
name,
keyHint: sigBytes.subarray(0, 4),
signature: sigBytes.subarray(4),
};
});
if (signatures.length === 0) {
throw new error_1.VerificationError({
code: 'TLOG_INCLUSION_PROOF_ERROR',
message: 'no signatures found in checkpoint',
});
}
return new SignedNote(header, signatures);
}
}
// LogCheckpoint represents a transparency log checkpoint. Consists of the
// following:
// - origin: the name of the transparency log
// - logSize: the size of the log at the time of the checkpoint
// - logHash: the root hash of the log at the time of the checkpoint
// - rest: the rest of the checkpoint body, which is a list of log entries
// See:
// https://github.com/transparency-dev/formats/blob/main/log/README.md#checkpoint-body
class LogCheckpoint {
constructor(origin, logSize, logHash, rest) {
this.origin = origin;
this.logSize = logSize;
this.logHash = logHash;
this.rest = rest;
}
static fromString(note) {
const lines = note.trimEnd().split('\n');
if (lines.length < 3) {
throw new error_1.VerificationError({
code: 'TLOG_INCLUSION_PROOF_ERROR',
message: 'too few lines in checkpoint header',
});
}
const origin = lines[0];
const logSize = BigInt(lines[1]);
const rootHash = Buffer.from(lines[2], 'base64');
const rest = lines.slice(3);
return new LogCheckpoint(origin, logSize, rootHash, rest);
}
}

View file

@ -0,0 +1,12 @@
/// <reference types="node" />
import { RFC3161Timestamp } from '@sigstore/core';
import type { TransparencyLogEntry } from '@sigstore/bundle';
import type { CertAuthority, TLogAuthority } from '../trust';
export type TimestampType = 'transparency-log' | 'timestamp-authority';
export type TimestampVerificationResult = {
type: TimestampType;
logID: Buffer;
timestamp: Date;
};
export declare function verifyTSATimestamp(timestamp: RFC3161Timestamp, data: Buffer, timestampAuthorities: CertAuthority[]): TimestampVerificationResult;
export declare function verifyTLogTimestamp(entry: TransparencyLogEntry, tlogAuthorities: TLogAuthority[]): TimestampVerificationResult;

47
node_modules/@sigstore/verify/dist/timestamp/index.js generated vendored Normal file
View file

@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyTLogTimestamp = exports.verifyTSATimestamp = void 0;
const error_1 = require("../error");
const checkpoint_1 = require("./checkpoint");
const merkle_1 = require("./merkle");
const set_1 = require("./set");
const tsa_1 = require("./tsa");
function verifyTSATimestamp(timestamp, data, timestampAuthorities) {
(0, tsa_1.verifyRFC3161Timestamp)(timestamp, data, timestampAuthorities);
return {
type: 'timestamp-authority',
logID: timestamp.signerSerialNumber,
timestamp: timestamp.signingTime,
};
}
exports.verifyTSATimestamp = verifyTSATimestamp;
function verifyTLogTimestamp(entry, tlogAuthorities) {
let inclusionVerified = false;
if (isTLogEntryWithInclusionPromise(entry)) {
(0, set_1.verifyTLogSET)(entry, tlogAuthorities);
inclusionVerified = true;
}
if (isTLogEntryWithInclusionProof(entry)) {
(0, merkle_1.verifyMerkleInclusion)(entry);
(0, checkpoint_1.verifyCheckpoint)(entry, tlogAuthorities);
inclusionVerified = true;
}
if (!inclusionVerified) {
throw new error_1.VerificationError({
code: 'TLOG_MISSING_INCLUSION_ERROR',
message: 'inclusion could not be verified',
});
}
return {
type: 'transparency-log',
logID: entry.logId.keyId,
timestamp: new Date(Number(entry.integratedTime) * 1000),
};
}
exports.verifyTLogTimestamp = verifyTLogTimestamp;
function isTLogEntryWithInclusionPromise(entry) {
return entry.inclusionPromise !== undefined;
}
function isTLogEntryWithInclusionProof(entry) {
return entry.inclusionProof !== undefined;
}

View file

@ -0,0 +1,2 @@
import type { TLogEntryWithInclusionProof } from '@sigstore/bundle';
export declare function verifyMerkleInclusion(entry: TLogEntryWithInclusionProof): void;

105
node_modules/@sigstore/verify/dist/timestamp/merkle.js generated vendored Normal file
View file

@ -0,0 +1,105 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyMerkleInclusion = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const core_1 = require("@sigstore/core");
const error_1 = require("../error");
const RFC6962_LEAF_HASH_PREFIX = Buffer.from([0x00]);
const RFC6962_NODE_HASH_PREFIX = Buffer.from([0x01]);
function verifyMerkleInclusion(entry) {
const inclusionProof = entry.inclusionProof;
const logIndex = BigInt(inclusionProof.logIndex);
const treeSize = BigInt(inclusionProof.treeSize);
if (logIndex < 0n || logIndex >= treeSize) {
throw new error_1.VerificationError({
code: 'TLOG_INCLUSION_PROOF_ERROR',
message: `invalid index: ${logIndex}`,
});
}
// Figure out which subset of hashes corresponds to the inner and border
// nodes
const { inner, border } = decompInclProof(logIndex, treeSize);
if (inclusionProof.hashes.length !== inner + border) {
throw new error_1.VerificationError({
code: 'TLOG_INCLUSION_PROOF_ERROR',
message: 'invalid hash count',
});
}
const innerHashes = inclusionProof.hashes.slice(0, inner);
const borderHashes = inclusionProof.hashes.slice(inner);
// The entry's hash is the leaf hash
const leafHash = hashLeaf(entry.canonicalizedBody);
// Chain the hashes belonging to the inner and border portions
const calculatedHash = chainBorderRight(chainInner(leafHash, innerHashes, logIndex), borderHashes);
// Calculated hash should match the root hash in the inclusion proof
if (!core_1.crypto.bufferEqual(calculatedHash, inclusionProof.rootHash)) {
throw new error_1.VerificationError({
code: 'TLOG_INCLUSION_PROOF_ERROR',
message: 'calculated root hash does not match inclusion proof',
});
}
}
exports.verifyMerkleInclusion = verifyMerkleInclusion;
// Breaks down inclusion proof for a leaf at the specified index in a tree of
// the specified size. The split point is where paths to the index leaf and
// the (size - 1) leaf diverge. Returns lengths of the bottom and upper proof
// parts.
function decompInclProof(index, size) {
const inner = innerProofSize(index, size);
const border = onesCount(index >> BigInt(inner));
return { inner, border };
}
// Computes a subtree hash for a node on or below the tree's right border.
// Assumes the provided proof hashes are ordered from lower to higher levels
// and seed is the initial hash of the node specified by the index.
function chainInner(seed, hashes, index) {
return hashes.reduce((acc, h, i) => {
if ((index >> BigInt(i)) & BigInt(1)) {
return hashChildren(h, acc);
}
else {
return hashChildren(acc, h);
}
}, seed);
}
// Computes a subtree hash for nodes along the tree's right border.
function chainBorderRight(seed, hashes) {
return hashes.reduce((acc, h) => hashChildren(h, acc), seed);
}
function innerProofSize(index, size) {
return bitLength(index ^ (size - BigInt(1)));
}
// Counts the number of ones in the binary representation of the given number.
// https://en.wikipedia.org/wiki/Hamming_weight
function onesCount(num) {
return num.toString(2).split('1').length - 1;
}
// Returns the number of bits necessary to represent an integer in binary.
function bitLength(n) {
if (n === 0n) {
return 0;
}
return n.toString(2).length;
}
// Hashing logic according to RFC6962.
// https://datatracker.ietf.org/doc/html/rfc6962#section-2
function hashChildren(left, right) {
return core_1.crypto.hash(RFC6962_NODE_HASH_PREFIX, left, right);
}
function hashLeaf(leaf) {
return core_1.crypto.hash(RFC6962_LEAF_HASH_PREFIX, leaf);
}

View file

@ -0,0 +1,3 @@
import { TLogAuthority } from '../trust';
import type { TLogEntryWithInclusionPromise } from '@sigstore/bundle';
export declare function verifyTLogSET(entry: TLogEntryWithInclusionPromise, tlogs: TLogAuthority[]): void;

61
node_modules/@sigstore/verify/dist/timestamp/set.js generated vendored Normal file
View file

@ -0,0 +1,61 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyTLogSET = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const core_1 = require("@sigstore/core");
const error_1 = require("../error");
const trust_1 = require("../trust");
// Verifies the SET for the given entry against the list of trusted
// transparency logs. Returns true if the SET can be verified against at least
// one of the trusted logs; otherwise, returns false.
function verifyTLogSET(entry, tlogs) {
// Filter the list of tlog instances to only those which might be able to
// verify the SET
const validTLogs = (0, trust_1.filterTLogAuthorities)(tlogs, {
logID: entry.logId.keyId,
targetDate: new Date(Number(entry.integratedTime) * 1000),
});
// Check to see if we can verify the SET against any of the valid tlogs
const verified = validTLogs.some((tlog) => {
// Re-create the original Rekor verification payload
const payload = toVerificationPayload(entry);
// Canonicalize the payload and turn into a buffer for verification
const data = Buffer.from(core_1.json.canonicalize(payload), 'utf8');
// Extract the SET from the tlog entry
const signature = entry.inclusionPromise.signedEntryTimestamp;
return core_1.crypto.verify(data, tlog.publicKey, signature);
});
if (!verified) {
throw new error_1.VerificationError({
code: 'TLOG_INCLUSION_PROMISE_ERROR',
message: 'inclusion promise could not be verified',
});
}
}
exports.verifyTLogSET = verifyTLogSET;
// Returns a properly formatted "VerificationPayload" for one of the
// transaction log entires in the given bundle which can be used for SET
// verification.
function toVerificationPayload(entry) {
const { integratedTime, logIndex, logId, canonicalizedBody } = entry;
return {
body: canonicalizedBody.toString('base64'),
integratedTime: Number(integratedTime),
logIndex: Number(logIndex),
logID: logId.keyId.toString('hex'),
};
}

View file

@ -0,0 +1,4 @@
/// <reference types="node" />
import { RFC3161Timestamp } from '@sigstore/core';
import { CertAuthority } from '../trust';
export declare function verifyRFC3161Timestamp(timestamp: RFC3161Timestamp, data: Buffer, timestampAuthorities: CertAuthority[]): void;

74
node_modules/@sigstore/verify/dist/timestamp/tsa.js generated vendored Normal file
View file

@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyRFC3161Timestamp = void 0;
const core_1 = require("@sigstore/core");
const error_1 = require("../error");
const certificate_1 = require("../key/certificate");
const trust_1 = require("../trust");
function verifyRFC3161Timestamp(timestamp, data, timestampAuthorities) {
const signingTime = timestamp.signingTime;
// Filter for CAs which were valid at the time of signing
timestampAuthorities = (0, trust_1.filterCertAuthorities)(timestampAuthorities, {
start: signingTime,
end: signingTime,
});
// Filter for CAs which match serial and issuer embedded in the timestamp
timestampAuthorities = filterCAsBySerialAndIssuer(timestampAuthorities, {
serialNumber: timestamp.signerSerialNumber,
issuer: timestamp.signerIssuer,
});
// Check that we can verify the timestamp with AT LEAST ONE of the remaining
// CAs
const verified = timestampAuthorities.some((ca) => {
try {
verifyTimestampForCA(timestamp, data, ca);
return true;
}
catch (e) {
return false;
}
});
if (!verified) {
throw new error_1.VerificationError({
code: 'TIMESTAMP_ERROR',
message: 'timestamp could not be verified',
});
}
}
exports.verifyRFC3161Timestamp = verifyRFC3161Timestamp;
function verifyTimestampForCA(timestamp, data, ca) {
const [leaf, ...cas] = ca.certChain;
const signingKey = core_1.crypto.createPublicKey(leaf.publicKey);
const signingTime = timestamp.signingTime;
// Verify the certificate chain for the provided CA
try {
new certificate_1.CertificateChainVerifier({
untrustedCert: leaf,
trustedCerts: cas,
}).verify();
}
catch (e) {
throw new error_1.VerificationError({
code: 'TIMESTAMP_ERROR',
message: 'invalid certificate chain',
});
}
// Check that all of the CA certs were valid at the time of signing
const validAtSigningTime = ca.certChain.every((cert) => cert.validForDate(signingTime));
if (!validAtSigningTime) {
throw new error_1.VerificationError({
code: 'TIMESTAMP_ERROR',
message: 'timestamp was signed with an expired certificate',
});
}
// Check that the signing certificate's key can be used to verify the
// timestamp signature.
timestamp.verify(data, signingKey);
}
// Filters the list of CAs to those which have a leaf signing certificate which
// matches the given serial number and issuer.
function filterCAsBySerialAndIssuer(timestampAuthorities, criteria) {
return timestampAuthorities.filter((ca) => ca.certChain.length > 0 &&
core_1.crypto.bufferEqual(ca.certChain[0].serialNumber, criteria.serialNumber) &&
core_1.crypto.bufferEqual(ca.certChain[0].issuer, criteria.issuer));
}

3
node_modules/@sigstore/verify/dist/tlog/dsse.d.ts generated vendored Normal file
View file

@ -0,0 +1,3 @@
import type { ProposedDSSEEntry } from '@sigstore/rekor-types';
import type { SignatureContent } from '../shared.types';
export declare function verifyDSSETLogBody(tlogEntry: ProposedDSSEEntry, content: SignatureContent): void;

58
node_modules/@sigstore/verify/dist/tlog/dsse.js generated vendored Normal file
View file

@ -0,0 +1,58 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyDSSETLogBody = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const error_1 = require("../error");
// Compare the given intoto tlog entry to the given bundle
function verifyDSSETLogBody(tlogEntry, content) {
switch (tlogEntry.apiVersion) {
case '0.0.1':
return verifyDSSE001TLogBody(tlogEntry, content);
default:
throw new error_1.VerificationError({
code: 'TLOG_BODY_ERROR',
message: `unsupported dsse version: ${tlogEntry.apiVersion}`,
});
}
}
exports.verifyDSSETLogBody = verifyDSSETLogBody;
// Compare the given dsse v0.0.1 tlog entry to the given DSSE envelope.
function verifyDSSE001TLogBody(tlogEntry, content) {
// Ensure the bundle's DSSE only contains a single signature
if (tlogEntry.spec.signatures?.length !== 1) {
throw new error_1.VerificationError({
code: 'TLOG_BODY_ERROR',
message: 'signature count mismatch',
});
}
const tlogSig = tlogEntry.spec.signatures[0].signature;
// Ensure that the signature in the bundle's DSSE matches tlog entry
if (!content.compareSignature(Buffer.from(tlogSig, 'base64')))
throw new error_1.VerificationError({
code: 'TLOG_BODY_ERROR',
message: 'tlog entry signature mismatch',
});
// Ensure the digest of the bundle's DSSE payload matches the digest in the
// tlog entry
const tlogHash = tlogEntry.spec.payloadHash?.value || '';
if (!content.compareDigest(Buffer.from(tlogHash, 'hex'))) {
throw new error_1.VerificationError({
code: 'TLOG_BODY_ERROR',
message: 'DSSE payload hash mismatch',
});
}
}

View file

@ -0,0 +1,3 @@
import type { ProposedHashedRekordEntry } from '@sigstore/rekor-types';
import type { SignatureContent } from '../shared.types';
export declare function verifyHashedRekordTLogBody(tlogEntry: ProposedHashedRekordEntry, content: SignatureContent): void;

View file

@ -0,0 +1,52 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyHashedRekordTLogBody = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const error_1 = require("../error");
// Compare the given hashedrekord tlog entry to the given bundle
function verifyHashedRekordTLogBody(tlogEntry, content) {
switch (tlogEntry.apiVersion) {
case '0.0.1':
return verifyHashedrekord001TLogBody(tlogEntry, content);
default:
throw new error_1.VerificationError({
code: 'TLOG_BODY_ERROR',
message: `unsupported hashedrekord version: ${tlogEntry.apiVersion}`,
});
}
}
exports.verifyHashedRekordTLogBody = verifyHashedRekordTLogBody;
// Compare the given hashedrekord v0.0.1 tlog entry to the given message
// signature
function verifyHashedrekord001TLogBody(tlogEntry, content) {
// Ensure that the bundles message signature matches the tlog entry
const tlogSig = tlogEntry.spec.signature.content || '';
if (!content.compareSignature(Buffer.from(tlogSig, 'base64'))) {
throw new error_1.VerificationError({
code: 'TLOG_BODY_ERROR',
message: 'signature mismatch',
});
}
// Ensure that the bundle's message digest matches the tlog entry
const tlogDigest = tlogEntry.spec.data.hash?.value || '';
if (!content.compareDigest(Buffer.from(tlogDigest, 'hex'))) {
throw new error_1.VerificationError({
code: 'TLOG_BODY_ERROR',
message: 'digest mismatch',
});
}
}

3
node_modules/@sigstore/verify/dist/tlog/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,3 @@
import type { TransparencyLogEntry } from '@sigstore/bundle';
import type { SignatureContent } from '../shared.types';
export declare function verifyTLogBody(entry: TransparencyLogEntry, sigContent: SignatureContent): void;

48
node_modules/@sigstore/verify/dist/tlog/index.js generated vendored Normal file
View file

@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyTLogBody = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const error_1 = require("../error");
const dsse_1 = require("./dsse");
const hashedrekord_1 = require("./hashedrekord");
const intoto_1 = require("./intoto");
// Verifies that the given tlog entry matches the supplied signature content.
function verifyTLogBody(entry, sigContent) {
const { kind, version } = entry.kindVersion;
const body = JSON.parse(entry.canonicalizedBody.toString('utf8'));
if (kind !== body.kind || version !== body.apiVersion) {
throw new error_1.VerificationError({
code: 'TLOG_BODY_ERROR',
message: `kind/version mismatch - expected: ${kind}/${version}, received: ${body.kind}/${body.apiVersion}`,
});
}
switch (body.kind) {
case 'dsse':
return (0, dsse_1.verifyDSSETLogBody)(body, sigContent);
case 'intoto':
return (0, intoto_1.verifyIntotoTLogBody)(body, sigContent);
case 'hashedrekord':
return (0, hashedrekord_1.verifyHashedRekordTLogBody)(body, sigContent);
/* istanbul ignore next */
default:
throw new error_1.VerificationError({
code: 'TLOG_BODY_ERROR',
message: `unsupported kind: ${kind}`,
});
}
}
exports.verifyTLogBody = verifyTLogBody;

3
node_modules/@sigstore/verify/dist/tlog/intoto.d.ts generated vendored Normal file
View file

@ -0,0 +1,3 @@
import type { ProposedIntotoEntry } from '@sigstore/rekor-types';
import type { SignatureContent } from '../shared.types';
export declare function verifyIntotoTLogBody(tlogEntry: ProposedIntotoEntry, content: SignatureContent): void;

63
node_modules/@sigstore/verify/dist/tlog/intoto.js generated vendored Normal file
View file

@ -0,0 +1,63 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyIntotoTLogBody = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const error_1 = require("../error");
// Compare the given intoto tlog entry to the given bundle
function verifyIntotoTLogBody(tlogEntry, content) {
switch (tlogEntry.apiVersion) {
case '0.0.2':
return verifyIntoto002TLogBody(tlogEntry, content);
default:
throw new error_1.VerificationError({
code: 'TLOG_BODY_ERROR',
message: `unsupported intoto version: ${tlogEntry.apiVersion}`,
});
}
}
exports.verifyIntotoTLogBody = verifyIntotoTLogBody;
// Compare the given intoto v0.0.2 tlog entry to the given DSSE envelope.
function verifyIntoto002TLogBody(tlogEntry, content) {
// Ensure the bundle's DSSE contains a single signature
if (tlogEntry.spec.content.envelope.signatures?.length !== 1) {
throw new error_1.VerificationError({
code: 'TLOG_BODY_ERROR',
message: 'signature count mismatch',
});
}
// Signature is double-base64-encoded in the tlog entry
const tlogSig = base64Decode(tlogEntry.spec.content.envelope.signatures[0].sig);
// Ensure that the signature in the bundle's DSSE matches tlog entry
if (!content.compareSignature(Buffer.from(tlogSig, 'base64'))) {
throw new error_1.VerificationError({
code: 'TLOG_BODY_ERROR',
message: 'tlog entry signature mismatch',
});
}
// Ensure the digest of the bundle's DSSE payload matches the digest in the
// tlog entry
const tlogHash = tlogEntry.spec.content.payloadHash?.value || '';
if (!content.compareDigest(Buffer.from(tlogHash, 'hex'))) {
throw new error_1.VerificationError({
code: 'TLOG_BODY_ERROR',
message: 'DSSE payload hash mismatch',
});
}
}
function base64Decode(str) {
return Buffer.from(str, 'base64').toString('utf-8');
}

13
node_modules/@sigstore/verify/dist/trust/filter.d.ts generated vendored Normal file
View file

@ -0,0 +1,13 @@
/// <reference types="node" />
import type { CertAuthority, TLogAuthority } from './trust.types';
type CertAuthorityFilterCriteria = {
start: Date;
end: Date;
};
export declare function filterCertAuthorities(certAuthorities: CertAuthority[], criteria: CertAuthorityFilterCriteria): CertAuthority[];
type TLogAuthorityFilterCriteria = {
targetDate: Date;
logID?: Buffer;
};
export declare function filterTLogAuthorities(tlogAuthorities: TLogAuthority[], criteria: TLogAuthorityFilterCriteria): TLogAuthority[];
export {};

24
node_modules/@sigstore/verify/dist/trust/filter.js generated vendored Normal file
View file

@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.filterTLogAuthorities = exports.filterCertAuthorities = void 0;
function filterCertAuthorities(certAuthorities, criteria) {
return certAuthorities.filter((ca) => {
return (ca.validFor.start <= criteria.start && ca.validFor.end >= criteria.end);
});
}
exports.filterCertAuthorities = filterCertAuthorities;
// Filter the list of tlog instances to only those which match the given log
// ID and have public keys which are valid for the given integrated time.
function filterTLogAuthorities(tlogAuthorities, criteria) {
return tlogAuthorities.filter((tlog) => {
// If we're filtering by log ID and the log IDs don't match, we can't use
// this tlog
if (criteria.logID && !tlog.logID.equals(criteria.logID)) {
return false;
}
// Check that the integrated time is within the validFor range
return (tlog.validFor.start <= criteria.targetDate &&
criteria.targetDate <= tlog.validFor.end);
});
}
exports.filterTLogAuthorities = filterTLogAuthorities;

5
node_modules/@sigstore/verify/dist/trust/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,5 @@
import { type PublicKey, type TrustedRoot } from '@sigstore/protobuf-specs';
import type { KeyFinderFunc, TrustMaterial } from './trust.types';
export { filterCertAuthorities, filterTLogAuthorities } from './filter';
export type { CertAuthority, KeyFinderFunc, TLogAuthority, TrustMaterial, } from './trust.types';
export declare function toTrustMaterial(root: TrustedRoot, keys?: Record<string, PublicKey> | KeyFinderFunc): TrustMaterial;

84
node_modules/@sigstore/verify/dist/trust/index.js generated vendored Normal file
View file

@ -0,0 +1,84 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.toTrustMaterial = exports.filterTLogAuthorities = exports.filterCertAuthorities = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const core_1 = require("@sigstore/core");
const protobuf_specs_1 = require("@sigstore/protobuf-specs");
const error_1 = require("../error");
const BEGINNING_OF_TIME = new Date(0);
const END_OF_TIME = new Date(8640000000000000);
var filter_1 = require("./filter");
Object.defineProperty(exports, "filterCertAuthorities", { enumerable: true, get: function () { return filter_1.filterCertAuthorities; } });
Object.defineProperty(exports, "filterTLogAuthorities", { enumerable: true, get: function () { return filter_1.filterTLogAuthorities; } });
function toTrustMaterial(root, keys) {
const keyFinder = typeof keys === 'function' ? keys : keyLocator(keys);
return {
certificateAuthorities: root.certificateAuthorities.map(createCertAuthority),
timestampAuthorities: root.timestampAuthorities.map(createCertAuthority),
tlogs: root.tlogs.map(createTLogAuthority),
ctlogs: root.ctlogs.map(createTLogAuthority),
publicKey: keyFinder,
};
}
exports.toTrustMaterial = toTrustMaterial;
function createTLogAuthority(tlogInstance) {
const keyDetails = tlogInstance.publicKey.keyDetails;
const keyType = keyDetails === protobuf_specs_1.PublicKeyDetails.PKCS1_RSA_PKCS1V5 ||
keyDetails === protobuf_specs_1.PublicKeyDetails.PKIX_RSA_PKCS1V5 ||
keyDetails === protobuf_specs_1.PublicKeyDetails.PKIX_RSA_PKCS1V15_2048_SHA256 ||
keyDetails === protobuf_specs_1.PublicKeyDetails.PKIX_RSA_PKCS1V15_3072_SHA256 ||
keyDetails === protobuf_specs_1.PublicKeyDetails.PKIX_RSA_PKCS1V15_4096_SHA256
? 'pkcs1'
: 'spki';
return {
logID: tlogInstance.logId.keyId,
publicKey: core_1.crypto.createPublicKey(tlogInstance.publicKey.rawBytes, keyType),
validFor: {
start: tlogInstance.publicKey.validFor?.start || BEGINNING_OF_TIME,
end: tlogInstance.publicKey.validFor?.end || END_OF_TIME,
},
};
}
function createCertAuthority(ca) {
return {
certChain: ca.certChain.certificates.map((cert) => {
return core_1.X509Certificate.parse(cert.rawBytes);
}),
validFor: {
start: ca.validFor?.start || BEGINNING_OF_TIME,
end: ca.validFor?.end || END_OF_TIME,
},
};
}
function keyLocator(keys) {
return (hint) => {
const key = (keys || {})[hint];
if (!key) {
throw new error_1.VerificationError({
code: 'PUBLIC_KEY_ERROR',
message: `key not found: ${hint}`,
});
}
return {
publicKey: core_1.crypto.createPublicKey(key.rawBytes),
validFor: (date) => {
return ((key.validFor?.start || BEGINNING_OF_TIME) <= date &&
(key.validFor?.end || END_OF_TIME) >= date);
},
};
};
}

View file

@ -0,0 +1,30 @@
/// <reference types="node" />
/// <reference types="node" />
import type { X509Certificate, crypto } from '@sigstore/core';
export type TLogAuthority = {
logID: Buffer;
publicKey: crypto.KeyObject;
validFor: {
start: Date;
end: Date;
};
};
export type CertAuthority = {
certChain: X509Certificate[];
validFor: {
start: Date;
end: Date;
};
};
export type TimeConstrainedKey = {
publicKey: crypto.KeyObject;
validFor(date: Date): boolean;
};
export type KeyFinderFunc = (hint: string) => TimeConstrainedKey;
export type TrustMaterial = {
certificateAuthorities: CertAuthority[];
timestampAuthorities: CertAuthority[];
tlogs: TLogAuthority[];
ctlogs: TLogAuthority[];
publicKey: KeyFinderFunc;
};

View file

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

18
node_modules/@sigstore/verify/dist/verifier.d.ts generated vendored Normal file
View file

@ -0,0 +1,18 @@
import type { SignedEntity, Signer, VerificationPolicy } from './shared.types';
import type { TrustMaterial } from './trust';
export type VerifierOptions = {
tlogThreshold?: number;
ctlogThreshold?: number;
tsaThreshold?: number;
};
export declare class Verifier {
private trustMaterial;
private options;
constructor(trustMaterial: TrustMaterial, options?: VerifierOptions);
verify(entity: SignedEntity, policy?: VerificationPolicy): Signer;
private verifyTimestamps;
private verifySigningKey;
private verifyTLogs;
private verifySignature;
private verifyPolicy;
}

141
node_modules/@sigstore/verify/dist/verifier.js generated vendored Normal file
View file

@ -0,0 +1,141 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Verifier = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const util_1 = require("util");
const error_1 = require("./error");
const key_1 = require("./key");
const policy_1 = require("./policy");
const timestamp_1 = require("./timestamp");
const tlog_1 = require("./tlog");
class Verifier {
constructor(trustMaterial, options = {}) {
this.trustMaterial = trustMaterial;
this.options = {
ctlogThreshold: options.ctlogThreshold ?? 1,
tlogThreshold: options.tlogThreshold ?? 1,
tsaThreshold: options.tsaThreshold ?? 0,
};
}
verify(entity, policy) {
const timestamps = this.verifyTimestamps(entity);
const signer = this.verifySigningKey(entity, timestamps);
this.verifyTLogs(entity);
this.verifySignature(entity, signer);
if (policy) {
this.verifyPolicy(policy, signer.identity || {});
}
return signer;
}
// Checks that all of the timestamps in the entity are valid and returns them
verifyTimestamps(entity) {
let tlogCount = 0;
let tsaCount = 0;
const timestamps = entity.timestamps.map((timestamp) => {
switch (timestamp.$case) {
case 'timestamp-authority':
tsaCount++;
return (0, timestamp_1.verifyTSATimestamp)(timestamp.timestamp, entity.signature.signature, this.trustMaterial.timestampAuthorities);
case 'transparency-log':
tlogCount++;
return (0, timestamp_1.verifyTLogTimestamp)(timestamp.tlogEntry, this.trustMaterial.tlogs);
}
});
// Check for duplicate timestamps
if (containsDupes(timestamps)) {
throw new error_1.VerificationError({
code: 'TIMESTAMP_ERROR',
message: 'duplicate timestamp',
});
}
if (tlogCount < this.options.tlogThreshold) {
throw new error_1.VerificationError({
code: 'TIMESTAMP_ERROR',
message: `expected ${this.options.tlogThreshold} tlog timestamps, got ${tlogCount}`,
});
}
if (tsaCount < this.options.tsaThreshold) {
throw new error_1.VerificationError({
code: 'TIMESTAMP_ERROR',
message: `expected ${this.options.tsaThreshold} tsa timestamps, got ${tsaCount}`,
});
}
return timestamps.map((t) => t.timestamp);
}
// Checks that the signing key is valid for all of the the supplied timestamps
// and returns the signer.
verifySigningKey({ key }, timestamps) {
switch (key.$case) {
case 'public-key': {
return (0, key_1.verifyPublicKey)(key.hint, timestamps, this.trustMaterial);
}
case 'certificate': {
const result = (0, key_1.verifyCertificate)(key.certificate, timestamps, this.trustMaterial);
/* istanbul ignore next - no fixture */
if (containsDupes(result.scts)) {
throw new error_1.VerificationError({
code: 'CERTIFICATE_ERROR',
message: 'duplicate SCT',
});
}
if (result.scts.length < this.options.ctlogThreshold) {
throw new error_1.VerificationError({
code: 'CERTIFICATE_ERROR',
message: `expected ${this.options.ctlogThreshold} SCTs, got ${result.scts.length}`,
});
}
return result.signer;
}
}
}
// Checks that the tlog entries are valid for the supplied content
verifyTLogs({ signature: content, tlogEntries }) {
tlogEntries.forEach((entry) => (0, tlog_1.verifyTLogBody)(entry, content));
}
// Checks that the signature is valid for the supplied content
verifySignature(entity, signer) {
if (!entity.signature.verifySignature(signer.key)) {
throw new error_1.VerificationError({
code: 'SIGNATURE_ERROR',
message: 'signature verification failed',
});
}
}
verifyPolicy(policy, identity) {
// Check the subject alternative name of the signer matches the policy
if (policy.subjectAlternativeName) {
(0, policy_1.verifySubjectAlternativeName)(policy.subjectAlternativeName, identity.subjectAlternativeName);
}
// Check that the extensions of the signer match the policy
if (policy.extensions) {
(0, policy_1.verifyExtensions)(policy.extensions, identity.extensions);
}
}
}
exports.Verifier = Verifier;
// Checks for duplicate items in the array. Objects are compared using
// deep equality.
function containsDupes(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if ((0, util_1.isDeepStrictEqual)(arr[i], arr[j])) {
return true;
}
}
}
return false;
}