if (!ctx)
return -ENOMEM;
+ /* If the digest is supported by systemd-resolved but disabled by host policy, also return -EOPNOTSUPP
+ */
if (EVP_DigestInit_ex(ctx, md_algorithm, NULL) <= 0)
- return -EIO;
+ return -EOPNOTSUPP;
if (EVP_DigestUpdate(ctx, wire_format, encoded_length) <= 0)
return -EIO;
int dnssec_verify_dnskey_by_ds_search(DnsResourceRecord *dnskey, DnsAnswer *validated_ds) {
DnsResourceRecord *ds;
DnsAnswerFlags flags;
+ bool found_unsupported_algorithm = false;
int r;
assert(dnskey);
continue;
r = dnssec_verify_dnskey_by_ds(dnskey, ds, false);
- if (IN_SET(r, -EKEYREJECTED, -EOPNOTSUPP))
- continue; /* The DNSKEY is revoked or otherwise invalid, or we don't support the digest algorithm */
+ if (r == -EKEYREJECTED)
+ continue; /* The DNSKEY is revoked or otherwise invalid. */
+ if (r == -EOPNOTSUPP) {
+ found_unsupported_algorithm = true;
+ continue;
+ }
if (r < 0)
return r;
if (r > 0)
return 1;
}
+ if (found_unsupported_algorithm)
+ return -EOPNOTSUPP;
+
return 0;
}
DNS_ANSWER_FOREACH_ITEM(item, t->answer) {
r = dnssec_verify_dnskey_by_ds_search(item->rr, t->validated_keys);
- if (r < 0)
+ if (r < 0 && r != -EOPNOTSUPP)
return r;
if (r == 0)
continue;
- /* If so, the DNSKEY is validated too. */
- r = dns_answer_add_extend(&t->validated_keys, item->rr, item->ifindex, item->flags|DNS_ANSWER_AUTHENTICATED, item->rrsig);
+ /* If so, the DNSKEY is validated too, but only mark it authenticated if the DS verification
+ * succeeded with a known algorithm. */
+ if (r == -EOPNOTSUPP)
+ r = dns_answer_add_extend(&t->validated_keys, item->rr, item->ifindex, item->flags, NULL);
+ else
+ r = dns_answer_add_extend(&t->validated_keys, item->rr, item->ifindex, item->flags|DNS_ANSWER_AUTHENTICATED, item->rrsig);
+
if (r < 0)
return r;
}