{
case PDKIM_VERIFY_FAIL_BODY: return "PDKIM_VERIFY_FAIL_BODY";
case PDKIM_VERIFY_FAIL_MESSAGE: return "PDKIM_VERIFY_FAIL_MESSAGE";
+ case PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH: return "PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH";
case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE: return "PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE";
case PDKIM_VERIFY_INVALID_BUFFER_SIZE: return "PDKIM_VERIFY_INVALID_BUFFER_SIZE";
case PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD: return "PDKIM_VERIFY_INVALID_PUBKEY_DNSRECORD";
case PDKIM_ERR_BUFFER_TOO_SMALL: return US"BUFFER_TOO_SMALL";
case PDKIM_SIGN_PRIVKEY_WRAP: return US"PRIVKEY_WRAP";
case PDKIM_SIGN_PRIVKEY_B64D: return US"PRIVKEY_B64D";
- default: return "(unknown)";
+ default: return US"(unknown)";
}
}
case 'v':
pub->version = string_copy(cur_val); break;
case 'h':
+ pub->hashes = string_copy(cur_val); break;
case 'k':
-/* This field appears to never be used. Also, unclear why
-a 'k' (key-type_ would go in this field name. There is a field
-"keytype", also never used.
- pub->hashes = string_copy(cur_val);
-*/
break;
case 'g':
pub->granularity = string_copy(cur_val); break;
/* Set fallback defaults */
if (!pub->version ) pub->version = string_copy(PDKIM_PUB_RECORD_VERSION);
-else if (Ustrcmp(pub->version, PDKIM_PUB_RECORD_VERSION) != 0) return NULL;
+else if (Ustrcmp(pub->version, PDKIM_PUB_RECORD_VERSION) != 0)
+ {
+ DEBUG(D_acl) debug_printf(" Bad v= field\n");
+ return NULL;
+ }
if (!pub->granularity) pub->granularity = string_copy(US"*");
/*
if (pub->key.data)
return pub;
+DEBUG(D_acl) debug_printf(" Missing p= field\n");
return NULL;
}
#define HEADER_BUFFER_FRAG_SIZE 256
DLLEXPORT int
-pdkim_feed(pdkim_ctx *ctx, char *data, int len)
+pdkim_feed(pdkim_ctx * ctx, uschar * data, int len)
{
int p, rc;
}
DEBUG(D_acl) debug_printf(
- "PDKIM >> Header data for hash, canonicalized, in sequence >>>>>>>>>>>>>>\n");
+ "PDKIM >> Header data for hash, canonicalized, in sequence >>>>>>>>>>>>\n");
/* SIGNING ---------------------------------------------------------------- */
/* When signing, walk through our header list and add them to the hash. As we
if (!(sig->pubkey = pdkim_key_from_dns(ctx, sig, &vctx, err)))
goto NEXT_VERIFY;
+ /* If the pubkey limits to a list of specific hashes, ignore sigs that
+ do not have the hash part of the sig algorithm matching */
+
+ if (sig->pubkey->hashes)
+ {
+ const uschar * list = sig->pubkey->hashes, * ele;
+ int sep = ':';
+ while ((ele = string_nextinlist(&list, &sep, NULL, 0)))
+ if (Ustrcmp(ele, pdkim_algos[sig->algo] + 4) == 0) break;
+ if (!ele)
+ {
+ DEBUG(D_acl) debug_printf("pubkey h=%s vs sig a=%s\n",
+ sig->pubkey->hashes, pdkim_algos[sig->algo]);
+ sig->verify_status = PDKIM_VERIFY_FAIL;
+ sig->verify_ext_status = PDKIM_VERIFY_FAIL_SIG_ALGO_MISMATCH;
+ goto NEXT_VERIFY;
+ }
+ }
+
/* Check the signature */
if ((*err = exim_rsa_verify(&vctx, is_sha1, &hhash, &sig->sighash)))
{
pdkim_signature s = *sig;
ev_ctx vctx;
- debug_printf("PDKIM (checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
+ debug_printf("PDKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
if (!pdkim_key_from_dns(ctx, &s, &vctx, errstr))
debug_printf("WARNING: bad dkim key in dns\n");
- debug_printf("PDKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
+ debug_printf("PDKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
}
return ctx;
}