mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-25 04:17:59 +01:00
Progress
This commit is contained in:
parent
f611f54cad
commit
6416ef1e07
7 changed files with 108 additions and 80 deletions
|
@ -7,24 +7,28 @@ package org.pgpainless.algorithm
|
|||
class AlgorithmSuite(
|
||||
symmetricKeyAlgorithms: List<SymmetricKeyAlgorithm>,
|
||||
hashAlgorithms: List<HashAlgorithm>,
|
||||
compressionAlgorithms: List<CompressionAlgorithm>
|
||||
compressionAlgorithms: List<CompressionAlgorithm>,
|
||||
features: List<Feature>
|
||||
) {
|
||||
|
||||
val symmetricKeyAlgorithms: Set<SymmetricKeyAlgorithm> = symmetricKeyAlgorithms.toSet()
|
||||
val hashAlgorithms: Set<HashAlgorithm> = hashAlgorithms.toSet()
|
||||
val compressionAlgorithms: Set<CompressionAlgorithm> = compressionAlgorithms.toSet()
|
||||
val features: Set<Feature> = features.toSet()
|
||||
|
||||
companion object {
|
||||
|
||||
@JvmStatic
|
||||
val defaultSymmetricKeyAlgorithms =
|
||||
val v4SymmetricKeyAlgorithms =
|
||||
listOf(
|
||||
SymmetricKeyAlgorithm.AES_256,
|
||||
SymmetricKeyAlgorithm.AES_192,
|
||||
SymmetricKeyAlgorithm.AES_128)
|
||||
|
||||
@JvmStatic val defaultSymmetricKeyAlgorithms = v4SymmetricKeyAlgorithms
|
||||
|
||||
@JvmStatic
|
||||
val defaultHashAlgorithms =
|
||||
val v4HashAlgorithms =
|
||||
listOf(
|
||||
HashAlgorithm.SHA512,
|
||||
HashAlgorithm.SHA384,
|
||||
|
@ -32,7 +36,18 @@ class AlgorithmSuite(
|
|||
HashAlgorithm.SHA224)
|
||||
|
||||
@JvmStatic
|
||||
val defaultCompressionAlgorithms =
|
||||
val v6HashAlgorithms =
|
||||
listOf(
|
||||
HashAlgorithm.SHA3_512,
|
||||
HashAlgorithm.SHA3_256,
|
||||
HashAlgorithm.SHA512,
|
||||
HashAlgorithm.SHA384,
|
||||
HashAlgorithm.SHA256)
|
||||
|
||||
@JvmStatic val defaultHashAlgorithms = v4HashAlgorithms
|
||||
|
||||
@JvmStatic
|
||||
val v4CompressionAlgorithms =
|
||||
listOf(
|
||||
CompressionAlgorithm.ZLIB,
|
||||
CompressionAlgorithm.BZIP2,
|
||||
|
@ -40,8 +55,32 @@ class AlgorithmSuite(
|
|||
CompressionAlgorithm.UNCOMPRESSED)
|
||||
|
||||
@JvmStatic
|
||||
val defaultAlgorithmSuite =
|
||||
val v6CompressionAlgorithms =
|
||||
listOf(
|
||||
CompressionAlgorithm.ZLIB,
|
||||
CompressionAlgorithm.BZIP2,
|
||||
CompressionAlgorithm.ZIP,
|
||||
CompressionAlgorithm.UNCOMPRESSED)
|
||||
|
||||
@JvmStatic val defaultCompressionAlgorithms = v4CompressionAlgorithms
|
||||
|
||||
@JvmStatic val v4Features = listOf(Feature.MODIFICATION_DETECTION)
|
||||
|
||||
@JvmStatic
|
||||
val v6Features = listOf(Feature.MODIFICATION_DETECTION, Feature.MODIFICATION_DETECTION_2)
|
||||
|
||||
@JvmStatic val defaultFeatures = v4Features
|
||||
|
||||
@JvmStatic
|
||||
val v4AlgorithmSuite =
|
||||
AlgorithmSuite(
|
||||
defaultSymmetricKeyAlgorithms, defaultHashAlgorithms, defaultCompressionAlgorithms)
|
||||
v4SymmetricKeyAlgorithms, v4HashAlgorithms, v4CompressionAlgorithms, v4Features)
|
||||
|
||||
@JvmStatic
|
||||
val v6AlgorithmSuite =
|
||||
AlgorithmSuite(
|
||||
v4SymmetricKeyAlgorithms, v6HashAlgorithms, v6CompressionAlgorithms, v6Features)
|
||||
|
||||
@JvmStatic val defaultAlgorithmSuite = v4AlgorithmSuite
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ class BaseOpenPgpKeyBuilder {
|
|||
|
||||
internal abstract fun primaryKey(): BaseV4PrimaryKeyBuilder
|
||||
|
||||
// Note: The result is a *primary* key pair, so subkeys need adjustment (toPrimaryOrSubkey)
|
||||
private fun generateKeyPair(): PGPKeyPair {
|
||||
// Create raw Key Pair
|
||||
val keyPair =
|
||||
|
@ -54,14 +55,14 @@ class BaseOpenPgpKeyBuilder {
|
|||
// Form PGP Key Pair
|
||||
return ImplementationFactory.getInstance()
|
||||
.getPGPV4KeyPair(type.algorithm, keyPair, creationTime)
|
||||
.let { adjustKeyPacket(it) }
|
||||
.let { toPrimaryOrSubkey(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure, the PGP key packet is a subkey packet for subkeys, and a primary key packet
|
||||
* for primary keys.
|
||||
*/
|
||||
protected abstract fun adjustKeyPacket(keyPair: PGPKeyPair): PGPKeyPair
|
||||
protected abstract fun toPrimaryOrSubkey(keyPair: PGPKeyPair): PGPKeyPair
|
||||
}
|
||||
|
||||
class BaseV4PrimaryKeyBuilder(type: KeyType, creationTime: Date, policy: Policy) :
|
||||
|
@ -76,12 +77,16 @@ class BaseOpenPgpKeyBuilder {
|
|||
bindingTime: Date = creationTime,
|
||||
hashAlgorithm: HashAlgorithm =
|
||||
policy.certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm,
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback =
|
||||
SelfSignatureSubpackets.defaultCallback()
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback = SelfSignatureSubpackets.nop()
|
||||
) = apply {
|
||||
val sig =
|
||||
buildCertificationFor(
|
||||
userId, algorithmSuite, certificationType, bindingTime, hashAlgorithm, subpacketsCallback)
|
||||
userId,
|
||||
algorithmSuite,
|
||||
certificationType,
|
||||
bindingTime,
|
||||
hashAlgorithm,
|
||||
subpacketsCallback)
|
||||
key =
|
||||
PGPKeyPair(
|
||||
PGPPublicKey.addCertification(key.publicKey, userId.toString(), sig),
|
||||
|
@ -116,8 +121,7 @@ class BaseOpenPgpKeyBuilder {
|
|||
bindingTime: Date = creationTime,
|
||||
hashAlgorithm: HashAlgorithm =
|
||||
policy.certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm,
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback =
|
||||
SelfSignatureSubpackets.defaultCallback()
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback = SelfSignatureSubpackets.nop()
|
||||
) = apply {
|
||||
val sig =
|
||||
buildCertificationFor(
|
||||
|
@ -159,10 +163,11 @@ class BaseOpenPgpKeyBuilder {
|
|||
algorithmSuite: AlgorithmSuite = policy.keyGenerationAlgorithmSuite,
|
||||
hashAlgorithm: HashAlgorithm =
|
||||
policy.certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm(),
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback =
|
||||
SelfSignatureSubpackets.defaultCallback()
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback = SelfSignatureSubpackets.nop()
|
||||
) = apply {
|
||||
val sig = buildDirectKeySignature(bindingTime, algorithmSuite, hashAlgorithm, subpacketsCallback)
|
||||
val sig =
|
||||
buildDirectKeySignature(
|
||||
bindingTime, algorithmSuite, hashAlgorithm, subpacketsCallback)
|
||||
key = PGPKeyPair(PGPPublicKey.addCertification(key.publicKey, sig), key.privateKey)
|
||||
}
|
||||
|
||||
|
@ -187,7 +192,9 @@ class BaseOpenPgpKeyBuilder {
|
|||
return builder.build()
|
||||
}
|
||||
|
||||
override fun adjustKeyPacket(keyPair: PGPKeyPair): PGPKeyPair {
|
||||
override fun toPrimaryOrSubkey(keyPair: PGPKeyPair) = toPrimaryKey(keyPair)
|
||||
|
||||
private fun toPrimaryKey(keyPair: PGPKeyPair): PGPKeyPair {
|
||||
return keyPair // is already a secret key packet
|
||||
}
|
||||
|
||||
|
@ -205,8 +212,7 @@ class BaseOpenPgpKeyBuilder {
|
|||
bindingTime: Date = creationTime,
|
||||
hashAlgorithm: HashAlgorithm =
|
||||
policy.certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm,
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback =
|
||||
SelfSignatureSubpackets.defaultCallback()
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback = SelfSignatureSubpackets.nop()
|
||||
) = apply {
|
||||
val sig = buildBindingSignature(bindingTime, hashAlgorithm, subpacketsCallback)
|
||||
key = PGPKeyPair(PGPPublicKey.addCertification(key.publicKey, sig), key.privateKey)
|
||||
|
@ -216,8 +222,7 @@ class BaseOpenPgpKeyBuilder {
|
|||
bindingTime: Date = creationTime,
|
||||
hashAlgorithm: HashAlgorithm =
|
||||
policy.certificationSignatureHashAlgorithmPolicy.defaultHashAlgorithm,
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback =
|
||||
SelfSignatureSubpackets.defaultCallback()
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback = SelfSignatureSubpackets.nop()
|
||||
): PGPSignature {
|
||||
val builder =
|
||||
SubkeyBindingSignatureBuilder(
|
||||
|
@ -245,7 +250,9 @@ class BaseOpenPgpKeyBuilder {
|
|||
return builder.build(key.publicKey)
|
||||
}
|
||||
|
||||
override fun adjustKeyPacket(keyPair: PGPKeyPair): PGPKeyPair {
|
||||
override fun toPrimaryOrSubkey(keyPair: PGPKeyPair) = toSubkey(keyPair)
|
||||
|
||||
private fun toSubkey(keyPair: PGPKeyPair): PGPKeyPair {
|
||||
val fpCalc = ImplementationFactory.getInstance().keyFingerprintCalculator
|
||||
val pubkey = keyPair.publicKey
|
||||
val privkey = keyPair.privateKey
|
||||
|
|
|
@ -43,16 +43,19 @@ open class OpenPgpKeyBuilder(
|
|||
fun addUserId(
|
||||
userId: CharSequence,
|
||||
algorithmSuite: AlgorithmSuite = keyGenerationPolicy,
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback =
|
||||
SelfSignatureSubpackets.defaultCallback()
|
||||
) = apply { primaryKey.userId(userId, algorithmSuite, subpacketsCallback = subpacketsCallback) }
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback = SelfSignatureSubpackets.nop()
|
||||
) = apply {
|
||||
primaryKey.userId(userId, algorithmSuite, subpacketsCallback = subpacketsCallback)
|
||||
}
|
||||
|
||||
fun addUserAttribute(
|
||||
attribute: PGPUserAttributeSubpacketVector,
|
||||
algorithmSuite: AlgorithmSuite = keyGenerationPolicy,
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback =
|
||||
SelfSignatureSubpackets.defaultCallback()
|
||||
) = apply { primaryKey.userAttribute(attribute, algorithmSuite, subpacketsCallback = subpacketsCallback) }
|
||||
subpacketsCallback: SelfSignatureSubpackets.Callback = SelfSignatureSubpackets.nop()
|
||||
) = apply {
|
||||
primaryKey.userAttribute(
|
||||
attribute, algorithmSuite, subpacketsCallback = subpacketsCallback)
|
||||
}
|
||||
|
||||
fun addSubkey(
|
||||
keyType: KeyType,
|
||||
|
@ -112,7 +115,8 @@ open class OpenPgpKeyBuilder(
|
|||
|
||||
// Add DK sig in case of no user-id
|
||||
if (primaryKey.isWithoutUserIds()) {
|
||||
primaryKey.directKeySignature()
|
||||
primaryKey.directKeySignature(
|
||||
subpacketsCallback = defaultPrimarySubpacketsCallback())
|
||||
}
|
||||
|
||||
return PGPSecretKeyRing(
|
||||
|
@ -139,7 +143,8 @@ open class OpenPgpKeyBuilder(
|
|||
override fun modifyHashedSubpackets(hashedSubpackets: SelfSignatureSubpackets) {
|
||||
hashedSubpackets.apply {
|
||||
setPreferredHashAlgorithms(keyGenerationPolicy.hashAlgorithms)
|
||||
setPreferredSymmetricKeyAlgorithms(keyGenerationPolicy.symmetricKeyAlgorithms)
|
||||
setPreferredSymmetricKeyAlgorithms(
|
||||
keyGenerationPolicy.symmetricKeyAlgorithms)
|
||||
setPreferredCompressionAlgorithms(keyGenerationPolicy.compressionAlgorithms)
|
||||
setKeyFlags(KeyFlag.CERTIFY_OTHER)
|
||||
}
|
||||
|
|
|
@ -10,26 +10,22 @@ import org.pgpainless.util.DateUtil
|
|||
import org.pgpainless.util.NotationRegistry
|
||||
|
||||
class Policy(
|
||||
var certificationSignatureHashAlgorithmPolicy: HashAlgorithmPolicy,
|
||||
var revocationSignatureHashAlgorithmPolicy: HashAlgorithmPolicy,
|
||||
var dataSignatureHashAlgorithmPolicy: HashAlgorithmPolicy,
|
||||
var symmetricKeyEncryptionAlgorithmPolicy: SymmetricKeyAlgorithmPolicy,
|
||||
var symmetricKeyDecryptionAlgorithmPolicy: SymmetricKeyAlgorithmPolicy,
|
||||
var compressionAlgorithmPolicy: CompressionAlgorithmPolicy,
|
||||
var publicKeyAlgorithmPolicy: PublicKeyAlgorithmPolicy,
|
||||
var notationRegistry: NotationRegistry
|
||||
) {
|
||||
|
||||
constructor() :
|
||||
this(
|
||||
HashAlgorithmPolicy.smartCertificationSignatureHashAlgorithmPolicy(),
|
||||
var certificationSignatureHashAlgorithmPolicy: HashAlgorithmPolicy =
|
||||
HashAlgorithmPolicy.smartCertificationSignatureHashAlgorithmPolicy(),
|
||||
var revocationSignatureHashAlgorithmPolicy: HashAlgorithmPolicy =
|
||||
certificationSignatureHashAlgorithmPolicy,
|
||||
var dataSignatureHashAlgorithmPolicy: HashAlgorithmPolicy =
|
||||
HashAlgorithmPolicy.smartDataSignatureHashAlgorithmPolicy(),
|
||||
var symmetricKeyEncryptionAlgorithmPolicy: SymmetricKeyAlgorithmPolicy =
|
||||
SymmetricKeyAlgorithmPolicy.symmetricKeyEncryptionPolicy2022(),
|
||||
SymmetricKeyAlgorithmPolicy.symmetricKeyDecryptionPolicy2022(),
|
||||
var symmetricKeyDecryptionAlgorithmPolicy: SymmetricKeyAlgorithmPolicy =
|
||||
symmetricKeyEncryptionAlgorithmPolicy,
|
||||
var compressionAlgorithmPolicy: CompressionAlgorithmPolicy =
|
||||
CompressionAlgorithmPolicy.anyCompressionAlgorithmPolicy(),
|
||||
var publicKeyAlgorithmPolicy: PublicKeyAlgorithmPolicy =
|
||||
PublicKeyAlgorithmPolicy.bsi2021PublicKeyAlgorithmPolicy(),
|
||||
NotationRegistry())
|
||||
var notationRegistry: NotationRegistry = NotationRegistry()
|
||||
) {
|
||||
|
||||
var keyGenerationAlgorithmSuite = AlgorithmSuite.defaultAlgorithmSuite
|
||||
var signerUserIdValidationLevel = SignerUserIdValidationLevel.DISABLED
|
||||
|
|
|
@ -217,7 +217,5 @@ interface SelfSignatureSubpackets : BaseSignatureSubpackets {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic fun defaultCallback() = object : Callback {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,24 +23,4 @@ interface SignatureSubpacketCallback<S : BaseSignatureSubpackets> {
|
|||
fun modifyUnhashedSubpackets(unhashedSubpackets: S) {
|
||||
// Empty default implementation to allow for cleaner overriding
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new [SignatureSubpacketCallback] which first applies the current callback instance,
|
||||
* followed by the passed in [nextCallback].
|
||||
* This is useful to composite different [SignatureSubpacketCallback] instances.
|
||||
*/
|
||||
fun then(nextCallback: SignatureSubpacketCallback<S>): SignatureSubpacketCallback<S> {
|
||||
val currCallback = this
|
||||
return object : SignatureSubpacketCallback<S> {
|
||||
override fun modifyHashedSubpackets(hashedSubpackets: S) {
|
||||
currCallback.modifyHashedSubpackets(hashedSubpackets)
|
||||
nextCallback.modifyHashedSubpackets(hashedSubpackets)
|
||||
}
|
||||
|
||||
override fun modifyUnhashedSubpackets(unhashedSubpackets: S) {
|
||||
currCallback.modifyUnhashedSubpackets(unhashedSubpackets)
|
||||
nextCallback.modifyUnhashedSubpackets(unhashedSubpackets)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@ class OpenPgpKeyBuilderTest {
|
|||
@Test
|
||||
fun test() {
|
||||
val date = DateUtil.parseUTCDate("2020-04-01 10:00:00 UTC")
|
||||
val key = OpenPgpKeyBuilder(Policy.getInstance(), date)
|
||||
val key =
|
||||
OpenPgpKeyBuilder(Policy.getInstance(), date)
|
||||
.buildV4Key(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.addUserId("Alice")
|
||||
.addUserAttribute(
|
||||
|
@ -31,7 +32,8 @@ class OpenPgpKeyBuilderTest {
|
|||
|
||||
@Test
|
||||
fun minimal() {
|
||||
val key = OpenPgpKeyBuilder(Policy.getInstance())
|
||||
val key =
|
||||
OpenPgpKeyBuilder(Policy.getInstance())
|
||||
.buildV4Key(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.build()
|
||||
println(PGPainless.asciiArmor(key))
|
||||
|
@ -39,7 +41,8 @@ class OpenPgpKeyBuilderTest {
|
|||
|
||||
@Test
|
||||
fun minimalWithUserId() {
|
||||
val key = OpenPgpKeyBuilder(Policy.getInstance())
|
||||
val key =
|
||||
OpenPgpKeyBuilder(Policy.getInstance())
|
||||
.buildV4Key(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
.addUserId("Alice <alice@pgpainless.org>")
|
||||
.build()
|
||||
|
|
Loading…
Reference in a new issue