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

WIP: Transform Options and OpenPgpMessageInputStream

This commit is contained in:
Paul Schaub 2025-02-10 17:05:16 +01:00
parent 337dbbbc0a
commit c039ab543a
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
13 changed files with 231 additions and 111 deletions

View file

@ -17,6 +17,8 @@ import org.bouncycastle.bcpg.S2K;
import org.bouncycastle.bcpg.SecretKeyPacket;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.bouncycastle.openpgp.api.OpenPGPKeyReader;
import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless;
import org.pgpainless.key.SubkeyIdentifier;
@ -178,8 +180,9 @@ public class GnuPGDummyKeyUtilTest {
@Test
public void testMoveAllKeysToCard() throws IOException {
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
PGPSecretKeyRing expected = PGPainless.readKeyRing().secretKeyRing(ALL_KEYS_ON_CARD);
OpenPGPKeyReader reader = PGPainless.getInstance().readKey();
OpenPGPKey secretKeys = reader.parseKey(FULL_KEY);
OpenPGPKey expected = reader.parseKey(ALL_KEYS_ON_CARD);
PGPSecretKeyRing onCard = GnuPGDummyKeyUtil.modify(secretKeys)
.divertPrivateKeysToCard(GnuPGDummyKeyUtil.KeyFilter.any(), cardSerial);
@ -190,46 +193,50 @@ public class GnuPGDummyKeyUtilTest {
assertEquals(S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD, s2K.getProtectionMode());
}
assertArrayEquals(expected.getEncoded(), onCard.getEncoded());
assertArrayEquals(expected.getPGPSecretKeyRing().getEncoded(), onCard.getEncoded());
}
@Test
public void testMovePrimaryKeyToCard() throws IOException {
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
PGPSecretKeyRing expected = PGPainless.readKeyRing().secretKeyRing(PRIMARY_KEY_ON_CARD);
OpenPGPKeyReader reader = PGPainless.getInstance().readKey();
OpenPGPKey secretKeys = reader.parseKey(FULL_KEY);
OpenPGPKey expected = reader.parseKey(PRIMARY_KEY_ON_CARD);
PGPSecretKeyRing onCard = GnuPGDummyKeyUtil.modify(secretKeys)
.divertPrivateKeysToCard(GnuPGDummyKeyUtil.KeyFilter.only(primaryKeyId), cardSerial);
assertArrayEquals(expected.getEncoded(), onCard.getEncoded());
assertArrayEquals(expected.getPGPSecretKeyRing().getEncoded(), onCard.getEncoded());
}
@Test
public void testMoveEncryptionKeyToCard() throws IOException {
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
PGPSecretKeyRing expected = PGPainless.readKeyRing().secretKeyRing(ENCRYPTION_KEY_ON_CARD);
OpenPGPKeyReader reader = PGPainless.getInstance().readKey();
OpenPGPKey secretKeys = reader.parseKey(FULL_KEY);
OpenPGPKey expected = reader.parseKey(ENCRYPTION_KEY_ON_CARD);
PGPSecretKeyRing onCard = GnuPGDummyKeyUtil.modify(secretKeys)
.divertPrivateKeysToCard(GnuPGDummyKeyUtil.KeyFilter.only(encryptionKeyId), cardSerial);
assertArrayEquals(expected.getEncoded(), onCard.getEncoded());
assertArrayEquals(expected.getPGPSecretKeyRing().getEncoded(), onCard.getEncoded());
}
@Test
public void testMoveSigningKeyToCard() throws IOException {
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
PGPSecretKeyRing expected = PGPainless.readKeyRing().secretKeyRing(SIGNATURE_KEY_ON_CARD);
OpenPGPKeyReader reader = PGPainless.getInstance().readKey();
OpenPGPKey secretKeys = reader.parseKey(FULL_KEY);
OpenPGPKey expected = reader.parseKey(SIGNATURE_KEY_ON_CARD);
PGPSecretKeyRing onCard = GnuPGDummyKeyUtil.modify(secretKeys)
.divertPrivateKeysToCard(GnuPGDummyKeyUtil.KeyFilter.only(signatureKeyId), cardSerial);
assertArrayEquals(expected.getEncoded(), onCard.getEncoded());
assertArrayEquals(expected.getPGPSecretKeyRing().getEncoded(), onCard.getEncoded());
}
@Test
public void testRemoveAllKeys() throws IOException {
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
PGPSecretKeyRing expected = PGPainless.readKeyRing().secretKeyRing(ALL_KEYS_REMOVED);
OpenPGPKeyReader reader = PGPainless.getInstance().readKey();
OpenPGPKey secretKeys = reader.parseKey(FULL_KEY);
OpenPGPKey expected = reader.parseKey(ALL_KEYS_REMOVED);
PGPSecretKeyRing removedSecretKeys = GnuPGDummyKeyUtil.modify(secretKeys)
.removePrivateKeys(GnuPGDummyKeyUtil.KeyFilter.any());
@ -240,33 +247,35 @@ public class GnuPGDummyKeyUtilTest {
assertEquals(GnuPGDummyExtension.NO_PRIVATE_KEY.getId(), s2k.getProtectionMode());
}
assertArrayEquals(expected.getEncoded(), removedSecretKeys.getEncoded());
assertArrayEquals(expected.getPGPSecretKeyRing().getEncoded(), removedSecretKeys.getEncoded());
}
@Test
public void testGetSingleIdOfHardwareBackedKey() throws IOException {
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
assertTrue(GnuPGDummyKeyUtil.getIdsOfKeysWithGnuPGS2KDivertedToCard(secretKeys).isEmpty());
OpenPGPKeyReader reader = PGPainless.getInstance().readKey();
OpenPGPKey secretKeys = reader.parseKey(FULL_KEY);
assertTrue(GnuPGDummyKeyUtil.getIdsOfKeysWithGnuPGS2KDivertedToCard(secretKeys.getPGPSecretKeyRing()).isEmpty());
PGPSecretKeyRing withHardwareBackedEncryptionKey = GnuPGDummyKeyUtil.modify(secretKeys)
.divertPrivateKeysToCard(GnuPGDummyKeyUtil.KeyFilter.only(encryptionKeyId));
Set<SubkeyIdentifier> hardwareBackedKeys = GnuPGDummyKeyUtil
.getIdsOfKeysWithGnuPGS2KDivertedToCard(withHardwareBackedEncryptionKey);
assertEquals(Collections.singleton(new SubkeyIdentifier(secretKeys, encryptionKeyId)), hardwareBackedKeys);
assertEquals(Collections.singleton(new SubkeyIdentifier(secretKeys.getPGPSecretKeyRing(), encryptionKeyId)), hardwareBackedKeys);
}
@Test
public void testGetIdsOfFullyHardwareBackedKey() throws IOException {
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
assertTrue(GnuPGDummyKeyUtil.getIdsOfKeysWithGnuPGS2KDivertedToCard(secretKeys).isEmpty());
OpenPGPKeyReader reader = PGPainless.getInstance().readKey();
OpenPGPKey secretKeys = reader.parseKey(FULL_KEY);
assertTrue(GnuPGDummyKeyUtil.getIdsOfKeysWithGnuPGS2KDivertedToCard(secretKeys.getPGPSecretKeyRing()).isEmpty());
PGPSecretKeyRing withHardwareBackedEncryptionKey = GnuPGDummyKeyUtil.modify(secretKeys)
.divertPrivateKeysToCard(GnuPGDummyKeyUtil.KeyFilter.any());
Set<SubkeyIdentifier> expected = new HashSet<>();
for (PGPSecretKey key : secretKeys) {
expected.add(new SubkeyIdentifier(secretKeys, key.getKeyID()));
for (PGPSecretKey key : secretKeys.getPGPSecretKeyRing()) {
expected.add(new SubkeyIdentifier(secretKeys.getPGPSecretKeyRing(), key.getKeyID()));
}
Set<SubkeyIdentifier> hardwareBackedKeys = GnuPGDummyKeyUtil

View file

@ -15,8 +15,9 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.bouncycastle.openpgp.api.OpenPGPKeyReader;
import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@ -134,15 +135,16 @@ public class DecryptOrVerify {
"=9PiO\n" +
"-----END PGP MESSAGE-----";
private static PGPSecretKeyRing secretKey;
private static PGPPublicKeyRing certificate;
private static OpenPGPKey secretKey;
private static OpenPGPCertificate certificate;
@BeforeAll
public static void prepare() throws IOException {
OpenPGPKeyReader reader = PGPainless.getInstance().readKey();
// read the secret key
secretKey = PGPainless.readKeyRing().secretKeyRing(KEY);
secretKey = reader.parseKey(KEY);
// certificate is the public part of the key
certificate = PGPainless.extractCertificate(secretKey);
certificate = secretKey.toCertificate();
}
/**
@ -153,7 +155,7 @@ public class DecryptOrVerify {
*/
@Test
public void decryptMessage() throws PGPException, IOException {
ConsumerOptions consumerOptions = new ConsumerOptions()
ConsumerOptions consumerOptions = ConsumerOptions.get()
.addDecryptionKey(secretKey, keyProtector); // add the decryption key ring
ByteArrayOutputStream plaintextOut = new ByteArrayOutputStream();
@ -186,7 +188,7 @@ public class DecryptOrVerify {
*/
@Test
public void decryptMessageAndVerifySignatures() throws PGPException, IOException {
ConsumerOptions consumerOptions = new ConsumerOptions()
ConsumerOptions consumerOptions = ConsumerOptions.get()
.addDecryptionKey(secretKey, keyProtector) // provide the secret key of the recipient for decryption
.addVerificationCert(certificate); // provide the signers public key for signature verification
@ -218,7 +220,7 @@ public class DecryptOrVerify {
*/
@Test
public void verifySignatures() throws PGPException, IOException {
ConsumerOptions options = new ConsumerOptions()
ConsumerOptions options = ConsumerOptions.get()
.addVerificationCert(certificate); // provide the signers certificate for verification of signatures
for (String signed : new String[] {INBAND_SIGNED, CLEARTEXT_SIGNED}) {
@ -257,7 +259,7 @@ public class DecryptOrVerify {
SigningOptions signingOptions = SigningOptions.get();
// for cleartext signed messages, we need to add a detached signature...
signingOptions.addDetachedSignature(keyProtector, secretKey, DocumentSignatureType.CANONICAL_TEXT_DOCUMENT);
signingOptions.addDetachedSignature(keyProtector, secretKey.getPGPSecretKeyRing(), DocumentSignatureType.CANONICAL_TEXT_DOCUMENT);
ProducerOptions producerOptions = ProducerOptions.sign(signingOptions)
.setCleartextSigned(); // and declare that the message will be cleartext signed
@ -279,7 +281,7 @@ public class DecryptOrVerify {
// and pass it to the decryption stream
DecryptionStream verificationStream = PGPainless.decryptAndOrVerify()
.onInputStream(signedIn)
.withOptions(new ConsumerOptions().addVerificationCert(certificate));
.withOptions(ConsumerOptions.get().addVerificationCert(certificate));
// plain will receive the plaintext message
ByteArrayOutputStream plain = new ByteArrayOutputStream();