1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-09-10 02:39:39 +02:00

Port SignatureBuilders over to new classes

This commit is contained in:
Paul Schaub 2025-02-19 12:43:38 +01:00
parent 975548fc76
commit 88df92fd1f
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
18 changed files with 397 additions and 245 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -6,11 +6,11 @@ package org.pgpainless.signature.builder
import java.util.function.Predicate import java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPrivateKey
import org.bouncycastle.openpgp.PGPPublicKey import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.PGPSignatureGenerator 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.PGPainless
import org.pgpainless.algorithm.HashAlgorithm import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.algorithm.SignatureType import org.pgpainless.algorithm.SignatureType
@ -23,8 +23,7 @@ import org.pgpainless.signature.subpackets.SignatureSubpackets
import org.pgpainless.signature.subpackets.SignatureSubpacketsHelper import org.pgpainless.signature.subpackets.SignatureSubpacketsHelper
abstract class AbstractSignatureBuilder<B : AbstractSignatureBuilder<B>>( abstract class AbstractSignatureBuilder<B : AbstractSignatureBuilder<B>>(
protected val privateSigningKey: PGPPrivateKey, protected val signingKey: OpenPGPKey.OpenPGPPrivateKey,
protected val publicSigningKey: PGPPublicKey,
protected var _hashAlgorithm: HashAlgorithm, protected var _hashAlgorithm: HashAlgorithm,
protected var _signatureType: SignatureType, protected var _signatureType: SignatureType,
protected val _hashedSubpackets: SignatureSubpackets, protected val _hashedSubpackets: SignatureSubpackets,
@ -42,14 +41,13 @@ abstract class AbstractSignatureBuilder<B : AbstractSignatureBuilder<B>>(
@Throws(PGPException::class) @Throws(PGPException::class)
protected constructor( protected constructor(
signatureType: SignatureType, signatureType: SignatureType,
signingKey: PGPSecretKey, signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector, protector: SecretKeyRingProtector,
hashAlgorithm: HashAlgorithm, hashAlgorithm: HashAlgorithm,
hashedSubpackets: SignatureSubpackets, hashedSubpackets: SignatureSubpackets,
unhashedSubpackets: SignatureSubpackets unhashedSubpackets: SignatureSubpackets
) : this( ) : this(
UnlockSecretKey.unlockSecretKey(signingKey, protector), UnlockSecretKey.unlockSecretKey(signingKey, protector),
signingKey.publicKey,
hashAlgorithm, hashAlgorithm,
signatureType, signatureType,
hashedSubpackets, hashedSubpackets,
@ -58,27 +56,28 @@ abstract class AbstractSignatureBuilder<B : AbstractSignatureBuilder<B>>(
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signatureType: SignatureType, signatureType: SignatureType,
signingKey: PGPSecretKey, signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector protector: SecretKeyRingProtector
) : this( ) : this(
signatureType, signatureType,
signingKey, signingKey,
protector, protector,
negotiateHashAlgorithm(signingKey.publicKey), negotiateHashAlgorithm(signingKey),
SignatureSubpackets.createHashedSubpackets(signingKey.publicKey), SignatureSubpackets.createHashedSubpackets(signingKey.pgpSecretKey.publicKey),
SignatureSubpackets.createEmptySubpackets()) SignatureSubpackets.createEmptySubpackets())
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signingKey: PGPSecretKey, signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector, protector: SecretKeyRingProtector,
archetypeSignature: PGPSignature archetypeSignature: PGPSignature
) : this( ) : this(
SignatureType.requireFromCode(archetypeSignature.signatureType), SignatureType.requireFromCode(archetypeSignature.signatureType),
signingKey, signingKey,
protector, protector,
negotiateHashAlgorithm(signingKey.publicKey), negotiateHashAlgorithm(signingKey),
SignatureSubpackets.refreshHashedSubpackets(signingKey.publicKey, archetypeSignature), SignatureSubpackets.refreshHashedSubpackets(
signingKey.publicKey.pgpPublicKey, archetypeSignature),
SignatureSubpackets.refreshUnhashedSubpackets(archetypeSignature)) SignatureSubpackets.refreshUnhashedSubpackets(archetypeSignature))
val hashAlgorithm = _hashAlgorithm val hashAlgorithm = _hashAlgorithm
@ -113,11 +112,11 @@ abstract class AbstractSignatureBuilder<B : AbstractSignatureBuilder<B>>(
PGPSignatureGenerator( PGPSignatureGenerator(
ImplementationFactory.getInstance() ImplementationFactory.getInstance()
.getPGPContentSignerBuilder( .getPGPContentSignerBuilder(
publicSigningKey.algorithm, hashAlgorithm.algorithmId)) signingKey.publicKey.pgpPublicKey.algorithm, hashAlgorithm.algorithmId))
.apply { .apply {
setUnhashedSubpackets(SignatureSubpacketsHelper.toVector(_unhashedSubpackets)) setUnhashedSubpackets(SignatureSubpacketsHelper.toVector(_unhashedSubpackets))
setHashedSubpackets(SignatureSubpacketsHelper.toVector(_hashedSubpackets)) setHashedSubpackets(SignatureSubpacketsHelper.toVector(_hashedSubpackets))
init(_signatureType.code, privateSigningKey) init(_signatureType.code, signingKey.keyPair.privateKey)
} }
companion object { companion object {
@ -133,5 +132,9 @@ abstract class AbstractSignatureBuilder<B : AbstractSignatureBuilder<B>>(
HashAlgorithmNegotiator.negotiateSignatureHashAlgorithm(PGPainless.getPolicy()) HashAlgorithmNegotiator.negotiateSignatureHashAlgorithm(PGPainless.getPolicy())
.negotiateHashAlgorithm( .negotiateHashAlgorithm(
OpenPgpKeyAttributeUtil.getOrGuessPreferredHashAlgorithms(publicKey)) 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 java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPSecretKey import org.bouncycastle.openpgp.PGPSecretKeyRing
import org.bouncycastle.openpgp.PGPSignature 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.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets import org.pgpainless.signature.subpackets.SelfSignatureSubpackets
@ -23,14 +27,24 @@ class DirectKeySelfSignatureBuilder : AbstractSignatureBuilder<DirectKeySelfSign
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( 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, protector: SecretKeyRingProtector,
archetypeSignature: PGPSignature archetypeSignature: PGPSignature
) : super(signingKey, protector, archetypeSignature) ) : super(signingKey, protector, archetypeSignature)
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signingKey: PGPSecretKey, signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector protector: SecretKeyRingProtector
) : super(SignatureType.DIRECT_KEY, signingKey, protector) ) : super(SignatureType.DIRECT_KEY, signingKey, protector)
@ -45,6 +59,8 @@ class DirectKeySelfSignatureBuilder : AbstractSignatureBuilder<DirectKeySelfSign
} }
@Throws(PGPException::class) @Throws(PGPException::class)
fun build(): PGPSignature = fun build(): OpenPGPSignature =
buildAndInitSignatureGenerator().let { it.generateCertification(publicSigningKey) } 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 java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKey import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.pgpainless.algorithm.HashAlgorithm import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.algorithm.SignatureType import org.pgpainless.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.key.protection.SecretKeyRingProtector
@ -28,13 +28,13 @@ class PrimaryKeyBindingSignatureBuilder :
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signingSubkey: PGPSecretKey, signingSubkey: OpenPGPKey.OpenPGPSecretKey,
subkeyProtector: SecretKeyRingProtector subkeyProtector: SecretKeyRingProtector
) : super(SignatureType.PRIMARYKEY_BINDING, signingSubkey, subkeyProtector) ) : super(SignatureType.PRIMARYKEY_BINDING, signingSubkey, subkeyProtector)
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signingSubkey: PGPSecretKey, signingSubkey: OpenPGPKey.OpenPGPSecretKey,
subkeyProtector: SecretKeyRingProtector, subkeyProtector: SecretKeyRingProtector,
hashAlgorithm: HashAlgorithm hashAlgorithm: HashAlgorithm
) : super( ) : super(
@ -42,7 +42,7 @@ class PrimaryKeyBindingSignatureBuilder :
signingSubkey, signingSubkey,
subkeyProtector, subkeyProtector,
hashAlgorithm, hashAlgorithm,
SignatureSubpackets.createHashedSubpackets(signingSubkey.publicKey), SignatureSubpackets.createHashedSubpackets(signingSubkey.publicKey.pgpPublicKey),
SignatureSubpackets.createEmptySubpackets()) SignatureSubpackets.createEmptySubpackets())
val hashedSubpackets: SelfSignatureSubpackets = _hashedSubpackets val hashedSubpackets: SelfSignatureSubpackets = _hashedSubpackets
@ -57,5 +57,6 @@ class PrimaryKeyBindingSignatureBuilder :
@Throws(PGPException::class) @Throws(PGPException::class)
fun build(primaryKey: PGPPublicKey): PGPSignature = 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 java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKey import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.pgpainless.algorithm.SignatureType import org.pgpainless.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.signature.subpackets.RevocationSignatureSubpackets import org.pgpainless.signature.subpackets.RevocationSignatureSubpackets
/** [AbstractSignatureBuilder] subclass devoted to revocation signatures. */ /** [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> override val signatureTypePredicate: Predicate<SignatureType>
get() = get() =
@ -26,15 +32,6 @@ class RevocationSignatureBuilder : AbstractSignatureBuilder<RevocationSignatureB
SignatureType.CERTIFICATION_REVOCATION) 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 hashedSubpackets: RevocationSignatureSubpackets = _hashedSubpackets
val unhashedSubpackets: RevocationSignatureSubpackets = _unhashedSubpackets val unhashedSubpackets: RevocationSignatureSubpackets = _unhashedSubpackets
@ -54,7 +51,7 @@ class RevocationSignatureBuilder : AbstractSignatureBuilder<RevocationSignatureB
} }
it.generateCertification(revokeeKey) it.generateCertification(revokeeKey)
} else { } else {
it.generateCertification(publicSigningKey, revokeeKey) it.generateCertification(signingKey.publicKey.pgpPublicKey, revokeeKey)
} }
} }
@ -66,5 +63,9 @@ class RevocationSignatureBuilder : AbstractSignatureBuilder<RevocationSignatureB
"Signature type is != CERTIFICATION_REVOCATION." "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 java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.pgpainless.algorithm.SignatureType import org.pgpainless.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets import org.pgpainless.signature.subpackets.SelfSignatureSubpackets
@ -31,20 +31,20 @@ class SelfSignatureBuilder : AbstractSignatureBuilder<SelfSignatureBuilder> {
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signingKey: PGPSecretKey, signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector protector: SecretKeyRingProtector
) : super(SignatureType.GENERIC_CERTIFICATION, signingKey, protector) ) : super(SignatureType.GENERIC_CERTIFICATION, signingKey, protector)
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signatureType: SignatureType, signatureType: SignatureType,
signingKey: PGPSecretKey, signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector protector: SecretKeyRingProtector
) : super(signatureType, signingKey, protector) ) : super(signatureType, signingKey, protector)
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
primaryKey: PGPSecretKey, primaryKey: OpenPGPKey.OpenPGPSecretKey,
primaryKeyProtector: SecretKeyRingProtector, primaryKeyProtector: SecretKeyRingProtector,
oldCertification: PGPSignature oldCertification: PGPSignature
) : super(primaryKey, primaryKeyProtector, oldCertification) ) : super(primaryKey, primaryKeyProtector, oldCertification)
@ -61,9 +61,11 @@ class SelfSignatureBuilder : AbstractSignatureBuilder<SelfSignatureBuilder> {
@Throws(PGPException::class) @Throws(PGPException::class)
fun build(userId: CharSequence): PGPSignature = fun build(userId: CharSequence): PGPSignature =
buildAndInitSignatureGenerator().generateCertification(userId.toString(), publicSigningKey) buildAndInitSignatureGenerator()
.generateCertification(userId.toString(), signingKey.publicKey.pgpPublicKey)
@Throws(PGPException::class) @Throws(PGPException::class)
fun build(userAttributes: PGPUserAttributeSubpacketVector): PGPSignature = 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 java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKey import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.pgpainless.algorithm.HashAlgorithm import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.algorithm.SignatureType import org.pgpainless.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.key.protection.SecretKeyRingProtector
@ -26,13 +26,13 @@ class SubkeyBindingSignatureBuilder : AbstractSignatureBuilder<SubkeyBindingSign
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signingKey: PGPSecretKey, signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector protector: SecretKeyRingProtector
) : super(SignatureType.SUBKEY_BINDING, signingKey, protector) ) : super(SignatureType.SUBKEY_BINDING, signingKey, protector)
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signingKey: PGPSecretKey, signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector, protector: SecretKeyRingProtector,
hashAlgorithm: HashAlgorithm hashAlgorithm: HashAlgorithm
) : super( ) : super(
@ -40,12 +40,12 @@ class SubkeyBindingSignatureBuilder : AbstractSignatureBuilder<SubkeyBindingSign
signingKey, signingKey,
protector, protector,
hashAlgorithm, hashAlgorithm,
SignatureSubpackets.createHashedSubpackets(signingKey.publicKey), SignatureSubpackets.createHashedSubpackets(signingKey.publicKey.pgpPublicKey),
SignatureSubpackets.createEmptySubpackets()) SignatureSubpackets.createEmptySubpackets())
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signingKey: PGPSecretKey, signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector, protector: SecretKeyRingProtector,
oldSubkeyBinding: PGPSignature oldSubkeyBinding: PGPSignature
) : super( ) : super(
@ -69,5 +69,6 @@ class SubkeyBindingSignatureBuilder : AbstractSignatureBuilder<SubkeyBindingSign
@Throws(PGPException::class) @Throws(PGPException::class)
fun build(subkey: PGPPublicKey): PGPSignature = 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 java.util.function.Predicate
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKeyRing import org.bouncycastle.openpgp.PGPPublicKeyRing
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector 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.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.signature.subpackets.CertificationSubpackets import org.pgpainless.signature.subpackets.CertificationSubpackets
@ -42,7 +46,7 @@ class ThirdPartyCertificationSignatureBuilder :
*/ */
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signingKey: PGPSecretKey, signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector protector: SecretKeyRingProtector
) : super(SignatureType.GENERIC_CERTIFICATION, signingKey, protector) ) : super(SignatureType.GENERIC_CERTIFICATION, signingKey, protector)
@ -57,7 +61,7 @@ class ThirdPartyCertificationSignatureBuilder :
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signatureType: SignatureType, signatureType: SignatureType,
signingKey: PGPSecretKey, signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector protector: SecretKeyRingProtector
) : super(signatureType, signingKey, protector) ) : super(signatureType, signingKey, protector)
@ -71,7 +75,7 @@ class ThirdPartyCertificationSignatureBuilder :
*/ */
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signingKey: PGPSecretKey, signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector, protector: SecretKeyRingProtector,
archetypeSignature: PGPSignature archetypeSignature: PGPSignature
) : super(signingKey, protector, archetypeSignature) ) : 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. * 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 if the signature generator cannot be initialized
*/ */
@Throws(PGPException::class) @Throws(PGPException::class)
@Deprecated("Pass in an OpenPGPCertificate instead of a PGPPublicKeyRing.")
fun build(certificate: PGPPublicKeyRing, userId: CharSequence): PGPSignature = fun build(certificate: PGPPublicKeyRing, userId: CharSequence): PGPSignature =
build(PGPainless.getInstance().toCertificate(certificate), userId).signature
fun build(
certificate: OpenPGPCertificate,
userAttribute: PGPUserAttributeSubpacketVector
): OpenPGPSignature =
OpenPGPComponentSignature(
buildAndInitSignatureGenerator() buildAndInitSignatureGenerator()
.generateCertification(userId.toString(), certificate.publicKey) .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 * 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 if the signature generator cannot be initialized
*/ */
@Throws(PGPException::class) @Throws(PGPException::class)
@Deprecated("Pass in an OpenPGPCertificate instead of a PGPPublicKeyRing.")
fun build( fun build(
certificate: PGPPublicKeyRing, certificate: PGPPublicKeyRing,
userAttribute: PGPUserAttributeSubpacketVector userAttribute: PGPUserAttributeSubpacketVector
): PGPSignature = ): 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.PGPException
import org.bouncycastle.openpgp.PGPPublicKey import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPPublicKeyRing import org.bouncycastle.openpgp.PGPPublicKeyRing
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSignature 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.algorithm.SignatureType
import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.signature.subpackets.CertificationSubpackets import org.pgpainless.signature.subpackets.CertificationSubpackets
@ -27,13 +32,13 @@ class ThirdPartyDirectKeySignatureBuilder :
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signingKey: PGPSecretKey, signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector protector: SecretKeyRingProtector
) : super(SignatureType.DIRECT_KEY, signingKey, protector) ) : super(SignatureType.DIRECT_KEY, signingKey, protector)
@Throws(PGPException::class) @Throws(PGPException::class)
constructor( constructor(
signingKey: PGPSecretKey, signingKey: OpenPGPKey.OpenPGPSecretKey,
protector: SecretKeyRingProtector, protector: SecretKeyRingProtector,
archetypeSignature: PGPSignature archetypeSignature: PGPSignature
) : super(signingKey, protector, archetypeSignature) ) : super(signingKey, protector, archetypeSignature)
@ -48,9 +53,20 @@ class ThirdPartyDirectKeySignatureBuilder :
} }
} }
@Throws(PGPException::class) fun build(certificate: OpenPGPCertificate): OpenPGPSignature = build(certificate.primaryKey)
fun build(certificate: PGPPublicKeyRing): PGPSignature = build(certificate.publicKey)
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) @Throws(PGPException::class)
fun build(certifiedKey: PGPPublicKey): PGPSignature = fun build(certifiedKey: PGPPublicKey): PGPSignature =
buildAndInitSignatureGenerator().generateCertification(certifiedKey) buildAndInitSignatureGenerator().generateCertification(certifiedKey)

View file

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

View file

@ -15,9 +15,10 @@ import java.util.List;
import org.bouncycastle.bcpg.sig.TrustSignature; import org.bouncycastle.bcpg.sig.TrustSignature;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; 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.bouncycastle.util.Arrays; import org.bouncycastle.util.Arrays;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
@ -36,13 +37,11 @@ public class CertifyCertificateTest {
@Test @Test
public void testUserIdCertification() throws PGPException, IOException { public void testUserIdCertification() throws PGPException, IOException {
SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys(); SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
PGPSecretKeyRing alice = PGPainless.generateKeyRing().modernKeyRing("Alice <alice@pgpainless.org>") OpenPGPKey alice = PGPainless.generateKeyRing().modernKeyRing("Alice <alice@pgpainless.org>");
.getPGPSecretKeyRing();
String bobUserId = "Bob <bob@pgpainless.org>"; String bobUserId = "Bob <bob@pgpainless.org>";
PGPSecretKeyRing bob = PGPainless.generateKeyRing().modernKeyRing(bobUserId) OpenPGPKey bob = PGPainless.generateKeyRing().modernKeyRing(bobUserId);
.getPGPSecretKeyRing();
PGPPublicKeyRing bobCertificate = PGPainless.extractCertificate(bob); OpenPGPCertificate bobCertificate = bob.toCertificate();
CertifyCertificate.CertificationResult result = PGPainless.certify() CertifyCertificate.CertificationResult result = PGPainless.certify()
.userIdOnCertificate(bobUserId, bobCertificate) .userIdOnCertificate(bobUserId, bobCertificate)
@ -50,35 +49,33 @@ public class CertifyCertificateTest {
.build(); .build();
assertNotNull(result); assertNotNull(result);
PGPSignature signature = result.getCertification(); PGPSignature signature = result.getPgpSignature();
assertNotNull(signature); assertNotNull(signature);
assertEquals(SignatureType.GENERIC_CERTIFICATION, SignatureType.valueOf(signature.getSignatureType())); assertEquals(SignatureType.GENERIC_CERTIFICATION, SignatureType.valueOf(signature.getSignatureType()));
assertEquals(alice.getPublicKey().getKeyID(), signature.getKeyID()); assertEquals(alice.getPrimaryKey().getPGPPublicKey().getKeyID(), signature.getKeyID());
assertTrue(SignatureVerifier.verifyUserIdCertification( assertTrue(SignatureVerifier.verifyUserIdCertification(
bobUserId, signature, alice.getPublicKey(), bob.getPublicKey(), PGPainless.getPolicy(), DateUtil.now())); bobUserId, signature, alice.getPrimaryKey().getPGPPublicKey(), bob.getPrimaryKey().getPGPPublicKey(), PGPainless.getPolicy(), DateUtil.now()));
PGPPublicKeyRing bobCertified = result.getCertifiedCertificate(); OpenPGPCertificate bobCertified = result.getCertifiedCertificate();
PGPPublicKey bobCertifiedKey = bobCertified.getPublicKey(); PGPPublicKey bobCertifiedKey = bobCertified.getPrimaryKey().getPGPPublicKey();
// There are 2 sigs now, bobs own and alice' // There are 2 sigs now, bobs own and alice'
assertEquals(2, CollectionUtils.iteratorToList(bobCertifiedKey.getSignaturesForID(bobUserId)).size()); assertEquals(2, CollectionUtils.iteratorToList(bobCertifiedKey.getSignaturesForID(bobUserId)).size());
List<PGPSignature> sigsByAlice = CollectionUtils.iteratorToList( List<PGPSignature> sigsByAlice = CollectionUtils.iteratorToList(
bobCertifiedKey.getSignaturesForKeyID(alice.getPublicKey().getKeyID())); bobCertifiedKey.getSignaturesForKeyID(alice.getPrimaryKey().getPGPPublicKey().getKeyID()));
assertEquals(1, sigsByAlice.size()); assertEquals(1, sigsByAlice.size());
assertEquals(signature, sigsByAlice.get(0)); assertEquals(signature, sigsByAlice.get(0));
assertFalse(Arrays.areEqual(bobCertificate.getEncoded(), bobCertified.getEncoded())); assertFalse(Arrays.areEqual(bobCertificate.getPGPPublicKeyRing().getEncoded(), bobCertified.getPGPPublicKeyRing().getEncoded()));
} }
@Test @Test
public void testKeyDelegation() throws PGPException, IOException { public void testKeyDelegation() throws PGPException, IOException {
SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys(); SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
PGPSecretKeyRing alice = PGPainless.generateKeyRing().modernKeyRing("Alice <alice@pgpainless.org>") OpenPGPKey alice = PGPainless.generateKeyRing().modernKeyRing("Alice <alice@pgpainless.org>");
.getPGPSecretKeyRing(); OpenPGPKey bob = PGPainless.generateKeyRing().modernKeyRing("Bob <bob@pgpainless.org>");
PGPSecretKeyRing bob = PGPainless.generateKeyRing().modernKeyRing("Bob <bob@pgpainless.org>")
.getPGPSecretKeyRing();
PGPPublicKeyRing bobCertificate = PGPainless.extractCertificate(bob); OpenPGPCertificate bobCertificate = bob.toCertificate();
CertifyCertificate.CertificationResult result = PGPainless.certify() CertifyCertificate.CertificationResult result = PGPainless.certify()
.certificate(bobCertificate, Trustworthiness.fullyTrusted().introducer()) .certificate(bobCertificate, Trustworthiness.fullyTrusted().introducer())
@ -86,11 +83,12 @@ public class CertifyCertificateTest {
.build(); .build();
assertNotNull(result); assertNotNull(result);
PGPSignature signature = result.getCertification(); OpenPGPSignature signature = result.getCertification();
PGPSignature pgpSignature = signature.getSignature();
assertNotNull(signature); assertNotNull(signature);
assertEquals(SignatureType.DIRECT_KEY, SignatureType.valueOf(signature.getSignatureType())); assertEquals(SignatureType.DIRECT_KEY, SignatureType.valueOf(pgpSignature.getSignatureType()));
assertEquals(alice.getPublicKey().getKeyID(), signature.getKeyID()); assertEquals(alice.getPrimaryKey().getPGPPublicKey().getKeyID(), pgpSignature.getKeyID());
TrustSignature trustSignaturePacket = signature.getHashedSubPackets().getTrust(); TrustSignature trustSignaturePacket = pgpSignature.getHashedSubPackets().getTrust();
assertNotNull(trustSignaturePacket); assertNotNull(trustSignaturePacket);
Trustworthiness trustworthiness = new Trustworthiness(trustSignaturePacket.getTrustAmount(), trustSignaturePacket.getDepth()); Trustworthiness trustworthiness = new Trustworthiness(trustSignaturePacket.getTrustAmount(), trustSignaturePacket.getDepth());
assertTrue(trustworthiness.isFullyTrusted()); assertTrue(trustworthiness.isFullyTrusted());
@ -98,29 +96,27 @@ public class CertifyCertificateTest {
assertFalse(trustworthiness.canIntroduce(1)); assertFalse(trustworthiness.canIntroduce(1));
assertTrue(SignatureVerifier.verifyDirectKeySignature( assertTrue(SignatureVerifier.verifyDirectKeySignature(
signature, alice.getPublicKey(), bob.getPublicKey(), PGPainless.getPolicy(), DateUtil.now())); pgpSignature, alice.getPrimaryKey().getPGPPublicKey(), bob.getPrimaryKey().getPGPPublicKey(), PGPainless.getPolicy(), DateUtil.now()));
PGPPublicKeyRing bobCertified = result.getCertifiedCertificate(); OpenPGPCertificate bobCertified = result.getCertifiedCertificate();
PGPPublicKey bobCertifiedKey = bobCertified.getPublicKey(); PGPPublicKey bobCertifiedKey = bobCertified.getPrimaryKey().getPGPPublicKey();
List<PGPSignature> sigsByAlice = CollectionUtils.iteratorToList( List<PGPSignature> sigsByAlice = CollectionUtils.iteratorToList(
bobCertifiedKey.getSignaturesForKeyID(alice.getPublicKey().getKeyID())); bobCertifiedKey.getSignaturesForKeyID(alice.getPrimaryKey().getPGPPublicKey().getKeyID()));
assertEquals(1, sigsByAlice.size()); assertEquals(1, sigsByAlice.size());
assertEquals(signature, sigsByAlice.get(0)); assertEquals(signature.getSignature(), sigsByAlice.get(0));
assertFalse(Arrays.areEqual(bobCertificate.getEncoded(), bobCertified.getEncoded())); assertFalse(Arrays.areEqual(bobCertificate.getPGPPublicKeyRing().getEncoded(), bobCertified.getPGPPublicKeyRing().getEncoded()));
} }
@Test @Test
public void testPetNameCertification() { public void testPetNameCertification() {
PGPSecretKeyRing aliceKey = PGPainless.generateKeyRing() OpenPGPKey aliceKey = PGPainless.generateKeyRing()
.modernKeyRing("Alice <alice@pgpainless.org>") .modernKeyRing("Alice <alice@pgpainless.org>");
.getPGPSecretKeyRing(); OpenPGPKey bobKey = PGPainless.generateKeyRing()
PGPSecretKeyRing bobKey = PGPainless.generateKeyRing() .modernKeyRing("Bob <bob@pgpainless.org>");
.modernKeyRing("Bob <bob@pgpainless.org>")
.getPGPSecretKeyRing();
PGPPublicKeyRing bobCert = PGPainless.extractCertificate(bobKey); OpenPGPCertificate bobCert = bobKey.toCertificate();
String petName = "Bobby"; String petName = "Bobby";
CertifyCertificate.CertificationResult result = PGPainless.certify() CertifyCertificate.CertificationResult result = PGPainless.certify()
@ -133,11 +129,12 @@ public class CertifyCertificateTest {
} }
}); });
PGPSignature certification = result.getCertification(); OpenPGPSignature certification = result.getCertification();
assertEquals(aliceKey.getPublicKey().getKeyID(), certification.getKeyID()); PGPSignature signature = certification.getSignature();
assertEquals(CertificationType.GENERIC.asSignatureType().getCode(), certification.getSignatureType()); assertEquals(aliceKey.getPrimaryKey().getPGPPublicKey().getKeyID(), signature.getKeyID());
assertEquals(CertificationType.GENERIC.asSignatureType().getCode(), signature.getSignatureType());
PGPPublicKeyRing certWithPetName = result.getCertifiedCertificate(); OpenPGPCertificate certWithPetName = result.getCertifiedCertificate();
KeyRingInfo info = PGPainless.inspectKeyRing(certWithPetName); KeyRingInfo info = PGPainless.inspectKeyRing(certWithPetName);
assertTrue(info.getUserIds().contains(petName)); assertTrue(info.getUserIds().contains(petName));
assertFalse(info.getValidUserIds().contains(petName)); assertFalse(info.getValidUserIds().contains(petName));
@ -145,13 +142,11 @@ public class CertifyCertificateTest {
@Test @Test
public void testScopedDelegation() { public void testScopedDelegation() {
PGPSecretKeyRing aliceKey = PGPainless.generateKeyRing() OpenPGPKey aliceKey = PGPainless.generateKeyRing()
.modernKeyRing("Alice <alice@pgpainless.org>") .modernKeyRing("Alice <alice@pgpainless.org>");
.getPGPSecretKeyRing(); OpenPGPKey caKey = PGPainless.generateKeyRing()
PGPSecretKeyRing caKey = PGPainless.generateKeyRing() .modernKeyRing("CA <ca@example.com>");
.modernKeyRing("CA <ca@example.com>") OpenPGPCertificate caCert = caKey.toCertificate();
.getPGPSecretKeyRing();
PGPPublicKeyRing caCert = PGPainless.extractCertificate(caKey);
CertifyCertificate.CertificationResult result = PGPainless.certify() CertifyCertificate.CertificationResult result = PGPainless.certify()
.certificate(caCert, Trustworthiness.fullyTrusted().introducer()) .certificate(caCert, Trustworthiness.fullyTrusted().introducer())
@ -163,9 +158,10 @@ public class CertifyCertificateTest {
} }
}); });
PGPSignature certification = result.getCertification(); OpenPGPSignature certification = result.getCertification();
assertEquals(SignatureType.DIRECT_KEY.getCode(), certification.getSignatureType()); PGPSignature signature = certification.getSignature();
assertEquals(SignatureType.DIRECT_KEY.getCode(), signature.getSignatureType());
assertEquals("^.*<.+@example.com>.*$", assertEquals("^.*<.+@example.com>.*$",
certification.getHashedSubPackets().getRegularExpression().getRegex()); signature.getHashedSubPackets().getRegularExpression().getRegex());
} }
} }

View file

@ -14,10 +14,10 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
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.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.EncryptionPurpose; import org.pgpainless.algorithm.EncryptionPurpose;
@ -33,10 +33,10 @@ public class SubkeyAndPrimaryKeyBindingSignatureTest {
@Test @Test
public void testRebindSubkey() throws PGPException, IOException { public void testRebindSubkey() throws PGPException, IOException {
PGPSecretKeyRing secretKeys = TestKeys.getEmilSecretKeyRing(); OpenPGPKey secretKeys = PGPainless.getInstance().toKey(TestKeys.getEmilSecretKeyRing());
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys); KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
PGPSecretKey primaryKey = secretKeys.getSecretKey(); OpenPGPKey.OpenPGPSecretKey primaryKey = secretKeys.getPrimarySecretKey();
OpenPGPCertificate.OpenPGPComponentKey encryptionSubkey = OpenPGPCertificate.OpenPGPComponentKey encryptionSubkey =
info.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0); info.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0);
assertNotNull(encryptionSubkey); assertNotNull(encryptionSubkey);
@ -57,9 +57,9 @@ public class SubkeyAndPrimaryKeyBindingSignatureTest {
}); });
PGPSignature binding = sbb.build(encryptionSubkey.getPGPPublicKey()); PGPSignature binding = sbb.build(encryptionSubkey.getPGPPublicKey());
secretKeys = KeyRingUtils.injectCertification(secretKeys, encryptionSubkey.getPGPPublicKey(), binding); PGPSecretKeyRing secretKeyRing = KeyRingUtils.injectCertification(secretKeys.getPGPKeyRing(), encryptionSubkey.getPGPPublicKey(), binding);
info = PGPainless.inspectKeyRing(secretKeys); info = PGPainless.inspectKeyRing(secretKeyRing);
assertEquals(Collections.singleton(HashAlgorithm.SHA512), info.getPreferredHashAlgorithms(encryptionSubkey.getKeyIdentifier())); assertEquals(Collections.singleton(HashAlgorithm.SHA512), info.getPreferredHashAlgorithms(encryptionSubkey.getKeyIdentifier()));
} }
} }

View file

@ -4,11 +4,13 @@
package org.pgpainless.signature.builder; package org.pgpainless.signature.builder;
import org.bouncycastle.bcpg.KeyIdentifier;
import org.bouncycastle.bcpg.sig.Exportable; import org.bouncycastle.bcpg.sig.Exportable;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; 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.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
@ -28,28 +30,25 @@ public class ThirdPartyCertificationSignatureBuilderTest {
@Test @Test
public void testInvalidSignatureTypeThrows() { public void testInvalidSignatureTypeThrows() {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() OpenPGPKey secretKeys = PGPainless.generateKeyRing()
.modernKeyRing("Alice") .modernKeyRing("Alice");
.getPGPSecretKeyRing();
assertThrows(IllegalArgumentException.class, () -> assertThrows(IllegalArgumentException.class, () ->
new ThirdPartyCertificationSignatureBuilder( new ThirdPartyCertificationSignatureBuilder(
SignatureType.BINARY_DOCUMENT, // invalid type SignatureType.BINARY_DOCUMENT, // invalid type
secretKeys.getSecretKey(), secretKeys.getPrimarySecretKey(),
SecretKeyRingProtector.unprotectedKeys())); SecretKeyRingProtector.unprotectedKeys()));
} }
@Test @Test
public void testUserIdCertification() throws PGPException { public void testUserIdCertification() throws PGPException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() OpenPGPKey secretKeys = PGPainless.generateKeyRing()
.modernKeyRing("Alice") .modernKeyRing("Alice");
.getPGPSecretKeyRing();
PGPPublicKeyRing bobsPublicKeys = PGPainless.extractCertificate( OpenPGPCertificate bobsPublicKeys = PGPainless.generateKeyRing().modernKeyRing("Bob")
PGPainless.generateKeyRing().modernKeyRing("Bob") .toCertificate();
.getPGPSecretKeyRing());
ThirdPartyCertificationSignatureBuilder signatureBuilder = new ThirdPartyCertificationSignatureBuilder( ThirdPartyCertificationSignatureBuilder signatureBuilder = new ThirdPartyCertificationSignatureBuilder(
secretKeys.getSecretKey(), secretKeys.getPrimarySecretKey(),
SecretKeyRingProtector.unprotectedKeys()); SecretKeyRingProtector.unprotectedKeys());
signatureBuilder.applyCallback(new CertificationSubpackets.Callback() { signatureBuilder.applyCallback(new CertificationSubpackets.Callback() {
@ -59,16 +58,20 @@ public class ThirdPartyCertificationSignatureBuilderTest {
} }
}); });
PGPSignature certification = signatureBuilder.build(bobsPublicKeys, "Bob"); OpenPGPSignature certification = signatureBuilder.build(bobsPublicKeys, "Bob");
assertEquals(SignatureType.GENERIC_CERTIFICATION, SignatureType.valueOf(certification.getSignatureType())); PGPSignature signature = certification.getSignature();
assertEquals(secretKeys.getPublicKey().getKeyID(), certification.getKeyID()); assertEquals(SignatureType.GENERIC_CERTIFICATION, SignatureType.valueOf(signature.getSignatureType()));
assertArrayEquals(secretKeys.getPublicKey().getFingerprint(), certification.getHashedSubPackets().getIssuerFingerprint().getFingerprint()); assertTrue(KeyIdentifier.matches(signature.getKeyIdentifiers(), secretKeys.getKeyIdentifier(), true));
Exportable exportable = SignatureSubpacketsUtil.getExportableCertification(certification); assertArrayEquals(
secretKeys.getPrimaryKey().getPGPPublicKey().getFingerprint(),
signature.getHashedSubPackets().getIssuerFingerprint().getFingerprint());
Exportable exportable = SignatureSubpacketsUtil.getExportableCertification(signature);
assertNotNull(exportable); assertNotNull(exportable);
assertFalse(exportable.isExportable()); assertFalse(exportable.isExportable());
// test sig correctness // test sig correctness
certification.init(ImplementationFactory.getInstance().getPgpContentVerifierBuilderProvider(), secretKeys.getPublicKey()); signature.init(ImplementationFactory.getInstance().getPgpContentVerifierBuilderProvider(),
assertTrue(certification.verifyCertification("Bob", bobsPublicKeys.getPublicKey())); secretKeys.getPrimaryKey().getPGPPublicKey());
assertTrue(signature.verifyCertification("Bob", bobsPublicKeys.getPrimaryKey().getPGPPublicKey()));
} }
} }

