Skip to content

Commit 9238682

Browse files
authoredJul 3, 2023
deps: sigstore@1.7.0 (#6623)
Signed-off-by: Brian DeHamer <bdehamer@github.com>
1 parent 5baf6a2 commit 9238682

15 files changed

+207
-224
lines changed
 

‎DEPENDENCIES.md

-2
Original file line numberDiff line numberDiff line change
@@ -769,8 +769,6 @@ graph LR;
769769
sigstore-->make-fetch-happen;
770770
sigstore-->sigstore-protobuf-specs["@sigstore/protobuf-specs"];
771771
sigstore-->sigstore-tuf["@sigstore/tuf"];
772-
sigstore-->tuf-js;
773-
sigstore-tuf-->make-fetch-happen;
774772
sigstore-tuf-->sigstore-protobuf-specs["@sigstore/protobuf-specs"];
775773
sigstore-tuf-->tuf-js;
776774
socks-->ip;

‎node_modules/@sigstore/tuf/package.json

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sigstore/tuf",
3-
"version": "1.0.0",
3+
"version": "1.0.2",
44
"description": "Client for the Sigstore TUF repository",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
@@ -27,17 +27,13 @@
2727
"provenance": true
2828
},
2929
"devDependencies": {
30-
"@total-typescript/shoehorn": "^0.1.0",
30+
"@sigstore/jest": "^0.0.0",
3131
"@tufjs/repo-mock": "^1.1.0",
32-
"@types/node": "^20.2.5",
33-
"nock": "^13.2.4",
34-
"shx": "^0.3.3",
35-
"typescript": "^5.1.3"
32+
"@types/make-fetch-happen": "^10.0.0"
3633
},
3734
"dependencies": {
3835
"@sigstore/protobuf-specs": "^0.1.0",
39-
"tuf-js": "^1.1.3",
40-
"make-fetch-happen": "^11.0.1"
36+
"tuf-js": "^1.1.7"
4137
},
4238
"engines": {
4339
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"

‎node_modules/sigstore/dist/merkle/digest.js

-48
This file was deleted.

‎node_modules/sigstore/dist/merkle/index.js

-22
This file was deleted.

‎node_modules/sigstore/dist/merkle/verify.js

-78
This file was deleted.

‎node_modules/sigstore/dist/sigstore-utils.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,6 @@ async function createRekorEntry(dsseEnvelope, publicKey, options = {}) {
7575
signature: sigMaterial,
7676
tlogEntry: entry,
7777
});
78-
return sigstore.Bundle.toJSON(bundle);
78+
return sigstore.bundleToJSON(bundle);
7979
}
8080
exports.createRekorEntry = createRekorEntry;

‎node_modules/sigstore/dist/sigstore.js

+21-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
2323
return result;
2424
};
2525
Object.defineProperty(exports, "__esModule", { value: true });
26-
exports.DEFAULT_REKOR_URL = exports.DEFAULT_FULCIO_URL = exports.tuf = exports.utils = exports.VerificationError = exports.ValidationError = exports.PolicyError = exports.InternalError = exports.verify = exports.attest = exports.sign = void 0;
26+
exports.DEFAULT_REKOR_URL = exports.DEFAULT_FULCIO_URL = exports.tuf = exports.utils = exports.VerificationError = exports.ValidationError = exports.PolicyError = exports.InternalError = exports.createVerifier = exports.verify = exports.attest = exports.sign = void 0;
2727
/*
2828
Copyright 2023 The Sigstore Authors.
2929
@@ -57,7 +57,7 @@ async function sign(payload, options = {}) {
5757
tlogUpload: options.tlogUpload,
5858
});
5959
const bundle = await signer.signBlob(payload);
60-
return sigstore.Bundle.toJSON(bundle);
60+
return sigstore.bundleToJSON(bundle);
6161
}
6262
exports.sign = sign;
6363
async function attest(payload, payloadType, options = {}) {
@@ -75,7 +75,7 @@ async function attest(payload, payloadType, options = {}) {
7575
tlogUpload: options.tlogUpload,
7676
});
7777
const bundle = await signer.signAttestation(payload, payloadType);
78-
return sigstore.Bundle.toJSON(bundle);
78+
return sigstore.bundleToJSON(bundle);
7979
}
8080
exports.attest = attest;
8181
async function verify(bundle, payload, options = {}) {
@@ -92,6 +92,24 @@ async function verify(bundle, payload, options = {}) {
9292
return verifier.verify(deserializedBundle, opts, payload);
9393
}
9494
exports.verify = verify;
95+
async function createVerifier(options) {
96+
const trustedRoot = await tuf.getTrustedRoot({
97+
mirrorURL: options.tufMirrorURL,
98+
rootPath: options.tufRootPath,
99+
cachePath: options.tufCachePath,
100+
retry: options.retry ?? config.DEFAULT_RETRY,
101+
timeout: options.timeout ?? config.DEFAULT_TIMEOUT,
102+
});
103+
const verifier = new verify_1.Verifier(trustedRoot, options.keySelector);
104+
const verifyOpts = config.artifactVerificationOptions(options);
105+
return {
106+
verify: (bundle) => {
107+
const deserializedBundle = sigstore.bundleFromJSON(bundle);
108+
return verifier.verify(deserializedBundle, verifyOpts);
109+
},
110+
};
111+
}
112+
exports.createVerifier = createVerifier;
95113
const tufUtils = {
96114
client: (options = {}) => {
97115
return tuf.initTUF({

‎node_modules/sigstore/dist/tlog/verify/index.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ limitations under the License.
4141
*/
4242
const error_1 = require("../../error");
4343
const sigstore = __importStar(require("../../types/sigstore"));
44+
const cert_1 = require("../../x509/cert");
4445
const body_1 = require("./body");
4546
const set_1 = require("./set");
4647
// Verifies that the number of tlog entries that pass offline verification
@@ -50,7 +51,7 @@ function verifyTLogEntries(bundle, trustedRoot, options) {
5051
throw new error_1.VerificationError('Online verification not implemented');
5152
}
5253
// Extract the signing cert, if available
53-
const signingCert = sigstore.signingCertificate(bundle);
54+
const signingCert = signingCertificate(bundle);
5455
// Iterate over the tlog entries and verify each one
5556
const verifiedEntries = bundle.verificationMaterial.tlogEntries.filter((entry) => verifyTLogEntryOffline(entry, bundle.content, trustedRoot.tlogs, signingCert));
5657
if (verifiedEntries.length < options.threshold) {
@@ -73,3 +74,10 @@ function verifyTLogEntryOffline(entry, bundleContent, tlogs, signingCert) {
7374
(0, set_1.verifyTLogSET)(entry, tlogs) &&
7475
verifyTLogIntegrationTime());
7576
}
77+
function signingCertificate(bundle) {
78+
if (!sigstore.isBundleWithCertificateChain(bundle)) {
79+
return undefined;
80+
}
81+
const signingCert = bundle.verificationMaterial.content.x509CertificateChain.certificates[0];
82+
return cert_1.x509Certificate.parse(signingCert.rawBytes);
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
"use strict";
2+
var __importDefault = (this && this.__importDefault) || function (mod) {
3+
return (mod && mod.__esModule) ? mod : { "default": mod };
4+
};
5+
Object.defineProperty(exports, "__esModule", { value: true });
6+
exports.verifyMerkleInclusion = void 0;
7+
/*
8+
Copyright 2023 The Sigstore Authors.
9+
10+
Licensed under the Apache License, Version 2.0 (the "License");
11+
you may not use this file except in compliance with the License.
12+
You may obtain a copy of the License at
13+
14+
http://www.apache.org/licenses/LICENSE-2.0
15+
16+
Unless required by applicable law or agreed to in writing, software
17+
distributed under the License is distributed on an "AS IS" BASIS,
18+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19+
See the License for the specific language governing permissions and
20+
limitations under the License.
21+
*/
22+
const crypto_1 = __importDefault(require("crypto"));
23+
const error_1 = require("../../error");
24+
const RFC6962_LEAF_HASH_PREFIX = Buffer.from([0x00]);
25+
const RFC6962_NODE_HASH_PREFIX = Buffer.from([0x01]);
26+
function verifyMerkleInclusion(entry) {
27+
const inclusionProof = entry.inclusionProof;
28+
if (!inclusionProof) {
29+
throw new error_1.VerificationError('tlog entry has no inclusion proof');
30+
}
31+
const logIndex = BigInt(inclusionProof.logIndex);
32+
const treeSize = BigInt(inclusionProof.treeSize);
33+
if (logIndex < 0n || logIndex >= treeSize) {
34+
throw new error_1.VerificationError('invalid inclusion proof index');
35+
}
36+
// Figure out which subset of hashes corresponds to the inner and border
37+
// nodes
38+
const { inner, border } = decompInclProof(logIndex, treeSize);
39+
if (inclusionProof.hashes.length !== inner + border) {
40+
throw new error_1.VerificationError('invalid inclusion proof length');
41+
}
42+
const innerHashes = inclusionProof.hashes.slice(0, inner);
43+
const borderHashes = inclusionProof.hashes.slice(inner);
44+
// The entry's hash is the leaf hash
45+
const leafHash = hashLeaf(entry.canonicalizedBody);
46+
// Chain the hashes belonging to the inner and border portions
47+
const calculatedHash = chainBorderRight(chainInner(leafHash, innerHashes, logIndex), borderHashes);
48+
// Calculated hash should match the root hash in the inclusion proof
49+
return bufferEqual(calculatedHash, inclusionProof.rootHash);
50+
}
51+
exports.verifyMerkleInclusion = verifyMerkleInclusion;
52+
// Breaks down inclusion proof for a leaf at the specified index in a tree of
53+
// the specified size. The split point is where paths to the index leaf and
54+
// the (size - 1) leaf diverge. Returns lengths of the bottom and upper proof
55+
// parts.
56+
function decompInclProof(index, size) {
57+
const inner = innerProofSize(index, size);
58+
const border = onesCount(index >> BigInt(inner));
59+
return { inner, border };
60+
}
61+
// Computes a subtree hash for a node on or below the tree's right border.
62+
// Assumes the provided proof hashes are ordered from lower to higher levels
63+
// and seed is the initial hash of the node specified by the index.
64+
function chainInner(seed, hashes, index) {
65+
return hashes.reduce((acc, h, i) => {
66+
if ((index >> BigInt(i)) & BigInt(1)) {
67+
return hashChildren(h, acc);
68+
}
69+
else {
70+
return hashChildren(acc, h);
71+
}
72+
}, seed);
73+
}
74+
// Computes a subtree hash for nodes along the tree's right border.
75+
function chainBorderRight(seed, hashes) {
76+
return hashes.reduce((acc, h) => hashChildren(h, acc), seed);
77+
}
78+
function innerProofSize(index, size) {
79+
return (index ^ (size - BigInt(1))).toString(2).length;
80+
}
81+
// Counts the number of ones in the binary representation of the given number.
82+
// https://en.wikipedia.org/wiki/Hamming_weight
83+
function onesCount(x) {
84+
return x.toString(2).split('1').length - 1;
85+
}
86+
// Hashing logic according to RFC6962.
87+
// https://datatracker.ietf.org/doc/html/rfc6962#section-2
88+
function hashChildren(left, right) {
89+
const hasher = crypto_1.default.createHash('sha256');
90+
hasher.update(RFC6962_NODE_HASH_PREFIX);
91+
hasher.update(left);
92+
hasher.update(right);
93+
return hasher.digest();
94+
}
95+
function hashLeaf(leaf) {
96+
const hasher = crypto_1.default.createHash('sha256');
97+
hasher.update(RFC6962_LEAF_HASH_PREFIX);
98+
hasher.update(leaf);
99+
return hasher.digest();
100+
}
101+
function bufferEqual(a, b) {
102+
try {
103+
return crypto_1.default.timingSafeEqual(a, b);
104+
}
105+
catch {
106+
/* istanbul ignore next */
107+
return false;
108+
}
109+
}

‎node_modules/sigstore/dist/types/sigstore/index.js

+32-35
Original file line numberDiff line numberDiff line change

‎node_modules/sigstore/dist/types/sigstore/validate.js

+15
Original file line numberDiff line numberDiff line change

‎node_modules/sigstore/package.json

+5-12
Original file line numberDiff line numberDiff line change

‎node_modules/sigstore/store/public-good-instance-root.json

-1
This file was deleted.

‎package-lock.json

+10-12
Original file line numberDiff line numberDiff line change

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@
107107
"qrcode-terminal": "^0.12.0",
108108
"read": "^2.1.0",
109109
"semver": "^7.5.2",
110-
"sigstore": "^1.6.0",
110+
"sigstore": "^1.7.0",
111111
"ssri": "^10.0.4",
112112
"supports-color": "^9.3.1",
113113
"tar": "^6.1.15",

0 commit comments

Comments
 (0)
Please sign in to comment.