1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-01-09 19:57:57 +01:00

Fix NPE when attempting to decrypt GNU_DUMMY_S2K keys

This commit is contained in:
Paul Schaub 2021-12-06 15:01:37 +01:00
parent 601efd94f2
commit 073cf870d2
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
10 changed files with 48 additions and 43 deletions

View file

@ -20,27 +20,40 @@ public final class UnlockSecretKey {
} }
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, SecretKeyRingProtector protector) public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, SecretKeyRingProtector protector)
throws WrongPassphraseException { throws PGPException {
PBESecretKeyDecryptor decryptor = null;
if (KeyInfo.isEncrypted(secretKey)) {
decryptor = protector.getDecryptor(secretKey.getKeyID());
}
PGPPrivateKey privateKey = unlockSecretKey(secretKey, decryptor);
return privateKey;
}
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, PBESecretKeyDecryptor decryptor)
throws PGPException {
PGPPrivateKey privateKey;
try { try {
PBESecretKeyDecryptor decryptor = null; privateKey = secretKey.extractPrivateKey(decryptor);
if (KeyInfo.isEncrypted(secretKey)) { } catch (PGPException e) {
decryptor = protector.getDecryptor(secretKey.getKeyID()); throw new WrongPassphraseException(secretKey.getKeyID(), e);
}
if (privateKey == null) {
int s2kType = secretKey.getS2K().getType();
if (s2kType >= 100 && s2kType <= 110) {
throw new PGPException("Cannot decrypt secret key" + Long.toHexString(secretKey.getKeyID()) + ": " +
"Unsupported private S2K usage type " + s2kType);
} }
return secretKey.extractPrivateKey(decryptor);
} catch (PGPException e) { throw new PGPException("Cannot decrypt secret key.");
throw new WrongPassphraseException(secretKey.getKeyID(), e);
} }
return privateKey;
} }
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, PBESecretKeyDecryptor decryptor) throws WrongPassphraseException { public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, Passphrase passphrase)
try { throws PGPException {
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)); return unlockSecretKey(secretKey, SecretKeyRingProtector.unlockSingleKeyWith(passphrase, secretKey));
} }
} }

View file

@ -5,6 +5,7 @@
package org.pgpainless.signature.builder; package org.pgpainless.signature.builder;
import java.util.Set; import java.util.Set;
import javax.annotation.Nonnull;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPrivateKey;
@ -16,7 +17,6 @@ import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.HashAlgorithm; import org.pgpainless.algorithm.HashAlgorithm;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.algorithm.negotiation.HashAlgorithmNegotiator; import org.pgpainless.algorithm.negotiation.HashAlgorithmNegotiator;
import org.pgpainless.exception.WrongPassphraseException;
import org.pgpainless.implementation.ImplementationFactory; import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.key.protection.UnlockSecretKey; import org.pgpainless.key.protection.UnlockSecretKey;
@ -24,8 +24,6 @@ import org.pgpainless.key.util.OpenPgpKeyAttributeUtil;
import org.pgpainless.signature.subpackets.SignatureSubpackets; import org.pgpainless.signature.subpackets.SignatureSubpackets;
import org.pgpainless.signature.subpackets.SignatureSubpacketsHelper; import org.pgpainless.signature.subpackets.SignatureSubpacketsHelper;
import javax.annotation.Nonnull;
public abstract class AbstractSignatureBuilder<B extends AbstractSignatureBuilder<B>> { public abstract class AbstractSignatureBuilder<B extends AbstractSignatureBuilder<B>> {
protected final PGPPrivateKey privateSigningKey; protected final PGPPrivateKey privateSigningKey;
protected final PGPPublicKey publicSigningKey; protected final PGPPublicKey publicSigningKey;
@ -42,7 +40,7 @@ public abstract class AbstractSignatureBuilder<B extends AbstractSignatureBuilde
HashAlgorithm hashAlgorithm, HashAlgorithm hashAlgorithm,
SignatureSubpackets hashedSubpackets, SignatureSubpackets hashedSubpackets,
SignatureSubpackets unhashedSubpackets) SignatureSubpackets unhashedSubpackets)
throws WrongPassphraseException { throws PGPException {
if (!isValidSignatureType(signatureType)) { if (!isValidSignatureType(signatureType)) {
throw new IllegalArgumentException("Invalid signature type."); throw new IllegalArgumentException("Invalid signature type.");
} }
@ -55,7 +53,7 @@ public abstract class AbstractSignatureBuilder<B extends AbstractSignatureBuilde
} }
public AbstractSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector) public AbstractSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector)
throws WrongPassphraseException { throws PGPException {
this( this(
signatureType, signatureType,
signingKey, signingKey,
@ -67,7 +65,7 @@ public abstract class AbstractSignatureBuilder<B extends AbstractSignatureBuilde
} }
public AbstractSignatureBuilder(PGPSecretKey certificationKey, SecretKeyRingProtector protector, PGPSignature archetypeSignature) public AbstractSignatureBuilder(PGPSecretKey certificationKey, SecretKeyRingProtector protector, PGPSignature archetypeSignature)
throws WrongPassphraseException { throws PGPException {
this( this(
SignatureType.valueOf(archetypeSignature.getSignatureType()), SignatureType.valueOf(archetypeSignature.getSignatureType()),
certificationKey, certificationKey,

View file

@ -11,17 +11,17 @@ import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.exception.WrongPassphraseException;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets; import org.pgpainless.signature.subpackets.SelfSignatureSubpackets;
public class DirectKeySignatureBuilder extends AbstractSignatureBuilder<DirectKeySignatureBuilder> { public class DirectKeySignatureBuilder extends AbstractSignatureBuilder<DirectKeySignatureBuilder> {
public DirectKeySignatureBuilder(PGPSecretKey certificationKey, SecretKeyRingProtector protector, PGPSignature archetypeSignature) throws WrongPassphraseException { public DirectKeySignatureBuilder(PGPSecretKey certificationKey, SecretKeyRingProtector protector, PGPSignature archetypeSignature)
throws PGPException {
super(certificationKey, protector, archetypeSignature); super(certificationKey, protector, archetypeSignature);
} }
public DirectKeySignatureBuilder(PGPSecretKey signingKey, SecretKeyRingProtector protector) throws WrongPassphraseException { public DirectKeySignatureBuilder(PGPSecretKey signingKey, SecretKeyRingProtector protector) throws PGPException {
super(SignatureType.DIRECT_KEY, signingKey, protector); super(SignatureType.DIRECT_KEY, signingKey, protector);
} }

View file

@ -11,14 +11,13 @@ import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.exception.WrongPassphraseException;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets; import org.pgpainless.signature.subpackets.SelfSignatureSubpackets;
public class PrimaryKeyBindingSignatureBuilder extends AbstractSignatureBuilder<PrimaryKeyBindingSignatureBuilder> { public class PrimaryKeyBindingSignatureBuilder extends AbstractSignatureBuilder<PrimaryKeyBindingSignatureBuilder> {
public PrimaryKeyBindingSignatureBuilder(PGPSecretKey subkey, SecretKeyRingProtector subkeyProtector) public PrimaryKeyBindingSignatureBuilder(PGPSecretKey subkey, SecretKeyRingProtector subkeyProtector)
throws WrongPassphraseException { throws PGPException {
super(SignatureType.PRIMARYKEY_BINDING, subkey, subkeyProtector); super(SignatureType.PRIMARYKEY_BINDING, subkey, subkeyProtector);
} }

View file

@ -12,13 +12,12 @@ import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.exception.WrongPassphraseException;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.signature.subpackets.RevocationSignatureSubpackets; import org.pgpainless.signature.subpackets.RevocationSignatureSubpackets;
public class RevocationSignatureBuilder extends AbstractSignatureBuilder<RevocationSignatureBuilder> { public class RevocationSignatureBuilder extends AbstractSignatureBuilder<RevocationSignatureBuilder> {
public RevocationSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector) throws WrongPassphraseException { public RevocationSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector) throws PGPException {
super(signatureType, signingKey, protector); super(signatureType, signingKey, protector);
getHashedSubpackets().setRevocable(true, false); getHashedSubpackets().setRevocable(true, false);
} }

View file

@ -12,18 +12,17 @@ import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.exception.WrongPassphraseException;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets; import org.pgpainless.signature.subpackets.SelfSignatureSubpackets;
public class SelfSignatureBuilder extends AbstractSignatureBuilder<SelfSignatureBuilder> { public class SelfSignatureBuilder extends AbstractSignatureBuilder<SelfSignatureBuilder> {
public SelfSignatureBuilder(PGPSecretKey signingKey, SecretKeyRingProtector protector) throws WrongPassphraseException { public SelfSignatureBuilder(PGPSecretKey signingKey, SecretKeyRingProtector protector) throws PGPException {
this(SignatureType.GENERIC_CERTIFICATION, signingKey, protector); this(SignatureType.GENERIC_CERTIFICATION, signingKey, protector);
} }
public SelfSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector) public SelfSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector)
throws WrongPassphraseException { throws PGPException {
super(signatureType, signingKey, protector); super(signatureType, signingKey, protector);
} }
@ -31,7 +30,7 @@ public class SelfSignatureBuilder extends AbstractSignatureBuilder<SelfSignature
PGPSecretKey primaryKey, PGPSecretKey primaryKey,
SecretKeyRingProtector primaryKeyProtector, SecretKeyRingProtector primaryKeyProtector,
PGPSignature oldCertification) PGPSignature oldCertification)
throws WrongPassphraseException { throws PGPException {
super(primaryKey, primaryKeyProtector, oldCertification); super(primaryKey, primaryKeyProtector, oldCertification);
} }

View file

@ -11,14 +11,13 @@ import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.exception.WrongPassphraseException;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets; import org.pgpainless.signature.subpackets.SelfSignatureSubpackets;
public class SubkeyBindingSignatureBuilder extends AbstractSignatureBuilder<SubkeyBindingSignatureBuilder> { public class SubkeyBindingSignatureBuilder extends AbstractSignatureBuilder<SubkeyBindingSignatureBuilder> {
public SubkeyBindingSignatureBuilder(PGPSecretKey signingKey, SecretKeyRingProtector protector) public SubkeyBindingSignatureBuilder(PGPSecretKey signingKey, SecretKeyRingProtector protector)
throws WrongPassphraseException { throws PGPException {
super(SignatureType.SUBKEY_BINDING, signingKey, protector); super(SignatureType.SUBKEY_BINDING, signingKey, protector);
} }

View file

@ -31,7 +31,7 @@ public class ThirdPartyCertificationSignatureBuilder extends AbstractSignatureBu
* @throws WrongPassphraseException in case of a wrong passphrase * @throws WrongPassphraseException in case of a wrong passphrase
*/ */
public ThirdPartyCertificationSignatureBuilder(PGPSecretKey signingKey, SecretKeyRingProtector protector) public ThirdPartyCertificationSignatureBuilder(PGPSecretKey signingKey, SecretKeyRingProtector protector)
throws WrongPassphraseException { throws PGPException {
this(SignatureType.GENERIC_CERTIFICATION, signingKey, protector); this(SignatureType.GENERIC_CERTIFICATION, signingKey, protector);
} }
@ -44,7 +44,7 @@ public class ThirdPartyCertificationSignatureBuilder extends AbstractSignatureBu
* @throws WrongPassphraseException in case of a wrong passphrase * @throws WrongPassphraseException in case of a wrong passphrase
*/ */
public ThirdPartyCertificationSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector) public ThirdPartyCertificationSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector)
throws WrongPassphraseException { throws PGPException {
super(signatureType, signingKey, protector); super(signatureType, signingKey, protector);
} }
@ -60,7 +60,7 @@ public class ThirdPartyCertificationSignatureBuilder extends AbstractSignatureBu
PGPSecretKey signingKey, PGPSecretKey signingKey,
SecretKeyRingProtector protector, SecretKeyRingProtector protector,
PGPSignature archetypeSignature) PGPSignature archetypeSignature)
throws WrongPassphraseException { throws PGPException {
super(signingKey, protector, archetypeSignature); super(signingKey, protector, archetypeSignature);
} }

View file

@ -11,7 +11,6 @@ import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.exception.WrongPassphraseException;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.signature.subpackets.BaseSignatureSubpackets; import org.pgpainless.signature.subpackets.BaseSignatureSubpackets;
import org.pgpainless.signature.subpackets.SignatureSubpackets; import org.pgpainless.signature.subpackets.SignatureSubpackets;
@ -22,12 +21,12 @@ import org.pgpainless.signature.subpackets.SignatureSubpackets;
public class UniversalSignatureBuilder extends AbstractSignatureBuilder<UniversalSignatureBuilder> { public class UniversalSignatureBuilder extends AbstractSignatureBuilder<UniversalSignatureBuilder> {
public UniversalSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector) public UniversalSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector)
throws WrongPassphraseException { throws PGPException {
super(signatureType, signingKey, protector); super(signatureType, signingKey, protector);
} }
public UniversalSignatureBuilder(PGPSecretKey certificationKey, SecretKeyRingProtector protector, PGPSignature archetypeSignature) public UniversalSignatureBuilder(PGPSecretKey certificationKey, SecretKeyRingProtector protector, PGPSignature archetypeSignature)
throws WrongPassphraseException { throws PGPException {
super(certificationKey, protector, archetypeSignature); super(certificationKey, protector, archetypeSignature);
} }

View file

@ -11,7 +11,6 @@ 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.exception.WrongPassphraseException;
import org.pgpainless.key.OpenPgpV4Fingerprint; import org.pgpainless.key.OpenPgpV4Fingerprint;
import org.pgpainless.key.TestKeys; import org.pgpainless.key.TestKeys;
import org.pgpainless.key.protection.CachingSecretKeyRingProtector; import org.pgpainless.key.protection.CachingSecretKeyRingProtector;
@ -120,7 +119,7 @@ public class UnlockSecretKeys {
} }
private void assertProtectorUnlocksAllSecretKeys(PGPSecretKeyRing secretKey, SecretKeyRingProtector protector) private void assertProtectorUnlocksAllSecretKeys(PGPSecretKeyRing secretKey, SecretKeyRingProtector protector)
throws WrongPassphraseException { throws PGPException {
for (PGPSecretKey key : secretKey) { for (PGPSecretKey key : secretKey) {
UnlockSecretKey.unlockSecretKey(key, protector); UnlockSecretKey.unlockSecretKey(key, protector);
} }