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 a47ea4f892616..6a3f57c98d205 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 @@ -47,6 +47,7 @@ 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; @@ -71,7 +72,6 @@ import java.nio.file.attribute.PosixFilePermissions; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.security.Security; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; @@ -543,8 +543,8 @@ void verifySignature(final Path zip, final String urlString) throws IOException, 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 decoded base64 stream over the embedded public key in RFC2045 format - InputStream pin = Base64.getMimeDecoder().wrap(getPublicKey())) { + // pin is a input stream to the public key in ASCII-Armor format (RFC4880); the Armor data is in RFC2045 format + InputStream pin = getPublicKey()) { final JcaPGPObjectFactory factory = new JcaPGPObjectFactory(PGPUtil.getDecoderStream(sin)); final PGPSignature signature = ((PGPSignatureList) factory.nextObject()).get(0); @@ -555,7 +555,19 @@ void verifySignature(final Path zip, final String urlString) throws IOException, } // compute the signature of the downloaded plugin zip - final PGPPublicKeyRingCollection collection = new PGPPublicKeyRingCollection(pin, new JcaKeyFingerprintCalculator()); + 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); final byte[] buffer = new byte[1024]; @@ -597,7 +609,7 @@ String getPublicKeyId() { * @return an input stream to the public key */ InputStream getPublicKey() { - return InstallPluginCommand.class.getResourceAsStream("/public_key"); + return InstallPluginCommand.class.getResourceAsStream("/public_key.asc"); } /** diff --git a/distribution/tools/plugin-cli/src/main/resources/public_key b/distribution/tools/plugin-cli/src/main/resources/public_key.asc similarity index 93% rename from distribution/tools/plugin-cli/src/main/resources/public_key rename to distribution/tools/plugin-cli/src/main/resources/public_key.asc index 552c8e3379d3b..57fb72a35cf6b 100644 --- a/distribution/tools/plugin-cli/src/main/resources/public_key +++ b/distribution/tools/plugin-cli/src/main/resources/public_key.asc @@ -1,3 +1,7 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: SKS 1.1.6 +Comment: Hostname: pgp.mit.edu + mQENBFI3HsoBCADXDtbNJnxbPqB1vDNtCsqhe49vFYsZN9IOZsZXgp7aHjh6CJBDA+bGFOwy hbd7at35jQjWAw1O3cfYsKAmFy+Ar3LHCMkV3oZspJACTIgCrwnkic/9CUliQe324qvObU2Q RtP4Fl0zWcfb/S8UYzWXWIFuJqMvE9MaRY1bwUBvzoqavLGZj3SF1SPO+TB5QrHkrQHBsmX+ @@ -22,3 +26,4 @@ EyUJ8SKsaHh4jV9wp9KmC8C+9CwMukL7vM5w8cgvJoAwsp3Fn59AxWthN3XJYcnMfStkIuWg R7U2r+a210W6vnUxU4oN0PmMcursYPyeV0NX/KQeUeNMwGTFB6QHS/anRaGQewijkrYYoTNt fllxIu9XYmiBERQ/qPDlGRlOgVTd9xUfHFkzB52c70E= =92oX +-----END PGP PUBLIC KEY BLOCK----- \ No newline at end of file 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 d9238091d8769..1db551934c768 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 @@ -893,12 +893,7 @@ InputStream getPublicKey() { final ArmoredOutputStream armored = new ArmoredOutputStream(output); secretKey.getPublicKey().encode(armored); armored.close(); - final String publicKey = new String(output.toByteArray(), "UTF-8"); - int start = publicKey.indexOf("\n", 1 + publicKey.indexOf("\n")); - int end = publicKey.lastIndexOf("\n", publicKey.lastIndexOf("\n") - 1); - // strip the header (first two lines) and footer (last line) - final String substring = publicKey.substring(1 + start, end); - return new ByteArrayInputStream(substring.getBytes("UTF-8")); + return new ByteArrayInputStream(output.toByteArray()); } catch (final IOException e) { throw new AssertionError(e); }