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

Remove ImplementationFactory in favor of BCs OpenPGPImplementation

This commit is contained in:
Paul Schaub 2025-03-07 14:48:03 +01:00
parent 3834f354d6
commit 32afabf878
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
48 changed files with 303 additions and 550 deletions

View file

@ -86,6 +86,12 @@ Consequently, `KeyIdentifier` is now also the preferred way to reference keys in
previously a key-id or fingerprint was expected, now also accept `KeyIdentifier` objects. previously a key-id or fingerprint was expected, now also accept `KeyIdentifier` objects.
In places, where you need to access a 64-bit key-id, you can call `keyIdentifier.getKeyId()`. In places, where you need to access a 64-bit key-id, you can call `keyIdentifier.getKeyId()`.
## `SecretKeyRingProtector`
When an OpenPGP v6 key is encrypted, the public key parts are incorporated as authenticated data into the encryption
process. Therefore, when instantiating a `PBESecretKeyEncryptor`, the public key needs to be passed in.
As a consequence, the API of `SecretKeyRingProtector` changed and now a `PGPPublicKey` needs to be passed in,
instead of merely a key-id or `KeyIdentifier`.
## Differences between BCs high-level API and PGPainless ## Differences between BCs high-level API and PGPainless

View file

@ -7,7 +7,7 @@ package org.pgpainless.decryption_verification
import java.io.IOException import java.io.IOException
import java.io.InputStream import java.io.InputStream
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.pgpainless.implementation.ImplementationFactory import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.pgpainless.util.ArmorUtils import org.pgpainless.util.ArmorUtils
/** /**
@ -68,7 +68,7 @@ class MessageInspector {
@JvmStatic @JvmStatic
@Throws(PGPException::class, IOException::class) @Throws(PGPException::class, IOException::class)
private fun processMessage(inputStream: InputStream): EncryptionInfo { private fun processMessage(inputStream: InputStream): EncryptionInfo {
var objectFactory = ImplementationFactory.getInstance().getPGPObjectFactory(inputStream) var objectFactory = OpenPGPImplementation.getInstance().pgpObjectFactory(inputStream)
var n: Any? var n: Any?
while (objectFactory.nextObject().also { n = it } != null) { while (objectFactory.nextObject().also { n = it } != null) {
@ -94,8 +94,8 @@ class MessageInspector {
} }
is PGPCompressedData -> { is PGPCompressedData -> {
objectFactory = objectFactory =
ImplementationFactory.getInstance() OpenPGPImplementation.getInstance()
.getPGPObjectFactory(PGPUtil.getDecoderStream(next.dataStream)) .pgpObjectFactory(PGPUtil.getDecoderStream(next.dataStream))
continue continue
} }
is PGPLiteralData -> { is PGPLiteralData -> {

View file

@ -23,8 +23,10 @@ import org.bouncycastle.openpgp.PGPOnePassSignature
import org.bouncycastle.openpgp.PGPPBEEncryptedData import org.bouncycastle.openpgp.PGPPBEEncryptedData
import org.bouncycastle.openpgp.PGPPublicKey import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData
import org.bouncycastle.openpgp.PGPSessionKey
import org.bouncycastle.openpgp.PGPSignature import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.api.OpenPGPCertificate import org.bouncycastle.openpgp.api.OpenPGPCertificate
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.bouncycastle.openpgp.api.OpenPGPKey import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPPrivateKey import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPPrivateKey
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPSecretKey import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPSecretKey
@ -57,7 +59,6 @@ import org.pgpainless.exception.MissingPassphraseException
import org.pgpainless.exception.SignatureValidationException import org.pgpainless.exception.SignatureValidationException
import org.pgpainless.exception.UnacceptableAlgorithmException import org.pgpainless.exception.UnacceptableAlgorithmException
import org.pgpainless.exception.WrongPassphraseException import org.pgpainless.exception.WrongPassphraseException
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.SubkeyIdentifier import org.pgpainless.key.SubkeyIdentifier
import org.pgpainless.key.protection.UnlockSecretKey.Companion.unlockSecretKey import org.pgpainless.key.protection.UnlockSecretKey.Companion.unlockSecretKey
import org.pgpainless.policy.Policy import org.pgpainless.policy.Policy
@ -360,8 +361,9 @@ class OpenPgpMessageInputStream(
LOGGER.debug("Attempt decryption with provided session key.") LOGGER.debug("Attempt decryption with provided session key.")
throwIfUnacceptable(sk.algorithm) throwIfUnacceptable(sk.algorithm)
val pgpSk = PGPSessionKey(sk.algorithm.algorithmId, sk.key)
val decryptorFactory = val decryptorFactory =
ImplementationFactory.getInstance().getSessionKeyDataDecryptorFactory(sk) OpenPGPImplementation.getInstance().sessionKeyDataDecryptorFactory(pgpSk)
val layer = EncryptedData(sk.algorithm, layerMetadata.depth + 1) val layer = EncryptedData(sk.algorithm, layerMetadata.depth + 1)
val skEncData = encDataList.extractSessionKeyEncryptedData() val skEncData = encDataList.extractSessionKeyEncryptedData()
try { try {
@ -393,7 +395,8 @@ class OpenPgpMessageInputStream(
} }
val decryptorFactory = val decryptorFactory =
ImplementationFactory.getInstance().getPBEDataDecryptorFactory(passphrase) OpenPGPImplementation.getInstance()
.pbeDataDecryptorFactory(passphrase.getChars())
if (decryptSKESKAndStream(esks, skesk, decryptorFactory)) { if (decryptSKESKAndStream(esks, skesk, decryptorFactory)) {
return true return true
} }
@ -515,8 +518,7 @@ class OpenPgpMessageInputStream(
pkesk: PGPPublicKeyEncryptedData pkesk: PGPPublicKeyEncryptedData
): Boolean { ): Boolean {
val decryptorFactory = val decryptorFactory =
ImplementationFactory.getInstance() OpenPGPImplementation.getInstance().publicKeyDataDecryptorFactory(privateKey.privateKey)
.getPublicKeyDataDecryptorFactory(privateKey.privateKey)
return decryptPKESKAndStream(esks, decryptionKeyId, decryptorFactory, pkesk) return decryptPKESKAndStream(esks, decryptionKeyId, decryptorFactory, pkesk)
} }
@ -1046,7 +1048,7 @@ class OpenPgpMessageInputStream(
@JvmStatic @JvmStatic
private fun initialize(signature: PGPSignature, publicKey: PGPPublicKey) { private fun initialize(signature: PGPSignature, publicKey: PGPPublicKey) {
val verifierProvider = val verifierProvider =
ImplementationFactory.getInstance().pgpContentVerifierBuilderProvider OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider()
try { try {
signature.init(verifierProvider, publicKey) signature.init(verifierProvider, publicKey)
} catch (e: PGPException) { } catch (e: PGPException) {
@ -1057,7 +1059,7 @@ class OpenPgpMessageInputStream(
@JvmStatic @JvmStatic
private fun initialize(ops: PGPOnePassSignature, publicKey: PGPPublicKey) { private fun initialize(ops: PGPOnePassSignature, publicKey: PGPPublicKey) {
val verifierProvider = val verifierProvider =
ImplementationFactory.getInstance().pgpContentVerifierBuilderProvider OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider()
try { try {
ops.init(verifierProvider, publicKey) ops.init(verifierProvider, publicKey)
} catch (e: PGPException) { } catch (e: PGPException) {

View file

@ -8,9 +8,9 @@ import java.io.*
import kotlin.jvm.Throws import kotlin.jvm.Throws
import org.bouncycastle.bcpg.ArmoredInputStream import org.bouncycastle.bcpg.ArmoredInputStream
import org.bouncycastle.openpgp.PGPSignatureList import org.bouncycastle.openpgp.PGPSignatureList
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.bouncycastle.util.Strings import org.bouncycastle.util.Strings
import org.pgpainless.exception.WrongConsumingMethodException import org.pgpainless.exception.WrongConsumingMethodException
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.util.ArmoredInputStreamFactory import org.pgpainless.util.ArmoredInputStreamFactory
/** /**
@ -72,7 +72,7 @@ class ClearsignedMessageUtil {
} }
} }
val objectFactory = ImplementationFactory.getInstance().getPGPObjectFactory(input) val objectFactory = OpenPGPImplementation.getInstance().pgpObjectFactory(input)
val next = objectFactory.nextObject() ?: PGPSignatureList(arrayOf()) val next = objectFactory.nextObject() ?: PGPSignatureList(arrayOf())
return next as PGPSignatureList return next as PGPSignatureList
} }

View file

@ -8,6 +8,7 @@ import java.util.*
import org.bouncycastle.openpgp.PGPPublicKeyRing import org.bouncycastle.openpgp.PGPPublicKeyRing
import org.bouncycastle.openpgp.api.OpenPGPCertificate import org.bouncycastle.openpgp.api.OpenPGPCertificate
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.bouncycastle.openpgp.operator.PGPKeyEncryptionMethodGenerator import org.bouncycastle.openpgp.operator.PGPKeyEncryptionMethodGenerator
import org.pgpainless.PGPainless.Companion.inspectKeyRing import org.pgpainless.PGPainless.Companion.inspectKeyRing
import org.pgpainless.algorithm.EncryptionPurpose import org.pgpainless.algorithm.EncryptionPurpose
@ -16,7 +17,6 @@ import org.pgpainless.authentication.CertificateAuthority
import org.pgpainless.bouncycastle.extensions.toOpenPGPCertificate import org.pgpainless.bouncycastle.extensions.toOpenPGPCertificate
import org.pgpainless.encryption_signing.EncryptionOptions.EncryptionKeySelector import org.pgpainless.encryption_signing.EncryptionOptions.EncryptionKeySelector
import org.pgpainless.exception.KeyException.* import org.pgpainless.exception.KeyException.*
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.SubkeyIdentifier import org.pgpainless.key.SubkeyIdentifier
import org.pgpainless.key.info.KeyAccessor import org.pgpainless.key.info.KeyAccessor
import org.pgpainless.key.info.KeyRingInfo import org.pgpainless.key.info.KeyRingInfo
@ -326,13 +326,13 @@ class EncryptionOptions(private val purpose: EncryptionPurpose) {
} }
} }
private fun addRecipientKey(key: OpenPGPComponentKey, wildcardKeyId: Boolean) { private fun addRecipientKey(key: OpenPGPComponentKey, wildcardRecipient: Boolean) {
_encryptionKeys.add(key) _encryptionKeys.add(key)
_encryptionKeyIdentifiers.add(SubkeyIdentifier(key)) _encryptionKeyIdentifiers.add(SubkeyIdentifier(key))
addEncryptionMethod( addEncryptionMethod(
ImplementationFactory.getInstance() OpenPGPImplementation.getInstance()
.getPublicKeyKeyEncryptionMethodGenerator(key.pgpPublicKey) .publicKeyKeyEncryptionMethodGenerator(key.pgpPublicKey)
.also { it.setUseWildcardKeyID(wildcardKeyId) }) .also { it.setUseWildcardRecipient(wildcardRecipient) })
} }
/** /**
@ -355,7 +355,8 @@ class EncryptionOptions(private val purpose: EncryptionPurpose) {
fun addMessagePassphrase(passphrase: Passphrase) = apply { fun addMessagePassphrase(passphrase: Passphrase) = apply {
require(!passphrase.isEmpty) { "Passphrase MUST NOT be empty." } require(!passphrase.isEmpty) { "Passphrase MUST NOT be empty." }
addEncryptionMethod( addEncryptionMethod(
ImplementationFactory.getInstance().getPBEKeyEncryptionMethodGenerator(passphrase)) OpenPGPImplementation.getInstance()
.pbeKeyEncryptionMethodGenerator(passphrase.getChars()))
} }
/** /**

View file

@ -13,10 +13,10 @@ import org.bouncycastle.openpgp.PGPCompressedDataGenerator
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator import org.bouncycastle.openpgp.PGPEncryptedDataGenerator
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPLiteralDataGenerator import org.bouncycastle.openpgp.PGPLiteralDataGenerator
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.pgpainless.algorithm.CompressionAlgorithm import org.pgpainless.algorithm.CompressionAlgorithm
import org.pgpainless.algorithm.StreamEncoding import org.pgpainless.algorithm.StreamEncoding
import org.pgpainless.algorithm.SymmetricKeyAlgorithm import org.pgpainless.algorithm.SymmetricKeyAlgorithm
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.SubkeyIdentifier import org.pgpainless.key.SubkeyIdentifier
import org.pgpainless.util.ArmoredOutputStreamFactory import org.pgpainless.util.ArmoredOutputStreamFactory
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
@ -89,9 +89,9 @@ class EncryptionStream(
LOGGER.debug("Encrypt message using symmetric algorithm $it.") LOGGER.debug("Encrypt message using symmetric algorithm $it.")
val encryptedDataGenerator = val encryptedDataGenerator =
PGPEncryptedDataGenerator( PGPEncryptedDataGenerator(
ImplementationFactory.getInstance().getPGPDataEncryptorBuilder(it).apply { OpenPGPImplementation.getInstance()
setWithIntegrityPacket(true) .pgpDataEncryptorBuilder(it.algorithmId)
}) .apply { setWithIntegrityPacket(true) })
options.encryptionOptions.encryptionMethods.forEach { m -> options.encryptionOptions.encryptionMethods.forEach { m ->
encryptedDataGenerator.addMethod(m) encryptedDataGenerator.addMethod(m)
} }

View file

@ -7,6 +7,7 @@ package org.pgpainless.encryption_signing
import java.util.* import java.util.*
import org.bouncycastle.bcpg.KeyIdentifier import org.bouncycastle.bcpg.KeyIdentifier
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.bouncycastle.openpgp.api.OpenPGPKey import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPPrivateKey import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPPrivateKey
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPSecretKey import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPSecretKey
@ -19,7 +20,6 @@ import org.pgpainless.algorithm.negotiation.HashAlgorithmNegotiator.Companion.ne
import org.pgpainless.bouncycastle.extensions.toOpenPGPKey import org.pgpainless.bouncycastle.extensions.toOpenPGPKey
import org.pgpainless.exception.KeyException import org.pgpainless.exception.KeyException
import org.pgpainless.exception.KeyException.* import org.pgpainless.exception.KeyException.*
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.OpenPgpFingerprint.Companion.of import org.pgpainless.key.OpenPgpFingerprint.Companion.of
import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.key.protection.UnlockSecretKey.Companion.unlockSecretKey import org.pgpainless.key.protection.UnlockSecretKey.Companion.unlockSecretKey
@ -495,8 +495,8 @@ class SigningOptions {
hashAlgorithm: HashAlgorithm, hashAlgorithm: HashAlgorithm,
signatureType: DocumentSignatureType signatureType: DocumentSignatureType
): PGPSignatureGenerator { ): PGPSignatureGenerator {
return ImplementationFactory.getInstance() return OpenPGPImplementation.getInstance()
.getPGPContentSignerBuilder(signingKey.publicKey.algorithm, hashAlgorithm.algorithmId) .pgpContentSignerBuilder(signingKey.publicKey.algorithm, hashAlgorithm.algorithmId)
.let { csb -> .let { csb ->
PGPSignatureGenerator(csb, signingKey.publicKey).also { PGPSignatureGenerator(csb, signingKey.publicKey).also {
it.init(signatureType.signatureType.code, signingKey.privateKey) it.init(signatureType.signatureType.code, signingKey.privateKey)

View file

@ -1,114 +0,0 @@
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.implementation
import java.io.InputStream
import java.security.KeyPair
import java.util.*
import org.bouncycastle.crypto.AsymmetricCipherKeyPair
import org.bouncycastle.openpgp.*
import org.bouncycastle.openpgp.bc.BcPGPObjectFactory
import org.bouncycastle.openpgp.operator.*
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator
import org.bouncycastle.openpgp.operator.bc.BcPBEDataDecryptorFactory
import org.bouncycastle.openpgp.operator.bc.BcPBEKeyEncryptionMethodGenerator
import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder
import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyEncryptorBuilder
import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder
import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider
import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder
import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider
import org.bouncycastle.openpgp.operator.bc.BcPGPKeyConverter
import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory
import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator
import org.bouncycastle.openpgp.operator.bc.BcSessionKeyDataDecryptorFactory
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair
import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.algorithm.PublicKeyAlgorithm
import org.pgpainless.algorithm.SymmetricKeyAlgorithm
import org.pgpainless.util.Passphrase
class BcImplementationFactory : ImplementationFactory() {
override val pgpDigestCalculatorProvider: BcPGPDigestCalculatorProvider =
BcPGPDigestCalculatorProvider()
override val pgpContentVerifierBuilderProvider: BcPGPContentVerifierBuilderProvider =
BcPGPContentVerifierBuilderProvider()
override val keyFingerprintCalculator: BcKeyFingerprintCalculator = BcKeyFingerprintCalculator()
override fun getPBESecretKeyEncryptor(
symmetricKeyAlgorithm: SymmetricKeyAlgorithm,
digestCalculator: PGPDigestCalculator,
passphrase: Passphrase
): PBESecretKeyEncryptor =
BcPBESecretKeyEncryptorBuilder(symmetricKeyAlgorithm.algorithmId, digestCalculator)
.build(passphrase.getChars())
override fun getPBESecretKeyEncryptor(
encryptionAlgorithm: SymmetricKeyAlgorithm,
hashAlgorithm: HashAlgorithm,
s2kCount: Int,
passphrase: Passphrase
): PBESecretKeyEncryptor =
BcPBESecretKeyEncryptorBuilder(
encryptionAlgorithm.algorithmId, getPGPDigestCalculator(hashAlgorithm), s2kCount)
.build(passphrase.getChars())
override fun getPBESecretKeyDecryptor(passphrase: Passphrase): PBESecretKeyDecryptor =
BcPBESecretKeyDecryptorBuilder(pgpDigestCalculatorProvider).build(passphrase.getChars())
override fun getPGPContentSignerBuilder(
keyAlgorithm: Int,
hashAlgorithm: Int
): PGPContentSignerBuilder = BcPGPContentSignerBuilder(keyAlgorithm, hashAlgorithm)
override fun getPBEDataDecryptorFactory(passphrase: Passphrase): PBEDataDecryptorFactory =
BcPBEDataDecryptorFactory(passphrase.getChars(), pgpDigestCalculatorProvider)
override fun getPublicKeyDataDecryptorFactory(
privateKey: PGPPrivateKey
): PublicKeyDataDecryptorFactory = BcPublicKeyDataDecryptorFactory(privateKey)
override fun getSessionKeyDataDecryptorFactory(
sessionKey: PGPSessionKey
): SessionKeyDataDecryptorFactory = BcSessionKeyDataDecryptorFactory(sessionKey)
override fun getPublicKeyKeyEncryptionMethodGenerator(
key: PGPPublicKey
): PublicKeyKeyEncryptionMethodGenerator = BcPublicKeyKeyEncryptionMethodGenerator(key)
override fun getPBEKeyEncryptionMethodGenerator(
passphrase: Passphrase
): PBEKeyEncryptionMethodGenerator = BcPBEKeyEncryptionMethodGenerator(passphrase.getChars())
override fun getPGPDataEncryptorBuilder(symmetricKeyAlgorithm: Int): PGPDataEncryptorBuilder =
BcPGPDataEncryptorBuilder(symmetricKeyAlgorithm)
override fun getPGPKeyPair(
publicKeyAlgorithm: PublicKeyAlgorithm,
keyPair: KeyPair,
creationDate: Date
): PGPKeyPair =
BcPGPKeyPair(
publicKeyAlgorithm.algorithmId,
jceToBcKeyPair(publicKeyAlgorithm, keyPair, creationDate),
creationDate)
override fun getPGPObjectFactory(inputStream: InputStream): PGPObjectFactory =
BcPGPObjectFactory(inputStream)
private fun jceToBcKeyPair(
publicKeyAlgorithm: PublicKeyAlgorithm,
keyPair: KeyPair,
creationDate: Date
): AsymmetricCipherKeyPair =
BcPGPKeyConverter().let { converter ->
JcaPGPKeyPair(publicKeyAlgorithm.algorithmId, keyPair, creationDate).let { pair ->
AsymmetricCipherKeyPair(
converter.getPublicKey(pair.publicKey),
converter.getPrivateKey(pair.privateKey))
}
}
}

View file

@ -1,117 +0,0 @@
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.implementation
import java.io.InputStream
import java.security.KeyPair
import java.util.*
import org.bouncycastle.openpgp.*
import org.bouncycastle.openpgp.operator.*
import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.algorithm.PublicKeyAlgorithm
import org.pgpainless.algorithm.SymmetricKeyAlgorithm
import org.pgpainless.util.Passphrase
import org.pgpainless.util.SessionKey
abstract class ImplementationFactory {
companion object {
@JvmStatic private var instance: ImplementationFactory = BcImplementationFactory()
@JvmStatic fun getInstance() = instance
@JvmStatic
fun setFactoryImplementation(implementation: ImplementationFactory) = apply {
instance = implementation
}
}
abstract val pgpDigestCalculatorProvider: PGPDigestCalculatorProvider
abstract val pgpContentVerifierBuilderProvider: PGPContentVerifierBuilderProvider
abstract val keyFingerprintCalculator: KeyFingerPrintCalculator
val v4FingerprintCalculator: PGPDigestCalculator
get() = getPGPDigestCalculator(HashAlgorithm.SHA1)
@Throws(PGPException::class)
abstract fun getPBESecretKeyEncryptor(
symmetricKeyAlgorithm: SymmetricKeyAlgorithm,
digestCalculator: PGPDigestCalculator,
passphrase: Passphrase
): PBESecretKeyEncryptor
@Throws(PGPException::class)
abstract fun getPBESecretKeyDecryptor(passphrase: Passphrase): PBESecretKeyDecryptor
@Throws(PGPException::class)
abstract fun getPBESecretKeyEncryptor(
encryptionAlgorithm: SymmetricKeyAlgorithm,
hashAlgorithm: HashAlgorithm,
s2kCount: Int,
passphrase: Passphrase
): PBESecretKeyEncryptor
fun getPGPDigestCalculator(hashAlgorithm: HashAlgorithm): PGPDigestCalculator =
getPGPDigestCalculator(hashAlgorithm.algorithmId)
fun getPGPDigestCalculator(hashAlgorithm: Int): PGPDigestCalculator =
pgpDigestCalculatorProvider.get(hashAlgorithm)
fun getPGPContentSignerBuilder(
keyAlgorithm: PublicKeyAlgorithm,
hashAlgorithm: HashAlgorithm
): PGPContentSignerBuilder =
getPGPContentSignerBuilder(keyAlgorithm.algorithmId, hashAlgorithm.algorithmId)
abstract fun getPGPContentSignerBuilder(
keyAlgorithm: Int,
hashAlgorithm: Int
): PGPContentSignerBuilder
@Throws(PGPException::class)
abstract fun getPBEDataDecryptorFactory(passphrase: Passphrase): PBEDataDecryptorFactory
abstract fun getPublicKeyDataDecryptorFactory(
privateKey: PGPPrivateKey
): PublicKeyDataDecryptorFactory
fun getSessionKeyDataDecryptorFactory(sessionKey: SessionKey): SessionKeyDataDecryptorFactory =
getSessionKeyDataDecryptorFactory(
PGPSessionKey(sessionKey.algorithm.algorithmId, sessionKey.key))
abstract fun getSessionKeyDataDecryptorFactory(
sessionKey: PGPSessionKey
): SessionKeyDataDecryptorFactory
abstract fun getPublicKeyKeyEncryptionMethodGenerator(
key: PGPPublicKey
): PublicKeyKeyEncryptionMethodGenerator
abstract fun getPBEKeyEncryptionMethodGenerator(
passphrase: Passphrase
): PBEKeyEncryptionMethodGenerator
fun getPGPDataEncryptorBuilder(
symmetricKeyAlgorithm: SymmetricKeyAlgorithm
): PGPDataEncryptorBuilder = getPGPDataEncryptorBuilder(symmetricKeyAlgorithm.algorithmId)
abstract fun getPGPDataEncryptorBuilder(symmetricKeyAlgorithm: Int): PGPDataEncryptorBuilder
@Throws(PGPException::class)
abstract fun getPGPKeyPair(
publicKeyAlgorithm: PublicKeyAlgorithm,
keyPair: KeyPair,
creationDate: Date
): PGPKeyPair
fun getPGPObjectFactory(bytes: ByteArray): PGPObjectFactory =
getPGPObjectFactory(bytes.inputStream())
abstract fun getPGPObjectFactory(inputStream: InputStream): PGPObjectFactory
override fun toString(): String {
return javaClass.simpleName
}
}

View file

@ -1,112 +0,0 @@
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.implementation
import java.io.InputStream
import java.security.KeyPair
import java.util.*
import org.bouncycastle.openpgp.*
import org.bouncycastle.openpgp.operator.*
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair
import org.bouncycastle.openpgp.operator.jcajce.JcePBEDataDecryptorFactoryBuilder
import org.bouncycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator
import org.bouncycastle.openpgp.operator.jcajce.JceSessionKeyDataDecryptorFactoryBuilder
import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.algorithm.PublicKeyAlgorithm
import org.pgpainless.algorithm.SymmetricKeyAlgorithm
import org.pgpainless.provider.ProviderFactory
import org.pgpainless.util.Passphrase
class JceImplementationFactory : ImplementationFactory() {
override val pgpDigestCalculatorProvider: PGPDigestCalculatorProvider =
JcaPGPDigestCalculatorProviderBuilder().setProvider(ProviderFactory.provider).build()
override val pgpContentVerifierBuilderProvider: PGPContentVerifierBuilderProvider =
JcaPGPContentVerifierBuilderProvider().setProvider(ProviderFactory.provider)
override val keyFingerprintCalculator: KeyFingerPrintCalculator =
JcaKeyFingerprintCalculator().setProvider(ProviderFactory.provider)
override fun getPBESecretKeyEncryptor(
symmetricKeyAlgorithm: SymmetricKeyAlgorithm,
digestCalculator: PGPDigestCalculator,
passphrase: Passphrase
): PBESecretKeyEncryptor =
JcePBESecretKeyEncryptorBuilder(symmetricKeyAlgorithm.algorithmId, digestCalculator)
.setProvider(ProviderFactory.provider)
.build(passphrase.getChars())
override fun getPBESecretKeyEncryptor(
encryptionAlgorithm: SymmetricKeyAlgorithm,
hashAlgorithm: HashAlgorithm,
s2kCount: Int,
passphrase: Passphrase
): PBESecretKeyEncryptor =
JcePBESecretKeyEncryptorBuilder(
encryptionAlgorithm.algorithmId, getPGPDigestCalculator(hashAlgorithm), s2kCount)
.setProvider(ProviderFactory.provider)
.build(passphrase.getChars())
override fun getPBESecretKeyDecryptor(passphrase: Passphrase): PBESecretKeyDecryptor =
JcePBESecretKeyDecryptorBuilder(pgpDigestCalculatorProvider)
.setProvider(ProviderFactory.provider)
.build(passphrase.getChars())
override fun getPGPContentSignerBuilder(
keyAlgorithm: Int,
hashAlgorithm: Int
): PGPContentSignerBuilder =
JcaPGPContentSignerBuilder(keyAlgorithm, hashAlgorithm)
.setProvider(ProviderFactory.provider)
override fun getPBEDataDecryptorFactory(passphrase: Passphrase): PBEDataDecryptorFactory =
JcePBEDataDecryptorFactoryBuilder(pgpDigestCalculatorProvider)
.setProvider(ProviderFactory.provider)
.build(passphrase.getChars())
override fun getPublicKeyDataDecryptorFactory(
privateKey: PGPPrivateKey
): PublicKeyDataDecryptorFactory =
JcePublicKeyDataDecryptorFactoryBuilder()
.setProvider(ProviderFactory.provider)
.build(privateKey)
override fun getSessionKeyDataDecryptorFactory(
sessionKey: PGPSessionKey
): SessionKeyDataDecryptorFactory =
JceSessionKeyDataDecryptorFactoryBuilder()
.setProvider(ProviderFactory.provider)
.build(sessionKey)
override fun getPublicKeyKeyEncryptionMethodGenerator(
key: PGPPublicKey
): PublicKeyKeyEncryptionMethodGenerator =
JcePublicKeyKeyEncryptionMethodGenerator(key).setProvider(ProviderFactory.provider)
override fun getPBEKeyEncryptionMethodGenerator(
passphrase: Passphrase
): PBEKeyEncryptionMethodGenerator =
JcePBEKeyEncryptionMethodGenerator(passphrase.getChars())
.setProvider(ProviderFactory.provider)
override fun getPGPDataEncryptorBuilder(symmetricKeyAlgorithm: Int): PGPDataEncryptorBuilder =
JcePGPDataEncryptorBuilder(symmetricKeyAlgorithm).setProvider(ProviderFactory.provider)
override fun getPGPKeyPair(
publicKeyAlgorithm: PublicKeyAlgorithm,
keyPair: KeyPair,
creationDate: Date
): PGPKeyPair = JcaPGPKeyPair(publicKeyAlgorithm.algorithmId, keyPair, creationDate)
override fun getPGPObjectFactory(inputStream: InputStream): PGPObjectFactory =
PGPObjectFactory(inputStream, keyFingerprintCalculator)
}

View file

@ -6,7 +6,7 @@ package org.pgpainless.key.collection
import java.io.InputStream import java.io.InputStream
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.pgpainless.implementation.ImplementationFactory import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.pgpainless.util.ArmorUtils import org.pgpainless.util.ArmorUtils
/** /**
@ -55,8 +55,8 @@ class PGPKeyRingCollection(
val certificates = mutableListOf<PGPPublicKeyRing>() val certificates = mutableListOf<PGPPublicKeyRing>()
// Double getDecoderStream because of #96 // Double getDecoderStream because of #96
val objectFactory = val objectFactory =
ImplementationFactory.getInstance() OpenPGPImplementation.getInstance()
.getPGPObjectFactory(ArmorUtils.getDecoderStream(inputStream)) .pgpObjectFactory(ArmorUtils.getDecoderStream(inputStream))
for (obj in objectFactory) { for (obj in objectFactory) {
if (obj == null) { if (obj == null) {

View file

@ -6,20 +6,19 @@ package org.pgpainless.key.generation
import java.io.IOException import java.io.IOException
import java.util.* import java.util.*
import org.bouncycastle.bcpg.HashAlgorithmTags
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.bouncycastle.openpgp.api.OpenPGPImplementation import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.bouncycastle.openpgp.api.OpenPGPKey import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder
import org.bouncycastle.openpgp.operator.PGPDigestCalculator
import org.bouncycastle.util.Strings import org.bouncycastle.util.Strings
import org.pgpainless.PGPainless import org.pgpainless.PGPainless
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
import org.pgpainless.bouncycastle.extensions.unlock import org.pgpainless.bouncycastle.extensions.unlock
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.policy.Policy import org.pgpainless.policy.Policy
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets import org.pgpainless.signature.subpackets.SelfSignatureSubpackets
import org.pgpainless.signature.subpackets.SignatureSubpackets import org.pgpainless.signature.subpackets.SignatureSubpackets
@ -84,15 +83,20 @@ class KeyRingBuilder(
private fun keyIsCertificationCapable(keySpec: KeySpec) = keySpec.keyType.canCertify private fun keyIsCertificationCapable(keySpec: KeySpec) = keySpec.keyType.canCertify
override fun build(): OpenPGPKey { override fun build(): OpenPGPKey {
val keyFingerprintCalculator = ImplementationFactory.getInstance().v4FingerprintCalculator val keyFingerprintCalculator =
val secretKeyEncryptor = buildSecretKeyEncryptor(keyFingerprintCalculator) OpenPGPImplementation.getInstance()
val secretKeyDecryptor = buildSecretKeyDecryptor() .pgpDigestCalculatorProvider()
.get(HashAlgorithmTags.SHA1)
passphrase.clear() // Passphrase was used above, so we can get rid of it
// generate primary key // generate primary key
requireNotNull(primaryKeySpec) { "Primary Key spec required." } requireNotNull(primaryKeySpec) { "Primary Key spec required." }
val certKey = generateKeyPair(primaryKeySpec!!, version) val certKey = generateKeyPair(primaryKeySpec!!, version)
val secretKeyEncryptor = buildSecretKeyEncryptor(certKey.publicKey, false)
val secretKeyDecryptor = buildSecretKeyDecryptor()
passphrase.clear() // Passphrase was used above, so we can get rid of it
val signer = buildContentSigner(certKey) val signer = buildContentSigner(certKey)
val signatureGenerator = PGPSignatureGenerator(signer, certKey.publicKey) val signatureGenerator = PGPSignatureGenerator(signer, certKey.publicKey)
@ -220,29 +224,30 @@ class KeyRingBuilder(
private fun buildContentSigner(certKey: PGPKeyPair): PGPContentSignerBuilder { private fun buildContentSigner(certKey: PGPKeyPair): PGPContentSignerBuilder {
val hashAlgorithm = val hashAlgorithm =
PGPainless.getPolicy().certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm PGPainless.getPolicy().certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm
return ImplementationFactory.getInstance() return OpenPGPImplementation.getInstance()
.getPGPContentSignerBuilder(certKey.publicKey.algorithm, hashAlgorithm.algorithmId) .pgpContentSignerBuilder(certKey.publicKey.algorithm, hashAlgorithm.algorithmId)
} }
private fun buildSecretKeyEncryptor( private fun buildSecretKeyEncryptor(
keyFingerprintCalculator: PGPDigestCalculator publicKey: PGPPublicKey,
aead: Boolean
): PBESecretKeyEncryptor? { ): PBESecretKeyEncryptor? {
val keyEncryptionAlgorithm =
PGPainless.getPolicy()
.symmetricKeyEncryptionAlgorithmPolicy
.defaultSymmetricKeyAlgorithm
check(passphrase.isValid) { "Passphrase was cleared." } check(passphrase.isValid) { "Passphrase was cleared." }
return if (passphrase.isEmpty) null return if (passphrase.isEmpty) null
else else
ImplementationFactory.getInstance() OpenPGPImplementation.getInstance()
.getPBESecretKeyEncryptor( .pbeSecretKeyEncryptorFactory(aead)
keyEncryptionAlgorithm, keyFingerprintCalculator, passphrase) .build(passphrase.getChars(), publicKey.publicKeyPacket)
} }
private fun buildSecretKeyDecryptor(): PBESecretKeyDecryptor? { private fun buildSecretKeyDecryptor(): PBESecretKeyDecryptor? {
check(passphrase.isValid) { "Passphrase was cleared." } check(passphrase.isValid) { "Passphrase was cleared." }
return if (passphrase.isEmpty) null return if (passphrase.isEmpty) null
else ImplementationFactory.getInstance().getPBESecretKeyDecryptor(passphrase) else
OpenPGPImplementation.getInstance()
.pbeSecretKeyDecryptorBuilderProvider()
.provide()
.build(passphrase.getChars())
} }
companion object { companion object {

View file

@ -9,10 +9,12 @@ import java.util.function.Predicate
import javax.annotation.Nonnull import javax.annotation.Nonnull
import kotlin.NoSuchElementException import kotlin.NoSuchElementException
import openpgp.openPgpKeyId import openpgp.openPgpKeyId
import org.bouncycastle.bcpg.HashAlgorithmTags
import org.bouncycastle.bcpg.KeyIdentifier import org.bouncycastle.bcpg.KeyIdentifier
import org.bouncycastle.bcpg.sig.KeyExpirationTime import org.bouncycastle.bcpg.sig.KeyExpirationTime
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPSubkey import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPSubkey
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.bouncycastle.openpgp.api.OpenPGPKey import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPSecretKey import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPSecretKey
import org.bouncycastle.openpgp.api.OpenPGPSignature import org.bouncycastle.openpgp.api.OpenPGPSignature
@ -27,7 +29,6 @@ import org.pgpainless.algorithm.negotiation.HashAlgorithmNegotiator
import org.pgpainless.bouncycastle.extensions.getKeyExpirationDate import org.pgpainless.bouncycastle.extensions.getKeyExpirationDate
import org.pgpainless.bouncycastle.extensions.publicKeyAlgorithm import org.pgpainless.bouncycastle.extensions.publicKeyAlgorithm
import org.pgpainless.bouncycastle.extensions.requirePublicKey import org.pgpainless.bouncycastle.extensions.requirePublicKey
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.OpenPgpFingerprint import org.pgpainless.key.OpenPgpFingerprint
import org.pgpainless.key.generation.KeyRingBuilder import org.pgpainless.key.generation.KeyRingBuilder
import org.pgpainless.key.generation.KeySpec import org.pgpainless.key.generation.KeySpec
@ -302,9 +303,11 @@ class SecretKeyRingEditor(var key: OpenPGPKey, override val referenceTime: Date
PGPSecretKey( PGPSecretKey(
subkey.privateKey, subkey.privateKey,
subkey.publicKey, subkey.publicKey,
ImplementationFactory.getInstance().v4FingerprintCalculator, OpenPGPImplementation.getInstance()
.pgpDigestCalculatorProvider()
.get(HashAlgorithmTags.SHA1),
false, false,
subkeyProtector.getEncryptor(subkey.keyID)) subkeyProtector.getEncryptor(subkey.publicKey))
val componentKey = val componentKey =
OpenPGPSecretKey( OpenPGPSecretKey(

View file

@ -9,9 +9,9 @@ import java.io.InputStream
import java.nio.charset.Charset import java.nio.charset.Charset
import kotlin.jvm.Throws import kotlin.jvm.Throws
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.bouncycastle.util.io.Streams import org.bouncycastle.util.io.Streams
import org.pgpainless.PGPainless import org.pgpainless.PGPainless
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.collection.PGPKeyRingCollection import org.pgpainless.key.collection.PGPKeyRingCollection
import org.pgpainless.util.ArmorUtils import org.pgpainless.util.ArmorUtils
@ -130,8 +130,8 @@ class KeyRingReader {
maxIterations: Int = MAX_ITERATIONS maxIterations: Int = MAX_ITERATIONS
): PGPKeyRing? { ): PGPKeyRing? {
val objectFactory = val objectFactory =
ImplementationFactory.getInstance() OpenPGPImplementation.getInstance()
.getPGPObjectFactory(ArmorUtils.getDecoderStream(inputStream)) .pgpObjectFactory(ArmorUtils.getDecoderStream(inputStream))
try { try {
for ((i, next) in objectFactory.withIndex()) { for ((i, next) in objectFactory.withIndex()) {
@ -172,8 +172,8 @@ class KeyRingReader {
maxIterations: Int = MAX_ITERATIONS maxIterations: Int = MAX_ITERATIONS
): PGPPublicKeyRing? { ): PGPPublicKeyRing? {
val objectFactory = val objectFactory =
ImplementationFactory.getInstance() OpenPGPImplementation.getInstance()
.getPGPObjectFactory(ArmorUtils.getDecoderStream(inputStream)) .pgpObjectFactory(ArmorUtils.getDecoderStream(inputStream))
try { try {
for ((i, next) in objectFactory.withIndex()) { for ((i, next) in objectFactory.withIndex()) {
@ -213,8 +213,8 @@ class KeyRingReader {
maxIterations: Int = MAX_ITERATIONS maxIterations: Int = MAX_ITERATIONS
): PGPPublicKeyRingCollection { ): PGPPublicKeyRingCollection {
val objectFactory = val objectFactory =
ImplementationFactory.getInstance() OpenPGPImplementation.getInstance()
.getPGPObjectFactory(ArmorUtils.getDecoderStream(inputStream)) .pgpObjectFactory(ArmorUtils.getDecoderStream(inputStream))
val certificates = mutableListOf<PGPPublicKeyRing>() val certificates = mutableListOf<PGPPublicKeyRing>()
try { try {
for ((i, next) in objectFactory.withIndex()) { for ((i, next) in objectFactory.withIndex()) {
@ -260,8 +260,7 @@ class KeyRingReader {
maxIterations: Int = MAX_ITERATIONS maxIterations: Int = MAX_ITERATIONS
): PGPSecretKeyRing? { ): PGPSecretKeyRing? {
val decoderStream = ArmorUtils.getDecoderStream(inputStream) val decoderStream = ArmorUtils.getDecoderStream(inputStream)
val objectFactory = val objectFactory = OpenPGPImplementation.getInstance().pgpObjectFactory(decoderStream)
ImplementationFactory.getInstance().getPGPObjectFactory(decoderStream)
try { try {
for ((i, next) in objectFactory.withIndex()) { for ((i, next) in objectFactory.withIndex()) {
@ -300,8 +299,8 @@ class KeyRingReader {
maxIterations: Int = MAX_ITERATIONS maxIterations: Int = MAX_ITERATIONS
): PGPSecretKeyRingCollection { ): PGPSecretKeyRingCollection {
val objectFactory = val objectFactory =
ImplementationFactory.getInstance() OpenPGPImplementation.getInstance()
.getPGPObjectFactory(ArmorUtils.getDecoderStream(inputStream)) .pgpObjectFactory(ArmorUtils.getDecoderStream(inputStream))
val secretKeys = mutableListOf<PGPSecretKeyRing>() val secretKeys = mutableListOf<PGPSecretKeyRing>()
try { try {

View file

@ -5,10 +5,11 @@
package org.pgpainless.key.protection package org.pgpainless.key.protection
import org.bouncycastle.bcpg.KeyIdentifier import org.bouncycastle.bcpg.KeyIdentifier
import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.bouncycastle.openpgp.api.OpenPGPKey import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.protection.passphrase_provider.SecretKeyPassphraseProvider import org.pgpainless.key.protection.passphrase_provider.SecretKeyPassphraseProvider
/** /**
@ -34,19 +35,20 @@ open class BaseSecretKeyRingProtector(
override fun getDecryptor(keyIdentifier: KeyIdentifier): PBESecretKeyDecryptor? = override fun getDecryptor(keyIdentifier: KeyIdentifier): PBESecretKeyDecryptor? =
passphraseProvider.getPassphraseFor(keyIdentifier)?.let { passphraseProvider.getPassphraseFor(keyIdentifier)?.let {
if (it.isEmpty) null if (it.isEmpty) null
else ImplementationFactory.getInstance().getPBESecretKeyDecryptor(it) else
OpenPGPImplementation.getInstance()
.pbeSecretKeyDecryptorBuilderProvider()
.provide()
.build(it.getChars())
} }
override fun getEncryptor(keyIdentifier: KeyIdentifier): PBESecretKeyEncryptor? { override fun getEncryptor(key: PGPPublicKey): PBESecretKeyEncryptor? {
return passphraseProvider.getPassphraseFor(keyIdentifier)?.let { return passphraseProvider.getPassphraseFor(key.keyIdentifier)?.let {
if (it.isEmpty) null if (it.isEmpty) null
else else
ImplementationFactory.getInstance() OpenPGPImplementation.getInstance()
.getPBESecretKeyEncryptor( .pbeSecretKeyEncryptorFactory(false)
protectionSettings.encryptionAlgorithm, .build(it.getChars(), key.publicKeyPacket)
protectionSettings.hashAlgorithm,
protectionSettings.s2kCount,
it)
} }
} }

View file

@ -184,8 +184,8 @@ class CachingSecretKeyRingProtector : SecretKeyRingProtector, SecretKeyPassphras
override fun getDecryptor(keyIdentifier: KeyIdentifier): PBESecretKeyDecryptor? = override fun getDecryptor(keyIdentifier: KeyIdentifier): PBESecretKeyDecryptor? =
protector.getDecryptor(keyIdentifier) protector.getDecryptor(keyIdentifier)
override fun getEncryptor(keyIdentifier: KeyIdentifier): PBESecretKeyEncryptor? = override fun getEncryptor(key: PGPPublicKey): PBESecretKeyEncryptor? =
protector.getEncryptor(keyIdentifier) protector.getEncryptor(key)
override fun getKeyPassword(p0: OpenPGPKey.OpenPGPSecretKey): CharArray? = override fun getKeyPassword(p0: OpenPGPKey.OpenPGPSecretKey): CharArray? =
getPassphraseFor(p0.keyIdentifier)?.getChars() getPassphraseFor(p0.keyIdentifier)?.getChars()

View file

@ -7,9 +7,11 @@ package org.pgpainless.key.protection
import kotlin.Throws import kotlin.Throws
import org.bouncycastle.bcpg.KeyIdentifier import org.bouncycastle.bcpg.KeyIdentifier
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPSecretKey import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSecretKeyRing import org.bouncycastle.openpgp.PGPSecretKeyRing
import org.bouncycastle.openpgp.api.KeyPassphraseProvider import org.bouncycastle.openpgp.api.KeyPassphraseProvider
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor
import org.pgpainless.key.protection.passphrase_provider.SecretKeyPassphraseProvider import org.pgpainless.key.protection.passphrase_provider.SecretKeyPassphraseProvider
@ -32,8 +34,15 @@ interface SecretKeyRingProtector : KeyPassphraseProvider {
* @param keyId key id * @param keyId key id
* @return true if it has a passphrase, false otherwise * @return true if it has a passphrase, false otherwise
*/ */
@Deprecated("Pass in a KeyIdentifier instead.")
fun hasPassphraseFor(keyId: Long): Boolean = hasPassphraseFor(KeyIdentifier(keyId)) fun hasPassphraseFor(keyId: Long): Boolean = hasPassphraseFor(KeyIdentifier(keyId))
/**
* Returns true, if the protector has a passphrase for the key with the given [keyIdentifier].
*
* @param keyIdentifier key identifier
* @return true if it has a passphrase, false otherwise
*/
fun hasPassphraseFor(keyIdentifier: KeyIdentifier): Boolean fun hasPassphraseFor(keyIdentifier: KeyIdentifier): Boolean
/** /**
@ -43,24 +52,37 @@ interface SecretKeyRingProtector : KeyPassphraseProvider {
* @param keyId id of the key * @param keyId id of the key
* @return decryptor for the key * @return decryptor for the key
*/ */
@Deprecated("Pass in a KeyIdentifier instead.")
@Throws(PGPException::class) @Throws(PGPException::class)
fun getDecryptor(keyId: Long): PBESecretKeyDecryptor? = getDecryptor(KeyIdentifier(keyId)) fun getDecryptor(keyId: Long): PBESecretKeyDecryptor? = getDecryptor(KeyIdentifier(keyId))
/**
* Return a decryptor for the key with the given [keyIdentifier]. This method returns null if
* the key is unprotected.
*
* @param keyIdentifier identifier of the key
* @return decryptor for the key
*/
@Throws(PGPException::class) @Throws(PGPException::class)
fun getDecryptor(keyIdentifier: KeyIdentifier): PBESecretKeyDecryptor? fun getDecryptor(keyIdentifier: KeyIdentifier): PBESecretKeyDecryptor?
/** /**
* Return an encryptor for the key of id `keyId`. This method returns null if the key is * Return an encryptor for the given key.
* unprotected.
* *
* @param keyId id of the key * @param key component key
* @return encryptor for the key * @return encryptor or null if the key shall not be encrypted
*/ */
@Throws(PGPException::class) @Throws(PGPException::class)
fun getEncryptor(keyId: Long): PBESecretKeyEncryptor? = getEncryptor(KeyIdentifier(keyId)) fun getEncryptor(key: OpenPGPComponentKey): PBESecretKeyEncryptor? =
getEncryptor(key.pgpPublicKey)
@Throws(PGPException::class) /**
fun getEncryptor(keyIdentifier: KeyIdentifier): PBESecretKeyEncryptor? * Return an encryptor for the given key.
*
* @param key component key
* @return encryptor or null if the key shall not be encrypted
*/
@Throws(PGPException::class) fun getEncryptor(key: PGPPublicKey): PBESecretKeyEncryptor?
companion object { companion object {

View file

@ -4,6 +4,7 @@
package org.pgpainless.key.protection package org.pgpainless.key.protection
import org.bouncycastle.bcpg.KeyIdentifier import org.bouncycastle.bcpg.KeyIdentifier
import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.api.OpenPGPKey import org.bouncycastle.openpgp.api.OpenPGPKey
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor
@ -17,7 +18,7 @@ class UnprotectedKeysProtector : SecretKeyRingProtector {
override fun getDecryptor(keyIdentifier: KeyIdentifier): PBESecretKeyDecryptor? = null override fun getDecryptor(keyIdentifier: KeyIdentifier): PBESecretKeyDecryptor? = null
override fun getEncryptor(keyIdentifier: KeyIdentifier): PBESecretKeyEncryptor? = null override fun getEncryptor(key: PGPPublicKey): PBESecretKeyEncryptor? = null
override fun getKeyPassword(p0: OpenPGPKey.OpenPGPSecretKey?): CharArray? = null override fun getKeyPassword(p0: OpenPGPKey.OpenPGPSecretKey?): CharArray? = null
} }

View file

@ -4,14 +4,15 @@
package org.pgpainless.key.protection.fixes package org.pgpainless.key.protection.fixes
import org.bouncycastle.bcpg.HashAlgorithmTags
import org.bouncycastle.bcpg.SecretKeyPacket import org.bouncycastle.bcpg.SecretKeyPacket
import org.bouncycastle.openpgp.PGPSecretKey import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSecretKeyRing import org.bouncycastle.openpgp.PGPSecretKeyRing
import org.pgpainless.algorithm.HashAlgorithm import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.pgpainless.bouncycastle.extensions.unlock import org.pgpainless.bouncycastle.extensions.unlock
import org.pgpainless.exception.WrongPassphraseException import org.pgpainless.exception.WrongPassphraseException
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.key.protection.fixes.S2KUsageFix.Companion.replaceUsageChecksumWithUsageSha1
/** /**
* Repair class to fix keys which use S2K usage of value [SecretKeyPacket.USAGE_CHECKSUM]. The * Repair class to fix keys which use S2K usage of value [SecretKeyPacket.USAGE_CHECKSUM]. The
@ -48,7 +49,9 @@ class S2KUsageFix {
skipKeysWithMissingPassphrase: Boolean = false skipKeysWithMissingPassphrase: Boolean = false
): PGPSecretKeyRing { ): PGPSecretKeyRing {
val digestCalculator = val digestCalculator =
ImplementationFactory.getInstance().getPGPDigestCalculator(HashAlgorithm.SHA1) OpenPGPImplementation.getInstance()
.pgpDigestCalculatorProvider()
.get(HashAlgorithmTags.SHA1)
val keyList = mutableListOf<PGPSecretKey>() val keyList = mutableListOf<PGPSecretKey>()
for (key in keys) { for (key in keys) {
// CHECKSUM is not recommended // CHECKSUM is not recommended
@ -58,7 +61,7 @@ class S2KUsageFix {
} }
val keyId = key.keyID val keyId = key.keyID
val encryptor = protector.getEncryptor(keyId) val encryptor = protector.getEncryptor(key.publicKey)
if (encryptor == null) { if (encryptor == null) {
if (skipKeysWithMissingPassphrase) { if (skipKeysWithMissingPassphrase) {
keyList.add(key) keyList.add(key)
@ -76,7 +79,7 @@ class S2KUsageFix {
key.publicKey, key.publicKey,
digestCalculator, digestCalculator,
key.isMasterKey, key.isMasterKey,
protector.getEncryptor(keyId)) protector.getEncryptor(key.publicKey))
keyList.add(fixedKey) keyList.add(fixedKey)
} }
return PGPSecretKeyRing(keyList) return PGPSecretKeyRing(keyList)

View file

@ -11,11 +11,11 @@ import org.bouncycastle.bcpg.KeyIdentifier
import org.bouncycastle.bcpg.S2K import org.bouncycastle.bcpg.S2K
import org.bouncycastle.bcpg.SecretKeyPacket import org.bouncycastle.bcpg.SecretKeyPacket
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.bouncycastle.util.Strings import org.bouncycastle.util.Strings
import org.pgpainless.bouncycastle.extensions.certificate import org.pgpainless.bouncycastle.extensions.certificate
import org.pgpainless.bouncycastle.extensions.requireSecretKey import org.pgpainless.bouncycastle.extensions.requireSecretKey
import org.pgpainless.exception.MissingPassphraseException import org.pgpainless.exception.MissingPassphraseException
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.key.protection.fixes.S2KUsageFix import org.pgpainless.key.protection.fixes.S2KUsageFix
import org.slf4j.Logger import org.slf4j.Logger
@ -436,7 +436,7 @@ class KeyRingUtils {
} }
secretKeys.extraPublicKeys.forEach { it.encode(out) } secretKeys.extraPublicKeys.forEach { it.encode(out) }
return PGPSecretKeyRing( return PGPSecretKeyRing(
out.toByteArray(), ImplementationFactory.getInstance().keyFingerprintCalculator) out.toByteArray(), OpenPGPImplementation.getInstance().keyFingerPrintCalculator())
} }
/** /**
@ -450,7 +450,7 @@ class KeyRingUtils {
fun getStrippedDownPublicKey(bloatedKey: PGPPublicKey): PGPPublicKey { fun getStrippedDownPublicKey(bloatedKey: PGPPublicKey): PGPPublicKey {
return PGPPublicKey( return PGPPublicKey(
bloatedKey.publicKeyPacket, bloatedKey.publicKeyPacket,
ImplementationFactory.getInstance().keyFingerprintCalculator) OpenPGPImplementation.getInstance().keyFingerPrintCalculator())
} }
@JvmStatic @JvmStatic
@ -510,7 +510,7 @@ class KeyRingUtils {
return PGPSecretKey.copyWithNewPassword( return PGPSecretKey.copyWithNewPassword(
secretKey, secretKey,
oldProtector.getDecryptor(secretKey.keyID), oldProtector.getDecryptor(secretKey.keyID),
newProtector.getEncryptor(secretKey.keyID)) newProtector.getEncryptor(secretKey.publicKey))
} }
@JvmStatic @JvmStatic

View file

@ -10,15 +10,12 @@ import java.math.BigInteger
import java.security.SecureRandom import java.security.SecureRandom
import org.bouncycastle.bcpg.* import org.bouncycastle.bcpg.*
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.bouncycastle.util.Arrays import org.bouncycastle.util.Arrays
import org.bouncycastle.util.io.Streams import org.bouncycastle.util.io.Streams
import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.algorithm.PublicKeyAlgorithm.Companion.requireFromId
import org.pgpainless.algorithm.SignatureType import org.pgpainless.algorithm.SignatureType
import org.pgpainless.algorithm.SymmetricKeyAlgorithm
import org.pgpainless.bouncycastle.extensions.publicKeyAlgorithm import org.pgpainless.bouncycastle.extensions.publicKeyAlgorithm
import org.pgpainless.exception.KeyIntegrityException import org.pgpainless.exception.KeyIntegrityException
import org.pgpainless.implementation.ImplementationFactory.Companion.getInstance
/** /**
* Utility class to verify keys against Key Overwriting (KO) attacks. This class of attacks is only * Utility class to verify keys against Key Overwriting (KO) attacks. This class of attacks is only
@ -224,9 +221,9 @@ class PublicKeyParameterValidationUtil {
val data = ByteArray(512).also { SecureRandom().nextBytes(it) } val data = ByteArray(512).also { SecureRandom().nextBytes(it) }
val signatureGenerator = val signatureGenerator =
PGPSignatureGenerator( PGPSignatureGenerator(
getInstance() OpenPGPImplementation.getInstance()
.getPGPContentSignerBuilder( .pgpContentSignerBuilder(publicKey.algorithm, HashAlgorithmTags.SHA256),
requireFromId(publicKey.algorithm), HashAlgorithm.SHA256)) publicKey)
return try { return try {
signatureGenerator signatureGenerator
.apply { .apply {
@ -235,7 +232,9 @@ class PublicKeyParameterValidationUtil {
} }
.generate() .generate()
.apply { .apply {
init(getInstance().pgpContentVerifierBuilderProvider, publicKey) init(
OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
publicKey)
update(data) update(data)
} }
.verify() .verify()
@ -257,9 +256,12 @@ class PublicKeyParameterValidationUtil {
val data = ByteArray(1024).also { SecureRandom().nextBytes(it) } val data = ByteArray(1024).also { SecureRandom().nextBytes(it) }
val encryptedDataGenerator = val encryptedDataGenerator =
PGPEncryptedDataGenerator( PGPEncryptedDataGenerator(
getInstance().getPGPDataEncryptorBuilder(SymmetricKeyAlgorithm.AES_256)) OpenPGPImplementation.getInstance()
.pgpDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256))
.apply { .apply {
addMethod(getInstance().getPublicKeyKeyEncryptionMethodGenerator(publicKey)) addMethod(
OpenPGPImplementation.getInstance()
.publicKeyKeyEncryptionMethodGenerator(publicKey))
} }
var out = ByteArrayOutputStream() var out = ByteArrayOutputStream()
@ -268,7 +270,8 @@ class PublicKeyParameterValidationUtil {
outputStream.write(data) outputStream.write(data)
encryptedDataGenerator.close() encryptedDataGenerator.close()
val encryptedDataList = PGPEncryptedDataList(out.toByteArray()) val encryptedDataList = PGPEncryptedDataList(out.toByteArray())
val decryptorFactory = getInstance().getPublicKeyDataDecryptorFactory(privateKey) val decryptorFactory =
OpenPGPImplementation.getInstance().publicKeyDataDecryptorFactory(privateKey)
val encryptedData = val encryptedData =
encryptedDataList.encryptedDataObjects.next() as PGPPublicKeyEncryptedData encryptedDataList.encryptedDataObjects.next() as PGPPublicKeyEncryptedData
val decrypted = encryptedData.getDataStream(decryptorFactory) val decrypted = encryptedData.getDataStream(decryptorFactory)

View file

@ -10,10 +10,10 @@ import java.util.*
import openpgp.plusSeconds import openpgp.plusSeconds
import org.bouncycastle.bcpg.sig.KeyExpirationTime import org.bouncycastle.bcpg.sig.KeyExpirationTime
import org.bouncycastle.openpgp.* import org.bouncycastle.openpgp.*
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.bouncycastle.util.encoders.Hex import org.bouncycastle.util.encoders.Hex
import org.bouncycastle.util.io.Streams import org.bouncycastle.util.io.Streams
import org.pgpainless.bouncycastle.extensions.* import org.pgpainless.bouncycastle.extensions.*
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.OpenPgpFingerprint import org.pgpainless.key.OpenPgpFingerprint
import org.pgpainless.key.util.RevocationAttributes.Reason import org.pgpainless.key.util.RevocationAttributes.Reason
import org.pgpainless.util.ArmorUtils import org.pgpainless.util.ArmorUtils
@ -153,7 +153,7 @@ class SignatureUtils {
fun readSignatures(inputStream: InputStream, maxIterations: Int): List<PGPSignature> { fun readSignatures(inputStream: InputStream, maxIterations: Int): List<PGPSignature> {
val signatures = mutableListOf<PGPSignature>() val signatures = mutableListOf<PGPSignature>()
val pgpIn = ArmorUtils.getDecoderStream(inputStream) val pgpIn = ArmorUtils.getDecoderStream(inputStream)
val objectFactory = ImplementationFactory.getInstance().getPGPObjectFactory(pgpIn) val objectFactory = OpenPGPImplementation.getInstance().pgpObjectFactory(pgpIn)
var i = 0 var i = 0
var nextObject: Any? = null var nextObject: Any? = null

View file

@ -10,12 +10,12 @@ import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPSignature import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.PGPSignatureGenerator import org.bouncycastle.openpgp.PGPSignatureGenerator
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.bouncycastle.openpgp.api.OpenPGPKey import org.bouncycastle.openpgp.api.OpenPGPKey
import org.pgpainless.PGPainless import org.pgpainless.PGPainless
import org.pgpainless.algorithm.HashAlgorithm import org.pgpainless.algorithm.HashAlgorithm
import org.pgpainless.algorithm.SignatureType import org.pgpainless.algorithm.SignatureType
import org.pgpainless.algorithm.negotiation.HashAlgorithmNegotiator import org.pgpainless.algorithm.negotiation.HashAlgorithmNegotiator
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.protection.SecretKeyRingProtector import org.pgpainless.key.protection.SecretKeyRingProtector
import org.pgpainless.key.protection.UnlockSecretKey import org.pgpainless.key.protection.UnlockSecretKey
import org.pgpainless.key.util.OpenPgpKeyAttributeUtil import org.pgpainless.key.util.OpenPgpKeyAttributeUtil
@ -110,9 +110,10 @@ abstract class AbstractSignatureBuilder<B : AbstractSignatureBuilder<B>>(
@Throws(PGPException::class) @Throws(PGPException::class)
protected fun buildAndInitSignatureGenerator(): PGPSignatureGenerator = protected fun buildAndInitSignatureGenerator(): PGPSignatureGenerator =
PGPSignatureGenerator( PGPSignatureGenerator(
ImplementationFactory.getInstance() OpenPGPImplementation.getInstance()
.getPGPContentSignerBuilder( .pgpContentSignerBuilder(
signingKey.publicKey.pgpPublicKey.algorithm, hashAlgorithm.algorithmId)) signingKey.keyPair.publicKey.algorithm, hashAlgorithm.algorithmId),
signingKey.keyPair.publicKey)
.apply { .apply {
setUnhashedSubpackets(SignatureSubpacketsHelper.toVector(_unhashedSubpackets)) setUnhashedSubpackets(SignatureSubpacketsHelper.toVector(_unhashedSubpackets))
setHashedSubpackets(SignatureSubpacketsHelper.toVector(_hashedSubpackets)) setHashedSubpackets(SignatureSubpacketsHelper.toVector(_hashedSubpackets))

View file

@ -12,17 +12,16 @@ import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKey import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPSignature import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.pgpainless.algorithm.KeyFlag import org.pgpainless.algorithm.KeyFlag
import org.pgpainless.algorithm.SignatureSubpacket import org.pgpainless.algorithm.SignatureSubpacket
import org.pgpainless.algorithm.SignatureType import org.pgpainless.algorithm.SignatureType
import org.pgpainless.bouncycastle.extensions.fingerprint import org.pgpainless.bouncycastle.extensions.fingerprint
import org.pgpainless.bouncycastle.extensions.isHardRevocation
import org.pgpainless.bouncycastle.extensions.isOfType import org.pgpainless.bouncycastle.extensions.isOfType
import org.pgpainless.bouncycastle.extensions.publicKeyAlgorithm import org.pgpainless.bouncycastle.extensions.publicKeyAlgorithm
import org.pgpainless.bouncycastle.extensions.signatureExpirationDate import org.pgpainless.bouncycastle.extensions.signatureExpirationDate
import org.pgpainless.bouncycastle.extensions.signatureHashAlgorithm import org.pgpainless.bouncycastle.extensions.signatureHashAlgorithm
import org.pgpainless.exception.SignatureValidationException import org.pgpainless.exception.SignatureValidationException
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.key.OpenPgpFingerprint import org.pgpainless.key.OpenPgpFingerprint
import org.pgpainless.policy.Policy import org.pgpainless.policy.Policy
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil
@ -486,7 +485,7 @@ abstract class SignatureValidator {
} }
try { try {
signature.init( signature.init(
ImplementationFactory.getInstance().pgpContentVerifierBuilderProvider, OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
primaryKey) primaryKey)
if (!signature.verifyCertification(primaryKey, subkey)) { if (!signature.verifyCertification(primaryKey, subkey)) {
throw SignatureValidationException("Signature is not correct.") throw SignatureValidationException("Signature is not correct.")
@ -521,7 +520,7 @@ abstract class SignatureValidator {
} }
try { try {
signature.init( signature.init(
ImplementationFactory.getInstance().pgpContentVerifierBuilderProvider, OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
subkey) subkey)
if (!signature.verifyCertification(primaryKey, subkey)) { if (!signature.verifyCertification(primaryKey, subkey)) {
throw SignatureValidationException( throw SignatureValidationException(
@ -554,7 +553,7 @@ abstract class SignatureValidator {
override fun verify(signature: PGPSignature) { override fun verify(signature: PGPSignature) {
try { try {
signature.init( signature.init(
ImplementationFactory.getInstance().pgpContentVerifierBuilderProvider, OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
signingKey) signingKey)
val valid = val valid =
if (signingKey.keyID == signedKey.keyID || if (signingKey.keyID == signedKey.keyID ||
@ -625,7 +624,7 @@ abstract class SignatureValidator {
override fun verify(signature: PGPSignature) { override fun verify(signature: PGPSignature) {
try { try {
signature.init( signature.init(
ImplementationFactory.getInstance().pgpContentVerifierBuilderProvider, OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
certifyingKey) certifyingKey)
if (!signature.verifyCertification(userId.toString(), certifiedKey)) { if (!signature.verifyCertification(userId.toString(), certifiedKey)) {
throw SignatureValidationException( throw SignatureValidationException(
@ -660,7 +659,7 @@ abstract class SignatureValidator {
override fun verify(signature: PGPSignature) { override fun verify(signature: PGPSignature) {
try { try {
signature.init( signature.init(
ImplementationFactory.getInstance().pgpContentVerifierBuilderProvider, OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
certifyingKey) certifyingKey)
if (!signature.verifyCertification(userAttributes, certifiedKey)) { if (!signature.verifyCertification(userAttributes, certifiedKey)) {
throw SignatureValidationException( throw SignatureValidationException(

View file

@ -12,9 +12,9 @@ import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKey import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPSignature import org.bouncycastle.openpgp.PGPSignature
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.pgpainless.algorithm.SignatureType import org.pgpainless.algorithm.SignatureType
import org.pgpainless.exception.SignatureValidationException import org.pgpainless.exception.SignatureValidationException
import org.pgpainless.implementation.ImplementationFactory.Companion.getInstance
import org.pgpainless.policy.Policy import org.pgpainless.policy.Policy
import org.pgpainless.signature.consumer.SignatureValidator.Companion.correctSignatureOverKey import org.pgpainless.signature.consumer.SignatureValidator.Companion.correctSignatureOverKey
import org.pgpainless.signature.consumer.SignatureValidator.Companion.correctSignatureOverUserAttributes import org.pgpainless.signature.consumer.SignatureValidator.Companion.correctSignatureOverUserAttributes
@ -479,7 +479,7 @@ class SignatureVerifier {
) { ) {
try { try {
signature.init( signature.init(
getInstance().pgpContentVerifierBuilderProvider, OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
signingKey, signingKey,
) )
var read: Int var read: Int

View file

@ -14,6 +14,7 @@ import java.nio.charset.StandardCharsets;
import java.util.Date; import java.util.Date;
import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
@ -21,6 +22,7 @@ import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
import org.bouncycastle.openpgp.api.OpenPGPKey; import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
@ -29,11 +31,9 @@ import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.EncryptionPurpose; import org.pgpainless.algorithm.EncryptionPurpose;
import org.pgpainless.algorithm.HashAlgorithm; import org.pgpainless.algorithm.HashAlgorithm;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
import org.pgpainless.decryption_verification.ConsumerOptions; import org.pgpainless.decryption_verification.ConsumerOptions;
import org.pgpainless.decryption_verification.DecryptionStream; import org.pgpainless.decryption_verification.DecryptionStream;
import org.pgpainless.exception.MalformedOpenPgpMessageException; import org.pgpainless.exception.MalformedOpenPgpMessageException;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.info.KeyRingInfo; import org.pgpainless.key.info.KeyRingInfo;
import org.pgpainless.key.protection.UnlockSecretKey; import org.pgpainless.key.protection.UnlockSecretKey;
import org.pgpainless.util.Passphrase; import org.pgpainless.util.Passphrase;
@ -130,7 +130,7 @@ public class InvestigateMultiSEIPMessageHandlingTest {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
ArmoredOutputStream armorOut = new ArmoredOutputStream(out); ArmoredOutputStream armorOut = new ArmoredOutputStream(out);
PGPDataEncryptorBuilder cryptBuilder = ImplementationFactory.getInstance().getPGPDataEncryptorBuilder(SymmetricKeyAlgorithm.AES_256); PGPDataEncryptorBuilder cryptBuilder = OpenPGPImplementation.getInstance().pgpDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256);
cryptBuilder.setWithIntegrityPacket(true); cryptBuilder.setWithIntegrityPacket(true);
encryptAndSign(cryptKey1, signKey1, armorOut, data1.getBytes(StandardCharsets.UTF_8)); encryptAndSign(cryptKey1, signKey1, armorOut, data1.getBytes(StandardCharsets.UTF_8));
@ -145,15 +145,16 @@ public class InvestigateMultiSEIPMessageHandlingTest {
private void encryptAndSign(PGPPublicKey cryptKey, PGPSecretKey signKey, ArmoredOutputStream armorOut, byte[] data) throws IOException, PGPException { private void encryptAndSign(PGPPublicKey cryptKey, PGPSecretKey signKey, ArmoredOutputStream armorOut, byte[] data) throws IOException, PGPException {
PGPDataEncryptorBuilder cryptBuilder = ImplementationFactory.getInstance().getPGPDataEncryptorBuilder(SymmetricKeyAlgorithm.AES_256); PGPDataEncryptorBuilder cryptBuilder = OpenPGPImplementation.getInstance().pgpDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256);
cryptBuilder.setWithIntegrityPacket(true); cryptBuilder.setWithIntegrityPacket(true);
PGPEncryptedDataGenerator cryptGen = new PGPEncryptedDataGenerator(cryptBuilder); PGPEncryptedDataGenerator cryptGen = new PGPEncryptedDataGenerator(cryptBuilder);
cryptGen.addMethod(ImplementationFactory.getInstance().getPublicKeyKeyEncryptionMethodGenerator(cryptKey)); cryptGen.addMethod(OpenPGPImplementation.getInstance().publicKeyKeyEncryptionMethodGenerator(cryptKey));
OutputStream cryptStream = cryptGen.open(armorOut, new byte[512]); OutputStream cryptStream = cryptGen.open(armorOut, new byte[512]);
PGPSignatureGenerator sigGen = new PGPSignatureGenerator(ImplementationFactory.getInstance() PGPSignatureGenerator sigGen = new PGPSignatureGenerator(OpenPGPImplementation.getInstance()
.getPGPContentSignerBuilder(signKey.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId())); .pgpContentSignerBuilder(signKey.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId()),
signKey.getPublicKey());
sigGen.init(SignatureType.BINARY_DOCUMENT.getCode(), UnlockSecretKey sigGen.init(SignatureType.BINARY_DOCUMENT.getCode(), UnlockSecretKey
.unlockSecretKey(signKey, (Passphrase) null)); .unlockSecretKey(signKey, (Passphrase) null));

View file

@ -9,6 +9,7 @@ import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPV3SignatureGenerator; import org.bouncycastle.openpgp.PGPV3SignatureGenerator;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -16,7 +17,6 @@ import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.HashAlgorithm; import org.pgpainless.algorithm.HashAlgorithm;
import org.pgpainless.algorithm.PublicKeyAlgorithm; import org.pgpainless.algorithm.PublicKeyAlgorithm;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.TestKeys; import org.pgpainless.key.TestKeys;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
@ -48,7 +48,7 @@ class VerifyVersion3SignaturePacketTest {
} }
private static PGPSignature generateV3Signature() throws IOException, PGPException { private static PGPSignature generateV3Signature() throws IOException, PGPException {
PGPContentSignerBuilder builder = ImplementationFactory.getInstance().getPGPContentSignerBuilder(PublicKeyAlgorithm.ECDSA, HashAlgorithm.SHA512); PGPContentSignerBuilder builder = OpenPGPImplementation.getInstance().pgpContentSignerBuilder(PublicKeyAlgorithm.ECDSA.getAlgorithmId(), HashAlgorithm.SHA512.getAlgorithmId());
PGPV3SignatureGenerator signatureGenerator = new PGPV3SignatureGenerator(builder); PGPV3SignatureGenerator signatureGenerator = new PGPV3SignatureGenerator(builder);
PGPSecretKeyRing secretKeys = TestKeys.getEmilSecretKeyRing(); PGPSecretKeyRing secretKeys = TestKeys.getEmilSecretKeyRing();

View file

@ -12,10 +12,10 @@ import java.io.IOException;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator; import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.util.TestAllImplementations; import org.pgpainless.util.TestAllImplementations;
public class ImportExportKeyTest { public class ImportExportKeyTest {
@ -29,7 +29,7 @@ public class ImportExportKeyTest {
public void testExportImportPublicKeyRing() throws IOException { public void testExportImportPublicKeyRing() throws IOException {
PGPPublicKeyRing publicKeys = TestKeys.getJulietPublicKeyRing(); PGPPublicKeyRing publicKeys = TestKeys.getJulietPublicKeyRing();
KeyFingerPrintCalculator calc = ImplementationFactory.getInstance().getKeyFingerprintCalculator(); KeyFingerPrintCalculator calc = OpenPGPImplementation.getInstance().keyFingerPrintCalculator();
byte[] bytes = publicKeys.getEncoded(); byte[] bytes = publicKeys.getEncoded();
PGPPublicKeyRing parsed = new PGPPublicKeyRing(bytes, calc); PGPPublicKeyRing parsed = new PGPPublicKeyRing(bytes, calc);
assertArrayEquals(publicKeys.getEncoded(), parsed.getEncoded()); assertArrayEquals(publicKeys.getEncoded(), parsed.getEncoded());
@ -40,7 +40,7 @@ public class ImportExportKeyTest {
public void testExportImportSecretKeyRing() throws IOException, PGPException { public void testExportImportSecretKeyRing() throws IOException, PGPException {
PGPSecretKeyRing secretKeys = TestKeys.getRomeoSecretKeyRing(); PGPSecretKeyRing secretKeys = TestKeys.getRomeoSecretKeyRing();
KeyFingerPrintCalculator calc = ImplementationFactory.getInstance().getKeyFingerprintCalculator(); KeyFingerPrintCalculator calc = OpenPGPImplementation.getInstance().keyFingerPrintCalculator();
byte[] bytes = secretKeys.getEncoded(); byte[] bytes = secretKeys.getEncoded();
PGPSecretKeyRing parsed = new PGPSecretKeyRing(bytes, calc); PGPSecretKeyRing parsed = new PGPSecretKeyRing(bytes, calc);
assertArrayEquals(secretKeys.getEncoded(), parsed.getEncoded()); assertArrayEquals(secretKeys.getEncoded(), parsed.getEncoded());

View file

@ -20,11 +20,11 @@ import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
import org.bouncycastle.util.Strings; import org.bouncycastle.util.Strings;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.info.KeyRingInfo; import org.pgpainless.key.info.KeyRingInfo;
import org.pgpainless.key.protection.UnlockSecretKey; import org.pgpainless.key.protection.UnlockSecretKey;
import org.pgpainless.util.Passphrase; import org.pgpainless.util.Passphrase;
@ -121,9 +121,10 @@ public class WeirdKeys {
assertThrows(IllegalArgumentException.class, () -> Strings.fromUTF8ByteArray(idBytes)); assertThrows(IllegalArgumentException.class, () -> Strings.fromUTF8ByteArray(idBytes));
PGPSignatureGenerator sigGen = new PGPSignatureGenerator( PGPSignatureGenerator sigGen = new PGPSignatureGenerator(
ImplementationFactory.getInstance().getPGPContentSignerBuilder( OpenPGPImplementation.getInstance().pgpContentSignerBuilder(
pubKey.getAlgorithm(), pubKey.getAlgorithm(),
HashAlgorithmTags.SHA512)); HashAlgorithmTags.SHA512),
pubKey);
sigGen.init(SignatureType.GENERIC_CERTIFICATION.getCode(), privKey); sigGen.init(SignatureType.GENERIC_CERTIFICATION.getCode(), privKey);
// We have to manually generate the signature over the user-ID // We have to manually generate the signature over the user-ID

View file

@ -6,7 +6,6 @@ package org.pgpainless.key.generation;
import org.bouncycastle.bcpg.SignatureSubpacketTags; import org.bouncycastle.bcpg.SignatureSubpacketTags;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.api.OpenPGPCertificate; import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.openpgp.api.OpenPGPKey; import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.bouncycastle.openpgp.api.SignatureParameters; import org.bouncycastle.openpgp.api.SignatureParameters;
@ -16,6 +15,7 @@ import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.KeyFlag; import org.pgpainless.algorithm.KeyFlag;
import org.pgpainless.algorithm.OpenPGPKeyVersion; import org.pgpainless.algorithm.OpenPGPKeyVersion;
import org.pgpainless.algorithm.PublicKeyAlgorithm; import org.pgpainless.algorithm.PublicKeyAlgorithm;
import org.pgpainless.key.generation.type.rsa.RsaLength;
import java.io.IOException; import java.io.IOException;
@ -27,10 +27,25 @@ public class GenerateV6KeyTest {
@Test @Test
public void generateModernV6Key() { public void generateModernV6Key() {
PGPSecretKeyRing secretKey = PGPainless.generateKeyRing(OpenPGPKeyVersion.v6) OpenPGPKey key = PGPainless.generateKeyRing(OpenPGPKeyVersion.v6)
.modernKeyRing("Alice <alice@example.org>") .modernKeyRing("Alice <alice@example.org>");
.getPGPSecretKeyRing(); assertEquals(3, key.getKeys().size());
assertEquals(6, secretKey.getPublicKey().getVersion());
OpenPGPCertificate.OpenPGPPrimaryKey primaryKey = key.getPrimaryKey();
assertEquals(primaryKey, key.getCertificationKeys().get(0));
assertEquals(6, primaryKey.getVersion());
assertEquals(PublicKeyAlgorithm.ED25519.getAlgorithmId(),
primaryKey.getAlgorithm());
OpenPGPCertificate.OpenPGPComponentKey signingKey = key.getSigningKeys().get(0);
assertEquals(6, signingKey.getVersion());
assertEquals(PublicKeyAlgorithm.ED25519.getAlgorithmId(),
signingKey.getAlgorithm());
OpenPGPCertificate.OpenPGPComponentKey encryptionKey = key.getEncryptionKeys().get(0);
assertEquals(6, encryptionKey.getVersion());
assertEquals(PublicKeyAlgorithm.X25519.getAlgorithmId(),
encryptionKey.getAlgorithm());
} }
@Test @Test
@ -53,9 +68,11 @@ public class GenerateV6KeyTest {
assertEquals(1, key.getKeys().size()); assertEquals(1, key.getKeys().size());
OpenPGPCertificate.OpenPGPPrimaryKey primaryKey = key.getPrimaryKey(); OpenPGPCertificate.OpenPGPPrimaryKey primaryKey = key.getPrimaryKey();
assertTrue(key.getCertificationKeys().isEmpty());
assertEquals(6, primaryKey.getVersion()); assertEquals(6, primaryKey.getVersion());
assertTrue(primaryKey.isPrimaryKey()); assertTrue(primaryKey.isPrimaryKey());
assertEquals(PublicKeyAlgorithm.ED25519.getAlgorithmId(), primaryKey.getPGPPublicKey().getAlgorithm()); assertEquals(PublicKeyAlgorithm.ED25519.getAlgorithmId(),
primaryKey.getAlgorithm());
assertEquals(primaryKey, key.getSigningKeys().get(0)); assertEquals(primaryKey, key.getSigningKeys().get(0));
assertTrue(key.getEncryptionKeys().isEmpty()); assertTrue(key.getEncryptionKeys().isEmpty());
@ -76,7 +93,8 @@ public class GenerateV6KeyTest {
assertTrue(key.isSecretKey()); assertTrue(key.isSecretKey());
assertEquals(3, key.getKeys().size()); assertEquals(3, key.getKeys().size());
OpenPGPCertificate.OpenPGPPrimaryKey primaryKey = key.getPrimaryKey(); OpenPGPCertificate.OpenPGPPrimaryKey primaryKey = key.getPrimaryKey();
assertEquals(PublicKeyAlgorithm.ED25519.getAlgorithmId(), primaryKey.getPGPPublicKey().getAlgorithm()); assertEquals(primaryKey, key.getCertificationKeys().get(0));
assertEquals(PublicKeyAlgorithm.ED25519.getAlgorithmId(), primaryKey.getAlgorithm());
assertEquals(6, primaryKey.getVersion()); assertEquals(6, primaryKey.getVersion());
assertTrue(primaryKey.isPrimaryKey()); assertTrue(primaryKey.isPrimaryKey());
assertEquals(primaryKey, key.getKeys().get(0)); assertEquals(primaryKey, key.getKeys().get(0));
@ -84,13 +102,13 @@ public class GenerateV6KeyTest {
OpenPGPCertificate.OpenPGPComponentKey signingKey = key.getKeys().get(1); OpenPGPCertificate.OpenPGPComponentKey signingKey = key.getKeys().get(1);
assertTrue(key.getSigningKeys().contains(signingKey)); assertTrue(key.getSigningKeys().contains(signingKey));
assertEquals(6, signingKey.getVersion()); assertEquals(6, signingKey.getVersion());
assertEquals(PublicKeyAlgorithm.ED25519.getAlgorithmId(), signingKey.getPGPPublicKey().getAlgorithm()); assertEquals(PublicKeyAlgorithm.ED25519.getAlgorithmId(), signingKey.getAlgorithm());
assertFalse(signingKey.isPrimaryKey()); assertFalse(signingKey.isPrimaryKey());
OpenPGPCertificate.OpenPGPComponentKey encryptionKey = key.getKeys().get(2); OpenPGPCertificate.OpenPGPComponentKey encryptionKey = key.getKeys().get(2);
assertTrue(key.getEncryptionKeys().contains(encryptionKey)); assertTrue(key.getEncryptionKeys().contains(encryptionKey));
assertEquals(6, encryptionKey.getVersion()); assertEquals(6, encryptionKey.getVersion());
assertEquals(PublicKeyAlgorithm.X25519.getAlgorithmId(), encryptionKey.getPGPPublicKey().getAlgorithm()); assertEquals(PublicKeyAlgorithm.X25519.getAlgorithmId(), encryptionKey.getAlgorithm());
assertFalse(encryptionKey.isPrimaryKey()); assertFalse(encryptionKey.isPrimaryKey());
OpenPGPCertificate certificate = key.toCertificate(); OpenPGPCertificate certificate = key.toCertificate();
@ -100,4 +118,32 @@ public class GenerateV6KeyTest {
System.out.println(certificate.toAsciiArmoredString()); System.out.println(certificate.toAsciiArmoredString());
// CHECKSTYLE:ON // CHECKSTYLE:ON
} }
@Test
public void buildMonolithicRSAKey() {
OpenPGPKey key = PGPainless.getInstance().generateKey(OpenPGPKeyVersion.v6)
.simpleRsaKeyRing("Alice <alice@example.org>", RsaLength._4096);
OpenPGPCertificate.OpenPGPPrimaryKey primaryKey = key.getPrimaryKey();
// Primary key is used for all purposes
assertEquals(primaryKey, key.getCertificationKeys().get(0));
assertEquals(primaryKey, key.getSigningKeys().get(0));
assertEquals(primaryKey, key.getEncryptionKeys().get(0));
}
@Test
public void generateAEADProtectedModernKey()
throws IOException {
OpenPGPKey key = PGPainless.getInstance()
.generateKey(OpenPGPKeyVersion.v6)
.modernKeyRing("Alice <alice@example.com>", "p455w0rd");
String armored = key.toAsciiArmoredString();
OpenPGPKey parsed = PGPainless.getInstance().readKey().parseKey(armored);
OpenPGPKey.OpenPGPSecretKey primaryKey = key.getPrimarySecretKey();
assertEquals(armored, parsed.toAsciiArmoredString());
}
} }

View file

@ -16,6 +16,7 @@ import java.util.Iterator;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.TestTemplate;
@ -26,7 +27,6 @@ import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
import org.pgpainless.encryption_signing.EncryptionStream; import org.pgpainless.encryption_signing.EncryptionStream;
import org.pgpainless.encryption_signing.ProducerOptions; import org.pgpainless.encryption_signing.ProducerOptions;
import org.pgpainless.encryption_signing.SigningOptions; import org.pgpainless.encryption_signing.SigningOptions;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.protection.KeyRingProtectionSettings; import org.pgpainless.key.protection.KeyRingProtectionSettings;
import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector; import org.pgpainless.key.protection.PasswordBasedSecretKeyRingProtector;
import org.pgpainless.key.protection.UnlockSecretKey; import org.pgpainless.key.protection.UnlockSecretKey;
@ -166,7 +166,12 @@ public class ChangeSecretKeyRingPassphraseTest {
} else if (!passphrase.isEmpty() && secretKey.getKeyEncryptionAlgorithm() == SymmetricKeyAlgorithm.NULL.getAlgorithmId()) { } else if (!passphrase.isEmpty() && secretKey.getKeyEncryptionAlgorithm() == SymmetricKeyAlgorithm.NULL.getAlgorithmId()) {
throw new PGPException("Cannot unlock unprotected private key with non-empty passphrase."); throw new PGPException("Cannot unlock unprotected private key with non-empty passphrase.");
} }
PBESecretKeyDecryptor decryptor = passphrase.isEmpty() ? null : ImplementationFactory.getInstance().getPBESecretKeyDecryptor(passphrase); PBESecretKeyDecryptor decryptor = passphrase.isEmpty() ?
null :
OpenPGPImplementation.getInstance()
.pbeSecretKeyDecryptorBuilderProvider()
.provide()
.build(passphrase.getChars());
UnlockSecretKey.unlockSecretKey(secretKey, decryptor); UnlockSecretKey.unlockSecretKey(secretKey, decryptor);
} }

View file

@ -29,11 +29,11 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.opentest4j.TestAbortedException; import org.opentest4j.TestAbortedException;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.OpenPgpV4Fingerprint; import org.pgpainless.key.OpenPgpV4Fingerprint;
import org.pgpainless.key.collection.PGPKeyRingCollection; import org.pgpainless.key.collection.PGPKeyRingCollection;
import org.pgpainless.key.util.KeyRingUtils; import org.pgpainless.key.util.KeyRingUtils;
@ -63,7 +63,7 @@ class KeyRingReaderTest {
InputStream possiblyArmored = PGPUtil.getDecoderStream(PGPUtil.getDecoderStream(inputStream)); InputStream possiblyArmored = PGPUtil.getDecoderStream(PGPUtil.getDecoderStream(inputStream));
PGPPublicKeyRingCollection collection = new PGPPublicKeyRingCollection( PGPPublicKeyRingCollection collection = new PGPPublicKeyRingCollection(
possiblyArmored, ImplementationFactory.getInstance().getKeyFingerprintCalculator()); possiblyArmored, OpenPGPImplementation.getInstance().keyFingerPrintCalculator());
assertEquals(10, collection.size()); assertEquals(10, collection.size());
} }

View file

@ -53,7 +53,6 @@ public class CachingSecretKeyRingProtectorTest {
@Test @Test
public void noCallbackReturnsNullForUnknownKeyId() throws PGPException { public void noCallbackReturnsNullForUnknownKeyId() throws PGPException {
assertNull(protector.getDecryptor(123L)); assertNull(protector.getDecryptor(123L));
assertNull(protector.getEncryptor(123L));
} }
@Test @Test
@ -61,7 +60,6 @@ public class CachingSecretKeyRingProtectorTest {
Passphrase passphrase = Passphrase.fromPassword("HelloWorld"); Passphrase passphrase = Passphrase.fromPassword("HelloWorld");
protector.addPassphrase(new KeyIdentifier(123L), passphrase); protector.addPassphrase(new KeyIdentifier(123L), passphrase);
assertEquals(passphrase, protector.getPassphraseFor(123L)); assertEquals(passphrase, protector.getPassphraseFor(123L));
assertNotNull(protector.getEncryptor(123L));
assertNotNull(protector.getDecryptor(123L)); assertNotNull(protector.getDecryptor(123L));
assertNull(protector.getPassphraseFor(999L)); assertNull(protector.getPassphraseFor(999L));
@ -88,7 +86,7 @@ public class CachingSecretKeyRingProtectorTest {
while (it.hasNext()) { while (it.hasNext()) {
PGPSecretKey key = it.next(); PGPSecretKey key = it.next();
assertEquals(passphrase, protector.getPassphraseFor(key)); assertEquals(passphrase, protector.getPassphraseFor(key));
assertNotNull(protector.getEncryptor(key.getKeyID())); assertNotNull(protector.getEncryptor(key.getPublicKey()));
assertNotNull(protector.getDecryptor(key.getKeyID())); assertNotNull(protector.getDecryptor(key.getKeyID()));
} }
@ -100,7 +98,7 @@ public class CachingSecretKeyRingProtectorTest {
while (it.hasNext()) { while (it.hasNext()) {
PGPSecretKey key = it.next(); PGPSecretKey key = it.next();
assertNull(protector.getPassphraseFor(key)); assertNull(protector.getPassphraseFor(key));
assertNull(protector.getEncryptor(key.getKeyID())); assertNull(protector.getEncryptor(key.getPublicKey()));
assertNull(protector.getDecryptor(key.getKeyID())); assertNull(protector.getDecryptor(key.getKeyID()));
} }
} }

View file

@ -7,6 +7,7 @@ package org.pgpainless.key.protection;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -46,14 +47,14 @@ public class PassphraseProtectedKeyTest {
}); });
@Test @Test
public void testReturnsNonNullDecryptorEncryptorForPassword() throws PGPException { public void testReturnsNonNullDecryptorEncryptorForPassword() throws IOException {
assertNotNull(protector.getEncryptor(TestKeys.CRYPTIE_KEY_ID)); assertNotNull(protector.getEncryptor(TestKeys.getCryptiePublicKeyRing().getPublicKey(TestKeys.CRYPTIE_KEY_ID)));
assertNotNull(protector.getDecryptor(TestKeys.CRYPTIE_KEY_ID)); assertNotNull(protector.getDecryptor(TestKeys.CRYPTIE_KEY_ID));
} }
@Test @Test
public void testReturnsNullDecryptorEncryptorForNoPassword() throws PGPException { public void testReturnsNullDecryptorEncryptorForNoPassword() throws IOException {
assertNull(protector.getEncryptor(TestKeys.JULIET_KEY_ID)); assertNull(protector.getEncryptor(TestKeys.getJulietPublicKeyRing().getPublicKey(TestKeys.JULIET_KEY_ID)));
assertNull(protector.getDecryptor(TestKeys.JULIET_KEY_ID)); assertNull(protector.getDecryptor(TestKeys.JULIET_KEY_ID));
} }
@ -64,7 +65,7 @@ public class PassphraseProtectedKeyTest {
SecretKeyRingProtector protector = PasswordBasedSecretKeyRingProtector.forKey(secretKeys, Passphrase.fromPassword("passphrase")); SecretKeyRingProtector protector = PasswordBasedSecretKeyRingProtector.forKey(secretKeys, Passphrase.fromPassword("passphrase"));
for (Iterator<PGPPublicKey> it = secretKeys.getPublicKeys(); it.hasNext(); ) { for (Iterator<PGPPublicKey> it = secretKeys.getPublicKeys(); it.hasNext(); ) {
PGPPublicKey subkey = it.next(); PGPPublicKey subkey = it.next();
assertNotNull(protector.getEncryptor(subkey.getKeyID())); assertNotNull(protector.getEncryptor(subkey));
assertNotNull(protector.getDecryptor(subkey.getKeyID())); assertNotNull(protector.getDecryptor(subkey.getKeyID()));
} }
} }

View file

@ -62,7 +62,6 @@ public class SecretKeyRingProtectorTest {
SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys(); SecretKeyRingProtector protector = SecretKeyRingProtector.unprotectedKeys();
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
Long keyId = random.nextLong(); Long keyId = random.nextLong();
assertNull(protector.getEncryptor(keyId));
assertNull(protector.getDecryptor(keyId)); assertNull(protector.getDecryptor(keyId));
} }
} }
@ -80,8 +79,8 @@ public class SecretKeyRingProtectorTest {
SecretKeyRingProtector protector = SecretKeyRingProtector protector =
SecretKeyRingProtector.unlockSingleKeyWith(TestKeys.CRYPTIE_PASSPHRASE, secretKey); SecretKeyRingProtector.unlockSingleKeyWith(TestKeys.CRYPTIE_PASSPHRASE, secretKey);
assertNotNull(protector.getDecryptor(secretKey.getKeyID())); assertNotNull(protector.getDecryptor(secretKey.getKeyID()));
assertNotNull(protector.getEncryptor(secretKey.getKeyID())); assertNotNull(protector.getEncryptor(secretKey.getPublicKey()));
assertNull(protector.getEncryptor(subKey.getKeyID())); assertNull(protector.getEncryptor(subKey.getPublicKey()));
assertNull(protector.getDecryptor(subKey.getKeyID())); assertNull(protector.getDecryptor(subKey.getKeyID()));
} }

View file

@ -17,9 +17,4 @@ public class UnprotectedKeysProtectorTest {
public void testKeyProtectorReturnsNullDecryptor() throws PGPException { public void testKeyProtectorReturnsNullDecryptor() throws PGPException {
assertNull(protector.getDecryptor(0L)); assertNull(protector.getDecryptor(0L));
} }
@Test
public void testKeyProtectorReturnsNullEncryptor() throws PGPException {
assertNull(protector.getEncryptor(0L));
}
} }

View file

@ -14,13 +14,13 @@ import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector;
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVectorGenerator; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVectorGenerator;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.HashAlgorithm; import org.pgpainless.algorithm.HashAlgorithm;
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;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.generation.KeyRingBuilder; import org.pgpainless.key.generation.KeyRingBuilder;
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;
@ -57,9 +57,9 @@ public class KeyRingUtilTest {
// create sig // create sig
PGPSignatureGenerator sigGen = new PGPSignatureGenerator( PGPSignatureGenerator sigGen = new PGPSignatureGenerator(
ImplementationFactory.getInstance().getPGPContentSignerBuilder( OpenPGPImplementation.getInstance().pgpContentSignerBuilder(
secretKeys.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId() secretKeys.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId()
)); ), secretKeys.getPublicKey());
sigGen.init( sigGen.init(
SignatureType.POSITIVE_CERTIFICATION.getCode(), SignatureType.POSITIVE_CERTIFICATION.getCode(),
UnlockSecretKey.unlockSecretKey(secretKeys.getSecretKey(), SecretKeyRingProtector.unprotectedKeys())); UnlockSecretKey.unlockSecretKey(secretKeys.getSecretKey(), SecretKeyRingProtector.unprotectedKeys()));

View file

@ -29,6 +29,7 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPSignatureList;
import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory; import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.TestTemplate;
@ -42,7 +43,6 @@ import org.pgpainless.encryption_signing.EncryptionOptions;
import org.pgpainless.encryption_signing.EncryptionStream; import org.pgpainless.encryption_signing.EncryptionStream;
import org.pgpainless.encryption_signing.ProducerOptions; import org.pgpainless.encryption_signing.ProducerOptions;
import org.pgpainless.encryption_signing.SigningOptions; import org.pgpainless.encryption_signing.SigningOptions;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.key.protection.UnlockSecretKey; import org.pgpainless.key.protection.UnlockSecretKey;
import org.pgpainless.util.TestAllImplementations; import org.pgpainless.util.TestAllImplementations;
@ -78,7 +78,7 @@ public class OnePassSignatureBracketingTest {
ByteArrayInputStream ciphertextIn = new ByteArrayInputStream(out.toByteArray()); ByteArrayInputStream ciphertextIn = new ByteArrayInputStream(out.toByteArray());
InputStream inputStream = PGPUtil.getDecoderStream(ciphertextIn); InputStream inputStream = PGPUtil.getDecoderStream(ciphertextIn);
PGPObjectFactory objectFactory = ImplementationFactory.getInstance().getPGPObjectFactory(inputStream); PGPObjectFactory objectFactory = OpenPGPImplementation.getInstance().pgpObjectFactory(inputStream);
PGPOnePassSignatureList onePassSignatures = null; PGPOnePassSignatureList onePassSignatures = null;
PGPSignatureList signatures = null; PGPSignatureList signatures = null;
@ -95,9 +95,9 @@ public class OnePassSignatureBracketingTest {
PGPPublicKeyEncryptedData publicKeyEncryptedData = (PGPPublicKeyEncryptedData) encryptedData; PGPPublicKeyEncryptedData publicKeyEncryptedData = (PGPPublicKeyEncryptedData) encryptedData;
PGPSecretKey secretKey = key1.getSecretKey(publicKeyEncryptedData.getKeyID()); PGPSecretKey secretKey = key1.getSecretKey(publicKeyEncryptedData.getKeyID());
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, SecretKeyRingProtector.unprotectedKeys()); PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, SecretKeyRingProtector.unprotectedKeys());
PublicKeyDataDecryptorFactory decryptorFactory = ImplementationFactory.getInstance().getPublicKeyDataDecryptorFactory(privateKey); PublicKeyDataDecryptorFactory decryptorFactory = OpenPGPImplementation.getInstance().publicKeyDataDecryptorFactory(privateKey);
InputStream decryptionStream = publicKeyEncryptedData.getDataStream(decryptorFactory); InputStream decryptionStream = publicKeyEncryptedData.getDataStream(decryptorFactory);
objectFactory = ImplementationFactory.getInstance().getPGPObjectFactory(decryptionStream); objectFactory = OpenPGPImplementation.getInstance().pgpObjectFactory(decryptionStream);
continue outerloop; continue outerloop;
} }
} }
@ -107,7 +107,7 @@ public class OnePassSignatureBracketingTest {
} else if (next instanceof PGPCompressedData) { } else if (next instanceof PGPCompressedData) {
PGPCompressedData compressed = (PGPCompressedData) next; PGPCompressedData compressed = (PGPCompressedData) next;
InputStream decompressor = compressed.getDataStream(); InputStream decompressor = compressed.getDataStream();
objectFactory = ImplementationFactory.getInstance().getPGPObjectFactory(decompressor); objectFactory = OpenPGPImplementation.getInstance().pgpObjectFactory(decompressor);
continue outerloop; continue outerloop;
} else if (next instanceof PGPLiteralData) { } else if (next instanceof PGPLiteralData) {
continue outerloop; continue outerloop;

View file

@ -19,12 +19,12 @@ import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector;
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVectorGenerator; import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVectorGenerator;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.HashAlgorithm; import org.pgpainless.algorithm.HashAlgorithm;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.exception.SignatureValidationException; import org.pgpainless.exception.SignatureValidationException;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.TestKeys; import org.pgpainless.key.TestKeys;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.key.protection.UnlockSecretKey; import org.pgpainless.key.protection.UnlockSecretKey;
@ -58,8 +58,9 @@ public class SignatureOverUserAttributesTest {
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, SecretKeyRingProtector.unprotectedKeys()); PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, SecretKeyRingProtector.unprotectedKeys());
PGPSignatureGenerator generator = new PGPSignatureGenerator( PGPSignatureGenerator generator = new PGPSignatureGenerator(
ImplementationFactory.getInstance() OpenPGPImplementation.getInstance()
.getPGPContentSignerBuilder(secretKey.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId())); .pgpContentSignerBuilder(secretKey.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId()),
secretKey.getPublicKey());
generator.init(SignatureType.CASUAL_CERTIFICATION.getCode(), privateKey); generator.init(SignatureType.CASUAL_CERTIFICATION.getCode(), privateKey);
PGPSignature signature = generator.generateCertification(attribute, publicKey); PGPSignature signature = generator.generateCertification(attribute, publicKey);
@ -78,8 +79,9 @@ public class SignatureOverUserAttributesTest {
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, SecretKeyRingProtector.unprotectedKeys()); PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, SecretKeyRingProtector.unprotectedKeys());
PGPSignatureGenerator generator = new PGPSignatureGenerator( PGPSignatureGenerator generator = new PGPSignatureGenerator(
ImplementationFactory.getInstance() OpenPGPImplementation.getInstance()
.getPGPContentSignerBuilder(secretKey.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId())); .pgpContentSignerBuilder(secretKey.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId()),
secretKey.getPublicKey());
generator.init(SignatureType.CERTIFICATION_REVOCATION.getCode(), privateKey); generator.init(SignatureType.CERTIFICATION_REVOCATION.getCode(), privateKey);
PGPSignature signature = generator.generateCertification(attribute, publicKey); PGPSignature signature = generator.generateCertification(attribute, publicKey);

View file

@ -33,13 +33,13 @@ import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.bouncycastle.openpgp.api.OpenPGPCertificate; import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
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.CompressionAlgorithm;
import org.pgpainless.algorithm.Feature; import org.pgpainless.algorithm.Feature;
import org.pgpainless.algorithm.HashAlgorithm; import org.pgpainless.algorithm.HashAlgorithm;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.TestKeys; import org.pgpainless.key.TestKeys;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.key.protection.UnlockSecretKey; import org.pgpainless.key.protection.UnlockSecretKey;
@ -286,7 +286,7 @@ public class SignatureSubpacketsUtilTest {
private PGPSignatureGenerator getSignatureGenerator(PGPPrivateKey signingKey, private PGPSignatureGenerator getSignatureGenerator(PGPPrivateKey signingKey,
SignatureType signatureType) throws PGPException { SignatureType signatureType) throws PGPException {
PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator( PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(
ImplementationFactory.getInstance().getPGPContentSignerBuilder( OpenPGPImplementation.getInstance().pgpContentSignerBuilder(
signingKey.getPublicKeyPacket().getAlgorithm(), signingKey.getPublicKeyPacket().getAlgorithm(),
HashAlgorithm.SHA512.getAlgorithmId())); HashAlgorithm.SHA512.getAlgorithmId()));
signatureGenerator.init(signatureType.getCode(), signingKey); signatureGenerator.init(signatureType.getCode(), signingKey);

View file

@ -9,12 +9,12 @@ import org.bouncycastle.bcpg.sig.Exportable;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.api.OpenPGPCertificate; import org.bouncycastle.openpgp.api.OpenPGPCertificate;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
import org.bouncycastle.openpgp.api.OpenPGPKey; import org.bouncycastle.openpgp.api.OpenPGPKey;
import org.bouncycastle.openpgp.api.OpenPGPSignature; import org.bouncycastle.openpgp.api.OpenPGPSignature;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.SecretKeyRingProtector;
import org.pgpainless.signature.subpackets.CertificationSubpackets; import org.pgpainless.signature.subpackets.CertificationSubpackets;
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil; import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil;
@ -70,7 +70,7 @@ public class ThirdPartyCertificationSignatureBuilderTest {
assertFalse(exportable.isExportable()); assertFalse(exportable.isExportable());
// test sig correctness // test sig correctness
signature.init(ImplementationFactory.getInstance().getPgpContentVerifierBuilderProvider(), signature.init(OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
secretKeys.getPrimaryKey().getPGPPublicKey()); secretKeys.getPrimaryKey().getPGPPublicKey());
assertTrue(signature.verifyCertification("Bob", bobsPublicKeys.getPrimaryKey().getPGPPublicKey())); assertTrue(signature.verifyCertification("Bob", bobsPublicKeys.getPrimaryKey().getPGPPublicKey()));
} }

View file

@ -39,6 +39,7 @@ import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; import org.bouncycastle.openpgp.PGPSignatureSubpacketVector;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -49,7 +50,6 @@ import org.pgpainless.algorithm.KeyFlag;
import org.pgpainless.algorithm.PublicKeyAlgorithm; import org.pgpainless.algorithm.PublicKeyAlgorithm;
import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.SignatureType;
import org.pgpainless.algorithm.SymmetricKeyAlgorithm; import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.OpenPgpFingerprint; import org.pgpainless.key.OpenPgpFingerprint;
import org.pgpainless.key.TestKeys; import org.pgpainless.key.TestKeys;
import org.pgpainless.key.protection.UnlockSecretKey; import org.pgpainless.key.protection.UnlockSecretKey;
@ -414,8 +414,9 @@ public class SignatureSubpacketsTest {
Iterator<PGPSecretKey> secretKeyIterator = secretKeys.iterator(); Iterator<PGPSecretKey> secretKeyIterator = secretKeys.iterator();
PGPSecretKey primaryKey = secretKeyIterator.next(); PGPSecretKey primaryKey = secretKeyIterator.next();
PGPSignatureGenerator generator = new PGPSignatureGenerator( PGPSignatureGenerator generator = new PGPSignatureGenerator(
ImplementationFactory.getInstance().getPGPContentSignerBuilder(primaryKey.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId()) OpenPGPImplementation.getInstance().pgpContentSignerBuilder(
); primaryKey.getPublicKey().getAlgorithm(), HashAlgorithm.SHA512.getAlgorithmId()),
primaryKey.getPublicKey());
PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(primaryKey, (Passphrase) null); PGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(primaryKey, (Passphrase) null);
generator.init(SignatureType.DIRECT_KEY.getCode(), privateKey); generator.init(SignatureType.DIRECT_KEY.getCode(), privateKey);

View file

@ -26,6 +26,7 @@ import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPUtil; import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
@ -35,7 +36,6 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.algorithm.HashAlgorithm; import org.pgpainless.algorithm.HashAlgorithm;
import org.pgpainless.algorithm.KeyFlag; import org.pgpainless.algorithm.KeyFlag;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.TestKeys; import org.pgpainless.key.TestKeys;
import org.pgpainless.key.generation.KeySpec; import org.pgpainless.key.generation.KeySpec;
import org.pgpainless.key.generation.type.ecc.EllipticCurve; import org.pgpainless.key.generation.type.ecc.EllipticCurve;
@ -257,9 +257,9 @@ public class ArmorUtilsTest {
"-----END PGP MESSAGE-----"; "-----END PGP MESSAGE-----";
InputStream inputStream = PGPUtil.getDecoderStream(new ByteArrayInputStream(armored.getBytes(StandardCharsets.UTF_8))); InputStream inputStream = PGPUtil.getDecoderStream(new ByteArrayInputStream(armored.getBytes(StandardCharsets.UTF_8)));
PGPObjectFactory factory = ImplementationFactory.getInstance().getPGPObjectFactory(inputStream); PGPObjectFactory factory = OpenPGPImplementation.getInstance().pgpObjectFactory(inputStream);
PGPCompressedData compressed = (PGPCompressedData) factory.nextObject(); PGPCompressedData compressed = (PGPCompressedData) factory.nextObject();
factory = ImplementationFactory.getInstance().getPGPObjectFactory(compressed.getDataStream()); factory = OpenPGPImplementation.getInstance().pgpObjectFactory(compressed.getDataStream());
PGPLiteralData literal = (PGPLiteralData) factory.nextObject(); PGPLiteralData literal = (PGPLiteralData) factory.nextObject();
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
assertEquals("_CONSOLE", literal.getFileName()); assertEquals("_CONSOLE", literal.getFileName());

View file

@ -9,18 +9,18 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
import org.bouncycastle.openpgp.api.bc.BcOpenPGPImplementation;
import org.bouncycastle.openpgp.api.jcajce.JcaOpenPGPImplementation;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback; import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.Extension; import org.junit.jupiter.api.extension.Extension;
import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.TestTemplateInvocationContext; import org.junit.jupiter.api.extension.TestTemplateInvocationContext;
import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider; import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider;
import org.pgpainless.implementation.BcImplementationFactory;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.implementation.JceImplementationFactory;
/** /**
* InvocationContextProvider that sets different {@link ImplementationFactory} implementations before running annotated * InvocationContextProvider that sets different {@link org.bouncycastle.openpgp.api.OpenPGPImplementation}
* tests. * before running annotated tests.
* *
* Example test annotation: * Example test annotation:
* {@code * {@code
@ -35,9 +35,9 @@ import org.pgpainless.implementation.JceImplementationFactory;
*/ */
public class TestAllImplementations implements TestTemplateInvocationContextProvider { public class TestAllImplementations implements TestTemplateInvocationContextProvider {
private static final List<ImplementationFactory> IMPLEMENTATIONS = Arrays.asList( private static final List<OpenPGPImplementation> IMPLEMENTATIONS = Arrays.asList(
new BcImplementationFactory(), new BcOpenPGPImplementation(),
new JceImplementationFactory() new JcaOpenPGPImplementation()
); );
@Override @Override
@ -49,16 +49,16 @@ public class TestAllImplementations implements TestTemplateInvocationContextProv
public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext context) { public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext context) {
return IMPLEMENTATIONS.stream() return IMPLEMENTATIONS.stream()
.map(implementationFactory -> new TestTemplateInvocationContext() { .map(implementation -> new TestTemplateInvocationContext() {
@Override @Override
public String getDisplayName(int invocationIndex) { public String getDisplayName(int invocationIndex) {
return context.getDisplayName() + " with " + implementationFactory.getClass().getSimpleName(); return context.getDisplayName() + " with " + implementation.getClass().getSimpleName();
} }
@Override @Override
public List<Extension> getAdditionalExtensions() { public List<Extension> getAdditionalExtensions() {
return Collections.singletonList( return Collections.singletonList(
(BeforeTestExecutionCallback) ctx -> ImplementationFactory.setFactoryImplementation(implementationFactory) (BeforeTestExecutionCallback) ctx -> OpenPGPImplementation.setInstance(implementation)
); );
} }
}); });

View file

@ -13,11 +13,11 @@ import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPLiteralData import org.bouncycastle.openpgp.PGPLiteralData
import org.bouncycastle.openpgp.PGPOnePassSignatureList import org.bouncycastle.openpgp.PGPOnePassSignatureList
import org.bouncycastle.openpgp.PGPSignatureList import org.bouncycastle.openpgp.PGPSignatureList
import org.bouncycastle.openpgp.api.OpenPGPImplementation
import org.bouncycastle.util.io.Streams import org.bouncycastle.util.io.Streams
import org.pgpainless.decryption_verification.OpenPgpInputStream import org.pgpainless.decryption_verification.OpenPgpInputStream
import org.pgpainless.decryption_verification.cleartext_signatures.ClearsignedMessageUtil import org.pgpainless.decryption_verification.cleartext_signatures.ClearsignedMessageUtil
import org.pgpainless.exception.WrongConsumingMethodException import org.pgpainless.exception.WrongConsumingMethodException
import org.pgpainless.implementation.ImplementationFactory
import org.pgpainless.util.ArmoredOutputStreamFactory import org.pgpainless.util.ArmoredOutputStreamFactory
import sop.ReadyWithResult import sop.ReadyWithResult
import sop.Signatures import sop.Signatures
@ -72,8 +72,7 @@ class InlineDetachImpl : InlineDetach {
} }
// handle binary OpenPGP data // handle binary OpenPGP data
var objectFactory = var objectFactory = OpenPGPImplementation.getInstance().pgpObjectFactory(pgpIn)
ImplementationFactory.getInstance().getPGPObjectFactory(pgpIn)
var next: Any? var next: Any?
while (objectFactory.nextObject().also { next = it } != null) { while (objectFactory.nextObject().also { next = it } != null) {
@ -95,8 +94,8 @@ class InlineDetachImpl : InlineDetach {
// Decompress compressed data // Decompress compressed data
try { try {
objectFactory = objectFactory =
ImplementationFactory.getInstance() OpenPGPImplementation.getInstance()
.getPGPObjectFactory((next as PGPCompressedData).dataStream) .pgpObjectFactory((next as PGPCompressedData).dataStream)
} catch (e: PGPException) { } catch (e: PGPException) {
throw SOPGPException.BadData( throw SOPGPException.BadData(
"Cannot decompress PGPCompressedData", e) "Cannot decompress PGPCompressedData", e)

View file

@ -6,6 +6,7 @@ package org.pgpainless.sop
import org.bouncycastle.bcpg.KeyIdentifier import org.bouncycastle.bcpg.KeyIdentifier
import org.bouncycastle.openpgp.PGPException import org.bouncycastle.openpgp.PGPException
import org.bouncycastle.openpgp.PGPPublicKey
import org.bouncycastle.openpgp.PGPSecretKey import org.bouncycastle.openpgp.PGPSecretKey
import org.bouncycastle.openpgp.PGPSecretKeyRing import org.bouncycastle.openpgp.PGPSecretKeyRing
import org.bouncycastle.openpgp.api.OpenPGPKey import org.bouncycastle.openpgp.api.OpenPGPKey
@ -82,8 +83,8 @@ class MatchMakingSecretKeyRingProtector : SecretKeyRingProtector {
override fun getDecryptor(keyIdentifier: KeyIdentifier): PBESecretKeyDecryptor? = override fun getDecryptor(keyIdentifier: KeyIdentifier): PBESecretKeyDecryptor? =
protector.getDecryptor(keyIdentifier) protector.getDecryptor(keyIdentifier)
override fun getEncryptor(keyIdentifier: KeyIdentifier): PBESecretKeyEncryptor? = override fun getEncryptor(key: PGPPublicKey): PBESecretKeyEncryptor? =
protector.getEncryptor(keyIdentifier) protector.getEncryptor(key)
override fun getKeyPassword(p0: OpenPGPKey.OpenPGPSecretKey): CharArray? = override fun getKeyPassword(p0: OpenPGPKey.OpenPGPSecretKey): CharArray? =
protector.getKeyPassword(p0) protector.getKeyPassword(p0)

View file

@ -22,10 +22,10 @@ import org.bouncycastle.openpgp.PGPObjectFactory;
import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureList; import org.bouncycastle.openpgp.PGPSignatureList;
import org.bouncycastle.openpgp.api.OpenPGPImplementation;
import org.bouncycastle.util.io.Streams; import org.bouncycastle.util.io.Streams;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.pgpainless.PGPainless; import org.pgpainless.PGPainless;
import org.pgpainless.implementation.ImplementationFactory;
import org.pgpainless.key.OpenPgpV4Fingerprint; import org.pgpainless.key.OpenPgpV4Fingerprint;
import sop.ByteArrayAndResult; import sop.ByteArrayAndResult;
import sop.SOP; import sop.SOP;
@ -153,13 +153,13 @@ public class InlineDetachTest {
ByteArrayOutputStream literalDataAndSignatures = new ByteArrayOutputStream(); ByteArrayOutputStream literalDataAndSignatures = new ByteArrayOutputStream();
ArmoredInputStream armorIn = new ArmoredInputStream(new ByteArrayInputStream(inlineSigned)); ArmoredInputStream armorIn = new ArmoredInputStream(new ByteArrayInputStream(inlineSigned));
PGPObjectFactory objectFactory = ImplementationFactory.getInstance().getPGPObjectFactory(armorIn); PGPObjectFactory objectFactory = OpenPGPImplementation.getInstance().pgpObjectFactory(armorIn);
Object next; Object next;
while ((next = objectFactory.nextObject()) != null) { while ((next = objectFactory.nextObject()) != null) {
if (next instanceof PGPCompressedData) { if (next instanceof PGPCompressedData) {
PGPCompressedData compressedData = (PGPCompressedData) next; PGPCompressedData compressedData = (PGPCompressedData) next;
try { try {
objectFactory = ImplementationFactory.getInstance().getPGPObjectFactory(compressedData.getDataStream()); objectFactory = OpenPGPImplementation.getInstance().pgpObjectFactory(compressedData.getDataStream());
} catch (PGPException e) { } catch (PGPException e) {
throw new SOPGPException.BadData("Cannot decompress compressed data", e); throw new SOPGPException.BadData("Cannot decompress compressed data", e);
} }

View file

@ -96,13 +96,13 @@ public class MatchMakingSecretKeyRingProtectorTest {
MatchMakingSecretKeyRingProtector protector = new MatchMakingSecretKeyRingProtector(); MatchMakingSecretKeyRingProtector protector = new MatchMakingSecretKeyRingProtector();
protector.addSecretKey(unprotectedKey); protector.addSecretKey(unprotectedKey);
assertTrue(protector.hasPassphraseFor(unprotectedKey.getPublicKey().getKeyID())); assertTrue(protector.hasPassphraseFor(unprotectedKey.getPublicKey().getKeyID()));
assertNull(protector.getEncryptor(unprotectedKey.getPublicKey().getKeyID())); assertNull(protector.getEncryptor(unprotectedKey.getPublicKey()));
assertNull(protector.getDecryptor(unprotectedKey.getPublicKey().getKeyID())); assertNull(protector.getDecryptor(unprotectedKey.getPublicKey().getKeyID()));
PGPSecretKeyRing protectedKey = PGPainless.readKeyRing().secretKeyRing(PROTECTED_KEY); PGPSecretKeyRing protectedKey = PGPainless.readKeyRing().secretKeyRing(PROTECTED_KEY);
protector.addSecretKey(protectedKey); protector.addSecretKey(protectedKey);
protector.addPassphrase(Passphrase.fromPassword(PASSWORD)); protector.addPassphrase(Passphrase.fromPassword(PASSWORD));
assertNotNull(protector.getEncryptor(protectedKey.getPublicKey().getKeyID())); assertNotNull(protector.getEncryptor(protectedKey.getPublicKey()));
assertNotNull(protector.getDecryptor(protectedKey.getPublicKey().getKeyID())); assertNotNull(protector.getDecryptor(protectedKey.getPublicKey().getKeyID()));
} }
} }