1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-06-25 04:54:49 +02:00
pgpainless/pgpainless-core/src/main/kotlin/org/pgpainless/key/generation/OpenPgpKeyBuilder.kt

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

168 lines
6.6 KiB
Kotlin
Raw Normal View History

2024-01-22 16:52:40 +01:00
// SPDX-FileCopyrightText: 2024 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
2024-01-06 01:31:12 +01:00
package org.pgpainless.key.generation
2024-01-11 16:44:21 +01:00
import java.util.*
2024-01-22 16:52:40 +01:00
import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSecretKeyRing
2024-01-11 16:44:21 +01:00
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector
2024-01-22 16:52:40 +01:00
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor
import org.pgpainless.algorithm.AlgorithmSuite
2024-01-11 16:44:21 +01:00
import org.pgpainless.algorithm.KeyFlag
2024-01-06 01:31:12 +01:00
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.generation.type.KeyType
2024-01-22 16:52:40 +01:00
import org.pgpainless.key.protection.SecretKeyRingProtector
2024-01-11 16:44:21 +01:00
import org.pgpainless.policy.Policy
2024-01-08 13:51:16 +01:00
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets
2024-01-06 01:31:12 +01:00
2024-01-22 16:52:40 +01:00
open class OpenPgpKeyBuilder(
protected val policy: Policy,
protected val referenceTime: Date = Date(),
protected val keyGenerationPolicy: AlgorithmSuite = policy.keyGenerationAlgorithmSuite
) {
2024-01-06 01:31:12 +01:00
fun buildV4Key(
2024-01-22 16:52:40 +01:00
keyType: KeyType,
): V4OpenPgpKeyBuilder =
V4OpenPgpKeyBuilder(keyType, policy, referenceTime, keyGenerationPolicy)
2024-01-08 13:51:16 +01:00
2024-01-22 16:52:40 +01:00
class V4OpenPgpKeyBuilder(
keyType: KeyType,
policy: Policy,
referenceTime: Date,
keyGenerationPolicy: AlgorithmSuite
) : OpenPgpKeyBuilder(policy, referenceTime, keyGenerationPolicy) {
2024-01-06 01:31:12 +01:00
2024-01-22 16:52:40 +01:00
private val primaryKey =
BaseOpenPgpKeyBuilder.BaseV4PrimaryKeyBuilder(keyType, referenceTime, policy)
2024-01-06 01:31:12 +01:00
2024-01-22 16:52:40 +01:00
private val subkeys = mutableListOf<BaseOpenPgpKeyBuilder.BaseV4SubkeyBuilder>()
2024-01-08 13:51:16 +01:00
2024-01-22 16:52:40 +01:00
fun addUserId(
2024-01-11 16:44:21 +01:00
userId: CharSequence,
2024-01-22 16:52:40 +01:00
algorithmSuite: AlgorithmSuite = keyGenerationPolicy,
2024-01-24 11:27:42 +01:00
subpacketsCallback: SelfSignatureSubpackets.Callback = SelfSignatureSubpackets.nop()
) = apply {
primaryKey.userId(userId, algorithmSuite, subpacketsCallback = subpacketsCallback)
}
2024-01-11 16:44:21 +01:00
2024-01-22 16:52:40 +01:00
fun addUserAttribute(
attribute: PGPUserAttributeSubpacketVector,
algorithmSuite: AlgorithmSuite = keyGenerationPolicy,
2024-01-24 11:27:42 +01:00
subpacketsCallback: SelfSignatureSubpackets.Callback = SelfSignatureSubpackets.nop()
) = apply {
primaryKey.userAttribute(
attribute, algorithmSuite, subpacketsCallback = subpacketsCallback)
}
2024-01-11 16:44:21 +01:00
2024-01-22 16:52:40 +01:00
fun addSubkey(
keyType: KeyType,
creationTime: Date = referenceTime,
2024-01-11 16:44:21 +01:00
bindingTime: Date = creationTime,
2024-01-22 16:52:40 +01:00
keyFlags: List<KeyFlag>?
) =
addSubkey(
BaseOpenPgpKeyBuilder.BaseV4SubkeyBuilder(
keyType, creationTime, policy, primaryKey),
bindingTime,
keyFlags)
fun addSubkey(
subkeyBuilder: BaseOpenPgpKeyBuilder.BaseV4SubkeyBuilder,
bindingTime: Date = subkeyBuilder.creationTime,
keyFlags: List<KeyFlag>?
2024-01-11 16:44:21 +01:00
) = apply {
2024-01-22 16:52:40 +01:00
subkeys.add(
subkeyBuilder.also {
it.bindingSignature(
bindingTime,
subpacketsCallback =
object : SelfSignatureSubpackets.Callback {
override fun modifyHashedSubpackets(
hashedSubpackets: SelfSignatureSubpackets
) {
hashedSubpackets.setSignatureCreationTime(bindingTime)
keyFlags?.let { flagList ->
hashedSubpackets.setKeyFlags(flagList)
}
}
})
})
2024-01-11 16:44:21 +01:00
}
2024-01-22 16:52:40 +01:00
fun addEncryptionSubkey(
keyType: KeyType,
creationTime: Date = referenceTime,
bindingTime: Date = creationTime
) =
addSubkey(
keyType,
creationTime,
bindingTime,
listOf(KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS))
fun addSigningSubkey(
keyType: KeyType,
creationTime: Date = referenceTime,
bindingTime: Date = creationTime
) = addSubkey(keyType, creationTime, bindingTime, listOf(KeyFlag.SIGN_DATA))
fun build(
protector: SecretKeyRingProtector = SecretKeyRingProtector.unprotectedKeys()
): PGPSecretKeyRing {
// Add DK sig in case of no user-id
if (primaryKey.isWithoutUserIds()) {
2024-01-24 11:27:42 +01:00
primaryKey.directKeySignature(
subpacketsCallback = defaultPrimarySubpacketsCallback())
}
2024-01-22 16:52:40 +01:00
return PGPSecretKeyRing(
mutableListOf(
PGPSecretKey(
primaryKey.key.privateKey,
primaryKey.key.publicKey,
ImplementationFactory.getInstance().v4FingerprintCalculator,
true,
protector.getEncryptor(primaryKey.key.keyID)))
.plus(
subkeys.map {
PGPSecretKey(
it.key.privateKey,
it.key.publicKey,
ImplementationFactory.getInstance().v4FingerprintCalculator,
false,
protector.getEncryptor(it.key.keyID))
}))
}
2024-01-11 16:44:21 +01:00
2024-01-22 16:52:40 +01:00
private fun defaultPrimarySubpacketsCallback(): SelfSignatureSubpackets.Callback =
object : SelfSignatureSubpackets.Callback {
override fun modifyHashedSubpackets(hashedSubpackets: SelfSignatureSubpackets) {
hashedSubpackets.apply {
setPreferredHashAlgorithms(keyGenerationPolicy.hashAlgorithms)
2024-01-24 11:27:42 +01:00
setPreferredSymmetricKeyAlgorithms(
keyGenerationPolicy.symmetricKeyAlgorithms)
2024-01-22 16:52:40 +01:00
setPreferredCompressionAlgorithms(keyGenerationPolicy.compressionAlgorithms)
setKeyFlags(KeyFlag.CERTIFY_OTHER)
}
}
2024-01-11 16:44:21 +01:00
}
2024-01-22 16:52:40 +01:00
private fun toSecretKey(
key: BaseOpenPgpKeyBuilder.BaseV4KeyBuilder<*>,
isPrimaryKey: Boolean,
encryptor: PBESecretKeyEncryptor?
): PGPSecretKey {
return PGPSecretKey(
key.key.privateKey,
key.key.publicKey,
ImplementationFactory.getInstance().v4FingerprintCalculator,
isPrimaryKey,
encryptor)
2024-01-08 13:51:16 +01:00
}
}
2024-01-06 01:31:12 +01:00
}