Skip to content

Commit ee6633c

Browse files
authored
test: FIPS sample module (#1196)
1 parent a32f57e commit ee6633c

8 files changed

Lines changed: 311 additions & 0 deletions

File tree

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<parent>
5+
<groupId>com.sap.cloud.sdk.cloudplatform</groupId>
6+
<artifactId>cloudplatform-parent</artifactId>
7+
<version>5.31.0-SNAPSHOT</version>
8+
</parent>
9+
<artifactId>connectivity-fips-sample</artifactId>
10+
<name>Connectivity - FIPS Sample</name>
11+
<description>Non-released sample module that runs connectivity tests under the FIPS-approved Bouncy Castle provider.</description>
12+
<url>https://sap.github.io/cloud-sdk/docs/java/getting-started</url>
13+
<organization>
14+
<name>SAP SE</name>
15+
<url>https://www.sap.com</url>
16+
</organization>
17+
<licenses>
18+
<license>
19+
<name>The Apache Software License, Version 2.0</name>
20+
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
21+
</license>
22+
</licenses>
23+
<developers>
24+
<developer>
25+
<name>SAP</name>
26+
<email>cloudsdk@sap.com</email>
27+
<organization>SAP SE</organization>
28+
<organizationUrl>https://www.sap.com</organizationUrl>
29+
</developer>
30+
</developers>
31+
<properties>
32+
<bc-fips.version>2.1.2</bc-fips.version>
33+
<bcpkix-fips.version>2.1.9</bcpkix-fips.version>
34+
</properties>
35+
<dependencies>
36+
<dependency>
37+
<groupId>com.sap.cloud.sdk.cloudplatform</groupId>
38+
<artifactId>cloudplatform-connectivity</artifactId>
39+
<exclusions>
40+
<exclusion>
41+
<groupId>org.bouncycastle</groupId>
42+
<artifactId>bcprov-jdk18on</artifactId>
43+
</exclusion>
44+
<exclusion>
45+
<groupId>org.bouncycastle</groupId>
46+
<artifactId>bcpkix-jdk18on</artifactId>
47+
</exclusion>
48+
</exclusions>
49+
<scope>test</scope>
50+
</dependency>
51+
<dependency>
52+
<groupId>org.bouncycastle</groupId>
53+
<artifactId>bc-fips</artifactId>
54+
<version>${bc-fips.version}</version>
55+
<scope>test</scope>
56+
</dependency>
57+
<dependency>
58+
<groupId>org.bouncycastle</groupId>
59+
<artifactId>bcpkix-fips</artifactId>
60+
<version>${bcpkix-fips.version}</version>
61+
<scope>test</scope>
62+
</dependency>
63+
<dependency>
64+
<groupId>org.projectlombok</groupId>
65+
<artifactId>lombok</artifactId>
66+
<scope>provided</scope>
67+
</dependency>
68+
<dependency>
69+
<groupId>org.junit.jupiter</groupId>
70+
<artifactId>junit-jupiter-api</artifactId>
71+
<scope>test</scope>
72+
</dependency>
73+
<dependency>
74+
<groupId>org.assertj</groupId>
75+
<artifactId>assertj-core</artifactId>
76+
<scope>test</scope>
77+
</dependency>
78+
</dependencies>
79+
<build>
80+
<plugins>
81+
<plugin>
82+
<groupId>org.apache.maven.plugins</groupId>
83+
<artifactId>maven-surefire-plugin</artifactId>
84+
<configuration>
85+
<argLine>${argLine} -Dorg.bouncycastle.fips.approved_only=true
86+
</argLine>
87+
</configuration>
88+
</plugin>
89+
<plugin>
90+
<groupId>org.apache.maven.plugins</groupId>
91+
<artifactId>maven-dependency-plugin</artifactId>
92+
<configuration>
93+
<ignoredUnusedDeclaredDependencies combine.children="append">
94+
<ignoredUnusedDeclaredDependency>org.bouncycastle:bc-fips</ignoredUnusedDeclaredDependency>
95+
<ignoredUnusedDeclaredDependency>org.bouncycastle:bcpkix-fips</ignoredUnusedDeclaredDependency>
96+
<ignoredUnusedDeclaredDependency>com.sap.cloud.sdk.cloudplatform:cloudplatform-connectivity</ignoredUnusedDeclaredDependency>
97+
</ignoredUnusedDeclaredDependencies>
98+
</configuration>
99+
</plugin>
100+
<plugin>
101+
<groupId>org.apache.maven.plugins</groupId>
102+
<artifactId>maven-checkstyle-plugin</artifactId>
103+
<configuration><skip>true</skip></configuration>
104+
</plugin>
105+
<plugin>
106+
<groupId>org.apache.maven.plugins</groupId>
107+
<artifactId>maven-pmd-plugin</artifactId>
108+
<configuration><skip>true</skip></configuration>
109+
</plugin>
110+
<plugin>
111+
<groupId>org.apache.maven.plugins</groupId>
112+
<artifactId>maven-javadoc-plugin</artifactId>
113+
<configuration><skip>true</skip></configuration>
114+
</plugin>
115+
<plugin>
116+
<groupId>org.jacoco</groupId>
117+
<artifactId>jacoco-maven-plugin</artifactId>
118+
<configuration><skip>true</skip></configuration>
119+
</plugin>
120+
</plugins>
121+
</build>
122+
<profiles>
123+
<profile>
124+
<id>release</id>
125+
<activation>
126+
<property><name>release</name></property>
127+
</activation>
128+
<build>
129+
<plugins>
130+
<plugin>
131+
<groupId>org.sonatype.central</groupId>
132+
<artifactId>central-publishing-maven-plugin</artifactId>
133+
<executions>
134+
<execution>
135+
<id>injected-central-publishing</id>
136+
<phase />
137+
</execution>
138+
</executions>
139+
</plugin>
140+
</plugins>
141+
</build>
142+
</profile>
143+
</profiles>
144+
</project>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.sap.cloud.sdk.cloudplatform.connectivity;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
5+
6+
import java.io.FileReader;
7+
import java.security.KeyStore;
8+
import java.security.MessageDigest;
9+
import java.security.NoSuchAlgorithmException;
10+
import java.security.Security;
11+
12+
import org.bouncycastle.crypto.CryptoServicesRegistrar;
13+
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
14+
import org.junit.jupiter.api.AfterAll;
15+
import org.junit.jupiter.api.BeforeAll;
16+
import org.junit.jupiter.api.Test;
17+
18+
import lombok.SneakyThrows;
19+
20+
/**
21+
* Tests the behavior of {@link KeyStoreReader} when operating in FIPS-approved mode with BouncyCastle FIPS provider.
22+
*/
23+
class FipsProviderTest
24+
{
25+
private static final String RES = "src/test/resources/certificates";
26+
private static final String CRT_PATH = RES + "/client-cert.crt";
27+
private static final String KEY_PATH = RES + "/client-cert.key";
28+
private static final String ALIAS = "client-cert";
29+
private static final char[] EMPTY_PASSWORD = new char[0];
30+
31+
@AfterAll
32+
static void removeBouncyCastleFips()
33+
{
34+
Security.removeProvider("BCFIPS");
35+
}
36+
37+
@BeforeAll
38+
static void registerBouncyCastleFips()
39+
{
40+
Security.insertProviderAt(new BouncyCastleFipsProvider(), 1);
41+
42+
assertThat(Security.getProvider("BCFIPS"))
43+
.describedAs("BC FIPS provider must be registered as a JCA provider")
44+
.isNotNull();
45+
46+
assertThat(CryptoServicesRegistrar.isInApprovedOnlyMode())
47+
.describedAs("BC FIPS must be in approved-only mode. ")
48+
.isTrue();
49+
}
50+
51+
@Test
52+
@SneakyThrows
53+
void testDefaultKeystoreTypeIsP12()
54+
{
55+
final KeyStore keyStore =
56+
KeyStoreReader.createKeyStore(ALIAS, EMPTY_PASSWORD, new FileReader(CRT_PATH), new FileReader(KEY_PATH));
57+
58+
assertThat(keyStore.getType()).isEqualToIgnoringCase("PKCS12");
59+
}
60+
61+
@Test
62+
@SneakyThrows
63+
void testKeystoreTypeOverrideToBCFKS()
64+
{
65+
Security.setProperty("keystore.type", "BCFKS");
66+
67+
final KeyStore keyStore = KeyStore.getInstance("BCFKS");
68+
assertThat(keyStore.getType()).isEqualTo("BCFKS");
69+
}
70+
71+
@Test
72+
void testMD5IsRejectedInApprovedOnlyMode()
73+
{
74+
assertThatThrownBy(() -> MessageDigest.getInstance("MD5", "BCFIPS"))
75+
.isInstanceOf(NoSuchAlgorithmException.class);
76+
77+
}
78+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Credentials
2+
3+
The credential files are required for running the FIPS provider tests.
4+
5+
## Generate Client Credentials
6+
7+
Run the following commands from `cloudplatform/connectivity-fips-sample/src/test/resources/`:
8+
9+
```bash
10+
# Create the directory
11+
mkdir -p certificates
12+
13+
# Generate the key and certificate using Docker (alpine/openssl)
14+
docker run --rm -v "$(pwd)/certificates:/certs" alpine/openssl \
15+
req -x509 -newkey rsa:2048 -nodes \
16+
-keyout /certs/client-cert.key \
17+
-out /certs/client-cert.crt \
18+
-days 3650 -subj "/CN=localhost"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDCTCCAfGgAwIBAgIUBERZ7w9qG2je5O6o+Nn+ssaZYOQwDQYJKoZIhvcNAQEL
3+
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI2MDYwODEzMjQzNVoXDTM2MDYw
4+
NTEzMjQzNVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
5+
AAOCAQ8AMIIBCgKCAQEAsXImnalCNo7Jk4EyD1aqWJgrzVXYALVKm8kq5E+azFpv
6+
3XB8QQBUXfJJNdkY1uNni6cd+twTzAhdBK+ygTsBkDbMz/r0oniLlLmGTG7L5aCW
7+
asYVa+HTesi0EunlGDzFbRSuwy/IdfvK2uaU0VeGoyt7Zr0OWg72mPwGPQRvPcEI
8+
ZljEkgajhiHeEGM9hlCTZnpx9Aye3C/4yek4734QK+ZYqvW/1mYJ08EwDudQUy8n
9+
rrXhAg7/ppS9v2480fAGI7WonRt4y+sAlaET8YkxNXCRPygwTDaGfQ/yjvXfK37B
10+
yiEl8qDMFU/WVjEBlet8wLT2/A7qxzjow0UWtsPWWQIDAQABo1MwUTAdBgNVHQ4E
11+
FgQUEfT0MvVXq56A21bschMDKdUqg7UwHwYDVR0jBBgwFoAUEfT0MvVXq56A21bs
12+
chMDKdUqg7UwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAQI0R
13+
I+x9f2zfQThxkRsF5NoQCqgtaGckcsqk1ADcDLqQWck/j9CE3xMLPYcDKgwURG5s
14+
/yHUJhv+9/S2uQ/0Xl32GF8fl45av3yUz1aPW6T1JsHWD6/thUtoxvuZr5W1rn/1
15+
UdYvVnNutLGp1PQWbjxmdH2sZwmDZ/2ovKNCEwnmzOi3Jft7xnu94SyTZqVYnJt0
16+
rQw5NwrjxspPsJQx/2Rd7EEeg4b/LQEQrEIhchNPzGyLK14mF4nk/ImZ5unkNePt
17+
kgy6ysoQWHBf+N+184c9B3+qFZAItWOGvBx9z0jS9eQELWT7MBsJ4s2Lufku73kn
18+
V2gbQ/izbQlQpKduuw==
19+
-----END CERTIFICATE-----
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCxciadqUI2jsmT
3+
gTIPVqpYmCvNVdgAtUqbySrkT5rMWm/dcHxBAFRd8kk12RjW42eLpx363BPMCF0E
4+
r7KBOwGQNszP+vSieIuUuYZMbsvloJZqxhVr4dN6yLQS6eUYPMVtFK7DL8h1+8ra
5+
5pTRV4ajK3tmvQ5aDvaY/AY9BG89wQhmWMSSBqOGId4QYz2GUJNmenH0DJ7cL/jJ
6+
6TjvfhAr5liq9b/WZgnTwTAO51BTLyeuteECDv+mlL2/bjzR8AYjtaidG3jL6wCV
7+
oRPxiTE1cJE/KDBMNoZ9D/KO9d8rfsHKISXyoMwVT9ZWMQGV63zAtPb8DurHOOjD
8+
RRa2w9ZZAgMBAAECggEAA0Y7+C97YqOtNzpBwOQJ2KtWLj/Qmz1n1wrAmTNELqks
9+
j0WCxXWgGOuzoM6/ape0/XAOruZeEdHFsE8drXd38T/8SjTd9sbgAdU6k9vSNLaL
10+
Oq/VDVyUGRvtrBECLTmnMFAauXdUQk5se9rtZr+FYyrA6DBs518x+w4Lf2y+22uA
11+
lj5MD+rXxwGPz3doVmNNfX3pxrswuwD3yAu4E9A3vFSth1OF/4Li4Y2rFVLUELtw
12+
8halPQAlBu2lmawCD8J68cUCIzlVu9OBPtinrjGxuAvj6lhEmkuakwvkSxFeOZwB
13+
ZvtC0RIGM6mOzwqTWy1dJ35Le3f2qLYT3tO7zIguUQKBgQDdyV8nyu3Y1odRA/Rd
14+
y36Xidm7YySwnyF/GZMVM0Cm2iKFGoo0Ym0gK6HdLPr5dxQlziXwJXh2dROt43//
15+
ABuHRQLyRAi79aGJS7Zehk0NSqxzNcPevXNELGI9TQkm0T0UQZu2Mbq0ciQGKBxu
16+
WNvsshzzr2UQ8RVRJdZA1De3BwKBgQDM0bWqtCK8Lp1XfF6LhY0kDiXOs/uFD0FB
17+
ToBzbbZPPII7tpVRy9jLXO2DXEwCj3AsdIwhxAWYWUy75J9EpI41JmY+D4SQRzTq
18+
y6GiwHcmFr0RtYZpSdmnpWVPTbWwqoH1KCJEyA8sKrOd0BSh06EiFKM8yYjxHs2q
19+
VYsRqmJPnwKBgQDFwlpDvDHLCLdN6Q3LWLk/XF62NRgxGSOgFmjNHY9Hd/gR4XFc
20+
dmtBpUZGVmZPbPudHi077d11Gr36boHiGfFx83pGFZ4II2TvbIBn1q777BrK/CT0
21+
Bs+x+TV73aYMY8RnvHygv8TwQ1qV1sxLJJatfsBMFZgzvBQ68FcUJWasnwKBgQCk
22+
An2lfu+dnvoxdw7CTKQzrfyKY8dRymBnqjPjuoPVOU/T/yXcxQ4J8pTiroLTPgcG
23+
IiGgXDZaw49VmgILVnXli6UtpwFxAwQVzA/XoqUGZAjsaF6EazWWMDRK56BJIpBE
24+
PuoKB+VWaa9A/MG4wB10i/AXGg7FffQUpMFi2Pw2YwKBgHRt+tnkw3gvUSWQ4E/z
25+
/g525QMFP3xTadIT7qzif+LSMqtip3vVbC+sBAJQ+GChNq8MFnr72H/siOwmODS2
26+
hWaN/7EQCuxo6bzs9QYIgMa5qkBaQIO5RQWsbj8jcUGKXuGTxbWNkR2+tHzLYxeG
27+
p/Hb2ZSw9PU5Q7fHpaU9wjEo
28+
-----END PRIVATE KEY-----

cloudplatform/pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
<module>connectivity-oauth</module>
4343
<module>connectivity-apache-httpclient4</module>
4444
<module>connectivity-apache-httpclient5</module>
45+
<module>connectivity-fips-sample</module>
4546
<module>resilience</module>
4647
<module>resilience-api</module>
4748
<module>resilience4j</module>
@@ -59,6 +60,17 @@
5960
<project.rootdir>${project.basedir}/../../</project.rootdir>
6061
</properties>
6162
<profiles>
63+
<profile>
64+
<id>non-release</id>
65+
<activation>
66+
<property>
67+
<name>!release</name>
68+
</property>
69+
</activation>
70+
<modules>
71+
<module>connectivity-fips-sample</module>
72+
</modules>
73+
</profile>
6274
<profile>
6375
<id>release</id>
6476
<activation>

module-inventory.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,17 @@
120120
"parentArtifactId": "cloudplatform-parent",
121121
"excludeFromBlackDuckScan": false
122122
},
123+
{
124+
"groupId": "com.sap.cloud.sdk.cloudplatform",
125+
"artifactId": "connectivity-fips-sample",
126+
"packaging": "jar",
127+
"releaseAudience": "None",
128+
"releaseMaturity": "Stable",
129+
"pomFile": "cloudplatform/connectivity-fips-sample/pom.xml",
130+
"parentGroupId": "com.sap.cloud.sdk.cloudplatform",
131+
"parentArtifactId": "cloudplatform-parent",
132+
"excludeFromBlackDuckScan": true
133+
},
123134
{
124135
"groupId": "com.sap.cloud.sdk.cloudplatform",
125136
"artifactId": "connectivity-oauth",

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,7 @@
705705
<exclude>com.sap.cloud.sdk.datamodel:odata-v4-api-sample</exclude>
706706
<exclude>com.sap.cloud.sdk.datamodel:openapi-api-sample</exclude>
707707
<exclude>com.sap.cloud.sdk.datamodel:openapi-api-apache-sample</exclude>
708+
<exclude>com.sap.cloud.sdk.cloudplatform:connectivity-fips-sample</exclude>
708709
</excludes>
709710
</bannedDependencies>
710711
</rules>

0 commit comments

Comments
 (0)