mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-19 02:42:05 +01:00
Add PGPSecretKey.unlock() methods
This commit is contained in:
parent
6f9e692474
commit
19063454cb
6 changed files with 60 additions and 15 deletions
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue