mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-23 04:42:06 +01:00
Add test for decryption with removed private key
This commit is contained in:
parent
3af6ab1b85
commit
df4fc94ce7
5 changed files with 159 additions and 113 deletions
|
@ -4,18 +4,12 @@
|
||||||
|
|
||||||
package org.pgpainless.decryption_verification;
|
package org.pgpainless.decryption_verification;
|
||||||
|
|
||||||
import org.bouncycastle.bcpg.S2K;
|
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
|
||||||
import org.bouncycastle.openpgp.operator.PGPDataDecryptor;
|
import org.bouncycastle.openpgp.operator.PGPDataDecryptor;
|
||||||
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.pgpainless.key.SubkeyIdentifier;
|
import org.pgpainless.key.SubkeyIdentifier;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable integration of hardware-backed OpenPGP keys.
|
* Enable integration of hardware-backed OpenPGP keys.
|
||||||
*/
|
*/
|
||||||
|
@ -41,31 +35,6 @@ public class HardwareSecurity {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the key-ids of all keys which appear to be stored on a hardware token / smartcard.
|
|
||||||
*
|
|
||||||
* @param secretKeys secret keys
|
|
||||||
* @return set of keys with S2K type DIVERT_TO_CARD or GNU_DUMMY_S2K
|
|
||||||
*/
|
|
||||||
public static Set<SubkeyIdentifier> getIdsOfHardwareBackedKeys(PGPSecretKeyRing secretKeys) {
|
|
||||||
Set<SubkeyIdentifier> hardwareBackedKeys = new HashSet<>();
|
|
||||||
for (PGPSecretKey secretKey : secretKeys) {
|
|
||||||
S2K s2K = secretKey.getS2K();
|
|
||||||
if (s2K == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int type = s2K.getType();
|
|
||||||
int mode = s2K.getProtectionMode();
|
|
||||||
// TODO: Is GNU_DUMMY_S2K appropriate?
|
|
||||||
if (type == S2K.GNU_DUMMY_S2K && mode == S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD) {
|
|
||||||
SubkeyIdentifier hardwareBackedKey = new SubkeyIdentifier(secretKeys, secretKey.getKeyID());
|
|
||||||
hardwareBackedKeys.add(hardwareBackedKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hardwareBackedKeys;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link PublicKeyDataDecryptorFactory} which delegates decryption of encrypted session keys
|
* Implementation of {@link PublicKeyDataDecryptorFactory} which delegates decryption of encrypted session keys
|
||||||
* to a {@link DecryptionCallback}.
|
* to a {@link DecryptionCallback}.
|
||||||
|
|
|
@ -10,11 +10,14 @@ import org.bouncycastle.bcpg.SecretKeyPacket;
|
||||||
import org.bouncycastle.bcpg.SecretSubkeyPacket;
|
import org.bouncycastle.bcpg.SecretSubkeyPacket;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.pgpainless.key.SubkeyIdentifier;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class can be used to remove private keys from secret software-keys by replacing them with
|
* This class can be used to remove private keys from secret software-keys by replacing them with
|
||||||
|
@ -29,6 +32,33 @@ public final class GnuPGDummyKeyUtil {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the key-ids of all keys which appear to be stored on a hardware token / smartcard by GnuPG.
|
||||||
|
* Note, that this functionality is based on GnuPGs proprietary S2K extensions, which are not strictly required
|
||||||
|
* for dealing with hardware-backed keys.
|
||||||
|
*
|
||||||
|
* @param secretKeys secret keys
|
||||||
|
* @return set of keys with S2K type GNU_DUMMY_S2K and protection mode DIVERT_TO_CARD
|
||||||
|
*/
|
||||||
|
public static Set<SubkeyIdentifier> getIdsOfKeysWithGnuPGS2KDivertedToCard(PGPSecretKeyRing secretKeys) {
|
||||||
|
Set<SubkeyIdentifier> hardwareBackedKeys = new HashSet<>();
|
||||||
|
for (PGPSecretKey secretKey : secretKeys) {
|
||||||
|
S2K s2K = secretKey.getS2K();
|
||||||
|
if (s2K == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int type = s2K.getType();
|
||||||
|
int mode = s2K.getProtectionMode();
|
||||||
|
// TODO: Is GNU_DUMMY_S2K appropriate?
|
||||||
|
if (type == S2K.GNU_DUMMY_S2K && mode == S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD) {
|
||||||
|
SubkeyIdentifier hardwareBackedKey = new SubkeyIdentifier(secretKeys, secretKey.getKeyID());
|
||||||
|
hardwareBackedKeys.add(hardwareBackedKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hardwareBackedKeys;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modify the given {@link PGPSecretKeyRing}.
|
* Modify the given {@link PGPSecretKeyRing}.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
package org.pgpainless.decryption_verification;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.pgpainless.PGPainless;
|
|
||||||
import org.pgpainless.key.SubkeyIdentifier;
|
|
||||||
import org.pgpainless.key.gnu_dummy_s2k.GnuPGDummyKeyUtil;
|
|
||||||
import org.pgpainless.key.util.KeyIdUtil;
|
|
||||||
|
|
||||||
public class HardwareSecurityTest {
|
|
||||||
|
|
||||||
private static final String KEY = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
|
|
||||||
"Version: PGPainless\n" +
|
|
||||||
"Comment: DE2E 9AB2 6650 8191 53E7 D599 C176 507F 2B5D 43B3\n" +
|
|
||||||
"Comment: Alice <alice@pgpainless.org>\n" +
|
|
||||||
"\n" +
|
|
||||||
"lFgEY1vjgRYJKwYBBAHaRw8BAQdAXjLoPTOIOdvlFT2Nt3rcvLTVx5ujPBGghZ5S\n" +
|
|
||||||
"D5tEnyoAAP0fAUJTiPrxZYdzs6MP0KFo+Nmr/wb1PJHTkzmYpt4wkRKBtBxBbGlj\n" +
|
|
||||||
"ZSA8YWxpY2VAcGdwYWlubGVzcy5vcmc+iI8EExYKAEEFAmNb44EJEMF2UH8rXUOz\n" +
|
|
||||||
"FiEE3i6asmZQgZFT59WZwXZQfytdQ7MCngECmwEFFgIDAQAECwkIBwUVCgkICwKZ\n" +
|
|
||||||
"AQAAHLYA/AgW+YrpU+UqrwX2dhY6RAfgHTTMU89RHjaTHJx8pLrBAP4gthGof00a\n" +
|
|
||||||
"XEjwTWteDOO049SIp2AUfj9deJqtrQcHD5xdBGNb44ESCisGAQQBl1UBBQEBB0DN\n" +
|
|
||||||
"vUT3awa3YLmwf41LRpPrm7B87AOHfYIP8S9QJ4GDJgMBCAcAAP9bwlSaF+lti8JY\n" +
|
|
||||||
"qKFO3qt3ZYQMu1l/LRBle89ZB4zD+BDOiHUEGBYKAB0FAmNb44ECngECmwwFFgID\n" +
|
|
||||||
"AQAECwkIBwUVCgkICwAKCRDBdlB/K11Ds/TsAP9kvpUrCWnrWGq+a9n1CqEfCMX5\n" +
|
|
||||||
"cT+qzrwNf+J0L22KowD+M9SVO0qssiAqutLE9h9dGYLbEiFvsHzK3WSnjKYbIgac\n" +
|
|
||||||
"WARjW+OBFgkrBgEEAdpHDwEBB0BCPh8M5TnXSmG6Ygwp4j5RR4u3hmxl8CYjX4h/\n" +
|
|
||||||
"XtvvNwAA/RP04coSrLHVI6vUfbJk4MhWYeyhJBRYY0vGp7yq+wVtEpKI1QQYFgoA\n" +
|
|
||||||
"fQUCY1vjgQKeAQKbAgUWAgMBAAQLCQgHBRUKCQgLXyAEGRYKAAYFAmNb44EACgkQ\n" +
|
|
||||||
"mlozJSF7rXQW+AD/TA3YBxTd+YbBSwfgqzWNbfT9BBcFrdn3uPCsbvfmqXoA/3oj\n" +
|
|
||||||
"oupkgoaXesrGxn2k9hW9/GBXSvNcgY2txZ6/oYoIAAoJEMF2UH8rXUOziZ4A/0Xl\n" +
|
|
||||||
"xSZJWmkRpBh5AO8Cnqosz6j947IYAxS16ay+sIOHAP9aN9CUNJIIdHnHdFHO4GZz\n" +
|
|
||||||
"ejjknn4wt8NVJP97JxlnBQ==\n" +
|
|
||||||
"=qSQb\n" +
|
|
||||||
"-----END PGP PRIVATE KEY BLOCK-----";
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetSingleIdOfHardwareBackedKey() throws IOException {
|
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(KEY);
|
|
||||||
assertTrue(HardwareSecurity.getIdsOfHardwareBackedKeys(secretKeys).isEmpty());
|
|
||||||
long encryptionKeyId = KeyIdUtil.fromLongKeyId("0AAD8F5891262F50");
|
|
||||||
|
|
||||||
PGPSecretKeyRing withHardwareBackedEncryptionKey = GnuPGDummyKeyUtil.modify(secretKeys)
|
|
||||||
.divertPrivateKeysToCard(GnuPGDummyKeyUtil.KeyFilter.only(encryptionKeyId));
|
|
||||||
|
|
||||||
Set<SubkeyIdentifier> hardwareBackedKeys = HardwareSecurity
|
|
||||||
.getIdsOfHardwareBackedKeys(withHardwareBackedEncryptionKey);
|
|
||||||
assertEquals(Collections.singleton(new SubkeyIdentifier(secretKeys, encryptionKeyId)), hardwareBackedKeys);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetIdsOfFullyHardwareBackedKey() throws IOException {
|
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(KEY);
|
|
||||||
assertTrue(HardwareSecurity.getIdsOfHardwareBackedKeys(secretKeys).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()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<SubkeyIdentifier> hardwareBackedKeys = HardwareSecurity
|
|
||||||
.getIdsOfHardwareBackedKeys(withHardwareBackedEncryptionKey);
|
|
||||||
|
|
||||||
assertEquals(expected, hardwareBackedKeys);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
// SPDX-FileCopyrightText: 2022 Paul Schaub <vanitasvitae@fsfe.org>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package org.pgpainless.decryption_verification;
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.bouncycastle.util.io.Streams;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.pgpainless.PGPainless;
|
||||||
|
import org.pgpainless.encryption_signing.EncryptionOptions;
|
||||||
|
import org.pgpainless.encryption_signing.EncryptionStream;
|
||||||
|
import org.pgpainless.encryption_signing.ProducerOptions;
|
||||||
|
import org.pgpainless.key.gnu_dummy_s2k.GnuPGDummyKeyUtil;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
public class TryDecryptWithUnavailableGnuDummyKeyTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAttemptToDecryptWithRemovedPrivateKeysThrows()
|
||||||
|
throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException {
|
||||||
|
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
||||||
|
.modernKeyRing("Hardy Hardware <hardy@hard.ware>");
|
||||||
|
PGPPublicKeyRing certificate = PGPainless.extractCertificate(secretKeys);
|
||||||
|
|
||||||
|
ByteArrayOutputStream ciphertextOut = new ByteArrayOutputStream();
|
||||||
|
EncryptionStream encryptionStream = PGPainless.encryptAndOrSign()
|
||||||
|
.onOutputStream(ciphertextOut)
|
||||||
|
.withOptions(
|
||||||
|
ProducerOptions.encrypt(EncryptionOptions.get().addRecipient(certificate)));
|
||||||
|
ByteArrayInputStream plaintextIn = new ByteArrayInputStream("Hello, World!\n".getBytes());
|
||||||
|
Streams.pipeAll(plaintextIn, encryptionStream);
|
||||||
|
encryptionStream.close();
|
||||||
|
|
||||||
|
PGPSecretKeyRing removedKeys = GnuPGDummyKeyUtil.modify(secretKeys)
|
||||||
|
.removePrivateKeys(GnuPGDummyKeyUtil.KeyFilter.any());
|
||||||
|
|
||||||
|
ByteArrayInputStream ciphertextIn = new ByteArrayInputStream(ciphertextOut.toByteArray());
|
||||||
|
assertThrows(PGPException.class, () -> PGPainless.decryptAndOrVerify()
|
||||||
|
.onInputStream(ciphertextIn)
|
||||||
|
.withOptions(ConsumerOptions.get().addDecryptionKey(removedKeys)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,12 +10,17 @@ import org.bouncycastle.openpgp.PGPSecretKey;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
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.util.KeyIdUtil;
|
import org.pgpainless.key.util.KeyIdUtil;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
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;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
public class GnuPGDummyKeyUtilTest {
|
public class GnuPGDummyKeyUtilTest {
|
||||||
// normal, non-hw-backed key
|
// normal, non-hw-backed key
|
||||||
|
@ -73,6 +78,29 @@ public class GnuPGDummyKeyUtilTest {
|
||||||
"=rYoa\n" +
|
"=rYoa\n" +
|
||||||
"-----END PGP PRIVATE KEY BLOCK-----";
|
"-----END PGP PRIVATE KEY BLOCK-----";
|
||||||
|
|
||||||
|
public static final String ALL_KEYS_REMOVED = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
|
||||||
|
"Version: PGPainless\n" +
|
||||||
|
"Comment: 01FD AB6C E04A 5078 79FE 4A18 C312 C97D A9F7 6A4F\n" +
|
||||||
|
"Comment: Hardy Hardware <hardy@hard.ware>\n" +
|
||||||
|
"\n" +
|
||||||
|
"lDsEY1vSiBYJKwYBBAHaRw8BAQdAQ58lZn/HOtg+1b1KS18odyQ6M4LaDdbJAyRf\n" +
|
||||||
|
"eBwCeTT+AGUAR05VAbQgSGFyZHkgSGFyZHdhcmUgPGhhcmR5QGhhcmQud2FyZT6I\n" +
|
||||||
|
"jwQTFgoAQQUCY1vSiAkQwxLJfan3ak8WIQQB/ats4EpQeHn+ShjDEsl9qfdqTwKe\n" +
|
||||||
|
"AQKbAQUWAgMBAAQLCQgHBRUKCQgLApkBAAD5NgD/dtk+U0O4bpBZacV904TIYniZ\n" +
|
||||||
|
"xAhmORKreVNP7xGNV3YA/3hNTJfaqsekBnGjSnvHXjHtxIU2p7epkvbajB6dv94J\n" +
|
||||||
|
"nEAEY1vSiBIKKwYBBAGXVQEFAQEHQFVwSzbzZhYfSl+oi5nTSTNvGXPTxp8xKAA/\n" +
|
||||||
|
"fk+KdJQ8AwEIB/4AZQBHTlUBiHUEGBYKAB0FAmNb0ogCngECmwwFFgIDAQAECwkI\n" +
|
||||||
|
"BwUVCgkICwAKCRDDEsl9qfdqT8nJAP0YGPS+O1hkB/kWLR4Qp2ICCzTJmtA+Qyzp\n" +
|
||||||
|
"4v7ze17vvQD+MbQN4nL7zx859ZOP6aLE73w9k+dDQzJtYL/VBRO8/QGcOwRjW9KI\n" +
|
||||||
|
"FgkrBgEEAdpHDwEBB0C9JhMPrS3y/HXR1IQEAJSgh9UKl44HfQPqd/Am1sNPRv4A\n" +
|
||||||
|
"ZQBHTlUBiNUEGBYKAH0FAmNb0ogCngECmwIFFgIDAQAECwkIBwUVCgkIC18gBBkW\n" +
|
||||||
|
"CgAGBQJjW9KIAAoJEJQCL6VtwFtJDmMBAKqsGfRFQxJXyPgugWBgEaO5lt9fMM0y\n" +
|
||||||
|
"Uxa76cmSWe5fAQD2oLSEW1GOgIs64+Z3gvtXopmeupT09HhI7ger98zDAwAKCRDD\n" +
|
||||||
|
"Esl9qfdqTwR6AP9Xftw8xZ7/MWhYImk/xheqPy07K4qo3T1pGKUvUqjWQQEAhE3r\n" +
|
||||||
|
"0oTcJn+KVCwGjF6AYiLOzO/R1x5bSlYD3FeJ3Qo=\n" +
|
||||||
|
"=GEN/\n" +
|
||||||
|
"-----END PGP PRIVATE KEY BLOCK-----";
|
||||||
|
|
||||||
public static final String PRIMARY_KEY_ON_CARD = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
|
public static final String PRIMARY_KEY_ON_CARD = "-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
|
||||||
"Version: PGPainless\n" +
|
"Version: PGPainless\n" +
|
||||||
"Comment: 01FD AB6C E04A 5078 79FE 4A18 C312 C97D A9F7 6A4F\n" +
|
"Comment: 01FD AB6C E04A 5078 79FE 4A18 C312 C97D A9F7 6A4F\n" +
|
||||||
|
@ -197,4 +225,53 @@ public class GnuPGDummyKeyUtilTest {
|
||||||
|
|
||||||
assertArrayEquals(expected.getEncoded(), onCard.getEncoded());
|
assertArrayEquals(expected.getEncoded(), onCard.getEncoded());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemoveAllKeys() throws IOException {
|
||||||
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
|
||||||
|
PGPSecretKeyRing expected = PGPainless.readKeyRing().secretKeyRing(ALL_KEYS_REMOVED);
|
||||||
|
|
||||||
|
PGPSecretKeyRing removedSecretKeys = GnuPGDummyKeyUtil.modify(secretKeys)
|
||||||
|
.removePrivateKeys(GnuPGDummyKeyUtil.KeyFilter.any());
|
||||||
|
|
||||||
|
for (PGPSecretKey key : removedSecretKeys) {
|
||||||
|
assertEquals(key.getS2KUsage(), SecretKeyPacket.USAGE_SHA1);
|
||||||
|
S2K s2k = key.getS2K();
|
||||||
|
assertEquals(GnuPGDummyExtension.NO_PRIVATE_KEY.getId(), s2k.getProtectionMode());
|
||||||
|
}
|
||||||
|
|
||||||
|
assertArrayEquals(expected.getEncoded(), removedSecretKeys.getEncoded());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSingleIdOfHardwareBackedKey() throws IOException {
|
||||||
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
|
||||||
|
assertTrue(GnuPGDummyKeyUtil.getIdsOfKeysWithGnuPGS2KDivertedToCard(secretKeys).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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetIdsOfFullyHardwareBackedKey() throws IOException {
|
||||||
|
PGPSecretKeyRing secretKeys = PGPainless.readKeyRing().secretKeyRing(FULL_KEY);
|
||||||
|
assertTrue(GnuPGDummyKeyUtil.getIdsOfKeysWithGnuPGS2KDivertedToCard(secretKeys).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()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<SubkeyIdentifier> hardwareBackedKeys = GnuPGDummyKeyUtil
|
||||||
|
.getIdsOfKeysWithGnuPGS2KDivertedToCard(withHardwareBackedEncryptionKey);
|
||||||
|
|
||||||
|
assertEquals(expected, hardwareBackedKeys);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue