mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-22 19:08:00 +01:00
Kotlin conversion: SignatureVerifier
This commit is contained in:
parent
dc05a492f5
commit
19b45644ae
4 changed files with 596 additions and 494 deletions
|
@ -1,486 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
package org.pgpainless.signature.consumer;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
|
||||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
|
||||||
import org.bouncycastle.openpgp.PGPSignature;
|
|
||||||
import org.bouncycastle.openpgp.PGPUserAttributeSubpacketVector;
|
|
||||||
import org.pgpainless.algorithm.SignatureType;
|
|
||||||
import org.pgpainless.exception.SignatureValidationException;
|
|
||||||
import org.pgpainless.implementation.ImplementationFactory;
|
|
||||||
import org.pgpainless.policy.Policy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collection of static methods for signature verification.
|
|
||||||
* Signature verification entails validation of certain criteria (see {@link SignatureValidator}), as well as
|
|
||||||
* cryptographic verification of signature correctness.
|
|
||||||
*/
|
|
||||||
public final class SignatureVerifier {
|
|
||||||
|
|
||||||
private SignatureVerifier() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 referenceDate reference date for signature verification
|
|
||||||
* @return true if signature verification is successful
|
|
||||||
*
|
|
||||||
* @throws SignatureValidationException if signature verification fails for some reason
|
|
||||||
*/
|
|
||||||
public static boolean verifySignatureOverUserId(String userId, PGPSignature signature, PGPPublicKey signingKey,
|
|
||||||
PGPPublicKey keyWithUserId, Policy policy, Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
SignatureType type = SignatureType.valueOf(signature.getSignatureType());
|
|
||||||
switch (type) {
|
|
||||||
case GENERIC_CERTIFICATION:
|
|
||||||
case NO_CERTIFICATION:
|
|
||||||
case CASUAL_CERTIFICATION:
|
|
||||||
case POSITIVE_CERTIFICATION:
|
|
||||||
return verifyUserIdCertification(userId, signature, signingKey, keyWithUserId, policy, referenceDate);
|
|
||||||
case CERTIFICATION_REVOCATION:
|
|
||||||
return verifyUserIdRevocation(userId, signature, signingKey, keyWithUserId, policy, referenceDate);
|
|
||||||
default:
|
|
||||||
throw new 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 referenceDate reference date for signature verification
|
|
||||||
* @return true if the self-signature is verified successfully
|
|
||||||
*
|
|
||||||
* @throws SignatureValidationException if signature verification fails for some reason
|
|
||||||
*/
|
|
||||||
public static boolean verifyUserIdCertification(String userId, PGPSignature signature, PGPPublicKey primaryKey,
|
|
||||||
Policy policy, Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
return verifyUserIdCertification(userId, signature, primaryKey, primaryKey, policy, referenceDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 referenceDate reference date for signature verification
|
|
||||||
* @return true if signature verification is successful
|
|
||||||
*
|
|
||||||
* @throws SignatureValidationException if signature verification fails for some reason
|
|
||||||
*/
|
|
||||||
public static boolean verifyUserIdCertification(String userId, PGPSignature signature, PGPPublicKey signingKey,
|
|
||||||
PGPPublicKey keyWithUserId, Policy policy, Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
SignatureValidator.wasPossiblyMadeByKey(signingKey).verify(signature);
|
|
||||||
SignatureValidator.signatureIsCertification().verify(signature);
|
|
||||||
SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature);
|
|
||||||
SignatureValidator.signatureIsEffective(referenceDate).verify(signature);
|
|
||||||
SignatureValidator.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 referenceDate 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
|
|
||||||
*/
|
|
||||||
public static boolean verifyUserIdRevocation(String userId, PGPSignature signature, PGPPublicKey primaryKey,
|
|
||||||
Policy policy, Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
return verifyUserIdRevocation(userId, signature, primaryKey, primaryKey, policy, referenceDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 referenceDate 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
|
|
||||||
*/
|
|
||||||
public static boolean verifyUserIdRevocation(String userId, PGPSignature signature, PGPPublicKey signingKey,
|
|
||||||
PGPPublicKey keyWithUserId, Policy policy, Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
SignatureValidator.wasPossiblyMadeByKey(signingKey).verify(signature);
|
|
||||||
SignatureValidator.signatureIsOfType(SignatureType.CERTIFICATION_REVOCATION).verify(signature);
|
|
||||||
SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature);
|
|
||||||
SignatureValidator.signatureIsEffective(referenceDate).verify(signature);
|
|
||||||
SignatureValidator.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 referenceDate reference date for signature verification
|
|
||||||
* @return true if the signature can be verified successfully
|
|
||||||
*
|
|
||||||
* @throws SignatureValidationException if signature verification fails for some reason
|
|
||||||
*/
|
|
||||||
public static boolean verifyUserAttributesCertification(PGPUserAttributeSubpacketVector userAttributes,
|
|
||||||
PGPSignature signature, PGPPublicKey primaryKey,
|
|
||||||
Policy policy, Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
return verifyUserAttributesCertification(userAttributes, signature, primaryKey, primaryKey, policy,
|
|
||||||
referenceDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 keyWithUserAttributes key that carries the user-attributes certification
|
|
||||||
* @param policy policy
|
|
||||||
* @param referenceDate reference date for signature verification
|
|
||||||
* @return true if the signature can be verified successfully
|
|
||||||
*
|
|
||||||
* @throws SignatureValidationException if signature verification fails for some reason
|
|
||||||
*/
|
|
||||||
public static boolean verifyUserAttributesCertification(PGPUserAttributeSubpacketVector userAttributes,
|
|
||||||
PGPSignature signature, PGPPublicKey signingKey,
|
|
||||||
PGPPublicKey keyWithUserAttributes, Policy policy,
|
|
||||||
Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
SignatureValidator.wasPossiblyMadeByKey(signingKey).verify(signature);
|
|
||||||
SignatureValidator.signatureIsCertification().verify(signature);
|
|
||||||
SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature);
|
|
||||||
SignatureValidator.signatureIsEffective(referenceDate).verify(signature);
|
|
||||||
SignatureValidator.correctSignatureOverUserAttributes(userAttributes, keyWithUserAttributes, 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 referenceDate reference date for signature verification
|
|
||||||
* @return true if the revocation signature can be verified successfully
|
|
||||||
*
|
|
||||||
* @throws SignatureValidationException if signature verification fails for some reason
|
|
||||||
*/
|
|
||||||
public static boolean verifyUserAttributesRevocation(PGPUserAttributeSubpacketVector userAttributes,
|
|
||||||
PGPSignature signature, PGPPublicKey primaryKey,
|
|
||||||
Policy policy, Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
return verifyUserAttributesRevocation(userAttributes, signature, primaryKey, primaryKey, policy, referenceDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify a user-attributes revocation signature.
|
|
||||||
*
|
|
||||||
* @param userAttributes user-attributes
|
|
||||||
* @param signature revocation signature
|
|
||||||
* @param signingKey revocation key
|
|
||||||
* @param keyWithUserAttributes key that carries the user-attributes
|
|
||||||
* @param policy policy
|
|
||||||
* @param referenceDate reference date for signature verification
|
|
||||||
* @return true if the revocation signature can be verified successfully
|
|
||||||
*
|
|
||||||
* @throws SignatureValidationException if signature verification fails for some reason
|
|
||||||
*/
|
|
||||||
public static boolean verifyUserAttributesRevocation(PGPUserAttributeSubpacketVector userAttributes,
|
|
||||||
PGPSignature signature, PGPPublicKey signingKey,
|
|
||||||
PGPPublicKey keyWithUserAttributes, Policy policy,
|
|
||||||
Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
SignatureValidator.wasPossiblyMadeByKey(signingKey).verify(signature);
|
|
||||||
SignatureValidator.signatureIsOfType(SignatureType.CERTIFICATION_REVOCATION).verify(signature);
|
|
||||||
SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature);
|
|
||||||
SignatureValidator.signatureIsEffective(referenceDate).verify(signature);
|
|
||||||
SignatureValidator.correctSignatureOverUserAttributes(userAttributes, keyWithUserAttributes, 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 referenceDate reference date for signature verification
|
|
||||||
* @return true if the binding signature can be verified successfully
|
|
||||||
*
|
|
||||||
* @throws SignatureValidationException if signature verification fails for some reason
|
|
||||||
*/
|
|
||||||
public static boolean verifySubkeyBindingSignature(PGPSignature signature, PGPPublicKey primaryKey,
|
|
||||||
PGPPublicKey subkey, Policy policy, Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
SignatureValidator.signatureIsOfType(SignatureType.SUBKEY_BINDING).verify(signature);
|
|
||||||
SignatureValidator.signatureStructureIsAcceptable(primaryKey, policy).verify(signature);
|
|
||||||
SignatureValidator.signatureDoesNotPredateSignee(subkey).verify(signature);
|
|
||||||
SignatureValidator.signatureIsEffective(referenceDate).verify(signature);
|
|
||||||
SignatureValidator.hasValidPrimaryKeyBindingSignatureIfRequired(primaryKey, subkey, policy, referenceDate)
|
|
||||||
.verify(signature);
|
|
||||||
SignatureValidator.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 referenceDate 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
|
|
||||||
*/
|
|
||||||
public static boolean verifySubkeyBindingRevocation(PGPSignature signature, PGPPublicKey primaryKey,
|
|
||||||
PGPPublicKey subkey, Policy policy, Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
SignatureValidator.signatureIsOfType(SignatureType.SUBKEY_REVOCATION).verify(signature);
|
|
||||||
SignatureValidator.signatureStructureIsAcceptable(primaryKey, policy).verify(signature);
|
|
||||||
SignatureValidator.signatureDoesNotPredateSignee(subkey).verify(signature);
|
|
||||||
SignatureValidator.signatureIsEffective(referenceDate).verify(signature);
|
|
||||||
SignatureValidator.correctSignatureOverKey(primaryKey, subkey).verify(signature);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify a direct-key self-signature.
|
|
||||||
*
|
|
||||||
* @param signature signature
|
|
||||||
* @param primaryKey primary key
|
|
||||||
* @param policy policy
|
|
||||||
* @param referenceDate reference date for signature verification
|
|
||||||
* @return true if the signature can be verified successfully
|
|
||||||
*
|
|
||||||
* @throws SignatureValidationException if signature verification fails for some reason
|
|
||||||
*/
|
|
||||||
public static boolean verifyDirectKeySignature(PGPSignature signature, PGPPublicKey primaryKey,
|
|
||||||
Policy policy, Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
return verifyDirectKeySignature(signature, primaryKey, primaryKey, policy, referenceDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify a direct-key signature.
|
|
||||||
*
|
|
||||||
* @param signature signature
|
|
||||||
* @param signingKey signing key
|
|
||||||
* @param signedKey signed key
|
|
||||||
* @param policy policy
|
|
||||||
* @param referenceDate reference date for signature verification
|
|
||||||
* @return true if signature verification is successful
|
|
||||||
*
|
|
||||||
* @throws SignatureValidationException if signature verification fails for some reason
|
|
||||||
*/
|
|
||||||
public static boolean verifyDirectKeySignature(PGPSignature signature, PGPPublicKey signingKey,
|
|
||||||
PGPPublicKey signedKey, Policy policy, Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
SignatureValidator.signatureIsOfType(SignatureType.DIRECT_KEY).verify(signature);
|
|
||||||
SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature);
|
|
||||||
SignatureValidator.signatureDoesNotPredateSignee(signedKey).verify(signature);
|
|
||||||
SignatureValidator.signatureIsEffective(referenceDate).verify(signature);
|
|
||||||
SignatureValidator.correctSignatureOverKey(signingKey, signedKey).verify(signature);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify a key revocation signature.
|
|
||||||
*
|
|
||||||
* @param signature signature
|
|
||||||
* @param primaryKey primary key
|
|
||||||
* @param policy policy
|
|
||||||
* @param referenceDate reference date for signature verification
|
|
||||||
* @return true if signature verification is successful
|
|
||||||
*
|
|
||||||
* @throws SignatureValidationException if signature verification fails for some reason
|
|
||||||
*/
|
|
||||||
public static boolean verifyKeyRevocationSignature(PGPSignature signature, PGPPublicKey primaryKey,
|
|
||||||
Policy policy, Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
SignatureValidator.signatureIsOfType(SignatureType.KEY_REVOCATION).verify(signature);
|
|
||||||
SignatureValidator.signatureStructureIsAcceptable(primaryKey, policy).verify(signature);
|
|
||||||
SignatureValidator.signatureIsEffective(referenceDate).verify(signature);
|
|
||||||
SignatureValidator.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 referenceDate reference date of signature verification
|
|
||||||
* @return true if the signature is successfully verified
|
|
||||||
*
|
|
||||||
* @throws SignatureValidationException if the signature verification fails for some reason
|
|
||||||
*/
|
|
||||||
public static boolean verifyUninitializedSignature(PGPSignature signature, InputStream signedData,
|
|
||||||
PGPPublicKey signingKey, Policy policy, Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
initializeSignatureAndUpdateWithSignedData(signature, signedData, signingKey);
|
|
||||||
return verifyInitializedSignature(signature, signingKey, policy, referenceDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize a signature and then update it with the signed data from the given {@link 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
|
|
||||||
*/
|
|
||||||
public static void initializeSignatureAndUpdateWithSignedData(PGPSignature signature, InputStream signedData,
|
|
||||||
PGPPublicKey signingKey)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
try {
|
|
||||||
signature.init(ImplementationFactory.getInstance().getPgpContentVerifierBuilderProvider(), signingKey);
|
|
||||||
int read;
|
|
||||||
byte[] buf = new byte[8192];
|
|
||||||
byte lastByte = -1;
|
|
||||||
while ((read = signedData.read(buf)) != -1) {
|
|
||||||
// If we previously omitted a newline, but the stream is not yet empty, add it now
|
|
||||||
if (lastByte == (byte) '\n') {
|
|
||||||
signature.update(lastByte);
|
|
||||||
}
|
|
||||||
lastByte = buf[read - 1];
|
|
||||||
|
|
||||||
if (lastByte == (byte) '\n') {
|
|
||||||
// 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 (PGPException e) {
|
|
||||||
throw new SignatureValidationException("Cannot init signature.", e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new 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 referenceDate reference date for signature verification
|
|
||||||
* @return true if signature is verified successfully
|
|
||||||
*
|
|
||||||
* @throws SignatureValidationException if signature verification fails for some reason
|
|
||||||
*/
|
|
||||||
public static boolean verifyInitializedSignature(PGPSignature signature, PGPPublicKey signingKey, Policy policy,
|
|
||||||
Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
SignatureValidator.wasPossiblyMadeByKey(signingKey).verify(signature);
|
|
||||||
SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature);
|
|
||||||
SignatureValidator.signatureIsEffective(referenceDate).verify(signature);
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!signature.verify()) {
|
|
||||||
throw new SignatureValidationException("Signature is not correct.");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} catch (PGPException e) {
|
|
||||||
throw new SignatureValidationException("Could not verify signature correctness.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean verifyOnePassSignature(PGPSignature signature, PGPPublicKey signingKey,
|
|
||||||
OnePassSignatureCheck onePassSignature, Policy policy)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
try {
|
|
||||||
SignatureValidator.wasPossiblyMadeByKey(signingKey).verify(signature);
|
|
||||||
SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature);
|
|
||||||
SignatureValidator.signatureIsEffective().verify(signature);
|
|
||||||
} catch (SignatureValidationException e) {
|
|
||||||
throw new SignatureValidationException("Signature is not valid: " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (onePassSignature.getSignature() == null) {
|
|
||||||
throw new IllegalStateException("No comparison signature provided.");
|
|
||||||
}
|
|
||||||
if (!onePassSignature.getOnePassSignature().verify(signature)) {
|
|
||||||
throw new SignatureValidationException("Bad signature of key " +
|
|
||||||
Long.toHexString(signingKey.getKeyID()));
|
|
||||||
}
|
|
||||||
} catch (PGPException e) {
|
|
||||||
throw new SignatureValidationException("Could not verify correctness of One-Pass-Signature: " +
|
|
||||||
e.getMessage(), 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 referenceDate reference date for signature verification
|
|
||||||
* @return true if the signature is successfully verified
|
|
||||||
*
|
|
||||||
* @throws SignatureValidationException if signature verification fails for some reason
|
|
||||||
*/
|
|
||||||
public static boolean verifySignatureOverUserId(String userId, PGPSignature signature, PGPPublicKey primaryKey,
|
|
||||||
Policy policy, Date referenceDate)
|
|
||||||
throws SignatureValidationException {
|
|
||||||
return verifySignatureOverUserId(userId, signature, primaryKey, primaryKey, policy, referenceDate);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Classes related to OpenPGP signature verification.
|
|
||||||
*/
|
|
||||||
package org.pgpainless.signature.consumer;
|
|
|
@ -0,0 +1,596 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
|
||||||
|
//
|
||||||
|
// 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.pgpainless.algorithm.SignatureType
|
||||||
|
import org.pgpainless.exception.SignatureValidationException
|
||||||
|
import org.pgpainless.implementation.ImplementationFactory.Companion.getInstance
|
||||||
|
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.requireFromCode(signature.signatureType)
|
||||||
|
return when (type) {
|
||||||
|
SignatureType.GENERIC_CERTIFICATION,
|
||||||
|
SignatureType.NO_CERTIFICATION,
|
||||||
|
SignatureType.CASUAL_CERTIFICATION,
|
||||||
|
SignatureType.POSITIVE_CERTIFICATION ->
|
||||||
|
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(
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue