diff --git a/adapters/saml/core/pom.xml b/adapters/saml/core/pom.xml
index 49c5a82b80..ac557d8297 100755
--- a/adapters/saml/core/pom.xml
+++ b/adapters/saml/core/pom.xml
@@ -61,11 +61,6 @@
keycloak-common
provided
-
- org.keycloak
- keycloak-crypto-default
- test
-
org.jboss.logging
jboss-logging
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/PemUtils.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/PemUtils.java
new file mode 100644
index 0000000000..d60d1e3922
--- /dev/null
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/PemUtils.java
@@ -0,0 +1,144 @@
+/*
+ * 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.adapters.saml.config;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+import org.keycloak.common.util.Base64;
+import org.keycloak.common.util.BouncyIntegration;
+import org.keycloak.common.util.PemException;
+
+/**
+ * Fork of the PemUtils from common module to avoid dependency on keycloak-crypto-default
+ */
+public class PemUtils {
+
+ /**
+ * Decode a X509 Certificate from a PEM string
+ *
+ * @param cert
+ * @return
+ * @throws Exception
+ */
+ public static X509Certificate decodeCertificate(String cert) {
+ if (cert == null) {
+ return null;
+ }
+
+ try {
+ byte[] der = pemToDer(cert);
+ ByteArrayInputStream bis = new ByteArrayInputStream(der);
+ return decodeCertificate(bis);
+ } catch (Exception e) {
+ throw new PemException(e);
+ }
+ }
+
+
+ /**
+ * Decode a Public Key from a PEM string
+ *
+ * @param pem
+ * @return
+ * @throws Exception
+ */
+ public static PublicKey decodePublicKey(String pem) {
+ if (pem == null) {
+ return null;
+ }
+
+ try {
+ byte[] der = pemToDer(pem);
+ return decodePublicKey(der, "RSA");
+ } catch (Exception e) {
+ throw new PemException(e);
+ }
+ }
+
+ /**
+ * Decode a Private Key from a PEM string
+ *
+ * @param pem
+ * @return
+ * @throws Exception
+ */
+ public static PrivateKey decodePrivateKey(String pem){
+ if (pem == null) {
+ return null;
+ }
+
+ try {
+ byte[] der = pemToDer(pem);
+ return decodePrivateKey(der);
+ } catch (Exception e) {
+ throw new PemException(e);
+ }
+ }
+
+ private static byte[] pemToDer(String pem) {
+ try {
+ pem = removeBeginEnd(pem);
+ return Base64.decode(pem);
+ } catch (IOException ioe) {
+ throw new PemException(ioe);
+ }
+ }
+
+ private static String removeBeginEnd(String pem) {
+ pem = pem.replaceAll("-----BEGIN (.*)-----", "");
+ pem = pem.replaceAll("-----END (.*)----", "");
+ pem = pem.replaceAll("\r\n", "");
+ pem = pem.replaceAll("\n", "");
+ return pem.trim();
+ }
+
+ private static PrivateKey decodePrivateKey(byte[] der) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
+ PKCS8EncodedKeySpec spec =
+ new PKCS8EncodedKeySpec(der);
+ KeyFactory kf = KeyFactory.getInstance("RSA", BouncyIntegration.PROVIDER);
+ return kf.generatePrivate(spec);
+ }
+
+ private static X509Certificate decodeCertificate(InputStream is) throws Exception {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyIntegration.PROVIDER);
+ X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
+ is.close();
+ return cert;
+ }
+
+ private static PublicKey decodePublicKey(byte[] der, String type) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
+ X509EncodedKeySpec spec =
+ new X509EncodedKeySpec(der);
+ KeyFactory kf = KeyFactory.getInstance("RSA", BouncyIntegration.PROVIDER);
+ return kf.generatePublic(spec);
+ }
+}
diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java
index 27336b5cd8..298d0b2b8d 100755
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/config/parsers/DeploymentBuilder.java
@@ -24,10 +24,9 @@ import org.keycloak.adapters.saml.SamlDeployment;
import org.keycloak.adapters.saml.config.IDP;
import org.keycloak.adapters.saml.config.Key;
import org.keycloak.adapters.saml.config.KeycloakSamlAdapter;
+import org.keycloak.adapters.saml.config.PemUtils;
import org.keycloak.adapters.saml.config.SP;
-import org.keycloak.common.crypto.CryptoIntegration;
import org.keycloak.common.enums.SslRequired;
-import org.keycloak.common.util.PemUtils;
import org.keycloak.saml.SignatureAlgorithm;
import org.keycloak.saml.common.exceptions.ParsingException;
@@ -58,7 +57,6 @@ public class DeploymentBuilder {
protected static Logger log = Logger.getLogger(DeploymentBuilder.class);
public SamlDeployment build(InputStream xml, ResourceLoader resourceLoader) throws ParsingException {
- CryptoIntegration.init(DeploymentBuilder.class.getClassLoader());
DefaultSamlDeployment deployment = new DefaultSamlDeployment();
DefaultSamlDeployment.DefaultIDP defaultIDP = new DefaultSamlDeployment.DefaultIDP();
DefaultSamlDeployment.DefaultSingleSignOnService sso = new DefaultSamlDeployment.DefaultSingleSignOnService();
diff --git a/core/pom.xml b/core/pom.xml
index 61068466a4..fc63273305 100755
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -32,8 +32,6 @@
-
- 11
${maven.build.timestamp}
yyyy-MM-dd HH:mm
@@ -74,38 +72,6 @@
-
-
- jdk-16
-
- [16,)
-
-
-
-
- maven-compiler-plugin
-
-
- compile-java16
- compile
-
- compile
-
-
- 16
-
- ${project.basedir}/src/main/java16
-
- true
-
-
-
-
-
-
-
-
-
diff --git a/core/src/main/java/org/keycloak/jose/jwk/AbstractJWKParser.java b/core/src/main/java/org/keycloak/jose/jwk/AbstractJWKParser.java
index b45e3a0bca..1e089626db 100644
--- a/core/src/main/java/org/keycloak/jose/jwk/AbstractJWKParser.java
+++ b/core/src/main/java/org/keycloak/jose/jwk/AbstractJWKParser.java
@@ -41,10 +41,13 @@ public abstract class AbstractJWKParser {
}
public PublicKey toPublicKey() {
+ if (jwk == null) {
+ throw new IllegalStateException("Not possible to convert to the publicKey. The jwk is not set");
+ }
String keyType = jwk.getKeyType();
- if (keyType.equals(KeyType.RSA)) {
+ if (KeyType.RSA.equals(keyType)) {
return createRSAPublicKey();
- } else if (keyType.equals(KeyType.EC)) {
+ } else if (KeyType.EC.equals(keyType)) {
return createECPublicKey();
} else {
@@ -87,7 +90,7 @@ public abstract class AbstractJWKParser {
}
try {
-
+
ECPoint point = new ECPoint(x, y);
ECParameterSpec params = CryptoIntegration.getProvider().createECParams(name);
ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, params);
diff --git a/core/src/main/java/org/keycloak/jose/jwk/JWKBuilder.java b/core/src/main/java/org/keycloak/jose/jwk/JWKBuilder.java
index 282dbd3d80..c3943c742a 100644
--- a/core/src/main/java/org/keycloak/jose/jwk/JWKBuilder.java
+++ b/core/src/main/java/org/keycloak/jose/jwk/JWKBuilder.java
@@ -17,15 +17,27 @@
package org.keycloak.jose.jwk;
-import org.keycloak.crypto.KeyUse;
-
+import java.math.BigInteger;
import java.security.Key;
+import java.security.interfaces.EdECPublicKey;
+import java.security.spec.EdECPoint;
+import java.util.Arrays;
+import java.util.Optional;
+
+import org.keycloak.common.util.Base64Url;
+import org.keycloak.common.util.KeyUtils;
+import org.keycloak.crypto.Algorithm;
+import org.keycloak.crypto.KeyType;
+import org.keycloak.crypto.KeyUse;
/**
* @author Stian Thorgersen
*/
public class JWKBuilder extends AbstractJWKBuilder {
+ private JWKBuilder() {
+ }
+
public static JWKBuilder create() {
return new JWKBuilder();
}
@@ -42,13 +54,55 @@ public class JWKBuilder extends AbstractJWKBuilder {
@Override
public JWK okp(Key key) {
- // not supported if jdk vesion < 17
- throw new UnsupportedOperationException("EdDSA algorithms not supported in this JDK version");
+ return okp(key, DEFAULT_PUBLIC_KEY_USE);
}
@Override
public JWK okp(Key key, KeyUse keyUse) {
- // not supported if jdk version < 17
- throw new UnsupportedOperationException("EdDSA algorithms not supported in this JDK version");
+ EdECPublicKey eddsaPublicKey = (EdECPublicKey) key;
+
+ OKPPublicJWK k = new OKPPublicJWK();
+
+ String kid = this.kid != null ? this.kid : KeyUtils.createKeyId(key);
+
+ k.setKeyId(kid);
+ k.setKeyType(KeyType.OKP);
+ k.setAlgorithm(algorithm);
+ k.setPublicKeyUse(keyUse == null ? DEFAULT_PUBLIC_KEY_USE.getSpecName() : keyUse.getSpecName());
+ k.setCrv(eddsaPublicKey.getParams().getName());
+
+ Optional x = edPublicKeyInJwkRepresentation(eddsaPublicKey);
+ k.setX(x.orElse(""));
+
+ return k;
}
+
+ private Optional edPublicKeyInJwkRepresentation(EdECPublicKey eddsaPublicKey) {
+ EdECPoint edEcPoint = eddsaPublicKey.getPoint();
+ BigInteger yCoordinate = edEcPoint.getY();
+
+ // JWK representation "x" of a public key
+ int bytesLength = 0;
+ if (Algorithm.Ed25519.equals(eddsaPublicKey.getParams().getName())) {
+ bytesLength = 32;
+ } else if (Algorithm.Ed448.equals(eddsaPublicKey.getParams().getName())) {
+ bytesLength = 57;
+ } else {
+ return Optional.ofNullable(null);
+ }
+
+ // consider the case where yCoordinate.toByteArray() is less than bytesLength due to relatively small value of y-coordinate.
+ byte[] yCoordinateLittleEndianBytes = new byte[bytesLength];
+
+ // convert big endian representation of BigInteger to little endian representation of JWK representation (RFC 8032,8027)
+ yCoordinateLittleEndianBytes = Arrays.copyOf(reverseBytes(yCoordinate.toByteArray()), bytesLength);
+
+ // set a parity of x-coordinate to the most significant bit of the last octet (RFC 8032, 8037)
+ if (edEcPoint.isXOdd()) {
+ yCoordinateLittleEndianBytes[yCoordinateLittleEndianBytes.length - 1] |= -128; // 0b10000000
+ }
+
+ return Optional.ofNullable(Base64Url.encode(yCoordinateLittleEndianBytes));
+ }
+
}
diff --git a/core/src/main/java/org/keycloak/jose/jwk/JWKParser.java b/core/src/main/java/org/keycloak/jose/jwk/JWKParser.java
index 13820e30d5..cfa646cbbd 100755
--- a/core/src/main/java/org/keycloak/jose/jwk/JWKParser.java
+++ b/core/src/main/java/org/keycloak/jose/jwk/JWKParser.java
@@ -17,6 +17,18 @@
package org.keycloak.jose.jwk;
+import java.math.BigInteger;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.spec.EdECPoint;
+import java.security.spec.EdECPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.NamedParameterSpec;
+
+import org.keycloak.common.util.Base64Url;
+import org.keycloak.crypto.Algorithm;
+import org.keycloak.crypto.KeyType;
import org.keycloak.util.JsonSerialization;
/**
@@ -24,17 +36,17 @@ import org.keycloak.util.JsonSerialization;
*/
public class JWKParser extends AbstractJWKParser {
- protected JWKParser() {
- }
-
- public JWKParser(JWK jwk) {
- this.jwk = jwk;
+ private JWKParser() {
}
public static JWKParser create() {
return new JWKParser();
}
+ public JWKParser(JWK jwk) {
+ this.jwk = jwk;
+ }
+
public static JWKParser create(JWK jwk) {
return new JWKParser(jwk);
}
@@ -48,4 +60,68 @@ public class JWKParser extends AbstractJWKParser {
}
}
+ @Override
+ public PublicKey toPublicKey() {
+ if (jwk == null) {
+ throw new IllegalStateException("Not possible to convert to the publicKey. The jwk is not set");
+ }
+ String keyType = jwk.getKeyType();
+ if (KeyType.RSA.equals(keyType)) {
+ return createRSAPublicKey();
+ } else if (KeyType.EC.equals(keyType)) {
+ return createECPublicKey();
+ } else if (KeyType.OKP.equals(keyType)) {
+ return createOKPPublicKey();
+ } else {
+ throw new RuntimeException("Unsupported keyType " + keyType);
+ }
+ }
+
+ private PublicKey createOKPPublicKey() {
+ String x = (String) jwk.getOtherClaims().get(OKPPublicJWK.X);
+ String crv = (String) jwk.getOtherClaims().get(OKPPublicJWK.CRV);
+ // JWK representation "x" of a public key
+ int bytesLength = 0;
+ if (Algorithm.Ed25519.equals(crv)) {
+ bytesLength = 32;
+ } else if (Algorithm.Ed448.equals(crv)) {
+ bytesLength = 57;
+ } else {
+ throw new RuntimeException("Invalid JWK representation of OKP type algorithm");
+ }
+
+ byte[] decodedX = Base64Url.decode(x);
+ if (decodedX.length != bytesLength) {
+ throw new RuntimeException("Invalid JWK representation of OKP type public key");
+ }
+
+ // x-coordinate's parity check shown by MSB(bit) of MSB(byte) of decoded "x": 1 is odd, 0 is even
+ boolean isOddX = false;
+ if ((decodedX[decodedX.length - 1] & -128) != 0) { // 0b10000000
+ isOddX = true;
+ }
+
+ // MSB(bit) of MSB(byte) showing x-coodinate's parity is set to 0
+ decodedX[decodedX.length - 1] &= 127; // 0b01111111
+
+ // both x and y-coordinate in twisted Edwards curve are always 0 or natural number
+ BigInteger y = new BigInteger(1, JWKBuilder.reverseBytes(decodedX));
+ NamedParameterSpec spec = new NamedParameterSpec(crv);
+ EdECPoint ep = new EdECPoint(isOddX, y);
+ EdECPublicKeySpec keySpec = new EdECPublicKeySpec(spec, ep);
+
+ PublicKey publicKey = null;
+ try {
+ publicKey = KeyFactory.getInstance(crv).generatePublic(keySpec);
+ } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ return publicKey;
+ }
+
+ @Override
+ public boolean isKeyTypeSupported(String keyType) {
+ return (RSAPublicJWK.RSA.equals(keyType) || ECPublicJWK.EC.equals(keyType) || OKPPublicJWK.OKP.equals(keyType));
+ }
+
}
diff --git a/core/src/main/java16/org/keycloak/jose/jwk/JWKBuilder.java b/core/src/main/java16/org/keycloak/jose/jwk/JWKBuilder.java
deleted file mode 100644
index 808eb84607..0000000000
--- a/core/src/main/java16/org/keycloak/jose/jwk/JWKBuilder.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2023 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.jose.jwk;
-
-import java.math.BigInteger;
-import java.security.Key;
-import java.security.interfaces.EdECPublicKey;
-import java.security.spec.EdECPoint;
-import java.util.Arrays;
-import java.util.Optional;
-
-import org.keycloak.common.util.Base64Url;
-import org.keycloak.common.util.KeyUtils;
-import org.keycloak.crypto.Algorithm;
-import org.keycloak.crypto.KeyType;
-import org.keycloak.crypto.KeyUse;
-
-/**
- * @author Takashi Norimatsu
- */
-public class JWKBuilder extends AbstractJWKBuilder {
-
- private JWKBuilder() {
- }
-
- public static JWKBuilder create() {
- return new JWKBuilder();
- }
-
- public JWKBuilder kid(String kid) {
- this.kid = kid;
- return this;
- }
-
- public JWKBuilder algorithm(String algorithm) {
- this.algorithm = algorithm;
- return this;
- }
-
- @Override
- public JWK okp(Key key) {
- return okp(key, DEFAULT_PUBLIC_KEY_USE);
- }
-
- @Override
- public JWK okp(Key key, KeyUse keyUse) {
- EdECPublicKey eddsaPublicKey = (EdECPublicKey) key;
-
- OKPPublicJWK k = new OKPPublicJWK();
-
- String kid = this.kid != null ? this.kid : KeyUtils.createKeyId(key);
-
- k.setKeyId(kid);
- k.setKeyType(KeyType.OKP);
- k.setAlgorithm(algorithm);
- k.setPublicKeyUse(keyUse == null ? DEFAULT_PUBLIC_KEY_USE.getSpecName() : keyUse.getSpecName());
- k.setCrv(eddsaPublicKey.getParams().getName());
-
- Optional x = edPublicKeyInJwkRepresentation(eddsaPublicKey);
- k.setX(x.orElse(""));
-
- return k;
- }
-
- private Optional edPublicKeyInJwkRepresentation(EdECPublicKey eddsaPublicKey) {
- EdECPoint edEcPoint = eddsaPublicKey.getPoint();
- BigInteger yCoordinate = edEcPoint.getY();
-
- // JWK representation "x" of a public key
- int bytesLength = 0;
- if (Algorithm.Ed25519.equals(eddsaPublicKey.getParams().getName())) {
- bytesLength = 32;
- } else if (Algorithm.Ed448.equals(eddsaPublicKey.getParams().getName())) {
- bytesLength = 57;
- } else {
- return Optional.ofNullable(null);
- }
-
- // consider the case where yCoordinate.toByteArray() is less than bytesLength due to relatively small value of y-coordinate.
- byte[] yCoordinateLittleEndianBytes = new byte[bytesLength];
-
- // convert big endian representation of BigInteger to little endian representation of JWK representation (RFC 8032,8027)
- yCoordinateLittleEndianBytes = Arrays.copyOf(reverseBytes(yCoordinate.toByteArray()), bytesLength);
-
- // set a parity of x-coordinate to the most significant bit of the last octet (RFC 8032, 8037)
- if (edEcPoint.isXOdd()) {
- yCoordinateLittleEndianBytes[yCoordinateLittleEndianBytes.length - 1] |= -128; // 0b10000000
- }
-
- return Optional.ofNullable(Base64Url.encode(yCoordinateLittleEndianBytes));
- }
-
-}
diff --git a/core/src/main/java16/org/keycloak/jose/jwk/JWKParser.java b/core/src/main/java16/org/keycloak/jose/jwk/JWKParser.java
deleted file mode 100644
index c99cf5d287..0000000000
--- a/core/src/main/java16/org/keycloak/jose/jwk/JWKParser.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright 2023 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.jose.jwk;
-
-import java.math.BigInteger;
-import java.security.KeyFactory;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.spec.EdECPoint;
-import java.security.spec.EdECPublicKeySpec;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.NamedParameterSpec;
-
-import org.keycloak.common.util.Base64Url;
-import org.keycloak.crypto.Algorithm;
-import org.keycloak.crypto.KeyType;
-import org.keycloak.util.JsonSerialization;
-
-/**
- * @author Takashi Norimatsu
- */
-public class JWKParser extends AbstractJWKParser {
-
- private JWKParser() {
- }
-
- public static JWKParser create() {
- return new JWKParser();
- }
-
- public JWKParser(JWK jwk) {
- this.jwk = jwk;
- }
-
- public static JWKParser create(JWK jwk) {
- return new JWKParser(jwk);
- }
-
- public JWKParser parse(String jwk) {
- try {
- this.jwk = JsonSerialization.mapper.readValue(jwk, JWK.class);
- return this;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public PublicKey toPublicKey() {
- String keyType = jwk.getKeyType();
- if (keyType.equals(KeyType.RSA)) {
- return createRSAPublicKey();
- } else if (keyType.equals(KeyType.EC)) {
- return createECPublicKey();
- } else if (keyType.equals(KeyType.OKP)) {
- return createOKPPublicKey();
- } else {
- throw new RuntimeException("Unsupported keyType " + keyType);
- }
- }
-
- private PublicKey createOKPPublicKey() {
- String x = (String) jwk.getOtherClaims().get(OKPPublicJWK.X);
- String crv = (String) jwk.getOtherClaims().get(OKPPublicJWK.CRV);
- // JWK representation "x" of a public key
- int bytesLength = 0;
- if (Algorithm.Ed25519.equals(crv)) {
- bytesLength = 32;
- } else if (Algorithm.Ed448.equals(crv)) {
- bytesLength = 57;
- } else {
- throw new RuntimeException("Invalid JWK representation of OKP type algorithm");
- }
-
- byte[] decodedX = Base64Url.decode(x);
- if (decodedX.length != bytesLength) {
- throw new RuntimeException("Invalid JWK representation of OKP type public key");
- }
-
- // x-coordinate's parity check shown by MSB(bit) of MSB(byte) of decoded "x": 1 is odd, 0 is even
- boolean isOddX = false;
- if ((decodedX[decodedX.length - 1] & -128) != 0) { // 0b10000000
- isOddX = true;
- }
-
- // MSB(bit) of MSB(byte) showing x-coodinate's parity is set to 0
- decodedX[decodedX.length - 1] &= 127; // 0b01111111
-
- // both x and y-coordinate in twisted Edwards curve are always 0 or natural number
- BigInteger y = new BigInteger(1, JWKBuilder.reverseBytes(decodedX));
- NamedParameterSpec spec = new NamedParameterSpec(crv);
- EdECPoint ep = new EdECPoint(isOddX, y);
- EdECPublicKeySpec keySpec = new EdECPublicKeySpec(spec, ep);
-
- PublicKey publicKey = null;
- try {
- publicKey = KeyFactory.getInstance(crv).generatePublic(keySpec);
- } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
- throw new RuntimeException(e);
- }
- return publicKey;
- }
-
- @Override
- public boolean isKeyTypeSupported(String keyType) {
- return (RSAPublicJWK.RSA.equals(keyType) || ECPublicJWK.EC.equals(keyType) || OKPPublicJWK.OKP.equals(keyType));
- }
-
-}
\ No newline at end of file
diff --git a/crypto/default/pom.xml b/crypto/default/pom.xml
index 33aa7a62f5..2b0cf1fb23 100644
--- a/crypto/default/pom.xml
+++ b/crypto/default/pom.xml
@@ -30,11 +30,6 @@
Keycloak Crypto Default
-
-
- 11
-
-
org.keycloak
diff --git a/distribution/galleon-feature-packs/saml-adapter-galleon-pack/src/main/resources/modules/system/add-ons/keycloak/org/keycloak/keycloak-core/main/module.xml b/distribution/galleon-feature-packs/saml-adapter-galleon-pack/src/main/resources/modules/system/add-ons/keycloak/org/keycloak/keycloak-core/main/module.xml
deleted file mode 100755
index ae472c9dba..0000000000
--- a/distribution/galleon-feature-packs/saml-adapter-galleon-pack/src/main/resources/modules/system/add-ons/keycloak/org/keycloak/keycloak-core/main/module.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/distribution/galleon-feature-packs/saml-adapter-galleon-pack/src/main/resources/modules/system/add-ons/keycloak/org/keycloak/keycloak-crypto-default/main/module.xml b/distribution/galleon-feature-packs/saml-adapter-galleon-pack/src/main/resources/modules/system/add-ons/keycloak/org/keycloak/keycloak-crypto-default/main/module.xml
deleted file mode 100644
index 341f074123..0000000000
--- a/distribution/galleon-feature-packs/saml-adapter-galleon-pack/src/main/resources/modules/system/add-ons/keycloak/org/keycloak/keycloak-crypto-default/main/module.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/distribution/galleon-feature-packs/saml-adapter-galleon-pack/src/main/resources/modules/system/add-ons/keycloak/org/keycloak/keycloak-saml-adapter-core/main/module.xml b/distribution/galleon-feature-packs/saml-adapter-galleon-pack/src/main/resources/modules/system/add-ons/keycloak/org/keycloak/keycloak-saml-adapter-core/main/module.xml
index 4cf0bae3aa..465593f379 100755
--- a/distribution/galleon-feature-packs/saml-adapter-galleon-pack/src/main/resources/modules/system/add-ons/keycloak/org/keycloak/keycloak-saml-adapter-core/main/module.xml
+++ b/distribution/galleon-feature-packs/saml-adapter-galleon-pack/src/main/resources/modules/system/add-ons/keycloak/org/keycloak/keycloak-saml-adapter-core/main/module.xml
@@ -35,10 +35,9 @@
-
-
+
diff --git a/services/src/test/java/org/keycloak/jose/jwk/ServerJWKTest.java b/services/src/test/java/org/keycloak/jose/jwk/ServerJWKTest.java
index ec0a51b6ad..5420cf72db 100644
--- a/services/src/test/java/org/keycloak/jose/jwk/ServerJWKTest.java
+++ b/services/src/test/java/org/keycloak/jose/jwk/ServerJWKTest.java
@@ -42,7 +42,7 @@ import org.keycloak.util.JsonSerialization;
*
* @author Takashi Norimatsu
*/
-public abstract class ServerJWKTest {
+public class ServerJWKTest {
@ClassRule
public static CryptoInitRule cryptoInitRule = new CryptoInitRule();