Skip to content

Commit 5412beb

Browse files
authored
Merge pull request #1201 from sigstore/ts-algo-reg
Ts algo reg
2 parents 3ad519c + 25204fe commit 5412beb

8 files changed

Lines changed: 96 additions & 85 deletions

File tree

sigstore-java/src/main/java/dev/sigstore/KeylessSigner.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
import dev.sigstore.rekor.client.RekorVerifier;
6060
import dev.sigstore.rekor.v2.client.RekorV2Client;
6161
import dev.sigstore.rekor.v2.client.RekorV2ClientHttp;
62-
import dev.sigstore.timestamp.client.HashAlgorithm;
6362
import dev.sigstore.timestamp.client.ImmutableTimestampRequest;
6463
import dev.sigstore.timestamp.client.TimestampClient;
6564
import dev.sigstore.timestamp.client.TimestampClientHttp;
@@ -472,7 +471,7 @@ public List<Bundle> sign(List<byte[]> artifactDigests) throws KeylessSignerExcep
472471

473472
var tsReq =
474473
ImmutableTimestampRequest.builder()
475-
.hashAlgorithm(HashAlgorithm.from(signingAlgorithm.getHashAlgorithm()))
474+
.hashAlgorithm(signingAlgorithm.getHashAlgorithm())
476475
.hash(signatureDigest)
477476
.build();
478477

@@ -804,7 +803,7 @@ public Bundle attest(String payload) throws KeylessSignerException {
804803

805804
var tsReq =
806805
ImmutableTimestampRequest.builder()
807-
.hashAlgorithm(HashAlgorithm.from(signingAlgorithm.getHashAlgorithm()))
806+
.hashAlgorithm(signingAlgorithm.getHashAlgorithm())
808807
.hash(signatureDigest)
809808
.build();
810809

sigstore-java/src/main/java/dev/sigstore/timestamp/client/HashAlgorithm.java

Lines changed: 22 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,53 +16,38 @@
1616
package dev.sigstore.timestamp.client;
1717

1818
import dev.sigstore.AlgorithmRegistry;
19+
import dev.sigstore.UnsupportedAlgorithmException;
1920
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
2021
import org.bouncycastle.tsp.TSPAlgorithms;
2122

2223
/** Supported hash algorithms for timestamp requests. */
23-
public enum HashAlgorithm {
24-
SHA256("SHA256", TSPAlgorithms.SHA256),
25-
SHA384("SHA384", TSPAlgorithms.SHA384),
26-
SHA512("SHA512", TSPAlgorithms.SHA512);
24+
public class HashAlgorithm {
25+
private HashAlgorithm() {}
2726

28-
private final String algorithmName;
29-
private final ASN1ObjectIdentifier oid;
30-
31-
HashAlgorithm(String algorithmName, ASN1ObjectIdentifier oid) {
32-
this.algorithmName = algorithmName;
33-
this.oid = oid;
34-
}
35-
36-
public String getAlgorithmName() {
37-
return algorithmName;
38-
}
39-
40-
public ASN1ObjectIdentifier getOid() {
41-
return oid;
42-
}
43-
44-
public static HashAlgorithm from(ASN1ObjectIdentifier oid)
45-
throws UnsupportedHashAlgorithmException {
46-
for (HashAlgorithm value : values()) {
47-
if (value.getOid().equals(oid)) {
48-
return value;
49-
}
50-
}
51-
throw new UnsupportedHashAlgorithmException(oid.getId());
52-
}
53-
54-
// this is just temporary to avoid messing with the timestamp package too much while we
55-
// transition, this enum
56-
// should really just be using AlgorithmRegistry as much as possible
57-
public static HashAlgorithm from(AlgorithmRegistry.HashAlgorithm hashAlgorithm) {
27+
public static ASN1ObjectIdentifier toOid(AlgorithmRegistry.HashAlgorithm hashAlgorithm) {
5828
switch (hashAlgorithm) {
5929
case SHA2_256:
60-
return SHA256;
30+
return TSPAlgorithms.SHA256;
6131
case SHA2_384:
62-
return SHA384;
32+
return TSPAlgorithms.SHA384;
6333
case SHA2_512:
64-
return SHA512;
34+
return TSPAlgorithms.SHA512;
6535
}
6636
throw new IllegalArgumentException();
6737
}
38+
39+
public static AlgorithmRegistry.HashAlgorithm fromOid(ASN1ObjectIdentifier oid)
40+
throws UnsupportedAlgorithmException {
41+
if (oid.equals(TSPAlgorithms.SHA256)) {
42+
return AlgorithmRegistry.HashAlgorithm.SHA2_256;
43+
}
44+
if (oid.equals(TSPAlgorithms.SHA384)) {
45+
return AlgorithmRegistry.HashAlgorithm.SHA2_384;
46+
}
47+
if (oid.equals(TSPAlgorithms.SHA512)) {
48+
return AlgorithmRegistry.HashAlgorithm.SHA2_512;
49+
}
50+
throw new UnsupportedAlgorithmException(
51+
"Unsupported timestamp hashing algorithm oid: " + oid.getId());
52+
}
6853
}

sigstore-java/src/main/java/dev/sigstore/timestamp/client/TimestampClientHttp.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public TimestampResponse timestamp(TimestampRequest tsReq) throws TimestampExcep
8181
TimeStampRequestGenerator bcTsReqGen = new TimeStampRequestGenerator();
8282

8383
// Prepare and send the timestamp request
84-
var bcAlgorithmOid = tsReq.getHashAlgorithm().getOid();
84+
var bcAlgorithmOid = HashAlgorithm.toOid(tsReq.getHashAlgorithm());
8585
var artifactHashBytes = tsReq.getHash();
8686
var nonce = tsReq.getNonce();
8787
bcTsReqGen.setCertReq(tsReq.requestCertificates());

sigstore-java/src/main/java/dev/sigstore/timestamp/client/TimestampRequest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package dev.sigstore.timestamp.client;
1717

18+
import dev.sigstore.AlgorithmRegistry;
1819
import java.math.BigInteger;
1920
import java.security.SecureRandom;
2021
import org.immutables.value.Value;
@@ -23,7 +24,7 @@
2324
@Immutable
2425
public interface TimestampRequest {
2526
/** The hash algorithm used to hash the artifact. */
26-
HashAlgorithm getHashAlgorithm();
27+
AlgorithmRegistry.HashAlgorithm getHashAlgorithm();
2728

2829
/**
2930
* The hash of the artifact to be timestamped. For sigstore-java, this typically refers to the

sigstore-java/src/main/java/dev/sigstore/timestamp/client/TimestampVerifier.java

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
*/
1616
package dev.sigstore.timestamp.client;
1717

18-
import com.google.common.hash.Hashing;
18+
import dev.sigstore.AlgorithmRegistry;
19+
import dev.sigstore.UnsupportedAlgorithmException;
20+
import dev.sigstore.encryption.Hashers;
1921
import dev.sigstore.encryption.certificates.Certificates;
2022
import dev.sigstore.trustroot.CertificateAuthority;
2123
import dev.sigstore.trustroot.SigstoreTrustedRoot;
@@ -147,26 +149,13 @@ public void verify(TimestampResponse tsResp, byte[] artifact)
147149

148150
// Validate the message imprint digest in the token
149151
var oid = tsToken.getTimeStampInfo().getMessageImprintAlgOID();
150-
HashAlgorithm hashAlgorithm;
152+
AlgorithmRegistry.HashAlgorithm hashAlgorithm;
151153
try {
152-
hashAlgorithm = HashAlgorithm.from(oid);
153-
} catch (UnsupportedHashAlgorithmException e) {
154+
hashAlgorithm = HashAlgorithm.fromOid(oid);
155+
} catch (UnsupportedAlgorithmException e) {
154156
throw new TimestampVerificationException(e);
155157
}
156-
byte[] artifactDigest;
157-
switch (hashAlgorithm) {
158-
case SHA256:
159-
artifactDigest = Hashing.sha256().hashBytes(artifact).asBytes();
160-
break;
161-
case SHA384:
162-
artifactDigest = Hashing.sha384().hashBytes(artifact).asBytes();
163-
break;
164-
case SHA512:
165-
artifactDigest = Hashing.sha512().hashBytes(artifact).asBytes();
166-
break;
167-
default:
168-
throw new IllegalStateException(); // We shouldn't be here.
169-
}
158+
byte[] artifactDigest = Hashers.from(hashAlgorithm).hashBytes(artifact).asBytes();
170159
validateTokenMessageImprintDigest(tsToken, artifactDigest);
171160
}
172161

sigstore-java/src/main/java/dev/sigstore/timestamp/client/UnsupportedHashAlgorithmException.java

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2026 The Sigstore Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package dev.sigstore.timestamp.client;
17+
18+
import static org.junit.jupiter.api.Assertions.assertEquals;
19+
import static org.junit.jupiter.api.Assertions.assertThrows;
20+
21+
import dev.sigstore.AlgorithmRegistry;
22+
import dev.sigstore.UnsupportedAlgorithmException;
23+
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
24+
import org.bouncycastle.tsp.TSPAlgorithms;
25+
import org.junit.jupiter.api.Test;
26+
27+
public class HashAlgorithmTest {
28+
29+
@Test
30+
public void toOid_success() {
31+
assertEquals(
32+
TSPAlgorithms.SHA256, HashAlgorithm.toOid(AlgorithmRegistry.HashAlgorithm.SHA2_256));
33+
assertEquals(
34+
TSPAlgorithms.SHA384, HashAlgorithm.toOid(AlgorithmRegistry.HashAlgorithm.SHA2_384));
35+
assertEquals(
36+
TSPAlgorithms.SHA512, HashAlgorithm.toOid(AlgorithmRegistry.HashAlgorithm.SHA2_512));
37+
}
38+
39+
@Test
40+
public void fromOid_success() throws Exception {
41+
assertEquals(
42+
AlgorithmRegistry.HashAlgorithm.SHA2_256, HashAlgorithm.fromOid(TSPAlgorithms.SHA256));
43+
assertEquals(
44+
AlgorithmRegistry.HashAlgorithm.SHA2_384, HashAlgorithm.fromOid(TSPAlgorithms.SHA384));
45+
assertEquals(
46+
AlgorithmRegistry.HashAlgorithm.SHA2_512, HashAlgorithm.fromOid(TSPAlgorithms.SHA512));
47+
}
48+
49+
@Test
50+
public void fromOid_unsupported() {
51+
ASN1ObjectIdentifier unsupportedOid = new ASN1ObjectIdentifier("1.2.840.113549.2.5"); // MD5 OID
52+
UnsupportedAlgorithmException exception =
53+
assertThrows(
54+
UnsupportedAlgorithmException.class, () -> HashAlgorithm.fromOid(unsupportedOid));
55+
assertEquals(
56+
"Unsupported timestamp hashing algorithm oid: 1.2.840.113549.2.5", exception.getMessage());
57+
}
58+
}

sigstore-java/src/test/java/dev/sigstore/timestamp/client/TimestampClientHttpTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static org.junit.jupiter.api.Assertions.assertThrows;
2222
import static org.junit.jupiter.api.Assertions.assertTrue;
2323

24+
import dev.sigstore.AlgorithmRegistry;
2425
import dev.sigstore.trustroot.Service;
2526
import dev.sigstore.tuf.SigstoreTufClient;
2627
import java.nio.charset.StandardCharsets;
@@ -45,7 +46,7 @@ public static void setup() throws Exception {
4546
tsReq =
4647
ImmutableTimestampRequest.builder()
4748
.hash(artifactHashBytes)
48-
.hashAlgorithm(HashAlgorithm.SHA256)
49+
.hashAlgorithm(AlgorithmRegistry.HashAlgorithm.SHA2_256)
4950
.build();
5051
}
5152

@@ -74,7 +75,7 @@ public void timestamp_success() throws Exception {
7475

7576
assertEquals(tsReq.getNonce(), tsInfo.getNonce());
7677

77-
var expectedOid = tsReq.getHashAlgorithm().getOid();
78+
var expectedOid = HashAlgorithm.toOid(tsReq.getHashAlgorithm());
7879
assertEquals(expectedOid, tsInfo.getMessageImprintAlgOID());
7980
}
8081

@@ -83,7 +84,7 @@ public void timestamp_failure_badResponse_incorrectDigestLength() throws Excepti
8384
var tsReqWithIncorrectDigestLength =
8485
ImmutableTimestampRequest.builder()
8586
.hash(tsReq.getHash())
86-
.hashAlgorithm(HashAlgorithm.SHA512)
87+
.hashAlgorithm(AlgorithmRegistry.HashAlgorithm.SHA2_512)
8788
.nonce(tsReq.getNonce())
8889
.build();
8990

0 commit comments

Comments
 (0)