1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-12-09 05:41:07 +01:00

Work on AlgorithmSuite

This commit is contained in:
Paul Schaub 2025-03-05 15:15:13 +01:00
parent 2be4c28a52
commit 1562c9630a
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
8 changed files with 158 additions and 20 deletions

View file

@ -14,6 +14,7 @@ import org.bouncycastle.openpgp.api.OpenPGPApi
import org.bouncycastle.openpgp.api.OpenPGPCertificate
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.openpgp.api.OpenPGPKeyGenerator
import org.bouncycastle.openpgp.api.OpenPGPKeyReader
import org.bouncycastle.openpgp.api.bc.BcOpenPGPApi
import org.pgpainless.algorithm.OpenPGPKeyVersion
@ -43,8 +44,23 @@ class PGPainless(
api = BcOpenPGPApi(implementation)
}
fun generateKey(version: OpenPGPKeyVersion = OpenPGPKeyVersion.v4): KeyRingTemplates =
KeyRingTemplates(version)
@JvmOverloads
fun generateKey(
version: OpenPGPKeyVersion = OpenPGPKeyVersion.v4,
creationTime: Date = Date()
): KeyRingTemplates = KeyRingTemplates(version, creationTime)
@JvmOverloads
fun buildKey(
version: OpenPGPKeyVersion = OpenPGPKeyVersion.v4,
creationTime: Date = Date()
): OpenPGPKeyGenerator =
OpenPGPKeyGenerator(
implementation, version.numeric, version == OpenPGPKeyVersion.v6, creationTime)
.apply {
val genAlgs = algorithmPolicy.keyGenerationAlgorithmSuite
setDefaultFeatures(genAlgs.features.toSignatureSubpacketsFunction(true))
}
fun readKey(): OpenPGPKeyReader = api.readKeyOrCertificate()

View file

@ -4,15 +4,30 @@
package org.pgpainless.algorithm
import org.bouncycastle.openpgp.api.SignatureSubpacketsFunction
class AlgorithmSuite(
symmetricKeyAlgorithms: List<SymmetricKeyAlgorithm>,
hashAlgorithms: List<HashAlgorithm>,
compressionAlgorithms: List<CompressionAlgorithm>
symmetricKeyAlgorithms: List<SymmetricKeyAlgorithm>?,
hashAlgorithms: List<HashAlgorithm>?,
compressionAlgorithms: List<CompressionAlgorithm>?,
aeadAlgorithms: List<AEADCipherMode>?,
features: List<Feature>
) {
val symmetricKeyAlgorithms: Set<SymmetricKeyAlgorithm> = symmetricKeyAlgorithms.toSet()
val hashAlgorithms: Set<HashAlgorithm> = hashAlgorithms.toSet()
val compressionAlgorithms: Set<CompressionAlgorithm> = compressionAlgorithms.toSet()
val symmetricKeyAlgorithms: Set<SymmetricKeyAlgorithm>? = symmetricKeyAlgorithms?.toSet()
val hashAlgorithms: Set<HashAlgorithm>? = hashAlgorithms?.toSet()
val compressionAlgorithms: Set<CompressionAlgorithm>? = compressionAlgorithms?.toSet()
val aeadAlgorithms: Set<AEADCipherMode>? = aeadAlgorithms?.toSet()
val features: FeatureSet = FeatureSet(features.toSet())
class FeatureSet(val features: Set<Feature>) {
fun toSignatureSubpacketsFunction(critical: Boolean = true): SignatureSubpacketsFunction {
return SignatureSubpacketsFunction {
val b = Feature.toBitmask(*features.toTypedArray())
it.apply { setFeature(critical, b) }
}
}
}
companion object {
@ -39,9 +54,26 @@ class AlgorithmSuite(
CompressionAlgorithm.ZIP,
CompressionAlgorithm.UNCOMPRESSED)
@JvmStatic
val defaultAEADAlgorithmSuites =
listOf(
AEADCipherMode(AEADAlgorithm.EAX, SymmetricKeyAlgorithm.AES_256),
AEADCipherMode(AEADAlgorithm.OCB, SymmetricKeyAlgorithm.AES_256),
AEADCipherMode(AEADAlgorithm.GCM, SymmetricKeyAlgorithm.AES_256),
AEADCipherMode(AEADAlgorithm.EAX, SymmetricKeyAlgorithm.AES_192),
AEADCipherMode(AEADAlgorithm.EAX, SymmetricKeyAlgorithm.AES_192))
@JvmStatic
val defaultFeatures =
listOf(Feature.MODIFICATION_DETECTION, Feature.MODIFICATION_DETECTION_2)
@JvmStatic
val defaultAlgorithmSuite =
AlgorithmSuite(
defaultSymmetricKeyAlgorithms, defaultHashAlgorithms, defaultCompressionAlgorithms)
defaultSymmetricKeyAlgorithms,
defaultHashAlgorithms,
defaultCompressionAlgorithms,
defaultAEADAlgorithmSuites,
defaultFeatures)
}
}

View file

@ -4,6 +4,7 @@
package org.pgpainless.key.generation
import java.util.*
import org.bouncycastle.openpgp.api.OpenPGPKey
import org.pgpainless.PGPainless.Companion.buildKeyRing
import org.pgpainless.algorithm.KeyFlag
@ -15,7 +16,10 @@ import org.pgpainless.key.generation.type.rsa.RsaLength
import org.pgpainless.key.generation.type.xdh_legacy.XDHLegacySpec
import org.pgpainless.util.Passphrase
class KeyRingTemplates(private val version: OpenPGPKeyVersion) {
class KeyRingTemplates(
private val version: OpenPGPKeyVersion,
private val creationTime: Date = Date()
) {
/**
* Generate an RSA OpenPGP key consisting of an RSA primary key used for certification, a

View file

@ -20,11 +20,12 @@ constructor(
private val hashedSubpackets: SelfSignatureSubpackets = SignatureSubpackets()
private val algorithmSuite: AlgorithmSuite = PGPainless.getPolicy().keyGenerationAlgorithmSuite
private var preferredCompressionAlgorithms: Set<CompressionAlgorithm> =
private var preferredCompressionAlgorithms: Set<CompressionAlgorithm>? =
algorithmSuite.compressionAlgorithms
private var preferredHashAlgorithms: Set<HashAlgorithm> = algorithmSuite.hashAlgorithms
private var preferredSymmetricAlgorithms: Set<SymmetricKeyAlgorithm> =
private var preferredHashAlgorithms: Set<HashAlgorithm>? = algorithmSuite.hashAlgorithms
private var preferredSymmetricAlgorithms: Set<SymmetricKeyAlgorithm>? =
algorithmSuite.symmetricKeyAlgorithms
private var preferredAEADAlgorithms: Set<AEADCipherMode>? = algorithmSuite.aeadAlgorithms
private var keyCreationDate: Date? = null
constructor(type: KeyType, vararg keyFlags: KeyFlag) : this(type, listOf(*keyFlags))
@ -59,9 +60,10 @@ constructor(
return hashedSubpackets
.apply {
setKeyFlags(keyFlags)
setPreferredCompressionAlgorithms(preferredCompressionAlgorithms)
setPreferredHashAlgorithms(preferredHashAlgorithms)
setPreferredSymmetricKeyAlgorithms(preferredSymmetricAlgorithms)
preferredCompressionAlgorithms?.let { setPreferredCompressionAlgorithms(it) }
preferredHashAlgorithms?.let { setPreferredHashAlgorithms(it) }
preferredSymmetricAlgorithms?.let { setPreferredSymmetricKeyAlgorithms(it) }
preferredAEADAlgorithms?.let { setPreferredAEADCiphersuites(it) }
setFeatures(Feature.MODIFICATION_DETECTION)
}
.let { KeySpec(type, hashedSubpackets as SignatureSubpackets, false, keyCreationDate) }

View file

@ -21,14 +21,17 @@ interface BaseSignatureSubpackets {
fun setAppropriateIssuerInfo(key: PGPPublicKey): BaseSignatureSubpackets
/**
* Depending on the given [version], use the appropriate means of setting issuer information.
* V6 signatures for example MUST NOT contain an [IssuerKeyID] packet.
* Depending on the given [version], use the appropriate means of setting issuer information. V6
* signatures for example MUST NOT contain an [IssuerKeyID] packet.
*
* @param key issuer key
* @param version signature version
* @return this
*/
fun setAppropriateIssuerInfo(key: PGPPublicKey, version: OpenPGPKeyVersion): BaseSignatureSubpackets
fun setAppropriateIssuerInfo(
key: PGPPublicKey,
version: OpenPGPKeyVersion
): BaseSignatureSubpackets
/**
* Add both an [IssuerKeyID] and [IssuerFingerprint] subpacket pointing to the given key.

View file

@ -112,6 +112,8 @@ interface SelfSignatureSubpackets : BaseSignatureSubpackets {
fun setPreferredHashAlgorithms(algorithms: PreferredAlgorithms?): SelfSignatureSubpackets
fun setPreferredAEADCiphersuites(aeadAlgorithms: Set<AEADCipherMode>)
fun addRevocationKey(revocationKey: PGPPublicKey): SelfSignatureSubpackets
fun addRevocationKey(isCritical: Boolean, revocationKey: PGPPublicKey): SelfSignatureSubpackets

View file

@ -360,7 +360,8 @@ class SignatureSubpackets :
when (version) {
OpenPGPKeyVersion.v3 -> setIssuerKeyId(key.keyID)
OpenPGPKeyVersion.v4 -> setIssuerFingerprintAndKeyId(key)
OpenPGPKeyVersion.librePgp, OpenPGPKeyVersion.v6 -> setIssuerFingerprint(key)
OpenPGPKeyVersion.librePgp,
OpenPGPKeyVersion.v6 -> setIssuerFingerprint(key)
}
}