diff --git a/core/src/main/java/org/keycloak/crypto/ECDSASignatureVerifierContext.java b/core/src/main/java/org/keycloak/crypto/ECDSASignatureVerifierContext.java new file mode 100644 index 0000000000..177aaeb2d9 --- /dev/null +++ b/core/src/main/java/org/keycloak/crypto/ECDSASignatureVerifierContext.java @@ -0,0 +1,36 @@ +/* + * Copyright 2024 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * 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 org.keycloak.crypto; + +import org.keycloak.common.VerificationException; + +public class ECDSASignatureVerifierContext extends AsymmetricSignatureVerifierContext{ + public ECDSASignatureVerifierContext(KeyWrapper key) { + super(key); + } + + @Override + public boolean verify(byte[] data, byte[] signature) throws VerificationException { + try { + int expectedSize = ECDSAAlgorithm.getSignatureLength(getAlgorithm()); + byte[] derSignature = ECDSAAlgorithm.concatenatedRSToASN1DER(signature, expectedSize); + return super.verify(data, derSignature); + } catch (Exception e) { + throw new VerificationException("Verification failed", e); + } + } +} diff --git a/core/src/test/java/org/keycloak/sdjwt/TestSettings.java b/core/src/test/java/org/keycloak/sdjwt/TestSettings.java index c38411844c..f9bdc8c5b6 100644 --- a/core/src/test/java/org/keycloak/sdjwt/TestSettings.java +++ b/core/src/test/java/org/keycloak/sdjwt/TestSettings.java @@ -30,16 +30,18 @@ import java.security.spec.ECPublicKeySpec; import java.util.HashMap; import java.util.Map; +import org.junit.ClassRule; import org.keycloak.common.util.Base64Url; import org.keycloak.common.util.KeyUtils; -import org.keycloak.crypto.AsymmetricSignatureSignerContext; -import org.keycloak.crypto.AsymmetricSignatureVerifierContext; +import org.keycloak.crypto.ECDSASignatureSignerContext; +import org.keycloak.crypto.ECDSASignatureVerifierContext; import org.keycloak.crypto.KeyUse; import org.keycloak.crypto.KeyWrapper; import org.keycloak.crypto.SignatureSignerContext; import org.keycloak.crypto.SignatureVerifierContext; import com.fasterxml.jackson.databind.JsonNode; +import org.keycloak.rule.CryptoInitRule; /** * Import test-settings from: @@ -208,7 +210,7 @@ public class TestSettings { keyWrapper.setType(keyPair.getPublic().getAlgorithm()); keyWrapper.setUse(KeyUse.SIG); keyWrapper.setKid(kid); - return new AsymmetricSignatureSignerContext(keyWrapper); + return new ECDSASignatureSignerContext(keyWrapper); } private static SignatureVerifierContext getSignatureVerifierContext(PublicKey publicKey, String algorithm, @@ -219,7 +221,7 @@ public class TestSettings { keyWrapper.setType(publicKey.getAlgorithm()); keyWrapper.setUse(KeyUse.SIG); keyWrapper.setKid(kid); - return new AsymmetricSignatureVerifierContext(keyWrapper); + return new ECDSASignatureVerifierContext(keyWrapper); } private static final Map ECDSA_CURVE_2_SPECS_NAMES = new HashMap<>(); diff --git a/core/src/test/java/org/keycloak/sdjwt/sdjwtvp/SdJwtVPTest.java b/core/src/test/java/org/keycloak/sdjwt/sdjwtvp/SdJwtVPTest.java index ef5bcf3d60..f787076b29 100644 --- a/core/src/test/java/org/keycloak/sdjwt/sdjwtvp/SdJwtVPTest.java +++ b/core/src/test/java/org/keycloak/sdjwt/sdjwtvp/SdJwtVPTest.java @@ -16,13 +16,12 @@ */ package org.keycloak.sdjwt.sdjwtvp; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; - +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.junit.ClassRule; import org.junit.Test; import org.keycloak.common.VerificationException; +import org.keycloak.rule.CryptoInitRule; import org.keycloak.sdjwt.DisclosureSpec; import org.keycloak.sdjwt.IssuerSignedJWT; import org.keycloak.sdjwt.SdJwt; @@ -30,13 +29,17 @@ import org.keycloak.sdjwt.TestSettings; import org.keycloak.sdjwt.TestUtils; import org.keycloak.sdjwt.vp.SdJwtVP; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; /** * @author Francis Pouatcha */ -public class SdJwtVPTest { +public abstract class SdJwtVPTest { + @ClassRule + public static CryptoInitRule cryptoInitRule = new CryptoInitRule(); // Additional tests can be written to cover edge cases, error conditions, // and any other functionality specific to the SdJwt class. @Test diff --git a/core/src/test/resources/sdjwt/s7.3-sdjwt.txt b/core/src/test/resources/sdjwt/s7.3-sdjwt.txt index c980125ad5..87001644ce 100644 --- a/core/src/test/resources/sdjwt/s7.3-sdjwt.txt +++ b/core/src/test/resources/sdjwt/s7.3-sdjwt.txt @@ -1 +1 @@ -eyJhbGciOiJFUzI1NiIsInR5cCIgOiAidmMrc2Qtand0Iiwia2lkIiA6ICJkb2Mtc2lnbmVyLTA1LTI1LTIwMjIifQ.eyJfc2QiOlsiSHZyS1g2ZlBWMHY5S195Q1ZGQmlMRkhzTWF4Y0RfMTE0RW02VlQ4eDFsZyJdLCJfc2RfYWxnIjoic2hhLTI1NiIsInN1YiI6IjZjNWMwYTQ5LWI1ODktNDMxZC1iYWU3LTIxOTEyMmE5ZWMyYyIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwiaWF0IjoxNjgzMDAwMDAwLCJleHAiOjE4ODMwMDAwMDB9.MEQCICde3GkeuNWixUiD3zk5F9OMGD2HJW6Lmo4waWkVXDddAiByEPMrOn8aE9Tf33_J3SIiVBEhQNthU58O7D0Y1Xywcg~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgInN0cmVldF9hZGRyZXNzIiwgIlNjaHVsc3RyLiAxMiJd~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImxvY2FsaXR5IiwgIlNjaHVscGZvcnRhIl0~WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgInJlZ2lvbiIsICJTYWNoc2VuLUFuaGFsdCJd~WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgImNvdW50cnkiLCAiREUiXQ~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgImFkZHJlc3MiLCB7Il9zZCI6IFsiNnZoOWJxLXpTNEdLTV83R3BnZ1ZiWXp6dTZvT0dYcm1OVkdQSFA3NVVkMCIsICI5Z2pWdVh0ZEZST0NnUnJ0TmNHVVhtRjY1cmRlemlfNkVyX2o3NmttWXlNIiwgIktVUkRQaDRaQzE5LTN0aXotRGYzOVY4ZWlkeTFvVjNhM0gxRGEyTjBnODgiLCAiV045cjlkQ0JKOEhUQ3NTMmpLQVN4VGpFeVc1bTV4NjVfWl8ycm8yamZYTSJdfV0~ \ No newline at end of file +eyJraWQiOiJkb2Mtc2lnbmVyLTA1LTI1LTIwMjIiLCJ0eXAiOiJ2YytzZC1qd3QiLCJhbGciOiJFUzI1NiJ9.eyJfc2QiOlsiSHZyS1g2ZlBWMHY5S195Q1ZGQmlMRkhzTWF4Y0RfMTE0RW02VlQ4eDFsZyJdLCJfc2RfYWxnIjoic2hhLTI1NiIsInN1YiI6IjZjNWMwYTQ5LWI1ODktNDMxZC1iYWU3LTIxOTEyMmE5ZWMyYyIsImlzcyI6Imh0dHBzOi8vaXNzdWVyLmV4YW1wbGUuY29tIiwiaWF0IjoxNjgzMDAwMDAwLCJleHAiOjE4ODMwMDAwMDB9.Bhhy9eDenyBCsh9F064pxs5SK0Tbfc0o4xXlzmYv50qODKShpfsiC8__W1SXrF687JsbXmbD7VA5Db7iMoPwbg~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgInN0cmVldF9hZGRyZXNzIiwgIlNjaHVsc3RyLiAxMiJd~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImxvY2FsaXR5IiwgIlNjaHVscGZvcnRhIl0~WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgInJlZ2lvbiIsICJTYWNoc2VuLUFuaGFsdCJd~WyJlSThaV205UW5LUHBOUGVOZW5IZGhRIiwgImNvdW50cnkiLCAiREUiXQ~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgImFkZHJlc3MiLCB7Il9zZCI6IFsiNnZoOWJxLXpTNEdLTV83R3BnZ1ZiWXp6dTZvT0dYcm1OVkdQSFA3NVVkMCIsICI5Z2pWdVh0ZEZST0NnUnJ0TmNHVVhtRjY1cmRlemlfNkVyX2o3NmttWXlNIiwgIktVUkRQaDRaQzE5LTN0aXotRGYzOVY4ZWlkeTFvVjNhM0gxRGEyTjBnODgiLCAiV045cjlkQ0JKOEhUQ3NTMmpLQVN4VGpFeVc1bTV4NjVfWl8ycm8yamZYTSJdfV0~ \ No newline at end of file diff --git a/crypto/default/src/test/java/org/keycloak/crypto/def/test/DefaultCryptoSdJwtVPTest.java b/crypto/default/src/test/java/org/keycloak/crypto/def/test/DefaultCryptoSdJwtVPTest.java new file mode 100644 index 0000000000..1b7e1b1e29 --- /dev/null +++ b/crypto/default/src/test/java/org/keycloak/crypto/def/test/DefaultCryptoSdJwtVPTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2024 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * 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 org.keycloak.crypto.def.test; + +import org.junit.Assume; +import org.junit.Before; +import org.keycloak.common.util.Environment; +import org.keycloak.sdjwt.sdjwtvp.SdJwtVPTest; + +/** + * Test with default security provider and non-fips bouncycastle + * + * @author Francis Pouatcha + */ +public class DefaultCryptoSdJwtVPTest extends SdJwtVPTest { + + @Before + public void before() { + // Run this test just if java is not in FIPS mode + Assume.assumeFalse("Java is in FIPS mode. Skipping the test.", Environment.isJavaInFipsMode()); + } +} diff --git a/crypto/elytron/src/test/java/org/keycloak/crypto/elytron/test/ElytronCryptoSdJwtVPTest.java b/crypto/elytron/src/test/java/org/keycloak/crypto/elytron/test/ElytronCryptoSdJwtVPTest.java new file mode 100644 index 0000000000..c81c686be2 --- /dev/null +++ b/crypto/elytron/src/test/java/org/keycloak/crypto/elytron/test/ElytronCryptoSdJwtVPTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2024 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * 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 org.keycloak.crypto.elytron.test; + +import org.keycloak.sdjwt.sdjwtvp.SdJwtVPTest; + +/** + * Test with Elytron provider + * + * @author Francis Pouatcha + */ +public class ElytronCryptoSdJwtVPTest extends SdJwtVPTest { +}