From ab6ab04bcb5be209aa75654d50709ecd5329e999 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Tue, 6 May 2025 12:04:08 +0200 Subject: [PATCH] Add documentation --- .../extensions/PGPKeyRingExtensions.kt | 4 ++++ .../MessageMetadata.kt | 19 +++++++++++++++++ .../SignatureVerification.kt | 21 ++++++++++++------- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/bouncycastle/extensions/PGPKeyRingExtensions.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/bouncycastle/extensions/PGPKeyRingExtensions.kt index f7222c67..50633fcf 100644 --- a/pgpainless-core/src/main/kotlin/org/pgpainless/bouncycastle/extensions/PGPKeyRingExtensions.kt +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/bouncycastle/extensions/PGPKeyRingExtensions.kt @@ -10,6 +10,7 @@ import org.bouncycastle.openpgp.PGPOnePassSignature import org.bouncycastle.openpgp.PGPPublicKey import org.bouncycastle.openpgp.PGPSignature import org.bouncycastle.openpgp.api.OpenPGPCertificate +import org.bouncycastle.openpgp.api.OpenPGPCertificate.OpenPGPComponentKey import org.bouncycastle.openpgp.api.OpenPGPImplementation import org.pgpainless.PGPainless import org.pgpainless.key.OpenPgpFingerprint @@ -20,6 +21,9 @@ fun PGPKeyRing.matches(subkeyIdentifier: SubkeyIdentifier): Boolean = this.publicKey.keyIdentifier.matches(subkeyIdentifier.certificateIdentifier) && this.getPublicKey(subkeyIdentifier.componentKeyIdentifier) != null +fun PGPKeyRing.matches(componentKey: OpenPGPComponentKey): Boolean = + this.matches(SubkeyIdentifier(componentKey)) + /** * Return true, if the [PGPKeyRing] contains a public key with the given [keyIdentifier]. * diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/decryption_verification/MessageMetadata.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/decryption_verification/MessageMetadata.kt index bb96e117..33e4c862 100644 --- a/pgpainless-core/src/main/kotlin/org/pgpainless/decryption_verification/MessageMetadata.kt +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/decryption_verification/MessageMetadata.kt @@ -39,6 +39,10 @@ class MessageMetadata(val message: Message) { val encryptionAlgorithm: SymmetricKeyAlgorithm? get() = encryptionAlgorithms.let { if (it.hasNext()) it.next() else null } + /** + * The [MessageEncryptionMechanism] of the outermost encrypted data packet, or null if the + * message is unencrypted. + */ val encryptionMechanism: MessageEncryptionMechanism? get() = encryptionMechanisms.let { if (it.hasNext()) it.next() else null } @@ -54,9 +58,16 @@ class MessageMetadata(val message: Message) { val encryptionAlgorithms: Iterator get() = encryptionLayers.asSequence().map { it.algorithm }.iterator() + /** + * [Iterator] of each [MessageEncryptionMechanism] encountered in the message. The first item + * returned by the iterator is the encryption mechanism of the outermost encrypted data packet, + * the next item that of the next nested encrypted data packet and so on. The iterator might + * also be empty in case of an unencrypted message. + */ val encryptionMechanisms: Iterator get() = encryptionLayers.asSequence().map { it.mechanism }.iterator() + /** Return true, if the message is encrypted, false otherwise. */ val isEncrypted: Boolean get() = if (encryptionMechanism == null) false @@ -64,12 +75,14 @@ class MessageMetadata(val message: Message) { encryptionMechanism!!.symmetricKeyAlgorithm != SymmetricKeyAlgorithm.NULL.algorithmId + /** Return true, if the message was encrypted for the given [OpenPGPCertificate]. */ fun isEncryptedFor(cert: OpenPGPCertificate): Boolean { return encryptionLayers.asSequence().any { it.recipients.any { identifier -> cert.getKey(identifier) != null } } } + /** Return true, if the message was encrypted for the given [PGPKeyRing]. */ fun isEncryptedFor(cert: PGPKeyRing): Boolean { return encryptionLayers.asSequence().any { it.recipients.any { keyId -> cert.getPublicKey(keyId) != null } @@ -101,9 +114,13 @@ class MessageMetadata(val message: Message) { get() = encryptionLayers.asSequence().mapNotNull { it.decryptionKey }.firstOrNull() /** List containing all recipient keyIDs. */ + @Deprecated( + "Use of key-ids is discouraged in favor of KeyIdentifiers", + replaceWith = ReplaceWith("recipientKeyIdentifiers")) val recipientKeyIds: List get() = recipientKeyIdentifiers.map { it.keyId }.toList() + /** List containing all recipient [KeyIdentifiers][KeyIdentifier]. */ val recipientKeyIdentifiers: List get() = encryptionLayers @@ -115,6 +132,7 @@ class MessageMetadata(val message: Message) { } .toList() + /** [Iterator] of all [EncryptedData] layers of the message. */ val encryptionLayers: Iterator get() = object : LayerIterator(message) { @@ -144,6 +162,7 @@ class MessageMetadata(val message: Message) { val compressionAlgorithms: Iterator get() = compressionLayers.asSequence().map { it.algorithm }.iterator() + /** [Iterator] of all [CompressedData] layers of the message. */ val compressionLayers: Iterator get() = object : LayerIterator(message) { diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/decryption_verification/SignatureVerification.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/decryption_verification/SignatureVerification.kt index c32cdc71..b5a5bc0d 100644 --- a/pgpainless-core/src/main/kotlin/org/pgpainless/decryption_verification/SignatureVerification.kt +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/decryption_verification/SignatureVerification.kt @@ -14,16 +14,17 @@ import org.pgpainless.signature.SignatureUtils /** * Tuple of a signature and an identifier of its corresponding verification key. Semantic meaning of * the signature verification (success, failure) is merely given by context. E.g. - * [MessageMetadata.getVerifiedInlineSignatures] contains verified verifications, while the class - * [Failure] contains failed verifications. + * [MessageMetadata.verifiedSignatures] contains verified verifications, while the class [Failure] + * contains failed verifications. * - * @param signature PGPSignature object - * @param signingKey [SubkeyIdentifier] of the (sub-) key that is used for signature verification. - * Note, that this might be null, e.g. in case of a [Failure] due to missing verification key. + * @param documentSignature OpenPGPDocumentSignature object */ data class SignatureVerification(val documentSignature: OpenPGPDocumentSignature) { + /** Underlying [PGPSignature]. */ val signature: PGPSignature = documentSignature.signature + + /** [SubkeyIdentifier] of the component key that created the signature. */ val signingKey: SubkeyIdentifier = SubkeyIdentifier(documentSignature.issuer) override fun toString(): String { @@ -35,15 +36,21 @@ data class SignatureVerification(val documentSignature: OpenPGPDocumentSignature * Tuple object of a [SignatureVerification] and the corresponding * [SignatureValidationException] that caused the verification to fail. * - * @param signatureVerification verification (tuple of [PGPSignature] and corresponding - * [SubkeyIdentifier]) + * @param documentSignature signature that could not be verified * @param validationException exception that caused the verification to fail */ data class Failure( val documentSignature: OpenPGPDocumentSignature, val validationException: SignatureValidationException ) { + + /** Underlying [PGPSignature]. */ val signature: PGPSignature = documentSignature.signature + + /** + * [SubkeyIdentifier] of the component key that created the signature. Note: In case of a + * missing verification key, this might be null. + */ val signingKey: SubkeyIdentifier? = documentSignature.issuer?.let { SubkeyIdentifier(it) } constructor(