Skip to content

Commit 9e529d9

Browse files
authored
Enable testing in FIPS140 JVM (#31666)
Ensure our tests can run in a FIPS JVM JKS keystores cannot be used in a FIPS JVM as attempting to use one in order to init a KeyManagerFactory or a TrustManagerFactory is not allowed.( JKS keystore algorithms for private key encryption are not FIPS 140 approved) This commit replaces JKS keystores in our tests with the corresponding PEM encoded key and certificates both for key and trust configurations. Whenever it's not possible to refactor the test, i.e. when we are testing that we can load a JKS keystore, etc. we attempt to mute the test when we are running in FIPS 140 JVM. Testing for the JVM is naive and is based on the name of the security provider as we would control the testing infrastrtucture and so this would be reliable enough. Other cases of tests being muted are the ones that involve custom TrustStoreManagers or KeyStoreManagers, null TLS Ciphers and the SAMLAuthneticator class as we cannot sign XML documents in the way we were doing. SAMLAuthenticator tests in a FIPS JVM can be reenabled with precomputed and signed SAML messages at a later stage. IT will be covered in a subsequent PR
1 parent 3616526 commit 9e529d9

File tree

72 files changed

+1215
-610
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1215
-610
lines changed

client/rest/build.gradle

+4
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ forbiddenApisMain {
5959
PrecommitTasks.getResource('/forbidden/http-signatures.txt')]
6060
}
6161

62+
forbiddenPatterns {
63+
exclude '**/*.der'
64+
}
65+
6266
forbiddenApisTest {
6367
//we are using jdk-internal instead of jdk-non-portable to allow for com.sun.net.httpserver.* usage
6468
bundledSignatures -= 'jdk-non-portable'

client/rest/src/test/java/org/elasticsearch/client/RestClientBuilderIntegTests.java

+19-5
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@
3636
import java.io.InputStream;
3737
import java.net.InetAddress;
3838
import java.net.InetSocketAddress;
39+
import java.nio.file.Files;
40+
import java.nio.file.Paths;
41+
import java.security.KeyFactory;
3942
import java.security.KeyStore;
43+
import java.security.cert.Certificate;
44+
import java.security.cert.CertificateFactory;
45+
import java.security.spec.PKCS8EncodedKeySpec;
4046

4147
import static org.hamcrest.Matchers.instanceOf;
4248
import static org.junit.Assert.assertEquals;
@@ -101,12 +107,20 @@ private RestClient buildRestClient() {
101107

102108
private static SSLContext getSslContext() throws Exception {
103109
SSLContext sslContext = SSLContext.getInstance("TLS");
104-
try (InputStream in = RestClientBuilderIntegTests.class.getResourceAsStream("/testks.jks")) {
105-
KeyStore keyStore = KeyStore.getInstance("JKS");
106-
keyStore.load(in, "password".toCharArray());
107-
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
110+
try (InputStream certFile = RestClientBuilderIntegTests.class.getResourceAsStream("/test.crt")) {
111+
// Build a keystore of default type programmatically since we can't use JKS keystores to
112+
// init a KeyManagerFactory in FIPS 140 JVMs.
113+
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
114+
keyStore.load(null, "password".toCharArray());
115+
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
116+
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(Files.readAllBytes(Paths.get(RestClientBuilderIntegTests.class
117+
.getResource("/test.der").toURI())));
118+
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
119+
keyStore.setKeyEntry("mykey", keyFactory.generatePrivate(privateKeySpec), "password".toCharArray(),
120+
new Certificate[]{certFactory.generateCertificate(certFile)});
121+
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
108122
kmf.init(keyStore, "password".toCharArray());
109-
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
123+
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
110124
tmf.init(keyStore);
111125
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
112126
}
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIEATCCAumgAwIBAgIEObhDZDANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJV
3+
UzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxEDAOBgNVBAoT
4+
B2VsYXN0aWMxDTALBgNVBAsTBHRlc3QxEjAQBgNVBAMTCXRlc3Qgbm9kZTAeFw0x
5+
NzA3MTcxNjEyNTZaFw0yNzA3MTUxNjEyNTZaMGcxCzAJBgNVBAYTAlVTMQswCQYD
6+
VQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHZWxhc3Rp
7+
YzENMAsGA1UECxMEdGVzdDESMBAGA1UEAxMJdGVzdCBub2RlMIIBIjANBgkqhkiG
8+
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnXtuGIgAq6vWzUD34HXkYF+0u103hb8d1h35
9+
kjeuNApkUhS6x/VbuNp7TpWmprfDgG5w9TourHvyiqcQMDEWrBunS6rmKo1jK1Wm
10+
le3qA3F2l9VIZSNeeYQgezmzuElEPPmBjN8XBByIWKYjZcGd5u7DiquPUh9QLIev
11+
itgB2jfi9D8ewyvaSbVAQuQwyIaDN9L74wKyMC8EuzzAWNSDjgIhhwcR5qg17msa
12+
ItyM44/3hik+ObIGpMlLSxQu2V1U9bOaq48JjQBLHVg1vzC9VzGuNdEb8haFnhJN
13+
UrdESdHymbtBSUvy30iB+kHq5R8wQ4pC+WxChQnbA2GskuFrMQIDAQABo4G0MIGx
14+
MIGPBgNVHREEgYcwgYSHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCCWxvY2FsaG9z
15+
dIIVbG9jYWxob3N0LmxvY2FsZG9tYWluggpsb2NhbGhvc3Q0ghdsb2NhbGhvc3Q0
16+
LmxvY2FsZG9tYWluNIIKbG9jYWxob3N0NoIXbG9jYWxob3N0Ni5sb2NhbGRvbWFp
17+
bjYwHQYDVR0OBBYEFFwNcqIKfGBCBGo9faQJ3TsHmp0SMA0GCSqGSIb3DQEBCwUA
18+
A4IBAQBvUJTRjSOf/+vtyS3OokwRilg1ZGF3psg0DWhjH2ehIRfNibU1Y8FVQo3I
19+
VU8LjcIUK1cN85z+AsYqLXo/C4qmJPydQ1tGpQL7uIrPD4h+Xh3tY6A2DKRJRQFO
20+
w2LjswPidGufMztpPbXxLREqvkvn80VkDnc44UPxYfHvZFqYwYyxZccA5mm+BhYu
21+
IerjfvgX+8zMWIQZOd+jRq8EaVTmVK2Azwwhc5ImWfc0DA3pmGPdECzE4N0VVoIJ
22+
N8PCVltXXP3F7K3LoT6CLSiJ3c/IDVNoVS4pRV6R6Y4oIKD9T/T1kAgAvOrUGRWY
23+
ejWQ41GdUmkmxrqCaMbVCO4s72BC
24+
-----END CERTIFICATE-----
1.19 KB
Binary file not shown.

distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java

+6
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import org.elasticsearch.test.PosixPermissionsResetter;
6262
import org.junit.After;
6363
import org.junit.Before;
64+
import org.junit.BeforeClass;
6465

6566
import java.io.BufferedReader;
6667
import java.io.ByteArrayInputStream;
@@ -139,6 +140,11 @@ public InstallPluginCommandTests(FileSystem fs, Function<String, Path> temp) {
139140
System.setProperty("java.io.tmpdir", temp.apply("tmpdir").toString());
140141
}
141142

143+
@BeforeClass
144+
public static void testIfFipsMode() {
145+
assumeFalse("Can't run in a FIPS JVM because this depends on BouncyCastle (non-fips)", inFipsJvm());
146+
}
147+
142148
@Override
143149
@Before
144150
public void setUp() throws Exception {

modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/DateProcessorTests.java

+2
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ public void testInvalidJodaPattern() {
114114
}
115115

116116
public void testJodaPatternLocale() {
117+
//TODO investigate if this is a bug in Joda
118+
assumeFalse("Can't run in a FIPS JVM, Joda parse date error", inFipsJvm());
117119
DateProcessor dateProcessor = new DateProcessor(randomAlphaOfLength(10),
118120
templatize(ZoneId.of("Europe/Amsterdam")), templatize(Locale.ITALIAN),
119121
"date_as_string", Collections.singletonList("yyyy dd MMM"), "date_as_date");

plugins/discovery-azure-classic/src/test/java/org/elasticsearch/discovery/azure/classic/AzureDiscoveryClusterFormationTests.java

+10
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import org.elasticsearch.transport.TcpTransport;
4141
import org.junit.AfterClass;
4242
import org.junit.BeforeClass;
43+
import org.junit.ClassRule;
44+
import org.junit.rules.ExternalResource;
4345

4446
import javax.net.ssl.KeyManagerFactory;
4547
import javax.net.ssl.SSLContext;
@@ -87,6 +89,14 @@ protected Collection<Class<? extends Plugin>> nodePlugins() {
8789

8890
private static Path keyStoreFile;
8991

92+
@ClassRule
93+
public static final ExternalResource MUTE_IN_FIPS_JVM = new ExternalResource() {
94+
@Override
95+
protected void before() {
96+
assumeFalse("Can't run in a FIPS JVM because none of the supported Keystore types can be used", inFipsJvm());
97+
}
98+
};
99+
90100
@BeforeClass
91101
public static void setupKeyStore() throws IOException {
92102
Path tempDir = createTempDir();

server/src/test/java/org/elasticsearch/common/settings/KeyStoreWrapperTests.java

+2
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ public void testIllegalSettingName() throws Exception {
290290
}
291291

292292
public void testBackcompatV1() throws Exception {
293+
assumeFalse("Can't run in a FIPS JVM as PBE is not available", inFipsJvm());
293294
Path configDir = env.configFile();
294295
SimpleFSDirectory directory = new SimpleFSDirectory(configDir);
295296
try (IndexOutput output = directory.createOutput("elasticsearch.keystore", IOContext.DEFAULT)) {
@@ -320,6 +321,7 @@ public void testBackcompatV1() throws Exception {
320321
}
321322

322323
public void testBackcompatV2() throws Exception {
324+
assumeFalse("Can't run in a FIPS JVM as PBE is not available", inFipsJvm());
323325
Path configDir = env.configFile();
324326
SimpleFSDirectory directory = new SimpleFSDirectory(configDir);
325327
byte[] fileBytes = new byte[20];

test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java

+6
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,15 @@
125125
import java.nio.file.Files;
126126
import java.nio.file.Path;
127127
import java.time.ZoneId;
128+
import java.security.Security;
128129
import java.util.ArrayList;
129130
import java.util.Arrays;
130131
import java.util.Collection;
131132
import java.util.Collections;
132133
import java.util.HashSet;
133134
import java.util.LinkedHashMap;
134135
import java.util.List;
136+
import java.util.Locale;
135137
import java.util.Map;
136138
import java.util.Objects;
137139
import java.util.Random;
@@ -1363,4 +1365,8 @@ public TestAnalysis(IndexAnalyzers indexAnalyzers,
13631365
}
13641366
}
13651367

1368+
public static boolean inFipsJvm() {
1369+
return Security.getProviders()[0].getName().toLowerCase(Locale.ROOT).contains("fips");
1370+
}
1371+
13661372
}

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/CertParsingUtils.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public static X509ExtendedKeyManager keyManager(Certificate[] certificateChain,
158158

159159
private static KeyStore getKeyStore(Certificate[] certificateChain, PrivateKey privateKey, char[] password)
160160
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
161-
KeyStore keyStore = KeyStore.getInstance("jks");
161+
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
162162
keyStore.load(null, null);
163163
// password must be non-null for keystore...
164164
keyStore.setKeyEntry("key", privateKey, password, certificateChain);
@@ -242,7 +242,7 @@ public static X509ExtendedTrustManager trustManager(Certificate[] certificates)
242242
static KeyStore trustStore(Certificate[] certificates)
243243
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
244244
assert certificates != null : "Cannot create trust store with null certificates";
245-
KeyStore store = KeyStore.getInstance("jks");
245+
KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
246246
store.load(null, null);
247247
int counter = 0;
248248
for (Certificate certificate : certificates) {

x-pack/plugin/core/src/test/java/org/elasticsearch/license/LicenseServiceClusterTests.java

+1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ public void testClusterRestartWhileExpired() throws Exception {
153153
}
154154

155155
public void testClusterRestartWithOldSignature() throws Exception {
156+
assumeFalse("Can't run in a FIPS JVM. We can't generate old licenses since PBEWithSHA1AndDESede is not available", inFipsJvm());
156157
wipeAllLicenses();
157158
internalCluster().startNode();
158159
ensureGreen();

x-pack/plugin/core/src/test/java/org/elasticsearch/license/SelfGeneratedLicenseTests.java

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public void testFrom1x() throws Exception {
7676
}
7777

7878
public void testTrialLicenseVerifyWithOlderVersion() throws Exception {
79+
assumeFalse("Can't run in a FIPS JVM. We can't generate old licenses since PBEWithSHA1AndDESede is not available", inFipsJvm());
7980
long issueDate = System.currentTimeMillis();
8081
License.Builder specBuilder = License.builder()
8182
.issuedTo("customer")

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ssl/CertGenUtilsTests.java

+6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.elasticsearch.common.network.InetAddresses;
1313
import org.elasticsearch.common.network.NetworkAddress;
1414
import org.elasticsearch.test.ESTestCase;
15+
import org.junit.BeforeClass;
1516

1617
import java.math.BigInteger;
1718
import java.net.InetAddress;
@@ -32,6 +33,11 @@
3233
*/
3334
public class CertGenUtilsTests extends ESTestCase {
3435

36+
@BeforeClass
37+
public static void muteInFips(){
38+
assumeFalse("Can't run in a FIPS JVM", inFipsJvm());
39+
}
40+
3541
public void testSerialNotRepeated() {
3642
int iterations = scaledRandomIntBetween(10, 100);
3743
List<BigInteger> list = new ArrayList<>(iterations);

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ssl/PemUtilsTests.java

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public void testReadPKCS8EcKey() throws Exception {
5353
}
5454

5555
public void testReadEncryptedPKCS8Key() throws Exception {
56+
assumeFalse("Can't run in a FIPS JVM, PBE KeySpec is not available", inFipsJvm());
5657
Key key = getKeyFromKeystore("RSA");
5758
assertThat(key, notNullValue());
5859
assertThat(key, instanceOf(PrivateKey.class));

0 commit comments

Comments
 (0)