Skip to content

Commit 03db716

Browse files
committed
Add Rekor v2 support to bundle reader and writer
Signed-off-by: Aaron Lew <[email protected]>
1 parent 0438cdc commit 03db716

File tree

4 files changed

+65
-17
lines changed

4 files changed

+65
-17
lines changed

sigstore-java/src/main/java/dev/sigstore/bundle/BundleReader.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,15 @@ static Bundle readBundle(Reader jsonReader) throws BundleParseException {
7373
.collect(Collectors.toList()))
7474
.build();
7575

76-
var verification =
77-
ImmutableVerification.builder()
78-
.signedEntryTimestamp(
79-
Base64.getEncoder()
80-
.encodeToString(
81-
bundleEntry
82-
.getInclusionPromise()
83-
.getSignedEntryTimestamp()
84-
.toByteArray()))
85-
.inclusionProof(inclusionProof)
86-
.build();
76+
var verificationBuilder = ImmutableVerification.builder().inclusionProof(inclusionProof);
77+
if (bundleEntry.hasInclusionPromise()
78+
&& !bundleEntry.getInclusionPromise().getSignedEntryTimestamp().isEmpty()) {
79+
verificationBuilder.signedEntryTimestamp(
80+
Base64.getEncoder()
81+
.encodeToString(
82+
bundleEntry.getInclusionPromise().getSignedEntryTimestamp().toByteArray()));
83+
}
84+
var verification = verificationBuilder.build();
8785

8886
var rekorEntry =
8987
ImmutableRekorEntry.builder()

sigstore-java/src/main/java/dev/sigstore/bundle/BundleWriter.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ static String writeBundle(Bundle signingResult) {
5353
try {
5454
String jsonBundle = JSON_PRINTER.print(bundle);
5555
List<String> missingFields = BundleVerifier.findMissingFields(bundle);
56+
// TODO(#1018): Update handling of integrated_time once it becomes an optional field
57+
// integrated_time is a required field in the Bundle spec
58+
missingFields.removeIf(f -> f.endsWith("integrated_time"));
5659
if (!missingFields.isEmpty()) {
5760
throw new IllegalStateException(
5861
"Some of the fields were not initialized: "
@@ -128,13 +131,15 @@ private static TransparencyLogEntry.Builder buildTlogEntries(RekorEntry entry) {
128131
.setKind(entry.getBodyDecoded().getKind())
129132
.setVersion(entry.getBodyDecoded().getApiVersion()))
130133
.setIntegratedTime(entry.getIntegratedTime())
131-
.setInclusionPromise(
132-
InclusionPromise.newBuilder()
133-
.setSignedEntryTimestamp(
134-
ByteString.copyFrom(
135-
Base64.getDecoder()
136-
.decode(entry.getVerification().getSignedEntryTimestamp()))))
137134
.setCanonicalizedBody(ByteString.copyFrom(Base64.getDecoder().decode(entry.getBody())));
135+
if (entry.getVerification().getSignedEntryTimestamp() != null) {
136+
transparencyLogEntry.setInclusionPromise(
137+
InclusionPromise.newBuilder()
138+
.setSignedEntryTimestamp(
139+
ByteString.copyFrom(
140+
Base64.getDecoder()
141+
.decode(entry.getVerification().getSignedEntryTimestamp()))));
142+
}
138143
addInclusionProof(transparencyLogEntry, entry);
139144
return transparencyLogEntry;
140145
}

sigstore-java/src/test/java/dev/sigstore/bundle/BundleReaderTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ public void readBundle_timestamp() throws Exception {
9292
readBundle("dev/sigstore/samples/bundles/bundle-with-timestamp.sigstore");
9393
}
9494

95+
@Test
96+
public void readBundle_rekorV2Entry() throws Exception {
97+
readBundle("dev/sigstore/samples/bundles/bundle-with-rekor-v2-entry.sigstore");
98+
}
99+
95100
private Bundle readBundle(String resourcePath) throws Exception {
96101
try (var reader =
97102
new InputStreamReader(
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"mediaType": "application/vnd.dev.sigstore.bundle.v0.3+json",
3+
"verificationMaterial": {
4+
"tlogEntries": [{
5+
"logIndex": "4423",
6+
"logId": {
7+
"keyId": "8w1amZ2S5mJIQkQmPxdMuOrL/oJkvFg9MnQXmeOCXck="
8+
},
9+
"kindVersion": {
10+
"kind": "hashedrekord",
11+
"version": "0.0.2"
12+
},
13+
"inclusionProof": {
14+
"logIndex": "4423",
15+
"rootHash": "vz8cWrY7CxbLJb3KSgqqhJ36LYWBmsHQIosDW+jz6Mo=",
16+
"treeSize": "4424",
17+
"hashes": ["NTHGhFLQsx1sNpRFYsL8ojXorva801HqWY0VmFcOdG8=", "mNYKGdHB92+dfYqbxAaAmAEwJionRJRIJkp9Hd9qAEI=", "7Z5SW5fiCoeni4AiOaxH29+fy/yHvxoJs0NIgr4205Y=", "pnfrCn+zMIndV2oSiVJgUwDUl877+tscVelEn8ocmCg=", "Y9dHtdFhpgfmulbHFbY0lA3Gy3QJof82auCf/EoYppU=", "xbDsGnxf1siByWHEuiK85p0reQCaKKWUjf8YNl9s/Vo="],
18+
"checkpoint": {
19+
"envelope": "log2025-alpha1.rekor.sigstage.dev\n4424\nvz8cWrY7CxbLJb3KSgqqhJ36LYWBmsHQIosDW+jz6Mo\u003d\n\n— log2025-alpha1.rekor.sigstage.dev 8w1ambRbXNoVP7oYsfLKBZszx0NESaWaSswYn/enUk/olcaQjGuCTmN8GheotGFBLvbP+QcswGIIyDOJPyHYoVODCw4\u003d\n"
20+
}
21+
},
22+
"canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJoYXNoZWRSZWtvcmRWMDAyIjp7ImRhdGEiOnsiYWxnb3JpdGhtIjoiU0hBMl8yNTYiLCJkaWdlc3QiOiJvTS9IRW5IVzRuamxmTk15LzVWOFAzQkQvZG8xVEV5N0dRb3cxVzc2QWI4PSJ9LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FVUNJUUQySHFTd0NTOFRSSndCc0V5TWhrN3Z4MlhQWWZRQ3hLSzJkc0lMclhEd0NRSWdGL2tRUEdIMHlRcVNIODZVa1pBYTFoYmhFWFZlZXAwZWx4S0ZoNDNUV05FPSIsInZlcmlmaWVyIjp7ImtleURldGFpbHMiOiJQS0lYX0VDRFNBX1AyNTZfU0hBXzI1NiIsIng1MDlDZXJ0aWZpY2F0ZSI6eyJyYXdCeXRlcyI6Ik1JSUN6RENDQWxLZ0F3SUJBZ0lVQzl3aGd6STI0aytuR2xWRm1OL3I2cEc5NXBRd0NnWUlLb1pJemowRUF3TXdOekVWTUJNR0ExVUVDaE1NYzJsbmMzUnZjbVV1WkdWMk1SNHdIQVlEVlFRREV4VnphV2R6ZEc5eVpTMXBiblJsY20xbFpHbGhkR1V3SGhjTk1qVXdOekF5TVRnMU1UVXdXaGNOTWpVd056QXlNVGt3TVRVd1dqQUFNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVoaDl3c3A0OUdhMlY3emJlV0FwNXN5L243RUliaWhuQm8vb3B0N2pnWVBuZ3EyMCttYjZkb3FJR0x3OXdKbkRmRkFIeFdSMmtTdS95SmNPalZTZ1B6YU9DQVhFd2dnRnRNQTRHQTFVZER3RUIvd1FFQXdJSGdEQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBekFkQmdOVkhRNEVGZ1FVZFJ2UDRlVG5BY0ozNHZYK2t3Tk1YYW5EOUNrd0h3WURWUjBqQkJnd0ZvQVVjWVl3cGhSOFltLzU5OWIwQlJwL1gvL3JiNnd3SVFZRFZSMFJBUUgvQkJjd0ZZRVRZV0Z5YjI1c1pYZEFaMjl2WjJ4bExtTnZiVEFwQmdvckJnRUVBWU8vTUFFQkJCdG9kSFJ3Y3pvdkwyRmpZMjkxYm5SekxtZHZiMmRzWlM1amIyMHdLd1lLS3dZQkJBR0R2ekFCQ0FRZERCdG9kSFJ3Y3pvdkwyRmpZMjkxYm5SekxtZHZiMmRzWlM1amIyMHdnWW9HQ2lzR0FRUUIxbmtDQkFJRWZBUjZBSGdBZGdBck1MemNhSWpKNHVIWUppbGVkQjlJT1RHV0F2S2NNOHRlUTBEK3NxeUdlZ0FBQVpmTWV5RlVBQUFFQXdCSE1FVUNJSE1RNHgzelBnTWpjWnV1dUxNQmFSYTlSL05HM1JqUTlJazV1cHd3MWJ4a0FpRUFpYzBYcUd0RUtpa1pndkRWRmRYeDgxSXhTQlUzQXdRMWIwOXppQzczcjQwd0NnWUlLb1pJemowRUF3TURhQUF3WlFJd1RqMXJmVjlsK0JGOEhWRXd5Z05COHhPSlEzVDJyVktSSkR1dU1adTBUUlcrNUI0Z1pBSmdGcGltdzZ4QU9UZ25BakVBcGRkcnJXRHRHbHV2K0ZlWkhGcWNsaFZ6OEVHK0pOd0NEc2dFdjdHTU9DTjhON05VWjNzVDZ6T1VCaEZjUmJuOSJ9fX19fX0="
23+
}],
24+
"timestampVerificationData": {
25+
"rfc3161Timestamps": [{
26+
"signedTimestamp": "MIIC1DADAgEAMIICywYJKoZIhvcNAQcCoIICvDCCArgCAQMxDTALBglghkgBZQMEAgEwgcIGCyqGSIb3DQEJEAEEoIGyBIGvMIGsAgEBBgkrBgEEAYO/MAIwMTANBglghkgBZQMEAgEFAAQgtF/jtMHzKroX8UjkT/BViNcIlC5Y7za/y4n5cjasXD0CFQCxAdEfFrtmTuy4mcW7QjLeeOAUXhgPMjAyNTA3MDIxODUxNTFaMAMCAQECCE0pZTAXtl1eoDKkMDAuMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxFTATBgNVBAMTDHNpZ3N0b3JlLXRzYaAAMYIB2zCCAdcCAQEwUTA5MRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxIDAeBgNVBAMTF3NpZ3N0b3JlLXRzYS1zZWxmc2lnbmVkAhQKNaEGYdXiQXPGiZan8n3yfgN8pzALBglghkgBZQMEAgGggfwwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNTA3MDIxODUxNTFaMC8GCSqGSIb3DQEJBDEiBCCiICYObTnM098xx9niiVyPo+gxp4FTvN94z4K6gH/LgjCBjgYLKoZIhvcNAQkQAi8xfzB9MHsweQQgBvT/4Ef+s1mZtzOw16MjUBz8GOTAM2aoRdd1NudLJ0QwVTA9pDswOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZAIUCjWhBmHV4kFzxomWp/J98n4DfKcwCgYIKoZIzj0EAwIEZzBlAjB0/hfB4Hm4GO5SZYuDzCtgnNdXQkETtx/QTtILM09awUdez2kQNmCAkLtPBf8ojB8CMQDfRBy5WNohfrWNDh0o+NBR7Yj67vsUyBS1WK5nT5QatouJQ3PbtSJN3Kk8xsiVxFc="
27+
}]
28+
},
29+
"certificate": {
30+
"rawBytes": "MIICzDCCAlKgAwIBAgIUC9whgzI24k+nGlVFmN/r6pG95pQwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUwNzAyMTg1MTUwWhcNMjUwNzAyMTkwMTUwWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhh9wsp49Ga2V7zbeWAp5sy/n7EIbihnBo/opt7jgYPngq20+mb6doqIGLw9wJnDfFAHxWR2kSu/yJcOjVSgPzaOCAXEwggFtMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUdRvP4eTnAcJ34vX+kwNMXanD9CkwHwYDVR0jBBgwFoAUcYYwphR8Ym/599b0BRp/X//rb6wwIQYDVR0RAQH/BBcwFYETYWFyb25sZXdAZ29vZ2xlLmNvbTApBgorBgEEAYO/MAEBBBtodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20wKwYKKwYBBAGDvzABCAQdDBtodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20wgYoGCisGAQQB1nkCBAIEfAR6AHgAdgArMLzcaIjJ4uHYJiledB9IOTGWAvKcM8teQ0D+sqyGegAAAZfMeyFUAAAEAwBHMEUCIHMQ4x3zPgMjcZuuuLMBaRa9R/NG3RjQ9Ik5upww1bxkAiEAic0XqGtEKikZgvDVFdXx81IxSBU3AwQ1b09ziC73r40wCgYIKoZIzj0EAwMDaAAwZQIwTj1rfV9l+BF8HVEwygNB8xOJQ3T2rVKRJDuuMZu0TRW+5B4gZAJgFpimw6xAOTgnAjEApddrrWDtGluv+FeZHFqclhVz8EG+JNwCDsgEv7GMOCN8N7NUZ3sT6zOUBhFcRbn9"
31+
}
32+
},
33+
"messageSignature": {
34+
"messageDigest": {
35+
"algorithm": "SHA2_256",
36+
"digest": "oM/HEnHW4njlfNMy/5V8P3BD/do1TEy7GQow1W76Ab8="
37+
},
38+
"signature": "MEUCIQD2HqSwCS8TRJwBsEyMhk7vx2XPYfQCxKK2dsILrXDwCQIgF/kQPGH0yQqSH86UkZAa1hbhEXVeep0elxKFh43TWNE="
39+
}
40+
}

0 commit comments

Comments
 (0)