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 aef9ebfd7b
commit d54a40196b
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
10 changed files with 45 additions and 48 deletions

View File

@ -22,34 +22,41 @@ public final class UnlockSecretKey {
}
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, SecretKeyRingProtector protector)
throws WrongPassphraseException, KeyIntegrityException {
try {
PBESecretKeyDecryptor decryptor = null;
if (KeyInfo.isEncrypted(secretKey)) {
decryptor = protector.getDecryptor(secretKey.getKeyID());
}
PGPPrivateKey privateKey = secretKey.extractPrivateKey(decryptor);
throws PGPException, KeyIntegrityException {
if (secretKey.getPublicKey() != null) {
PublicKeyParameterValidationUtil.verifyPublicKeyParameterIntegrity(privateKey, secretKey.getPublicKey());
}
return privateKey;
} catch (KeyIntegrityException e) {
throw e;
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 {
privateKey = 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);
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);
}
throw new PGPException("Cannot decrypt secret key.");
}
if (secretKey.getPublicKey() != null) {
PublicKeyParameterValidationUtil.verifyPublicKeyParameterIntegrity(privateKey, secretKey.getPublicKey());
}
return privateKey;
}
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, Passphrase passphrase) throws WrongPassphraseException, KeyIntegrityException {
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, Passphrase passphrase) throws PGPException, KeyIntegrityException {
return unlockSecretKey(secretKey, SecretKeyRingProtector.unlockSingleKeyWith(passphrase, secretKey));
}
}

View File

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

View File

@ -13,19 +13,18 @@ import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector;
import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.exception.WrongPassphraseException;
import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.signature.subpackets.CertificationSubpackets;
public class CertificationSignatureBuilder extends AbstractSignatureBuilder<CertificationSignatureBuilder> {
public CertificationSignatureBuilder(PGPSecretKey certificationKey, SecretKeyRingProtector protector)
throws WrongPassphraseException {
throws PGPException {
this(SignatureType.GENERIC_CERTIFICATION, certificationKey, protector);
}
public CertificationSignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector)
throws WrongPassphraseException {
throws PGPException {
super(signatureType, signingKey, protector);
}
@ -33,7 +32,7 @@ public class CertificationSignatureBuilder extends AbstractSignatureBuilder<Cert
PGPSecretKey certificationKey,
SecretKeyRingProtector protector,
PGPSignature archetypeSignature)
throws WrongPassphraseException {
throws PGPException {
super(certificationKey, protector, archetypeSignature);
}

View File

@ -11,17 +11,16 @@ import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature;
import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.exception.WrongPassphraseException;
import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets;
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);
}
public DirectKeySignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector) throws WrongPassphraseException {
public DirectKeySignatureBuilder(SignatureType signatureType, PGPSecretKey signingKey, SecretKeyRingProtector protector) throws PGPException {
super(signatureType, signingKey, protector);
}

View File

@ -11,14 +11,13 @@ import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSignature;
import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.exception.WrongPassphraseException;
import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets;
public class PrimaryKeyBindingSignatureBuilder extends AbstractSignatureBuilder<PrimaryKeyBindingSignatureBuilder> {
public PrimaryKeyBindingSignatureBuilder(PGPSecretKey subkey, SecretKeyRingProtector subkeyProtector)
throws WrongPassphraseException {
throws PGPException {
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.PGPSignatureGenerator;
import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.exception.WrongPassphraseException;
import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.signature.subpackets.RevocationSignatureSubpackets;
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);
getHashedSubpackets().setRevocable(true, false);
}

View File

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

View File

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

View File

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

View File

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