|
|
@@ -38,6 +38,7 @@ import org.elasticsearch.xpack.core.security.SecurityField;
|
|
|
import org.elasticsearch.xpack.core.security.authc.Realm;
|
|
|
import org.elasticsearch.xpack.core.security.authc.RealmSettings;
|
|
|
import org.elasticsearch.xpack.core.security.authc.file.FileRealmSettings;
|
|
|
+import org.elasticsearch.xpack.core.security.authc.support.Hasher;
|
|
|
import org.elasticsearch.xpack.core.security.authz.AuthorizationServiceField;
|
|
|
import org.elasticsearch.xpack.core.security.authz.accesscontrol.IndicesAccessControl;
|
|
|
import org.elasticsearch.xpack.core.security.authz.permission.DocumentPermissions;
|
|
|
@@ -65,6 +66,7 @@ import java.util.function.Predicate;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
import static org.elasticsearch.cluster.metadata.IndexMetaData.INDEX_FORMAT_SETTING;
|
|
|
+import static org.elasticsearch.license.XPackLicenseState.FIPS_ALLOWED_LICENSE_OPERATION_MODES;
|
|
|
import static org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames.SECURITY_MAIN_ALIAS;
|
|
|
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.INTERNAL_MAIN_INDEX_FORMAT;
|
|
|
import static org.hamcrest.Matchers.containsString;
|
|
|
@@ -243,24 +245,36 @@ public class SecurityTests extends ESTestCase {
|
|
|
assertNull(joinValidator);
|
|
|
}
|
|
|
|
|
|
- public void testJoinValidatorForFIPSLicense() throws Exception {
|
|
|
+ public void testJoinValidatorForFIPSOnAllowedLicense() throws Exception {
|
|
|
DiscoveryNode node = new DiscoveryNode("foo", buildNewFakeTransportAddress(),
|
|
|
VersionUtils.randomVersionBetween(random(), null, Version.CURRENT));
|
|
|
MetaData.Builder builder = MetaData.builder();
|
|
|
- License license = TestUtils.generateSignedLicense(TimeValue.timeValueHours(24));
|
|
|
+ License license =
|
|
|
+ TestUtils.generateSignedLicense(randomFrom(FIPS_ALLOWED_LICENSE_OPERATION_MODES).toString(), TimeValue.timeValueHours(24));
|
|
|
TestUtils.putLicense(builder, license);
|
|
|
ClusterState state = ClusterState.builder(ClusterName.DEFAULT).metaData(builder.build()).build();
|
|
|
new Security.ValidateLicenseForFIPS(false).accept(node, state);
|
|
|
+ // no exception thrown
|
|
|
+ new Security.ValidateLicenseForFIPS(true).accept(node, state);
|
|
|
+ // no exception thrown
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testJoinValidatorForFIPSOnForbiddenLicense() throws Exception {
|
|
|
+ DiscoveryNode node = new DiscoveryNode("foo", buildNewFakeTransportAddress(),
|
|
|
+ VersionUtils.randomVersionBetween(random(), null, Version.CURRENT));
|
|
|
+ MetaData.Builder builder = MetaData.builder();
|
|
|
+ final String forbiddenLicenseType =
|
|
|
+ randomFrom(List.of(License.OperationMode.values()).stream()
|
|
|
+ .filter(l -> FIPS_ALLOWED_LICENSE_OPERATION_MODES.contains(l) == false).collect(Collectors.toList())).toString();
|
|
|
+ License license = TestUtils.generateSignedLicense(forbiddenLicenseType, TimeValue.timeValueHours(24));
|
|
|
+ TestUtils.putLicense(builder, license);
|
|
|
+ ClusterState state = ClusterState.builder(ClusterName.DEFAULT).metaData(builder.build()).build();
|
|
|
+ new Security.ValidateLicenseForFIPS(false).accept(node, state);
|
|
|
+ // no exception thrown
|
|
|
+ IllegalStateException e = expectThrows(IllegalStateException.class,
|
|
|
+ () -> new Security.ValidateLicenseForFIPS(true).accept(node, state));
|
|
|
+ assertThat(e.getMessage(), containsString("FIPS mode cannot be used"));
|
|
|
|
|
|
- final boolean isLicenseValidForFips =
|
|
|
- FIPS140LicenseBootstrapCheck.ALLOWED_LICENSE_OPERATION_MODES.contains(license.operationMode());
|
|
|
- if (isLicenseValidForFips) {
|
|
|
- new Security.ValidateLicenseForFIPS(true).accept(node, state);
|
|
|
- } else {
|
|
|
- IllegalStateException e = expectThrows(IllegalStateException.class,
|
|
|
- () -> new Security.ValidateLicenseForFIPS(true).accept(node, state));
|
|
|
- assertThat(e.getMessage(), containsString("FIPS mode cannot be used"));
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
public void testIndexJoinValidator_FullyCurrentCluster() throws Exception {
|
|
|
@@ -377,4 +391,71 @@ public class SecurityTests extends ESTestCase {
|
|
|
Security.validateRealmSettings(settings);
|
|
|
// no-exception
|
|
|
}
|
|
|
+
|
|
|
+ public void testValidateForFipsKeystoreWithImplicitJksType() {
|
|
|
+ final Settings settings = Settings.builder()
|
|
|
+ .put(XPackSettings.FIPS_MODE_ENABLED.getKey(), true)
|
|
|
+ .put("xpack.security.transport.ssl.keystore.path", "path/to/keystore")
|
|
|
+ .put(XPackSettings.PASSWORD_HASHING_ALGORITHM.getKey(),
|
|
|
+ randomFrom(Hasher.getAvailableAlgoStoredHash().stream()
|
|
|
+ .filter(alg -> alg.startsWith("pbkdf2") == false).collect(Collectors.toList())))
|
|
|
+ .build();
|
|
|
+ final IllegalArgumentException iae =
|
|
|
+ expectThrows(IllegalArgumentException.class, () -> Security.validateForFips(settings));
|
|
|
+ assertThat(iae.getMessage(), containsString("JKS Keystores cannot be used in a FIPS 140 compliant JVM"));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testValidateForFipsKeystoreWithExplicitJksType() {
|
|
|
+ final Settings settings = Settings.builder()
|
|
|
+ .put(XPackSettings.FIPS_MODE_ENABLED.getKey(), true)
|
|
|
+ .put("xpack.security.transport.ssl.keystore.path", "path/to/keystore")
|
|
|
+ .put("xpack.security.transport.ssl.keystore.type", "JKS")
|
|
|
+ .put(XPackSettings.PASSWORD_HASHING_ALGORITHM.getKey(),
|
|
|
+ randomFrom(Hasher.getAvailableAlgoStoredHash().stream()
|
|
|
+ .filter(alg -> alg.startsWith("pbkdf2")).collect(Collectors.toList())))
|
|
|
+ .build();
|
|
|
+ final IllegalArgumentException iae =
|
|
|
+ expectThrows(IllegalArgumentException.class, () -> Security.validateForFips(settings));
|
|
|
+ assertThat(iae.getMessage(), containsString("JKS Keystores cannot be used in a FIPS 140 compliant JVM"));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testValidateForFipsInvalidPasswordHashingAlgorithm() {
|
|
|
+ final Settings settings = Settings.builder()
|
|
|
+ .put(XPackSettings.FIPS_MODE_ENABLED.getKey(), true)
|
|
|
+ .put(XPackSettings.PASSWORD_HASHING_ALGORITHM.getKey(),
|
|
|
+ randomFrom(Hasher.getAvailableAlgoStoredHash().stream()
|
|
|
+ .filter(alg -> alg.startsWith("pbkdf2") == false).collect(Collectors.toList())))
|
|
|
+ .build();
|
|
|
+ final IllegalArgumentException iae =
|
|
|
+ expectThrows(IllegalArgumentException.class, () -> Security.validateForFips(settings));
|
|
|
+ assertThat(iae.getMessage(), containsString("Only PBKDF2 is allowed for password hashing in a FIPS 140 JVM."));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testValidateForFipsMultipleValidationErrors() {
|
|
|
+ final Settings settings = Settings.builder()
|
|
|
+ .put(XPackSettings.FIPS_MODE_ENABLED.getKey(), true)
|
|
|
+ .put("xpack.security.transport.ssl.keystore.path", "path/to/keystore")
|
|
|
+ .put("xpack.security.transport.ssl.keystore.type", "JKS")
|
|
|
+ .put(XPackSettings.PASSWORD_HASHING_ALGORITHM.getKey(),
|
|
|
+ randomFrom(Hasher.getAvailableAlgoStoredHash().stream()
|
|
|
+ .filter(alg -> alg.startsWith("pbkdf2") == false).collect(Collectors.toList())))
|
|
|
+ .build();
|
|
|
+ final IllegalArgumentException iae =
|
|
|
+ expectThrows(IllegalArgumentException.class, () -> Security.validateForFips(settings));
|
|
|
+ assertThat(iae.getMessage(), containsString("JKS Keystores cannot be used in a FIPS 140 compliant JVM"));
|
|
|
+ assertThat(iae.getMessage(), containsString("Only PBKDF2 is allowed for password hashing in a FIPS 140 JVM."));
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testValidateForFipsNoErrors() {
|
|
|
+ final Settings settings = Settings.builder()
|
|
|
+ .put(XPackSettings.FIPS_MODE_ENABLED.getKey(), true)
|
|
|
+ .put("xpack.security.transport.ssl.keystore.path", "path/to/keystore")
|
|
|
+ .put("xpack.security.transport.ssl.keystore.type", "BCFKS")
|
|
|
+ .put(XPackSettings.PASSWORD_HASHING_ALGORITHM.getKey(),
|
|
|
+ randomFrom(Hasher.getAvailableAlgoStoredHash().stream()
|
|
|
+ .filter(alg -> alg.startsWith("pbkdf2")).collect(Collectors.toList())))
|
|
|
+ .build();
|
|
|
+ Security.validateForFips(settings);
|
|
|
+ // no exception thrown
|
|
|
+ }
|
|
|
}
|