mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-09-09 18:29:39 +02:00
Port SignatureBuilders over to new classes
This commit is contained in:
parent
975548fc76
commit
88df92fd1f
18 changed files with 397 additions and 245 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -54,7 +51,7 @@ class RevocationSignatureBuilder : AbstractSignatureBuilder<RevocationSignatureB
|
|||
}
|
||||
it.generateCertification(revokeeKey)
|
||||
} 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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -15,9 +15,10 @@ import java.util.List;
|
|||
import org.bouncycastle.bcpg.sig.TrustSignature;
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||
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.bouncycastle.util.Arrays;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.pgpainless.PGPainless;
|
||||
|
@ -36,13 +37,11 @@ public class CertifyCertificateTest {
|
|||
@Test
|
||||
public void testUserIdCertification() throws PGPException, IOException {
|
||||
SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
|
||||
PGPSecretKeyRing alice = PGPainless.generateKeyRing().modernKeyRing("Alice <alice@pgpainless.org>")
|
||||
.getPGPSecretKeyRing();
|
||||
OpenPGPKey alice = PGPainless.generateKeyRing().modernKeyRing("Alice <alice@pgpainless.org>");
|
||||
String bobUserId = "Bob <bob@pgpainless.org>";
|
||||
PGPSecretKeyRing bob = PGPainless.generateKeyRing().modernKeyRing(bobUserId)
|
||||
.getPGPSecretKeyRing();
|
||||
OpenPGPKey bob = PGPainless.generateKeyRing().modernKeyRing(bobUserId);
|
||||
|
||||
PGPPublicKeyRing bobCertificate = PGPainless.extractCertificate(bob);
|
||||
OpenPGPCertificate bobCertificate = bob.toCertificate();
|
||||
|
||||
CertifyCertificate.CertificationResult result = PGPainless.certify()
|
||||
.userIdOnCertificate(bobUserId, bobCertificate)
|
||||
|
@ -50,35 +49,33 @@ public class CertifyCertificateTest {
|
|||
.build();
|
||||
|
||||
assertNotNull(result);
|
||||
PGPSignature signature = result.getCertification();
|
||||
PGPSignature signature = result.getPgpSignature();
|
||||
assertNotNull(signature);
|
||||
assertEquals(SignatureType.GENERIC_CERTIFICATION, SignatureType.valueOf(signature.getSignatureType()));
|
||||
assertEquals(alice.getPublicKey().getKeyID(), signature.getKeyID());
|
||||
assertEquals(alice.getPrimaryKey().getPGPPublicKey().getKeyID(), signature.getKeyID());
|
||||
|
||||
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();
|
||||
PGPPublicKey bobCertifiedKey = bobCertified.getPublicKey();
|
||||
OpenPGPCertificate bobCertified = result.getCertifiedCertificate();
|
||||
PGPPublicKey bobCertifiedKey = bobCertified.getPrimaryKey().getPGPPublicKey();
|
||||
// There are 2 sigs now, bobs own and alice'
|
||||
assertEquals(2, CollectionUtils.iteratorToList(bobCertifiedKey.getSignaturesForID(bobUserId)).size());
|
||||
List<PGPSignature> sigsByAlice = CollectionUtils.iteratorToList(
|
||||
bobCertifiedKey.getSignaturesForKeyID(alice.getPublicKey().getKeyID()));
|
||||
bobCertifiedKey.getSignaturesForKeyID(alice.getPrimaryKey().getPGPPublicKey().getKeyID()));
|
||||
assertEquals(1, sigsByAlice.size());
|
||||
assertEquals(signature, sigsByAlice.get(0));
|
||||
|
||||
assertFalse(Arrays.areEqual(bobCertificate.getEncoded(), bobCertified.getEncoded()));
|
||||
assertFalse(Arrays.areEqual(bobCertificate.getPGPPublicKeyRing().getEncoded(), bobCertified.getPGPPublicKeyRing().getEncoded()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyDelegation() throws PGPException, IOException {
|
||||
SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
|
||||
PGPSecretKeyRing alice = PGPainless.generateKeyRing().modernKeyRing("Alice <alice@pgpainless.org>")
|
||||
.getPGPSecretKeyRing();
|
||||
PGPSecretKeyRing bob = PGPainless.generateKeyRing().modernKeyRing("Bob <bob@pgpainless.org>")
|
||||
.getPGPSecretKeyRing();
|
||||
OpenPGPKey alice = PGPainless.generateKeyRing().modernKeyRing("Alice <alice@pgpainless.org>");
|
||||
OpenPGPKey bob = PGPainless.generateKeyRing().modernKeyRing("Bob <bob@pgpainless.org>");
|
||||
|
||||
PGPPublicKeyRing bobCertificate = PGPainless.extractCertificate(bob);
|
||||
OpenPGPCertificate bobCertificate = bob.toCertificate();
|
||||
|
||||
CertifyCertificate.CertificationResult result = PGPainless.certify()
|
||||
.certificate(bobCertificate, Trustworthiness.fullyTrusted().introducer())
|
||||
|
@ -86,11 +83,12 @@ public class CertifyCertificateTest {
|
|||
.build();
|
||||
|
||||
assertNotNull(result);
|
||||
PGPSignature signature = result.getCertification();
|
||||
OpenPGPSignature signature = result.getCertification();
|
||||
PGPSignature pgpSignature = signature.getSignature();
|
||||
assertNotNull(signature);
|
||||
assertEquals(SignatureType.DIRECT_KEY, SignatureType.valueOf(signature.getSignatureType()));
|
||||
assertEquals(alice.getPublicKey().getKeyID(), signature.getKeyID());
|
||||
TrustSignature trustSignaturePacket = signature.getHashedSubPackets().getTrust();
|
||||
assertEquals(SignatureType.DIRECT_KEY, SignatureType.valueOf(pgpSignature.getSignatureType()));
|
||||
assertEquals(alice.getPrimaryKey().getPGPPublicKey().getKeyID(), pgpSignature.getKeyID());
|
||||
TrustSignature trustSignaturePacket = pgpSignature.getHashedSubPackets().getTrust();
|
||||
assertNotNull(trustSignaturePacket);
|
||||
Trustworthiness trustworthiness = new Trustworthiness(trustSignaturePacket.getTrustAmount(), trustSignaturePacket.getDepth());
|
||||
assertTrue(trustworthiness.isFullyTrusted());
|
||||
|
@ -98,29 +96,27 @@ public class CertifyCertificateTest {
|
|||
assertFalse(trustworthiness.canIntroduce(1));
|
||||
|
||||
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();
|
||||
PGPPublicKey bobCertifiedKey = bobCertified.getPublicKey();
|
||||
OpenPGPCertificate bobCertified = result.getCertifiedCertificate();
|
||||
PGPPublicKey bobCertifiedKey = bobCertified.getPrimaryKey().getPGPPublicKey();
|
||||
|
||||
List<PGPSignature> sigsByAlice = CollectionUtils.iteratorToList(
|
||||
bobCertifiedKey.getSignaturesForKeyID(alice.getPublicKey().getKeyID()));
|
||||
bobCertifiedKey.getSignaturesForKeyID(alice.getPrimaryKey().getPGPPublicKey().getKeyID()));
|
||||
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
|
||||
public void testPetNameCertification() {
|
||||
PGPSecretKeyRing aliceKey = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("Alice <alice@pgpainless.org>")
|
||||
.getPGPSecretKeyRing();
|
||||
PGPSecretKeyRing bobKey = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("Bob <bob@pgpainless.org>")
|
||||
.getPGPSecretKeyRing();
|
||||
OpenPGPKey aliceKey = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("Alice <alice@pgpainless.org>");
|
||||
OpenPGPKey bobKey = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("Bob <bob@pgpainless.org>");
|
||||
|
||||
PGPPublicKeyRing bobCert = PGPainless.extractCertificate(bobKey);
|
||||
OpenPGPCertificate bobCert = bobKey.toCertificate();
|
||||
String petName = "Bobby";
|
||||
|
||||
CertifyCertificate.CertificationResult result = PGPainless.certify()
|
||||
|
@ -133,11 +129,12 @@ public class CertifyCertificateTest {
|
|||
}
|
||||
});
|
||||
|
||||
PGPSignature certification = result.getCertification();
|
||||
assertEquals(aliceKey.getPublicKey().getKeyID(), certification.getKeyID());
|
||||
assertEquals(CertificationType.GENERIC.asSignatureType().getCode(), certification.getSignatureType());
|
||||
OpenPGPSignature certification = result.getCertification();
|
||||
PGPSignature signature = certification.getSignature();
|
||||
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);
|
||||
assertTrue(info.getUserIds().contains(petName));
|
||||
assertFalse(info.getValidUserIds().contains(petName));
|
||||
|
@ -145,13 +142,11 @@ public class CertifyCertificateTest {
|
|||
|
||||
@Test
|
||||
public void testScopedDelegation() {
|
||||
PGPSecretKeyRing aliceKey = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("Alice <alice@pgpainless.org>")
|
||||
.getPGPSecretKeyRing();
|
||||
PGPSecretKeyRing caKey = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("CA <ca@example.com>")
|
||||
.getPGPSecretKeyRing();
|
||||
PGPPublicKeyRing caCert = PGPainless.extractCertificate(caKey);
|
||||
OpenPGPKey aliceKey = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("Alice <alice@pgpainless.org>");
|
||||
OpenPGPKey caKey = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("CA <ca@example.com>");
|
||||
OpenPGPCertificate caCert = caKey.toCertificate();
|
||||
|
||||
CertifyCertificate.CertificationResult result = PGPainless.certify()
|
||||
.certificate(caCert, Trustworthiness.fullyTrusted().introducer())
|
||||
|
@ -163,9 +158,10 @@ public class CertifyCertificateTest {
|
|||
}
|
||||
});
|
||||
|
||||
PGPSignature certification = result.getCertification();
|
||||
assertEquals(SignatureType.DIRECT_KEY.getCode(), certification.getSignatureType());
|
||||
OpenPGPSignature certification = result.getCertification();
|
||||
PGPSignature signature = certification.getSignature();
|
||||
assertEquals(SignatureType.DIRECT_KEY.getCode(), signature.getSignatureType());
|
||||
assertEquals("^.*<.+@example.com>.*$",
|
||||
certification.getHashedSubPackets().getRegularExpression().getRegex());
|
||||
signature.getHashedSubPackets().getRegularExpression().getRegex());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,10 @@ import java.util.HashSet;
|
|||
import java.util.Set;
|
||||
|
||||
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;
|
||||
import org.bouncycastle.openpgp.api.OpenPGPKey;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.pgpainless.PGPainless;
|
||||
import org.pgpainless.algorithm.EncryptionPurpose;
|
||||
|
@ -33,10 +33,10 @@ public class SubkeyAndPrimaryKeyBindingSignatureTest {
|
|||
|
||||
@Test
|
||||
public void testRebindSubkey() throws PGPException, IOException {
|
||||
PGPSecretKeyRing secretKeys = TestKeys.getEmilSecretKeyRing();
|
||||
OpenPGPKey secretKeys = PGPainless.getInstance().toKey(TestKeys.getEmilSecretKeyRing());
|
||||
KeyRingInfo info = PGPainless.inspectKeyRing(secretKeys);
|
||||
|
||||
PGPSecretKey primaryKey = secretKeys.getSecretKey();
|
||||
OpenPGPKey.OpenPGPSecretKey primaryKey = secretKeys.getPrimarySecretKey();
|
||||
OpenPGPCertificate.OpenPGPComponentKey encryptionSubkey =
|
||||
info.getEncryptionSubkeys(EncryptionPurpose.ANY).get(0);
|
||||
assertNotNull(encryptionSubkey);
|
||||
|
@ -57,9 +57,9 @@ public class SubkeyAndPrimaryKeyBindingSignatureTest {
|
|||
});
|
||||
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
|
||||
package org.pgpainless.signature.builder;
|
||||
|
||||
import org.bouncycastle.bcpg.KeyIdentifier;
|
||||
import org.bouncycastle.bcpg.sig.Exportable;
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||
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.junit.jupiter.api.Test;
|
||||
import org.pgpainless.PGPainless;
|
||||
import org.pgpainless.algorithm.SignatureType;
|
||||
|
@ -28,28 +30,25 @@ public class ThirdPartyCertificationSignatureBuilderTest {
|
|||
|
||||
@Test
|
||||
public void testInvalidSignatureTypeThrows() {
|
||||
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("Alice")
|
||||
.getPGPSecretKeyRing();
|
||||
OpenPGPKey secretKeys = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("Alice");
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
new ThirdPartyCertificationSignatureBuilder(
|
||||
SignatureType.BINARY_DOCUMENT, // invalid type
|
||||
secretKeys.getSecretKey(),
|
||||
secretKeys.getPrimarySecretKey(),
|
||||
SecretKeyRingProtector.unprotectedKeys()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserIdCertification() throws PGPException {
|
||||
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("Alice")
|
||||
.getPGPSecretKeyRing();
|
||||
OpenPGPKey secretKeys = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("Alice");
|
||||
|
||||
PGPPublicKeyRing bobsPublicKeys = PGPainless.extractCertificate(
|
||||
PGPainless.generateKeyRing().modernKeyRing("Bob")
|
||||
.getPGPSecretKeyRing());
|
||||
OpenPGPCertificate bobsPublicKeys = PGPainless.generateKeyRing().modernKeyRing("Bob")
|
||||
.toCertificate();
|
||||
|
||||
ThirdPartyCertificationSignatureBuilder signatureBuilder = new ThirdPartyCertificationSignatureBuilder(
|
||||
secretKeys.getSecretKey(),
|
||||
secretKeys.getPrimarySecretKey(),
|
||||
SecretKeyRingProtector.unprotectedKeys());
|
||||
|
||||
signatureBuilder.applyCallback(new CertificationSubpackets.Callback() {
|
||||
|
@ -59,16 +58,20 @@ public class ThirdPartyCertificationSignatureBuilderTest {
|
|||
}
|
||||
});
|
||||
|
||||
PGPSignature certification = signatureBuilder.build(bobsPublicKeys, "Bob");
|
||||
assertEquals(SignatureType.GENERIC_CERTIFICATION, SignatureType.valueOf(certification.getSignatureType()));
|
||||
assertEquals(secretKeys.getPublicKey().getKeyID(), certification.getKeyID());
|
||||
assertArrayEquals(secretKeys.getPublicKey().getFingerprint(), certification.getHashedSubPackets().getIssuerFingerprint().getFingerprint());
|
||||
Exportable exportable = SignatureSubpacketsUtil.getExportableCertification(certification);
|
||||
OpenPGPSignature certification = signatureBuilder.build(bobsPublicKeys, "Bob");
|
||||
PGPSignature signature = certification.getSignature();
|
||||
assertEquals(SignatureType.GENERIC_CERTIFICATION, SignatureType.valueOf(signature.getSignatureType()));
|
||||
assertTrue(KeyIdentifier.matches(signature.getKeyIdentifiers(), secretKeys.getKeyIdentifier(), true));
|
||||
assertArrayEquals(
|
||||
secretKeys.getPrimaryKey().getPGPPublicKey().getFingerprint(),
|
||||
signature.getHashedSubPackets().getIssuerFingerprint().getFingerprint());
|
||||
Exportable exportable = SignatureSubpacketsUtil.getExportableCertification(signature);
|
||||
assertNotNull(exportable);
|
||||
assertFalse(exportable.isExportable());
|
||||
|
||||
// test sig correctness
|
||||
certification.init(ImplementationFactory.getInstance().getPgpContentVerifierBuilderProvider(), secretKeys.getPublicKey());
|
||||
assertTrue(certification.verifyCertification("Bob", bobsPublicKeys.getPublicKey()));
|
||||
signature.init(ImplementationFactory.getInstance().getPgpContentVerifierBuilderProvider(),
|
||||
secretKeys.getPrimaryKey().getPGPPublicKey());
|
||||
assertTrue(signature.verifyCertification("Bob", bobsPublicKeys.getPrimaryKey().getPGPPublicKey()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ import java.util.Date;
|
|||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||
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.pgpainless.PGPainless;
|
||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||
|
@ -32,12 +34,11 @@ public class ThirdPartyDirectKeySignatureBuilderTest {
|
|||
|
||||
@Test
|
||||
public void testDirectKeySignatureBuilding() throws PGPException {
|
||||
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("Alice")
|
||||
.getPGPSecretKeyRing();
|
||||
OpenPGPKey secretKeys = PGPainless.generateKeyRing()
|
||||
.modernKeyRing("Alice");
|
||||
|
||||
DirectKeySelfSignatureBuilder dsb = new DirectKeySelfSignatureBuilder(
|
||||
secretKeys.getSecretKey(),
|
||||
secretKeys.getPrimarySecretKey(),
|
||||
SecretKeyRingProtector.unprotectedKeys());
|
||||
|
||||
Date now = new Date();
|
||||
|
@ -54,11 +55,14 @@ public class ThirdPartyDirectKeySignatureBuilderTest {
|
|||
}
|
||||
});
|
||||
|
||||
PGPSignature directKeySig = dsb.build();
|
||||
OpenPGPSignature directKeySig = dsb.build();
|
||||
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();
|
||||
|
||||
assertNotNull(signature);
|
||||
|
@ -69,7 +73,7 @@ public class ThirdPartyDirectKeySignatureBuilderTest {
|
|||
assertEquals(Collections.singleton(HashAlgorithm.SHA512), SignatureSubpacketsUtil.parsePreferredHashAlgorithms(signature));
|
||||
assertEquals(Collections.singleton(CompressionAlgorithm.ZIP), SignatureSubpacketsUtil.parsePreferredCompressionAlgorithms(signature));
|
||||
assertEquals(Collections.singleton(SymmetricKeyAlgorithm.AES_256), SignatureSubpacketsUtil.parsePreferredSymmetricKeyAlgorithms(signature));
|
||||
assertEquals(secretKeys.getPublicKey().getKeyID(), signature.getKeyID());
|
||||
assertArrayEquals(secretKeys.getPublicKey().getFingerprint(), signature.getHashedSubPackets().getIssuerFingerprint().getFingerprint());
|
||||
assertEquals(secretKeyRing.getPublicKey().getKeyID(), signature.getKeyID());
|
||||
assertArrayEquals(secretKeyRing.getPublicKey().getFingerprint(), signature.getHashedSubPackets().getIssuerFingerprint().getFingerprint());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,15 +6,16 @@ package org.pgpainless.signature.builder;
|
|||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bouncycastle.bcpg.KeyIdentifier;
|
||||
import org.bouncycastle.bcpg.sig.PrimaryUserID;
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPSignature;
|
||||
import org.bouncycastle.openpgp.PGPSignatureGenerator;
|
||||
import org.bouncycastle.openpgp.api.OpenPGPKey;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.pgpainless.PGPainless;
|
||||
|
@ -51,18 +52,18 @@ public class UniversalSignatureBuilderTest {
|
|||
"=Dqbd\n" +
|
||||
"-----END PGP PRIVATE KEY BLOCK-----";
|
||||
|
||||
private PGPSecretKeyRing secretKeys;
|
||||
private OpenPGPKey secretKeys;
|
||||
private final SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
|
||||
|
||||
@BeforeEach
|
||||
public void parseKey() throws IOException {
|
||||
secretKeys = PGPainless.readKeyRing().secretKeyRing(KEY);
|
||||
secretKeys = PGPainless.getInstance().readKey().parseKey(KEY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createPetNameSignature() throws PGPException {
|
||||
PGPSecretKey signingKey = secretKeys.getSecretKey();
|
||||
PGPSignature archetype = signingKey.getPublicKey().getSignatures().next();
|
||||
OpenPGPKey.OpenPGPSecretKey signingKey = secretKeys.getPrimarySecretKey();
|
||||
PGPSignature archetype = signingKey.getPublicKey().getPGPPublicKey().getSignatures().next();
|
||||
UniversalSignatureBuilder builder = new UniversalSignatureBuilder(
|
||||
signingKey, protector, archetype);
|
||||
|
||||
|
@ -77,11 +78,11 @@ public class UniversalSignatureBuilderTest {
|
|||
PGPSignatureGenerator generator = builder.getSignatureGenerator();
|
||||
|
||||
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(4, petNameSig.getVersion());
|
||||
assertEquals(signingKey.getKeyID(), petNameSig.getKeyID());
|
||||
assertTrue(KeyIdentifier.matches(petNameSig.getKeyIdentifiers(), signingKey.getKeyIdentifier(), true));
|
||||
assertEquals(HashAlgorithm.SHA512.getAlgorithmId(), petNameSig.getHashAlgorithm());
|
||||
assertEquals(KeyFlag.toBitmask(KeyFlag.CERTIFY_OTHER), petNameSig.getHashedSubPackets().getKeyFlags());
|
||||
assertFalse(petNameSig.getHashedSubPackets().isExportable());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue