mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-05 03:55:58 +01:00
Rename KeyGenerator and add MalformedKeyGenerationTest
This commit is contained in:
parent
6df4211985
commit
44a3096467
3 changed files with 75 additions and 22 deletions
|
@ -24,31 +24,51 @@ import org.pgpainless.signature.subpackets.SelfSignatureSubpackets
|
|||
* @param referenceTime reference time for key generation
|
||||
* @param preferences set of preferred algorithms and enabled features
|
||||
*/
|
||||
open class OpenPgpKeyBuilder(
|
||||
protected val policy: Policy,
|
||||
protected val referenceTime: Date = Date(),
|
||||
protected val preferences: AlgorithmSuite = policy.keyGenerationAlgorithmSuite
|
||||
open class GenerateOpenPgpKey(
|
||||
private val policy: Policy,
|
||||
private val referenceTime: Date = Date(),
|
||||
private val preferences: AlgorithmSuite = policy.keyGenerationAlgorithmSuite
|
||||
) {
|
||||
|
||||
abstract class OpenPgpKeyBuilder(
|
||||
protected val policy: Policy,
|
||||
protected val referenceTime: Date,
|
||||
protected val preferences: AlgorithmSuite
|
||||
) {
|
||||
|
||||
/**
|
||||
* Make sure, that the chosen [KeyType] is allowed.
|
||||
*/
|
||||
open fun sanitizePublicKeyAlgorithms(keyType: KeyType, policy: Policy) {
|
||||
verifyAlgorithmComplianceWithPolicy(keyType, policy)
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure, that the chosen [KeyType] complies to the given [Policy] by comparing it to the
|
||||
* [Policy.PublicKeyAlgorithmPolicy].
|
||||
*
|
||||
* @throws IllegalArgumentException if [keyType] fails to be accepted by [policy]
|
||||
*/
|
||||
private fun verifyAlgorithmComplianceWithPolicy(keyType: KeyType, policy: Policy) {
|
||||
val algorithm = keyType.algorithm
|
||||
val bitStrength = keyType.bitStrength
|
||||
require(policy.publicKeyAlgorithmPolicy.isAcceptable(algorithm, bitStrength)) {
|
||||
"Public key algorithm policy violation: $algorithm with bit strength $bitStrength is not acceptable."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an OpenPGP v4 key. The result will be a key compliant to RFC4880, RFC6637.
|
||||
*
|
||||
* @param keyType type of the primary key
|
||||
* @param flags key flags for the primary key. Defaults to [KeyFlag.CERTIFY_OTHER].
|
||||
* @return [V4OpenPgpKeyBuilder] which can be further modified, e.g. add subkeys, user-ids etc.
|
||||
* @return [V4GenerateOpenPgpKey] which can be further modified, e.g. add subkeys, user-ids etc.
|
||||
*/
|
||||
fun buildV4Key(
|
||||
keyType: KeyType,
|
||||
flags: List<KeyFlag>? = listOf(KeyFlag.CERTIFY_OTHER)
|
||||
): V4OpenPgpKeyBuilder = V4OpenPgpKeyBuilder(keyType, flags, policy, referenceTime, preferences)
|
||||
|
||||
internal fun verifyAlgorithmComplianceWithPolicy(keyType: KeyType, policy: Policy) {
|
||||
val algorithm = keyType.algorithm
|
||||
val bitStrength = keyType.bitStrength
|
||||
require(policy.publicKeyAlgorithmPolicy.isAcceptable(algorithm, bitStrength)) {
|
||||
"Public key algorithm policy violation: $algorithm with bit strength $bitStrength is not acceptable."
|
||||
}
|
||||
}
|
||||
): V4GenerateOpenPgpKey = V4GenerateOpenPgpKey(keyType, flags, policy, referenceTime, preferences)
|
||||
|
||||
/**
|
||||
* Builder for version 4 OpenPGP keys.
|
||||
|
@ -59,7 +79,7 @@ open class OpenPgpKeyBuilder(
|
|||
* @param referenceTime reference time for key generation
|
||||
* @param preferences set of algorithm preferences and enabled features for the key
|
||||
*/
|
||||
class V4OpenPgpKeyBuilder
|
||||
class V4GenerateOpenPgpKey
|
||||
internal constructor(
|
||||
primaryKeyType: KeyType,
|
||||
primaryFlags: List<KeyFlag>?,
|
||||
|
@ -69,7 +89,7 @@ open class OpenPgpKeyBuilder(
|
|||
) : OpenPgpKeyBuilder(policy, referenceTime, preferences) {
|
||||
|
||||
init {
|
||||
verifyAlgorithmComplianceWithPolicy(primaryKeyType, policy)
|
||||
sanitizePublicKeyAlgorithms(primaryKeyType, policy)
|
||||
}
|
||||
|
||||
private val primaryKey =
|
||||
|
@ -152,7 +172,7 @@ open class OpenPgpKeyBuilder(
|
|||
subkeyBuilder: BaseOpenPgpKeyBuilder.BaseV4SubkeyBuilder,
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback = SelfSignatureSubpackets.nop()
|
||||
) = apply {
|
||||
verifyAlgorithmComplianceWithPolicy(subkeyBuilder.type, policy)
|
||||
sanitizePublicKeyAlgorithms(subkeyBuilder.type, policy)
|
||||
subkeys.add(subkeyBuilder.bindingSignature(subpacketsCallback = subpacketsCallback))
|
||||
}
|
||||
|
|
@ -15,13 +15,13 @@ import org.pgpainless.key.protection.SecretKeyRingProtector
|
|||
import org.pgpainless.policy.Policy
|
||||
import org.pgpainless.util.DateUtil
|
||||
|
||||
class OpenPgpKeyBuilderTest {
|
||||
class GenerateOpenPgpKeyTest {
|
||||
|
||||
@Test
|
||||
fun test() {
|
||||
val date = DateUtil.parseUTCDate("2020-04-01 10:00:00 UTC")
|
||||
val key =
|
||||
OpenPgpKeyBuilder(Policy.getInstance(), date)
|
||||
GenerateOpenPgpKey(Policy.getInstance(), date)
|
||||
.buildV4Key(KeyType.EDDSA(EdDSACurve._Ed25519), listOf(KeyFlag.CERTIFY_OTHER))
|
||||
.addUserId("Alice")
|
||||
.addUserAttribute(
|
||||
|
@ -37,7 +37,7 @@ class OpenPgpKeyBuilderTest {
|
|||
@Test
|
||||
fun minimal() {
|
||||
val key =
|
||||
OpenPgpKeyBuilder(Policy.getInstance())
|
||||
GenerateOpenPgpKey(Policy.getInstance())
|
||||
.buildV4Key(KeyType.EDDSA(EdDSACurve._Ed25519), listOf(KeyFlag.CERTIFY_OTHER))
|
||||
.build()
|
||||
println(PGPainless.asciiArmor(key))
|
||||
|
@ -46,7 +46,7 @@ class OpenPgpKeyBuilderTest {
|
|||
@Test
|
||||
fun minimalWithUserId() {
|
||||
val key =
|
||||
OpenPgpKeyBuilder(Policy.getInstance())
|
||||
GenerateOpenPgpKey(Policy.getInstance())
|
||||
.buildV4Key(KeyType.EDDSA(EdDSACurve._Ed25519), listOf(KeyFlag.CERTIFY_OTHER))
|
||||
.addUserId("Alice <alice@pgpainless.org>")
|
||||
.build()
|
||||
|
@ -60,7 +60,7 @@ class OpenPgpKeyBuilderTest {
|
|||
Policy(
|
||||
publicKeyAlgorithmPolicy =
|
||||
Policy.PublicKeyAlgorithmPolicy(mapOf(PublicKeyAlgorithm.RSA_GENERAL to 4096)))
|
||||
val builder = OpenPgpKeyBuilder(policy)
|
||||
val builder = GenerateOpenPgpKey(policy)
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
builder.buildV4Key(KeyType.RSA(RsaLength._3072)) // too weak
|
|
@ -0,0 +1,33 @@
|
|||
// SPDX-FileCopyrightText: 2024 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package org.pgpainless.key.generation
|
||||
|
||||
import org.bouncycastle.bcpg.sig.PrimaryUserID
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.pgpainless.PGPainless
|
||||
import org.pgpainless.key.generation.type.KeyType
|
||||
import org.pgpainless.key.generation.type.eddsa.EdDSACurve
|
||||
import org.pgpainless.policy.Policy
|
||||
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets
|
||||
|
||||
class MalformedKeyGenerationTest {
|
||||
|
||||
@Test
|
||||
fun malformedPrimaryUserIdSubpacket() {
|
||||
val userId = "Alice <alice@pgpainless.org>"
|
||||
val key = GenerateOpenPgpKey(Policy.getInstance())
|
||||
.buildV4Key(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.addUserId(userId,
|
||||
SelfSignatureSubpackets.applyHashed {
|
||||
setPrimaryUserId(PrimaryUserID(false, false, byteArrayOf(0x02)))
|
||||
})
|
||||
.build()
|
||||
|
||||
println(PGPainless.asciiArmor(key))
|
||||
|
||||
PGPainless.readKeyRing().secretKeyRing(key.encoded)!!
|
||||
// TODO: Check interpretation of faulty PrimaryUserID packet
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue