Add public key header/footer (#30877)

A previous commit added the public key used for signing artifacts to the
plugin CLI. This commit is an iteration on that to add the header and
footer to the key so that it is clear what the key is. Instead, we strip
the header/footer on read. With this change we simplify our test where
keys already in this format are generated and we had to strip on the
test side.
This commit is contained in:
Jason Tedor 2018-05-25 18:06:59 -04:00 committed by GitHub
parent dbb2e8143c
commit 35ffb8c65a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 11 deletions

View File

@ -47,6 +47,7 @@ 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;
@ -71,7 +72,6 @@ import java.nio.file.attribute.PosixFilePermission;
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 @@ 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 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 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
}
// compute the signature of the downloaded plugin zip
final PGPPublicKeyRingCollection collection = new PGPPublicKeyRingCollection(pin, new JcaKeyFingerprintCalculator());
final List<String> 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 @@ class InstallPluginCommand extends EnvironmentAwareCommand {
* @return an input stream to the public key
*/
InputStream getPublicKey() {
return InstallPluginCommand.class.getResourceAsStream("/public_key");
return InstallPluginCommand.class.getResourceAsStream("/public_key.asc");
}
/**

View File

@ -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-----

View File

@ -893,12 +893,7 @@ public class InstallPluginCommandTests extends ESTestCase {
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);
}