Skip to content

Commit 905663a

Browse files
authored
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.
1 parent f88b9e8 commit 905663a

File tree

2 files changed

+3
-18
lines changed

2 files changed

+3
-18
lines changed

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

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import joptsimple.OptionSpec;
2424
import org.apache.lucene.search.spell.LevensteinDistance;
2525
import org.apache.lucene.util.CollectionUtil;
26+
import org.bouncycastle.bcpg.ArmoredInputStream;
2627
import org.bouncycastle.jce.provider.BouncyCastleProvider;
2728
import org.bouncycastle.openpgp.PGPException;
2829
import org.bouncycastle.openpgp.PGPPublicKey;
@@ -47,7 +48,6 @@
4748
import org.elasticsearch.env.Environment;
4849

4950
import java.io.BufferedReader;
50-
import java.io.ByteArrayInputStream;
5151
import java.io.IOException;
5252
import java.io.InputStream;
5353
import java.io.InputStreamReader;
@@ -74,7 +74,6 @@
7474
import java.security.NoSuchAlgorithmException;
7575
import java.util.ArrayList;
7676
import java.util.Arrays;
77-
import java.util.Base64;
7877
import java.util.Collections;
7978
import java.util.HashMap;
8079
import java.util.HashSet;
@@ -543,8 +542,8 @@ void verifySignature(final Path zip, final String urlString) throws IOException,
543542
InputStream fin = pluginZipInputStream(zip);
544543
// sin is a URL stream to the signature corresponding to the downloaded plugin zip
545544
InputStream sin = urlOpenStream(ascUrl);
546-
// pin is a input stream to the public key in ASCII-Armor format (RFC4880); the Armor data is in RFC2045 format
547-
InputStream pin = getPublicKey()) {
545+
// ain is a input stream to the public key in ASCII-Armor format (RFC4880)
546+
InputStream ain = new ArmoredInputStream(getPublicKey())) {
548547
final JcaPGPObjectFactory factory = new JcaPGPObjectFactory(PGPUtil.getDecoderStream(sin));
549548
final PGPSignature signature = ((PGPSignatureList) factory.nextObject()).get(0);
550549

@@ -555,18 +554,6 @@ void verifySignature(final Path zip, final String urlString) throws IOException,
555554
}
556555

557556
// compute the signature of the downloaded plugin zip
558-
final List<String> lines =
559-
new BufferedReader(new InputStreamReader(pin, StandardCharsets.UTF_8)).lines().collect(Collectors.toList());
560-
// skip armor headers and possible blank line
561-
int index = 1;
562-
for (; index < lines.size(); index++) {
563-
if (lines.get(index).matches(".*: .*") == false && lines.get(index).matches("\\s*") == false) {
564-
break;
565-
}
566-
}
567-
final byte[] armoredData =
568-
lines.subList(index, lines.size() - 1).stream().collect(Collectors.joining("\n")).getBytes(StandardCharsets.UTF_8);
569-
final InputStream ain = Base64.getMimeDecoder().wrap(new ByteArrayInputStream(armoredData));
570557
final PGPPublicKeyRingCollection collection = new PGPPublicKeyRingCollection(ain, new JcaKeyFingerprintCalculator());
571558
final PGPPublicKey key = collection.getPublicKey(signature.getKeyID());
572559
signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider(new BouncyCastleProvider()), key);

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import com.google.common.jimfs.Configuration;
2424
import com.google.common.jimfs.Jimfs;
2525
import org.apache.lucene.util.LuceneTestCase;
26-
import org.apache.lucene.util.LuceneTestCase.AwaitsFix;
2726
import org.bouncycastle.bcpg.ArmoredOutputStream;
2827
import org.bouncycastle.bcpg.BCPGOutputStream;
2928
import org.bouncycastle.bcpg.HashAlgorithmTags;
@@ -116,7 +115,6 @@
116115
import static org.hamcrest.Matchers.not;
117116

118117
@LuceneTestCase.SuppressFileSystems("*")
119-
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/30900")
120118
public class InstallPluginCommandTests extends ESTestCase {
121119

122120
private InstallPluginCommand skipJarHellCommand;

0 commit comments

Comments
 (0)