1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-11-16 17:32:06 +01:00

Add documentation

This commit is contained in:
Paul Schaub 2024-02-19 14:01:06 +01:00
parent f7d389c8d3
commit 4063fcb6ad
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311

View file

@ -69,12 +69,56 @@ internal constructor(val policy: Policy, val creationTime: Date, val preferences
// If set to true, no default direct-key signature will be added to the key // If set to true, no default direct-key signature will be added to the key
internal var skipDefaultDirectKeySignature = false internal var skipDefaultDirectKeySignature = false
// The key flags are set with the setPrimaryKey method
// It can be reused (e.g. by the v4 builder) to populate direct-key and self-certification
// signatures with the intended key flags.
internal var keyFlags: List<KeyFlag>? = null internal var keyFlags: List<KeyFlag>? = null
/**
* Callback to set preferences on the key and user-ids, such as algorithm preferences, features
* etc. This callback will be used to modify direct-key signatures and bindings for user-ids.
*
* @return callback
*/
internal abstract fun preferencesSubpackets(): SelfSignatureSubpackets.Callback internal abstract fun preferencesSubpackets(): SelfSignatureSubpackets.Callback
/**
* Builder-provided subpackets for direct-key signatures.
*
* @return callback
*/
internal fun directKeySignatureSubpackets() = preferencesSubpackets()
/**
* Builder-provided subpackets for UserID binding signatures.
*
* @param primaryKey primary key
* @return callback
*/
internal abstract fun userIdSubpackets(primaryKey: PGPKeyPair): SelfSignatureSubpackets.Callback
/**
* Builder-provided subpackets for UserAttribute binding signatures.
*
* @param primaryKey primary key
* @return callback
*/
internal abstract fun userAttributeSubpackets(
primaryKey: PGPKeyPair
): SelfSignatureSubpackets.Callback
/**
* Generate an OpenPGP primary key.
*
* @return primary key
*/
internal abstract fun generatePrimaryKey(type: KeyType, creationTime: Date): PGPKeyPair internal abstract fun generatePrimaryKey(type: KeyType, creationTime: Date): PGPKeyPair
/**
* Apply a [ApplyToPrimaryKey] instance to the given [PGPKeyPair].
*
* @return altered [PGPKeyPair]
*/
internal abstract fun applyToPrimaryKey( internal abstract fun applyToPrimaryKey(
primaryKey: PGPKeyPair, primaryKey: PGPKeyPair,
applyToPrimaryKey: (ApplyToPrimaryKey.() -> PGPKeyPair)? applyToPrimaryKey: (ApplyToPrimaryKey.() -> PGPKeyPair)?
@ -156,11 +200,24 @@ internal constructor(
} }
as B as B
/**
* Apply the given [applyToSubkey] function block to the given [subkey].
*
* @param subkey subkey
* @param applyToSubkey function block
* @return modified subkey
*/
internal abstract fun applyToSubkey( internal abstract fun applyToSubkey(
subkey: PGPKeyPair, subkey: PGPKeyPair,
applyToSubkey: (ApplyToSubkey.() -> PGPKeyPair)? applyToSubkey: (ApplyToSubkey.() -> PGPKeyPair)?
): PGPKeyPair ): PGPKeyPair
/**
* Generate an OpenPGP subkey.
*
* @param type subkey type
* @param creationTime subkey creation time
*/
internal abstract fun generateSubkey( internal abstract fun generateSubkey(
type: KeyType, type: KeyType,
creationTime: Date = this.creationTime creationTime: Date = this.creationTime
@ -186,6 +243,14 @@ internal constructor(
fun build(passphrase: Passphrase) = build(SecretKeyRingProtector.unlockAnyKeyWith(passphrase)) fun build(passphrase: Passphrase) = build(SecretKeyRingProtector.unlockAnyKeyWith(passphrase))
} }
/**
* Implementation of [DefineSubkeys] tailored to version 4 OpenPGP keys.
*
* @param primaryKey primary key
* @param policy policy
* @param creationTime creation time of the OpenPGP key
* @param subkeys list of already added subkeys
*/
abstract class DefineSubkeysV4<O : DefineSubkeys<O>>( abstract class DefineSubkeysV4<O : DefineSubkeys<O>>(
primaryKey: PGPKeyPair, primaryKey: PGPKeyPair,
policy: Policy, policy: Policy,
@ -235,15 +300,21 @@ abstract class DefineSubkeysV4<O : DefineSubkeys<O>>(
} }
/** /**
* Implementation of an [OpinionatedDefinePrimaryKey] for OpenPGP v4 keys. * Implementation of an opinionated [DefinePrimaryKeyV4] builder.
* *
* @param policy policy for algorithm compliance and fallbacks * @param policy policy for algorithm compliance and fallbacks
* @param creationTime creation time of the primary key * @param creationTime creation time of the primary key
* @param preferences algorithm preferences
*/ */
class OpinionatedDefinePrimaryKeyV4 class OpinionatedDefinePrimaryKeyV4
internal constructor(policy: Policy, creationTime: Date, preferences: AlgorithmSuite) : internal constructor(policy: Policy, creationTime: Date, preferences: AlgorithmSuite) :
DefinePrimaryKeyV4<OpinionatedDefineSubkeysV4>(policy, creationTime, preferences) { DefinePrimaryKeyV4<OpinionatedDefineSubkeysV4>(policy, creationTime, preferences) {
/**
* Return an unopinionated implementation of this builder.
*
* @return unopinionated builder
*/
fun unopinionated() = UnopinionatedDefinePrimaryKeyV4(this) fun unopinionated() = UnopinionatedDefinePrimaryKeyV4(this)
override fun preferencesSubpackets(): SelfSignatureSubpackets.Callback = override fun preferencesSubpackets(): SelfSignatureSubpackets.Callback =
@ -256,6 +327,39 @@ internal constructor(policy: Policy, creationTime: Date, preferences: AlgorithmS
keyFlags?.let { setKeyFlags(it) } keyFlags?.let { setKeyFlags(it) }
} }
override fun userIdSubpackets(primaryKey: PGPKeyPair): SelfSignatureSubpackets.Callback {
return preferencesSubpackets()
.then(
// if key has primary User-IDs already, do nothing
if (primaryKey.publicKey.userIDs.asSequence().any { uid ->
primaryKey.publicKey.getSignaturesForID(uid).asSequence().any { sig ->
sig.hashedSubPackets.isPrimaryUserID
}
}) {
SelfSignatureSubpackets.nop()
} else {
// else set this user-id as primary
SelfSignatureSubpackets.applyHashed { setPrimaryUserId() }
})
}
override fun userAttributeSubpackets(primaryKey: PGPKeyPair): SelfSignatureSubpackets.Callback {
return preferencesSubpackets()
.then(
// if key has primary User-IDs already, do nothing
if (primaryKey.publicKey.userAttributes.asSequence().any { attr ->
primaryKey.publicKey.getSignaturesForUserAttribute(attr).asSequence().any { sig
->
sig.hashedSubPackets.isPrimaryUserID
}
}) {
SelfSignatureSubpackets.nop()
} else {
// else set this user-id as primary
SelfSignatureSubpackets.applyHashed { setPrimaryUserId() }
})
}
override fun setPrimaryKey( override fun setPrimaryKey(
type: KeyType, type: KeyType,
keyFlags: List<KeyFlag>?, keyFlags: List<KeyFlag>?,
@ -287,21 +391,36 @@ internal constructor(policy: Policy, creationTime: Date, preferences: AlgorithmS
} }
/** /**
* Implementation of an [UnopinionatedDefinePrimaryKey] for OpenPGP v4 keys. * Implementation of an unopinionated [DefinePrimaryKeyV4] builder.
* *
* @param policy policy
* @param creationTime creation time of the primary key * @param creationTime creation time of the primary key
* @param preferences algorithm preferences
*/ */
class UnopinionatedDefinePrimaryKeyV4 class UnopinionatedDefinePrimaryKeyV4
internal constructor(policy: Policy, creationTime: Date, preferences: AlgorithmSuite) : internal constructor(policy: Policy, creationTime: Date, preferences: AlgorithmSuite) :
DefinePrimaryKeyV4<UnopinionatedDefineSubkeysV4>(policy, creationTime, preferences) { DefinePrimaryKeyV4<UnopinionatedDefineSubkeysV4>(policy, creationTime, preferences) {
constructor( /**
* Constructor for an unopinionated variant of the passed in [OpinionatedDefinePrimaryKeyV4].
*
* @param opinionated opinionated builder
*/
internal constructor(
opinionated: OpinionatedDefinePrimaryKeyV4 opinionated: OpinionatedDefinePrimaryKeyV4
) : this(opinionated.policy, opinionated.creationTime, opinionated.preferences) ) : this(opinionated.policy, opinionated.creationTime, opinionated.preferences)
override fun preferencesSubpackets(): SelfSignatureSubpackets.Callback = override fun preferencesSubpackets(): SelfSignatureSubpackets.Callback =
SelfSignatureSubpackets.nop() SelfSignatureSubpackets.nop()
override fun userIdSubpackets(primaryKey: PGPKeyPair): SelfSignatureSubpackets.Callback {
return preferencesSubpackets()
}
override fun userAttributeSubpackets(primaryKey: PGPKeyPair): SelfSignatureSubpackets.Callback {
return preferencesSubpackets()
}
override fun setPrimaryKey( override fun setPrimaryKey(
type: KeyType, type: KeyType,
keyFlags: List<KeyFlag>?, keyFlags: List<KeyFlag>?,
@ -321,44 +440,66 @@ internal constructor(policy: Policy, creationTime: Date, preferences: AlgorithmS
} }
/** /**
* Implementation of an [OpinionatedDefineSubkeys] builder for version 4 OpenPGP keys. * Implementation of an opinionated [DefineSubkeysV4] builder.
* *
* @param primaryKey version 4 OpenPGP primary key * @param primaryKey version 4 OpenPGP primary key
* @param policy policy * @param policy policy
* @param creationTime creation time of the OpenPGP key * @param creationTime creation time of the OpenPGP key
* @param unopinionated unopinionated variant of this builder
*/ */
class OpinionatedDefineSubkeysV4 class OpinionatedDefineSubkeysV4
internal constructor(primaryKey: PGPKeyPair, policy: Policy, creationTime: Date) : internal constructor(primaryKey: PGPKeyPair, policy: Policy, creationTime: Date) :
DefineSubkeysV4<OpinionatedDefineSubkeysV4>(primaryKey, policy, creationTime, listOf()) { DefineSubkeysV4<OpinionatedDefineSubkeysV4>(primaryKey, policy, creationTime, listOf()) {
/**
* Return an unopinionated implementation of this builder.
*
* @return unopinionated builder
*/
fun unopinionated() = UnopinionatedDefineSubkeysV4(this) fun unopinionated() = UnopinionatedDefineSubkeysV4(this)
/**
* Add a subkey for signing messages to the OpenPGP key.
*
* @param type signing key type
* @param creationTime creation time of the signing subkey
* @param applyToSubkey function block to add binding signatures to the subkey
*/
fun addSigningSubkey( fun addSigningSubkey(
type: KeyType, type: KeyType,
creationTime: Date = this.creationTime, creationTime: Date = this.creationTime,
applyToSubkey: (ApplyToSubkey.() -> PGPKeyPair)? = { applyToSubkey: (ApplyToSubkey.() -> PGPKeyPair)? = {
addBindingSignature( addBindingSignature(
SelfSignatureSubpackets.applyHashed { SelfSignatureSubpackets.applyHashed { setKeyFlags(KeyFlag.SIGN_DATA) })
setSignatureCreationTime(creationTime)
setKeyFlags(KeyFlag.SIGN_DATA)
})
} }
) = addSubkey(type, creationTime, applyToSubkey) ) = addSubkey(type, creationTime, applyToSubkey)
/**
* Add a subkey for message encryption to the OpenPGP key.
*
* @param type encryption key type
* @param creationTime creation time of the encryption key
* @param applyToSubkey function block to add binding signatures to the subkey
*/
fun addEncryptionSubkey( fun addEncryptionSubkey(
type: KeyType, type: KeyType,
creationTime: Date = this.creationTime, creationTime: Date = this.creationTime,
applyToSubkey: (ApplyToSubkey.() -> PGPKeyPair)? = { applyToSubkey: (ApplyToSubkey.() -> PGPKeyPair)? = {
addBindingSignature( addBindingSignature(
SelfSignatureSubpackets.applyHashed { SelfSignatureSubpackets.applyHashed {
setSignatureCreationTime(creationTime)
setKeyFlags(KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE) setKeyFlags(KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE)
}) })
} }
) = addSubkey(type, creationTime, applyToSubkey) ) = addSubkey(type, creationTime, applyToSubkey)
} }
/**
* Unopinionated implementation of [DefineSubkeysV4].
*
* @param primaryKey primary key of the OpenPGP key
* @param policy policy
* @param creationTime creation time of the OpenPGP key
* @param subkeys list of already added subkeys
*/
class UnopinionatedDefineSubkeysV4 class UnopinionatedDefineSubkeysV4
internal constructor( internal constructor(
primaryKey: PGPKeyPair, primaryKey: PGPKeyPair,
@ -367,7 +508,12 @@ internal constructor(
subkeys: List<PGPKeyPair> = mutableListOf() subkeys: List<PGPKeyPair> = mutableListOf()
) : DefineSubkeysV4<UnopinionatedDefineSubkeysV4>(primaryKey, policy, creationTime, subkeys) { ) : DefineSubkeysV4<UnopinionatedDefineSubkeysV4>(primaryKey, policy, creationTime, subkeys) {
constructor( /**
* Constructor to build an unopinionated variant of the given [OpinionatedDefineSubkeysV4].
*
* @param opinionated opinionated builder
*/
internal constructor(
opinionated: OpinionatedDefineSubkeysV4 opinionated: OpinionatedDefineSubkeysV4
) : this( ) : this(
opinionated.primaryKey, opinionated.policy, opinionated.creationTime, opinionated.subkeys) opinionated.primaryKey, opinionated.policy, opinionated.creationTime, opinionated.subkeys)
@ -401,40 +547,86 @@ internal constructor(var keyPair: PGPKeyPair, val builder: DefinePrimaryKey<*>)
* Add a UserID to the primary key. * Add a UserID to the primary key.
* *
* @param userId UserID to be bound to the primary key * @param userId UserID to be bound to the primary key
* @param subpacketsCallback callback to modify the binding signatures subpackets * @param subpacketsCallback callback to modify the binding signatures subpackets Note: The
* user-provided changes are applied over builder-provided subpackets
* @param certificationType type of the certification signature. Defaults to * @param certificationType type of the certification signature. Defaults to
* [CertificationType.POSITIVE] * [CertificationType.POSITIVE]
* @param hashAlgorithm hash algorithm to be used during signature calculation * @param hashAlgorithm hash algorithm to be used during signature calculation
* @param bindingTime creation time of the binding signature * @param bindingTime creation time of the binding signature
* @return modified key pair * @return modified key pair
*/ */
abstract fun addUserId( fun addUserId(
userId: CharSequence, userId: CharSequence,
subpacketsCallback: SelfSignatureSubpackets.Callback = builder.preferencesSubpackets(), subpacketsCallback: SelfSignatureSubpackets.Callback = builder.preferencesSubpackets(),
certificationType: CertificationType = CertificationType.POSITIVE, certificationType: CertificationType = CertificationType.POSITIVE,
hashAlgorithm: HashAlgorithm = hashAlgorithm: HashAlgorithm =
builder.policy.certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm, builder.policy.certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm,
bindingTime: Date = builder.creationTime bindingTime: Date = builder.creationTime
): PGPKeyPair {
val callback = builder.userIdSubpackets(keyPair).then(subpacketsCallback)
return doAddUserId(userId, callback, certificationType, hashAlgorithm, bindingTime)
}
/**
* Actually add a UserID to the primary key.
*
* @param userId UserId
* @param subpacketsCallback callback to modify the subpackets of the binding signature with
* @param certificationType signature type of the binding signature (certification level)
* @param hashAlgorithm hash algorithm to be used to calculate the signature
* @param bindingTime creation time of the binding signature
* @return modified primary key
*/
internal abstract fun doAddUserId(
userId: CharSequence,
subpacketsCallback: SelfSignatureSubpackets.Callback,
certificationType: CertificationType,
hashAlgorithm: HashAlgorithm,
bindingTime: Date
): PGPKeyPair ): PGPKeyPair
/** /**
* Add a UserAttribute to the primary key. * Add a UserAttribute to the primary key.
* *
* @param userAttribute UserAttribute to be bound to the primary key * @param userAttribute UserAttribute to be bound to the primary key
* @param subpacketsCallback callback to modify the binding signature subpackets * @param subpacketsCallback user-provided callback to modify the binding signature subpackets
* Note: The user-provided changes are applied over subpackets provided by the builder
* @param certificationType type of the binding signature. Default to * @param certificationType type of the binding signature. Default to
* [CertificationType.POSITIVE] * [CertificationType.POSITIVE]
* @param hashAlgorithm hash algorithm to be used during signature calculation * @param hashAlgorithm hash algorithm to be used during signature calculation
* @param bindingTime creation time of the binding signature * @param bindingTime creation time of the binding signature
* @return modified key pair * @return modified key pair
*/ */
abstract fun addUserAttribute( fun addUserAttribute(
userAttribute: PGPUserAttributeSubpacketVector, userAttribute: PGPUserAttributeSubpacketVector,
subpacketsCallback: SelfSignatureSubpackets.Callback = SelfSignatureSubpackets.nop(), subpacketsCallback: SelfSignatureSubpackets.Callback = SelfSignatureSubpackets.nop(),
certificationType: CertificationType = CertificationType.POSITIVE, certificationType: CertificationType = CertificationType.POSITIVE,
hashAlgorithm: HashAlgorithm = hashAlgorithm: HashAlgorithm =
builder.policy.certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm, builder.policy.certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm,
bindingTime: Date = builder.creationTime bindingTime: Date = builder.creationTime
): PGPKeyPair {
val callback = builder.userAttributeSubpackets(keyPair).then(subpacketsCallback)
return doAddUserAttribute(
userAttribute, callback, certificationType, hashAlgorithm, bindingTime)
}
/**
* Actually add the UserAttribute to the primary key.
*
* @param userAttribute UserAttribute to be added to the primary key
* @param subpacketsCallback callback to modify the subpackets of the binding signature with
* @param certificationType signature type (certification level)
* @param hashAlgorithm hash algorithm to calculate the binding signature with
* @param bindingTime creation time of the binding signature
* @return modified primary key
*/
abstract fun doAddUserAttribute(
userAttribute: PGPUserAttributeSubpacketVector,
subpacketsCallback: SelfSignatureSubpackets.Callback,
certificationType: CertificationType,
hashAlgorithm: HashAlgorithm,
bindingTime: Date
): PGPKeyPair ): PGPKeyPair
/** /**
@ -469,23 +661,39 @@ internal constructor(var keyPair: PGPKeyPair, val builder: DefinePrimaryKey<*>)
/** /**
* Add a DirectKeySignature to the primary key. Such a signature usually carries information * Add a DirectKeySignature to the primary key. Such a signature usually carries information
* that applies to the whole OpenPGP key, such as algorithm preferences etc. * that applies to the whole OpenPGP key, such as algorithm preferences etc.
*
* @param subpacketsCallback callback to modify the direct-key signatures subpackets with Note,
* that the user-provided changed subpackets are applied over builder-provided subpackets.
* @param hashAlgorithm hash algorithm to calculate the signature with
* @param bindingTime signature creation time
* @return modified primary key
*/ */
fun addDirectKeySignature( fun addDirectKeySignature(
subpacketsCallback: SelfSignatureSubpackets.Callback = builder.preferencesSubpackets(), subpacketsCallback: SelfSignatureSubpackets.Callback = SelfSignatureSubpackets.nop(),
hashAlgorithm: HashAlgorithm = hashAlgorithm: HashAlgorithm =
builder.policy.certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm, builder.policy.certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm,
bindingTime: Date = builder.creationTime bindingTime: Date = builder.creationTime
): PGPKeyPair { ): PGPKeyPair {
skipDefaultSignature() skipDefaultSignature()
return doAddDirectKeySignature(subpacketsCallback, hashAlgorithm, bindingTime) val callback = builder.directKeySignatureSubpackets().then(subpacketsCallback)
return doAddDirectKeySignature(callback, hashAlgorithm, bindingTime)
} }
/**
* Actually add a direct-key signature to the primary key.
*
* @param subpacketsCallback callback to modify the direct-key signatures subpackets with
* @param hashAlgorithm hash algorithm to calculate the signature with
* @param bindingTime creation time for the direct-key signature
* @return modified primary key
*/
protected abstract fun doAddDirectKeySignature( protected abstract fun doAddDirectKeySignature(
subpacketsCallback: SelfSignatureSubpackets.Callback, subpacketsCallback: SelfSignatureSubpackets.Callback,
hashAlgorithm: HashAlgorithm, hashAlgorithm: HashAlgorithm,
bindingTime: Date bindingTime: Date
): PGPKeyPair ): PGPKeyPair
/** Do not add the default direct-key signature automatically. */
fun skipDefaultSignature(): PGPKeyPair { fun skipDefaultSignature(): PGPKeyPair {
builder.skipDefaultDirectKeySignature = true builder.skipDefaultDirectKeySignature = true
return keyPair return keyPair
@ -501,59 +709,45 @@ internal constructor(var keyPair: PGPKeyPair, val builder: DefinePrimaryKey<*>)
abstract fun then(other: (ApplyToPrimaryKey.() -> PGPKeyPair)?): PGPKeyPair abstract fun then(other: (ApplyToPrimaryKey.() -> PGPKeyPair)?): PGPKeyPair
} }
/** Implementation of [ApplyToPrimaryKey] tailored to version 4 OpenPGP keys. */
class ApplyToPrimaryKeyV4 internal constructor(keyPair: PGPKeyPair, builder: DefinePrimaryKey<*>) : class ApplyToPrimaryKeyV4 internal constructor(keyPair: PGPKeyPair, builder: DefinePrimaryKey<*>) :
ApplyToPrimaryKey(keyPair, builder) { ApplyToPrimaryKey(keyPair, builder) {
override fun addUserId( override fun doAddUserId(
userId: CharSequence, userId: CharSequence,
subpacketsCallback: SelfSignatureSubpackets.Callback, subpacketsCallback: SelfSignatureSubpackets.Callback,
certificationType: CertificationType, certificationType: CertificationType,
hashAlgorithm: HashAlgorithm, hashAlgorithm: HashAlgorithm,
bindingTime: Date bindingTime: Date
): PGPKeyPair { ): PGPKeyPair {
val callback = markAsPrimaryIfNecessary(subpacketsCallback) val builder =
SelfSignatureBuilder(
val sig = keyPair.privateKey,
buildCertificationFor( keyPair.publicKey,
keyPair, userId, certificationType, bindingTime, hashAlgorithm, callback) certificationType.signatureType,
hashAlgorithm)
builder.applyCallback(subpacketsCallback.then(setCreationTime(bindingTime)))
val sig = builder.build(userId)
keyPair = keyPair.plusCertification(userId, sig) keyPair = keyPair.plusCertification(userId, sig)
return keyPair return keyPair
} }
private fun markAsPrimaryIfNecessary( override fun doAddUserAttribute(
subpacketsCallback: SelfSignatureSubpackets.Callback
): SelfSignatureSubpackets.Callback {
val callback =
// if key has primary User-IDs already, do nothing
if (keyPair.publicKey.userIDs.asSequence().any { uid ->
keyPair.publicKey.getSignaturesForID(uid).asSequence().any { sig ->
sig.hashedSubPackets.isPrimaryUserID
}
}) {
subpacketsCallback
} else {
// else set this user-id as primary
SelfSignatureSubpackets.applyHashed { setPrimaryUserId() }.then(subpacketsCallback)
}
return callback
}
override fun addUserAttribute(
userAttribute: PGPUserAttributeSubpacketVector, userAttribute: PGPUserAttributeSubpacketVector,
subpacketsCallback: SelfSignatureSubpackets.Callback, subpacketsCallback: SelfSignatureSubpackets.Callback,
certificationType: CertificationType, certificationType: CertificationType,
hashAlgorithm: HashAlgorithm, hashAlgorithm: HashAlgorithm,
bindingTime: Date bindingTime: Date
): PGPKeyPair { ): PGPKeyPair {
val sig = val builder =
buildCertificationFor( SelfSignatureBuilder(
keyPair, keyPair.privateKey,
userAttribute, keyPair.publicKey,
certificationType, certificationType.signatureType,
bindingTime, hashAlgorithm)
hashAlgorithm, builder.applyCallback(subpacketsCallback.then(setCreationTime(bindingTime)))
subpacketsCallback) val sig = builder.build(userAttribute)
keyPair = keyPair.plusCertification(userAttribute, sig) keyPair = keyPair.plusCertification(userAttribute, sig)
return keyPair return keyPair
@ -564,98 +758,32 @@ class ApplyToPrimaryKeyV4 internal constructor(keyPair: PGPKeyPair, builder: Def
hashAlgorithm: HashAlgorithm, hashAlgorithm: HashAlgorithm,
bindingTime: Date bindingTime: Date
): PGPKeyPair { ): PGPKeyPair {
val sig = val builder =
buildDirectKeySignature( DirectKeySelfSignatureBuilder(keyPair.privateKey, keyPair.publicKey, hashAlgorithm)
keyPair, builder.applyCallback(subpacketsCallback.then(setCreationTime(bindingTime)))
hashAlgorithm, val sig = builder.build()
subpacketsCallback.then(
SelfSignatureSubpackets.applyHashed { setSignatureCreationTime(bindingTime) }))
keyPair = keyPair.plusCertification(sig) keyPair = keyPair.plusCertification(sig)
return keyPair return keyPair
} }
/**
* Return a [SelfSignatureSubpackets.Callback] that sets the signature creation time to the
* given [bindingTime].
*
* @param bindingTime signature creation time
* @return callback
*/
private fun setCreationTime(bindingTime: Date): SelfSignatureSubpackets.Callback {
return SelfSignatureSubpackets.applyHashed { setSignatureCreationTime(bindingTime) }
}
override fun then(other: (ApplyToPrimaryKey.() -> PGPKeyPair)?): PGPKeyPair { override fun then(other: (ApplyToPrimaryKey.() -> PGPKeyPair)?): PGPKeyPair {
if (other != null) { if (other != null) {
keyPair = ApplyToPrimaryKeyV4(keyPair, builder).other() keyPair = ApplyToPrimaryKeyV4(keyPair, builder).other()
} }
return keyPair return keyPair
} }
/**
* Build a certification signature that binds the given [userId] to the given primary key
* [pair].
*
* @param pair primary key pair
* @param userId UserID to be bound
* @param certificationType type of the binding signature
* @param bindingTime creation time of the binding signature
* @param hashAlgorithm hash algorithm to be used during signature calculation
* @param subpacketsCallback callback to modify the binding signatures subpackets
* @return binding signature
*/
private fun buildCertificationFor(
pair: PGPKeyPair,
userId: CharSequence,
certificationType: CertificationType,
bindingTime: Date,
hashAlgorithm: HashAlgorithm,
subpacketsCallback: SelfSignatureSubpackets.Callback
): PGPSignature {
val builder =
SelfSignatureBuilder(
pair.privateKey, pair.publicKey, certificationType.signatureType, hashAlgorithm)
builder.hashedSubpackets.apply { setSignatureCreationTime(bindingTime) }
builder.applyCallback(subpacketsCallback)
return builder.build(userId)
}
/**
* Build a certification signature that binds the given [userAttribute] to the given primary key
* [pair].
*
* @param pair primary key pair
* @param userAttribute UserAttribute to be bound
* @param certificationType type of the binding signature
* @param bindingTime creation time of the binding signature
* @param hashAlgorithm hash algorithm to be used during signature calculation
* @param subpacketsCallback callback to modify the binding signatures subpackets
* @return binding signature
*/
private fun buildCertificationFor(
pair: PGPKeyPair,
userAttribute: PGPUserAttributeSubpacketVector,
certificationType: CertificationType,
bindingTime: Date,
hashAlgorithm: HashAlgorithm,
subpacketsCallback: SelfSignatureSubpackets.Callback
): PGPSignature {
val builder =
SelfSignatureBuilder(
pair.privateKey, pair.publicKey, certificationType.signatureType, hashAlgorithm)
builder.hashedSubpackets.apply { setSignatureCreationTime(bindingTime) }
builder.applyCallback(subpacketsCallback)
return builder.build(userAttribute)
}
/**
* Build a DirectKey self signature over the primary key [pair].
*
* @param pair primary key pair
* @param hashAlgorithm hash algorithm to be used during signature calculation
* @param subpacketsCallback callback to modify the subpackets of the direct-key signature
* @return direct-key self signature
*/
private fun buildDirectKeySignature(
pair: PGPKeyPair,
hashAlgorithm: HashAlgorithm,
subpacketsCallback: SelfSignatureSubpackets.Callback
): PGPSignature {
val builder = DirectKeySelfSignatureBuilder(pair.privateKey, pair.publicKey, hashAlgorithm)
builder.applyCallback(subpacketsCallback)
return builder.build()
}
} }
/** /**
@ -747,10 +875,15 @@ internal constructor(primaryKey: PGPKeyPair, subkey: PGPKeyPair, builder: Define
.build(subkey) .build(subkey)
} }
private fun isSigningCapable(flags: List<KeyFlag>?): Boolean { /**
val signCapableFlags = listOf(KeyFlag.SIGN_DATA, KeyFlag.CERTIFY_OTHER) * Return `true` if the given [flags] list contains either [KeyFlag.SIGN_DATA] or
return flags?.any { signCapableFlags.contains(it) } ?: false * [KeyFlag.CERTIFY_OTHER].
} *
* @return true if contains SIGN_DATA or CERTIFY_OTHER
*/
private fun isSigningCapable(flags: List<KeyFlag>?): Boolean =
flags.orEmpty().contains(KeyFlag.SIGN_DATA) ||
flags.orEmpty().contains(KeyFlag.CERTIFY_OTHER)
} }
/** Templates for OpenPGP key generation. */ /** Templates for OpenPGP key generation. */