1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-09-09 10:19:39 +02:00

Port some more tests

This commit is contained in:
Paul Schaub 2025-04-02 15:27:58 +02:00
parent f6284fd59b
commit c0207f50e9
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
3 changed files with 57 additions and 59 deletions

View file

@ -17,8 +17,9 @@ import java.nio.charset.StandardCharsets;
import org.bouncycastle.bcpg.KeyIdentifier; import org.bouncycastle.bcpg.KeyIdentifier;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -62,45 +63,46 @@ public class CertificateWithMissingSecretKeyTest {
"=eTh7\n" + "=eTh7\n" +
"-----END PGP PRIVATE KEY BLOCK-----"; "-----END PGP PRIVATE KEY BLOCK-----";
private static final long signingSubkeyId = -7647663290973502178L; private static final KeyIdentifier signingSubkeyId = new KeyIdentifier(-7647663290973502178L);
private static PGPSecretKeyRing missingSigningSecKey; private static OpenPGPKey missingSigningSecKey;
private static KeyIdentifier encryptionSubkeyId; private static KeyIdentifier encryptionSubkeyId;
private static PGPSecretKeyRing missingDecryptionSecKey; private static OpenPGPKey missingDecryptionSecKey;
private static final SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys(); private static final SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
@BeforeAll @BeforeAll
public static void prepare() throws IOException { public static void prepare() throws IOException {
PGPainless api = PGPainless.getInstance();
// missing signing sec key we read from bytes // missing signing sec key we read from bytes
missingSigningSecKey = PGPainless.readKeyRing().secretKeyRing(MISSING_SIGNING_SECKEY); missingSigningSecKey = api.readKey().parseKey(MISSING_SIGNING_SECKEY);
// missing encryption sec key we generate on the fly // missing encryption sec key we generate on the fly
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() OpenPGPKey secretKeys = api.generateKey()
.modernKeyRing("Missing Decryption Key <missing@decryption.key>") .modernKeyRing("Missing Decryption Key <missing@decryption.key>");
.getPGPSecretKeyRing(); encryptionSubkeyId = api.inspect(secretKeys)
encryptionSubkeyId = PGPainless.inspectKeyRing(secretKeys)
.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0).getKeyIdentifier(); .getEncryptionSubkeys(EncryptionPurpose.ANY).get(0).getKeyIdentifier();
// remove the encryption/decryption secret key // remove the encryption/decryption secret key
missingDecryptionSecKey = KeyRingUtils.stripSecretKey(secretKeys, encryptionSubkeyId.getKeyId()); PGPSecretKeyRing withSecretKeyStripped = KeyRingUtils.stripSecretKey(secretKeys.getPGPSecretKeyRing(), encryptionSubkeyId);
missingDecryptionSecKey = api.toKey(withSecretKeyStripped);
} }
@Test @Test
public void assureMissingSigningSecKeyOnlyContainSigningPubKey() { public void assureMissingSigningSecKeyOnlyContainSigningPubKey() {
assertNotNull(missingSigningSecKey.getPublicKey(signingSubkeyId)); assertNotNull(missingSigningSecKey.getKey(signingSubkeyId));
assertNull(missingSigningSecKey.getSecretKey(signingSubkeyId)); assertNull(missingSigningSecKey.getSecretKey(signingSubkeyId));
KeyRingInfo info = PGPainless.inspectKeyRing(missingSigningSecKey); KeyRingInfo info = PGPainless.getInstance().inspect(missingSigningSecKey);
assertFalse(info.getSigningSubkeys().isEmpty()); // This method only tests for pub keys. assertFalse(info.getSigningSubkeys().isEmpty()); // This method only tests for pub keys.
} }
@Test @Test
public void assureMissingDecryptionSecKeyOnlyContainsEncryptionPubKey() { public void assureMissingDecryptionSecKeyOnlyContainsEncryptionPubKey() {
assertNotNull(missingDecryptionSecKey.getPublicKey(encryptionSubkeyId)); assertNotNull(missingDecryptionSecKey.getKey(encryptionSubkeyId));
assertNull(missingDecryptionSecKey.getSecretKey(encryptionSubkeyId)); assertNull(missingDecryptionSecKey.getSecretKey(encryptionSubkeyId));
KeyRingInfo info = PGPainless.inspectKeyRing(missingDecryptionSecKey); KeyRingInfo info = PGPainless.getInstance().inspect(missingDecryptionSecKey);
assertFalse(info.getEncryptionSubkeys(EncryptionPurpose.ANY).isEmpty()); // pub key is still there assertFalse(info.getEncryptionSubkeys(EncryptionPurpose.ANY).isEmpty()); // pub key is still there
} }
@ -119,12 +121,14 @@ public class CertificateWithMissingSecretKeyTest {
ByteArrayInputStream in = new ByteArrayInputStream("Hello, World!\n".getBytes(StandardCharsets.UTF_8)); ByteArrayInputStream in = new ByteArrayInputStream("Hello, World!\n".getBytes(StandardCharsets.UTF_8));
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
PGPPublicKeyRing certificate = PGPainless.extractCertificate(missingDecryptionSecKey); PGPainless api = PGPainless.getInstance();
OpenPGPCertificate certificate = missingDecryptionSecKey.toCertificate();
ProducerOptions producerOptions = ProducerOptions.encrypt( ProducerOptions producerOptions = ProducerOptions.encrypt(
EncryptionOptions.encryptCommunications() EncryptionOptions.encryptCommunications(api)
.addRecipient(certificate)); // we can still encrypt, since the pub key is still there .addRecipient(certificate)); // we can still encrypt, since the pub key is still there
EncryptionStream encryptionStream = PGPainless.encryptAndOrSign() EncryptionStream encryptionStream = api.generateMessage()
.onOutputStream(out) .onOutputStream(out)
.withOptions(producerOptions); .withOptions(producerOptions);
@ -136,7 +140,7 @@ public class CertificateWithMissingSecretKeyTest {
// Test decryption // Test decryption
ByteArrayInputStream cipherIn = new ByteArrayInputStream(out.toByteArray()); ByteArrayInputStream cipherIn = new ByteArrayInputStream(out.toByteArray());
ConsumerOptions consumerOptions = ConsumerOptions.get() ConsumerOptions consumerOptions = ConsumerOptions.get(api)
.addDecryptionKey(missingDecryptionSecKey); .addDecryptionKey(missingDecryptionSecKey);
assertThrows(MissingDecryptionMethodException.class, () -> assertThrows(MissingDecryptionMethodException.class, () ->

View file

@ -19,9 +19,9 @@ import java.nio.charset.StandardCharsets;
import java.util.Random; import java.util.Random;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
@ -36,7 +36,6 @@ import org.pgpainless.exception.WrongConsumingMethodException;
import org.pgpainless.key.TestKeys; import org.pgpainless.key.TestKeys;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.signature.SignatureUtils; import org.pgpainless.signature.SignatureUtils;
import org.pgpainless.util.ArmorUtils;
import org.pgpainless.util.TestUtils; import org.pgpainless.util.TestUtils;
public class CleartextSignatureVerificationTest { public class CleartextSignatureVerificationTest {
@ -73,13 +72,14 @@ public class CleartextSignatureVerificationTest {
public static final String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; public static final String alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
public static final Random random = new Random(); public static final Random random = new Random();
private static final PGPainless api = PGPainless.getInstance();
@Test @Test
public void cleartextSignVerification_InMemoryMultiPassStrategy() public void cleartextSignVerification_InMemoryMultiPassStrategy()
throws IOException, PGPException { throws IOException, PGPException {
PGPPublicKeyRing signingKeys = TestKeys.getEmilPublicKeyRing(); OpenPGPCertificate signingCert = TestKeys.getEmilCertificate();
ConsumerOptions options = ConsumerOptions.get() ConsumerOptions options = ConsumerOptions.get(api)
.addVerificationCert(signingKeys); .addVerificationCert(signingCert);
InMemoryMultiPassStrategy multiPassStrategy = MultiPassStrategy.keepMessageInMemory(); InMemoryMultiPassStrategy multiPassStrategy = MultiPassStrategy.keepMessageInMemory();
options.setMultiPassStrategy(multiPassStrategy); options.setMultiPassStrategy(multiPassStrategy);
@ -97,16 +97,16 @@ public class CleartextSignatureVerificationTest {
PGPSignature signature = result.getVerifiedSignatures().iterator().next().getSignature(); PGPSignature signature = result.getVerifiedSignatures().iterator().next().getSignature();
assertEquals(signature.getKeyID(), signingKeys.getPublicKey().getKeyID()); assertTrue(signature.hasKeyIdentifier(signingCert.getKeyIdentifier()));
assertArrayEquals(MESSAGE_BODY, out.toByteArray()); assertArrayEquals(MESSAGE_BODY, out.toByteArray());
} }
@Test @Test
public void cleartextSignVerification_FileBasedMultiPassStrategy() public void cleartextSignVerification_FileBasedMultiPassStrategy()
throws IOException, PGPException { throws IOException, PGPException {
PGPPublicKeyRing signingKeys = TestKeys.getEmilPublicKeyRing(); OpenPGPCertificate signingCert = TestKeys.getEmilCertificate();
ConsumerOptions options = ConsumerOptions.get() ConsumerOptions options = ConsumerOptions.get(api)
.addVerificationCert(signingKeys); .addVerificationCert(signingCert);
File tempDir = TestUtils.createTempDirectory(); File tempDir = TestUtils.createTempDirectory();
File file = new File(tempDir, "file"); File file = new File(tempDir, "file");
@ -125,7 +125,7 @@ public class CleartextSignatureVerificationTest {
PGPSignature signature = result.getVerifiedSignatures().iterator().next().getSignature(); PGPSignature signature = result.getVerifiedSignatures().iterator().next().getSignature();
assertEquals(signature.getKeyID(), signingKeys.getPublicKey().getKeyID()); assertTrue(signature.hasKeyIdentifier(signingCert.getKeyIdentifier()));
FileInputStream fileIn = new FileInputStream(file); FileInputStream fileIn = new FileInputStream(file);
ByteArrayOutputStream bytes = new ByteArrayOutputStream(); ByteArrayOutputStream bytes = new ByteArrayOutputStream();
Streams.pipeAll(fileIn, bytes); Streams.pipeAll(fileIn, bytes);
@ -135,8 +135,8 @@ public class CleartextSignatureVerificationTest {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
// CHECKSTYLE:OFF // CHECKSTYLE:OFF
PGPPublicKeyRing keys = TestKeys.getEmilPublicKeyRing(); OpenPGPCertificate cert = TestKeys.getEmilCertificate();
System.out.println(ArmorUtils.toAsciiArmoredString(keys)); System.out.println(cert.toAsciiArmoredString());
System.out.println(new String(MESSAGE_SIGNED)); System.out.println(new String(MESSAGE_SIGNED));
System.out.println(new String(MESSAGE_BODY)); System.out.println(new String(MESSAGE_BODY));
System.out.println(new String(SIGNATURE)); System.out.println(new String(SIGNATURE));
@ -148,8 +148,8 @@ public class CleartextSignatureVerificationTest {
throws IOException, PGPException { throws IOException, PGPException {
PGPSignature signature = SignatureUtils.readSignatures(SIGNATURE).get(0); PGPSignature signature = SignatureUtils.readSignatures(SIGNATURE).get(0);
ConsumerOptions options = ConsumerOptions.get() ConsumerOptions options = ConsumerOptions.get(api)
.addVerificationCert(TestKeys.getEmilPublicKeyRing()) .addVerificationCert(TestKeys.getEmilCertificate())
.addVerificationOfDetachedSignature(signature); .addVerificationOfDetachedSignature(signature);
DecryptionStream decryptionStream = PGPainless.decryptAndOrVerify() DecryptionStream decryptionStream = PGPainless.decryptAndOrVerify()
@ -170,10 +170,10 @@ public class CleartextSignatureVerificationTest {
String message = "Foo\nBar"; // PGPUtil.getDecoderStream() would have mistaken this for base64 data String message = "Foo\nBar"; // PGPUtil.getDecoderStream() would have mistaken this for base64 data
ByteArrayInputStream msgIn = new ByteArrayInputStream(message.getBytes(StandardCharsets.UTF_8)); ByteArrayInputStream msgIn = new ByteArrayInputStream(message.getBytes(StandardCharsets.UTF_8));
PGPSecretKeyRing secretKey = TestKeys.getEmilSecretKeyRing(); OpenPGPKey secretKey = TestKeys.getEmilKey();
ByteArrayOutputStream signedOut = new ByteArrayOutputStream(); ByteArrayOutputStream signedOut = new ByteArrayOutputStream();
EncryptionStream signingStream = PGPainless.encryptAndOrSign().onOutputStream(signedOut) EncryptionStream signingStream = api.generateMessage().onOutputStream(signedOut)
.withOptions(ProducerOptions.sign(SigningOptions.get() .withOptions(ProducerOptions.sign(SigningOptions.get(api)
.addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(), secretKey, DocumentSignatureType.CANONICAL_TEXT_DOCUMENT)) .addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(), secretKey, DocumentSignatureType.CANONICAL_TEXT_DOCUMENT))
.setCleartextSigned()); .setCleartextSigned());
@ -185,8 +185,8 @@ public class CleartextSignatureVerificationTest {
ByteArrayInputStream signedIn = new ByteArrayInputStream(signed.getBytes(StandardCharsets.UTF_8)); ByteArrayInputStream signedIn = new ByteArrayInputStream(signed.getBytes(StandardCharsets.UTF_8));
DecryptionStream verificationStream = PGPainless.decryptAndOrVerify() DecryptionStream verificationStream = PGPainless.decryptAndOrVerify()
.onInputStream(signedIn) .onInputStream(signedIn)
.withOptions(ConsumerOptions.get() .withOptions(ConsumerOptions.get(api)
.addVerificationCert(TestKeys.getEmilPublicKeyRing())); .addVerificationCert(TestKeys.getEmilCertificate()));
ByteArrayOutputStream msgOut = new ByteArrayOutputStream(); ByteArrayOutputStream msgOut = new ByteArrayOutputStream();
Streams.pipeAll(verificationStream, msgOut); Streams.pipeAll(verificationStream, msgOut);
@ -201,13 +201,12 @@ public class CleartextSignatureVerificationTest {
throws PGPException, IOException { throws PGPException, IOException {
String message = randomString(28, 4000); String message = randomString(28, 4000);
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().modernKeyRing("Alice") OpenPGPKey secretKeys = api.generateKey().modernKeyRing("Alice");
.getPGPSecretKeyRing();
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
EncryptionStream encryptionStream = PGPainless.encryptAndOrSign() EncryptionStream encryptionStream = api.generateMessage()
.onOutputStream(out) .onOutputStream(out)
.withOptions(ProducerOptions.sign( .withOptions(ProducerOptions.sign(
SigningOptions.get() SigningOptions.get(api)
.addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(), .addDetachedSignature(SecretKeyRingProtector.unprotectedKeys(),
secretKeys, DocumentSignatureType.CANONICAL_TEXT_DOCUMENT) secretKeys, DocumentSignatureType.CANONICAL_TEXT_DOCUMENT)
).setCleartextSigned()); ).setCleartextSigned());
@ -221,7 +220,7 @@ public class CleartextSignatureVerificationTest {
DecryptionStream decryptionStream = PGPainless.decryptAndOrVerify() DecryptionStream decryptionStream = PGPainless.decryptAndOrVerify()
.onInputStream(in) .onInputStream(in)
.withOptions(ConsumerOptions.get() .withOptions(ConsumerOptions.get()
.addVerificationCert(PGPainless.extractCertificate(secretKeys))); .addVerificationCert(secretKeys.toCertificate()));
out = new ByteArrayOutputStream(); out = new ByteArrayOutputStream();
Streams.pipeAll(decryptionStream, out); Streams.pipeAll(decryptionStream, out);

View file

@ -5,15 +5,11 @@
package org.pgpainless.decryption_verification; package org.pgpainless.decryption_verification;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.api.OpenPGPCertificate; import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.EncryptionPurpose; import org.pgpainless.algorithm.EncryptionPurpose;
@ -35,22 +31,21 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
public class CustomPublicKeyDataDecryptorFactoryTest { public class CustomPublicKeyDataDecryptorFactoryTest {
@Test @Test
@Disabled
public void testDecryptionWithEmulatedHardwareDecryptionCallback() public void testDecryptionWithEmulatedHardwareDecryptionCallback()
throws PGPException, IOException { throws PGPException, IOException {
PGPSecretKeyRing secretKey = PGPainless.generateKeyRing().modernKeyRing("Alice") PGPainless api = PGPainless.getInstance();
.getPGPSecretKeyRing(); OpenPGPKey secretKey = api.generateKey().modernKeyRing("Alice");
PGPPublicKeyRing cert = PGPainless.extractCertificate(secretKey); OpenPGPCertificate cert = secretKey.toCertificate();
KeyRingInfo info = PGPainless.inspectKeyRing(secretKey); KeyRingInfo info = api.inspect(secretKey);
OpenPGPCertificate.OpenPGPComponentKey encryptionKey = OpenPGPCertificate.OpenPGPComponentKey encryptionKey =
info.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0); info.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0);
// Encrypt a test message // Encrypt a test message
String plaintext = "Hello, World!\n"; String plaintext = "Hello, World!\n";
ByteArrayOutputStream ciphertextOut = new ByteArrayOutputStream(); ByteArrayOutputStream ciphertextOut = new ByteArrayOutputStream();
EncryptionStream encryptionStream = PGPainless.encryptAndOrSign() EncryptionStream encryptionStream = api.generateMessage()
.onOutputStream(ciphertextOut) .onOutputStream(ciphertextOut)
.withOptions(ProducerOptions.encrypt(EncryptionOptions.get() .withOptions(ProducerOptions.encrypt(EncryptionOptions.get(api)
.addRecipient(cert))); .addRecipient(cert)));
encryptionStream.write(plaintext.getBytes(StandardCharsets.UTF_8)); encryptionStream.write(plaintext.getBytes(StandardCharsets.UTF_8));
encryptionStream.close(); encryptionStream.close();
@ -61,9 +56,9 @@ public class CustomPublicKeyDataDecryptorFactoryTest {
throws HardwareSecurity.HardwareSecurityException { throws HardwareSecurity.HardwareSecurityException {
// Emulate hardware decryption. // Emulate hardware decryption.
try { try {
PGPSecretKey decryptionKey = secretKey.getSecretKey(encryptionKey.getKeyIdentifier()); OpenPGPKey.OpenPGPSecretKey decryptionKey = secretKey.getSecretKey(encryptionKey.getKeyIdentifier());
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(decryptionKey, Passphrase.emptyPassphrase()); OpenPGPKey.OpenPGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(decryptionKey, Passphrase.emptyPassphrase());
PublicKeyDataDecryptorFactory internal = new BcPublicKeyDataDecryptorFactory(privateKey); PublicKeyDataDecryptorFactory internal = new BcPublicKeyDataDecryptorFactory(privateKey.getKeyPair().getPrivateKey());
return internal.recoverSessionData(keyAlgorithm, new byte[][] {sessionKeyData}, pkeskVersion); return internal.recoverSessionData(keyAlgorithm, new byte[][] {sessionKeyData}, pkeskVersion);
} catch (PGPException e) { } catch (PGPException e) {
throw new HardwareSecurity.HardwareSecurityException(); throw new HardwareSecurity.HardwareSecurityException();
@ -77,7 +72,7 @@ public class CustomPublicKeyDataDecryptorFactoryTest {
.withOptions(ConsumerOptions.get() .withOptions(ConsumerOptions.get()
.addCustomDecryptorFactory( .addCustomDecryptorFactory(
new HardwareSecurity.HardwareDataDecryptorFactory( new HardwareSecurity.HardwareDataDecryptorFactory(
new SubkeyIdentifier(cert, encryptionKey.getKeyIdentifier()), new SubkeyIdentifier(encryptionKey),
hardwareDecryptionCallback))); hardwareDecryptionCallback)));
ByteArrayOutputStream decryptedOut = new ByteArrayOutputStream(); ByteArrayOutputStream decryptedOut = new ByteArrayOutputStream();