1
0
Fork 0
mirror of https://github.com/pgpainless/pgpainless.git synced 2025-12-10 06:11:08 +01:00

Fix signature creation using keys without preferred algorithms

This commit is contained in:
Paul Schaub 2021-01-21 13:47:43 +01:00
parent 831dbb3c5d
commit 74c0c8a32e
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
4 changed files with 245 additions and 2 deletions

View file

@ -16,6 +16,8 @@
package org.pgpainless.key.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
@ -42,6 +44,9 @@ public class OpenPgpKeyAttributeUtil {
if (signatureType == SignatureType.POSITIVE_CERTIFICATION
|| signatureType == SignatureType.GENERIC_CERTIFICATION) {
int[] hashAlgos = signature.getHashedSubPackets().getPreferredHashAlgorithms();
if (hashAlgos == null) {
continue;
}
for (int h : hashAlgos) {
hashAlgorithms.add(HashAlgorithm.fromId(h));
}
@ -53,4 +58,40 @@ public class OpenPgpKeyAttributeUtil {
}
return hashAlgorithms;
}
/**
* Return the hash algorithm that was used in the latest self signature.
*
* @param publicKey public key
* @return list of hash algorithm
*/
public static List<HashAlgorithm> guessPreferredHashAlgorithms(PGPPublicKey publicKey) {
HashAlgorithm hashAlgorithm = null;
Date lastCreationDate = null;
Iterator<?> keySignatures = publicKey.getSignatures();
while (keySignatures.hasNext()) {
PGPSignature signature = (PGPSignature) keySignatures.next();
if (signature.getKeyID() != publicKey.getKeyID()) {
continue;
}
SignatureType signatureType = SignatureType.valueOf(signature.getSignatureType());
if (signatureType != SignatureType.POSITIVE_CERTIFICATION
&& signatureType != SignatureType.GENERIC_CERTIFICATION) {
continue;
}
Date creationDate = signature.getCreationTime();
if (lastCreationDate == null || lastCreationDate.before(creationDate)) {
lastCreationDate = creationDate;
hashAlgorithm = HashAlgorithm.fromId(signature.getHashAlgorithm());
}
}
if (hashAlgorithm == null) {
return Collections.emptyList();
}
return Collections.singletonList(hashAlgorithm);
}
}

View file

@ -37,14 +37,18 @@ public class SignatureUtils {
private static BcPGPContentSignerBuilder getPgpContentSignerBuilderForKey(PGPPublicKey publicKey) {
List<HashAlgorithm> preferredHashAlgorithms = OpenPgpKeyAttributeUtil.getPreferredHashAlgorithms(publicKey);
if (preferredHashAlgorithms.isEmpty()) {
preferredHashAlgorithms = OpenPgpKeyAttributeUtil.guessPreferredHashAlgorithms(publicKey);
}
HashAlgorithm hashAlgorithm = negotiateHashAlgorithm(preferredHashAlgorithms);
return new BcPGPContentSignerBuilder(publicKey.getAlgorithm(), hashAlgorithm.getAlgorithmId());
}
private static HashAlgorithm negotiateHashAlgorithm(List<HashAlgorithm> preferredHashAlgorithms) {
// TODO: Match our list of supported hash algorithms against the list, to determine the best suitable algo.
// For now we just take the first algorithm in the list and hope that BC has support for it.
if (preferredHashAlgorithms.isEmpty()) {
return HashAlgorithm.SHA512;
}
return preferredHashAlgorithms.get(0);
}
}