This commit is contained in:
2025-08-18 23:06:34 +08:00
parent 0bc04fb659
commit ed18af0cad
1926 changed files with 275098 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseBundleBuilder = void 0;
// BaseBundleBuilder is a base class for BundleBuilder implementations. It
// provides a the basic wokflow for signing and witnessing an artifact.
// Subclasses must implement the `package` method to assemble a valid bundle
// with the generated signature and verification material.
class BaseBundleBuilder {
constructor(options) {
this.signer = options.signer;
this.witnesses = options.witnesses;
}
// Executes the signing/witnessing process for the given artifact.
async create(artifact) {
const signature = await this.prepare(artifact).then((blob) => this.signer.sign(blob));
const bundle = await this.package(artifact, signature);
// Invoke all of the witnesses in parallel
const verificationMaterials = await Promise.all(this.witnesses.map((witness) => witness.testify(bundle.content, publicKey(signature.key))));
// Collect the verification material from all of the witnesses
const tlogEntryList = [];
const timestampList = [];
verificationMaterials.forEach(({ tlogEntries, rfc3161Timestamps }) => {
tlogEntryList.push(...(tlogEntries ?? []));
timestampList.push(...(rfc3161Timestamps ?? []));
});
// Merge the collected verification material into the bundle
bundle.verificationMaterial.tlogEntries = tlogEntryList;
bundle.verificationMaterial.timestampVerificationData = {
rfc3161Timestamps: timestampList,
};
return bundle;
}
// Override this function to apply any pre-signing transformations to the
// artifact. The returned buffer will be signed by the signer. The default
// implementation simply returns the artifact data.
async prepare(artifact) {
return artifact.data;
}
}
exports.BaseBundleBuilder = BaseBundleBuilder;
// Extracts the public key from a KeyMaterial. Returns either the public key
// or the certificate, depending on the type of key material.
function publicKey(key) {
switch (key.$case) {
case 'publicKey':
return key.publicKey;
case 'x509Certificate':
return key.certificate;
}
}

View File

@@ -0,0 +1,71 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.toDSSEBundle = exports.toMessageSignatureBundle = 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 sigstore = __importStar(require("@sigstore/bundle"));
const util_1 = require("../util");
// Helper functions for assembling the parts of a Sigstore bundle
// Message signature bundle - $case: 'messageSignature'
function toMessageSignatureBundle(artifact, signature) {
const digest = util_1.crypto.hash(artifact.data);
return sigstore.toMessageSignatureBundle({
digest,
signature: signature.signature,
certificate: signature.key.$case === 'x509Certificate'
? util_1.pem.toDER(signature.key.certificate)
: undefined,
keyHint: signature.key.$case === 'publicKey' ? signature.key.hint : undefined,
});
}
exports.toMessageSignatureBundle = toMessageSignatureBundle;
// DSSE envelope bundle - $case: 'dsseEnvelope'
function toDSSEBundle(artifact, signature, singleCertificate) {
return sigstore.toDSSEBundle({
artifact: artifact.data,
artifactType: artifact.type,
signature: signature.signature,
certificate: signature.key.$case === 'x509Certificate'
? util_1.pem.toDER(signature.key.certificate)
: undefined,
keyHint: signature.key.$case === 'publicKey' ? signature.key.hint : undefined,
singleCertificate,
});
}
exports.toDSSEBundle = toDSSEBundle;

View File

@@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DSSEBundleBuilder = 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 base_1 = require("./base");
const bundle_1 = require("./bundle");
// BundleBuilder implementation for DSSE wrapped attestations
class DSSEBundleBuilder extends base_1.BaseBundleBuilder {
constructor(options) {
super(options);
this.singleCertificate = options.singleCertificate ?? false;
}
// DSSE requires the artifact to be pre-encoded with the payload type
// before the signature is generated.
async prepare(artifact) {
const a = artifactDefaults(artifact);
return util_1.dsse.preAuthEncoding(a.type, a.data);
}
// Packages the artifact and signature into a DSSE bundle
async package(artifact, signature) {
return (0, bundle_1.toDSSEBundle)(artifactDefaults(artifact), signature, this.singleCertificate);
}
}
exports.DSSEBundleBuilder = DSSEBundleBuilder;
// Defaults the artifact type to an empty string if not provided
function artifactDefaults(artifact) {
return {
...artifact,
type: artifact.type ?? '',
};
}

View File

@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageSignatureBundleBuilder = exports.DSSEBundleBuilder = void 0;
var dsse_1 = require("./dsse");
Object.defineProperty(exports, "DSSEBundleBuilder", { enumerable: true, get: function () { return dsse_1.DSSEBundleBuilder; } });
var message_1 = require("./message");
Object.defineProperty(exports, "MessageSignatureBundleBuilder", { enumerable: true, get: function () { return message_1.MessageSignatureBundleBuilder; } });

View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageSignatureBundleBuilder = 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 base_1 = require("./base");
const bundle_1 = require("./bundle");
// BundleBuilder implementation for raw message signatures
class MessageSignatureBundleBuilder extends base_1.BaseBundleBuilder {
constructor(options) {
super(options);
}
async package(artifact, signature) {
return (0, bundle_1.toMessageSignatureBundle)(artifact, signature);
}
}
exports.MessageSignatureBundleBuilder = MessageSignatureBundleBuilder;

39
package/node_modules/@sigstore/sign/dist/error.js generated vendored Normal file
View File

@@ -0,0 +1,39 @@
"use strict";
/*
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.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.internalError = exports.InternalError = void 0;
const error_1 = require("./external/error");
class InternalError extends Error {
constructor({ code, message, cause, }) {
super(message);
this.name = this.constructor.name;
this.cause = cause;
this.code = code;
}
}
exports.InternalError = InternalError;
function internalError(err, code, message) {
if (err instanceof error_1.HTTPError) {
message += ` - ${err.message}`;
}
throw new InternalError({
code: code,
message: message,
cause: err,
});
}
exports.internalError = internalError;

View File

@@ -0,0 +1,26 @@
"use strict";
/*
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.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.HTTPError = void 0;
class HTTPError extends Error {
constructor({ status, message, location, }) {
super(`(${status}) ${message}`);
this.statusCode = status;
this.location = location;
}
}
exports.HTTPError = HTTPError;

View File

@@ -0,0 +1,99 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.fetchWithRetry = 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 http2_1 = require("http2");
const make_fetch_happen_1 = __importDefault(require("make-fetch-happen"));
const proc_log_1 = require("proc-log");
const promise_retry_1 = __importDefault(require("promise-retry"));
const util_1 = require("../util");
const error_1 = require("./error");
const { HTTP2_HEADER_LOCATION, HTTP2_HEADER_CONTENT_TYPE, HTTP2_HEADER_USER_AGENT, HTTP_STATUS_INTERNAL_SERVER_ERROR, HTTP_STATUS_TOO_MANY_REQUESTS, HTTP_STATUS_REQUEST_TIMEOUT, } = http2_1.constants;
async function fetchWithRetry(url, options) {
return (0, promise_retry_1.default)(async (retry, attemptNum) => {
const method = options.method || 'POST';
const headers = {
[HTTP2_HEADER_USER_AGENT]: util_1.ua.getUserAgent(),
...options.headers,
};
const response = await (0, make_fetch_happen_1.default)(url, {
method,
headers,
body: options.body,
timeout: options.timeout,
retry: false, // We're handling retries ourselves
}).catch((reason) => {
proc_log_1.log.http('fetch', `${method} ${url} attempt ${attemptNum} failed with ${reason}`);
return retry(reason);
});
if (response.ok) {
return response;
}
else {
const error = await errorFromResponse(response);
proc_log_1.log.http('fetch', `${method} ${url} attempt ${attemptNum} failed with ${response.status}`);
if (retryable(response.status)) {
return retry(error);
}
else {
throw error;
}
}
}, retryOpts(options.retry));
}
exports.fetchWithRetry = fetchWithRetry;
// Translate a Response into an HTTPError instance. This will attempt to parse
// the response body for a message, but will default to the statusText if none
// is found.
const errorFromResponse = async (response) => {
let message = response.statusText;
const location = response.headers?.get(HTTP2_HEADER_LOCATION) || undefined;
const contentType = response.headers?.get(HTTP2_HEADER_CONTENT_TYPE);
// If response type is JSON, try to parse the body for a message
if (contentType?.includes('application/json')) {
try {
const body = await response.json();
message = body.message || message;
}
catch (e) {
// ignore
}
}
return new error_1.HTTPError({
status: response.status,
message: message,
location: location,
});
};
// Determine if a status code is retryable. This includes 5xx errors, 408, and
// 429.
const retryable = (status) => [HTTP_STATUS_REQUEST_TIMEOUT, HTTP_STATUS_TOO_MANY_REQUESTS].includes(status) || status >= HTTP_STATUS_INTERNAL_SERVER_ERROR;
// Normalize the retry options to the format expected by promise-retry
const retryOpts = (retry) => {
if (typeof retry === 'boolean') {
return { retries: retry ? 1 : 0 };
}
else if (typeof retry === 'number') {
return { retries: retry };
}
else {
return { retries: 0, ...retry };
}
};

View File

@@ -0,0 +1,41 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Fulcio = 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 fetch_1 = require("./fetch");
/**
* Fulcio API client.
*/
class Fulcio {
constructor(options) {
this.options = options;
}
async createSigningCertificate(request) {
const { baseURL, retry, timeout } = this.options;
const url = `${baseURL}/api/v2/signingCert`;
const response = await (0, fetch_1.fetchWithRetry)(url, {
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(request),
timeout,
retry,
});
return response.json();
}
}
exports.Fulcio = Fulcio;

View File

@@ -0,0 +1,80 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Rekor = 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 fetch_1 = require("./fetch");
/**
* Rekor API client.
*/
class Rekor {
constructor(options) {
this.options = options;
}
/**
* Create a new entry in the Rekor log.
* @param propsedEntry {ProposedEntry} Data to create a new entry
* @returns {Promise<Entry>} The created entry
*/
async createEntry(propsedEntry) {
const { baseURL, timeout, retry } = this.options;
const url = `${baseURL}/api/v1/log/entries`;
const response = await (0, fetch_1.fetchWithRetry)(url, {
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify(propsedEntry),
timeout,
retry,
});
const data = await response.json();
return entryFromResponse(data);
}
/**
* Get an entry from the Rekor log.
* @param uuid {string} The UUID of the entry to retrieve
* @returns {Promise<Entry>} The retrieved entry
*/
async getEntry(uuid) {
const { baseURL, timeout, retry } = this.options;
const url = `${baseURL}/api/v1/log/entries/${uuid}`;
const response = await (0, fetch_1.fetchWithRetry)(url, {
method: 'GET',
headers: {
Accept: 'application/json',
},
timeout,
retry,
});
const data = await response.json();
return entryFromResponse(data);
}
}
exports.Rekor = Rekor;
// Unpack the response from the Rekor API into a more convenient format.
function entryFromResponse(data) {
const entries = Object.entries(data);
if (entries.length != 1) {
throw new Error('Received multiple entries in Rekor response');
}
// Grab UUID and entry data from the response
const [uuid, entry] = entries[0];
return {
...entry,
uuid,
};
}

View File

@@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TimestampAuthority = 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 fetch_1 = require("./fetch");
class TimestampAuthority {
constructor(options) {
this.options = options;
}
async createTimestamp(request) {
const { baseURL, timeout, retry } = this.options;
const url = `${baseURL}/api/v1/timestamp`;
const response = await (0, fetch_1.fetchWithRetry)(url, {
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(request),
timeout,
retry,
});
return response.buffer();
}
}
exports.TimestampAuthority = TimestampAuthority;

View File

@@ -0,0 +1,73 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CIContextProvider = 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 make_fetch_happen_1 = __importDefault(require("make-fetch-happen"));
// Collection of all the CI-specific providers we have implemented
const providers = [getGHAToken, getEnv];
/**
* CIContextProvider is a composite identity provider which will iterate
* over all of the CI-specific providers and return the token from the first
* one that resolves.
*/
class CIContextProvider {
/* istanbul ignore next */
constructor(audience = 'sigstore') {
this.audience = audience;
}
// Invoke all registered ProviderFuncs and return the value of whichever one
// resolves first.
async getToken() {
return Promise.any(providers.map((getToken) => getToken(this.audience))).catch(() => Promise.reject('CI: no tokens available'));
}
}
exports.CIContextProvider = CIContextProvider;
/**
* getGHAToken can retrieve an OIDC token when running in a GitHub Actions
* workflow
*/
async function getGHAToken(audience) {
// Check to see if we're running in GitHub Actions
if (!process.env.ACTIONS_ID_TOKEN_REQUEST_URL ||
!process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN) {
return Promise.reject('no token available');
}
// Construct URL to request token w/ appropriate audience
const url = new URL(process.env.ACTIONS_ID_TOKEN_REQUEST_URL);
url.searchParams.append('audience', audience);
const response = await (0, make_fetch_happen_1.default)(url.href, {
retry: 2,
headers: {
Accept: 'application/json',
Authorization: `Bearer ${process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN}`,
},
});
return response.json().then((data) => data.value);
}
/**
* getEnv can retrieve an OIDC token from an environment variable.
* This matches the behavior of https://github.com/sigstore/cosign/tree/main/pkg/providers/envvar
*/
async function getEnv() {
if (!process.env.SIGSTORE_ID_TOKEN) {
return Promise.reject('no token available');
}
return process.env.SIGSTORE_ID_TOKEN;
}

View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CIContextProvider = 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.
*/
var ci_1 = require("./ci");
Object.defineProperty(exports, "CIContextProvider", { enumerable: true, get: function () { return ci_1.CIContextProvider; } });

View File

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

17
package/node_modules/@sigstore/sign/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TSAWitness = exports.RekorWitness = exports.DEFAULT_REKOR_URL = exports.FulcioSigner = exports.DEFAULT_FULCIO_URL = exports.CIContextProvider = exports.InternalError = exports.MessageSignatureBundleBuilder = exports.DSSEBundleBuilder = void 0;
var bundler_1 = require("./bundler");
Object.defineProperty(exports, "DSSEBundleBuilder", { enumerable: true, get: function () { return bundler_1.DSSEBundleBuilder; } });
Object.defineProperty(exports, "MessageSignatureBundleBuilder", { enumerable: true, get: function () { return bundler_1.MessageSignatureBundleBuilder; } });
var error_1 = require("./error");
Object.defineProperty(exports, "InternalError", { enumerable: true, get: function () { return error_1.InternalError; } });
var identity_1 = require("./identity");
Object.defineProperty(exports, "CIContextProvider", { enumerable: true, get: function () { return identity_1.CIContextProvider; } });
var signer_1 = require("./signer");
Object.defineProperty(exports, "DEFAULT_FULCIO_URL", { enumerable: true, get: function () { return signer_1.DEFAULT_FULCIO_URL; } });
Object.defineProperty(exports, "FulcioSigner", { enumerable: true, get: function () { return signer_1.FulcioSigner; } });
var witness_1 = require("./witness");
Object.defineProperty(exports, "DEFAULT_REKOR_URL", { enumerable: true, get: function () { return witness_1.DEFAULT_REKOR_URL; } });
Object.defineProperty(exports, "RekorWitness", { enumerable: true, get: function () { return witness_1.RekorWitness; } });
Object.defineProperty(exports, "TSAWitness", { enumerable: true, get: function () { return witness_1.TSAWitness; } });

View File

@@ -0,0 +1,60 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CAClient = 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 fulcio_1 = require("../../external/fulcio");
class CAClient {
constructor(options) {
this.fulcio = new fulcio_1.Fulcio({
baseURL: options.fulcioBaseURL,
retry: options.retry,
timeout: options.timeout,
});
}
async createSigningCertificate(identityToken, publicKey, challenge) {
const request = toCertificateRequest(identityToken, publicKey, challenge);
try {
const resp = await this.fulcio.createSigningCertificate(request);
// Account for the fact that the response may contain either a
// signedCertificateEmbeddedSct or a signedCertificateDetachedSct.
const cert = resp.signedCertificateEmbeddedSct
? resp.signedCertificateEmbeddedSct
: resp.signedCertificateDetachedSct;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return cert.chain.certificates;
}
catch (err) {
(0, error_1.internalError)(err, 'CA_CREATE_SIGNING_CERTIFICATE_ERROR', 'error creating signing certificate');
}
}
}
exports.CAClient = CAClient;
function toCertificateRequest(identityToken, publicKey, challenge) {
return {
credentials: {
oidcIdentityToken: identityToken,
},
publicKeyRequest: {
publicKey: {
algorithm: 'ECDSA',
content: publicKey,
},
proofOfPossession: challenge.toString('base64'),
},
};
}

View File

@@ -0,0 +1,45 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EphemeralSigner = 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 crypto_1 = __importDefault(require("crypto"));
const EC_KEYPAIR_TYPE = 'ec';
const P256_CURVE = 'P-256';
// Signer implementation which uses an ephemeral keypair to sign artifacts.
// The private key lives only in memory and is tied to the lifetime of the
// EphemeralSigner instance.
class EphemeralSigner {
constructor() {
this.keypair = crypto_1.default.generateKeyPairSync(EC_KEYPAIR_TYPE, {
namedCurve: P256_CURVE,
});
}
async sign(data) {
const signature = crypto_1.default.sign(null, data, this.keypair.privateKey);
const publicKey = this.keypair.publicKey
.export({ format: 'pem', type: 'spki' })
.toString('ascii');
return {
signature: signature,
key: { $case: 'publicKey', publicKey },
};
}
}
exports.EphemeralSigner = EphemeralSigner;

View File

@@ -0,0 +1,87 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FulcioSigner = exports.DEFAULT_FULCIO_URL = 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 util_1 = require("../../util");
const ca_1 = require("./ca");
const ephemeral_1 = require("./ephemeral");
exports.DEFAULT_FULCIO_URL = 'https://fulcio.sigstore.dev';
// Signer implementation which can be used to decorate another signer
// with a Fulcio-issued signing certificate for the signer's public key.
// Must be instantiated with an identity provider which can provide a JWT
// which represents the identity to be bound to the signing certificate.
class FulcioSigner {
constructor(options) {
this.ca = new ca_1.CAClient({
...options,
fulcioBaseURL: options.fulcioBaseURL || /* istanbul ignore next */ exports.DEFAULT_FULCIO_URL,
});
this.identityProvider = options.identityProvider;
this.keyHolder = options.keyHolder || new ephemeral_1.EphemeralSigner();
}
async sign(data) {
// Retrieve identity token from the supplied identity provider
const identityToken = await this.getIdentityToken();
// Extract challenge claim from OIDC token
let subject;
try {
subject = util_1.oidc.extractJWTSubject(identityToken);
}
catch (err) {
throw new error_1.InternalError({
code: 'IDENTITY_TOKEN_PARSE_ERROR',
message: `invalid identity token: ${identityToken}`,
cause: err,
});
}
// Construct challenge value by signing the subject claim
const challenge = await this.keyHolder.sign(Buffer.from(subject));
if (challenge.key.$case !== 'publicKey') {
throw new error_1.InternalError({
code: 'CA_CREATE_SIGNING_CERTIFICATE_ERROR',
message: 'unexpected format for signing key',
});
}
// Create signing certificate
const certificates = await this.ca.createSigningCertificate(identityToken, challenge.key.publicKey, challenge.signature);
// Generate artifact signature
const signature = await this.keyHolder.sign(data);
// Specifically returning only the first certificate in the chain
// as the key.
return {
signature: signature.signature,
key: {
$case: 'x509Certificate',
certificate: certificates[0],
},
};
}
async getIdentityToken() {
try {
return await this.identityProvider.getToken();
}
catch (err) {
throw new error_1.InternalError({
code: 'IDENTITY_TOKEN_READ_ERROR',
message: 'error retrieving identity token',
cause: err,
});
}
}
}
exports.FulcioSigner = FulcioSigner;

View File

@@ -0,0 +1,22 @@
"use strict";
/* istanbul ignore file */
Object.defineProperty(exports, "__esModule", { value: true });
exports.FulcioSigner = exports.DEFAULT_FULCIO_URL = 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.
*/
var fulcio_1 = require("./fulcio");
Object.defineProperty(exports, "DEFAULT_FULCIO_URL", { enumerable: true, get: function () { return fulcio_1.DEFAULT_FULCIO_URL; } });
Object.defineProperty(exports, "FulcioSigner", { enumerable: true, get: function () { return fulcio_1.FulcioSigner; } });

View File

@@ -0,0 +1,17 @@
"use strict";
/*
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.
*/
Object.defineProperty(exports, "__esModule", { value: true });

View File

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

49
package/node_modules/@sigstore/sign/dist/util/index.js generated vendored Normal file
View File

@@ -0,0 +1,49 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ua = exports.oidc = exports.pem = exports.json = exports.encoding = exports.dsse = exports.crypto = 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.
*/
var core_1 = require("@sigstore/core");
Object.defineProperty(exports, "crypto", { enumerable: true, get: function () { return core_1.crypto; } });
Object.defineProperty(exports, "dsse", { enumerable: true, get: function () { return core_1.dsse; } });
Object.defineProperty(exports, "encoding", { enumerable: true, get: function () { return core_1.encoding; } });
Object.defineProperty(exports, "json", { enumerable: true, get: function () { return core_1.json; } });
Object.defineProperty(exports, "pem", { enumerable: true, get: function () { return core_1.pem; } });
exports.oidc = __importStar(require("./oidc"));
exports.ua = __importStar(require("./ua"));

31
package/node_modules/@sigstore/sign/dist/util/oidc.js generated vendored Normal file
View File

@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractJWTSubject = 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");
function extractJWTSubject(jwt) {
const parts = jwt.split('.', 3);
const payload = JSON.parse(core_1.encoding.base64Decode(parts[1]));
switch (payload.iss) {
case 'https://accounts.google.com':
case 'https://oauth2.sigstore.dev/auth':
return payload.email;
default:
return payload.sub;
}
}
exports.extractJWTSubject = extractJWTSubject;

33
package/node_modules/@sigstore/sign/dist/util/ua.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getUserAgent = 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 os_1 = __importDefault(require("os"));
// Format User-Agent: <product> / <product-version> (<platform>)
// source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent
const getUserAgent = () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const packageVersion = require('../../package.json').version;
const nodeVersion = process.version;
const platformName = os_1.default.platform();
const archName = os_1.default.arch();
return `sigstore-js/${packageVersion} (Node ${nodeVersion}) (${platformName}/${archName})`;
};
exports.getUserAgent = getUserAgent;

View File

@@ -0,0 +1,24 @@
"use strict";
/* istanbul ignore file */
Object.defineProperty(exports, "__esModule", { value: true });
exports.TSAWitness = exports.RekorWitness = exports.DEFAULT_REKOR_URL = 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.
*/
var tlog_1 = require("./tlog");
Object.defineProperty(exports, "DEFAULT_REKOR_URL", { enumerable: true, get: function () { return tlog_1.DEFAULT_REKOR_URL; } });
Object.defineProperty(exports, "RekorWitness", { enumerable: true, get: function () { return tlog_1.RekorWitness; } });
var tsa_1 = require("./tsa");
Object.defineProperty(exports, "TSAWitness", { enumerable: true, get: function () { return tsa_1.TSAWitness; } });

View File

@@ -0,0 +1,61 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TLogClient = 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 error_2 = require("../../external/error");
const rekor_1 = require("../../external/rekor");
class TLogClient {
constructor(options) {
this.fetchOnConflict = options.fetchOnConflict ?? false;
this.rekor = new rekor_1.Rekor({
baseURL: options.rekorBaseURL,
retry: options.retry,
timeout: options.timeout,
});
}
async createEntry(proposedEntry) {
let entry;
try {
entry = await this.rekor.createEntry(proposedEntry);
}
catch (err) {
// If the entry already exists, fetch it (if enabled)
if (entryExistsError(err) && this.fetchOnConflict) {
// Grab the UUID of the existing entry from the location header
/* istanbul ignore next */
const uuid = err.location.split('/').pop() || '';
try {
entry = await this.rekor.getEntry(uuid);
}
catch (err) {
(0, error_1.internalError)(err, 'TLOG_FETCH_ENTRY_ERROR', 'error fetching tlog entry');
}
}
else {
(0, error_1.internalError)(err, 'TLOG_CREATE_ENTRY_ERROR', 'error creating tlog entry');
}
}
return entry;
}
}
exports.TLogClient = TLogClient;
function entryExistsError(value) {
return (value instanceof error_2.HTTPError &&
value.statusCode === 409 &&
value.location !== undefined);
}

View File

@@ -0,0 +1,136 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.toProposedEntry = 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 bundle_1 = require("@sigstore/bundle");
const util_1 = require("../../util");
function toProposedEntry(content, publicKey,
// TODO: Remove this parameter once have completely switched to 'dsse' entries
entryType = 'intoto') {
switch (content.$case) {
case 'dsseEnvelope':
// TODO: Remove this conditional once have completely switched to 'dsse' entries
if (entryType === 'dsse') {
return toProposedDSSEEntry(content.dsseEnvelope, publicKey);
}
return toProposedIntotoEntry(content.dsseEnvelope, publicKey);
case 'messageSignature':
return toProposedHashedRekordEntry(content.messageSignature, publicKey);
}
}
exports.toProposedEntry = toProposedEntry;
// Returns a properly formatted Rekor "hashedrekord" entry for the given digest
// and signature
function toProposedHashedRekordEntry(messageSignature, publicKey) {
const hexDigest = messageSignature.messageDigest.digest.toString('hex');
const b64Signature = messageSignature.signature.toString('base64');
const b64Key = util_1.encoding.base64Encode(publicKey);
return {
apiVersion: '0.0.1',
kind: 'hashedrekord',
spec: {
data: {
hash: {
algorithm: 'sha256',
value: hexDigest,
},
},
signature: {
content: b64Signature,
publicKey: {
content: b64Key,
},
},
},
};
}
// Returns a properly formatted Rekor "dsse" entry for the given DSSE envelope
// and signature
function toProposedDSSEEntry(envelope, publicKey) {
const envelopeJSON = JSON.stringify((0, bundle_1.envelopeToJSON)(envelope));
const encodedKey = util_1.encoding.base64Encode(publicKey);
return {
apiVersion: '0.0.1',
kind: 'dsse',
spec: {
proposedContent: {
envelope: envelopeJSON,
verifiers: [encodedKey],
},
},
};
}
// Returns a properly formatted Rekor "intoto" entry for the given DSSE
// envelope and signature
function toProposedIntotoEntry(envelope, publicKey) {
// Calculate the value for the payloadHash field in the Rekor entry
const payloadHash = util_1.crypto.hash(envelope.payload).toString('hex');
// Calculate the value for the hash field in the Rekor entry
const envelopeHash = calculateDSSEHash(envelope, publicKey);
// Collect values for re-creating the DSSE envelope.
// Double-encode payload and signature cause that's what Rekor expects
const payload = util_1.encoding.base64Encode(envelope.payload.toString('base64'));
const sig = util_1.encoding.base64Encode(envelope.signatures[0].sig.toString('base64'));
const keyid = envelope.signatures[0].keyid;
const encodedKey = util_1.encoding.base64Encode(publicKey);
// Create the envelope portion of the entry. Note the inclusion of the
// publicKey in the signature struct is not a standard part of a DSSE
// envelope, but is required by Rekor.
const dsse = {
payloadType: envelope.payloadType,
payload: payload,
signatures: [{ sig, publicKey: encodedKey }],
};
// If the keyid is an empty string, Rekor seems to remove it altogether. We
// need to do the same here so that we can properly recreate the entry for
// verification.
if (keyid.length > 0) {
dsse.signatures[0].keyid = keyid;
}
return {
apiVersion: '0.0.2',
kind: 'intoto',
spec: {
content: {
envelope: dsse,
hash: { algorithm: 'sha256', value: envelopeHash },
payloadHash: { algorithm: 'sha256', value: payloadHash },
},
},
};
}
// Calculates the hash of a DSSE envelope for inclusion in a Rekor entry.
// There is no standard way to do this, so the scheme we're using as as
// follows:
// * payload is base64 encoded
// * signature is base64 encoded (only the first signature is used)
// * keyid is included ONLY if it is NOT an empty string
// * The resulting JSON is canonicalized and hashed to a hex string
function calculateDSSEHash(envelope, publicKey) {
const dsse = {
payloadType: envelope.payloadType,
payload: envelope.payload.toString('base64'),
signatures: [
{ sig: envelope.signatures[0].sig.toString('base64'), publicKey },
],
};
// If the keyid is an empty string, Rekor seems to remove it altogether.
if (envelope.signatures[0].keyid.length > 0) {
dsse.signatures[0].keyid = envelope.signatures[0].keyid;
}
return util_1.crypto.hash(util_1.json.canonicalize(dsse)).toString('hex');
}

View File

@@ -0,0 +1,82 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RekorWitness = exports.DEFAULT_REKOR_URL = 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 client_1 = require("./client");
const entry_1 = require("./entry");
exports.DEFAULT_REKOR_URL = 'https://rekor.sigstore.dev';
class RekorWitness {
constructor(options) {
this.entryType = options.entryType;
this.tlog = new client_1.TLogClient({
...options,
rekorBaseURL: options.rekorBaseURL || /* istanbul ignore next */ exports.DEFAULT_REKOR_URL,
});
}
async testify(content, publicKey) {
const proposedEntry = (0, entry_1.toProposedEntry)(content, publicKey, this.entryType);
const entry = await this.tlog.createEntry(proposedEntry);
return toTransparencyLogEntry(entry);
}
}
exports.RekorWitness = RekorWitness;
function toTransparencyLogEntry(entry) {
const logID = Buffer.from(entry.logID, 'hex');
// Parse entry body so we can extract the kind and version.
const bodyJSON = util_1.encoding.base64Decode(entry.body);
const entryBody = JSON.parse(bodyJSON);
const promise = entry?.verification?.signedEntryTimestamp
? inclusionPromise(entry.verification.signedEntryTimestamp)
: undefined;
const proof = entry?.verification?.inclusionProof
? inclusionProof(entry.verification.inclusionProof)
: undefined;
const tlogEntry = {
logIndex: entry.logIndex.toString(),
logId: {
keyId: logID,
},
integratedTime: entry.integratedTime.toString(),
kindVersion: {
kind: entryBody.kind,
version: entryBody.apiVersion,
},
inclusionPromise: promise,
inclusionProof: proof,
canonicalizedBody: Buffer.from(entry.body, 'base64'),
};
return {
tlogEntries: [tlogEntry],
};
}
function inclusionPromise(promise) {
return {
signedEntryTimestamp: Buffer.from(promise, 'base64'),
};
}
function inclusionProof(proof) {
return {
logIndex: proof.logIndex.toString(),
treeSize: proof.treeSize.toString(),
rootHash: Buffer.from(proof.rootHash, 'hex'),
hashes: proof.hashes.map((h) => Buffer.from(h, 'hex')),
checkpoint: {
envelope: proof.checkpoint,
},
};
}

View File

@@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TSAClient = 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 tsa_1 = require("../../external/tsa");
const util_1 = require("../../util");
class TSAClient {
constructor(options) {
this.tsa = new tsa_1.TimestampAuthority({
baseURL: options.tsaBaseURL,
retry: options.retry,
timeout: options.timeout,
});
}
async createTimestamp(signature) {
const request = {
artifactHash: util_1.crypto.hash(signature).toString('base64'),
hashAlgorithm: 'sha256',
};
try {
return await this.tsa.createTimestamp(request);
}
catch (err) {
(0, error_1.internalError)(err, 'TSA_CREATE_TIMESTAMP_ERROR', 'error creating timestamp');
}
}
}
exports.TSAClient = TSAClient;

View File

@@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TSAWitness = 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 client_1 = require("./client");
class TSAWitness {
constructor(options) {
this.tsa = new client_1.TSAClient({
tsaBaseURL: options.tsaBaseURL,
retry: options.retry,
timeout: options.timeout,
});
}
async testify(content) {
const signature = extractSignature(content);
const timestamp = await this.tsa.createTimestamp(signature);
return {
rfc3161Timestamps: [{ signedTimestamp: timestamp }],
};
}
}
exports.TSAWitness = TSAWitness;
function extractSignature(content) {
switch (content.$case) {
case 'dsseEnvelope':
return content.dsseEnvelope.signatures[0].sig;
case 'messageSignature':
return content.messageSignature.signature;
}
}

View File

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