View file

@ -14,6 +14,8 @@ import java.util.Date;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.bouncycastle.openpgp.api.OpenPGPSignature;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.CompressionAlgorithm; import org.pgpainless.algorithm.CompressionAlgorithm;
@ -32,12 +34,11 @@ public class ThirdPartyDirectKeySignatureBuilderTest {
@Test @Test
public void testDirectKeySignatureBuilding() throws PGPException { public void testDirectKeySignatureBuilding() throws PGPException {
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing() OpenPGPKey secretKeys = PGPainless.generateKeyRing()
.modernKeyRing("Alice") .modernKeyRing("Alice");
.getPGPSecretKeyRing();
DirectKeySelfSignatureBuilder dsb = new DirectKeySelfSignatureBuilder( DirectKeySelfSignatureBuilder dsb = new DirectKeySelfSignatureBuilder(
secretKeys.getSecretKey(), secretKeys.getPrimarySecretKey(),
SecretKeyRingProtector.unprotectedKeys()); SecretKeyRingProtector.unprotectedKeys());
Date now = new Date(); Date now = new Date();
@ -54,11 +55,14 @@ public class ThirdPartyDirectKeySignatureBuilderTest {
} }
}); });
PGPSignature directKeySig = dsb.build(); OpenPGPSignature directKeySig = dsb.build();
assertNotNull(directKeySig); assertNotNull(directKeySig);
secretKeys = KeyRingUtils.injectCertification(secretKeys, secretKeys.getPublicKey(), directKeySig); PGPSecretKeyRing secretKeyRing = KeyRingUtils.injectCertification(
secretKeys.getPGPSecretKeyRing(),
secretKeys.getPrimaryKey().getPGPPublicKey(),
directKeySig.getSignature());
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys, t1); KeyRingInfo info = PGPainless.inspectKeyRing(secretKeyRing, t1);
PGPSignature signature = info.getLatestDirectKeySelfSignature(); PGPSignature signature = info.getLatestDirectKeySelfSignature();
assertNotNull(signature); assertNotNull(signature);
@ -69,7 +73,7 @@ public class ThirdPartyDirectKeySignatureBuilderTest {
assertEquals(Collections.singleton(HashAlgorithm.SHA512), SignatureSubpacketsUtil.parsePreferredHashAlgorithms(signature)); assertEquals(Collections.singleton(HashAlgorithm.SHA512), SignatureSubpacketsUtil.parsePreferredHashAlgorithms(signature));
assertEquals(Collections.singleton(CompressionAlgorithm.ZIP), SignatureSubpacketsUtil.parsePreferredCompressionAlgorithms(signature)); assertEquals(Collections.singleton(CompressionAlgorithm.ZIP), SignatureSubpacketsUtil.parsePreferredCompressionAlgorithms(signature));
assertEquals(Collections.singleton(SymmetricKeyAlgorithm.AES_256), SignatureSubpacketsUtil.parsePreferredSymmetricKeyAlgorithms(signature)); assertEquals(Collections.singleton(SymmetricKeyAlgorithm.AES_256), SignatureSubpacketsUtil.parsePreferredSymmetricKeyAlgorithms(signature));
assertEquals(secretKeys.getPublicKey().getKeyID(), signature.getKeyID()); assertEquals(secretKeyRing.getPublicKey().getKeyID(), signature.getKeyID());
assertArrayEquals(secretKeys.getPublicKey().getFingerprint(), signature.getHashedSubPackets().getIssuerFingerprint().getFingerprint()); assertArrayEquals(secretKeyRing.getPublicKey().getFingerprint(), signature.getHashedSubPackets().getIssuerFingerprint().getFingerprint());
} }
} }

View file

@ -6,15 +6,16 @@ package org.pgpainless.signature.builder;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException; import java.io.IOException;
import org.bouncycastle.bcpg.KeyIdentifier;
import org.bouncycastle.bcpg.sig.PrimaryUserID; import org.bouncycastle.bcpg.sig.PrimaryUserID;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
@ -51,18 +52,18 @@ public class UniversalSignatureBuilderTest {
"=Dqbd\n" + "=Dqbd\n" +
"-----END PGP PRIVATE KEY BLOCK-----"; "-----END PGP PRIVATE KEY BLOCK-----";
private PGPSecretKeyRing secretKeys; private OpenPGPKey secretKeys;
private final SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys(); private final SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
@BeforeEach @BeforeEach
public void parseKey() throws IOException { public void parseKey() throws IOException {
secretKeys = PGPainless.readKeyRing().secretKeyRing(KEY); secretKeys = PGPainless.getInstance().readKey().parseKey(KEY);
} }
@Test @Test
public void createPetNameSignature() throws PGPException { public void createPetNameSignature() throws PGPException {
PGPSecretKey signingKey = secretKeys.getSecretKey(); OpenPGPKey.OpenPGPSecretKey signingKey = secretKeys.getPrimarySecretKey();
PGPSignature archetype = signingKey.getPublicKey().getSignatures().next(); PGPSignature archetype = signingKey.getPublicKey().getPGPPublicKey().getSignatures().next();
UniversalSignatureBuilder builder = new UniversalSignatureBuilder( UniversalSignatureBuilder builder = new UniversalSignatureBuilder(
signingKey, protector, archetype); signingKey, protector, archetype);
@ -77,11 +78,11 @@ public class UniversalSignatureBuilderTest {
PGPSignatureGenerator generator = builder.getSignatureGenerator(); PGPSignatureGenerator generator = builder.getSignatureGenerator();
String petName = "mykey"; String petName = "mykey";
PGPSignature petNameSig = generator.generateCertification(petName, secretKeys.getPublicKey()); PGPSignature petNameSig = generator.generateCertification(petName, secretKeys.getPrimarySecretKey().getPublicKey().getPGPPublicKey());
assertEquals(SignatureType.POSITIVE_CERTIFICATION.getCode(), petNameSig.getSignatureType()); assertEquals(SignatureType.POSITIVE_CERTIFICATION.getCode(), petNameSig.getSignatureType());
assertEquals(4, petNameSig.getVersion()); assertEquals(4, petNameSig.getVersion());
assertEquals(signingKey.getKeyID(), petNameSig.getKeyID()); assertTrue(KeyIdentifier.matches(petNameSig.getKeyIdentifiers(), signingKey.getKeyIdentifier(), true));
assertEquals(HashAlgorithm.SHA512.getAlgorithmId(), petNameSig.getHashAlgorithm()); assertEquals(HashAlgorithm.SHA512.getAlgorithmId(), petNameSig.getHashAlgorithm());
assertEquals(KeyFlag.toBitmask(KeyFlag.CERTIFY_OTHER), petNameSig.getHashedSubPackets().getKeyFlags()); assertEquals(KeyFlag.toBitmask(KeyFlag.CERTIFY_OTHER), petNameSig.getHashedSubPackets().getKeyFlags());
assertFalse(petNameSig.getHashedSubPackets().isExportable()); assertFalse(petNameSig.getHashedSubPackets().isExportable());