Skip to content

Commit 343fb36

Browse files
authored
Test modifications for FIPS 140 mode (#51832) (#52128)
- Enable SunJGSS provider for Kerberos tests - Handle the fact that in the decrypt method in KeyStoreWrapper might not throw immediately when the GCM cipher is from BouncyCastle FIPS and we end up with a DataInputStream that has reached it's end. - Disable tests, jarHell, testingConventions for ingest attachment plugin. We don't support this plugin (and document this) in FIPS mode. - Don't attempt to install ingest-attachment in smoke-test-plugins
1 parent 44ea1ef commit 343fb36

File tree

11 files changed

+109
-18
lines changed

11 files changed

+109
-18
lines changed

buildSrc/src/main/resources/fips_java.security

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
22
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
33
security.provider.3=SUN
4+
security.provider.4=SunJGSS
45
securerandom.source=file:/dev/urandom
56
securerandom.strongAlgorithms=NativePRNGBlocking:SUN,DRBG:SUN
67
securerandom.drbg.config=

plugins/ingest-attachment/build.gradle

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,11 @@ thirdPartyAudit {
8888
ignoreMissingClasses()
8989
}
9090

91-
jarHell.onlyIf {
91+
if (BuildParams.inFipsJvm) {
9292
// FIPS JVM includes many classes from bouncycastle which count as jar hell for the third party audit,
9393
// rather than provide a long list of exclusions, disable the check on FIPS.
94-
BuildParams.inFipsJvm == false
94+
jarHell.enabled = false
95+
test.enabled = false
96+
integTest.enabled = false;
97+
testingConventions.enabled = false;
9598
}

qa/os/src/test/java/org/elasticsearch/packaging/test/KeystoreManagementTests.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.nio.file.Path;
3636
import java.nio.file.Paths;
3737
import java.nio.file.StandardOpenOption;
38+
import java.util.Arrays;
3839
import java.util.HashMap;
3940
import java.util.Map;
4041

@@ -58,13 +59,15 @@
5859
import static org.hamcrest.CoreMatchers.containsString;
5960
import static org.hamcrest.CoreMatchers.is;
6061
import static org.hamcrest.CoreMatchers.notNullValue;
62+
import static org.hamcrest.Matchers.anyOf;
6163
import static org.hamcrest.Matchers.startsWith;
6264
import static org.junit.Assume.assumeThat;
6365
import static org.junit.Assume.assumeTrue;
6466

6567
public class KeystoreManagementTests extends PackagingTestCase {
6668

6769
public static final String ERROR_INCORRECT_PASSWORD = "Provided keystore password was incorrect";
70+
public static final String ERROR_CORRUPTED_KEYSTORE = "Keystore has been corrupted or tampered with";
6871
public static final String ERROR_KEYSTORE_NOT_PASSWORD_PROTECTED = "ERROR: Keystore is not password-protected";
6972
public static final String ERROR_KEYSTORE_NOT_FOUND = "ERROR: Elasticsearch keystore not found";
7073

@@ -174,7 +177,7 @@ public void test41WrongKeystorePasswordOnStandardInput() {
174177
assertPasswordProtectedKeystore();
175178

176179
Shell.Result result = startElasticsearchStandardInputPassword("wrong");
177-
assertElasticsearchFailure(result, ERROR_INCORRECT_PASSWORD, null);
180+
assertElasticsearchFailure(result, Arrays.asList(ERROR_INCORRECT_PASSWORD, ERROR_CORRUPTED_KEYSTORE), null);
178181
}
179182

180183
@Ignore /* Ignored for feature branch, awaits fix: https://github.com/elastic/elasticsearch/issues/49340 */
@@ -210,7 +213,7 @@ public void test43WrongKeystorePasswordOnTty() throws Exception {
210213

211214
Shell.Result result = startElasticsearchTtyPassword("wrong");
212215
// error will be on stdout for "expect"
213-
assertThat(result.stdout, containsString(ERROR_INCORRECT_PASSWORD));
216+
assertThat(result.stdout, anyOf(containsString(ERROR_INCORRECT_PASSWORD), containsString(ERROR_CORRUPTED_KEYSTORE)));
214217
}
215218

216219
/**
@@ -279,7 +282,7 @@ public void test51WrongKeystorePasswordFromFile() throws Exception {
279282

280283
Packages.JournaldWrapper journaldWrapper = new Packages.JournaldWrapper(sh);
281284
Shell.Result result = runElasticsearchStartCommand();
282-
assertElasticsearchFailure(result, ERROR_INCORRECT_PASSWORD, journaldWrapper);
285+
assertElasticsearchFailure(result, Arrays.asList(ERROR_INCORRECT_PASSWORD, ERROR_CORRUPTED_KEYSTORE), journaldWrapper);
283286
} finally {
284287
sh.run("sudo systemctl unset-environment ES_KEYSTORE_PASSPHRASE_FILE");
285288
}

qa/os/src/test/java/org/elasticsearch/packaging/test/PackagingTestCase.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import org.elasticsearch.packaging.util.Packages;
3535
import org.elasticsearch.packaging.util.Platforms;
3636
import org.elasticsearch.packaging.util.Shell;
37+
import org.hamcrest.CoreMatchers;
38+
import org.hamcrest.Matcher;
3739
import org.junit.After;
3840
import org.junit.AfterClass;
3941
import org.junit.Assert;
@@ -48,13 +50,16 @@
4850
import java.nio.file.Files;
4951
import java.nio.file.Path;
5052
import java.nio.file.Paths;
53+
import java.util.Collections;
54+
import java.util.List;
5155

5256
import static org.elasticsearch.packaging.util.Cleanup.cleanEverything;
5357
import static org.elasticsearch.packaging.util.Docker.ensureImageIsLoaded;
5458
import static org.elasticsearch.packaging.util.Docker.removeContainer;
5559
import static org.elasticsearch.packaging.util.FileExistenceMatchers.fileExists;
5660
import static org.hamcrest.CoreMatchers.containsString;
5761
import static org.hamcrest.CoreMatchers.equalTo;
62+
import static org.hamcrest.CoreMatchers.anyOf;
5863
import static org.junit.Assume.assumeFalse;
5964
import static org.junit.Assume.assumeTrue;
6065

@@ -311,23 +316,28 @@ public Shell.Result startElasticsearchTtyPassword(String password) throws Except
311316
return Archives.startElasticsearchWithTty(installation, sh, password);
312317
}
313318

314-
315319
public void assertElasticsearchFailure(Shell.Result result, String expectedMessage, Packages.JournaldWrapper journaldWrapper) {
320+
assertElasticsearchFailure(result, Collections.singletonList(expectedMessage), journaldWrapper);
321+
}
316322

323+
public void assertElasticsearchFailure(Shell.Result result, List<String> expectedMessages, Packages.JournaldWrapper journaldWrapper) {
324+
@SuppressWarnings("unchecked")
325+
Matcher<String>[] stringMatchers = expectedMessages.stream().map(CoreMatchers::containsString).toArray(Matcher[]::new);
317326
if (Files.exists(installation.logs.resolve("elasticsearch.log"))) {
318327

319328
// If log file exists, then we have bootstrapped our logging and the
320329
// error should be in the logs
321330
assertThat(installation.logs.resolve("elasticsearch.log"), fileExists());
322331
String logfile = FileUtils.slurp(installation.logs.resolve("elasticsearch.log"));
323-
assertThat(logfile, containsString(expectedMessage));
332+
333+
assertThat(logfile, anyOf(stringMatchers));
324334

325335
} else if (distribution().isPackage() && Platforms.isSystemd()) {
326336

327337
// For systemd, retrieve the error from journalctl
328338
assertThat(result.stderr, containsString("Job for elasticsearch.service failed"));
329339
Shell.Result error = journaldWrapper.getLogs();
330-
assertThat(error.stdout, containsString(expectedMessage));
340+
assertThat(error.stdout, anyOf(stringMatchers));
331341

332342
} else if (Platforms.WINDOWS) {
333343

@@ -338,12 +348,12 @@ public void assertElasticsearchFailure(Shell.Result result, String expectedMessa
338348
sh.runIgnoreExitCode("Get-EventSubscriber | " +
339349
"where {($_.EventName -eq 'OutputDataReceived' -Or $_.EventName -eq 'ErrorDataReceived' |" +
340350
"Unregister-EventSubscriber -Force");
341-
assertThat(FileUtils.slurp(Archives.getPowershellErrorPath(installation)), containsString(expectedMessage));
351+
assertThat(FileUtils.slurp(Archives.getPowershellErrorPath(installation)), anyOf(stringMatchers));
342352

343353
} else {
344354

345355
// Otherwise, error should be on shell stderr
346-
assertThat(result.stderr, containsString(expectedMessage));
356+
assertThat(result.stderr, anyOf(stringMatchers));
347357
}
348358
}
349359

qa/smoke-test-plugins/build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919

2020
import org.elasticsearch.gradle.MavenFilteringHack
21+
import org.elasticsearch.gradle.info.BuildParams
2122

2223
apply plugin: 'elasticsearch.testclusters'
2324
apply plugin: 'elasticsearch.standalone-rest-test'
@@ -27,6 +28,10 @@ int pluginsCount = 0
2728

2829
testClusters.integTest {
2930
project(':plugins').getChildProjects().each { pluginName, pluginProject ->
31+
if (BuildParams.inFipsJvm && pluginName == "ingest-attachment"){
32+
//Do not attempt to install ingest-attachment in FIPS 140 as it is not supported (it depends on non-FIPS BouncyCastle
33+
return
34+
}
3035
plugin file(pluginProject.tasks.bundlePlugin.archiveFile)
3136
tasks.integTest.dependsOn pluginProject.tasks.bundlePlugin
3237
pluginsCount += 1

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.elasticsearch.cli.UserException;
3030
import org.elasticsearch.env.Environment;
3131

32+
import static org.hamcrest.Matchers.anyOf;
3233
import static org.hamcrest.Matchers.containsString;
3334

3435
public class AddFileKeyStoreCommandTests extends KeyStoreCommandTestCase {
@@ -192,7 +193,17 @@ public void testIncorrectPassword() throws Exception {
192193
terminal.addSecretInput("thewrongkeystorepassword");
193194
UserException e = expectThrows(UserException.class, () -> execute("foo", file.toString()));
194195
assertEquals(e.getMessage(), ExitCodes.DATA_ERROR, e.exitCode);
195-
assertThat(e.getMessage(), containsString("Provided keystore password was incorrect"));
196+
if (inFipsJvm()) {
197+
assertThat(
198+
e.getMessage(),
199+
anyOf(
200+
containsString("Provided keystore password was incorrect"),
201+
containsString("Keystore has been corrupted or tampered with")
202+
)
203+
);
204+
} else {
205+
assertThat(e.getMessage(), containsString("Provided keystore password was incorrect"));
206+
}
196207
}
197208

198209
public void testAddToUnprotectedKeystore() throws Exception {

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.elasticsearch.cli.UserException;
3131
import org.elasticsearch.env.Environment;
3232

33+
import static org.hamcrest.Matchers.anyOf;
3334
import static org.hamcrest.Matchers.containsString;
3435
import static org.hamcrest.Matchers.hasToString;
3536

@@ -57,7 +58,17 @@ public void testInvalidPassphrease() throws Exception {
5758
terminal.addSecretInput("thewrongpassword");
5859
UserException e = expectThrows(UserException.class, () -> execute("foo2"));
5960
assertEquals(e.getMessage(), ExitCodes.DATA_ERROR, e.exitCode);
60-
assertThat(e.getMessage(), containsString("Provided keystore password was incorrect"));
61+
if (inFipsJvm()) {
62+
assertThat(
63+
e.getMessage(),
64+
anyOf(
65+
containsString("Provided keystore password was incorrect"),
66+
containsString("Keystore has been corrupted or tampered with")
67+
)
68+
);
69+
} else {
70+
assertThat(e.getMessage(), containsString("Provided keystore password was incorrect"));
71+
}
6172

6273
}
6374

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import java.util.Map;
2828

29+
import static org.hamcrest.Matchers.anyOf;
2930
import static org.hamcrest.Matchers.containsString;
3031

3132
public class ChangeKeyStorePasswordCommandTests extends KeyStoreCommandTestCase {
@@ -90,6 +91,16 @@ public void testChangeKeyStorePasswordWrongExistingPassword() throws Exception {
9091
// We'll only be prompted once (for the old password)
9192
UserException e = expectThrows(UserException.class, this::execute);
9293
assertEquals(e.getMessage(), ExitCodes.DATA_ERROR, e.exitCode);
93-
assertThat(e.getMessage(), containsString("Provided keystore password was incorrect"));
94+
if (inFipsJvm()) {
95+
assertThat(
96+
e.getMessage(),
97+
anyOf(
98+
containsString("Provided keystore password was incorrect"),
99+
containsString("Keystore has been corrupted or tampered with")
100+
)
101+
);
102+
} else {
103+
assertThat(e.getMessage(), containsString("Provided keystore password was incorrect"));
104+
}
94105
}
95106
}

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import java.util.List;
6161
import java.util.Locale;
6262

63+
import static org.hamcrest.Matchers.anyOf;
6364
import static org.hamcrest.Matchers.containsString;
6465
import static org.hamcrest.Matchers.equalTo;
6566
import static org.hamcrest.Matchers.instanceOf;
@@ -111,9 +112,21 @@ public void testDecryptKeyStoreWithWrongPassword() throws Exception {
111112
KeyStoreWrapper keystore = KeyStoreWrapper.create();
112113
keystore.save(env.configFile(), new char[0]);
113114
final KeyStoreWrapper loadedkeystore = KeyStoreWrapper.load(env.configFile());
114-
final SecurityException exception = expectThrows(SecurityException.class,
115-
() -> loadedkeystore.decrypt(new char[]{'i', 'n', 'v', 'a', 'l', 'i', 'd'}));
116-
assertThat(exception.getMessage(), containsString("Provided keystore password was incorrect"));
115+
final SecurityException exception = expectThrows(
116+
SecurityException.class,
117+
() -> loadedkeystore.decrypt(new char[] { 'i', 'n', 'v', 'a', 'l', 'i', 'd' })
118+
);
119+
if (inFipsJvm()) {
120+
assertThat(
121+
exception.getMessage(),
122+
anyOf(
123+
containsString("Provided keystore password was incorrect"),
124+
containsString("Keystore has been corrupted or tampered with")
125+
)
126+
);
127+
} else {
128+
assertThat(exception.getMessage(), containsString("Provided keystore password was incorrect"));
129+
}
117130
}
118131

119132
public void testCannotReadStringFromClosedKeystore() throws Exception {

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.elasticsearch.cli.UserException;
2727
import org.elasticsearch.env.Environment;
2828

29+
import static org.hamcrest.Matchers.anyOf;
2930
import static org.hamcrest.Matchers.containsString;
3031

3132
public class ListKeyStoreCommandTests extends KeyStoreCommandTestCase {
@@ -76,7 +77,17 @@ public void testListWithIncorrectPassword() throws Exception {
7677
terminal.addSecretInput("thewrongkeystorepassword");
7778
UserException e = expectThrows(UserException.class, this::execute);
7879
assertEquals(e.getMessage(), ExitCodes.DATA_ERROR, e.exitCode);
79-
assertThat(e.getMessage(), containsString("Provided keystore password was incorrect"));
80+
if (inFipsJvm()) {
81+
assertThat(
82+
e.getMessage(),
83+
anyOf(
84+
containsString("Provided keystore password was incorrect"),
85+
containsString("Keystore has been corrupted or tampered with")
86+
)
87+
);
88+
} else {
89+
assertThat(e.getMessage(), containsString("Provided keystore password was incorrect"));
90+
}
8091
}
8192

8293
public void testListWithUnprotectedKeystore() throws Exception {

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.Map;
2828
import java.util.Set;
2929

30+
import static org.hamcrest.Matchers.anyOf;
3031
import static org.hamcrest.Matchers.containsString;
3132

3233
public class RemoveSettingKeyStoreCommandTests extends KeyStoreCommandTestCase {
@@ -93,7 +94,18 @@ public void testRemoveWithIncorrectPassword() throws Exception {
9394
terminal.addSecretInput("thewrongpassword");
9495
UserException e = expectThrows(UserException.class, () -> execute("foo"));
9596
assertEquals(e.getMessage(), ExitCodes.DATA_ERROR, e.exitCode);
96-
assertThat(e.getMessage(), containsString("Provided keystore password was incorrect"));
97+
if (inFipsJvm()) {
98+
assertThat(
99+
e.getMessage(),
100+
anyOf(
101+
containsString("Provided keystore password was incorrect"),
102+
containsString("Keystore has been corrupted or tampered with")
103+
)
104+
);
105+
} else {
106+
assertThat(e.getMessage(), containsString("Provided keystore password was incorrect"));
107+
}
108+
97109
}
98110

99111
public void testRemoveFromUnprotectedKeystore() throws Exception {

0 commit comments

Comments
 (0)