diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/PGPainless.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/PGPainless.kt index 896692c2..863a10da 100644 --- a/pgpainless-core/src/main/kotlin/org/pgpainless/PGPainless.kt +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/PGPainless.kt @@ -10,7 +10,9 @@ import org.bouncycastle.openpgp.PGPKeyRing import org.bouncycastle.openpgp.PGPPublicKeyRing import org.bouncycastle.openpgp.PGPSecretKeyRing import org.bouncycastle.openpgp.PGPSignature +import org.bouncycastle.openpgp.api.OpenPGPImplementation import org.pgpainless.algorithm.OpenPGPKeyVersion +import org.pgpainless.bouncycastle.PolicyAdapter import org.pgpainless.decryption_verification.DecryptionBuilder import org.pgpainless.encryption_signing.EncryptionBuilder import org.pgpainless.key.certification.CertifyCertificate @@ -23,10 +25,24 @@ import org.pgpainless.key.util.KeyRingUtils import org.pgpainless.policy.Policy import org.pgpainless.util.ArmorUtils -class PGPainless private constructor() { +class PGPainless( + val implementation: OpenPGPImplementation = OpenPGPImplementation.getInstance(), + val algorithmPolicy: Policy = Policy.getInstance() +) { + + init { + implementation.setPolicy( + PolicyAdapter(algorithmPolicy)) // adapt PGPainless' Policy to BCs OpenPGPPolicy + } companion object { + @Volatile private var instance: PGPainless? = null + + @JvmStatic + fun getInstance() = + instance ?: synchronized(this) { instance ?: PGPainless().also { instance = it } } + /** * Generate a fresh OpenPGP key ring from predefined templates. * @@ -166,7 +182,7 @@ class PGPainless private constructor() { * * @return policy */ - @JvmStatic fun getPolicy() = Policy.getInstance() + @JvmStatic fun getPolicy() = getInstance().algorithmPolicy /** * Create different kinds of signatures on other keys. diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/bouncycastle/PolicyAdapter.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/bouncycastle/PolicyAdapter.kt new file mode 100644 index 00000000..eed5e24c --- /dev/null +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/bouncycastle/PolicyAdapter.kt @@ -0,0 +1,77 @@ +// SPDX-FileCopyrightText: 2025 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package org.pgpainless.bouncycastle + +import java.util.Date +import org.bouncycastle.openpgp.api.OpenPGPPolicy +import org.bouncycastle.openpgp.api.OpenPGPPolicy.OpenPGPNotationRegistry +import org.pgpainless.policy.Policy + +class PolicyAdapter(val policy: Policy = Policy.getInstance()) : OpenPGPPolicy { + + override fun isAcceptableDocumentSignatureHashAlgorithm( + algorithmId: Int, + signatureCreationTime: Date? + ): Boolean { + return if (signatureCreationTime == null) + policy.dataSignatureHashAlgorithmPolicy.isAcceptable(algorithmId) + else + policy.dataSignatureHashAlgorithmPolicy.isAcceptable(algorithmId, signatureCreationTime) + } + + override fun isAcceptableRevocationSignatureHashAlgorithm( + algorithmId: Int, + revocationCreationTime: Date? + ): Boolean { + return if (revocationCreationTime == null) + policy.revocationSignatureHashAlgorithmPolicy.isAcceptable(algorithmId) + else + policy.revocationSignatureHashAlgorithmPolicy.isAcceptable( + algorithmId, revocationCreationTime) + } + + override fun isAcceptableCertificationSignatureHashAlgorithm( + algorithmId: Int, + certificationCreationTime: Date? + ): Boolean { + return if (certificationCreationTime == null) + policy.certificationSignatureHashAlgorithmPolicy.isAcceptable(algorithmId) + else + policy.certificationSignatureHashAlgorithmPolicy.isAcceptable( + algorithmId, certificationCreationTime) + } + + override fun getDefaultCertificationSignatureHashAlgorithm(): Int { + return policy.certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm.algorithmId + } + + override fun getDefaultDocumentSignatureHashAlgorithm(): Int { + return policy.dataSignatureHashAlgorithmPolicy.defaultHashAlgorithm.algorithmId + } + + override fun isAcceptableSymmetricKeyAlgorithm(p0: Int): Boolean { + return policy.symmetricKeyEncryptionAlgorithmPolicy.isAcceptable(p0) + } + + override fun getDefaultSymmetricKeyAlgorithm(): Int { + return policy.symmetricKeyEncryptionAlgorithmPolicy.defaultSymmetricKeyAlgorithm.algorithmId + } + + override fun isAcceptablePublicKeyStrength(algorithmId: Int, bitStrength: Int): Boolean { + return policy.publicKeyAlgorithmPolicy.isAcceptable(algorithmId, bitStrength) + } + + override fun getNotationRegistry(): OpenPGPPolicy.OpenPGPNotationRegistry { + return object : OpenPGPNotationRegistry() { + override fun isNotationKnown(notationName: String?): Boolean { + return notationName?.let { policy.notationRegistry.isKnownNotation(it) } ?: false + } + + override fun addKnownNotation(notationName: String?) { + notationName?.let { policy.notationRegistry.addKnownNotation(it) } + } + } + } +}