bool *selfsig, bool *othersig)
{
struct openpgp_packet_list *tmpsig;
- struct openpgp_publickey *sigkey = NULL;
+ struct openpgp_publickey *sigkeys = NULL, *curkey;
onak_status_t ret;
uint8_t hashtype;
uint8_t hash[64];
bool remove;
get_keyid(key, &keyid);
- if (othersig != NULL) {
- *othersig = false;
- }
if (selfsig != NULL) {
*selfsig = false;
}
}
}
- if (remove && dbctx->fetch_key_id(dbctx, sigid,
- &sigkey, false)) {
+ if (remove) {
+ dbctx->fetch_key_id(dbctx, sigid,
+ &sigkeys, false);
+ }
+
+ /*
+ * A 64 bit collision is probably a sign of something
+ * sneaky happening, but if the signature verifies we
+ * should keep it.
+ */
+ for (curkey = sigkeys; curkey != NULL;
+ curkey = curkey->next) {
- ret = onak_check_hash_sig(sigkey,
+ ret = onak_check_hash_sig(curkey,
(*sigs)->packet,
hash, hashtype);
if (othersig != NULL) {
*othersig = true;
}
+ break;
}
-
- free_publickey(sigkey);
- sigkey = NULL;
}
+
+ free_publickey(sigkeys);
+ sigkeys = NULL;
}
#endif
struct openpgp_signedpacket_list **siglist,
bool fullverify, bool needother)
{
- struct openpgp_signedpacket_list *tmp = NULL;
+ struct openpgp_signedpacket_list **orig, *tmp = NULL;
bool selfsig, othersig;
int removed = 0;
+ othersig = false;
+ orig = siglist;
while (siglist != NULL && *siglist != NULL) {
- selfsig = othersig = false;
+ selfsig = false;
removed += clean_sighashes(dbctx, key, (*siglist)->packet,
&(*siglist)->sigs, fullverify, &selfsig, &othersig);
- if (fullverify && (!selfsig || (needother && !othersig))) {
+ if (fullverify && !selfsig) {
/* Remove the UID/subkey if there's no selfsig */
tmp = *siglist;
*siglist = (*siglist)->next;
}
}
+ /*
+ * We need at least one UID to have a signature from another key,
+ * otherwise we remove all of them if needother is set.
+ */
+ if (needother && fullverify && !othersig) {
+ siglist = orig;
+ while (siglist != NULL && *siglist != NULL) {
+ tmp = *siglist;
+ *siglist = (*siglist)->next;
+ tmp->next = NULL;
+ free_signedpacket_list(tmp);
+ }
+ }
+
return removed;
}
uint64_t policies)
{
struct openpgp_publickey **curkey, *tmp;
+ struct openpgp_fingerprint fp;
int changed = 0, count = 0;
+ bool needother;
if (keys == NULL)
return 0;
count += dedupsubkeys(*curkey);
if (policies & (ONAK_CLEAN_CHECK_SIGHASH |
ONAK_CLEAN_VERIFY_SIGNATURES)) {
+
+ needother = policies & ONAK_CLEAN_NEED_OTHER_SIG;
+ if (needother) {
+ /*
+ * Check if we already have the key; if we do
+ * then we can skip the check to make sure we
+ * have signatures from other keys.
+ */
+ get_fingerprint((*curkey)->publickey, &fp);
+ tmp = NULL;
+ needother = dbctx->fetch_key(dbctx, &fp,
+ &tmp, false) == 0;
+ free_publickey(tmp);
+ }
+
count += clean_key_signatures(dbctx, *curkey,
policies & ONAK_CLEAN_VERIFY_SIGNATURES,
- policies & ONAK_CLEAN_NEED_OTHER_SIG);
+ needother);
}
if (count > 0) {
changed++;