From 34d02f970ce947c03c936bca32f11753c5cf5e20 Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Wed, 20 May 2026 14:19:43 +0200 Subject: [PATCH 01/12] Change KeyStore type Assumptions - Only changes memory representation of key. - Key never serialized and directly passed to SSLContextBuilder.loadKeyMaterial which accepts any. --- .../cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java b/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java index 618f9ab28..228a30477 100644 --- a/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java +++ b/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java @@ -53,7 +53,7 @@ static KeyStore createKeyStore( Try.of(() -> loadCertificates(certReader)).getOrElseThrow(e -> new DestinationAccessException(MSG_CERT, e)); final PrivateKey privateKey = Try.of(() -> loadKey(keyReader, password)).getOrElseThrow(e -> new DestinationAccessException(MSG_KEY, e)); - final KeyStore keyStore = KeyStore.getInstance("JKS"); + final KeyStore keyStore = KeyStore.getInstance("PKCS12"); keyStore.load(null); keyStore.setKeyEntry(alias, privateKey, password, clientCertificates); return keyStore; From 9d26587d9830d002a858f7613f4622c18188865c Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Wed, 20 May 2026 14:32:04 +0200 Subject: [PATCH 02/12] Same as before. - Only change internal representation and directly forwared to apache SSLContextBuilder --- .../cloudplatform/connectivity/ZeroTrustIdentityService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudplatform/connectivity-ztis/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ZeroTrustIdentityService.java b/cloudplatform/connectivity-ztis/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ZeroTrustIdentityService.java index b9433549d..eba892e88 100644 --- a/cloudplatform/connectivity-ztis/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ZeroTrustIdentityService.java +++ b/cloudplatform/connectivity-ztis/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ZeroTrustIdentityService.java @@ -209,7 +209,7 @@ KeyStore loadKeyStore( @Nonnull final X509Svid svid ) final KeyStore.Entry privateKeyEntry = new PrivateKeyEntry(svid.getPrivateKey(), svid.getChainArray()); final KeyStore keyStore; try { - keyStore = KeyStore.getInstance("JKS"); + keyStore = KeyStore.getInstance("PKCS12"); keyStore.load(null); keyStore.setEntry("spiffe", privateKeyEntry, new KeyStore.PasswordProtection(new char[0])); } From 264290552ef480aa9b634e4e0ace34ba57a7eb0b Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Wed, 20 May 2026 16:35:26 +0200 Subject: [PATCH 03/12] Use standard notation X.509 instead of X509 --- .../cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java b/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java index 228a30477..cbb09cbf0 100644 --- a/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java +++ b/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java @@ -65,7 +65,7 @@ static Certificate[] loadCertificates( @Nonnull final Reader certReader ) IOException { final List certs = new ArrayList<>(); - final CertificateFactory factory = CertificateFactory.getInstance("X509"); + final CertificateFactory factory = CertificateFactory.getInstance("X.509"); try( PEMParser pemParser = new PEMParser(certReader) ) { PemObject object; From d35ed4cd066b0614c855e17baae25e67d214259d Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Wed, 20 May 2026 16:36:13 +0200 Subject: [PATCH 04/12] Update test to show default keystore type used --- .../sdk/cloudplatform/connectivity/KeyStoreReaderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReaderTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReaderTest.java index 20629e686..40bc21672 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReaderTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReaderTest.java @@ -31,7 +31,7 @@ void testPem() final FileReader certs = new FileReader(CRT_PATH), key = new FileReader(KEY_PATH); final KeyStore createdKeystore = createKeyStore(ALIAS, PASS, certs, key); - assertThat(createdKeystore.getType()).isEqualTo("JKS"); + assertThat(createdKeystore.getType()).isEqualTo("PKCS12"); assertThat(createdKeystore.getProvider()).isNotNull(); assertThat(createdKeystore.getCertificateChain(ALIAS)).hasSize(1); From c8a0f3bd8386614752a65a9bf9fc96628efd3381 Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Thu, 21 May 2026 16:10:03 +0200 Subject: [PATCH 05/12] added a test profile --- .../connectivity-apache-httpclient4/pom.xml | 64 ++++++++++++ ...entCertificateAuthenticationLocalTest.java | 2 + .../connectivity/FipsApprovedSmokeTest.java | 99 +++++++++++++++++++ .../HttpClientAndServerTrustTest.java | 2 + ...entCertificateAuthenticationLocalTest.java | 2 + pom.xml | 7 ++ 6 files changed, 176 insertions(+) create mode 100644 cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsApprovedSmokeTest.java diff --git a/cloudplatform/connectivity-apache-httpclient4/pom.xml b/cloudplatform/connectivity-apache-httpclient4/pom.xml index 02a3141db..b19962b06 100644 --- a/cloudplatform/connectivity-apache-httpclient4/pom.xml +++ b/cloudplatform/connectivity-apache-httpclient4/pom.xml @@ -139,4 +139,68 @@ test + + + fips-approved + + + + com.sap.cloud.sdk.cloudplatform + cloudplatform-connectivity + + + org.bouncycastle + bcprov-jdk18on + + + org.bouncycastle + bcpkix-jdk18on + + + + + + org.bouncycastle + bc-fips + 2.1.2 + test + + + + org.bouncycastle + bcpkix-fips + 2.1.9 + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + org.bouncycastle:bcpkix-fips + org.bouncycastle:bc-fips + + + + + + + diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java index e418c79f8..6bbc05439 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java @@ -26,6 +26,7 @@ import org.apache.http.client.protocol.HttpClientContext; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.Mockito; @@ -36,6 +37,7 @@ import lombok.SneakyThrows; +@Tag( "fips-incompatible" ) class ClientCertificateAuthenticationLocalTest { private static final String CCA_PASSWORD = "cca-password"; diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsApprovedSmokeTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsApprovedSmokeTest.java new file mode 100644 index 000000000..20b0bf734 --- /dev/null +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsApprovedSmokeTest.java @@ -0,0 +1,99 @@ +package com.sap.cloud.sdk.cloudplatform.connectivity; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.FileReader; +import java.security.KeyStore; +import java.security.Security; + +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import lombok.SneakyThrows; + +/** + * FIPS compatibility smoke tests for PEM credential loading and KeyStore creation. + * + *

+ * These tests replicate the user scenario from FIPS analysis (User Analysis A/B, Flow 1): the user has registered BC + * FIPS as the JCA provider, enabled approved-only mode, and is using the SDK to load a BTP destination configured with + * a PEM client certificate. + * + *

+ * The meaningful assertion is that no {@code FipsUnapprovedOperationError} is thrown — meaning the code path does not + * invoke any non-FIPS-approved algorithms when BC FIPS is registered and {@code approved_only=true} is active. + * + *

+ * Note on provider resolution: {@code KeyStore.getInstance("PKCS12")} resolves to the {@code SUN} provider on a + * standard JDK even with BCFIPS at position 1. BCFIPS passes PKCS12 requests through since PKCS12 is a FIPS-approved + * format regardless of which JCA provider constructs the in-memory container. On a real FIPS JVM (e.g., Red Hat FIPS + * OpenJDK), provider configuration is enforced at the OS/JDK level. No assertion on the provider name is made. + * + *

+ * Run with: {@code mvn test -P fips-approved} (Requires -Dorg.bouncycastle.fips.approved_only=true which is set by the + * profile argLine) + */ +@Tag( "fips-approved" ) +class FipsApprovedSmokeTest +{ + private static final String RES = + "src/test/resources/" + ClientCertificateAuthenticationLocalTest.class.getSimpleName(); + private static final String CRT_PATH = RES + "/client-cert.crt"; + private static final String KEY_PATH = RES + "/client-cert.key"; + private static final String ALIAS = "client-cert"; + private static final char[] EMPTY_PASSWORD = new char[0]; + + @BeforeAll + static void registerBouncyCastleFips() + { + Security.insertProviderAt(new BouncyCastleFipsProvider(), 1); + + assertThat(Security.getProvider("BCFIPS")) + .describedAs("BC FIPS provider must be registered as a JCA provider") + .isNotNull(); + + assertThat(CryptoServicesRegistrar.isInApprovedOnlyMode()) + .describedAs( + "BC FIPS must be in approved-only mode. " + + "Ensure -Dorg.bouncycastle.fips.approved_only=true is set (done by the fips-approved Maven profile).") + .isTrue(); + } + + /** + * Verifies Flow 1 from User Analysis A/B: PEM certificate + unencrypted PKCS#8 private key → in-memory PKCS12 + * KeyStore → available for mTLS. + * + *

+ * This is the critical code path fixed in P1: {@code KeyStoreReader.createKeyStore()} now creates a PKCS12 KeyStore + * (was JKS before the fix). If any non-FIPS algorithm were invoked during key loading (e.g., JKS key cipher which + * uses MD5), BC FIPS would throw {@code FipsUnapprovedOperationError}. The fact that this test completes without + * throwing confirms the fix is effective. + */ + @Test + @SneakyThrows + void pemCertificateAndKeyLoadCompletesWithoutFipsViolation() + { + // If any non-FIPS algorithm were invoked, FipsUnapprovedOperationError would be thrown here. + final KeyStore keyStore = + KeyStoreReader.createKeyStore(ALIAS, EMPTY_PASSWORD, new FileReader(CRT_PATH), new FileReader(KEY_PATH)); + + assertThat(keyStore.getType()) + .describedAs("KeyStore must be PKCS12 type — validates the P1 fix (was JKS before)") + .isEqualTo("PKCS12"); + + assertThat(keyStore.getCertificateChain(ALIAS)) + .describedAs("Certificate chain must be present and non-empty") + .isNotNull() + .isNotEmpty(); + + assertThat(keyStore.getKey(ALIAS, EMPTY_PASSWORD)) + .describedAs("Private key must be accessible from the KeyStore") + .isNotNull(); + + // No assertion on keyStore.getProvider().getName() — on a standard JDK, SUN provides PKCS12 + // even with BCFIPS at position 1. PKCS12 is FIPS-approved regardless of the provider. + } +} diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientAndServerTrustTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientAndServerTrustTest.java index 0367bee5a..cceb50263 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientAndServerTrustTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientAndServerTrustTest.java @@ -23,6 +23,7 @@ import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -36,6 +37,7 @@ * Read the readme.md in the resources folder on how to generate keys, certificates and key stores. Certificates expire * after 50 years in around 2070. */ +@Tag( "fips-incompatible" ) class HttpClientAndServerTrustTest { private static final String RELATIVE_PATH = "some/path"; diff --git a/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java b/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java index d6a15226b..54c6a71d4 100644 --- a/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java +++ b/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java @@ -25,6 +25,7 @@ import org.apache.hc.core5.http.HttpHeaders; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.Mockito; @@ -35,6 +36,7 @@ import lombok.SneakyThrows; +@Tag( "fips-incompatible" ) class ClientCertificateAuthenticationLocalTest { private static final String JKS_PREFIX = diff --git a/pom.xml b/pom.xml index 9fee0baa3..91ab343ea 100644 --- a/pom.xml +++ b/pom.xml @@ -933,6 +933,13 @@ + + fips-approved + + -Xmx${surefire.maxMemorySize} -Dfile.encoding=${project.build.sourceEncoding} -Dorg.slf4j.simpleLogger.defaultLogLevel=${surefire.logLevel} -Dorg.bouncycastle.fips.approved_only=true + fips-approved + + skip-openapi-vdm-generation From ded243fb1690eca9d675907c6f9e2b0ce5c09597 Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Thu, 28 May 2026 11:01:56 +0200 Subject: [PATCH 06/12] Change all JKS usage to PKCS12 --- .../cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java | 4 ++-- .../sdk/cloudplatform/connectivity/KeyStoreReaderTest.java | 2 +- .../cloudplatform/connectivity/ZeroTrustIdentityService.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java b/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java index 618f9ab28..cbb09cbf0 100644 --- a/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java +++ b/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java @@ -53,7 +53,7 @@ static KeyStore createKeyStore( Try.of(() -> loadCertificates(certReader)).getOrElseThrow(e -> new DestinationAccessException(MSG_CERT, e)); final PrivateKey privateKey = Try.of(() -> loadKey(keyReader, password)).getOrElseThrow(e -> new DestinationAccessException(MSG_KEY, e)); - final KeyStore keyStore = KeyStore.getInstance("JKS"); + final KeyStore keyStore = KeyStore.getInstance("PKCS12"); keyStore.load(null); keyStore.setKeyEntry(alias, privateKey, password, clientCertificates); return keyStore; @@ -65,7 +65,7 @@ static Certificate[] loadCertificates( @Nonnull final Reader certReader ) IOException { final List certs = new ArrayList<>(); - final CertificateFactory factory = CertificateFactory.getInstance("X509"); + final CertificateFactory factory = CertificateFactory.getInstance("X.509"); try( PEMParser pemParser = new PEMParser(certReader) ) { PemObject object; diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReaderTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReaderTest.java index 20629e686..40bc21672 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReaderTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReaderTest.java @@ -31,7 +31,7 @@ void testPem() final FileReader certs = new FileReader(CRT_PATH), key = new FileReader(KEY_PATH); final KeyStore createdKeystore = createKeyStore(ALIAS, PASS, certs, key); - assertThat(createdKeystore.getType()).isEqualTo("JKS"); + assertThat(createdKeystore.getType()).isEqualTo("PKCS12"); assertThat(createdKeystore.getProvider()).isNotNull(); assertThat(createdKeystore.getCertificateChain(ALIAS)).hasSize(1); diff --git a/cloudplatform/connectivity-ztis/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ZeroTrustIdentityService.java b/cloudplatform/connectivity-ztis/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ZeroTrustIdentityService.java index b9433549d..eba892e88 100644 --- a/cloudplatform/connectivity-ztis/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ZeroTrustIdentityService.java +++ b/cloudplatform/connectivity-ztis/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ZeroTrustIdentityService.java @@ -209,7 +209,7 @@ KeyStore loadKeyStore( @Nonnull final X509Svid svid ) final KeyStore.Entry privateKeyEntry = new PrivateKeyEntry(svid.getPrivateKey(), svid.getChainArray()); final KeyStore keyStore; try { - keyStore = KeyStore.getInstance("JKS"); + keyStore = KeyStore.getInstance("PKCS12"); keyStore.load(null); keyStore.setEntry("spiffe", privateKeyEntry, new KeyStore.PasswordProtection(new char[0])); } From 5ba452c3a526a806e5529f169c15a60fac6f058f Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Tue, 2 Jun 2026 10:55:42 +0200 Subject: [PATCH 07/12] Cleanup --- .../connectivity-apache-httpclient4/pom.xml | 26 ++--- ...entCertificateAuthenticationLocalTest.java | 2 - .../connectivity/FipsApprovedSmokeTest.java | 99 ------------------- .../connectivity/FipsProviderTest.java | 55 +++++++++++ .../HttpClientAndServerTrustTest.java | 2 - ...entCertificateAuthenticationLocalTest.java | 2 - 6 files changed, 62 insertions(+), 124 deletions(-) delete mode 100644 cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsApprovedSmokeTest.java create mode 100644 cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java diff --git a/cloudplatform/connectivity-apache-httpclient4/pom.xml b/cloudplatform/connectivity-apache-httpclient4/pom.xml index b19962b06..2c2366012 100644 --- a/cloudplatform/connectivity-apache-httpclient4/pom.xml +++ b/cloudplatform/connectivity-apache-httpclient4/pom.xml @@ -28,6 +28,10 @@ https://www.sap.com + + 2.1.2 + 2.1.9 + com.sap.cloud.sdk.cloudplatform @@ -142,14 +146,6 @@ fips-approved - com.sap.cloud.sdk.cloudplatform @@ -165,18 +161,16 @@ - org.bouncycastle bc-fips - 2.1.2 + ${bc-fips.version} test - org.bouncycastle bcpkix-fips - 2.1.9 + ${bcpkix-fips.version} test @@ -187,13 +181,7 @@ maven-dependency-plugin - + org.bouncycastle:bcpkix-fips org.bouncycastle:bc-fips diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java index 6bbc05439..e418c79f8 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java @@ -26,7 +26,6 @@ import org.apache.http.client.protocol.HttpClientContext; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.Mockito; @@ -37,7 +36,6 @@ import lombok.SneakyThrows; -@Tag( "fips-incompatible" ) class ClientCertificateAuthenticationLocalTest { private static final String CCA_PASSWORD = "cca-password"; diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsApprovedSmokeTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsApprovedSmokeTest.java deleted file mode 100644 index 20b0bf734..000000000 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsApprovedSmokeTest.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.sap.cloud.sdk.cloudplatform.connectivity; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.io.FileReader; -import java.security.KeyStore; -import java.security.Security; - -import org.bouncycastle.crypto.CryptoServicesRegistrar; -import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -import lombok.SneakyThrows; - -/** - * FIPS compatibility smoke tests for PEM credential loading and KeyStore creation. - * - *

- * These tests replicate the user scenario from FIPS analysis (User Analysis A/B, Flow 1): the user has registered BC - * FIPS as the JCA provider, enabled approved-only mode, and is using the SDK to load a BTP destination configured with - * a PEM client certificate. - * - *

- * The meaningful assertion is that no {@code FipsUnapprovedOperationError} is thrown — meaning the code path does not - * invoke any non-FIPS-approved algorithms when BC FIPS is registered and {@code approved_only=true} is active. - * - *

- * Note on provider resolution: {@code KeyStore.getInstance("PKCS12")} resolves to the {@code SUN} provider on a - * standard JDK even with BCFIPS at position 1. BCFIPS passes PKCS12 requests through since PKCS12 is a FIPS-approved - * format regardless of which JCA provider constructs the in-memory container. On a real FIPS JVM (e.g., Red Hat FIPS - * OpenJDK), provider configuration is enforced at the OS/JDK level. No assertion on the provider name is made. - * - *

- * Run with: {@code mvn test -P fips-approved} (Requires -Dorg.bouncycastle.fips.approved_only=true which is set by the - * profile argLine) - */ -@Tag( "fips-approved" ) -class FipsApprovedSmokeTest -{ - private static final String RES = - "src/test/resources/" + ClientCertificateAuthenticationLocalTest.class.getSimpleName(); - private static final String CRT_PATH = RES + "/client-cert.crt"; - private static final String KEY_PATH = RES + "/client-cert.key"; - private static final String ALIAS = "client-cert"; - private static final char[] EMPTY_PASSWORD = new char[0]; - - @BeforeAll - static void registerBouncyCastleFips() - { - Security.insertProviderAt(new BouncyCastleFipsProvider(), 1); - - assertThat(Security.getProvider("BCFIPS")) - .describedAs("BC FIPS provider must be registered as a JCA provider") - .isNotNull(); - - assertThat(CryptoServicesRegistrar.isInApprovedOnlyMode()) - .describedAs( - "BC FIPS must be in approved-only mode. " - + "Ensure -Dorg.bouncycastle.fips.approved_only=true is set (done by the fips-approved Maven profile).") - .isTrue(); - } - - /** - * Verifies Flow 1 from User Analysis A/B: PEM certificate + unencrypted PKCS#8 private key → in-memory PKCS12 - * KeyStore → available for mTLS. - * - *

- * This is the critical code path fixed in P1: {@code KeyStoreReader.createKeyStore()} now creates a PKCS12 KeyStore - * (was JKS before the fix). If any non-FIPS algorithm were invoked during key loading (e.g., JKS key cipher which - * uses MD5), BC FIPS would throw {@code FipsUnapprovedOperationError}. The fact that this test completes without - * throwing confirms the fix is effective. - */ - @Test - @SneakyThrows - void pemCertificateAndKeyLoadCompletesWithoutFipsViolation() - { - // If any non-FIPS algorithm were invoked, FipsUnapprovedOperationError would be thrown here. - final KeyStore keyStore = - KeyStoreReader.createKeyStore(ALIAS, EMPTY_PASSWORD, new FileReader(CRT_PATH), new FileReader(KEY_PATH)); - - assertThat(keyStore.getType()) - .describedAs("KeyStore must be PKCS12 type — validates the P1 fix (was JKS before)") - .isEqualTo("PKCS12"); - - assertThat(keyStore.getCertificateChain(ALIAS)) - .describedAs("Certificate chain must be present and non-empty") - .isNotNull() - .isNotEmpty(); - - assertThat(keyStore.getKey(ALIAS, EMPTY_PASSWORD)) - .describedAs("Private key must be accessible from the KeyStore") - .isNotNull(); - - // No assertion on keyStore.getProvider().getName() — on a standard JDK, SUN provides PKCS12 - // even with BCFIPS at position 1. PKCS12 is FIPS-approved regardless of the provider. - } -} diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java new file mode 100644 index 000000000..0e1ed5059 --- /dev/null +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java @@ -0,0 +1,55 @@ +package com.sap.cloud.sdk.cloudplatform.connectivity; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.FileReader; +import java.security.KeyStore; +import java.security.Security; + +import org.bouncycastle.crypto.CryptoServicesRegistrar; +import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import lombok.SneakyThrows; + +/** + * Regression guard for the P1 fix: asserts that {@code KeyStoreReader.createKeyStore()} produces a PKCS12 keystore. + * Run with {@code mvn test -P fips-approved}. + */ +@Tag("fips-approved") +class FipsProviderTest { + private static final String RES = "src/test/resources/ClientCertificateAuthenticationLocalTest"; + private static final String CRT_PATH = RES + "/client-cert.crt"; + private static final String KEY_PATH = RES + "/client-cert.key"; + private static final String ALIAS = "client-cert"; + private static final char[] EMPTY_PASSWORD = new char[0]; + + @AfterAll + static void removeBouncyCastleFips() + { + Security.removeProvider("BCFIPS"); + } + + @BeforeAll + static void registerBouncyCastleFips() { + Security.insertProviderAt(new BouncyCastleFipsProvider("C:DEFRND[SHA256];ENABLE{ALL}"), 1); + + assertThat(Security.getProvider("BCFIPS")).describedAs("BC FIPS provider must be registered as a JCA provider").isNotNull(); + + assertThat(CryptoServicesRegistrar.isInApprovedOnlyMode()).describedAs("BC FIPS must be in approved-only mode. " + "Ensure -Dorg.bouncycastle.fips.approved_only=true is set (done by the fips-approved Maven profile).").isTrue(); + } + + /** + * Regression guard for the P1 fix: verifies that {@code KeyStoreReader.createKeyStore()} produces a PKCS12 + */ + @Test + @SneakyThrows + void keystoreTypeIsP12() { + final KeyStore keyStore = KeyStoreReader.createKeyStore(ALIAS, EMPTY_PASSWORD, new FileReader(CRT_PATH), new FileReader(KEY_PATH)); + + assertThat(keyStore.getType()).isEqualTo("PKCS12"); + } +} \ No newline at end of file diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientAndServerTrustTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientAndServerTrustTest.java index cceb50263..0367bee5a 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientAndServerTrustTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/HttpClientAndServerTrustTest.java @@ -23,7 +23,6 @@ import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; -import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -37,7 +36,6 @@ * Read the readme.md in the resources folder on how to generate keys, certificates and key stores. Certificates expire * after 50 years in around 2070. */ -@Tag( "fips-incompatible" ) class HttpClientAndServerTrustTest { private static final String RELATIVE_PATH = "some/path"; diff --git a/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java b/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java index 54c6a71d4..d6a15226b 100644 --- a/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java +++ b/cloudplatform/connectivity-apache-httpclient5/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/ClientCertificateAuthenticationLocalTest.java @@ -25,7 +25,6 @@ import org.apache.hc.core5.http.HttpHeaders; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.mockito.Mockito; @@ -36,7 +35,6 @@ import lombok.SneakyThrows; -@Tag( "fips-incompatible" ) class ClientCertificateAuthenticationLocalTest { private static final String JKS_PREFIX = From 18a346a4cce4e0ea2e8dc82ac260d940fbff037d Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Tue, 2 Jun 2026 14:11:31 +0200 Subject: [PATCH 08/12] Add test to confirm BCFIPS is working correctly --- .../connectivity/FipsProviderTest.java | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java index 0e1ed5059..c8db49d88 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java @@ -1,9 +1,12 @@ package com.sap.cloud.sdk.cloudplatform.connectivity; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.io.FileReader; import java.security.KeyStore; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.security.Security; import org.bouncycastle.crypto.CryptoServicesRegistrar; @@ -16,11 +19,12 @@ import lombok.SneakyThrows; /** - * Regression guard for the P1 fix: asserts that {@code KeyStoreReader.createKeyStore()} produces a PKCS12 keystore. - * Run with {@code mvn test -P fips-approved}. + * Regression guard for the P1 fix: asserts that {@code KeyStoreReader.createKeyStore()} produces a PKCS12 keystore. Run + * with {@code mvn test -P fips-approved}. */ -@Tag("fips-approved") -class FipsProviderTest { +@Tag( "fips-approved" ) +class FipsProviderTest +{ private static final String RES = "src/test/resources/ClientCertificateAuthenticationLocalTest"; private static final String CRT_PATH = RES + "/client-cert.crt"; private static final String KEY_PATH = RES + "/client-cert.key"; @@ -34,22 +38,34 @@ static void removeBouncyCastleFips() } @BeforeAll - static void registerBouncyCastleFips() { - Security.insertProviderAt(new BouncyCastleFipsProvider("C:DEFRND[SHA256];ENABLE{ALL}"), 1); + static void registerBouncyCastleFips() + { + Security.insertProviderAt(new BouncyCastleFipsProvider(), 1); - assertThat(Security.getProvider("BCFIPS")).describedAs("BC FIPS provider must be registered as a JCA provider").isNotNull(); + assertThat(Security.getProvider("BCFIPS")) + .describedAs("BC FIPS provider must be registered as a JCA provider") + .isNotNull(); - assertThat(CryptoServicesRegistrar.isInApprovedOnlyMode()).describedAs("BC FIPS must be in approved-only mode. " + "Ensure -Dorg.bouncycastle.fips.approved_only=true is set (done by the fips-approved Maven profile).").isTrue(); + assertThat(CryptoServicesRegistrar.isInApprovedOnlyMode()) + .describedAs("BC FIPS must be in approved-only mode. ") + .isTrue(); } - /** - * Regression guard for the P1 fix: verifies that {@code KeyStoreReader.createKeyStore()} produces a PKCS12 - */ @Test @SneakyThrows - void keystoreTypeIsP12() { - final KeyStore keyStore = KeyStoreReader.createKeyStore(ALIAS, EMPTY_PASSWORD, new FileReader(CRT_PATH), new FileReader(KEY_PATH)); + void keystoreTypeIsP12() + { + final KeyStore keyStore = + KeyStoreReader.createKeyStore(ALIAS, EMPTY_PASSWORD, new FileReader(CRT_PATH), new FileReader(KEY_PATH)); assertThat(keyStore.getType()).isEqualTo("PKCS12"); } -} \ No newline at end of file + + @Test + void md5IsRejectedInApprovedOnlyMode() + { + assertThatThrownBy(() -> MessageDigest.getInstance("MD5", "BCFIPS")) + .isInstanceOf(NoSuchAlgorithmException.class); + + } +} From 1658ad3fa253560414e73112be77dc3c25b90c73 Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Wed, 3 Jun 2026 11:21:44 +0200 Subject: [PATCH 09/12] Move fips test into new test source root --- .../connectivity-apache-httpclient4/pom.xml | 18 ++++++++++++++++++ .../connectivity/FipsProviderTest.java | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) rename cloudplatform/connectivity-apache-httpclient4/src/{test => test-fips}/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java (99%) diff --git a/cloudplatform/connectivity-apache-httpclient4/pom.xml b/cloudplatform/connectivity-apache-httpclient4/pom.xml index 2c2366012..e1e48a2a0 100644 --- a/cloudplatform/connectivity-apache-httpclient4/pom.xml +++ b/cloudplatform/connectivity-apache-httpclient4/pom.xml @@ -176,6 +176,24 @@ + + org.codehaus.mojo + build-helper-maven-plugin + + + add-fips-test-sources + generate-test-sources + + add-test-source + + + + src/test-fips/java + + + + + org.apache.maven.plugins maven-dependency-plugin diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test-fips/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java similarity index 99% rename from cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java rename to cloudplatform/connectivity-apache-httpclient4/src/test-fips/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java index c8db49d88..f7a7dba88 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test-fips/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java @@ -68,4 +68,4 @@ void md5IsRejectedInApprovedOnlyMode() .isInstanceOf(NoSuchAlgorithmException.class); } -} +} \ No newline at end of file From 127b3536b5e7f87a13a6824ced1a0d34c9cc12fd Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Wed, 3 Jun 2026 13:43:39 +0200 Subject: [PATCH 10/12] Switch to defaultType() from harcoded pkcs12 --- .../cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java | 2 +- .../sdk/cloudplatform/connectivity/KeyStoreReaderTest.java | 2 +- .../cloudplatform/connectivity/ZeroTrustIdentityService.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java b/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java index cbb09cbf0..55965736f 100644 --- a/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java +++ b/cloudplatform/cloudplatform-connectivity/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReader.java @@ -53,7 +53,7 @@ static KeyStore createKeyStore( Try.of(() -> loadCertificates(certReader)).getOrElseThrow(e -> new DestinationAccessException(MSG_CERT, e)); final PrivateKey privateKey = Try.of(() -> loadKey(keyReader, password)).getOrElseThrow(e -> new DestinationAccessException(MSG_KEY, e)); - final KeyStore keyStore = KeyStore.getInstance("PKCS12"); + final KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null); keyStore.setKeyEntry(alias, privateKey, password, clientCertificates); return keyStore; diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReaderTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReaderTest.java index 40bc21672..9059e31e2 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReaderTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/KeyStoreReaderTest.java @@ -31,7 +31,7 @@ void testPem() final FileReader certs = new FileReader(CRT_PATH), key = new FileReader(KEY_PATH); final KeyStore createdKeystore = createKeyStore(ALIAS, PASS, certs, key); - assertThat(createdKeystore.getType()).isEqualTo("PKCS12"); + assertThat(createdKeystore.getType()).isEqualTo(KeyStore.getDefaultType()); assertThat(createdKeystore.getProvider()).isNotNull(); assertThat(createdKeystore.getCertificateChain(ALIAS)).hasSize(1); diff --git a/cloudplatform/connectivity-ztis/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ZeroTrustIdentityService.java b/cloudplatform/connectivity-ztis/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ZeroTrustIdentityService.java index eba892e88..842b49cba 100644 --- a/cloudplatform/connectivity-ztis/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ZeroTrustIdentityService.java +++ b/cloudplatform/connectivity-ztis/src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/ZeroTrustIdentityService.java @@ -209,7 +209,7 @@ KeyStore loadKeyStore( @Nonnull final X509Svid svid ) final KeyStore.Entry privateKeyEntry = new PrivateKeyEntry(svid.getPrivateKey(), svid.getChainArray()); final KeyStore keyStore; try { - keyStore = KeyStore.getInstance("PKCS12"); + keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null); keyStore.setEntry("spiffe", privateKeyEntry, new KeyStore.PasswordProtection(new char[0])); } From 27541c24159b37926bf24560a81a6adb7fd51bcb Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Wed, 3 Jun 2026 17:23:44 +0200 Subject: [PATCH 11/12] minor fix --- .../cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test-fips/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java b/cloudplatform/connectivity-apache-httpclient4/src/test-fips/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java index f7a7dba88..0cdfad0f9 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test-fips/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java +++ b/cloudplatform/connectivity-apache-httpclient4/src/test-fips/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java @@ -58,7 +58,7 @@ void keystoreTypeIsP12() final KeyStore keyStore = KeyStoreReader.createKeyStore(ALIAS, EMPTY_PASSWORD, new FileReader(CRT_PATH), new FileReader(KEY_PATH)); - assertThat(keyStore.getType()).isEqualTo("PKCS12"); + assertThat(keyStore.getType()).isEqualTo("pkcs12"); } @Test From cc4a5f033b503e9050d1446d2d9a5075f3171f0c Mon Sep 17 00:00:00 2001 From: Roshin Rajan Panackal Date: Fri, 5 Jun 2026 15:59:19 +0200 Subject: [PATCH 12/12] Remove the profile and introduce a test module --- .../connectivity-apache-httpclient4/pom.xml | 70 --------- .../connectivity-fips-sample/pom.xml | 143 ++++++++++++++++++ .../connectivity/FipsProviderTest.java | 4 +- .../resources/certificates/client-cert.crt | 22 +++ .../resources/certificates/client-cert.key | 28 ++++ cloudplatform/pom.xml | 12 ++ module-inventory.json | 11 ++ pom.xml | 8 +- 8 files changed, 219 insertions(+), 79 deletions(-) create mode 100644 cloudplatform/connectivity-fips-sample/pom.xml rename cloudplatform/{connectivity-apache-httpclient4/src/test-fips => connectivity-fips-sample/src/test}/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java (95%) create mode 100644 cloudplatform/connectivity-fips-sample/src/test/resources/certificates/client-cert.crt create mode 100644 cloudplatform/connectivity-fips-sample/src/test/resources/certificates/client-cert.key diff --git a/cloudplatform/connectivity-apache-httpclient4/pom.xml b/cloudplatform/connectivity-apache-httpclient4/pom.xml index e1e48a2a0..02a3141db 100644 --- a/cloudplatform/connectivity-apache-httpclient4/pom.xml +++ b/cloudplatform/connectivity-apache-httpclient4/pom.xml @@ -28,10 +28,6 @@ https://www.sap.com - - 2.1.2 - 2.1.9 - com.sap.cloud.sdk.cloudplatform @@ -143,70 +139,4 @@ test - - - fips-approved - - - com.sap.cloud.sdk.cloudplatform - cloudplatform-connectivity - - - org.bouncycastle - bcprov-jdk18on - - - org.bouncycastle - bcpkix-jdk18on - - - - - org.bouncycastle - bc-fips - ${bc-fips.version} - test - - - org.bouncycastle - bcpkix-fips - ${bcpkix-fips.version} - test - - - - - - org.codehaus.mojo - build-helper-maven-plugin - - - add-fips-test-sources - generate-test-sources - - add-test-source - - - - src/test-fips/java - - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - - org.bouncycastle:bcpkix-fips - org.bouncycastle:bc-fips - - - - - - - diff --git a/cloudplatform/connectivity-fips-sample/pom.xml b/cloudplatform/connectivity-fips-sample/pom.xml new file mode 100644 index 000000000..b6feb5a2e --- /dev/null +++ b/cloudplatform/connectivity-fips-sample/pom.xml @@ -0,0 +1,143 @@ + + + 4.0.0 + + com.sap.cloud.sdk.cloudplatform + cloudplatform-parent + 5.31.0-SNAPSHOT + + connectivity-fips-sample + Connectivity - FIPS Sample + Non-released sample module that runs connectivity tests under the FIPS-approved Bouncy Castle provider. + https://sap.github.io/cloud-sdk/docs/java/getting-started + + SAP SE + https://www.sap.com + + + + The Apache Software License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + + + + + SAP + cloudsdk@sap.com + SAP SE + https://www.sap.com + + + + 2.1.2 + 2.1.9 + + + + com.sap.cloud.sdk.cloudplatform + cloudplatform-connectivity + + + org.bouncycastle + bcprov-jdk18on + + + org.bouncycastle + bcpkix-jdk18on + + + test + + + org.bouncycastle + bc-fips + ${bc-fips.version} + test + + + org.bouncycastle + bcpkix-fips + ${bcpkix-fips.version} + test + + + org.projectlombok + lombok + provided + + + org.junit.jupiter + junit-jupiter-api + test + + + org.assertj + assertj-core + test + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + ${argLine} -Dorg.bouncycastle.fips.approved_only=true + + + + org.apache.maven.plugins + maven-dependency-plugin + + + org.bouncycastle:bc-fips + org.bouncycastle:bcpkix-fips + com.sap.cloud.sdk.cloudplatform:cloudplatform-connectivity + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + true + + + org.apache.maven.plugins + maven-pmd-plugin + true + + + org.apache.maven.plugins + maven-javadoc-plugin + true + + + org.jacoco + jacoco-maven-plugin + true + + + + + + release + + release + + + + + org.sonatype.central + central-publishing-maven-plugin + + + injected-central-publishing + + + + + + + + + diff --git a/cloudplatform/connectivity-apache-httpclient4/src/test-fips/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java b/cloudplatform/connectivity-fips-sample/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java similarity index 95% rename from cloudplatform/connectivity-apache-httpclient4/src/test-fips/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java rename to cloudplatform/connectivity-fips-sample/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java index 0cdfad0f9..b61c5cd68 100644 --- a/cloudplatform/connectivity-apache-httpclient4/src/test-fips/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java +++ b/cloudplatform/connectivity-fips-sample/src/test/java/com/sap/cloud/sdk/cloudplatform/connectivity/FipsProviderTest.java @@ -25,7 +25,7 @@ @Tag( "fips-approved" ) class FipsProviderTest { - private static final String RES = "src/test/resources/ClientCertificateAuthenticationLocalTest"; + private static final String RES = "src/test/resources/certificates"; private static final String CRT_PATH = RES + "/client-cert.crt"; private static final String KEY_PATH = RES + "/client-cert.key"; private static final String ALIAS = "client-cert"; @@ -68,4 +68,4 @@ void md5IsRejectedInApprovedOnlyMode() .isInstanceOf(NoSuchAlgorithmException.class); } -} \ No newline at end of file +} diff --git a/cloudplatform/connectivity-fips-sample/src/test/resources/certificates/client-cert.crt b/cloudplatform/connectivity-fips-sample/src/test/resources/certificates/client-cert.crt new file mode 100644 index 000000000..8b313ee50 --- /dev/null +++ b/cloudplatform/connectivity-fips-sample/src/test/resources/certificates/client-cert.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIUDfIuo9MZ6BTCuQAndYmYHMsnKrYwDQYJKoZIhvcNAQEL +BQAwajELMAkGA1UEBhMCREUxFDASBgNVBAgMC0JyYW5kZW5idXJnMRAwDgYDVQQK +DAdQb3RzZGFtMR8wHQYJKoZIhvcNAQkBFhBjbG91ZHNka0BzYXAuY29tMRIwEAYD +VQQDDAlsb2NhbGhvc3QwHhcNMjQwMTEyMTAyOTMwWhcNMzQwMTA5MTAyOTMwWjBq +MQswCQYDVQQGEwJERTEUMBIGA1UECAwLQnJhbmRlbmJ1cmcxEDAOBgNVBAoMB1Bv +dHNkYW0xHzAdBgkqhkiG9w0BCQEWEGNsb3Vkc2RrQHNhcC5jb20xEjAQBgNVBAMM +CWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALSd6Fz/ +ZfDA52fZBuB+kP0JT5b8HqcKMX/Smt7S5bi5DwFi/RhHoaD1o5td8HPIP+N6sm8s +l/HiZhZmIleGabyOUiO1JnglHijElrJZrny6ZYJcrzMkOWGtM/8mUZRXzm6Ae8bP +pib6Kza3qsIq5Br0yBo/XOClbE+BFilvoUGiBb78eIHH14OQGYMkXzbUWJOVTQ6q +5tlfQP1yHm9txVvlMwD+qqS1LjNdj3L72vFrkZil2AHXA0pdWLWn13K8r0U6+RNT +99mYEw/5BoaOZA0NRX3kFeCGJKDz92SEdzbPU2F4+dt8/Is3Xj397zku/OITWRtW +oQTOgp4l01ev2TcCAwEAAaNVMFMwCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwGgYD +VR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMB0GA1UdDgQWBBQChuZYKEuGYQLWgSPS +njRacT/rJjANBgkqhkiG9w0BAQsFAAOCAQEAXqiPPxWiNXw9stwC3PIwMbgHjmJG +0gSy/OLOWihP8Fet4m2mhYiZ6E1vx1THjgl7+s1BYc4HE7GgXrvoSEKJsTUUVjCf +u4xbN4YxBjxBSs0If0hOPrtOEln5ij6rKuTFh9+cskt4MYgy+XuP0iT7MOrk7jqp +Jx6QdPbQEPTdmZ0XWlJz+qP+BQIl/lTcD7GoBS/tCYoyaljmfMMGaJ83HVlKfMpH +ELWFT2Y4mSNFo1jOFt7lR+cWy9YJ9gerxEskHKYqIX0e4ELhSyovix4c7dUstszy +RjVcfhNI8gsxAbkT+mYuIMl4zkTA1yUcmqEgBhxA9vIVD7kfL8S0bELBHA== +-----END CERTIFICATE----- diff --git a/cloudplatform/connectivity-fips-sample/src/test/resources/certificates/client-cert.key b/cloudplatform/connectivity-fips-sample/src/test/resources/certificates/client-cert.key new file mode 100644 index 000000000..250483648 --- /dev/null +++ b/cloudplatform/connectivity-fips-sample/src/test/resources/certificates/client-cert.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC0nehc/2XwwOdn +2QbgfpD9CU+W/B6nCjF/0pre0uW4uQ8BYv0YR6Gg9aObXfBzyD/jerJvLJfx4mYW +ZiJXhmm8jlIjtSZ4JR4oxJayWa58umWCXK8zJDlhrTP/JlGUV85ugHvGz6Ym+is2 +t6rCKuQa9MgaP1zgpWxPgRYpb6FBogW+/HiBx9eDkBmDJF821FiTlU0OqubZX0D9 +ch5vbcVb5TMA/qqktS4zXY9y+9rxa5GYpdgB1wNKXVi1p9dyvK9FOvkTU/fZmBMP ++QaGjmQNDUV95BXghiSg8/dkhHc2z1NhePnbfPyLN149/e85LvziE1kbVqEEzoKe +JdNXr9k3AgMBAAECggEADh8af8roKX6rmQ763qqGo4IK2v8zVlQRsrDAsxNCKsMt +TSp0J2XSWUdbV1Zs6mCJvjtloBOYfaz51l596OH1emyWN3x+WX5tcTqNnbwtTEs2 +jI66lAENC3oDSruwPSzwUutwwgaSMxH0Nv79NtkrpH/m9UZm+Jl2cnDhTrQPo5Xp +siezDaO1vhX1WyHXKvSZy04+k1idy38XcZTMQ3xquapc4QhkYB3hj8qbF63gZUiw +Q7XhvETavKYCoVL5yC1RkNVZT5cCGzyQJePWvApQLB+ynr/aNjstjQhCcv74x0b3 +9Zs56UD5sTw3JwSlQmDGX72689qx/VO3OOEXJYzcoQKBgQDlzvpcifmzGLodGZcG +RPSauvRoAb7osSSAOU3ANNaP10jOJG/qiG4d99c1wC0wGSRFeILAAUIU5xuq5k2X +Sl5LfSSmwK8z1d2LfAXoEx91PlF9/MH5UncQIclHn+hsevu5eFwDkx1oKE5l9whB +hlgzTGKCO1lbUPL499poDFa2hQKBgQDJM6+Da5OebqXZ/BPtY5jCcoGgBl4L8NQW +EN668TbGGdcFXcsIbbN+qaFik8h37TU76xI8EQoW4YVDIGivHQXFmPpvpylglHto +4RcPRNE+0rykNasoCrEqEcL+WAX4b3+0dgszNgsZLA64kLZQa5fMjn2+nVvn+YSU +AwGs6TlziwKBgCx3bThEtl0yNqj0z6U16IKcFDifxdnulNp+vA2p665vgLXqlQEz +nuMLlsfexJ+e7cbHd71BQREcWt0prO/OQwqmT1Y4yG3mPvUDbX0nXhnokgonwzzD ++SfU8cZ7KZT8AwMzR9KlP7Zsvia6sw1CuoRKjnEWnMavliQYiVlCsfClAoGAQDXJ +doR3aOFg9o83ANR/JNcMPTiq/N6PoLcjjb97Pn9ympjTOc5gsTSLd304ReWizot3 +l0nM0X6JW+HU5sW5WNU4XzeWwebA97iV9l589LKmVzV1eOLopUdj1m3bAez7cWkW +q/I8Wn0v+YDdXg7oM/TpdlKbyQ1dXSsUds07c38CgYBfi2Zo2R2Sgfq6bQyCmzze +740nqiBTPf7NuA9n2yESOFUkskaLcWb5o83iT71I2eUxZJCSelgXxVHtGK5y3PLu +QWVWgN/qn6D3skuQNXEY5iAQ/C47Rq15ZUcWF2utzkAxrmgcSUjrj7xjsk5MG3RX +mK1AS3XT0sLIpGuhSUNrOw== +-----END PRIVATE KEY----- diff --git a/cloudplatform/pom.xml b/cloudplatform/pom.xml index 93565fd99..b0f1bd2ff 100644 --- a/cloudplatform/pom.xml +++ b/cloudplatform/pom.xml @@ -42,6 +42,7 @@ connectivity-oauth connectivity-apache-httpclient4 connectivity-apache-httpclient5 + connectivity-fips-sample resilience resilience-api resilience4j @@ -59,6 +60,17 @@ ${project.basedir}/../../ + + non-release + + + !release + + + + connectivity-fips-sample + + release diff --git a/module-inventory.json b/module-inventory.json index 71f993b18..348da66b0 100644 --- a/module-inventory.json +++ b/module-inventory.json @@ -120,6 +120,17 @@ "parentArtifactId": "cloudplatform-parent", "excludeFromBlackDuckScan": false }, + { + "groupId": "com.sap.cloud.sdk.cloudplatform", + "artifactId": "connectivity-fips-sample", + "packaging": "jar", + "releaseAudience": "None", + "releaseMaturity": "Stable", + "pomFile": "cloudplatform/connectivity-fips-sample/pom.xml", + "parentGroupId": "com.sap.cloud.sdk.cloudplatform", + "parentArtifactId": "cloudplatform-parent", + "excludeFromBlackDuckScan": true + }, { "groupId": "com.sap.cloud.sdk.cloudplatform", "artifactId": "connectivity-oauth", diff --git a/pom.xml b/pom.xml index 15836c82f..cf80eb76e 100644 --- a/pom.xml +++ b/pom.xml @@ -705,6 +705,7 @@ com.sap.cloud.sdk.datamodel:odata-v4-api-sample com.sap.cloud.sdk.datamodel:openapi-api-sample com.sap.cloud.sdk.datamodel:openapi-api-apache-sample + com.sap.cloud.sdk.cloudplatform:connectivity-fips-sample @@ -933,13 +934,6 @@ - - fips-approved - - -Xmx${surefire.maxMemorySize} -Dfile.encoding=${project.build.sourceEncoding} -Dorg.slf4j.simpleLogger.defaultLogLevel=${surefire.logLevel} -Dorg.bouncycastle.fips.approved_only=true - fips-approved - - skip-openapi-vdm-generation