Просмотр исходного кода

Make plugin verification FIPS 140 compliant (#44224)

This change makes the process of verifying the signature of
official plugins FIPS 140 compliant by defaulting to use the
BouncyCastle FIPS provider and adding a dependency to bcpg-fips
that implement parts of openPGP in a FIPS compliant manner.

In already FIPS 140 enabled environments that use the 
BouncyCastle FIPS provider, the bcfips dependency is redundant
but doesn't cause an issue as it will be added only in the classpath
 of the cli-tools
Ioannis Kakavas 6 лет назад
Родитель
Сommit
5292e17f39

+ 28 - 3
distribution/tools/plugin-cli/build.gradle

@@ -24,8 +24,8 @@ archivesBaseName = 'elasticsearch-plugin-cli'
 dependencies {
   compileOnly project(":server")
   compileOnly project(":libs:elasticsearch-cli")
-  compile "org.bouncycastle:bcpg-jdk15on:${versions.bouncycastle}"
-  compile "org.bouncycastle:bcprov-jdk15on:${versions.bouncycastle}"
+  compile "org.bouncycastle:bcpg-fips:1.0.3"
+  compile "org.bouncycastle:bc-fips:1.0.1"
   testCompile project(":test:framework")
   testCompile 'com.google.jimfs:jimfs:1.1'
   testCompile 'com.google.guava:guava:18.0'
@@ -44,4 +44,29 @@ thirdPartyAudit.onlyIf {
   // FIPS JVM includes manny 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.
   project.inFipsJvm == false
-}
+}
+
+/*
+ * these two classes intentionally use the following JDK internal APIs in order to offer the necessary
+ * functionality
+ *
+ * sun.security.internal.spec.TlsKeyMaterialParameterSpec
+ * sun.security.internal.spec.TlsKeyMaterialSpec
+ * sun.security.internal.spec.TlsMasterSecretParameterSpec
+ * sun.security.internal.spec.TlsPrfParameterSpec
+ * sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec
+ * sun.security.provider.SecureRandom
+ *
+ */
+thirdPartyAudit.ignoreViolations(
+        'org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider$CoreSecureRandom',
+        'org.bouncycastle.jcajce.provider.ProvSunTLSKDF',
+        'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$BaseTLSKeyGeneratorSpi',
+        'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSKeyMaterialGenerator',
+        'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSKeyMaterialGenerator$2',
+        'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSMasterSecretGenerator',
+        'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSMasterSecretGenerator$2',
+        'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSPRFKeyGenerator',
+        'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSRsaPreMasterSecretGenerator',
+        'org.bouncycastle.jcajce.provider.ProvSunTLSKDF$TLSRsaPreMasterSecretGenerator$2'
+)

+ 1 - 0
distribution/tools/plugin-cli/licenses/bc-fips-1.0.1.jar.sha1

@@ -0,0 +1 @@
+ed8dd3144761eaa33b9c56f5e2bef85f1b731d6f

+ 1 - 0
distribution/tools/plugin-cli/licenses/bcpg-fips-1.0.3.jar.sha1

@@ -0,0 +1 @@
+e67f464dc25594fa4dca92281e093eab03e170e0

+ 0 - 1
distribution/tools/plugin-cli/licenses/bcpg-jdk15on-1.61.jar.sha1

@@ -1 +0,0 @@
-422656435514ab8a28752b117d5d2646660a0ace

+ 0 - 1
distribution/tools/plugin-cli/licenses/bcprov-jdk15on-1.61.jar.sha1

@@ -1 +0,0 @@
-00df4b474e71be02c1349c3292d98886f888d1f7

+ 2 - 2
distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java

@@ -24,7 +24,7 @@ import joptsimple.OptionSpec;
 import org.apache.lucene.search.spell.LevenshteinDistance;
 import org.apache.lucene.util.CollectionUtil;
 import org.bouncycastle.bcpg.ArmoredInputStream;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
 import org.bouncycastle.openpgp.PGPException;
 import org.bouncycastle.openpgp.PGPPublicKey;
 import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
@@ -551,7 +551,7 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
             // compute the signature of the downloaded plugin zip
             final PGPPublicKeyRingCollection collection = new PGPPublicKeyRingCollection(ain, new JcaKeyFingerprintCalculator());
             final PGPPublicKey key = collection.getPublicKey(signature.getKeyID());
-            signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider(new BouncyCastleProvider()), key);
+            signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider(new BouncyCastleFipsProvider()), key);
             final byte[] buffer = new byte[1024];
             int read;
             while ((read = fin.read(buffer)) != -1) {

+ 7 - 14
distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java

@@ -26,7 +26,7 @@ import org.apache.lucene.util.LuceneTestCase;
 import org.bouncycastle.bcpg.ArmoredOutputStream;
 import org.bouncycastle.bcpg.BCPGOutputStream;
 import org.bouncycastle.bcpg.HashAlgorithmTags;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
 import org.bouncycastle.openpgp.PGPEncryptedData;
 import org.bouncycastle.openpgp.PGPException;
 import org.bouncycastle.openpgp.PGPKeyPair;
@@ -36,11 +36,10 @@ import org.bouncycastle.openpgp.PGPSecretKey;
 import org.bouncycastle.openpgp.PGPSignature;
 import org.bouncycastle.openpgp.PGPSignatureGenerator;
 import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
-import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder;
-import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder;
 import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
 import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
 import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
+import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
 import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
 import org.elasticsearch.Build;
 import org.elasticsearch.Version;
@@ -61,7 +60,6 @@ import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.test.PosixPermissionsResetter;
 import org.junit.After;
 import org.junit.Before;
-import org.junit.BeforeClass;
 
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
@@ -141,11 +139,6 @@ public class InstallPluginCommandTests extends ESTestCase {
         System.setProperty("java.io.tmpdir", temp.apply("tmpdir").toString());
     }
 
-    @BeforeClass
-    public static void testIfFipsMode() {
-        assumeFalse("Can't run in a FIPS JVM because this depends on BouncyCastle (non-fips)", inFipsJvm());
-    }
-
     @Override
     @Before
     public void setUp() throws Exception {
@@ -1174,9 +1167,9 @@ public class InstallPluginCommandTests extends ESTestCase {
                 sha1Calc,
                 null,
                 null,
-                new JcaPGPContentSignerBuilder(pkp.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1),
-                new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.CAST5, sha1Calc)
-                        .setProvider(new BouncyCastleProvider())
+            new JcaPGPContentSignerBuilder(pkp.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA256),
+            new JcePBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_192, sha1Calc)
+                .setProvider(new BouncyCastleFipsProvider())
                         .build("passphrase".toCharArray()));
     }
 
@@ -1197,11 +1190,11 @@ public class InstallPluginCommandTests extends ESTestCase {
         try {
             final PGPPrivateKey privateKey
                     = secretKey.extractPrivateKey(
-                            new BcPBESecretKeyDecryptorBuilder(
+                new JcePBESecretKeyDecryptorBuilder(
                                     new JcaPGPDigestCalculatorProviderBuilder().build()).build("passphrase".toCharArray()));
             final PGPSignatureGenerator generator =
                     new PGPSignatureGenerator(
-                            new BcPGPContentSignerBuilder(privateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512));
+                        new JcaPGPContentSignerBuilder(privateKey.getPublicKeyPacket().getAlgorithm(), HashAlgorithmTags.SHA512));
             generator.init(PGPSignature.BINARY_DOCUMENT, privateKey);
             final ByteArrayOutputStream output = new ByteArrayOutputStream();
             try (BCPGOutputStream pout = new BCPGOutputStream(new ArmoredOutputStream(output));

+ 0 - 3
x-pack/docs/en/security/fips-140-compliance.asciidoc

@@ -119,9 +119,6 @@ features are not available while running in fips mode. The list is as follows:
   enabled JVM (pointing `JAVA_HOME` environment variable to a different java
   installation) in order to generate the keys and certificates that
   can be later used in the FIPS 140-2 enabled JVM.
-* The `elasticsearch-plugin` tool. Accordingly, `elasticsearch-plugin` can be
-  used with a different (non FIPS 140-2 enabled) Java installation if
-  available.
 * The SQL CLI client cannot run in a FIPS 140-2 enabled JVM while using
   TLS for transport security or PKI for client authentication.
 * The SAML Realm cannot decrypt and consume encrypted Assertions or encrypted