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

Allow passing creation time into KeyRingTemplates, replace deprecated methods

This commit is contained in:
Paul Schaub 2025-03-17 16:12:10 +01:00
parent 0ff347b836
commit 1e7a357b68
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
4 changed files with 54 additions and 36 deletions

View file

@ -48,8 +48,9 @@ class PGPainless(
@JvmOverloads @JvmOverloads
fun generateKey( fun generateKey(
version: OpenPGPKeyVersion = OpenPGPKeyVersion.v4, version: OpenPGPKeyVersion = OpenPGPKeyVersion.v4,
creationTime: Date = Date() creationTime: Date = Date(),
): KeyRingTemplates = KeyRingTemplates(version, creationTime) policy: Policy = algorithmPolicy
): KeyRingTemplates = KeyRingTemplates(version, creationTime, policy)
@JvmOverloads @JvmOverloads
fun buildKey( fun buildKey(
@ -98,8 +99,10 @@ class PGPainless(
*/ */
@JvmStatic @JvmStatic
@JvmOverloads @JvmOverloads
fun buildKeyRing(version: OpenPGPKeyVersion = OpenPGPKeyVersion.v4) = fun buildKeyRing(
KeyRingBuilder(version, getInstance().implementation) version: OpenPGPKeyVersion = OpenPGPKeyVersion.v4,
policy: Policy = getInstance().algorithmPolicy
) = KeyRingBuilder(version, getInstance().implementation, policy)
/** /**
* Read an existing OpenPGP key ring. * Read an existing OpenPGP key ring.

View file

@ -27,7 +27,8 @@ import org.pgpainless.util.Passphrase
class KeyRingBuilder( class KeyRingBuilder(
private val version: OpenPGPKeyVersion, private val version: OpenPGPKeyVersion,
private val implementation: OpenPGPImplementation private val implementation: OpenPGPImplementation,
private val policy: Policy = PGPainless.getInstance().algorithmPolicy
) : KeyRingBuilderInterface<KeyRingBuilder> { ) : KeyRingBuilderInterface<KeyRingBuilder> {
private var primaryKeySpec: KeySpec? = null private var primaryKeySpec: KeySpec? = null
@ -37,13 +38,13 @@ class KeyRingBuilder(
private var expirationDate: Date? = Date(System.currentTimeMillis() + (5 * MILLIS_IN_YEAR)) private var expirationDate: Date? = Date(System.currentTimeMillis() + (5 * MILLIS_IN_YEAR))
override fun setPrimaryKey(keySpec: KeySpec): KeyRingBuilder = apply { override fun setPrimaryKey(keySpec: KeySpec): KeyRingBuilder = apply {
verifyKeySpecCompliesToPolicy(keySpec, PGPainless.getPolicy()) verifyKeySpecCompliesToPolicy(keySpec, policy)
verifyPrimaryKeyCanCertify(keySpec) verifyPrimaryKeyCanCertify(keySpec)
this.primaryKeySpec = keySpec this.primaryKeySpec = keySpec
} }
override fun addSubkey(keySpec: KeySpec): KeyRingBuilder = apply { override fun addSubkey(keySpec: KeySpec): KeyRingBuilder = apply {
verifyKeySpecCompliesToPolicy(keySpec, PGPainless.getPolicy()) verifyKeySpecCompliesToPolicy(keySpec, policy)
subKeySpecs.add(keySpec) subKeySpecs.add(keySpec)
} }
@ -83,11 +84,11 @@ class KeyRingBuilder(
private fun keyIsCertificationCapable(keySpec: KeySpec) = keySpec.keyType.canCertify private fun keyIsCertificationCapable(keySpec: KeySpec) = keySpec.keyType.canCertify
override fun build(): OpenPGPKey { override fun build(): OpenPGPKey {
val checksumCalculator = OpenPGPImplementation.getInstance().checksumCalculator() val checksumCalculator = implementation.checksumCalculator()
// generate primary key // generate primary key
requireNotNull(primaryKeySpec) { "Primary Key spec required." } requireNotNull(primaryKeySpec) { "Primary Key spec required." }
val certKey = generateKeyPair(primaryKeySpec!!, version) val certKey = generateKeyPair(primaryKeySpec!!, version, implementation)
val secretKeyEncryptor = buildSecretKeyEncryptor(certKey.publicKey) val secretKeyEncryptor = buildSecretKeyEncryptor(certKey.publicKey)
val secretKeyDecryptor = buildSecretKeyDecryptor() val secretKeyDecryptor = buildSecretKeyDecryptor()
@ -168,7 +169,7 @@ class KeyRingBuilder(
private fun addSubKeys(primaryKey: PGPKeyPair, ringGenerator: PGPKeyRingGenerator) { private fun addSubKeys(primaryKey: PGPKeyPair, ringGenerator: PGPKeyRingGenerator) {
for (subKeySpec in subKeySpecs) { for (subKeySpec in subKeySpecs) {
val subKey = generateKeyPair(subKeySpec, version) val subKey = generateKeyPair(subKeySpec, version, implementation)
if (subKeySpec.isInheritedSubPackets) { if (subKeySpec.isInheritedSubPackets) {
ringGenerator.addSubKey(subKey) ringGenerator.addSubKey(subKey)
} else { } else {
@ -209,20 +210,19 @@ class KeyRingBuilder(
} }
private fun buildContentSigner(certKey: PGPKeyPair): PGPContentSignerBuilder { private fun buildContentSigner(certKey: PGPKeyPair): PGPContentSignerBuilder {
val hashAlgorithm = val hashAlgorithm = policy.certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm
PGPainless.getPolicy().certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm return implementation.pgpContentSignerBuilder(
return OpenPGPImplementation.getInstance() certKey.publicKey.algorithm, hashAlgorithm.algorithmId)
.pgpContentSignerBuilder(certKey.publicKey.algorithm, hashAlgorithm.algorithmId)
} }
private fun buildSecretKeyEncryptor( private fun buildSecretKeyEncryptor(
publicKey: PGPPublicKey, publicKey: PGPPublicKey,
): PBESecretKeyEncryptor? { ): PBESecretKeyEncryptor? {
check(passphrase.isValid) { "Passphrase was cleared." } check(passphrase.isValid) { "Passphrase was cleared." }
val protectionSettings = PGPainless.getPolicy().keyProtectionSettings val protectionSettings = policy.keyProtectionSettings
return if (passphrase.isEmpty) null return if (passphrase.isEmpty) null
else else
OpenPGPImplementation.getInstance() implementation
.pbeSecretKeyEncryptorFactory( .pbeSecretKeyEncryptorFactory(
protectionSettings.aead, protectionSettings.aead,
protectionSettings.encryptionAlgorithm.algorithmId, protectionSettings.encryptionAlgorithm.algorithmId,
@ -234,7 +234,7 @@ class KeyRingBuilder(
check(passphrase.isValid) { "Passphrase was cleared." } check(passphrase.isValid) { "Passphrase was cleared." }
return if (passphrase.isEmpty) null return if (passphrase.isEmpty) null
else else
OpenPGPImplementation.getInstance() implementation
.pbeSecretKeyDecryptorBuilderProvider() .pbeSecretKeyDecryptorBuilderProvider()
.provide() .provide()
.build(passphrase.getChars()) .build(passphrase.getChars())
@ -248,12 +248,11 @@ class KeyRingBuilder(
fun generateKeyPair( fun generateKeyPair(
spec: KeySpec, spec: KeySpec,
version: OpenPGPKeyVersion, version: OpenPGPKeyVersion,
implementation: OpenPGPImplementation = PGPainless.getInstance().implementation,
creationTime: Date = spec.keyCreationDate ?: Date() creationTime: Date = spec.keyCreationDate ?: Date()
): PGPKeyPair { ): PGPKeyPair {
val gen = val gen =
OpenPGPImplementation.getInstance() implementation.pgpKeyPairGeneratorProvider().get(version.numeric, creationTime)
.pgpKeyPairGeneratorProvider()
.get(version.numeric, creationTime)
return spec.keyType.generateKeyPair(gen) return spec.keyType.generateKeyPair(gen)
} }

View file

@ -6,6 +6,7 @@ package org.pgpainless.key.generation
import java.util.* import java.util.*
import org.bouncycastle.openpgp.api.OpenPGPKey import org.bouncycastle.openpgp.api.OpenPGPKey
import org.pgpainless.PGPainless
import org.pgpainless.PGPainless.Companion.buildKeyRing import org.pgpainless.PGPainless.Companion.buildKeyRing
import org.pgpainless.algorithm.KeyFlag import org.pgpainless.algorithm.KeyFlag
import org.pgpainless.algorithm.OpenPGPKeyVersion import org.pgpainless.algorithm.OpenPGPKeyVersion
@ -14,11 +15,13 @@ import org.pgpainless.key.generation.type.KeyType
import org.pgpainless.key.generation.type.eddsa_legacy.EdDSALegacyCurve import org.pgpainless.key.generation.type.eddsa_legacy.EdDSALegacyCurve
import org.pgpainless.key.generation.type.rsa.RsaLength import org.pgpainless.key.generation.type.rsa.RsaLength
import org.pgpainless.key.generation.type.xdh_legacy.XDHLegacySpec import org.pgpainless.key.generation.type.xdh_legacy.XDHLegacySpec
import org.pgpainless.policy.Policy
import org.pgpainless.util.Passphrase import org.pgpainless.util.Passphrase
class KeyRingTemplates( class KeyRingTemplates(
private val version: OpenPGPKeyVersion, private val version: OpenPGPKeyVersion,
private val creationTime: Date = Date() private val creationTime: Date = Date(),
private val policy: Policy = PGPainless.getInstance().algorithmPolicy
) { ) {
/** /**
@ -36,12 +39,17 @@ class KeyRingTemplates(
length: RsaLength, length: RsaLength,
passphrase: Passphrase = Passphrase.emptyPassphrase() passphrase: Passphrase = Passphrase.emptyPassphrase()
): OpenPGPKey = ): OpenPGPKey =
buildKeyRing(version) buildKeyRing(version, policy)
.apply { .apply {
setPrimaryKey(getBuilder(KeyType.RSA(length), KeyFlag.CERTIFY_OTHER)) setPrimaryKey(
addSubkey(getBuilder(KeyType.RSA(length), KeyFlag.SIGN_DATA)) getBuilder(KeyType.RSA(length), KeyFlag.CERTIFY_OTHER)
.setKeyCreationDate(creationTime))
addSubkey( addSubkey(
getBuilder(KeyType.RSA(length), KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE)) getBuilder(KeyType.RSA(length), KeyFlag.SIGN_DATA)
.setKeyCreationDate(creationTime))
addSubkey(
getBuilder(KeyType.RSA(length), KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE)
.setKeyCreationDate(creationTime))
setPassphrase(passphrase) setPassphrase(passphrase)
if (userId != null) { if (userId != null) {
addUserId(userId) addUserId(userId)
@ -90,7 +98,8 @@ class KeyRingTemplates(
KeyType.RSA(length), KeyType.RSA(length),
KeyFlag.CERTIFY_OTHER, KeyFlag.CERTIFY_OTHER,
KeyFlag.SIGN_DATA, KeyFlag.SIGN_DATA,
KeyFlag.ENCRYPT_COMMS)) KeyFlag.ENCRYPT_COMMS)
.setKeyCreationDate(creationTime))
setPassphrase(passphrase) setPassphrase(passphrase)
if (userId != null) { if (userId != null) {
addUserId(userId.toString()) addUserId(userId.toString())
@ -138,9 +147,12 @@ class KeyRingTemplates(
else KeyType.XDH_LEGACY(XDHLegacySpec._X25519) else KeyType.XDH_LEGACY(XDHLegacySpec._X25519)
return buildKeyRing(version) return buildKeyRing(version)
.apply { .apply {
setPrimaryKey(getBuilder(signingKeyType, KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)) setPrimaryKey(
getBuilder(signingKeyType, KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
.setKeyCreationDate(creationTime))
addSubkey( addSubkey(
getBuilder(encryptionKeyType, KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS)) getBuilder(encryptionKeyType, KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS)
.setKeyCreationDate(creationTime))
setPassphrase(passphrase) setPassphrase(passphrase)
if (userId != null) { if (userId != null) {
addUserId(userId.toString()) addUserId(userId.toString())
@ -188,10 +200,14 @@ class KeyRingTemplates(
else KeyType.XDH_LEGACY(XDHLegacySpec._X25519) else KeyType.XDH_LEGACY(XDHLegacySpec._X25519)
return buildKeyRing(version) return buildKeyRing(version)
.apply { .apply {
setPrimaryKey(getBuilder(signingKeyType, KeyFlag.CERTIFY_OTHER)) setPrimaryKey(
getBuilder(signingKeyType, KeyFlag.CERTIFY_OTHER)
.setKeyCreationDate(creationTime))
addSubkey( addSubkey(
getBuilder(encryptionKeyType, KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE)) getBuilder(encryptionKeyType, KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE)
addSubkey(getBuilder(signingKeyType, KeyFlag.SIGN_DATA)) .setKeyCreationDate(creationTime))
addSubkey(
getBuilder(signingKeyType, KeyFlag.SIGN_DATA).setKeyCreationDate(creationTime))
setPassphrase(passphrase) setPassphrase(passphrase)
if (userId != null) { if (userId != null) {
addUserId(userId) addUserId(userId)

View file

@ -266,8 +266,8 @@ class SecretKeyRingEditor(var key: OpenPGPKey, override val referenceTime: Date
callback: SelfSignatureSubpackets.Callback?, callback: SelfSignatureSubpackets.Callback?,
protector: SecretKeyRingProtector protector: SecretKeyRingProtector
): SecretKeyRingEditorInterface { ): SecretKeyRingEditorInterface {
val version = OpenPGPKeyVersion.from(secretKeyRing.getPublicKey().version) val version = OpenPGPKeyVersion.from(secretKeyRing.publicKey.version)
val keyPair = KeyRingBuilder.generateKeyPair(keySpec, OpenPGPKeyVersion.v4, referenceTime) val keyPair = KeyRingBuilder.generateKeyPair(keySpec, version)
val subkeyProtector = val subkeyProtector =
PasswordBasedSecretKeyRingProtector.forKeyId(keyPair.keyIdentifier, subkeyPassphrase) PasswordBasedSecretKeyRingProtector.forKeyId(keyPair.keyIdentifier, subkeyPassphrase)
val keyFlags = KeyFlag.fromBitmask(keySpec.subpackets.keyFlags).toMutableList() val keyFlags = KeyFlag.fromBitmask(keySpec.subpackets.keyFlags).toMutableList()