mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-23 19:38:00 +01:00
Explicitly reject non-self signatures when picking user-id self sigs
This commit is contained in:
parent
545c660815
commit
1f08815633
3 changed files with 48 additions and 0 deletions
|
@ -239,6 +239,7 @@ public class SignaturePicker {
|
||||||
PGPSignature latestUserIdCert = null;
|
PGPSignature latestUserIdCert = null;
|
||||||
for (PGPSignature signature : signatures) {
|
for (PGPSignature signature : signatures) {
|
||||||
try {
|
try {
|
||||||
|
SignatureValidator.verifyWasPossiblyMadeByKey(primaryKey, signature);
|
||||||
SignatureValidator.signatureIsCertification().verify(signature);
|
SignatureValidator.signatureIsCertification().verify(signature);
|
||||||
SignatureValidator.signatureStructureIsAcceptable(primaryKey, policy).verify(signature);
|
SignatureValidator.signatureStructureIsAcceptable(primaryKey, policy).verify(signature);
|
||||||
SignatureValidator.signatureIsAlreadyEffective(validationDate).verify(signature);
|
SignatureValidator.signatureIsAlreadyEffective(validationDate).verify(signature);
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.pgpainless.algorithm.SignatureSubpacket;
|
||||||
import org.pgpainless.algorithm.SignatureType;
|
import org.pgpainless.algorithm.SignatureType;
|
||||||
import org.pgpainless.exception.SignatureValidationException;
|
import org.pgpainless.exception.SignatureValidationException;
|
||||||
import org.pgpainless.implementation.ImplementationFactory;
|
import org.pgpainless.implementation.ImplementationFactory;
|
||||||
|
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
import org.pgpainless.policy.Policy;
|
import org.pgpainless.policy.Policy;
|
||||||
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil;
|
import org.pgpainless.signature.subpackets.SignatureSubpacketsUtil;
|
||||||
import org.pgpainless.util.BCUtil;
|
import org.pgpainless.util.BCUtil;
|
||||||
|
@ -103,6 +104,44 @@ public abstract class SignatureValidator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check, whether there is the possibility that the given signature was created by the given key.
|
||||||
|
* This method throws a {@link SignatureValidationException} if we can say with certainty that the signature
|
||||||
|
* was not created by the given key (e.g. if the sig carries another issuer, issuer fingerprint packet).
|
||||||
|
*
|
||||||
|
* If there is no information found in the signature about who created it (no issuer, no fingerprint),
|
||||||
|
* return true since it is plausible that the given key created the sig.
|
||||||
|
*
|
||||||
|
* @param signingKey signing key
|
||||||
|
* @param signature signature
|
||||||
|
* @return true only if the signing key either created the signature or the signature doesn't carry signer information
|
||||||
|
* @throws SignatureValidationException if the sig was not created by the key
|
||||||
|
*/
|
||||||
|
public static boolean verifyWasPossiblyMadeByKey(PGPPublicKey signingKey, PGPSignature signature) throws SignatureValidationException {
|
||||||
|
OpenPgpV4Fingerprint signingKeyFingerprint = new OpenPgpV4Fingerprint(signingKey);
|
||||||
|
|
||||||
|
Long issuer = SignatureSubpacketsUtil.getIssuerKeyIdAsLong(signature);
|
||||||
|
if (issuer != null) {
|
||||||
|
if (issuer != signingKey.getKeyID()) {
|
||||||
|
throw new SignatureValidationException("Signature was not created by " + signingKeyFingerprint + " (signature issuer: " + Long.toHexString(issuer) + ")");
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenPgpV4Fingerprint fingerprint = SignatureSubpacketsUtil.getIssuerFingerprintAsOpenPgpV4Fingerprint(signature);
|
||||||
|
if (fingerprint != null) {
|
||||||
|
if (!fingerprint.equals(signingKeyFingerprint)) {
|
||||||
|
throw new SignatureValidationException("Signature was not created by " + signingKeyFingerprint + " (signature fingerprint: " + fingerprint + ")");
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No issuer information found, so we cannot rule out that we did not create the sig
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean verifyUserIdCertification(String userId, PGPSignature signature, PGPPublicKey primaryKey, Policy policy, Date validationDate)
|
public static boolean verifyUserIdCertification(String userId, PGPSignature signature, PGPPublicKey primaryKey, Policy policy, Date validationDate)
|
||||||
throws SignatureValidationException {
|
throws SignatureValidationException {
|
||||||
return verifyUserIdCertification(userId, signature, primaryKey, primaryKey, policy, validationDate);
|
return verifyUserIdCertification(userId, signature, primaryKey, primaryKey, policy, validationDate);
|
||||||
|
|
|
@ -104,6 +104,14 @@ public class SignatureSubpacketsUtil {
|
||||||
return hashedOrUnhashed(signature, SignatureSubpacket.issuerKeyId);
|
return hashedOrUnhashed(signature, SignatureSubpacket.issuerKeyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Long getIssuerKeyIdAsLong(PGPSignature signature) {
|
||||||
|
IssuerKeyID keyID = getIssuerKeyId(signature);
|
||||||
|
if (keyID == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return keyID.getKeyID();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the revocation reason subpacket of the signature.
|
* Return the revocation reason subpacket of the signature.
|
||||||
* Since this packet is rather important for revocations, we only search for it in the
|
* Since this packet is rather important for revocations, we only search for it in the
|
||||||
|
|
Loading…
Reference in a new issue