mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-15 17:02:06 +01:00
Rename GnuPGDummyExtension + GnuPGDummyKeyUtil
This commit is contained in:
parent
b5bd4875ae
commit
3b9159e632
4 changed files with 36 additions and 27 deletions
|
@ -6,7 +6,7 @@ package org.pgpainless.key.gnu_dummy_s2k;
|
||||||
|
|
||||||
import org.bouncycastle.bcpg.S2K;
|
import org.bouncycastle.bcpg.S2K;
|
||||||
|
|
||||||
public enum GNUExtension {
|
public enum GnuPGDummyExtension {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do not store the secret part at all.
|
* Do not store the secret part at all.
|
||||||
|
@ -21,7 +21,7 @@ public enum GNUExtension {
|
||||||
|
|
||||||
private final int id;
|
private final int id;
|
||||||
|
|
||||||
GNUExtension(int id) {
|
GnuPGDummyExtension(int id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,15 @@ import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class can be used to remove private keys from secret keys.
|
* This class can be used to remove private keys from secret software-keys by replacing them with
|
||||||
|
* stub secret keys in the style of GnuPGs proprietary extensions.
|
||||||
|
*
|
||||||
|
* @see <a href="https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=doc/DETAILS;hb=HEAD#l1489">
|
||||||
|
* GnuPGs doc/DETAILS - GNU extensions to the S2K algorithm</a>
|
||||||
*/
|
*/
|
||||||
public final class GnuDummyKeyUtil {
|
public final class GnuPGDummyKeyUtil {
|
||||||
|
|
||||||
private GnuDummyKeyUtil() {
|
private GnuPGDummyKeyUtil() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,18 +49,18 @@ public final class GnuDummyKeyUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all private keys that match the given {@link KeyFilter} from the key ring and replace them with
|
* Remove all private keys that match the given {@link KeyFilter} from the key ring and replace them with
|
||||||
* GNU_DUMMY keys with S2K protection mode {@link GNUExtension#NO_PRIVATE_KEY}.
|
* GNU_DUMMY keys with S2K protection mode {@link GnuPGDummyExtension#NO_PRIVATE_KEY}.
|
||||||
*
|
*
|
||||||
* @param filter filter to select keys for removal
|
* @param filter filter to select keys for removal
|
||||||
* @return modified key ring
|
* @return modified key ring
|
||||||
*/
|
*/
|
||||||
public PGPSecretKeyRing removePrivateKeys(KeyFilter filter) {
|
public PGPSecretKeyRing removePrivateKeys(KeyFilter filter) {
|
||||||
return replacePrivateKeys(GNUExtension.NO_PRIVATE_KEY, null, filter);
|
return replacePrivateKeys(GnuPGDummyExtension.NO_PRIVATE_KEY, null, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all private keys that match the given {@link KeyFilter} from the key ring and replace them with
|
* Remove all private keys that match the given {@link KeyFilter} from the key ring and replace them with
|
||||||
* GNU_DUMMY keys with S2K protection mode {@link GNUExtension#DIVERT_TO_CARD}.
|
* GNU_DUMMY keys with S2K protection mode {@link GnuPGDummyExtension#DIVERT_TO_CARD}.
|
||||||
* This method will set the serial number of the card to 0x00000000000000000000000000000000.
|
* This method will set the serial number of the card to 0x00000000000000000000000000000000.
|
||||||
*
|
*
|
||||||
* NOTE: This method does not actually move any keys to a card.
|
* NOTE: This method does not actually move any keys to a card.
|
||||||
|
@ -70,7 +74,7 @@ public final class GnuDummyKeyUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all private keys that match the given {@link KeyFilter} from the key ring and replace them with
|
* Remove all private keys that match the given {@link KeyFilter} from the key ring and replace them with
|
||||||
* GNU_DUMMY keys with S2K protection mode {@link GNUExtension#DIVERT_TO_CARD}.
|
* GNU_DUMMY keys with S2K protection mode {@link GnuPGDummyExtension#DIVERT_TO_CARD}.
|
||||||
* This method will include the card serial number into the encoded dummy key.
|
* This method will include the card serial number into the encoded dummy key.
|
||||||
*
|
*
|
||||||
* NOTE: This method does not actually move any keys to a card.
|
* NOTE: This method does not actually move any keys to a card.
|
||||||
|
@ -83,10 +87,10 @@ public final class GnuDummyKeyUtil {
|
||||||
if (cardSerialNumber != null && cardSerialNumber.length > 16) {
|
if (cardSerialNumber != null && cardSerialNumber.length > 16) {
|
||||||
throw new IllegalArgumentException("Card serial number length cannot exceed 16 bytes.");
|
throw new IllegalArgumentException("Card serial number length cannot exceed 16 bytes.");
|
||||||
}
|
}
|
||||||
return replacePrivateKeys(GNUExtension.DIVERT_TO_CARD, cardSerialNumber, filter);
|
return replacePrivateKeys(GnuPGDummyExtension.DIVERT_TO_CARD, cardSerialNumber, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PGPSecretKeyRing replacePrivateKeys(GNUExtension extension, byte[] serial, KeyFilter filter) {
|
private PGPSecretKeyRing replacePrivateKeys(GnuPGDummyExtension extension, byte[] serial, KeyFilter filter) {
|
||||||
byte[] encodedSerial = serial != null ? encodeSerial(serial) : null;
|
byte[] encodedSerial = serial != null ? encodeSerial(serial) : null;
|
||||||
S2K s2k = extensionToS2K(extension);
|
S2K s2k = extensionToS2K(extension);
|
||||||
|
|
||||||
|
@ -122,12 +126,16 @@ public final class GnuDummyKeyUtil {
|
||||||
return encoded;
|
return encoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
private S2K extensionToS2K(@Nonnull GNUExtension extension) {
|
private S2K extensionToS2K(@Nonnull GnuPGDummyExtension extension) {
|
||||||
return S2K.gnuDummyS2K(extension == GNUExtension.DIVERT_TO_CARD ?
|
return S2K.gnuDummyS2K(extension == GnuPGDummyExtension.DIVERT_TO_CARD ?
|
||||||
S2K.GNUDummyParams.divertToCard() : S2K.GNUDummyParams.noPrivateKey());
|
S2K.GNUDummyParams.divertToCard() : S2K.GNUDummyParams.noPrivateKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter for selecting keys.
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
public interface KeyFilter {
|
public interface KeyFilter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -140,6 +148,7 @@ public final class GnuDummyKeyUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select any key.
|
* Select any key.
|
||||||
|
*
|
||||||
* @return filter
|
* @return filter
|
||||||
*/
|
*/
|
||||||
static KeyFilter any() {
|
static KeyFilter any() {
|
|
@ -17,7 +17,7 @@ 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.key.SubkeyIdentifier;
|
import org.pgpainless.key.SubkeyIdentifier;
|
||||||
import org.pgpainless.key.gnu_dummy_s2k.GnuDummyKeyUtil;
|
import org.pgpainless.key.gnu_dummy_s2k.GnuPGDummyKeyUtil;
|
||||||
import org.pgpainless.key.util.KeyIdUtil;
|
import org.pgpainless.key.util.KeyIdUtil;
|
||||||
|
|
||||||
public class HardwareSecurityTest {
|
public class HardwareSecurityTest {
|
||||||
|
@ -53,8 +53,8 @@ public class HardwareSecurityTest {
|
||||||
assertTrue(HardwareSecurity.getIdsOfHardwareBackedKeys(secretKeys).isEmpty());
|
assertTrue(HardwareSecurity.getIdsOfHardwareBackedKeys(secretKeys).isEmpty());
|
||||||
long encryptionKeyId = KeyIdUtil.fromLongKeyId("0AAD8F5891262F50");
|
long encryptionKeyId = KeyIdUtil.fromLongKeyId("0AAD8F5891262F50");
|
||||||
|
|
||||||
PGPSecretKeyRing withHardwareBackedEncryptionKey = GnuDummyKeyUtil.modify(secretKeys)
|
PGPSecretKeyRing withHardwareBackedEncryptionKey = GnuPGDummyKeyUtil.modify(secretKeys)
|
||||||
.divertPrivateKeysToCard(GnuDummyKeyUtil.KeyFilter.only(encryptionKeyId));
|
.divertPrivateKeysToCard(GnuPGDummyKeyUtil.KeyFilter.only(encryptionKeyId));
|
||||||
|
|
||||||
Set<SubkeyIdentifier> hardwareBackedKeys = HardwareSecurity
|
Set<SubkeyIdentifier> hardwareBackedKeys = HardwareSecurity
|
||||||
.getIdsOfHardwareBackedKeys(withHardwareBackedEncryptionKey);
|
.getIdsOfHardwareBackedKeys(withHardwareBackedEncryptionKey);
|
||||||
|
@ -67,8 +67,8 @@ public class HardwareSecurityTest {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(KEY);
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(KEY);
|
||||||
assertTrue(HardwareSecurity.getIdsOfHardwareBackedKeys(secretKeys).isEmpty());
|
assertTrue(HardwareSecurity.getIdsOfHardwareBackedKeys(secretKeys).isEmpty());
|
||||||
|
|
||||||
PGPSecretKeyRing withHardwareBackedEncryptionKey = GnuDummyKeyUtil.modify(secretKeys)
|
PGPSecretKeyRing withHardwareBackedEncryptionKey = GnuPGDummyKeyUtil.modify(secretKeys)
|
||||||
.divertPrivateKeysToCard(GnuDummyKeyUtil.KeyFilter.any());
|
.divertPrivateKeysToCard(GnuPGDummyKeyUtil.KeyFilter.any());
|
||||||
Set<SubkeyIdentifier> expected = new HashSet<>();
|
Set<SubkeyIdentifier> expected = new HashSet<>();
|
||||||
for (PGPSecretKey key : secretKeys) {
|
for (PGPSecretKey key : secretKeys) {
|
||||||
expected.add(new SubkeyIdentifier(secretKeys, key.getKeyID()));
|
expected.add(new SubkeyIdentifier(secretKeys, key.getKeyID()));
|
||||||
|
|
|
@ -17,7 +17,7 @@ import java.io.IOException;
|
||||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
public class GnuDummyKeyUtilTest {
|
public class GnuPGDummyKeyUtilTest {
|
||||||
// normal, non-hw-backed key
|
// normal, non-hw-backed key
|
||||||
private static final String FULL_KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
|
private static final String FULL_KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
|
||||||
"Version: PGPainless\n" +
|
"Version: PGPainless\n" +
|
||||||
|
@ -153,8 +153,8 @@ public class GnuDummyKeyUtilTest {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
|
||||||
PGPSecretKeyRing expected = PGPainless.readKeyRing().secretKeyRing(ALL_KEYS_ON_CARD);
|
PGPSecretKeyRing expected = PGPainless.readKeyRing().secretKeyRing(ALL_KEYS_ON_CARD);
|
||||||
|
|
||||||
PGPSecretKeyRing onCard = GnuDummyKeyUtil.modify(secretKeys)
|
PGPSecretKeyRing onCard = GnuPGDummyKeyUtil.modify(secretKeys)
|
||||||
.divertPrivateKeysToCard(GnuDummyKeyUtil.KeyFilter.any(), cardSerial);
|
.divertPrivateKeysToCard(GnuPGDummyKeyUtil.KeyFilter.any(), cardSerial);
|
||||||
|
|
||||||
for (PGPSecretKey key : onCard) {
|
for (PGPSecretKey key : onCard) {
|
||||||
assertEquals(SecretKeyPacket.USAGE_SHA1, key.getS2KUsage());
|
assertEquals(SecretKeyPacket.USAGE_SHA1, key.getS2KUsage());
|
||||||
|
@ -170,8 +170,8 @@ public class GnuDummyKeyUtilTest {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
|
||||||
PGPSecretKeyRing expected = PGPainless.readKeyRing().secretKeyRing(PRIMARY_KEY_ON_CARD);
|
PGPSecretKeyRing expected = PGPainless.readKeyRing().secretKeyRing(PRIMARY_KEY_ON_CARD);
|
||||||
|
|
||||||
PGPSecretKeyRing onCard = GnuDummyKeyUtil.modify(secretKeys)
|
PGPSecretKeyRing onCard = GnuPGDummyKeyUtil.modify(secretKeys)
|
||||||
.divertPrivateKeysToCard(GnuDummyKeyUtil.KeyFilter.only(primaryKeyId), cardSerial);
|
.divertPrivateKeysToCard(GnuPGDummyKeyUtil.KeyFilter.only(primaryKeyId), cardSerial);
|
||||||
|
|
||||||
assertArrayEquals(expected.getEncoded(), onCard.getEncoded());
|
assertArrayEquals(expected.getEncoded(), onCard.getEncoded());
|
||||||
}
|
}
|
||||||
|
@ -181,8 +181,8 @@ public class GnuDummyKeyUtilTest {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
|
||||||
PGPSecretKeyRing expected = PGPainless.readKeyRing().secretKeyRing(ENCRYPTION_KEY_ON_CARD);
|
PGPSecretKeyRing expected = PGPainless.readKeyRing().secretKeyRing(ENCRYPTION_KEY_ON_CARD);
|
||||||
|
|
||||||
PGPSecretKeyRing onCard = GnuDummyKeyUtil.modify(secretKeys)
|
PGPSecretKeyRing onCard = GnuPGDummyKeyUtil.modify(secretKeys)
|
||||||
.divertPrivateKeysToCard(GnuDummyKeyUtil.KeyFilter.only(encryptionKeyId), cardSerial);
|
.divertPrivateKeysToCard(GnuPGDummyKeyUtil.KeyFilter.only(encryptionKeyId), cardSerial);
|
||||||
|
|
||||||
assertArrayEquals(expected.getEncoded(), onCard.getEncoded());
|
assertArrayEquals(expected.getEncoded(), onCard.getEncoded());
|
||||||
}
|
}
|
||||||
|
@ -192,8 +192,8 @@ public class GnuDummyKeyUtilTest {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
|
||||||
PGPSecretKeyRing expected = PGPainless.readKeyRing().secretKeyRing(SIGNATURE_KEY_ON_CARD);
|
PGPSecretKeyRing expected = PGPainless.readKeyRing().secretKeyRing(SIGNATURE_KEY_ON_CARD);
|
||||||
|
|
||||||
PGPSecretKeyRing onCard = GnuDummyKeyUtil.modify(secretKeys)
|
PGPSecretKeyRing onCard = GnuPGDummyKeyUtil.modify(secretKeys)
|
||||||
.divertPrivateKeysToCard(GnuDummyKeyUtil.KeyFilter.only(signatureKeyId), cardSerial);
|
.divertPrivateKeysToCard(GnuPGDummyKeyUtil.KeyFilter.only(signatureKeyId), cardSerial);
|
||||||
|
|
||||||
assertArrayEquals(expected.getEncoded(), onCard.getEncoded());
|
assertArrayEquals(expected.getEncoded(), onCard.getEncoded());
|
||||||
}
|
}
|
Loading…
Reference in a new issue