1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2024-11-14 00:12:06 +01:00

Add PGPKeyRingExtensions class and make use of it

This commit is contained in:
Paul Schaub 2023-09-06 16:49:28 +02:00
parent b621f8937e
commit 4d23607067
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
4 changed files with 36 additions and 28 deletions

View file

@ -0,0 +1,15 @@
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.bouncycastle.extensions
import org.bouncycastle.openpgp.PGPKeyRing
import org.pgpainless.key.SubkeyIdentifier
/**
* Return true, if this [PGPKeyRing] contains the subkey identified by the [SubkeyIdentifier].
*/
fun PGPKeyRing.matches(subkeyIdentifier: SubkeyIdentifier): Boolean =
this.publicKey.keyID == subkeyIdentifier.primaryKeyId &&
this.getPublicKey(subkeyIdentifier.subkeyId) != null

View file

@ -4,6 +4,7 @@
package org.pgpainless.decryption_verification package org.pgpainless.decryption_verification
import org.bouncycastle.extensions.matches
import org.bouncycastle.openpgp.PGPKeyRing import org.bouncycastle.openpgp.PGPKeyRing
import org.bouncycastle.openpgp.PGPLiteralData import org.bouncycastle.openpgp.PGPLiteralData
import org.pgpainless.algorithm.CompressionAlgorithm import org.pgpainless.algorithm.CompressionAlgorithm
@ -227,10 +228,9 @@ class MessageMetadata(
*/ */
@JvmOverloads @JvmOverloads
fun isAuthenticatablySignedBy(userId: String, email: Boolean, certificateAuthority: CertificateAuthority, targetAmount: Int = 120): Boolean { fun isAuthenticatablySignedBy(userId: String, email: Boolean, certificateAuthority: CertificateAuthority, targetAmount: Int = 120): Boolean {
return verifiedSignatures.any { return verifiedSignatures.any { certificateAuthority
certificateAuthority.authenticateBinding( .authenticateBinding(it.signingKey.fingerprint, userId, email, it.signature.creationTime, targetAmount)
it.signingKey.fingerprint, userId, email, it.signature.creationTime, targetAmount .authenticated
).authenticated
} }
} }
@ -241,31 +241,23 @@ class MessageMetadata(
* @param fingerprint fingerprint * @param fingerprint fingerprint
* @return true if message was signed by a cert identified by the given fingerprint * @return true if message was signed by a cert identified by the given fingerprint
*/ */
fun isVerifiedSignedBy(fingerprint: OpenPgpFingerprint) = verifiedSignatures.any { fun isVerifiedSignedBy(fingerprint: OpenPgpFingerprint) =
it.signingKey.primaryKeyFingerprint == fingerprint || it.signingKey.subkeyFingerprint == fingerprint verifiedSignatures.any { it.signingKey.matches(fingerprint) }
}
fun isVerifiedSignedBy(keys: PGPKeyRing) = containsSignatureBy(verifiedSignatures, keys) fun isVerifiedSignedBy(keys: PGPKeyRing) =
verifiedSignatures.any { keys.matches(it.signingKey) }
fun isVerifiedDetachedSignedBy(fingerprint: OpenPgpFingerprint) = verifiedDetachedSignatures.any { fun isVerifiedDetachedSignedBy(fingerprint: OpenPgpFingerprint) =
it.signingKey.primaryKeyFingerprint == fingerprint || it.signingKey.subkeyFingerprint == fingerprint verifiedDetachedSignatures.any { it.signingKey.matches(fingerprint) }
}
fun isVerifiedDetachedSignedBy(keys: PGPKeyRing) = containsSignatureBy(verifiedDetachedSignatures, keys) fun isVerifiedDetachedSignedBy(keys: PGPKeyRing) =
verifiedDetachedSignatures.any { keys.matches(it.signingKey) }
fun isVerifiedInlineSignedBy(fingerprint: OpenPgpFingerprint) = verifiedInlineSignatures.any { fun isVerifiedInlineSignedBy(fingerprint: OpenPgpFingerprint) =
it.signingKey.primaryKeyFingerprint == fingerprint || it.signingKey.subkeyFingerprint == fingerprint verifiedInlineSignatures.any { it.signingKey.matches(fingerprint) }
}
fun isVerifiedInlineSignedBy(keys: PGPKeyRing) = containsSignatureBy(verifiedInlineSignatures, keys) fun isVerifiedInlineSignedBy(keys: PGPKeyRing) =
verifiedInlineSignatures.any { keys.matches(it.signingKey) }
private fun containsSignatureBy(signatures: List<SignatureVerification>, keys: PGPKeyRing) =
signatures.any {
// Match certificate by primary key id
keys.publicKey.keyID == it.signingKey.primaryKeyId &&
// match signing subkey
keys.getPublicKey(it.signingKey.subkeyId) != null
}
// ################################################################################################################ // ################################################################################################################
// ### Literal Data ### // ### Literal Data ###

View file

@ -4,6 +4,7 @@
package org.pgpainless.encryption_signing package org.pgpainless.encryption_signing
import org.bouncycastle.extensions.matches
import org.bouncycastle.openpgp.PGPLiteralData import org.bouncycastle.openpgp.PGPLiteralData
import org.bouncycastle.openpgp.PGPPublicKeyRing import org.bouncycastle.openpgp.PGPPublicKeyRing
import org.bouncycastle.openpgp.PGPSignature import org.bouncycastle.openpgp.PGPSignature
@ -39,10 +40,7 @@ data class EncryptionResult(
* @param certificate certificate * @param certificate certificate
* @return true if encrypted for 1+ subkeys, false otherwise. * @return true if encrypted for 1+ subkeys, false otherwise.
*/ */
fun isEncryptedFor(certificate: PGPPublicKeyRing) = recipients.any { fun isEncryptedFor(certificate: PGPPublicKeyRing) = recipients.any { certificate.matches(it) }
certificate.publicKey.keyID == it.primaryKeyId &&
certificate.getPublicKey(it.subkeyId) != null
}
companion object { companion object {
/** /**

View file

@ -31,6 +31,9 @@ class SubkeyIdentifier(
val subkeyId = subkeyFingerprint.keyId val subkeyId = subkeyFingerprint.keyId
val primaryKeyId = primaryKeyFingerprint.keyId val primaryKeyId = primaryKeyFingerprint.keyId
fun matches(fingerprint: OpenPgpFingerprint) =
primaryKeyFingerprint == fingerprint || subkeyFingerprint == fingerprint
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (other == null) { if (other == null) {
return false return false