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.

135 lines
4.9 KiB
Kotlin
Raw Normal View History

2024-01-06 01:31:12 +01:00
package org.pgpainless.key.generation
2024-01-08 13:51:16 +01:00
import org.bouncycastle.bcpg.PublicSubkeyPacket
2024-01-06 01:31:12 +01:00
import org.bouncycastle.openpgp.PGPKeyPair
2024-01-08 13:51:16 +01:00
import org.bouncycastle.openpgp.PGPPrivateKey
import org.bouncycastle.openpgp.PGPPublicKey
import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.algorithm.SignatureType
2024-01-06 01:31:12 +01:00
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.generation.type.KeyType
import org.pgpainless.key.generation.type.eddsa.EdDSACurve
import org.pgpainless.key.generation.type.rsa.RsaLength
import org.pgpainless.key.generation.type.xdh.XDHSpec
import org.pgpainless.provider.ProviderFactory
2024-01-08 13:51:16 +01:00
import org.pgpainless.signature.builder.SelfSignatureBuilder
import org.pgpainless.signature.builder.SubkeyBindingSignatureBuilder
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets
2024-01-06 01:31:12 +01:00
import java.security.KeyPairGenerator
2024-01-08 13:51:16 +01:00
import java.util.*
2024-01-06 01:31:12 +01:00
class OpenPgpKeyBuilder {
fun buildV4Key(
type: KeyType,
creationTime: Date = Date()
): V4PrimaryKeyBuilder = V4PrimaryKeyBuilder(type, creationTime)
abstract class V4KeyBuilder<T: V4KeyBuilder<T>>(
2024-01-08 13:51:16 +01:00
val type: KeyType,
val creationTime: Date,
2024-01-06 01:31:12 +01:00
val certificateCreationTime: Date = Date()
) {
2024-01-08 13:51:16 +01:00
internal var key = generateKeyPair()
2024-01-06 01:31:12 +01:00
fun subkey(
type: KeyType,
creationTime: Date = certificateCreationTime
2024-01-08 13:51:16 +01:00
): V4SubkeyBuilder = V4SubkeyBuilder(type, creationTime, primaryKey())
2024-01-06 01:31:12 +01:00
2024-01-08 13:51:16 +01:00
internal abstract fun primaryKey(): V4PrimaryKeyBuilder
2024-01-06 01:31:12 +01:00
private fun generateKeyPair(): PGPKeyPair {
// Create raw Key Pair
val keyPair = KeyPairGenerator.getInstance(type.name, ProviderFactory.provider)
.also { it.initialize(type.algorithmSpec) }
.generateKeyPair()
// Form PGP Key Pair
return ImplementationFactory.getInstance()
.getPGPV4KeyPair(type.algorithm, keyPair, creationTime)
2024-01-08 13:51:16 +01:00
.let {
adjustKeyPacket(it)
}
2024-01-06 01:31:12 +01:00
}
2024-01-08 13:51:16 +01:00
protected abstract fun adjustKeyPacket(keyPair: PGPKeyPair): PGPKeyPair
2024-01-06 01:31:12 +01:00
}
class V4PrimaryKeyBuilder(
type: KeyType,
creationTime: Date
): V4KeyBuilder<V4PrimaryKeyBuilder>(type, creationTime) {
2024-01-08 13:51:16 +01:00
fun userId(
userId: CharSequence,
bindingTime: Date = creationTime,
hashAlgorithm: HashAlgorithm = HashAlgorithm.SHA512,
subpacketsCallback: SelfSignatureSubpackets.Callback =
object : SelfSignatureSubpackets.Callback {
}
) = apply {
val sig = SelfSignatureBuilder(
key.privateKey,
key.publicKey,
SignatureType.POSITIVE_CERTIFICATION,
hashAlgorithm)
.applyCallback(subpacketsCallback)
.build(userId)
key = PGPKeyPair(
PGPPublicKey.addCertification(key.publicKey, userId.toString(), sig),
key.privateKey
)
2024-01-06 01:31:12 +01:00
}
2024-01-08 13:51:16 +01:00
override fun adjustKeyPacket(keyPair: PGPKeyPair): PGPKeyPair {
return keyPair // is already a secret key packet
2024-01-06 01:31:12 +01:00
}
2024-01-08 13:51:16 +01:00
override fun primaryKey() = this
2024-01-06 01:31:12 +01:00
}
class V4SubkeyBuilder(
type: KeyType,
creationTime: Date,
2024-01-08 13:51:16 +01:00
private val primaryKeyBuilder: V4PrimaryKeyBuilder
): V4KeyBuilder<V4SubkeyBuilder>(type, creationTime) {
fun bindingSignature(subpacketCallback: SelfSignatureSubpackets.Callback) = apply {
SubkeyBindingSignatureBuilder(primaryKeyBuilder.key.privateKey, primaryKeyBuilder.key.publicKey)
.applyCallback(subpacketCallback)
.build(key.publicKey)
.let {
key = PGPKeyPair(
PGPPublicKey.addCertification(key.publicKey, it),
key.privateKey)
}
}
2024-01-06 01:31:12 +01:00
2024-01-08 13:51:16 +01:00
override fun adjustKeyPacket(keyPair: PGPKeyPair): PGPKeyPair {
val fpCalc = ImplementationFactory.getInstance().keyFingerprintCalculator
val pubkey = keyPair.publicKey
val privkey = keyPair.privateKey
// form subkey packet
val subkey = PublicSubkeyPacket(pubkey.algorithm,
pubkey.creationTime, pubkey.publicKeyPacket.key)
return PGPKeyPair(
PGPPublicKey(subkey, fpCalc),
PGPPrivateKey(pubkey.keyID, subkey, privkey.privateKeyDataPacket)
)
2024-01-06 01:31:12 +01:00
}
2024-01-08 13:51:16 +01:00
override fun primaryKey() = primaryKeyBuilder.primaryKey()
fun bindingSignature(
bindingTime: Date = creationTime
): V4SubkeyBuilder = bindingSignature(object : SelfSignatureSubpackets.Callback {
override fun modifyHashedSubpackets(hashedSubpackets: SelfSignatureSubpackets) {
hashedSubpackets.setSignatureCreationTime(bindingTime)
}
})
}
2024-01-06 01:31:12 +01:00
}