mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-09-09 18:29:39 +02:00
Rework KeyAccessor
This commit is contained in:
parent
94febc33df
commit
0266d14594
12 changed files with 247 additions and 139 deletions
|
@ -4,22 +4,91 @@
|
||||||
|
|
||||||
package org.pgpainless.algorithm
|
package org.pgpainless.algorithm
|
||||||
|
|
||||||
class AlgorithmSuite(
|
class AlgorithmSuite
|
||||||
symmetricKeyAlgorithms: List<SymmetricKeyAlgorithm>?,
|
private constructor(
|
||||||
hashAlgorithms: List<HashAlgorithm>?,
|
val symmetricKeyAlgorithms: Set<SymmetricKeyAlgorithm>?,
|
||||||
compressionAlgorithms: List<CompressionAlgorithm>?,
|
val hashAlgorithms: Set<HashAlgorithm>?,
|
||||||
aeadAlgorithms: List<AEADCipherMode>?,
|
val compressionAlgorithms: Set<CompressionAlgorithm>?,
|
||||||
features: List<Feature>
|
val aeadAlgorithms: Set<AEADCipherMode>?,
|
||||||
|
val features: Set<Feature>?
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val symmetricKeyAlgorithms: Set<SymmetricKeyAlgorithm>? = symmetricKeyAlgorithms?.toSet()
|
constructor(
|
||||||
val hashAlgorithms: Set<HashAlgorithm>? = hashAlgorithms?.toSet()
|
symmetricKeyAlgorithms: List<SymmetricKeyAlgorithm>?,
|
||||||
val compressionAlgorithms: Set<CompressionAlgorithm>? = compressionAlgorithms?.toSet()
|
hashAlgorithms: List<HashAlgorithm>?,
|
||||||
val aeadAlgorithms: Set<AEADCipherMode>? = aeadAlgorithms?.toSet()
|
compressionAlgorithms: List<CompressionAlgorithm>?,
|
||||||
val features: Set<Feature> = features.toSet()
|
aeadAlgorithms: List<AEADCipherMode>?,
|
||||||
|
features: List<Feature>?
|
||||||
|
) : this(
|
||||||
|
symmetricKeyAlgorithms?.toSet(),
|
||||||
|
hashAlgorithms?.toSet(),
|
||||||
|
compressionAlgorithms?.toSet(),
|
||||||
|
aeadAlgorithms?.toSet(),
|
||||||
|
features?.toSet())
|
||||||
|
|
||||||
|
fun modify(): Builder = Builder(this)
|
||||||
|
|
||||||
|
class Builder(suite: AlgorithmSuite? = null) {
|
||||||
|
private var symmetricKeyAlgorithms: Set<SymmetricKeyAlgorithm>? =
|
||||||
|
suite?.symmetricKeyAlgorithms
|
||||||
|
private var hashAlgorithms: Set<HashAlgorithm>? = suite?.hashAlgorithms
|
||||||
|
private var compressionAlgorithms: Set<CompressionAlgorithm>? = suite?.compressionAlgorithms
|
||||||
|
private var aeadAlgorithms: Set<AEADCipherMode>? = suite?.aeadAlgorithms
|
||||||
|
private var features: Set<Feature>? = suite?.features
|
||||||
|
|
||||||
|
fun overrideSymmetricKeyAlgorithms(
|
||||||
|
vararg symmetricKeyAlgorithms: SymmetricKeyAlgorithm
|
||||||
|
): Builder = overrideSymmetricKeyAlgorithms(symmetricKeyAlgorithms.toSet())
|
||||||
|
|
||||||
|
fun overrideSymmetricKeyAlgorithms(
|
||||||
|
symmetricKeyAlgorithms: Collection<SymmetricKeyAlgorithm>?
|
||||||
|
): Builder = apply { this.symmetricKeyAlgorithms = symmetricKeyAlgorithms?.toSet() }
|
||||||
|
|
||||||
|
fun overrideHashAlgorithms(vararg hashAlgorithms: HashAlgorithm): Builder =
|
||||||
|
overrideHashAlgorithms(hashAlgorithms.toSet())
|
||||||
|
|
||||||
|
fun overrideHashAlgorithms(hashAlgorithms: Collection<HashAlgorithm>?): Builder = apply {
|
||||||
|
this.hashAlgorithms = hashAlgorithms?.toSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun overrideCompressionAlgorithms(
|
||||||
|
vararg compressionAlgorithms: CompressionAlgorithm
|
||||||
|
): Builder = overrideCompressionAlgorithms(compressionAlgorithms.toSet())
|
||||||
|
|
||||||
|
fun overrideCompressionAlgorithms(
|
||||||
|
compressionAlgorithms: Collection<CompressionAlgorithm>?
|
||||||
|
): Builder = apply { this.compressionAlgorithms = compressionAlgorithms?.toSet() }
|
||||||
|
|
||||||
|
fun overrideAeadAlgorithms(vararg aeadAlgorithms: AEADCipherMode): Builder =
|
||||||
|
overrideAeadAlgorithms(aeadAlgorithms.toSet())
|
||||||
|
|
||||||
|
fun overrideAeadAlgorithms(aeadAlgorithms: Collection<AEADCipherMode>?): Builder = apply {
|
||||||
|
this.aeadAlgorithms = aeadAlgorithms?.toSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun overrideFeatures(vararg features: Feature): Builder = overrideFeatures(features.toSet())
|
||||||
|
|
||||||
|
fun overrideFeatures(features: Collection<Feature>?): Builder = apply {
|
||||||
|
this.features = features?.toSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun build(): AlgorithmSuite {
|
||||||
|
return AlgorithmSuite(
|
||||||
|
symmetricKeyAlgorithms,
|
||||||
|
hashAlgorithms,
|
||||||
|
compressionAlgorithms,
|
||||||
|
aeadAlgorithms,
|
||||||
|
features)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun emptyBuilder(): Builder {
|
||||||
|
return Builder()
|
||||||
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
val defaultSymmetricKeyAlgorithms =
|
val defaultSymmetricKeyAlgorithms =
|
||||||
listOf(
|
listOf(
|
||||||
|
|
|
@ -32,10 +32,10 @@ fun OpenPGPKeyGenerator.setAlgorithmSuite(algorithms: AlgorithmSuite): OpenPGPKe
|
||||||
|
|
||||||
fun OpenPGPKeyGenerator.setDefaultFeatures(
|
fun OpenPGPKeyGenerator.setDefaultFeatures(
|
||||||
critical: Boolean = true,
|
critical: Boolean = true,
|
||||||
features: Set<Feature>
|
features: Set<Feature>?
|
||||||
): OpenPGPKeyGenerator {
|
): OpenPGPKeyGenerator {
|
||||||
this.setDefaultFeatures {
|
this.setDefaultFeatures {
|
||||||
val b = Feature.toBitmask(*features.toTypedArray())
|
val b = features?.let { f -> Feature.toBitmask(*f.toTypedArray()) } ?: 0
|
||||||
it.apply { setFeature(critical, b) }
|
it.apply { setFeature(critical, b) }
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
|
|
|
@ -33,9 +33,9 @@ class MessageMetadata(val message: Message) {
|
||||||
* The [SymmetricKeyAlgorithm] of the outermost encrypted data packet, or null if message is
|
* The [SymmetricKeyAlgorithm] of the outermost encrypted data packet, or null if message is
|
||||||
* unencrypted.
|
* unencrypted.
|
||||||
*/
|
*/
|
||||||
@Deprecated("Deprecated in favor of encryptionMechanism",
|
@Deprecated(
|
||||||
replaceWith = ReplaceWith("encryptionMechanism")
|
"Deprecated in favor of encryptionMechanism",
|
||||||
)
|
replaceWith = ReplaceWith("encryptionMechanism"))
|
||||||
val encryptionAlgorithm: SymmetricKeyAlgorithm?
|
val encryptionAlgorithm: SymmetricKeyAlgorithm?
|
||||||
get() = encryptionAlgorithms.let { if (it.hasNext()) it.next() else null }
|
get() = encryptionAlgorithms.let { if (it.hasNext()) it.next() else null }
|
||||||
|
|
||||||
|
@ -48,9 +48,9 @@ class MessageMetadata(val message: Message) {
|
||||||
* item that of the next nested encrypted data packet and so on. The iterator might also be
|
* item that of the next nested encrypted data packet and so on. The iterator might also be
|
||||||
* empty, in case of an unencrypted message.
|
* empty, in case of an unencrypted message.
|
||||||
*/
|
*/
|
||||||
@Deprecated("Deprecated in favor of encryptionMechanisms",
|
@Deprecated(
|
||||||
replaceWith = ReplaceWith("encryptionMechanisms")
|
"Deprecated in favor of encryptionMechanisms",
|
||||||
)
|
replaceWith = ReplaceWith("encryptionMechanisms"))
|
||||||
val encryptionAlgorithms: Iterator<SymmetricKeyAlgorithm>
|
val encryptionAlgorithms: Iterator<SymmetricKeyAlgorithm>
|
||||||
get() = encryptionLayers.asSequence().map { it.algorithm }.iterator()
|
get() = encryptionLayers.asSequence().map { it.algorithm }.iterator()
|
||||||
|
|
||||||
|
@ -60,7 +60,9 @@ class MessageMetadata(val message: Message) {
|
||||||
val isEncrypted: Boolean
|
val isEncrypted: Boolean
|
||||||
get() =
|
get() =
|
||||||
if (encryptionMechanism == null) false
|
if (encryptionMechanism == null) false
|
||||||
else encryptionMechanism!!.symmetricKeyAlgorithm != SymmetricKeyAlgorithm.NULL.algorithmId
|
else
|
||||||
|
encryptionMechanism!!.symmetricKeyAlgorithm !=
|
||||||
|
SymmetricKeyAlgorithm.NULL.algorithmId
|
||||||
|
|
||||||
fun isEncryptedFor(cert: OpenPGPCertificate): Boolean {
|
fun isEncryptedFor(cert: OpenPGPCertificate): Boolean {
|
||||||
return encryptionLayers.asSequence().any {
|
return encryptionLayers.asSequence().any {
|
||||||
|
|
|
@ -24,7 +24,6 @@ import org.pgpainless.util.Passphrase
|
||||||
class EncryptionOptions(private val purpose: EncryptionPurpose, private val api: PGPainless) {
|
class EncryptionOptions(private val purpose: EncryptionPurpose, private val api: PGPainless) {
|
||||||
private val _encryptionMethods: MutableSet<PGPKeyEncryptionMethodGenerator> = mutableSetOf()
|
private val _encryptionMethods: MutableSet<PGPKeyEncryptionMethodGenerator> = mutableSetOf()
|
||||||
private val _encryptionKeys: MutableSet<OpenPGPComponentKey> = mutableSetOf()
|
private val _encryptionKeys: MutableSet<OpenPGPComponentKey> = mutableSetOf()
|
||||||
private val _encryptionKeyIdentifiers: MutableSet<SubkeyIdentifier> = mutableSetOf()
|
|
||||||
private val _keyRingInfo: MutableMap<SubkeyIdentifier, KeyRingInfo> = mutableMapOf()
|
private val _keyRingInfo: MutableMap<SubkeyIdentifier, KeyRingInfo> = mutableMapOf()
|
||||||
private val _keyViews: MutableMap<SubkeyIdentifier, KeyAccessor> = mutableMapOf()
|
private val _keyViews: MutableMap<SubkeyIdentifier, KeyAccessor> = mutableMapOf()
|
||||||
private val encryptionKeySelector: EncryptionKeySelector = encryptToAllCapableSubkeys()
|
private val encryptionKeySelector: EncryptionKeySelector = encryptToAllCapableSubkeys()
|
||||||
|
@ -37,7 +36,7 @@ class EncryptionOptions(private val purpose: EncryptionPurpose, private val api:
|
||||||
get() = _encryptionMethods.toSet()
|
get() = _encryptionMethods.toSet()
|
||||||
|
|
||||||
val encryptionKeyIdentifiers
|
val encryptionKeyIdentifiers
|
||||||
get() = _encryptionKeyIdentifiers.toSet()
|
get() = _encryptionKeys.map { SubkeyIdentifier(it) }
|
||||||
|
|
||||||
val encryptionKeys
|
val encryptionKeys
|
||||||
get() = _encryptionKeys.toSet()
|
get() = _encryptionKeys.toSet()
|
||||||
|
@ -201,7 +200,7 @@ class EncryptionOptions(private val purpose: EncryptionPurpose, private val api:
|
||||||
for (subkey in subkeys) {
|
for (subkey in subkeys) {
|
||||||
val keyId = SubkeyIdentifier(subkey)
|
val keyId = SubkeyIdentifier(subkey)
|
||||||
_keyRingInfo[keyId] = info
|
_keyRingInfo[keyId] = info
|
||||||
_keyViews[keyId] = KeyAccessor.ViaUserId(info, keyId, userId.toString())
|
_keyViews[keyId] = KeyAccessor.ViaUserId(subkey, cert.getUserId(userId.toString()))
|
||||||
addRecipientKey(subkey, false)
|
addRecipientKey(subkey, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,14 +319,13 @@ class EncryptionOptions(private val purpose: EncryptionPurpose, private val api:
|
||||||
for (subkey in encryptionSubkeys) {
|
for (subkey in encryptionSubkeys) {
|
||||||
val keyId = SubkeyIdentifier(subkey)
|
val keyId = SubkeyIdentifier(subkey)
|
||||||
_keyRingInfo[keyId] = info
|
_keyRingInfo[keyId] = info
|
||||||
_keyViews[keyId] = KeyAccessor.ViaKeyId(info, keyId)
|
_keyViews[keyId] = KeyAccessor.ViaKeyIdentifier(subkey)
|
||||||
addRecipientKey(subkey, wildcardKeyId)
|
addRecipientKey(subkey, wildcardKeyId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addRecipientKey(key: OpenPGPComponentKey, wildcardRecipient: Boolean) {
|
private fun addRecipientKey(key: OpenPGPComponentKey, wildcardRecipient: Boolean) {
|
||||||
_encryptionKeys.add(key)
|
_encryptionKeys.add(key)
|
||||||
_encryptionKeyIdentifiers.add(SubkeyIdentifier(key))
|
|
||||||
addEncryptionMethod(
|
addEncryptionMethod(
|
||||||
api.implementation.publicKeyKeyEncryptionMethodGenerator(key.pgpPublicKey).also {
|
api.implementation.publicKeyKeyEncryptionMethodGenerator(key.pgpPublicKey).also {
|
||||||
it.setUseWildcardRecipient(wildcardRecipient)
|
it.setUseWildcardRecipient(wildcardRecipient)
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor
|
||||||
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder
|
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder
|
||||||
import org.bouncycastle.util.Strings
|
import org.bouncycastle.util.Strings
|
||||||
import org.pgpainless.PGPainless
|
import org.pgpainless.PGPainless
|
||||||
|
import org.pgpainless.algorithm.AlgorithmSuite
|
||||||
import org.pgpainless.algorithm.KeyFlag
|
import org.pgpainless.algorithm.KeyFlag
|
||||||
import org.pgpainless.algorithm.OpenPGPKeyVersion
|
import org.pgpainless.algorithm.OpenPGPKeyVersion
|
||||||
import org.pgpainless.algorithm.SignatureType
|
import org.pgpainless.algorithm.SignatureType
|
||||||
|
@ -33,6 +34,11 @@ class KeyRingBuilder(private val version: OpenPGPKeyVersion, private val api: PG
|
||||||
private val userIds = mutableMapOf<String, SelfSignatureSubpackets.Callback?>()
|
private val userIds = mutableMapOf<String, SelfSignatureSubpackets.Callback?>()
|
||||||
private var passphrase = Passphrase.emptyPassphrase()
|
private var passphrase = Passphrase.emptyPassphrase()
|
||||||
private var expirationDate: Date? = Date(System.currentTimeMillis() + (5 * MILLIS_IN_YEAR))
|
private var expirationDate: Date? = Date(System.currentTimeMillis() + (5 * MILLIS_IN_YEAR))
|
||||||
|
private var algorithmSuite: AlgorithmSuite = api.algorithmPolicy.keyGenerationAlgorithmSuite
|
||||||
|
|
||||||
|
override fun withPreferences(preferences: AlgorithmSuite): KeyRingBuilder = apply {
|
||||||
|
algorithmSuite = preferences
|
||||||
|
}
|
||||||
|
|
||||||
override fun setPrimaryKey(keySpec: KeySpec): KeyRingBuilder = apply {
|
override fun setPrimaryKey(keySpec: KeySpec): KeyRingBuilder = apply {
|
||||||
verifyKeySpecCompliesToPolicy(keySpec, api.algorithmPolicy)
|
verifyKeySpecCompliesToPolicy(keySpec, api.algorithmPolicy)
|
||||||
|
@ -95,14 +101,32 @@ class KeyRingBuilder(private val version: OpenPGPKeyVersion, private val api: PG
|
||||||
val signer = buildContentSigner(certKey)
|
val signer = buildContentSigner(certKey)
|
||||||
val signatureGenerator = PGPSignatureGenerator(signer, certKey.publicKey)
|
val signatureGenerator = PGPSignatureGenerator(signer, certKey.publicKey)
|
||||||
|
|
||||||
val hashedSubPacketGenerator = primaryKeySpec!!.subpacketGenerator
|
val hashedSignatureSubpackets: SignatureSubpackets =
|
||||||
hashedSubPacketGenerator.setAppropriateIssuerInfo(certKey.publicKey, version)
|
SignatureSubpackets.createHashedSubpackets(certKey.publicKey).apply {
|
||||||
expirationDate?.let { hashedSubPacketGenerator.setKeyExpirationTime(certKey.publicKey, it) }
|
setKeyFlags(primaryKeySpec!!.keyFlags)
|
||||||
|
(primaryKeySpec!!.preferredHashAlgorithmsOverride ?: algorithmSuite.hashAlgorithms)
|
||||||
|
?.let { setPreferredHashAlgorithms(it) }
|
||||||
|
(primaryKeySpec!!.preferredCompressionAlgorithmsOverride
|
||||||
|
?: algorithmSuite.compressionAlgorithms)
|
||||||
|
?.let { setPreferredCompressionAlgorithms(it) }
|
||||||
|
(primaryKeySpec!!.preferredSymmetricAlgorithmsOverride
|
||||||
|
?: algorithmSuite.symmetricKeyAlgorithms)
|
||||||
|
?.let { setPreferredSymmetricKeyAlgorithms(it) }
|
||||||
|
(primaryKeySpec!!.preferredAEADAlgorithmsOverride ?: algorithmSuite.aeadAlgorithms)
|
||||||
|
?.let { setPreferredAEADCiphersuites(it) }
|
||||||
|
(primaryKeySpec!!.featuresOverride ?: algorithmSuite.features)?.let {
|
||||||
|
setFeatures(*it.toTypedArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expirationDate?.let {
|
||||||
|
hashedSignatureSubpackets.setKeyExpirationTime(certKey.publicKey, it)
|
||||||
|
}
|
||||||
if (userIds.isNotEmpty()) {
|
if (userIds.isNotEmpty()) {
|
||||||
hashedSubPacketGenerator.setPrimaryUserId()
|
hashedSignatureSubpackets.setPrimaryUserId()
|
||||||
}
|
}
|
||||||
|
|
||||||
val hashedSubPackets = hashedSubPacketGenerator.subpacketsGenerator.generate()
|
val hashedSubPackets = hashedSignatureSubpackets.subpacketsGenerator.generate()
|
||||||
val ringGenerator =
|
val ringGenerator =
|
||||||
if (userIds.isEmpty()) {
|
if (userIds.isEmpty()) {
|
||||||
PGPKeyRingGenerator(
|
PGPKeyRingGenerator(
|
||||||
|
@ -138,7 +162,7 @@ class KeyRingBuilder(private val version: OpenPGPKeyVersion, private val api: PG
|
||||||
val callback = additionalUserId.value
|
val callback = additionalUserId.value
|
||||||
val subpackets =
|
val subpackets =
|
||||||
if (callback == null) {
|
if (callback == null) {
|
||||||
hashedSubPacketGenerator.also { it.setPrimaryUserId(null) }
|
hashedSignatureSubpackets.also { it.setPrimaryUserId(null) }
|
||||||
} else {
|
} else {
|
||||||
SignatureSubpackets.createHashedSubpackets(primaryPubKey).also {
|
SignatureSubpackets.createHashedSubpackets(primaryPubKey).also {
|
||||||
callback.modifyHashedSubpackets(it)
|
callback.modifyHashedSubpackets(it)
|
||||||
|
@ -167,21 +191,34 @@ class KeyRingBuilder(private val version: OpenPGPKeyVersion, private val api: PG
|
||||||
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, api.implementation)
|
val subKey = generateKeyPair(subKeySpec, version, api.implementation)
|
||||||
if (subKeySpec.isInheritedSubPackets) {
|
var hashedSignatureSubpackets: SignatureSubpackets =
|
||||||
ringGenerator.addSubKey(subKey)
|
SignatureSubpackets.createHashedSubpackets(subKey.publicKey).apply {
|
||||||
} else {
|
setKeyFlags(subKeySpec.keyFlags)
|
||||||
var hashedSubpackets = subKeySpec.subpackets
|
subKeySpec.preferredHashAlgorithmsOverride?.let {
|
||||||
try {
|
setPreferredHashAlgorithms(it)
|
||||||
hashedSubpackets =
|
}
|
||||||
addPrimaryKeyBindingSignatureIfNecessary(
|
subKeySpec.preferredCompressionAlgorithmsOverride?.let {
|
||||||
primaryKey, subKey, hashedSubpackets)
|
setPreferredCompressionAlgorithms(it)
|
||||||
} catch (e: IOException) {
|
}
|
||||||
throw PGPException(
|
subKeySpec.preferredSymmetricAlgorithmsOverride?.let {
|
||||||
"Exception while adding primary key binding signature to signing subkey.",
|
setPreferredSymmetricKeyAlgorithms(it)
|
||||||
e)
|
}
|
||||||
|
subKeySpec.preferredAEADAlgorithmsOverride?.let {
|
||||||
|
setPreferredAEADCiphersuites(it)
|
||||||
|
}
|
||||||
|
subKeySpec.featuresOverride?.let { setFeatures(*it.toTypedArray()) }
|
||||||
}
|
}
|
||||||
ringGenerator.addSubKey(subKey, hashedSubpackets, null)
|
|
||||||
|
var hashedSubpackets: PGPSignatureSubpacketVector =
|
||||||
|
hashedSignatureSubpackets.subpacketsGenerator.generate()
|
||||||
|
try {
|
||||||
|
hashedSubpackets =
|
||||||
|
addPrimaryKeyBindingSignatureIfNecessary(primaryKey, subKey, hashedSubpackets)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw PGPException(
|
||||||
|
"Exception while adding primary key binding signature to signing subkey.", e)
|
||||||
}
|
}
|
||||||
|
ringGenerator.addSubKey(subKey, hashedSubpackets, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,13 @@ import java.security.NoSuchAlgorithmException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import org.bouncycastle.openpgp.PGPException
|
import org.bouncycastle.openpgp.PGPException
|
||||||
import org.bouncycastle.openpgp.api.OpenPGPKey
|
import org.bouncycastle.openpgp.api.OpenPGPKey
|
||||||
|
import org.pgpainless.algorithm.AlgorithmSuite
|
||||||
import org.pgpainless.util.Passphrase
|
import org.pgpainless.util.Passphrase
|
||||||
|
|
||||||
interface KeyRingBuilderInterface<B : KeyRingBuilderInterface<B>> {
|
interface KeyRingBuilderInterface<B : KeyRingBuilderInterface<B>> {
|
||||||
|
|
||||||
|
fun withPreferences(preferences: AlgorithmSuite): B
|
||||||
|
|
||||||
fun setPrimaryKey(keySpec: KeySpec): B
|
fun setPrimaryKey(keySpec: KeySpec): B
|
||||||
|
|
||||||
fun setPrimaryKey(builder: KeySpecBuilder): B = setPrimaryKey(builder.build())
|
fun setPrimaryKey(builder: KeySpecBuilder): B = setPrimaryKey(builder.build())
|
||||||
|
|
|
@ -5,22 +5,25 @@
|
||||||
package org.pgpainless.key.generation
|
package org.pgpainless.key.generation
|
||||||
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import org.bouncycastle.openpgp.PGPSignatureSubpacketVector
|
import org.pgpainless.algorithm.AEADCipherMode
|
||||||
|
import org.pgpainless.algorithm.CompressionAlgorithm
|
||||||
|
import org.pgpainless.algorithm.Feature
|
||||||
|
import org.pgpainless.algorithm.HashAlgorithm
|
||||||
import org.pgpainless.algorithm.KeyFlag
|
import org.pgpainless.algorithm.KeyFlag
|
||||||
|
import org.pgpainless.algorithm.SymmetricKeyAlgorithm
|
||||||
import org.pgpainless.key.generation.type.KeyType
|
import org.pgpainless.key.generation.type.KeyType
|
||||||
import org.pgpainless.signature.subpackets.SignatureSubpackets
|
|
||||||
import org.pgpainless.signature.subpackets.SignatureSubpacketsHelper
|
|
||||||
|
|
||||||
data class KeySpec(
|
data class KeySpec(
|
||||||
val keyType: KeyType,
|
val keyType: KeyType,
|
||||||
val subpacketGenerator: SignatureSubpackets,
|
val keyFlags: List<KeyFlag>,
|
||||||
val isInheritedSubPackets: Boolean,
|
val preferredCompressionAlgorithmsOverride: Set<CompressionAlgorithm>?,
|
||||||
|
val preferredHashAlgorithmsOverride: Set<HashAlgorithm>?,
|
||||||
|
val preferredSymmetricAlgorithmsOverride: Set<SymmetricKeyAlgorithm>?,
|
||||||
|
val preferredAEADAlgorithmsOverride: Set<AEADCipherMode>?,
|
||||||
|
val featuresOverride: Set<Feature>?,
|
||||||
val keyCreationDate: Date?
|
val keyCreationDate: Date?
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val subpackets: PGPSignatureSubpacketVector
|
|
||||||
get() = SignatureSubpacketsHelper.toVector(subpacketGenerator)
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getBuilder(type: KeyType, vararg flags: KeyFlag) = KeySpecBuilder(type, *flags)
|
fun getBuilder(type: KeyType, vararg flags: KeyFlag) = KeySpecBuilder(type, *flags)
|
||||||
|
|
|
@ -5,11 +5,8 @@
|
||||||
package org.pgpainless.key.generation
|
package org.pgpainless.key.generation
|
||||||
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import org.pgpainless.PGPainless
|
|
||||||
import org.pgpainless.algorithm.*
|
import org.pgpainless.algorithm.*
|
||||||
import org.pgpainless.key.generation.type.KeyType
|
import org.pgpainless.key.generation.type.KeyType
|
||||||
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets
|
|
||||||
import org.pgpainless.signature.subpackets.SignatureSubpackets
|
|
||||||
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil
|
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil
|
||||||
|
|
||||||
class KeySpecBuilder(
|
class KeySpecBuilder(
|
||||||
|
@ -17,16 +14,11 @@ class KeySpecBuilder(
|
||||||
private val keyFlags: List<KeyFlag>,
|
private val keyFlags: List<KeyFlag>,
|
||||||
) : KeySpecBuilderInterface {
|
) : KeySpecBuilderInterface {
|
||||||
|
|
||||||
private val hashedSubpackets: SelfSignatureSubpackets = SignatureSubpackets()
|
private var preferredCompressionAlgorithms: Set<CompressionAlgorithm>? = null
|
||||||
private val algorithmSuite: AlgorithmSuite =
|
private var preferredHashAlgorithms: Set<HashAlgorithm>? = null
|
||||||
PGPainless.getInstance().algorithmPolicy.keyGenerationAlgorithmSuite
|
private var preferredSymmetricAlgorithms: Set<SymmetricKeyAlgorithm>? = null
|
||||||
private var preferredCompressionAlgorithms: Set<CompressionAlgorithm>? =
|
private var preferredAEADAlgorithms: Set<AEADCipherMode>? = null
|
||||||
algorithmSuite.compressionAlgorithms
|
private var features: Set<Feature>? = null
|
||||||
private var preferredHashAlgorithms: Set<HashAlgorithm>? = algorithmSuite.hashAlgorithms
|
|
||||||
private var preferredSymmetricAlgorithms: Set<SymmetricKeyAlgorithm>? =
|
|
||||||
algorithmSuite.symmetricKeyAlgorithms
|
|
||||||
private var preferredAEADAlgorithms: Set<AEADCipherMode>? = algorithmSuite.aeadAlgorithms
|
|
||||||
private var features: Set<Feature>? = algorithmSuite.features
|
|
||||||
private var keyCreationDate: Date? = null
|
private var keyCreationDate: Date? = null
|
||||||
|
|
||||||
constructor(type: KeyType, vararg keyFlags: KeyFlag) : this(type, listOf(*keyFlags))
|
constructor(type: KeyType, vararg keyFlags: KeyFlag) : this(type, listOf(*keyFlags))
|
||||||
|
@ -70,15 +62,14 @@ class KeySpecBuilder(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun build(): KeySpec {
|
override fun build(): KeySpec {
|
||||||
return hashedSubpackets
|
return KeySpec(
|
||||||
.apply {
|
type,
|
||||||
setKeyFlags(keyFlags)
|
keyFlags,
|
||||||
preferredCompressionAlgorithms?.let { setPreferredCompressionAlgorithms(it) }
|
preferredCompressionAlgorithms,
|
||||||
preferredHashAlgorithms?.let { setPreferredHashAlgorithms(it) }
|
preferredHashAlgorithms,
|
||||||
preferredSymmetricAlgorithms?.let { setPreferredSymmetricKeyAlgorithms(it) }
|
preferredSymmetricAlgorithms,
|
||||||
preferredAEADAlgorithms?.let { setPreferredAEADCiphersuites(it) }
|
preferredAEADAlgorithms,
|
||||||
features?.let { setFeatures(*it.toTypedArray()) }
|
features,
|
||||||
}
|
keyCreationDate)
|
||||||
.let { KeySpec(type, hashedSubpackets as SignatureSubpackets, false, keyCreationDate) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,80 +4,67 @@
|
||||||
|
|
||||||
package org.pgpainless.key.info
|
package org.pgpainless.key.info
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPSignature
|
import java.util.*
|
||||||
|
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPCertificateComponent
|
||||||
|
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey
|
||||||
|
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPIdentityComponent
|
||||||
import org.pgpainless.algorithm.AEADCipherMode
|
import org.pgpainless.algorithm.AEADCipherMode
|
||||||
import org.pgpainless.algorithm.CompressionAlgorithm
|
import org.pgpainless.algorithm.CompressionAlgorithm
|
||||||
|
import org.pgpainless.algorithm.Feature
|
||||||
import org.pgpainless.algorithm.HashAlgorithm
|
import org.pgpainless.algorithm.HashAlgorithm
|
||||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm
|
import org.pgpainless.algorithm.SymmetricKeyAlgorithm
|
||||||
import org.pgpainless.key.SubkeyIdentifier
|
import org.pgpainless.bouncycastle.extensions.toAEADCipherModes
|
||||||
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil
|
import org.pgpainless.bouncycastle.extensions.toCompressionAlgorithms
|
||||||
|
import org.pgpainless.bouncycastle.extensions.toHashAlgorithms
|
||||||
|
import org.pgpainless.bouncycastle.extensions.toSymmetricKeyAlgorithms
|
||||||
|
|
||||||
abstract class KeyAccessor(protected val info: KeyRingInfo, protected val key: SubkeyIdentifier) {
|
abstract class KeyAccessor(
|
||||||
|
protected val key: OpenPGPComponentKey,
|
||||||
|
private val referenceTime: Date
|
||||||
|
) {
|
||||||
|
|
||||||
/**
|
abstract val component: OpenPGPCertificateComponent
|
||||||
* Depending on the way we address the key (key-id or user-id), return the respective
|
|
||||||
* [PGPSignature] which contains the algorithm preferences we are going to use.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* If we address a key via its user-id, we want to rely on the algorithm preferences in the
|
|
||||||
* user-id certification, while we would instead rely on those in the direct-key signature if
|
|
||||||
* we'd address the key by key-id.
|
|
||||||
*
|
|
||||||
* @return signature
|
|
||||||
*/
|
|
||||||
abstract val signatureWithPreferences: PGPSignature
|
|
||||||
|
|
||||||
/** Preferred symmetric key encryption algorithms. */
|
|
||||||
val preferredSymmetricKeyAlgorithms: Set<SymmetricKeyAlgorithm>
|
val preferredSymmetricKeyAlgorithms: Set<SymmetricKeyAlgorithm>
|
||||||
get() =
|
get() =
|
||||||
SignatureSubpacketsUtil.parsePreferredSymmetricKeyAlgorithms(signatureWithPreferences)
|
component.getSymmetricCipherPreferences(referenceTime)?.toSymmetricKeyAlgorithms()
|
||||||
|
?: setOf()
|
||||||
|
|
||||||
/** Preferred hash algorithms. */
|
|
||||||
val preferredHashAlgorithms: Set<HashAlgorithm>
|
val preferredHashAlgorithms: Set<HashAlgorithm>
|
||||||
get() = SignatureSubpacketsUtil.parsePreferredHashAlgorithms(signatureWithPreferences)
|
get() = component.getHashAlgorithmPreferences(referenceTime)?.toHashAlgorithms() ?: setOf()
|
||||||
|
|
||||||
/** Preferred compression algorithms. */
|
|
||||||
val preferredCompressionAlgorithms: Set<CompressionAlgorithm>
|
val preferredCompressionAlgorithms: Set<CompressionAlgorithm>
|
||||||
get() =
|
get() =
|
||||||
SignatureSubpacketsUtil.parsePreferredCompressionAlgorithms(signatureWithPreferences)
|
component.getCompressionAlgorithmPreferences(referenceTime)?.toCompressionAlgorithms()
|
||||||
|
?: setOf()
|
||||||
|
|
||||||
/** Preferred AEAD algorithm suites. */
|
|
||||||
val preferredAEADCipherSuites: Set<AEADCipherMode>
|
val preferredAEADCipherSuites: Set<AEADCipherMode>
|
||||||
get() = SignatureSubpacketsUtil.parsePreferredAEADCipherSuites(signatureWithPreferences)
|
get() =
|
||||||
|
component.getAEADCipherSuitePreferences(referenceTime)?.toAEADCipherModes() ?: setOf()
|
||||||
|
|
||||||
|
val features: Set<Feature>
|
||||||
|
get() =
|
||||||
|
Feature.fromBitmask(component.getFeatures(referenceTime)?.features?.toInt() ?: 0)
|
||||||
|
.toSet()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Address the key via a user-id (e.g. `Alice <alice@wonderland.lit>`). In this case we are
|
* Address the key via a user-id (e.g. `Alice <alice@wonderland.lit>`). In this case we are
|
||||||
* sourcing preferred algorithms from the user-id certification first.
|
* sourcing preferred algorithms from the user-id certification first.
|
||||||
*/
|
*/
|
||||||
class ViaUserId(info: KeyRingInfo, key: SubkeyIdentifier, private val userId: CharSequence) :
|
class ViaUserId(
|
||||||
KeyAccessor(info, key) {
|
key: OpenPGPComponentKey,
|
||||||
override val signatureWithPreferences: PGPSignature
|
userId: OpenPGPIdentityComponent,
|
||||||
get() =
|
referenceTime: Date = Date()
|
||||||
checkNotNull(info.getLatestUserIdCertification(userId.toString())) {
|
) : KeyAccessor(key, referenceTime) {
|
||||||
"No valid user-id certification signature found for '$userId'."
|
override val component: OpenPGPCertificateComponent = userId
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Address the key via key-id. In this case we are sourcing preferred algorithms from the keys
|
* Address the key via key-id. In this case we are sourcing preferred algorithms from the keys
|
||||||
* direct-key signature first.
|
* direct-key signature first.
|
||||||
*/
|
*/
|
||||||
class ViaKeyId(info: KeyRingInfo, key: SubkeyIdentifier) : KeyAccessor(info, key) {
|
class ViaKeyIdentifier(key: OpenPGPComponentKey, referenceTime: Date = Date()) :
|
||||||
override val signatureWithPreferences: PGPSignature
|
KeyAccessor(key, referenceTime) {
|
||||||
get() {
|
override val component: OpenPGPCertificateComponent = key
|
||||||
if (key.isPrimaryKey) {
|
|
||||||
// If the key is located by Key ID, the algorithm of the primary User ID of the
|
|
||||||
// key
|
|
||||||
// provides the
|
|
||||||
// preferred symmetric algorithm.
|
|
||||||
info.primaryUserId?.let { userId ->
|
|
||||||
info.getLatestUserIdCertification(userId).let { if (it != null) return it }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return info.getCurrentSubkeyBindingSignature(key.keyIdentifier)
|
|
||||||
?: throw NoSuchElementException(
|
|
||||||
"Key does not carry acceptable self-signature signature.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,8 +250,22 @@ class SecretKeyRingEditor(
|
||||||
val callback =
|
val callback =
|
||||||
object : SelfSignatureSubpackets.Callback {
|
object : SelfSignatureSubpackets.Callback {
|
||||||
override fun modifyHashedSubpackets(hashedSubpackets: SelfSignatureSubpackets) {
|
override fun modifyHashedSubpackets(hashedSubpackets: SelfSignatureSubpackets) {
|
||||||
SignatureSubpacketsHelper.applyFrom(
|
hashedSubpackets.apply {
|
||||||
keySpec.subpackets, hashedSubpackets as SignatureSubpackets)
|
setKeyFlags(keySpec.keyFlags)
|
||||||
|
keySpec.preferredHashAlgorithmsOverride?.let {
|
||||||
|
setPreferredHashAlgorithms(it)
|
||||||
|
}
|
||||||
|
keySpec.preferredCompressionAlgorithmsOverride?.let {
|
||||||
|
setPreferredCompressionAlgorithms(it)
|
||||||
|
}
|
||||||
|
keySpec.preferredSymmetricAlgorithmsOverride?.let {
|
||||||
|
setPreferredSymmetricKeyAlgorithms(it)
|
||||||
|
}
|
||||||
|
keySpec.preferredAEADAlgorithmsOverride?.let {
|
||||||
|
setPreferredAEADCiphersuites(it)
|
||||||
|
}
|
||||||
|
keySpec.featuresOverride?.let { setFeatures(*it.toTypedArray()) }
|
||||||
|
}
|
||||||
hashedSubpackets.setSignatureCreationTime(referenceTime)
|
hashedSubpackets.setSignatureCreationTime(referenceTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -268,7 +282,7 @@ class SecretKeyRingEditor(
|
||||||
val keyPair = KeyRingBuilder.generateKeyPair(keySpec, version, api.implementation)
|
val keyPair = KeyRingBuilder.generateKeyPair(keySpec, version, api.implementation)
|
||||||
val subkeyProtector =
|
val subkeyProtector =
|
||||||
PasswordBasedSecretKeyRingProtector.forKeyId(keyPair.keyIdentifier, subkeyPassphrase)
|
PasswordBasedSecretKeyRingProtector.forKeyId(keyPair.keyIdentifier, subkeyPassphrase)
|
||||||
val keyFlags = KeyFlag.fromBitmask(keySpec.subpackets.keyFlags).toMutableList()
|
val keyFlags = keySpec.keyFlags.toMutableList()
|
||||||
return addSubKey(
|
return addSubKey(
|
||||||
keyPair,
|
keyPair,
|
||||||
callback,
|
callback,
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.pgpainless.PGPainless;
|
import org.pgpainless.PGPainless;
|
||||||
import org.pgpainless.algorithm.AEADAlgorithm;
|
import org.pgpainless.algorithm.AEADAlgorithm;
|
||||||
import org.pgpainless.algorithm.AEADCipherMode;
|
import org.pgpainless.algorithm.AEADCipherMode;
|
||||||
|
import org.pgpainless.algorithm.AlgorithmSuite;
|
||||||
import org.pgpainless.algorithm.DocumentSignatureType;
|
import org.pgpainless.algorithm.DocumentSignatureType;
|
||||||
import org.pgpainless.algorithm.Feature;
|
import org.pgpainless.algorithm.Feature;
|
||||||
import org.pgpainless.algorithm.KeyFlag;
|
import org.pgpainless.algorithm.KeyFlag;
|
||||||
|
@ -323,9 +324,11 @@ public class EncryptDecryptTest {
|
||||||
public void testEncryptToOnlyV4CertWithOnlySEIPD1Feature() throws PGPException, IOException {
|
public void testEncryptToOnlyV4CertWithOnlySEIPD1Feature() throws PGPException, IOException {
|
||||||
PGPainless api = PGPainless.getInstance();
|
PGPainless api = PGPainless.getInstance();
|
||||||
OpenPGPKey v4Key = api.buildKey(OpenPGPKeyVersion.v4)
|
OpenPGPKey v4Key = api.buildKey(OpenPGPKeyVersion.v4)
|
||||||
.setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
|
.withPreferences(AlgorithmSuite.emptyBuilder()
|
||||||
.overridePreferredSymmetricKeyAlgorithms(SymmetricKeyAlgorithm.AES_192)
|
.overrideSymmetricKeyAlgorithms(SymmetricKeyAlgorithm.AES_192)
|
||||||
.overrideFeatures(Feature.MODIFICATION_DETECTION)) // the key only supports SEIPD1
|
.overrideFeatures(Feature.MODIFICATION_DETECTION)
|
||||||
|
.build())
|
||||||
|
.setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA))
|
||||||
.addSubkey(KeySpec.getBuilder(KeyType.XDH_LEGACY(XDHLegacySpec._X25519), KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE))
|
.addSubkey(KeySpec.getBuilder(KeyType.XDH_LEGACY(XDHLegacySpec._X25519), KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -358,9 +361,11 @@ public class EncryptDecryptTest {
|
||||||
public void testEncryptToOnlyV6CertWithOnlySEIPD2Features() throws IOException, PGPException {
|
public void testEncryptToOnlyV6CertWithOnlySEIPD2Features() throws IOException, PGPException {
|
||||||
PGPainless api = PGPainless.getInstance();
|
PGPainless api = PGPainless.getInstance();
|
||||||
OpenPGPKey v6Key = api.buildKey(OpenPGPKeyVersion.v6)
|
OpenPGPKey v6Key = api.buildKey(OpenPGPKeyVersion.v6)
|
||||||
.setPrimaryKey(KeySpec.getBuilder(KeyType.Ed25519(), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
|
.withPreferences(AlgorithmSuite.emptyBuilder()
|
||||||
.overridePreferredAEADAlgorithms(new AEADCipherMode(AEADAlgorithm.OCB, SymmetricKeyAlgorithm.AES_128))
|
.overrideFeatures(Feature.MODIFICATION_DETECTION_2)
|
||||||
.overrideFeatures(Feature.MODIFICATION_DETECTION_2)) // the key only supports SEIPD2
|
.overrideAeadAlgorithms(new AEADCipherMode(AEADAlgorithm.OCB, SymmetricKeyAlgorithm.AES_192))
|
||||||
|
.build())
|
||||||
|
.setPrimaryKey(KeySpec.getBuilder(KeyType.Ed25519(), KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA))
|
||||||
.addSubkey(KeySpec.getBuilder(KeyType.X25519(), KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE))
|
.addSubkey(KeySpec.getBuilder(KeyType.X25519(), KeyFlag.ENCRYPT_COMMS, KeyFlag.ENCRYPT_STORAGE))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,10 @@ import org.bouncycastle.openpgp.PGPPublicKey;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.pgpainless.PGPainless;
|
import org.pgpainless.PGPainless;
|
||||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
import org.pgpainless.algorithm.AlgorithmSuite;
|
||||||
import org.pgpainless.algorithm.HashAlgorithm;
|
import org.pgpainless.algorithm.HashAlgorithm;
|
||||||
import org.pgpainless.algorithm.KeyFlag;
|
import org.pgpainless.algorithm.KeyFlag;
|
||||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
import org.pgpainless.algorithm.OpenPGPKeyVersion;
|
||||||
import org.pgpainless.key.generation.KeySpec;
|
import org.pgpainless.key.generation.KeySpec;
|
||||||
import org.pgpainless.key.generation.type.KeyType;
|
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;
|
||||||
|
@ -25,12 +25,11 @@ public class GuessPreferredHashAlgorithmTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void guessPreferredHashAlgorithmsAssumesHashAlgoUsedBySelfSig() {
|
public void guessPreferredHashAlgorithmsAssumesHashAlgoUsedBySelfSig() {
|
||||||
PGPSecretKeyRing secretKeys = PGPainless.buildKeyRing()
|
PGPainless api = PGPainless.getInstance();
|
||||||
|
PGPSecretKeyRing secretKeys = api.buildKey(OpenPGPKeyVersion.v4)
|
||||||
|
.withPreferences(AlgorithmSuite.emptyBuilder().build())
|
||||||
.setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519),
|
.setPrimaryKey(KeySpec.getBuilder(KeyType.EDDSA_LEGACY(EdDSALegacyCurve._Ed25519),
|
||||||
KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA)
|
KeyFlag.CERTIFY_OTHER, KeyFlag.SIGN_DATA))
|
||||||
.overridePreferredHashAlgorithms(new HashAlgorithm[] {})
|
|
||||||
.overridePreferredSymmetricKeyAlgorithms(new SymmetricKeyAlgorithm[] {})
|
|
||||||
.overridePreferredCompressionAlgorithms(new CompressionAlgorithm[] {}))
|
|
||||||
.addUserId("test@test.test")
|
.addUserId("test@test.test")
|
||||||
.build()
|
.build()
|
||||||
.getPGPSecretKeyRing();
|
.getPGPSecretKeyRing();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue