Enable tests in FIPS 140 in JDK 11 (#49485)
This change changes the way to run our test suites in JVMs configured in FIPS 140 approved mode. It does so by: - Configuring any given runtime Java in FIPS mode with the bundled policy and security properties files, setting the system properties java.security.properties and java.security.policy with the == operator that overrides the default JVM properties and policy. - When runtime java is 11 and higher, using BouncyCastle FIPS Cryptographic provider and BCJSSE in FIPS mode. These are used as testRuntime dependencies for unit tests and internal clusters, and copied (relevant jars) explicitly to the lib directory for testclusters used in REST tests - When runtime java is 8, using BouncyCastle FIPS Cryptographic provider and SunJSSE in FIPS mode. Running the tests in FIPS 140 approved mode doesn't require an additional configuration either in CI workers or locally and is controlled by specifying -Dtests.fips.enabled=true
This commit is contained in:
parent
dd3e2f1e18
commit
ee202a642f
|
@ -7,7 +7,6 @@
|
|||
|
||||
ES_RUNTIME_JAVA:
|
||||
- java8
|
||||
- java8fips
|
||||
- java11
|
||||
- openjdk13
|
||||
- openjdk14
|
||||
|
|
|
@ -172,6 +172,9 @@ if (project != rootProject) {
|
|||
forbiddenApisTest.enabled = false
|
||||
jarHell.enabled = false
|
||||
thirdPartyAudit.enabled = false
|
||||
if (Boolean.parseBoolean(System.getProperty("tests.fips.enabled"))){
|
||||
test.enabled = false
|
||||
}
|
||||
|
||||
configurations {
|
||||
distribution
|
||||
|
@ -204,6 +207,7 @@ if (project != rootProject) {
|
|||
exclude '**/*.p12'
|
||||
// the file that actually defines nocommit
|
||||
exclude '**/ForbiddenPatternsTask.java'
|
||||
exclude '**/*.bcfks'
|
||||
}
|
||||
|
||||
testingConventions {
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.elasticsearch.gradle
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
|
||||
import com.github.jengelman.gradle.plugins.shadow.ShadowBasePlugin
|
||||
import com.github.jengelman.gradle.plugins.shadow.ShadowExtension
|
||||
import com.github.jengelman.gradle.plugins.shadow.ShadowJavaPlugin
|
||||
|
@ -34,9 +33,9 @@ import org.elasticsearch.gradle.precommit.PrecommitTasks
|
|||
import org.elasticsearch.gradle.test.ErrorReportingTestListener
|
||||
import org.elasticsearch.gradle.testclusters.ElasticsearchCluster
|
||||
import org.elasticsearch.gradle.testclusters.TestClustersPlugin
|
||||
import org.gradle.api.Action
|
||||
import org.elasticsearch.gradle.testclusters.TestDistribution
|
||||
import org.elasticsearch.gradle.tool.Boilerplate
|
||||
import org.gradle.api.Action
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.InvalidUserDataException
|
||||
import org.gradle.api.JavaVersion
|
||||
|
@ -141,34 +140,71 @@ class BuildPlugin implements Plugin<Project> {
|
|||
configureTestTasks(project)
|
||||
configurePrecommit(project)
|
||||
configureDependenciesInfo(project)
|
||||
|
||||
configureFips140(project)
|
||||
}
|
||||
|
||||
public static void configureFips140(Project project) {
|
||||
// Need to do it here to support external plugins
|
||||
GlobalInfoExtension globalInfo = project.rootProject.extensions.getByType(GlobalInfoExtension)
|
||||
// wait until global info is populated because we don't know if we are running in a fips jvm until execution time
|
||||
globalInfo.ready {
|
||||
// Common config when running with a FIPS-140 runtime JVM
|
||||
if (BuildParams.inFipsJvm) {
|
||||
project.tasks.withType(Test).configureEach { Test task ->
|
||||
task.systemProperty 'javax.net.ssl.trustStorePassword', 'password'
|
||||
task.systemProperty 'javax.net.ssl.keyStorePassword', 'password'
|
||||
}
|
||||
project.pluginManager.withPlugin("elasticsearch.testclusters") {
|
||||
NamedDomainObjectContainer<ElasticsearchCluster> testClusters = project.extensions.findByName(TestClustersPlugin.EXTENSION_NAME) as NamedDomainObjectContainer<ElasticsearchCluster>
|
||||
if (testClusters != null) {
|
||||
testClusters.all { ElasticsearchCluster cluster ->
|
||||
cluster.setTestDistribution(TestDistribution.DEFAULT)
|
||||
cluster.systemProperty 'javax.net.ssl.trustStorePassword', 'password'
|
||||
cluster.systemProperty 'javax.net.ssl.keyStorePassword', 'password'
|
||||
// Can't use our DiagnosticTrustManager with SunJSSE in FIPS mode
|
||||
cluster.setting 'xpack.security.ssl.diagnose.trust', 'false'
|
||||
static void configureFips140(Project project) {
|
||||
// Common config when running with a FIPS-140 runtime JVM
|
||||
if (inFipsJvm()) {
|
||||
// This configuration can be removed once system modules are available
|
||||
Boilerplate.maybeCreate(project.configurations, 'extraJars') {
|
||||
project.dependencies.add('extraJars', "org.bouncycastle:bc-fips:1.0.1")
|
||||
project.dependencies.add('extraJars', "org.bouncycastle:bctls-fips:1.0.9")
|
||||
}
|
||||
ExportElasticsearchBuildResourcesTask buildResources = project.tasks.getByName('buildResources') as ExportElasticsearchBuildResourcesTask
|
||||
File securityProperties = buildResources.copy("fips_java.security")
|
||||
File security8Properties = buildResources.copy("fips_java8.security")
|
||||
File securityPolicy = buildResources.copy("fips_java.policy")
|
||||
File security8Policy = buildResources.copy("fips_java8.policy")
|
||||
File bcfksKeystore = buildResources.copy("cacerts.bcfks")
|
||||
GlobalInfoExtension globalInfo = project.rootProject.extensions.getByType(GlobalInfoExtension)
|
||||
project.pluginManager.withPlugin("elasticsearch.testclusters") {
|
||||
NamedDomainObjectContainer<ElasticsearchCluster> testClusters = project.extensions.findByName(TestClustersPlugin.EXTENSION_NAME) as NamedDomainObjectContainer<ElasticsearchCluster>
|
||||
if (testClusters != null) {
|
||||
testClusters.all { ElasticsearchCluster cluster ->
|
||||
cluster.setTestDistribution(TestDistribution.DEFAULT)
|
||||
for (File dep : project.getConfigurations().getByName("extraJars").getFiles()) {
|
||||
cluster.extraJarFile(dep)
|
||||
}
|
||||
globalInfo.ready {
|
||||
if (BuildParams.runtimeJavaVersion > JavaVersion.VERSION_1_8) {
|
||||
cluster.extraConfigFile("fips_java.security", securityProperties)
|
||||
cluster.extraConfigFile("fips_java.policy", securityPolicy)
|
||||
} else {
|
||||
cluster.extraConfigFile("fips_java.security", security8Properties)
|
||||
cluster.extraConfigFile("fips_java.policy", security8Policy)
|
||||
}
|
||||
}
|
||||
cluster.extraConfigFile("cacerts.bcfks", bcfksKeystore)
|
||||
cluster.systemProperty('java.security.properties', '=${ES_PATH_CONF}/fips_java.security')
|
||||
cluster.systemProperty('java.security.policy', '=${ES_PATH_CONF}/fips_java.policy')
|
||||
cluster.systemProperty('javax.net.ssl.trustStore', '${ES_PATH_CONF}/cacerts.bcfks')
|
||||
cluster.systemProperty('javax.net.ssl.trustStorePassword', 'password')
|
||||
cluster.systemProperty('javax.net.ssl.keyStorePassword', 'password')
|
||||
cluster.systemProperty('javax.net.ssl.keyStoreType', 'BCFKS')
|
||||
// Can't use our DiagnosticTrustManager with SunJSSE in FIPS mode
|
||||
cluster.setting 'xpack.security.ssl.diagnose.trust', 'false'
|
||||
}
|
||||
}
|
||||
}
|
||||
project.tasks.withType(Test).configureEach { Test task ->
|
||||
task.dependsOn(buildResources)
|
||||
globalInfo.ready {
|
||||
// Using the key==value format to override default JVM security settings and policy
|
||||
// see also: https://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html
|
||||
if (BuildParams.runtimeJavaVersion > JavaVersion.VERSION_1_8) {
|
||||
task.systemProperty('java.security.properties', String.format(Locale.ROOT, "=%s", securityProperties.toString()))
|
||||
task.systemProperty('java.security.policy', String.format(Locale.ROOT, "=%s", securityPolicy.toString()))
|
||||
} else {
|
||||
task.systemProperty('java.security.properties', String.format(Locale.ROOT, "=%s", security8Properties.toString()))
|
||||
task.systemProperty('java.security.policy', String.format(Locale.ROOT, "=%s", security8Policy.toString()))
|
||||
}
|
||||
}
|
||||
task.systemProperty('javax.net.ssl.trustStorePassword', 'password')
|
||||
task.systemProperty('javax.net.ssl.keyStorePassword', 'password')
|
||||
task.systemProperty('javax.net.ssl.trustStoreType', 'BCFKS')
|
||||
task.systemProperty('javax.net.ssl.trustStore', bcfksKeystore.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -659,12 +695,6 @@ class BuildPlugin implements Plugin<Project> {
|
|||
project.mkdir(heapdumpDir)
|
||||
project.mkdir(test.workingDir)
|
||||
|
||||
if (BuildParams.inFipsJvm) {
|
||||
nonInputProperties.systemProperty('runtime.java', "${-> BuildParams.runtimeJavaVersion.majorVersion}FIPS")
|
||||
} else {
|
||||
nonInputProperties.systemProperty('runtime.java', "${-> BuildParams.runtimeJavaVersion.majorVersion}")
|
||||
}
|
||||
|
||||
if (BuildParams.runtimeJavaVersion >= JavaVersion.VERSION_1_9) {
|
||||
test.jvmArgs '--illegal-access=warn'
|
||||
}
|
||||
|
@ -675,7 +705,10 @@ class BuildPlugin implements Plugin<Project> {
|
|||
test.systemProperty ('java.locale.providers','SPI,COMPAT')
|
||||
}
|
||||
}
|
||||
|
||||
if (inFipsJvm()) {
|
||||
project.dependencies.add('testRuntimeOnly', "org.bouncycastle:bc-fips:1.0.1")
|
||||
project.dependencies.add('testRuntimeOnly', "org.bouncycastle:bctls-fips:1.0.9")
|
||||
}
|
||||
test.jvmArgumentProviders.add(nonInputProperties)
|
||||
test.extensions.add('nonInputProperties', nonInputProperties)
|
||||
|
||||
|
@ -821,4 +854,8 @@ class BuildPlugin implements Plugin<Project> {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
private static inFipsJvm(){
|
||||
return Boolean.parseBoolean(System.getProperty("tests.fips.enabled"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,14 +42,12 @@ public class GenerateGlobalBuildInfoTask extends DefaultTask {
|
|||
private final RegularFileProperty outputFile;
|
||||
private final RegularFileProperty compilerVersionFile;
|
||||
private final RegularFileProperty runtimeVersionFile;
|
||||
private final RegularFileProperty fipsJvmFile;
|
||||
|
||||
@Inject
|
||||
public GenerateGlobalBuildInfoTask(ObjectFactory objectFactory) {
|
||||
this.outputFile = objectFactory.fileProperty();
|
||||
this.compilerVersionFile = objectFactory.fileProperty();
|
||||
this.runtimeVersionFile = objectFactory.fileProperty();
|
||||
this.fipsJvmFile = objectFactory.fileProperty();
|
||||
}
|
||||
|
||||
@Input
|
||||
|
@ -114,11 +112,6 @@ public class GenerateGlobalBuildInfoTask extends DefaultTask {
|
|||
return runtimeVersionFile;
|
||||
}
|
||||
|
||||
@OutputFile
|
||||
public RegularFileProperty getFipsJvmFile() {
|
||||
return fipsJvmFile;
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public void generate() {
|
||||
String javaVendorVersion = System.getProperty("java.vendor.version", System.getProperty("java.vendor"));
|
||||
|
@ -137,7 +130,6 @@ public class GenerateGlobalBuildInfoTask extends DefaultTask {
|
|||
String runtimeJavaVersionDetails = gradleJavaVersionDetails;
|
||||
JavaVersion runtimeJavaVersionEnum = JavaVersion.current();
|
||||
File gradleJavaHome = Jvm.current().getJavaHome();
|
||||
boolean inFipsJvm = false;
|
||||
|
||||
try {
|
||||
if (Files.isSameFile(compilerJavaHome.toPath(), gradleJavaHome.toPath()) == false) {
|
||||
|
@ -153,10 +145,6 @@ public class GenerateGlobalBuildInfoTask extends DefaultTask {
|
|||
if (runtimeJavaHome.exists()) {
|
||||
runtimeJavaVersionDetails = findJavaVersionDetails(runtimeJavaHome);
|
||||
runtimeJavaVersionEnum = JavaVersion.toVersion(findJavaSpecificationVersion(runtimeJavaHome));
|
||||
|
||||
// We don't expect Gradle to be running in a FIPS JVM
|
||||
String inFipsJvmScript = "print(java.security.Security.getProviders()[0].name.toLowerCase().contains(\"fips\"));";
|
||||
inFipsJvm = Boolean.parseBoolean(runJavaAsScript(runtimeJavaHome, inFipsJvmScript));
|
||||
} else {
|
||||
throw new RuntimeException("Runtime Java home path of '" + compilerJavaHome + "' does not exist");
|
||||
}
|
||||
|
@ -242,7 +230,6 @@ public class GenerateGlobalBuildInfoTask extends DefaultTask {
|
|||
|
||||
writeToFile(compilerVersionFile.getAsFile().get(), compilerJavaVersionEnum.name());
|
||||
writeToFile(runtimeVersionFile.getAsFile().get(), runtimeJavaVersionEnum.name());
|
||||
writeToFile(fipsJvmFile.getAsFile().get(), Boolean.toString(inFipsJvm));
|
||||
}
|
||||
|
||||
private void writeToFile(File file, String content) {
|
||||
|
|
|
@ -76,14 +76,12 @@ public class GlobalBuildInfoPlugin implements Plugin<Project> {
|
|||
task.getOutputFile().set(new File(project.getBuildDir(), "global-build-info"));
|
||||
task.getCompilerVersionFile().set(new File(project.getBuildDir(), "java-compiler-version"));
|
||||
task.getRuntimeVersionFile().set(new File(project.getBuildDir(), "java-runtime-version"));
|
||||
task.getFipsJvmFile().set(new File(project.getBuildDir(), "in-fips-jvm"));
|
||||
});
|
||||
|
||||
PrintGlobalBuildInfoTask printTask = project.getTasks().create("printGlobalBuildInfo", PrintGlobalBuildInfoTask.class, task -> {
|
||||
task.getBuildInfoFile().set(generateTask.getOutputFile());
|
||||
task.getCompilerVersionFile().set(generateTask.getCompilerVersionFile());
|
||||
task.getRuntimeVersionFile().set(generateTask.getRuntimeVersionFile());
|
||||
task.getFipsJvmFile().set(generateTask.getFipsJvmFile());
|
||||
task.setGlobalInfoListeners(extension.listeners);
|
||||
});
|
||||
|
||||
|
@ -103,6 +101,7 @@ public class GlobalBuildInfoPlugin implements Plugin<Project> {
|
|||
params.setIsCi(System.getenv("JENKINS_URL") != null);
|
||||
params.setIsInternal(GlobalBuildInfoPlugin.class.getResource("/buildSrc.marker") != null);
|
||||
params.setDefaultParallel(findDefaultParallel(project));
|
||||
params.setInFipsJvm(isInFipsJvm());
|
||||
});
|
||||
|
||||
project.allprojects(
|
||||
|
@ -160,6 +159,10 @@ public class GlobalBuildInfoPlugin implements Plugin<Project> {
|
|||
return "JAVA" + version + "_HOME";
|
||||
}
|
||||
|
||||
private static boolean isInFipsJvm() {
|
||||
return Boolean.parseBoolean(System.getProperty("tests.fips.enabled"));
|
||||
}
|
||||
|
||||
private static String getResourceContents(String resourcePath) {
|
||||
try (
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(GlobalBuildInfoPlugin.class.getResourceAsStream(resourcePath)))
|
||||
|
|
|
@ -16,7 +16,6 @@ public class PrintGlobalBuildInfoTask extends DefaultTask {
|
|||
private final RegularFileProperty buildInfoFile;
|
||||
private final RegularFileProperty compilerVersionFile;
|
||||
private final RegularFileProperty runtimeVersionFile;
|
||||
private final RegularFileProperty fipsJvmFile;
|
||||
private List<Runnable> globalInfoListeners = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
|
@ -24,7 +23,6 @@ public class PrintGlobalBuildInfoTask extends DefaultTask {
|
|||
this.buildInfoFile = objectFactory.fileProperty();
|
||||
this.compilerVersionFile = objectFactory.fileProperty();
|
||||
this.runtimeVersionFile = objectFactory.fileProperty();
|
||||
this.fipsJvmFile = objectFactory.fileProperty();
|
||||
}
|
||||
|
||||
@InputFile
|
||||
|
@ -42,11 +40,6 @@ public class PrintGlobalBuildInfoTask extends DefaultTask {
|
|||
return runtimeVersionFile;
|
||||
}
|
||||
|
||||
@InputFile
|
||||
public RegularFileProperty getFipsJvmFile() {
|
||||
return fipsJvmFile;
|
||||
}
|
||||
|
||||
public void setGlobalInfoListeners(List<Runnable> globalInfoListeners) {
|
||||
this.globalInfoListeners = globalInfoListeners;
|
||||
}
|
||||
|
@ -57,6 +50,7 @@ public class PrintGlobalBuildInfoTask extends DefaultTask {
|
|||
getLogger().quiet("Elasticsearch Build Hamster says Hello!");
|
||||
getLogger().quiet(getFileText(getBuildInfoFile()).asString());
|
||||
getLogger().quiet(" Random Testing Seed : " + BuildParams.getTestSeed());
|
||||
getLogger().quiet(" In FIPS 140 mode : " + BuildParams.isInFipsJvm());
|
||||
getLogger().quiet("=======================================");
|
||||
|
||||
setGlobalProperties();
|
||||
|
@ -76,7 +70,6 @@ public class PrintGlobalBuildInfoTask extends DefaultTask {
|
|||
BuildParams.init(params -> {
|
||||
params.setCompilerJavaVersion(JavaVersion.valueOf(getFileText(getCompilerVersionFile()).asString()));
|
||||
params.setRuntimeJavaVersion(JavaVersion.valueOf(getFileText(getRuntimeVersionFile()).asString()));
|
||||
params.setInFipsJvm(Boolean.parseBoolean(getFileText(getFipsJvmFile()).asString()));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -366,6 +366,11 @@ public class ElasticsearchCluster implements TestClusterConfiguration, Named {
|
|||
nodes.all(node -> node.extraConfigFile(destination, from, normalization));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void extraJarFile(File from) {
|
||||
nodes.all(node -> node.extraJarFile(from));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void user(Map<String, String> userSpec) {
|
||||
nodes.all(node -> node.user(userSpec));
|
||||
|
|
|
@ -129,6 +129,7 @@ public class ElasticsearchNode implements TestClusterConfiguration {
|
|||
private final LazyPropertyMap<String, CharSequence> environment = new LazyPropertyMap<>("Environment", this);
|
||||
private final LazyPropertyList<CharSequence> jvmArgs = new LazyPropertyList<>("JVM arguments", this);
|
||||
private final LazyPropertyMap<String, File> extraConfigFiles = new LazyPropertyMap<>("Extra config files", this, FileEntry::new);
|
||||
private final LazyPropertyList<File> extraJarFiles = new LazyPropertyList<>("Extra jar files", this);
|
||||
private final List<Map<String, String>> credentials = new ArrayList<>();
|
||||
final LinkedHashMap<String, String> defaultConfig = new LinkedHashMap<>();
|
||||
|
||||
|
@ -420,6 +421,11 @@ public class ElasticsearchNode implements TestClusterConfiguration {
|
|||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Failed to create working directory for " + this, e);
|
||||
}
|
||||
|
||||
copyExtraJars();
|
||||
|
||||
copyExtraConfigFiles();
|
||||
|
||||
createConfiguration();
|
||||
|
||||
final List<String> pluginsToInstall = new ArrayList<>();
|
||||
|
@ -465,8 +471,6 @@ public class ElasticsearchNode implements TestClusterConfiguration {
|
|||
|
||||
installModules();
|
||||
|
||||
copyExtraConfigFiles();
|
||||
|
||||
if (isSettingTrue("xpack.security.enabled")) {
|
||||
if (credentials.isEmpty()) {
|
||||
user(Collections.emptyMap());
|
||||
|
@ -551,6 +555,25 @@ public class ElasticsearchNode implements TestClusterConfiguration {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies extra jars to the `/lib` directory.
|
||||
* //TODO: Remove this when system modules are available
|
||||
*/
|
||||
private void copyExtraJars() {
|
||||
if (extraJarFiles.isEmpty() == false) {
|
||||
logToProcessStdout("Setting up " + extraJarFiles.size() + " additional jar dependencies");
|
||||
}
|
||||
extraJarFiles.forEach(from -> {
|
||||
Path destination = getDistroDir().resolve("lib").resolve(from.getName());
|
||||
try {
|
||||
Files.copy(from.toPath(), destination, StandardCopyOption.REPLACE_EXISTING);
|
||||
LOGGER.info("Added extra jar {} to {}", from.getName(), destination);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException("Can't copy extra jar dependency " + from.getName() + " to " + destination.toString(), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void installModules() {
|
||||
if (testDistribution == TestDistribution.INTEG_TEST) {
|
||||
logToProcessStdout("Installing " + modules.size() + "modules");
|
||||
|
@ -593,6 +616,14 @@ public class ElasticsearchNode implements TestClusterConfiguration {
|
|||
extraConfigFiles.put(destination, from, normalization);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void extraJarFile(File from) {
|
||||
if (from.toString().endsWith(".jar") == false) {
|
||||
throw new IllegalArgumentException("extra jar file " + from.toString() + " doesn't appear to be a JAR");
|
||||
}
|
||||
extraJarFiles.add(from);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void user(Map<String, String> userSpec) {
|
||||
Set<String> keys = new HashSet<>(userSpec.keySet());
|
||||
|
@ -654,6 +685,10 @@ public class ElasticsearchNode implements TestClusterConfiguration {
|
|||
+ systemProperties.entrySet()
|
||||
.stream()
|
||||
.map(entry -> "-D" + entry.getKey() + "=" + entry.getValue())
|
||||
// ES_PATH_CONF is also set as an environment variable and for a reference to ${ES_PATH_CONF}
|
||||
// to work ES_JAVA_OPTS, we need to make sure that ES_PATH_CONF before ES_JAVA_OPTS. Instead,
|
||||
// we replace the reference with the actual value in other environment variables
|
||||
.map(p -> p.replace("${ES_PATH_CONF}", configFile.getParent().toString()))
|
||||
.collect(Collectors.joining(" "));
|
||||
}
|
||||
String jvmArgsString = "";
|
||||
|
|
|
@ -93,6 +93,8 @@ public interface TestClusterConfiguration {
|
|||
|
||||
void extraConfigFile(String destination, File from, PropertyNormalization normalization);
|
||||
|
||||
void extraJarFile(File from);
|
||||
|
||||
void user(Map<String, String> userSpec);
|
||||
|
||||
String getHttpSocketURI();
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,16 @@
|
|||
grant {
|
||||
permission java.security.SecurityPermission "putProviderProperty.BCFIPS";
|
||||
permission java.security.SecurityPermission "putProviderProperty.BCJSSE";
|
||||
permission java.lang.RuntimePermission "getProtectionDomain";
|
||||
permission java.util.PropertyPermission "java.runtime.name", "read";
|
||||
permission org.bouncycastle.crypto.CryptoServicesPermission "tlsAlgorithmsEnabled";
|
||||
//io.netty.handler.codec.DecoderException
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.security.internal.spec";
|
||||
//java.security.InvalidAlgorithmParameterException: Cannot process GCMParameterSpec
|
||||
permission java.lang.RuntimePermission "accessDeclaredMembers";
|
||||
permission java.util.PropertyPermission "intellij.debug.agent", "read";
|
||||
permission java.util.PropertyPermission "intellij.debug.agent", "write";
|
||||
permission org.bouncycastle.crypto.CryptoServicesPermission "exportSecretKey";
|
||||
permission org.bouncycastle.crypto.CryptoServicesPermission "exportPrivateKey";
|
||||
permission java.io.FilePermission "${javax.net.ssl.trustStore}", "read";
|
||||
};
|
|
@ -0,0 +1,50 @@
|
|||
security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
|
||||
security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider fips:BCFIPS
|
||||
security.provider.3=SUN
|
||||
securerandom.source=file:/dev/urandom
|
||||
securerandom.strongAlgorithms=NativePRNGBlocking:SUN,DRBG:SUN
|
||||
securerandom.drbg.config=
|
||||
login.configuration.provider=sun.security.provider.ConfigFile
|
||||
policy.provider=sun.security.provider.PolicyFile
|
||||
policy.expandProperties=true
|
||||
policy.allowSystemProperty=true
|
||||
policy.ignoreIdentityScope=false
|
||||
keystore.type=BCFKS
|
||||
keystore.type.compat=true
|
||||
package.access=sun.misc.,\
|
||||
sun.reflect.
|
||||
package.definition=sun.misc.,\
|
||||
sun.reflect.
|
||||
security.overridePropertiesFile=true
|
||||
ssl.KeyManagerFactory.algorithm=PKIX
|
||||
ssl.TrustManagerFactory.algorithm=PKIX
|
||||
networkaddress.cache.negative.ttl=10
|
||||
krb5.kdc.bad.policy = tryLast
|
||||
jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \
|
||||
RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
|
||||
jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
|
||||
DSA keySize < 1024
|
||||
jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 1024, \
|
||||
EC keySize < 224, DES40_CBC, RC4_40, 3DES_EDE_CBC
|
||||
jdk.tls.legacyAlgorithms= \
|
||||
K_NULL, C_NULL, M_NULL, \
|
||||
DH_anon, ECDH_anon, \
|
||||
RC4_128, RC4_40, DES_CBC, DES40_CBC, \
|
||||
3DES_EDE_CBC
|
||||
jdk.tls.keyLimits=AES/GCM/NoPadding KeyUpdate 2^37
|
||||
crypto.policy=unlimited
|
||||
jdk.xml.dsig.secureValidationPolicy=\
|
||||
disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\
|
||||
disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\
|
||||
disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\
|
||||
disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\
|
||||
maxTransforms 5,\
|
||||
maxReferences 30,\
|
||||
disallowReferenceUriSchemes file http https,\
|
||||
minKeySize RSA 1024,\
|
||||
minKeySize DSA 1024,\
|
||||
minKeySize EC 224,\
|
||||
noDuplicateIds,\
|
||||
noRetrievalMethodLoops
|
||||
jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep;\
|
||||
java.base/java.security.KeyRep$Type;java.base/javax.crypto.spec.SecretKeySpec;!*
|
|
@ -0,0 +1,16 @@
|
|||
grant codeBase "file:${java.home}/lib/ext/localedata.jar" {
|
||||
// Allow resource bundles to be loaded for non root locales. See
|
||||
// https://github.com/elastic/elasticsearch/issues/39981
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.util.*";
|
||||
};
|
||||
grant {
|
||||
permission org.bouncycastle.crypto.CryptoServicesPermission "exportPrivateKey";
|
||||
permission org.bouncycastle.crypto.CryptoServicesPermission "exportSecretKey";
|
||||
permission java.lang.RuntimePermission "getProtectionDomain";
|
||||
permission java.util.PropertyPermission "java.runtime.name", "read";
|
||||
permission org.bouncycastle.crypto.CryptoServicesPermission "tlsAlgorithmsEnabled";
|
||||
//io.netty.handler.codec.DecoderException
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.sun.security.internal.spec";
|
||||
//java.security.InvalidAlgorithmParameterException: Cannot process GCMParameterSpec
|
||||
permission java.lang.RuntimePermission "accessDeclaredMembers";
|
||||
};
|
|
@ -0,0 +1,133 @@
|
|||
# List of providers and their preference orders (see above):
|
||||
security.provider.1=org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider
|
||||
security.provider.2=com.sun.net.ssl.internal.ssl.Provider BCFIPS
|
||||
security.provider.3=sun.security.provider.Sun
|
||||
security.provider.4=sun.security.jgss.SunProvider
|
||||
securerandom.source=file:/dev/urandom
|
||||
securerandom.strongAlgorithms=NativePRNGBlocking:SUN
|
||||
login.configuration.provider=sun.security.provider.ConfigFile
|
||||
policy.provider=sun.security.provider.PolicyFile
|
||||
policy.url.1=file:${java.home}/lib/security/java.policy
|
||||
policy.url.2=file:${user.home}/.java.policy
|
||||
policy.expandProperties=true
|
||||
policy.allowSystemProperty=true
|
||||
policy.ignoreIdentityScope=false
|
||||
keystore.type=bcfks
|
||||
keystore.type.compat=true
|
||||
package.access=sun.,\
|
||||
org.GNOME.Accessibility.,\
|
||||
com.sun.xml.internal.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.media.sound.,\
|
||||
com.sun.naming.internal.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.corba.se.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
com.sun.org.apache.regexp.internal.,\
|
||||
com.sun.org.apache.xerces.internal.,\
|
||||
com.sun.org.apache.xpath.internal.,\
|
||||
com.sun.org.apache.xalan.internal.extensions.,\
|
||||
com.sun.org.apache.xalan.internal.lib.,\
|
||||
com.sun.org.apache.xalan.internal.res.,\
|
||||
com.sun.org.apache.xalan.internal.templates.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.apache.xalan.internal.xslt.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.trax.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.util.,\
|
||||
com.sun.org.apache.xml.internal.res.,\
|
||||
com.sun.org.apache.xml.internal.resolver.helpers.,\
|
||||
com.sun.org.apache.xml.internal.resolver.readers.,\
|
||||
com.sun.org.apache.xml.internal.security.,\
|
||||
com.sun.org.apache.xml.internal.serializer.utils.,\
|
||||
com.sun.org.apache.xml.internal.utils.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
org.jcp.xml.dsig.internal.,\
|
||||
jdk.internal.,\
|
||||
jdk.nashorn.internal.,\
|
||||
jdk.nashorn.tools.,\
|
||||
jdk.xml.internal.,\
|
||||
com.sun.activation.registries.
|
||||
|
||||
package.definition=sun.,\
|
||||
com.sun.xml.internal.,\
|
||||
com.sun.imageio.,\
|
||||
com.sun.istack.internal.,\
|
||||
com.sun.jmx.,\
|
||||
com.sun.media.sound.,\
|
||||
com.sun.naming.internal.,\
|
||||
com.sun.proxy.,\
|
||||
com.sun.corba.se.,\
|
||||
com.sun.org.apache.bcel.internal.,\
|
||||
com.sun.org.apache.regexp.internal.,\
|
||||
com.sun.org.apache.xerces.internal.,\
|
||||
com.sun.org.apache.xpath.internal.,\
|
||||
com.sun.org.apache.xalan.internal.extensions.,\
|
||||
com.sun.org.apache.xalan.internal.lib.,\
|
||||
com.sun.org.apache.xalan.internal.res.,\
|
||||
com.sun.org.apache.xalan.internal.templates.,\
|
||||
com.sun.org.apache.xalan.internal.utils.,\
|
||||
com.sun.org.apache.xalan.internal.xslt.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.trax.,\
|
||||
com.sun.org.apache.xalan.internal.xsltc.util.,\
|
||||
com.sun.org.apache.xml.internal.res.,\
|
||||
com.sun.org.apache.xml.internal.resolver.helpers.,\
|
||||
com.sun.org.apache.xml.internal.resolver.readers.,\
|
||||
com.sun.org.apache.xml.internal.security.,\
|
||||
com.sun.org.apache.xml.internal.serializer.utils.,\
|
||||
com.sun.org.apache.xml.internal.utils.,\
|
||||
com.sun.org.glassfish.,\
|
||||
com.oracle.xmlns.internal.,\
|
||||
com.oracle.webservices.internal.,\
|
||||
oracle.jrockit.jfr.,\
|
||||
org.jcp.xml.dsig.internal.,\
|
||||
jdk.internal.,\
|
||||
jdk.nashorn.internal.,\
|
||||
jdk.nashorn.tools.,\
|
||||
jdk.xml.internal.,\
|
||||
com.sun.activation.registries.
|
||||
|
||||
ssl.KeyManagerFactory.algorithm=SunX509
|
||||
ssl.TrustManagerFactory.algorithm=PKIX
|
||||
networkaddress.cache.negative.ttl=10
|
||||
krb5.kdc.bad.policy = tryLast
|
||||
jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \
|
||||
RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
|
||||
|
||||
jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, DSA keySize < 1024
|
||||
|
||||
|
||||
jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 1024, \
|
||||
EC keySize < 224, DES40_CBC, RC4_40, 3DES_EDE_CBC
|
||||
|
||||
jdk.tls.legacyAlgorithms= \
|
||||
K_NULL, C_NULL, M_NULL, \
|
||||
DH_anon, ECDH_anon, \
|
||||
RC4_128, RC4_40, DES_CBC, DES40_CBC, \
|
||||
3DES_EDE_CBC
|
||||
crypto.policy=unlimited
|
||||
|
||||
jdk.xml.dsig.secureValidationPolicy=\
|
||||
disallowAlg http://www.w3.org/TR/1999/REC-xslt-19991116,\
|
||||
disallowAlg http://www.w3.org/2001/04/xmldsig-more#rsa-md5,\
|
||||
disallowAlg http://www.w3.org/2001/04/xmldsig-more#hmac-md5,\
|
||||
disallowAlg http://www.w3.org/2001/04/xmldsig-more#md5,\
|
||||
maxTransforms 5,\
|
||||
maxReferences 30,\
|
||||
disallowReferenceUriSchemes file http https,\
|
||||
minKeySize RSA 1024,\
|
||||
minKeySize DSA 1024,\
|
||||
minKeySize EC 224,\
|
||||
noDuplicateIds,\
|
||||
noRetrievalMethodLoops
|
||||
|
||||
jceks.key.serialFilter = java.lang.Enum;java.security.KeyRep;\
|
||||
java.security.KeyRep$Type;javax.crypto.spec.SecretKeySpec;!*
|
|
@ -81,6 +81,7 @@ public class RestClientBuilderIntegTests extends RestClientTestCase {
|
|||
}
|
||||
|
||||
public void testBuilderUsesDefaultSSLContext() throws Exception {
|
||||
assumeFalse("https://github.com/elastic/elasticsearch/issues/49094", inFipsJvm());
|
||||
final SSLContext defaultSSLContext = SSLContext.getDefault();
|
||||
try {
|
||||
try (RestClient client = buildRestClient()) {
|
||||
|
@ -109,7 +110,8 @@ public class RestClientBuilderIntegTests extends RestClientTestCase {
|
|||
|
||||
private static SSLContext getSslContext() throws Exception {
|
||||
SSLContext sslContext = SSLContext.getInstance(getProtocol());
|
||||
try (InputStream certFile = RestClientBuilderIntegTests.class.getResourceAsStream("/test.crt")) {
|
||||
try (InputStream certFile = RestClientBuilderIntegTests.class.getResourceAsStream("/test.crt");
|
||||
InputStream keyStoreFile = RestClientBuilderIntegTests.class.getResourceAsStream("/test_truststore.jks")) {
|
||||
// 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());
|
||||
|
@ -122,8 +124,10 @@ public class RestClientBuilderIntegTests extends RestClientTestCase {
|
|||
new Certificate[]{certFactory.generateCertificate(certFile)});
|
||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||
kmf.init(keyStore, "password".toCharArray());
|
||||
KeyStore trustStore = KeyStore.getInstance("JKS");
|
||||
trustStore.load(keyStoreFile, "password".toCharArray());
|
||||
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
tmf.init(keyStore);
|
||||
tmf.init(trustStore);
|
||||
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
|
||||
}
|
||||
return sslContext;
|
||||
|
|
Binary file not shown.
|
@ -108,4 +108,8 @@ public abstract class RestClientTestCase extends RandomizedTest {
|
|||
}
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
public static boolean inFipsJvm() {
|
||||
return Boolean.parseBoolean(System.getProperty("tests.fips.enabled"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.nio.file.Paths;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -85,10 +86,12 @@ final class JvmOptionsParser {
|
|||
Arrays.stream(environmentJvmOptions.split("\\s+")).filter(s -> s.trim().isEmpty() == false).collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
final List<String> substitutedJvmOptions = substitutePlaceholders(
|
||||
jvmOptions,
|
||||
Collections.singletonMap("ES_TMPDIR", System.getenv("ES_TMPDIR"))
|
||||
);
|
||||
final Map<String, String> substitutions = new HashMap<>();
|
||||
substitutions.put("ES_TMPDIR", System.getenv("ES_TMPDIR"));
|
||||
if (null != System.getenv("ES_PATH_CONF")) {
|
||||
substitutions.put("ES_PATH_CONF", System.getenv("ES_PATH_CONF"));
|
||||
}
|
||||
final List<String> substitutedJvmOptions = substitutePlaceholders(jvmOptions, Collections.unmodifiableMap(substitutions));
|
||||
final List<String> ergonomicJvmOptions = JvmErgonomics.choose(substitutedJvmOptions);
|
||||
final List<String> systemJvmOptions = SystemJvmOptions.systemJvmOptions();
|
||||
final List<String> finalJvmOptions = new ArrayList<>(
|
||||
|
|
|
@ -74,6 +74,10 @@ project.rootProject.subprojects.findAll { it.parent.path == ':plugins' }.each {
|
|||
if (subproj.path.startsWith(':plugins:repository-')) {
|
||||
return
|
||||
}
|
||||
// Do not install ingest-attachment in a FIPS 140 JVM as this is not supported
|
||||
if (subproj.path.startsWith(':plugins:ingest-attachment') && Boolean.parseBoolean(System.getProperty("tests.fips.enabled"))) {
|
||||
return
|
||||
}
|
||||
// FIXME
|
||||
subproj.afterEvaluate { // need to wait until the project has been configured
|
||||
testClusters.integTest {
|
||||
|
@ -92,6 +96,12 @@ buildRestTests.docs = fileTree(projectDir) {
|
|||
exclude 'README.asciidoc'
|
||||
// Broken code snippet tests
|
||||
exclude 'reference/graph/explore.asciidoc'
|
||||
if (Boolean.parseBoolean(System.getProperty("tests.fips.enabled"))) {
|
||||
// We don't install/support this plugin in FIPS 140
|
||||
exclude 'plugins/ingest-attachment.asciidoc'
|
||||
// We can't conditionally control output, this would be missing the ingest-attachment plugin
|
||||
exclude 'reference/cat/plugins.asciidoc'
|
||||
}
|
||||
}
|
||||
|
||||
listSnippets.docs = buildRestTests.docs
|
||||
|
|
|
@ -56,7 +56,7 @@ public class SslConfiguration {
|
|||
SSLContext.getInstance("TLSv1.3");
|
||||
protocolAlgorithmMap.put("TLSv1.3", "TLSv1.3");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// ignore since we support JVMs that do not support TLSv1.3
|
||||
// ignore since we support JVMs (and BC JSSE in FIPS mode) that do not support TLSv1.3
|
||||
}
|
||||
protocolAlgorithmMap.put("TLSv1.2", "TLSv1.2");
|
||||
protocolAlgorithmMap.put("TLSv1.1", "TLSv1.1");
|
||||
|
|
|
@ -117,6 +117,7 @@ public class ReindexRestClientSslTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testClientFailsWithUntrustedCertificate() throws IOException {
|
||||
assumeFalse("https://github.com/elastic/elasticsearch/issues/49094", inFipsJvm());
|
||||
final List<Thread> threads = new ArrayList<>();
|
||||
final Settings settings = Settings.builder()
|
||||
.put("path.home", createTempDir())
|
||||
|
|
|
@ -113,6 +113,7 @@ thirdPartyAudit {
|
|||
'org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder',
|
||||
'org.bouncycastle.jce.provider.BouncyCastleProvider',
|
||||
'org.bouncycastle.operator.jcajce.JcaContentSignerBuilder',
|
||||
'org.bouncycastle.asn1.x500.X500Name',
|
||||
|
||||
// from io.netty.handler.ssl.JettyNpnSslEngine (netty)
|
||||
'org.eclipse.jetty.npn.NextProtoNego$ClientProvider',
|
||||
|
@ -169,7 +170,6 @@ thirdPartyAudit {
|
|||
'org.eclipse.jetty.alpn.ALPN$ServerProvider',
|
||||
'org.eclipse.jetty.alpn.ALPN',
|
||||
|
||||
|
||||
'org.conscrypt.AllocatedBuffer',
|
||||
'org.conscrypt.BufferAllocator',
|
||||
'org.conscrypt.Conscrypt',
|
||||
|
@ -197,12 +197,10 @@ thirdPartyAudit {
|
|||
)
|
||||
}
|
||||
|
||||
rootProject.globalInfo.ready {
|
||||
if (BuildParams.inFipsJvm == false) {
|
||||
// BouncyCastleFIPS provides this class, so the exclusion is invalid when running CI in
|
||||
// a FIPS JVM with BouncyCastleFIPS Provider
|
||||
thirdPartyAudit.ignoreMissingClasses(
|
||||
'org.bouncycastle.asn1.x500.X500Name'
|
||||
)
|
||||
}
|
||||
if (BuildParams.inFipsJvm == false) {
|
||||
// BouncyCastleFIPS provides this class, so the exclusion is invalid when running CI in
|
||||
// a FIPS JVM with BouncyCastleFIPS Provider
|
||||
thirdPartyAudit.ignoreMissingClasses(
|
||||
'org.bouncycastle.asn1.x500.X500Name'
|
||||
)
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ thirdPartyAudit {
|
|||
}
|
||||
|
||||
thirdPartyAudit.onlyIf {
|
||||
// FIPS JVM includes manny classes from bouncycastle which count as jar hell for the third party audit,
|
||||
// FIPS JVM includes many classes from bouncycastle which count as jar hell for the third party audit,
|
||||
// rather than provide a long list of exclusions, disable the check on FIPS.
|
||||
BuildParams.inFipsJvm == false
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ thirdPartyAudit {
|
|||
'org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder',
|
||||
'org.bouncycastle.jce.provider.BouncyCastleProvider',
|
||||
'org.bouncycastle.operator.jcajce.JcaContentSignerBuilder',
|
||||
'org.bouncycastle.asn1.x500.X500Name',
|
||||
|
||||
// from io.netty.handler.ssl.JettyNpnSslEngine (netty)
|
||||
'org.eclipse.jetty.npn.NextProtoNego$ClientProvider',
|
||||
|
@ -155,12 +156,12 @@ thirdPartyAudit {
|
|||
'io.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator'
|
||||
)
|
||||
}
|
||||
rootProject.globalInfo.ready {
|
||||
if (BuildParams.inFipsJvm == false) {
|
||||
// BouncyCastleFIPS provides this class, so the exclusion is invalid when running CI in
|
||||
// a FIPS JVM with BouncyCastleFIPS Provider
|
||||
thirdPartyAudit.ignoreMissingClasses(
|
||||
'org.bouncycastle.asn1.x500.X500Name'
|
||||
)
|
||||
}
|
||||
|
||||
if (BuildParams.inFipsJvm == false) {
|
||||
// BouncyCastleFIPS provides this class, so the exclusion is invalid when running CI in
|
||||
// a FIPS JVM with BouncyCastleFIPS Provider
|
||||
thirdPartyAudit.ignoreMissingClasses(
|
||||
'org.bouncycastle.asn1.x500.X500Name'
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -158,7 +158,6 @@ import java.net.InetSocketAddress;
|
|||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.Security;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
@ -2253,6 +2252,6 @@ public abstract class ESIntegTestCase extends ESTestCase {
|
|||
}
|
||||
|
||||
public static boolean inFipsJvm() {
|
||||
return Security.getProviders()[0].getName().toLowerCase(Locale.ROOT).contains("fips");
|
||||
return Boolean.parseBoolean(System.getProperty(FIPS_SYSPROP));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,7 +119,6 @@ import org.junit.rules.RuleChain;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.security.Security;
|
||||
import java.time.ZoneId;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -193,6 +192,8 @@ public abstract class ESTestCase extends LuceneTestCase {
|
|||
|
||||
public static final String DEFAULT_TEST_WORKER_ID = "--not-gradle--";
|
||||
|
||||
public static final String FIPS_SYSPROP = "tests.fips.enabled";
|
||||
|
||||
static {
|
||||
TEST_WORKER_VM_ID = System.getProperty(TEST_WORKER_SYS_PROPERTY, DEFAULT_TEST_WORKER_ID);
|
||||
setTestSysProps();
|
||||
|
@ -1366,7 +1367,7 @@ public abstract class ESTestCase extends LuceneTestCase {
|
|||
}
|
||||
|
||||
public static boolean inFipsJvm() {
|
||||
return Security.getProviders()[0].getName().toLowerCase(Locale.ROOT).contains("fips");
|
||||
return Boolean.parseBoolean(System.getProperty(FIPS_SYSPROP));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -174,8 +174,7 @@ public class ReproduceInfoPrinter extends RunListener {
|
|||
appendOpt("tests.distribution", System.getProperty("tests.distribution"));
|
||||
appendOpt("compiler.java", System.getProperty("compiler.java"));
|
||||
appendOpt("runtime.java", System.getProperty("runtime.java"));
|
||||
appendOpt("javax.net.ssl.keyStorePassword", System.getProperty("javax.net.ssl.keyStorePassword"));
|
||||
appendOpt("javax.net.ssl.trustStorePassword", System.getProperty("javax.net.ssl.trustStorePassword"));
|
||||
appendOpt(ESTestCase.FIPS_SYSPROP, System.getProperty(ESTestCase.FIPS_SYSPROP));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.elasticsearch.common.Nullable;
|
|||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.xpack.core.ssl.cert.CertificateInfo;
|
||||
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.X509ExtendedKeyManager;
|
||||
import javax.net.ssl.X509ExtendedTrustManager;
|
||||
|
||||
|
@ -17,7 +18,12 @@ import java.io.IOException;
|
|||
import java.nio.file.AccessDeniedException;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -27,7 +33,15 @@ abstract class KeyConfig extends TrustConfig {
|
|||
static final KeyConfig NONE = new KeyConfig() {
|
||||
@Override
|
||||
X509ExtendedKeyManager createKeyManager(@Nullable Environment environment) {
|
||||
return null;
|
||||
try {
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
keyStore.load(null, null);
|
||||
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||
keyManagerFactory.init(keyStore, null);
|
||||
return (X509ExtendedKeyManager) keyManagerFactory.getKeyManagers()[0];
|
||||
} catch (IOException | CertificateException | NoSuchAlgorithmException | UnrecoverableKeyException | KeyStoreException e) {
|
||||
throw new ElasticsearchException("failed to initialize SSL KeyManager", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.elasticsearch.xpack.core.ssl.cert.CertificateInfo;
|
|||
import org.elasticsearch.xpack.core.watcher.WatcherField;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.SSLException;
|
||||
|
@ -39,7 +38,6 @@ import javax.net.ssl.SSLSession;
|
|||
import javax.net.ssl.SSLSessionContext;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.X509ExtendedKeyManager;
|
||||
import javax.net.ssl.X509ExtendedTrustManager;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
@ -48,7 +46,6 @@ import java.net.InetAddress;
|
|||
import java.net.Socket;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
@ -698,10 +695,8 @@ public class SSLService {
|
|||
|
||||
private void reloadSslContext() {
|
||||
try {
|
||||
X509ExtendedKeyManager loadedKeyManager = Optional.ofNullable(keyConfig.createKeyManager(env)).
|
||||
orElse(getEmptyKeyManager());
|
||||
X509ExtendedTrustManager loadedTrustManager = Optional.ofNullable(trustConfig.createTrustManager(env)).
|
||||
orElse(getEmptyTrustManager());
|
||||
X509ExtendedKeyManager loadedKeyManager = keyConfig.createKeyManager(env);
|
||||
X509ExtendedTrustManager loadedTrustManager = trustConfig.createTrustManager(env);
|
||||
loadedTrustManager = wrapWithDiagnostics(loadedTrustManager, sslConfiguration);
|
||||
|
||||
SSLContext loadedSslContext = SSLContext.getInstance(sslContextAlgorithm(sslConfiguration.supportedProtocols()));
|
||||
|
@ -709,27 +704,11 @@ public class SSLService {
|
|||
new X509ExtendedTrustManager[]{loadedTrustManager}, null);
|
||||
supportedCiphers(loadedSslContext.getSupportedSSLParameters().getCipherSuites(), sslConfiguration.cipherSuites(), false);
|
||||
this.context = loadedSslContext;
|
||||
} catch (GeneralSecurityException | IOException e) {
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new ElasticsearchException("failed to initialize the SSLContext", e);
|
||||
}
|
||||
}
|
||||
|
||||
X509ExtendedKeyManager getEmptyKeyManager() throws GeneralSecurityException, IOException {
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
keyStore.load(null, null);
|
||||
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||
keyManagerFactory.init(keyStore, null);
|
||||
return (X509ExtendedKeyManager) keyManagerFactory.getKeyManagers()[0];
|
||||
}
|
||||
|
||||
X509ExtendedTrustManager getEmptyTrustManager() throws GeneralSecurityException, IOException {
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
keyStore.load(null, null);
|
||||
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("X509");
|
||||
trustManagerFactory.init(keyStore);
|
||||
return (X509ExtendedTrustManager) trustManagerFactory.getTrustManagers()[0];
|
||||
}
|
||||
|
||||
public void addReloadListener(Runnable listener) {
|
||||
this.reloadListeners.add(listener);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
package org.elasticsearch.xpack.core.ssl;
|
||||
|
||||
import org.elasticsearch.bootstrap.JavaVersion;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.TypeSafeMatcher;
|
||||
|
@ -33,6 +34,8 @@ import java.util.Objects;
|
|||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.elasticsearch.test.ESIntegTestCase.inFipsJvm;
|
||||
|
||||
public class RestrictedTrustManagerTests extends ESTestCase {
|
||||
|
||||
private X509ExtendedTrustManager baseTrustManager;
|
||||
|
@ -132,7 +135,9 @@ public class RestrictedTrustManagerTests extends ESTestCase {
|
|||
if (cert.endsWith("/ca")) {
|
||||
assertTrusted(trustManager, cert);
|
||||
} else {
|
||||
assertNotValid(trustManager, cert, "PKIX path building failed.*");
|
||||
assertNotValid(trustManager, cert, inFipsJvm() && JavaVersion.current().compareTo(JavaVersion.parse("8")) > 0 ?
|
||||
"unable to process certificates: Unable to find certificate chain.":
|
||||
"PKIX path building failed.*");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,15 +154,16 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
|
|||
* Tests the reloading of SSLContext when a PEM key and certificate are used.
|
||||
*/
|
||||
public void testPEMKeyConfigReloading() throws Exception {
|
||||
assumeFalse("https://github.com/elastic/elasticsearch/issues/49094", inFipsJvm());
|
||||
Path tempDir = createTempDir();
|
||||
Path keyPath = tempDir.resolve("testnode.pem");
|
||||
Path updatedKeyPath = tempDir.resolve("testnode_updated.pem");
|
||||
Path certPath = tempDir.resolve("testnode.crt");
|
||||
Path updatedKeyPath = tempDir.resolve("testnode_updated.pem");
|
||||
Path updatedCertPath = tempDir.resolve("testnode_updated.crt");
|
||||
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem"), keyPath);
|
||||
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"), certPath);
|
||||
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.pem"), updatedKeyPath);
|
||||
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.crt"), updatedCertPath);
|
||||
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"), certPath);
|
||||
MockSecureSettings secureSettings = new MockSecureSettings();
|
||||
secureSettings.setString("xpack.security.transport.ssl.secure_key_passphrase", "testnode");
|
||||
final Settings settings = Settings.builder()
|
||||
|
@ -267,15 +268,14 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
|
|||
* Test the reloading of SSLContext whose trust config is backed by PEM certificate files.
|
||||
*/
|
||||
public void testReloadingPEMTrustConfig() throws Exception {
|
||||
assumeFalse("https://github.com/elastic/elasticsearch/issues/49094", inFipsJvm());
|
||||
Path tempDir = createTempDir();
|
||||
Path serverCertPath = tempDir.resolve("testnode.crt");
|
||||
Path serverKeyPath = tempDir.resolve("testnode.pem");
|
||||
Path updatedCert = tempDir.resolve("updated.crt");
|
||||
//Our keystore contains two Certificates it can present. One build from the RSA keypair and one build from the EC keypair. EC is
|
||||
// used since it keyManager presents the first one in alias alphabetical order (and testnode_ec comes before testnode_rsa)
|
||||
Path updatedCertPath = tempDir.resolve("updated.crt");
|
||||
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"), serverCertPath);
|
||||
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem"), serverKeyPath);
|
||||
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.crt"), updatedCert);
|
||||
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.crt"), updatedCertPath);
|
||||
Settings settings = baseKeystoreSettings(tempDir, null)
|
||||
.put("xpack.security.transport.ssl.enabled", true)
|
||||
.putList("xpack.security.transport.ssl.certificate_authorities", serverCertPath.toString())
|
||||
|
@ -294,7 +294,7 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
|
|||
|
||||
final Runnable modifier = () -> {
|
||||
try {
|
||||
atomicMoveIfPossible(updatedCert, serverCertPath);
|
||||
atomicMoveIfPossible(updatedCertPath, serverCertPath);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("failed to modify file", e);
|
||||
}
|
||||
|
|
|
@ -65,7 +65,6 @@ import static org.elasticsearch.test.TestMatchers.throwableWithMessage;
|
|||
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.emptyArray;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
|
@ -504,14 +503,6 @@ public class SSLServiceTests extends ESTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testEmptyTrustManager() throws Exception {
|
||||
Settings settings = Settings.EMPTY;
|
||||
final SSLService sslService = new SSLService(settings, env);
|
||||
X509ExtendedTrustManager trustManager = sslService.sslContextHolder(sslService.getSSLConfiguration("xpack.security.transport.ssl"))
|
||||
.getEmptyTrustManager();
|
||||
assertThat(trustManager.getAcceptedIssuers(), emptyArray());
|
||||
}
|
||||
|
||||
public void testGetConfigurationByContextName() throws Exception {
|
||||
assumeFalse("Can't run in a FIPS JVM, JKS keystores can't be used", inFipsJvm());
|
||||
final SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
|
||||
|
@ -587,11 +578,12 @@ public class SSLServiceTests extends ESTestCase {
|
|||
|
||||
final SSLService sslService = new SSLService(settings, env);
|
||||
final List<CertificateInfo> certificates = new ArrayList<>(sslService.getLoadedCertificates());
|
||||
assertThat(certificates, iterableWithSize(10));
|
||||
assertThat(certificates, iterableWithSize(13));
|
||||
Collections.sort(certificates,
|
||||
Comparator.comparing((CertificateInfo c) -> c.alias() == null ? "" : c.alias()).thenComparing(CertificateInfo::path));
|
||||
|
||||
final Iterator<CertificateInfo> iterator = certificates.iterator();
|
||||
|
||||
CertificateInfo cert = iterator.next();
|
||||
assertThat(cert.alias(), nullValue());
|
||||
assertThat(cert.path(), equalTo(pemPath.toString()));
|
||||
|
@ -655,6 +647,15 @@ public class SSLServiceTests extends ESTestCase {
|
|||
assertThat(cert.expiry(), equalTo(ZonedDateTime.parse("2045-10-02T09:43:18.000Z")));
|
||||
assertThat(cert.hasPrivateKey(), equalTo(true));
|
||||
|
||||
cert = iterator.next();
|
||||
assertThat(cert.alias(), equalTo("testnode_dsa"));
|
||||
assertThat(cert.path(), equalTo(p12Path.toString()));
|
||||
assertThat(cert.format(), equalTo("PKCS12"));
|
||||
assertThat(cert.serialNumber(), equalTo("223c736a"));
|
||||
assertThat(cert.subjectDn(), equalTo("CN=Elasticsearch Test Node"));
|
||||
assertThat(cert.expiry(), equalTo(ZonedDateTime.parse("2045-10-02T09:43:18.000Z")));
|
||||
assertThat(cert.hasPrivateKey(), equalTo(true));
|
||||
|
||||
cert = iterator.next();
|
||||
assertThat(cert.alias(), equalTo("testnode_ec"));
|
||||
assertThat(cert.path(), equalTo(jksPath.toString()));
|
||||
|
@ -664,6 +665,15 @@ public class SSLServiceTests extends ESTestCase {
|
|||
assertThat(cert.expiry(), equalTo(ZonedDateTime.parse("2045-10-02T09:36:10.000Z")));
|
||||
assertThat(cert.hasPrivateKey(), equalTo(true));
|
||||
|
||||
cert = iterator.next();
|
||||
assertThat(cert.alias(), equalTo("testnode_ec"));
|
||||
assertThat(cert.path(), equalTo(p12Path.toString()));
|
||||
assertThat(cert.format(), equalTo("PKCS12"));
|
||||
assertThat(cert.serialNumber(), equalTo("7268203b"));
|
||||
assertThat(cert.subjectDn(), equalTo("CN=Elasticsearch Test Node"));
|
||||
assertThat(cert.expiry(), equalTo(ZonedDateTime.parse("2045-10-02T09:36:10.000Z")));
|
||||
assertThat(cert.hasPrivateKey(), equalTo(true));
|
||||
|
||||
cert = iterator.next();
|
||||
assertThat(cert.alias(), equalTo("testnode_rsa"));
|
||||
assertThat(cert.path(), equalTo(jksPath.toString()));
|
||||
|
@ -679,9 +689,18 @@ public class SSLServiceTests extends ESTestCase {
|
|||
assertThat(cert.format(), equalTo("PKCS12"));
|
||||
assertThat(cert.serialNumber(), equalTo("b8b96c37e332cccb"));
|
||||
assertThat(cert.subjectDn(), equalTo("CN=Elasticsearch Test Node, OU=elasticsearch, O=org"));
|
||||
assertThat(cert.expiry(), equalTo(ZonedDateTime.parse("2019-09-22T18:52:57Z")));
|
||||
assertThat(cert.expiry(), equalTo(ZonedDateTime.parse("2019-09-22T18:52:57.000Z")));
|
||||
assertThat(cert.hasPrivateKey(), equalTo(true));
|
||||
|
||||
cert = iterator.next();
|
||||
assertThat(cert.alias(), equalTo("trusted_testnode_ec"));
|
||||
assertThat(cert.path(), equalTo(jksPath.toString()));
|
||||
assertThat(cert.format(), equalTo("jks"));
|
||||
assertThat(cert.serialNumber(), equalTo("7268203b"));
|
||||
assertThat(cert.subjectDn(), equalTo("CN=Elasticsearch Test Node"));
|
||||
assertThat(cert.expiry(), equalTo(ZonedDateTime.parse("2045-10-02T09:36:10.000Z")));
|
||||
assertThat(cert.hasPrivateKey(), equalTo(false));
|
||||
|
||||
assertFalse(iterator.hasNext());
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -24,9 +24,7 @@ dependencies {
|
|||
|
||||
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
|
||||
|
||||
compile 'com.unboundid:unboundid-ldapsdk:4.0.8'
|
||||
compileOnly 'org.bouncycastle:bcprov-jdk15on:1.59'
|
||||
compileOnly 'org.bouncycastle:bcpkix-jdk15on:1.59'
|
||||
compile 'com.unboundid:unboundid-ldapsdk:4.0.8'
|
||||
|
||||
// the following are all SAML dependencies - might as well download the whole internet
|
||||
compile "org.opensaml:opensaml-core:3.4.5"
|
||||
|
@ -47,7 +45,9 @@ dependencies {
|
|||
compile "net.shibboleth.utilities:java-support:7.5.1"
|
||||
compile "org.apache.santuario:xmlsec:2.1.4"
|
||||
compile "io.dropwizard.metrics:metrics-core:3.2.2"
|
||||
compile "org.cryptacular:cryptacular:1.2.3"
|
||||
compile ("org.cryptacular:cryptacular:1.2.3") {
|
||||
exclude group: 'org.bouncycastle'
|
||||
}
|
||||
compile "org.slf4j:slf4j-api:${versions.slf4j}"
|
||||
compile "org.apache.logging.log4j:log4j-slf4j-impl:${versions.log4j}"
|
||||
compile "org.apache.httpcomponents:httpclient:${versions.httpclient}"
|
||||
|
@ -178,107 +178,269 @@ forbiddenApisMain {
|
|||
|
||||
// classes are missing, e.g. com.ibm.icu.lang.UCharacter
|
||||
thirdPartyAudit {
|
||||
ignoreMissingClasses (
|
||||
// SAML dependencies
|
||||
// [missing classes] Some cli utilities that we don't use depend on these missing JCommander classes
|
||||
'com.beust.jcommander.JCommander',
|
||||
'com.beust.jcommander.converters.BaseConverter',
|
||||
// [missing classes] Shibboleth + OpenSAML have servlet support that we don't use
|
||||
'javax.servlet.AsyncContext',
|
||||
'javax.servlet.DispatcherType',
|
||||
'javax.servlet.Filter',
|
||||
'javax.servlet.FilterChain',
|
||||
'javax.servlet.FilterConfig',
|
||||
'javax.servlet.RequestDispatcher',
|
||||
'javax.servlet.ServletContext',
|
||||
'javax.servlet.ServletException',
|
||||
'javax.servlet.ServletInputStream',
|
||||
'javax.servlet.ServletOutputStream',
|
||||
'javax.servlet.ServletRequest',
|
||||
'javax.servlet.ServletResponse',
|
||||
'javax.servlet.http.Cookie',
|
||||
'javax.servlet.http.HttpServletRequest',
|
||||
'javax.servlet.http.HttpServletResponse',
|
||||
'javax.servlet.http.HttpServletResponseWrapper',
|
||||
'javax.servlet.http.HttpSession',
|
||||
'javax.servlet.http.Part',
|
||||
// [missing classes] Shibboleth + OpenSAML have velocity support that we don't use
|
||||
'org.apache.velocity.VelocityContext',
|
||||
'org.apache.velocity.app.VelocityEngine',
|
||||
'org.apache.velocity.context.Context',
|
||||
'org.apache.velocity.exception.VelocityException',
|
||||
'org.apache.velocity.runtime.RuntimeServices',
|
||||
'org.apache.velocity.runtime.log.LogChute',
|
||||
'org.apache.velocity.runtime.resource.loader.StringResourceLoader',
|
||||
'org.apache.velocity.runtime.resource.util.StringResourceRepository',
|
||||
// [missing classes] OpenSAML depends on Apache XML security which depends on Xalan, but only for functionality that OpenSAML doesn't use
|
||||
'org.apache.xml.dtm.DTM',
|
||||
'org.apache.xml.utils.PrefixResolver',
|
||||
'org.apache.xml.utils.PrefixResolverDefault',
|
||||
'org.apache.xpath.Expression',
|
||||
'org.apache.xpath.NodeSetDTM',
|
||||
'org.apache.xpath.XPath',
|
||||
'org.apache.xpath.XPathContext',
|
||||
'org.apache.xpath.compiler.FunctionTable',
|
||||
'org.apache.xpath.functions.Function',
|
||||
'org.apache.xpath.objects.XNodeSet',
|
||||
'org.apache.xpath.objects.XObject',
|
||||
// [missing classes] OpenSAML storage has an optional LDAP storage impl
|
||||
'org.ldaptive.AttributeModification',
|
||||
'org.ldaptive.AttributeModificationType',
|
||||
'org.ldaptive.Connection',
|
||||
'org.ldaptive.DeleteOperation',
|
||||
'org.ldaptive.DeleteRequest',
|
||||
'org.ldaptive.LdapAttribute',
|
||||
'org.ldaptive.LdapEntry',
|
||||
'org.ldaptive.LdapException',
|
||||
'org.ldaptive.ModifyOperation',
|
||||
'org.ldaptive.ModifyRequest',
|
||||
'org.ldaptive.Response',
|
||||
'org.ldaptive.ResultCode',
|
||||
'org.ldaptive.SearchOperation',
|
||||
'org.ldaptive.SearchRequest',
|
||||
'org.ldaptive.SearchResult',
|
||||
'org.ldaptive.ext.MergeOperation',
|
||||
'org.ldaptive.ext.MergeRequest',
|
||||
'org.ldaptive.pool.ConnectionPool',
|
||||
'org.ldaptive.pool.PooledConnectionFactory',
|
||||
// [missing classes] OpenSAML storage has an optional JSON-backed storage impl
|
||||
'javax.json.Json',
|
||||
'javax.json.JsonException',
|
||||
'javax.json.JsonNumber',
|
||||
'javax.json.JsonObject',
|
||||
'javax.json.JsonReader',
|
||||
'javax.json.JsonValue$ValueType',
|
||||
'javax.json.JsonValue',
|
||||
'javax.json.stream.JsonGenerator',
|
||||
// [missing classes] OpenSAML storage has an optional JPA storage impl
|
||||
'javax.persistence.EntityManager',
|
||||
'javax.persistence.EntityManagerFactory',
|
||||
'javax.persistence.EntityTransaction',
|
||||
'javax.persistence.LockModeType',
|
||||
'javax.persistence.Query',
|
||||
// [missing classes] OpenSAML storage and HttpClient cache have optional memcache support
|
||||
'net.spy.memcached.CASResponse',
|
||||
'net.spy.memcached.CASValue',
|
||||
'net.spy.memcached.MemcachedClient',
|
||||
'net.spy.memcached.MemcachedClientIF',
|
||||
'net.spy.memcached.CachedData',
|
||||
'net.spy.memcached.internal.OperationFuture',
|
||||
'net.spy.memcached.transcoders.Transcoder',
|
||||
// [missing classes] Http Client cache has optional ehcache support
|
||||
'net.sf.ehcache.Ehcache',
|
||||
'net.sf.ehcache.Element',
|
||||
// [missing classes] SLF4j includes an optional class that depends on an extension class (!)
|
||||
'org.slf4j.ext.EventData',
|
||||
// Optional dependency of oauth2-oidc-sdk that we don't need since we do not support AES-SIV for JWE
|
||||
'org.cryptomator.siv.SivMode',
|
||||
// Optional dependency of nimbus-jose-jwt for handling Ed25519 signatures and ECDH with X25519 (RFC 8037)
|
||||
'com.google.crypto.tink.subtle.Ed25519Sign',
|
||||
'com.google.crypto.tink.subtle.Ed25519Sign$KeyPair',
|
||||
'com.google.crypto.tink.subtle.Ed25519Verify',
|
||||
'com.google.crypto.tink.subtle.X25519'
|
||||
)
|
||||
ignoreMissingClasses (
|
||||
// SAML dependencies
|
||||
// [missing classes] Some cli utilities that we don't use depend on these missing JCommander classes
|
||||
'com.beust.jcommander.JCommander',
|
||||
'com.beust.jcommander.converters.BaseConverter',
|
||||
// [missing classes] Shibboleth + OpenSAML have servlet support that we don't use
|
||||
'javax.servlet.AsyncContext',
|
||||
'javax.servlet.DispatcherType',
|
||||
'javax.servlet.Filter',
|
||||
'javax.servlet.FilterChain',
|
||||
'javax.servlet.FilterConfig',
|
||||
'javax.servlet.RequestDispatcher',
|
||||
'javax.servlet.ServletContext',
|
||||
'javax.servlet.ServletException',
|
||||
'javax.servlet.ServletInputStream',
|
||||
'javax.servlet.ServletOutputStream',
|
||||
'javax.servlet.ServletRequest',
|
||||
'javax.servlet.ServletResponse',
|
||||
'javax.servlet.http.Cookie',
|
||||
'javax.servlet.http.HttpServletRequest',
|
||||
'javax.servlet.http.HttpServletResponse',
|
||||
'javax.servlet.http.HttpServletResponseWrapper',
|
||||
'javax.servlet.http.HttpSession',
|
||||
'javax.servlet.http.Part',
|
||||
// [missing classes] Shibboleth + OpenSAML have velocity support that we don't use
|
||||
'org.apache.velocity.VelocityContext',
|
||||
'org.apache.velocity.app.VelocityEngine',
|
||||
'org.apache.velocity.context.Context',
|
||||
'org.apache.velocity.exception.VelocityException',
|
||||
'org.apache.velocity.runtime.RuntimeServices',
|
||||
'org.apache.velocity.runtime.log.LogChute',
|
||||
'org.apache.velocity.runtime.resource.loader.StringResourceLoader',
|
||||
'org.apache.velocity.runtime.resource.util.StringResourceRepository',
|
||||
// [missing classes] OpenSAML depends on Apache XML security which depends on Xalan, but only for functionality that OpenSAML doesn't use
|
||||
'org.apache.xml.dtm.DTM',
|
||||
'org.apache.xml.utils.PrefixResolver',
|
||||
'org.apache.xml.utils.PrefixResolverDefault',
|
||||
'org.apache.xpath.Expression',
|
||||
'org.apache.xpath.NodeSetDTM',
|
||||
'org.apache.xpath.XPath',
|
||||
'org.apache.xpath.XPathContext',
|
||||
'org.apache.xpath.compiler.FunctionTable',
|
||||
'org.apache.xpath.functions.Function',
|
||||
'org.apache.xpath.objects.XNodeSet',
|
||||
'org.apache.xpath.objects.XObject',
|
||||
// [missing classes] OpenSAML storage has an optional LDAP storage impl
|
||||
'org.ldaptive.AttributeModification',
|
||||
'org.ldaptive.AttributeModificationType',
|
||||
'org.ldaptive.Connection',
|
||||
'org.ldaptive.DeleteOperation',
|
||||
'org.ldaptive.DeleteRequest',
|
||||
'org.ldaptive.LdapAttribute',
|
||||
'org.ldaptive.LdapEntry',
|
||||
'org.ldaptive.LdapException',
|
||||
'org.ldaptive.ModifyOperation',
|
||||
'org.ldaptive.ModifyRequest',
|
||||
'org.ldaptive.Response',
|
||||
'org.ldaptive.ResultCode',
|
||||
'org.ldaptive.SearchOperation',
|
||||
'org.ldaptive.SearchRequest',
|
||||
'org.ldaptive.SearchResult',
|
||||
'org.ldaptive.ext.MergeOperation',
|
||||
'org.ldaptive.ext.MergeRequest',
|
||||
'org.ldaptive.pool.ConnectionPool',
|
||||
'org.ldaptive.pool.PooledConnectionFactory',
|
||||
// [missing classes] OpenSAML storage has an optional JSON-backed storage impl
|
||||
'javax.json.Json',
|
||||
'javax.json.JsonException',
|
||||
'javax.json.JsonNumber',
|
||||
'javax.json.JsonObject',
|
||||
'javax.json.JsonReader',
|
||||
'javax.json.JsonValue$ValueType',
|
||||
'javax.json.JsonValue',
|
||||
'javax.json.stream.JsonGenerator',
|
||||
// [missing classes] OpenSAML storage has an optional JPA storage impl
|
||||
'javax.persistence.EntityManager',
|
||||
'javax.persistence.EntityManagerFactory',
|
||||
'javax.persistence.EntityTransaction',
|
||||
'javax.persistence.LockModeType',
|
||||
'javax.persistence.Query',
|
||||
// [missing classes] OpenSAML storage and HttpClient cache have optional memcache support
|
||||
'net.spy.memcached.CASResponse',
|
||||
'net.spy.memcached.CASValue',
|
||||
'net.spy.memcached.MemcachedClient',
|
||||
'net.spy.memcached.MemcachedClientIF',
|
||||
'net.spy.memcached.CachedData',
|
||||
'net.spy.memcached.internal.OperationFuture',
|
||||
'net.spy.memcached.transcoders.Transcoder',
|
||||
// [missing classes] Http Client cache has optional ehcache support
|
||||
'net.sf.ehcache.Ehcache',
|
||||
'net.sf.ehcache.Element',
|
||||
// [missing classes] SLF4j includes an optional class that depends on an extension class (!)
|
||||
'org.slf4j.ext.EventData',
|
||||
// Optional dependency of oauth2-oidc-sdk that we don't need since we do not support AES-SIV for JWE
|
||||
'org.cryptomator.siv.SivMode',
|
||||
// Optional dependency of nimbus-jose-jwt for handling Ed25519 signatures and ECDH with X25519 (RFC 8037)
|
||||
'com.google.crypto.tink.subtle.Ed25519Sign',
|
||||
'com.google.crypto.tink.subtle.Ed25519Sign$KeyPair',
|
||||
'com.google.crypto.tink.subtle.Ed25519Verify',
|
||||
'com.google.crypto.tink.subtle.X25519',
|
||||
// Bouncycastle is an optional dependency for apache directory, cryptacular and opensaml packages. We
|
||||
// acknowledge them here instead of adding bouncy castle as a compileOnly dependency
|
||||
'org.bouncycastle.asn1.ASN1Encodable',
|
||||
'org.bouncycastle.asn1.ASN1InputStream',
|
||||
'org.bouncycastle.asn1.ASN1Integer',
|
||||
'org.bouncycastle.asn1.ASN1ObjectIdentifier',
|
||||
'org.bouncycastle.asn1.ASN1OctetString',
|
||||
'org.bouncycastle.asn1.ASN1Primitive',
|
||||
'org.bouncycastle.asn1.ASN1Sequence',
|
||||
'org.bouncycastle.asn1.ASN1TaggedObject',
|
||||
'org.bouncycastle.asn1.DEROctetString',
|
||||
'org.bouncycastle.asn1.DERSequence',
|
||||
'org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo',
|
||||
'org.bouncycastle.asn1.pkcs.EncryptionScheme',
|
||||
'org.bouncycastle.asn1.pkcs.KeyDerivationFunc',
|
||||
'org.bouncycastle.asn1.pkcs.PBEParameter',
|
||||
'org.bouncycastle.asn1.pkcs.PBES2Parameters',
|
||||
'org.bouncycastle.asn1.pkcs.PBKDF2Params',
|
||||
'org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers',
|
||||
'org.bouncycastle.asn1.pkcs.PrivateKeyInfo',
|
||||
'org.bouncycastle.asn1.x500.AttributeTypeAndValue',
|
||||
'org.bouncycastle.asn1.x500.RDN',
|
||||
'org.bouncycastle.asn1.x500.X500Name',
|
||||
'org.bouncycastle.asn1.x509.AccessDescription',
|
||||
'org.bouncycastle.asn1.x509.AlgorithmIdentifier',
|
||||
'org.bouncycastle.asn1.x509.AuthorityKeyIdentifier',
|
||||
'org.bouncycastle.asn1.x509.BasicConstraints',
|
||||
'org.bouncycastle.asn1.x509.DistributionPoint',
|
||||
'org.bouncycastle.asn1.x509.Extension',
|
||||
'org.bouncycastle.asn1.x509.GeneralName',
|
||||
'org.bouncycastle.asn1.x509.GeneralNames',
|
||||
'org.bouncycastle.asn1.x509.GeneralNamesBuilder',
|
||||
'org.bouncycastle.asn1.x509.KeyPurposeId',
|
||||
'org.bouncycastle.asn1.x509.KeyUsage',
|
||||
'org.bouncycastle.asn1.x509.PolicyInformation',
|
||||
'org.bouncycastle.asn1.x509.SubjectKeyIdentifier',
|
||||
'org.bouncycastle.asn1.x509.SubjectPublicKeyInfo',
|
||||
'org.bouncycastle.asn1.x9.X9ECParameters',
|
||||
'org.bouncycastle.cert.X509v3CertificateBuilder',
|
||||
'org.bouncycastle.cert.jcajce.JcaX509CertificateConverter',
|
||||
'org.bouncycastle.cert.jcajce.JcaX509CertificateHolder',
|
||||
'org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils',
|
||||
'org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder',
|
||||
'org.bouncycastle.crypto.BlockCipher',
|
||||
'org.bouncycastle.crypto.BufferedBlockCipher',
|
||||
'org.bouncycastle.crypto.CipherParameters',
|
||||
'org.bouncycastle.crypto.Digest',
|
||||
'org.bouncycastle.crypto.InvalidCipherTextException',
|
||||
'org.bouncycastle.crypto.PBEParametersGenerator',
|
||||
'org.bouncycastle.crypto.StreamCipher',
|
||||
'org.bouncycastle.crypto.digests.GOST3411Digest',
|
||||
'org.bouncycastle.crypto.digests.MD2Digest',
|
||||
'org.bouncycastle.crypto.digests.MD4Digest',
|
||||
'org.bouncycastle.crypto.digests.MD5Digest',
|
||||
'org.bouncycastle.crypto.digests.RIPEMD128Digest',
|
||||
'org.bouncycastle.crypto.digests.RIPEMD160Digest',
|
||||
'org.bouncycastle.crypto.digests.RIPEMD256Digest',
|
||||
'org.bouncycastle.crypto.digests.RIPEMD320Digest',
|
||||
'org.bouncycastle.crypto.digests.SHA1Digest',
|
||||
'org.bouncycastle.crypto.digests.SHA224Digest',
|
||||
'org.bouncycastle.crypto.digests.SHA256Digest',
|
||||
'org.bouncycastle.crypto.digests.SHA384Digest',
|
||||
'org.bouncycastle.crypto.digests.SHA3Digest',
|
||||
'org.bouncycastle.crypto.digests.SHA512Digest',
|
||||
'org.bouncycastle.crypto.digests.TigerDigest',
|
||||
'org.bouncycastle.crypto.digests.WhirlpoolDigest',
|
||||
'org.bouncycastle.crypto.engines.AESEngine',
|
||||
'org.bouncycastle.crypto.engines.BlowfishEngine',
|
||||
'org.bouncycastle.crypto.engines.CAST5Engine',
|
||||
'org.bouncycastle.crypto.engines.CAST6Engine',
|
||||
'org.bouncycastle.crypto.engines.CamelliaEngine',
|
||||
'org.bouncycastle.crypto.engines.DESEngine',
|
||||
'org.bouncycastle.crypto.engines.DESedeEngine',
|
||||
'org.bouncycastle.crypto.engines.GOST28147Engine',
|
||||
'org.bouncycastle.crypto.engines.Grain128Engine',
|
||||
'org.bouncycastle.crypto.engines.HC128Engine',
|
||||
'org.bouncycastle.crypto.engines.HC256Engine',
|
||||
'org.bouncycastle.crypto.engines.ISAACEngine',
|
||||
'org.bouncycastle.crypto.engines.NoekeonEngine',
|
||||
'org.bouncycastle.crypto.engines.RC2Engine',
|
||||
'org.bouncycastle.crypto.engines.RC4Engine',
|
||||
'org.bouncycastle.crypto.engines.RC532Engine',
|
||||
'org.bouncycastle.crypto.engines.RC564Engine',
|
||||
'org.bouncycastle.crypto.engines.RC6Engine',
|
||||
'org.bouncycastle.crypto.engines.SEEDEngine',
|
||||
'org.bouncycastle.crypto.engines.Salsa20Engine',
|
||||
'org.bouncycastle.crypto.engines.SerpentEngine',
|
||||
'org.bouncycastle.crypto.engines.SkipjackEngine',
|
||||
'org.bouncycastle.crypto.engines.TEAEngine',
|
||||
'org.bouncycastle.crypto.engines.TwofishEngine',
|
||||
'org.bouncycastle.crypto.engines.VMPCEngine',
|
||||
'org.bouncycastle.crypto.engines.XTEAEngine',
|
||||
'org.bouncycastle.crypto.generators.BCrypt',
|
||||
'org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator',
|
||||
'org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator',
|
||||
'org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator',
|
||||
'org.bouncycastle.crypto.io.CipherInputStream',
|
||||
'org.bouncycastle.crypto.io.CipherOutputStream',
|
||||
'org.bouncycastle.crypto.macs.HMac',
|
||||
'org.bouncycastle.crypto.modes.AEADBlockCipher',
|
||||
'org.bouncycastle.crypto.modes.CBCBlockCipher',
|
||||
'org.bouncycastle.crypto.modes.CCMBlockCipher',
|
||||
'org.bouncycastle.crypto.modes.CFBBlockCipher',
|
||||
'org.bouncycastle.crypto.modes.EAXBlockCipher',
|
||||
'org.bouncycastle.crypto.modes.GCMBlockCipher',
|
||||
'org.bouncycastle.crypto.modes.OCBBlockCipher',
|
||||
'org.bouncycastle.crypto.modes.OFBBlockCipher',
|
||||
'org.bouncycastle.crypto.paddings.BlockCipherPadding',
|
||||
'org.bouncycastle.crypto.paddings.ISO10126d2Padding',
|
||||
'org.bouncycastle.crypto.paddings.ISO7816d4Padding',
|
||||
'org.bouncycastle.crypto.paddings.PKCS7Padding',
|
||||
'org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher',
|
||||
'org.bouncycastle.crypto.paddings.TBCPadding',
|
||||
'org.bouncycastle.crypto.paddings.X923Padding',
|
||||
'org.bouncycastle.crypto.paddings.ZeroBytePadding',
|
||||
'org.bouncycastle.crypto.params.AEADParameters',
|
||||
'org.bouncycastle.crypto.params.AsymmetricKeyParameter',
|
||||
'org.bouncycastle.crypto.params.DSAKeyParameters',
|
||||
'org.bouncycastle.crypto.params.DSAParameters',
|
||||
'org.bouncycastle.crypto.params.DSAPrivateKeyParameters',
|
||||
'org.bouncycastle.crypto.params.DSAPublicKeyParameters',
|
||||
'org.bouncycastle.crypto.params.ECDomainParameters',
|
||||
'org.bouncycastle.crypto.params.ECKeyParameters',
|
||||
'org.bouncycastle.crypto.params.ECPrivateKeyParameters',
|
||||
'org.bouncycastle.crypto.params.ECPublicKeyParameters',
|
||||
'org.bouncycastle.crypto.params.KeyParameter',
|
||||
'org.bouncycastle.crypto.params.ParametersWithIV',
|
||||
'org.bouncycastle.crypto.params.RC2Parameters',
|
||||
'org.bouncycastle.crypto.params.RC5Parameters',
|
||||
'org.bouncycastle.crypto.params.RSAKeyParameters',
|
||||
'org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters',
|
||||
'org.bouncycastle.crypto.prng.EntropySource',
|
||||
'org.bouncycastle.crypto.prng.SP800SecureRandom',
|
||||
'org.bouncycastle.crypto.prng.SP800SecureRandomBuilder',
|
||||
'org.bouncycastle.crypto.prng.drbg.HashSP800DRBG',
|
||||
'org.bouncycastle.crypto.prng.drbg.SP80090DRBG',
|
||||
'org.bouncycastle.crypto.signers.DSASigner',
|
||||
'org.bouncycastle.crypto.signers.ECDSASigner',
|
||||
'org.bouncycastle.crypto.signers.RSADigestSigner',
|
||||
'org.bouncycastle.crypto.util.PrivateKeyFactory',
|
||||
'org.bouncycastle.crypto.util.PrivateKeyInfoFactory',
|
||||
'org.bouncycastle.crypto.util.PublicKeyFactory',
|
||||
'org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory',
|
||||
'org.bouncycastle.jcajce.provider.asymmetric.dsa.KeyPairGeneratorSpi',
|
||||
'org.bouncycastle.jcajce.provider.asymmetric.ec.KeyPairGeneratorSpi$EC',
|
||||
'org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyPairGeneratorSpi',
|
||||
'org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util',
|
||||
'org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil',
|
||||
'org.bouncycastle.jce.provider.BouncyCastleProvider',
|
||||
'org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec',
|
||||
'org.bouncycastle.math.ec.ECFieldElement',
|
||||
'org.bouncycastle.math.ec.ECPoint',
|
||||
'org.bouncycastle.openssl.jcajce.JcaPEMWriter',
|
||||
'org.bouncycastle.operator.jcajce.JcaContentSignerBuilder',
|
||||
'org.bouncycastle.util.Arrays',
|
||||
'org.bouncycastle.util.Strings',
|
||||
'org.bouncycastle.util.io.Streams',
|
||||
'org.bouncycastle.x509.extension.X509ExtensionUtil',
|
||||
'org.bouncycastle.cert.X509CertificateHolder',
|
||||
'org.bouncycastle.openssl.PEMKeyPair',
|
||||
'org.bouncycastle.openssl.PEMParser',
|
||||
'org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter'
|
||||
)
|
||||
|
||||
ignoreViolations(
|
||||
// Guava uses internal java api: sun.misc.Unsafe
|
||||
|
|
|
@ -24,18 +24,16 @@ forbiddenPatterns {
|
|||
exclude '**/*.jks'
|
||||
}
|
||||
|
||||
rootProject.globalInfo.ready {
|
||||
if (BuildParams.inFipsJvm) {
|
||||
test.enabled = false
|
||||
testingConventions.enabled = false
|
||||
// Forbiden APIs non-portable checks fail because bouncy castle classes being used from the FIPS JDK since those are
|
||||
// not part of the Java specification - all of this is as designed, so we have to relax this check for FIPS.
|
||||
tasks.withType(CheckForbiddenApis) {
|
||||
bundledSignatures -= "jdk-non-portable"
|
||||
}
|
||||
// FIPS JVM includes many classes from bouncycastle which count as jar hell for the third party audit,
|
||||
// rather than provide a long list of exclusions, disable the check on FIPS.
|
||||
thirdPartyAudit.enabled = false
|
||||
|
||||
if (BuildParams.inFipsJvm) {
|
||||
test.enabled = false
|
||||
testingConventions.enabled = false
|
||||
// Forbiden APIs non-portable checks fail because bouncy castle classes being used from the FIPS JDK since those are
|
||||
// not part of the Java specification - all of this is as designed, so we have to relax this check for FIPS.
|
||||
tasks.withType(CheckForbiddenApis) {
|
||||
bundledSignatures -= "jdk-non-portable"
|
||||
}
|
||||
// FIPS JVM includes many classes from bouncycastle which count as jar hell for the third party audit,
|
||||
// rather than provide a long list of exclusions, disable the check on FIPS.
|
||||
thirdPartyAudit.enabled = false
|
||||
|
||||
}
|
||||
|
|
|
@ -239,6 +239,9 @@ public class LdapSessionFactoryTests extends LdapTestCase {
|
|||
* (one failure, one success) depending on which file content is in place.
|
||||
*/
|
||||
public void testSslTrustIsReloaded() throws Exception {
|
||||
assumeFalse("NPE thrown in BCFIPS JSSE - addressed in " +
|
||||
"https://github.com/bcgit/bc-java/commit/5aed687e17a3cd63f34373cafe92699b90076fb6#diff-8e5d8089bc0d504d93194a1e484d3950R179",
|
||||
inFipsJvm());
|
||||
InMemoryDirectoryServer ldapServer = randomFrom(ldapServers);
|
||||
InetAddress listenAddress = ldapServer.getListenAddress("ldaps");
|
||||
if (listenAddress == null) {
|
||||
|
|
|
@ -236,6 +236,7 @@ public class PkiRealmTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testVerificationUsingATruststore() throws Exception {
|
||||
assumeFalse("Can't run in a FIPS JVM, JKS keystores can't be used", inFipsJvm());
|
||||
X509Certificate certificate = readCert(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
|
||||
|
||||
UserRoleMapper roleMapper = buildRoleMapper();
|
||||
|
@ -294,6 +295,7 @@ public class PkiRealmTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testAuthenticationDelegationSuccess() throws Exception {
|
||||
assumeFalse("Can't run in a FIPS JVM, JKS keystores can't be used", inFipsJvm());
|
||||
X509Certificate certificate = readCert(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
|
||||
Authentication mockAuthentication = mock(Authentication.class);
|
||||
User mockUser = mock(User.class);
|
||||
|
@ -330,6 +332,7 @@ public class PkiRealmTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testAuthenticationDelegationFailure() throws Exception {
|
||||
assumeFalse("Can't run in a FIPS JVM, JKS keystores can't be used", inFipsJvm());
|
||||
X509Certificate certificate = readCert(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
|
||||
X509AuthenticationToken delegatedToken = X509AuthenticationToken.delegated(new X509Certificate[] { certificate },
|
||||
mock(Authentication.class));
|
||||
|
@ -353,6 +356,7 @@ public class PkiRealmTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testVerificationFailsUsingADifferentTruststore() throws Exception {
|
||||
assumeFalse("Can't run in a FIPS JVM, JKS keystores can't be used", inFipsJvm());
|
||||
X509Certificate certificate = readCert(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"));
|
||||
UserRoleMapper roleMapper = buildRoleMapper();
|
||||
MockSecureSettings secureSettings = new MockSecureSettings();
|
||||
|
@ -377,6 +381,7 @@ public class PkiRealmTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testTruststorePathWithoutPasswordThrowsException() throws Exception {
|
||||
assumeFalse("Can't run in a FIPS JVM, JKS keystores can't be used", inFipsJvm());
|
||||
Settings settings = Settings.builder()
|
||||
.put(globalSettings)
|
||||
.put("xpack.security.authc.realms.pki.mypki.truststore.path",
|
||||
|
@ -391,6 +396,7 @@ public class PkiRealmTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testTruststorePathWithLegacyPasswordDoesNotThrow() throws Exception {
|
||||
assumeFalse("Can't run in a FIPS JVM, JKS keystores can't be used", inFipsJvm());
|
||||
Settings settings = Settings.builder()
|
||||
.put(globalSettings)
|
||||
.put("xpack.security.authc.realms.pki.mypki.truststore.path",
|
||||
|
|
|
@ -136,6 +136,8 @@ public abstract class AbstractSimpleSecurityTransportTestCase extends AbstractSi
|
|||
|
||||
@SuppressForbidden(reason = "Need to open socket connection")
|
||||
public void testRenegotiation() throws Exception {
|
||||
assumeFalse("BCTLS doesn't support renegotiation: https://github.com/bcgit/bc-java/issues/593#issuecomment-533518845",
|
||||
inFipsJvm());
|
||||
// force TLSv1.2 since renegotiation is not supported by 1.3
|
||||
SSLService sslService =
|
||||
createSSLService(Settings.builder().put("xpack.security.transport.ssl.supported_protocols", "TLSv1.2").build());
|
||||
|
|
|
@ -38,6 +38,7 @@ public class SSLDriverTests extends ESTestCase {
|
|||
private final AtomicInteger openPages = new AtomicInteger(0);
|
||||
|
||||
public void testPingPongAndClose() throws Exception {
|
||||
assumeFalse("Fails in normalClose as receiveDriver.getOutboundBuffer().hasEncryptedBytesToFlush() is false", inFipsJvm());
|
||||
SSLContext sslContext = getSSLContext();
|
||||
|
||||
SSLDriver clientDriver = getDriver(sslContext.createSSLEngine(), true);
|
||||
|
@ -76,6 +77,8 @@ public class SSLDriverTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testRenegotiate() throws Exception {
|
||||
assumeFalse("BCTLS doesn't support renegotiation: https://github.com/bcgit/bc-java/issues/593#issuecomment-533518845",
|
||||
inFipsJvm());
|
||||
SSLContext sslContext = getSSLContext();
|
||||
|
||||
SSLEngine serverEngine = sslContext.createSSLEngine();
|
||||
|
@ -121,6 +124,7 @@ public class SSLDriverTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testBigApplicationData() throws Exception {
|
||||
assumeFalse("Fails in normalClose as receiveDriver.getOutboundBuffer().hasEncryptedBytesToFlush() is false", inFipsJvm());
|
||||
SSLContext sslContext = getSSLContext();
|
||||
|
||||
SSLDriver clientDriver = getDriver(sslContext.createSSLEngine(), true);
|
||||
|
@ -165,7 +169,9 @@ public class SSLDriverTests extends ESTestCase {
|
|||
SSLException sslException = expectThrows(SSLException.class, () -> handshake(clientDriver, serverDriver));
|
||||
String oldExpected = "Client requested protocol TLSv1.1 not enabled or not supported";
|
||||
String jdk11Expected = "The client supported protocol versions [TLSv1.1] are not accepted by server preferences [TLS12]";
|
||||
boolean expectedMessage = oldExpected.equals(sslException.getMessage()) || jdk11Expected.equals(sslException.getMessage());
|
||||
String bctlsExpected = "org.bouncycastle.tls.TlsFatalAlert: protocol_version(70)";
|
||||
boolean expectedMessage = oldExpected.equals(sslException.getMessage()) || jdk11Expected.equals(sslException.getMessage())
|
||||
|| bctlsExpected.equals(sslException.getMessage());
|
||||
assertTrue("Unexpected exception message: " + sslException.getMessage(), expectedMessage);
|
||||
|
||||
// Prior to JDK11 we still need to send a close alert
|
||||
|
@ -199,7 +205,8 @@ public class SSLDriverTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testCloseDuringHandshakeJDK11() throws Exception {
|
||||
assumeTrue("this tests ssl engine for JDK11", JavaVersion.current().compareTo(JavaVersion.parse("11")) >= 0);
|
||||
assumeTrue("this tests ssl engine for JDK11",
|
||||
JavaVersion.current().compareTo(JavaVersion.parse("11")) >= 0 && inFipsJvm() == false);
|
||||
SSLContext sslContext = getSSLContext();
|
||||
SSLDriver clientDriver = getDriver(sslContext.createSSLEngine(), true);
|
||||
SSLDriver serverDriver = getDriver(sslContext.createSSLEngine(), false);
|
||||
|
@ -288,7 +295,7 @@ public class SSLDriverTests extends ESTestCase {
|
|||
(certPath))));
|
||||
KeyManager km = CertParsingUtils.keyManager(CertParsingUtils.readCertificates(Collections.singletonList(getDataPath
|
||||
(certPath))), PemUtils.readPrivateKey(getDataPath(keyPath), "testclient"::toCharArray), "testclient".toCharArray());
|
||||
if (JavaVersion.current().compareTo(JavaVersion.parse("11")) >= 0) {
|
||||
if (JavaVersion.current().compareTo(JavaVersion.parse("11")) >= 0 && inFipsJvm() == false) {
|
||||
sslContext = SSLContext.getInstance(randomFrom("TLSv1.2", "TLSv1.3"));
|
||||
} else {
|
||||
sslContext = SSLContext.getInstance(randomFrom("TLSv1.2"));
|
||||
|
|
|
@ -75,6 +75,7 @@ public class EllipticCurveSSLTests extends SecurityIntegTestCase {
|
|||
}
|
||||
|
||||
public void testConnection() throws Exception {
|
||||
assumeFalse("Fails on BCTLS with 'Closed engine without receiving the close alert message.'", inFipsJvm());
|
||||
final Path keyPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/prime256v1-key.pem");
|
||||
final Path certPath = getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/prime256v1-cert.pem");
|
||||
PrivateKey privateKey = PemUtils.readPrivateKey(keyPath, () -> null);
|
||||
|
|
|
@ -184,7 +184,7 @@ public class SSLClientAuthTests extends SecurityIntegTestCase {
|
|||
(certPath))), PemUtils.readPrivateKey(getDataPath(keyPath), "testclient"::toCharArray), "testclient".toCharArray());
|
||||
|
||||
final SSLContext context;
|
||||
if (XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS.contains("TLSv1.3")) {
|
||||
if (XPackSettings.DEFAULT_SUPPORTED_PROTOCOLS.contains("TLSv1.3") && inFipsJvm() == false) {
|
||||
context = SSLContext.getInstance(randomBoolean() ? "TLSv1.3" : "TLSv1.2");
|
||||
} else {
|
||||
context = SSLContext.getInstance("TLSv1.2");
|
||||
|
|
|
@ -91,6 +91,7 @@ public class SSLReloadIntegTests extends SecurityIntegTestCase {
|
|||
}
|
||||
|
||||
public void testThatSSLConfigurationReloadsOnModification() throws Exception {
|
||||
assumeFalse("https://github.com/elastic/elasticsearch/issues/49094", inFipsJvm());
|
||||
Path keyPath = createTempDir().resolve("testnode_updated.pem");
|
||||
Path certPath = createTempDir().resolve("testnode_updated.crt");
|
||||
Files.copy(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode_updated.pem"), keyPath);
|
||||
|
|
Loading…
Reference in New Issue