From 08ac0e874be296efaf73fc57998bb53c26ce4088 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Mon, 31 Mar 2025 09:52:49 +0200 Subject: [PATCH] Replace SignatureVerifier usage with BC API --- .../signature/consumer/SignatureValidator.kt | 143 ----- .../signature/consumer/SignatureVerifier.kt | 597 ------------------ .../certification/CertifyCertificateTest.java | 8 +- .../SignatureOverUserAttributesTest.java | 32 +- 4 files changed, 18 insertions(+), 762 deletions(-) delete mode 100644 pgpainless-core/src/main/kotlin/org/pgpainless/signature/consumer/SignatureVerifier.kt diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/signature/consumer/SignatureValidator.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/signature/consumer/SignatureValidator.kt index 046aa714..120f9d2b 100644 --- a/pgpainless-core/src/main/kotlin/org/pgpainless/signature/consumer/SignatureValidator.kt +++ b/pgpainless-core/src/main/kotlin/org/pgpainless/signature/consumer/SignatureValidator.kt @@ -4,7 +4,6 @@ package org.pgpainless.signature.consumer -import java.lang.Exception import java.util.Date import openpgp.formatUTC import openpgp.openPgpKeyId @@ -13,7 +12,6 @@ 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 @@ -74,76 +72,6 @@ abstract class SignatureValidator { } } - /** - * Verify that a subkey binding signature - if the subkey is signing-capable - contains a - * valid primary key binding signature. - * - * @param primaryKey primary key - * @param subkey subkey - * @param policy policy - * @param referenceDate reference date for signature verification - * @return validator - */ - @JvmStatic - fun hasValidPrimaryKeyBindingSignatureIfRequired( - primaryKey: PGPPublicKey, - subkey: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): SignatureValidator { - return object : SignatureValidator() { - override fun verify(signature: PGPSignature) { - if (!signature.publicKeyAlgorithm.isSigningCapable()) { - // subkey is not signing capable -> No need to process embedded signatures - return - } - - // Make sure we have key flags - SignatureSubpacketsUtil.getKeyFlags(signature)?.let { - if (!KeyFlag.hasKeyFlag(it.flags, KeyFlag.SIGN_DATA) && - !KeyFlag.hasKeyFlag(it.flags, KeyFlag.CERTIFY_OTHER)) { - return - } - } - ?: return - - try { - val embeddedSignatures = - SignatureSubpacketsUtil.getEmbeddedSignature(signature) - if (embeddedSignatures.isEmpty) { - throw SignatureValidationException( - "Missing primary key binding" + - " signature on signing capable subkey ${subkey.keyID.openPgpKeyId()}", - mapOf()) - } - - val rejectedEmbeddedSignatures = mutableMapOf() - if (!embeddedSignatures.any { embedded -> - if (embedded.isOfType(SignatureType.PRIMARYKEY_BINDING)) { - try { - signatureStructureIsAcceptable(subkey, policy).verify(embedded) - signatureIsEffective(referenceTime).verify(embedded) - correctPrimaryKeyBindingSignature(primaryKey, subkey) - .verify(embedded) - return@any true - } catch (e: SignatureValidationException) { - rejectedEmbeddedSignatures[embedded] = e - } - } - false - }) { - throw SignatureValidationException( - "Missing primary key binding signature on signing capable subkey ${subkey.keyID.openPgpKeyId()}", - rejectedEmbeddedSignatures) - } - } catch (e: PGPException) { - throw SignatureValidationException( - "Cannot process list of embedded signatures.", e) - } - } - } - } - /** * Verify that a signature has an acceptable structure. * @@ -466,77 +394,6 @@ abstract class SignatureValidator { } } - /** - * Verify that a subkey binding signature is correct. - * - * @param primaryKey primary key - * @param subkey subkey - * @return validator - */ - @JvmStatic - fun correctSubkeyBindingSignature( - primaryKey: PGPPublicKey, - subkey: PGPPublicKey - ): SignatureValidator { - return object : SignatureValidator() { - override fun verify(signature: PGPSignature) { - if (primaryKey.keyID == subkey.keyID) { - throw SignatureValidationException("Primary key cannot be its own subkey.") - } - try { - signature.init( - OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(), - primaryKey) - if (!signature.verifyCertification(primaryKey, subkey)) { - throw SignatureValidationException("Signature is not correct.") - } - } catch (e: PGPException) { - throw SignatureValidationException( - "Cannot verify subkey binding signature correctness", e) - } catch (e: ClassCastException) { - throw SignatureValidationException( - "Cannot verify subkey binding signature correctness", e) - } - } - } - } - - /** - * Verify that a primary key binding signature is correct. - * - * @param primaryKey primary key - * @param subkey subkey - * @return validator - */ - @JvmStatic - fun correctPrimaryKeyBindingSignature( - primaryKey: PGPPublicKey, - subkey: PGPPublicKey - ): SignatureValidator { - return object : SignatureValidator() { - override fun verify(signature: PGPSignature) { - if (primaryKey.keyID == subkey.keyID) { - throw SignatureValidationException("Primary key cannot be its own subkey.") - } - try { - signature.init( - OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(), - subkey) - if (!signature.verifyCertification(primaryKey, subkey)) { - throw SignatureValidationException( - "Primary Key Binding Signature is not correct.") - } - } catch (e: PGPException) { - throw SignatureValidationException( - "Cannot verify primary key binding signature correctness", e) - } catch (e: ClassCastException) { - throw SignatureValidationException( - "Cannot verify primary key binding signature correctness", e) - } - } - } - } - /** * Verify that a direct-key signature is correct. * diff --git a/pgpainless-core/src/main/kotlin/org/pgpainless/signature/consumer/SignatureVerifier.kt b/pgpainless-core/src/main/kotlin/org/pgpainless/signature/consumer/SignatureVerifier.kt deleted file mode 100644 index 1ac204cf..00000000 --- a/pgpainless-core/src/main/kotlin/org/pgpainless/signature/consumer/SignatureVerifier.kt +++ /dev/null @@ -1,597 +0,0 @@ -// SPDX-FileCopyrightText: 2023 Paul Schaub -// -// SPDX-License-Identifier: Apache-2.0 - -package org.pgpainless.signature.consumer - -import java.io.IOException -import java.io.InputStream -import java.util.* -import openpgp.openPgpKeyId -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.policy.Policy -import org.pgpainless.signature.consumer.SignatureValidator.Companion.correctSignatureOverKey -import org.pgpainless.signature.consumer.SignatureValidator.Companion.correctSignatureOverUserAttributes -import org.pgpainless.signature.consumer.SignatureValidator.Companion.correctSignatureOverUserId -import org.pgpainless.signature.consumer.SignatureValidator.Companion.correctSubkeyBindingSignature -import org.pgpainless.signature.consumer.SignatureValidator.Companion.hasValidPrimaryKeyBindingSignatureIfRequired -import org.pgpainless.signature.consumer.SignatureValidator.Companion.signatureDoesNotPredateSignee -import org.pgpainless.signature.consumer.SignatureValidator.Companion.signatureIsCertification -import org.pgpainless.signature.consumer.SignatureValidator.Companion.signatureIsEffective -import org.pgpainless.signature.consumer.SignatureValidator.Companion.signatureIsOfType -import org.pgpainless.signature.consumer.SignatureValidator.Companion.signatureStructureIsAcceptable -import org.pgpainless.signature.consumer.SignatureValidator.Companion.wasPossiblyMadeByKey - -/** - * Collection of static methods for signature verification. Signature verification entails - * validation of certain criteria (see [SignatureValidator]), as well as cryptographic verification - * of signature correctness. - */ -class SignatureVerifier { - - companion object { - - /** - * Verify a signature (certification or revocation) over a user-id. - * - * @param userId user-id - * @param signature certification signature - * @param signingKey key that created the certification - * @param keyWithUserId key carrying the user-id - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if signature verification is successful - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifySignatureOverUserId( - userId: CharSequence, - signature: PGPSignature, - signingKey: PGPPublicKey, - keyWithUserId: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - val type = SignatureType.fromCode(signature.signatureType) - return when (type) { - SignatureType.GENERIC_CERTIFICATION, - SignatureType.NO_CERTIFICATION, - SignatureType.CASUAL_CERTIFICATION, - SignatureType.POSITIVE_CERTIFICATION, - null -> - verifyUserIdCertification( - userId, signature, signingKey, keyWithUserId, policy, referenceTime) - SignatureType.CERTIFICATION_REVOCATION -> - verifyUserIdRevocation( - userId, signature, signingKey, keyWithUserId, policy, referenceTime) - else -> - throw SignatureValidationException( - "Signature is not a valid user-id certification/revocation signature: $type") - } - } - - /** - * Verify a certification self-signature over a user-id. - * - * @param userId user-id - * @param signature certification signature - * @param primaryKey primary key - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if the self-signature is verified successfully - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifyUserIdCertification( - userId: CharSequence, - signature: PGPSignature, - primaryKey: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - return verifyUserIdCertification( - userId, signature, primaryKey, primaryKey, policy, referenceTime) - } - - /** - * Verify a user-id certification. - * - * @param userId user-id - * @param signature certification signature - * @param signingKey key that created the certification - * @param keyWithUserId primary key that carries the user-id - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if signature verification is successful - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifyUserIdCertification( - userId: CharSequence, - signature: PGPSignature, - signingKey: PGPPublicKey, - keyWithUserId: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - wasPossiblyMadeByKey(signingKey).verify(signature) - signatureIsCertification().verify(signature) - signatureStructureIsAcceptable(signingKey, policy).verify(signature) - signatureIsEffective(referenceTime).verify(signature) - correctSignatureOverUserId(userId, keyWithUserId, signingKey).verify(signature) - - return true - } - - /** - * Verify a user-id revocation self-signature. - * - * @param userId user-id - * @param signature user-id revocation signature - * @param primaryKey primary key - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if the user-id revocation signature is successfully verified - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifyUserIdRevocation( - userId: CharSequence, - signature: PGPSignature, - primaryKey: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - return verifyUserIdRevocation( - userId, signature, primaryKey, primaryKey, policy, referenceTime) - } - - /** - * Verify a user-id revocation signature. - * - * @param userId user-id - * @param signature revocation signature - * @param signingKey key that created the revocation signature - * @param keyWithUserId primary key carrying the user-id - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if the user-id revocation signature is successfully verified - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifyUserIdRevocation( - userId: CharSequence, - signature: PGPSignature, - signingKey: PGPPublicKey, - keyWithUserId: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - wasPossiblyMadeByKey(signingKey).verify(signature) - signatureIsOfType(SignatureType.CERTIFICATION_REVOCATION).verify(signature) - signatureStructureIsAcceptable(signingKey, policy).verify(signature) - signatureIsEffective(referenceTime).verify(signature) - correctSignatureOverUserId(userId, keyWithUserId, signingKey).verify(signature) - - return true - } - - /** - * Verify a certification self-signature over a user-attributes packet. - * - * @param userAttributes user attributes - * @param signature certification self-signature - * @param primaryKey primary key that carries the user-attributes - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if the signature can be verified successfully - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifyUserAttributesCertification( - userAttributes: PGPUserAttributeSubpacketVector, - signature: PGPSignature, - primaryKey: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - return verifyUserAttributesCertification( - userAttributes, signature, primaryKey, primaryKey, policy, referenceTime) - } - - /** - * Verify a certification signature over a user-attributes packet. - * - * @param userAttributes user attributes - * @param signature certification signature - * @param signingKey key that created the user-attributes certification - * @param keyWithAttributes key that carries the user-attributes certification - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if the signature can be verified successfully - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifyUserAttributesCertification( - userAttributes: PGPUserAttributeSubpacketVector, - signature: PGPSignature, - signingKey: PGPPublicKey, - keyWithAttributes: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - wasPossiblyMadeByKey(signingKey).verify(signature) - signatureIsCertification().verify(signature) - signatureStructureIsAcceptable(signingKey, policy).verify(signature) - signatureIsEffective(referenceTime).verify(signature) - correctSignatureOverUserAttributes(userAttributes, keyWithAttributes, signingKey) - .verify(signature) - - return true - } - - /** - * Verify a user-attributes revocation self-signature. - * - * @param userAttributes user-attributes - * @param signature user-attributes revocation signature - * @param primaryKey primary key that carries the user-attributes - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if the revocation signature can be verified successfully - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifyUserAttributesRevocation( - userAttributes: PGPUserAttributeSubpacketVector, - signature: PGPSignature, - primaryKey: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - return verifyUserAttributesRevocation( - userAttributes, signature, primaryKey, primaryKey, policy, referenceTime) - } - - /** - * Verify a user-attributes revocation signature. - * - * @param userAttributes user-attributes - * @param signature revocation signature - * @param signingKey revocation key - * @param keyWithAttributes key that carries the user-attributes - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if the revocation signature can be verified successfully - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifyUserAttributesRevocation( - userAttributes: PGPUserAttributeSubpacketVector, - signature: PGPSignature, - signingKey: PGPPublicKey, - keyWithAttributes: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - wasPossiblyMadeByKey(signingKey).verify(signature) - signatureIsOfType(SignatureType.CERTIFICATION_REVOCATION).verify(signature) - signatureStructureIsAcceptable(signingKey, policy).verify(signature) - signatureIsEffective(referenceTime).verify(signature) - correctSignatureOverUserAttributes(userAttributes, keyWithAttributes, signingKey) - .verify(signature) - - return true - } - - /** - * Verify a subkey binding signature. - * - * @param signature binding signature - * @param primaryKey primary key - * @param subkey subkey - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if the binding signature can be verified successfully - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifySubkeyBindingSignature( - signature: PGPSignature, - primaryKey: PGPPublicKey, - subkey: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - signatureIsOfType(SignatureType.SUBKEY_BINDING).verify(signature) - signatureStructureIsAcceptable(primaryKey, policy).verify(signature) - signatureDoesNotPredateSignee(subkey).verify(signature) - signatureIsEffective(referenceTime).verify(signature) - hasValidPrimaryKeyBindingSignatureIfRequired(primaryKey, subkey, policy, referenceTime) - .verify(signature) - correctSubkeyBindingSignature(primaryKey, subkey).verify(signature) - - return true - } - - /** - * Verify a subkey revocation signature. - * - * @param signature subkey revocation signature - * @param primaryKey primary key - * @param subkey subkey - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if the subkey revocation signature can be verified successfully - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifySubkeyBindingRevocation( - signature: PGPSignature, - primaryKey: PGPPublicKey, - subkey: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - signatureIsOfType(SignatureType.SUBKEY_REVOCATION).verify(signature) - signatureStructureIsAcceptable(primaryKey, policy).verify(signature) - signatureDoesNotPredateSignee(subkey).verify(signature) - signatureIsEffective(referenceTime).verify(signature) - correctSignatureOverKey(primaryKey, subkey).verify(signature) - - return true - } - - /** - * Verify a direct-key self-signature. - * - * @param signature signature - * @param primaryKey primary key - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if the signature can be verified successfully - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifyDirectKeySignature( - signature: PGPSignature, - primaryKey: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - return verifyDirectKeySignature( - signature, primaryKey, primaryKey, policy, referenceTime) - } - - /** - * Verify a direct-key signature. - * - * @param signature signature - * @param signingKey signing key - * @param signedKey signed key - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if signature verification is successful - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifyDirectKeySignature( - signature: PGPSignature, - signingKey: PGPPublicKey, - signedKey: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - signatureIsOfType(SignatureType.DIRECT_KEY).verify(signature) - signatureStructureIsAcceptable(signingKey, policy).verify(signature) - signatureDoesNotPredateSignee(signedKey).verify(signature) - signatureIsEffective(referenceTime).verify(signature) - correctSignatureOverKey(signingKey, signedKey).verify(signature) - - return true - } - - /** - * Verify a key revocation signature. - * - * @param signature signature - * @param primaryKey primary key - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if signature verification is successful - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifyKeyRevocationSignature( - signature: PGPSignature, - primaryKey: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - signatureIsOfType(SignatureType.KEY_REVOCATION).verify(signature) - signatureStructureIsAcceptable(primaryKey, policy).verify(signature) - signatureIsEffective(referenceTime).verify(signature) - correctSignatureOverKey(primaryKey, primaryKey).verify(signature) - - return true - } - - /** - * Initialize a signature and verify it afterwards by updating it with the signed data. - * - * @param signature OpenPGP signature - * @param signedData input stream containing the signed data - * @param signingKey the key that created the signature - * @param policy policy - * @param referenceTime reference date of signature verification - * @return true if the signature is successfully verified - * @throws SignatureValidationException if the signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifyUninitializedSignature( - signature: PGPSignature, - signedData: InputStream, - signingKey: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - initializeSignatureAndUpdateWithSignedData(signature, signedData, signingKey) - return verifyInitializedSignature(signature, signingKey, policy, referenceTime) - } - - /** - * Initialize a signature and then update it with the signed data from the given - * [InputStream]. - * - * @param signature OpenPGP signature - * @param signedData input stream containing signed data - * @param signingKey key that created the signature - * @throws SignatureValidationException in case the signature cannot be verified for some - * reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun initializeSignatureAndUpdateWithSignedData( - signature: PGPSignature, - signedData: InputStream, - signingKey: PGPPublicKey - ) { - try { - signature.init( - OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(), - signingKey, - ) - var read: Int - val buf = ByteArray(8192) - var lastByte: Byte = -1 - while (signedData.read(buf).also { read = it } != -1) { - // If we previously omitted a newline, but the stream is not yet empty, add it - // now - if (lastByte == '\n'.code.toByte()) { - signature.update(lastByte) - } - lastByte = buf[read - 1] - if (lastByte == '\n'.code.toByte()) { - // if last byte in buffer is newline, omit it for now - signature.update(buf, 0, read - 1) - } else { - // otherwise, write buffer as usual - signature.update(buf, 0, read) - } - } - } catch (e: PGPException) { - throw SignatureValidationException("Cannot init signature.", e) - } catch (e: IOException) { - throw SignatureValidationException("Cannot update signature.", e) - } - } - - /** - * Verify an initialized signature. An initialized signature was already updated with the - * signed data. - * - * @param signature OpenPGP signature - * @param signingKey key that created the signature - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if signature is verified successfully - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifyInitializedSignature( - signature: PGPSignature, - signingKey: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - wasPossiblyMadeByKey(signingKey).verify(signature) - signatureStructureIsAcceptable(signingKey, policy).verify(signature) - signatureIsEffective(referenceTime).verify(signature) - - return try { - if (!signature.verify()) { - throw SignatureValidationException("Signature is not correct.") - } - true - } catch (e: PGPException) { - throw SignatureValidationException("Could not verify signature correctness.", e) - } - } - - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifyOnePassSignature( - signature: PGPSignature, - signingKey: PGPPublicKey, - onePassSignature: OnePassSignatureCheck, - policy: Policy - ): Boolean { - try { - wasPossiblyMadeByKey(signingKey).verify(signature) - signatureStructureIsAcceptable(signingKey, policy).verify(signature) - signatureIsEffective().verify(signature) - } catch (e: SignatureValidationException) { - throw SignatureValidationException("Signature is not valid: ${e.message}", e) - } - - try { - checkNotNull(onePassSignature.signature) { "No comparison signature provided." } - if (!onePassSignature.onePassSignature.verify(signature)) { - throw SignatureValidationException( - "Bad signature of key ${signingKey.keyID.openPgpKeyId()}") - } - } catch (e: PGPException) { - throw SignatureValidationException( - "Could not verify correctness of One-Pass-Signature: ${e.message}", e) - } - - return true - } - - /** - * Verify a signature (certification or revocation) over a user-id. - * - * @param userId user-id - * @param signature self-signature - * @param primaryKey primary key that created the signature - * @param policy policy - * @param referenceTime reference date for signature verification - * @return true if the signature is successfully verified - * @throws SignatureValidationException if signature verification fails for some reason - */ - @JvmStatic - @Throws(SignatureValidationException::class) - fun verifySignatureOverUserId( - userId: CharSequence, - signature: PGPSignature, - primaryKey: PGPPublicKey, - policy: Policy, - referenceTime: Date - ): Boolean { - return verifySignatureOverUserId( - userId, signature, primaryKey, primaryKey, policy, referenceTime) - } - } -} diff --git a/pgpainless-core/src/test/java/org/pgpainless/key/certification/CertifyCertificateTest.java b/pgpainless-core/src/test/java/org/pgpainless/key/certification/CertifyCertificateTest.java index 0cd74325..c0361f89 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/key/certification/CertifyCertificateTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/key/certification/CertifyCertificateTest.java @@ -27,10 +27,8 @@ import org.pgpainless.algorithm.SignatureType; import org.pgpainless.algorithm.Trustworthiness; import org.pgpainless.key.info.KeyRingInfo; import org.pgpainless.key.protection.SecretKeyRingProtector; -import org.pgpainless.signature.consumer.SignatureVerifier; import org.pgpainless.signature.subpackets.CertificationSubpackets; import org.pgpainless.util.CollectionUtils; -import org.pgpainless.util.DateUtil; import javax.annotation.Nonnull; @@ -57,8 +55,7 @@ public class CertifyCertificateTest { assertEquals(SignatureType.GENERIC_CERTIFICATION, SignatureType.requireFromCode(signature.getSignatureType())); assertEquals(alice.getPrimaryKey().getPGPPublicKey().getKeyID(), signature.getKeyID()); - assertTrue(SignatureVerifier.verifyUserIdCertification( - bobUserId, signature, alice.getPrimaryKey().getPGPPublicKey(), bob.getPrimaryKey().getPGPPublicKey(), api.getAlgorithmPolicy(), DateUtil.now())); + assertTrue(result.getCertifiedCertificate().getUserId("Bob ").getCertificationBy(alice).isValid()); OpenPGPCertificate bobCertified = result.getCertifiedCertificate(); PGPPublicKey bobCertifiedKey = bobCertified.getPrimaryKey().getPGPPublicKey(); @@ -99,8 +96,7 @@ public class CertifyCertificateTest { assertTrue(trustworthiness.isIntroducer()); assertFalse(trustworthiness.canIntroduce(1)); - assertTrue(SignatureVerifier.verifyDirectKeySignature( - pgpSignature, alice.getPrimaryKey().getPGPPublicKey(), bob.getPrimaryKey().getPGPPublicKey(), api.getAlgorithmPolicy(), DateUtil.now())); + assertTrue(result.getCertifiedCertificate().getDelegationBy(alice).isValid()); OpenPGPCertificate bobCertified = result.getCertifiedCertificate(); PGPPublicKey bobCertifiedKey = bobCertified.getPrimaryKey().getPGPPublicKey(); diff --git a/pgpainless-core/src/test/java/org/pgpainless/signature/SignatureOverUserAttributesTest.java b/pgpainless-core/src/test/java/org/pgpainless/signature/SignatureOverUserAttributesTest.java index bf1ef550..c7b7ce6c 100644 --- a/pgpainless-core/src/test/java/org/pgpainless/signature/SignatureOverUserAttributesTest.java +++ b/pgpainless-core/src/test/java/org/pgpainless/signature/SignatureOverUserAttributesTest.java @@ -4,18 +4,12 @@ package org.pgpainless.signature; -import static org.junit.jupiter.api.Assertions.assertThrows; - import java.io.IOException; import java.util.Date; +import java.util.List; import org.bouncycastle.bcpg.attr.ImageAttribute; -import org.bouncycastle.openpgp.PGPException; -import org.bouncycastle.openpgp.PGPPublicKey; -import org.bouncycastle.openpgp.PGPSignature; -import org.bouncycastle.openpgp.PGPSignatureGenerator; -import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector; -import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVectorGenerator; +import org.bouncycastle.openpgp.*; import org.bouncycastle.openpgp.api.OpenPGPCertificate; import org.bouncycastle.openpgp.api.OpenPGPImplementation; import org.bouncycastle.openpgp.api.OpenPGPKey; @@ -23,11 +17,11 @@ import org.junit.jupiter.api.Test; import org.pgpainless.PGPainless; import org.pgpainless.algorithm.HashAlgorithm; import org.pgpainless.algorithm.SignatureType; -import org.pgpainless.exception.SignatureValidationException; import org.pgpainless.key.TestKeys; import org.pgpainless.key.protection.SecretKeyRingProtector; import org.pgpainless.key.protection.UnlockSecretKey; -import org.pgpainless.signature.consumer.SignatureVerifier; + +import static org.junit.jupiter.api.Assertions.*; public class SignatureOverUserAttributesTest { @@ -53,6 +47,7 @@ public class SignatureOverUserAttributesTest { public void createAndVerifyUserAttributeCertification() throws PGPException, IOException { PGPainless api = PGPainless.getInstance(); OpenPGPKey secretKeys = TestKeys.getEmilKey(); + OpenPGPKey.OpenPGPSecretKey secretKey = secretKeys.getPrimarySecretKey(); OpenPGPCertificate.OpenPGPComponentKey publicKey = secretKey.getPublicKey(); OpenPGPKey.OpenPGPPrivateKey privateKey = UnlockSecretKey.unlockSecretKey(secretKey, SecretKeyRingProtector.unprotectedKeys()); @@ -65,9 +60,12 @@ public class SignatureOverUserAttributesTest { PGPSignature signature = generator.generateCertification(attribute, publicKey.getPGPPublicKey()); PGPPublicKey pgpPublicKey = PGPPublicKey.addCertification(publicKey.getPGPPublicKey(), attribute, signature); - SignatureVerifier.verifyUserAttributesCertification(attribute, signature, pgpPublicKey, api.getAlgorithmPolicy(), new Date()); + pgpPublicKey = PGPPublicKey.addCertification(pgpPublicKey, invalidAttribute, signature); + OpenPGPCertificate withUserAttribute = api.toCertificate(PGPPublicKeyRing.insertPublicKey(secretKeys.getPGPPublicKeyRing(), pgpPublicKey)); + List identities = withUserAttribute.getIdentities(); - assertThrows(SignatureValidationException.class, () -> SignatureVerifier.verifyUserAttributesCertification(invalidAttribute, signature, pgpPublicKey, api.getAlgorithmPolicy(), new Date())); + assertTrue(identities.get(1).isBound()); // valid + assertFalse(identities.get(2).isBound()); // invalid } @Test @@ -86,9 +84,11 @@ public class SignatureOverUserAttributesTest { PGPSignature signature = generator.generateCertification(attribute, publicKey.getPGPPublicKey()); PGPPublicKey pgpPublicKey = PGPPublicKey.addCertification(publicKey.getPGPPublicKey(), attribute, signature); - SignatureVerifier.verifyUserAttributesRevocation(attribute, signature, pgpPublicKey, api.getAlgorithmPolicy(), new Date()); - assertThrows(SignatureValidationException.class, () -> - SignatureVerifier.verifyUserAttributesCertification( - invalidAttribute, signature, pgpPublicKey, api.getAlgorithmPolicy(), new Date())); + OpenPGPCertificate withRevocation = api.toCertificate(PGPPublicKeyRing.insertPublicKey(secretKeys.getPGPPublicKeyRing(), pgpPublicKey)); + List identities = withRevocation.getIdentities(); + OpenPGPCertificate.OpenPGPComponentSignature revocation = identities.get(1).getRevocation(new Date()); + revocation.verify(api.getImplementation()); + assertTrue(revocation.isRevocation()); + assertTrue(revocation.isTestedCorrect()); } }