1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-11-19 10:52:05 +01:00

Add PGPSecretKey.unlock() methods

This commit is contained in:
Paul Schaub 2023-09-12 14:35:29 +02:00
parent 6f9e692474
commit 19063454cb
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
6 changed files with 60 additions and 15 deletions

View file

@ -5,7 +5,50 @@
package org.bouncycastle.extensions package org.bouncycastle.extensions
import org.bouncycastle.bcpg.S2K import org.bouncycastle.bcpg.S2K
import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPrivateKey
import org.bouncycastle.openpgp.PGPSecretKey import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor
import org.pgpainless.exception.KeyIntegrityException
import org.pgpainless.exception.WrongPassphraseException
import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.key.protection.UnlockSecretKey
import org.pgpainless.util.Passphrase
/**
* Unlock the secret key to get its [PGPPrivateKey].
*
* @param passphrase passphrase to unlock the secret key with.
* @throws PGPException if the key cannot be unlocked
* @throws KeyIntegrityException if the public key part was tampered with
* @throws WrongPassphraseException
*/
@Throws(PGPException::class, KeyIntegrityException::class)
fun PGPSecretKey.unlock(passphrase: Passphrase): PGPPrivateKey =
UnlockSecretKey.unlockSecretKey(this, passphrase)
/**
* Unlock the secret key to get its [PGPPrivateKey].
*
* @param protector protector to unlock the secret key.
* @throws PGPException if the key cannot be unlocked
* @throws KeyIntegrityException if the public key part was tampered with
*/
@Throws(PGPException::class, KeyIntegrityException::class)
@JvmOverloads
fun PGPSecretKey.unlock(protector: SecretKeyRingProtector = SecretKeyRingProtector.unprotectedKeys()): PGPPrivateKey =
UnlockSecretKey.unlockSecretKey(this, protector)
/**
* Unlock the secret key to get its [PGPPrivateKey].
*
* @param decryptor decryptor to unlock the secret key.
* @throws PGPException if the key cannot be unlocked
* @throws KeyIntegrityException if the public key part was tampered with
*/
@Throws(PGPException::class, KeyIntegrityException::class)
fun PGPSecretKey.unlock(decryptor: PBESecretKeyDecryptor?): PGPPrivateKey =
UnlockSecretKey.unlockSecretKey(this, decryptor)
/** /**
* Returns indication that the secret key is encrypted. * Returns indication that the secret key is encrypted.

View file

@ -7,6 +7,7 @@ package org.pgpainless.decryption_verification
import openpgp.openPgpKeyId import openpgp.openPgpKeyId
import org.bouncycastle.bcpg.BCPGInputStream import org.bouncycastle.bcpg.BCPGInputStream
import org.bouncycastle.bcpg.UnsupportedPacketVersionException import org.bouncycastle.bcpg.UnsupportedPacketVersionException
import org.bouncycastle.extensions.unlock
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory
@ -21,7 +22,6 @@ import org.pgpainless.decryption_verification.syntax_check.StackSymbol
import org.pgpainless.exception.* import org.pgpainless.exception.*
import org.pgpainless.implementation.ImplementationFactory import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.SubkeyIdentifier import org.pgpainless.key.SubkeyIdentifier
import org.pgpainless.key.protection.UnlockSecretKey
import org.pgpainless.key.util.KeyRingUtils import org.pgpainless.key.util.KeyRingUtils
import org.pgpainless.policy.Policy import org.pgpainless.policy.Policy
import org.pgpainless.signature.SignatureUtils import org.pgpainless.signature.SignatureUtils
@ -302,7 +302,7 @@ class OpenPgpMessageInputStream(
continue continue
} }
val privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector) val privateKey = secretKey.unlock(protector)
if (decryptWithPrivateKey(esks, privateKey, decryptionKeyId, pkesk)) { if (decryptWithPrivateKey(esks, privateKey, decryptionKeyId, pkesk)) {
return true return true
} }
@ -325,7 +325,7 @@ class OpenPgpMessageInputStream(
continue continue
} }
val privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector) val privateKey = secretKey.unlock(protector)
if (decryptWithPrivateKey(esks, privateKey, decryptionKeyId, pkesk)) { if (decryptWithPrivateKey(esks, privateKey, decryptionKeyId, pkesk)) {
return true return true
} }
@ -351,7 +351,7 @@ class OpenPgpMessageInputStream(
LOGGER.debug("Attempt decryption with key $decryptionKeyId while interactively requesting its passphrase.") LOGGER.debug("Attempt decryption with key $decryptionKeyId while interactively requesting its passphrase.")
val protector = options.getSecretKeyProtector(decryptionKeys) ?: continue val protector = options.getSecretKeyProtector(decryptionKeys) ?: continue
val privateKey = UnlockSecretKey.unlockSecretKey(secretKey, protector) val privateKey = secretKey.unlock(protector)
if (decryptWithPrivateKey(esks, privateKey, decryptionKeyId, pkesk)) { if (decryptWithPrivateKey(esks, privateKey, decryptionKeyId, pkesk)) {
return true return true
} }

View file

@ -4,6 +4,7 @@
package org.pgpainless.encryption_signing package org.pgpainless.encryption_signing
import org.bouncycastle.extensions.unlock
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.pgpainless.PGPainless.Companion.getPolicy import org.pgpainless.PGPainless.Companion.getPolicy
import org.pgpainless.PGPainless.Companion.inspectKeyRing import org.pgpainless.PGPainless.Companion.inspectKeyRing
@ -17,7 +18,6 @@ import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.OpenPgpFingerprint.Companion.of import org.pgpainless.key.OpenPgpFingerprint.Companion.of
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.Companion.unlockSecretKey
import org.pgpainless.policy.Policy import org.pgpainless.policy.Policy
import org.pgpainless.signature.subpackets.BaseSignatureSubpackets.Callback import org.pgpainless.signature.subpackets.BaseSignatureSubpackets.Callback
import org.pgpainless.signature.subpackets.SignatureSubpackets import org.pgpainless.signature.subpackets.SignatureSubpackets
@ -157,7 +157,7 @@ class SigningOptions {
for (signingPubKey in signingPubKeys) { for (signingPubKey in signingPubKeys) {
val signingSecKey: PGPSecretKey = signingKey.getSecretKey(signingPubKey.keyID) val signingSecKey: PGPSecretKey = signingKey.getSecretKey(signingPubKey.keyID)
?: throw MissingSecretKeyException(of(signingKey), signingPubKey.keyID) ?: throw MissingSecretKeyException(of(signingKey), signingPubKey.keyID)
val signingSubkey: PGPPrivateKey = unlockSecretKey(signingSecKey, signingKeyProtector) val signingSubkey: PGPPrivateKey = signingSecKey.unlock(signingKeyProtector)
val hashAlgorithms = val hashAlgorithms =
if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId) if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId)
else keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyID) else keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyID)
@ -199,7 +199,7 @@ class SigningOptions {
val signingSecKey = signingKey.getSecretKey(signingPubKey.keyID) val signingSecKey = signingKey.getSecretKey(signingPubKey.keyID)
?: throw MissingSecretKeyException(of(signingKey), signingPubKey.keyID) ?: throw MissingSecretKeyException(of(signingKey), signingPubKey.keyID)
val signingSubkey = unlockSecretKey(signingSecKey, signingKeyProtector) val signingSubkey = signingSecKey.unlock(signingKeyProtector)
val hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyID) val hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyID)
val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy()) val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy())
addSigningMethod(signingKey, signingSubkey, hashAlgorithm, signatureType, false, subpacketsCallback) addSigningMethod(signingKey, signingSubkey, hashAlgorithm, signatureType, false, subpacketsCallback)
@ -292,7 +292,7 @@ class SigningOptions {
for (signingPubKey in signingPubKeys) { for (signingPubKey in signingPubKeys) {
val signingSecKey: PGPSecretKey = signingKey.getSecretKey(signingPubKey.keyID) val signingSecKey: PGPSecretKey = signingKey.getSecretKey(signingPubKey.keyID)
?: throw MissingSecretKeyException(of(signingKey), signingPubKey.keyID) ?: throw MissingSecretKeyException(of(signingKey), signingPubKey.keyID)
val signingSubkey: PGPPrivateKey = unlockSecretKey(signingSecKey, signingKeyProtector) val signingSubkey: PGPPrivateKey = signingSecKey.unlock(signingKeyProtector)
val hashAlgorithms = val hashAlgorithms =
if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId) if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId)
else keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyID) else keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyID)
@ -332,7 +332,7 @@ class SigningOptions {
if (signingPubKey.keyID == keyId) { if (signingPubKey.keyID == keyId) {
val signingSecKey: PGPSecretKey = signingKey.getSecretKey(signingPubKey.keyID) val signingSecKey: PGPSecretKey = signingKey.getSecretKey(signingPubKey.keyID)
?: throw MissingSecretKeyException(of(signingKey), signingPubKey.keyID) ?: throw MissingSecretKeyException(of(signingKey), signingPubKey.keyID)
val signingSubkey: PGPPrivateKey = unlockSecretKey(signingSecKey, signingKeyProtector) val signingSubkey: PGPPrivateKey = signingSecKey.unlock(signingKeyProtector)
val hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyID) val hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyID)
val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy()) val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy())
addSigningMethod(signingKey, signingSubkey, hashAlgorithm, signatureType, true, subpacketsCallback) addSigningMethod(signingKey, signingSubkey, hashAlgorithm, signatureType, true, subpacketsCallback)

View file

@ -4,6 +4,7 @@
package org.pgpainless.key.generation package org.pgpainless.key.generation
import org.bouncycastle.extensions.unlock
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor
@ -14,7 +15,6 @@ import org.pgpainless.PGPainless
import org.pgpainless.algorithm.KeyFlag import org.pgpainless.algorithm.KeyFlag
import org.pgpainless.algorithm.SignatureType import org.pgpainless.algorithm.SignatureType
import org.pgpainless.implementation.ImplementationFactory import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.protection.UnlockSecretKey
import org.pgpainless.policy.Policy import org.pgpainless.policy.Policy
import org.pgpainless.provider.ProviderFactory import org.pgpainless.provider.ProviderFactory
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets import org.pgpainless.signature.subpackets.SelfSignatureSubpackets
@ -129,7 +129,7 @@ class KeyRingBuilder : KeyRingBuilderInterface<KeyRingBuilder> {
// Attempt to add additional user-ids to the primary public key // Attempt to add additional user-ids to the primary public key
var primaryPubKey = secretKeys.next().publicKey var primaryPubKey = secretKeys.next().publicKey
val privateKey = UnlockSecretKey.unlockSecretKey(secretKeyRing.secretKey, secretKeyDecryptor) val privateKey = secretKeyRing.secretKey.unlock(secretKeyDecryptor)
val userIdIterator = userIds.entries.iterator() val userIdIterator = userIds.entries.iterator()
if (userIdIterator.hasNext()) { if (userIdIterator.hasNext()) {
userIdIterator.next() // Skip primary userId userIdIterator.next() // Skip primary userId

View file

@ -5,13 +5,13 @@
package org.pgpainless.key.protection.fixes package org.pgpainless.key.protection.fixes
import org.bouncycastle.bcpg.SecretKeyPacket import org.bouncycastle.bcpg.SecretKeyPacket
import org.bouncycastle.extensions.unlock
import org.bouncycastle.openpgp.PGPSecretKey import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSecretKeyRing import org.bouncycastle.openpgp.PGPSecretKeyRing
import org.pgpainless.algorithm.HashAlgorithm import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.exception.WrongPassphraseException 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.Companion.unlockSecretKey
/** /**
* Repair class to fix keys which use S2K usage of value [SecretKeyPacket.USAGE_CHECKSUM]. * Repair class to fix keys which use S2K usage of value [SecretKeyPacket.USAGE_CHECKSUM].
@ -62,7 +62,7 @@ class S2KUsageFix {
throw WrongPassphraseException("Missing passphrase for key with ID " + java.lang.Long.toHexString(keyId)) throw WrongPassphraseException("Missing passphrase for key with ID " + java.lang.Long.toHexString(keyId))
} }
val privateKey = unlockSecretKey(key, protector) val privateKey = key.unlock(protector)
// This constructor makes use of USAGE_SHA1 by default // This constructor makes use of USAGE_SHA1 by default
val fixedKey = PGPSecretKey( val fixedKey = PGPSecretKey(
privateKey, privateKey,

View file

@ -8,12 +8,12 @@ import openpgp.openPgpKeyId
import org.bouncycastle.bcpg.S2K import org.bouncycastle.bcpg.S2K
import org.bouncycastle.bcpg.SecretKeyPacket import org.bouncycastle.bcpg.SecretKeyPacket
import org.bouncycastle.extensions.certificate import org.bouncycastle.extensions.certificate
import org.bouncycastle.extensions.unlock
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.bouncycastle.util.Strings import org.bouncycastle.util.Strings
import org.pgpainless.exception.MissingPassphraseException import org.pgpainless.exception.MissingPassphraseException
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.fixes.S2KUsageFix import org.pgpainless.key.protection.fixes.S2KUsageFix
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
@ -164,8 +164,10 @@ class KeyRingUtils {
* @throws PGPException if something goes wrong (e.g. wrong passphrase) * @throws PGPException if something goes wrong (e.g. wrong passphrase)
*/ */
@JvmStatic @JvmStatic
@Deprecated("Deprecated in favor of secretKey.unlock(protector)",
ReplaceWith("secretKey.unlock(protector)"))
fun unlockSecretKey(secretKey: PGPSecretKey, protector: SecretKeyRingProtector): PGPPrivateKey { fun unlockSecretKey(secretKey: PGPSecretKey, protector: SecretKeyRingProtector): PGPPrivateKey {
return UnlockSecretKey.unlockSecretKey(secretKey, protector) return secretKey.unlock(protector)
} }
/** /**