Add methods to control direct-key sigs and add unfinished test for primaryUserId test

This commit is contained in:
Paul Schaub 2024-02-03 13:16:37 +01:00
parent fa9b07d2ce
commit f08981b78c
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
2 changed files with 52 additions and 1 deletions

View File

@ -103,6 +103,7 @@ open class GenerateOpenPgpKey(
private val primaryKey =
OpenPgpComponentKeyBuilder.V4PrimaryKeyBuilder(primaryKeyType, referenceTime, policy)
private val subkeys = mutableListOf<OpenPgpComponentKeyBuilder.V4SubkeyBuilder>()
private var addDirectKeySignature = true
private val preferencesCallback =
SelfSignatureSubpackets.applyHashed {
@ -113,6 +114,16 @@ open class GenerateOpenPgpKey(
primaryFlags?.let { setKeyFlags(*it.toTypedArray()) }
}
fun directKeySignature(
subpacketsCallback: SelfSignatureSubpackets.Callback = SelfSignatureSubpackets.nop()
) = apply {
addDirectKeySignature = false
primaryKey.directKeySignature(
subpacketsCallback = preferencesCallback.then(subpacketsCallback))
}
fun noDirectKeySignature() = apply { addDirectKeySignature = false }
/**
* Add a user-id to the key. The subpackets of the binding signature are prepopulated,
* setting algorithm preferences and features. However, the subpackets can still be modified
@ -259,7 +270,9 @@ open class GenerateOpenPgpKey(
): PGPSecretKeyRing {
// add a direct key sig with preferences
primaryKey.directKeySignature(subpacketsCallback = preferencesCallback)
if (addDirectKeySignature) {
primaryKey.directKeySignature(subpacketsCallback = preferencesCallback)
}
return PGPSecretKeyRing(
mutableListOf(

View File

@ -7,10 +7,14 @@ package org.pgpainless.key.generation
import org.bouncycastle.bcpg.sig.Exportable
import org.bouncycastle.bcpg.sig.PrimaryUserID
import org.bouncycastle.bcpg.sig.Revocable
import org.bouncycastle.extensions.toAsciiArmor
import org.junit.jupiter.api.Test
import org.pgpainless.PGPainless
import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.algorithm.KeyFlag
import org.pgpainless.key.generation.type.KeyType
import org.pgpainless.key.generation.type.eddsa.EdDSACurve
import org.pgpainless.key.generation.type.xdh.XDHSpec
import org.pgpainless.policy.Policy
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets
@ -70,4 +74,38 @@ class MalformedKeyGenerationTest {
PGPainless.readKeyRing().secretKeyRing(key.encoded)!!
// TODO: Check interpretation of faulty packet
}
@Test
fun primaryUserIdOnDirectKeySig() {
val policy = Policy.getInstance()
val key =
GenerateOpenPgpKey(policy)
.buildV4Key(
KeyType.EDDSA(EdDSACurve._Ed25519),
listOf(KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA))
.directKeySignature(
SelfSignatureSubpackets.applyHashed {
setPrimaryUserId()
setPreferredHashAlgorithms(HashAlgorithm.SHA224)
})
.addUserId(
"Alice <alice@pgpainless.org>",
SelfSignatureSubpackets.applyHashed {
setPrimaryUserId(null)
setPreferredHashAlgorithms(HashAlgorithm.SHA256)
})
.addUserId(
"Bob <bob@pgpainless.org>",
SelfSignatureSubpackets.applyHashed {
setPrimaryUserId()
setPreferredHashAlgorithms(HashAlgorithm.SHA384)
})
.addEncryptionSubkey(KeyType.XDH(XDHSpec._X25519))
.build()
println(key.toAsciiArmor())
// TODO: Test, which hash algo is used when we encrypt+sign a message for this key.
// Correct would be SHA384, since this is the primary user-id.
// PrimaryUserID packets on the DK sig shall be ignored.
}
}