mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-27 06:42:05 +01:00
Throw WrongPassphraseException when wrong passphrase is provided to unlock secret key
This commit is contained in:
parent
32e1b0c838
commit
5a56949dd7
11 changed files with 172 additions and 24 deletions
|
@ -60,6 +60,7 @@ import org.pgpainless.implementation.ImplementationFactory;
|
||||||
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
import org.pgpainless.key.SubkeyIdentifier;
|
import org.pgpainless.key.SubkeyIdentifier;
|
||||||
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||||
|
import org.pgpainless.key.protection.UnlockSecretKey;
|
||||||
import org.pgpainless.signature.DetachedSignature;
|
import org.pgpainless.signature.DetachedSignature;
|
||||||
import org.pgpainless.signature.OnePassSignature;
|
import org.pgpainless.signature.OnePassSignature;
|
||||||
import org.pgpainless.util.IntegrityProtectedInputStream;
|
import org.pgpainless.util.IntegrityProtectedInputStream;
|
||||||
|
@ -209,7 +210,7 @@ public final class DecryptionStreamFactory {
|
||||||
if (!encryptedData.isIntegrityProtected()) {
|
if (!encryptedData.isIntegrityProtected()) {
|
||||||
throw new MessageNotIntegrityProtectedException();
|
throw new MessageNotIntegrityProtectedException();
|
||||||
}
|
}
|
||||||
|
// Data is passphrase encrypted
|
||||||
if (encryptedData instanceof PGPPBEEncryptedData) {
|
if (encryptedData instanceof PGPPBEEncryptedData) {
|
||||||
PGPPBEEncryptedData pbeEncryptedData = (PGPPBEEncryptedData) encryptedData;
|
PGPPBEEncryptedData pbeEncryptedData = (PGPPBEEncryptedData) encryptedData;
|
||||||
if (decryptionPassphrase != null) {
|
if (decryptionPassphrase != null) {
|
||||||
|
@ -228,8 +229,9 @@ public final class DecryptionStreamFactory {
|
||||||
LOGGER.log(LEVEL, "Probable passphrase mismatch, skip PBE encrypted data block", e);
|
LOGGER.log(LEVEL, "Probable passphrase mismatch, skip PBE encrypted data block", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (encryptedData instanceof PGPPublicKeyEncryptedData) {
|
// data is public key encrypted
|
||||||
|
else if (encryptedData instanceof PGPPublicKeyEncryptedData) {
|
||||||
PGPPublicKeyEncryptedData publicKeyEncryptedData = (PGPPublicKeyEncryptedData) encryptedData;
|
PGPPublicKeyEncryptedData publicKeyEncryptedData = (PGPPublicKeyEncryptedData) encryptedData;
|
||||||
long keyId = publicKeyEncryptedData.getKeyID();
|
long keyId = publicKeyEncryptedData.getKeyID();
|
||||||
if (decryptionKeys != null) {
|
if (decryptionKeys != null) {
|
||||||
|
@ -242,7 +244,7 @@ public final class DecryptionStreamFactory {
|
||||||
LOGGER.log(LEVEL, "Found respective secret key " + Long.toHexString(keyId));
|
LOGGER.log(LEVEL, "Found respective secret key " + Long.toHexString(keyId));
|
||||||
// Watch out! This assignment is possibly done multiple times.
|
// Watch out! This assignment is possibly done multiple times.
|
||||||
encryptedSessionKey = publicKeyEncryptedData;
|
encryptedSessionKey = publicKeyEncryptedData;
|
||||||
decryptionKey = secretKey.extractPrivateKey(decryptionKeyDecryptor.getDecryptor(keyId));
|
decryptionKey = UnlockSecretKey.unlockSecretKey(secretKey, decryptionKeyDecryptor);
|
||||||
resultBuilder.setDecryptionFingerprint(new OpenPgpV4Fingerprint(secretKey));
|
resultBuilder.setDecryptionFingerprint(new OpenPgpV4Fingerprint(secretKey));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -46,6 +46,7 @@ import org.pgpainless.key.KeyRingValidator;
|
||||||
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
import org.pgpainless.key.SubkeyIdentifier;
|
import org.pgpainless.key.SubkeyIdentifier;
|
||||||
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||||
|
import org.pgpainless.key.protection.UnlockSecretKey;
|
||||||
import org.pgpainless.util.Passphrase;
|
import org.pgpainless.util.Passphrase;
|
||||||
import org.pgpainless.util.Tuple;
|
import org.pgpainless.util.Tuple;
|
||||||
import org.pgpainless.util.selection.key.PublicKeySelectionStrategy;
|
import org.pgpainless.util.selection.key.PublicKeySelectionStrategy;
|
||||||
|
@ -345,7 +346,7 @@ public class EncryptionBuilder implements EncryptionBuilderInterface {
|
||||||
PGPSecretKeyRing secretKeyRing = signingKeys.get(signingKey);
|
PGPSecretKeyRing secretKeyRing = signingKeys.get(signingKey);
|
||||||
PGPSecretKey secretKey = secretKeyRing.getSecretKey(signingKey.getSubkeyFingerprint().getKeyId());
|
PGPSecretKey secretKey = secretKeyRing.getSecretKey(signingKey.getSubkeyFingerprint().getKeyId());
|
||||||
PBESecretKeyDecryptor decryptor = signingKeysDecryptor.getDecryptor(secretKey.getKeyID());
|
PBESecretKeyDecryptor decryptor = signingKeysDecryptor.getDecryptor(secretKey.getKeyID());
|
||||||
PGPPrivateKey privateKey = secretKey.extractPrivateKey(decryptor);
|
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, decryptor);
|
||||||
privateKeys.put(signingKey, new Tuple<>(secretKeyRing, privateKey));
|
privateKeys.put(signingKey, new Tuple<>(secretKeyRing, privateKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.pgpainless.exception;
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
|
||||||
|
public class WrongPassphraseException extends PGPException {
|
||||||
|
|
||||||
|
public WrongPassphraseException(long keyId, PGPException cause) {
|
||||||
|
this("Wrong passphrase provided for key " + Long.toHexString(keyId), cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WrongPassphraseException(String message, PGPException cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -57,6 +57,7 @@ import org.pgpainless.key.generation.type.KeyType;
|
||||||
import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
|
import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
|
||||||
import org.pgpainless.key.generation.type.rsa.RsaLength;
|
import org.pgpainless.key.generation.type.rsa.RsaLength;
|
||||||
import org.pgpainless.key.generation.type.xdh.XDHCurve;
|
import org.pgpainless.key.generation.type.xdh.XDHCurve;
|
||||||
|
import org.pgpainless.key.protection.UnlockSecretKey;
|
||||||
import org.pgpainless.key.util.UserId;
|
import org.pgpainless.key.util.UserId;
|
||||||
import org.pgpainless.provider.ProviderFactory;
|
import org.pgpainless.provider.ProviderFactory;
|
||||||
import org.pgpainless.util.Passphrase;
|
import org.pgpainless.util.Passphrase;
|
||||||
|
@ -376,7 +377,7 @@ public class KeyRingBuilder implements KeyRingBuilderInterface {
|
||||||
|
|
||||||
// Attempt to add additional user-ids to the primary public key
|
// Attempt to add additional user-ids to the primary public key
|
||||||
PGPPublicKey primaryPubKey = secretKeys.next().getPublicKey();
|
PGPPublicKey primaryPubKey = secretKeys.next().getPublicKey();
|
||||||
PGPPrivateKey privateKey = secretKeyRing.getSecretKey().extractPrivateKey(secretKeyDecryptor);
|
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKeyRing.getSecretKey(), secretKeyDecryptor);
|
||||||
for (String additionalUserId : additionalUserIds) {
|
for (String additionalUserId : additionalUserIds) {
|
||||||
signatureGenerator.init(SignatureType.POSITIVE_CERTIFICATION.getCode(), privateKey);
|
signatureGenerator.init(SignatureType.POSITIVE_CERTIFICATION.getCode(), privateKey);
|
||||||
PGPSignature additionalUserIdSignature =
|
PGPSignature additionalUserIdSignature =
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package org.pgpainless.key.modification.secretkeyring;
|
package org.pgpainless.key.modification.secretkeyring;
|
||||||
|
|
||||||
import static org.pgpainless.key.util.KeyRingUtils.unlockSecretKey;
|
|
||||||
import static org.pgpainless.util.CollectionUtils.iteratorToList;
|
import static org.pgpainless.util.CollectionUtils.iteratorToList;
|
||||||
|
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
@ -59,6 +58,7 @@ import org.pgpainless.key.protection.KeyRingProtectionSettings;
|
||||||
import org.pgpainless.key.protection.PassphraseMapKeyRingProtector;
|
import org.pgpainless.key.protection.PassphraseMapKeyRingProtector;
|
||||||
import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector;
|
import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector;
|
||||||
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||||
|
import org.pgpainless.key.protection.UnlockSecretKey;
|
||||||
import org.pgpainless.key.protection.UnprotectedKeysProtector;
|
import org.pgpainless.key.protection.UnprotectedKeysProtector;
|
||||||
import org.pgpainless.key.protection.passphrase_provider.SolitaryPassphraseProvider;
|
import org.pgpainless.key.protection.passphrase_provider.SolitaryPassphraseProvider;
|
||||||
import org.pgpainless.key.util.KeyRingUtils;
|
import org.pgpainless.key.util.KeyRingUtils;
|
||||||
|
@ -102,7 +102,7 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
||||||
if (secretKey.getKeyID() == keyId) {
|
if (secretKey.getKeyID() == keyId) {
|
||||||
found = true;
|
found = true;
|
||||||
PGPPublicKey publicKey = secretKey.getPublicKey();
|
PGPPublicKey publicKey = secretKey.getPublicKey();
|
||||||
PGPPrivateKey privateKey = unlockSecretKey(secretKey, secretKeyRingProtector);
|
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, secretKeyRingProtector);
|
||||||
publicKey = addUserIdToPubKey(userId, privateKey, publicKey);
|
publicKey = addUserIdToPubKey(userId, privateKey, publicKey);
|
||||||
secretKey = PGPSecretKey.replacePublicKey(secretKey, publicKey);
|
secretKey = PGPSecretKey.replacePublicKey(secretKey, publicKey);
|
||||||
}
|
}
|
||||||
|
@ -222,7 +222,7 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
||||||
HashAlgorithm.SHA256.getAlgorithmId() // TODO: Why SHA256?
|
HashAlgorithm.SHA256.getAlgorithmId() // TODO: Why SHA256?
|
||||||
);
|
);
|
||||||
|
|
||||||
PGPPrivateKey privateSubKey = unlockSecretKey(secretSubKey, subKeyProtector);
|
PGPPrivateKey privateSubKey = UnlockSecretKey.unlockSecretKey(secretSubKey, subKeyProtector);
|
||||||
PGPKeyPair subKeyPair = new PGPKeyPair(secretSubKey.getPublicKey(), privateSubKey);
|
PGPKeyPair subKeyPair = new PGPKeyPair(secretSubKey.getPublicKey(), privateSubKey);
|
||||||
|
|
||||||
PGPKeyRingGenerator keyRingGenerator = new PGPKeyRingGenerator(
|
PGPKeyRingGenerator keyRingGenerator = new PGPKeyRingGenerator(
|
||||||
|
@ -362,7 +362,7 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
||||||
RevocationAttributes revocationAttributes) throws PGPException {
|
RevocationAttributes revocationAttributes) throws PGPException {
|
||||||
PGPPublicKey publicKey = KeyRingUtils.requirePublicKeyFrom(secretKeyRing, subKeyId);
|
PGPPublicKey publicKey = KeyRingUtils.requirePublicKeyFrom(secretKeyRing, subKeyId);
|
||||||
PGPSecretKey primaryKey = secretKeyRing.getSecretKey();
|
PGPSecretKey primaryKey = secretKeyRing.getSecretKey();
|
||||||
PGPPrivateKey privateKey = unlockSecretKey(primaryKey, protector);
|
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(primaryKey, protector);
|
||||||
|
|
||||||
PGPSignatureSubpacketGenerator subpacketGenerator = new PGPSignatureSubpacketGenerator();
|
PGPSignatureSubpacketGenerator subpacketGenerator = new PGPSignatureSubpacketGenerator();
|
||||||
subpacketGenerator.setSignatureCreationTime(false, new Date());
|
subpacketGenerator.setSignatureCreationTime(false, new Date());
|
||||||
|
@ -445,7 +445,7 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
||||||
throw new IllegalArgumentException("Expiration date cannot be before creation date.");
|
throw new IllegalArgumentException("Expiration date cannot be before creation date.");
|
||||||
}
|
}
|
||||||
|
|
||||||
PGPPrivateKey privateKey = KeyRingUtils.unlockSecretKey(primaryKey, secretKeyRingProtector);
|
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(primaryKey, secretKeyRingProtector);
|
||||||
PGPPublicKey subjectPubKey = subjectKey.getPublicKey();
|
PGPPublicKey subjectPubKey = subjectKey.getPublicKey();
|
||||||
|
|
||||||
PGPSignature oldSignature = getPreviousSignature(primaryKey, subjectPubKey);
|
PGPSignature oldSignature = getPreviousSignature(primaryKey, subjectPubKey);
|
||||||
|
@ -562,7 +562,7 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
||||||
PGPSignatureSubpacketVector subPackets = subpacketGenerator.generate();
|
PGPSignatureSubpacketVector subPackets = subpacketGenerator.generate();
|
||||||
signatureGenerator.setHashedSubpackets(subPackets);
|
signatureGenerator.setHashedSubpackets(subPackets);
|
||||||
|
|
||||||
PGPPrivateKey privateKey = primaryKey.extractPrivateKey(protector.getDecryptor(primaryKey.getKeyID()));
|
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(primaryKey, protector);
|
||||||
|
|
||||||
PGPSignature revocation;
|
PGPSignature revocation;
|
||||||
if (revokeeSubKey.isMasterKey()) {
|
if (revokeeSubKey.isMasterKey()) {
|
||||||
|
@ -675,7 +675,7 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
||||||
Iterator<PGPSecretKey> secretKeyIterator = secretKeys.getSecretKeys();
|
Iterator<PGPSecretKey> secretKeyIterator = secretKeys.getSecretKeys();
|
||||||
while (secretKeyIterator.hasNext()) {
|
while (secretKeyIterator.hasNext()) {
|
||||||
PGPSecretKey secretKey = secretKeyIterator.next();
|
PGPSecretKey secretKey = secretKeyIterator.next();
|
||||||
PGPPrivateKey privateKey = unlockSecretKey(secretKey, oldProtector);
|
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, oldProtector);
|
||||||
secretKey = lockPrivateKey(privateKey, secretKey.getPublicKey(), newProtector);
|
secretKey = lockPrivateKey(privateKey, secretKey.getPublicKey(), newProtector);
|
||||||
newlyEncryptedSecretKeys.add(secretKey);
|
newlyEncryptedSecretKeys.add(secretKey);
|
||||||
}
|
}
|
||||||
|
@ -689,7 +689,7 @@ public class SecretKeyRingEditor implements SecretKeyRingEditorInterface {
|
||||||
|
|
||||||
if (secretKey.getPublicKey().getKeyID() == keyId) {
|
if (secretKey.getPublicKey().getKeyID() == keyId) {
|
||||||
// Re-encrypt only the selected subkey
|
// Re-encrypt only the selected subkey
|
||||||
PGPPrivateKey privateKey = unlockSecretKey(secretKey, oldProtector);
|
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, oldProtector);
|
||||||
secretKey = lockPrivateKey(privateKey, secretKey.getPublicKey(), newProtector);
|
secretKey = lockPrivateKey(privateKey, secretKey.getPublicKey(), newProtector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.pgpainless.key.protection;
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPPrivateKey;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||||
|
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
|
||||||
|
import org.pgpainless.exception.WrongPassphraseException;
|
||||||
|
import org.pgpainless.util.Passphrase;
|
||||||
|
|
||||||
|
public class UnlockSecretKey {
|
||||||
|
|
||||||
|
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, SecretKeyRingProtector protector)
|
||||||
|
throws WrongPassphraseException {
|
||||||
|
try {
|
||||||
|
PBESecretKeyDecryptor decryptor = protector.getDecryptor(secretKey.getKeyID());
|
||||||
|
return secretKey.extractPrivateKey(decryptor);
|
||||||
|
} catch (PGPException e) {
|
||||||
|
throw new WrongPassphraseException(secretKey.getKeyID(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, SecretKeyRingProtector2 protector) throws WrongPassphraseException {
|
||||||
|
try {
|
||||||
|
PBESecretKeyDecryptor decryptor = protector.getDecryptor(secretKey);
|
||||||
|
return secretKey.extractPrivateKey(decryptor);
|
||||||
|
} catch (PGPException e) {
|
||||||
|
throw new WrongPassphraseException(secretKey.getKeyID(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, PBESecretKeyDecryptor decryptor) throws WrongPassphraseException {
|
||||||
|
try {
|
||||||
|
return secretKey.extractPrivateKey(decryptor);
|
||||||
|
} catch (PGPException e) {
|
||||||
|
throw new WrongPassphraseException(secretKey.getKeyID(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, Passphrase passphrase) throws WrongPassphraseException {
|
||||||
|
return unlockSecretKey(secretKey, SecretKeyRingProtector.unlockSingleKeyWith(passphrase, secretKey));
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,8 +27,8 @@ import org.bouncycastle.openpgp.PGPPublicKey;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
|
|
||||||
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||||
|
import org.pgpainless.key.protection.UnlockSecretKey;
|
||||||
|
|
||||||
public class KeyRingUtils {
|
public class KeyRingUtils {
|
||||||
|
|
||||||
|
@ -136,8 +136,6 @@ public class KeyRingUtils {
|
||||||
* @throws PGPException if something goes wrong (eg. wrong passphrase)
|
* @throws PGPException if something goes wrong (eg. wrong passphrase)
|
||||||
*/
|
*/
|
||||||
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, SecretKeyRingProtector protector) throws PGPException {
|
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, SecretKeyRingProtector protector) throws PGPException {
|
||||||
PBESecretKeyDecryptor secretKeyDecryptor = protector.getDecryptor(secretKey.getKeyID());
|
return UnlockSecretKey.unlockSecretKey(secretKey, protector);
|
||||||
PGPPrivateKey privateKey = secretKey.extractPrivateKey(secretKeyDecryptor);
|
|
||||||
return privateKey;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,8 @@ import org.pgpainless.key.generation.KeySpec;
|
||||||
import org.pgpainless.key.generation.type.ecc.EllipticCurve;
|
import org.pgpainless.key.generation.type.ecc.EllipticCurve;
|
||||||
import org.pgpainless.key.generation.type.ecc.ecdsa.ECDSA;
|
import org.pgpainless.key.generation.type.ecc.ecdsa.ECDSA;
|
||||||
import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector;
|
import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector;
|
||||||
|
import org.pgpainless.key.protection.SecretKeyRingProtector;
|
||||||
|
import org.pgpainless.key.protection.UnlockSecretKey;
|
||||||
import org.pgpainless.util.Passphrase;
|
import org.pgpainless.util.Passphrase;
|
||||||
|
|
||||||
public class AddSubKeyTest {
|
public class AddSubKeyTest {
|
||||||
|
@ -73,9 +75,8 @@ public class AddSubKeyTest {
|
||||||
long subKeyId = keyIdsAfter.get(0);
|
long subKeyId = keyIdsAfter.get(0);
|
||||||
|
|
||||||
PGPSecretKey subKey = secretKeys.getSecretKey(subKeyId);
|
PGPSecretKey subKey = secretKeys.getSecretKey(subKeyId);
|
||||||
PGPPrivateKey privateKey = subKey.extractPrivateKey(
|
SecretKeyRingProtector protector = SecretKeyRingProtector.unlockAllKeysWith(
|
||||||
PasswordBasedSecretKeyRingProtector
|
Passphrase.fromPassword("subKeyPassphrase"), secretKeys);
|
||||||
.forKey(subKey, Passphrase.fromPassword("subKeyPassphrase"))
|
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(subKey, protector);
|
||||||
.getDecryptor(subKeyId));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ import org.pgpainless.encryption_signing.EncryptionStream;
|
||||||
import org.pgpainless.implementation.ImplementationFactory;
|
import org.pgpainless.implementation.ImplementationFactory;
|
||||||
import org.pgpainless.key.protection.KeyRingProtectionSettings;
|
import org.pgpainless.key.protection.KeyRingProtectionSettings;
|
||||||
import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector;
|
import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector;
|
||||||
|
import org.pgpainless.key.protection.UnlockSecretKey;
|
||||||
import org.pgpainless.util.Passphrase;
|
import org.pgpainless.util.Passphrase;
|
||||||
|
|
||||||
public class ChangeSecretKeyRingPassphraseTest {
|
public class ChangeSecretKeyRingPassphraseTest {
|
||||||
|
@ -184,7 +185,7 @@ public class ChangeSecretKeyRingPassphraseTest {
|
||||||
PBESecretKeyDecryptor decryptor = passphrase.isEmpty() ? null : new BcPBESecretKeyDecryptorBuilder(digestCalculatorProvider)
|
PBESecretKeyDecryptor decryptor = passphrase.isEmpty() ? null : new BcPBESecretKeyDecryptorBuilder(digestCalculatorProvider)
|
||||||
.build(passphrase.getChars());
|
.build(passphrase.getChars());
|
||||||
|
|
||||||
secretKey.extractPrivateKey(decryptor);
|
UnlockSecretKey.unlockSecretKey(secretKey, decryptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void signDummyMessageWithKeysAndPassphrase(PGPSecretKeyRing keyRing, Passphrase passphrase) throws IOException, PGPException {
|
private void signDummyMessageWithKeysAndPassphrase(PGPSecretKeyRing keyRing, Passphrase passphrase) throws IOException, PGPException {
|
||||||
|
|
|
@ -140,7 +140,7 @@ public class SecretKeyRingProtectorTest {
|
||||||
|
|
||||||
PGPSecretKeyRing secretKeys = TestKeys.getEmilSecretKeyRing();
|
PGPSecretKeyRing secretKeys = TestKeys.getEmilSecretKeyRing();
|
||||||
for (PGPSecretKey secretKey : secretKeys) {
|
for (PGPSecretKey secretKey : secretKeys) {
|
||||||
secretKey.extractPrivateKey(protector.getDecryptor(secretKey));
|
UnlockSecretKey.unlockSecretKey(secretKey, protector);
|
||||||
assertNotNull(protector.getEncryptor(secretKey));
|
assertNotNull(protector.getEncryptor(secretKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Paul Schaub.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.pgpainless.key.protection;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPPrivateKey;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.pgpainless.PGPainless;
|
||||||
|
import org.pgpainless.exception.WrongPassphraseException;
|
||||||
|
import org.pgpainless.util.Passphrase;
|
||||||
|
|
||||||
|
public class UnlockSecretKeyTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUnlockSecretKey() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
||||||
|
PGPSecretKeyRing secretKeyRing = PGPainless.generateKeyRing()
|
||||||
|
.simpleEcKeyRing("alice@wonderland.lit", "heureka!");
|
||||||
|
PGPSecretKey secretKey = secretKeyRing.getSecretKey();
|
||||||
|
|
||||||
|
SecretKeyRingProtector correctPassphrase = SecretKeyRingProtector.unlockAllKeysWith(Passphrase.fromPassword("heureka!"), secretKeyRing);
|
||||||
|
SecretKeyRingProtector incorrectPassphrase = SecretKeyRingProtector.unlockAllKeysWith(Passphrase.fromPassword("bazinga!"), secretKeyRing);
|
||||||
|
SecretKeyRingProtector emptyPassphrase = SecretKeyRingProtector.unlockAllKeysWith(Passphrase.emptyPassphrase(), secretKeyRing);
|
||||||
|
Passphrase cleared = Passphrase.fromPassword("cleared");
|
||||||
|
cleared.clear();
|
||||||
|
SecretKeyRingProtector invalidPassphrase = SecretKeyRingProtector.unlockAllKeysWith(cleared, secretKeyRing);
|
||||||
|
// Correct passphrase works
|
||||||
|
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, correctPassphrase);
|
||||||
|
assertNotNull(privateKey);
|
||||||
|
|
||||||
|
assertThrows(WrongPassphraseException.class, () ->
|
||||||
|
UnlockSecretKey.unlockSecretKey(secretKey, incorrectPassphrase));
|
||||||
|
assertThrows(WrongPassphraseException.class, () ->
|
||||||
|
UnlockSecretKey.unlockSecretKey(secretKey, emptyPassphrase));
|
||||||
|
assertThrows(WrongPassphraseException.class, () ->
|
||||||
|
UnlockSecretKey.unlockSecretKey(secretKey, invalidPassphrase));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue