Do not attempt to verify signatures made by external keys using primary key.

This aims at fixing #266 in combination with #267.
This commit is contained in:
Paul Schaub 2022-04-05 14:10:04 +02:00
parent 0bce68d6ee
commit f6c6b9aded
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
4 changed files with 33 additions and 0 deletions

View File

@ -94,6 +94,10 @@ public final class KeyRingValidator {
List<PGPSignature> signatures = CollectionUtils.iteratorToList(userIdSigs); List<PGPSignature> signatures = CollectionUtils.iteratorToList(userIdSigs);
Collections.sort(signatures, new SignatureCreationDateComparator(SignatureCreationDateComparator.Order.NEW_TO_OLD)); Collections.sort(signatures, new SignatureCreationDateComparator(SignatureCreationDateComparator.Order.NEW_TO_OLD));
for (PGPSignature signature : signatures) { for (PGPSignature signature : signatures) {
if (signature.getKeyID() != primaryKey.getKeyID()) {
// Signature was not made by primary key
continue;
}
try { try {
if (SignatureType.valueOf(signature.getSignatureType()) == SignatureType.CERTIFICATION_REVOCATION) { if (SignatureType.valueOf(signature.getSignatureType()) == SignatureType.CERTIFICATION_REVOCATION) {
if (SignatureVerifier.verifyUserIdRevocation(userId, signature, primaryKey, policy, validationDate)) { if (SignatureVerifier.verifyUserIdRevocation(userId, signature, primaryKey, policy, validationDate)) {
@ -116,6 +120,10 @@ public final class KeyRingValidator {
Iterator<PGPSignature> userAttributeSignatureIterator = primaryKey.getSignaturesForUserAttribute(userAttribute); Iterator<PGPSignature> userAttributeSignatureIterator = primaryKey.getSignaturesForUserAttribute(userAttribute);
while (userAttributeSignatureIterator.hasNext()) { while (userAttributeSignatureIterator.hasNext()) {
PGPSignature signature = userAttributeSignatureIterator.next(); PGPSignature signature = userAttributeSignatureIterator.next();
if (signature.getKeyID() != primaryKey.getKeyID()) {
// Signature was not made by primary key
continue;
}
try { try {
if (SignatureType.valueOf(signature.getSignatureType()) == SignatureType.CERTIFICATION_REVOCATION) { if (SignatureType.valueOf(signature.getSignatureType()) == SignatureType.CERTIFICATION_REVOCATION) {
if (SignatureVerifier.verifyUserAttributesRevocation(userAttribute, signature, primaryKey, policy, validationDate)) { if (SignatureVerifier.verifyUserAttributesRevocation(userAttribute, signature, primaryKey, policy, validationDate)) {

View File

@ -72,6 +72,10 @@ public final class CertificateValidator {
Iterator<PGPSignature> primaryKeyRevocationIterator = primaryKey.getSignaturesOfType(SignatureType.KEY_REVOCATION.getCode()); Iterator<PGPSignature> primaryKeyRevocationIterator = primaryKey.getSignaturesOfType(SignatureType.KEY_REVOCATION.getCode());
while (primaryKeyRevocationIterator.hasNext()) { while (primaryKeyRevocationIterator.hasNext()) {
PGPSignature revocation = primaryKeyRevocationIterator.next(); PGPSignature revocation = primaryKeyRevocationIterator.next();
if (revocation.getKeyID() != primaryKey.getKeyID()) {
// Revocation was not made by primary key, skip
// TODO: What about external revocation keys?
}
try { try {
if (SignatureVerifier.verifyKeyRevocationSignature(revocation, primaryKey, policy, signature.getCreationTime())) { if (SignatureVerifier.verifyKeyRevocationSignature(revocation, primaryKey, policy, signature.getCreationTime())) {
directKeySignatures.add(revocation); directKeySignatures.add(revocation);
@ -86,6 +90,10 @@ public final class CertificateValidator {
Iterator<PGPSignature> keySignatures = primaryKey.getSignaturesOfType(SignatureType.DIRECT_KEY.getCode()); Iterator<PGPSignature> keySignatures = primaryKey.getSignaturesOfType(SignatureType.DIRECT_KEY.getCode());
while (keySignatures.hasNext()) { while (keySignatures.hasNext()) {
PGPSignature keySignature = keySignatures.next(); PGPSignature keySignature = keySignatures.next();
if (keySignature.getKeyID() != primaryKey.getKeyID()) {
// Signature was not made by primary key, skip
continue;
}
try { try {
if (SignatureVerifier.verifyDirectKeySignature(keySignature, primaryKey, policy, signature.getCreationTime())) { if (SignatureVerifier.verifyDirectKeySignature(keySignature, primaryKey, policy, signature.getCreationTime())) {
directKeySignatures.add(keySignature); directKeySignatures.add(keySignature);
@ -112,6 +120,10 @@ public final class CertificateValidator {
Iterator<PGPSignature> userIdSigs = primaryKey.getSignaturesForID(userId); Iterator<PGPSignature> userIdSigs = primaryKey.getSignaturesForID(userId);
while (userIdSigs.hasNext()) { while (userIdSigs.hasNext()) {
PGPSignature userIdSig = userIdSigs.next(); PGPSignature userIdSig = userIdSigs.next();
if (userIdSig.getKeyID() != primaryKey.getKeyID()) {
// Sig was made by external key, skip
continue;
}
try { try {
if (SignatureVerifier.verifySignatureOverUserId(userId, userIdSig, primaryKey, policy, signature.getCreationTime())) { if (SignatureVerifier.verifySignatureOverUserId(userId, userIdSig, primaryKey, policy, signature.getCreationTime())) {
signaturesOnUserId.add(userIdSig); signaturesOnUserId.add(userIdSig);
@ -168,6 +180,10 @@ public final class CertificateValidator {
Iterator<PGPSignature> bindingRevocations = signingSubkey.getSignaturesOfType(SignatureType.SUBKEY_REVOCATION.getCode()); Iterator<PGPSignature> bindingRevocations = signingSubkey.getSignaturesOfType(SignatureType.SUBKEY_REVOCATION.getCode());
while (bindingRevocations.hasNext()) { while (bindingRevocations.hasNext()) {
PGPSignature revocation = bindingRevocations.next(); PGPSignature revocation = bindingRevocations.next();
if (revocation.getKeyID() != primaryKey.getKeyID()) {
// Subkey Revocation was not made by primary key, skip
continue;
}
try { try {
if (SignatureVerifier.verifySubkeyBindingRevocation(revocation, primaryKey, signingSubkey, policy, signature.getCreationTime())) { if (SignatureVerifier.verifySubkeyBindingRevocation(revocation, primaryKey, signingSubkey, policy, signature.getCreationTime())) {
subkeySigs.add(revocation); subkeySigs.add(revocation);

View File

@ -209,10 +209,15 @@ public final class SignaturePicker {
Iterator<PGPSignature> userIdSigIterator = primaryKey.getSignaturesForID(userId); Iterator<PGPSignature> userIdSigIterator = primaryKey.getSignaturesForID(userId);
List<PGPSignature> signatures = CollectionUtils.iteratorToList(userIdSigIterator); List<PGPSignature> signatures = CollectionUtils.iteratorToList(userIdSigIterator);
Collections.sort(signatures, new SignatureCreationDateComparator()); Collections.sort(signatures, new SignatureCreationDateComparator());
PGPSignature mostRecentUserIdCertification = null; PGPSignature mostRecentUserIdCertification = null;
for (PGPSignature signature : signatures) { for (PGPSignature signature : signatures) {
if (primaryKey.getKeyID() != signature.getKeyID()) {
// Signature not made by primary key
continue;
}
try { try {
SignatureVerifier.verifyUserIdCertification(userId, signature, primaryKey, policy, validationDate); SignatureVerifier.verifyUserIdCertification(userId, signature, primaryKey, policy, validationDate);
} catch (SignatureValidationException e) { } catch (SignatureValidationException e) {

View File

@ -89,6 +89,7 @@ public final class SignatureVerifier {
*/ */
public static boolean verifyUserIdCertification(String userId, PGPSignature signature, PGPPublicKey signingKey, PGPPublicKey keyWithUserId, Policy policy, Date validationDate) public static boolean verifyUserIdCertification(String userId, PGPSignature signature, PGPPublicKey signingKey, PGPPublicKey keyWithUserId, Policy policy, Date validationDate)
throws SignatureValidationException { throws SignatureValidationException {
SignatureValidator.wasPossiblyMadeByKey(signingKey).verify(signature);
SignatureValidator.signatureIsCertification().verify(signature); SignatureValidator.signatureIsCertification().verify(signature);
SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature); SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature);
SignatureValidator.signatureIsEffective(validationDate).verify(signature); SignatureValidator.signatureIsEffective(validationDate).verify(signature);
@ -129,6 +130,7 @@ public final class SignatureVerifier {
*/ */
public static boolean verifyUserIdRevocation(String userId, PGPSignature signature, PGPPublicKey signingKey, PGPPublicKey keyWithUserId, Policy policy, Date validationDate) public static boolean verifyUserIdRevocation(String userId, PGPSignature signature, PGPPublicKey signingKey, PGPPublicKey keyWithUserId, Policy policy, Date validationDate)
throws SignatureValidationException { throws SignatureValidationException {
SignatureValidator.wasPossiblyMadeByKey(signingKey).verify(signature);
SignatureValidator.signatureIsOfType(SignatureType.CERTIFICATION_REVOCATION).verify(signature); SignatureValidator.signatureIsOfType(SignatureType.CERTIFICATION_REVOCATION).verify(signature);
SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature); SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature);
SignatureValidator.signatureIsEffective(validationDate).verify(signature); SignatureValidator.signatureIsEffective(validationDate).verify(signature);
@ -174,6 +176,7 @@ public final class SignatureVerifier {
PGPPublicKey keyWithUserAttributes, Policy policy, PGPPublicKey keyWithUserAttributes, Policy policy,
Date validationDate) Date validationDate)
throws SignatureValidationException { throws SignatureValidationException {
SignatureValidator.wasPossiblyMadeByKey(signingKey).verify(signature);
SignatureValidator.signatureIsCertification().verify(signature); SignatureValidator.signatureIsCertification().verify(signature);
SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature); SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature);
SignatureValidator.signatureIsEffective(validationDate).verify(signature); SignatureValidator.signatureIsEffective(validationDate).verify(signature);
@ -219,6 +222,7 @@ public final class SignatureVerifier {
PGPPublicKey keyWithUserAttributes, Policy policy, PGPPublicKey keyWithUserAttributes, Policy policy,
Date validationDate) Date validationDate)
throws SignatureValidationException { throws SignatureValidationException {
SignatureValidator.wasPossiblyMadeByKey(signingKey).verify(signature);
SignatureValidator.signatureIsOfType(SignatureType.CERTIFICATION_REVOCATION).verify(signature); SignatureValidator.signatureIsOfType(SignatureType.CERTIFICATION_REVOCATION).verify(signature);
SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature); SignatureValidator.signatureStructureIsAcceptable(signingKey, policy).verify(signature);
SignatureValidator.signatureIsEffective(validationDate).verify(signature); SignatureValidator.signatureIsEffective(validationDate).verify(signature);