diff --git a/sigstore-java/src/main/java/dev/sigstore/KeylessSigner.java b/sigstore-java/src/main/java/dev/sigstore/KeylessSigner.java index 134f52e1..f140d603 100644 --- a/sigstore-java/src/main/java/dev/sigstore/KeylessSigner.java +++ b/sigstore-java/src/main/java/dev/sigstore/KeylessSigner.java @@ -378,12 +378,9 @@ private void renewSigningCertificate() // check if we have an allow list and if so, ensure the provided token is in there if (!oidcIdentities.isEmpty()) { - var obtainedToken = OidcIdentity.from(tokenInfo); - if (!oidcIdentities.contains(OidcIdentity.from(tokenInfo))) { + if (oidcIdentities.stream().noneMatch(id -> id.matches(tokenInfo))) { throw new KeylessSignerException( - "Obtained Oidc Token " - + obtainedToken - + " does not match any identities in allow list"); + "Obtained Oidc Token " + tokenInfo + " does not match any identities in allow list"); } } diff --git a/sigstore-java/src/main/java/dev/sigstore/OidcIdentity.java b/sigstore-java/src/main/java/dev/sigstore/OidcIdentity.java index 5e6996bc..84a813a3 100644 --- a/sigstore-java/src/main/java/dev/sigstore/OidcIdentity.java +++ b/sigstore-java/src/main/java/dev/sigstore/OidcIdentity.java @@ -16,25 +16,26 @@ package dev.sigstore; import dev.sigstore.oidc.client.OidcToken; +import dev.sigstore.strings.StringMatcher; +import org.immutables.value.Value.Default; import org.immutables.value.Value.Immutable; @Immutable public interface OidcIdentity { - static OidcIdentity of(String identity, String issuer) { + static OidcIdentity of(StringMatcher identity, StringMatcher issuer) { return ImmutableOidcIdentity.builder().identity(identity).issuer(issuer).build(); } - static OidcIdentity from(OidcToken oidcToken) { - return ImmutableOidcIdentity.builder() - .identity(oidcToken.getSubjectAlternativeName()) - .issuer(oidcToken.getIssuer()) - .build(); + @Default + default boolean matches(OidcToken oidcToken) { + return getIdentity().test(oidcToken.getSubjectAlternativeName()) + && getIssuer().test(oidcToken.getIssuer()); } /** The user or machineId. */ - String getIdentity(); + StringMatcher getIdentity(); /** The oidc issuing authority */ - String getIssuer(); + StringMatcher getIssuer(); } diff --git a/sigstore-java/src/main/java/dev/sigstore/oidc/client/OidcToken.java b/sigstore-java/src/main/java/dev/sigstore/oidc/client/OidcToken.java index e82fe323..546ef22a 100644 --- a/sigstore-java/src/main/java/dev/sigstore/oidc/client/OidcToken.java +++ b/sigstore-java/src/main/java/dev/sigstore/oidc/client/OidcToken.java @@ -27,5 +27,6 @@ public interface OidcToken { String getIssuer(); /** The full oidc token obtained from the provider. */ + @Value.Redacted String getIdToken(); } diff --git a/sigstore-java/src/test/java/dev/sigstore/KeylessSignerTest.java b/sigstore-java/src/test/java/dev/sigstore/KeylessSignerTest.java index d4261074..7a14fd38 100644 --- a/sigstore-java/src/test/java/dev/sigstore/KeylessSignerTest.java +++ b/sigstore-java/src/test/java/dev/sigstore/KeylessSignerTest.java @@ -15,11 +15,9 @@ */ package dev.sigstore; -import com.google.api.client.json.gson.GsonFactory; -import com.google.api.client.json.webtoken.JsonWebSignature; import com.google.common.hash.Hashing; import dev.sigstore.bundle.Bundle; -import dev.sigstore.oidc.client.GithubActionsOidcClient; +import dev.sigstore.strings.StringMatcher; import dev.sigstore.testing.matchers.ByteArrayListMatcher; import dev.sigstore.testkit.annotations.EnabledIfOidcExists; import dev.sigstore.testkit.annotations.OidcProviderType; @@ -104,12 +102,15 @@ public void sign_digest() throws Exception { @Test @EnabledIfOidcExists(provider = OidcProviderType.GITHUB) - // this test will only pass on the github.com/sigstore/sigstore-java repository public void sign_failGithubOidcCheck() throws Exception { var signer = KeylessSigner.builder() .sigstorePublicDefaults() - .allowedOidcIdentities(List.of(OidcIdentity.of("goose@goose.com", "goose.com"))) + .allowedOidcIdentities( + List.of( + OidcIdentity.of( + StringMatcher.string("goose@goose.com"), + StringMatcher.string("goose.com")))) .build(); var ex = Assertions.assertThrows( @@ -127,20 +128,18 @@ public void sign_failGithubOidcCheck() throws Exception { @EnabledIfOidcExists(provider = OidcProviderType.GITHUB) // this test will only pass on the github.com/sigstore/sigstore-java repository public void sign_passGithubOidcCheck() throws Exception { - // silly way to get the right oidc identity to make sure our simple matcher works - var jws = - JsonWebSignature.parse( - new GsonFactory(), - GithubActionsOidcClient.builder().build().getIDToken(System.getenv()).getIdToken()); - var expectedGithubSubject = jws.getPayload().getSubject(); var signer = KeylessSigner.builder() .sigstorePublicDefaults() .allowedOidcIdentities( List.of( OidcIdentity.of( - expectedGithubSubject, "https://token.actions.githubusercontent.com"), - OidcIdentity.of("some@other.com", "https://accounts.other.com"))) + StringMatcher.regex( + "https://github\\.com/sigstore/sigstore-java/\\.github/workflows/.*\\.yaml@.*"), + StringMatcher.string("https://token.actions.githubusercontent.com")), + OidcIdentity.of( + StringMatcher.string("some@other.com"), + StringMatcher.string("https://accounts.other.com")))) .build(); Assertions.assertDoesNotThrow( () -> diff --git a/sigstore-java/src/test/java/dev/sigstore/oidc/client/OidcTokenTest.java b/sigstore-java/src/test/java/dev/sigstore/oidc/client/OidcTokenTest.java new file mode 100644 index 00000000..2df83599 --- /dev/null +++ b/sigstore-java/src/test/java/dev/sigstore/oidc/client/OidcTokenTest.java @@ -0,0 +1,34 @@ +/* + * Copyright 2024 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. + */ +package dev.sigstore.oidc.client; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class OidcTokenTest { + + @Test + public void test_redacted() { + var testToken = + ImmutableOidcToken.builder() + .issuer("issuer") + .idToken("secret") + .subjectAlternativeName("name") + .build(); + Assertions.assertEquals( + "OidcToken{subjectAlternativeName=name, issuer=issuer}", testToken.toString()); + } +}