Kotlin conversion: UnlockSecretKey

This commit is contained in:
Paul Schaub 2023-08-31 18:45:09 +02:00
parent 2547f1c687
commit 873db12125
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
3 changed files with 69 additions and 68 deletions

View File

@ -1,67 +0,0 @@
// Copyright 2021 Paul Schaub.
// SPDX-FileCopyrightText: 2021 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.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.pgpainless.PGPainless;
import org.pgpainless.exception.KeyIntegrityException;
import org.pgpainless.exception.WrongPassphraseException;
import org.pgpainless.key.info.KeyInfo;
import org.pgpainless.key.util.PublicKeyParameterValidationUtil;
import org.pgpainless.util.Passphrase;
public final class UnlockSecretKey {
private UnlockSecretKey() {
}
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, SecretKeyRingProtector protector)
throws PGPException, KeyIntegrityException {
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);
}
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 (PGPainless.getPolicy().isEnableKeyParameterValidation()) {
PublicKeyParameterValidationUtil.verifyPublicKeyParameterIntegrity(privateKey, secretKey.getPublicKey());
}
return privateKey;
}
public static PGPPrivateKey unlockSecretKey(PGPSecretKey secretKey, Passphrase passphrase)
throws PGPException, KeyIntegrityException {
return unlockSecretKey(secretKey, SecretKeyRingProtector.unlockSingleKeyWith(
passphrase == null ? Passphrase.emptyPassphrase() : passphrase, secretKey));
}
}

View File

@ -350,7 +350,7 @@ class OpenPgpMessageInputStream(
}
LOGGER.debug("Attempt decryption with key $decryptionKeyId while interactively requesting its passphrase.")
val protector = options.getSecretKeyProtector(decryptionKeys)
val protector = options.getSecretKeyProtector(decryptionKeys) ?: continue
val privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector)
if (decryptWithPrivateKey(esks, privateKey, decryptionKeyId, pkesk)) {
return true

View File

@ -0,0 +1,68 @@
// Copyright 2023 Paul Schaub.
// SPDX-FileCopyrightText: 2021 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.PGPPrivateKey
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor
import org.pgpainless.PGPainless
import org.pgpainless.exception.KeyIntegrityException
import org.pgpainless.exception.WrongPassphraseException
import org.pgpainless.key.info.KeyInfo
import org.pgpainless.key.util.KeyIdUtil
import org.pgpainless.key.util.PublicKeyParameterValidationUtil
import org.pgpainless.util.Passphrase
import kotlin.jvm.Throws
class UnlockSecretKey {
companion object {
@JvmStatic
@Throws(PGPException::class, KeyIntegrityException::class)
fun unlockSecretKey(secretKey: PGPSecretKey, protector: SecretKeyRingProtector): PGPPrivateKey {
return if (KeyInfo.isEncrypted(secretKey)) {
unlockSecretKey(secretKey, protector.getDecryptor(secretKey.keyID))
} else {
unlockSecretKey(secretKey, null as PBESecretKeyDecryptor?)
}
}
@JvmStatic
@Throws(PGPException::class)
fun unlockSecretKey(secretKey: PGPSecretKey, decryptor: PBESecretKeyDecryptor?): PGPPrivateKey {
val privateKey = try {
secretKey.extractPrivateKey(decryptor)
} catch (e : PGPException) {
throw WrongPassphraseException(secretKey.keyID, e)
}
if (privateKey == null) {
if (secretKey.s2K.type in 100..110) {
throw PGPException("Cannot decrypt secret key ${KeyIdUtil.formatKeyId(secretKey.keyID)}: \n" +
"Unsupported private S2K type ${secretKey.s2K.type}")
}
throw PGPException("Cannot decrypt secret key.")
}
if (PGPainless.getPolicy().isEnableKeyParameterValidation()) {
PublicKeyParameterValidationUtil.verifyPublicKeyParameterIntegrity(privateKey, secretKey.publicKey)
}
return privateKey
}
@JvmStatic
fun unlockSecretKey(secretKey: PGPSecretKey, passphrase: Passphrase?): PGPPrivateKey {
return if (passphrase == null) {
unlockSecretKey(secretKey, SecretKeyRingProtector.unprotectedKeys())
} else {
unlockSecretKey(secretKey, SecretKeyRingProtector.unlockSingleKeyWith(passphrase, secretKey))
}
}
}
}