Skip to content

Commit 9cd655b

Browse files
committed
Improve PGPv6KeyTest
1 parent c2af444 commit 9cd655b

File tree

1 file changed

+142
-13
lines changed

1 file changed

+142
-13
lines changed

pg/src/test/java/org/bouncycastle/openpgp/test/PGPv6KeyTest.java

Lines changed: 142 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,31 @@
11
package org.bouncycastle.openpgp.test;
22

33
import java.io.ByteArrayInputStream;
4+
import java.io.IOException;
5+
import java.nio.charset.StandardCharsets;
6+
import java.util.Date;
47
import java.util.Iterator;
58

9+
import org.bouncycastle.bcpg.AEADAlgorithmTags;
610
import org.bouncycastle.bcpg.ArmoredInputStream;
711
import org.bouncycastle.bcpg.BCPGInputStream;
12+
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
13+
import org.bouncycastle.bcpg.PublicKeyPacket;
14+
import org.bouncycastle.bcpg.SecretKeyPacket;
15+
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
16+
import org.bouncycastle.jce.provider.BouncyCastleProvider;
17+
import org.bouncycastle.openpgp.PGPException;
818
import org.bouncycastle.openpgp.PGPPublicKey;
919
import org.bouncycastle.openpgp.PGPPublicKeyRing;
1020
import org.bouncycastle.openpgp.PGPSecretKey;
1121
import org.bouncycastle.openpgp.PGPSecretKeyRing;
1222
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
1323
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
14-
import org.bouncycastle.util.Arrays;
24+
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
1525
import org.bouncycastle.util.encoders.Hex;
16-
import org.bouncycastle.util.test.SimpleTest;
1726

1827
public class PGPv6KeyTest
19-
extends SimpleTest
28+
extends AbstractPgpKeyPairTest
2029
{
2130

2231
private static final String ARMORED_CERT = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
@@ -45,9 +54,31 @@ public class PGPv6KeyTest
4554
"M0g12vYxoWM8Y81W+bHBw805I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUr\n" +
4655
"k0mXubZvyl4GBg==\n" +
4756
"-----END PGP PRIVATE KEY BLOCK-----";
57+
// https://www.rfc-editor.org/rfc/rfc9580.html#name-sample-locked-version-6-sec
58+
private static final String ARMORED_PROTECTED_KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
59+
"\n" +
60+
"xYIGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laP9JgkC\n" +
61+
"FARdb9ccngltHraRe25uHuyuAQQVtKipJ0+r5jL4dacGWSAheCWPpITYiyfyIOPS\n" +
62+
"3gIDyg8f7strd1OB4+LZsUhcIjOMpVHgmiY/IutJkulneoBYwrEGHxsKAAAAQgWC\n" +
63+
"Y4d/4wMLCQcFFQoOCAwCFgACmwMCHgkiIQbLGGxPBgmml+TVLfpscisMHx4nwYpW\n" +
64+
"cI9lJewnutmsyQUnCQIHAgAAAACtKCAQPi19In7A5tfORHHbNr/JcIMlNpAnFJin\n" +
65+
"7wV2wH+q4UWFs7kDsBJ+xP2i8CMEWi7Ha8tPlXGpZR4UruETeh1mhELIj5UeM8T/\n" +
66+
"0z+5oX1RHu11j8bZzFDLX9eTsgOdWATHggZjh3/jGQAAACCGkySDZ/nlAV25Ivj0\n" +
67+
"gJXdp4SYfy1ZhbEvutFsr15ENf0mCQIUBA5hhGgp2oaavg6mFUXcFMwBBBUuE8qf\n" +
68+
"9Ock+xwusd+GAglBr5LVyr/lup3xxQvHXFSjjA2haXfoN6xUGRdDEHI6+uevKjVR\n" +
69+
"v5oAxgu7eJpaXNjCmwYYGwoAAAAsBYJjh3/jApsMIiEGyxhsTwYJppfk1S36bHIr\n" +
70+
"DB8eJ8GKVnCPZSXsJ7rZrMkAAAAABAEgpukYbZ1ZNfyP5WMUzbUnSGpaUSD5t2Ki\n" +
71+
"Nacp8DkBClZRa2c3AMQzSDXa9jGhYzxjzVb5scHDzTkjyRZWRdTq8U6L4da+/+Kt\n" +
72+
"ruh8m7Xo2ehSSFyWRSuTSZe5tm/KXgYG\n" +
73+
"-----END PGP PRIVATE KEY BLOCK-----";
74+
private static final Date CREATION_TIME = parseUTCTimestamp("2022-11-30 16:08:03 UTC");
75+
4876
private static final byte[] PRIMARY_FINGERPRINT = Hex.decode("CB186C4F0609A697E4D52DFA6C722B0C1F1E27C18A56708F6525EC27BAD9ACC9");
4977
private static final byte[] SUBKEY_FINGERPRINT = Hex.decode("12C83F1E706F6308FE151A417743A1F033790E93E9978488D1DB378DA9930885");
78+
private static final long PRIMARY_KEYID = -3812177997909612905L;
79+
private static final long SUBKEY_KEYID = 1353401087992750856L;
5080

81+
private static final KeyFingerPrintCalculator fingerPrintCalculator = new BcKeyFingerprintCalculator();
5182

5283
@Override
5384
public String getName()
@@ -59,7 +90,15 @@ public String getName()
5990
public void performTest()
6091
throws Exception
6192
{
62-
KeyFingerPrintCalculator fingerPrintCalculator = new BcKeyFingerprintCalculator();
93+
parseUnprotectedCertTest();
94+
parseUnprotectedKeyTest();
95+
testJcaFingerprintCalculation();
96+
parseProtectedKeyTest();
97+
}
98+
99+
private void parseUnprotectedCertTest()
100+
throws IOException
101+
{
63102
ByteArrayInputStream bIn = new ByteArrayInputStream(ARMORED_CERT.getBytes());
64103
ArmoredInputStream armorIn = new ArmoredInputStream(bIn);
65104
BCPGInputStream bcIn = new BCPGInputStream(armorIn);
@@ -68,22 +107,112 @@ public void performTest()
68107

69108
Iterator<PGPPublicKey> pIt = publicKeys.getPublicKeys();
70109
PGPPublicKey key = (PGPPublicKey)pIt.next();
71-
isTrue(key.hasFingerprint(PRIMARY_FINGERPRINT));
110+
isTrue("Primary key fingerprint mismatch", key.hasFingerprint(PRIMARY_FINGERPRINT));
111+
isEquals("Primary key-ID mismatch", PRIMARY_KEYID, key.getKeyID());
112+
isEquals("Primary key version mismatch", PublicKeyPacket.VERSION_6, key.getVersion());
113+
isEquals("Primary key creation time mismatch", CREATION_TIME, key.getCreationTime());
114+
isEquals("Primary key bit-strength mismatch", 256, key.getBitStrength());
115+
72116
key = (PGPPublicKey)pIt.next();
73-
isTrue(key.hasFingerprint(SUBKEY_FINGERPRINT));
117+
isTrue("Subkey fingerprint mismatch", key.hasFingerprint(SUBKEY_FINGERPRINT));
118+
isEquals("Subkey key-ID mismatch", SUBKEY_KEYID, key.getKeyID());
119+
isEquals("Subkey version mismatch", PublicKeyPacket.VERSION_6, key.getVersion());
120+
isEquals("Subkey creation time mismatch", CREATION_TIME, key.getCreationTime());
121+
isEquals("Subkey bit-strength mismatch", 256, key.getBitStrength());
74122

75-
bIn = new ByteArrayInputStream(ARMORED_KEY.getBytes());
76-
armorIn = new ArmoredInputStream(bIn);
77-
bcIn = new BCPGInputStream(armorIn);
123+
isFalse("Unexpected key object in key ring", pIt.hasNext());
124+
}
125+
126+
private void parseUnprotectedKeyTest()
127+
throws IOException, PGPException
128+
{
129+
ByteArrayInputStream bIn = new ByteArrayInputStream(ARMORED_KEY.getBytes());
130+
ArmoredInputStream armorIn = new ArmoredInputStream(bIn);
131+
BCPGInputStream bcIn = new BCPGInputStream(armorIn);
78132

79133
PGPSecretKeyRing secretKeys = new PGPSecretKeyRing(bcIn, fingerPrintCalculator);
80134

81135
Iterator<PGPSecretKey> sIt = secretKeys.getSecretKeys();
82-
PGPSecretKey sKey = (PGPSecretKey)sIt.next();
83-
isTrue(Arrays.areEqual(PRIMARY_FINGERPRINT, sKey.getFingerprint()));
136+
PGPSecretKey key = (PGPSecretKey)sIt.next();
137+
isEncodingEqual("Primary key fingerprint mismatch", PRIMARY_FINGERPRINT, key.getFingerprint());
138+
isEquals("Primary key-ID mismatch", PRIMARY_KEYID, key.getKeyID());
139+
isEquals("Primary key version mismatch", PublicKeyPacket.VERSION_6, key.getPublicKey().getVersion());
140+
isEquals("Primary key creation time mismatch", CREATION_TIME, key.getPublicKey().getCreationTime());
141+
isEquals("Primary key S2K-usage mismatch", SecretKeyPacket.USAGE_NONE, key.getS2KUsage());
142+
isNull("Primary key S2K MUST be null", key.getS2K());
143+
144+
key = (PGPSecretKey)sIt.next();
145+
isEncodingEqual("Subkey fingerprint mismatch", SUBKEY_FINGERPRINT, key.getFingerprint());
146+
isEquals("Subkey key-ID mismatch", SUBKEY_KEYID, key.getKeyID());
147+
isEquals("Subkey version mismatch", PublicKeyPacket.VERSION_6, key.getPublicKey().getVersion());
148+
isEquals("Subkey creation time mismatch", CREATION_TIME, key.getPublicKey().getCreationTime());
149+
isEquals("Subkey S2K-usage mismatch", SecretKeyPacket.USAGE_NONE, key.getS2KUsage());
150+
isNull("Subkey S2K MUST be null", key.getS2K());
151+
152+
isFalse("Unexpected key object in key ring", sIt.hasNext());
153+
}
154+
155+
private void testJcaFingerprintCalculation()
156+
throws IOException
157+
{
158+
ByteArrayInputStream bIn = new ByteArrayInputStream(ARMORED_CERT.getBytes());
159+
ArmoredInputStream armorIn = new ArmoredInputStream(bIn);
160+
BCPGInputStream bcIn = new BCPGInputStream(armorIn);
161+
162+
JcaKeyFingerprintCalculator fpCalc = new JcaKeyFingerprintCalculator();
163+
fpCalc.setProvider(new BouncyCastleProvider());
164+
PGPPublicKeyRing publicKeys = new PGPPublicKeyRing(bcIn, fpCalc);
165+
166+
Iterator<PGPPublicKey> pIt = publicKeys.getPublicKeys();
167+
PGPPublicKey key = (PGPPublicKey)pIt.next();
168+
isTrue("Primary key fingerprint mismatch", key.hasFingerprint(PRIMARY_FINGERPRINT));
169+
isEquals("Primary key-ID mismatch", PRIMARY_KEYID, key.getKeyID());
170+
key = (PGPPublicKey)pIt.next();
171+
isTrue("Subkey fingerprint mismatch", key.hasFingerprint(SUBKEY_FINGERPRINT));
172+
isEquals("Subkey key-ID mismatch", SUBKEY_KEYID, key.getKeyID());
173+
}
174+
175+
private void parseProtectedKeyTest()
176+
throws IOException, PGPException
177+
{
178+
ByteArrayInputStream bIn = new ByteArrayInputStream(ARMORED_PROTECTED_KEY.getBytes(StandardCharsets.UTF_8));
179+
ArmoredInputStream aIn = new ArmoredInputStream(bIn);
180+
BCPGInputStream pIn = new BCPGInputStream(aIn);
181+
182+
PGPSecretKeyRing secretKeys = new PGPSecretKeyRing(pIn, fingerPrintCalculator);
183+
Iterator<PGPSecretKey> sIt = secretKeys.getSecretKeys();
184+
185+
PGPSecretKey key = sIt.next();
186+
isEncodingEqual("Primary key fingerprint mismatch", PRIMARY_FINGERPRINT, key.getFingerprint());
187+
isEquals("Primary key ID mismatch", PRIMARY_KEYID, key.getKeyID());
188+
isEquals("Primary key algorithm mismatch",
189+
PublicKeyAlgorithmTags.Ed25519, key.getPublicKey().getAlgorithm());
190+
isEquals("Primary key version mismatch", PublicKeyPacket.VERSION_6, key.getPublicKey().getVersion());
191+
isEquals("Primary key creation time mismatch", CREATION_TIME, key.getPublicKey().getCreationTime());
192+
isEquals("Primary key S2K-Usage mismatch", SecretKeyPacket.USAGE_AEAD, key.getS2KUsage());
193+
isEquals("Primary key AEAD algorithm mismatch",
194+
AEADAlgorithmTags.OCB, key.getAEADKeyEncryptionAlgorithm());
195+
isEquals("Primary key protection algorithm mismatch",
196+
SymmetricKeyAlgorithmTags.AES_256, key.getKeyEncryptionAlgorithm());
197+
isEncodingEqual("Primary key S2K salt mismatch",
198+
Hex.decode("5d6fd71c9e096d1eb6917b6e6e1eecae"), key.getS2K().getIV());
199+
200+
key = sIt.next();
201+
isEncodingEqual("Subkey fingerprint mismatch", SUBKEY_FINGERPRINT, key.getFingerprint());
202+
isEquals("Subkey ID mismatch", SUBKEY_KEYID, key.getKeyID());
203+
isEquals("Subkey algorithm mismatch",
204+
PublicKeyAlgorithmTags.X25519, key.getPublicKey().getAlgorithm());
205+
isEquals("Subkey version mismatch", PublicKeyPacket.VERSION_6, key.getPublicKey().getVersion());
206+
isEquals("Subkey creation time mismatch", CREATION_TIME, key.getPublicKey().getCreationTime());
207+
isEquals("Subkey S2K-Usage mismatch", SecretKeyPacket.USAGE_AEAD, key.getS2KUsage());
208+
isEquals("Subkey AEAD algorithm mismatch",
209+
AEADAlgorithmTags.OCB, key.getAEADKeyEncryptionAlgorithm());
210+
isEquals("Subkey protection algorithm mismatch",
211+
SymmetricKeyAlgorithmTags.AES_256, key.getKeyEncryptionAlgorithm());
212+
isEncodingEqual("Subkey S2K salt mismatch",
213+
Hex.decode("0e61846829da869abe0ea61545dc14cc"), key.getS2K().getIV());
84214

85-
sKey = (PGPSecretKey)sIt.next();
86-
isTrue(Arrays.areEqual(SUBKEY_FINGERPRINT, sKey.getFingerprint()));
215+
isFalse("Unexpected key in key ring", sIt.hasNext());
87216
}
88217

89218
public static void main(String[] args)

0 commit comments

Comments
 (0)