mirror of
https://github.com/pgpainless/pgpainless.git
synced 2025-12-08 21:31:08 +01:00
Remove ImplementationFactory in favor of BCs OpenPGPImplementation
This commit is contained in:
parent
3834f354d6
commit
32afabf878
48 changed files with 303 additions and 550 deletions
|
|
@ -7,7 +7,7 @@ package org.pgpainless.decryption_verification
|
|||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import org.bouncycastle.openpgp.*
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.pgpainless.util.ArmorUtils
|
||||
|
||||
/**
|
||||
|
|
@ -68,7 +68,7 @@ class MessageInspector {
|
|||
@JvmStatic
|
||||
@Throws(PGPException::class, IOException::class)
|
||||
private fun processMessage(inputStream: InputStream): EncryptionInfo {
|
||||
var objectFactory = ImplementationFactory.getInstance().getPGPObjectFactory(inputStream)
|
||||
var objectFactory = OpenPGPImplementation.getInstance().pgpObjectFactory(inputStream)
|
||||
|
||||
var n: Any?
|
||||
while (objectFactory.nextObject().also { n = it } != null) {
|
||||
|
|
@ -94,8 +94,8 @@ class MessageInspector {
|
|||
}
|
||||
is PGPCompressedData -> {
|
||||
objectFactory =
|
||||
ImplementationFactory.getInstance()
|
||||
.getPGPObjectFactory(PGPUtil.getDecoderStream(next.dataStream))
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pgpObjectFactory(PGPUtil.getDecoderStream(next.dataStream))
|
||||
continue
|
||||
}
|
||||
is PGPLiteralData -> {
|
||||
|
|
|
|||
|
|
@ -23,8 +23,10 @@ import org.bouncycastle.openpgp.PGPOnePassSignature
|
|||
import org.bouncycastle.openpgp.PGPPBEEncryptedData
|
||||
import org.bouncycastle.openpgp.PGPPublicKey
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData
|
||||
import org.bouncycastle.openpgp.PGPSessionKey
|
||||
import org.bouncycastle.openpgp.PGPSignature
|
||||
import org.bouncycastle.openpgp.api.OpenPGPCertificate
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.bouncycastle.openpgp.api.OpenPGPKey
|
||||
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPPrivateKey
|
||||
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.UnacceptableAlgorithmException
|
||||
import org.pgpainless.exception.WrongPassphraseException
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.pgpainless.key.SubkeyIdentifier
|
||||
import org.pgpainless.key.protection.UnlockSecretKey.Companion.unlockSecretKey
|
||||
import org.pgpainless.policy.Policy
|
||||
|
|
@ -360,8 +361,9 @@ class OpenPgpMessageInputStream(
|
|||
LOGGER.debug("Attempt decryption with provided session key.")
|
||||
throwIfUnacceptable(sk.algorithm)
|
||||
|
||||
val pgpSk = PGPSessionKey(sk.algorithm.algorithmId, sk.key)
|
||||
val decryptorFactory =
|
||||
ImplementationFactory.getInstance().getSessionKeyDataDecryptorFactory(sk)
|
||||
OpenPGPImplementation.getInstance().sessionKeyDataDecryptorFactory(pgpSk)
|
||||
val layer = EncryptedData(sk.algorithm, layerMetadata.depth + 1)
|
||||
val skEncData = encDataList.extractSessionKeyEncryptedData()
|
||||
try {
|
||||
|
|
@ -393,7 +395,8 @@ class OpenPgpMessageInputStream(
|
|||
}
|
||||
|
||||
val decryptorFactory =
|
||||
ImplementationFactory.getInstance().getPBEDataDecryptorFactory(passphrase)
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pbeDataDecryptorFactory(passphrase.getChars())
|
||||
if (decryptSKESKAndStream(esks, skesk, decryptorFactory)) {
|
||||
return true
|
||||
}
|
||||
|
|
@ -515,8 +518,7 @@ class OpenPgpMessageInputStream(
|
|||
pkesk: PGPPublicKeyEncryptedData
|
||||
): Boolean {
|
||||
val decryptorFactory =
|
||||
ImplementationFactory.getInstance()
|
||||
.getPublicKeyDataDecryptorFactory(privateKey.privateKey)
|
||||
OpenPGPImplementation.getInstance().publicKeyDataDecryptorFactory(privateKey.privateKey)
|
||||
return decryptPKESKAndStream(esks, decryptionKeyId, decryptorFactory, pkesk)
|
||||
}
|
||||
|
||||
|
|
@ -1046,7 +1048,7 @@ class OpenPgpMessageInputStream(
|
|||
@JvmStatic
|
||||
private fun initialize(signature: PGPSignature, publicKey: PGPPublicKey) {
|
||||
val verifierProvider =
|
||||
ImplementationFactory.getInstance().pgpContentVerifierBuilderProvider
|
||||
OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider()
|
||||
try {
|
||||
signature.init(verifierProvider, publicKey)
|
||||
} catch (e: PGPException) {
|
||||
|
|
@ -1057,7 +1059,7 @@ class OpenPgpMessageInputStream(
|
|||
@JvmStatic
|
||||
private fun initialize(ops: PGPOnePassSignature, publicKey: PGPPublicKey) {
|
||||
val verifierProvider =
|
||||
ImplementationFactory.getInstance().pgpContentVerifierBuilderProvider
|
||||
OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider()
|
||||
try {
|
||||
ops.init(verifierProvider, publicKey)
|
||||
} catch (e: PGPException) {
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ import java.io.*
|
|||
import kotlin.jvm.Throws
|
||||
import org.bouncycastle.bcpg.ArmoredInputStream
|
||||
import org.bouncycastle.openpgp.PGPSignatureList
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.bouncycastle.util.Strings
|
||||
import org.pgpainless.exception.WrongConsumingMethodException
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
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())
|
||||
return next as PGPSignatureList
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import java.util.*
|
|||
import org.bouncycastle.openpgp.PGPPublicKeyRing
|
||||
import org.bouncycastle.openpgp.api.OpenPGPCertificate
|
||||
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.bouncycastle.openpgp.operator.PGPKeyEncryptionMethodGenerator
|
||||
import org.pgpainless.PGPainless.Companion.inspectKeyRing
|
||||
import org.pgpainless.algorithm.EncryptionPurpose
|
||||
|
|
@ -16,7 +17,6 @@ import org.pgpainless.authentication.CertificateAuthority
|
|||
import org.pgpainless.bouncycastle.extensions.toOpenPGPCertificate
|
||||
import org.pgpainless.encryption_signing.EncryptionOptions.EncryptionKeySelector
|
||||
import org.pgpainless.exception.KeyException.*
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.pgpainless.key.SubkeyIdentifier
|
||||
import org.pgpainless.key.info.KeyAccessor
|
||||
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)
|
||||
_encryptionKeyIdentifiers.add(SubkeyIdentifier(key))
|
||||
addEncryptionMethod(
|
||||
ImplementationFactory.getInstance()
|
||||
.getPublicKeyKeyEncryptionMethodGenerator(key.pgpPublicKey)
|
||||
.also { it.setUseWildcardKeyID(wildcardKeyId) })
|
||||
OpenPGPImplementation.getInstance()
|
||||
.publicKeyKeyEncryptionMethodGenerator(key.pgpPublicKey)
|
||||
.also { it.setUseWildcardRecipient(wildcardRecipient) })
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -355,7 +355,8 @@ class EncryptionOptions(private val purpose: EncryptionPurpose) {
|
|||
fun addMessagePassphrase(passphrase: Passphrase) = apply {
|
||||
require(!passphrase.isEmpty) { "Passphrase MUST NOT be empty." }
|
||||
addEncryptionMethod(
|
||||
ImplementationFactory.getInstance().getPBEKeyEncryptionMethodGenerator(passphrase))
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pbeKeyEncryptionMethodGenerator(passphrase.getChars()))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ import org.bouncycastle.openpgp.PGPCompressedDataGenerator
|
|||
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator
|
||||
import org.bouncycastle.openpgp.PGPException
|
||||
import org.bouncycastle.openpgp.PGPLiteralDataGenerator
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.pgpainless.algorithm.CompressionAlgorithm
|
||||
import org.pgpainless.algorithm.StreamEncoding
|
||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.pgpainless.key.SubkeyIdentifier
|
||||
import org.pgpainless.util.ArmoredOutputStreamFactory
|
||||
import org.slf4j.LoggerFactory
|
||||
|
|
@ -89,9 +89,9 @@ class EncryptionStream(
|
|||
LOGGER.debug("Encrypt message using symmetric algorithm $it.")
|
||||
val encryptedDataGenerator =
|
||||
PGPEncryptedDataGenerator(
|
||||
ImplementationFactory.getInstance().getPGPDataEncryptorBuilder(it).apply {
|
||||
setWithIntegrityPacket(true)
|
||||
})
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pgpDataEncryptorBuilder(it.algorithmId)
|
||||
.apply { setWithIntegrityPacket(true) })
|
||||
options.encryptionOptions.encryptionMethods.forEach { m ->
|
||||
encryptedDataGenerator.addMethod(m)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ package org.pgpainless.encryption_signing
|
|||
import java.util.*
|
||||
import org.bouncycastle.bcpg.KeyIdentifier
|
||||
import org.bouncycastle.openpgp.*
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.bouncycastle.openpgp.api.OpenPGPKey
|
||||
import org.bouncycastle.openpgp.api.OpenPGPKey.OpenPGPPrivateKey
|
||||
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.exception.KeyException
|
||||
import org.pgpainless.exception.KeyException.*
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.pgpainless.key.OpenPgpFingerprint.Companion.of
|
||||
import org.pgpainless.key.protection.SecretKeyRingProtector
|
||||
import org.pgpainless.key.protection.UnlockSecretKey.Companion.unlockSecretKey
|
||||
|
|
@ -495,8 +495,8 @@ class SigningOptions {
|
|||
hashAlgorithm: HashAlgorithm,
|
||||
signatureType: DocumentSignatureType
|
||||
): PGPSignatureGenerator {
|
||||
return ImplementationFactory.getInstance()
|
||||
.getPGPContentSignerBuilder(signingKey.publicKey.algorithm, hashAlgorithm.algorithmId)
|
||||
return OpenPGPImplementation.getInstance()
|
||||
.pgpContentSignerBuilder(signingKey.publicKey.algorithm, hashAlgorithm.algorithmId)
|
||||
.let { csb ->
|
||||
PGPSignatureGenerator(csb, signingKey.publicKey).also {
|
||||
it.init(signatureType.signatureType.code, signingKey.privateKey)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ package org.pgpainless.key.collection
|
|||
|
||||
import java.io.InputStream
|
||||
import org.bouncycastle.openpgp.*
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.pgpainless.util.ArmorUtils
|
||||
|
||||
/**
|
||||
|
|
@ -55,8 +55,8 @@ class PGPKeyRingCollection(
|
|||
val certificates = mutableListOf<PGPPublicKeyRing>()
|
||||
// Double getDecoderStream because of #96
|
||||
val objectFactory =
|
||||
ImplementationFactory.getInstance()
|
||||
.getPGPObjectFactory(ArmorUtils.getDecoderStream(inputStream))
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pgpObjectFactory(ArmorUtils.getDecoderStream(inputStream))
|
||||
|
||||
for (obj in objectFactory) {
|
||||
if (obj == null) {
|
||||
|
|
|
|||
|
|
@ -6,20 +6,19 @@ package org.pgpainless.key.generation
|
|||
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import org.bouncycastle.bcpg.HashAlgorithmTags
|
||||
import org.bouncycastle.openpgp.*
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.bouncycastle.openpgp.api.OpenPGPKey
|
||||
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor
|
||||
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor
|
||||
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder
|
||||
import org.bouncycastle.openpgp.operator.PGPDigestCalculator
|
||||
import org.bouncycastle.util.Strings
|
||||
import org.pgpainless.PGPainless
|
||||
import org.pgpainless.algorithm.KeyFlag
|
||||
import org.pgpainless.algorithm.OpenPGPKeyVersion
|
||||
import org.pgpainless.algorithm.SignatureType
|
||||
import org.pgpainless.bouncycastle.extensions.unlock
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.pgpainless.policy.Policy
|
||||
import org.pgpainless.signature.subpackets.SelfSignatureSubpackets
|
||||
import org.pgpainless.signature.subpackets.SignatureSubpackets
|
||||
|
|
@ -84,15 +83,20 @@ class KeyRingBuilder(
|
|||
private fun keyIsCertificationCapable(keySpec: KeySpec) = keySpec.keyType.canCertify
|
||||
|
||||
override fun build(): OpenPGPKey {
|
||||
val keyFingerprintCalculator = ImplementationFactory.getInstance().v4FingerprintCalculator
|
||||
val secretKeyEncryptor = buildSecretKeyEncryptor(keyFingerprintCalculator)
|
||||
val secretKeyDecryptor = buildSecretKeyDecryptor()
|
||||
|
||||
passphrase.clear() // Passphrase was used above, so we can get rid of it
|
||||
val keyFingerprintCalculator =
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pgpDigestCalculatorProvider()
|
||||
.get(HashAlgorithmTags.SHA1)
|
||||
|
||||
// generate primary key
|
||||
requireNotNull(primaryKeySpec) { "Primary Key spec required." }
|
||||
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 signatureGenerator = PGPSignatureGenerator(signer, certKey.publicKey)
|
||||
|
||||
|
|
@ -220,29 +224,30 @@ class KeyRingBuilder(
|
|||
private fun buildContentSigner(certKey: PGPKeyPair): PGPContentSignerBuilder {
|
||||
val hashAlgorithm =
|
||||
PGPainless.getPolicy().certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm
|
||||
return ImplementationFactory.getInstance()
|
||||
.getPGPContentSignerBuilder(certKey.publicKey.algorithm, hashAlgorithm.algorithmId)
|
||||
return OpenPGPImplementation.getInstance()
|
||||
.pgpContentSignerBuilder(certKey.publicKey.algorithm, hashAlgorithm.algorithmId)
|
||||
}
|
||||
|
||||
private fun buildSecretKeyEncryptor(
|
||||
keyFingerprintCalculator: PGPDigestCalculator
|
||||
publicKey: PGPPublicKey,
|
||||
aead: Boolean
|
||||
): PBESecretKeyEncryptor? {
|
||||
val keyEncryptionAlgorithm =
|
||||
PGPainless.getPolicy()
|
||||
.symmetricKeyEncryptionAlgorithmPolicy
|
||||
.defaultSymmetricKeyAlgorithm
|
||||
check(passphrase.isValid) { "Passphrase was cleared." }
|
||||
return if (passphrase.isEmpty) null
|
||||
else
|
||||
ImplementationFactory.getInstance()
|
||||
.getPBESecretKeyEncryptor(
|
||||
keyEncryptionAlgorithm, keyFingerprintCalculator, passphrase)
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pbeSecretKeyEncryptorFactory(aead)
|
||||
.build(passphrase.getChars(), publicKey.publicKeyPacket)
|
||||
}
|
||||
|
||||
private fun buildSecretKeyDecryptor(): PBESecretKeyDecryptor? {
|
||||
check(passphrase.isValid) { "Passphrase was cleared." }
|
||||
return if (passphrase.isEmpty) null
|
||||
else ImplementationFactory.getInstance().getPBESecretKeyDecryptor(passphrase)
|
||||
else
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pbeSecretKeyDecryptorBuilderProvider()
|
||||
.provide()
|
||||
.build(passphrase.getChars())
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -9,10 +9,12 @@ import java.util.function.Predicate
|
|||
import javax.annotation.Nonnull
|
||||
import kotlin.NoSuchElementException
|
||||
import openpgp.openPgpKeyId
|
||||
import org.bouncycastle.bcpg.HashAlgorithmTags
|
||||
import org.bouncycastle.bcpg.KeyIdentifier
|
||||
import org.bouncycastle.bcpg.sig.KeyExpirationTime
|
||||
import org.bouncycastle.openpgp.*
|
||||
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.OpenPGPSecretKey
|
||||
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.publicKeyAlgorithm
|
||||
import org.pgpainless.bouncycastle.extensions.requirePublicKey
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.pgpainless.key.OpenPgpFingerprint
|
||||
import org.pgpainless.key.generation.KeyRingBuilder
|
||||
import org.pgpainless.key.generation.KeySpec
|
||||
|
|
@ -302,9 +303,11 @@ class SecretKeyRingEditor(var key: OpenPGPKey, override val referenceTime: Date
|
|||
PGPSecretKey(
|
||||
subkey.privateKey,
|
||||
subkey.publicKey,
|
||||
ImplementationFactory.getInstance().v4FingerprintCalculator,
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pgpDigestCalculatorProvider()
|
||||
.get(HashAlgorithmTags.SHA1),
|
||||
false,
|
||||
subkeyProtector.getEncryptor(subkey.keyID))
|
||||
subkeyProtector.getEncryptor(subkey.publicKey))
|
||||
|
||||
val componentKey =
|
||||
OpenPGPSecretKey(
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ import java.io.InputStream
|
|||
import java.nio.charset.Charset
|
||||
import kotlin.jvm.Throws
|
||||
import org.bouncycastle.openpgp.*
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.bouncycastle.util.io.Streams
|
||||
import org.pgpainless.PGPainless
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.pgpainless.key.collection.PGPKeyRingCollection
|
||||
import org.pgpainless.util.ArmorUtils
|
||||
|
||||
|
|
@ -130,8 +130,8 @@ class KeyRingReader {
|
|||
maxIterations: Int = MAX_ITERATIONS
|
||||
): PGPKeyRing? {
|
||||
val objectFactory =
|
||||
ImplementationFactory.getInstance()
|
||||
.getPGPObjectFactory(ArmorUtils.getDecoderStream(inputStream))
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pgpObjectFactory(ArmorUtils.getDecoderStream(inputStream))
|
||||
|
||||
try {
|
||||
for ((i, next) in objectFactory.withIndex()) {
|
||||
|
|
@ -172,8 +172,8 @@ class KeyRingReader {
|
|||
maxIterations: Int = MAX_ITERATIONS
|
||||
): PGPPublicKeyRing? {
|
||||
val objectFactory =
|
||||
ImplementationFactory.getInstance()
|
||||
.getPGPObjectFactory(ArmorUtils.getDecoderStream(inputStream))
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pgpObjectFactory(ArmorUtils.getDecoderStream(inputStream))
|
||||
|
||||
try {
|
||||
for ((i, next) in objectFactory.withIndex()) {
|
||||
|
|
@ -213,8 +213,8 @@ class KeyRingReader {
|
|||
maxIterations: Int = MAX_ITERATIONS
|
||||
): PGPPublicKeyRingCollection {
|
||||
val objectFactory =
|
||||
ImplementationFactory.getInstance()
|
||||
.getPGPObjectFactory(ArmorUtils.getDecoderStream(inputStream))
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pgpObjectFactory(ArmorUtils.getDecoderStream(inputStream))
|
||||
val certificates = mutableListOf<PGPPublicKeyRing>()
|
||||
try {
|
||||
for ((i, next) in objectFactory.withIndex()) {
|
||||
|
|
@ -260,8 +260,7 @@ class KeyRingReader {
|
|||
maxIterations: Int = MAX_ITERATIONS
|
||||
): PGPSecretKeyRing? {
|
||||
val decoderStream = ArmorUtils.getDecoderStream(inputStream)
|
||||
val objectFactory =
|
||||
ImplementationFactory.getInstance().getPGPObjectFactory(decoderStream)
|
||||
val objectFactory = OpenPGPImplementation.getInstance().pgpObjectFactory(decoderStream)
|
||||
|
||||
try {
|
||||
for ((i, next) in objectFactory.withIndex()) {
|
||||
|
|
@ -300,8 +299,8 @@ class KeyRingReader {
|
|||
maxIterations: Int = MAX_ITERATIONS
|
||||
): PGPSecretKeyRingCollection {
|
||||
val objectFactory =
|
||||
ImplementationFactory.getInstance()
|
||||
.getPGPObjectFactory(ArmorUtils.getDecoderStream(inputStream))
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pgpObjectFactory(ArmorUtils.getDecoderStream(inputStream))
|
||||
|
||||
val secretKeys = mutableListOf<PGPSecretKeyRing>()
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@
|
|||
package org.pgpainless.key.protection
|
||||
|
||||
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.operator.PBESecretKeyDecryptor
|
||||
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.pgpainless.key.protection.passphrase_provider.SecretKeyPassphraseProvider
|
||||
|
||||
/**
|
||||
|
|
@ -34,19 +35,20 @@ open class BaseSecretKeyRingProtector(
|
|||
override fun getDecryptor(keyIdentifier: KeyIdentifier): PBESecretKeyDecryptor? =
|
||||
passphraseProvider.getPassphraseFor(keyIdentifier)?.let {
|
||||
if (it.isEmpty) null
|
||||
else ImplementationFactory.getInstance().getPBESecretKeyDecryptor(it)
|
||||
else
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pbeSecretKeyDecryptorBuilderProvider()
|
||||
.provide()
|
||||
.build(it.getChars())
|
||||
}
|
||||
|
||||
override fun getEncryptor(keyIdentifier: KeyIdentifier): PBESecretKeyEncryptor? {
|
||||
return passphraseProvider.getPassphraseFor(keyIdentifier)?.let {
|
||||
override fun getEncryptor(key: PGPPublicKey): PBESecretKeyEncryptor? {
|
||||
return passphraseProvider.getPassphraseFor(key.keyIdentifier)?.let {
|
||||
if (it.isEmpty) null
|
||||
else
|
||||
ImplementationFactory.getInstance()
|
||||
.getPBESecretKeyEncryptor(
|
||||
protectionSettings.encryptionAlgorithm,
|
||||
protectionSettings.hashAlgorithm,
|
||||
protectionSettings.s2kCount,
|
||||
it)
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pbeSecretKeyEncryptorFactory(false)
|
||||
.build(it.getChars(), key.publicKeyPacket)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -184,8 +184,8 @@ class CachingSecretKeyRingProtector : SecretKeyRingProtector, SecretKeyPassphras
|
|||
override fun getDecryptor(keyIdentifier: KeyIdentifier): PBESecretKeyDecryptor? =
|
||||
protector.getDecryptor(keyIdentifier)
|
||||
|
||||
override fun getEncryptor(keyIdentifier: KeyIdentifier): PBESecretKeyEncryptor? =
|
||||
protector.getEncryptor(keyIdentifier)
|
||||
override fun getEncryptor(key: PGPPublicKey): PBESecretKeyEncryptor? =
|
||||
protector.getEncryptor(key)
|
||||
|
||||
override fun getKeyPassword(p0: OpenPGPKey.OpenPGPSecretKey): CharArray? =
|
||||
getPassphraseFor(p0.keyIdentifier)?.getChars()
|
||||
|
|
|
|||
|
|
@ -7,9 +7,11 @@ package org.pgpainless.key.protection
|
|||
import kotlin.Throws
|
||||
import org.bouncycastle.bcpg.KeyIdentifier
|
||||
import org.bouncycastle.openpgp.PGPException
|
||||
import org.bouncycastle.openpgp.PGPPublicKey
|
||||
import org.bouncycastle.openpgp.PGPSecretKey
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing
|
||||
import org.bouncycastle.openpgp.api.KeyPassphraseProvider
|
||||
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey
|
||||
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor
|
||||
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor
|
||||
import org.pgpainless.key.protection.passphrase_provider.SecretKeyPassphraseProvider
|
||||
|
|
@ -32,8 +34,15 @@ interface SecretKeyRingProtector : KeyPassphraseProvider {
|
|||
* @param keyId key id
|
||||
* @return true if it has a passphrase, false otherwise
|
||||
*/
|
||||
@Deprecated("Pass in a KeyIdentifier instead.")
|
||||
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
|
||||
|
||||
/**
|
||||
|
|
@ -43,24 +52,37 @@ interface SecretKeyRingProtector : KeyPassphraseProvider {
|
|||
* @param keyId id of the key
|
||||
* @return decryptor for the key
|
||||
*/
|
||||
@Deprecated("Pass in a KeyIdentifier instead.")
|
||||
@Throws(PGPException::class)
|
||||
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)
|
||||
fun getDecryptor(keyIdentifier: KeyIdentifier): PBESecretKeyDecryptor?
|
||||
|
||||
/**
|
||||
* Return an encryptor for the key of id `keyId`. This method returns null if the key is
|
||||
* unprotected.
|
||||
* Return an encryptor for the given key.
|
||||
*
|
||||
* @param keyId id of the key
|
||||
* @return encryptor for the key
|
||||
* @param key component key
|
||||
* @return encryptor or null if the key shall not be encrypted
|
||||
*/
|
||||
@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 {
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
package org.pgpainless.key.protection
|
||||
|
||||
import org.bouncycastle.bcpg.KeyIdentifier
|
||||
import org.bouncycastle.openpgp.PGPPublicKey
|
||||
import org.bouncycastle.openpgp.api.OpenPGPKey
|
||||
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor
|
||||
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor
|
||||
|
|
@ -17,7 +18,7 @@ class UnprotectedKeysProtector : SecretKeyRingProtector {
|
|||
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,14 +4,15 @@
|
|||
|
||||
package org.pgpainless.key.protection.fixes
|
||||
|
||||
import org.bouncycastle.bcpg.HashAlgorithmTags
|
||||
import org.bouncycastle.bcpg.SecretKeyPacket
|
||||
import org.bouncycastle.openpgp.PGPSecretKey
|
||||
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.exception.WrongPassphraseException
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
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
|
||||
|
|
@ -48,7 +49,9 @@ class S2KUsageFix {
|
|||
skipKeysWithMissingPassphrase: Boolean = false
|
||||
): PGPSecretKeyRing {
|
||||
val digestCalculator =
|
||||
ImplementationFactory.getInstance().getPGPDigestCalculator(HashAlgorithm.SHA1)
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pgpDigestCalculatorProvider()
|
||||
.get(HashAlgorithmTags.SHA1)
|
||||
val keyList = mutableListOf<PGPSecretKey>()
|
||||
for (key in keys) {
|
||||
// CHECKSUM is not recommended
|
||||
|
|
@ -58,7 +61,7 @@ class S2KUsageFix {
|
|||
}
|
||||
|
||||
val keyId = key.keyID
|
||||
val encryptor = protector.getEncryptor(keyId)
|
||||
val encryptor = protector.getEncryptor(key.publicKey)
|
||||
if (encryptor == null) {
|
||||
if (skipKeysWithMissingPassphrase) {
|
||||
keyList.add(key)
|
||||
|
|
@ -76,7 +79,7 @@ class S2KUsageFix {
|
|||
key.publicKey,
|
||||
digestCalculator,
|
||||
key.isMasterKey,
|
||||
protector.getEncryptor(keyId))
|
||||
protector.getEncryptor(key.publicKey))
|
||||
keyList.add(fixedKey)
|
||||
}
|
||||
return PGPSecretKeyRing(keyList)
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ import org.bouncycastle.bcpg.KeyIdentifier
|
|||
import org.bouncycastle.bcpg.S2K
|
||||
import org.bouncycastle.bcpg.SecretKeyPacket
|
||||
import org.bouncycastle.openpgp.*
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.bouncycastle.util.Strings
|
||||
import org.pgpainless.bouncycastle.extensions.certificate
|
||||
import org.pgpainless.bouncycastle.extensions.requireSecretKey
|
||||
import org.pgpainless.exception.MissingPassphraseException
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.pgpainless.key.protection.SecretKeyRingProtector
|
||||
import org.pgpainless.key.protection.fixes.S2KUsageFix
|
||||
import org.slf4j.Logger
|
||||
|
|
@ -436,7 +436,7 @@ class KeyRingUtils {
|
|||
}
|
||||
secretKeys.extraPublicKeys.forEach { it.encode(out) }
|
||||
return PGPSecretKeyRing(
|
||||
out.toByteArray(), ImplementationFactory.getInstance().keyFingerprintCalculator)
|
||||
out.toByteArray(), OpenPGPImplementation.getInstance().keyFingerPrintCalculator())
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -450,7 +450,7 @@ class KeyRingUtils {
|
|||
fun getStrippedDownPublicKey(bloatedKey: PGPPublicKey): PGPPublicKey {
|
||||
return PGPPublicKey(
|
||||
bloatedKey.publicKeyPacket,
|
||||
ImplementationFactory.getInstance().keyFingerprintCalculator)
|
||||
OpenPGPImplementation.getInstance().keyFingerPrintCalculator())
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
|
@ -510,7 +510,7 @@ class KeyRingUtils {
|
|||
return PGPSecretKey.copyWithNewPassword(
|
||||
secretKey,
|
||||
oldProtector.getDecryptor(secretKey.keyID),
|
||||
newProtector.getEncryptor(secretKey.keyID))
|
||||
newProtector.getEncryptor(secretKey.publicKey))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
|||
|
|
@ -10,15 +10,12 @@ import java.math.BigInteger
|
|||
import java.security.SecureRandom
|
||||
import org.bouncycastle.bcpg.*
|
||||
import org.bouncycastle.openpgp.*
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.bouncycastle.util.Arrays
|
||||
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.SymmetricKeyAlgorithm
|
||||
import org.pgpainless.bouncycastle.extensions.publicKeyAlgorithm
|
||||
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
|
||||
|
|
@ -224,9 +221,9 @@ class PublicKeyParameterValidationUtil {
|
|||
val data = ByteArray(512).also { SecureRandom().nextBytes(it) }
|
||||
val signatureGenerator =
|
||||
PGPSignatureGenerator(
|
||||
getInstance()
|
||||
.getPGPContentSignerBuilder(
|
||||
requireFromId(publicKey.algorithm), HashAlgorithm.SHA256))
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pgpContentSignerBuilder(publicKey.algorithm, HashAlgorithmTags.SHA256),
|
||||
publicKey)
|
||||
return try {
|
||||
signatureGenerator
|
||||
.apply {
|
||||
|
|
@ -235,7 +232,9 @@ class PublicKeyParameterValidationUtil {
|
|||
}
|
||||
.generate()
|
||||
.apply {
|
||||
init(getInstance().pgpContentVerifierBuilderProvider, publicKey)
|
||||
init(
|
||||
OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
|
||||
publicKey)
|
||||
update(data)
|
||||
}
|
||||
.verify()
|
||||
|
|
@ -257,9 +256,12 @@ class PublicKeyParameterValidationUtil {
|
|||
val data = ByteArray(1024).also { SecureRandom().nextBytes(it) }
|
||||
val encryptedDataGenerator =
|
||||
PGPEncryptedDataGenerator(
|
||||
getInstance().getPGPDataEncryptorBuilder(SymmetricKeyAlgorithm.AES_256))
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pgpDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256))
|
||||
.apply {
|
||||
addMethod(getInstance().getPublicKeyKeyEncryptionMethodGenerator(publicKey))
|
||||
addMethod(
|
||||
OpenPGPImplementation.getInstance()
|
||||
.publicKeyKeyEncryptionMethodGenerator(publicKey))
|
||||
}
|
||||
|
||||
var out = ByteArrayOutputStream()
|
||||
|
|
@ -268,7 +270,8 @@ class PublicKeyParameterValidationUtil {
|
|||
outputStream.write(data)
|
||||
encryptedDataGenerator.close()
|
||||
val encryptedDataList = PGPEncryptedDataList(out.toByteArray())
|
||||
val decryptorFactory = getInstance().getPublicKeyDataDecryptorFactory(privateKey)
|
||||
val decryptorFactory =
|
||||
OpenPGPImplementation.getInstance().publicKeyDataDecryptorFactory(privateKey)
|
||||
val encryptedData =
|
||||
encryptedDataList.encryptedDataObjects.next() as PGPPublicKeyEncryptedData
|
||||
val decrypted = encryptedData.getDataStream(decryptorFactory)
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ import java.util.*
|
|||
import openpgp.plusSeconds
|
||||
import org.bouncycastle.bcpg.sig.KeyExpirationTime
|
||||
import org.bouncycastle.openpgp.*
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.bouncycastle.util.encoders.Hex
|
||||
import org.bouncycastle.util.io.Streams
|
||||
import org.pgpainless.bouncycastle.extensions.*
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.pgpainless.key.OpenPgpFingerprint
|
||||
import org.pgpainless.key.util.RevocationAttributes.Reason
|
||||
import org.pgpainless.util.ArmorUtils
|
||||
|
|
@ -153,7 +153,7 @@ class SignatureUtils {
|
|||
fun readSignatures(inputStream: InputStream, maxIterations: Int): List<PGPSignature> {
|
||||
val signatures = mutableListOf<PGPSignature>()
|
||||
val pgpIn = ArmorUtils.getDecoderStream(inputStream)
|
||||
val objectFactory = ImplementationFactory.getInstance().getPGPObjectFactory(pgpIn)
|
||||
val objectFactory = OpenPGPImplementation.getInstance().pgpObjectFactory(pgpIn)
|
||||
|
||||
var i = 0
|
||||
var nextObject: Any? = null
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ import org.bouncycastle.openpgp.PGPPublicKey
|
|||
import org.bouncycastle.openpgp.PGPSignature
|
||||
import org.bouncycastle.openpgp.PGPSignatureGenerator
|
||||
import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.bouncycastle.openpgp.api.OpenPGPKey
|
||||
import org.pgpainless.PGPainless
|
||||
import org.pgpainless.algorithm.HashAlgorithm
|
||||
import org.pgpainless.algorithm.SignatureType
|
||||
import org.pgpainless.algorithm.negotiation.HashAlgorithmNegotiator
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.pgpainless.key.protection.SecretKeyRingProtector
|
||||
import org.pgpainless.key.protection.UnlockSecretKey
|
||||
import org.pgpainless.key.util.OpenPgpKeyAttributeUtil
|
||||
|
|
@ -110,9 +110,10 @@ abstract class AbstractSignatureBuilder<B : AbstractSignatureBuilder<B>>(
|
|||
@Throws(PGPException::class)
|
||||
protected fun buildAndInitSignatureGenerator(): PGPSignatureGenerator =
|
||||
PGPSignatureGenerator(
|
||||
ImplementationFactory.getInstance()
|
||||
.getPGPContentSignerBuilder(
|
||||
signingKey.publicKey.pgpPublicKey.algorithm, hashAlgorithm.algorithmId))
|
||||
OpenPGPImplementation.getInstance()
|
||||
.pgpContentSignerBuilder(
|
||||
signingKey.keyPair.publicKey.algorithm, hashAlgorithm.algorithmId),
|
||||
signingKey.keyPair.publicKey)
|
||||
.apply {
|
||||
setUnhashedSubpackets(SignatureSubpacketsHelper.toVector(_unhashedSubpackets))
|
||||
setHashedSubpackets(SignatureSubpacketsHelper.toVector(_hashedSubpackets))
|
||||
|
|
|
|||
|
|
@ -12,17 +12,16 @@ import org.bouncycastle.openpgp.PGPException
|
|||
import org.bouncycastle.openpgp.PGPPublicKey
|
||||
import org.bouncycastle.openpgp.PGPSignature
|
||||
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.pgpainless.algorithm.KeyFlag
|
||||
import org.pgpainless.algorithm.SignatureSubpacket
|
||||
import org.pgpainless.algorithm.SignatureType
|
||||
import org.pgpainless.bouncycastle.extensions.fingerprint
|
||||
import org.pgpainless.bouncycastle.extensions.isHardRevocation
|
||||
import org.pgpainless.bouncycastle.extensions.isOfType
|
||||
import org.pgpainless.bouncycastle.extensions.publicKeyAlgorithm
|
||||
import org.pgpainless.bouncycastle.extensions.signatureExpirationDate
|
||||
import org.pgpainless.bouncycastle.extensions.signatureHashAlgorithm
|
||||
import org.pgpainless.exception.SignatureValidationException
|
||||
import org.pgpainless.implementation.ImplementationFactory
|
||||
import org.pgpainless.key.OpenPgpFingerprint
|
||||
import org.pgpainless.policy.Policy
|
||||
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil
|
||||
|
|
@ -486,7 +485,7 @@ abstract class SignatureValidator {
|
|||
}
|
||||
try {
|
||||
signature.init(
|
||||
ImplementationFactory.getInstance().pgpContentVerifierBuilderProvider,
|
||||
OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
|
||||
primaryKey)
|
||||
if (!signature.verifyCertification(primaryKey, subkey)) {
|
||||
throw SignatureValidationException("Signature is not correct.")
|
||||
|
|
@ -521,7 +520,7 @@ abstract class SignatureValidator {
|
|||
}
|
||||
try {
|
||||
signature.init(
|
||||
ImplementationFactory.getInstance().pgpContentVerifierBuilderProvider,
|
||||
OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
|
||||
subkey)
|
||||
if (!signature.verifyCertification(primaryKey, subkey)) {
|
||||
throw SignatureValidationException(
|
||||
|
|
@ -554,7 +553,7 @@ abstract class SignatureValidator {
|
|||
override fun verify(signature: PGPSignature) {
|
||||
try {
|
||||
signature.init(
|
||||
ImplementationFactory.getInstance().pgpContentVerifierBuilderProvider,
|
||||
OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
|
||||
signingKey)
|
||||
val valid =
|
||||
if (signingKey.keyID == signedKey.keyID ||
|
||||
|
|
@ -625,7 +624,7 @@ abstract class SignatureValidator {
|
|||
override fun verify(signature: PGPSignature) {
|
||||
try {
|
||||
signature.init(
|
||||
ImplementationFactory.getInstance().pgpContentVerifierBuilderProvider,
|
||||
OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
|
||||
certifyingKey)
|
||||
if (!signature.verifyCertification(userId.toString(), certifiedKey)) {
|
||||
throw SignatureValidationException(
|
||||
|
|
@ -660,7 +659,7 @@ abstract class SignatureValidator {
|
|||
override fun verify(signature: PGPSignature) {
|
||||
try {
|
||||
signature.init(
|
||||
ImplementationFactory.getInstance().pgpContentVerifierBuilderProvider,
|
||||
OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
|
||||
certifyingKey)
|
||||
if (!signature.verifyCertification(userAttributes, certifiedKey)) {
|
||||
throw SignatureValidationException(
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ import org.bouncycastle.openpgp.PGPException
|
|||
import org.bouncycastle.openpgp.PGPPublicKey
|
||||
import org.bouncycastle.openpgp.PGPSignature
|
||||
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector
|
||||
import org.bouncycastle.openpgp.api.OpenPGPImplementation
|
||||
import org.pgpainless.algorithm.SignatureType
|
||||
import org.pgpainless.exception.SignatureValidationException
|
||||
import org.pgpainless.implementation.ImplementationFactory.Companion.getInstance
|
||||
import org.pgpainless.policy.Policy
|
||||
import org.pgpainless.signature.consumer.SignatureValidator.Companion.correctSignatureOverKey
|
||||
import org.pgpainless.signature.consumer.SignatureValidator.Companion.correctSignatureOverUserAttributes
|
||||
|
|
@ -479,7 +479,7 @@ class SignatureVerifier {
|
|||
) {
|
||||
try {
|
||||
signature.init(
|
||||
getInstance().pgpContentVerifierBuilderProvider,
|
||||
OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
|
||||
signingKey,
|
||||
)
|
||||
var read: Int
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue