1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-09-09 10:19:39 +02:00

Remove unused SignatureValidator methods

This commit is contained in:
Paul Schaub 2025-03-31 09:58:19 +02:00
parent cb7c61cf10
commit 2c1d89a249
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311

View file

@ -7,23 +7,12 @@ package org.pgpainless.signature.consumer
import java.util.Date
import openpgp.formatUTC
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.SignatureSubpacket
import org.pgpainless.algorithm.SignatureType
import org.pgpainless.bouncycastle.extensions.fingerprint
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.key.OpenPgpFingerprint
import org.pgpainless.policy.Policy
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil
import org.pgpainless.util.NotationRegistry
abstract class SignatureValidator {
@ -72,467 +61,6 @@ abstract class SignatureValidator {
}
}
/**
* Verify that a signature has an acceptable structure.
*
* @param signingKey signing key
* @param policy policy
* @return validator
*/
@JvmStatic
fun signatureStructureIsAcceptable(
signingKey: PGPPublicKey,
policy: Policy
): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
signatureIsNotMalformed(signingKey).verify(signature)
if (signature.version >= 4) {
signatureDoesNotHaveCriticalUnknownNotations(policy.notationRegistry)
.verify(signature)
signatureDoesNotHaveCriticalUnknownSubpackets().verify(signature)
}
signatureUsesAcceptableHashAlgorithm(policy).verify(signature)
signatureUsesAcceptablePublicKeyAlgorithm(policy, signingKey).verify(signature)
}
}
}
/**
* Verify that a signature was made using an acceptable [PublicKeyAlgorithm].
*
* @param policy policy
* @param signingKey signing key
* @return validator
*/
@JvmStatic
fun signatureUsesAcceptablePublicKeyAlgorithm(
policy: Policy,
signingKey: PGPPublicKey
): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
if (signingKey.bitStrength == -1) {
throw SignatureValidationException(
"Cannot determine bit strength of signing key.")
}
if (!policy.publicKeyAlgorithmPolicy.isAcceptable(
signingKey.publicKeyAlgorithm, signingKey.bitStrength)) {
throw SignatureValidationException(
"Signature was made using unacceptable key. " +
"${signingKey.publicKeyAlgorithm} (${signingKey.bitStrength} bits) is " +
"not acceptable according to the public key algorithm policy.")
}
}
}
}
@JvmStatic
fun signatureUsesAcceptableHashAlgorithm(policy: Policy): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
try {
val algorithmPolicy = getHashAlgorithmPolicyForSignature(signature, policy)
if (!algorithmPolicy.isAcceptable(
signature.signatureHashAlgorithm, signature.creationTime)) {
throw SignatureValidationException(
"Signature uses unacceptable" +
" hash algorithm ${signature.signatureHashAlgorithm}" +
" (Signature creation time: ${signature.creationTime.formatUTC()})")
}
} catch (e: NoSuchElementException) {
throw SignatureValidationException(
"Signature uses unknown hash" + " algorithm ${signature.hashAlgorithm}")
}
}
}
}
/**
* Return the applicable [Policy.HashAlgorithmPolicy] for the given [PGPSignature].
* Revocation signatures are being policed using a different policy than non-revocation
* signatures.
*
* @param signature signature
* @param policy revocation policy for revocation sigs, normal policy for non-rev sigs
* @return policy
*/
@JvmStatic
private fun getHashAlgorithmPolicyForSignature(
signature: PGPSignature,
policy: Policy
): Policy.HashAlgorithmPolicy {
return when (SignatureType.fromCode(signature.signatureType)) {
null -> policy.certificationSignatureHashAlgorithmPolicy
SignatureType.CERTIFICATION_REVOCATION,
SignatureType.KEY_REVOCATION,
SignatureType.SUBKEY_REVOCATION -> policy.revocationSignatureHashAlgorithmPolicy
SignatureType.GENERIC_CERTIFICATION,
SignatureType.NO_CERTIFICATION,
SignatureType.CASUAL_CERTIFICATION,
SignatureType.POSITIVE_CERTIFICATION,
SignatureType.DIRECT_KEY,
SignatureType.SUBKEY_BINDING,
SignatureType.PRIMARYKEY_BINDING -> policy.certificationSignatureHashAlgorithmPolicy
else -> policy.dataSignatureHashAlgorithmPolicy
}
}
/**
* Verify that a signature does not carry critical unknown notations.
*
* @param registry notation registry of known notations
* @return validator
*/
@JvmStatic
fun signatureDoesNotHaveCriticalUnknownNotations(
registry: NotationRegistry
): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
SignatureSubpacketsUtil.getHashedNotationData(signature)
.filter { it.isCritical && !registry.isKnownNotation(it.notationName) }
.forEach {
throw SignatureValidationException(
"Signature contains unknown critical notation '${it.notationName}' in its hashed area.")
}
}
}
}
/**
* Verify that a signature does not contain critical unknown subpackets.
*
* @return validator
*/
@JvmStatic
fun signatureDoesNotHaveCriticalUnknownSubpackets(): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
signature.hashedSubPackets.criticalTags.forEach {
try {
SignatureSubpacket.requireFromCode(it)
} catch (e: NoSuchElementException) {
throw SignatureValidationException(
"Signature contains unknown critical subpacket of type 0x${Integer.toHexString(it)}")
}
}
}
}
}
/**
* Verify that a signature is effective at the given reference date.
*
* @param referenceTime reference date for signature verification
* @return validator
*/
@JvmStatic
@JvmOverloads
fun signatureIsEffective(referenceTime: Date = Date()): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
signatureIsAlreadyEffective(referenceTime).verify(signature)
signatureIsNotYetExpired(referenceTime).verify(signature)
}
}
}
/**
* Verify that a signature was created prior to the given reference date.
*
* @param referenceTime reference date for signature verification
* @return validator
*/
@JvmStatic
fun signatureIsAlreadyEffective(referenceTime: Date): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
if (signature.isHardRevocation) {
return
}
if (signature.creationTime > referenceTime) {
throw SignatureValidationException(
"Signature was created at ${signature.creationTime.formatUTC()} and" +
" is therefore not yet valid at ${referenceTime.formatUTC()}")
}
}
}
}
/**
* Verify that a signature is not yet expired.
*
* @param referenceTime reference date for signature verification
* @return validator
*/
@JvmStatic
fun signatureIsNotYetExpired(referenceTime: Date): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
if (signature.isHardRevocation) {
return
}
val expirationDate = signature.signatureExpirationDate
if (expirationDate != null && expirationDate < referenceTime) {
throw SignatureValidationException(
"Signature is already expired " +
"(expiration: ${expirationDate.formatUTC()}," +
" validation: ${referenceTime.formatUTC()})")
}
}
}
}
/**
* Verify that a signature is not malformed. A signature is malformed if it has no hashed
* creation time subpacket, it predates the creation time of the signing key, or it predates
* the creation date of the signing key binding signature.
*
* @param signingKey signing key
* @return validator
*/
@JvmStatic
fun signatureIsNotMalformed(signingKey: PGPPublicKey): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
if (signature.version >= 4) {
signatureHasHashedCreationTime().verify(signature)
}
signatureDoesNotPredateSigningKey(signingKey).verify(signature)
if (!signature.isOfType(SignatureType.PRIMARYKEY_BINDING)) {
signatureDoesNotPredateSigningKeyBindingDate(signingKey).verify(signature)
}
}
}
}
@JvmStatic
fun signatureDoesNotPredateSignee(signee: PGPPublicKey): SignatureValidator {
return signatureDoesNotPredateKeyCreation(signee)
}
/**
* Verify that a signature does not predate the creation time of the signing key.
*
* @param key signing key
* @return validator
*/
@JvmStatic
fun signatureDoesNotPredateSigningKey(signingKey: PGPPublicKey): SignatureValidator {
return signatureDoesNotPredateKeyCreation(signingKey)
}
/**
* Verify that a signature does not predate the creation time of the given key.
*
* @param key key
* @return validator
*/
@JvmStatic
fun signatureDoesNotPredateKeyCreation(key: PGPPublicKey): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
if (key.creationTime > signature.creationTime) {
throw SignatureValidationException(
"Signature predates key" +
" (key creation: ${key.creationTime.formatUTC()}," +
" signature creation: ${signature.creationTime.formatUTC()})")
}
}
}
}
/**
* Verify that a signature has a hashed creation time subpacket.
*
* @return validator
*/
@JvmStatic
fun signatureHasHashedCreationTime(): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
if (SignatureSubpacketsUtil.getSignatureCreationTime(signature) == null) {
throw SignatureValidationException(
"Malformed signature." +
"Signature has no signature creation time subpacket in its hashed area.")
}
}
}
}
/**
* Verify that a signature does not predate the binding date of the signing key.
*
* @param signingKey signing key
* @return validator
*/
@JvmStatic
fun signatureDoesNotPredateSigningKeyBindingDate(
signingKey: PGPPublicKey
): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
if (signingKey.isMasterKey) {
return
}
if (signingKey
.getSignaturesOfType(SignatureType.SUBKEY_BINDING.code)
.asSequence()
.map {
if (signature.creationTime < it.creationTime) {
throw SignatureValidationException(
"Signature was created " +
"before the signing key was bound to the certificate.")
}
}
.none()) {
throw SignatureValidationException(
"Signing subkey does not have a subkey binding signature.")
}
}
}
}
/**
* Verify that a direct-key signature is correct.
*
* @param signingKey signing key
* @param signedKey signed key
* @return validator
*/
@JvmStatic
fun correctSignatureOverKey(
signingKey: PGPPublicKey,
signedKey: PGPPublicKey
): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
try {
signature.init(
OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
signingKey)
val valid =
if (signingKey.keyID == signedKey.keyID ||
signature.isOfType(SignatureType.DIRECT_KEY)) {
signature.verifyCertification(signedKey)
} else {
signature.verifyCertification(signingKey, signedKey)
}
if (!valid) {
throw SignatureValidationException("Signature is not correct.")
}
} catch (e: PGPException) {
throw SignatureValidationException(
"Cannot verify direct-key signature correctness", e)
} catch (e: ClassCastException) {
throw SignatureValidationException(
"Cannot verify direct-key signature correctness", e)
}
}
}
}
@JvmStatic
fun signatureIsCertification(): SignatureValidator {
return signatureIsOfType(
SignatureType.POSITIVE_CERTIFICATION,
SignatureType.CASUAL_CERTIFICATION,
SignatureType.GENERIC_CERTIFICATION,
SignatureType.NO_CERTIFICATION)
}
/**
* Verify that a signature type equals one of the given [SignatureType].
*
* @param signatureType one or more signature types
* @return validator
*/
@JvmStatic
fun signatureIsOfType(vararg signatureType: SignatureType): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
if (signatureType.none { signature.isOfType(it) }) {
throw SignatureValidationException(
"Signature is of type" +
" ${SignatureType.fromCode(signature.signatureType) ?:
("0x" + signature.signatureType.toString(16))}, " +
"while only ${signatureType.contentToString()} are allowed here.")
}
}
}
}
/**
* Verify that a signature over a user-id is correct.
*
* @param userId user-id
* @param certifiedKey key carrying the user-id
* @param certifyingKey key that created the signature.
* @return validator
*/
@JvmStatic
fun correctSignatureOverUserId(
userId: CharSequence,
certifiedKey: PGPPublicKey,
certifyingKey: PGPPublicKey
): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
try {
signature.init(
OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
certifyingKey)
if (!signature.verifyCertification(userId.toString(), certifiedKey)) {
throw SignatureValidationException(
"Signature over user-id '$userId' is not valid.")
}
} catch (e: PGPException) {
throw SignatureValidationException(
"Cannot verify signature over user-id '$userId'.", e)
} catch (e: ClassCastException) {
throw SignatureValidationException(
"Cannot verify signature over user-id '$userId'.", e)
}
}
}
}
/**
* Verify that a signature over a user-attribute packet is correct.
*
* @param userAttributes user attributes
* @param certifiedKey key carrying the user-attributes
* @param certifyingKey key that created the certification signature
* @return validator
*/
@JvmStatic
fun correctSignatureOverUserAttributes(
userAttributes: PGPUserAttributeSubpacketVector,
certifiedKey: PGPPublicKey,
certifyingKey: PGPPublicKey
): SignatureValidator {
return object : SignatureValidator() {
override fun verify(signature: PGPSignature) {
try {
signature.init(
OpenPGPImplementation.getInstance().pgpContentVerifierBuilderProvider(),
certifyingKey)
if (!signature.verifyCertification(userAttributes, certifiedKey)) {
throw SignatureValidationException(
"Signature over user-attributes is not correct.")
}
} catch (e: PGPException) {
throw SignatureValidationException(
"Cannot verify signature over user-attribute vector.", e)
} catch (e: ClassCastException) {
throw SignatureValidationException(
"Cannot verify signature over user-attribute vector.", e)
}
}
}
}
@JvmStatic
fun signatureWasCreatedInBounds(notBefore: Date?, notAfter: Date?): SignatureValidator {
return object : SignatureValidator() {