avancement planning
This commit is contained in:
+13
@@ -1,3 +1,5 @@
|
||||
import type { TransparencyLogEntry } from '@sigstore/bundle';
|
||||
import type { CreateEntryRequest } from '@sigstore/protobuf-specs/rekor/v2';
|
||||
import type { Entry, ProposedEntry } from '../../external/rekor';
|
||||
import type { FetchOptions } from '../../types/fetch';
|
||||
export type { Entry, ProposedEntry };
|
||||
@@ -14,3 +16,14 @@ export declare class TLogClient implements TLog {
|
||||
constructor(options: TLogClientOptions);
|
||||
createEntry(proposedEntry: ProposedEntry): Promise<Entry>;
|
||||
}
|
||||
export interface TLogV2 {
|
||||
createEntry: (createEntryRequest: CreateEntryRequest) => Promise<TransparencyLogEntry>;
|
||||
}
|
||||
export type TLogV2ClientOptions = {
|
||||
rekorBaseURL: string;
|
||||
} & FetchOptions;
|
||||
export declare class TLogV2Client implements TLogV2 {
|
||||
private rekor;
|
||||
constructor(options: TLogV2ClientOptions);
|
||||
createEntry(createEntryRequest: CreateEntryRequest): Promise<TransparencyLogEntry>;
|
||||
}
|
||||
|
||||
+33
-2
@@ -1,8 +1,8 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TLogClient = void 0;
|
||||
exports.TLogV2Client = exports.TLogClient = void 0;
|
||||
/*
|
||||
Copyright 2023 The Sigstore Authors.
|
||||
Copyright 2025 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.
|
||||
@@ -19,7 +19,10 @@ limitations under the License.
|
||||
const error_1 = require("../../error");
|
||||
const error_2 = require("../../external/error");
|
||||
const rekor_1 = require("../../external/rekor");
|
||||
const rekor_v2_1 = require("../../external/rekor-v2");
|
||||
class TLogClient {
|
||||
rekor;
|
||||
fetchOnConflict;
|
||||
constructor(options) {
|
||||
this.fetchOnConflict = options.fetchOnConflict ?? false;
|
||||
this.rekor = new rekor_1.Rekor({
|
||||
@@ -59,3 +62,31 @@ function entryExistsError(value) {
|
||||
value.statusCode === 409 &&
|
||||
value.location !== undefined);
|
||||
}
|
||||
class TLogV2Client {
|
||||
rekor;
|
||||
constructor(options) {
|
||||
this.rekor = new rekor_v2_1.RekorV2({
|
||||
baseURL: options.rekorBaseURL,
|
||||
retry: options.retry,
|
||||
timeout: options.timeout,
|
||||
});
|
||||
}
|
||||
async createEntry(createEntryRequest) {
|
||||
let entry;
|
||||
try {
|
||||
entry = await this.rekor.createEntry(createEntryRequest);
|
||||
}
|
||||
catch (err) {
|
||||
(0, error_1.internalError)(err, 'TLOG_CREATE_ENTRY_ERROR', 'error creating tlog entry');
|
||||
}
|
||||
if (entry.logId === undefined || entry.kindVersion === undefined) {
|
||||
(0, error_1.internalError)(new Error('invalid tlog entry'), 'TLOG_CREATE_ENTRY_ERROR', 'error creating tlog entry');
|
||||
}
|
||||
return {
|
||||
...entry,
|
||||
logId: entry.logId,
|
||||
kindVersion: entry.kindVersion,
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.TLogV2Client = TLogV2Client;
|
||||
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
import type { CreateEntryRequest } from '@sigstore/protobuf-specs/rekor/v2';
|
||||
import type { ProposedEntry } from '../../external/rekor';
|
||||
import type { SignatureBundle } from '../witness';
|
||||
export declare function toProposedEntry(content: SignatureBundle, publicKey: string, entryType?: 'dsse' | 'intoto'): ProposedEntry;
|
||||
export declare function toCreateEntryRequest(content: SignatureBundle, publicKey: string): CreateEntryRequest;
|
||||
|
||||
+58
-1
@@ -1,8 +1,9 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.toProposedEntry = toProposedEntry;
|
||||
exports.toCreateEntryRequest = toCreateEntryRequest;
|
||||
/*
|
||||
Copyright 2023 The Sigstore Authors.
|
||||
Copyright 2025 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.
|
||||
@@ -17,6 +18,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
const bundle_1 = require("@sigstore/bundle");
|
||||
const protobuf_specs_1 = require("@sigstore/protobuf-specs");
|
||||
const util_1 = require("../../util");
|
||||
const SHA256_ALGORITHM = 'sha256';
|
||||
function toProposedEntry(content, publicKey,
|
||||
@@ -138,3 +140,58 @@ function calculateDSSEHash(envelope, publicKey) {
|
||||
.digest(SHA256_ALGORITHM, util_1.json.canonicalize(dsse))
|
||||
.toString('hex');
|
||||
}
|
||||
function toCreateEntryRequest(content, publicKey) {
|
||||
switch (content.$case) {
|
||||
case 'dsseEnvelope':
|
||||
return toCreateEntryRequestDSSE(content.dsseEnvelope, publicKey);
|
||||
case 'messageSignature':
|
||||
return toCreateEntryRequestMessageSignature(content.messageSignature, publicKey);
|
||||
}
|
||||
}
|
||||
function toCreateEntryRequestDSSE(envelope, publicKey) {
|
||||
return {
|
||||
spec: {
|
||||
$case: 'dsseRequestV002',
|
||||
dsseRequestV002: {
|
||||
envelope: envelope,
|
||||
verifiers: [
|
||||
{
|
||||
// TODO: We need to add support of passing the key details in the
|
||||
// signature bundle. For now we're hardcoding the key details here.
|
||||
keyDetails: protobuf_specs_1.PublicKeyDetails.PKIX_ECDSA_P256_SHA_256,
|
||||
verifier: {
|
||||
$case: 'x509Certificate',
|
||||
x509Certificate: {
|
||||
rawBytes: util_1.pem.toDER(publicKey),
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
function toCreateEntryRequestMessageSignature(messageSignature, publicKey) {
|
||||
return {
|
||||
spec: {
|
||||
$case: 'hashedRekordRequestV002',
|
||||
hashedRekordRequestV002: {
|
||||
digest: messageSignature.messageDigest.digest,
|
||||
signature: {
|
||||
content: messageSignature.signature,
|
||||
verifier: {
|
||||
// TODO: We need to add support of passing the key details in the
|
||||
// signature bundle. For now we're hardcoding the key details here.
|
||||
keyDetails: protobuf_specs_1.PublicKeyDetails.PKIX_ECDSA_P256_SHA_256,
|
||||
verifier: {
|
||||
$case: 'x509Certificate',
|
||||
x509Certificate: {
|
||||
rawBytes: util_1.pem.toDER(publicKey),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
+4
-1
@@ -7,10 +7,13 @@ type TransparencyLogEntries = {
|
||||
};
|
||||
export type RekorWitnessOptions = Partial<TLogClientOptions> & {
|
||||
entryType?: 'dsse' | 'intoto';
|
||||
majorApiVersion?: number;
|
||||
};
|
||||
export declare class RekorWitness implements Witness {
|
||||
private tlog;
|
||||
private tlogV1;
|
||||
private tlogV2;
|
||||
private entryType?;
|
||||
private majorApiVersion;
|
||||
constructor(options: RekorWitnessOptions);
|
||||
testify(content: SignatureBundle, publicKey: string): Promise<TransparencyLogEntries>;
|
||||
}
|
||||
|
||||
+23
-8
@@ -2,7 +2,7 @@
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RekorWitness = exports.DEFAULT_REKOR_URL = void 0;
|
||||
/*
|
||||
Copyright 2023 The Sigstore Authors.
|
||||
Copyright 2025 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.
|
||||
@@ -21,17 +21,34 @@ const client_1 = require("./client");
|
||||
const entry_1 = require("./entry");
|
||||
exports.DEFAULT_REKOR_URL = 'https://rekor.sigstore.dev';
|
||||
class RekorWitness {
|
||||
tlogV1;
|
||||
tlogV2;
|
||||
entryType;
|
||||
majorApiVersion;
|
||||
constructor(options) {
|
||||
this.entryType = options.entryType;
|
||||
this.tlog = new client_1.TLogClient({
|
||||
this.majorApiVersion = options.majorApiVersion || 1;
|
||||
this.tlogV1 = new client_1.TLogClient({
|
||||
...options,
|
||||
rekorBaseURL: options.rekorBaseURL || /* istanbul ignore next */ exports.DEFAULT_REKOR_URL,
|
||||
});
|
||||
this.tlogV2 = new client_1.TLogV2Client({
|
||||
...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);
|
||||
let tlogEntry;
|
||||
if (this.majorApiVersion === 2) {
|
||||
const request = (0, entry_1.toCreateEntryRequest)(content, publicKey);
|
||||
tlogEntry = await this.tlogV2.createEntry(request);
|
||||
}
|
||||
else {
|
||||
const proposedEntry = (0, entry_1.toProposedEntry)(content, publicKey, this.entryType);
|
||||
const entry = await this.tlogV1.createEntry(proposedEntry);
|
||||
tlogEntry = toTransparencyLogEntry(entry);
|
||||
}
|
||||
return { tlogEntries: [tlogEntry] };
|
||||
}
|
||||
}
|
||||
exports.RekorWitness = RekorWitness;
|
||||
@@ -60,9 +77,7 @@ function toTransparencyLogEntry(entry) {
|
||||
inclusionProof: proof,
|
||||
canonicalizedBody: Buffer.from(entry.body, 'base64'),
|
||||
};
|
||||
return {
|
||||
tlogEntries: [tlogEntry],
|
||||
};
|
||||
return tlogEntry;
|
||||
}
|
||||
function inclusionPromise(promise) {
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user