diff --git a/pgpainless-core/src/main/java/org/pgpainless/util/ArmorUtils.java b/pgpainless-core/src/main/java/org/pgpainless/util/ArmorUtils.java index 6807e37f..02d5892d 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/util/ArmorUtils.java +++ b/pgpainless-core/src/main/java/org/pgpainless/util/ArmorUtils.java @@ -19,30 +19,61 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Iterator; import org.bouncycastle.bcpg.ArmoredOutputStream; +import org.bouncycastle.openpgp.PGPKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.util.io.Streams; +import org.pgpainless.key.OpenPgpV4Fingerprint; public class ArmorUtils { public static String toAsciiArmoredString(PGPSecretKeyRing secretKeys) throws IOException { - return toAsciiArmoredString(secretKeys.getEncoded()); + MultiMap header = keyToHeader(secretKeys); + return toAsciiArmoredString(secretKeys.getEncoded(), header); } public static String toAsciiArmoredString(PGPPublicKeyRing publicKeys) throws IOException { - return toAsciiArmoredString(publicKeys.getEncoded()); + MultiMap header = keyToHeader(publicKeys); + return toAsciiArmoredString(publicKeys.getEncoded(), header); + } + + private static MultiMap keyToHeader(PGPKeyRing keyRing) { + MultiMap header = new MultiMap<>(); + OpenPgpV4Fingerprint fingerprint = new OpenPgpV4Fingerprint(keyRing); + Iterator userIds = keyRing.getPublicKey().getUserIDs(); + + header.put("Comment", fingerprint.prettyPrint()); + if (userIds.hasNext()) { + header.put("Comment", userIds.next()); + } + return header; } public static String toAsciiArmoredString(byte[] bytes) throws IOException { - return toAsciiArmoredString(new ByteArrayInputStream(bytes)); + return toAsciiArmoredString(bytes, null); + } + + public static String toAsciiArmoredString(byte[] bytes, MultiMap additionalHeaderValues) throws IOException { + return toAsciiArmoredString(new ByteArrayInputStream(bytes), additionalHeaderValues); } public static String toAsciiArmoredString(InputStream inputStream) throws IOException { + return toAsciiArmoredString(inputStream, null); + } + + public static String toAsciiArmoredString(InputStream inputStream, MultiMap additionalHeaderValues) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); ArmoredOutputStream armor = ArmoredOutputStreamFactory.get(out); - + if (additionalHeaderValues != null) { + for (String header : additionalHeaderValues.keySet()) { + for (String value : additionalHeaderValues.get(header)) { + armor.addHeader(header, value); + } + } + } Streams.pipeAll(inputStream, armor); armor.close(); diff --git a/pgpainless-core/src/main/java/org/pgpainless/util/MultiMap.java b/pgpainless-core/src/main/java/org/pgpainless/util/MultiMap.java index d9b7c584..45c5000b 100644 --- a/pgpainless-core/src/main/java/org/pgpainless/util/MultiMap.java +++ b/pgpainless-core/src/main/java/org/pgpainless/util/MultiMap.java @@ -18,7 +18,7 @@ package org.pgpainless.util; import javax.annotation.Nonnull; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; @@ -33,7 +33,7 @@ public class MultiMap { public MultiMap(@Nonnull MultiMap other) { this.map = new HashMap<>(); for (K k : other.map.keySet()) { - map.put(k, new HashSet<>(other.map.get(k))); + map.put(k, new LinkedHashSet<>(other.map.get(k))); } } @@ -67,7 +67,7 @@ public class MultiMap { public void put(K k, V v) { Set values = map.get(k); if (values == null) { - values = new HashSet<>(); + values = new LinkedHashSet<>(); map.put(k, values); } values.add(v);