Skip to content

Commit

Permalink
#1736 FingerprintUtil: Add prettifyFingerprint method
Browse files Browse the repository at this point in the history
  • Loading branch information
gefeili committed Sep 4, 2024
2 parents 902266f + e081c2d commit d1a0f2c
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
76 changes: 76 additions & 0 deletions pg/src/main/java/org/bouncycastle/bcpg/FingerprintUtil.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,35 @@
package org.bouncycastle.bcpg;

import org.bouncycastle.util.Pack;
import org.bouncycastle.util.encoders.Hex;

public class FingerprintUtil
{

/**
* Derive a key-id from the given key fingerprint.
* This method can derive key-ids from v4, v5 (LibrePGP) and v6 keys.
* For keys with other versions (2,3) it will return 0.
*
* @param keyVersion version of the key
* @param fingerprint fingerprint of the key
* @return derived key-id
*/
public static long keyIdFromFingerprint(int keyVersion, byte[] fingerprint)
{
switch (keyVersion)
{
case PublicKeyPacket.VERSION_4:
return keyIdFromV4Fingerprint(fingerprint);
case PublicKeyPacket.LIBREPGP_5:
return keyIdFromLibrePgpFingerprint(fingerprint);
case PublicKeyPacket.VERSION_6:
return keyIdFromV6Fingerprint(fingerprint);
default:
return 0;
}
}

/**
* Derive a 64 bit key-id from a version 6 OpenPGP fingerprint.
* For v6 keys, the key-id corresponds to the left-most 8 octets of the fingerprint.
Expand Down Expand Up @@ -112,4 +137,55 @@ public static void writeKeyID(long keyID, byte[] bytes)
{
writeKeyID(keyID, bytes, 0);
}

public static String prettifyFingerprint(byte[] fingerprint)
{
// -DM Hex.toHexString
String hex = Hex.toHexString(fingerprint).toUpperCase();
StringBuilder sb = new StringBuilder();
switch (hex.length())
{
case 32:
// v3 keys
for (int i = 0; i < 4; i++)
{
sb.append(hex, i * 4, (i + 1) * 4).append(' ');
}
sb.append(' ');
for (int i = 4; i < 7; i++)
{
sb.append(hex, i * 4, (i + 1) * 4).append(' ');
}
sb.append(hex, 28, 32);
return sb.toString();
case 40:
// v4 keys
for (int i = 0; i <= 4; i++)
{
sb.append(hex, i * 4, (i + 1) * 4).append(' ');
}
sb.append(' ');
for (int i = 5; i <= 8; i++)
{
sb.append(hex, i * 4, (i + 1) * 4).append(' ');
}
sb.append(hex, 36, 40);
return sb.toString();
case 64:
// v5, v6 keys
for (int i = 0; i < 4; i++)
{
sb.append(hex, i * 8, (i + 1) * 8).append(' ');
}
sb.append(' ');
for (int i = 4; i < 7; i++)
{
sb.append(hex, i * 8, (i + 1) * 8).append(' ');
}
sb.append(hex, 56, 64);
return sb.toString();
default:
return hex;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,19 @@ private void testLibrePgpKeyIdFromFingerprint()
-3812177997909612905L, FingerprintUtil.keyIdFromLibrePgpFingerprint(decoded));
}

private void testKeyIdFromFingerprint()
{
isEquals("v4 key-id from fingerprint mismatch",
-5425419407118114754L, FingerprintUtil.keyIdFromFingerprint(
4, Hex.decode("1D018C772DF8C5EF86A1DCC9B4B509CB5936E03E")));
isEquals("v5 key-id from fingerprint mismatch",
-3812177997909612905L, FingerprintUtil.keyIdFromFingerprint(
5, Hex.decode("cb186c4f0609a697e4d52dfa6c722b0c1f1e27c18a56708f6525ec27bad9acc9")));
isEquals("v6 key-id from fingerprint mismatch",
-3812177997909612905L, FingerprintUtil.keyIdFromFingerprint(
6, Hex.decode("cb186c4f0609a697e4d52dfa6c722b0c1f1e27c18a56708f6525ec27bad9acc9")));
}

private void testLeftMostEqualsRightMostFor8Bytes()
{
byte[] bytes = new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
Expand Down Expand Up @@ -79,6 +92,23 @@ private void testWriteKeyIdToBytes()
}
}

private void testPrettifyFingerprint()
{
isEquals("Prettified v4 fingerprint mismatch",
"1D01 8C77 2DF8 C5EF 86A1 DCC9 B4B5 09CB 5936 E03E",
FingerprintUtil.prettifyFingerprint(Hex.decode("1D018C772DF8C5EF86A1DCC9B4B509CB5936E03E")));
isEquals("Prettified v5/v6 fingerprint mismatch",
"CB186C4F 0609A697 E4D52DFA 6C722B0C 1F1E27C1 8A56708F 6525EC27 BAD9ACC9",
FingerprintUtil.prettifyFingerprint(Hex.decode("cb186c4f0609a697e4d52dfa6c722b0c1f1e27c18a56708f6525ec27bad9acc9")));
}

private void testPrettifyFingerprintReturnsHexForUnknownFormat()
{
String fp = "C0FFEE1DECAFF0";
isEquals("Prettifying fingerprint with unknown format MUST return uppercase hex fingerprint",
fp, FingerprintUtil.prettifyFingerprint(Hex.decode(fp)));
}

@Override
public String getName()
{
Expand All @@ -95,6 +125,9 @@ public void performTest()
testLibrePgpKeyIdFromFingerprint();
testLeftMostEqualsRightMostFor8Bytes();
testWriteKeyIdToBytes();
testKeyIdFromFingerprint();
testPrettifyFingerprint();
testPrettifyFingerprintReturnsHexForUnknownFormat();
}

public static void main(String[] args)
Expand Down

0 comments on commit d1a0f2c

Please sign in to comment.