mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-26 14:22:05 +01:00
Identify custom decryptor factories by subkey id
This commit is contained in:
parent
cfd3f77491
commit
a39c6bc881
5 changed files with 22 additions and 12 deletions
|
@ -25,6 +25,7 @@ import org.bouncycastle.openpgp.PGPSignature;
|
|||
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
|
||||
import org.pgpainless.decryption_verification.cleartext_signatures.InMemoryMultiPassStrategy;
|
||||
import org.pgpainless.decryption_verification.cleartext_signatures.MultiPassStrategy;
|
||||
import org.pgpainless.key.SubkeyIdentifier;
|
||||
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||
import org.pgpainless.signature.SignatureUtils;
|
||||
import org.pgpainless.util.Passphrase;
|
||||
|
@ -49,7 +50,7 @@ public class ConsumerOptions {
|
|||
|
||||
// Session key for decryption without passphrase/key
|
||||
private SessionKey sessionKey = null;
|
||||
private final Map<Long, PublicKeyDataDecryptorFactory> customPublicKeyDataDecryptorFactories = new HashMap<>();
|
||||
private final Map<SubkeyIdentifier, PublicKeyDataDecryptorFactory> customPublicKeyDataDecryptorFactories = new HashMap<>();
|
||||
|
||||
private final Map<PGPSecretKeyRing, SecretKeyRingProtector> decryptionKeys = new HashMap<>();
|
||||
private final Set<Passphrase> decryptionPassphrases = new HashSet<>();
|
||||
|
@ -249,11 +250,11 @@ public class ConsumerOptions {
|
|||
* @return options
|
||||
*/
|
||||
public ConsumerOptions addCustomDecryptorFactory(@Nonnull CustomPublicKeyDataDecryptorFactory factory) {
|
||||
this.customPublicKeyDataDecryptorFactories.put(factory.getKeyId(), factory);
|
||||
this.customPublicKeyDataDecryptorFactories.put(factory.getSubkeyIdentifier(), factory);
|
||||
return this;
|
||||
}
|
||||
|
||||
Map<Long, PublicKeyDataDecryptorFactory> getCustomDecryptorFactories() {
|
||||
Map<SubkeyIdentifier, PublicKeyDataDecryptorFactory> getCustomDecryptorFactories() {
|
||||
return new HashMap<>(customPublicKeyDataDecryptorFactories);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
package org.pgpainless.decryption_verification;
|
||||
|
||||
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
|
||||
import org.pgpainless.key.SubkeyIdentifier;
|
||||
|
||||
public interface CustomPublicKeyDataDecryptorFactory extends PublicKeyDataDecryptorFactory {
|
||||
|
||||
long getKeyId();
|
||||
SubkeyIdentifier getSubkeyIdentifier();
|
||||
|
||||
}
|
||||
|
|
|
@ -409,7 +409,7 @@ public final class DecryptionStreamFactory {
|
|||
}
|
||||
|
||||
// Try custom PublicKeyDataDecryptorFactories (e.g. hardware-backed).
|
||||
Map<Long, PublicKeyDataDecryptorFactory> customFactories = options.getCustomDecryptorFactories();
|
||||
Map<SubkeyIdentifier, PublicKeyDataDecryptorFactory> customFactories = options.getCustomDecryptorFactories();
|
||||
for (PGPPublicKeyEncryptedData publicKeyEncryptedData : publicKeyProtected) {
|
||||
Long keyId = publicKeyEncryptedData.getKeyID();
|
||||
if (!customFactories.containsKey(keyId)) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
|||
import org.bouncycastle.openpgp.operator.PGPDataDecryptor;
|
||||
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
|
||||
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory;
|
||||
import org.pgpainless.key.SubkeyIdentifier;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
@ -74,16 +75,16 @@ public class HardwareSecurity {
|
|||
// luckily we can instantiate the BcPublicKeyDataDecryptorFactory with null as argument.
|
||||
private final PublicKeyDataDecryptorFactory factory =
|
||||
new BcPublicKeyDataDecryptorFactory(null);
|
||||
private long keyId;
|
||||
private SubkeyIdentifier subkey;
|
||||
|
||||
/**
|
||||
* Create a new {@link HardwareDataDecryptorFactory}.
|
||||
*
|
||||
* @param callback decryption callback
|
||||
*/
|
||||
public HardwareDataDecryptorFactory(long keyId, DecryptionCallback callback) {
|
||||
public HardwareDataDecryptorFactory(SubkeyIdentifier subkeyIdentifier, DecryptionCallback callback) {
|
||||
this.callback = callback;
|
||||
this.keyId = keyId;
|
||||
this.subkey = subkeyIdentifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -91,7 +92,7 @@ public class HardwareSecurity {
|
|||
throws PGPException {
|
||||
try {
|
||||
// delegate decryption to the callback
|
||||
return callback.decryptSessionKey(keyId, keyAlgorithm, secKeyData[0]);
|
||||
return callback.decryptSessionKey(subkey.getSubkeyId(), keyAlgorithm, secKeyData[0]);
|
||||
} catch (HardwareSecurityException e) {
|
||||
throw new PGPException("Hardware-backed decryption failed.", e);
|
||||
}
|
||||
|
@ -104,8 +105,14 @@ public class HardwareSecurity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public long getKeyId() {
|
||||
return keyId;
|
||||
public PGPDataDecryptor createDataDecryptor(int aeadAlgorithm, byte[] iv, int chunkSize, int encAlgorithm, byte[] key)
|
||||
throws PGPException {
|
||||
return factory.createDataDecryptor(aeadAlgorithm, iv, chunkSize, encAlgorithm, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubkeyIdentifier getSubkeyIdentifier() {
|
||||
return subkey;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import org.pgpainless.algorithm.EncryptionPurpose;
|
|||
import org.pgpainless.encryption_signing.EncryptionOptions;
|
||||
import org.pgpainless.encryption_signing.EncryptionStream;
|
||||
import org.pgpainless.encryption_signing.ProducerOptions;
|
||||
import org.pgpainless.key.SubkeyIdentifier;
|
||||
import org.pgpainless.key.info.KeyRingInfo;
|
||||
import org.pgpainless.key.protection.UnlockSecretKey;
|
||||
import org.pgpainless.util.Passphrase;
|
||||
|
@ -74,7 +75,7 @@ public class CustomPublicKeyDataDecryptorFactoryTest {
|
|||
.withOptions(ConsumerOptions.get()
|
||||
.addCustomDecryptorFactory(
|
||||
new HardwareSecurity.HardwareDataDecryptorFactory(
|
||||
encryptionKey.getKeyID(),
|
||||
new SubkeyIdentifier(cert, encryptionKey.getKeyID()),
|
||||
hardwareDecryptionCallback)));
|
||||
|
||||
ByteArrayOutputStream decryptedOut = new ByteArrayOutputStream();
|
||||
|
|
Loading…
Reference in a new issue