From 905663a94264aa43a772e11eade16c9262cf546c Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Tue, 12 Jun 2018 19:13:02 -0400 Subject: [PATCH] Use armored input stream for reading public key (#31229) This was silly; Bouncy Castle has an armored input stream for reading keys in ASCII armor format. This means that we do not need to strip the header ourselves and base64 decode the key. This had problems anyway because of discrepancies in the padding that Bouncy Castle would produce and the JDK base64 decoder was expecting. Now that we armor input/output the whole way during tests, we fix all random failures in test cases too. --- .../plugins/InstallPluginCommand.java | 19 +++---------------- .../plugins/InstallPluginCommandTests.java | 2 -- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java b/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java index 6a3f57c98d2..3c54afb92c7 100644 --- a/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java +++ b/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/InstallPluginCommand.java @@ -23,6 +23,7 @@ import joptsimple.OptionSet; import joptsimple.OptionSpec; import org.apache.lucene.search.spell.LevensteinDistance; import org.apache.lucene.util.CollectionUtil; +import org.bouncycastle.bcpg.ArmoredInputStream; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; @@ -47,7 +48,6 @@ import org.elasticsearch.core.internal.io.IOUtils; import org.elasticsearch.env.Environment; import java.io.BufferedReader; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -74,7 +74,6 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Base64; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -543,8 +542,8 @@ class InstallPluginCommand extends EnvironmentAwareCommand { InputStream fin = pluginZipInputStream(zip); // sin is a URL stream to the signature corresponding to the downloaded plugin zip InputStream sin = urlOpenStream(ascUrl); - // pin is a input stream to the public key in ASCII-Armor format (RFC4880); the Armor data is in RFC2045 format - InputStream pin = getPublicKey()) { + // ain is a input stream to the public key in ASCII-Armor format (RFC4880) + InputStream ain = new ArmoredInputStream(getPublicKey())) { final JcaPGPObjectFactory factory = new JcaPGPObjectFactory(PGPUtil.getDecoderStream(sin)); final PGPSignature signature = ((PGPSignatureList) factory.nextObject()).get(0); @@ -555,18 +554,6 @@ class InstallPluginCommand extends EnvironmentAwareCommand { } // compute the signature of the downloaded plugin zip - final List lines = - new BufferedReader(new InputStreamReader(pin, StandardCharsets.UTF_8)).lines().collect(Collectors.toList()); - // skip armor headers and possible blank line - int index = 1; - for (; index < lines.size(); index++) { - if (lines.get(index).matches(".*: .*") == false && lines.get(index).matches("\\s*") == false) { - break; - } - } - final byte[] armoredData = - lines.subList(index, lines.size() - 1).stream().collect(Collectors.joining("\n")).getBytes(StandardCharsets.UTF_8); - final InputStream ain = Base64.getMimeDecoder().wrap(new ByteArrayInputStream(armoredData)); final PGPPublicKeyRingCollection collection = new PGPPublicKeyRingCollection(ain, new JcaKeyFingerprintCalculator()); final PGPPublicKey key = collection.getPublicKey(signature.getKeyID()); signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider(new BouncyCastleProvider()), key); diff --git a/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java b/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java index e9d0974c143..1db551934c7 100644 --- a/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java +++ b/distribution/tools/plugin-cli/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java @@ -23,7 +23,6 @@ import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; import com.google.common.jimfs.Configuration; import com.google.common.jimfs.Jimfs; import org.apache.lucene.util.LuceneTestCase; -import org.apache.lucene.util.LuceneTestCase.AwaitsFix; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.BCPGOutputStream; import org.bouncycastle.bcpg.HashAlgorithmTags; @@ -116,7 +115,6 @@ import static org.hamcrest.Matchers.hasToString; import static org.hamcrest.Matchers.not; @LuceneTestCase.SuppressFileSystems("*") -@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/30900") public class InstallPluginCommandTests extends ESTestCase { private InstallPluginCommand skipJarHellCommand;