Skip to content

Commit

Permalink
Enable testing in FIPS140 JVM (#31666) (#32231)
Browse files Browse the repository at this point in the history
* 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 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
  • Loading branch information
jkakavas committed Jul 20, 2018
1 parent c3f9f96 commit 1d8dd10
Show file tree
Hide file tree
Showing 70 changed files with 1,193 additions and 588 deletions.
4 changes: 4 additions & 0 deletions client/rest/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ forbiddenApisMain {
PrecommitTasks.getResource('/forbidden/http-signatures.txt')]
}

forbiddenPatterns {
exclude '**/*.der'
}

forbiddenApisTest {
//we are using jdk-internal instead of jdk-non-portable to allow for com.sun.net.httpserver.* usage
bundledSignatures -= 'jdk-non-portable'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,13 @@
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.spec.PKCS8EncodedKeySpec;

import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
Expand Down Expand Up @@ -103,12 +109,20 @@ private RestClient buildRestClient() {

private static SSLContext getSslContext() throws Exception {
SSLContext sslContext = SSLContext.getInstance("TLS");
try (InputStream in = RestClientBuilderIntegTests.class.getResourceAsStream("/testks.jks")) {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(in, "password".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
try (InputStream certFile = RestClientBuilderIntegTests.class.getResourceAsStream("/test.crt")) {
// Build a keystore of default type programmatically since we can't use JKS keystores to
// init a KeyManagerFactory in FIPS 140 JVMs.
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, "password".toCharArray());
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(Files.readAllBytes(Paths.get(RestClientBuilderIntegTests.class
.getResource("/test.der").toURI())));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
keyStore.setKeyEntry("mykey", keyFactory.generatePrivate(privateKeySpec), "password".toCharArray(),
new Certificate[]{certFactory.generateCertificate(certFile)});
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, "password".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
}
Expand Down
24 changes: 24 additions & 0 deletions client/rest/src/test/resources/test.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEATCCAumgAwIBAgIEObhDZDANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJV
UzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxEDAOBgNVBAoT
B2VsYXN0aWMxDTALBgNVBAsTBHRlc3QxEjAQBgNVBAMTCXRlc3Qgbm9kZTAeFw0x
NzA3MTcxNjEyNTZaFw0yNzA3MTUxNjEyNTZaMGcxCzAJBgNVBAYTAlVTMQswCQYD
VQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHZWxhc3Rp
YzENMAsGA1UECxMEdGVzdDESMBAGA1UEAxMJdGVzdCBub2RlMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnXtuGIgAq6vWzUD34HXkYF+0u103hb8d1h35
kjeuNApkUhS6x/VbuNp7TpWmprfDgG5w9TourHvyiqcQMDEWrBunS6rmKo1jK1Wm
le3qA3F2l9VIZSNeeYQgezmzuElEPPmBjN8XBByIWKYjZcGd5u7DiquPUh9QLIev
itgB2jfi9D8ewyvaSbVAQuQwyIaDN9L74wKyMC8EuzzAWNSDjgIhhwcR5qg17msa
ItyM44/3hik+ObIGpMlLSxQu2V1U9bOaq48JjQBLHVg1vzC9VzGuNdEb8haFnhJN
UrdESdHymbtBSUvy30iB+kHq5R8wQ4pC+WxChQnbA2GskuFrMQIDAQABo4G0MIGx
MIGPBgNVHREEgYcwgYSHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCCWxvY2FsaG9z
dIIVbG9jYWxob3N0LmxvY2FsZG9tYWluggpsb2NhbGhvc3Q0ghdsb2NhbGhvc3Q0
LmxvY2FsZG9tYWluNIIKbG9jYWxob3N0NoIXbG9jYWxob3N0Ni5sb2NhbGRvbWFp
bjYwHQYDVR0OBBYEFFwNcqIKfGBCBGo9faQJ3TsHmp0SMA0GCSqGSIb3DQEBCwUA
A4IBAQBvUJTRjSOf/+vtyS3OokwRilg1ZGF3psg0DWhjH2ehIRfNibU1Y8FVQo3I
VU8LjcIUK1cN85z+AsYqLXo/C4qmJPydQ1tGpQL7uIrPD4h+Xh3tY6A2DKRJRQFO
w2LjswPidGufMztpPbXxLREqvkvn80VkDnc44UPxYfHvZFqYwYyxZccA5mm+BhYu
IerjfvgX+8zMWIQZOd+jRq8EaVTmVK2Azwwhc5ImWfc0DA3pmGPdECzE4N0VVoIJ
N8PCVltXXP3F7K3LoT6CLSiJ3c/IDVNoVS4pRV6R6Y4oIKD9T/T1kAgAvOrUGRWY
ejWQ41GdUmkmxrqCaMbVCO4s72BC
-----END CERTIFICATE-----
Binary file added client/rest/src/test/resources/test.der
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import org.elasticsearch.test.PosixPermissionsResetter;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;

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

@BeforeClass
public static void testIfFipsMode() {
assumeFalse("Can't run in a FIPS JVM because this depends on BouncyCastle (non-fips)", inFipsJvm());
}

@Override
@Before
public void setUp() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ public void testInvalidJodaPattern() {
}

public void testJodaPatternLocale() {
//TODO investigate if this is a bug in Joda
assumeFalse("Can't run in a FIPS JVM, Joda parse date error", inFipsJvm());
DateProcessor dateProcessor = new DateProcessor(randomAlphaOfLength(10),
templatize(ZoneId.of("Europe/Amsterdam")), templatize(Locale.ITALIAN),
"date_as_string", Collections.singletonList("yyyy dd MMM"), "date_as_date");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
import org.elasticsearch.transport.TcpTransport;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.rules.ExternalResource;

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

private static Path keyStoreFile;

@ClassRule
public static final ExternalResource MUTE_IN_FIPS_JVM = new ExternalResource() {
@Override
protected void before() {
assumeFalse("Can't run in a FIPS JVM because none of the supported Keystore types can be used", inFipsJvm());
}
};

@BeforeClass
public static void setupKeyStore() throws IOException {
Path tempDir = createTempDir();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ public void testIllegalSettingName() throws Exception {
}

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

public void testBackcompatV2() throws Exception {
assumeFalse("Can't run in a FIPS JVM as PBE is not available", inFipsJvm());
Path configDir = env.configFile();
SimpleFSDirectory directory = new SimpleFSDirectory(configDir);
byte[] fileBytes = new byte[20];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,15 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.ZoneId;
import java.security.Security;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
Expand Down Expand Up @@ -1396,4 +1398,8 @@ public TestAnalysis(IndexAnalyzers indexAnalyzers,
}
}

public static boolean inFipsJvm() {
return Security.getProviders()[0].getName().toLowerCase(Locale.ROOT).contains("fips");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public static X509ExtendedKeyManager keyManager(Certificate[] certificateChain,

private static KeyStore getKeyStore(Certificate[] certificateChain, PrivateKey privateKey, char[] password)
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
KeyStore keyStore = KeyStore.getInstance("jks");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
// password must be non-null for keystore...
keyStore.setKeyEntry("key", privateKey, password, certificateChain);
Expand Down Expand Up @@ -242,7 +242,7 @@ public static X509ExtendedTrustManager trustManager(Certificate[] certificates)
static KeyStore trustStore(Certificate[] certificates)
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
assert certificates != null : "Cannot create trust store with null certificates";
KeyStore store = KeyStore.getInstance("jks");
KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
store.load(null, null);
int counter = 0;
for (Certificate certificate : certificates) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ public void testClusterRestartWhileExpired() throws Exception {
}

public void testClusterRestartWithOldSignature() throws Exception {
assumeFalse("Can't run in a FIPS JVM. We can't generate old licenses since PBEWithSHA1AndDESede is not available", inFipsJvm());
wipeAllLicenses();
internalCluster().startNode();
ensureGreen();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public void testFrom1x() throws Exception {
}

public void testTrialLicenseVerifyWithOlderVersion() throws Exception {
assumeFalse("Can't run in a FIPS JVM. We can't generate old licenses since PBEWithSHA1AndDESede is not available", inFipsJvm());
long issueDate = System.currentTimeMillis();
License.Builder specBuilder = License.builder()
.issuedTo("customer")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.network.NetworkAddress;
import org.elasticsearch.test.ESTestCase;
import org.junit.BeforeClass;

import java.math.BigInteger;
import java.net.InetAddress;
Expand All @@ -32,6 +33,11 @@
*/
public class CertGenUtilsTests extends ESTestCase {

@BeforeClass
public static void muteInFips(){
assumeFalse("Can't run in a FIPS JVM", inFipsJvm());
}

public void testSerialNotRepeated() {
int iterations = scaledRandomIntBetween(10, 100);
List<BigInteger> list = new ArrayList<>(iterations);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public void testReadPKCS8EcKey() throws Exception {
}

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

0 comments on commit 1d8dd10

Please sign in to comment.