diff --git a/pg/src/main/java/org/bouncycastle/openpgp/api/OpenPGPKey.java b/pg/src/main/java/org/bouncycastle/openpgp/api/OpenPGPKey.java index 4bb5a98f35..1e594f81d8 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/api/OpenPGPKey.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/api/OpenPGPKey.java @@ -2,6 +2,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.LinkedHashMap; @@ -61,6 +63,26 @@ public OpenPGPKey(PGPSecretKeyRing keyRing, OpenPGPImplementation implementation this(keyRing, implementation, implementation.policy()); } + public OpenPGPKey(Collection secretKeys, OpenPGPImplementation implementation) + { + this(secretKeys, implementation, implementation.policy()); + } + + public OpenPGPKey(Collection secretKeys, OpenPGPImplementation implementation, OpenPGPPolicy policy) + { + this(fromSecretKeys(secretKeys), implementation, policy); + } + + private static PGPSecretKeyRing fromSecretKeys(Collection secretKeys) + { + List pgpSecretKeys = new ArrayList<>(); + for (OpenPGPSecretKey secretKey : secretKeys) + { + pgpSecretKeys.add(secretKey.getPGPSecretKey()); + } + return new PGPSecretKeyRing(pgpSecretKeys); + } + /** * Create an {@link OpenPGPKey} instance based on a {@link PGPSecretKeyRing}, * a provided {@link OpenPGPImplementation} and {@link OpenPGPPolicy}. diff --git a/pg/src/main/java/org/bouncycastle/openpgp/api/OpenPGPKeyEditor.java b/pg/src/main/java/org/bouncycastle/openpgp/api/OpenPGPKeyEditor.java index 5a7801bad1..ac99d4795c 100644 --- a/pg/src/main/java/org/bouncycastle/openpgp/api/OpenPGPKeyEditor.java +++ b/pg/src/main/java/org/bouncycastle/openpgp/api/OpenPGPKeyEditor.java @@ -49,7 +49,15 @@ public OpenPGPKeyEditor(OpenPGPKey key, throws PGPException { this.key = key; - this.primaryKey = key.getPrimarySecretKey().unlock(passphraseProvider); + OpenPGPKey.OpenPGPSecretKey primarySecretKey = key.getPrimarySecretKey(); + if (primarySecretKey.isLocked()) + { + this.primaryKey = primarySecretKey.unlock(passphraseProvider); + } + else + { + this.primaryKey = primarySecretKey.unlock(); + } this.implementation = implementation; this.policy = policy; } @@ -429,6 +437,37 @@ public OpenPGPKeyEditor changePassphrase(KeyIdentifier componentKeyIdentifier, return this; } + /** + * Change the passphrase of the given component key. + * + * @param componentKeyIdentifier identifier of the component key, whose passphrase shall be changed + * @param passphraseProvider provider for the old key passphrase + * @param newPassphrase new passphrase (or null) + * @param useAEAD whether to use AEAD + * @return this + * @throws OpenPGPKeyException if the secret component of the component key is missing + * @throws PGPException if the key passphrase cannot be changed + */ + public OpenPGPKeyEditor changePassphrase(KeyIdentifier componentKeyIdentifier, + KeyPassphraseProvider passphraseProvider, + char[] newPassphrase, + boolean useAEAD) + throws OpenPGPKeyException, PGPException + { + OpenPGPKey.OpenPGPSecretKey secretKey = key.getSecretKey(componentKeyIdentifier); + if (secretKey == null) + { + throw new OpenPGPKeyException(key, "Secret component key " + componentKeyIdentifier + + " is missing from the key."); + } + + return changePassphrase( + componentKeyIdentifier, + passphraseProvider.getKeyPassword(secretKey), + newPassphrase, + useAEAD); + } + /** * Return the modified {@link OpenPGPKey}. *