mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-09-09 18:29:39 +02:00
Port ConsumerOptions, SigningOptions to new OpenPGPCertificate, OpenPGPKey classes
This commit is contained in:
parent
bbecdd693f
commit
4a90b8721f
6 changed files with 260 additions and 150 deletions
|
@ -12,6 +12,7 @@ import org.bouncycastle.openpgp.*
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPCertificate
|
import org.bouncycastle.openpgp.api.OpenPGPCertificate
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPKey
|
import org.bouncycastle.openpgp.api.OpenPGPKey
|
||||||
|
import org.bouncycastle.openpgp.api.OpenPGPSignature.OpenPGPDocumentSignature
|
||||||
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory
|
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory
|
||||||
import org.pgpainless.PGPainless
|
import org.pgpainless.PGPainless
|
||||||
import org.pgpainless.decryption_verification.cleartext_signatures.InMemoryMultiPassStrategy
|
import org.pgpainless.decryption_verification.cleartext_signatures.InMemoryMultiPassStrategy
|
||||||
|
@ -73,12 +74,20 @@ class ConsumerOptions {
|
||||||
this.certificates.addCertificate(verificationCert)
|
this.certificates.addCertificate(verificationCert)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addVerificationCerts(verificationCerts: Collection<OpenPGPCertificate>): ConsumerOptions =
|
||||||
|
apply {
|
||||||
|
for (cert in verificationCerts) {
|
||||||
|
addVerificationCert(cert)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a certificate (public key ring) for signature verification.
|
* Add a certificate (public key ring) for signature verification.
|
||||||
*
|
*
|
||||||
* @param verificationCert certificate for signature verification
|
* @param verificationCert certificate for signature verification
|
||||||
* @return options
|
* @return options
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Pass OpenPGPCertificate instead.")
|
||||||
fun addVerificationCert(verificationCert: PGPPublicKeyRing): ConsumerOptions = apply {
|
fun addVerificationCert(verificationCert: PGPPublicKeyRing): ConsumerOptions = apply {
|
||||||
this.certificates.addCertificate(verificationCert)
|
this.certificates.addCertificate(verificationCert)
|
||||||
}
|
}
|
||||||
|
@ -89,6 +98,7 @@ class ConsumerOptions {
|
||||||
* @param verificationCerts certificates for signature verification
|
* @param verificationCerts certificates for signature verification
|
||||||
* @return options
|
* @return options
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Use of methods taking PGPPublicKeyRingCollections is discouraged.")
|
||||||
fun addVerificationCerts(verificationCerts: PGPPublicKeyRingCollection): ConsumerOptions =
|
fun addVerificationCerts(verificationCerts: PGPPublicKeyRingCollection): ConsumerOptions =
|
||||||
apply {
|
apply {
|
||||||
for (cert in verificationCerts) {
|
for (cert in verificationCerts) {
|
||||||
|
@ -125,6 +135,14 @@ class ConsumerOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addVerificationOfDetachedSignature(signature: OpenPGPDocumentSignature): ConsumerOptions =
|
||||||
|
apply {
|
||||||
|
if (signature.issuerCertificate != null) {
|
||||||
|
addVerificationCert(signature.issuerCertificate)
|
||||||
|
}
|
||||||
|
addVerificationOfDetachedSignature(signature.signature)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a detached signature for the signature verification process.
|
* Add a detached signature for the signature verification process.
|
||||||
*
|
*
|
||||||
|
@ -178,6 +196,7 @@ class ConsumerOptions {
|
||||||
* @return options
|
* @return options
|
||||||
*/
|
*/
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
|
@Deprecated("Pass OpenPGPKey instead.")
|
||||||
fun addDecryptionKey(
|
fun addDecryptionKey(
|
||||||
key: PGPSecretKeyRing,
|
key: PGPSecretKeyRing,
|
||||||
protector: SecretKeyRingProtector = SecretKeyRingProtector.unprotectedKeys(),
|
protector: SecretKeyRingProtector = SecretKeyRingProtector.unprotectedKeys(),
|
||||||
|
@ -192,6 +211,7 @@ class ConsumerOptions {
|
||||||
* @return options
|
* @return options
|
||||||
*/
|
*/
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
|
@Deprecated("Pass OpenPGPKey instances instead.")
|
||||||
fun addDecryptionKeys(
|
fun addDecryptionKeys(
|
||||||
keys: PGPSecretKeyRingCollection,
|
keys: PGPSecretKeyRingCollection,
|
||||||
protector: SecretKeyRingProtector = SecretKeyRingProtector.unprotectedKeys()
|
protector: SecretKeyRingProtector = SecretKeyRingProtector.unprotectedKeys()
|
||||||
|
@ -201,21 +221,6 @@ class ConsumerOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a passphrase for message decryption. This passphrase will be used to try to decrypt
|
|
||||||
* messages which were symmetrically encrypted for a passphrase.
|
|
||||||
*
|
|
||||||
* See
|
|
||||||
* [Symmetrically Encrypted Data Packet](https://datatracker.ietf.org/doc/html/rfc4880#section-5.7)
|
|
||||||
*
|
|
||||||
* @param passphrase passphrase
|
|
||||||
* @return options
|
|
||||||
*/
|
|
||||||
@Deprecated(
|
|
||||||
"Deprecated in favor of addMessagePassphrase",
|
|
||||||
ReplaceWith("addMessagePassphrase(passphrase)"))
|
|
||||||
fun addDecryptionPassphrase(passphrase: Passphrase) = addMessagePassphrase(passphrase)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a passphrase for message decryption. This passphrase will be used to try to decrypt
|
* Add a passphrase for message decryption. This passphrase will be used to try to decrypt
|
||||||
* messages which were symmetrically encrypted for a passphrase.
|
* messages which were symmetrically encrypted for a passphrase.
|
||||||
|
@ -255,21 +260,21 @@ class ConsumerOptions {
|
||||||
*
|
*
|
||||||
* @return decryption keys
|
* @return decryption keys
|
||||||
*/
|
*/
|
||||||
fun getDecryptionKeys() = decryptionKeys.keys.toSet()
|
fun getDecryptionKeys(): Set<OpenPGPKey> = decryptionKeys.keys.toSet()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the set of available message decryption passphrases.
|
* Return the set of available message decryption passphrases.
|
||||||
*
|
*
|
||||||
* @return decryption passphrases
|
* @return decryption passphrases
|
||||||
*/
|
*/
|
||||||
fun getDecryptionPassphrases() = decryptionPassphrases.toSet()
|
fun getDecryptionPassphrases(): Set<Passphrase> = decryptionPassphrases.toSet()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an object holding available certificates for signature verification.
|
* Return an object holding available certificates for signature verification.
|
||||||
*
|
*
|
||||||
* @return certificate source
|
* @return certificate source
|
||||||
*/
|
*/
|
||||||
fun getCertificateSource() = certificates
|
fun getCertificateSource(): CertificateSource = certificates
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the callback that gets called when a certificate for signature verification is
|
* Return the callback that gets called when a certificate for signature verification is
|
||||||
|
@ -277,7 +282,7 @@ class ConsumerOptions {
|
||||||
*
|
*
|
||||||
* @return missing public key callback
|
* @return missing public key callback
|
||||||
*/
|
*/
|
||||||
fun getMissingCertificateCallback() = missingCertificateCallback
|
fun getMissingCertificateCallback(): MissingPublicKeyCallback? = missingCertificateCallback
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the [SecretKeyRingProtector] for the given [PGPSecretKeyRing].
|
* Return the [SecretKeyRingProtector] for the given [PGPSecretKeyRing].
|
||||||
|
@ -321,7 +326,7 @@ class ConsumerOptions {
|
||||||
this.ignoreMDCErrors = ignoreMDCErrors
|
this.ignoreMDCErrors = ignoreMDCErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isIgnoreMDCErrors() = ignoreMDCErrors
|
fun isIgnoreMDCErrors(): Boolean = ignoreMDCErrors
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Force PGPainless to handle the data provided by the [InputStream] as non-OpenPGP data. This
|
* Force PGPainless to handle the data provided by the [InputStream] as non-OpenPGP data. This
|
||||||
|
@ -337,7 +342,7 @@ class ConsumerOptions {
|
||||||
*
|
*
|
||||||
* @return true if non-OpenPGP data is forced
|
* @return true if non-OpenPGP data is forced
|
||||||
*/
|
*/
|
||||||
fun isForceNonOpenPgpData() = forceNonOpenPgpData
|
fun isForceNonOpenPgpData(): Boolean = forceNonOpenPgpData
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the [MissingKeyPassphraseStrategy]. This strategy defines, how missing passphrases
|
* Specify the [MissingKeyPassphraseStrategy]. This strategy defines, how missing passphrases
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData
|
||||||
import org.bouncycastle.openpgp.PGPSignature
|
import org.bouncycastle.openpgp.PGPSignature
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPCertificate
|
import org.bouncycastle.openpgp.api.OpenPGPCertificate
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPKey
|
import org.bouncycastle.openpgp.api.OpenPGPKey
|
||||||
|
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPPrivateKey
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPSecretKey
|
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPSecretKey
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPSignature.OpenPGPDocumentSignature
|
import org.bouncycastle.openpgp.api.OpenPGPSignature.OpenPGPDocumentSignature
|
||||||
import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory
|
import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory
|
||||||
|
@ -58,6 +59,7 @@ import org.pgpainless.exception.UnacceptableAlgorithmException
|
||||||
import org.pgpainless.exception.WrongPassphraseException
|
import org.pgpainless.exception.WrongPassphraseException
|
||||||
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.Companion.unlockSecretKey
|
||||||
import org.pgpainless.policy.Policy
|
import org.pgpainless.policy.Policy
|
||||||
import org.pgpainless.signature.consumer.CertificateValidator
|
import org.pgpainless.signature.consumer.CertificateValidator
|
||||||
import org.pgpainless.signature.consumer.OnePassSignatureCheck
|
import org.pgpainless.signature.consumer.OnePassSignatureCheck
|
||||||
|
@ -420,10 +422,15 @@ class OpenPgpMessageInputStream(
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
val privateKey = secretKey.unlock(protector)
|
val privateKey =
|
||||||
|
try {
|
||||||
|
unlockSecretKey(secretKey, protector)
|
||||||
|
} catch (e: PGPException) {
|
||||||
|
throw WrongPassphraseException(secretKey.keyIdentifier, e)
|
||||||
|
}
|
||||||
if (decryptWithPrivateKey(
|
if (decryptWithPrivateKey(
|
||||||
esks,
|
esks,
|
||||||
privateKey,
|
privateKey.unlockedKey,
|
||||||
SubkeyIdentifier(
|
SubkeyIdentifier(
|
||||||
secretKey.openPGPKey.pgpSecretKeyRing, secretKey.keyIdentifier),
|
secretKey.openPGPKey.pgpSecretKeyRing, secretKey.keyIdentifier),
|
||||||
pkesk)) {
|
pkesk)) {
|
||||||
|
@ -451,7 +458,7 @@ class OpenPgpMessageInputStream(
|
||||||
|
|
||||||
val privateKey = decryptionKey.unlock(protector)
|
val privateKey = decryptionKey.unlock(protector)
|
||||||
if (decryptWithPrivateKey(
|
if (decryptWithPrivateKey(
|
||||||
esks, privateKey, SubkeyIdentifier(decryptionKey), pkesk)) {
|
esks, privateKey.unlockedKey, SubkeyIdentifier(decryptionKey), pkesk)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -476,13 +483,13 @@ class OpenPgpMessageInputStream(
|
||||||
LOGGER.debug(
|
LOGGER.debug(
|
||||||
"Attempt decryption with key $decryptionKeyId while interactively requesting its passphrase.")
|
"Attempt decryption with key $decryptionKeyId while interactively requesting its passphrase.")
|
||||||
val protector = options.getSecretKeyProtector(decryptionKeys) ?: continue
|
val protector = options.getSecretKeyProtector(decryptionKeys) ?: continue
|
||||||
val privateKey =
|
val privateKey: OpenPGPPrivateKey =
|
||||||
try {
|
try {
|
||||||
secretKey.unlock(protector)
|
unlockSecretKey(secretKey, protector)
|
||||||
} catch (e: PGPException) {
|
} catch (e: PGPException) {
|
||||||
throw WrongPassphraseException(secretKey.keyIdentifier, e)
|
throw WrongPassphraseException(secretKey.keyIdentifier, e)
|
||||||
}
|
}
|
||||||
if (decryptWithPrivateKey(esks, privateKey, decryptionKeyId, pkesk)) {
|
if (decryptWithPrivateKey(esks, privateKey.unlockedKey, decryptionKeyId, pkesk)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.pgpainless.algorithm.CompressionAlgorithm
|
||||||
import org.pgpainless.algorithm.StreamEncoding
|
import org.pgpainless.algorithm.StreamEncoding
|
||||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm
|
import org.pgpainless.algorithm.SymmetricKeyAlgorithm
|
||||||
import org.pgpainless.implementation.ImplementationFactory
|
import org.pgpainless.implementation.ImplementationFactory
|
||||||
|
import org.pgpainless.key.SubkeyIdentifier
|
||||||
import org.pgpainless.util.ArmoredOutputStreamFactory
|
import org.pgpainless.util.ArmoredOutputStreamFactory
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
|
@ -250,7 +251,7 @@ class EncryptionStream(
|
||||||
options.signingOptions.signingMethods.entries.reversed().forEach { (key, method) ->
|
options.signingOptions.signingMethods.entries.reversed().forEach { (key, method) ->
|
||||||
method.signatureGenerator.generate().let { sig ->
|
method.signatureGenerator.generate().let { sig ->
|
||||||
if (method.isDetached) {
|
if (method.isDetached) {
|
||||||
resultBuilder.addDetachedSignature(key, sig)
|
resultBuilder.addDetachedSignature(SubkeyIdentifier(key), sig)
|
||||||
}
|
}
|
||||||
if (!method.isDetached || options.isCleartextSigned) {
|
if (!method.isDetached || options.isCleartextSigned) {
|
||||||
sig.encode(signatureLayerStream)
|
sig.encode(signatureLayerStream)
|
||||||
|
|
|
@ -7,19 +7,22 @@ package org.pgpainless.encryption_signing
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import org.bouncycastle.bcpg.KeyIdentifier
|
import org.bouncycastle.bcpg.KeyIdentifier
|
||||||
import org.bouncycastle.openpgp.*
|
import org.bouncycastle.openpgp.*
|
||||||
|
import org.bouncycastle.openpgp.api.OpenPGPKey
|
||||||
|
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPPrivateKey
|
||||||
|
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPSecretKey
|
||||||
import org.pgpainless.PGPainless.Companion.getPolicy
|
import org.pgpainless.PGPainless.Companion.getPolicy
|
||||||
import org.pgpainless.PGPainless.Companion.inspectKeyRing
|
import org.pgpainless.PGPainless.Companion.inspectKeyRing
|
||||||
import org.pgpainless.algorithm.DocumentSignatureType
|
import org.pgpainless.algorithm.DocumentSignatureType
|
||||||
import org.pgpainless.algorithm.HashAlgorithm
|
import org.pgpainless.algorithm.HashAlgorithm
|
||||||
import org.pgpainless.algorithm.PublicKeyAlgorithm.Companion.requireFromId
|
import org.pgpainless.algorithm.PublicKeyAlgorithm.Companion.requireFromId
|
||||||
import org.pgpainless.algorithm.negotiation.HashAlgorithmNegotiator.Companion.negotiateSignatureHashAlgorithm
|
import org.pgpainless.algorithm.negotiation.HashAlgorithmNegotiator.Companion.negotiateSignatureHashAlgorithm
|
||||||
import org.pgpainless.bouncycastle.extensions.unlock
|
import org.pgpainless.bouncycastle.extensions.toOpenPGPKey
|
||||||
import org.pgpainless.exception.KeyException
|
import org.pgpainless.exception.KeyException
|
||||||
import org.pgpainless.exception.KeyException.*
|
import org.pgpainless.exception.KeyException.*
|
||||||
import org.pgpainless.implementation.ImplementationFactory
|
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.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
|
||||||
|
@ -27,7 +30,7 @@ import org.pgpainless.signature.subpackets.SignatureSubpacketsHelper
|
||||||
|
|
||||||
class SigningOptions {
|
class SigningOptions {
|
||||||
|
|
||||||
val signingMethods: Map<SubkeyIdentifier, SigningMethod> = mutableMapOf()
|
val signingMethods: Map<OpenPGPPrivateKey, SigningMethod> = mutableMapOf()
|
||||||
private var _hashAlgorithmOverride: HashAlgorithm? = null
|
private var _hashAlgorithmOverride: HashAlgorithm? = null
|
||||||
private var _evaluationDate: Date = Date()
|
private var _evaluationDate: Date = Date()
|
||||||
|
|
||||||
|
@ -62,17 +65,33 @@ class SigningOptions {
|
||||||
* Sign the message using an inline signature made by the provided signing key.
|
* Sign the message using an inline signature made by the provided signing key.
|
||||||
*
|
*
|
||||||
* @param signingKeyProtector protector to unlock the signing key
|
* @param signingKeyProtector protector to unlock the signing key
|
||||||
* @param signingKey key ring containing the signing key
|
* @param signingKey OpenPGPKey containing the signing (sub-)key.
|
||||||
* @return this
|
* @return this
|
||||||
* @throws KeyException if something is wrong with the key
|
* @throws KeyException if something is wrong with the key
|
||||||
* @throws PGPException if the key cannot be unlocked or a signing method cannot be created
|
* @throws PGPException if the key cannot be unlocked or a signing method cannot be created
|
||||||
*/
|
*/
|
||||||
@Throws(KeyException::class, PGPException::class)
|
@Throws(KeyException::class, PGPException::class)
|
||||||
|
fun addSignature(
|
||||||
|
signingKeyProtector: SecretKeyRingProtector,
|
||||||
|
signingKey: OpenPGPKey
|
||||||
|
): SigningOptions = apply {
|
||||||
|
addInlineSignature(
|
||||||
|
signingKeyProtector, signingKey, null, DocumentSignatureType.BINARY_DOCUMENT)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign the message using an inline signature made by the provided signing key.
|
||||||
|
*
|
||||||
|
* @param signingKeyProtector protector to unlock the signing key
|
||||||
|
* @param signingKey key ring containing the signing key
|
||||||
|
* @return this
|
||||||
|
* @throws KeyException if something is wrong with the key
|
||||||
|
* @throws PGPException if the key cannot be unlocked or a signing method cannot be created
|
||||||
|
*/
|
||||||
|
@Deprecated("Pass an OpenPGPKey instead.")
|
||||||
|
@Throws(KeyException::class, PGPException::class)
|
||||||
fun addSignature(signingKeyProtector: SecretKeyRingProtector, signingKey: PGPSecretKeyRing) =
|
fun addSignature(signingKeyProtector: SecretKeyRingProtector, signingKey: PGPSecretKeyRing) =
|
||||||
apply {
|
addSignature(signingKeyProtector, signingKey.toOpenPGPKey())
|
||||||
addInlineSignature(
|
|
||||||
signingKeyProtector, signingKey, null, DocumentSignatureType.BINARY_DOCUMENT)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add inline signatures with all secret key rings in the provided secret key ring collection.
|
* Add inline signatures with all secret key rings in the provided secret key ring collection.
|
||||||
|
@ -86,6 +105,7 @@ class SigningOptions {
|
||||||
* created
|
* created
|
||||||
*/
|
*/
|
||||||
@Throws(KeyException::class, PGPException::class)
|
@Throws(KeyException::class, PGPException::class)
|
||||||
|
@Deprecated("Repeatedly call addInlineSignature(), passing an OpenPGPKey instead.")
|
||||||
fun addInlineSignatures(
|
fun addInlineSignatures(
|
||||||
signingKeyProtector: SecretKeyRingProtector,
|
signingKeyProtector: SecretKeyRingProtector,
|
||||||
signingKeys: Iterable<PGPSecretKeyRing>,
|
signingKeys: Iterable<PGPSecretKeyRing>,
|
||||||
|
@ -94,6 +114,12 @@ class SigningOptions {
|
||||||
signingKeys.forEach { addInlineSignature(signingKeyProtector, it, null, signatureType) }
|
signingKeys.forEach { addInlineSignature(signingKeyProtector, it, null, signatureType) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addInlineSignature(
|
||||||
|
signingKeyProtector: SecretKeyRingProtector,
|
||||||
|
signingKey: OpenPGPKey,
|
||||||
|
signatureType: DocumentSignatureType = DocumentSignatureType.BINARY_DOCUMENT
|
||||||
|
): SigningOptions = addInlineSignature(signingKeyProtector, signingKey, null, signatureType)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an inline-signature. Inline signatures are being embedded into the message itself and can
|
* Add an inline-signature. Inline signatures are being embedded into the message itself and can
|
||||||
* be processed in one pass, thanks to the use of one-pass-signature packets.
|
* be processed in one pass, thanks to the use of one-pass-signature packets.
|
||||||
|
@ -106,11 +132,49 @@ class SigningOptions {
|
||||||
* @throws PGPException if the key cannot be unlocked or the signing method cannot be created
|
* @throws PGPException if the key cannot be unlocked or the signing method cannot be created
|
||||||
*/
|
*/
|
||||||
@Throws(KeyException::class, PGPException::class)
|
@Throws(KeyException::class, PGPException::class)
|
||||||
|
@Deprecated("Pass an OpenPGPKey instead.")
|
||||||
fun addInlineSignature(
|
fun addInlineSignature(
|
||||||
signingKeyProtector: SecretKeyRingProtector,
|
signingKeyProtector: SecretKeyRingProtector,
|
||||||
signingKey: PGPSecretKeyRing,
|
signingKey: PGPSecretKeyRing,
|
||||||
signatureType: DocumentSignatureType
|
signatureType: DocumentSignatureType
|
||||||
) = apply { addInlineSignature(signingKeyProtector, signingKey, null, signatureType) }
|
) = addInlineSignature(signingKeyProtector, signingKey.toOpenPGPKey(), signatureType)
|
||||||
|
|
||||||
|
fun addInlineSignature(
|
||||||
|
signingKeyProtector: SecretKeyRingProtector,
|
||||||
|
signingKey: OpenPGPKey,
|
||||||
|
userId: CharSequence? = null,
|
||||||
|
signatureType: DocumentSignatureType = DocumentSignatureType.BINARY_DOCUMENT,
|
||||||
|
subpacketsCallback: Callback? = null
|
||||||
|
) = apply {
|
||||||
|
val keyRingInfo = inspectKeyRing(signingKey, evaluationDate)
|
||||||
|
if (userId != null && !keyRingInfo.isUserIdValid(userId)) {
|
||||||
|
throw UnboundUserIdException(
|
||||||
|
of(signingKey.pgpSecretKeyRing),
|
||||||
|
userId.toString(),
|
||||||
|
keyRingInfo.getLatestUserIdCertification(userId),
|
||||||
|
keyRingInfo.getUserIdRevocation(userId))
|
||||||
|
}
|
||||||
|
|
||||||
|
val signingPubKeys = keyRingInfo.signingSubkeys
|
||||||
|
if (signingPubKeys.isEmpty()) {
|
||||||
|
throw UnacceptableSigningKeyException(of(signingKey.pgpSecretKeyRing))
|
||||||
|
}
|
||||||
|
|
||||||
|
for (signingPubKey in signingPubKeys) {
|
||||||
|
val signingSecKey: OpenPGPSecretKey =
|
||||||
|
signingKey.getSecretKey(signingPubKey)
|
||||||
|
?: throw MissingSecretKeyException(
|
||||||
|
of(signingKey.pgpSecretKeyRing), signingPubKey.keyIdentifier.keyId)
|
||||||
|
val signingPrivKey: OpenPGPPrivateKey =
|
||||||
|
unlockSecretKey(signingSecKey, signingKeyProtector)
|
||||||
|
val hashAlgorithms =
|
||||||
|
if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId)
|
||||||
|
else keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyIdentifier)
|
||||||
|
val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy())
|
||||||
|
addSigningMethod(
|
||||||
|
signingPrivKey, hashAlgorithm, signatureType, false, subpacketsCallback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an inline-signature. Inline signatures are being embedded into the message itself and can
|
* Add an inline-signature. Inline signatures are being embedded into the message itself and can
|
||||||
|
@ -129,6 +193,7 @@ class SigningOptions {
|
||||||
* @throws KeyException if the key is invalid
|
* @throws KeyException if the key is invalid
|
||||||
* @throws PGPException if the key cannot be unlocked or the signing method cannot be created
|
* @throws PGPException if the key cannot be unlocked or the signing method cannot be created
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Pass an OpenPGPKey instead.")
|
||||||
@Throws(KeyException::class, PGPException::class)
|
@Throws(KeyException::class, PGPException::class)
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun addInlineSignature(
|
fun addInlineSignature(
|
||||||
|
@ -137,34 +202,36 @@ class SigningOptions {
|
||||||
userId: CharSequence? = null,
|
userId: CharSequence? = null,
|
||||||
signatureType: DocumentSignatureType = DocumentSignatureType.BINARY_DOCUMENT,
|
signatureType: DocumentSignatureType = DocumentSignatureType.BINARY_DOCUMENT,
|
||||||
subpacketsCallback: Callback? = null
|
subpacketsCallback: Callback? = null
|
||||||
) = apply {
|
) =
|
||||||
val keyRingInfo = inspectKeyRing(signingKey, evaluationDate)
|
addInlineSignature(
|
||||||
if (userId != null && !keyRingInfo.isUserIdValid(userId)) {
|
signingKeyProtector,
|
||||||
throw UnboundUserIdException(
|
signingKey.toOpenPGPKey(),
|
||||||
of(signingKey),
|
userId,
|
||||||
userId.toString(),
|
signatureType,
|
||||||
keyRingInfo.getLatestUserIdCertification(userId),
|
subpacketsCallback)
|
||||||
keyRingInfo.getUserIdRevocation(userId))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
fun addInlineSignature(
|
||||||
|
signingKeyProtector: SecretKeyRingProtector,
|
||||||
|
signingKey: OpenPGPSecretKey,
|
||||||
|
signatureType: DocumentSignatureType = DocumentSignatureType.BINARY_DOCUMENT,
|
||||||
|
subpacketsCallback: Callback? = null
|
||||||
|
): SigningOptions = apply {
|
||||||
|
val openPGPKey = signingKey.openPGPKey
|
||||||
|
val keyRingInfo = inspectKeyRing(openPGPKey, evaluationDate)
|
||||||
val signingPubKeys = keyRingInfo.signingSubkeys
|
val signingPubKeys = keyRingInfo.signingSubkeys
|
||||||
if (signingPubKeys.isEmpty()) {
|
if (signingPubKeys.isEmpty()) {
|
||||||
throw UnacceptableSigningKeyException(of(signingKey))
|
throw UnacceptableSigningKeyException(of(openPGPKey.pgpSecretKeyRing))
|
||||||
}
|
}
|
||||||
|
|
||||||
for (signingPubKey in signingPubKeys) {
|
if (!signingPubKeys.any { it.keyIdentifier.matches(signingKey.keyIdentifier) }) {
|
||||||
val signingSecKey: PGPSecretKey =
|
throw MissingSecretKeyException(
|
||||||
signingKey.getSecretKey(signingPubKey.keyIdentifier)
|
of(openPGPKey.pgpSecretKeyRing), signingKey.keyIdentifier.keyId)
|
||||||
?: throw MissingSecretKeyException(
|
|
||||||
of(signingKey), signingPubKey.keyIdentifier.keyId)
|
|
||||||
val signingSubkey: PGPPrivateKey = signingSecKey.unlock(signingKeyProtector)
|
|
||||||
val hashAlgorithms =
|
|
||||||
if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId)
|
|
||||||
else keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyIdentifier)
|
|
||||||
val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy())
|
|
||||||
addSigningMethod(
|
|
||||||
signingKey, signingSubkey, hashAlgorithm, signatureType, false, subpacketsCallback)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val signingPrivKey = unlockSecretKey(signingKey, signingKeyProtector)
|
||||||
|
val hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(signingKey.keyIdentifier)
|
||||||
|
val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy())
|
||||||
|
addSigningMethod(signingPrivKey, hashAlgorithm, signatureType, false, subpacketsCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -191,31 +258,13 @@ class SigningOptions {
|
||||||
keyId: Long,
|
keyId: Long,
|
||||||
signatureType: DocumentSignatureType = DocumentSignatureType.BINARY_DOCUMENT,
|
signatureType: DocumentSignatureType = DocumentSignatureType.BINARY_DOCUMENT,
|
||||||
subpacketsCallback: Callback? = null
|
subpacketsCallback: Callback? = null
|
||||||
) = apply {
|
) =
|
||||||
val keyRingInfo = inspectKeyRing(signingKey, evaluationDate)
|
addInlineSignature(
|
||||||
val signingPubKeys = keyRingInfo.signingSubkeys
|
signingKeyProtector,
|
||||||
if (signingPubKeys.isEmpty()) {
|
signingKey.toOpenPGPKey().getSecretKey(KeyIdentifier(keyId))
|
||||||
throw UnacceptableSigningKeyException(of(signingKey))
|
?: throw MissingSecretKeyException(of(signingKey), keyId),
|
||||||
}
|
signatureType,
|
||||||
|
subpacketsCallback)
|
||||||
for (signingPubKey in signingPubKeys) {
|
|
||||||
if (!signingPubKey.keyIdentifier.matches(KeyIdentifier(keyId))) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
val signingSecKey =
|
|
||||||
signingKey.getSecretKey(signingPubKey.keyIdentifier)
|
|
||||||
?: throw MissingSecretKeyException(
|
|
||||||
of(signingKey), signingPubKey.keyIdentifier.keyId)
|
|
||||||
val signingSubkey = signingSecKey.unlock(signingKeyProtector)
|
|
||||||
val hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyIdentifier)
|
|
||||||
val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy())
|
|
||||||
addSigningMethod(
|
|
||||||
signingKey, signingSubkey, hashAlgorithm, signatureType, false, subpacketsCallback)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
throw MissingSecretKeyException(of(signingKey), keyId)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add detached signatures with all key rings from the provided secret key ring collection.
|
* Add detached signatures with all key rings from the provided secret key ring collection.
|
||||||
|
@ -229,6 +278,7 @@ class SigningOptions {
|
||||||
* method cannot be created
|
* method cannot be created
|
||||||
*/
|
*/
|
||||||
@Throws(KeyException::class, PGPException::class)
|
@Throws(KeyException::class, PGPException::class)
|
||||||
|
@Deprecated("Repeatedly call addDetachedSignature(), passing an OpenPGPKey instead.")
|
||||||
fun addDetachedSignatures(
|
fun addDetachedSignatures(
|
||||||
signingKeyProtector: SecretKeyRingProtector,
|
signingKeyProtector: SecretKeyRingProtector,
|
||||||
signingKeys: Iterable<PGPSecretKeyRing>,
|
signingKeys: Iterable<PGPSecretKeyRing>,
|
||||||
|
@ -237,6 +287,12 @@ class SigningOptions {
|
||||||
signingKeys.forEach { addDetachedSignature(signingKeyProtector, it, null, signatureType) }
|
signingKeys.forEach { addDetachedSignature(signingKeyProtector, it, null, signatureType) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun addDetachedSignature(
|
||||||
|
signingKeyProtector: SecretKeyRingProtector,
|
||||||
|
signingKey: OpenPGPKey,
|
||||||
|
signatureType: DocumentSignatureType = DocumentSignatureType.BINARY_DOCUMENT
|
||||||
|
): SigningOptions = addDetachedSignature(signingKeyProtector, signingKey, null, signatureType)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a detached signature. Detached signatures are not being added into the PGP message
|
* Create a detached signature. Detached signatures are not being added into the PGP message
|
||||||
* itself. Instead, they can be distributed separately to the message. Detached signatures are
|
* itself. Instead, they can be distributed separately to the message. Detached signatures are
|
||||||
|
@ -250,6 +306,7 @@ class SigningOptions {
|
||||||
* @throws PGPException if the key cannot be validated or unlocked, or if no signature method
|
* @throws PGPException if the key cannot be validated or unlocked, or if no signature method
|
||||||
* can be created
|
* can be created
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Pass an OpenPGPKey instead.")
|
||||||
@Throws(KeyException::class, PGPException::class)
|
@Throws(KeyException::class, PGPException::class)
|
||||||
fun addDetachedSignature(
|
fun addDetachedSignature(
|
||||||
signingKeyProtector: SecretKeyRingProtector,
|
signingKeyProtector: SecretKeyRingProtector,
|
||||||
|
@ -257,6 +314,37 @@ class SigningOptions {
|
||||||
signatureType: DocumentSignatureType
|
signatureType: DocumentSignatureType
|
||||||
) = apply { addDetachedSignature(signingKeyProtector, signingKey, null, signatureType) }
|
) = apply { addDetachedSignature(signingKeyProtector, signingKey, null, signatureType) }
|
||||||
|
|
||||||
|
fun addDetachedSignature(
|
||||||
|
signingKeyProtector: SecretKeyRingProtector,
|
||||||
|
signingKey: OpenPGPKey,
|
||||||
|
userId: CharSequence? = null,
|
||||||
|
signatureType: DocumentSignatureType = DocumentSignatureType.BINARY_DOCUMENT,
|
||||||
|
subpacketCallback: Callback? = null
|
||||||
|
): SigningOptions = apply {
|
||||||
|
val keyRingInfo = inspectKeyRing(signingKey, evaluationDate)
|
||||||
|
if (userId != null && !keyRingInfo.isUserIdValid(userId)) {
|
||||||
|
throw UnboundUserIdException(
|
||||||
|
of(signingKey.pgpSecretKeyRing),
|
||||||
|
userId.toString(),
|
||||||
|
keyRingInfo.getLatestUserIdCertification(userId),
|
||||||
|
keyRingInfo.getUserIdRevocation(userId))
|
||||||
|
}
|
||||||
|
|
||||||
|
val signingPubKeys = keyRingInfo.signingSubkeys
|
||||||
|
if (signingPubKeys.isEmpty()) {
|
||||||
|
throw UnacceptableSigningKeyException(of(signingKey.pgpSecretKeyRing))
|
||||||
|
}
|
||||||
|
|
||||||
|
for (signingPubKey in signingPubKeys) {
|
||||||
|
val signingSecKey: OpenPGPSecretKey =
|
||||||
|
signingKey.getSecretKey(signingPubKey.keyIdentifier)
|
||||||
|
?: throw MissingSecretKeyException(
|
||||||
|
of(signingKey.pgpSecretKeyRing), signingPubKey.keyIdentifier.keyId)
|
||||||
|
addDetachedSignature(
|
||||||
|
signingKeyProtector, signingSecKey, userId, signatureType, subpacketCallback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a detached signature. Detached signatures are not being added into the PGP message
|
* Create a detached signature. Detached signatures are not being added into the PGP message
|
||||||
* itself. Instead, they can be distributed separately to the message. Detached signatures are
|
* itself. Instead, they can be distributed separately to the message. Detached signatures are
|
||||||
|
@ -275,6 +363,7 @@ class SigningOptions {
|
||||||
* @throws PGPException if the key cannot be validated or unlocked, or if no signature method
|
* @throws PGPException if the key cannot be validated or unlocked, or if no signature method
|
||||||
* can be created
|
* can be created
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Pass an OpenPGPKey instead.")
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
@Throws(KeyException::class, PGPException::class)
|
@Throws(KeyException::class, PGPException::class)
|
||||||
fun addDetachedSignature(
|
fun addDetachedSignature(
|
||||||
|
@ -283,34 +372,28 @@ class SigningOptions {
|
||||||
userId: String? = null,
|
userId: String? = null,
|
||||||
signatureType: DocumentSignatureType = DocumentSignatureType.BINARY_DOCUMENT,
|
signatureType: DocumentSignatureType = DocumentSignatureType.BINARY_DOCUMENT,
|
||||||
subpacketCallback: Callback? = null
|
subpacketCallback: Callback? = null
|
||||||
) = apply {
|
) =
|
||||||
val keyRingInfo = inspectKeyRing(signingKey, evaluationDate)
|
addDetachedSignature(
|
||||||
if (userId != null && !keyRingInfo.isUserIdValid(userId)) {
|
signingKeyProtector,
|
||||||
throw UnboundUserIdException(
|
signingKey.toOpenPGPKey(),
|
||||||
of(signingKey),
|
userId,
|
||||||
userId.toString(),
|
signatureType,
|
||||||
keyRingInfo.getLatestUserIdCertification(userId),
|
subpacketCallback)
|
||||||
keyRingInfo.getUserIdRevocation(userId))
|
|
||||||
}
|
|
||||||
|
|
||||||
val signingPubKeys = keyRingInfo.signingSubkeys
|
fun addDetachedSignature(
|
||||||
if (signingPubKeys.isEmpty()) {
|
signingKeyProtector: SecretKeyRingProtector,
|
||||||
throw UnacceptableSigningKeyException(of(signingKey))
|
signingKey: OpenPGPSecretKey,
|
||||||
}
|
userId: CharSequence? = null,
|
||||||
|
signatureType: DocumentSignatureType = DocumentSignatureType.BINARY_DOCUMENT,
|
||||||
for (signingPubKey in signingPubKeys) {
|
subpacketCallback: Callback? = null
|
||||||
val signingSecKey: PGPSecretKey =
|
): SigningOptions = apply {
|
||||||
signingKey.getSecretKey(signingPubKey.keyIdentifier)
|
val keyRingInfo = inspectKeyRing(signingKey.openPGPKey, evaluationDate)
|
||||||
?: throw MissingSecretKeyException(
|
val signingPrivKey: OpenPGPPrivateKey = signingKey.unlock(signingKeyProtector)
|
||||||
of(signingKey), signingPubKey.keyIdentifier.keyId)
|
val hashAlgorithms =
|
||||||
val signingSubkey: PGPPrivateKey = signingSecKey.unlock(signingKeyProtector)
|
if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId)
|
||||||
val hashAlgorithms =
|
else keyRingInfo.getPreferredHashAlgorithms(signingKey.keyIdentifier)
|
||||||
if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId)
|
val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy())
|
||||||
else keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyIdentifier)
|
addSigningMethod(signingPrivKey, hashAlgorithm, signatureType, true, subpacketCallback)
|
||||||
val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms, getPolicy())
|
|
||||||
addSigningMethod(
|
|
||||||
signingKey, signingSubkey, hashAlgorithm, signatureType, true, subpacketCallback)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -331,65 +414,44 @@ class SigningOptions {
|
||||||
*/
|
*/
|
||||||
@Throws(KeyException::class, PGPException::class)
|
@Throws(KeyException::class, PGPException::class)
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
|
@Deprecated("Pass an OpenPGPSecretKey instead.")
|
||||||
fun addDetachedSignature(
|
fun addDetachedSignature(
|
||||||
signingKeyProtector: SecretKeyRingProtector,
|
signingKeyProtector: SecretKeyRingProtector,
|
||||||
signingKey: PGPSecretKeyRing,
|
signingKey: PGPSecretKeyRing,
|
||||||
keyId: Long,
|
keyId: Long,
|
||||||
signatureType: DocumentSignatureType = DocumentSignatureType.BINARY_DOCUMENT,
|
signatureType: DocumentSignatureType = DocumentSignatureType.BINARY_DOCUMENT,
|
||||||
subpacketsCallback: Callback? = null
|
subpacketsCallback: Callback? = null
|
||||||
) = apply {
|
) =
|
||||||
val keyRingInfo = inspectKeyRing(signingKey, evaluationDate)
|
addDetachedSignature(
|
||||||
|
signingKeyProtector,
|
||||||
val signingPubKeys = keyRingInfo.signingSubkeys
|
signingKey.toOpenPGPKey().getSecretKey(KeyIdentifier(keyId))
|
||||||
if (signingPubKeys.isEmpty()) {
|
?: throw MissingSecretKeyException(of(signingKey), keyId),
|
||||||
throw UnacceptableSigningKeyException(of(signingKey))
|
null,
|
||||||
}
|
signatureType,
|
||||||
|
subpacketsCallback)
|
||||||
for (signingPubKey in signingPubKeys) {
|
|
||||||
if (signingPubKey.keyIdentifier.matches(KeyIdentifier(keyId))) {
|
|
||||||
val signingSecKey: PGPSecretKey =
|
|
||||||
signingKey.getSecretKey(signingPubKey.keyIdentifier)
|
|
||||||
?: throw MissingSecretKeyException(
|
|
||||||
of(signingKey), signingPubKey.keyIdentifier.keyId)
|
|
||||||
val signingSubkey: PGPPrivateKey = signingSecKey.unlock(signingKeyProtector)
|
|
||||||
val hashAlgorithms =
|
|
||||||
keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyIdentifier)
|
|
||||||
val hashAlgorithm: HashAlgorithm =
|
|
||||||
negotiateHashAlgorithm(hashAlgorithms, getPolicy())
|
|
||||||
addSigningMethod(
|
|
||||||
signingKey,
|
|
||||||
signingSubkey,
|
|
||||||
hashAlgorithm,
|
|
||||||
signatureType,
|
|
||||||
true,
|
|
||||||
subpacketsCallback)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw MissingSecretKeyException(of(signingKey), keyId)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addSigningMethod(
|
private fun addSigningMethod(
|
||||||
signingKey: PGPSecretKeyRing,
|
signingKey: OpenPGPPrivateKey,
|
||||||
signingSubkey: PGPPrivateKey,
|
|
||||||
hashAlgorithm: HashAlgorithm,
|
hashAlgorithm: HashAlgorithm,
|
||||||
signatureType: DocumentSignatureType,
|
signatureType: DocumentSignatureType,
|
||||||
detached: Boolean,
|
detached: Boolean,
|
||||||
subpacketCallback: Callback? = null
|
subpacketCallback: Callback? = null
|
||||||
) {
|
) {
|
||||||
val signingKeyIdentifier = SubkeyIdentifier(signingKey, signingSubkey.keyID)
|
val signingSecretKey: PGPSecretKey = signingKey.secretKey.pgpSecretKey
|
||||||
val signingSecretKey: PGPSecretKey = signingKey.getSecretKey(signingSubkey.keyID)
|
|
||||||
val publicKeyAlgorithm = requireFromId(signingSecretKey.publicKey.algorithm)
|
val publicKeyAlgorithm = requireFromId(signingSecretKey.publicKey.algorithm)
|
||||||
val bitStrength = signingSecretKey.publicKey.bitStrength
|
val bitStrength = signingSecretKey.publicKey.bitStrength
|
||||||
if (!getPolicy().publicKeyAlgorithmPolicy.isAcceptable(publicKeyAlgorithm, bitStrength)) {
|
if (!getPolicy().publicKeyAlgorithmPolicy.isAcceptable(publicKeyAlgorithm, bitStrength)) {
|
||||||
throw UnacceptableSigningKeyException(
|
throw UnacceptableSigningKeyException(
|
||||||
PublicKeyAlgorithmPolicyException(
|
PublicKeyAlgorithmPolicyException(
|
||||||
of(signingKey), signingSecretKey.keyID, publicKeyAlgorithm, bitStrength))
|
of(signingKey.secretKey.pgpSecretKey),
|
||||||
|
signingSecretKey.keyID,
|
||||||
|
publicKeyAlgorithm,
|
||||||
|
bitStrength))
|
||||||
}
|
}
|
||||||
|
|
||||||
val generator: PGPSignatureGenerator =
|
val generator: PGPSignatureGenerator =
|
||||||
createSignatureGenerator(signingSubkey, hashAlgorithm, signatureType)
|
createSignatureGenerator(
|
||||||
|
signingKey.unlockedKey.privateKey, hashAlgorithm, signatureType)
|
||||||
|
|
||||||
// Subpackets
|
// Subpackets
|
||||||
val hashedSubpackets =
|
val hashedSubpackets =
|
||||||
|
@ -405,7 +467,7 @@ class SigningOptions {
|
||||||
val signingMethod =
|
val signingMethod =
|
||||||
if (detached) SigningMethod.detachedSignature(generator, hashAlgorithm)
|
if (detached) SigningMethod.detachedSignature(generator, hashAlgorithm)
|
||||||
else SigningMethod.inlineSignature(generator, hashAlgorithm)
|
else SigningMethod.inlineSignature(generator, hashAlgorithm)
|
||||||
(signingMethods as MutableMap)[signingKeyIdentifier] = signingMethod
|
(signingMethods as MutableMap)[signingKey] = signingMethod
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,6 +8,7 @@ import org.bouncycastle.bcpg.KeyIdentifier
|
||||||
import org.bouncycastle.openpgp.PGPKeyRing
|
import org.bouncycastle.openpgp.PGPKeyRing
|
||||||
import org.bouncycastle.openpgp.PGPPublicKey
|
import org.bouncycastle.openpgp.PGPPublicKey
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey
|
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey
|
||||||
|
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPPrivateKey
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tuple class used to identify a subkey by fingerprints of the primary key of the subkeys key ring,
|
* Tuple class used to identify a subkey by fingerprints of the primary key of the subkeys key ring,
|
||||||
|
@ -32,6 +33,8 @@ class SubkeyIdentifier(
|
||||||
OpenPgpFingerprint.of(key.certificate.pgpPublicKeyRing),
|
OpenPgpFingerprint.of(key.certificate.pgpPublicKeyRing),
|
||||||
OpenPgpFingerprint.of(key.pgpPublicKey))
|
OpenPgpFingerprint.of(key.pgpPublicKey))
|
||||||
|
|
||||||
|
constructor(key: OpenPGPPrivateKey) : this(key.secretKey)
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
keys: PGPKeyRing,
|
keys: PGPKeyRing,
|
||||||
subkeyFingerprint: OpenPgpFingerprint
|
subkeyFingerprint: OpenPgpFingerprint
|
||||||
|
|
|
@ -10,6 +10,8 @@ import openpgp.openPgpKeyId
|
||||||
import org.bouncycastle.openpgp.PGPException
|
import org.bouncycastle.openpgp.PGPException
|
||||||
import org.bouncycastle.openpgp.PGPPrivateKey
|
import org.bouncycastle.openpgp.PGPPrivateKey
|
||||||
import org.bouncycastle.openpgp.PGPSecretKey
|
import org.bouncycastle.openpgp.PGPSecretKey
|
||||||
|
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPPrivateKey
|
||||||
|
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPSecretKey
|
||||||
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor
|
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor
|
||||||
import org.pgpainless.PGPainless
|
import org.pgpainless.PGPainless
|
||||||
import org.pgpainless.bouncycastle.extensions.isEncrypted
|
import org.pgpainless.bouncycastle.extensions.isEncrypted
|
||||||
|
@ -35,6 +37,36 @@ class UnlockSecretKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@Throws(PGPException::class)
|
||||||
|
fun unlockSecretKey(
|
||||||
|
secretKey: OpenPGPSecretKey,
|
||||||
|
protector: SecretKeyRingProtector
|
||||||
|
): OpenPGPPrivateKey {
|
||||||
|
val privateKey =
|
||||||
|
try {
|
||||||
|
secretKey.unlock(protector)
|
||||||
|
} catch (e: PGPException) {
|
||||||
|
throw WrongPassphraseException(secretKey.keyIdentifier, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (privateKey == null) {
|
||||||
|
if (secretKey.pgpSecretKey.s2K.type in 100..110) {
|
||||||
|
throw PGPException(
|
||||||
|
"Cannot decrypt secret key ${secretKey.keyIdentifier}: \n" +
|
||||||
|
"Unsupported private S2K type ${secretKey.pgpSecretKey.s2K.type}")
|
||||||
|
}
|
||||||
|
throw PGPException("Cannot decrypt secret key.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PGPainless.getPolicy().isEnableKeyParameterValidation()) {
|
||||||
|
PublicKeyParameterValidationUtil.verifyPublicKeyParameterIntegrity(
|
||||||
|
privateKey.unlockedKey.privateKey, privateKey.unlockedKey.publicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
return privateKey
|
||||||
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@Throws(PGPException::class)
|
@Throws(PGPException::class)
|
||||||
fun unlockSecretKey(
|
fun unlockSecretKey(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue