1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-12-08 21:31:08 +01:00

Port SignatureBuilders over to new classes

This commit is contained in:
Paul Schaub 2025-02-19 12:43:38 +01:00
parent 94dc25aa8b
commit 3feaf9134b
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
18 changed files with 398 additions and 246 deletions

View file

@ -409,7 +409,8 @@ class OpenPgpMessageInputStream(
val decryptionKeyCandidates = getDecryptionKeys(pkesk)
for (decryptionKeys in decryptionKeyCandidates) {
val secretKey = decryptionKeys.getSecretKeyFor(pkesk)!!
if (!secretKey.isEncryptionKey && !options.getAllowDecryptionWithNonEncryptionKey()) {
if (!secretKey.isEncryptionKey &&
!options.getAllowDecryptionWithNonEncryptionKey()) {
LOGGER.debug(
"Message is encrypted for ${secretKey.keyIdentifier}, but the key is not encryption capable.")
continue

View file

@ -11,8 +11,8 @@ import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPPrivateKey
/**
* Tuple class used to identify a subkey (component key) by fingerprints of the certificate,
* as well as the component keys fingerprint.
* Tuple class used to identify a subkey (component key) by fingerprints of the certificate, as well
* as the component keys fingerprint.
*/
class SubkeyIdentifier(
val certificateFingerprint: OpenPgpFingerprint,
@ -22,9 +22,12 @@ class SubkeyIdentifier(
/**
* Constructor for a [SubkeyIdentifier] pointing to the primary key identified by the
* [certificateFingerprint].
*
* @param certificateFingerprint primary key fingerprint
*/
constructor(certificateFingerprint: OpenPgpFingerprint) : this(certificateFingerprint, certificateFingerprint)
constructor(
certificateFingerprint: OpenPgpFingerprint
) : this(certificateFingerprint, certificateFingerprint)
/**
* Constructor for a [SubkeyIdentifier] pointing to the primary key of the given [PGPKeyRing].
@ -45,7 +48,10 @@ class SubkeyIdentifier(
* [componentKeyId]) from the given [certificate].
*/
@Deprecated("Pass in a KeyIdentifier instead of a keyId.")
constructor(certificate: PGPKeyRing, componentKeyId: Long) : this(certificate, KeyIdentifier(componentKeyId))
constructor(
certificate: PGPKeyRing,
componentKeyId: Long
) : this(certificate, KeyIdentifier(componentKeyId))
/**
* Constructor for a [SubkeyIdentifier] pointing to the given [componentKey].
@ -54,18 +60,14 @@ class SubkeyIdentifier(
*/
constructor(
componentKey: OpenPGPComponentKey
) : this(
OpenPgpFingerprint.of(componentKey.certificate),
OpenPgpFingerprint.of(componentKey))
) : this(OpenPgpFingerprint.of(componentKey.certificate), OpenPgpFingerprint.of(componentKey))
/**
* Constructor for a [SubkeyIdentifier] pointing to the given [componentKey].
*/
/** Constructor for a [SubkeyIdentifier] pointing to the given [componentKey]. */
constructor(componentKey: OpenPGPPrivateKey) : this(componentKey.secretKey)
/**
* Constructor for a [SubkeyIdentifier] pointing to a component key (identified by
* the [componentKeyFingerprint]) of the given [certificate].
* Constructor for a [SubkeyIdentifier] pointing to a component key (identified by the
* [componentKeyFingerprint]) of the given [certificate].
*
* @param certificate certificate
* @param componentKeyFingerprint fingerprint of the component key
@ -92,48 +94,34 @@ class SubkeyIdentifier(
?: throw NoSuchElementException(
"OpenPGP key does not contain subkey $componentKeyIdentifier")))
@Deprecated("Use certificateFingerprint instead.",
replaceWith = ReplaceWith("certificateFingerprint")
)
@Deprecated(
"Use certificateFingerprint instead.", replaceWith = ReplaceWith("certificateFingerprint"))
val primaryKeyFingerprint: OpenPgpFingerprint = certificateFingerprint
@Deprecated("Use componentKeyFingerprint instead.",
@Deprecated(
"Use componentKeyFingerprint instead.",
replaceWith = ReplaceWith("componentKeyFingerprint"))
val subkeyFingerprint: OpenPgpFingerprint = componentKeyFingerprint
/**
* [KeyIdentifier] of the component key.
*/
/** [KeyIdentifier] of the component key. */
val keyIdentifier = componentKeyFingerprint.keyIdentifier
/**
* [KeyIdentifier] of the component key.
*/
/** [KeyIdentifier] of the component key. */
val componentKeyIdentifier = keyIdentifier
/**
* [KeyIdentifier] of the primary key of the certificate the component key belongs to.
*/
/** [KeyIdentifier] of the primary key of the certificate the component key belongs to. */
val certificateIdentifier = certificateFingerprint.keyIdentifier
/**
* Key-ID of the component key.
*/
/** Key-ID of the component key. */
@Deprecated("Use of key-ids is discouraged.") val keyId = keyIdentifier.keyId
/**
* Fingerprint of the component key.
*/
/** Fingerprint of the component key. */
val fingerprint = componentKeyFingerprint
/**
* Key-ID of the component key.
*/
/** Key-ID of the component key. */
@Deprecated("Use of key-ids is discouraged.") val subkeyId = componentKeyIdentifier.keyId
/**
* Key-ID of the primary key of the certificate the component key belongs to.
*/
/** Key-ID of the primary key of the certificate the component key belongs to. */
@Deprecated("Use of key-ids is discouraged.") val primaryKeyId = certificateIdentifier.keyId
val isPrimaryKey = certificateIdentifier.matches(componentKeyIdentifier)

View file

@ -7,9 +7,11 @@ package org.pgpainless.key.certification
import java.util.*
import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKeyRing
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSecretKeyRing
import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.api.OpenPGPCertificate
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.openpgp.api.OpenPGPSignature
import org.pgpainless.PGPainless
import org.pgpainless.algorithm.CertificationType
import org.pgpainless.algorithm.KeyFlag
@ -42,17 +44,34 @@ class CertifyCertificate {
* @param certificate certificate
* @return API
*/
@JvmOverloads
fun userIdOnCertificate(
userId: CharSequence,
certificate: OpenPGPCertificate,
certificationType: CertificationType = CertificationType.GENERIC
): CertificationOnUserId = CertificationOnUserId(userId, certificate, certificationType)
/**
* Create a certification over a User-Id. By default, this method will use
* [CertificationType.GENERIC] to create the signature.
*
* @param userId user-id to certify
* @param certificate certificate
* @return API
*/
@Deprecated("Pass in an OpenPGPCertificate instead of PGPPublicKeyRing.")
fun userIdOnCertificate(userId: String, certificate: PGPPublicKeyRing): CertificationOnUserId =
userIdOnCertificate(userId, certificate, CertificationType.GENERIC)
/**
* Create a certification of the given [CertificationType] over a User-Id.
*
* @param userid user-id to certify
* @param userId user-id to certify
* @param certificate certificate
* @param certificationType type of signature
* @return API
*/
@Deprecated("Pass in an OpenPGPCertificate instead of PGPPublicKeyRing.")
fun userIdOnCertificate(
userId: String,
certificate: PGPPublicKeyRing,
@ -67,6 +86,19 @@ class CertifyCertificate {
* @param certificate certificate
* @return API
*/
@JvmOverloads
fun certificate(certificate: OpenPGPCertificate, trustworthiness: Trustworthiness? = null) =
DelegationOnCertificate(certificate, trustworthiness)
/**
* Create a delegation (direct key signature) over a certificate. This can be used to mark a
* certificate as a trusted introducer (see [certificate] method with [Trustworthiness]
* argument).
*
* @param certificate certificate
* @return API
*/
@Deprecated("Pass in an OpenPGPCertificate instead of PGPPublicKeyRing.")
fun certificate(certificate: PGPPublicKeyRing): DelegationOnCertificate =
certificate(certificate, null)
@ -79,15 +111,35 @@ class CertifyCertificate {
* @param trustworthiness trustworthiness of the certificate
* @return API
*/
@Deprecated("Pass in an OpenPGPCertificate instead of PGPPublicKeyRing.")
fun certificate(certificate: PGPPublicKeyRing, trustworthiness: Trustworthiness?) =
DelegationOnCertificate(certificate, trustworthiness)
class CertificationOnUserId(
val userId: String,
val certificate: PGPPublicKeyRing,
val userId: CharSequence,
val certificate: OpenPGPCertificate,
val certificationType: CertificationType
) {
@Deprecated("Use primary constructor instead.")
constructor(
userId: String,
certificate: PGPPublicKeyRing,
certificationType: CertificationType
) : this(userId, PGPainless.getInstance().toCertificate(certificate), certificationType)
fun withKey(
key: OpenPGPKey,
protector: SecretKeyRingProtector
): CertificationOnUserIdWithSubpackets {
val secretKey = getCertifyingSecretKey(key)
val sigBuilder =
ThirdPartyCertificationSignatureBuilder(
certificationType.asSignatureType(), secretKey, protector)
return CertificationOnUserIdWithSubpackets(certificate, userId, sigBuilder)
}
/**
* Create the certification using the given key.
*
@ -96,26 +148,27 @@ class CertifyCertificate {
* @return API
* @throws PGPException in case of an OpenPGP related error
*/
@Deprecated("Pass in an OpenPGPKey instead of a PGPSecretKeyRing.")
fun withKey(
certificationKey: PGPSecretKeyRing,
protector: SecretKeyRingProtector
): CertificationOnUserIdWithSubpackets {
val secretKey = getCertifyingSecretKey(certificationKey)
val sigBuilder =
ThirdPartyCertificationSignatureBuilder(
certificationType.asSignatureType(), secretKey, protector)
return CertificationOnUserIdWithSubpackets(certificate, userId, sigBuilder)
}
): CertificationOnUserIdWithSubpackets =
withKey(PGPainless.getInstance().toKey(certificationKey), protector)
}
class CertificationOnUserIdWithSubpackets(
val certificate: PGPPublicKeyRing,
val userId: String,
val certificate: OpenPGPCertificate,
val userId: CharSequence,
val sigBuilder: ThirdPartyCertificationSignatureBuilder
) {
@Deprecated("Pass in an OpenPGPCertificate instead of a PGPPublicKeyRing.")
constructor(
certificate: PGPPublicKeyRing,
userId: String,
sigBuilder: ThirdPartyCertificationSignatureBuilder
) : this(PGPainless.getInstance().toCertificate(certificate), userId, sigBuilder)
/**
* Apply the given signature subpackets and build the certification.
*
@ -139,16 +192,38 @@ class CertifyCertificate {
fun build(): CertificationResult {
val signature = sigBuilder.build(certificate, userId)
val certifiedCertificate =
KeyRingUtils.injectCertification(certificate, userId, signature)
OpenPGPCertificate(
KeyRingUtils.injectCertification(
certificate.pgpPublicKeyRing, userId, signature.signature))
return CertificationResult(certifiedCertificate, signature)
}
}
class DelegationOnCertificate(
val certificate: PGPPublicKeyRing,
val certificate: OpenPGPCertificate,
val trustworthiness: Trustworthiness?
) {
@Deprecated("Pass in an OpenPGPCertificate instead of PGPPublicKeyRing.")
constructor(
certificate: PGPPublicKeyRing,
trustworthiness: Trustworthiness?
) : this(PGPainless.getInstance().toCertificate(certificate), trustworthiness)
fun withKey(
key: OpenPGPKey,
protector: SecretKeyRingProtector
): DelegationOnCertificateWithSubpackets {
val secretKey = getCertifyingSecretKey(key)
val sigBuilder = ThirdPartyDirectKeySignatureBuilder(secretKey, protector)
if (trustworthiness != null) {
sigBuilder.hashedSubpackets.setTrust(
true, trustworthiness.depth, trustworthiness.amount)
}
return DelegationOnCertificateWithSubpackets(certificate, sigBuilder)
}
/**
* Build the delegation using the given certification key.
*
@ -157,25 +232,25 @@ class CertifyCertificate {
* @return API
* @throws PGPException in case of an OpenPGP related error
*/
@Deprecated("Pass in an OpenPGPKey instead of PGPSecretKeyRing.")
fun withKey(
certificationKey: PGPSecretKeyRing,
protector: SecretKeyRingProtector
): DelegationOnCertificateWithSubpackets {
val secretKey = getCertifyingSecretKey(certificationKey)
val sigBuilder = ThirdPartyDirectKeySignatureBuilder(secretKey, protector)
if (trustworthiness != null) {
sigBuilder.hashedSubpackets.setTrust(
true, trustworthiness.depth, trustworthiness.amount)
}
return DelegationOnCertificateWithSubpackets(certificate, sigBuilder)
}
): DelegationOnCertificateWithSubpackets =
withKey(PGPainless.getInstance().toKey(certificationKey), protector)
}
class DelegationOnCertificateWithSubpackets(
val certificate: PGPPublicKeyRing,
val certificate: OpenPGPCertificate,
val sigBuilder: ThirdPartyDirectKeySignatureBuilder
) {
@Deprecated("Pass in an OpenPGPCertificate instead of a PGPPublicKeyRing.")
constructor(
certificate: PGPPublicKeyRing,
sigBuilder: ThirdPartyDirectKeySignatureBuilder
) : this(PGPainless.getInstance().toCertificate(certificate), sigBuilder)
/**
* Apply the given signature subpackets and build the delegation signature.
*
@ -197,10 +272,14 @@ class CertifyCertificate {
* @throws PGPException in case of an OpenPGP related error
*/
fun build(): CertificationResult {
val delegatedKey = certificate.publicKey
val delegatedKey = certificate.primaryKey
val delegation = sigBuilder.build(delegatedKey)
val delegatedCertificate =
KeyRingUtils.injectCertification(certificate, delegatedKey, delegation)
OpenPGPCertificate(
KeyRingUtils.injectCertification(
certificate.pgpPublicKeyRing,
delegatedKey.pgpPublicKey,
delegation.signature))
return CertificationResult(delegatedCertificate, delegation)
}
}
@ -212,13 +291,18 @@ class CertifyCertificate {
* @param certification the newly created signature
*/
data class CertificationResult(
val certifiedCertificate: PGPPublicKeyRing,
val certification: PGPSignature
)
val certifiedCertificate: OpenPGPCertificate,
val certification: OpenPGPSignature
) {
val publicKeyRing: PGPPublicKeyRing = certifiedCertificate.pgpPublicKeyRing
val pgpSignature: PGPSignature = certification.signature
}
companion object {
@JvmStatic
private fun getCertifyingSecretKey(certificationKey: PGPSecretKeyRing): PGPSecretKey {
private fun getCertifyingSecretKey(
certificationKey: OpenPGPKey
): OpenPGPKey.OpenPGPSecretKey {
val now = Date()
val info = PGPainless.inspectKeyRing(certificationKey, now)

View file

@ -12,6 +12,8 @@ import openpgp.openPgpKeyId
import org.bouncycastle.bcpg.KeyIdentifier
import org.bouncycastle.bcpg.sig.KeyExpirationTime
import org.bouncycastle.openpgp.*
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.openpgp.api.OpenPGPSignature
import org.pgpainless.PGPainless
import org.pgpainless.PGPainless.Companion.inspectKeyRing
import org.pgpainless.algorithm.AlgorithmSuite
@ -38,10 +40,16 @@ import org.pgpainless.signature.subpackets.*
import org.pgpainless.util.Passphrase
import org.pgpainless.util.selection.userid.SelectUserId
class SecretKeyRingEditor(
var secretKeyRing: PGPSecretKeyRing,
override val referenceTime: Date = Date()
) : SecretKeyRingEditorInterface {
class SecretKeyRingEditor(var key: OpenPGPKey, override val referenceTime: Date = Date()) :
SecretKeyRingEditorInterface {
private var secretKeyRing: PGPSecretKeyRing = key.pgpSecretKeyRing
@JvmOverloads
constructor(
secretKeyRing: PGPSecretKeyRing,
referenceTime: Date = Date()
) : this(PGPainless.getInstance().toKey(secretKeyRing), referenceTime)
override fun addUserId(
userId: CharSequence,
@ -74,7 +82,7 @@ class SecretKeyRingEditor(
}
val builder =
SelfSignatureBuilder(primaryKey, protector).apply {
SelfSignatureBuilder(key.primarySecretKey, protector).apply {
hashedSubpackets.setSignatureCreationTime(referenceTime)
setSignatureType(SignatureType.POSITIVE_CERTIFICATION)
}
@ -88,6 +96,7 @@ class SecretKeyRingEditor(
builder.applyCallback(callback)
secretKeyRing =
injectCertification(secretKeyRing, sanitizedUserId, builder.build(sanitizedUserId))
key = PGPainless.getInstance().toKey(secretKeyRing)
return this
}
@ -294,13 +303,14 @@ class SecretKeyRingEditor(
false,
subkeyProtector.getEncryptor(subkey.keyID))
val skBindingBuilder =
SubkeyBindingSignatureBuilder(primaryKey, primaryKeyProtector, hashAlgorithm)
SubkeyBindingSignatureBuilder(key.primarySecretKey, primaryKeyProtector, hashAlgorithm)
skBindingBuilder.apply {
hashedSubpackets.setSignatureCreationTime(referenceTime)
hashedSubpackets.setKeyFlags(flags)
if (subkeyAlgorithm.isSigningCapable()) {
val pkBindingBuilder =
PrimaryKeyBindingSignatureBuilder(secretSubkey, subkeyProtector, hashAlgorithm)
PrimaryKeyBindingSignatureBuilder(
key.primarySecretKey, subkeyProtector, hashAlgorithm)
pkBindingBuilder.hashedSubpackets.setSignatureCreationTime(referenceTime)
hashedSubpackets.addEmbeddedSignature(pkBindingBuilder.build(primaryKey.publicKey))
}
@ -430,7 +440,7 @@ class SecretKeyRingEditor(
injectCertification(
secretKeyRing,
secretKeyRing.publicKey,
reissueDirectKeySignature(expiration, protector, prevDirectKeySig))
reissueDirectKeySignature(expiration, protector, prevDirectKeySig).signature)
}
val primaryUserId =
@ -590,12 +600,11 @@ class SecretKeyRingEditor(
revokeeSubkey: PGPPublicKey,
callback: RevocationSignatureSubpackets.Callback?
): PGPSignature {
val primaryKey = secretKeyRing.secretKey
val signatureType =
if (revokeeSubkey.isMasterKey) SignatureType.KEY_REVOCATION
else SignatureType.SUBKEY_REVOCATION
return RevocationSignatureBuilder(signatureType, primaryKey, protector)
return RevocationSignatureBuilder(signatureType, key.primarySecretKey, protector)
.apply { applyCallback(callback) }
.build(revokeeSubkey)
}
@ -606,7 +615,7 @@ class SecretKeyRingEditor(
callback: RevocationSignatureSubpackets.Callback?
): SecretKeyRingEditorInterface {
RevocationSignatureBuilder(
SignatureType.CERTIFICATION_REVOCATION, secretKeyRing.secretKey, protector)
SignatureType.CERTIFICATION_REVOCATION, key.primarySecretKey, protector)
.apply {
hashedSubpackets.setSignatureCreationTime(referenceTime)
applyCallback(callback)
@ -635,7 +644,7 @@ class SecretKeyRingEditor(
prevUserIdSig: PGPSignature
): PGPSignature {
val builder =
SelfSignatureBuilder(secretKeyRing.secretKey, secretKeyRingProtector, prevUserIdSig)
SelfSignatureBuilder(key.primarySecretKey, secretKeyRingProtector, prevUserIdSig)
builder.hashedSubpackets.setSignatureCreationTime(referenceTime)
builder.applyCallback(
object : SelfSignatureSubpackets.Callback {
@ -654,7 +663,7 @@ class SecretKeyRingEditor(
@Nonnull primaryUserId: String,
@Nonnull prevUserIdSig: PGPSignature
): PGPSignature {
return SelfSignatureBuilder(secretKeyRing.secretKey, secretKeyRingProtector, prevUserIdSig)
return SelfSignatureBuilder(key.primarySecretKey, secretKeyRingProtector, prevUserIdSig)
.apply {
hashedSubpackets.setSignatureCreationTime(referenceTime)
applyCallback(
@ -680,9 +689,9 @@ class SecretKeyRingEditor(
expiration: Date?,
secretKeyRingProtector: SecretKeyRingProtector,
prevDirectKeySig: PGPSignature
): PGPSignature {
): OpenPGPSignature {
return DirectKeySelfSignatureBuilder(
secretKeyRing.secretKey, secretKeyRingProtector, prevDirectKeySig)
secretKeyRing, secretKeyRingProtector, prevDirectKeySig)
.apply {
hashedSubpackets.setSignatureCreationTime(referenceTime)
applyCallback(
@ -709,11 +718,11 @@ class SecretKeyRingEditor(
prevSubkeyBindingSignature: PGPSignature
): PGPSignature {
val primaryKey = secretKeyRing.publicKey
val secretPrimaryKey = secretKeyRing.secretKey
val secretSubkey: PGPSecretKey? = secretKeyRing.getSecretKey(subkey.keyID)
val builder =
SubkeyBindingSignatureBuilder(secretPrimaryKey, protector, prevSubkeyBindingSignature)
SubkeyBindingSignatureBuilder(
key.primarySecretKey, protector, prevSubkeyBindingSignature)
builder.hashedSubpackets.apply {
// set expiration
setSignatureCreationTime(referenceTime)
@ -732,7 +741,8 @@ class SecretKeyRingEditor(
// create new embedded back-sig
clearEmbeddedSignatures()
addEmbeddedSignature(
PrimaryKeyBindingSignatureBuilder(secretSubkey, protector)
PrimaryKeyBindingSignatureBuilder(
key.getSecretKey(subkey.keyIdentifier), protector)
.build(primaryKey))
}
}

View file

@ -6,11 +6,11 @@ package org.pgpainless.signature.builder
import java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPrivateKey
import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.PGPSignatureGenerator
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.pgpainless.PGPainless
import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.algorithm.SignatureType
@ -23,8 +23,7 @@ import org.pgpainless.signature.subpackets.SignatureSubpackets
import org.pgpainless.signature.subpackets.SignatureSubpacketsHelper
abstract class AbstractSignatureBuilder<B : AbstractSignatureBuilder<B>>(
protected val privateSigningKey: PGPPrivateKey,
protected val publicSigningKey: PGPPublicKey,
protected val signingKey: OpenPGPKey.OpenPGPPrivateKey,
protected var _hashAlgorithm: HashAlgorithm,
protected var _signatureType: SignatureType,
protected val _hashedSubpackets: SignatureSubpackets,
@ -42,14 +41,13 @@ abstract class AbstractSignatureBuilder<B : AbstractSignatureBuilder<B>>(
@Throws(PGPException::class)
protected constructor(
signatureType: SignatureType,
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector,
hashAlgorithm: HashAlgorithm,
hashedSubpackets: SignatureSubpackets,
unhashedSubpackets: SignatureSubpackets
) : this(
UnlockSecretKey.unlockSecretKey(signingKey, protector),
signingKey.publicKey,
hashAlgorithm,
signatureType,
hashedSubpackets,
@ -58,27 +56,28 @@ abstract class AbstractSignatureBuilder<B : AbstractSignatureBuilder<B>>(
@Throws(PGPException::class)
constructor(
signatureType: SignatureType,
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector
) : this(
signatureType,
signingKey,
protector,
negotiateHashAlgorithm(signingKey.publicKey),
SignatureSubpackets.createHashedSubpackets(signingKey.publicKey),
negotiateHashAlgorithm(signingKey),
SignatureSubpackets.createHashedSubpackets(signingKey.pgpSecretKey.publicKey),
SignatureSubpackets.createEmptySubpackets())
@Throws(PGPException::class)
constructor(
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector,
archetypeSignature: PGPSignature
) : this(
SignatureType.requireFromCode(archetypeSignature.signatureType),
signingKey,
protector,
negotiateHashAlgorithm(signingKey.publicKey),
SignatureSubpackets.refreshHashedSubpackets(signingKey.publicKey, archetypeSignature),
negotiateHashAlgorithm(signingKey),
SignatureSubpackets.refreshHashedSubpackets(
signingKey.publicKey.pgpPublicKey, archetypeSignature),
SignatureSubpackets.refreshUnhashedSubpackets(archetypeSignature))
val hashAlgorithm = _hashAlgorithm
@ -113,11 +112,11 @@ abstract class AbstractSignatureBuilder<B : AbstractSignatureBuilder<B>>(
PGPSignatureGenerator(
ImplementationFactory.getInstance()
.getPGPContentSignerBuilder(
publicSigningKey.algorithm, hashAlgorithm.algorithmId))
signingKey.publicKey.pgpPublicKey.algorithm, hashAlgorithm.algorithmId))
.apply {
setUnhashedSubpackets(SignatureSubpacketsHelper.toVector(_unhashedSubpackets))
setHashedSubpackets(SignatureSubpacketsHelper.toVector(_hashedSubpackets))
init(_signatureType.code, privateSigningKey)
init(_signatureType.code, signingKey.keyPair.privateKey)
}
companion object {
@ -133,5 +132,9 @@ abstract class AbstractSignatureBuilder<B : AbstractSignatureBuilder<B>>(
HashAlgorithmNegotiator.negotiateSignatureHashAlgorithm(PGPainless.getPolicy())
.negotiateHashAlgorithm(
OpenPgpKeyAttributeUtil.getOrGuessPreferredHashAlgorithms(publicKey))
@JvmStatic
fun negotiateHashAlgorithm(key: OpenPGPComponentKey): HashAlgorithm =
negotiateHashAlgorithm(key.pgpPublicKey)
}
}

View file

@ -6,8 +6,12 @@ package org.pgpainless.signature.builder
import java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSecretKeyRing
import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentSignature
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.openpgp.api.OpenPGPSignature
import org.pgpainless.PGPainless
import org.pgpainless.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets
@ -23,14 +27,24 @@ class DirectKeySelfSignatureBuilder : AbstractSignatureBuilder<DirectKeySelfSign
@Throws(PGPException::class)
constructor(
signingKey: PGPSecretKey,
signingKeyRing: PGPSecretKeyRing,
protector: SecretKeyRingProtector,
archetypeSignature: PGPSignature
) : this(
PGPainless.getInstance().toKey(signingKeyRing).primarySecretKey,
protector,
archetypeSignature)
@Throws(PGPException::class)
constructor(
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector,
archetypeSignature: PGPSignature
) : super(signingKey, protector, archetypeSignature)
@Throws(PGPException::class)
constructor(
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector
) : super(SignatureType.DIRECT_KEY, signingKey, protector)
@ -45,6 +59,8 @@ class DirectKeySelfSignatureBuilder : AbstractSignatureBuilder<DirectKeySelfSign
}
@Throws(PGPException::class)
fun build(): PGPSignature =
buildAndInitSignatureGenerator().let { it.generateCertification(publicSigningKey) }
fun build(): OpenPGPSignature =
buildAndInitSignatureGenerator()
.generateCertification(signingKey.publicKey.pgpPublicKey)
.let { OpenPGPComponentSignature(it, signingKey.publicKey, signingKey.publicKey) }
}

View file

@ -7,8 +7,8 @@ package org.pgpainless.signature.builder
import java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector
@ -28,13 +28,13 @@ class PrimaryKeyBindingSignatureBuilder :
@Throws(PGPException::class)
constructor(
signingSubkey: PGPSecretKey,
signingSubkey: OpenPGPKey.OpenPGPSecretKey,
subkeyProtector: SecretKeyRingProtector
) : super(SignatureType.PRIMARYKEY_BINDING, signingSubkey, subkeyProtector)
@Throws(PGPException::class)
constructor(
signingSubkey: PGPSecretKey,
signingSubkey: OpenPGPKey.OpenPGPSecretKey,
subkeyProtector: SecretKeyRingProtector,
hashAlgorithm: HashAlgorithm
) : super(
@ -42,7 +42,7 @@ class PrimaryKeyBindingSignatureBuilder :
signingSubkey,
subkeyProtector,
hashAlgorithm,
SignatureSubpackets.createHashedSubpackets(signingSubkey.publicKey),
SignatureSubpackets.createHashedSubpackets(signingSubkey.publicKey.pgpPublicKey),
SignatureSubpackets.createEmptySubpackets())
val hashedSubpackets: SelfSignatureSubpackets = _hashedSubpackets
@ -57,5 +57,6 @@ class PrimaryKeyBindingSignatureBuilder :
@Throws(PGPException::class)
fun build(primaryKey: PGPPublicKey): PGPSignature =
buildAndInitSignatureGenerator().generateCertification(primaryKey, publicSigningKey)
buildAndInitSignatureGenerator()
.generateCertification(primaryKey, signingKey.publicKey.pgpPublicKey)
}

View file

@ -7,14 +7,20 @@ package org.pgpainless.signature.builder
import java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.pgpainless.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.signature.subpackets.RevocationSignatureSubpackets
/** [AbstractSignatureBuilder] subclass devoted to revocation signatures. */
class RevocationSignatureBuilder : AbstractSignatureBuilder<RevocationSignatureBuilder> {
class RevocationSignatureBuilder
@Throws(PGPException::class)
constructor(
signatureType: SignatureType,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector
) : AbstractSignatureBuilder<RevocationSignatureBuilder>(signatureType, signingKey, protector) {
override val signatureTypePredicate: Predicate<SignatureType>
get() =
@ -26,15 +32,6 @@ class RevocationSignatureBuilder : AbstractSignatureBuilder<RevocationSignatureB
SignatureType.CERTIFICATION_REVOCATION)
}
@Throws(PGPException::class)
constructor(
signatureType: SignatureType,
signingKey: PGPSecretKey,
protector: SecretKeyRingProtector
) : super(signatureType, signingKey, protector) {
hashedSubpackets.setRevocable(false)
}
val hashedSubpackets: RevocationSignatureSubpackets = _hashedSubpackets
val unhashedSubpackets: RevocationSignatureSubpackets = _unhashedSubpackets
@ -52,9 +49,9 @@ class RevocationSignatureBuilder : AbstractSignatureBuilder<RevocationSignatureB
require(revokeeKey.isMasterKey) {
"Signature type is KEY_REVOCATION, but provided revokee does not appear to be a primary key."
}
it.generateCertification(publicSigningKey)
it.generateCertification(signingKey.publicKey.pgpPublicKey)
} else {
it.generateCertification(publicSigningKey, revokeeKey)
it.generateCertification(signingKey.publicKey.pgpPublicKey, revokeeKey)
}
}
@ -66,5 +63,9 @@ class RevocationSignatureBuilder : AbstractSignatureBuilder<RevocationSignatureB
"Signature type is != CERTIFICATION_REVOCATION."
}
}
.generateCertification(revokeeUserId.toString(), publicSigningKey)
.generateCertification(revokeeUserId.toString(), signingKey.publicKey.pgpPublicKey)
init {
hashedSubpackets.setRevocable(false)
}
}

View file

@ -6,9 +6,9 @@ package org.pgpainless.signature.builder
import java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.pgpainless.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets
@ -31,20 +31,20 @@ class SelfSignatureBuilder : AbstractSignatureBuilder<SelfSignatureBuilder> {
@Throws(PGPException::class)
constructor(
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector
) : super(SignatureType.GENERIC_CERTIFICATION, signingKey, protector)
@Throws(PGPException::class)
constructor(
signatureType: SignatureType,
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector
) : super(signatureType, signingKey, protector)
@Throws(PGPException::class)
constructor(
primaryKey: PGPSecretKey,
primaryKey: OpenPGPKey.OpenPGPSecretKey,
primaryKeyProtector: SecretKeyRingProtector,
oldCertification: PGPSignature
) : super(primaryKey, primaryKeyProtector, oldCertification)
@ -61,9 +61,11 @@ class SelfSignatureBuilder : AbstractSignatureBuilder<SelfSignatureBuilder> {
@Throws(PGPException::class)
fun build(userId: CharSequence): PGPSignature =
buildAndInitSignatureGenerator().generateCertification(userId.toString(), publicSigningKey)
buildAndInitSignatureGenerator()
.generateCertification(userId.toString(), signingKey.publicKey.pgpPublicKey)
@Throws(PGPException::class)
fun build(userAttributes: PGPUserAttributeSubpacketVector): PGPSignature =
buildAndInitSignatureGenerator().generateCertification(userAttributes, publicSigningKey)
buildAndInitSignatureGenerator()
.generateCertification(userAttributes, signingKey.publicKey.pgpPublicKey)
}

View file

@ -7,8 +7,8 @@ package org.pgpainless.signature.builder
import java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector
@ -26,13 +26,13 @@ class SubkeyBindingSignatureBuilder : AbstractSignatureBuilder<SubkeyBindingSign
@Throws(PGPException::class)
constructor(
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector
) : super(SignatureType.SUBKEY_BINDING, signingKey, protector)
@Throws(PGPException::class)
constructor(
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector,
hashAlgorithm: HashAlgorithm
) : super(
@ -40,12 +40,12 @@ class SubkeyBindingSignatureBuilder : AbstractSignatureBuilder<SubkeyBindingSign
signingKey,
protector,
hashAlgorithm,
SignatureSubpackets.createHashedSubpackets(signingKey.publicKey),
SignatureSubpackets.createHashedSubpackets(signingKey.publicKey.pgpPublicKey),
SignatureSubpackets.createEmptySubpackets())
@Throws(PGPException::class)
constructor(
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector,
oldSubkeyBinding: PGPSignature
) : super(
@ -69,5 +69,6 @@ class SubkeyBindingSignatureBuilder : AbstractSignatureBuilder<SubkeyBindingSign
@Throws(PGPException::class)
fun build(subkey: PGPPublicKey): PGPSignature =
buildAndInitSignatureGenerator().generateCertification(publicSigningKey, subkey)
buildAndInitSignatureGenerator()
.generateCertification(signingKey.publicKey.pgpPublicKey, subkey)
}

View file

@ -7,9 +7,13 @@ package org.pgpainless.signature.builder
import java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKeyRing
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector
import org.bouncycastle.openpgp.api.OpenPGPCertificate
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentSignature
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.openpgp.api.OpenPGPSignature
import org.pgpainless.PGPainless
import org.pgpainless.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.signature.subpackets.CertificationSubpackets
@ -42,7 +46,7 @@ class ThirdPartyCertificationSignatureBuilder :
*/
@Throws(PGPException::class)
constructor(
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector
) : super(SignatureType.GENERIC_CERTIFICATION, signingKey, protector)
@ -57,7 +61,7 @@ class ThirdPartyCertificationSignatureBuilder :
@Throws(PGPException::class)
constructor(
signatureType: SignatureType,
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector
) : super(signatureType, signingKey, protector)
@ -71,7 +75,7 @@ class ThirdPartyCertificationSignatureBuilder :
*/
@Throws(PGPException::class)
constructor(
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector,
archetypeSignature: PGPSignature
) : super(signingKey, protector, archetypeSignature)
@ -86,6 +90,16 @@ class ThirdPartyCertificationSignatureBuilder :
}
}
fun build(certificate: OpenPGPCertificate, userId: CharSequence): OpenPGPSignature =
buildAndInitSignatureGenerator()
.generateCertification(userId.toString(), certificate.primaryKey.pgpPublicKey)
.let {
OpenPGPComponentSignature(
it,
signingKey.publicKey,
OpenPGPCertificate.OpenPGPUserId(userId.toString(), certificate.primaryKey))
}
/**
* Create a certification signature for the given user-id and the given third-party certificate.
*
@ -95,9 +109,19 @@ class ThirdPartyCertificationSignatureBuilder :
* @throws PGPException if the signature generator cannot be initialized
*/
@Throws(PGPException::class)
@Deprecated("Pass in an OpenPGPCertificate instead of a PGPPublicKeyRing.")
fun build(certificate: PGPPublicKeyRing, userId: CharSequence): PGPSignature =
buildAndInitSignatureGenerator()
.generateCertification(userId.toString(), certificate.publicKey)
build(PGPainless.getInstance().toCertificate(certificate), userId).signature
fun build(
certificate: OpenPGPCertificate,
userAttribute: PGPUserAttributeSubpacketVector
): OpenPGPSignature =
OpenPGPComponentSignature(
buildAndInitSignatureGenerator()
.generateCertification(userAttribute, certificate.primaryKey.pgpPublicKey),
signingKey.publicKey,
OpenPGPCertificate.OpenPGPUserAttribute(userAttribute, certificate.primaryKey))
/**
* Create a certification signature for the given user attribute and the given third-party
@ -109,9 +133,10 @@ class ThirdPartyCertificationSignatureBuilder :
* @throws PGPException if the signature generator cannot be initialized
*/
@Throws(PGPException::class)
@Deprecated("Pass in an OpenPGPCertificate instead of a PGPPublicKeyRing.")
fun build(
certificate: PGPPublicKeyRing,
userAttribute: PGPUserAttributeSubpacketVector
): PGPSignature =
buildAndInitSignatureGenerator().generateCertification(userAttribute, certificate.publicKey)
build(PGPainless.getInstance().toCertificate(certificate), userAttribute).signature
}

View file

@ -8,8 +8,13 @@ import java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPPublicKeyRing
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.api.OpenPGPCertificate
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentSignature
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.openpgp.api.OpenPGPSignature
import org.pgpainless.PGPainless
import org.pgpainless.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.signature.subpackets.CertificationSubpackets
@ -27,13 +32,13 @@ class ThirdPartyDirectKeySignatureBuilder :
@Throws(PGPException::class)
constructor(
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector
) : super(SignatureType.DIRECT_KEY, signingKey, protector)
@Throws(PGPException::class)
constructor(
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector,
archetypeSignature: PGPSignature
) : super(signingKey, protector, archetypeSignature)
@ -48,9 +53,20 @@ class ThirdPartyDirectKeySignatureBuilder :
}
}
@Throws(PGPException::class)
fun build(certificate: PGPPublicKeyRing): PGPSignature = build(certificate.publicKey)
fun build(certificate: OpenPGPCertificate): OpenPGPSignature = build(certificate.primaryKey)
fun build(componentKey: OpenPGPComponentKey): OpenPGPSignature =
OpenPGPComponentSignature(
buildAndInitSignatureGenerator().generateCertification(componentKey.pgpPublicKey),
signingKey.publicKey,
componentKey)
@Throws(PGPException::class)
@Deprecated("Pass in an OpenPGPCertificate instead.")
fun build(certificate: PGPPublicKeyRing): PGPSignature =
build(PGPainless.getInstance().toCertificate(certificate)).signature
@Deprecated("Pass in an OpenPGPComponentKey instead.")
@Throws(PGPException::class)
fun build(certifiedKey: PGPPublicKey): PGPSignature =
buildAndInitSignatureGenerator().generateCertification(certifiedKey)

View file

@ -6,9 +6,9 @@ package org.pgpainless.signature.builder
import java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.PGPSignatureGenerator
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.pgpainless.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.signature.subpackets.SignatureSubpackets
@ -26,13 +26,13 @@ class UniversalSignatureBuilder : AbstractSignatureBuilder<UniversalSignatureBui
@Throws(PGPException::class)
constructor(
signatureType: SignatureType,
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector
) : super(signatureType, signingKey, protector)
@Throws(PGPException::class)
constructor(
signingKey: PGPSecretKey,
signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector,
archetypeSignature: PGPSignature
) : super(signingKey, protector, archetypeSignature)