Comparing version 1.8.0 to 1.9.0
@@ -1,18 +0,14 @@ | ||
import { CA } from './ca'; | ||
import { Provider } from './identity'; | ||
import { TLog } from './tlog'; | ||
import { TSA } from './tsa'; | ||
import { DSSEBundleBuilder, IdentityProvider, MessageSignatureBundleBuilder } from '@sigstore/sign'; | ||
import { SignerFunc } from './types/signature'; | ||
import * as sigstore from './types/sigstore'; | ||
import type { FetchOptions, Retry } from './types/fetch'; | ||
import type { KeySelector } from './verify'; | ||
interface CAOptions { | ||
export type TUFOptions = { | ||
tufMirrorURL?: string; | ||
tufRootPath?: string; | ||
tufCachePath?: string; | ||
} & FetchOptions; | ||
export type SignOptions = { | ||
fulcioURL?: string; | ||
} | ||
interface TLogOptions { | ||
rekorURL?: string; | ||
} | ||
interface TSAOptions { | ||
tsaServerURL?: string; | ||
} | ||
export interface IdentityProviderOptions { | ||
identityProvider?: IdentityProvider; | ||
identityToken?: string; | ||
@@ -23,12 +19,7 @@ oidcIssuer?: string; | ||
oidcRedirectURL?: string; | ||
} | ||
export type TUFOptions = { | ||
tufMirrorURL?: string; | ||
tufRootPath?: string; | ||
tufCachePath?: string; | ||
rekorURL?: string; | ||
signer?: SignerFunc; | ||
tlogUpload?: boolean; | ||
tsaServerURL?: string; | ||
} & FetchOptions; | ||
export type SignOptions = { | ||
identityProvider?: Provider; | ||
tlogUpload?: boolean; | ||
} & CAOptions & TLogOptions & TSAOptions & FetchOptions & IdentityProviderOptions; | ||
export type VerifyOptions = { | ||
@@ -42,3 +33,4 @@ ctLogThreshold?: number; | ||
keySelector?: KeySelector; | ||
} & TLogOptions & TUFOptions; | ||
rekorURL?: string; | ||
} & TUFOptions; | ||
export type CreateVerifierOptions = { | ||
@@ -51,7 +43,5 @@ keySelector?: KeySelector; | ||
export declare const DEFAULT_TIMEOUT = 5000; | ||
export declare function createCAClient(options: CAOptions & FetchOptions): CA; | ||
export declare function createTLogClient(options: TLogOptions & FetchOptions): TLog; | ||
export declare function createTSAClient(options: TSAOptions & FetchOptions): TSA | undefined; | ||
export type BundleType = 'messageSignature' | 'dsseEnvelope'; | ||
export declare function createBundleBuilder(bundleType: 'messageSignature', options: SignOptions): MessageSignatureBundleBuilder; | ||
export declare function createBundleBuilder(bundleType: 'dsseEnvelope', options: SignOptions): DSSEBundleBuilder; | ||
export declare function artifactVerificationOptions(options: VerifyOptions): sigstore.RequiredArtifactVerificationOptions; | ||
export declare function identityProviders(options: IdentityProviderOptions): Provider[]; | ||
export {}; |
@@ -29,3 +29,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.identityProviders = exports.artifactVerificationOptions = exports.createTSAClient = exports.createTLogClient = exports.createCAClient = exports.DEFAULT_TIMEOUT = exports.DEFAULT_RETRY = exports.DEFAULT_REKOR_URL = exports.DEFAULT_FULCIO_URL = void 0; | ||
exports.artifactVerificationOptions = exports.createBundleBuilder = exports.DEFAULT_TIMEOUT = exports.DEFAULT_RETRY = exports.DEFAULT_REKOR_URL = exports.DEFAULT_FULCIO_URL = void 0; | ||
/* | ||
@@ -46,6 +46,5 @@ Copyright 2023 The Sigstore Authors. | ||
*/ | ||
const ca_1 = require("./ca"); | ||
const sign_1 = require("@sigstore/sign"); | ||
const identity_1 = __importDefault(require("./identity")); | ||
const tlog_1 = require("./tlog"); | ||
const tsa_1 = require("./tsa"); | ||
const signature_1 = require("./types/signature"); | ||
const sigstore = __importStar(require("./types/sigstore")); | ||
@@ -56,28 +55,84 @@ exports.DEFAULT_FULCIO_URL = 'https://fulcio.sigstore.dev'; | ||
exports.DEFAULT_TIMEOUT = 5000; | ||
function createCAClient(options) { | ||
return new ca_1.CAClient({ | ||
fulcioBaseURL: options.fulcioURL || exports.DEFAULT_FULCIO_URL, | ||
retry: options.retry ?? exports.DEFAULT_RETRY, | ||
timeout: options.timeout ?? exports.DEFAULT_TIMEOUT, | ||
}); | ||
function createBundleBuilder(bundleType, options) { | ||
const bundlerOptions = { | ||
signer: initSigner(options), | ||
witnesses: initWitnesses(options), | ||
}; | ||
switch (bundleType) { | ||
case 'messageSignature': | ||
return new sign_1.MessageSignatureBundleBuilder(bundlerOptions); | ||
case 'dsseEnvelope': | ||
return new sign_1.DSSEBundleBuilder(bundlerOptions); | ||
} | ||
} | ||
exports.createCAClient = createCAClient; | ||
function createTLogClient(options) { | ||
return new tlog_1.TLogClient({ | ||
rekorBaseURL: options.rekorURL || exports.DEFAULT_REKOR_URL, | ||
retry: options.retry ?? exports.DEFAULT_RETRY, | ||
timeout: options.timeout ?? exports.DEFAULT_TIMEOUT, | ||
}); | ||
exports.createBundleBuilder = createBundleBuilder; | ||
// Instantiate a signer based on the supplied options. If a signer function is | ||
// provided, use that. Otherwise, if a Fulcio URL is provided, use the Fulcio | ||
// signer. Otherwise, throw an error. | ||
function initSigner(options) { | ||
if (isCallbackSignerEnabled(options)) { | ||
return new signature_1.CallbackSigner(options); | ||
} | ||
else { | ||
return new sign_1.FulcioSigner({ | ||
fulcioBaseURL: options.fulcioURL || exports.DEFAULT_FULCIO_URL, | ||
identityProvider: options.identityProvider || initIdentityProvider(options), | ||
retry: options.retry ?? exports.DEFAULT_RETRY, | ||
timeout: options.timeout ?? exports.DEFAULT_TIMEOUT, | ||
}); | ||
} | ||
} | ||
exports.createTLogClient = createTLogClient; | ||
function createTSAClient(options) { | ||
return options.tsaServerURL | ||
? new tsa_1.TSAClient({ | ||
// Instantiate an identity provider based on the supplied options. If an | ||
// explicit identity token is provided, use that. Otherwise, if an OIDC issuer | ||
// and client ID are provided, use the OIDC provider. Otherwise, use the CI | ||
// context provider. | ||
function initIdentityProvider(options) { | ||
const token = options.identityToken; | ||
if (token) { | ||
return { getToken: () => Promise.resolve(token) }; | ||
} | ||
else if (options.oidcIssuer && options.oidcClientID) { | ||
return identity_1.default.oauthProvider({ | ||
issuer: options.oidcIssuer, | ||
clientID: options.oidcClientID, | ||
clientSecret: options.oidcClientSecret, | ||
redirectURL: options.oidcRedirectURL, | ||
}); | ||
} | ||
else { | ||
return new sign_1.CIContextProvider('sigstore'); | ||
} | ||
} | ||
// Instantiate a collection of witnesses based on the supplied options. | ||
function initWitnesses(options) { | ||
const witnesses = []; | ||
if (isRekorEnabled(options)) { | ||
witnesses.push(new sign_1.RekorWitness({ | ||
rekorBaseURL: options.rekorURL || exports.DEFAULT_REKOR_URL, | ||
fetchOnConflict: false, | ||
retry: options.retry ?? exports.DEFAULT_RETRY, | ||
timeout: options.timeout ?? exports.DEFAULT_TIMEOUT, | ||
})); | ||
} | ||
if (isTSAEnabled(options)) { | ||
witnesses.push(new sign_1.TSAWitness({ | ||
tsaBaseURL: options.tsaServerURL, | ||
retry: options.retry ?? exports.DEFAULT_RETRY, | ||
timeout: options.timeout ?? exports.DEFAULT_TIMEOUT, | ||
}) | ||
: undefined; | ||
})); | ||
} | ||
return witnesses; | ||
} | ||
exports.createTSAClient = createTSAClient; | ||
// Type assertion to ensure that the signer is enabled | ||
function isCallbackSignerEnabled(options) { | ||
return options.signer !== undefined; | ||
} | ||
// Type assertion to ensure that Rekor is enabled | ||
function isRekorEnabled(options) { | ||
return options.tlogUpload !== false; | ||
} | ||
// Type assertion to ensure that TSA is enabled | ||
function isTSAEnabled(options) { | ||
return options.tsaServerURL !== undefined; | ||
} | ||
// Assembles the AtifactVerificationOptions from the supplied VerifyOptions. | ||
@@ -108,3 +163,3 @@ function artifactVerificationOptions(options) { | ||
} | ||
const oids = Object.entries(options.certificateOIDs || {}).map(([oid, value]) => ({ | ||
const oids = Object.entries(options.certificateOIDs || /* istanbul ignore next */ {}).map(([oid, value]) => ({ | ||
oid: { id: oid.split('.').map((s) => parseInt(s, 10)) }, | ||
@@ -142,26 +197,1 @@ value: Buffer.from(value), | ||
exports.artifactVerificationOptions = artifactVerificationOptions; | ||
// Translates the IdenityProviderOptions into a list of Providers which | ||
// should be queried to retrieve an identity token. | ||
function identityProviders(options) { | ||
const idps = []; | ||
const token = options.identityToken; | ||
// If an explicit identity token is provided, use that. Setup a dummy | ||
// provider that just returns the token. Otherwise, setup the CI context | ||
// provider and (optionally) the OAuth provider. | ||
if (token) { | ||
idps.push({ getToken: () => Promise.resolve(token) }); | ||
} | ||
else { | ||
idps.push(identity_1.default.ciContextProvider()); | ||
if (options.oidcIssuer && options.oidcClientID) { | ||
idps.push(identity_1.default.oauthProvider({ | ||
issuer: options.oidcIssuer, | ||
clientID: options.oidcClientID, | ||
clientSecret: options.oidcClientSecret, | ||
redirectURL: options.oidcRedirectURL, | ||
})); | ||
} | ||
} | ||
return idps; | ||
} | ||
exports.identityProviders = identityProviders; |
@@ -5,11 +5,6 @@ declare class BaseError extends Error { | ||
} | ||
export declare class VerificationError extends BaseError { | ||
} | ||
export declare class PolicyError extends BaseError { | ||
} | ||
type InternalErrorCode = 'TLOG_FETCH_ENTRY_ERROR' | 'TLOG_CREATE_ENTRY_ERROR' | 'CA_CREATE_SIGNING_CERTIFICATE_ERROR' | 'TSA_CREATE_TIMESTAMP_ERROR' | 'TUF_FIND_TARGET_ERROR' | 'TUF_REFRESH_METADATA_ERROR' | 'TUF_DOWNLOAD_TARGET_ERROR' | 'TUF_READ_TARGET_ERROR'; | ||
export declare class InternalError extends BaseError { | ||
code: InternalErrorCode; | ||
declare class ErrorWithCode<T extends string> extends BaseError { | ||
code: T; | ||
constructor({ code, message, cause, }: { | ||
code: InternalErrorCode; | ||
code: T; | ||
message: string; | ||
@@ -19,2 +14,12 @@ cause?: any; | ||
} | ||
export declare class VerificationError extends BaseError { | ||
} | ||
export declare class PolicyError extends BaseError { | ||
} | ||
type InternalErrorCode = 'TUF_FIND_TARGET_ERROR' | 'TUF_REFRESH_METADATA_ERROR' | 'TUF_DOWNLOAD_TARGET_ERROR' | 'TUF_READ_TARGET_ERROR'; | ||
export declare class InternalError extends ErrorWithCode<InternalErrorCode> { | ||
} | ||
type SignatureErrorCode = 'MISSING_SIGNATURE_ERROR' | 'MISSING_PUBLIC_KEY_ERROR'; | ||
export declare class SignatureError extends ErrorWithCode<SignatureErrorCode> { | ||
} | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.InternalError = exports.PolicyError = exports.VerificationError = void 0; | ||
exports.SignatureError = exports.InternalError = exports.PolicyError = exports.VerificationError = void 0; | ||
/* | ||
@@ -27,2 +27,9 @@ Copyright 2023 The Sigstore Authors. | ||
} | ||
class ErrorWithCode extends BaseError { | ||
constructor({ code, message, cause, }) { | ||
super(message, cause); | ||
this.code = code; | ||
this.name = this.constructor.name; | ||
} | ||
} | ||
class VerificationError extends BaseError { | ||
@@ -34,8 +41,7 @@ } | ||
exports.PolicyError = PolicyError; | ||
class InternalError extends BaseError { | ||
constructor({ code, message, cause, }) { | ||
super(message, cause); | ||
this.code = code; | ||
} | ||
class InternalError extends ErrorWithCode { | ||
} | ||
exports.InternalError = InternalError; | ||
class SignatureError extends ErrorWithCode { | ||
} | ||
exports.SignatureError = SignatureError; |
@@ -1,2 +0,2 @@ | ||
import { Provider } from './provider'; | ||
import { IdentityProvider } from '@sigstore/sign'; | ||
/** | ||
@@ -9,3 +9,3 @@ * oauthProvider returns a new Provider instance which attempts to retrieve | ||
* @param clientSecret Client secret for the issuer (optional) | ||
* @returns {Provider} | ||
* @returns {IdentityProvider} | ||
*/ | ||
@@ -17,16 +17,6 @@ declare function oauthProvider(options: { | ||
redirectURL?: string; | ||
}): Provider; | ||
/** | ||
* ciContextProvider returns a new Provider instance which attempts to retrieve | ||
* an identity token from the CI context. | ||
* | ||
* @param audience audience claim for the generated token | ||
* @returns {Provider} | ||
*/ | ||
declare function ciContextProvider(audience?: string): Provider; | ||
}): IdentityProvider; | ||
declare const _default: { | ||
ciContextProvider: typeof ciContextProvider; | ||
oauthProvider: typeof oauthProvider; | ||
}; | ||
export default _default; | ||
export { Provider } from './provider'; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/* | ||
Copyright 2022 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 ci_1 = require("./ci"); | ||
const issuer_1 = require("./issuer"); | ||
@@ -28,3 +12,3 @@ const oauth_1 = require("./oauth"); | ||
* @param clientSecret Client secret for the issuer (optional) | ||
* @returns {Provider} | ||
* @returns {IdentityProvider} | ||
*/ | ||
@@ -39,15 +23,4 @@ function oauthProvider(options) { | ||
} | ||
/** | ||
* ciContextProvider returns a new Provider instance which attempts to retrieve | ||
* an identity token from the CI context. | ||
* | ||
* @param audience audience claim for the generated token | ||
* @returns {Provider} | ||
*/ | ||
function ciContextProvider(audience = 'sigstore') { | ||
return new ci_1.CIContextProvider(audience); | ||
} | ||
exports.default = { | ||
ciContextProvider, | ||
oauthProvider, | ||
}; |
import { Issuer } from './issuer'; | ||
import { Provider } from './provider'; | ||
import type { IdentityProvider } from '@sigstore/sign'; | ||
interface OAuthProviderOptions { | ||
@@ -9,3 +9,3 @@ issuer: Issuer; | ||
} | ||
export declare class OAuthProvider implements Provider { | ||
export declare class OAuthProvider implements IdentityProvider { | ||
private clientID; | ||
@@ -12,0 +12,0 @@ private clientSecret; |
@@ -1,2 +0,2 @@ | ||
export type { Provider as IdentityProvider } from './identity'; | ||
export type { IdentityProvider } from '@sigstore/sign'; | ||
export * as sigstore from './sigstore'; |
"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 }); | ||
@@ -43,22 +20,11 @@ exports.createRekorEntry = exports.createDSSEEnvelope = void 0; | ||
const bundle_1 = require("@sigstore/bundle"); | ||
const sign_1 = require("@sigstore/sign"); | ||
const config_1 = require("./config"); | ||
const signature_1 = require("./types/signature"); | ||
const sigstore = __importStar(require("./types/sigstore")); | ||
const util_1 = require("./util"); | ||
async function createDSSEEnvelope(payload, payloadType, options) { | ||
// Pre-authentication encoding to be signed | ||
const paeBuffer = util_1.dsse.preAuthEncoding(payloadType, payload); | ||
// Get signature and verification material for pae | ||
const sigMaterial = await options.signer(paeBuffer); | ||
const envelope = { | ||
payloadType, | ||
payload, | ||
signatures: [ | ||
{ | ||
keyid: sigMaterial.key?.id || '', | ||
sig: sigMaterial.signature, | ||
}, | ||
], | ||
}; | ||
return sigstore.Envelope.toJSON(envelope); | ||
const bundler = (0, config_1.createBundleBuilder)('dsseEnvelope', { | ||
signer: options.signer, | ||
tlogUpload: false, | ||
}); | ||
const bundle = await bundler.create({ data: payload, type: payloadType }); | ||
return (0, bundle_1.envelopeToJSON)(bundle.content.dsseEnvelope); | ||
} | ||
@@ -68,16 +34,24 @@ exports.createDSSEEnvelope = createDSSEEnvelope; | ||
// transparency log. Returns a Sigstore bundle suitable for offline verification. | ||
async function createRekorEntry(dsseEnvelope, publicKey, options = {}) { | ||
const envelope = sigstore.Envelope.fromJSON(dsseEnvelope); | ||
const tlog = (0, config_1.createTLogClient)(options); | ||
const sigMaterial = (0, signature_1.extractSignatureMaterial)(envelope, publicKey); | ||
const entry = await tlog.createDSSEEntry(envelope, sigMaterial, { | ||
async function createRekorEntry(dsseEnvelope, publicKey, | ||
/* istanbul ignore next */ | ||
options = {}) { | ||
const envelope = (0, bundle_1.envelopeFromJSON)(dsseEnvelope); | ||
const bundle = (0, bundle_1.toDSSEBundle)({ | ||
artifact: envelope.payload, | ||
artifactType: envelope.payloadType, | ||
signature: envelope.signatures[0].sig, | ||
keyHint: envelope.signatures[0].keyid, | ||
}); | ||
const tlog = new sign_1.RekorWitness({ | ||
rekorBaseURL: options.rekorURL || /* istanbul ignore next */ config_1.DEFAULT_REKOR_URL, | ||
fetchOnConflict: true, | ||
retry: options.retry ?? config_1.DEFAULT_RETRY, | ||
timeout: options.timeout ?? config_1.DEFAULT_TIMEOUT, | ||
}); | ||
const bundle = sigstore.toDSSEBundle({ | ||
envelope, | ||
signature: sigMaterial, | ||
tlogEntry: entry, | ||
}); | ||
// Add entry to transparency log | ||
const vm = await tlog.testify(bundle.content, publicKey); | ||
// Add transparency log entries to bundle | ||
bundle.verificationMaterial.tlogEntries = [...vm.tlogEntries]; | ||
return (0, bundle_1.bundleToJSON)(bundle); | ||
} | ||
exports.createRekorEntry = createRekorEntry; |
@@ -45,17 +45,6 @@ "use strict"; | ||
const config = __importStar(require("./config")); | ||
const sign_1 = require("./sign"); | ||
const verify_1 = require("./verify"); | ||
async function sign(payload, options = {}) { | ||
const ca = config.createCAClient(options); | ||
const tlog = config.createTLogClient(options); | ||
const idps = config.identityProviders(options); | ||
const signer = new sign_1.Signer({ | ||
ca, | ||
tlog, | ||
identityProviders: options.identityProvider | ||
? [options.identityProvider] | ||
: idps, | ||
tlogUpload: options.tlogUpload, | ||
}); | ||
const bundle = await signer.signBlob(payload); | ||
const bundler = config.createBundleBuilder('messageSignature', options); | ||
const bundle = await bundler.create({ data: payload }); | ||
return (0, bundle_1.bundleToJSON)(bundle); | ||
@@ -65,16 +54,4 @@ } | ||
async function attest(payload, payloadType, options = {}) { | ||
const ca = config.createCAClient(options); | ||
const tlog = config.createTLogClient(options); | ||
const tsa = config.createTSAClient(options); | ||
const idps = config.identityProviders(options); | ||
const signer = new sign_1.Signer({ | ||
ca, | ||
tlog, | ||
tsa, | ||
identityProviders: options.identityProvider | ||
? [options.identityProvider] | ||
: idps, | ||
tlogUpload: options.tlogUpload, | ||
}); | ||
const bundle = await signer.signAttestation(payload, payloadType); | ||
const bundler = config.createBundleBuilder('dsseEnvelope', options); | ||
const bundle = await bundler.create({ data: payload, type: payloadType }); | ||
return (0, bundle_1.bundleToJSON)(bundle); | ||
@@ -81,0 +58,0 @@ } |
@@ -76,3 +76,3 @@ "use strict"; | ||
function innerProofSize(index, size) { | ||
return (index ^ (size - BigInt(1))).toString(2).length; | ||
return bitLength(index ^ (size - BigInt(1))); | ||
} | ||
@@ -84,2 +84,9 @@ // Counts the number of ones in the binary representation of the given number. | ||
} | ||
// 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. | ||
@@ -86,0 +93,0 @@ // https://datatracker.ietf.org/doc/html/rfc6962#section-2 |
/// <reference types="node" /> | ||
import { Envelope } from './sigstore'; | ||
import { Signature, Signer } from '@sigstore/sign'; | ||
import { OneOf } from './utility'; | ||
@@ -15,3 +15,10 @@ interface VerificationMaterial { | ||
export type SignerFunc = (payload: Buffer) => Promise<SignatureMaterial>; | ||
export declare function extractSignatureMaterial(dsseEnvelope: Envelope, publicKey: string): SignatureMaterial; | ||
type CallbackSignerOptions = { | ||
signer: SignerFunc; | ||
}; | ||
export declare class CallbackSigner implements Signer { | ||
private signer; | ||
constructor(options: CallbackSignerOptions); | ||
sign(data: Buffer): Promise<Signature>; | ||
} | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.extractSignatureMaterial = void 0; | ||
function extractSignatureMaterial(dsseEnvelope, publicKey) { | ||
const signature = dsseEnvelope.signatures[0]; | ||
return { | ||
signature: signature.sig, | ||
key: { | ||
id: signature.keyid, | ||
value: publicKey, | ||
}, | ||
certificates: undefined, | ||
}; | ||
exports.CallbackSigner = void 0; | ||
const error_1 = require("../error"); | ||
// Adapter to allow the legacy SignerFunc callback to be used as a new Signer | ||
// interface. | ||
class CallbackSigner { | ||
constructor(options) { | ||
this.signer = options.signer; | ||
} | ||
async sign(data) { | ||
const sigMaterial = await this.signer(data); | ||
// Since we're getting data from an external source, we need to validate | ||
// that it's well-formed and complete. | ||
if (!sigMaterial.signature) { | ||
throw new error_1.SignatureError({ | ||
code: 'MISSING_SIGNATURE_ERROR', | ||
message: 'no signature returned from signer', | ||
}); | ||
} | ||
if (!sigMaterial.key?.value) { | ||
throw new error_1.SignatureError({ | ||
code: 'MISSING_PUBLIC_KEY_ERROR', | ||
message: 'no key returned from signer', | ||
}); | ||
} | ||
return { | ||
signature: sigMaterial.signature, | ||
key: { | ||
$case: 'publicKey', | ||
hint: sigMaterial.key.id, | ||
publicKey: sigMaterial.key.value, | ||
}, | ||
}; | ||
} | ||
} | ||
exports.extractSignatureMaterial = extractSignatureMaterial; | ||
exports.CallbackSigner = CallbackSigner; |
@@ -1,9 +0,5 @@ | ||
/// <reference types="node" /> | ||
import { SignatureMaterial } from './signature'; | ||
import type { Bundle } from '@sigstore/bundle'; | ||
import type { ArtifactVerificationOptions, Envelope, PublicKey, TransparencyLogInstance } from '@sigstore/protobuf-specs'; | ||
import type { Entry } from '../external/rekor'; | ||
import type { ArtifactVerificationOptions, PublicKey, TransparencyLogInstance } from '@sigstore/protobuf-specs'; | ||
import type { WithRequired } from './utility'; | ||
export { Envelope, HashAlgorithm, PublicKeyDetails, SubjectAlternativeNameType, } from '@sigstore/protobuf-specs'; | ||
export type { ArtifactVerificationOptions, ArtifactVerificationOptions_CtlogOptions, ArtifactVerificationOptions_TlogOptions, CertificateAuthority, CertificateIdentities, CertificateIdentity, ObjectIdentifierValuePair, PublicKey, SubjectAlternativeName, TransparencyLogInstance, TrustedRoot, } from '@sigstore/protobuf-specs'; | ||
export { SubjectAlternativeNameType } from '@sigstore/protobuf-specs'; | ||
export type { ArtifactVerificationOptions, ArtifactVerificationOptions_CtlogOptions, ArtifactVerificationOptions_TlogOptions, CertificateAuthority, CertificateIdentities, CertificateIdentity, Envelope, ObjectIdentifierValuePair, PublicKey, SubjectAlternativeName, TransparencyLogInstance, TrustedRoot, } from '@sigstore/protobuf-specs'; | ||
export type RequiredArtifactVerificationOptions = WithRequired<ArtifactVerificationOptions, 'ctlogOptions' | 'tlogOptions'>; | ||
@@ -20,13 +16,1 @@ export type CAArtifactVerificationOptions = WithRequired<ArtifactVerificationOptions, 'ctlogOptions'> & { | ||
}; | ||
export declare function toDSSEBundle({ envelope, signature, tlogEntry, timestamp, }: { | ||
envelope: Envelope; | ||
signature: SignatureMaterial; | ||
tlogEntry?: Entry; | ||
timestamp?: Buffer; | ||
}): Bundle; | ||
export declare function toMessageSignatureBundle({ digest, signature, tlogEntry, timestamp, }: { | ||
digest: Buffer; | ||
signature: SignatureMaterial; | ||
tlogEntry?: Entry; | ||
timestamp?: Buffer; | ||
}): Bundle; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.toMessageSignatureBundle = exports.toDSSEBundle = exports.isCAVerificationOptions = exports.SubjectAlternativeNameType = exports.PublicKeyDetails = exports.HashAlgorithm = exports.Envelope = void 0; | ||
/* | ||
@@ -19,12 +17,7 @@ Copyright 2023 The Sigstore Authors. | ||
*/ | ||
const bundle_1 = require("@sigstore/bundle"); | ||
const protobuf_specs_1 = require("@sigstore/protobuf-specs"); | ||
const util_1 = require("../util"); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isCAVerificationOptions = exports.SubjectAlternativeNameType = void 0; | ||
// Enums from protobuf-specs | ||
// TODO: Move Envelope to "type" export once @sigstore/sign is a thing | ||
var protobuf_specs_2 = require("@sigstore/protobuf-specs"); | ||
Object.defineProperty(exports, "Envelope", { enumerable: true, get: function () { return protobuf_specs_2.Envelope; } }); | ||
Object.defineProperty(exports, "HashAlgorithm", { enumerable: true, get: function () { return protobuf_specs_2.HashAlgorithm; } }); | ||
Object.defineProperty(exports, "PublicKeyDetails", { enumerable: true, get: function () { return protobuf_specs_2.PublicKeyDetails; } }); | ||
Object.defineProperty(exports, "SubjectAlternativeNameType", { enumerable: true, get: function () { return protobuf_specs_2.SubjectAlternativeNameType; } }); | ||
var protobuf_specs_1 = require("@sigstore/protobuf-specs"); | ||
Object.defineProperty(exports, "SubjectAlternativeNameType", { enumerable: true, get: function () { return protobuf_specs_1.SubjectAlternativeNameType; } }); | ||
function isCAVerificationOptions(options) { | ||
@@ -36,105 +29,1 @@ return (options.ctlogOptions !== undefined && | ||
exports.isCAVerificationOptions = isCAVerificationOptions; | ||
// All of the following functions are used to construct a ValidBundle | ||
// from various types of input. When this code moves into the | ||
// @sigstore/sign package, these functions will be exported from there. | ||
function toDSSEBundle({ envelope, signature, tlogEntry, timestamp, }) { | ||
return { | ||
mediaType: bundle_1.BUNDLE_V01_MEDIA_TYPE, | ||
content: { $case: 'dsseEnvelope', dsseEnvelope: envelope }, | ||
verificationMaterial: toVerificationMaterial({ | ||
signature, | ||
tlogEntry, | ||
timestamp, | ||
}), | ||
}; | ||
} | ||
exports.toDSSEBundle = toDSSEBundle; | ||
function toMessageSignatureBundle({ digest, signature, tlogEntry, timestamp, }) { | ||
return { | ||
mediaType: bundle_1.BUNDLE_V01_MEDIA_TYPE, | ||
content: { | ||
$case: 'messageSignature', | ||
messageSignature: { | ||
messageDigest: { | ||
algorithm: protobuf_specs_1.HashAlgorithm.SHA2_256, | ||
digest: digest, | ||
}, | ||
signature: signature.signature, | ||
}, | ||
}, | ||
verificationMaterial: toVerificationMaterial({ | ||
signature, | ||
tlogEntry, | ||
timestamp, | ||
}), | ||
}; | ||
} | ||
exports.toMessageSignatureBundle = toMessageSignatureBundle; | ||
function toTransparencyLogEntry(entry) { | ||
/* istanbul ignore next */ | ||
const b64SET = entry.verification?.signedEntryTimestamp || ''; | ||
const set = Buffer.from(b64SET, 'base64'); | ||
const logID = Buffer.from(entry.logID, 'hex'); | ||
const proof = entry.verification?.inclusionProof | ||
? toInclusionProof(entry.verification.inclusionProof) | ||
: undefined; | ||
// Parse entry body so we can extract the kind and version. | ||
const bodyJSON = util_1.encoding.base64Decode(entry.body); | ||
const entryBody = JSON.parse(bodyJSON); | ||
return { | ||
inclusionPromise: { | ||
signedEntryTimestamp: set, | ||
}, | ||
logIndex: entry.logIndex.toString(), | ||
logId: { | ||
keyId: logID, | ||
}, | ||
integratedTime: entry.integratedTime.toString(), | ||
kindVersion: { | ||
kind: entryBody.kind, | ||
version: entryBody.apiVersion, | ||
}, | ||
inclusionProof: proof, | ||
canonicalizedBody: Buffer.from(entry.body, 'base64'), | ||
}; | ||
} | ||
function toInclusionProof(proof) { | ||
return { | ||
logIndex: proof.logIndex.toString(), | ||
rootHash: Buffer.from(proof.rootHash, 'hex'), | ||
treeSize: proof.treeSize.toString(), | ||
checkpoint: { | ||
envelope: proof.checkpoint, | ||
}, | ||
hashes: proof.hashes.map((h) => Buffer.from(h, 'hex')), | ||
}; | ||
} | ||
function toVerificationMaterial({ signature, tlogEntry, timestamp, }) { | ||
return { | ||
content: signature.certificates | ||
? toVerificationMaterialx509CertificateChain(signature.certificates) | ||
: toVerificationMaterialPublicKey(signature.key.id || ''), | ||
tlogEntries: tlogEntry ? [toTransparencyLogEntry(tlogEntry)] : [], | ||
timestampVerificationData: timestamp | ||
? toTimestampVerificationData(timestamp) | ||
: undefined, | ||
}; | ||
} | ||
function toVerificationMaterialx509CertificateChain(certificates) { | ||
return { | ||
$case: 'x509CertificateChain', | ||
x509CertificateChain: { | ||
certificates: certificates.map((c) => ({ | ||
rawBytes: util_1.pem.toDER(c), | ||
})), | ||
}, | ||
}; | ||
} | ||
function toVerificationMaterialPublicKey(hint) { | ||
return { $case: 'publicKey', publicKey: { hint } }; | ||
} | ||
function toTimestampVerificationData(timestamp) { | ||
return { | ||
rfc3161Timestamps: [{ signedTimestamp: timestamp }], | ||
}; | ||
} |
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
import { BinaryLike, KeyLike, KeyPairKeyObjectResult } from 'crypto'; | ||
export declare function generateKeyPair(): KeyPairKeyObjectResult; | ||
import { BinaryLike, KeyLike } from 'crypto'; | ||
export declare function createPublicKey(key: string | Buffer): KeyLike; | ||
export declare function signBlob(data: NodeJS.ArrayBufferView, privateKey: KeyLike): Buffer; | ||
export declare function verifyBlob(data: Buffer, key: KeyLike, signature: Buffer, algorithm?: string): boolean; | ||
@@ -9,0 +6,0 @@ export declare function hash(data: BinaryLike): Buffer; |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.bufferEqual = exports.randomBytes = exports.hash = exports.verifyBlob = exports.signBlob = exports.createPublicKey = exports.generateKeyPair = void 0; | ||
exports.bufferEqual = exports.randomBytes = exports.hash = exports.verifyBlob = exports.createPublicKey = void 0; | ||
/* | ||
@@ -24,11 +24,3 @@ Copyright 2022 The Sigstore Authors. | ||
const crypto_1 = __importDefault(require("crypto")); | ||
const EC_KEYPAIR_TYPE = 'ec'; | ||
const P256_CURVE = 'P-256'; | ||
const SHA256_ALGORITHM = 'sha256'; | ||
function generateKeyPair() { | ||
return crypto_1.default.generateKeyPairSync(EC_KEYPAIR_TYPE, { | ||
namedCurve: P256_CURVE, | ||
}); | ||
} | ||
exports.generateKeyPair = generateKeyPair; | ||
function createPublicKey(key) { | ||
@@ -43,6 +35,2 @@ if (typeof key === 'string') { | ||
exports.createPublicKey = createPublicKey; | ||
function signBlob(data, privateKey) { | ||
return crypto_1.default.sign(null, data, privateKey); | ||
} | ||
exports.signBlob = signBlob; | ||
function verifyBlob(data, key, signature, algorithm) { | ||
@@ -55,2 +43,3 @@ // The try/catch is to work around an issue in Node 14.x where verify throws | ||
catch (e) { | ||
/* istanbul ignore next */ | ||
return false; | ||
@@ -57,0 +46,0 @@ } |
@@ -6,5 +6,2 @@ export * as asn1 from './asn1'; | ||
export * as json from './json'; | ||
export * as oidc from './oidc'; | ||
export * as pem from './pem'; | ||
export * as promise from './promise'; | ||
export * as ua from './ua'; |
@@ -26,3 +26,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ua = exports.promise = exports.pem = exports.oidc = exports.json = exports.encoding = exports.dsse = exports.crypto = exports.asn1 = void 0; | ||
exports.pem = exports.json = exports.encoding = exports.dsse = exports.crypto = exports.asn1 = void 0; | ||
/* | ||
@@ -48,5 +48,2 @@ Copyright 2022 The Sigstore Authors. | ||
exports.json = __importStar(require("./json")); | ||
exports.oidc = __importStar(require("./oidc")); | ||
exports.pem = __importStar(require("./pem")); | ||
exports.promise = __importStar(require("./promise")); | ||
exports.ua = __importStar(require("./ua")); |
{ | ||
"name": "sigstore", | ||
"version": "1.8.0", | ||
"version": "1.9.0", | ||
"description": "code-signing for npm packages", | ||
@@ -35,2 +35,3 @@ "main": "dist/index.js", | ||
"@sigstore/jest": "^0.0.0", | ||
"@sigstore/mock": "^0.2.0", | ||
"@tufjs/repo-mock": "^1.1.0", | ||
@@ -40,4 +41,5 @@ "@types/make-fetch-happen": "^10.0.0" | ||
"dependencies": { | ||
"@sigstore/bundle": "^1.0.0", | ||
"@sigstore/bundle": "^1.1.0", | ||
"@sigstore/protobuf-specs": "^0.2.0", | ||
"@sigstore/sign": "^1.0.0", | ||
"@sigstore/tuf": "^1.0.3", | ||
@@ -44,0 +46,0 @@ "make-fetch-happen": "^11.0.1" |
117
README.md
@@ -23,2 +23,119 @@ # sigstore · [![npm version](https://img.shields.io/npm/v/sigstore.svg?style=flat)](https://www.npmjs.com/package/sigstore) [![CI Status](https://github.com/sigstore/sigstore-js/workflows/CI/badge.svg)](https://github.com/sigstore/sigstore-js/actions/workflows/ci.yml) [![Smoke Test Status](https://github.com/sigstore/sigstore-js/workflows/smoke-test/badge.svg)](https://github.com/sigstore/sigstore-js/actions/workflows/smoke-test.yml) | ||
## Compatibility | ||
The following table documents which combinations of Sigstore bundle versions | ||
and Rekor types can be verified by different versions of the `sigstore` | ||
library. It also lists which `sigstore` versions were shipped with different | ||
`npm` CLI versions. | ||
<table> | ||
<thead> | ||
<tr> | ||
<th colspan=2><code>sigstore</code></th> | ||
<th>1.0</th> | ||
<th>1.1</th> | ||
<th>1.2</th> | ||
<th>1.3</th> | ||
<th>1.4</th> | ||
<th>1.5</th> | ||
<th>1.6</th> | ||
<th>1.7</th> | ||
<th>1.8</th> | ||
</tr> | ||
<tr> | ||
<th colspan=2><code>npm</code></th> | ||
<th>9.5.0</th> | ||
<th>9.6.2</th> | ||
<th>9.6.3</th> | ||
<th>9.6.5</th> | ||
<th>9.6.6</th> | ||
<th>9.6.7</th> | ||
<th>9.7.2</th> | ||
<th>9.8.0</th> | ||
<th></th> | ||
</tr> | ||
<tr> | ||
<th>Bundle Version</th> | ||
<th>Rekor Type</th> | ||
<th colspan=9></th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr> | ||
<td rowspan=3>0.1</td> | ||
<td>hashedrekord</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
</tr> | ||
<tr> | ||
<td>intoto</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
</tr> | ||
<tr> | ||
<td>dsse</td> | ||
<td>:x:</td> | ||
<td>:x:</td> | ||
<td>:x:</td> | ||
<td>:x:</td> | ||
<td>:x:</td> | ||
<td>:x:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
</tr> | ||
<tr> | ||
<td rowspan=3>0.2</td> | ||
<td>hashedrekord</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
</tr> | ||
<tr> | ||
<td>intoto</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
</tr> | ||
<tr> | ||
<td>dsse</td> | ||
<td>:x:</td> | ||
<td>:x:</td> | ||
<td>:x:</td> | ||
<td>:x:</td> | ||
<td>:x:</td> | ||
<td>:x:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
<td>:white_check_mark:</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
## Usage | ||
@@ -25,0 +142,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
283
2
189183
5
5
86
3966
+ Added@sigstore/sign@^1.0.0
+ Added@sigstore/sign@1.0.0(transitive)
Updated@sigstore/bundle@^1.1.0