diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/CoreTestFrameworkExtension.java b/test-framework/core/src/main/java/org/keycloak/testframework/CoreTestFrameworkExtension.java index 4e96f39e9eb..0ae2974e8a9 100644 --- a/test-framework/core/src/main/java/org/keycloak/testframework/CoreTestFrameworkExtension.java +++ b/test-framework/core/src/main/java/org/keycloak/testframework/CoreTestFrameworkExtension.java @@ -2,6 +2,8 @@ package org.keycloak.testframework; import org.keycloak.testframework.admin.AdminClientFactorySupplier; import org.keycloak.testframework.admin.AdminClientSupplier; +import org.keycloak.testframework.crypto.CryptoHelper; +import org.keycloak.testframework.crypto.CryptoHelperSupplier; import org.keycloak.testframework.database.RemoteDatabaseSupplier; import org.keycloak.testframework.http.SimpleHttpSupplier; import org.keycloak.testframework.https.ManagedCertificates; @@ -52,7 +54,8 @@ public class CoreTestFrameworkExtension implements TestFrameworkExtension { new HttpServerSupplier(), new InfinispanExternalServerSupplier(), new SimpleHttpSupplier(), - new CertificatesSupplier() + new CertificatesSupplier(), + new CryptoHelperSupplier() ); } @@ -61,8 +64,13 @@ public class CoreTestFrameworkExtension implements TestFrameworkExtension { return Map.of( KeycloakServer.class, "server", TestDatabase.class, "database", - ManagedCertificates.class, "certificates" + ManagedCertificates.class, "certificates", + CryptoHelper.class, "crypto" ); } + @Override + public List> alwaysEnabledValueTypes() { + return List.of(CryptoHelper.class); + } } diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/annotations/InjectCryptoHelper.java b/test-framework/core/src/main/java/org/keycloak/testframework/annotations/InjectCryptoHelper.java new file mode 100644 index 00000000000..fe902f72a2a --- /dev/null +++ b/test-framework/core/src/main/java/org/keycloak/testframework/annotations/InjectCryptoHelper.java @@ -0,0 +1,11 @@ +package org.keycloak.testframework.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface InjectCryptoHelper { +} diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/crypto/CryptoHelper.java b/test-framework/core/src/main/java/org/keycloak/testframework/crypto/CryptoHelper.java new file mode 100644 index 00000000000..cc49c79f111 --- /dev/null +++ b/test-framework/core/src/main/java/org/keycloak/testframework/crypto/CryptoHelper.java @@ -0,0 +1,39 @@ +package org.keycloak.testframework.crypto; + +import org.keycloak.common.crypto.FipsMode; + +public class CryptoHelper { + + private final FipsMode fips; + + public CryptoHelper(FipsMode fips) { + this.fips = fips; + } + + public CryptoKeyStore keystore() { + return new CryptoKeyStore(this); + } + + public boolean isFips() { + return switch (fips) { + case STRICT, NON_STRICT -> true; + default -> false; + }; + } + + public String[] getExpectedSupportedKeyStoreTypes() { + return switch (fips) { + case NON_STRICT -> new String[] { "PKCS12", "BCFKS" }; + case STRICT -> new String[] { "BCFKS" }; + default -> new String[] { "BCFKS", "JKS", "PKCS12" }; + }; + } + + public String[] getExpectedSupportedRsaKeySizes() { + return switch (fips) { + case STRICT -> new String[]{"2048", "3072", "4096"}; + default -> new String[]{"1024", "2048", "3072", "4096"}; + }; + } + +} diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/crypto/CryptoHelperSupplier.java b/test-framework/core/src/main/java/org/keycloak/testframework/crypto/CryptoHelperSupplier.java new file mode 100644 index 00000000000..479084e1a7b --- /dev/null +++ b/test-framework/core/src/main/java/org/keycloak/testframework/crypto/CryptoHelperSupplier.java @@ -0,0 +1,34 @@ +package org.keycloak.testframework.crypto; + +import org.keycloak.common.crypto.CryptoIntegration; +import org.keycloak.common.crypto.FipsMode; +import org.keycloak.crypto.def.DefaultCryptoProvider; +import org.keycloak.testframework.annotations.InjectCryptoHelper; +import org.keycloak.testframework.config.Config; +import org.keycloak.testframework.injection.InstanceContext; +import org.keycloak.testframework.injection.LifeCycle; +import org.keycloak.testframework.injection.RequestedInstance; +import org.keycloak.testframework.injection.Supplier; + +public class CryptoHelperSupplier implements Supplier { + + @Override + public CryptoHelper getValue(InstanceContext instanceContext) { + if (!CryptoIntegration.isInitialised()) { + CryptoIntegration.setProvider(new DefaultCryptoProvider()); + } + FipsMode fips = Config.getValueTypeConfig(CryptoHelper.class, "fips", FipsMode.DISABLED.name(), FipsMode.class); + return new CryptoHelper(fips); + } + + @Override + public LifeCycle getDefaultLifecycle() { + return LifeCycle.GLOBAL; + } + + @Override + public boolean compatible(InstanceContext a, RequestedInstance b) { + return true; + } + +} diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/crypto/CryptoKeyStore.java b/test-framework/core/src/main/java/org/keycloak/testframework/crypto/CryptoKeyStore.java new file mode 100644 index 00000000000..d29faf7390b --- /dev/null +++ b/test-framework/core/src/main/java/org/keycloak/testframework/crypto/CryptoKeyStore.java @@ -0,0 +1,114 @@ +/* + * Copyright 2022 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.testframework.crypto; + +import org.junit.jupiter.api.Assumptions; +import org.keycloak.common.crypto.CryptoIntegration; +import org.keycloak.common.util.CertificateUtils; +import org.keycloak.common.util.KeyUtils; +import org.keycloak.common.util.KeystoreUtil; +import org.keycloak.common.util.PemUtils; +import org.keycloak.common.util.Time; +import org.keycloak.representations.idm.CertificateRepresentation; + +import javax.crypto.SecretKey; +import java.io.File; +import java.io.FileOutputStream; +import java.security.KeyPair; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.stream.Stream; + +/** + * @author Marek Posolda + */ +public class CryptoKeyStore { + + private final CryptoHelper cryptoHelper; + + CryptoKeyStore(CryptoHelper cryptoHelper) { + this.cryptoHelper = cryptoHelper; + } + + public KeystoreUtil.KeystoreFormat getPreferredKeystoreType() { + return Enum.valueOf(KeystoreUtil.KeystoreFormat.class, cryptoHelper.getExpectedSupportedKeyStoreTypes()[0]); + } + + public void assumeKeystoreTypeSupported(KeystoreUtil.KeystoreFormat keystoreType) { + String[] supportedKeystoreTypes = cryptoHelper.getExpectedSupportedKeyStoreTypes(); + Assumptions.assumeTrue(Stream.of(supportedKeystoreTypes).anyMatch(type -> type.equals(keystoreType.toString())), + "Keystore type '" + keystoreType + "' not supported. Supported keystore types: " + Arrays.asList(supportedKeystoreTypes)); + } + + public KeystoreInfo generateKeystore(File folder, KeystoreUtil.KeystoreFormat keystoreType, String subject, String keystorePassword, String keyPassword) throws Exception { + return generateKeystore(folder, keystoreType, subject, keystorePassword, keyPassword, KeyUtils.generateRsaKeyPair(2048)); + } + + public KeystoreInfo generateKeystore(File folder, KeystoreUtil.KeystoreFormat keystoreType, String subject, String keystorePassword, String keyPassword, KeyPair keyPair) throws Exception { + X509Certificate certificate = CertificateUtils.generateV1SelfSignedCertificate(keyPair, subject); + return generateKeystore(folder, keystoreType, subject, keystorePassword, keyPassword, keyPair.getPrivate(), certificate); + } + + public KeystoreInfo generateKeystore(File folder, KeystoreUtil.KeystoreFormat keystoreType, + String subject, String keystorePassword, String keyPassword, PrivateKey privKey, Certificate certificate) throws Exception { + KeyStore keyStore = CryptoIntegration.getProvider().getKeyStore(keystoreType); + keyStore.load(null, null); + Certificate[] chain = {certificate}; + keyStore.setKeyEntry(subject, privKey, keyPassword.trim().toCharArray(), chain); + + File file = saveKeystore(folder, keystoreType, keyStore, keystorePassword); + + CertificateRepresentation certRep = new CertificateRepresentation(); + certRep.setPrivateKey(PemUtils.encodeKey(privKey)); + certRep.setPublicKey(PemUtils.encodeKey(certificate.getPublicKey())); + certRep.setCertificate(PemUtils.encodeCertificate(certificate)); + return new KeystoreInfo(certRep, file); + } + + public KeystoreInfo generateKeystore(File folder, KeystoreUtil.KeystoreFormat keystoreType, String alias, + String keystorePassword, String keyPassword, SecretKey secretKey) throws Exception { + KeyStore keyStore = KeyStore.getInstance(keystoreType.name()); + keyStore.load(null, null); + + KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(secretKey); + KeyStore.ProtectionParameter protection = new KeyStore.PasswordProtection(keyPassword.trim().toCharArray()); + keyStore.setEntry(alias, secretKeyEntry, protection); + + File file = saveKeystore(folder, keystoreType, keyStore, keystorePassword); + + return new KeystoreInfo(null, file); + } + + private File saveKeystore(File folder, KeystoreUtil.KeystoreFormat keystoreType, KeyStore keyStore, String keystorePassword) throws Exception { + String fileName = "keystore-" + Time.currentTimeMillis() + "." + keystoreType.getPrimaryExtension(); + File file = new File(folder, fileName); + if (file.exists()) { + throw new RuntimeException("Keystore file already exists: " + file.getAbsolutePath()); + } + FileOutputStream fos = new FileOutputStream(file); + keyStore.store(fos, keystorePassword.trim().toCharArray()); + fos.close(); + return file; + } + +} diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/crypto/KeystoreInfo.java b/test-framework/core/src/main/java/org/keycloak/testframework/crypto/KeystoreInfo.java new file mode 100644 index 00000000000..a0a949fbefb --- /dev/null +++ b/test-framework/core/src/main/java/org/keycloak/testframework/crypto/KeystoreInfo.java @@ -0,0 +1,23 @@ +package org.keycloak.testframework.crypto; + +import org.keycloak.representations.idm.CertificateRepresentation; + +import java.io.File; + +public class KeystoreInfo { + private final CertificateRepresentation certificateInfo; + private final File keystoreFile; + + KeystoreInfo(CertificateRepresentation certificateInfo, File keystoreFile) { + this.certificateInfo = certificateInfo; + this.keystoreFile = keystoreFile; + } + + public CertificateRepresentation getCertificateInfo() { + return certificateInfo; + } + + public File getKeystoreFile() { + return keystoreFile; + } +} diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/injection/SuiteSupport.java b/test-framework/core/src/main/java/org/keycloak/testframework/injection/SuiteSupport.java index b824450c537..a64f204733e 100644 --- a/test-framework/core/src/main/java/org/keycloak/testframework/injection/SuiteSupport.java +++ b/test-framework/core/src/main/java/org/keycloak/testframework/injection/SuiteSupport.java @@ -34,6 +34,11 @@ public class SuiteSupport { return this; } + public SuiteConfig registerSupplierConfig(String supplierValueType, String supplierConfigKey, String supplierConfigValue) { + SuiteConfigSource.set("kc.test." + supplierValueType + "." + supplierConfigKey, supplierConfigValue); + return this; + } + public SuiteConfig supplier(String name, String supplier) { SuiteConfigSource.set("kc.test." + name, supplier); return this; diff --git a/test-framework/oauth/pom.xml b/test-framework/oauth/pom.xml index 75bd3334e9f..454f18e0a3e 100755 --- a/test-framework/oauth/pom.xml +++ b/test-framework/oauth/pom.xml @@ -32,6 +32,10 @@ OAuth extension for Keycloak Test Framework + + org.keycloak + keycloak-client-registration-api + org.keycloak.testframework keycloak-test-framework-core diff --git a/test-framework/oauth/src/main/java/org/keycloak/testframework/oauth/OAuthClient.java b/test-framework/oauth/src/main/java/org/keycloak/testframework/oauth/OAuthClient.java index b022938f619..e255d221cc0 100644 --- a/test-framework/oauth/src/main/java/org/keycloak/testframework/oauth/OAuthClient.java +++ b/test-framework/oauth/src/main/java/org/keycloak/testframework/oauth/OAuthClient.java @@ -2,6 +2,7 @@ package org.keycloak.testframework.oauth; import org.apache.http.impl.client.CloseableHttpClient; import org.keycloak.OAuth2Constants; +import org.keycloak.client.registration.ClientRegistration; import org.keycloak.testframework.ui.page.LoginPage; import org.keycloak.testsuite.util.oauth.AbstractOAuthClient; import org.keycloak.testsuite.util.oauth.OAuthClientConfig; @@ -25,6 +26,10 @@ public class OAuthClient extends AbstractOAuthClient { loginPage.submit(); } + public ClientRegistration clientRegistration() { + return ClientRegistration.create().httpClient(httpClient().get()).url(baseUrl, config.getRealm()).build(); + } + public void close() { } diff --git a/tests/base/src/test/java/org/keycloak/tests/admin/ServerInfoTest.java b/tests/base/src/test/java/org/keycloak/tests/admin/ServerInfoTest.java index 39cff5b3e42..082687229db 100644 --- a/tests/base/src/test/java/org/keycloak/tests/admin/ServerInfoTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/admin/ServerInfoTest.java @@ -30,9 +30,10 @@ import org.keycloak.representations.idm.ConfigPropertyRepresentation; import org.keycloak.representations.info.ProviderRepresentation; import org.keycloak.representations.info.ServerInfoRepresentation; import org.keycloak.testframework.annotations.InjectAdminClient; +import org.keycloak.testframework.annotations.InjectCryptoHelper; import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.crypto.CryptoHelper; import org.keycloak.tests.utils.Assert; -import org.keycloak.tests.utils.FipsUtils; import java.util.Map; @@ -48,6 +49,9 @@ public class ServerInfoTest { @InjectAdminClient Keycloak adminClient; + @InjectCryptoHelper + CryptoHelper cryptoHelper; + @Test public void testServerInfo() { ServerInfoRepresentation info = adminClient.serverInfo().getInfo(); @@ -71,10 +75,8 @@ public class ServerInfoTest { assertNotNull(info.getMemoryInfo()); assertNotNull(info.getSystemInfo()); - FipsUtils fipsUtils = FipsUtils.create(info); - assertNotNull(info.getCryptoInfo()); - Assert.assertNames(info.getCryptoInfo().getSupportedKeystoreTypes(), fipsUtils.getExpectedSupportedKeyStoreTypes()); + Assert.assertNames(info.getCryptoInfo().getSupportedKeystoreTypes(), cryptoHelper.getExpectedSupportedKeyStoreTypes()); Assert.assertNames(info.getCryptoInfo().getClientSignatureSymmetricAlgorithms(), Algorithm.HS256, Algorithm.HS384, Algorithm.HS512); Assert.assertNames(info.getCryptoInfo().getClientSignatureAsymmetricAlgorithms(), Algorithm.ES256, Algorithm.ES384, Algorithm.ES512, @@ -90,7 +92,7 @@ public class ServerInfoTest { .stream() .filter(configProp -> Attributes.KEY_SIZE_KEY.equals(configProp.getName())) .findFirst().orElseThrow(() -> new RuntimeException("Not found provider with ID 'rsa-generated'")); - Assert.assertNames(keySizeRep.getOptions(), fipsUtils.getExpectedSupportedRsaKeySizes()); + Assert.assertNames(keySizeRep.getOptions(), cryptoHelper.getExpectedSupportedRsaKeySizes()); assertEquals(Version.VERSION, info.getSystemInfo().getVersion()); assertNotNull(info.getSystemInfo().getServerTime()); diff --git a/tests/base/src/test/java/org/keycloak/tests/common/BasicRealmWithUserConfig.java b/tests/base/src/test/java/org/keycloak/tests/common/BasicRealmWithUserConfig.java new file mode 100644 index 00000000000..95dd78f9e32 --- /dev/null +++ b/tests/base/src/test/java/org/keycloak/tests/common/BasicRealmWithUserConfig.java @@ -0,0 +1,17 @@ +package org.keycloak.tests.common; + +import org.keycloak.testframework.realm.RealmConfig; +import org.keycloak.testframework.realm.RealmConfigBuilder; + +public class BasicRealmWithUserConfig implements RealmConfig { + + public static final String USERNAME = "basic-user"; + public static final String PASSWORD = "password"; + + @Override + public RealmConfigBuilder configure(RealmConfigBuilder realm) { + realm.addUser("basic-user").password("password").email("basic@localhost").name("First", "Last"); + return realm; + } + +} diff --git a/tests/base/src/test/java/org/keycloak/tests/keys/FallbackKeyProviderTest.java b/tests/base/src/test/java/org/keycloak/tests/keys/FallbackKeyProviderTest.java new file mode 100644 index 00000000000..e6ce04d90a3 --- /dev/null +++ b/tests/base/src/test/java/org/keycloak/tests/keys/FallbackKeyProviderTest.java @@ -0,0 +1,116 @@ +/* + * Copyright 2016 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.tests.keys; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.keycloak.crypto.Algorithm; +import org.keycloak.models.Constants; +import org.keycloak.representations.idm.ComponentRepresentation; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.injection.LifeCycle; +import org.keycloak.testframework.oauth.OAuthClient; +import org.keycloak.testframework.oauth.annotations.InjectOAuthClient; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.tests.common.BasicRealmWithUserConfig; +import org.keycloak.tests.utils.Assert; +import org.keycloak.testsuite.util.oauth.AccessTokenResponse; +import org.keycloak.testsuite.util.oauth.AuthorizationEndpointResponse; + +import java.util.LinkedList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@KeycloakIntegrationTest +public class FallbackKeyProviderTest { + + @InjectRealm(lifecycle = LifeCycle.METHOD, config = BasicRealmWithUserConfig.class) + ManagedRealm realm; + + @InjectOAuthClient + OAuthClient oauth; + + @Test + public void fallbackAfterDeletingAllKeysInRealm() { + String realmId = realm.getId(); + + List providers = realm.admin().components().query(realmId, "org.keycloak.keys.KeyProvider"); + assertEquals(4, providers.size()); + + for (ComponentRepresentation p : providers) { + realm.admin().components().component(p.getId()).remove(); + } + + providers = realm.admin().components().query(realmId, "org.keycloak.keys.KeyProvider"); + assertEquals(0, providers.size()); + + AuthorizationEndpointResponse authorizationEndpointResponse = oauth.doLogin(BasicRealmWithUserConfig.USERNAME, BasicRealmWithUserConfig.PASSWORD); + + AccessTokenResponse response = oauth.doAccessTokenRequest(authorizationEndpointResponse.getCode()); + Assertions.assertTrue(response.isSuccess()); + + providers = realm.admin().components().query(realmId, "org.keycloak.keys.KeyProvider"); + Assert.assertNames(providers, "fallback-RS256", "fallback-AES", "fallback-" + Constants.INTERNAL_SIGNATURE_ALGORITHM); + } + + @Test + public void differentAlgorithms() { + String realmId = realm.admin().toRepresentation().getId(); + + String[] algorithmsToTest = new String[] { + Algorithm.RS384, + Algorithm.RS512, + Algorithm.PS256, + Algorithm.PS384, + Algorithm.PS512, + Algorithm.ES256, + Algorithm.ES384, + Algorithm.ES512 + }; + + oauth.doLogin(BasicRealmWithUserConfig.USERNAME, BasicRealmWithUserConfig.PASSWORD); + + for (String algorithm : algorithmsToTest) { + RealmRepresentation rep = realm.admin().toRepresentation(); + rep.setDefaultSignatureAlgorithm(algorithm); + realm.admin().update(rep); + + AccessTokenResponse response = oauth.doClientCredentialsGrantAccessTokenRequest(); + Assertions.assertTrue(response.isSuccess()); + } + + List providers = realm.admin().components().query(realmId, "org.keycloak.keys.KeyProvider"); + + List expected = new LinkedList<>(); + expected.add("rsa-generated"); + expected.add("rsa-enc-generated"); + expected.add("hmac-generated-hs512"); + expected.add("aes-generated"); + + for (String a : algorithmsToTest) { + expected.add("fallback-" + a); + } + + Assert.assertNames(providers, expected.toArray(new String[providers.size()])); + } + +} + diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/GeneratedEcdhKeyProviderTest.java b/tests/base/src/test/java/org/keycloak/tests/keys/GeneratedEcdhKeyProviderTest.java similarity index 78% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/GeneratedEcdhKeyProviderTest.java rename to tests/base/src/test/java/org/keycloak/tests/keys/GeneratedEcdhKeyProviderTest.java index 5957edb912f..133258dabc7 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/GeneratedEcdhKeyProviderTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/keys/GeneratedEcdhKeyProviderTest.java @@ -14,25 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.keycloak.testsuite.keys; +package org.keycloak.tests.keys; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.keycloak.testsuite.AbstractAdminTest.loadJson; - -import java.security.KeyFactory; -import java.security.interfaces.ECPublicKey; -import java.security.spec.X509EncodedKeySpec; -import java.util.Base64; -import java.util.List; - -import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.Response; - -import org.jboss.arquillian.graphene.page.Page; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.crypto.Algorithm; import org.keycloak.crypto.KeyType; @@ -43,33 +28,36 @@ import org.keycloak.keys.KeyProvider; import org.keycloak.representations.idm.ComponentRepresentation; import org.keycloak.representations.idm.KeysMetadataRepresentation; import org.keycloak.representations.idm.KeysMetadataRepresentation.KeyMetadataRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.testsuite.AbstractKeycloakTest; -import org.keycloak.testsuite.AssertEvents; -import org.keycloak.testsuite.admin.ApiUtil; -import org.keycloak.testsuite.pages.AppPage; -import org.keycloak.testsuite.pages.LoginPage; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.oauth.OAuthClient; +import org.keycloak.testframework.oauth.annotations.InjectOAuthClient; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.testframework.util.ApiUtil; + +import jakarta.ws.rs.core.Response; + +import java.security.KeyFactory; +import java.security.interfaces.ECPublicKey; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@KeycloakIntegrationTest +public class GeneratedEcdhKeyProviderTest { -public class GeneratedEcdhKeyProviderTest extends AbstractKeycloakTest { private static final String DEFAULT_EC = GeneratedEcdhKeyProviderFactory.DEFAULT_ECDH_ELLIPTIC_CURVE; private static final String ECDH_ELLIPTIC_CURVE_KEY = GeneratedEcdhKeyProviderFactory.ECDH_ELLIPTIC_CURVE_KEY; private static final String ECDH_ALGORITHM_KEY = GeneratedEcdhKeyProviderFactory.ECDH_ALGORITHM_KEY; - private static final String TEST_REALM_NAME = "test"; - @Rule - public AssertEvents events = new AssertEvents(this); + @InjectRealm + ManagedRealm realm; - @Page - protected AppPage appPage; - - @Page - protected LoginPage loginPage; - - @Override - public void addTestRealms(List testRealms) { - RealmRepresentation realm = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class); - testRealms.add(realm); - } + @InjectOAuthClient + OAuthClient oauth; @Test public void defaultEcDirect() { @@ -188,12 +176,12 @@ public class GeneratedEcdhKeyProviderTest extends AbstractKeycloakTest { } rep.getConfig().putSingle(ECDH_ALGORITHM_KEY, algorithm); - Response response = adminClient.realm(TEST_REALM_NAME).components().add(rep); + Response response = realm.admin().components().add(rep); String id = ApiUtil.getCreatedId(response); - getCleanup().addComponentId(id); + realm.cleanup().add(r -> r.components().component(id).remove()); response.close(); - ComponentRepresentation createdRep = adminClient.realm(TEST_REALM_NAME).components().component(id).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(id).toRepresentation(); // stands for the number of properties in the key provider config assertEquals(3, createdRep.getConfig().size()); @@ -201,7 +189,7 @@ public class GeneratedEcdhKeyProviderTest extends AbstractKeycloakTest { assertEquals(ecInNistRep, createdRep.getConfig().getFirst(ECDH_ELLIPTIC_CURVE_KEY)); assertEquals(algorithm, createdRep.getConfig().getFirst(ECDH_ALGORITHM_KEY)); - KeysMetadataRepresentation keys = adminClient.realm(TEST_REALM_NAME).keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); KeysMetadataRepresentation.KeyMetadataRepresentation key = null; @@ -229,20 +217,10 @@ public class GeneratedEcdhKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle(Attributes.PRIORITY_KEY, Long.toString(priority)); rep.getConfig().putSingle(ECDH_ELLIPTIC_CURVE_KEY, ecInNistRep); rep.getConfig().putSingle(ECDH_ALGORITHM_KEY, algorithmMode); - boolean isEcAccepted = true; - Response response = null; - try { - response = adminClient.realm(TEST_REALM_NAME).components().add(rep); - String id = ApiUtil.getCreatedId(response); - getCleanup().addComponentId(id); - response.close(); - } catch (WebApplicationException e) { - isEcAccepted = false; - } finally { - response.close(); - } - assertEquals(isEcAccepted, false); + Response response = realm.admin().components().add(rep); + Assertions.assertEquals(400, response.getStatus()); + response.close(); } @Test @@ -278,7 +256,7 @@ public class GeneratedEcdhKeyProviderTest extends AbstractKeycloakTest { private void changeCurve(String fromEcInNistRep, String toEcInNistRep, String fromAlgorithm, String toAlgorithm) throws Exception { String keyComponentId = supportedEc(fromEcInNistRep, fromAlgorithm); - KeysMetadataRepresentation keys = adminClient.realm(TEST_REALM_NAME).keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); KeysMetadataRepresentation.KeyMetadataRepresentation originalKey = null; for (KeyMetadataRepresentation k : keys.getKeys()) { if (KeyType.EC.equals(k.getType()) && keyComponentId.equals(k.getProviderId())) { @@ -287,19 +265,19 @@ public class GeneratedEcdhKeyProviderTest extends AbstractKeycloakTest { } } - ComponentRepresentation createdRep = adminClient.realm(TEST_REALM_NAME).components().component(keyComponentId).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(keyComponentId).toRepresentation(); createdRep.getConfig().putSingle(ECDH_ELLIPTIC_CURVE_KEY, toEcInNistRep); createdRep.getConfig().putSingle(ECDH_ALGORITHM_KEY, toAlgorithm); - adminClient.realm(TEST_REALM_NAME).components().component(keyComponentId).update(createdRep); + realm.admin().components().component(keyComponentId).update(createdRep); - createdRep = adminClient.realm(TEST_REALM_NAME).components().component(keyComponentId).toRepresentation(); + createdRep = realm.admin().components().component(keyComponentId).toRepresentation(); // stands for the number of properties in the key provider config assertEquals(3, createdRep.getConfig().size()); assertEquals(toEcInNistRep, createdRep.getConfig().getFirst(ECDH_ELLIPTIC_CURVE_KEY)); assertEquals(toAlgorithm, createdRep.getConfig().getFirst(ECDH_ALGORITHM_KEY)); - keys = adminClient.realm(TEST_REALM_NAME).keys().getKeyMetadata(); + keys = realm.admin().keys().getKeyMetadata(); KeysMetadataRepresentation.KeyMetadataRepresentation key = null; for (KeyMetadataRepresentation k : keys.getKeys()) { if (KeyType.EC.equals(k.getType()) && keyComponentId.equals(k.getProviderId())) { @@ -321,7 +299,7 @@ public class GeneratedEcdhKeyProviderTest extends AbstractKeycloakTest { protected ComponentRepresentation createRep(String name, String providerId) { ComponentRepresentation rep = new ComponentRepresentation(); rep.setName(name); - rep.setParentId(adminClient.realm(TEST_REALM_NAME).toRepresentation().getId()); + rep.setParentId(realm.admin().toRepresentation().getId()); rep.setProviderId(providerId); rep.setProviderType(KeyProvider.class.getName()); rep.setConfig(new MultivaluedHashMap<>()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/GeneratedEcdsaKeyProviderTest.java b/tests/base/src/test/java/org/keycloak/tests/keys/GeneratedEcdsaKeyProviderTest.java similarity index 74% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/GeneratedEcdsaKeyProviderTest.java rename to tests/base/src/test/java/org/keycloak/tests/keys/GeneratedEcdsaKeyProviderTest.java index 218acab73e1..4768b61f55b 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/GeneratedEcdsaKeyProviderTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/keys/GeneratedEcdsaKeyProviderTest.java @@ -14,26 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.keycloak.testsuite.keys; +package org.keycloak.tests.keys; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.keycloak.testsuite.AbstractAdminTest.loadJson; - -import java.security.KeyFactory; -import java.security.cert.X509Certificate; -import java.security.interfaces.ECPublicKey; -import java.security.spec.X509EncodedKeySpec; -import java.util.Base64; -import java.util.List; - -import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.Response; - -import org.jboss.arquillian.graphene.page.Page; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.common.util.PemUtils; import org.keycloak.crypto.KeyType; @@ -43,33 +27,32 @@ import org.keycloak.keys.KeyProvider; import org.keycloak.representations.idm.ComponentRepresentation; import org.keycloak.representations.idm.KeysMetadataRepresentation; import org.keycloak.representations.idm.KeysMetadataRepresentation.KeyMetadataRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.testsuite.AbstractKeycloakTest; -import org.keycloak.testsuite.AssertEvents; -import org.keycloak.testsuite.admin.ApiUtil; -import org.keycloak.testsuite.pages.AppPage; -import org.keycloak.testsuite.pages.LoginPage; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.testframework.util.ApiUtil; + +import jakarta.ws.rs.core.Response; + +import java.security.KeyFactory; +import java.security.cert.X509Certificate; +import java.security.interfaces.ECPublicKey; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@KeycloakIntegrationTest +public class GeneratedEcdsaKeyProviderTest { -public class GeneratedEcdsaKeyProviderTest extends AbstractKeycloakTest { private static final String DEFAULT_EC = GeneratedEcdsaKeyProviderFactory.DEFAULT_ECDSA_ELLIPTIC_CURVE; private static final String ECDSA_ELLIPTIC_CURVE_KEY = GeneratedEcdsaKeyProviderFactory.ECDSA_ELLIPTIC_CURVE_KEY; private static final String TEST_REALM_NAME = "test"; - @Rule - public AssertEvents events = new AssertEvents(this); - - @Page - protected AppPage appPage; - - @Page - protected LoginPage loginPage; - - @Override - public void addTestRealms(List testRealms) { - RealmRepresentation realm = loadJson(getClass().getResourceAsStream("/testrealm.json"), - RealmRepresentation.class); - testRealms.add(realm); - } + @InjectRealm + ManagedRealm realm; @Test public void defaultEc() { @@ -133,12 +116,12 @@ public class GeneratedEcdsaKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle(Attributes.EC_GENERATE_CERTIFICATE_KEY, "true"); } - Response response = adminClient.realm(TEST_REALM_NAME).components().add(rep); + Response response = realm.admin().components().add(rep); String id = ApiUtil.getCreatedId(response); - getCleanup().addComponentId(id); + realm.cleanup().add(r -> r.components().component(id).remove()); response.close(); - ComponentRepresentation createdRep = adminClient.realm(TEST_REALM_NAME).components().component(id).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(id).toRepresentation(); // stands for the number of properties in the key provider config assertEquals(withCertificate ? 3 : 2, createdRep.getConfig().size()); @@ -148,7 +131,7 @@ public class GeneratedEcdsaKeyProviderTest extends AbstractKeycloakTest { assertNotNull(createdRep.getConfig().getFirst(Attributes.EC_GENERATE_CERTIFICATE_KEY)); } - KeysMetadataRepresentation keys = adminClient.realm(TEST_REALM_NAME).keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); KeysMetadataRepresentation.KeyMetadataRepresentation key = null; @@ -166,7 +149,7 @@ public class GeneratedEcdsaKeyProviderTest extends AbstractKeycloakTest { if (withCertificate) { assertNotNull(key.getCertificate()); X509Certificate certificate = PemUtils.decodeCertificate(key.getCertificate()); - final String expectedIssuerAndSubject = "CN=" + TEST_REALM_NAME; + final String expectedIssuerAndSubject = "CN=" + realm.getName(); assertEquals(expectedIssuerAndSubject, certificate.getIssuerX500Principal().getName()); assertEquals(expectedIssuerAndSubject, certificate.getSubjectX500Principal().getName()); } @@ -181,20 +164,10 @@ public class GeneratedEcdsaKeyProviderTest extends AbstractKeycloakTest { rep.setConfig(new MultivaluedHashMap<>()); rep.getConfig().putSingle("priority", Long.toString(priority)); rep.getConfig().putSingle(ECDSA_ELLIPTIC_CURVE_KEY, ecInNistRep); - boolean isEcAccepted = true; - Response response = null; - try { - response = adminClient.realm(TEST_REALM_NAME).components().add(rep); - String id = ApiUtil.getCreatedId(response); - getCleanup().addComponentId(id); - response.close(); - } catch (WebApplicationException e) { - isEcAccepted = false; - } finally { - response.close(); - } - assertEquals(isEcAccepted, false); + Response response = realm.admin().components().add(rep); + response.close(); + Assertions.assertEquals(400, response.getStatus()); } @Test @@ -214,7 +187,7 @@ public class GeneratedEcdsaKeyProviderTest extends AbstractKeycloakTest { private void changeCurve(String FromEcInNistRep, String ToEcInNistRep) throws Exception { String keyComponentId = supportedEc(FromEcInNistRep, false); - KeysMetadataRepresentation keys = adminClient.realm(TEST_REALM_NAME).keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); KeysMetadataRepresentation.KeyMetadataRepresentation originalKey = null; for (KeyMetadataRepresentation k : keys.getKeys()) { if (KeyType.EC.equals(k.getType()) && keyComponentId.equals(k.getProviderId())) { @@ -223,17 +196,17 @@ public class GeneratedEcdsaKeyProviderTest extends AbstractKeycloakTest { } } - ComponentRepresentation createdRep = adminClient.realm(TEST_REALM_NAME).components().component(keyComponentId).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(keyComponentId).toRepresentation(); createdRep.getConfig().putSingle(ECDSA_ELLIPTIC_CURVE_KEY, ToEcInNistRep); - adminClient.realm(TEST_REALM_NAME).components().component(keyComponentId).update(createdRep); + realm.admin().components().component(keyComponentId).update(createdRep); - createdRep = adminClient.realm(TEST_REALM_NAME).components().component(keyComponentId).toRepresentation(); + createdRep = realm.admin().components().component(keyComponentId).toRepresentation(); // stands for the number of properties in the key provider config assertEquals(2, createdRep.getConfig().size()); assertEquals(ToEcInNistRep, createdRep.getConfig().getFirst(ECDSA_ELLIPTIC_CURVE_KEY)); - keys = adminClient.realm(TEST_REALM_NAME).keys().getKeyMetadata(); + keys = realm.admin().keys().getKeyMetadata(); KeysMetadataRepresentation.KeyMetadataRepresentation key = null; for (KeyMetadataRepresentation k : keys.getKeys()) { if (KeyType.EC.equals(k.getType()) && keyComponentId.equals(k.getProviderId())) { @@ -254,7 +227,7 @@ public class GeneratedEcdsaKeyProviderTest extends AbstractKeycloakTest { protected ComponentRepresentation createRep(String name, String providerId) { ComponentRepresentation rep = new ComponentRepresentation(); rep.setName(name); - rep.setParentId(adminClient.realm(TEST_REALM_NAME).toRepresentation().getId()); + rep.setParentId(realm.admin().toRepresentation().getId()); rep.setProviderId(providerId); rep.setProviderType(KeyProvider.class.getName()); rep.setConfig(new MultivaluedHashMap<>()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/GeneratedHmacKeyProviderTest.java b/tests/base/src/test/java/org/keycloak/tests/keys/GeneratedHmacKeyProviderTest.java similarity index 64% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/GeneratedHmacKeyProviderTest.java rename to tests/base/src/test/java/org/keycloak/tests/keys/GeneratedHmacKeyProviderTest.java index dc15b8e1853..817d6989cdc 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/GeneratedHmacKeyProviderTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/keys/GeneratedHmacKeyProviderTest.java @@ -15,11 +15,9 @@ * limitations under the License. */ -package org.keycloak.testsuite.keys; +package org.keycloak.tests.keys; -import org.jboss.arquillian.graphene.page.Page; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.keycloak.common.util.Base64Url; import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.crypto.Algorithm; @@ -29,40 +27,30 @@ import org.keycloak.keys.KeyProvider; import org.keycloak.representations.idm.ComponentRepresentation; import org.keycloak.representations.idm.ErrorRepresentation; import org.keycloak.representations.idm.KeysMetadataRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.testsuite.AbstractKeycloakTest; -import org.keycloak.testsuite.AssertEvents; -import org.keycloak.testsuite.admin.ApiUtil; -import org.keycloak.testsuite.pages.AppPage; -import org.keycloak.testsuite.pages.LoginPage; -import org.keycloak.testsuite.runonserver.RunHelpers; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.testframework.remote.runonserver.InjectRunOnServer; +import org.keycloak.testframework.remote.runonserver.RunOnServerClient; +import org.keycloak.testframework.util.ApiUtil; +import org.keycloak.tests.utils.runonserver.RunHelpers; import jakarta.ws.rs.core.Response; -import java.util.List; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.keycloak.testsuite.AbstractAdminTest.loadJson; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; /** * @author Stian Thorgersen */ -public class GeneratedHmacKeyProviderTest extends AbstractKeycloakTest { +@KeycloakIntegrationTest +public class GeneratedHmacKeyProviderTest { - @Rule - public AssertEvents events = new AssertEvents(this); + @InjectRealm + ManagedRealm realm; - @Page - protected AppPage appPage; - - @Page - protected LoginPage loginPage; - - @Override - public void addTestRealms(List testRealms) { - RealmRepresentation realm = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class); - testRealms.add(realm); - } + @InjectRunOnServer + RunOnServerClient runOnServer; @Test public void defaultKeysize() throws Exception { @@ -72,15 +60,15 @@ public class GeneratedHmacKeyProviderTest extends AbstractKeycloakTest { rep.setConfig(new MultivaluedHashMap<>()); rep.getConfig().putSingle("priority", Long.toString(priority)); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); String id = ApiUtil.getCreatedId(response); response.close(); - ComponentRepresentation createdRep = adminClient.realm("test").components().component(id).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(id).toRepresentation(); assertEquals(1, createdRep.getConfig().size()); assertEquals(Long.toString(priority), createdRep.getConfig().getFirst("priority")); - KeysMetadataRepresentation keys = adminClient.realm("test").keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); KeysMetadataRepresentation.KeyMetadataRepresentation key = null; for (KeysMetadataRepresentation.KeyMetadataRepresentation k : keys.getKeys()) { @@ -94,7 +82,7 @@ public class GeneratedHmacKeyProviderTest extends AbstractKeycloakTest { assertEquals(KeyType.OCT, key.getType()); assertEquals(priority, key.getProviderPriority()); - ComponentRepresentation component = testingClient.server("test").fetch(RunHelpers.internalComponent(id)); + ComponentRepresentation component = runOnServer.fetch(RunHelpers.internalComponent(id)); assertEquals(GeneratedHmacKeyProviderFactory.DEFAULT_HMAC_KEY_SIZE, Base64Url.decode(component.getConfig().getFirst("secret")).length); } @@ -107,15 +95,15 @@ public class GeneratedHmacKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle("priority", Long.toString(priority)); rep.getConfig().putSingle("secretSize", "512"); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); String id = ApiUtil.getCreatedId(response); response.close(); - ComponentRepresentation createdRep = adminClient.realm("test").components().component(id).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(id).toRepresentation(); assertEquals(2, createdRep.getConfig().size()); assertEquals("512", createdRep.getConfig().getFirst("secretSize")); - KeysMetadataRepresentation keys = adminClient.realm("test").keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); KeysMetadataRepresentation.KeyMetadataRepresentation key = null; for (KeysMetadataRepresentation.KeyMetadataRepresentation k : keys.getKeys()) { @@ -129,7 +117,7 @@ public class GeneratedHmacKeyProviderTest extends AbstractKeycloakTest { assertEquals(KeyType.OCT, key.getType()); assertEquals(priority, key.getProviderPriority()); - ComponentRepresentation component = testingClient.server("test").fetch(RunHelpers.internalComponent(id)); + ComponentRepresentation component = runOnServer.fetch(RunHelpers.internalComponent(id)); assertEquals(512, Base64Url.decode(component.getConfig().getFirst("secret")).length); } @@ -141,30 +129,30 @@ public class GeneratedHmacKeyProviderTest extends AbstractKeycloakTest { rep.setConfig(new MultivaluedHashMap<>()); rep.getConfig().putSingle("priority", Long.toString(priority)); - try (Response response = adminClient.realm("test").components().add(rep)) { + try (Response response = realm.admin().components().add(rep)) { rep.setId(ApiUtil.getCreatedId(response)); } - ComponentRepresentation component = testingClient.server("test").fetch(RunHelpers.internalComponent(rep.getId())); + ComponentRepresentation component = runOnServer.fetch(RunHelpers.internalComponent(rep.getId())); assertEquals(GeneratedHmacKeyProviderFactory.DEFAULT_HMAC_KEY_SIZE, Base64Url.decode(component.getConfig().getFirst("secret")).length); - ComponentRepresentation createdRep = adminClient.realm("test").components().component(rep.getId()).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(rep.getId()).toRepresentation(); createdRep.getConfig().putSingle("secretSize", "512"); - adminClient.realm("test").components().component(rep.getId()).update(createdRep); + realm.admin().components().component(rep.getId()).update(createdRep); - component = testingClient.server("test").fetch(RunHelpers.internalComponent(rep.getId())); + component = runOnServer.fetch(RunHelpers.internalComponent(rep.getId())); assertEquals(512, Base64Url.decode(component.getConfig().getFirst("secret")).length); - component = testingClient.server("test").fetch(RunHelpers.internalComponent(rep.getId())); + component = runOnServer.fetch(RunHelpers.internalComponent(rep.getId())); String secret = component.getConfig().getFirst("secret"); - createdRep = adminClient.realm("test").components().component(rep.getId()).toRepresentation(); + createdRep = realm.admin().components().component(rep.getId()).toRepresentation(); createdRep.getConfig().putSingle("secretSize", ""); - adminClient.realm("test").components().component(rep.getId()).update(createdRep); + realm.admin().components().component(rep.getId()).update(createdRep); - component = testingClient.server("test").fetch(RunHelpers.internalComponent(rep.getId())); + component = runOnServer.fetch(RunHelpers.internalComponent(rep.getId())); assertEquals("512", component.getConfig().getFirst("secretSize")); assertEquals(512, Base64Url.decode(component.getConfig().getFirst("secret")).length); - component = testingClient.server("test").fetch(RunHelpers.internalComponent(rep.getId())); + component = runOnServer.fetch(RunHelpers.internalComponent(rep.getId())); assertEquals(secret, component.getConfig().getFirst("secret")); } @@ -173,7 +161,7 @@ public class GeneratedHmacKeyProviderTest extends AbstractKeycloakTest { ComponentRepresentation rep = createRep("invalid", GeneratedHmacKeyProviderFactory.ID); rep.getConfig().putSingle("secretSize", "1234"); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); assertErrror(response, "'Secret size' should be 16, 24, 32, 64, 128, 256 or 512"); } @@ -189,7 +177,7 @@ public class GeneratedHmacKeyProviderTest extends AbstractKeycloakTest { protected ComponentRepresentation createRep(String name, String providerId) { ComponentRepresentation rep = new ComponentRepresentation(); rep.setName(name); - rep.setParentId(adminClient.realm("test").toRepresentation().getId()); + rep.setParentId(realm.admin().toRepresentation().getId()); rep.setProviderId(providerId); rep.setProviderType(KeyProvider.class.getName()); rep.setConfig(new MultivaluedHashMap<>()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/GeneratedRsaKeyProviderTest.java b/tests/base/src/test/java/org/keycloak/tests/keys/GeneratedRsaKeyProviderTest.java similarity index 71% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/GeneratedRsaKeyProviderTest.java rename to tests/base/src/test/java/org/keycloak/tests/keys/GeneratedRsaKeyProviderTest.java index c5e44521f89..d24d5d4b158 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/GeneratedRsaKeyProviderTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/keys/GeneratedRsaKeyProviderTest.java @@ -15,11 +15,9 @@ * limitations under the License. */ -package org.keycloak.testsuite.keys; +package org.keycloak.tests.keys; -import org.jboss.arquillian.graphene.page.Page; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.common.util.PemUtils; import org.keycloak.crypto.KeyUse; @@ -30,44 +28,34 @@ import org.keycloak.keys.KeyProvider; import org.keycloak.representations.idm.ComponentRepresentation; import org.keycloak.representations.idm.ErrorRepresentation; import org.keycloak.representations.idm.KeysMetadataRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.testsuite.AbstractKeycloakTest; -import org.keycloak.testsuite.AssertEvents; -import org.keycloak.testsuite.admin.ApiUtil; -import org.keycloak.testsuite.pages.AppPage; -import org.keycloak.testsuite.pages.LoginPage; -import org.keycloak.testsuite.util.KeyUtils; +import org.keycloak.testframework.annotations.InjectCryptoHelper; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.crypto.CryptoHelper; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.testframework.util.ApiUtil; import org.keycloak.utils.StringUtil; import jakarta.ws.rs.core.Response; + import java.security.interfaces.RSAPublicKey; import java.util.Arrays; -import java.util.List; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.fail; -import static org.keycloak.testsuite.AbstractAdminTest.loadJson; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.fail; /** * @author Stian Thorgersen */ -public class GeneratedRsaKeyProviderTest extends AbstractKeycloakTest { +@KeycloakIntegrationTest +public class GeneratedRsaKeyProviderTest { - @Rule - public AssertEvents events = new AssertEvents(this); + @InjectRealm + ManagedRealm realm; - @Page - protected AppPage appPage; - - @Page - protected LoginPage loginPage; - - @Override - public void addTestRealms(List testRealms) { - RealmRepresentation realm = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class); - testRealms.add(realm); - } + @InjectCryptoHelper + CryptoHelper cryptoHelper; @Test public void defaultKeysizeForSig() throws Exception { @@ -86,16 +74,16 @@ public class GeneratedRsaKeyProviderTest extends AbstractKeycloakTest { rep.setConfig(new MultivaluedHashMap<>()); rep.getConfig().putSingle("priority", Long.toString(priority)); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); String id = ApiUtil.getCreatedId(response); - getCleanup().addComponentId(id); + realm.cleanup().add(r -> r.components().component(id).remove()); response.close(); - ComponentRepresentation createdRep = adminClient.realm("test").components().component(id).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(id).toRepresentation(); assertEquals(1, createdRep.getConfig().size()); assertEquals(Long.toString(priority), createdRep.getConfig().getFirst("priority")); - KeysMetadataRepresentation keys = adminClient.realm("test").keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); KeysMetadataRepresentation.KeyMetadataRepresentation key = keys.getKeys().get(0); @@ -124,16 +112,16 @@ public class GeneratedRsaKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle("priority", Long.toString(priority)); rep.getConfig().putSingle("keySize", "4096"); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); String id = ApiUtil.getCreatedId(response); - getCleanup().addComponentId(id); + realm.cleanup().add(r -> r.components().component(id).remove()); response.close(); - ComponentRepresentation createdRep = adminClient.realm("test").components().component(id).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(id).toRepresentation(); assertEquals(2, createdRep.getConfig().size()); assertEquals("4096", createdRep.getConfig().getFirst("keySize")); - KeysMetadataRepresentation keys = adminClient.realm("test").keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); KeysMetadataRepresentation.KeyMetadataRepresentation key = keys.getKeys().get(0); @@ -161,23 +149,23 @@ public class GeneratedRsaKeyProviderTest extends AbstractKeycloakTest { rep.setConfig(new MultivaluedHashMap<>()); rep.getConfig().putSingle("priority", Long.toString(priority)); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); String id = ApiUtil.getCreatedId(response); - getCleanup().addComponentId(id); + realm.cleanup().add(r -> r.components().component(id).remove()); response.close(); - KeysMetadataRepresentation keys = adminClient.realm("test").keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); String publicKey = keys.getKeys().get(0).getPublicKey(); - ComponentRepresentation createdRep = adminClient.realm("test").components().component(id).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(id).toRepresentation(); priority += 1000; createdRep.getConfig().putSingle("priority", Long.toString(priority)); - adminClient.realm("test").components().component(id).update(createdRep); + realm.admin().components().component(id).update(createdRep); - keys = adminClient.realm("test").keys().getKeyMetadata(); + keys = realm.admin().keys().getKeyMetadata(); String publicKey2 = keys.getKeys().get(0).getPublicKey(); @@ -202,20 +190,20 @@ public class GeneratedRsaKeyProviderTest extends AbstractKeycloakTest { rep.setConfig(new MultivaluedHashMap<>()); rep.getConfig().putSingle("priority", Long.toString(priority)); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); String id = ApiUtil.getCreatedId(response); - getCleanup().addComponentId(id); + realm.cleanup().add(r -> r.components().component(id).remove()); response.close(); - KeysMetadataRepresentation keys = adminClient.realm("test").keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); String publicKey = keys.getKeys().get(0).getPublicKey(); - ComponentRepresentation createdRep = adminClient.realm("test").components().component(id).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(id).toRepresentation(); createdRep.getConfig().putSingle("keySize", "4096"); - adminClient.realm("test").components().component(id).update(createdRep); + realm.admin().components().component(id).update(createdRep); - keys = adminClient.realm("test").keys().getKeyMetadata(); + keys = realm.admin().keys().getKeyMetadata(); String publicKey2 = keys.getKeys().get(0).getPublicKey(); @@ -239,8 +227,8 @@ public class GeneratedRsaKeyProviderTest extends AbstractKeycloakTest { ComponentRepresentation rep = createRep("invalid", providerId); rep.getConfig().putSingle("keySize", "1234"); - Response response = adminClient.realm("test").components().add(rep); - String expectedKeySizesDisplay = StringUtil.joinValuesWithLogicalCondition("or", Arrays.asList(KeyUtils.getExpectedSupportedRsaKeySizes())); + Response response = realm.admin().components().add(rep); + String expectedKeySizesDisplay = StringUtil.joinValuesWithLogicalCondition("or", Arrays.asList(cryptoHelper.getExpectedSupportedRsaKeySizes())); assertErrror(response, "'Key size' should be " + expectedKeySizesDisplay); } @@ -257,7 +245,7 @@ public class GeneratedRsaKeyProviderTest extends AbstractKeycloakTest { protected ComponentRepresentation createRep(String name, String providerId) { ComponentRepresentation rep = new ComponentRepresentation(); rep.setName(name); - rep.setParentId(adminClient.realm("test").toRepresentation().getId()); + rep.setParentId(realm.admin().toRepresentation().getId()); rep.setProviderId(providerId); rep.setProviderType(KeyProvider.class.getName()); rep.setConfig(new MultivaluedHashMap<>()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/ImportedRsaKeyProviderTest.java b/tests/base/src/test/java/org/keycloak/tests/keys/ImportedRsaKeyProviderTest.java similarity index 78% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/ImportedRsaKeyProviderTest.java rename to tests/base/src/test/java/org/keycloak/tests/keys/ImportedRsaKeyProviderTest.java index cecfd63b63c..0ffd6708d59 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/ImportedRsaKeyProviderTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/keys/ImportedRsaKeyProviderTest.java @@ -15,11 +15,9 @@ * limitations under the License. */ -package org.keycloak.testsuite.keys; +package org.keycloak.tests.keys; -import org.jboss.arquillian.graphene.page.Page; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.keycloak.common.util.CertificateUtils; import org.keycloak.common.util.KeyUtils; import org.keycloak.common.util.MultivaluedHashMap; @@ -35,47 +33,43 @@ import org.keycloak.keys.KeyProvider; import org.keycloak.representations.idm.ComponentRepresentation; import org.keycloak.representations.idm.ErrorRepresentation; import org.keycloak.representations.idm.KeysMetadataRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.testsuite.AbstractKeycloakTest; -import org.keycloak.testsuite.AssertEvents; -import org.keycloak.testsuite.admin.ApiUtil; -import org.keycloak.testsuite.pages.AppPage; -import org.keycloak.testsuite.pages.LoginPage; -import org.keycloak.testsuite.saml.AbstractSamlTest; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.oauth.OAuthClient; +import org.keycloak.testframework.oauth.annotations.InjectOAuthClient; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.testframework.remote.timeoffset.InjectTimeOffSet; +import org.keycloak.testframework.remote.timeoffset.TimeOffSet; +import org.keycloak.testframework.util.ApiUtil; +import org.keycloak.testsuite.util.saml.SamlConstants; import jakarta.ws.rs.core.Response; + import java.math.BigInteger; import java.security.KeyPair; import java.security.cert.Certificate; -import java.util.List; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Date; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import static org.keycloak.testsuite.AbstractAdminTest.loadJson; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.fail; /** * @author Stian Thorgersen */ -public class ImportedRsaKeyProviderTest extends AbstractKeycloakTest { +@KeycloakIntegrationTest +public class ImportedRsaKeyProviderTest { - @Rule - public AssertEvents events = new AssertEvents(this); + @InjectRealm + ManagedRealm realm; - @Page - protected AppPage appPage; + @InjectOAuthClient + OAuthClient oAuth; - @Page - protected LoginPage loginPage; - - @Override - public void addTestRealms(List testRealms) { - RealmRepresentation realm = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class); - testRealms.add(realm); - } + @InjectTimeOffSet + TimeOffSet timeOffSet; @Test public void privateKeyOnlyForSig() throws Exception { @@ -97,17 +91,17 @@ public class ImportedRsaKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle(Attributes.PRIVATE_KEY_KEY, PemUtils.encodeKey(keyPair.getPrivate())); rep.getConfig().putSingle(Attributes.PRIORITY_KEY, Long.toString(priority)); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); String id = ApiUtil.getCreatedId(response); response.close(); - ComponentRepresentation createdRep = adminClient.realm("test").components().component(id).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(id).toRepresentation(); assertEquals(ComponentRepresentation.SECRET_VALUE, createdRep.getConfig().getFirst(Attributes.PRIVATE_KEY_KEY)); assertNotNull(createdRep.getConfig().getFirst(Attributes.CERTIFICATE_KEY)); assertEquals(keyPair.getPublic(), PemUtils.decodeCertificate(createdRep.getConfig().getFirst(Attributes.CERTIFICATE_KEY)).getPublicKey()); - KeysMetadataRepresentation keys = adminClient.realm("test").keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); assertEquals(kid, keys.getActive().get(algorithm)); @@ -144,15 +138,15 @@ public class ImportedRsaKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle(Attributes.CERTIFICATE_KEY, certificatePem); rep.getConfig().putSingle(Attributes.PRIORITY_KEY, Long.toString(priority)); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); String id = ApiUtil.getCreatedId(response); response.close(); - ComponentRepresentation createdRep = adminClient.realm("test").components().component(id).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(id).toRepresentation(); assertEquals(ComponentRepresentation.SECRET_VALUE, createdRep.getConfig().getFirst(Attributes.PRIVATE_KEY_KEY)); assertEquals(certificatePem, createdRep.getConfig().getFirst(Attributes.CERTIFICATE_KEY)); - KeysMetadataRepresentation keys = adminClient.realm("test").keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); KeysMetadataRepresentation.KeyMetadataRepresentation key = keys.getKeys().get(0); assertEquals(certificatePem, key.getCertificate()); @@ -176,7 +170,7 @@ public class ImportedRsaKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle(Attributes.PRIVATE_KEY_KEY, PemUtils.encodeKey(keyPair.getPrivate())); rep.getConfig().putSingle(Attributes.PRIORITY_KEY, "invalid"); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); assertError(response, "'Priority' should be a number"); } @@ -197,7 +191,7 @@ public class ImportedRsaKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle(Attributes.PRIVATE_KEY_KEY, PemUtils.encodeKey(keyPair.getPrivate())); rep.getConfig().putSingle(Attributes.ENABLED_KEY, "invalid"); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); assertError(response, "'Enabled' should be 'true' or 'false'"); } @@ -218,7 +212,7 @@ public class ImportedRsaKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle(Attributes.PRIVATE_KEY_KEY, PemUtils.encodeKey(keyPair.getPrivate())); rep.getConfig().putSingle(Attributes.ACTIVE_KEY, "invalid"); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); assertError(response, "'Active' should be 'true' or 'false'"); } @@ -237,15 +231,15 @@ public class ImportedRsaKeyProviderTest extends AbstractKeycloakTest { ComponentRepresentation rep = createRep("invalid", providerId); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); assertError(response, "'Private RSA Key' is required"); rep.getConfig().putSingle(Attributes.PRIVATE_KEY_KEY, "nonsense"); - response = adminClient.realm("test").components().add(rep); + response = realm.admin().components().add(rep); assertError(response, "Failed to decode private key"); rep.getConfig().putSingle(Attributes.PRIVATE_KEY_KEY, PemUtils.encodeKey(keyPair.getPublic())); - response = adminClient.realm("test").components().add(rep); + response = realm.admin().components().add(rep); assertError(response, "Failed to decode private key"); } @@ -262,10 +256,10 @@ public class ImportedRsaKeyProviderTest extends AbstractKeycloakTest { @Test public void invalidExpiredCertificate() throws Exception { ComponentRepresentation rep = createRep("invalid", ImportedRsaEncKeyProviderFactory.ID); - rep.getConfig().putSingle(Attributes.PRIVATE_KEY_KEY, AbstractSamlTest.SAML_CLIENT_SALES_POST_SIG_EXPIRED_PRIVATE_KEY); + rep.getConfig().putSingle(Attributes.PRIVATE_KEY_KEY, SamlConstants.SAML_CLIENT_SALES_POST_SIG_EXPIRED_PRIVATE_KEY); - rep.getConfig().putSingle(Attributes.CERTIFICATE_KEY, AbstractSamlTest.SAML_CLIENT_SALES_POST_SIG_EXPIRED_CERTIFICATE); - Response response = adminClient.realm("test").components().add(rep); + rep.getConfig().putSingle(Attributes.CERTIFICATE_KEY, SamlConstants.SAML_CLIENT_SALES_POST_SIG_EXPIRED_CERTIFICATE); + Response response = realm.admin().components().add(rep); assertError(response, "Certificate is not valid"); } @@ -285,24 +279,24 @@ public class ImportedRsaKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle(Attributes.PRIORITY_KEY, Long.toString(priority)); String id; - try (Response response = adminClient.realm("test").components().add(rep)) { + try (Response response = realm.admin().components().add(rep)) { id = ApiUtil.getCreatedId(response); } - ComponentRepresentation createdRep = adminClient.realm("test").components().component(id).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(id).toRepresentation(); assertEquals(ComponentRepresentation.SECRET_VALUE, createdRep.getConfig().getFirst(Attributes.PRIVATE_KEY_KEY)); assertEquals(certificatePem, createdRep.getConfig().getFirst(Attributes.CERTIFICATE_KEY)); - KeysMetadataRepresentation keys = adminClient.realm("test").keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); KeysMetadataRepresentation.KeyMetadataRepresentation key = keys.getKeys().get(0); assertEquals(certificatePem, key.getCertificate()); assertEquals(KeyUse.SIG, key.getUse()); assertEquals(KeyStatus.ACTIVE.name(), key.getStatus()); - setTimeOffset(3610); + timeOffSet.set(3610); - keys = adminClient.realm("test").keys().getKeyMetadata(); + keys = realm.admin().keys().getKeyMetadata(); key = keys.getKeys().get(0); assertEquals(KeyStatus.PASSIVE.name(), key.getStatus()); } @@ -315,11 +309,11 @@ public class ImportedRsaKeyProviderTest extends AbstractKeycloakTest { rep.getConfig().putSingle(Attributes.PRIVATE_KEY_KEY, PemUtils.encodeKey(keyPair.getPrivate())); rep.getConfig().putSingle(Attributes.CERTIFICATE_KEY, "nonsense"); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); assertError(response, "Failed to decode certificate"); rep.getConfig().putSingle(Attributes.CERTIFICATE_KEY, PemUtils.encodeCertificate(invalidCertificate)); - response = adminClient.realm("test").components().add(rep); + response = realm.admin().components().add(rep); assertError(response, "Certificate does not match private key"); } @@ -337,7 +331,7 @@ public class ImportedRsaKeyProviderTest extends AbstractKeycloakTest { protected ComponentRepresentation createRep(String name, String providerId) { ComponentRepresentation rep = new ComponentRepresentation(); rep.setName(name); - rep.setParentId(adminClient.realm("test").toRepresentation().getId()); + rep.setParentId(realm.admin().toRepresentation().getId()); rep.setProviderId(providerId); rep.setProviderType(KeyProvider.class.getName()); rep.setConfig(new MultivaluedHashMap<>()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/JavaKeystoreKeyProviderTest.java b/tests/base/src/test/java/org/keycloak/tests/keys/JavaKeystoreKeyProviderTest.java similarity index 67% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/JavaKeystoreKeyProviderTest.java rename to tests/base/src/test/java/org/keycloak/tests/keys/JavaKeystoreKeyProviderTest.java index 3442b43945f..8c6acb8d823 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/JavaKeystoreKeyProviderTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/keys/JavaKeystoreKeyProviderTest.java @@ -15,16 +15,14 @@ * limitations under the License. */ -package org.keycloak.testsuite.keys; +package org.keycloak.tests.keys; -import jakarta.ws.rs.core.Response; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; -import org.jboss.arquillian.graphene.page.Page; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.keycloak.common.crypto.FipsMode; +import org.jboss.logging.Logger; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import org.keycloak.common.util.CertificateUtils; import org.keycloak.common.util.KeystoreUtil; import org.keycloak.common.util.MultivaluedHashMap; @@ -39,20 +37,27 @@ import org.keycloak.keys.KeyProvider; import org.keycloak.representations.idm.ComponentRepresentation; import org.keycloak.representations.idm.ErrorRepresentation; import org.keycloak.representations.idm.KeysMetadataRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.testsuite.AbstractKeycloakTest; -import org.keycloak.testsuite.Assert; -import org.keycloak.testsuite.AssertEvents; -import org.keycloak.testsuite.admin.ApiUtil; -import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; -import org.keycloak.testsuite.arquillian.annotation.EnableVault; -import org.keycloak.testsuite.pages.AppPage; -import org.keycloak.testsuite.pages.LoginPage; -import org.keycloak.testsuite.saml.AbstractSamlTest; -import org.keycloak.testsuite.util.KeyUtils; -import org.keycloak.testsuite.util.KeystoreUtils; +import org.keycloak.testframework.annotations.InjectCryptoHelper; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.crypto.CryptoHelper; +import org.keycloak.testframework.crypto.KeystoreInfo; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.testframework.remote.timeoffset.InjectTimeOffSet; +import org.keycloak.testframework.remote.timeoffset.TimeOffSet; +import org.keycloak.testframework.server.KeycloakServerConfig; +import org.keycloak.testframework.server.KeycloakServerConfigBuilder; +import org.keycloak.testframework.util.ApiUtil; +import org.keycloak.tests.utils.KeyUtils; +import org.keycloak.testsuite.util.saml.SamlConstants; +import jakarta.ws.rs.core.Response; + +import java.io.File; import java.math.BigInteger; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Path; import java.security.KeyPair; import java.security.PrivateKey; import java.security.PublicKey; @@ -61,37 +66,33 @@ import java.security.cert.X509Certificate; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.Date; -import java.util.List; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.keycloak.testsuite.AbstractAdminTest.loadJson; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; /** * @author Stian Thorgersen */ -@EnableVault -public class JavaKeystoreKeyProviderTest extends AbstractKeycloakTest { +@KeycloakIntegrationTest(config = JavaKeystoreKeyProviderTest.JavaKeystoreVaultConfig.class) +public class JavaKeystoreKeyProviderTest { - @Rule - public TemporaryFolder folder = new TemporaryFolder(); + @InjectRealm + ManagedRealm realm; - @Rule - public AssertEvents events = new AssertEvents(this); + @InjectTimeOffSet + TimeOffSet timeOffSet; - @Page - protected AppPage appPage; + @InjectCryptoHelper + CryptoHelper cryptoHelper; + + @TempDir + public static File folder; + + protected Logger log = Logger.getLogger(this.getClass()); - @Page - protected LoginPage loginPage; - private KeystoreUtils.KeystoreInfo generatedKeystore; private String keyAlgorithm; - @Override - public void addTestRealms(List testRealms) { - RealmRepresentation realm = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class); - testRealms.add(realm); - } + private KeystoreInfo generatedKeystore; @Test public void createJksRSA() throws Exception { @@ -146,7 +147,7 @@ public class JavaKeystoreKeyProviderTest extends AbstractKeycloakTest { @Test public void createHMAC() throws Exception { // BC provider fails storing HMAC in BCFKS (although BCFIPS works) - createSuccess(isFips()? KeystoreUtil.KeystoreFormat.BCFKS : KeystoreUtil.KeystoreFormat.PKCS12, AlgorithmType.HMAC, Algorithm.HS256, true); + createSuccess(cryptoHelper.isFips() ? KeystoreUtil.KeystoreFormat.BCFKS : KeystoreUtil.KeystoreFormat.PKCS12, AlgorithmType.HMAC, Algorithm.HS256, true); } @Test @@ -165,24 +166,24 @@ public class JavaKeystoreKeyProviderTest extends AbstractKeycloakTest { } private void createSuccess(KeystoreUtil.KeystoreFormat keystoreType, AlgorithmType algorithmType, String keyAlgorithm, boolean vault) throws Exception { - KeystoreUtils.assumeKeystoreTypeSupported(keystoreType); + cryptoHelper.keystore().assumeKeystoreTypeSupported(keystoreType); generateKeystore(keystoreType, algorithmType, keyAlgorithm); long priority = System.currentTimeMillis(); ComponentRepresentation rep = createRep("valid", priority, keyAlgorithm, vault? "${vault.keystore_password}" : "password"); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); String id = ApiUtil.getCreatedId(response); - getCleanup().addComponentId(id); + realm.cleanup().add(r -> r.components().component(id).remove()); - ComponentRepresentation createdRep = adminClient.realm("test").components().component(id).toRepresentation(); + ComponentRepresentation createdRep = realm.admin().components().component(id).toRepresentation(); assertEquals(6, createdRep.getConfig().size()); assertEquals(Long.toString(priority), createdRep.getConfig().getFirst("priority")); assertEquals(vault? "${vault.keystore_password}" : ComponentRepresentation.SECRET_VALUE, createdRep.getConfig().getFirst("keystorePassword")); assertEquals(vault? "${vault.keystore_password}" : ComponentRepresentation.SECRET_VALUE, createdRep.getConfig().getFirst("keyPassword")); - KeysMetadataRepresentation keys = adminClient.realm("test").keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); KeysMetadataRepresentation.KeyMetadataRepresentation key = keys.getKeys().get(0); @@ -217,42 +218,42 @@ public class JavaKeystoreKeyProviderTest extends AbstractKeycloakTest { @Test public void invalidKeystore() throws Exception { - generateKeystore(KeystoreUtils.getPreferredKeystoreType(), AlgorithmType.RSA, Algorithm.RS256); + generateKeystore(cryptoHelper.keystore().getPreferredKeystoreType(), AlgorithmType.RSA, Algorithm.RS256); ComponentRepresentation rep = createRep("valid", System.currentTimeMillis(), keyAlgorithm); rep.getConfig().putSingle("keystore", "/nosuchfile"); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); assertError(response, "Failed to load keys. File not found on server."); } @Test public void invalidKeystorePassword() throws Exception { - generateKeystore(KeystoreUtils.getPreferredKeystoreType(), AlgorithmType.RSA, Algorithm.RS256); + generateKeystore(cryptoHelper.keystore().getPreferredKeystoreType(), AlgorithmType.RSA, Algorithm.RS256); ComponentRepresentation rep = createRep("valid", System.currentTimeMillis(), keyAlgorithm); rep.getConfig().putSingle("keystore", "invalid"); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); assertError(response, "Failed to load keys. File not found on server."); } @Test public void invalidKeyAlias() throws Exception { - generateKeystore(KeystoreUtils.getPreferredKeystoreType(), AlgorithmType.RSA, Algorithm.RS256); + generateKeystore(cryptoHelper.keystore().getPreferredKeystoreType(), AlgorithmType.RSA, Algorithm.RS256); ComponentRepresentation rep = createRep("valid", System.currentTimeMillis(), keyAlgorithm); rep.getConfig().putSingle("keyAlias", "invalid"); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); assertError(response, "Alias invalid does not exists in the keystore."); } @Test public void invalidKeyPassword() throws Exception { - KeystoreUtil.KeystoreFormat keystoreType = KeystoreUtils.getPreferredKeystoreType(); + KeystoreUtil.KeystoreFormat keystoreType = cryptoHelper.keystore().getPreferredKeystoreType(); if (keystoreType == KeystoreUtil.KeystoreFormat.PKCS12) { // only the keyStore password is significant with PKCS12. Hence we need to test with different keystore type - String[] supportedKsTypes = KeystoreUtils.getSupportedKeystoreTypes(); + String[] supportedKsTypes = cryptoHelper.getExpectedSupportedKeyStoreTypes(); if (supportedKsTypes.length <= 1) { - Assert.fail("Only PKCS12 type is supported, but invalidKeyPassword() scenario cannot be tested with it"); + Assertions.fail("Only PKCS12 type is supported, but invalidKeyPassword() scenario cannot be tested with it"); } keystoreType = Enum.valueOf(KeystoreUtil.KeystoreFormat.class, supportedKsTypes[1]); log.infof("Fallback to keystore type '%s' for the invalidKeyPassword() test", keystoreType); @@ -261,51 +262,51 @@ public class JavaKeystoreKeyProviderTest extends AbstractKeycloakTest { ComponentRepresentation rep = createRep("valid", System.currentTimeMillis(), keyAlgorithm); rep.getConfig().putSingle("keyPassword", "invalid"); - Response response = adminClient.realm("test").components().add(rep); - Assert.assertEquals(400, response.getStatus()); + Response response = realm.admin().components().add(rep); + Assertions.assertEquals(400, response.getStatus()); assertError(response, "Failed to load keys. Key in the keystore cannot be recovered."); } @Test public void invalidKeyAlgorithmCreatedECButRegisteredRSA() throws Exception { - generateKeystore(KeystoreUtils.getPreferredKeystoreType(), AlgorithmType.ECDSA, Algorithm.RS256); + generateKeystore(cryptoHelper.keystore().getPreferredKeystoreType(), AlgorithmType.ECDSA, Algorithm.RS256); ComponentRepresentation rep = createRep("valid", System.currentTimeMillis(), Algorithm.RS256); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); assertError(response, "Invalid RS256 key for alias keyalias. Algorithm is EC."); } @Test public void invalidKeyUsageForRS256() throws Exception { - generateKeystore(KeystoreUtils.getPreferredKeystoreType(), AlgorithmType.RSA, Algorithm.RS256); + generateKeystore(cryptoHelper.keystore().getPreferredKeystoreType(), AlgorithmType.RSA, Algorithm.RS256); ComponentRepresentation rep = createRep("valid", System.currentTimeMillis(), Algorithm.RS256); rep.getConfig().putSingle(Attributes.KEY_USE, "enc"); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); assertError(response, "Invalid use enc for algorithm RS256."); } @Test public void invalidKeystoreExpiredCertificate() throws Exception { - generateRSAExpiredCertificateStore(KeystoreUtils.getPreferredKeystoreType()); + generateRSAExpiredCertificateStore(cryptoHelper.keystore().getPreferredKeystoreType()); ComponentRepresentation rep = createRep("valid", System.currentTimeMillis(), keyAlgorithm); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); assertError(response, "Certificate error on server."); } @Test public void testExpiredCertificateInOneHour() throws Exception { this.keyAlgorithm = Algorithm.RS256; - generateRSAExpiredInOneHourCertificateStore(KeystoreUtils.getPreferredKeystoreType()); + generateRSAExpiredInOneHourCertificateStore(cryptoHelper.keystore().getPreferredKeystoreType()); ComponentRepresentation rep = createRep("valid", System.currentTimeMillis(), keyAlgorithm); - try (Response response = adminClient.realm("test").components().add(rep)) { + try (Response response = realm.admin().components().add(rep)) { String id = ApiUtil.getCreatedId(response); - getCleanup().addComponentId(id); + realm.cleanup().add(r -> r.components().component(id).remove()); } - KeysMetadataRepresentation keys = adminClient.realm("test").keys().getKeyMetadata(); + KeysMetadataRepresentation keys = realm.admin().keys().getKeyMetadata(); KeysMetadataRepresentation.KeyMetadataRepresentation key = keys.getKeys().get(0); assertEquals(AlgorithmType.RSA.name(), key.getType()); PublicKey exp = PemUtils.decodePublicKey(generatedKeystore.getCertificateInfo().getPublicKey(), KeyType.RSA); @@ -314,9 +315,9 @@ public class JavaKeystoreKeyProviderTest extends AbstractKeycloakTest { assertEquals(generatedKeystore.getCertificateInfo().getCertificate(), key.getCertificate()); assertEquals(KeyStatus.ACTIVE.name(), key.getStatus()); - setTimeOffset(3610); + timeOffSet.set(3610); - keys = adminClient.realm("test").keys().getKeyMetadata(); + keys = realm.admin().keys().getKeyMetadata(); key = keys.getKeys().get(0); assertEquals(KeyStatus.PASSIVE.name(), key.getStatus()); } @@ -338,7 +339,7 @@ public class JavaKeystoreKeyProviderTest extends AbstractKeycloakTest { protected ComponentRepresentation createRep(String name, long priority, String algorithm, String password) { ComponentRepresentation rep = new ComponentRepresentation(); rep.setName(name); - rep.setParentId(adminClient.realm("test").toRepresentation().getId()); + rep.setParentId(realm.admin().toRepresentation().getId()); rep.setProviderId(JavaKeystoreKeyProviderFactory.ID); rep.setProviderType(KeyProvider.class.getName()); rep.setConfig(new MultivaluedHashMap<>()); @@ -355,42 +356,55 @@ public class JavaKeystoreKeyProviderTest extends AbstractKeycloakTest { this.keyAlgorithm = keyAlgorithm; switch (algorithmType) { case RSA -> { - this.generatedKeystore = KeystoreUtils.generateKeystore(folder, keystoreType, "keyalias", "password", "password"); + this.generatedKeystore = cryptoHelper.keystore().generateKeystore(folder, keystoreType, "keyalias", "password", "password"); } case ECDSA -> { - this.generatedKeystore = KeystoreUtils.generateKeystore(folder, keystoreType, "keyalias", "password", "password", + this.generatedKeystore = cryptoHelper.keystore().generateKeystore(folder, keystoreType, "keyalias", "password", "password", KeyUtils.generateECKey(Algorithm.ES256)); } case AES -> { - this.generatedKeystore = KeystoreUtils.generateKeystore(folder, keystoreType, "keyalias", "password", "password", + this.generatedKeystore = cryptoHelper.keystore().generateKeystore(folder, keystoreType, "keyalias", "password", "password", KeyUtils.generateSecretKey(Algorithm.AES, 256)); } case HMAC -> { - this.generatedKeystore = KeystoreUtils.generateKeystore(folder, keystoreType, "keyalias", "password", "password", + this.generatedKeystore = cryptoHelper.keystore().generateKeystore(folder, keystoreType, "keyalias", "password", "password", KeyUtils.generateSecretKey(Algorithm.HS256, 256)); } case EDDSA -> { - this.generatedKeystore = KeystoreUtils.generateKeystore(folder, keystoreType, "keyalias", "password", "password", + this.generatedKeystore = cryptoHelper.keystore().generateKeystore(folder, keystoreType, "keyalias", "password", "password", KeyUtils.generateEdDSAKey(Algorithm.Ed25519)); } } } private void generateRSAExpiredCertificateStore(KeystoreUtil.KeystoreFormat keystoreType) throws Exception { - PrivateKey privKey = PemUtils.decodePrivateKey(AbstractSamlTest.SAML_CLIENT_SALES_POST_SIG_EXPIRED_PRIVATE_KEY); - X509Certificate cert = PemUtils.decodeCertificate(AbstractSamlTest.SAML_CLIENT_SALES_POST_SIG_EXPIRED_CERTIFICATE); - this.generatedKeystore = KeystoreUtils.generateKeystore(folder, keystoreType, "keyalias", "password", "password", privKey, cert); + PrivateKey privKey = PemUtils.decodePrivateKey(SamlConstants.SAML_CLIENT_SALES_POST_SIG_EXPIRED_PRIVATE_KEY); + X509Certificate cert = PemUtils.decodeCertificate(SamlConstants.SAML_CLIENT_SALES_POST_SIG_EXPIRED_CERTIFICATE); + this.generatedKeystore = cryptoHelper.keystore().generateKeystore(folder, keystoreType, "keyalias", "password", "password", privKey, cert); } private void generateRSAExpiredInOneHourCertificateStore(KeystoreUtil.KeystoreFormat keystoreType) throws Exception { KeyPair keyPair = org.keycloak.common.util.KeyUtils.generateRsaKeyPair(2048); Certificate cert = CertificateUtils.generateV1SelfSignedCertificate( keyPair, "test", new BigInteger("1"), Date.from(Instant.now().plus(1, ChronoUnit.HOURS))); - this.generatedKeystore = KeystoreUtils.generateKeystore(folder, keystoreType, "keyalias", "password", "password", keyPair.getPrivate(), cert); + this.generatedKeystore = cryptoHelper.keystore().generateKeystore(folder, keystoreType, "keyalias", "password", "password", keyPair.getPrivate(), cert); } - private static boolean isFips() { - return AuthServerTestEnricher.AUTH_SERVER_FIPS_MODE != FipsMode.DISABLED; + public static class JavaKeystoreVaultConfig implements KeycloakServerConfig { + + @Override + public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config) { + try { + URL url = JavaKeystoreKeyProviderTest.class.getResource("vault"); + if (url == null) { + throw new RuntimeException("Unable to find the vault folder in the classpath for the default_keystore__password file!"); + } + return config.option("vault", "file").option("vault-dir", Path.of(url.toURI()).toString()); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } } + } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/KeyRotationTest.java b/tests/base/src/test/java/org/keycloak/tests/keys/KeyRotationTest.java similarity index 69% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/KeyRotationTest.java rename to tests/base/src/test/java/org/keycloak/tests/keys/KeyRotationTest.java index dc625121665..9aeb57b1604 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/KeyRotationTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/keys/KeyRotationTest.java @@ -15,12 +15,10 @@ * limitations under the License. */ -package org.keycloak.testsuite.keys; +package org.keycloak.tests.keys; import com.fasterxml.jackson.databind.JsonNode; -import org.jboss.arquillian.graphene.page.Page; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.keycloak.client.registration.Auth; import org.keycloak.client.registration.ClientRegistration; import org.keycloak.client.registration.ClientRegistrationException; @@ -32,96 +30,84 @@ import org.keycloak.jose.jws.JWSInput; import org.keycloak.jose.jws.JWSInputException; import org.keycloak.keys.Attributes; import org.keycloak.keys.GeneratedHmacKeyProviderFactory; -import org.keycloak.keys.KeyProvider; import org.keycloak.keys.ImportedRsaKeyProviderFactory; +import org.keycloak.keys.KeyProvider; import org.keycloak.models.Constants; import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation; import org.keycloak.representations.idm.ClientInitialAccessPresentation; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ComponentRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.testsuite.AbstractKeycloakTest; -import org.keycloak.testsuite.AssertEvents; -import org.keycloak.testsuite.admin.ApiUtil; -import org.keycloak.testsuite.pages.AppPage; -import org.keycloak.testsuite.pages.AppPage.RequestType; -import org.keycloak.testsuite.pages.LoginPage; -import org.keycloak.testsuite.util.AdminClientUtil; -import org.keycloak.testsuite.util.ClientBuilder; -import org.keycloak.testsuite.util.KeycloakModelUtils; +import org.keycloak.testframework.annotations.InjectCryptoHelper; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.crypto.CryptoHelper; +import org.keycloak.testframework.oauth.OAuthClient; +import org.keycloak.testframework.oauth.annotations.InjectOAuthClient; +import org.keycloak.testframework.realm.ClientConfigBuilder; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.testframework.util.ApiUtil; +import org.keycloak.tests.common.BasicRealmWithUserConfig; import org.keycloak.testsuite.util.oauth.AccessTokenResponse; -import org.keycloak.testsuite.util.UserInfoClientUtil; +import org.keycloak.testsuite.util.oauth.AuthorizationEndpointResponse; +import org.keycloak.testsuite.util.oauth.UserInfoResponse; import jakarta.ws.rs.core.Response; + import java.io.IOException; import java.security.KeyPair; import java.security.PublicKey; -import java.util.List; import java.util.Map; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.keycloak.testsuite.AbstractAdminTest.loadJson; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; /** * @author Stian Thorgersen */ -public class KeyRotationTest extends AbstractKeycloakTest { +@KeycloakIntegrationTest +public class KeyRotationTest { - @Rule - public AssertEvents events = new AssertEvents(this); + @InjectRealm(config = BasicRealmWithUserConfig.class) + ManagedRealm realm; - @Page - protected AppPage appPage; + @InjectOAuthClient + OAuthClient oauth; - @Page - protected LoginPage loginPage; - - @Override - public void addTestRealms(List testRealms) { - RealmRepresentation realm = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class); - testRealms.add(realm); - - ClientRepresentation confApp = KeycloakModelUtils.createClient(realm, "confidential-cli"); - confApp.setSecret("secret1"); - confApp.setServiceAccountsEnabled(Boolean.TRUE); - } + @InjectCryptoHelper + CryptoHelper cryptoHelper; @Test - public void testIdentityCookie() throws Exception { + public void testIdentityCookie() { // Create keys #1 createKeys1(); // Login with keys #1 - loginPage.open(); - loginPage.login("test-user@localhost", "password"); - assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); + AuthorizationEndpointResponse response = oauth.doLogin(BasicRealmWithUserConfig.USERNAME, BasicRealmWithUserConfig.PASSWORD); + assertTrue(response.isRedirected()); // Create keys #2 createKeys2(); // Login again with cookie signed with old keys - appPage.open(); oauth.openLoginForm(); - assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); + assertTrue(oauth.parseLoginResponse().isRedirected()); // Drop key #1 dropKeys1(); // Login again with key #1 dropped - should pass as cookie should be refreshed - appPage.open(); oauth.openLoginForm(); - assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); + assertTrue(oauth.parseLoginResponse().isRedirected()); // Drop key #2 dropKeys2(); // Login again with key #2 dropped - should fail as cookie hasn't been refreshed - appPage.open(); oauth.openLoginForm(); - assertTrue(loginPage.isCurrent()); + assertFalse(oauth.parseLoginResponse().isRedirected()); } @Test @@ -130,7 +116,7 @@ public class KeyRotationTest extends AbstractKeycloakTest { Map keys1 = createKeys1(); // Get token with keys #1 - oauth.doLogin("test-user@localhost", "password"); + oauth.doLogin(BasicRealmWithUserConfig.USERNAME, BasicRealmWithUserConfig.PASSWORD); AccessTokenResponse response = oauth.doAccessTokenRequest(oauth.parseLoginResponse().getCode()); assertEquals(200, response.getStatusCode()); assertTokenKid(keys1.get(Algorithm.RS256), response.getAccessToken()); @@ -140,12 +126,12 @@ public class KeyRotationTest extends AbstractKeycloakTest { ClientInitialAccessCreatePresentation initialToken = new ClientInitialAccessCreatePresentation(); initialToken.setCount(100); initialToken.setExpiration(0); - ClientInitialAccessPresentation accessRep = adminClient.realm("test").clientInitialAccess().create(initialToken); + ClientInitialAccessPresentation accessRep = realm.admin().clientInitialAccess().create(initialToken); String initialAccessToken = accessRep.getToken(); - ClientRegistration reg = ClientRegistration.create().url(suiteContext.getAuthServerInfo().getContextRoot() + "/auth", "test").build(); + ClientRegistration reg = oauth.clientRegistration(); reg.auth(Auth.token(initialAccessToken)); - ClientRepresentation clientRep = reg.create(ClientBuilder.create().clientId("test").build()); + ClientRepresentation clientRep = reg.create(ClientConfigBuilder.create().clientId("test").build()); // Userinfo with keys #1 assertUserInfo(response.getAccessToken(), 200); @@ -233,12 +219,13 @@ public class KeyRotationTest extends AbstractKeycloakTest { } @Test - public void rotateKeys() throws InterruptedException { + public void rotateKeys() { + realm.dirty(); for (int i = 0; i < 10; i++) { - String activeKid = adminClient.realm("test").keys().getKeyMetadata().getActive().get(Algorithm.RS256); + String activeKid = realm.admin().keys().getKeyMetadata().getActive().get(Algorithm.RS256); // Rotate public keys on the parent broker - String realmId = adminClient.realm("test").toRepresentation().getId(); + String realmId = realm.getId(); ComponentRepresentation keys = new ComponentRepresentation(); keys.setName("generated" + i); keys.setProviderType(KeyProvider.class.getName()); @@ -246,13 +233,12 @@ public class KeyRotationTest extends AbstractKeycloakTest { keys.setParentId(realmId); keys.setConfig(new MultivaluedHashMap<>()); keys.getConfig().putSingle("priority", "1000" + i); - Response response = adminClient.realm("test").components().add(keys); + Response response = realm.admin().components().add(keys); assertEquals(201, response.getStatus()); String newId = ApiUtil.getCreatedId(response); - getCleanup().addComponentId(newId); response.close(); - String updatedActiveKid = adminClient.realm("test").keys().getKeyMetadata().getActive().get(Algorithm.RS256); + String updatedActiveKid = realm.admin().keys().getKeyMetadata().getActive().get(Algorithm.RS256); assertNotEquals(activeKid, updatedActiveKid); } } @@ -262,20 +248,20 @@ public class KeyRotationTest extends AbstractKeycloakTest { assertEquals(expectedKid, new JWSInput(token).getHeader().getKeyId()); } - private Map createKeys1() throws Exception { + private Map createKeys1() { return createKeys("1000"); } - private Map createKeys2() throws Exception { + private Map createKeys2() { return createKeys("2000"); } - private Map createKeys(String priority) throws Exception { - KeyPair keyPair = KeyUtils.generateRsaKeyPair(org.keycloak.testsuite.util.KeyUtils.getLowestSupportedRsaKeySize()); + private Map createKeys(String priority) { + KeyPair keyPair = KeyUtils.generateRsaKeyPair(Integer.parseInt(cryptoHelper.getExpectedSupportedRsaKeySizes()[0])); String privateKeyPem = PemUtils.encodeKey(keyPair.getPrivate()); PublicKey publicKey = keyPair.getPublic(); - String testRealmId = adminClient.realm("test").toRepresentation().getId(); + String testRealmId = realm.getId(); ComponentRepresentation rep = new ComponentRepresentation(); rep.setName("mycomponent"); rep.setParentId(testRealmId); @@ -287,7 +273,7 @@ public class KeyRotationTest extends AbstractKeycloakTest { config.addFirst(Attributes.PRIVATE_KEY_KEY, privateKeyPem); rep.setConfig(config); - Response response = adminClient.realm("test").components().add(rep); + Response response = realm.admin().components().add(rep); response.close(); rep = new ComponentRepresentation(); @@ -301,10 +287,10 @@ public class KeyRotationTest extends AbstractKeycloakTest { config.addFirst(Attributes.ALGORITHM_KEY, Constants.INTERNAL_SIGNATURE_ALGORITHM); rep.setConfig(config); - response = adminClient.realm("test").components().add(rep); + response = realm.admin().components().add(rep); response.close(); - return realmsResouce().realm("test").keys().getKeyMetadata().getActive(); + return realm.admin().keys().getKeyMetadata().getActive(); } private void dropKeys1() { @@ -317,10 +303,10 @@ public class KeyRotationTest extends AbstractKeycloakTest { private void dropKeys(String priority) { int r = 0; - String parentId = adminClient.realm("test").toRepresentation().getId(); - for (ComponentRepresentation c : adminClient.realm("test").components().query(parentId, KeyProvider.class.getName())) { + String parentId = realm.getId(); + for (ComponentRepresentation c : realm.admin().components().query(parentId, KeyProvider.class.getName())) { if (c.getConfig().getFirst("priority").equals(priority)) { - adminClient.realm("test").components().component(c.getId()).remove(); + realm.admin().components().component(c.getId()).remove(); r++; } } @@ -330,16 +316,14 @@ public class KeyRotationTest extends AbstractKeycloakTest { } private void assertUserInfo(String token, int expectedStatus) { - try (Response userInfoResponse = UserInfoClientUtil.executeUserInfoRequest_getMethod(AdminClientUtil.createResteasyClient(), token)) { - assertEquals(expectedStatus, userInfoResponse.getStatus()); - } + UserInfoResponse response = oauth.doUserInfoRequest(token); + assertEquals(expectedStatus, response.getStatusCode()); } private void assertTokenIntrospection(String token, boolean expectActive) { try { - JsonNode jsonNode = oauth.client("confidential-cli", "secret1").doIntrospectionAccessTokenRequest(token).asJsonNode(); + JsonNode jsonNode = oauth.doIntrospectionAccessTokenRequest(token).asJsonNode(); assertEquals(expectActive, jsonNode.get("active").asBoolean()); - oauth.client("test-app", "password"); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/tests/base/src/test/java/org/keycloak/tests/suites/Base2TestSuite.java b/tests/base/src/test/java/org/keycloak/tests/suites/Base2TestSuite.java index 30dba866726..e9befcfeda1 100644 --- a/tests/base/src/test/java/org/keycloak/tests/suites/Base2TestSuite.java +++ b/tests/base/src/test/java/org/keycloak/tests/suites/Base2TestSuite.java @@ -11,6 +11,7 @@ import org.junit.platform.suite.api.Suite; "org.keycloak.tests.db", "org.keycloak.tests.forms", "org.keycloak.tests.infinispan", + "org.keycloak.tests.keys", "org.keycloak.tests.oauth", "org.keycloak.tests.tracing", "org.keycloak.tests.welcomepage" diff --git a/tests/base/src/test/java/org/keycloak/tests/suites/DatabaseTestSuite.java b/tests/base/src/test/java/org/keycloak/tests/suites/DatabaseTestSuite.java index 6c001f3c038..987040efbb7 100644 --- a/tests/base/src/test/java/org/keycloak/tests/suites/DatabaseTestSuite.java +++ b/tests/base/src/test/java/org/keycloak/tests/suites/DatabaseTestSuite.java @@ -1,9 +1,17 @@ package org.keycloak.tests.suites; +import org.junit.platform.suite.api.SelectClasses; import org.junit.platform.suite.api.SelectPackages; import org.junit.platform.suite.api.Suite; +import org.keycloak.tests.keys.GeneratedRsaKeyProviderTest; @Suite -@SelectPackages({"org.keycloak.tests.admin", "org.keycloak.tests.db"}) +@SelectPackages({ + "org.keycloak.tests.admin", + "org.keycloak.tests.db" +}) +@SelectClasses({ + GeneratedRsaKeyProviderTest.class +}) public class DatabaseTestSuite { } diff --git a/tests/base/src/test/java/org/keycloak/tests/suites/FipsNonStrictTestSuite.java b/tests/base/src/test/java/org/keycloak/tests/suites/FipsNonStrictTestSuite.java index 969ad24b3c0..c2ff9c21aa5 100644 --- a/tests/base/src/test/java/org/keycloak/tests/suites/FipsNonStrictTestSuite.java +++ b/tests/base/src/test/java/org/keycloak/tests/suites/FipsNonStrictTestSuite.java @@ -5,6 +5,7 @@ import org.junit.platform.suite.api.BeforeSuite; import org.junit.platform.suite.api.SelectClasses; import org.junit.platform.suite.api.Suite; import org.keycloak.common.Profile; +import org.keycloak.common.crypto.FipsMode; import org.keycloak.common.util.KeystoreUtil; import org.keycloak.testframework.https.CertificatesConfig; import org.keycloak.testframework.https.CertificatesConfigBuilder; @@ -13,16 +14,22 @@ import org.keycloak.testframework.server.KeycloakServerConfig; import org.keycloak.testframework.server.KeycloakServerConfigBuilder; import org.keycloak.tests.admin.ServerInfoTest; import org.keycloak.tests.admin.client.CredentialsTest; +import org.keycloak.tests.keys.JavaKeystoreKeyProviderTest; @Suite -@SelectClasses({CredentialsTest.class, ServerInfoTest.class}) +@SelectClasses({ + CredentialsTest.class, + JavaKeystoreKeyProviderTest.class, + ServerInfoTest.class +}) public class FipsNonStrictTestSuite { @BeforeSuite public static void beforeSuite() { SuiteSupport.startSuite() .registerServerConfig(FipsNonStrictServerConfig.class) - .registerSupplierConfig("certificates", FipsNonStrictCertificatesConfig.class);; + .registerSupplierConfig("certificates", FipsNonStrictCertificatesConfig.class) + .registerSupplierConfig("crypto", "fips", FipsMode.NON_STRICT.name()); } @AfterSuite diff --git a/tests/base/src/test/java/org/keycloak/tests/suites/FipsStrictTestSuite.java b/tests/base/src/test/java/org/keycloak/tests/suites/FipsStrictTestSuite.java index c574a8b7851..5617c4b9554 100644 --- a/tests/base/src/test/java/org/keycloak/tests/suites/FipsStrictTestSuite.java +++ b/tests/base/src/test/java/org/keycloak/tests/suites/FipsStrictTestSuite.java @@ -5,6 +5,7 @@ import org.junit.platform.suite.api.BeforeSuite; import org.junit.platform.suite.api.SelectClasses; import org.junit.platform.suite.api.Suite; import org.keycloak.common.Profile; +import org.keycloak.common.crypto.FipsMode; import org.keycloak.common.util.KeystoreUtil; import org.keycloak.testframework.https.CertificatesConfig; import org.keycloak.testframework.https.CertificatesConfigBuilder; @@ -13,16 +14,22 @@ import org.keycloak.testframework.server.KeycloakServerConfig; import org.keycloak.testframework.server.KeycloakServerConfigBuilder; import org.keycloak.tests.admin.ServerInfoTest; import org.keycloak.tests.admin.client.CredentialsTest; +import org.keycloak.tests.keys.JavaKeystoreKeyProviderTest; @Suite -@SelectClasses({CredentialsTest.class, ServerInfoTest.class}) +@SelectClasses({ + CredentialsTest.class, + JavaKeystoreKeyProviderTest.class, + ServerInfoTest.class +}) public class FipsStrictTestSuite { @BeforeSuite public static void beforeSuite() { SuiteSupport.startSuite() .registerServerConfig(FipsStrictServerConfig.class) - .registerSupplierConfig("certificates", FipsStrictCertificatesConfig.class); + .registerSupplierConfig("certificates", FipsStrictCertificatesConfig.class) + .registerSupplierConfig("crypto", "fips", FipsMode.STRICT.name()); } @AfterSuite diff --git a/tests/base/src/test/java/org/keycloak/tests/suites/JDKTestSuite.java b/tests/base/src/test/java/org/keycloak/tests/suites/JDKTestSuite.java index ba5f54c5410..21021fa09ec 100644 --- a/tests/base/src/test/java/org/keycloak/tests/suites/JDKTestSuite.java +++ b/tests/base/src/test/java/org/keycloak/tests/suites/JDKTestSuite.java @@ -3,8 +3,14 @@ package org.keycloak.tests.suites; import org.junit.platform.suite.api.SelectClasses; import org.junit.platform.suite.api.Suite; import org.keycloak.tests.admin.client.CredentialsTest; +import org.keycloak.tests.keys.GeneratedRsaKeyProviderTest; +import org.keycloak.tests.keys.JavaKeystoreKeyProviderTest; @Suite -@SelectClasses({CredentialsTest.class}) +@SelectClasses({ + CredentialsTest.class, + GeneratedRsaKeyProviderTest.class, + JavaKeystoreKeyProviderTest.class +}) public class JDKTestSuite { } diff --git a/tests/base/src/test/resources/org/keycloak/tests/keys/vault/default_keystore__password b/tests/base/src/test/resources/org/keycloak/tests/keys/vault/default_keystore__password new file mode 100644 index 00000000000..7aa311adf93 --- /dev/null +++ b/tests/base/src/test/resources/org/keycloak/tests/keys/vault/default_keystore__password @@ -0,0 +1 @@ +password \ No newline at end of file diff --git a/tests/utils-shared/src/main/java/org/keycloak/testsuite/util/saml/SamlConstants.java b/tests/utils-shared/src/main/java/org/keycloak/testsuite/util/saml/SamlConstants.java new file mode 100644 index 00000000000..b95777baede --- /dev/null +++ b/tests/utils-shared/src/main/java/org/keycloak/testsuite/util/saml/SamlConstants.java @@ -0,0 +1,28 @@ +package org.keycloak.testsuite.util.saml; + +public interface SamlConstants { + + String SAML_CLIENT_SALES_POST_SIG_EXPIRED_PRIVATE_KEY = "MIIEpQIBAAKCAQEA3SMEGYw330CS++XP0KqoFz2UezUxZAhkLv5C93hf5FPGw9QpPmimpGcsN8RCy4DDYOGrbuJLd8GkoBCkmp7xTqQMx/nrUvzDCAWAUSnxnBVgCsq9KbpI5sdacOHd0oEI9pQdRQ71Rj+tipeIt+Fy8S17bkpGBYjQk3xdusMX8E9LR04ksp0C9o2mvX+U0QCrF8HqVCCO9gMJJNOGaot7a3+QaTWnNrPguhMuHgJ6LlsyOUYNFQw5rdxs8Vz2mOsIGvWn1Em/c+KCcMltTIhOhDY3zW3ZrFL3Vwq4kTQ74ju9Qp1qyyQOOJmig6LLm31LQvQHPQWkY7rRcp9VBMRPcQIDAQABAoIBAQDPUpvuY9KiIYVsWvoqFUWAfIBvvuAue9uJX2JjZ1zn0U+Bm7CLTUwmyH/hTMSezHrgotK6I7lDbq4sT04zlJ6B7zX4aqwg4s7q/1VdQui9QCEKHSeaLodYrkBxoqD4UXeYziZe73YvRVYroIRSeTDtQon9Te82Ex4RmEC771rLNZ38rm2EsF2+GfNIavumo458TBmX0DI8w3QwlSMEeXaNZqch2adZSDxehrOFeqzZ9o8KtgCfrJ5P11vgXlKnVGFa7Pfndrc6XacfYhKAtTyX3Bgx9FFaOK+W5k5/XXc2UTbUV6aNmiQdNp5CrjoZ/DuttWFGwOWfg9zSG3i5wwLRAoGBAPR7IWPk1Ejf8+4vGvDED3ZDc94DINrFjszaVZBt2w/Hx0uePdeojulHhTBFMFUtV2Dn8vpG7D9TxDeZj7tmKSHE3/j1DXE6jpo72Z+iOR5byO/HmgiV0kblKxXnZfDy5/cq/Cy6GTJ2MU6k50SDgIIq86gWCXbRwveX9E66qlHdAoGBAOeOUEiuGC332m7N2wfUobBbczNviSWeAzIFP4t15u0QHRhMDeRmfE4xuWS4aL1vfsyTOrxaN5GJ2QeAIdkM42dSA0FqzzumRd9T8VdeJ+J2GGB+ALNmTHNuz8jWepLVD2F1GBhs+gkSh5yS1p+FUodQWkWC5YLI/y2rySpbiPylAoGBAJpV0LJbFpgaqMbH/d3YJ1qlIlQY7XiuFoPDoRhYAV5o46sc7jViNzWU7MOYKfbbdLm8M2tDsogXvVrMGixXRcgHnMxxBldge/1pouxfYGeF0cds3hRlYCVZLmXZekUtUrp57E/f+2AbtOzMtSJPUaTasI5/uuHDca0TxCqfND4RAoGAWS6Fm0h6BZJVLaHZPw3U7FB8cQ3/G17dSjGdRMA3HYy8N/Rq0VHrhE5AYhtoM7Wyd2YpFAwHJOWbkfj2kFsXZl6+5D4X7JhghuAUrpqT7/Od9ePxryayQS8nlemNMeofT2DC0/1822uokVQ4lx3JKFZ5PhZpANMa/OMRyl+QxgUCgYEA4D5YyD5wHz7fNFyaUrgJr4dFLG9vqRv8Pm9IozBAmNumi25Gi7gyi/WN8DrVbsRiq4ywiKiikui5TW3/RR51OYDnX3YCnWE5AGV4okci3PlclJ/UsPjlUOzNlXW7Wr0pFCcJc/WuQm1lgho/o6QGbMbS/BSwxBrUl/bUEp4IZKc="; + String SAML_CLIENT_SALES_POST_SIG_EXPIRED_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3SMEGYw330CS++XP0KqoFz2UezUxZAhkLv5C93hf5FPGw9QpPmimpGcsN8RCy4DDYOGrbuJLd8GkoBCkmp7xTqQMx/nrUvzDCAWAUSnxnBVgCsq9KbpI5sdacOHd0oEI9pQdRQ71Rj+tipeIt+Fy8S17bkpGBYjQk3xdusMX8E9LR04ksp0C9o2mvX+U0QCrF8HqVCCO9gMJJNOGaot7a3+QaTWnNrPguhMuHgJ6LlsyOUYNFQw5rdxs8Vz2mOsIGvWn1Em/c+KCcMltTIhOhDY3zW3ZrFL3Vwq4kTQ74ju9Qp1qyyQOOJmig6LLm31LQvQHPQWkY7rRcp9VBMRPcQIDAQAB"; + String SAML_CLIENT_SALES_POST_SIG_EXPIRED_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n" + + "MIIDQTCCAimgAwIBAgIUT8qwq3DECizGLB2tQAaaNSGAVLgwDQYJKoZIhvcNAQEL\n" + + "BQAwMDEuMCwGA1UEAwwlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qt\n" + + "c2lnLzAeFw0yMzAxMjcxNjAwMDBaFw0yMzAxMjgxNjAwMDBaMDAxLjAsBgNVBAMM\n" + + "JWh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9zYWxlcy1wb3N0LXNpZy8wggEiMA0GCSqG\n" + + "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDdIwQZjDffQJL75c/QqqgXPZR7NTFkCGQu\n" + + "/kL3eF/kU8bD1Ck+aKakZyw3xELLgMNg4atu4kt3waSgEKSanvFOpAzH+etS/MMI\n" + + "BYBRKfGcFWAKyr0pukjmx1pw4d3SgQj2lB1FDvVGP62Kl4i34XLxLXtuSkYFiNCT\n" + + "fF26wxfwT0tHTiSynQL2jaa9f5TRAKsXwepUII72Awkk04Zqi3trf5BpNac2s+C6\n" + + "Ey4eAnouWzI5Rg0VDDmt3GzxXPaY6wga9afUSb9z4oJwyW1MiE6ENjfNbdmsUvdX\n" + + "CriRNDviO71CnWrLJA44maKDosubfUtC9Ac9BaRjutFyn1UExE9xAgMBAAGjUzBR\n" + + "MB0GA1UdDgQWBBR4R5i1kWMxzzdQ3TdgI/MuNLChSDAfBgNVHSMEGDAWgBR4R5i1\n" + + "kWMxzzdQ3TdgI/MuNLChSDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUA\n" + + "A4IBAQAacI/f9YFVTUCGXfh/FCVBQI20bgOs9D6IpIhN8L5kEnY6Ox5t00b9G5Bz\n" + + "64alK3WMR3DdhTEpufX8IMFpMlme/JnnOQXkfmIvzbev4iIKxcKFvS8qNXav8PVx\n" + + "wDApuzgxEq/XZCtFXhDS3q1jGRmlOr+MtQdCNQuJmxy7kOoFPY+UYjhSXTZVrCyF\n" + + "I0LYJQfcZ69bYXd+5h1U3UsN4ZvsBgnrz/IhhadaCtTZVtvyr/uzHiJpqT99VO9/\n" + + "7lwh2zL8ihPyOUVDjdYxYyCi+BHLRB+udnVAfo7t3fbxMi1gV9xVcYaqTJgSArsY\n" + + "M8mxv8p5mhTa8TJknzs4V3Dm+PHs\n" + + "-----END CERTIFICATE-----"; + +} diff --git a/tests/utils/src/main/java/org/keycloak/tests/utils/FipsUtils.java b/tests/utils/src/main/java/org/keycloak/tests/utils/FipsUtils.java deleted file mode 100644 index 3053d58413a..00000000000 --- a/tests/utils/src/main/java/org/keycloak/tests/utils/FipsUtils.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.keycloak.tests.utils; - -import org.keycloak.representations.info.ServerInfoRepresentation; - -public class FipsUtils { - - private final String cryptoProvider; - - private FipsUtils(ServerInfoRepresentation info) { - this.cryptoProvider = info.getCryptoInfo().getCryptoProvider(); - } - - public static FipsUtils create(ServerInfoRepresentation info) { - return new FipsUtils(info); - } - - public String[] getExpectedSupportedKeyStoreTypes() { - return switch (cryptoProvider) { - case "FIPS1402Provider" -> new String[] { "PKCS12", "BCFKS" }; - case "Fips1402StrictCryptoProvider" -> new String[] { "BCFKS" }; - default -> new String[] { "JKS", "PKCS12", "BCFKS" }; - }; - } - - public String[] getExpectedSupportedRsaKeySizes() { - return switch (cryptoProvider) { - case "Fips1402StrictCryptoProvider" -> new String[]{"2048", "3072", "4096"}; - default -> new String[]{"1024", "2048", "3072", "4096"}; - }; - } - -} diff --git a/tests/utils/src/main/java/org/keycloak/tests/utils/KeyUtils.java b/tests/utils/src/main/java/org/keycloak/tests/utils/KeyUtils.java index abf4cafdc6b..cc8e7656d4e 100644 --- a/tests/utils/src/main/java/org/keycloak/tests/utils/KeyUtils.java +++ b/tests/utils/src/main/java/org/keycloak/tests/utils/KeyUtils.java @@ -149,20 +149,21 @@ public class KeyUtils { /** * @return key sizes, which are expected to be supported by Keycloak server for {@link org.keycloak.keys.GeneratedRsaKeyProviderFactory} and {@link org.keycloak.keys.GeneratedRsaEncKeyProviderFactory}. */ - public static String[] getExpectedSupportedRsaKeySizes() { - String expectedKeySizes = System.getProperty("auth.server.supported.rsa.key.sizes"); - if (expectedKeySizes == null || expectedKeySizes.trim().isEmpty()) { - Assertions.fail("System property 'auth.server.supported.rsa.key.sizes' should be set"); - } - return expectedKeySizes.split(","); - } +// This doesn't work in new testsuite as we don't set these system properties +// public static String[] getExpectedSupportedRsaKeySizes() { +// String expectedKeySizes = System.getProperty("auth.server.supported.rsa.key.sizes"); +// if (expectedKeySizes == null || expectedKeySizes.trim().isEmpty()) { +// Assertions.fail("System property 'auth.server.supported.rsa.key.sizes' should be set"); +// } +// return expectedKeySizes.split(","); +// } /** * @return Lowest key size supported by Keycloak server for {@link org.keycloak.keys.GeneratedRsaKeyProviderFactory}. * It is usually 1024, but can be 2048 in some environments (typically in FIPS environments) */ - public static int getLowestSupportedRsaKeySize() { - return Integer.parseInt(getExpectedSupportedRsaKeySizes()[0]); - } +// public static int getLowestSupportedRsaKeySize() { +// return Integer.parseInt(getExpectedSupportedRsaKeySizes()[0]); +// } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/FallbackKeyProviderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/FallbackKeyProviderTest.java deleted file mode 100644 index 12993eff930..00000000000 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/keys/FallbackKeyProviderTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2016 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.testsuite.keys; - -import org.jboss.arquillian.graphene.page.Page; -import org.junit.Rule; -import org.junit.Test; -import org.keycloak.crypto.Algorithm; -import org.keycloak.models.Constants; -import org.keycloak.representations.idm.ComponentRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.testsuite.AbstractKeycloakTest; -import org.keycloak.testsuite.Assert; -import org.keycloak.testsuite.AssertEvents; -import org.keycloak.testsuite.pages.AppPage; -import org.keycloak.testsuite.pages.LoginPage; -import org.keycloak.testsuite.util.oauth.AccessTokenResponse; - -import java.util.LinkedList; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.keycloak.testsuite.AbstractAdminTest.loadJson; - -/** - * @author Stian Thorgersen - */ -public class FallbackKeyProviderTest extends AbstractKeycloakTest { - - @Rule - public AssertEvents events = new AssertEvents(this); - - @Page - protected AppPage appPage; - - @Page - protected LoginPage loginPage; - - @Override - public void addTestRealms(List testRealms) { - RealmRepresentation realm = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class); - testRealms.add(realm); - } - - @Test - public void fallbackAfterDeletingAllKeysInRealm() { - String realmId = realmsResouce().realm("test").toRepresentation().getId(); - - List providers = realmsResouce().realm("test").components().query(realmId, "org.keycloak.keys.KeyProvider"); - assertEquals(4, providers.size()); - - for (ComponentRepresentation p : providers) { - realmsResouce().realm("test").components().component(p.getId()).remove(); - } - - providers = realmsResouce().realm("test").components().query(realmId, "org.keycloak.keys.KeyProvider"); - assertEquals(0, providers.size()); - - oauth.doLogin("test-user@localhost", "password"); - String code = oauth.parseLoginResponse().getCode(); - AccessTokenResponse response = oauth.doAccessTokenRequest(code); - - assertNotNull(response.getAccessToken()); - - Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - - providers = realmsResouce().realm("test").components().query(realmId, "org.keycloak.keys.KeyProvider"); - assertProviders(providers, "fallback-RS256", "fallback-AES", "fallback-" + Constants.INTERNAL_SIGNATURE_ALGORITHM); - } - - @Test - public void differentAlgorithms() { - String realmId = realmsResouce().realm("test").toRepresentation().getId(); - - String[] algorithmsToTest = new String[] { - Algorithm.RS384, - Algorithm.RS512, - Algorithm.PS256, - Algorithm.PS384, - Algorithm.PS512, - Algorithm.ES256, - Algorithm.ES384, - Algorithm.ES512 - }; - - oauth.doLogin("test-user@localhost", "password"); - - for (String algorithm : algorithmsToTest) { - RealmRepresentation rep = realmsResouce().realm("test").toRepresentation(); - rep.setDefaultSignatureAlgorithm(algorithm); - realmsResouce().realm("test").update(rep); - - oauth.openLoginForm(); - - String code = oauth.parseLoginResponse().getCode(); - AccessTokenResponse response = oauth.doAccessTokenRequest(code); - assertNotNull(response.getAccessToken()); - } - - List providers = realmsResouce().realm("test").components().query(realmId, "org.keycloak.keys.KeyProvider"); - - List expected = new LinkedList<>(); - expected.add("rsa-generated"); - expected.add("rsa-enc-generated"); - expected.add("hmac-generated-hs512"); - expected.add("aes-generated"); - - for (String a : algorithmsToTest) { - expected.add("fallback-" + a); - } - - assertProviders(providers, expected.toArray(new String[providers.size()])); - } - - @Override - protected boolean isImportAfterEachMethod() { - return true; - } - - private void assertProviders(List providers, String... expected) { - Assert.assertNames(providers, expected); - } -} - diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/AbstractSamlTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/AbstractSamlTest.java index 40aa02f0dd4..2765b377eee 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/AbstractSamlTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/saml/AbstractSamlTest.java @@ -19,6 +19,8 @@ import org.keycloak.testsuite.util.SamlClient; import jakarta.ws.rs.core.UriBuilder; import jakarta.ws.rs.core.UriBuilderException; import org.keycloak.saml.common.constants.JBossSAMLURIConstants; +import org.keycloak.testsuite.util.saml.SamlConstants; + import java.net.URI; import java.security.KeyFactory; import java.security.KeyPair; @@ -91,28 +93,9 @@ public abstract class AbstractSamlTest extends AbstractAuthTest { // Set date to past (For example with "faketime" utility); then: openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 1 -nodes -subj '/CN=http:\/\/localhost:8080\/sales-post-sig\/' - public static final String SAML_CLIENT_SALES_POST_SIG_EXPIRED_PRIVATE_KEY = "MIIEpQIBAAKCAQEA3SMEGYw330CS++XP0KqoFz2UezUxZAhkLv5C93hf5FPGw9QpPmimpGcsN8RCy4DDYOGrbuJLd8GkoBCkmp7xTqQMx/nrUvzDCAWAUSnxnBVgCsq9KbpI5sdacOHd0oEI9pQdRQ71Rj+tipeIt+Fy8S17bkpGBYjQk3xdusMX8E9LR04ksp0C9o2mvX+U0QCrF8HqVCCO9gMJJNOGaot7a3+QaTWnNrPguhMuHgJ6LlsyOUYNFQw5rdxs8Vz2mOsIGvWn1Em/c+KCcMltTIhOhDY3zW3ZrFL3Vwq4kTQ74ju9Qp1qyyQOOJmig6LLm31LQvQHPQWkY7rRcp9VBMRPcQIDAQABAoIBAQDPUpvuY9KiIYVsWvoqFUWAfIBvvuAue9uJX2JjZ1zn0U+Bm7CLTUwmyH/hTMSezHrgotK6I7lDbq4sT04zlJ6B7zX4aqwg4s7q/1VdQui9QCEKHSeaLodYrkBxoqD4UXeYziZe73YvRVYroIRSeTDtQon9Te82Ex4RmEC771rLNZ38rm2EsF2+GfNIavumo458TBmX0DI8w3QwlSMEeXaNZqch2adZSDxehrOFeqzZ9o8KtgCfrJ5P11vgXlKnVGFa7Pfndrc6XacfYhKAtTyX3Bgx9FFaOK+W5k5/XXc2UTbUV6aNmiQdNp5CrjoZ/DuttWFGwOWfg9zSG3i5wwLRAoGBAPR7IWPk1Ejf8+4vGvDED3ZDc94DINrFjszaVZBt2w/Hx0uePdeojulHhTBFMFUtV2Dn8vpG7D9TxDeZj7tmKSHE3/j1DXE6jpo72Z+iOR5byO/HmgiV0kblKxXnZfDy5/cq/Cy6GTJ2MU6k50SDgIIq86gWCXbRwveX9E66qlHdAoGBAOeOUEiuGC332m7N2wfUobBbczNviSWeAzIFP4t15u0QHRhMDeRmfE4xuWS4aL1vfsyTOrxaN5GJ2QeAIdkM42dSA0FqzzumRd9T8VdeJ+J2GGB+ALNmTHNuz8jWepLVD2F1GBhs+gkSh5yS1p+FUodQWkWC5YLI/y2rySpbiPylAoGBAJpV0LJbFpgaqMbH/d3YJ1qlIlQY7XiuFoPDoRhYAV5o46sc7jViNzWU7MOYKfbbdLm8M2tDsogXvVrMGixXRcgHnMxxBldge/1pouxfYGeF0cds3hRlYCVZLmXZekUtUrp57E/f+2AbtOzMtSJPUaTasI5/uuHDca0TxCqfND4RAoGAWS6Fm0h6BZJVLaHZPw3U7FB8cQ3/G17dSjGdRMA3HYy8N/Rq0VHrhE5AYhtoM7Wyd2YpFAwHJOWbkfj2kFsXZl6+5D4X7JhghuAUrpqT7/Od9ePxryayQS8nlemNMeofT2DC0/1822uokVQ4lx3JKFZ5PhZpANMa/OMRyl+QxgUCgYEA4D5YyD5wHz7fNFyaUrgJr4dFLG9vqRv8Pm9IozBAmNumi25Gi7gyi/WN8DrVbsRiq4ywiKiikui5TW3/RR51OYDnX3YCnWE5AGV4okci3PlclJ/UsPjlUOzNlXW7Wr0pFCcJc/WuQm1lgho/o6QGbMbS/BSwxBrUl/bUEp4IZKc="; - public static final String SAML_CLIENT_SALES_POST_SIG_EXPIRED_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3SMEGYw330CS++XP0KqoFz2UezUxZAhkLv5C93hf5FPGw9QpPmimpGcsN8RCy4DDYOGrbuJLd8GkoBCkmp7xTqQMx/nrUvzDCAWAUSnxnBVgCsq9KbpI5sdacOHd0oEI9pQdRQ71Rj+tipeIt+Fy8S17bkpGBYjQk3xdusMX8E9LR04ksp0C9o2mvX+U0QCrF8HqVCCO9gMJJNOGaot7a3+QaTWnNrPguhMuHgJ6LlsyOUYNFQw5rdxs8Vz2mOsIGvWn1Em/c+KCcMltTIhOhDY3zW3ZrFL3Vwq4kTQ74ju9Qp1qyyQOOJmig6LLm31LQvQHPQWkY7rRcp9VBMRPcQIDAQAB"; - public static final String SAML_CLIENT_SALES_POST_SIG_EXPIRED_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n" + - "MIIDQTCCAimgAwIBAgIUT8qwq3DECizGLB2tQAaaNSGAVLgwDQYJKoZIhvcNAQEL\n" + - "BQAwMDEuMCwGA1UEAwwlaHR0cDovL2xvY2FsaG9zdDo4MDgwL3NhbGVzLXBvc3Qt\n" + - "c2lnLzAeFw0yMzAxMjcxNjAwMDBaFw0yMzAxMjgxNjAwMDBaMDAxLjAsBgNVBAMM\n" + - "JWh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9zYWxlcy1wb3N0LXNpZy8wggEiMA0GCSqG\n" + - "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDdIwQZjDffQJL75c/QqqgXPZR7NTFkCGQu\n" + - "/kL3eF/kU8bD1Ck+aKakZyw3xELLgMNg4atu4kt3waSgEKSanvFOpAzH+etS/MMI\n" + - "BYBRKfGcFWAKyr0pukjmx1pw4d3SgQj2lB1FDvVGP62Kl4i34XLxLXtuSkYFiNCT\n" + - "fF26wxfwT0tHTiSynQL2jaa9f5TRAKsXwepUII72Awkk04Zqi3trf5BpNac2s+C6\n" + - "Ey4eAnouWzI5Rg0VDDmt3GzxXPaY6wga9afUSb9z4oJwyW1MiE6ENjfNbdmsUvdX\n" + - "CriRNDviO71CnWrLJA44maKDosubfUtC9Ac9BaRjutFyn1UExE9xAgMBAAGjUzBR\n" + - "MB0GA1UdDgQWBBR4R5i1kWMxzzdQ3TdgI/MuNLChSDAfBgNVHSMEGDAWgBR4R5i1\n" + - "kWMxzzdQ3TdgI/MuNLChSDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUA\n" + - "A4IBAQAacI/f9YFVTUCGXfh/FCVBQI20bgOs9D6IpIhN8L5kEnY6Ox5t00b9G5Bz\n" + - "64alK3WMR3DdhTEpufX8IMFpMlme/JnnOQXkfmIvzbev4iIKxcKFvS8qNXav8PVx\n" + - "wDApuzgxEq/XZCtFXhDS3q1jGRmlOr+MtQdCNQuJmxy7kOoFPY+UYjhSXTZVrCyF\n" + - "I0LYJQfcZ69bYXd+5h1U3UsN4ZvsBgnrz/IhhadaCtTZVtvyr/uzHiJpqT99VO9/\n" + - "7lwh2zL8ihPyOUVDjdYxYyCi+BHLRB+udnVAfo7t3fbxMi1gV9xVcYaqTJgSArsY\n" + - "M8mxv8p5mhTa8TJknzs4V3Dm+PHs\n" + - "-----END CERTIFICATE-----"; + public static final String SAML_CLIENT_SALES_POST_SIG_EXPIRED_PRIVATE_KEY = SamlConstants.SAML_CLIENT_SALES_POST_SIG_EXPIRED_PRIVATE_KEY; + public static final String SAML_CLIENT_SALES_POST_SIG_EXPIRED_PUBLIC_KEY = SamlConstants.SAML_CLIENT_SALES_POST_SIG_EXPIRED_PUBLIC_KEY; + public static final String SAML_CLIENT_SALES_POST_SIG_EXPIRED_CERTIFICATE = SamlConstants.SAML_CLIENT_SALES_POST_SIG_EXPIRED_CERTIFICATE; public static final String SAML_ASSERTION_CONSUMER_URL_SALES_POST_ENC = AUTH_SERVER_SCHEME + "://localhost:" + (AUTH_SERVER_SSL_REQUIRED ? AUTH_SERVER_PORT : 8080) + "/sales-post-enc/saml"; public static final String SAML_CLIENT_ID_SALES_POST_ENC = "http://localhost:8280/sales-post-enc/"; public static final String SAML_CLIENT_SALES_POST_ENC_PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDE5iKDNNW5XxHAF0ITErZcHDYZI68z7u68n7o4dsiywkfOWf7jVnw7PJVnMeDEtLWtTO6f0tRTqJ4OV5HYdJ9+mhPJtn+2UuvrepyYa2IsC1eFPH98ZEtYapsE6ObvhKBQMcu5G/tQrxkCFY2ssDa99unwBH5STLyX78UvqKiYnkPCvIhkiPIHy8ab7DQowc+EE9XhlE3b63A65rp4G9R87rwgJX5VTM3h81WcDuWLPOg7YRYLZoorWz2p38/qL9gXY5NxIRK16EHGfw2W1dPrX3GyMOJbXVyrBNZ6m5IL9Wn7lBEJ/Dl7ZFMFB5W36QkJ+3aaNLT/Tu/Gz+7f24inAgMBAAECggEATiW0zvR6Ww9jgST6AY3suNQtmH60O915/X07sMtcTq6TR1AqvNoHho8+EO4X8ppyfOzKzL4lrWqACNsytIFdCCdo8ScwuxFgN167pjcAiNCblPL0+k7oJJhzHFi/x5KQ+iM5Yye68EP+nfgl+cMahvznzm5KIKn6NCdi0M6U07VRuPIep0v5geqwLOYRWMm8guis5V1p6tpPm6ejplea0QaNpkGxpNuzE2GDJotPRja1TNZUBDV0cKPVY+00BOeuqbiM90V+uk+zRMb9UeeRsuufx2fnLythff19NTgnukgzxWPfU9sSzHen1If1Ul5Xmv3VRG6XhwvOWsLm1TqVuQKBgQD4YgOkRMtpm6BFhOp6pjBcy/H1hN54cMqcTHtpL4w9X7bW+LoN9alfxZiHIRS8+HNATpRtjyKoo5yOQ09NH12/4lFpEIPdkQPzJQIb+kh//QMqqtGcRblCitNObHnlz/HhYDJ3C0nA9frfXhkv3doBAKEELytceGbS1fJ2PcIi2wKBgQDK7+9AmuWXe1qtDt/21j5ymsqhDFjuriPdT6LNvE9ep36h+XRHLe7XEKCKqyOsfYJvK7QI8QQbvB8Jto3pxJf41kBJxmzI9n4SnBKKhInoIICRXXQN4tTDoXVXQGun0idvyhrNEVL3ryW3XPX/UJHFy/Hfjab0sYJm6F50WcQtJQKBgGojUBURBK8zPnCWlLAmdgIhcFqPFZX39MyHbjELjWzoirQgAzlV4bO4Ny5/N2Js9KrlKU4L3S6dA5hTMP7uyVvmtQ0lboPupPZwuQ8Fi5eNoZ3I8ttJfBnwQs1/UzOeAWlidw4ht7mKI1Lx3edzcOX+w8+K7IeON7oejIZ0a5IDAoGAXDrpmIoNWGg2kLpW7V73aKyS9NigvnEkWZus2SYBSHqFIeY2g3cLunCTFhKrluQ/2HibTQkEnfpEfOyb2KeBjhUJiL4GiNsF9z05a/zKlFXZOLepW/pASlzh8HKVuuLXC4Zl4ddCxtCyKoC0SIH8jlGfLsO5IjJemph2/RgjAYUCgYEAkE98bIHsK9jPbt+wnPPs6kyDGHy1JrG9yBlcHOPxsnpxWLFXuxU+9D0qkpbfA28D4jAgehpePzlNPXkF4uIlgarYRDIKss/dX6QQXmmBKjY8UEu+doZYpJGO9SnSuUyih6eRlC/7x9zER/uPjJYia055u2VB0GqO51PKAgq/tqc="; diff --git a/testsuite/integration-arquillian/tests/base/testsuites/base-suite b/testsuite/integration-arquillian/tests/base/testsuites/base-suite index 57304f2236d..e913863b1c4 100644 --- a/testsuite/integration-arquillian/tests/base/testsuites/base-suite +++ b/testsuite/integration-arquillian/tests/base/testsuites/base-suite @@ -18,7 +18,6 @@ feature,4 federation,5 forms,5 i18n,5 -keys,4 login,4 metrics,4 migration,4 diff --git a/testsuite/integration-arquillian/tests/base/testsuites/database-suite b/testsuite/integration-arquillian/tests/base/testsuites/database-suite index 92d3b8b2485..1775773b0f1 100644 --- a/testsuite/integration-arquillian/tests/base/testsuites/database-suite +++ b/testsuite/integration-arquillian/tests/base/testsuites/database-suite @@ -4,7 +4,6 @@ AuthorizationTest ClientRegistrationTest EventStoreProviderTest ExportImportTest -GeneratedRsaKeyProviderTest KcOidcBrokerTest LDAPUserLoginTest LoginTest diff --git a/testsuite/integration-arquillian/tests/base/testsuites/fips-suite b/testsuite/integration-arquillian/tests/base/testsuites/fips-suite index 14a2acacdca..47dc344672a 100644 --- a/testsuite/integration-arquillian/tests/base/testsuites/fips-suite +++ b/testsuite/integration-arquillian/tests/base/testsuites/fips-suite @@ -3,7 +3,6 @@ LoginTotpTest PasswordHashingTest ClientAuthSignedJWTTest ClientAuthEdDSASignedJWTTest -JavaKeystoreKeyProviderTest UserFederationLdapConnectionTest LDAPUserLoginTest org.keycloak.testsuite.x509.** diff --git a/testsuite/integration-arquillian/tests/base/testsuites/jdk-suite b/testsuite/integration-arquillian/tests/base/testsuites/jdk-suite index b578cbca934..2c69b1b6db1 100644 --- a/testsuite/integration-arquillian/tests/base/testsuites/jdk-suite +++ b/testsuite/integration-arquillian/tests/base/testsuites/jdk-suite @@ -2,8 +2,6 @@ AccountRestServiceTest AuthorizationCodeTest DeployedScriptAuthenticatorTest ExportImportTest -GeneratedRsaKeyProviderTest -JavaKeystoreKeyProviderTest KcOidcBrokerTest KerberosLdapTest LDAPUserLoginTest