mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-05 03:55:58 +01:00
Improve Key Generation API
This commit is contained in:
parent
20002efbf6
commit
b4240ac9f7
7 changed files with 219 additions and 154 deletions
|
@ -0,0 +1,24 @@
|
|||
// SPDX-FileCopyrightText: 2024 Paul Schaub <vanitasvitae@fsfe.org>
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package openpgp
|
||||
|
||||
import org.pgpainless.util.Passphrase
|
||||
|
||||
/**
|
||||
* Extension function to convert a nullable [CharSequence] into an [Array]. Iff [this] is `null`,
|
||||
* then return an empty array, otherwise return an array only consisting of [this].
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
fun CharSequence?.toArray(): Array<CharSequence> = this?.let { arrayOf(it) } ?: emptyArray()
|
||||
|
||||
/**
|
||||
* Return a [Passphrase] from this [CharSequence]. Iff [this] is `null` or blank, then this method
|
||||
* returns [Passphrase.emptyPassphrase], otherwise it returns [Passphrase.fromPassword].
|
||||
*
|
||||
* @return passphrase
|
||||
*/
|
||||
fun CharSequence?.toPassphrase(): Passphrase =
|
||||
this?.let { Passphrase.fromPassword(it) } ?: Passphrase.emptyPassphrase()
|
|
@ -15,6 +15,7 @@ import org.pgpainless.encryption_signing.EncryptionBuilder
|
|||
import org.pgpainless.key.certification.CertifyCertificate
|
||||
import org.pgpainless.key.generation.KeyRingBuilder
|
||||
import org.pgpainless.key.generation.KeyRingTemplates
|
||||
import org.pgpainless.key.generation.OpenPgpKeyGenerator
|
||||
import org.pgpainless.key.info.KeyRingInfo
|
||||
import org.pgpainless.key.modification.secretkeyring.SecretKeyRingEditor
|
||||
import org.pgpainless.key.parsing.KeyRingReader
|
||||
|
@ -26,19 +27,30 @@ class PGPainless private constructor() {
|
|||
|
||||
companion object {
|
||||
|
||||
/** Generate an OpenPGP key. */
|
||||
@JvmOverloads
|
||||
@JvmStatic
|
||||
fun generateOpenPgpKey(policy: Policy = getPolicy()) = OpenPgpKeyGenerator(policy)
|
||||
|
||||
/**
|
||||
* Generate a fresh OpenPGP key ring from predefined templates.
|
||||
*
|
||||
* @return templates
|
||||
*/
|
||||
@JvmStatic fun generateKeyRing() = KeyRingTemplates()
|
||||
@Deprecated(
|
||||
"Deprecated in favor of new API",
|
||||
ReplaceWith("generateOpenPgpKey().buildV4Key().fromTemplate()"))
|
||||
@JvmStatic
|
||||
fun generateKeyRing() = KeyRingTemplates()
|
||||
|
||||
/**
|
||||
* Build a custom OpenPGP key ring.
|
||||
*
|
||||
* @return builder
|
||||
*/
|
||||
@JvmStatic fun buildKeyRing() = KeyRingBuilder()
|
||||
@Deprecated("Deprecated in favor of new API", ReplaceWith("generateOpenPgpKey()"))
|
||||
@JvmStatic
|
||||
fun buildKeyRing() = KeyRingBuilder()
|
||||
|
||||
/**
|
||||
* Read an existing OpenPGP key ring.
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
package org.pgpainless.key.generation
|
||||
|
||||
import openpgp.toArray
|
||||
import openpgp.toPassphrase
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing
|
||||
import org.pgpainless.algorithm.KeyFlag
|
||||
import org.pgpainless.key.generation.type.KeyType
|
||||
|
@ -30,15 +32,13 @@ class KeyRingTemplates {
|
|||
length: RsaLength,
|
||||
passphrase: Passphrase = Passphrase.emptyPassphrase()
|
||||
): PGPSecretKeyRing =
|
||||
OpenPgpKeyGenerator.buildV4Key()
|
||||
.setPrimaryKey(KeyType.RSA(length), listOf(KeyFlag.CERTIFY_OTHER)) {
|
||||
if (userId != null) {
|
||||
addUserId(userId)
|
||||
}
|
||||
}
|
||||
.addSigningSubkey(KeyType.RSA(length))
|
||||
.addEncryptionSubkey(KeyType.RSA(length))
|
||||
.build(passphrase)
|
||||
OpenPgpKeyGenerator()
|
||||
.buildV4Key()
|
||||
.fromTemplate()
|
||||
.composedRsa(
|
||||
userId = userId.toArray(),
|
||||
length = length,
|
||||
protector = SecretKeyRingProtector.unlockAnyKeyWith(passphrase))
|
||||
|
||||
/**
|
||||
* Generate an RSA OpenPGP key consisting of an RSA primary key used for certification, a
|
||||
|
@ -50,14 +50,11 @@ class KeyRingTemplates {
|
|||
* keys.
|
||||
* @return key
|
||||
*/
|
||||
fun rsaKeyRing(userId: CharSequence?, length: RsaLength, password: String?): PGPSecretKeyRing =
|
||||
password.let {
|
||||
if (it.isNullOrBlank()) {
|
||||
rsaKeyRing(userId, length, Passphrase.emptyPassphrase())
|
||||
} else {
|
||||
rsaKeyRing(userId, length, Passphrase.fromPassword(it))
|
||||
}
|
||||
}
|
||||
fun rsaKeyRing(
|
||||
userId: CharSequence?,
|
||||
length: RsaLength,
|
||||
password: CharSequence?
|
||||
): PGPSecretKeyRing = rsaKeyRing(userId, length, password.toPassphrase())
|
||||
|
||||
/**
|
||||
* Creates a simple RSA KeyPair of length {@code length} with user-id {@code userId}. The
|
||||
|
@ -75,19 +72,13 @@ class KeyRingTemplates {
|
|||
length: RsaLength,
|
||||
passphrase: Passphrase = Passphrase.emptyPassphrase()
|
||||
): PGPSecretKeyRing =
|
||||
OpenPgpKeyGenerator.buildV4Key()
|
||||
.setPrimaryKey(
|
||||
KeyType.RSA(length),
|
||||
listOf(
|
||||
KeyFlag.CERTIFY_OTHER,
|
||||
KeyFlag.SIGN_DATA,
|
||||
KeyFlag.ENCRYPT_COMMS,
|
||||
KeyFlag.ENCRYPT_STORAGE)) {
|
||||
if (userId != null) {
|
||||
addUserId(userId)
|
||||
}
|
||||
}
|
||||
.build(passphrase)
|
||||
OpenPgpKeyGenerator()
|
||||
.buildV4Key()
|
||||
.fromTemplate()
|
||||
.singleRsa(
|
||||
userId = userId.toArray(),
|
||||
length = length,
|
||||
protector = SecretKeyRingProtector.unlockAnyKeyWith(passphrase))
|
||||
|
||||
/**
|
||||
* Creates a simple RSA KeyPair of length {@code length} with user-id {@code userId}. The
|
||||
|
@ -99,14 +90,8 @@ class KeyRingTemplates {
|
|||
* @param password Password of the key. Can be null or blank for unencrypted keys.
|
||||
* @return {@link PGPSecretKeyRing} containing the KeyPair.
|
||||
*/
|
||||
fun simpleRsaKeyRing(userId: CharSequence?, length: RsaLength, password: String?) =
|
||||
password.let {
|
||||
if (it.isNullOrBlank()) {
|
||||
simpleRsaKeyRing(userId, length, Passphrase.emptyPassphrase())
|
||||
} else {
|
||||
simpleRsaKeyRing(userId, length, Passphrase.fromPassword(it))
|
||||
}
|
||||
}
|
||||
fun simpleRsaKeyRing(userId: CharSequence?, length: RsaLength, password: CharSequence?) =
|
||||
simpleRsaKeyRing(userId, length, password.toPassphrase())
|
||||
|
||||
/**
|
||||
* Creates a key ring consisting of an ed25519 EdDSA primary key and a X25519 XDH subkey. The
|
||||
|
@ -122,7 +107,8 @@ class KeyRingTemplates {
|
|||
userId: CharSequence?,
|
||||
passphrase: Passphrase = Passphrase.emptyPassphrase()
|
||||
): PGPSecretKeyRing =
|
||||
OpenPgpKeyGenerator.buildV4Key()
|
||||
OpenPgpKeyGenerator()
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519),
|
||||
listOf(KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)) {
|
||||
|
@ -142,14 +128,8 @@ class KeyRingTemplates {
|
|||
* @param password Password of the private key. Can be null or blank for an unencrypted key.
|
||||
* @return {@link PGPSecretKeyRing} containing the key pairs.
|
||||
*/
|
||||
fun simpleEcKeyRing(userId: CharSequence?, password: String?): PGPSecretKeyRing =
|
||||
password.let {
|
||||
if (it.isNullOrBlank()) {
|
||||
simpleEcKeyRing(userId, Passphrase.emptyPassphrase())
|
||||
} else {
|
||||
simpleEcKeyRing(userId, Passphrase.fromPassword(it))
|
||||
}
|
||||
}
|
||||
fun simpleEcKeyRing(userId: CharSequence?, password: CharSequence?): PGPSecretKeyRing =
|
||||
simpleEcKeyRing(userId, password.toPassphrase())
|
||||
|
||||
/**
|
||||
* Generate a modern PGP key ring consisting of an ed25519 EdDSA primary key which is used to
|
||||
|
@ -164,17 +144,12 @@ class KeyRingTemplates {
|
|||
userId: CharSequence?,
|
||||
passphrase: Passphrase = Passphrase.emptyPassphrase()
|
||||
): PGPSecretKeyRing =
|
||||
OpenPgpKeyGenerator.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519), listOf(KeyFlag.CERTIFY_OTHER)) {
|
||||
if (userId != null) {
|
||||
addUserId(userId)
|
||||
}
|
||||
}
|
||||
.addEncryptionSubkey(KeyType.XDH(XDHSpec._X25519))
|
||||
.addSigningSubkey(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.build(
|
||||
if (passphrase.isEmpty) SecretKeyRingProtector.unprotectedKeys()
|
||||
else SecretKeyRingProtector.unlockAnyKeyWith(passphrase))
|
||||
OpenPgpKeyGenerator()
|
||||
.buildV4Key()
|
||||
.fromTemplate()
|
||||
.ed25519Curve25519(
|
||||
userId = userId.toArray(),
|
||||
protector = SecretKeyRingProtector.unlockAnyKeyWith(passphrase))
|
||||
|
||||
/**
|
||||
* Generate a modern PGP key ring consisting of an ed25519 EdDSA primary key which is used to
|
||||
|
@ -184,12 +159,6 @@ class KeyRingTemplates {
|
|||
* @param password passphrase for the private key. Can be null or blank for an unencrypted key.
|
||||
* @return key ring
|
||||
*/
|
||||
fun modernKeyRing(userId: CharSequence?, password: String?): PGPSecretKeyRing =
|
||||
password.let {
|
||||
if (it.isNullOrBlank()) {
|
||||
modernKeyRing(userId, Passphrase.emptyPassphrase())
|
||||
} else {
|
||||
modernKeyRing(userId, Passphrase.fromPassword(it))
|
||||
}
|
||||
}
|
||||
fun modernKeyRing(userId: CharSequence?, password: CharSequence?): PGPSecretKeyRing =
|
||||
modernKeyRing(userId, password.toPassphrase())
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.pgpainless.bouncycastle.extensions.plusCertification
|
|||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.pgpainless.key.generation.DefinePrimaryKey.PrimaryKeyBuilder
|
||||
import org.pgpainless.key.generation.DefineSubkeys.SubkeyBuilder
|
||||
import org.pgpainless.key.generation.OpenPgpKeyTemplates.Companion.v4
|
||||
import org.pgpainless.key.generation.type.KeyType
|
||||
import org.pgpainless.key.generation.type.eddsa.EdDSACurve
|
||||
import org.pgpainless.key.generation.type.rsa.RsaLength
|
||||
|
@ -37,8 +38,16 @@ import org.pgpainless.signature.builder.SubkeyBindingSignatureBuilder
|
|||
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets
|
||||
import org.pgpainless.util.Passphrase
|
||||
|
||||
/**
|
||||
* Function block that is applied to the OpenPGP [PrimaryKeyBuilder]. Within this block, you add
|
||||
* User-IDs, User-Attributes and Direct-Key signatures on the primary key.
|
||||
*/
|
||||
typealias PrimaryKeyBlock = (PrimaryKeyBuilder.() -> Unit)
|
||||
|
||||
/**
|
||||
* Function block that is applied to an OpenPGP [SubkeyBuilder]. Here you typically add
|
||||
* subkey-binding signatures.
|
||||
*/
|
||||
typealias SubkeyBlock = (SubkeyBuilder.() -> Unit)
|
||||
|
||||
/**
|
||||
|
@ -54,25 +63,20 @@ typealias SubkeyBlock = (SubkeyBuilder.() -> Unit)
|
|||
* You can switch from the opinionated API to the unopinionated API by calling `unopinionated()` on
|
||||
* the builder.
|
||||
*/
|
||||
class OpenPgpKeyGenerator internal constructor() {
|
||||
class OpenPgpKeyGenerator(private val policy: Policy = PGPainless.getPolicy()) {
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Build a version 4 OpenPGP secret key.
|
||||
*
|
||||
* @param policy policy to ensure algorithm compliance and to determine default algorithms
|
||||
* @param creationTime creation time for the secret key
|
||||
* @param preferences suite of algorithm preferences and enabled features
|
||||
*/
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun buildV4Key(
|
||||
policy: Policy = PGPainless.getPolicy(),
|
||||
creationTime: Date = Date(),
|
||||
preferences: AlgorithmSuite = policy.keyGenerationAlgorithmSuite
|
||||
): OpinionatedDefinePrimaryKeyV4 {
|
||||
return OpinionatedDefinePrimaryKeyV4(policy, creationTime, preferences)
|
||||
}
|
||||
/**
|
||||
* Build a version 4 OpenPGP secret key.
|
||||
*
|
||||
* @param creationTime creation time for the secret key
|
||||
* @param preferences suite of algorithm preferences and enabled features
|
||||
*/
|
||||
@JvmOverloads
|
||||
fun buildV4Key(
|
||||
creationTime: Date = Date(),
|
||||
preferences: AlgorithmSuite = policy.keyGenerationAlgorithmSuite
|
||||
): OpinionatedDefinePrimaryKeyV4 {
|
||||
return OpinionatedDefinePrimaryKeyV4(policy, creationTime, preferences)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,6 +215,14 @@ internal constructor(val policy: Policy, val creationTime: Date, val preferences
|
|||
// Do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a [OpenPgpKeyTemplates] object which provides factory methods for generating OpenPGP
|
||||
* keys from templates.
|
||||
*
|
||||
* @return templates
|
||||
*/
|
||||
abstract fun fromTemplate(): OpenPgpKeyTemplates
|
||||
|
||||
/**
|
||||
* Function that can be applied to the primary key.
|
||||
*
|
||||
|
@ -1094,11 +1106,13 @@ class PrimaryKeyBuilderV4 internal constructor(keyPair: PGPKeyPair, builder: Def
|
|||
this.keyPair
|
||||
}
|
||||
}
|
||||
|
||||
override fun fromTemplate(): OpenPgpKeyTemplates.V4 = v4()
|
||||
}
|
||||
}
|
||||
|
||||
/** Templates for OpenPGP key generation. */
|
||||
class OpenPgpKeyTemplates private constructor() {
|
||||
open class OpenPgpKeyTemplates private constructor() {
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -1111,7 +1125,7 @@ class OpenPgpKeyTemplates private constructor() {
|
|||
}
|
||||
|
||||
/** Templates for version 4 OpenPGP keys. Version 4 keys are compliant to RFC4880. */
|
||||
class V4 internal constructor() {
|
||||
class V4 : OpenPgpKeyTemplates() {
|
||||
|
||||
/**
|
||||
* Generate an OpenPGP key that consists of an Ed25519 primary key used for certification of
|
||||
|
@ -1123,9 +1137,11 @@ class OpenPgpKeyTemplates private constructor() {
|
|||
*/
|
||||
fun ed25519Curve25519(
|
||||
vararg userId: CharSequence,
|
||||
creationTime: Date = Date()
|
||||
creationTime: Date = Date(),
|
||||
protector: SecretKeyRingProtector = SecretKeyRingProtector.unprotectedKeys()
|
||||
): PGPSecretKeyRing =
|
||||
OpenPgpKeyGenerator.buildV4Key(creationTime = creationTime)
|
||||
OpenPgpKeyGenerator()
|
||||
.buildV4Key(creationTime = creationTime)
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
// Add UserIDs
|
||||
userId.forEachIndexed { index, uid ->
|
||||
|
@ -1145,7 +1161,7 @@ class OpenPgpKeyTemplates private constructor() {
|
|||
.addSigningSubkey(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
// encryption key
|
||||
.addEncryptionSubkey(KeyType.XDH(XDHSpec._X25519))
|
||||
.build()
|
||||
.build(protector)
|
||||
|
||||
/**
|
||||
* Generate an OpenPGP key that consists of an RSA primary key used for certification of
|
||||
|
@ -1159,9 +1175,11 @@ class OpenPgpKeyTemplates private constructor() {
|
|||
fun composedRsa(
|
||||
vararg userId: CharSequence,
|
||||
creationTime: Date = Date(),
|
||||
length: RsaLength = RsaLength._4096
|
||||
length: RsaLength = RsaLength._4096,
|
||||
protector: SecretKeyRingProtector = SecretKeyRingProtector.unprotectedKeys()
|
||||
): PGPSecretKeyRing =
|
||||
OpenPgpKeyGenerator.buildV4Key(creationTime = creationTime)
|
||||
OpenPgpKeyGenerator()
|
||||
.buildV4Key(creationTime = creationTime)
|
||||
.setPrimaryKey(KeyType.RSA(length)) {
|
||||
// Add UserIDs
|
||||
userId.forEachIndexed { index, uid ->
|
||||
|
@ -1181,7 +1199,7 @@ class OpenPgpKeyTemplates private constructor() {
|
|||
.addSigningSubkey(KeyType.RSA(length))
|
||||
// encryption key
|
||||
.addEncryptionSubkey(KeyType.RSA(length))
|
||||
.build()
|
||||
.build(protector)
|
||||
|
||||
/**
|
||||
* Generate an OpenPGP key consisting of a single RSA key that is used for certification of
|
||||
|
@ -1194,9 +1212,11 @@ class OpenPgpKeyTemplates private constructor() {
|
|||
fun singleRsa(
|
||||
vararg userId: CharSequence,
|
||||
creationTime: Date = Date(),
|
||||
length: RsaLength = RsaLength._4096
|
||||
length: RsaLength = RsaLength._4096,
|
||||
protector: SecretKeyRingProtector = SecretKeyRingProtector.unprotectedKeys()
|
||||
): PGPSecretKeyRing =
|
||||
OpenPgpKeyGenerator.buildV4Key(creationTime = creationTime)
|
||||
OpenPgpKeyGenerator()
|
||||
.buildV4Key(creationTime = creationTime)
|
||||
.setPrimaryKey(KeyType.RSA(length)) {
|
||||
userId.forEach { addUserId(it) }
|
||||
addDirectKeySignature(
|
||||
|
@ -1208,6 +1228,6 @@ class OpenPgpKeyTemplates private constructor() {
|
|||
KeyFlag.ENCRYPT_STORAGE)
|
||||
})
|
||||
}
|
||||
.build()
|
||||
.build(protector)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import org.pgpainless.PGPainless
|
|||
import org.pgpainless.algorithm.HashAlgorithm
|
||||
import org.pgpainless.algorithm.KeyFlag
|
||||
import org.pgpainless.bouncycastle.extensions.directKeySignatures
|
||||
import org.pgpainless.key.generation.OpenPgpKeyGenerator
|
||||
import org.pgpainless.key.generation.type.KeyType
|
||||
import org.pgpainless.key.generation.type.eddsa.EdDSACurve
|
||||
import org.pgpainless.key.generation.type.xdh.XDHSpec
|
||||
|
@ -21,19 +20,26 @@ class KeyWithInacceptableSelfSignatureTest {
|
|||
|
||||
@Test
|
||||
fun `key with inacceptable self-signature is not usable`() {
|
||||
val genPolicy = Policy().apply {
|
||||
certificationSignatureHashAlgorithmPolicy = Policy.HashAlgorithmPolicy(
|
||||
HashAlgorithm.SHA1, listOf(HashAlgorithm.SHA1))
|
||||
}
|
||||
val genPolicy =
|
||||
Policy().apply {
|
||||
certificationSignatureHashAlgorithmPolicy =
|
||||
Policy.HashAlgorithmPolicy(HashAlgorithm.SHA1, listOf(HashAlgorithm.SHA1))
|
||||
}
|
||||
|
||||
val key = OpenPgpKeyGenerator.buildV4Key(genPolicy)
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519), listOf(KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA))
|
||||
.addEncryptionSubkey(KeyType.XDH(XDHSpec._X25519))
|
||||
.build()
|
||||
val key =
|
||||
PGPainless.generateOpenPgpKey(genPolicy)
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519),
|
||||
listOf(KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA))
|
||||
.addEncryptionSubkey(KeyType.XDH(XDHSpec._X25519))
|
||||
.build()
|
||||
|
||||
assertEquals(HashAlgorithm.SHA1,
|
||||
key.publicKey.directKeySignatures.single().hashAlgorithm
|
||||
.let { HashAlgorithm.requireFromId(it) })
|
||||
assertEquals(
|
||||
HashAlgorithm.SHA1,
|
||||
key.publicKey.directKeySignatures.single().hashAlgorithm.let {
|
||||
HashAlgorithm.requireFromId(it)
|
||||
})
|
||||
|
||||
val info = PGPainless.inspectKeyRing(key)
|
||||
assertFalse(info.isUsableForSigning)
|
||||
|
|
|
@ -24,7 +24,8 @@ class MalformedKeyGenerationTest {
|
|||
fun malformedPrimaryUserIdSubpacket() {
|
||||
val userId = "Alice <alice@pgpainless.org>"
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key(Policy())
|
||||
PGPainless.generateOpenPgpKey(Policy())
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserId(
|
||||
userId,
|
||||
|
@ -43,7 +44,8 @@ class MalformedKeyGenerationTest {
|
|||
@Test
|
||||
fun malformedExportableSubpacket() {
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key(Policy())
|
||||
PGPainless.generateOpenPgpKey(Policy())
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserId(
|
||||
"Alice <alice@pgpainless.org>",
|
||||
|
@ -62,7 +64,8 @@ class MalformedKeyGenerationTest {
|
|||
@Test
|
||||
fun malformedRevocableSubpacket() {
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key(Policy())
|
||||
PGPainless.generateOpenPgpKey(Policy())
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserId(
|
||||
"Alice <alice@pgpainless.org>",
|
||||
|
@ -82,7 +85,8 @@ class MalformedKeyGenerationTest {
|
|||
fun primaryUserIdOnDirectKeySig() {
|
||||
val policy = Policy()
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key(policy)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519),
|
||||
listOf(KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)) {
|
||||
|
|
|
@ -38,7 +38,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
@Test
|
||||
fun `minimal call with opinionated builder adds a default DK sig but no user info`() {
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key()
|
||||
PGPainless.generateOpenPgpKey()
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.build()
|
||||
|
||||
|
@ -55,7 +56,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
@Test
|
||||
fun `minimal call with unopinionated builder does not add a default DK sig`() {
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key()
|
||||
PGPainless.generateOpenPgpKey()
|
||||
.buildV4Key()
|
||||
.unopinionated()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.build()
|
||||
|
@ -68,7 +70,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
@Test
|
||||
fun `adding a direct-key signature with the opinionated builder omits the default DK sig`() {
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key()
|
||||
PGPainless.generateOpenPgpKey()
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addDirectKeySignature() // "overwrites" the default dk sig
|
||||
}
|
||||
|
@ -82,7 +85,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
@Test
|
||||
fun `adding two user-ids will mark the first one as primary`() {
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key()
|
||||
PGPainless.generateOpenPgpKey()
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserId("Primary <primary@example.com>")
|
||||
addUserId("Non Primary <non-primary@example.com>")
|
||||
|
@ -96,7 +100,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
@Test
|
||||
fun `adding two user-ids but mark the first as non-primary will mark the second one as primary`() {
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key()
|
||||
PGPainless.generateOpenPgpKey()
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserId(
|
||||
"Non Primary <non-primary@example.com>",
|
||||
|
@ -126,7 +131,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
.generate()
|
||||
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key(policy)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserAttribute(attr1) // primary, since it is the first
|
||||
addUserAttribute(attr2) // non-primary
|
||||
|
@ -160,7 +166,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
.generate()
|
||||
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key(policy)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserId(userId)
|
||||
addUserAttribute(userAttribute)
|
||||
|
@ -186,7 +193,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
@Test
|
||||
fun `adding signing key will add embedded back-signature`() {
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key()
|
||||
PGPainless.generateOpenPgpKey()
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.addSubkey(KeyType.EDDSA(EdDSACurve._Ed25519), listOf(KeyFlag.SIGN_DATA))
|
||||
.build()
|
||||
|
@ -205,7 +213,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
@Test
|
||||
fun testUnopinionatedV4() {
|
||||
// Unopinionated
|
||||
OpenPgpKeyGenerator.buildV4Key()
|
||||
PGPainless.generateOpenPgpKey()
|
||||
.buildV4Key()
|
||||
.unopinionated()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addDirectKeySignature()
|
||||
|
@ -221,7 +230,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
fun testOpinionatedV4() {
|
||||
// Opinionated
|
||||
val time = DateUtil.parseUTCDate("2024-01-01 00:00:00 UTC")
|
||||
OpenPgpKeyGenerator.buildV4Key(creationTime = time)
|
||||
PGPainless.generateOpenPgpKey()
|
||||
.buildV4Key(creationTime = time)
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519), listOf(KeyFlag.CERTIFY_OTHER)) {
|
||||
addUserId("Alice <alice@pgpainless.org>")
|
||||
}
|
||||
|
@ -254,7 +264,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
|
||||
@Test
|
||||
fun test() {
|
||||
OpenPgpKeyGenerator.buildV4Key()
|
||||
PGPainless.generateOpenPgpKey()
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.RSA(RsaLength._3072), keyFlags = listOf(KeyFlag.CERTIFY_OTHER))
|
||||
.build()
|
||||
.toAsciiArmor()
|
||||
|
@ -268,7 +279,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
Policy.PublicKeyAlgorithmPolicy(buildMap { put(PublicKeyAlgorithm.RSA_GENERAL, 3072) })
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
OpenPgpKeyGenerator.buildV4Key(policy)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
// opinionated builder verifies PK parameters
|
||||
.setPrimaryKey(KeyType.RSA(RsaLength._2048)) // too weak
|
||||
}
|
||||
|
@ -280,7 +292,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
policy.publicKeyAlgorithmPolicy =
|
||||
Policy.PublicKeyAlgorithmPolicy(buildMap { put(PublicKeyAlgorithm.RSA_GENERAL, 3072) })
|
||||
|
||||
OpenPgpKeyGenerator.buildV4Key(policy)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
.unopinionated() // unopinionated builder allows for non-compliant configurations
|
||||
.setPrimaryKey(KeyType.RSA(RsaLength._2048))
|
||||
}
|
||||
|
@ -288,7 +301,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
@Test
|
||||
fun `skip default DirectKey signature will not add one`() {
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key()
|
||||
PGPainless.generateOpenPgpKey()
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519)) { skipDefaultSignature() }
|
||||
.build()
|
||||
|
||||
|
@ -304,7 +318,7 @@ class OpenPgpKeyGeneratorTest {
|
|||
fun `opinionated add UserID with weak hash algorithm fails`() {
|
||||
val policy = Policy()
|
||||
assertThrows<IllegalArgumentException> {
|
||||
OpenPgpKeyGenerator.buildV4Key(policy).setPrimaryKey(
|
||||
PGPainless.generateOpenPgpKey(policy).buildV4Key().setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserId("Alice <alice@example.org>", hashAlgorithm = HashAlgorithm.SHA1)
|
||||
}
|
||||
|
@ -314,7 +328,7 @@ class OpenPgpKeyGeneratorTest {
|
|||
@Test
|
||||
fun `unopinionated add UserID with weak hash algorithm is okay`() {
|
||||
val policy = Policy()
|
||||
OpenPgpKeyGenerator.buildV4Key(policy).unopinionated().setPrimaryKey(
|
||||
PGPainless.generateOpenPgpKey(policy).buildV4Key().unopinionated().setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserId("Alice <alice@example.org>", hashAlgorithm = HashAlgorithm.SHA1)
|
||||
}
|
||||
|
@ -324,7 +338,7 @@ class OpenPgpKeyGeneratorTest {
|
|||
fun `opinionated add UserAttribute with weak hash algorithm fails`() {
|
||||
val policy = Policy()
|
||||
assertThrows<IllegalArgumentException> {
|
||||
OpenPgpKeyGenerator.buildV4Key(policy).setPrimaryKey(
|
||||
PGPainless.generateOpenPgpKey(policy).buildV4Key().setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserAttribute(
|
||||
PGPUserAttributeSubpacketVectorGenerator().generate(),
|
||||
|
@ -336,7 +350,7 @@ class OpenPgpKeyGeneratorTest {
|
|||
@Test
|
||||
fun `unopinionated add UserAttribute with weak hash algorithm is okay`() {
|
||||
val policy = Policy()
|
||||
OpenPgpKeyGenerator.buildV4Key(policy).unopinionated().setPrimaryKey(
|
||||
PGPainless.generateOpenPgpKey(policy).buildV4Key().unopinionated().setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserAttribute(
|
||||
PGPUserAttributeSubpacketVectorGenerator().generate(),
|
||||
|
@ -348,7 +362,7 @@ class OpenPgpKeyGeneratorTest {
|
|||
fun `opinionated add DK sig with weak hash algorithm fails`() {
|
||||
val policy = Policy()
|
||||
assertThrows<IllegalArgumentException> {
|
||||
OpenPgpKeyGenerator.buildV4Key(policy).setPrimaryKey(
|
||||
PGPainless.generateOpenPgpKey(policy).buildV4Key().setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addDirectKeySignature(hashAlgorithm = HashAlgorithm.SHA1)
|
||||
}
|
||||
|
@ -358,7 +372,7 @@ class OpenPgpKeyGeneratorTest {
|
|||
@Test
|
||||
fun `unopinionated add DK sig with weak hash algorithm is okay`() {
|
||||
val policy = Policy()
|
||||
OpenPgpKeyGenerator.buildV4Key(policy).unopinionated().setPrimaryKey(
|
||||
PGPainless.generateOpenPgpKey(policy).buildV4Key().unopinionated().setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addDirectKeySignature(hashAlgorithm = HashAlgorithm.SHA1)
|
||||
}
|
||||
|
@ -371,7 +385,7 @@ class OpenPgpKeyGeneratorTest {
|
|||
val t1 = DateUtil.parseUTCDate("2024-02-01 00:00:00 UTC")
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
OpenPgpKeyGenerator.buildV4Key(policy, t1).setPrimaryKey(
|
||||
PGPainless.generateOpenPgpKey(policy).buildV4Key(t1).setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserId("Alice <alice@example.org>", bindingTime = t0)
|
||||
}
|
||||
|
@ -384,7 +398,7 @@ class OpenPgpKeyGeneratorTest {
|
|||
val t0 = DateUtil.parseUTCDate("2024-01-01 00:00:00 UTC")
|
||||
val t1 = DateUtil.parseUTCDate("2024-02-01 00:00:00 UTC")
|
||||
|
||||
OpenPgpKeyGenerator.buildV4Key(policy, t1).unopinionated().setPrimaryKey(
|
||||
PGPainless.generateOpenPgpKey(policy).buildV4Key(t1).unopinionated().setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserId("Alice <alice@example.org>", bindingTime = t0)
|
||||
}
|
||||
|
@ -397,7 +411,7 @@ class OpenPgpKeyGeneratorTest {
|
|||
val t1 = DateUtil.parseUTCDate("2024-02-01 00:00:00 UTC")
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
OpenPgpKeyGenerator.buildV4Key(policy, t1).setPrimaryKey(
|
||||
PGPainless.generateOpenPgpKey(policy).buildV4Key(t1).setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserAttribute(
|
||||
PGPUserAttributeSubpacketVectorGenerator().generate(), bindingTime = t0)
|
||||
|
@ -411,7 +425,7 @@ class OpenPgpKeyGeneratorTest {
|
|||
val t0 = DateUtil.parseUTCDate("2024-01-01 00:00:00 UTC")
|
||||
val t1 = DateUtil.parseUTCDate("2024-02-01 00:00:00 UTC")
|
||||
|
||||
OpenPgpKeyGenerator.buildV4Key(policy, t1).unopinionated().setPrimaryKey(
|
||||
PGPainless.generateOpenPgpKey(policy).buildV4Key(t1).unopinionated().setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addUserAttribute(
|
||||
PGPUserAttributeSubpacketVectorGenerator().generate(), bindingTime = t0)
|
||||
|
@ -425,7 +439,7 @@ class OpenPgpKeyGeneratorTest {
|
|||
val t1 = DateUtil.parseUTCDate("2024-02-01 00:00:00 UTC")
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
OpenPgpKeyGenerator.buildV4Key(policy, t1).setPrimaryKey(
|
||||
PGPainless.generateOpenPgpKey(policy).buildV4Key(t1).setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addDirectKeySignature(bindingTime = t0)
|
||||
}
|
||||
|
@ -438,7 +452,7 @@ class OpenPgpKeyGeneratorTest {
|
|||
val t0 = DateUtil.parseUTCDate("2024-01-01 00:00:00 UTC")
|
||||
val t1 = DateUtil.parseUTCDate("2024-02-01 00:00:00 UTC")
|
||||
|
||||
OpenPgpKeyGenerator.buildV4Key(policy, t1).unopinionated().setPrimaryKey(
|
||||
PGPainless.generateOpenPgpKey(policy).buildV4Key(t1).unopinionated().setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addDirectKeySignature(bindingTime = t0)
|
||||
}
|
||||
|
@ -451,7 +465,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
val t1 = DateUtil.parseUTCDate("2024-02-01 00:00:00 UTC")
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
OpenPgpKeyGenerator.buildV4Key(policy, t1)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key(t1)
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.addSubkey(KeyType.XDH(XDHSpec._X25519), null, t0)
|
||||
}
|
||||
|
@ -463,7 +478,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
val t0 = DateUtil.parseUTCDate("2024-01-01 00:00:00 UTC")
|
||||
val t1 = DateUtil.parseUTCDate("2024-02-01 00:00:00 UTC")
|
||||
|
||||
OpenPgpKeyGenerator.buildV4Key(policy, t1)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key(t1)
|
||||
.unopinionated()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.addSubkey(KeyType.XDH(XDHSpec._X25519), null, t0)
|
||||
|
@ -476,7 +492,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
val t1 = DateUtil.parseUTCDate("2024-02-01 00:00:00 UTC")
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
OpenPgpKeyGenerator.buildV4Key(policy, t1)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key(t1)
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.addSubkey(KeyType.XDH(XDHSpec._X25519)) { addBindingSignature(bindingTime = t0) }
|
||||
}
|
||||
|
@ -488,7 +505,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
val t0 = DateUtil.parseUTCDate("2024-01-01 00:00:00 UTC")
|
||||
val t1 = DateUtil.parseUTCDate("2024-02-01 00:00:00 UTC")
|
||||
|
||||
OpenPgpKeyGenerator.buildV4Key(policy, t1)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key(t1)
|
||||
.unopinionated()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.addSubkey(KeyType.XDH(XDHSpec._X25519)) { addBindingSignature(bindingTime = t0) }
|
||||
|
@ -499,7 +517,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
val policy = Policy()
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
OpenPgpKeyGenerator.buildV4Key(policy)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.addSubkey(KeyType.XDH(XDHSpec._X25519)) {
|
||||
addBindingSignature(hashAlgorithm = HashAlgorithm.SHA1)
|
||||
|
@ -511,7 +530,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
fun `unopinionated add subkey with weak binding signature hash algorithm is okay`() {
|
||||
val policy = Policy()
|
||||
|
||||
OpenPgpKeyGenerator.buildV4Key(policy)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.unopinionated()
|
||||
.addSubkey(KeyType.XDH(XDHSpec._X25519)) {
|
||||
|
@ -524,7 +544,9 @@ class OpenPgpKeyGeneratorTest {
|
|||
val policy = Policy()
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
OpenPgpKeyGenerator.buildV4Key(policy).setPrimaryKey(KeyType.XDH(XDHSpec._X25519))
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.XDH(XDHSpec._X25519))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -533,7 +555,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
val policy = Policy()
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
OpenPgpKeyGenerator.buildV4Key(policy)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519),
|
||||
listOf(KeyFlag.CERTIFY_OTHER, KeyFlag.ENCRYPT_STORAGE))
|
||||
|
@ -544,7 +567,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
fun `unopinionated set primary key to sign-only algorithm but with encryption flag is okay`() {
|
||||
val policy = Policy()
|
||||
|
||||
OpenPgpKeyGenerator.buildV4Key(policy)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
.unopinionated()
|
||||
.setPrimaryKey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519),
|
||||
|
@ -556,7 +580,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
val policy = Policy()
|
||||
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key(policy)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519), keyFlags = null)
|
||||
.build()
|
||||
|
||||
|
@ -568,7 +593,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
val policy = Policy()
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
OpenPgpKeyGenerator.buildV4Key(policy)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.addSubkey(
|
||||
KeyType.XDH(XDHSpec._X25519), listOf(KeyFlag.ENCRYPT_COMMS, KeyFlag.SIGN_DATA))
|
||||
|
@ -580,7 +606,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
val policy = Policy()
|
||||
|
||||
assertThrows<IllegalArgumentException> {
|
||||
OpenPgpKeyGenerator.buildV4Key(policy)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.addSubkey(
|
||||
KeyType.EDDSA(EdDSACurve._Ed25519),
|
||||
|
@ -592,7 +619,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
fun `unopinionated add sign-only sukey but with additional encryption flag is okay`() {
|
||||
val policy = Policy()
|
||||
|
||||
OpenPgpKeyGenerator.buildV4Key(policy)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.unopinionated()
|
||||
.addSubkey(
|
||||
|
@ -609,7 +637,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
"ffd8ffe000104a46494600010101004800480000ffdb004300030202020202030202020303030304060404040404080606050609080a0a090809090a0c0f0c0a0b0e0b09090d110d0e0f101011100a0c12131210130f101010ffc9000b080001000101011100ffcc000600101005ffda0008010100003f00d2cf20ffd9")
|
||||
|
||||
val key =
|
||||
OpenPgpKeyGenerator.buildV4Key()
|
||||
PGPainless.generateOpenPgpKey()
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addImageAttribute(jpegBytes.inputStream())
|
||||
}
|
||||
|
@ -622,7 +651,8 @@ class OpenPgpKeyGeneratorTest {
|
|||
fun `generate key with expiration time`() {
|
||||
val policy = Policy()
|
||||
|
||||
OpenPgpKeyGenerator.buildV4Key(policy)
|
||||
PGPainless.generateOpenPgpKey(policy)
|
||||
.buildV4Key()
|
||||
.setPrimaryKey(KeyType.EDDSA(EdDSACurve._Ed25519)) {
|
||||
addDirectKeySignature(
|
||||
SelfSignatureSubpackets.applyHashed {
|
||||
|
|
Loading…
Reference in a new issue