diff options
Diffstat (limited to 'lib/dns/dnssec.c')
-rw-r--r-- | lib/dns/dnssec.c | 69 |
1 files changed, 65 insertions, 4 deletions
diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c index baf3ec5..8ae29bc 100644 --- a/lib/dns/dnssec.c +++ b/lib/dns/dnssec.c @@ -16,7 +16,7 @@ */ /* - * $Id: dnssec.c,v 1.93.12.4 2009/06/08 23:47:00 tbox Exp $ + * $Id: dnssec.c,v 1.93.12.6 2009/06/22 23:47:18 tbox Exp $ */ /*! \file */ @@ -93,6 +93,7 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx, isc_result_t ret; int i = 0, n; dns_rdata_t *data; + dns_rdataset_t rdataset; n = dns_rdataset_count(set); @@ -100,8 +101,11 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx, if (data == NULL) return (ISC_R_NOMEMORY); - ret = dns_rdataset_first(set); + dns_rdataset_init(&rdataset); + dns_rdataset_clone(set, &rdataset); + ret = dns_rdataset_first(&rdataset); if (ret != ISC_R_SUCCESS) { + dns_rdataset_disassociate(&rdataset); isc_mem_put(mctx, data, n * sizeof(dns_rdata_t)); return (ret); } @@ -111,8 +115,8 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx, */ do { dns_rdata_init(&data[i]); - dns_rdataset_current(set, &data[i++]); - } while (dns_rdataset_next(set) == ISC_R_SUCCESS); + dns_rdataset_current(&rdataset, &data[i++]); + } while (dns_rdataset_next(&rdataset) == ISC_R_SUCCESS); /* * Sort the array. @@ -120,6 +124,7 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx, qsort(data, n, sizeof(dns_rdata_t), rdata_compare_wrapper); *rdata = data; *nrdata = n; + dns_rdataset_disassociate(&rdataset); return (ISC_R_SUCCESS); } @@ -890,3 +895,59 @@ failure: return (result); } + +/*% + * Does this key ('rdata') self sign the rrset ('rdataset')? + */ +isc_boolean_t +dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, + isc_boolean_t ignoretime, isc_mem_t *mctx) +{ + dst_key_t *dstkey = NULL; + dns_keytag_t keytag; + dns_rdata_dnskey_t key; + dns_rdata_rrsig_t sig; + dns_rdata_t sigrdata = DNS_RDATA_INIT; + isc_result_t result; + + INSIST(rdataset->type == dns_rdatatype_key || + rdataset->type == dns_rdatatype_dnskey); + if (rdataset->type == dns_rdatatype_key) { + INSIST(sigrdataset->type == dns_rdatatype_sig); + INSIST(sigrdataset->covers == dns_rdatatype_key); + } else { + INSIST(sigrdataset->type == dns_rdatatype_rrsig); + INSIST(sigrdataset->covers == dns_rdatatype_dnskey); + } + + result = dns_dnssec_keyfromrdata(name, rdata, mctx, &dstkey); + if (result != ISC_R_SUCCESS) + return (ISC_FALSE); + result = dns_rdata_tostruct(rdata, &key, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + keytag = dst_key_id(dstkey); + for (result = dns_rdataset_first(sigrdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(sigrdataset)) + { + dns_rdata_reset(&sigrdata); + dns_rdataset_current(sigrdataset, &sigrdata); + result = dns_rdata_tostruct(&sigrdata, &sig, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + if (sig.algorithm == key.algorithm && + sig.keyid == keytag) { + result = dns_dnssec_verify2(name, rdataset, dstkey, + ignoretime, mctx, + &sigrdata, NULL); + if (result == ISC_R_SUCCESS) { + dst_key_free(&dstkey); + return (ISC_TRUE); + } + } + } + dst_key_free(&dstkey); + return (ISC_FALSE); +} |