Skip to content

Commit

Permalink
verification of v0.2 Sigstore bundles (#605)
Browse files Browse the repository at this point in the history
* verification of v0.2 Sigstore bundles

Signed-off-by: Brian DeHamer <bdehamer@github.com>

* Update .changeset/good-penguins-brake.md

Co-authored-by: Philip Harrison <philip@mailharrison.com>
Signed-off-by: Brian DeHamer <bdehamer@github.com>

* add test for v0.3 bundle verification

Signed-off-by: Brian DeHamer <bdehamer@github.com>

---------

Signed-off-by: Brian DeHamer <bdehamer@github.com>
Co-authored-by: Philip Harrison <philip@mailharrison.com>
  • Loading branch information
bdehamer and feelepxyz committed Jul 12, 2023
1 parent 6ec4f0c commit f1b8bad
Show file tree
Hide file tree
Showing 26 changed files with 546 additions and 232 deletions.
5 changes: 5 additions & 0 deletions .changeset/fast-carrots-tan.md
@@ -0,0 +1,5 @@
---
'@sigstore/bundle': minor
---

Export bundle media type constants, refine `SerializedTLogEntry` type
5 changes: 5 additions & 0 deletions .changeset/good-penguins-brake.md
@@ -0,0 +1,5 @@
---
'sigstore': minor
---

Support for verifying v0.2 Sigstore bundles that contain inclusion proofs from Rekor
7 changes: 7 additions & 0 deletions packages/bundle/src/__tests__/index.test.ts
Expand Up @@ -15,6 +15,8 @@ limitations under the License.
*/
import { fromPartial } from '@total-typescript/shoehorn';
import {
BUNDLE_V01_MEDIA_TYPE,
BUNDLE_V02_MEDIA_TYPE,
Bundle,
BundleLatest,
BundleV01,
Expand Down Expand Up @@ -144,6 +146,11 @@ describe('public interface', () => {
expect(bundleToJSON).toBeDefined();
});

it('exports constants', () => {
expect(BUNDLE_V01_MEDIA_TYPE).toBeDefined();
expect(BUNDLE_V02_MEDIA_TYPE).toBeDefined();
});

it('exports errors', () => {
expect(ValidationError).toBeInstanceOf(Object);
});
Expand Down
4 changes: 2 additions & 2 deletions packages/bundle/src/__tests__/serialized.test.ts
Expand Up @@ -139,7 +139,7 @@ describe('bundleToJSON', () => {
expectedTlogEntry.integratedTime
);
expect(tlogEntry?.inclusionPromise).toBeTruthy();
expect(tlogEntry?.inclusionPromise.signedEntryTimestamp).toEqual(
expect(tlogEntry?.inclusionPromise?.signedEntryTimestamp).toEqual(
(
expectedTlogEntry.inclusionPromise?.signedEntryTimestamp as Buffer
).toString('base64')
Expand Down Expand Up @@ -260,7 +260,7 @@ describe('bundleToJSON', () => {
expectedTlogEntry.integratedTime
);
expect(tlogEntry?.inclusionPromise).toBeTruthy();
expect(tlogEntry?.inclusionPromise.signedEntryTimestamp).toEqual(
expect(tlogEntry?.inclusionPromise?.signedEntryTimestamp).toEqual(
(
expectedTlogEntry.inclusionPromise?.signedEntryTimestamp as Buffer
).toString('base64')
Expand Down
6 changes: 6 additions & 0 deletions packages/bundle/src/bundle.ts
Expand Up @@ -22,6 +22,12 @@ import type {
} from '@sigstore/protobuf-specs';
import type { WithRequired } from './utility';

export const BUNDLE_V01_MEDIA_TYPE =
'application/vnd.dev.sigstore.bundle+json;version=0.1';

export const BUNDLE_V02_MEDIA_TYPE =
'application/vnd.dev.sigstore.bundle+json;version=0.2';

// Extract types that are not explicitly defined in the protobuf specs.
type DsseEnvelopeContent = Extract<
ProtoBundle['content'],
Expand Down
2 changes: 2 additions & 0 deletions packages/bundle/src/index.ts
Expand Up @@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
export {
BUNDLE_V01_MEDIA_TYPE,
BUNDLE_V02_MEDIA_TYPE,
isBundleWithCertificateChain,
isBundleWithDsseEnvelope,
isBundleWithMessageSignature,
Expand Down
8 changes: 5 additions & 3 deletions packages/bundle/src/serialized.ts
Expand Up @@ -43,9 +43,11 @@ type SerializedTLogEntry = {
}
| undefined;
integratedTime: string;
inclusionPromise: {
signedEntryTimestamp: string;
};
inclusionPromise:
| {
signedEntryTimestamp: string;
}
| undefined;
inclusionProof:
| {
logIndex: string;
Expand Down
6 changes: 2 additions & 4 deletions packages/bundle/src/validate.ts
Expand Up @@ -13,6 +13,7 @@ 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.
*/
import { BUNDLE_V01_MEDIA_TYPE } from './bundle';
import { ValidationError } from './error';

import type { Bundle as ProtoBundle } from '@sigstore/protobuf-specs';
Expand Down Expand Up @@ -127,10 +128,7 @@ export function assertBundle(b: ProtoBundle): asserts b is Bundle {
export function assertBundleV01(b: Bundle): asserts b is BundleV01 {
const invalidValues: string[] = [];

if (
b.mediaType &&
b.mediaType !== 'application/vnd.dev.sigstore.bundle+json;version=0.1'
) {
if (b.mediaType && b.mediaType !== BUNDLE_V01_MEDIA_TYPE) {
invalidValues.push('mediaType');
}

Expand Down
32 changes: 32 additions & 0 deletions packages/client/src/__tests__/__fixtures__/bundles/v02/index.ts
@@ -0,0 +1,32 @@
/*
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.
*/
import crypto from 'crypto';
import signature from './signature';

export default { signature };

const tlogKey = crypto.createPublicKey(`-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwr
kBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==
-----END PUBLIC KEY-----`);

const tlogKeyID = crypto
.createHash('sha256')
.update(tlogKey.export({ format: 'der', type: 'spki' }))
.digest()
.toString('hex');

export const tlogKeys = { [tlogKeyID]: tlogKey };
166 changes: 166 additions & 0 deletions packages/client/src/__tests__/__fixtures__/bundles/v02/signature.ts
@@ -0,0 +1,166 @@
/*
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.
*/
///////////////////////////////////////////////////////////////////////////////
// VALID BUNDLES
///////////////////////////////////////////////////////////////////////////////

// Valid messageSignature bundle signed with a Fulcio signing certificate
const validBundleWithSigningCert = {
mediaType: 'application/vnd.dev.sigstore.bundle+json;version=0.2',
verificationMaterial: {
x509CertificateChain: {
certificates: [
{
rawBytes:
'MIICoDCCAiagAwIBAgIUevae+nLQ8mg6OyOB43MKJ10F2CEwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjIxMTA5MDEzMzA5WhcNMjIxMTA5MDE0MzA5WjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9DbYBIMQLtWb6J5gtL69jgRwwEfdtQtKvvG4+o3ZzlOroJplpXaVgF6wBDob++rNG9/AzSaBmApkEwI52XBjWqOCAUUwggFBMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUVIIFc08z6uV9Y96S+v5oDbbmHEYwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERYnJpYW5AZGVoYW1lci5jb20wLAYKKwYBBAGDvzABAQQeaHR0cHM6Ly9naXRodWIuY29tL2xvZ2luL29hdXRoMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGEWgUGQwAABAMARzBFAiEAlKycMBC2q+QM+mct60RNENxpURHes6vgOBWdx71XcXgCIAtnMzw/cBw5h0hrYJ8b1PJjoxn3k1N2TdgofqvMhbSTMAoGCCqGSM49BAMDA2gAMGUCMQC2KLFYSiD/+S1WEsyf9czf52w+E577Hi77r8pGUM1rQ/Bzg1aGvQs0/kAg3S/JSDgCMEdN5dIS0tRm1SOMbOFcW+1yzR+OiCVJ7DVFwUdI3D/7ERxtN9e/LJ6uaRnR/Sanrw==',
},
],
},
publicKey: undefined,
tlogEntries: [
{
logIndex: '6757503',
logId: { keyId: 'wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0=' },
kindVersion: { kind: 'hashedrekord', version: '0.0.1' },
integratedTime: '1667957590',
inclusionPromise: undefined,
inclusionProof: {
logIndex: '2594072',
rootHash: 'kAnoYYy8iB3NjC5tE2l6pGBqY3uw3CBJ6x2cBBQXu0U=',
treeSize: '22954907',
hashes: [
'qEpgYkIiW7jVzbHp54MraVJQ1AE72Zvr5XSohvcdBN4=',
'wtdXKmzwBO1Lr1bY5gOXpVUiP0OxYRRa9ZodfVYRKw8=',
'ikD2dl7XVH3EKAPc6k21SYog5TYdwp/8DayXZ8Eedtw=',
'3oHeiTXTqKZMOpundZhKh4c6dznt7SdFj88Gog5DCYY=',
'4By9NfYQqHZOn5CusfRqIGw9/NeQr5E1nG4ICulNnUo=',
'p3BgRy0uSg6SRAqcKt8qXUIDhhJhox1tCAIaHdT5tac=',
'lJvUc0jjih3wNA1S7cbtw1q5HYX3JxYY5fO9ytPIKLU=',
'5vWL6hRP9EBDNAuXS3E236YUwutNv6qvIWTfcdzywFA=',
'1ODC3wToc5Hqky2sJQ2w3mBFggDWdZROOAv4MXWWLw0=',
'QqwionvWKT5a3Kqsx1UWIYDsBIMK7H+pvKZNon1g4A4=',
'9Ckxujk8Sg094zTRpBWmwd4ZWNT7W72H/S2JPKbZiBY=',
'/gKT0/YRP2WbANUct+sWMGGQ2a9lQlNFBb/XYAhb/j8=',
'f+eeYNJFCZRAI6IKsab+xTmMUl9g6Km2h6KUztMHpxM=',
'P8eLjDLaNzX9cTdqiFIKYjyVJv4cNwxPBh1Ppg8eDvM=',
'7NR456rTv4HEGWxCwUOTYm7ze69yMkqG4f8MbhE43oU=',
'Ul2YswjUyBqbJ3eka2zE0MI0QxT4ez8sCJ1Z3+vvMw8=',
'ucRPSmGLhm/SyHL7chQ5vBEFull08HzsqtAC0TQ91tY=',
'EiS8ntcvGnB1xcGZg9Cf3fTkV1wBcJNVtSWKIYVZqAU=',
'Mx1LEx7szsPd62CGkL6HM+NWkOy9YwZTwukJEVgH7Cw=',
's2Z13KVYurVY6F1AUhr8Uby4RE3RXW1XEC2tWWdzCjI=',
'QRfYxLEHh/FwMZqWnxNNW+x3lY7o3LM86BW+z0MpMN4=',
'J0dGjQ7V5bETi7p7eWg2ephCQ32QBLMWY5HxFcuGfR4=',
'uFGzOQorMYmYZ2yumLpgr1tvXvZaL+tTTCqaXa7Hdds=',
'Lksw/hm/y+1p33SaEF8/60gPvFVNkueBpDWJ1tAVcAo=',
'o4Smg8NUiGzxKxvvvgjtH2NV82EZSBLcUDUo9IpzS0Y=',
],
checkpoint: {
envelope:
'rekor.sigstore.dev - 2605736670972794746\n22954907\nkAnoYYy8iB3NjC5tE2l6pGBqY3uw3CBJ6x2cBBQXu0U=\nTimestamp: 1689107716054191855\n\n— rekor.sigstore.dev wNI9ajBFAiEA8OpuifHq4iqd6ZJSRiVQbe00eTdZllaQ51fgfAVxAPkCIDC64vV4bCtkn3S8CyMaTHHWgD2E/a+nm0eFBADK/LFP\n',
},
},
canonicalizedBody:
'eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI2OGU2NTZiMjUxZTY3ZTgzNThiZWY4NDgzYWIwZDUxYzY2MTlmM2U3YTFhOWYwZTc1ODM4ZDQxZmYzNjhmNzI4In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FUUNJSHM1YVV1bHExSHBSK2Z3bVNLcExrL29Bd3E1TzlDRE5GSGhaQUtmRzVHbUFpQndjVm5mMm9ienNDR1ZsZjBBSXZidkhyMjFOWHQ3dHBMQmw0K0JyaDZPS0E9PSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTnZSRU5EUVdsaFowRjNTVUpCWjBsVlpYWmhaU3R1VEZFNGJXYzJUM2xQUWpRelRVdEtNVEJHTWtORmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcEplRTFVUVRWTlJFVjZUWHBCTlZkb1kwNU5ha2w0VFZSQk5VMUVSVEJOZWtFMVYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVU1UkdKWlFrbE5VVXgwVjJJMlNqVm5kRXcyT1dwblVuZDNSV1prZEZGMFMzWjJSelFLSzI4elducHNUM0p2U25Cc2NGaGhWbWRHTm5kQ1JHOWlLeXR5VGtjNUwwRjZVMkZDYlVGd2EwVjNTVFV5V0VKcVYzRlBRMEZWVlhkblowWkNUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZXU1VsR0NtTXdPSG8yZFZZNVdUazJVeXQyTlc5RVltSnRTRVZaZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1dXNUtjRmxYTlVGYVIxWnZXVmN4YkdOcE5XcGlNakIzVEVGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGbFlVaFNNR05JVFRaTWVUbHVZVmhTYjJSWFNYVlpNamwwVERKNGRsb3liSFZNTWpsb1pGaFNiMDFKUjB0Q1oyOXlRbWRGUlVGa1dqVkJaMUZEQ2tKSWQwVmxaMEkwUVVoWlFUTlVNSGRoYzJKSVJWUktha2RTTkdOdFYyTXpRWEZLUzFoeWFtVlFTek12YURSd2VXZERPSEEzYnpSQlFVRkhSVmRuVlVjS1VYZEJRVUpCVFVGU2VrSkdRV2xGUVd4TGVXTk5Ra015Y1N0UlRTdHRZM1EyTUZKT1JVNTRjRlZTU0dWek5uWm5UMEpYWkhnM01WaGpXR2REU1VGMGJncE5lbmN2WTBKM05XZ3dhSEpaU2poaU1WQkthbTk0YmpOck1VNHlWR1JuYjJaeGRrMW9ZbE5VVFVGdlIwTkRjVWRUVFRRNVFrRk5SRUV5WjBGTlIxVkRDazFSUXpKTFRFWlpVMmxFTHl0VE1WZEZjM2xtT1dONlpqVXlkeXRGTlRjM1NHazNOM0k0Y0VkVlRURnlVUzlDZW1jeFlVZDJVWE13TDJ0Qlp6TlRMMG9LVTBSblEwMUZaRTQxWkVsVE1IUlNiVEZUVDAxaVQwWmpWeXN4ZVhwU0swOXBRMVpLTjBSV1JuZFZaRWt6UkM4M1JWSjRkRTQ1WlM5TVNqWjFZVkp1VWdvdlUyRnVjbmM5UFFvdExTMHRMVVZPUkNCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2c9PSJ9fX19',
},
],
timestampVerificationData: { rfc3161Timestamps: [] },
},
messageSignature: {
messageDigest: {
algorithm: 'SHA2_256',
digest: 'aOZWslHmfoNYvvhIOrDVHGYZ8+ehqfDnWDjUH/No9yg=',
},
signature:
'MEQCIHs5aUulq1HpR+fwmSKpLk/oAwq5O9CDNFHhZAKfG5GmAiBwcVnf2obzsCGVlf0AIvbvHr21NXt7tpLBl4+Brh6OKA==',
},
dsseEnvelope: undefined,
};

// Valid messageSignature bundle signed with a public key
const validBundleWithPublicKey = {
mediaType: 'application/vnd.dev.sigstore.bundle+json;version=0.2',
verificationMaterial: {
publicKey: {
hint: '9a76331edc1cfd3933040996615b1c06adbe6f9b4f11df4106dcceb66e3bdb1b',
},
tlogEntries: [
{
logIndex: '6757503',
logId: { keyId: 'wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0=' },
kindVersion: { kind: 'hashedrekord', version: '0.0.1' },
integratedTime: '1667957590',
inclusionPromise: undefined,
inclusionProof: {
logIndex: '2594072',
rootHash: 'kAnoYYy8iB3NjC5tE2l6pGBqY3uw3CBJ6x2cBBQXu0U=',
treeSize: '22954907',
hashes: [
'qEpgYkIiW7jVzbHp54MraVJQ1AE72Zvr5XSohvcdBN4=',
'wtdXKmzwBO1Lr1bY5gOXpVUiP0OxYRRa9ZodfVYRKw8=',
'ikD2dl7XVH3EKAPc6k21SYog5TYdwp/8DayXZ8Eedtw=',
'3oHeiTXTqKZMOpundZhKh4c6dznt7SdFj88Gog5DCYY=',
'4By9NfYQqHZOn5CusfRqIGw9/NeQr5E1nG4ICulNnUo=',
'p3BgRy0uSg6SRAqcKt8qXUIDhhJhox1tCAIaHdT5tac=',
'lJvUc0jjih3wNA1S7cbtw1q5HYX3JxYY5fO9ytPIKLU=',
'5vWL6hRP9EBDNAuXS3E236YUwutNv6qvIWTfcdzywFA=',
'1ODC3wToc5Hqky2sJQ2w3mBFggDWdZROOAv4MXWWLw0=',
'QqwionvWKT5a3Kqsx1UWIYDsBIMK7H+pvKZNon1g4A4=',
'9Ckxujk8Sg094zTRpBWmwd4ZWNT7W72H/S2JPKbZiBY=',
'/gKT0/YRP2WbANUct+sWMGGQ2a9lQlNFBb/XYAhb/j8=',
'f+eeYNJFCZRAI6IKsab+xTmMUl9g6Km2h6KUztMHpxM=',
'P8eLjDLaNzX9cTdqiFIKYjyVJv4cNwxPBh1Ppg8eDvM=',
'7NR456rTv4HEGWxCwUOTYm7ze69yMkqG4f8MbhE43oU=',
'Ul2YswjUyBqbJ3eka2zE0MI0QxT4ez8sCJ1Z3+vvMw8=',
'ucRPSmGLhm/SyHL7chQ5vBEFull08HzsqtAC0TQ91tY=',
'EiS8ntcvGnB1xcGZg9Cf3fTkV1wBcJNVtSWKIYVZqAU=',
'Mx1LEx7szsPd62CGkL6HM+NWkOy9YwZTwukJEVgH7Cw=',
's2Z13KVYurVY6F1AUhr8Uby4RE3RXW1XEC2tWWdzCjI=',
'QRfYxLEHh/FwMZqWnxNNW+x3lY7o3LM86BW+z0MpMN4=',
'J0dGjQ7V5bETi7p7eWg2ephCQ32QBLMWY5HxFcuGfR4=',
'uFGzOQorMYmYZ2yumLpgr1tvXvZaL+tTTCqaXa7Hdds=',
'Lksw/hm/y+1p33SaEF8/60gPvFVNkueBpDWJ1tAVcAo=',
'o4Smg8NUiGzxKxvvvgjtH2NV82EZSBLcUDUo9IpzS0Y=',
],
checkpoint: {
envelope:
'rekor.sigstore.dev - 2605736670972794746\n22954907\nkAnoYYy8iB3NjC5tE2l6pGBqY3uw3CBJ6x2cBBQXu0U=\nTimestamp: 1689107716054191855\n\n— rekor.sigstore.dev wNI9ajBFAiEA8OpuifHq4iqd6ZJSRiVQbe00eTdZllaQ51fgfAVxAPkCIDC64vV4bCtkn3S8CyMaTHHWgD2E/a+nm0eFBADK/LFP\n',
},
},
canonicalizedBody:
'eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiI2OGU2NTZiMjUxZTY3ZTgzNThiZWY4NDgzYWIwZDUxYzY2MTlmM2U3YTFhOWYwZTc1ODM4ZDQxZmYzNjhmNzI4In19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FUUNJSHM1YVV1bHExSHBSK2Z3bVNLcExrL29Bd3E1TzlDRE5GSGhaQUtmRzVHbUFpQndjVm5mMm9ienNDR1ZsZjBBSXZidkhyMjFOWHQ3dHBMQmw0K0JyaDZPS0E9PSIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVTnZSRU5EUVdsaFowRjNTVUpCWjBsVlpYWmhaU3R1VEZFNGJXYzJUM2xQUWpRelRVdEtNVEJHTWtORmQwTm5XVWxMYjFwSmVtb3dSVUYzVFhjS1RucEZWazFDVFVkQk1WVkZRMmhOVFdNeWJHNWpNMUoyWTIxVmRWcEhWakpOVWpSM1NFRlpSRlpSVVVSRmVGWjZZVmRrZW1SSE9YbGFVekZ3WW01U2JBcGpiVEZzV2tkc2FHUkhWWGRJYUdOT1RXcEplRTFVUVRWTlJFVjZUWHBCTlZkb1kwNU5ha2w0VFZSQk5VMUVSVEJOZWtFMVYycEJRVTFHYTNkRmQxbElDa3R2V2tsNmFqQkRRVkZaU1V0dldrbDZhakJFUVZGalJGRm5RVVU1UkdKWlFrbE5VVXgwVjJJMlNqVm5kRXcyT1dwblVuZDNSV1prZEZGMFMzWjJSelFLSzI4elducHNUM0p2U25Cc2NGaGhWbWRHTm5kQ1JHOWlLeXR5VGtjNUwwRjZVMkZDYlVGd2EwVjNTVFV5V0VKcVYzRlBRMEZWVlhkblowWkNUVUUwUndwQk1WVmtSSGRGUWk5M1VVVkJkMGxJWjBSQlZFSm5UbFpJVTFWRlJFUkJTMEpuWjNKQ1owVkdRbEZqUkVGNlFXUkNaMDVXU0ZFMFJVWm5VVlZXU1VsR0NtTXdPSG8yZFZZNVdUazJVeXQyTlc5RVltSnRTRVZaZDBoM1dVUldVakJxUWtKbmQwWnZRVlV6T1ZCd2VqRlphMFZhWWpWeFRtcHdTMFpYYVhocE5Ga0tXa1E0ZDBoM1dVUldVakJTUVZGSUwwSkNWWGRGTkVWU1dXNUtjRmxYTlVGYVIxWnZXVmN4YkdOcE5XcGlNakIzVEVGWlMwdDNXVUpDUVVkRWRucEJRZ3BCVVZGbFlVaFNNR05JVFRaTWVUbHVZVmhTYjJSWFNYVlpNamwwVERKNGRsb3liSFZNTWpsb1pGaFNiMDFKUjB0Q1oyOXlRbWRGUlVGa1dqVkJaMUZEQ2tKSWQwVmxaMEkwUVVoWlFUTlVNSGRoYzJKSVJWUktha2RTTkdOdFYyTXpRWEZLUzFoeWFtVlFTek12YURSd2VXZERPSEEzYnpSQlFVRkhSVmRuVlVjS1VYZEJRVUpCVFVGU2VrSkdRV2xGUVd4TGVXTk5Ra015Y1N0UlRTdHRZM1EyTUZKT1JVNTRjRlZTU0dWek5uWm5UMEpYWkhnM01WaGpXR2REU1VGMGJncE5lbmN2WTBKM05XZ3dhSEpaU2poaU1WQkthbTk0YmpOck1VNHlWR1JuYjJaeGRrMW9ZbE5VVFVGdlIwTkRjVWRUVFRRNVFrRk5SRUV5WjBGTlIxVkRDazFSUXpKTFRFWlpVMmxFTHl0VE1WZEZjM2xtT1dONlpqVXlkeXRGTlRjM1NHazNOM0k0Y0VkVlRURnlVUzlDZW1jeFlVZDJVWE13TDJ0Qlp6TlRMMG9LVTBSblEwMUZaRTQxWkVsVE1IUlNiVEZUVDAxaVQwWmpWeXN4ZVhwU0swOXBRMVpLTjBSV1JuZFZaRWt6UkM4M1JWSjRkRTQ1WlM5TVNqWjFZVkp1VWdvdlUyRnVjbmM5UFFvdExTMHRMVVZPUkNCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2c9PSJ9fX19',
},
],
timestampVerificationData: { rfc3161Timestamps: [] },
},
messageSignature: {
messageDigest: {
algorithm: 'SHA2_256',
digest: 'aOZWslHmfoNYvvhIOrDVHGYZ8+ehqfDnWDjUH/No9yg=',
},
signature:
'MEQCIHs5aUulq1HpR+fwmSKpLk/oAwq5O9CDNFHhZAKfG5GmAiBwcVnf2obzsCGVlf0AIvbvHr21NXt7tpLBl4+Brh6OKA==',
},
};

export default {
artifact: Buffer.from('hello, world!'),
valid: {
withSigningCert: validBundleWithSigningCert,
withPublicKey: validBundleWithPublicKey,
},
invalid: {},
};
2 changes: 1 addition & 1 deletion packages/client/src/__tests__/ca/verify/index.test.ts
Expand Up @@ -16,7 +16,7 @@ limitations under the License.
import { bundleFromJSON, BundleWithCertificateChain } from '@sigstore/bundle';
import { verifySigningCertificate } from '../../../ca/verify';
import * as sigstore from '../../../types/sigstore';
import bundles from '../../__fixtures__/bundles/';
import bundles from '../../__fixtures__/bundles/v01';
import { trustedRoot } from '../../__fixtures__/trust';

describe('verifySigningCertificate', () => {
Expand Down
28 changes: 27 additions & 1 deletion packages/client/src/__tests__/sigstore.test.ts
Expand Up @@ -29,7 +29,8 @@ import mocktuf, { Target } from '@tufjs/repo-mock';
import { PolicyError, VerificationError } from '../error';
import { Signer } from '../sign';
import { attest, createVerifier, sign, tuf, verify } from '../sigstore';
import bundles from './__fixtures__/bundles';
import bundles from './__fixtures__/bundles/v01';
import bundlesV02 from './__fixtures__/bundles/v02';
import { trustedRoot } from './__fixtures__/trust';

import type { TUFOptions, VerifyOptions } from '../config';
Expand Down Expand Up @@ -318,6 +319,31 @@ describe('#verify', () => {
);
});
});

describe('when the bundle is a v0.2 bundle', () => {
const bundle = bundlesV02.signature.valid.withSigningCert;
const artifact = bundlesV02.signature.artifact;

it('does not throw an error', async () => {
await expect(verify(bundle, artifact, tufOptions)).resolves.toBe(
undefined
);
});
});

describe('when the bundle is newer then v0.2', () => {
// Check a theoretical v0.3 bundle that is the same shape as a v0.2 bundle
const bundle = { ...bundlesV02.signature.valid.withSigningCert };
bundle.mediaType = 'application/vnd.dev.sigstore.bundle+json;version=0.3';

const artifact = bundlesV02.signature.artifact;

it('does not throw an error', async () => {
await expect(verify(bundle, artifact, tufOptions)).resolves.toBe(
undefined
);
});
});
});

describe('#createVerifier', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/__tests__/tlog/verify/body.test.ts
Expand Up @@ -15,7 +15,7 @@ limitations under the License.
*/
import { bundleFromJSON, TransparencyLogEntry } from '@sigstore/bundle';
import { verifyTLogBody } from '../../../tlog/verify/body';
import bundles from '../../__fixtures__/bundles';
import bundles from '../../__fixtures__/bundles/v01';

describe('verifyTLogBody', () => {
describe('when a message signature bundle is provided', () => {
Expand Down

0 comments on commit f1b8bad

Please sign in to comment.