Skip to content

Fips compliance internal #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .idea/runConfigurations/Debug_OpenSearch.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions CHANGELOG-3.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- GHA to verify checklist items completion in PR descriptions ([#10800](https://github.com/opensearch-project/OpenSearch/pull/10800))
- Allow to pass the list settings through environment variables (like [], ["a", "b", "c"], ...) ([#10625](https://github.com/opensearch-project/OpenSearch/pull/10625))
- Views, simplify data access and manipulation by providing a virtual layer over one or more indices ([#11957](https://github.com/opensearch-project/OpenSearch/pull/11957))
- Support for FIPS-140-3 compliance through environment variable ([#3420](https://github.com/opensearch-project/OpenSearch/pull/14912))

### Dependencies

Expand Down
12 changes: 10 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ apply from: 'gradle/ide.gradle'
apply from: 'gradle/forbidden-dependencies.gradle'
apply from: 'gradle/formatting.gradle'
apply from: 'gradle/local-distribution.gradle'
apply from: 'gradle/fips.gradle'
apply from: 'gradle/run.gradle'
apply from: 'gradle/missing-javadoc.gradle'
apply from: 'gradle/code-coverage.gradle'
Expand Down Expand Up @@ -472,8 +471,8 @@ gradle.projectsEvaluated {
}
}

// test retry configuration
subprojects {
// test retry configuration
tasks.withType(Test).configureEach {
develocity.testRetry {
if (BuildParams.isCi()) {
Expand Down Expand Up @@ -559,6 +558,15 @@ subprojects {
}
}
}

// test with FIPS-140-3 enabled
plugins.withType(JavaPlugin).configureEach {
tasks.withType(Test).configureEach { testTask ->
if (System.getenv('OPENSEARCH_CRYPTO_STANDARD') == 'FIPS-140-3') {
testTask.jvmArgs += "-Dorg.bouncycastle.fips.approved_only=true"
}
}
}
}

// eclipse configuration
Expand Down
6 changes: 2 additions & 4 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ dependencies {
api 'org.jruby.joni:joni:2.2.1'
api "com.fasterxml.jackson.core:jackson-databind:${props.getProperty('jackson_databind')}"
api "org.ajoberstar.grgit:grgit-core:5.2.1"
api "org.bouncycastle:bc-fips:${props.getProperty('bouncycastle_jce')}"


testFixturesApi "junit:junit:${props.getProperty('junit')}"
testFixturesApi "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${props.getProperty('randomizedrunner')}"
Expand Down Expand Up @@ -229,12 +231,8 @@ if (project != rootProject) {

forbiddenPatterns {
exclude '**/*.wav'
exclude '**/*.p12'
exclude '**/*.jks'
exclude '**/*.crt'
// the file that actually defines nocommit
exclude '**/ForbiddenPatternsTask.java'
exclude '**/*.bcfks'
}

testingConventions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ public void execute(Task t) {
test.systemProperty("tests.seed", BuildParams.getTestSeed());
}

var securityFile = BuildParams.isInFipsJvm() ? "fips_java.security" : "java.security";
test.systemProperty(
"java.security.properties",
project.getRootProject().getLayout().getProjectDirectory() + "/distribution/src/config/" + securityFile
);

// don't track these as inputs since they contain absolute paths and break cache relocatability
File gradleHome = project.getGradle().getGradleUserHomeDir();
String gradleVersion = project.getGradle().getGradleVersion();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@

package org.opensearch.gradle.http;

import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.gradle.api.logging.Logger;
import org.gradle.api.logging.Logging;
import org.gradle.internal.impldep.com.jcraft.jsch.annotations.SuppressForbiddenApi;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
Expand All @@ -51,7 +53,6 @@
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
Expand Down Expand Up @@ -216,15 +217,15 @@ KeyStore buildTrustStore() throws GeneralSecurityException, IOException {
}

private KeyStore buildTrustStoreFromFile() throws GeneralSecurityException, IOException {
KeyStore keyStore = KeyStore.getInstance(trustStoreFile.getName().endsWith(".jks") ? "JKS" : "PKCS12");
var keyStore = getKeyStoreInstance(trustStoreFile.getName().endsWith(".jks") ? "JKS" : "PKCS12");
try (InputStream input = new FileInputStream(trustStoreFile)) {
keyStore.load(input, trustStorePassword == null ? null : trustStorePassword.toCharArray());
}
return keyStore;
}

private KeyStore buildTrustStoreFromCA() throws GeneralSecurityException, IOException {
final KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
var store = getKeyStoreInstance(KeyStore.getDefaultType());
store.load(null, null);
final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
int counter = 0;
Expand All @@ -239,12 +240,17 @@ private KeyStore buildTrustStoreFromCA() throws GeneralSecurityException, IOExce
return store;
}

@SuppressForbiddenApi("runs exclusively in test-context without KeyStoreFactory on classpath.")
private KeyStore getKeyStoreInstance(String type) throws KeyStoreException {
return KeyStore.getInstance(type);
}

private SSLContext createSslContext(KeyStore trustStore) throws GeneralSecurityException {
checkForTrustEntry(trustStore);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(new KeyManager[0], tmf.getTrustManagers(), new SecureRandom());
sslContext.init(new KeyManager[0], tmf.getTrustManagers(), CryptoServicesRegistrar.getSecureRandom());
return sslContext;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public class GlobalBuildInfoPlugin implements Plugin<Project> {
private static final Logger LOGGER = Logging.getLogger(GlobalBuildInfoPlugin.class);
private static final String DEFAULT_LEGACY_VERSION_JAVA_FILE_PATH = "libs/core/src/main/java/org/opensearch/LegacyESVersion.java";
private static final String DEFAULT_VERSION_JAVA_FILE_PATH = "libs/core/src/main/java/org/opensearch/Version.java";
protected static final String OPENSEARCH_CRYPTO_STANDARD = "OPENSEARCH_CRYPTO_STANDARD";
private static Integer _defaultParallel = null;

private final JvmMetadataDetector jvmMetadataDetector;
Expand Down Expand Up @@ -112,6 +113,8 @@ public void apply(Project project) {
BuildParams.init(params -> {
// Initialize global build parameters
boolean isInternal = GlobalBuildInfoPlugin.class.getResource("/buildSrc.marker") != null;
var cryptoStandard = System.getenv(OPENSEARCH_CRYPTO_STANDARD);
var inFipsJvm = cryptoStandard != null && cryptoStandard.equals("FIPS-140-3");

params.reset();
params.setRuntimeJavaHome(runtimeJavaHome);
Expand All @@ -129,7 +132,7 @@ public void apply(Project project) {
params.setIsCi(System.getenv("JENKINS_URL") != null);
params.setIsInternal(isInternal);
params.setDefaultParallel(findDefaultParallel(project));
params.setInFipsJvm(Util.getBooleanProperty("tests.fips.enabled", false));
params.setInFipsJvm(inFipsJvm);
params.setIsSnapshotBuild(Util.getBooleanProperty("build.snapshot", true));
if (isInternal) {
params.setBwcVersions(resolveBwcVersions(rootDir));
Expand Down Expand Up @@ -163,6 +166,7 @@ private void logGlobalBuildInfo() {
final String osArch = System.getProperty("os.arch");
final Jvm gradleJvm = Jvm.current();
final String gradleJvmDetails = getJavaInstallation(gradleJvm.getJavaHome()).getDisplayName();
final String cryptStandard = System.getenv(OPENSEARCH_CRYPTO_STANDARD);

LOGGER.quiet("=======================================");
LOGGER.quiet("OpenSearch Build Hamster says Hello!");
Expand All @@ -179,7 +183,11 @@ private void logGlobalBuildInfo() {
LOGGER.quiet(" JAVA_HOME : " + gradleJvm.getJavaHome());
}
LOGGER.quiet(" Random Testing Seed : " + BuildParams.getTestSeed());
LOGGER.quiet(" In FIPS 140 mode : " + BuildParams.isInFipsJvm());
if (cryptStandard != null && cryptStandard.equals("FIPS-140-3")) {
LOGGER.quiet(" Crypto Standard : FIPS-140-3");
} else {
LOGGER.quiet(" Crypto Standard : any-supported");
}
LOGGER.quiet("=======================================");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,13 @@ public class ForbiddenPatternsTask extends DefaultTask {
.exclude("**/*.ico")
.exclude("**/*.jar")
.exclude("**/*.zip")
.exclude("**/*.p12")
.exclude("**/*.jks")
.exclude("**/*.crt")
.exclude("**/*.der")
.exclude("**/*.pem")
.exclude("**/*.key")
.exclude("**/*.bcfks")
.exclude("**/*.keystore")
.exclude("**/*.png");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -548,15 +548,15 @@ public synchronized void start() {

logToProcessStdout("Creating opensearch keystore with password set to [" + keystorePassword + "]");
if (keystorePassword.length() > 0) {
runOpenSearchBinScriptWithInput(keystorePassword + "\n" + keystorePassword, "opensearch-keystore", "create", "-p");
runOpenSearchBinScriptWithInput(keystorePassword + "\n" + keystorePassword + "\n", "opensearch-keystore", "create", "-p");
} else {
runOpenSearchBinScript("opensearch-keystore", "-v", "create");
}

if (keystoreSettings.isEmpty() == false || keystoreFiles.isEmpty() == false) {
logToProcessStdout("Adding " + keystoreSettings.size() + " keystore settings and " + keystoreFiles.size() + " keystore files");

keystoreSettings.forEach((key, value) -> runKeystoreCommandWithPassword(keystorePassword, value.toString(), "add", "-x", key));
keystoreSettings.forEach((key, value) -> runKeystoreCommandWithPassword(keystorePassword, value.toString(), "add", key));

for (Map.Entry<String, File> entry : keystoreFiles.entrySet()) {
File file = entry.getValue();
Expand Down Expand Up @@ -738,7 +738,12 @@ private void runOpenSearchBinScriptWithInput(String input, String tool, CharSequ
}

private void runKeystoreCommandWithPassword(String keystorePassword, String input, CharSequence... args) {
final String actualInput = keystorePassword.length() > 0 ? keystorePassword + "\n" + input : input;
final String actualInput;
if (keystorePassword.length() > 0) {
actualInput = keystorePassword + "\n" + input + "\n" + input;
} else {
actualInput = input + "\n" + input;
}
runOpenSearchBinScriptWithInput(actualInput, "opensearch-keystore", args);
}

Expand Down
Binary file removed buildSrc/src/main/resources/cacerts.bcfks
Binary file not shown.
29 changes: 0 additions & 29 deletions buildSrc/src/main/resources/fips_java_bcjsse_11.policy

This file was deleted.

34 changes: 0 additions & 34 deletions buildSrc/src/main/resources/fips_java_bcjsse_8.policy

This file was deleted.

Loading
Loading