mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-09-09 18:29:39 +02:00
WIP: EncryptionMechanismPolicy
This commit is contained in:
parent
de7c2ea633
commit
5c0cdfd494
4 changed files with 241 additions and 29 deletions
|
@ -92,7 +92,8 @@ class PolicyAdapter(val policy: Policy) : OpenPGPPolicy {
|
|||
* @return boolean indicating, whether the encryption algorithm is acceptable
|
||||
*/
|
||||
override fun isAcceptableSymmetricKeyAlgorithm(algorithmId: Int): Boolean {
|
||||
return policy.symmetricKeyEncryptionAlgorithmPolicy.isAcceptable(algorithmId)
|
||||
return policy.messageEncryptionAlgorithmPolicy.symmetricAlgorithmPolicy.isAcceptable(
|
||||
algorithmId)
|
||||
}
|
||||
/**
|
||||
* Return the default symmetric encryption algorithm. This algorithm is used as fallback to
|
||||
|
@ -101,7 +102,9 @@ class PolicyAdapter(val policy: Policy) : OpenPGPPolicy {
|
|||
* @return default symmetric encryption algorithm
|
||||
*/
|
||||
override fun getDefaultSymmetricKeyAlgorithm(): Int {
|
||||
return policy.symmetricKeyEncryptionAlgorithmPolicy.defaultSymmetricKeyAlgorithm.algorithmId
|
||||
return policy.messageEncryptionAlgorithmPolicy.symmetricAlgorithmPolicy
|
||||
.defaultSymmetricKeyAlgorithm
|
||||
.algorithmId
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -739,7 +739,8 @@ class OpenPgpMessageInputStream(
|
|||
}
|
||||
|
||||
private fun isAcceptable(algorithm: SymmetricKeyAlgorithm): Boolean =
|
||||
api.algorithmPolicy.symmetricKeyDecryptionAlgorithmPolicy.isAcceptable(algorithm)
|
||||
api.algorithmPolicy.messageDecryptionAlgorithmPolicy.symmetricAlgorithmPolicy.isAcceptable(
|
||||
algorithm)
|
||||
|
||||
private fun throwIfUnacceptable(algorithm: SymmetricKeyAlgorithm) {
|
||||
if (!isAcceptable(algorithm)) {
|
||||
|
|
|
@ -404,8 +404,8 @@ class EncryptionOptions(private val purpose: EncryptionPurpose, private val api:
|
|||
|
||||
fun overrideEncryptionMechanism(encryptionMechanism: MessageEncryptionMechanism) = apply {
|
||||
require(
|
||||
api.algorithmPolicy.symmetricKeyEncryptionAlgorithmPolicy.isAcceptable(
|
||||
encryptionMechanism.symmetricKeyAlgorithm)) {
|
||||
api.algorithmPolicy.messageEncryptionAlgorithmPolicy.isAcceptable(
|
||||
encryptionMechanism)) {
|
||||
"Provided symmetric encryption algorithm is not acceptable."
|
||||
}
|
||||
_encryptionMechanismOverride = encryptionMechanism
|
||||
|
@ -431,7 +431,7 @@ class EncryptionOptions(private val purpose: EncryptionPurpose, private val api:
|
|||
val algorithm =
|
||||
byPopularity()
|
||||
.negotiate(
|
||||
api.algorithmPolicy.symmetricKeyEncryptionAlgorithmPolicy,
|
||||
api.algorithmPolicy.messageEncryptionAlgorithmPolicy.symmetricAlgorithmPolicy,
|
||||
encryptionAlgorithmOverride,
|
||||
preferences)
|
||||
return algorithm
|
||||
|
|
|
@ -5,23 +5,77 @@
|
|||
package org.pgpainless.policy
|
||||
|
||||
import java.util.*
|
||||
import org.bouncycastle.openpgp.api.EncryptedDataPacketType
|
||||
import org.bouncycastle.openpgp.api.MessageEncryptionMechanism
|
||||
import org.pgpainless.algorithm.*
|
||||
import org.pgpainless.key.protection.KeyRingProtectionSettings
|
||||
import org.pgpainless.util.DateUtil
|
||||
import org.pgpainless.util.NotationRegistry
|
||||
|
||||
class Policy(
|
||||
val certificationSignatureHashAlgorithmPolicy: HashAlgorithmPolicy,
|
||||
val revocationSignatureHashAlgorithmPolicy: HashAlgorithmPolicy,
|
||||
val dataSignatureHashAlgorithmPolicy: HashAlgorithmPolicy,
|
||||
val symmetricKeyEncryptionAlgorithmPolicy: SymmetricKeyAlgorithmPolicy,
|
||||
val symmetricKeyDecryptionAlgorithmPolicy: SymmetricKeyAlgorithmPolicy,
|
||||
val compressionAlgorithmPolicy: CompressionAlgorithmPolicy,
|
||||
val publicKeyAlgorithmPolicy: PublicKeyAlgorithmPolicy,
|
||||
val keyProtectionSettings: KeyRingProtectionSettings,
|
||||
val notationRegistry: NotationRegistry,
|
||||
class Policy {
|
||||
|
||||
val certificationSignatureHashAlgorithmPolicy: HashAlgorithmPolicy
|
||||
val revocationSignatureHashAlgorithmPolicy: HashAlgorithmPolicy
|
||||
val dataSignatureHashAlgorithmPolicy: HashAlgorithmPolicy
|
||||
val messageEncryptionAlgorithmPolicy: MessageEncryptionMechanismPolicy
|
||||
val messageDecryptionAlgorithmPolicy: MessageEncryptionMechanismPolicy
|
||||
val compressionAlgorithmPolicy: CompressionAlgorithmPolicy
|
||||
val publicKeyAlgorithmPolicy: PublicKeyAlgorithmPolicy
|
||||
val keyProtectionSettings: KeyRingProtectionSettings
|
||||
val notationRegistry: NotationRegistry
|
||||
val keyGenerationAlgorithmSuite: AlgorithmSuite
|
||||
) {
|
||||
|
||||
constructor(
|
||||
certificationSignatureHashAlgorithmPolicy: HashAlgorithmPolicy,
|
||||
revocationSignatureHashAlgorithmPolicy: HashAlgorithmPolicy,
|
||||
dataSignatureHashAlgorithmPolicy: HashAlgorithmPolicy,
|
||||
messageEncryptionMechanismPolicy: MessageEncryptionMechanismPolicy,
|
||||
messageDecryptionMechanismPolicy: MessageEncryptionMechanismPolicy,
|
||||
compressionAlgorithmPolicy: CompressionAlgorithmPolicy,
|
||||
publicKeyAlgorithmPolicy: PublicKeyAlgorithmPolicy,
|
||||
keyProtectionSettings: KeyRingProtectionSettings,
|
||||
notationRegistry: NotationRegistry,
|
||||
keyGenerationAlgorithmSuite: AlgorithmSuite
|
||||
) {
|
||||
this.certificationSignatureHashAlgorithmPolicy = certificationSignatureHashAlgorithmPolicy
|
||||
this.revocationSignatureHashAlgorithmPolicy = revocationSignatureHashAlgorithmPolicy
|
||||
this.dataSignatureHashAlgorithmPolicy = dataSignatureHashAlgorithmPolicy
|
||||
this.messageEncryptionAlgorithmPolicy = messageEncryptionMechanismPolicy
|
||||
this.messageDecryptionAlgorithmPolicy = messageDecryptionMechanismPolicy
|
||||
this.compressionAlgorithmPolicy = compressionAlgorithmPolicy
|
||||
this.publicKeyAlgorithmPolicy = publicKeyAlgorithmPolicy
|
||||
this.keyProtectionSettings = keyProtectionSettings
|
||||
this.notationRegistry = notationRegistry
|
||||
this.keyGenerationAlgorithmSuite = keyGenerationAlgorithmSuite
|
||||
}
|
||||
|
||||
constructor(
|
||||
certificationSignatureHashAlgorithmPolicy: HashAlgorithmPolicy,
|
||||
revocationSignatureHashAlgorithmPolicy: HashAlgorithmPolicy,
|
||||
dataSignatureHashAlgorithmPolicy: HashAlgorithmPolicy,
|
||||
symmetricKeyEncryptionAlgorithmPolicy: SymmetricKeyAlgorithmPolicy,
|
||||
symmetricKeyDecryptionAlgorithmPolicy: SymmetricKeyAlgorithmPolicy,
|
||||
compressionAlgorithmPolicy: CompressionAlgorithmPolicy,
|
||||
publicKeyAlgorithmPolicy: PublicKeyAlgorithmPolicy,
|
||||
keyProtectionSettings: KeyRingProtectionSettings,
|
||||
notationRegistry: NotationRegistry,
|
||||
keyGenerationAlgorithmSuite: AlgorithmSuite
|
||||
) {
|
||||
this.certificationSignatureHashAlgorithmPolicy = certificationSignatureHashAlgorithmPolicy
|
||||
this.revocationSignatureHashAlgorithmPolicy = revocationSignatureHashAlgorithmPolicy
|
||||
this.dataSignatureHashAlgorithmPolicy = dataSignatureHashAlgorithmPolicy
|
||||
this.messageEncryptionAlgorithmPolicy =
|
||||
MessageEncryptionMechanismPolicy.rfc4880Plus9580PlusLibrePGP(
|
||||
symmetricKeyEncryptionAlgorithmPolicy)
|
||||
this.messageDecryptionAlgorithmPolicy =
|
||||
MessageEncryptionMechanismPolicy.rfc4880Plus9580PlusLibrePGP(
|
||||
symmetricKeyDecryptionAlgorithmPolicy)
|
||||
this.compressionAlgorithmPolicy = compressionAlgorithmPolicy
|
||||
this.publicKeyAlgorithmPolicy = publicKeyAlgorithmPolicy
|
||||
this.keyProtectionSettings = keyProtectionSettings
|
||||
this.notationRegistry = notationRegistry
|
||||
this.keyGenerationAlgorithmSuite = keyGenerationAlgorithmSuite
|
||||
}
|
||||
|
||||
constructor() :
|
||||
this(
|
||||
|
@ -36,6 +90,14 @@ class Policy(
|
|||
NotationRegistry(),
|
||||
AlgorithmSuite.defaultAlgorithmSuite)
|
||||
|
||||
@Deprecated("Deprecated in favor of messageEncryptionAlgorithmPolicy")
|
||||
val symmetricKeyEncryptionAlgorithmPolicy
|
||||
get() = messageEncryptionAlgorithmPolicy.symmetricAlgorithmPolicy
|
||||
|
||||
@Deprecated("Deprecated in favor of messageDecryptionAlgorithmPolicy")
|
||||
val symmetricKeyDecryptionAlgorithmPolicy
|
||||
get() = messageDecryptionAlgorithmPolicy.symmetricAlgorithmPolicy
|
||||
|
||||
/**
|
||||
* Decide, whether to sanitize public key parameters when unlocking OpenPGP secret keys. OpenPGP
|
||||
* v4 keys are susceptible to a class of attacks, where an attacker with access to the locked
|
||||
|
@ -189,6 +251,138 @@ class Policy(
|
|||
}
|
||||
}
|
||||
|
||||
abstract class MessageEncryptionMechanismPolicy(
|
||||
val symmetricAlgorithmPolicy: SymmetricKeyAlgorithmPolicy,
|
||||
val asymmetricFallbackMechanism: MessageEncryptionMechanism,
|
||||
val symmetricFallbackMechanism: MessageEncryptionMechanism = asymmetricFallbackMechanism
|
||||
) {
|
||||
abstract fun isAcceptable(encryptionMechanism: MessageEncryptionMechanism): Boolean
|
||||
|
||||
companion object {
|
||||
|
||||
@JvmStatic
|
||||
fun rfc4880(
|
||||
symAlgPolicy: SymmetricKeyAlgorithmPolicy
|
||||
): MessageEncryptionMechanismPolicy {
|
||||
return object :
|
||||
MessageEncryptionMechanismPolicy(
|
||||
symAlgPolicy,
|
||||
MessageEncryptionMechanism.integrityProtected(
|
||||
symAlgPolicy.defaultSymmetricKeyAlgorithm.algorithmId)) {
|
||||
override fun isAcceptable(
|
||||
encryptionMechanism: MessageEncryptionMechanism
|
||||
): Boolean {
|
||||
return encryptionMechanism.mode == EncryptedDataPacketType.SEIPDv1 &&
|
||||
symAlgPolicy.isAcceptable(encryptionMechanism.symmetricKeyAlgorithm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun rfc9580(
|
||||
symAlgPolicy: SymmetricKeyAlgorithmPolicy
|
||||
): MessageEncryptionMechanismPolicy {
|
||||
return object :
|
||||
MessageEncryptionMechanismPolicy(
|
||||
symAlgPolicy,
|
||||
MessageEncryptionMechanism.aead(
|
||||
symAlgPolicy.defaultSymmetricKeyAlgorithm.algorithmId,
|
||||
AEADAlgorithm.OCB.algorithmId)) {
|
||||
val acceptableAEADAlgorithms =
|
||||
listOf(AEADAlgorithm.OCB, AEADAlgorithm.GCM, AEADAlgorithm.EAX).map {
|
||||
it.algorithmId
|
||||
}
|
||||
|
||||
override fun isAcceptable(
|
||||
encryptionMechanism: MessageEncryptionMechanism
|
||||
): Boolean {
|
||||
return when (encryptionMechanism.mode) {
|
||||
EncryptedDataPacketType.SEIPDv1 ->
|
||||
symAlgPolicy.isAcceptable(encryptionMechanism.symmetricKeyAlgorithm)
|
||||
EncryptedDataPacketType.SEIPDv2 ->
|
||||
symAlgPolicy.isAcceptable(
|
||||
encryptionMechanism.symmetricKeyAlgorithm) &&
|
||||
acceptableAEADAlgorithms.contains(
|
||||
encryptionMechanism.aeadAlgorithm)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun librePgp(
|
||||
symAlgPolicy: SymmetricKeyAlgorithmPolicy
|
||||
): MessageEncryptionMechanismPolicy {
|
||||
return object :
|
||||
MessageEncryptionMechanismPolicy(
|
||||
symAlgPolicy,
|
||||
MessageEncryptionMechanism.integrityProtected(
|
||||
symAlgPolicy.defaultSymmetricKeyAlgorithm.algorithmId)) {
|
||||
val acceptableAEADAlgorithms = listOf(AEADAlgorithm.OCB).map { it.algorithmId }
|
||||
|
||||
override fun isAcceptable(
|
||||
encryptionMechanism: MessageEncryptionMechanism
|
||||
): Boolean {
|
||||
return when (encryptionMechanism.mode) {
|
||||
EncryptedDataPacketType.SEIPDv1 ->
|
||||
symAlgPolicy.isAcceptable(encryptionMechanism.symmetricKeyAlgorithm)
|
||||
EncryptedDataPacketType.LIBREPGP_OED ->
|
||||
symAlgPolicy.isAcceptable(
|
||||
encryptionMechanism.symmetricKeyAlgorithm) &&
|
||||
acceptableAEADAlgorithms.contains(
|
||||
encryptionMechanism.aeadAlgorithm)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun rfc4880Plus9580(
|
||||
symAlgPolicy: SymmetricKeyAlgorithmPolicy
|
||||
): MessageEncryptionMechanismPolicy {
|
||||
val rfc4880 = rfc4880(symAlgPolicy)
|
||||
val rfc9580 = rfc9580(symAlgPolicy)
|
||||
return object :
|
||||
MessageEncryptionMechanismPolicy(
|
||||
symAlgPolicy,
|
||||
rfc4880.asymmetricFallbackMechanism,
|
||||
rfc4880.symmetricFallbackMechanism) {
|
||||
override fun isAcceptable(
|
||||
encryptionMechanism: MessageEncryptionMechanism
|
||||
): Boolean {
|
||||
return rfc9580.isAcceptable(encryptionMechanism) ||
|
||||
rfc4880.isAcceptable(encryptionMechanism)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun rfc4880Plus9580PlusLibrePGP(
|
||||
symAlgPolicy: SymmetricKeyAlgorithmPolicy
|
||||
): MessageEncryptionMechanismPolicy {
|
||||
return object :
|
||||
MessageEncryptionMechanismPolicy(
|
||||
symAlgPolicy,
|
||||
MessageEncryptionMechanism.integrityProtected(
|
||||
symAlgPolicy.defaultSymmetricKeyAlgorithm.algorithmId)) {
|
||||
override fun isAcceptable(
|
||||
encryptionMechanism: MessageEncryptionMechanism
|
||||
): Boolean {
|
||||
val rfc4480 = rfc4880(symAlgPolicy)
|
||||
val rfc9580 = rfc9580(symAlgPolicy)
|
||||
val librePgp = librePgp(symAlgPolicy)
|
||||
|
||||
return rfc4480.isAcceptable(encryptionMechanism) ||
|
||||
rfc9580.isAcceptable(encryptionMechanism) ||
|
||||
librePgp.isAcceptable(encryptionMechanism)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SymmetricKeyAlgorithmPolicy(
|
||||
val defaultSymmetricKeyAlgorithm: SymmetricKeyAlgorithm,
|
||||
val acceptableSymmetricKeyAlgorithms: List<SymmetricKeyAlgorithm>
|
||||
|
@ -440,10 +634,10 @@ class Policy(
|
|||
origin.revocationSignatureHashAlgorithmPolicy
|
||||
private var dataSignatureHashAlgorithmPolicy: HashAlgorithmPolicy =
|
||||
origin.dataSignatureHashAlgorithmPolicy
|
||||
private var symmetricKeyEncryptionAlgorithmPolicy: SymmetricKeyAlgorithmPolicy =
|
||||
origin.symmetricKeyEncryptionAlgorithmPolicy
|
||||
private var symmetricKeyDecryptionAlgorithmPolicy: SymmetricKeyAlgorithmPolicy =
|
||||
origin.symmetricKeyDecryptionAlgorithmPolicy
|
||||
private var messageEncryptionMechanismPolicy: MessageEncryptionMechanismPolicy =
|
||||
origin.messageEncryptionAlgorithmPolicy
|
||||
private var messageDecryptionMechanismPolicy: MessageEncryptionMechanismPolicy =
|
||||
origin.messageDecryptionAlgorithmPolicy
|
||||
private var compressionAlgorithmPolicy: CompressionAlgorithmPolicy =
|
||||
origin.compressionAlgorithmPolicy
|
||||
private var publicKeyAlgorithmPolicy: PublicKeyAlgorithmPolicy =
|
||||
|
@ -469,17 +663,31 @@ class Policy(
|
|||
dataSignatureHashAlgorithmPolicy: HashAlgorithmPolicy
|
||||
) = apply { this.dataSignatureHashAlgorithmPolicy = dataSignatureHashAlgorithmPolicy }
|
||||
|
||||
@Deprecated(
|
||||
"Usage of SymmetricKeyAlgorithmPolicy is deprecated in favor of MessageEncryptionMechanismPolicy.")
|
||||
fun withSymmetricKeyEncryptionAlgorithmPolicy(
|
||||
symmetricKeyEncryptionAlgorithmPolicy: SymmetricKeyAlgorithmPolicy
|
||||
) = apply {
|
||||
this.symmetricKeyEncryptionAlgorithmPolicy = symmetricKeyEncryptionAlgorithmPolicy
|
||||
}
|
||||
) =
|
||||
withMessageEncryptionAlgorithmPolicy(
|
||||
MessageEncryptionMechanismPolicy.rfc4880Plus9580PlusLibrePGP(
|
||||
symmetricKeyEncryptionAlgorithmPolicy))
|
||||
|
||||
@Deprecated(
|
||||
"Usage of SymmetricKeyAlgorithmPolicy is deprecated in favor of MessageEncryptionMechanismPolicy.")
|
||||
fun withSymmetricKeyDecryptionAlgorithmPolicy(
|
||||
symmetricKeyDecryptionAlgorithmPolicy: SymmetricKeyAlgorithmPolicy
|
||||
) = apply {
|
||||
this.symmetricKeyDecryptionAlgorithmPolicy = symmetricKeyDecryptionAlgorithmPolicy
|
||||
}
|
||||
) =
|
||||
withMessageDecryptionAlgorithmPolicy(
|
||||
MessageEncryptionMechanismPolicy.rfc4880Plus9580PlusLibrePGP(
|
||||
symmetricKeyDecryptionAlgorithmPolicy))
|
||||
|
||||
fun withMessageEncryptionAlgorithmPolicy(
|
||||
encryptionMechanismPolicy: MessageEncryptionMechanismPolicy
|
||||
) = apply { messageEncryptionMechanismPolicy = encryptionMechanismPolicy }
|
||||
|
||||
fun withMessageDecryptionAlgorithmPolicy(
|
||||
decryptionMechanismPolicy: MessageEncryptionMechanismPolicy
|
||||
) = apply { messageDecryptionMechanismPolicy = decryptionMechanismPolicy }
|
||||
|
||||
fun withCompressionAlgorithmPolicy(compressionAlgorithmPolicy: CompressionAlgorithmPolicy) =
|
||||
apply {
|
||||
|
@ -508,8 +716,8 @@ class Policy(
|
|||
certificationSignatureHashAlgorithmPolicy,
|
||||
revocationSignatureHashAlgorithmPolicy,
|
||||
dataSignatureHashAlgorithmPolicy,
|
||||
symmetricKeyEncryptionAlgorithmPolicy,
|
||||
symmetricKeyDecryptionAlgorithmPolicy,
|
||||
messageEncryptionMechanismPolicy,
|
||||
messageDecryptionMechanismPolicy,
|
||||
compressionAlgorithmPolicy,
|
||||
publicKeyAlgorithmPolicy,
|
||||
keyProtectionSettings,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue