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

Rework ModifiedPublicKeysInvestigation

This commit is contained in:
Paul Schaub 2025-03-20 20:51:36 +01:00
parent e61c3007c0
commit 63d1f855de
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311

View file

@ -9,16 +9,16 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.IOException; import java.io.IOException;
import org.bouncycastle.bcpg.KeyIdentifier;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.exception.KeyIntegrityException; import org.pgpainless.exception.KeyIntegrityException;
import org.pgpainless.key.generation.type.rsa.RsaLength; import org.pgpainless.key.generation.type.rsa.RsaLength;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.key.protection.UnlockSecretKey; import org.pgpainless.key.protection.UnlockSecretKey;
import org.pgpainless.key.util.KeyIdUtil; import org.pgpainless.policy.Policy;
import org.pgpainless.util.Passphrase; import org.pgpainless.util.Passphrase;
public class ModifiedPublicKeysInvestigation { public class ModifiedPublicKeysInvestigation {
@ -75,6 +75,8 @@ public class ModifiedPublicKeysInvestigation {
"RuvLdJPtAP9VND4sdnrXUXoUn6OgUmKoV0KKcTUPEnMqQ8QgfVDEJA==\n" + "RuvLdJPtAP9VND4sdnrXUXoUn6OgUmKoV0KKcTUPEnMqQ8QgfVDEJA==\n" +
"=p9kX\n" + "=p9kX\n" +
"-----END PGP PRIVATE KEY BLOCK-----"; "-----END PGP PRIVATE KEY BLOCK-----";
private static final KeyIdentifier dsaKID1 = new KeyIdentifier("0FE102C159C818EF2D7D9F7EB1BD1F049EC87F3D");
private static final KeyIdentifier dsaKID2 = new KeyIdentifier("AB30CFBA5A2ED4848B096123F5FFDF6D71DD5789");
private static final String ELGAMAL = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + private static final String ELGAMAL = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
"Version: OpenPGP.js VERSION\n" + "Version: OpenPGP.js VERSION\n" +
@ -127,6 +129,8 @@ public class ModifiedPublicKeysInvestigation {
"TsMBqN9H5d+2XQ==\n" + "TsMBqN9H5d+2XQ==\n" +
"=lI+G\n" + "=lI+G\n" +
"-----END PGP PRIVATE KEY BLOCK-----\n"; "-----END PGP PRIVATE KEY BLOCK-----\n";
private static final KeyIdentifier elgamalKID1 = new KeyIdentifier("9B0F5D6800DEA53499F455C75F04ACF44FD822B1");
private static final KeyIdentifier elgamalKID2 = new KeyIdentifier("AB30CFBA5A2ED4848B096123F5FFDF6D71DD5789");
// created with exploit code by cure53.de // created with exploit code by cure53.de
private static final String INJECTED_KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" + private static final String INJECTED_KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
@ -207,56 +211,65 @@ public class ModifiedPublicKeysInvestigation {
@Test @Test
public void assertModifiedDSAKeyThrowsKeyIntegrityException() throws IOException { public void assertModifiedDSAKeyThrowsKeyIntegrityException() throws IOException {
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("12345678")); System.out.println(DSA);
PGPSecretKeyRing dsa = PGPainless.readKeyRing().secretKeyRing(DSA); PGPainless api = PGPainless.newInstance();
Policy policy = api.getAlgorithmPolicy();
policy.setEnableKeyParameterValidation(true);
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("12345678"));
OpenPGPKey dsa = api.readKey().parseKey(DSA);
PGPainless.getPolicy().setEnableKeyParameterValidation(true);
assertThrows(KeyIntegrityException.class, () -> assertThrows(KeyIntegrityException.class, () ->
UnlockSecretKey.unlockSecretKey(dsa.getSecretKey(KeyIdUtil.fromLongKeyId("b1bd1f049ec87f3d")), protector)); UnlockSecretKey.unlockSecretKey(dsa.getSecretKey(dsaKID1), protector, policy));
assertThrows(KeyIntegrityException.class, () -> assertThrows(KeyIntegrityException.class, () ->
UnlockSecretKey.unlockSecretKey(dsa.getSecretKey(KeyIdUtil.fromLongKeyId("f5ffdf6d71dd5789")), protector)); UnlockSecretKey.unlockSecretKey(dsa.getSecretKey(dsaKID2), protector, policy));
PGPainless.getPolicy().setEnableKeyParameterValidation(false);
} }
@Test @Test
public void assertModifiedElGamalKeyThrowsKeyIntegrityException() throws IOException { public void assertModifiedElGamalKeyThrowsKeyIntegrityException() throws IOException {
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("12345678")); PGPainless api = PGPainless.newInstance();
PGPSecretKeyRing elgamal = PGPainless.readKeyRing().secretKeyRing(ELGAMAL); Policy policy = api.getAlgorithmPolicy();
policy.setEnableKeyParameterValidation(true);
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("12345678"));
OpenPGPKey elgamal = api.readKey().parseKey(ELGAMAL);
PGPainless.getPolicy().setEnableKeyParameterValidation(true);
assertThrows(KeyIntegrityException.class, () -> assertThrows(KeyIntegrityException.class, () ->
UnlockSecretKey.unlockSecretKey(elgamal.getSecretKey(KeyIdUtil.fromLongKeyId("f5ffdf6d71dd5789")), protector)); UnlockSecretKey.unlockSecretKey(elgamal.getSecretKey(elgamalKID2), protector, policy));
PGPainless.getPolicy().setEnableKeyParameterValidation(false);
} }
@Test @Test
public void assertInjectedKeyRingFailsToUnlockPrimaryKey() throws IOException { public void assertInjectedKeyRingFailsToUnlockPrimaryKey() throws IOException {
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(INJECTED_KEY); PGPainless api = PGPainless.newInstance();
Policy policy = api.getAlgorithmPolicy();
policy.setEnableKeyParameterValidation(true);
OpenPGPKey secretKeys = api.readKey().parseKey(INJECTED_KEY);
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("pass")); SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("pass"));
PGPainless.getPolicy().setEnableKeyParameterValidation(true);
assertThrows(KeyIntegrityException.class, () -> assertThrows(KeyIntegrityException.class, () ->
UnlockSecretKey.unlockSecretKey(secretKeys.getSecretKey(), protector)); UnlockSecretKey.unlockSecretKey(secretKeys.getPrimarySecretKey(), protector, policy));
PGPainless.getPolicy().setEnableKeyParameterValidation(false);
} }
@Test @Test
public void assertCannotUnlockElGamalPrimaryKeyDueToDummyS2K() throws IOException { public void assertCannotUnlockElGamalPrimaryKeyDueToDummyS2K() throws IOException {
PGPainless api = PGPainless.newInstance();
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("12345678")); SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("12345678"));
PGPSecretKeyRing elgamal = PGPainless.readKeyRing().secretKeyRing(ELGAMAL); OpenPGPKey elgamal = api.readKey().parseKey(ELGAMAL);
assertThrows(PGPException.class, () -> assertThrows(PGPException.class, () ->
UnlockSecretKey.unlockSecretKey(elgamal.getSecretKey(KeyIdUtil.fromLongKeyId("5f04acf44fd822b1")), protector)); UnlockSecretKey.unlockSecretKey(elgamal.getSecretKey(elgamalKID1), protector));
} }
@Test @Test
public void assertUnmodifiedRSAKeyDoesNotThrow() { public void assertUnmodifiedRSAKeyDoesNotThrow() {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() PGPainless api = PGPainless.getInstance();
.simpleRsaKeyRing("Unmodified", RsaLength._4096, "987654321") OpenPGPKey secretKeys = api.generateKey()
.getPGPSecretKeyRing(); .simpleRsaKeyRing("Unmodified", RsaLength._4096, "987654321");
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("987654321")); SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("987654321"));
for (PGPSecretKey secretKey : secretKeys) { for (OpenPGPKey.OpenPGPSecretKey secretKey : secretKeys.getSecretKeys().values()) {
assertDoesNotThrow(() -> assertDoesNotThrow(() ->
UnlockSecretKey.unlockSecretKey(secretKey, protector)); UnlockSecretKey.unlockSecretKey(secretKey, protector));
} }
@ -264,12 +277,12 @@ public class ModifiedPublicKeysInvestigation {
@Test @Test
public void assertUnmodifiedECKeyDoesNotThrow() { public void assertUnmodifiedECKeyDoesNotThrow() {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() PGPainless api = PGPainless.getInstance();
.simpleEcKeyRing("Unmodified", "987654321") OpenPGPKey secretKeys = api.generateKey()
.getPGPSecretKeyRing(); .simpleEcKeyRing("Unmodified", "987654321");
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("987654321")); SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("987654321"));
for (PGPSecretKey secretKey : secretKeys) { for (OpenPGPKey.OpenPGPSecretKey secretKey : secretKeys.getSecretKeys().values()) {
assertDoesNotThrow(() -> assertDoesNotThrow(() ->
UnlockSecretKey.unlockSecretKey(secretKey, protector)); UnlockSecretKey.unlockSecretKey(secretKey, protector));
} }
@ -277,12 +290,12 @@ public class ModifiedPublicKeysInvestigation {
@Test @Test
public void assertUnmodifiedModernKeyDoesNotThrow() { public void assertUnmodifiedModernKeyDoesNotThrow() {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() PGPainless api = PGPainless.getInstance();
.modernKeyRing("Unmodified", "987654321") OpenPGPKey secretKeys = api.generateKey()
.getPGPSecretKeyRing(); .modernKeyRing("Unmodified", "987654321");
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("987654321")); SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAnyKeyWith(Passphrase.fromPassword("987654321"));
for (PGPSecretKey secretKey : secretKeys) { for (OpenPGPKey.OpenPGPSecretKey secretKey : secretKeys.getSecretKeys().values()) {
assertDoesNotThrow(() -> assertDoesNotThrow(() ->
UnlockSecretKey.unlockSecretKey(secretKey, protector)); UnlockSecretKey.unlockSecretKey(secretKey, protector));
} }