1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-09-09 18:29:39 +02:00

Swappable algorithm negotiation delegates

This commit is contained in:
Paul Schaub 2025-06-03 11:58:59 +02:00
parent 91730fd13f
commit fa289e9ca2
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
4 changed files with 46 additions and 23 deletions

View file

@ -0,0 +1,24 @@
// SPDX-FileCopyrightText: 2025 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.algorithm.negotiation
import org.pgpainless.algorithm.CompressionAlgorithm
import org.pgpainless.policy.Policy
fun interface CompressionAlgorithmNegotiator {
fun negotiate(
policy: Policy,
override: CompressionAlgorithm?,
orderedPreferences: Set<CompressionAlgorithm>?
): CompressionAlgorithm
companion object {
@JvmStatic
fun staticNegotiation(): CompressionAlgorithmNegotiator =
CompressionAlgorithmNegotiator { policy, override, _ ->
override ?: policy.compressionAlgorithmPolicy.defaultCompressionAlgorithm
}
}
}

View file

@ -27,6 +27,9 @@ import org.pgpainless.key.info.KeyRingInfo
import org.pgpainless.util.Passphrase 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) {
var encryptionMechanismNegotiator: EncryptionMechanismNegotiator =
EncryptionMechanismNegotiator.modificationDetectionOrBetter(byPopularity())
private val _encryptionMethods: MutableSet<PGPKeyEncryptionMethodGenerator> = mutableSetOf() private val _encryptionMethods: MutableSet<PGPKeyEncryptionMethodGenerator> = mutableSetOf()
private val keysAndAccessors: MutableMap<OpenPGPComponentKey, KeyAccessor> = mutableMapOf() private val keysAndAccessors: MutableMap<OpenPGPComponentKey, KeyAccessor> = mutableMapOf()
private val _keyRingInfo: MutableMap<SubkeyIdentifier, KeyRingInfo> = mutableMapOf() private val _keyRingInfo: MutableMap<SubkeyIdentifier, KeyRingInfo> = mutableMapOf()
@ -442,13 +445,12 @@ class EncryptionOptions(private val purpose: EncryptionPurpose, private val api:
keysAndAccessors.values.map { it.preferredSymmetricKeyAlgorithms }.toList() keysAndAccessors.values.map { it.preferredSymmetricKeyAlgorithms }.toList()
val mechanism = val mechanism =
EncryptionMechanismNegotiator.modificationDetectionOrBetter(byPopularity()) encryptionMechanismNegotiator.negotiate(
.negotiate( api.algorithmPolicy,
api.algorithmPolicy, encryptionMechanismOverride,
encryptionMechanismOverride, features,
features, aeadAlgorithms,
aeadAlgorithms, symmetricKeyAlgorithms)
symmetricKeyAlgorithms)
return mechanism return mechanism
} }

View file

@ -8,13 +8,15 @@ import java.util.*
import org.bouncycastle.openpgp.PGPLiteralData import org.bouncycastle.openpgp.PGPLiteralData
import org.pgpainless.algorithm.CompressionAlgorithm import org.pgpainless.algorithm.CompressionAlgorithm
import org.pgpainless.algorithm.StreamEncoding import org.pgpainless.algorithm.StreamEncoding
import org.pgpainless.algorithm.negotiation.CompressionAlgorithmNegotiator
import org.pgpainless.policy.Policy import org.pgpainless.policy.Policy
class ProducerOptions( class ProducerOptions(
val encryptionOptions: EncryptionOptions?, val encryptionOptions: EncryptionOptions?,
val signingOptions: SigningOptions? val signingOptions: SigningOptions?
) { ) {
var compressionAlgorithmNegotiator: CompressionAlgorithmNegotiator =
CompressionAlgorithmNegotiator.staticNegotiation()
private var _fileName: String = "" private var _fileName: String = ""
private var _modificationDate: Date = PGPLiteralData.NOW private var _modificationDate: Date = PGPLiteralData.NOW
private var encodingField: StreamEncoding = StreamEncoding.BINARY private var encodingField: StreamEncoding = StreamEncoding.BINARY
@ -237,8 +239,8 @@ class ProducerOptions(
} }
internal fun negotiateCompressionAlgorithm(policy: Policy): CompressionAlgorithm { internal fun negotiateCompressionAlgorithm(policy: Policy): CompressionAlgorithm {
return compressionAlgorithmOverride return compressionAlgorithmNegotiator.negotiate(
?: policy.compressionAlgorithmPolicy.defaultCompressionAlgorithm policy, compressionAlgorithmOverride, setOf())
} }
companion object { companion object {

View file

@ -15,6 +15,7 @@ import org.pgpainless.PGPainless
import org.pgpainless.algorithm.DocumentSignatureType import org.pgpainless.algorithm.DocumentSignatureType
import org.pgpainless.algorithm.HashAlgorithm import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.algorithm.PublicKeyAlgorithm.Companion.requireFromId import org.pgpainless.algorithm.PublicKeyAlgorithm.Companion.requireFromId
import org.pgpainless.algorithm.negotiation.HashAlgorithmNegotiator
import org.pgpainless.algorithm.negotiation.HashAlgorithmNegotiator.Companion.negotiateSignatureHashAlgorithm import org.pgpainless.algorithm.negotiation.HashAlgorithmNegotiator.Companion.negotiateSignatureHashAlgorithm
import org.pgpainless.exception.KeyException import org.pgpainless.exception.KeyException
import org.pgpainless.exception.KeyException.* import org.pgpainless.exception.KeyException.*
@ -27,7 +28,8 @@ import org.pgpainless.signature.subpackets.SignatureSubpackets
import org.pgpainless.signature.subpackets.SignatureSubpacketsHelper import org.pgpainless.signature.subpackets.SignatureSubpacketsHelper
class SigningOptions(private val api: PGPainless) { class SigningOptions(private val api: PGPainless) {
var hashAlgorithmNegotiator: HashAlgorithmNegotiator =
negotiateSignatureHashAlgorithm(api.algorithmPolicy)
val signingMethods: Map<OpenPGPPrivateKey, SigningMethod> = mutableMapOf() val signingMethods: Map<OpenPGPPrivateKey, SigningMethod> = mutableMapOf()
private var _hashAlgorithmOverride: HashAlgorithm? = null private var _hashAlgorithmOverride: HashAlgorithm? = null
private var _evaluationDate: Date = Date() private var _evaluationDate: Date = Date()
@ -200,8 +202,7 @@ class SigningOptions(private val api: PGPainless) {
val hashAlgorithms = val hashAlgorithms =
if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId) if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId)
else keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyIdentifier) else keyRingInfo.getPreferredHashAlgorithms(signingPubKey.keyIdentifier)
val hashAlgorithm: HashAlgorithm = val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms)
negotiateHashAlgorithm(hashAlgorithms, api.algorithmPolicy)
addSigningMethod( addSigningMethod(
signingPrivKey, hashAlgorithm, signatureType, false, subpacketsCallback) signingPrivKey, hashAlgorithm, signatureType, false, subpacketsCallback)
} }
@ -268,8 +269,7 @@ class SigningOptions(private val api: PGPainless) {
val signingPrivKey = unlockSecretKey(signingKey, signingKeyProtector) val signingPrivKey = unlockSecretKey(signingKey, signingKeyProtector)
val hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(signingKey.keyIdentifier) val hashAlgorithms = keyRingInfo.getPreferredHashAlgorithms(signingKey.keyIdentifier)
val hashAlgorithm: HashAlgorithm = val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms)
negotiateHashAlgorithm(hashAlgorithms, api.algorithmPolicy)
addSigningMethod(signingPrivKey, hashAlgorithm, signatureType, false, subpacketsCallback) addSigningMethod(signingPrivKey, hashAlgorithm, signatureType, false, subpacketsCallback)
} }
@ -467,8 +467,7 @@ class SigningOptions(private val api: PGPainless) {
val hashAlgorithms = val hashAlgorithms =
if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId) if (userId != null) keyRingInfo.getPreferredHashAlgorithms(userId)
else keyRingInfo.getPreferredHashAlgorithms(signingKey.keyIdentifier) else keyRingInfo.getPreferredHashAlgorithms(signingKey.keyIdentifier)
val hashAlgorithm: HashAlgorithm = val hashAlgorithm: HashAlgorithm = negotiateHashAlgorithm(hashAlgorithms)
negotiateHashAlgorithm(hashAlgorithms, api.algorithmPolicy)
addSigningMethod(signingPrivKey, hashAlgorithm, signatureType, true, subpacketCallback) addSigningMethod(signingPrivKey, hashAlgorithm, signatureType, true, subpacketCallback)
} }
@ -559,12 +558,8 @@ class SigningOptions(private val api: PGPainless) {
* @param policy policy * @param policy policy
* @return selected hash algorithm * @return selected hash algorithm
*/ */
private fun negotiateHashAlgorithm( private fun negotiateHashAlgorithm(preferences: Set<HashAlgorithm>?): HashAlgorithm {
preferences: Set<HashAlgorithm>?, return _hashAlgorithmOverride ?: hashAlgorithmNegotiator.negotiateHashAlgorithm(preferences)
policy: Policy
): HashAlgorithm {
return _hashAlgorithmOverride
?: negotiateSignatureHashAlgorithm(policy).negotiateHashAlgorithm(preferences)
} }
@Throws(PGPException::class) @Throws(PGPException::class)