From 554fe279085a8e448d323b154ba68dbfa86adb51 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Thu, 2 May 2024 10:35:50 +0200 Subject: [PATCH 1/3] Use FingerprintUtil for deriving key-ID from fingerprint --- .../bcpg/OnePassSignaturePacket.java | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/pg/src/main/java/org/bouncycastle/bcpg/OnePassSignaturePacket.java b/pg/src/main/java/org/bouncycastle/bcpg/OnePassSignaturePacket.java index cf6189fdd4..3ffb8adbb8 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/OnePassSignaturePacket.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/OnePassSignaturePacket.java @@ -74,15 +74,7 @@ else if (version == VERSION_6) fingerprint = new byte[32]; in.readFully(fingerprint); - // TODO: Replace with FingerprintUtil - keyID = ((fingerprint[0] & 0xffL) << 56) | - ((fingerprint[1] & 0xffL) << 48) | - ((fingerprint[2] & 0xffL) << 40) | - ((fingerprint[3] & 0xffL) << 32) | - ((fingerprint[4] & 0xffL) << 24) | - ((fingerprint[5] & 0xffL) << 16) | - ((fingerprint[6] & 0xffL) << 8) | - ((fingerprint[7] & 0xffL)); + keyID = FingerprintUtil.keyIdFromV6Fingerprint(fingerprint); } else { @@ -154,15 +146,7 @@ public OnePassSignaturePacket( this.salt = salt; this.fingerprint = fingerprint; this.isContaining = (isNested) ? 0 : 1; - // TODO: Replace with FingerprintUtil - keyID = ((fingerprint[0] & 0xffL) << 56) | - ((fingerprint[1] & 0xffL) << 48) | - ((fingerprint[2] & 0xffL) << 40) | - ((fingerprint[3] & 0xffL) << 32) | - ((fingerprint[4] & 0xffL) << 24) | - ((fingerprint[5] & 0xffL) << 16) | - ((fingerprint[6] & 0xffL) << 8) | - ((fingerprint[7] & 0xffL)); + keyID = FingerprintUtil.keyIdFromV6Fingerprint(fingerprint); } /** From bc007226a809e8b09a7ad101c9a0a0a1a30dbec2 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Thu, 2 May 2024 10:57:13 +0200 Subject: [PATCH 2/3] Use FingerprintUtil in test --- .../bcpg/test/OnePassSignaturePacketTest.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/OnePassSignaturePacketTest.java b/pg/src/test/java/org/bouncycastle/bcpg/test/OnePassSignaturePacketTest.java index 9f26357554..109f062ab6 100644 --- a/pg/src/test/java/org/bouncycastle/bcpg/test/OnePassSignaturePacketTest.java +++ b/pg/src/test/java/org/bouncycastle/bcpg/test/OnePassSignaturePacketTest.java @@ -115,14 +115,7 @@ private void roundtripV6Packet() { byte[] salt = new byte[32]; byte[] fingerprint = Hex.decode("CB186C4F0609A697E4D52DFA6C722B0C1F1E27C18A56708F6525EC27BAD9ACC9"); - long keyID = ((fingerprint[0] & 0xffL) << 56) | - ((fingerprint[1] & 0xffL) << 48) | - ((fingerprint[2] & 0xffL) << 40) | - ((fingerprint[3] & 0xffL) << 32) | - ((fingerprint[4] & 0xffL) << 24) | - ((fingerprint[5] & 0xffL) << 16) | - ((fingerprint[6] & 0xffL) << 8) | - ((fingerprint[7] & 0xffL)); + long keyID = FingerprintUtil.keyIdFromV6Fingerprint(fingerprint); new SecureRandom().nextBytes(salt); OnePassSignaturePacket before = new OnePassSignaturePacket( From 5eed174d793ca542e36ad7907c82c17937b759ef Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Thu, 16 May 2024 10:53:02 +0200 Subject: [PATCH 3/3] Use Pack class for writing and reading key-IDs from byte arrays --- .../bouncycastle/bcpg/FingerprintUtil.java | 71 +++++++++++++------ .../bouncycastle/bcpg/sig/IssuerKeyID.java | 17 +---- .../bcpg/test/FingerprintUtilTest.java | 35 +++++++++ 3 files changed, 88 insertions(+), 35 deletions(-) diff --git a/pg/src/main/java/org/bouncycastle/bcpg/FingerprintUtil.java b/pg/src/main/java/org/bouncycastle/bcpg/FingerprintUtil.java index 8c8b74e040..6e258c623f 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/FingerprintUtil.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/FingerprintUtil.java @@ -1,5 +1,7 @@ package org.bouncycastle.bcpg; +import org.bouncycastle.util.Pack; + public class FingerprintUtil { @@ -47,18 +49,7 @@ public static long keyIdFromV4Fingerprint(byte[] v4Fingerprint) */ public static long longFromLeftMostBytes(byte[] bytes) { - if (bytes.length < 8) - { - throw new IllegalArgumentException("Byte array MUST contain at least 8 bytes"); - } - return ((bytes[0] & 0xffL) << 56) | - ((bytes[1] & 0xffL) << 48) | - ((bytes[2] & 0xffL) << 40) | - ((bytes[3] & 0xffL) << 32) | - ((bytes[4] & 0xffL) << 24) | - ((bytes[5] & 0xffL) << 16) | - ((bytes[6] & 0xffL) << 8) | - ((bytes[7] & 0xffL)); + return readKeyID(bytes); } /** @@ -68,19 +59,57 @@ public static long longFromLeftMostBytes(byte[] bytes) * @return long */ public static long longFromRightMostBytes(byte[] bytes) + { + return readKeyID(bytes, bytes.length - 8); + } + + /** + * Read a key-ID from the first 8 octets of the given byte array. + * @param bytes byte array + * @return key-ID + */ + public static long readKeyID(byte[] bytes) + { + return readKeyID(bytes, 0); + } + + /** + * Read a key-ID from 8 octets of the given byte array starting at offset. + * @param bytes byte array + * @param offset offset + * @return key-ID + */ + public static long readKeyID(byte[] bytes, int offset) { if (bytes.length < 8) { throw new IllegalArgumentException("Byte array MUST contain at least 8 bytes"); } - int i = bytes.length; - return ((bytes[i - 8] & 0xffL) << 56) | - ((bytes[i - 7] & 0xffL) << 48) | - ((bytes[i - 6] & 0xffL) << 40) | - ((bytes[i - 5] & 0xffL) << 32) | - ((bytes[i - 4] & 0xffL) << 24) | - ((bytes[i - 3] & 0xffL) << 16) | - ((bytes[i - 2] & 0xffL) << 8) | - ((bytes[i - 1] & 0xffL)); + return Pack.bigEndianToLong(bytes, offset); + } + + /** + * Write the key-ID encoded as 8 octets to the given byte array, starting at index offset. + * @param keyID keyID + * @param bytes byte array + * @param offset starting offset + */ + public static void writeKeyID(long keyID, byte[] bytes, int offset) + { + if (bytes.length - offset < 8) + { + throw new IllegalArgumentException("Not enough space to write key-ID to byte array."); + } + Pack.longToBigEndian(keyID, bytes, offset); + } + + /** + * Write the key-ID to the first 8 octets of the given byte array. + * @param keyID keyID + * @param bytes byte array + */ + public static void writeKeyID(long keyID, byte[] bytes) + { + writeKeyID(keyID, bytes, 0); } } diff --git a/pg/src/main/java/org/bouncycastle/bcpg/sig/IssuerKeyID.java b/pg/src/main/java/org/bouncycastle/bcpg/sig/IssuerKeyID.java index 737914cdfe..7b72728bb4 100644 --- a/pg/src/main/java/org/bouncycastle/bcpg/sig/IssuerKeyID.java +++ b/pg/src/main/java/org/bouncycastle/bcpg/sig/IssuerKeyID.java @@ -1,5 +1,6 @@ package org.bouncycastle.bcpg.sig; +import org.bouncycastle.bcpg.FingerprintUtil; import org.bouncycastle.bcpg.SignatureSubpacket; import org.bouncycastle.bcpg.SignatureSubpacketTags; @@ -13,16 +14,7 @@ protected static byte[] keyIDToBytes( long keyId) { byte[] data = new byte[8]; - - data[0] = (byte)(keyId >> 56); - data[1] = (byte)(keyId >> 48); - data[2] = (byte)(keyId >> 40); - data[3] = (byte)(keyId >> 32); - data[4] = (byte)(keyId >> 24); - data[5] = (byte)(keyId >> 16); - data[6] = (byte)(keyId >> 8); - data[7] = (byte)keyId; - + FingerprintUtil.writeKeyID(keyId, data); return data; } @@ -43,9 +35,6 @@ public IssuerKeyID( public long getKeyID() { - long keyID = ((long)(data[0] & 0xff) << 56) | ((long)(data[1] & 0xff) << 48) | ((long)(data[2] & 0xff) << 40) | ((long)(data[3] & 0xff) << 32) - | ((long)(data[4] & 0xff) << 24) | ((data[5] & 0xff) << 16) | ((data[6] & 0xff) << 8) | (data[7] & 0xff); - - return keyID; + return FingerprintUtil.readKeyID(data); } } diff --git a/pg/src/test/java/org/bouncycastle/bcpg/test/FingerprintUtilTest.java b/pg/src/test/java/org/bouncycastle/bcpg/test/FingerprintUtilTest.java index 94546232e6..3648c4b7fe 100644 --- a/pg/src/test/java/org/bouncycastle/bcpg/test/FingerprintUtilTest.java +++ b/pg/src/test/java/org/bouncycastle/bcpg/test/FingerprintUtilTest.java @@ -1,6 +1,7 @@ package org.bouncycastle.bcpg.test; import org.bouncycastle.bcpg.FingerprintUtil; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; @@ -46,6 +47,38 @@ private void testLibrePgpKeyIdFromFingerprint() -3812177997909612905L, FingerprintUtil.keyIdFromLibrePgpFingerprint(decoded)); } + private void testLeftMostEqualsRightMostFor8Bytes() + { + byte[] bytes = new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; + isEquals( + FingerprintUtil.longFromLeftMostBytes(bytes), + FingerprintUtil.longFromRightMostBytes(bytes)); + byte[] b = new byte[8]; + FingerprintUtil.writeKeyID(FingerprintUtil.longFromLeftMostBytes(bytes), b); + isTrue(Arrays.areEqual(bytes, b)); + } + + private void testWriteKeyIdToBytes() + { + byte[] bytes = new byte[12]; + long keyId = 72623859790382856L; + FingerprintUtil.writeKeyID(keyId, bytes, 2); + isTrue(Arrays.areEqual( + new byte[] {0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00}, + bytes)); + + try + { + byte[] b = new byte[7]; + FingerprintUtil.writeKeyID(0, b); + fail("Expected IllegalArgumentException for too short byte array."); + } + catch (IllegalArgumentException e) + { + // Expected + } + } + @Override public String getName() { @@ -60,6 +93,8 @@ public void performTest() testV6KeyIdFromFingerprint(); testKeyIdFromTooShortFails(); testLibrePgpKeyIdFromFingerprint(); + testLeftMostEqualsRightMostFor8Bytes(); + testWriteKeyIdToBytes(); } public static void main(String[] args)