mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-25 04:17:59 +01:00
Kotlin conversion: SecretKeyRingProtector and subclasses
This commit is contained in:
parent
56d573aec6
commit
17d74cb52c
16 changed files with 198 additions and 215 deletions
|
@ -44,13 +44,13 @@ public class BaseSecretKeyRingProtector implements SecretKeyRingProtector {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphraseFor(Long keyId) {
|
||||
public boolean hasPassphraseFor(long keyId) {
|
||||
return passphraseProvider.hasPassphrase(keyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PBESecretKeyDecryptor getDecryptor(Long keyId) throws PGPException {
|
||||
public PBESecretKeyDecryptor getDecryptor(long keyId) throws PGPException {
|
||||
Passphrase passphrase = passphraseProvider.getPassphraseFor(keyId);
|
||||
return passphrase == null || passphrase.isEmpty() ? null :
|
||||
ImplementationFactory.getInstance().getPBESecretKeyDecryptor(passphrase);
|
||||
|
@ -58,7 +58,7 @@ public class BaseSecretKeyRingProtector implements SecretKeyRingProtector {
|
|||
|
||||
@Override
|
||||
@Nullable
|
||||
public PBESecretKeyEncryptor getEncryptor(Long keyId) throws PGPException {
|
||||
public PBESecretKeyEncryptor getEncryptor(long keyId) throws PGPException {
|
||||
Passphrase passphrase = passphraseProvider.getPassphraseFor(keyId);
|
||||
return passphrase == null || passphrase.isEmpty() ? null :
|
||||
ImplementationFactory.getInstance().getPBESecretKeyEncryptor(
|
||||
|
|
|
@ -60,12 +60,12 @@ public class CachingSecretKeyRingProtector implements SecretKeyRingProtector, Se
|
|||
* containing a key with the same key-id but different passphrases.
|
||||
*
|
||||
* If you can ensure that there will be no key-id clash, and you want to replace the passphrase, you can use
|
||||
* {@link #replacePassphrase(Long, Passphrase)} to replace the passphrase.
|
||||
* {@link #replacePassphrase(long, Passphrase)} to replace the passphrase.
|
||||
*
|
||||
* @param keyId id of the key
|
||||
* @param passphrase passphrase
|
||||
*/
|
||||
public void addPassphrase(@Nonnull Long keyId, @Nonnull Passphrase passphrase) {
|
||||
public void addPassphrase(long keyId, @Nonnull Passphrase passphrase) {
|
||||
if (this.cache.containsKey(keyId)) {
|
||||
throw new IllegalArgumentException("The cache already holds a passphrase for ID " + Long.toHexString(keyId) + ".\n" +
|
||||
"If you want to replace the passphrase, use replacePassphrase(Long, Passphrase) instead.");
|
||||
|
@ -79,7 +79,7 @@ public class CachingSecretKeyRingProtector implements SecretKeyRingProtector, Se
|
|||
* @param keyId keyId
|
||||
* @param passphrase passphrase
|
||||
*/
|
||||
public void replacePassphrase(@Nonnull Long keyId, @Nonnull Passphrase passphrase) {
|
||||
public void replacePassphrase(long keyId, @Nonnull Passphrase passphrase) {
|
||||
this.cache.put(keyId, passphrase);
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,7 @@ public class CachingSecretKeyRingProtector implements SecretKeyRingProtector, Se
|
|||
*
|
||||
* @param keyId id of the key
|
||||
*/
|
||||
public void forgetPassphrase(@Nonnull Long keyId) {
|
||||
public void forgetPassphrase(long keyId) {
|
||||
Passphrase passphrase = cache.remove(keyId);
|
||||
if (passphrase != null) {
|
||||
passphrase.clear();
|
||||
|
@ -183,7 +183,7 @@ public class CachingSecretKeyRingProtector implements SecretKeyRingProtector, Se
|
|||
|
||||
@Override
|
||||
@Nullable
|
||||
public Passphrase getPassphraseFor(Long keyId) {
|
||||
public Passphrase getPassphraseFor(long keyId) {
|
||||
Passphrase passphrase = cache.get(keyId);
|
||||
if (passphrase == null || !passphrase.isValid()) {
|
||||
if (provider == null) {
|
||||
|
@ -198,25 +198,25 @@ public class CachingSecretKeyRingProtector implements SecretKeyRingProtector, Se
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphrase(Long keyId) {
|
||||
public boolean hasPassphrase(long keyId) {
|
||||
Passphrase passphrase = cache.get(keyId);
|
||||
return passphrase != null && passphrase.isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphraseFor(Long keyId) {
|
||||
public boolean hasPassphraseFor(long keyId) {
|
||||
return hasPassphrase(keyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PBESecretKeyDecryptor getDecryptor(@Nonnull Long keyId) throws PGPException {
|
||||
public PBESecretKeyDecryptor getDecryptor(long keyId) throws PGPException {
|
||||
return protector.getDecryptor(keyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PBESecretKeyEncryptor getEncryptor(@Nonnull Long keyId) throws PGPException {
|
||||
public PBESecretKeyEncryptor getEncryptor(long keyId) throws PGPException {
|
||||
return protector.getEncryptor(keyId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,12 +40,12 @@ public class PasswordBasedSecretKeyRingProtector extends BaseSecretKeyRingProtec
|
|||
SecretKeyPassphraseProvider passphraseProvider = new SecretKeyPassphraseProvider() {
|
||||
@Override
|
||||
@Nullable
|
||||
public Passphrase getPassphraseFor(Long keyId) {
|
||||
public Passphrase getPassphraseFor(long keyId) {
|
||||
return hasPassphrase(keyId) ? passphrase : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphrase(Long keyId) {
|
||||
public boolean hasPassphrase(long keyId) {
|
||||
return keyRing.getPublicKey(keyId) != null;
|
||||
}
|
||||
};
|
||||
|
@ -60,7 +60,7 @@ public class PasswordBasedSecretKeyRingProtector extends BaseSecretKeyRingProtec
|
|||
SecretKeyPassphraseProvider passphraseProvider = new SecretKeyPassphraseProvider() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Passphrase getPassphraseFor(Long keyId) {
|
||||
public Passphrase getPassphraseFor(long keyId) {
|
||||
if (keyId == singleKeyId) {
|
||||
return passphrase;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ public class PasswordBasedSecretKeyRingProtector extends BaseSecretKeyRingProtec
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphrase(Long keyId) {
|
||||
public boolean hasPassphrase(long keyId) {
|
||||
return keyId == singleKeyId;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,168 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2018 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.key.protection;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
|
||||
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor;
|
||||
import org.pgpainless.key.protection.passphrase_provider.SecretKeyPassphraseProvider;
|
||||
import org.pgpainless.key.protection.passphrase_provider.SolitaryPassphraseProvider;
|
||||
import org.pgpainless.util.Passphrase;
|
||||
|
||||
/**
|
||||
* Task of the {@link SecretKeyRingProtector} is to map encryptor/decryptor objects to key-ids.
|
||||
* {@link PBESecretKeyEncryptor PBESecretKeyEncryptors}/{@link PBESecretKeyDecryptor PBESecretKeyDecryptors} are used
|
||||
* to encrypt/decrypt secret keys using a passphrase.
|
||||
*
|
||||
* While it is easy to create an implementation of this interface that fits your needs, there are a bunch of
|
||||
* implementations ready for use.
|
||||
*/
|
||||
public interface SecretKeyRingProtector {
|
||||
|
||||
/**
|
||||
* Returns true, if the protector has a passphrase for the key with the given key-id.
|
||||
*
|
||||
* @param keyId key id
|
||||
* @return true if it has a passphrase, false otherwise
|
||||
*/
|
||||
boolean hasPassphraseFor(Long keyId);
|
||||
|
||||
/**
|
||||
* Return a decryptor for the key of id {@code keyId}.
|
||||
* This method returns null if the key is unprotected.
|
||||
*
|
||||
* @param keyId id of the key
|
||||
* @return decryptor for the key
|
||||
*
|
||||
* @throws PGPException if the decryptor cannot be created for some reason
|
||||
*/
|
||||
@Nullable PBESecretKeyDecryptor getDecryptor(Long keyId) throws PGPException;
|
||||
|
||||
/**
|
||||
* Return an encryptor for the key of id {@code keyId}.
|
||||
* This method returns null if the key is unprotected.
|
||||
*
|
||||
* @param keyId id of the key
|
||||
* @return encryptor for the key
|
||||
*
|
||||
* @throws PGPException if the encryptor cannot be created for some reason
|
||||
*/
|
||||
@Nullable PBESecretKeyEncryptor getEncryptor(Long keyId) throws PGPException;
|
||||
|
||||
/**
|
||||
* Return a protector for secret keys.
|
||||
* The protector maintains an in-memory cache of passphrases and can be extended with new passphrases
|
||||
* at runtime.
|
||||
*
|
||||
* See {@link CachingSecretKeyRingProtector} for how to memorize/forget additional passphrases during runtime.
|
||||
*
|
||||
* @param missingPassphraseCallback callback that is used to provide missing passphrases.
|
||||
* @return caching secret key protector
|
||||
*/
|
||||
static CachingSecretKeyRingProtector defaultSecretKeyRingProtector(SecretKeyPassphraseProvider missingPassphraseCallback) {
|
||||
return new CachingSecretKeyRingProtector(
|
||||
new HashMap<>(),
|
||||
KeyRingProtectionSettings.secureDefaultSettings(),
|
||||
missingPassphraseCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the provided passphrase to lock/unlock all keys in the provided key ring.
|
||||
*
|
||||
* This protector will use the provided passphrase to lock/unlock all subkeys present in the provided keys object.
|
||||
* For other keys that are not present in the ring, it will return null.
|
||||
*
|
||||
* @param passphrase passphrase
|
||||
* @param keys key ring
|
||||
* @return protector
|
||||
* @deprecated use {@link #unlockEachKeyWith(Passphrase, PGPSecretKeyRing)} instead.
|
||||
*
|
||||
* TODO: Remove in 1.2.X
|
||||
*/
|
||||
@Deprecated
|
||||
static SecretKeyRingProtector unlockAllKeysWith(@Nonnull Passphrase passphrase, @Nonnull PGPSecretKeyRing keys) {
|
||||
return unlockEachKeyWith(passphrase, keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the provided passphrase to lock/unlock all keys in the provided key ring.
|
||||
*
|
||||
* This protector will use the provided passphrase to lock/unlock all subkeys present in the provided keys object.
|
||||
* For other keys that are not present in the ring, it will return null.
|
||||
*
|
||||
* @param passphrase passphrase
|
||||
* @param keys key ring
|
||||
* @return protector
|
||||
*/
|
||||
static SecretKeyRingProtector unlockEachKeyWith(@Nonnull Passphrase passphrase, @Nonnull PGPSecretKeyRing keys) {
|
||||
Map<Long, Passphrase> map = new ConcurrentHashMap<>();
|
||||
for (PGPSecretKey secretKey : keys) {
|
||||
map.put(secretKey.getKeyID(), passphrase);
|
||||
}
|
||||
return fromPassphraseMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the provided passphrase to unlock any key.
|
||||
*
|
||||
* @param passphrase passphrase
|
||||
* @return protector
|
||||
*/
|
||||
static SecretKeyRingProtector unlockAnyKeyWith(@Nonnull Passphrase passphrase) {
|
||||
return new BaseSecretKeyRingProtector(new SolitaryPassphraseProvider(passphrase));
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the provided passphrase to lock/unlock only the provided (sub-)key.
|
||||
* This protector will only return a non-null encryptor/decryptor based on the provided passphrase if
|
||||
* {@link #getEncryptor(Long)}/{@link #getDecryptor(Long)} is getting called with the key-id of the provided key.
|
||||
*
|
||||
* Otherwise, this protector will always return null.
|
||||
*
|
||||
* @param passphrase passphrase
|
||||
* @param key key to lock/unlock
|
||||
* @return protector
|
||||
*/
|
||||
static SecretKeyRingProtector unlockSingleKeyWith(@Nonnull Passphrase passphrase, @Nonnull PGPSecretKey key) {
|
||||
return PasswordBasedSecretKeyRingProtector.forKey(key, passphrase);
|
||||
}
|
||||
|
||||
static SecretKeyRingProtector unlockSingleKeyWith(@Nonnull Passphrase passphrase, long keyId) {
|
||||
return PasswordBasedSecretKeyRingProtector.forKeyId(keyId, passphrase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Protector for unprotected keys.
|
||||
* This protector returns null for all {@link #getEncryptor(Long)}/{@link #getDecryptor(Long)} calls,
|
||||
* no matter what the key-id is.
|
||||
*
|
||||
* As a consequence, this protector can only "unlock" keys which are not protected using a passphrase, and it will
|
||||
* leave keys unprotected, should it be used to "protect" a key
|
||||
* (e.g. in {@link org.pgpainless.key.modification.secretkeyring.SecretKeyRingEditor#changePassphraseFromOldPassphrase(Passphrase)}).
|
||||
*
|
||||
* @return protector
|
||||
*/
|
||||
static SecretKeyRingProtector unprotectedKeys() {
|
||||
return new UnprotectedKeysProtector();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the provided map of key-ids and passphrases to unlock keys.
|
||||
*
|
||||
* @param passphraseMap map of key ids and their respective passphrases
|
||||
* @return protector
|
||||
*/
|
||||
static SecretKeyRingProtector fromPassphraseMap(@Nonnull Map<Long, Passphrase> passphraseMap) {
|
||||
return new CachingSecretKeyRingProtector(passphraseMap, KeyRingProtectionSettings.secureDefaultSettings(), null);
|
||||
}
|
||||
}
|
|
@ -61,6 +61,7 @@ public final class UnlockSecretKey {
|
|||
|
||||
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, Passphrase passphrase)
|
||||
throws PGPException, KeyIntegrityException {
|
||||
return unlockSecretKey(secretKey, SecretKeyRingProtector.unlockSingleKeyWith(passphrase, secretKey));
|
||||
return unlockSecretKey(secretKey, SecretKeyRingProtector.unlockSingleKeyWith(
|
||||
passphrase == null ? Passphrase.emptyPassphrase() : passphrase, secretKey));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,19 +15,19 @@ import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor;
|
|||
public class UnprotectedKeysProtector implements SecretKeyRingProtector {
|
||||
|
||||
@Override
|
||||
public boolean hasPassphraseFor(Long keyId) {
|
||||
public boolean hasPassphraseFor(long keyId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PBESecretKeyDecryptor getDecryptor(Long keyId) {
|
||||
public PBESecretKeyDecryptor getDecryptor(long keyId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PBESecretKeyEncryptor getEncryptor(Long keyId) {
|
||||
public PBESecretKeyEncryptor getEncryptor(long keyId) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,12 +31,12 @@ public class MapBasedPassphraseProvider implements SecretKeyPassphraseProvider {
|
|||
|
||||
@Nullable
|
||||
@Override
|
||||
public Passphrase getPassphraseFor(Long keyId) {
|
||||
public Passphrase getPassphraseFor(long keyId) {
|
||||
return map.get(keyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphrase(Long keyId) {
|
||||
public boolean hasPassphrase(long keyId) {
|
||||
return map.containsKey(keyId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public interface SecretKeyPassphraseProvider {
|
|||
* @param keyId if of the secret key
|
||||
* @return passphrase or null, if no passphrase record has been found.
|
||||
*/
|
||||
@Nullable Passphrase getPassphraseFor(Long keyId);
|
||||
@Nullable Passphrase getPassphraseFor(long keyId);
|
||||
|
||||
boolean hasPassphrase(Long keyId);
|
||||
boolean hasPassphrase(long keyId);
|
||||
}
|
||||
|
|
|
@ -21,13 +21,13 @@ public class SolitaryPassphraseProvider implements SecretKeyPassphraseProvider {
|
|||
|
||||
@Nullable
|
||||
@Override
|
||||
public Passphrase getPassphraseFor(Long keyId) {
|
||||
public Passphrase getPassphraseFor(long keyId) {
|
||||
// always return the same passphrase.
|
||||
return passphrase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphrase(Long keyId) {
|
||||
public boolean hasPassphrase(long keyId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.key.protection
|
||||
|
||||
import org.bouncycastle.openpgp.PGPException
|
||||
import org.bouncycastle.openpgp.PGPSecretKey
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing
|
||||
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor
|
||||
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor
|
||||
import org.pgpainless.key.protection.passphrase_provider.SecretKeyPassphraseProvider
|
||||
import org.pgpainless.key.protection.passphrase_provider.SolitaryPassphraseProvider
|
||||
import org.pgpainless.util.Passphrase
|
||||
import kotlin.jvm.Throws
|
||||
|
||||
/**
|
||||
* Task of the [SecretKeyRingProtector] is to map encryptor/decryptor objects to key-ids.
|
||||
* [PBESecretKeyEncryptor]/[PBESecretKeyDecryptor] are used to encrypt/decrypt secret keys using a passphrase.
|
||||
*
|
||||
* While it is easy to create an implementation of this interface that fits your needs, there are a bunch of
|
||||
* implementations ready for use.
|
||||
*/
|
||||
interface SecretKeyRingProtector {
|
||||
|
||||
/**
|
||||
* Returns true, if the protector has a passphrase for the key with the given key-id.
|
||||
*
|
||||
* @param keyId key id
|
||||
* @return true if it has a passphrase, false otherwise
|
||||
*/
|
||||
fun hasPassphraseFor(keyId: Long): Boolean
|
||||
|
||||
/**
|
||||
* Return a decryptor for the key of id `keyId`.
|
||||
* This method returns null if the key is unprotected.
|
||||
*
|
||||
* @param keyId id of the key
|
||||
* @return decryptor for the key
|
||||
*/
|
||||
@Throws(PGPException::class)
|
||||
fun getDecryptor(keyId: Long): PBESecretKeyDecryptor?
|
||||
|
||||
/**
|
||||
* Return an encryptor for the key of id `keyId`.
|
||||
* This method returns null if the key is unprotected.
|
||||
*
|
||||
* @param keyId id of the key
|
||||
* @return encryptor for the key
|
||||
*/
|
||||
@Throws(PGPException::class)
|
||||
fun getEncryptor(keyId: Long): PBESecretKeyEncryptor?
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Return a protector for secret keys.
|
||||
* The protector maintains an in-memory cache of passphrases and can be extended with new passphrases
|
||||
* at runtime.
|
||||
*
|
||||
* See [CachingSecretKeyRingProtector] for how to memorize/forget additional passphrases during runtime.
|
||||
*
|
||||
* @param missingPassphraseCallback callback that is used to provide missing passphrases.
|
||||
* @return caching secret key protector
|
||||
*/
|
||||
@JvmStatic
|
||||
fun defaultSecretKeyRingProtector(
|
||||
missingPassphraseCallback: SecretKeyPassphraseProvider?
|
||||
): CachingSecretKeyRingProtector = CachingSecretKeyRingProtector(
|
||||
mapOf(), KeyRingProtectionSettings.secureDefaultSettings(), missingPassphraseCallback)
|
||||
|
||||
/**
|
||||
* Use the provided passphrase to lock/unlock all keys in the provided key ring.
|
||||
*
|
||||
* This protector will use the provided passphrase to lock/unlock all subkeys present in the provided keys object.
|
||||
* For other keys that are not present in the ring, it will return null.
|
||||
*
|
||||
* @param passphrase passphrase
|
||||
* @param keys key ring
|
||||
* @return protector
|
||||
*/
|
||||
@JvmStatic
|
||||
fun unlockEachKeyWith(passphrase: Passphrase, keys: PGPSecretKeyRing): SecretKeyRingProtector =
|
||||
fromPassphraseMap(keys.map { it.keyID }.associateWith { passphrase })
|
||||
|
||||
/**
|
||||
* Use the provided passphrase to unlock any key.
|
||||
*
|
||||
* @param passphrase passphrase
|
||||
* @return protector
|
||||
*/
|
||||
@JvmStatic
|
||||
fun unlockAnyKeyWith(passphrase: Passphrase): SecretKeyRingProtector =
|
||||
BaseSecretKeyRingProtector(SolitaryPassphraseProvider(passphrase))
|
||||
|
||||
/**
|
||||
* Use the provided passphrase to lock/unlock only the provided (sub-)key.
|
||||
* This protector will only return a non-null encryptor/decryptor based on the provided passphrase if
|
||||
* [getEncryptor]/[getDecryptor] is getting called with the key-id of the provided key.
|
||||
*
|
||||
* Otherwise, this protector will always return null.
|
||||
*
|
||||
* @param passphrase passphrase
|
||||
* @param key key to lock/unlock
|
||||
* @return protector
|
||||
*/
|
||||
@JvmStatic
|
||||
fun unlockSingleKeyWith(passphrase: Passphrase, key: PGPSecretKey): SecretKeyRingProtector =
|
||||
PasswordBasedSecretKeyRingProtector.forKey(key, passphrase)
|
||||
|
||||
/**
|
||||
* Use the provided passphrase to lock/unlock only the provided (sub-)key.
|
||||
* This protector will only return a non-null encryptor/decryptor based on the provided passphrase if
|
||||
* [getEncryptor]/[getDecryptor] is getting called with the key-id of the provided key.
|
||||
*
|
||||
* Otherwise, this protector will always return null.
|
||||
*
|
||||
* @param passphrase passphrase
|
||||
* @param keyId id of the key to lock/unlock
|
||||
* @return protector
|
||||
*/
|
||||
@JvmStatic
|
||||
fun unlockSingleKeyWith(passphrase: Passphrase, keyId: Long): SecretKeyRingProtector =
|
||||
PasswordBasedSecretKeyRingProtector.forKeyId(keyId, passphrase)
|
||||
|
||||
/**
|
||||
* Protector for unprotected keys.
|
||||
* This protector returns null for all [getEncryptor]/[getDecryptor] calls,
|
||||
* no matter what the key-id is.
|
||||
*
|
||||
* As a consequence, this protector can only "unlock" keys which are not protected using a passphrase, and it will
|
||||
* leave keys unprotected, should it be used to "protect" a key
|
||||
* (e.g. in [org.pgpainless.key.modification.secretkeyring.SecretKeyRingEditor.changePassphraseFromOldPassphrase]).
|
||||
*
|
||||
* @return protector
|
||||
*/
|
||||
@JvmStatic
|
||||
fun unprotectedKeys() = UnprotectedKeysProtector()
|
||||
|
||||
/**
|
||||
* Use the provided map of key-ids and passphrases to unlock keys.
|
||||
*
|
||||
* @param passphraseMap map of key ids and their respective passphrases
|
||||
* @return protector
|
||||
*/
|
||||
@JvmStatic
|
||||
fun fromPassphraseMap(passphraseMap: Map<Long, Passphrase>): SecretKeyRingProtector =
|
||||
CachingSecretKeyRingProtector(passphraseMap, KeyRingProtectionSettings.secureDefaultSettings(), null)
|
||||
}
|
||||
}
|
|
@ -63,13 +63,13 @@ public class MissingPassphraseForDecryptionTest {
|
|||
// interactive callback
|
||||
SecretKeyPassphraseProvider callback = new SecretKeyPassphraseProvider() {
|
||||
@Override
|
||||
public Passphrase getPassphraseFor(Long keyId) {
|
||||
public Passphrase getPassphraseFor(long keyId) {
|
||||
// is called in interactive mode
|
||||
return Passphrase.fromPassword(passphrase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphrase(Long keyId) {
|
||||
public boolean hasPassphrase(long keyId) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -95,13 +95,13 @@ public class MissingPassphraseForDecryptionTest {
|
|||
|
||||
SecretKeyPassphraseProvider callback = new SecretKeyPassphraseProvider() {
|
||||
@Override
|
||||
public Passphrase getPassphraseFor(Long keyId) {
|
||||
public Passphrase getPassphraseFor(long keyId) {
|
||||
fail("MUST NOT get called in non-interactive mode.");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphrase(Long keyId) {
|
||||
public boolean hasPassphrase(long keyId) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -120,13 +120,13 @@ public class PostponeDecryptionUsingKeyWithMissingPassphraseTest {
|
|||
public void missingPassphraseFirst() throws PGPException, IOException {
|
||||
SecretKeyRingProtector protector1 = new CachingSecretKeyRingProtector(new SecretKeyPassphraseProvider() {
|
||||
@Override
|
||||
public Passphrase getPassphraseFor(Long keyId) {
|
||||
public Passphrase getPassphraseFor(long keyId) {
|
||||
fail("Although the first PKESK is for k1, we should have skipped it and tried k2 first, which has passphrase available.");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphrase(Long keyId) {
|
||||
public boolean hasPassphrase(long keyId) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
@ -150,13 +150,13 @@ public class PostponeDecryptionUsingKeyWithMissingPassphraseTest {
|
|||
SecretKeyRingProtector protector1 = SecretKeyRingProtector.unlockEachKeyWith(p1, k1);
|
||||
SecretKeyRingProtector protector2 = new CachingSecretKeyRingProtector(new SecretKeyPassphraseProvider() {
|
||||
@Override
|
||||
public Passphrase getPassphraseFor(Long keyId) {
|
||||
public Passphrase getPassphraseFor(long keyId) {
|
||||
fail("This callback should not get called, since the first PKESK is for k1, which has a passphrase available.");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphrase(Long keyId) {
|
||||
public boolean hasPassphrase(long keyId) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
@ -178,13 +178,13 @@ public class PostponeDecryptionUsingKeyWithMissingPassphraseTest {
|
|||
public void messagePassphraseFirst() throws PGPException, IOException {
|
||||
SecretKeyPassphraseProvider provider = new SecretKeyPassphraseProvider() {
|
||||
@Override
|
||||
public Passphrase getPassphraseFor(Long keyId) {
|
||||
public Passphrase getPassphraseFor(long keyId) {
|
||||
fail("Since we provide a decryption passphrase, we should not try to decrypt any key.");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphrase(Long keyId) {
|
||||
public boolean hasPassphrase(long keyId) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -32,13 +32,13 @@ public class CachingSecretKeyRingProtectorTest {
|
|||
// Dummy passphrase callback that returns the doubled key-id as passphrase
|
||||
private final SecretKeyPassphraseProvider dummyCallback = new SecretKeyPassphraseProvider() {
|
||||
@Override
|
||||
public Passphrase getPassphraseFor(Long keyId) {
|
||||
public Passphrase getPassphraseFor(long keyId) {
|
||||
long doubled = keyId * 2;
|
||||
return Passphrase.fromPassword(Long.toString(doubled));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphrase(Long keyId) {
|
||||
public boolean hasPassphrase(long keyId) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -31,8 +31,8 @@ public class PassphraseProtectedKeyTest {
|
|||
new SecretKeyPassphraseProvider() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Passphrase getPassphraseFor(Long keyId) {
|
||||
if (keyId.equals(TestKeys.CRYPTIE_KEY_ID)) {
|
||||
public Passphrase getPassphraseFor(long keyId) {
|
||||
if (keyId == TestKeys.CRYPTIE_KEY_ID) {
|
||||
return new Passphrase(TestKeys.CRYPTIE_PASSWORD.toCharArray());
|
||||
} else {
|
||||
return null;
|
||||
|
@ -40,8 +40,8 @@ public class PassphraseProtectedKeyTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphrase(Long keyId) {
|
||||
return keyId.equals(TestKeys.CRYPTIE_KEY_ID);
|
||||
public boolean hasPassphrase(long keyId) {
|
||||
return keyId == TestKeys.CRYPTIE_KEY_ID;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -108,12 +108,12 @@ public class SecretKeyRingProtectorTest {
|
|||
CachingSecretKeyRingProtector protector = new CachingSecretKeyRingProtector(passphraseMap,
|
||||
KeyRingProtectionSettings.secureDefaultSettings(), new SecretKeyPassphraseProvider() {
|
||||
@Override
|
||||
public Passphrase getPassphraseFor(Long keyId) {
|
||||
public Passphrase getPassphraseFor(long keyId) {
|
||||
return Passphrase.fromPassword("missingP455w0rd");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphrase(Long keyId) {
|
||||
public boolean hasPassphrase(long keyId) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -88,19 +88,19 @@ public class MatchMakingSecretKeyRingProtector implements SecretKeyRingProtector
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPassphraseFor(Long keyId) {
|
||||
public boolean hasPassphraseFor(long keyId) {
|
||||
return protector.hasPassphrase(keyId);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PBESecretKeyDecryptor getDecryptor(Long keyId) throws PGPException {
|
||||
public PBESecretKeyDecryptor getDecryptor(long keyId) throws PGPException {
|
||||
return protector.getDecryptor(keyId);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PBESecretKeyEncryptor getEncryptor(Long keyId) throws PGPException {
|
||||
public PBESecretKeyEncryptor getEncryptor(long keyId) throws PGPException {
|
||||
return protector.getEncryptor(keyId);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue