int verbosity = 5;
ldns_rdf *
-ldns_dnssec_nsec3_closest_encloser(ldns_rdf *qname, ldns_rr_type qtype, ldns_rr_list *nsec3s)
+ldns_dnssec_nsec3_closest_encloser(ldns_rdf *qname,
+ ldns_rr_type qtype,
+ ldns_rr_list *nsec3s)
{
/* remember parameters, they must match */
uint8_t algorithm;
return result;
}
-ldns_status
-ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
- ldns_rr_list *nsecs,
- ldns_rr_list *rrsigs,
- ldns_pkt_rcode packet_rcode,
- ldns_rr_type packet_qtype,
- bool packet_nodata)
-{
- ldns_rdf *closest_encloser;
- ldns_rdf *wildcard;
- bool wildcard_covered = false;
- ldns_rdf *zone_name;
- ldns_rdf *hashed_name;
- size_t i;
-
- rrsigs = rrsigs;
-
- /* section 8.4 */
- if (packet_rcode == LDNS_RCODE_NXDOMAIN) {
- closest_encloser = ldns_dnssec_nsec3_closest_encloser(ldns_rr_owner(rr),
- ldns_rr_get_type(rr),
- nsecs);
-
- printf("[XX} NSEC3 denial for: ");
- ldns_rr_print(stdout, rr);
- printf("[XX] closest encloser: ");
- ldns_rdf_print(stdout, closest_encloser);
- printf("\n");
-
- wildcard = ldns_dname_new_frm_str("*");
- ldns_dname_cat(wildcard, closest_encloser);
-
- for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
- if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
- wildcard)) {
- printf("[XX] wildcard covered\n");
- wildcard_covered = true;
- }
- }
-
- if (!wildcard_covered) {
- return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
- }
- if (closest_encloser && wildcard_covered) {
- return LDNS_STATUS_OK;
- }
- return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
- } else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) {
- /* section 8.5 */
- hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
- ldns_rr_owner(rr)
- );
- zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
- ldns_dname_cat(hashed_name, zone_name);
- printf("[XX] hashed name: ");
- ldns_rdf_print(stdout, hashed_name);
- printf("\n");
- for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
- if (ldns_dname_compare(hashed_name, ldns_rr_owner(ldns_rr_list_rr(nsecs, i))) == 0) {
- if (!ldns_nsec_bitmap_covers_type(ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)), packet_qtype) &&
- !ldns_nsec_bitmap_covers_type(ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)), LDNS_RR_TYPE_CNAME)) {
- printf("exact match!\n");
- return LDNS_STATUS_OK;
- }
- }
- }
- return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
- } else if (packet_nodata && packet_qtype == LDNS_RR_TYPE_DS) {
- /* section 8.6 */
- /* note: up to XXX this is the same as for 8.5 */
- hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
- ldns_rr_owner(rr)
- );
- zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
- ldns_dname_cat(hashed_name, zone_name);
- printf("[XX] hashed name: ");
- ldns_rdf_print(stdout, hashed_name);
- printf("\n");
- for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
- if (ldns_dname_compare(hashed_name, ldns_rr_owner(ldns_rr_list_rr(nsecs, i))) == 0) {
- if (!ldns_nsec_bitmap_covers_type(ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)), LDNS_RR_TYPE_DS) &&
- !ldns_nsec_bitmap_covers_type(ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)), LDNS_RR_TYPE_CNAME)) {
- printf("exact match!\n");
- return LDNS_STATUS_OK;
- }
- }
- }
-
- /* XXX see note above */
- closest_encloser = ldns_dnssec_nsec3_closest_encloser(ldns_rr_owner(rr),
- ldns_rr_get_type(rr),
- nsecs);
-
- if (closest_encloser) {
- printf("[XX] closest encloser: ");
- ldns_rdf_print(stdout, closest_encloser);
- printf("\n");
- exit(0);
- }
- return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
-
- }
- return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
-}
-
-ldns_status
-ldns_dnssec_verify_denial(ldns_rr *rr,
- ldns_rr_list *nsecs,
- ldns_rr_list *rrsigs)
-{
- ldns_rdf *rr_name;
- ldns_rdf *wildcard_name;
- ldns_rdf *chopped_dname;
- ldns_rr *cur_nsec;
- size_t i;
- ldns_status result;
- /* needed for wildcard check on exact match */
- ldns_rr *rrsig;
- bool name_covered = false;
- bool type_covered = false;
- bool wildcard_covered = false;
- bool wildcard_type_covered = false;
-
- wildcard_name = ldns_dname_new_frm_str("*");
- rr_name = ldns_rr_owner(rr);
- chopped_dname = ldns_dname_left_chop(rr_name);
- result = ldns_dname_cat(wildcard_name, chopped_dname);
- if (result != LDNS_STATUS_OK) {
- return result;
- }
-
- ldns_rdf_deep_free(chopped_dname);
-
- for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
- cur_nsec = ldns_rr_list_rr(nsecs, i);
- if (ldns_dname_compare(rr_name, ldns_rr_owner(cur_nsec)) == 0) {
- /* see section 5.4 of RFC4035, if the label count of the NSEC's
- RRSIG is equal, then it is proven that wildcard expansion
- could not have been used to match the request */
- rrsig = ldns_dnssec_get_rrsig_for_name_and_type(ldns_rr_owner(cur_nsec), ldns_rr_get_type(cur_nsec), rrsigs);
- if (rrsig && ldns_rdf2native_int8(ldns_rr_rrsig_labels(rrsig)) == ldns_dname_label_count(rr_name)) {
- printf("[XX] wildcard covered from label count\n");
- wildcard_covered = true;
- }
-
- if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec), ldns_rr_get_type(rr))) {
- printf("[XX] type covered\n");
- type_covered = true;
- }
- }
- printf("[XX] Name covered?\n");
- if (ldns_nsec_covers_name(cur_nsec, rr_name)) {
- printf("[XX] yes!\n");
- name_covered = true;
- }
-
- if (ldns_dname_compare(wildcard_name, ldns_rr_owner(cur_nsec)) == 0) {
- printf("[XX] Wildcard type covered?\n");
- if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec), ldns_rr_get_type(rr))) {
- printf("[XX] yes!\n");
- wildcard_type_covered = true;
- }
- }
-
- printf("[XX] Wildcard covered?\n");
- if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) {
- printf("[XX] yes!\n");
- wildcard_covered = true;
- }
-
- }
-
- ldns_rdf_deep_free(wildcard_name);
-
- if (type_covered || !name_covered) {
- return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
- }
-
- if (wildcard_type_covered || !wildcard_covered) {
- return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
- }
-
- return LDNS_STATUS_OK;
-}
-
-
bool
ldns_dnssec_pkt_has_rrsigs(const ldns_pkt *pkt)
{
}
}
+DSA *
+ldns_key_buf2dsa(ldns_buffer *key)
+{
+ return ldns_key_buf2dsa_raw((unsigned char*)ldns_buffer_begin(key),
+ ldns_buffer_position(key));
+}
+
+DSA *
+ldns_key_buf2dsa_raw(unsigned char* key, size_t len)
+{
+ uint8_t T;
+ uint16_t length;
+ uint16_t offset;
+ DSA *dsa;
+ BIGNUM *Q; BIGNUM *P;
+ BIGNUM *G; BIGNUM *Y;
+
+ if(len == 0)
+ return NULL;
+ T = (uint8_t)key[0];
+ length = (64 + T * 8);
+ offset = 1;
+
+ if (T > 8) {
+ return NULL;
+ }
+ if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
+ return NULL;
+
+ Q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
+ offset += SHA_DIGEST_LENGTH;
+
+ P = BN_bin2bn(key+offset, (int)length, NULL);
+ offset += length;
+
+ G = BN_bin2bn(key+offset, (int)length, NULL);
+ offset += length;
+
+ Y = BN_bin2bn(key+offset, (int)length, NULL);
+ offset += length;
+
+ /* create the key and set its properties */
+ dsa = DSA_new();
+ dsa->p = P;
+ dsa->q = Q;
+ dsa->g = G;
+ dsa->pub_key = Y;
+
+ return dsa;
+}
+
+RSA *
+ldns_key_buf2rsa(ldns_buffer *key)
+{
+ return ldns_key_buf2rsa_raw((unsigned char*)ldns_buffer_begin(key),
+ ldns_buffer_position(key));
+}
+
+RSA *
+ldns_key_buf2rsa_raw(unsigned char* key, size_t len)
+{
+ uint16_t offset;
+ uint16_t exp;
+ uint16_t int16;
+ RSA *rsa;
+ BIGNUM *modulus;
+ BIGNUM *exponent;
+
+ if (len == 0)
+ return NULL;
+ if (key[0] == 0) {
+ if(len < 3)
+ return NULL;
+ /* need some smart comment here XXX*/
+ /* the exponent is too large so it's places
+ * futher...???? */
+ memmove(&int16, key+1, 2);
+ exp = ntohs(int16);
+ offset = 3;
+ } else {
+ exp = key[0];
+ offset = 1;
+ }
+
+ /* key length at least one */
+ if(len < (size_t)offset + exp + 1)
+ return NULL;
+
+ /* Exponent */
+ exponent = BN_new();
+ (void) BN_bin2bn(key+offset, (int)exp, exponent);
+ offset += exp;
+
+ /* Modulus */
+ modulus = BN_new();
+ /* length of the buffer must match the key length! */
+ (void) BN_bin2bn(key+offset, (int)(len - offset), modulus);
+
+ rsa = RSA_new();
+ rsa->n = modulus;
+ rsa->e = exponent;
+
+ return rsa;
+}
+
ldns_rr *
ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
{
}
-ldns_rdf
-*ldns_nsec3_salt(const ldns_rr *nsec3_rr)
+ldns_rdf *
+ldns_nsec3_salt(const ldns_rr *nsec3_rr)
{
if (nsec3_rr && ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3) {
return ldns_rr_rdf(nsec3_rr, 3);
return ldns_verify(rrset, sigs, k, good_keys);
}
+#if 0
ldns_rr_list *
ldns_zone_create_nsecs(const ldns_zone *zone, ldns_rr_list *orig_zone_rrs, ldns_rr_list *glue_rrs)
{
return new_list;
}
+#endif
ldns_status
ldns_dnssec_chain_nsec3_list(ldns_rr_list *nsec3_rrs)
return status;
}
-static int
+int
qsort_rr_compare_nsec3(const void *a, const void *b)
{
const ldns_rr *rr1 = * (const ldns_rr **) a;
return ldns_rdf_compare(ldns_rr_owner(rr1), ldns_rr_owner(rr2));
}
-void ldns_rr_list_sort_nsec3(ldns_rr_list *unsorted) {
+void
+ldns_rr_list_sort_nsec3(ldns_rr_list *unsorted)
+{
qsort(unsorted->_rrs,
ldns_rr_list_rr_count(unsorted),
sizeof(ldns_rr *),
ldns_rr_list_push_rr(new_rrs, nsec_rr);
break;
case LDNS_RR_TYPE_NSEC3:
+ /*TODO separate function*/
break;
default:
return LDNS_STATUS_ERR;
ldns_dnssec_remove_signatures(ldns_dnssec_rrs *signatures,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void *),
- void *arg) {
+ void *arg)
+{
ldns_dnssec_rrs *base_rrs = signatures;
ldns_dnssec_rrs *cur_rr = base_rrs;
ldns_dnssec_rrs *prev_rr = NULL;
ldns_rr_list *new_rrs,
ldns_key_list *key_list,
int (*func)(ldns_rr *, void*),
- void *arg) {
+ void *arg)
+{
ldns_status result = LDNS_STATUS_OK;
zone = zone;
new_rrs = new_rrs;
ldns_rr_list_free(glue_rrs);
return signed_zone;
#endif
-
}
#endif
ldns_dnssec_trust_tree *
ldns_dnssec_trust_tree_new()
{
- ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree, 1);
-
+ ldns_dnssec_trust_tree *new_tree = LDNS_XMALLOC(ldns_dnssec_trust_tree,
+ 1);
new_tree->rr = NULL;
new_tree->rrset = NULL;
new_tree->parent_count = 0;
LDNS_FREE(tree);
}
-ldns_status
-ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree,
- const ldns_dnssec_trust_tree *parent,
- const ldns_rr *signature,
- const ldns_status parent_status)
+size_t
+ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree)
{
- if (tree && parent && tree->parent_count < LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS) {
- /*
- printf("Add parent for: ");
- ldns_rr_print(stdout, tree->rr);
- printf("parent: ");
- ldns_rr_print(stdout, parent->rr);
- */
- tree->parents[tree->parent_count] = (ldns_dnssec_trust_tree *) parent;
- tree->parent_status[tree->parent_count] = parent_status;
- tree->parent_signature[tree->parent_count] = (ldns_rr *) signature;
- tree->parent_count++;
- return LDNS_STATUS_OK;
- } else {
- return LDNS_STATUS_ERR;
+ size_t result = 0;
+ size_t parent = 0;
+ size_t i;
+
+ for (i = 0; i < tree->parent_count; i++) {
+ parent = ldns_dnssec_trust_tree_depth(tree->parents[i]);
+ if (parent > result) {
+ result = parent;
+ }
}
+ return 1 + result;
}
/* TODO ldns_ */
}
}
-size_t
-ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree)
-{
- size_t result = 0;
- size_t parent = 0;
- size_t i;
-
- for (i = 0; i < tree->parent_count; i++) {
- parent = ldns_dnssec_trust_tree_depth(tree->parents[i]);
- if (parent > result) {
- result = parent;
- }
- }
- return 1 + result;
-}
-
void
-ldns_dnssec_trust_tree_print_sm(FILE *out, ldns_dnssec_trust_tree *tree, size_t tabs, bool extended, uint8_t *sibmap, size_t treedepth)
+ldns_dnssec_trust_tree_print_sm(FILE *out,
+ ldns_dnssec_trust_tree *tree,
+ size_t tabs,
+ bool extended,
+ uint8_t *sibmap,
+ size_t treedepth)
{
size_t i;
const ldns_rr_descriptor *descriptor;
ldns_dnssec_trust_tree_print_sm(out, tree, tabs, extended, NULL, 0);
}
+ldns_status
+ldns_dnssec_trust_tree_add_parent(ldns_dnssec_trust_tree *tree,
+ const ldns_dnssec_trust_tree *parent,
+ const ldns_rr *signature,
+ const ldns_status parent_status)
+{
+ if (tree && parent && tree->parent_count < LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS) {
+ /*
+ printf("Add parent for: ");
+ ldns_rr_print(stdout, tree->rr);
+ printf("parent: ");
+ ldns_rr_print(stdout, parent->rr);
+ */
+ tree->parents[tree->parent_count] = (ldns_dnssec_trust_tree *) parent;
+ tree->parent_status[tree->parent_count] = parent_status;
+ tree->parent_signature[tree->parent_count] = (ldns_rr *) signature;
+ tree->parent_count++;
+ return LDNS_STATUS_OK;
+ } else {
+ return LDNS_STATUS_ERR;
+ }
+}
+
+/* if rr is null, take the first from the rrset */
+ldns_dnssec_trust_tree *
+ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
+{
+ ldns_rr_list *cur_rrset;
+ ldns_rr_list *cur_sigs;
+ ldns_rr *cur_rr = NULL;
+ ldns_rr *cur_sig_rr;
+ uint16_t cur_keytag;
+ size_t i, j;
+
+ ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
+
+ if (data_chain && data_chain->rrset) {
+ cur_rrset = data_chain->rrset;
+
+ cur_sigs = data_chain->signatures;
+
+ if (rr) {
+ cur_rr = rr;
+ }
+
+ if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
+ cur_rr = ldns_rr_list_rr(cur_rrset, 0);
+ }
+
+ if (cur_rr) {
+ new_tree->rr = cur_rr;
+ new_tree->rrset = cur_rrset;
+ /* there are three possibilities:
+ 1 - 'normal' rrset, signed by a key
+ 2 - dnskey signed by other dnskey
+ 3 - dnskey proven by higher level DS
+ (data denied by nsec is a special case that can
+ occur in multiple places)
+
+ */
+ if (cur_sigs) {
+ for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
+ /* find the appropriate key in the parent list */
+ cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
+ cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
+
+ if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
+ if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
+ ldns_rr_owner(cur_rr)))
+ {
+ /* find first that does match */
+
+ for (j = 0;
+ j < ldns_rr_list_rr_count(cur_rrset) &&
+ ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0;
+ j++) {
+ cur_rr = ldns_rr_list_rr(cur_rrset, j);
+
+ }
+ if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
+ ldns_rr_owner(cur_rr)))
+ {
+ break;
+ }
+ }
+
+ }
+ /* option 1 */
+ if (data_chain->parent) {
+ ldns_dnssec_derive_trust_tree_normal_rrset(new_tree, data_chain, cur_sig_rr);
+ }
+
+ /* option 2 */
+ ldns_dnssec_derive_trust_tree_dnskey_rrset(new_tree, data_chain, cur_rr, cur_sig_rr);
+ }
+
+ ldns_dnssec_derive_trust_tree_ds_rrset(new_tree, data_chain, cur_rr);
+ } else {
+ /* no signatures? maybe it's nsec data */
+
+ /* just add every rr from parent as new parent */
+ ldns_dnssec_derive_trust_tree_no_sig(new_tree, data_chain);
+ }
+ }
+ }
+
+ return new_tree;
+}
+
void
ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree *new_tree,
ldns_dnssec_data_chain *data_chain,
}
}
-void
-breakme()
-{
- // just to define a break point
- int i,j;
- i = 123;
- j = i + 1;
-}
-
void
ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree,
ldns_dnssec_data_chain *data_chain)
}
}
-/* if rr is null, take the first from the rrset */
-ldns_dnssec_trust_tree *
-ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr)
-{
- ldns_rr_list *cur_rrset;
- ldns_rr_list *cur_sigs;
- ldns_rr *cur_rr = NULL;
- ldns_rr *cur_sig_rr;
- uint16_t cur_keytag;
- size_t i, j;
-
- ldns_dnssec_trust_tree *new_tree = ldns_dnssec_trust_tree_new();
-
- if (data_chain && data_chain->rrset) {
- cur_rrset = data_chain->rrset;
-
- cur_sigs = data_chain->signatures;
-
- if (rr) {
- cur_rr = rr;
- }
-
- if (!cur_rr && ldns_rr_list_rr_count(cur_rrset) > 0) {
- cur_rr = ldns_rr_list_rr(cur_rrset, 0);
- }
-
- if (cur_rr) {
- new_tree->rr = cur_rr;
- new_tree->rrset = cur_rrset;
- /* there are three possibilities:
- 1 - 'normal' rrset, signed by a key
- 2 - dnskey signed by other dnskey
- 3 - dnskey proven by higher level DS
- (data denied by nsec is a special case that can
- occur in multiple places)
-
- */
- if (cur_sigs) {
- for (i = 0; i < ldns_rr_list_rr_count(cur_sigs); i++) {
- /* find the appropriate key in the parent list */
- cur_sig_rr = ldns_rr_list_rr(cur_sigs, i);
- cur_keytag = ldns_rdf2native_int16(ldns_rr_rrsig_keytag(cur_sig_rr));
-
- if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_NSEC) {
- if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
- ldns_rr_owner(cur_rr)))
- {
- /* find first that does match */
-
- for (j = 0;
- j < ldns_rr_list_rr_count(cur_rrset) &&
- ldns_dname_compare(ldns_rr_owner(cur_sig_rr),ldns_rr_owner(cur_rr)) != 0;
- j++) {
- cur_rr = ldns_rr_list_rr(cur_rrset, j);
-
- }
- if (ldns_dname_compare(ldns_rr_owner(cur_sig_rr),
- ldns_rr_owner(cur_rr)))
- {
- break;
- }
- }
-
- }
- /* option 1 */
- if (data_chain->parent) {
- ldns_dnssec_derive_trust_tree_normal_rrset(new_tree, data_chain, cur_sig_rr);
- }
-
- /* option 2 */
- ldns_dnssec_derive_trust_tree_dnskey_rrset(new_tree, data_chain, cur_rr, cur_sig_rr);
- }
-
- ldns_dnssec_derive_trust_tree_ds_rrset(new_tree, data_chain, cur_rr);
- } else {
- /* no signatures? maybe it's nsec data */
-
- /* just add every rr from parent as new parent */
- ldns_dnssec_derive_trust_tree_no_sig(new_tree, data_chain);
- }
- }
- }
-
- return new_tree;
-}
-
/*
* returns OK if there is a path from tree to key with only OK
* the (first) error in between otherwise
printf("Trying key: ");
ldns_rr_print(stdout, tree->rr);
*/
- equal = ldns_rr_compare_ds(tree->rr, ldns_rr_list_rr(trusted_keys, i));
+ equal = ldns_rr_compare_ds(tree->rr,
+ ldns_rr_list_rr(trusted_keys, i));
if (equal) {
result = LDNS_STATUS_OK;
return result;
}
ldns_rr_list *
-ldns_fetch_valid_domain_keys(const ldns_resolver * res, const ldns_rdf * domain, const ldns_rr_list * keys, ldns_status *status)
+ldns_fetch_valid_domain_keys(const ldns_resolver *res,
+ const ldns_rdf *domain,
+ const ldns_rr_list *keys,
+ ldns_status *status)
{
ldns_rr_list * trusted_keys = NULL;
ldns_rr_list * ds_keys = NULL;
}
ldns_rr_list *
-ldns_validate_domain_dnskey (const ldns_resolver * res, const ldns_rdf * domain, const ldns_rr_list * keys)
+ldns_validate_domain_dnskey(const ldns_resolver * res,
+ const ldns_rdf * domain,
+ const ldns_rr_list * keys)
{
ldns_status status;
ldns_pkt * keypkt;
}
ldns_rr_list *
-ldns_validate_domain_ds (const ldns_resolver * res, const ldns_rdf * domain, const ldns_rr_list * keys)
+ldns_validate_domain_ds(const ldns_resolver *res,
+ const ldns_rdf * domain,
+ const ldns_rr_list * keys)
{
ldns_status status;
ldns_pkt * dspkt;
}
ldns_status
-ldns_verify_trusted(ldns_resolver * res, ldns_rr_list * rrset, ldns_rr_list * rrsigs, ldns_rr_list * validating_keys)
+ldns_verify_trusted(ldns_resolver *res,
+ ldns_rr_list *rrset,
+ ldns_rr_list * rrsigs,
+ ldns_rr_list * validating_keys)
{
/* */
uint16_t sig_i; uint16_t key_i;
return result;
}
+ldns_status
+ldns_dnssec_verify_denial(ldns_rr *rr,
+ ldns_rr_list *nsecs,
+ ldns_rr_list *rrsigs)
+{
+ ldns_rdf *rr_name;
+ ldns_rdf *wildcard_name;
+ ldns_rdf *chopped_dname;
+ ldns_rr *cur_nsec;
+ size_t i;
+ ldns_status result;
+ /* needed for wildcard check on exact match */
+ ldns_rr *rrsig;
+ bool name_covered = false;
+ bool type_covered = false;
+ bool wildcard_covered = false;
+ bool wildcard_type_covered = false;
+
+ wildcard_name = ldns_dname_new_frm_str("*");
+ rr_name = ldns_rr_owner(rr);
+ chopped_dname = ldns_dname_left_chop(rr_name);
+ result = ldns_dname_cat(wildcard_name, chopped_dname);
+ if (result != LDNS_STATUS_OK) {
+ return result;
+ }
+
+ ldns_rdf_deep_free(chopped_dname);
+
+ for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
+ cur_nsec = ldns_rr_list_rr(nsecs, i);
+ if (ldns_dname_compare(rr_name, ldns_rr_owner(cur_nsec)) == 0) {
+ /* see section 5.4 of RFC4035, if the label count of the NSEC's
+ RRSIG is equal, then it is proven that wildcard expansion
+ could not have been used to match the request */
+ rrsig = ldns_dnssec_get_rrsig_for_name_and_type(ldns_rr_owner(cur_nsec), ldns_rr_get_type(cur_nsec), rrsigs);
+ if (rrsig && ldns_rdf2native_int8(ldns_rr_rrsig_labels(rrsig)) == ldns_dname_label_count(rr_name)) {
+ printf("[XX] wildcard covered from label count\n");
+ wildcard_covered = true;
+ }
+
+ if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec), ldns_rr_get_type(rr))) {
+ printf("[XX] type covered\n");
+ type_covered = true;
+ }
+ }
+ printf("[XX] Name covered?\n");
+ if (ldns_nsec_covers_name(cur_nsec, rr_name)) {
+ printf("[XX] yes!\n");
+ name_covered = true;
+ }
+
+ if (ldns_dname_compare(wildcard_name, ldns_rr_owner(cur_nsec)) == 0) {
+ printf("[XX] Wildcard type covered?\n");
+ if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec), ldns_rr_get_type(rr))) {
+ printf("[XX] yes!\n");
+ wildcard_type_covered = true;
+ }
+ }
+
+ printf("[XX] Wildcard covered?\n");
+ if (ldns_nsec_covers_name(cur_nsec, wildcard_name)) {
+ printf("[XX] yes!\n");
+ wildcard_covered = true;
+ }
+
+ }
+
+ ldns_rdf_deep_free(wildcard_name);
+
+ if (type_covered || !name_covered) {
+ return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
+ }
+
+ if (wildcard_type_covered || !wildcard_covered) {
+ return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
+ }
+
+ return LDNS_STATUS_OK;
+}
+
+ldns_status
+ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
+ ldns_rr_list *nsecs,
+ ldns_rr_list *rrsigs,
+ ldns_pkt_rcode packet_rcode,
+ ldns_rr_type packet_qtype,
+ bool packet_nodata)
+{
+ ldns_rdf *closest_encloser;
+ ldns_rdf *wildcard;
+ bool wildcard_covered = false;
+ ldns_rdf *zone_name;
+ ldns_rdf *hashed_name;
+ size_t i;
+
+ rrsigs = rrsigs;
+
+ /* section 8.4 */
+ if (packet_rcode == LDNS_RCODE_NXDOMAIN) {
+ closest_encloser = ldns_dnssec_nsec3_closest_encloser(ldns_rr_owner(rr),
+ ldns_rr_get_type(rr),
+ nsecs);
+
+ printf("[XX} NSEC3 denial for: ");
+ ldns_rr_print(stdout, rr);
+ printf("[XX] closest encloser: ");
+ ldns_rdf_print(stdout, closest_encloser);
+ printf("\n");
+
+ wildcard = ldns_dname_new_frm_str("*");
+ ldns_dname_cat(wildcard, closest_encloser);
+
+ for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
+ if (ldns_nsec_covers_name(ldns_rr_list_rr(nsecs, i),
+ wildcard)) {
+ printf("[XX] wildcard covered\n");
+ wildcard_covered = true;
+ }
+ }
+
+ if (!wildcard_covered) {
+ return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
+ }
+ if (closest_encloser && wildcard_covered) {
+ return LDNS_STATUS_OK;
+ }
+ return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
+ } else if (packet_nodata && packet_qtype != LDNS_RR_TYPE_DS) {
+ /* section 8.5 */
+ hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
+ ldns_rr_owner(rr)
+ );
+ zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
+ ldns_dname_cat(hashed_name, zone_name);
+ printf("[XX] hashed name: ");
+ ldns_rdf_print(stdout, hashed_name);
+ printf("\n");
+ for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
+ if (ldns_dname_compare(hashed_name, ldns_rr_owner(ldns_rr_list_rr(nsecs, i))) == 0) {
+ if (!ldns_nsec_bitmap_covers_type(ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)), packet_qtype) &&
+ !ldns_nsec_bitmap_covers_type(ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)), LDNS_RR_TYPE_CNAME)) {
+ printf("exact match!\n");
+ return LDNS_STATUS_OK;
+ }
+ }
+ }
+ return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
+ } else if (packet_nodata && packet_qtype == LDNS_RR_TYPE_DS) {
+ /* section 8.6 */
+ /* note: up to XXX this is the same as for 8.5 */
+ hashed_name = ldns_nsec3_hash_name_frm_nsec3(ldns_rr_list_rr(nsecs, 0),
+ ldns_rr_owner(rr)
+ );
+ zone_name = ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(nsecs,0)));
+ ldns_dname_cat(hashed_name, zone_name);
+ printf("[XX] hashed name: ");
+ ldns_rdf_print(stdout, hashed_name);
+ printf("\n");
+ for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
+ if (ldns_dname_compare(hashed_name, ldns_rr_owner(ldns_rr_list_rr(nsecs, i))) == 0) {
+ if (!ldns_nsec_bitmap_covers_type(ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)), LDNS_RR_TYPE_DS) &&
+ !ldns_nsec_bitmap_covers_type(ldns_nsec3_bitmap(ldns_rr_list_rr(nsecs, i)), LDNS_RR_TYPE_CNAME)) {
+ printf("exact match!\n");
+ return LDNS_STATUS_OK;
+ }
+ }
+ }
+
+ /* XXX see note above */
+ closest_encloser = ldns_dnssec_nsec3_closest_encloser(ldns_rr_owner(rr),
+ ldns_rr_get_type(rr),
+ nsecs);
+
+ if (closest_encloser) {
+ printf("[XX] closest encloser: ");
+ ldns_rdf_print(stdout, closest_encloser);
+ printf("\n");
+ exit(0);
+ }
+ return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
+
+ }
+ return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
+}
+
ldns_status
ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf,
ldns_buffer *key_buf, uint8_t algo)
}
ldns_status
-ldns_convert_dsa_rrsig_rdata(
- ldns_buffer *target_buffer,
- ldns_rdf *sig_rdf
- )
+ldns_convert_dsa_rrsig_rdata(ldns_buffer *target_buffer,
+ ldns_rdf *sig_rdf)
{
/* the EVP api wants the DER encoding of the signature... */
uint8_t t;
return ldns_buffer_status(target_buffer);
}
+#if 0
void
print_dates(time_t now, time_t inception)
{
LDNS_FREE(istr);
return;
}
+#endif
ldns_status
ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
return result;
}
-DSA *
-ldns_key_buf2dsa(ldns_buffer *key)
-{
- return ldns_key_buf2dsa_raw((unsigned char*)ldns_buffer_begin(key),
- ldns_buffer_position(key));
-}
-
-DSA *
-ldns_key_buf2dsa_raw(unsigned char* key, size_t len)
-{
- uint8_t T;
- uint16_t length;
- uint16_t offset;
- DSA *dsa;
- BIGNUM *Q; BIGNUM *P;
- BIGNUM *G; BIGNUM *Y;
-
- if(len == 0)
- return NULL;
- T = (uint8_t)key[0];
- length = (64 + T * 8);
- offset = 1;
-
- if (T > 8) {
- return NULL;
- }
- if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
- return NULL;
-
- Q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
- offset += SHA_DIGEST_LENGTH;
-
- P = BN_bin2bn(key+offset, (int)length, NULL);
- offset += length;
-
- G = BN_bin2bn(key+offset, (int)length, NULL);
- offset += length;
-
- Y = BN_bin2bn(key+offset, (int)length, NULL);
- offset += length;
-
- /* create the key and set its properties */
- dsa = DSA_new();
- dsa->p = P;
- dsa->q = Q;
- dsa->g = G;
- dsa->pub_key = Y;
-
- return dsa;
-}
-
-RSA *
-ldns_key_buf2rsa(ldns_buffer *key)
-{
- return ldns_key_buf2rsa_raw((unsigned char*)ldns_buffer_begin(key),
- ldns_buffer_position(key));
-}
-
-RSA *
-ldns_key_buf2rsa_raw(unsigned char* key, size_t len)
-{
- uint16_t offset;
- uint16_t exp;
- uint16_t int16;
- RSA *rsa;
- BIGNUM *modulus;
- BIGNUM *exponent;
-
- if (len == 0)
- return NULL;
- if (key[0] == 0) {
- if(len < 3)
- return NULL;
- /* need some smart comment here XXX*/
- /* the exponent is too large so it's places
- * futher...???? */
- memmove(&int16, key+1, 2);
- exp = ntohs(int16);
- offset = 3;
- } else {
- exp = key[0];
- offset = 1;
- }
-
- /* key length at least one */
- if(len < (size_t)offset + exp + 1)
- return NULL;
-
- /* Exponent */
- exponent = BN_new();
- (void) BN_bin2bn(key+offset, (int)exp, exponent);
- offset += exp;
-
- /* Modulus */
- modulus = BN_new();
- /* length of the buffer must match the key length! */
- (void) BN_bin2bn(key+offset, (int)(len - offset), modulus);
-
- rsa = RSA_new();
- rsa->n = modulus;
- rsa->e = exponent;
-
- return rsa;
-}
-
#endif
#define LDNS_NSEC3_MAX_ITERATIONS 65535
+/**
+ * Returns the dname of the closest (provable) encloser
+ */
+ldns_rdf *
+ldns_dnssec_nsec3_closest_encloser(ldns_rdf *qname,
+ ldns_rr_type qtype,
+ ldns_rr_list *nsec3s);
+
+/**
+ * Checks whether the packet contains rrsigs
+ */
+bool
+ldns_dnssec_pkt_has_rrsigs(const ldns_pkt *pkt);
+
+/**
+ * Returns a ldns_rr_list containing the signatures covering the given name
+ * and type
+ */
+ldns_rr_list *ldns_dnssec_pkt_get_rrsigs_for_name_and_type(const ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type);
+
+/**
+ * Returns a ldns_rr_list containing the signatures covering the given type
+ */
+ldns_rr_list *ldns_dnssec_pkt_get_rrsigs_for_type(const ldns_pkt *pkt, ldns_rr_type type);
+
/**
* calculates a keytag of a key for use in DNSSEC.
*
*/
uint16_t ldns_calc_keytag(const ldns_rr *key);
-ldns_rr_list *ldns_dnssec_pkt_get_rrsigs_for_type(const ldns_pkt *pkt, ldns_rr_type type);
-
-ldns_rr_list *ldns_dnssec_pkt_get_rrsigs_for_name_and_type(const ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type);
-
/**
* Calculates keytag of DNSSEC key, operates on wireformat rdata.
* \param[in] key the key as uncompressed wireformat rdata.
* \return a RSA * structure with the key material
*/
RSA *ldns_key_buf2rsa(ldns_buffer *key);
+
/**
* Like ldns_key_buf2rsa, but uses raw buffer.
* \param[in] key the uncompressed wireformat of the key.
*/
ldns_rr *ldns_key_rr2ds(const ldns_rr *key, ldns_hash h);
+/**
+ * Create the type bitmap for an NSEC(3) record
+ */
+ldns_rdf *
+ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[],
+ size_t size,
+ ldns_rr_type nsec_type);
+
+/**
+ * Creates NSEC
+ */
+ldns_rr *
+ldns_dnssec_create_nsec(ldns_dnssec_name *from,
+ ldns_dnssec_name *to,
+ ldns_rr_type nsec_type);
+
+/**
+ * Creates NSEC3
+ */
+ldns_rr *
+ldns_dnssec_create_nsec3(ldns_dnssec_name *from,
+ ldns_dnssec_name *to,
+ ldns_rdf *zone_name,
+ uint8_t algorithm,
+ uint8_t flags,
+ uint16_t iterations,
+ uint8_t salt_length,
+ uint8_t *salt);
+
/**
* Create a NSEC record
* \param[in] cur_owner the current owner which should be taken as the starting point
ldns_rr * ldns_create_nsec(ldns_rdf *cur_owner, ldns_rdf *next_owner, ldns_rr_list *rrs);
/**
- * Checks coverage of NSEC RR type bitmap
- * \param[in] nsec_bitmap The NSEC bitmap rdata field to check
- * \param[in] type The type to check
- * \return true if the NSEC RR covers the type
+ * Calculates the hashed name using the given parameters
+ * \param[in] *name The owner name to calculate the hash for
+ * \param[in] algorithm The hash algorithm to use
+ * \param[in] iterations The number of hash iterations to use
+ * \param[in] salt_length The length of the salt in bytes
+ * \param[in] salt The salt to use
+ * \return The hashed owner name rdf, without the domain name
*/
-bool ldns_nsec_bitmap_covers_type(const ldns_rdf *nsec_bitmap, ldns_rr_type type);
+ldns_rdf *ldns_nsec3_hash_name(ldns_rdf *name, uint8_t algorithm, uint16_t iterations, uint8_t salt_length, uint8_t *salt);
/**
- * Checks coverage of NSEC(3) RR name span
- * Remember that nsec and name must both be in canonical form (ie use
- * \ref ldns_rr2canonical and \ref ldns_dname2canonical prior to calling this
- * function)
- *
- * \param[in] nsec The NSEC RR to check
- * \param[in] name The owner dname to check, if the nsec record is a NSEC3 record, this should be the hashed name
- * \return true if the NSEC RR covers the owner name
+ * Sets all the NSEC3 options. The rr to set them in must be initialized with _new() and
+ * type LDNS_RR_TYPE_NSEC3
+ * \param[in] *rr The RR to set the values in
+ * \param[in] algorithm The NSEC3 hash algorithm
+ * \param[in] flags The flags field
+ * \param[in] iterations The number of hash iterations
+ * \param[in] salt_length The length of the salt in bytes
+ * \param[in] salt The salt bytes
*/
-bool ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name);
+void ldns_nsec3_add_param_rdfs(ldns_rr *rr,
+ uint8_t algorithm,
+ uint8_t flags,
+ uint16_t iterations,
+ uint8_t salt_length,
+ uint8_t *salt);
+
+/* this will NOT return the NSEC3 completed, you will have to run the
+ finalize function on the rrlist later! */
+ldns_rr *
+ldns_create_nsec3(ldns_rdf *cur_owner,
+ ldns_rdf *cur_zone,
+ ldns_rr_list *rrs,
+ uint8_t algorithm,
+ uint8_t flags,
+ uint16_t iterations,
+ uint8_t salt_length,
+ uint8_t *salt,
+ bool emptynonterminal);
/**
* Returns the hash algorithm used in the given NSEC3 RR
*/
uint8_t ldns_nsec3_algorithm(const ldns_rr *nsec3_rr);
+/**
+ * Returns flags field
+ */
+uint8_t
+ldns_nsec3_flags(const ldns_rr *nsec3_rr);
+
+/**
+ * Returns true if the opt-out flag has been set in the given NSEC3 RR
+ * \param[in] *nsec3_rr The RR to read from
+ * \return true if the RR has type NSEC3 and the opt-out bit has been set, false otherwise
+ */
+bool ldns_nsec3_optout(const ldns_rr *nsec3_rr);
+
/**
* Returns the number of hash iterations used in the given NSEC3 RR
* \param[in] *nsec3_rr The RR to read from
*/
uint8_t *ldns_nsec3_salt_data(const ldns_rr *nsec3_rr);
-/**
- * Returns true if the opt-out flag has been set in the given NSEC3 RR
- * \param[in] *nsec3_rr The RR to read from
- * \return true if the RR has type NSEC3 and the opt-out bit has been set, false otherwise
- */
-bool ldns_nsec3_optout(const ldns_rr *nsec3_rr);
-
/**
* Returns the first label of the next ownername in the NSEC3 chain (ie. without the domain)
* \param[in] nsec3_rr The RR to read from
*/
ldns_rdf *ldns_nsec3_next_owner(const ldns_rr *nsec3_rr);
-/**
- * Sets all the NSEC3 options. The rr to set them in must be initialized with _new() and
- * type LDNS_RR_TYPE_NSEC3
- * \param[in] *rr The RR to set the values in
- * \param[in] algorithm The NSEC3 hash algorithm
- * \param[in] flags The flags field
- * \param[in] iterations The number of hash iterations
- * \param[in] salt_length The length of the salt in bytes
- * \param[in] salt The salt bytes
- */
-void ldns_nsec3_add_param_rdfs(ldns_rr *rr, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt);
-
-
/**
* Returns the bitmap specifying the covered types of the given NSEC3 RR
* \param[in] *nsec3_rr The RR to read from
ldns_rdf *ldns_nsec3_hash_name_frm_nsec3(const ldns_rr *nsec, ldns_rdf *name);
/**
- * Calculates the hashed name using the given parameters
- * \param[in] *name The owner name to calculate the hash for
- * \param[in] algorithm The hash algorithm to use
- * \param[in] iterations The number of hash iterations to use
- * \param[in] salt_length The length of the salt in bytes
- * \param[in] salt The salt to use
- * \return The hashed owner name rdf, without the domain name
+ * Checks coverage of NSEC RR type bitmap
+ * \param[in] nsec_bitmap The NSEC bitmap rdata field to check
+ * \param[in] type The type to check
+ * \return true if the NSEC RR covers the type
*/
-ldns_rdf *ldns_nsec3_hash_name(ldns_rdf *name, uint8_t algorithm, uint16_t iterations, uint8_t salt_length, uint8_t *salt);
+bool ldns_nsec_bitmap_covers_type(const ldns_rdf *nsec_bitmap, ldns_rr_type type);
+/**
+ * Checks coverage of NSEC(3) RR name span
+ * Remember that nsec and name must both be in canonical form (ie use
+ * \ref ldns_rr2canonical and \ref ldns_dname2canonical prior to calling this
+ * function)
+ *
+ * \param[in] nsec The NSEC RR to check
+ * \param[in] name The owner dname to check, if the nsec record is a NSEC3 record, this should be the hashed name
+ * \return true if the NSEC RR covers the owner name
+ */
+bool ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name);
/**
* verify a packet
*/
ldns_status ldns_pkt_verify(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o, ldns_rr_list *k, ldns_rr_list *s, ldns_rr_list *good_keys);
-bool ldns_dnssec_pkt_has_rrsigs(const ldns_pkt *pkt);
+/**
+ * chains nsec3 list
+ */
+ldns_status
+ldns_dnssec_chain_nsec3_list(ldns_rr_list *nsec3_rrs);
+/**
+ * compare for nsec3 sort
+ */
+int
+qsort_rr_compare_nsec3(const void *a, const void *b);
+/**
+ * sort nsec3 list
+ */
+void
+ldns_rr_list_sort_nsec3(ldns_rr_list *unsorted);
+
+/**
+ * Adds NSEC3 records to the zone
+ */
+ldns_status
+ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
+ ldns_rr_list *new_rrs,
+ uint8_t algorithm,
+ uint8_t flags,
+ uint16_t iterations,
+ uint8_t salt_length,
+ uint8_t *salt);
/**
* Default callback function to always leave present signatures, and
* add new ones
*/
int ldns_dnssec_default_replace_signatures(ldns_rr *sig, void *n);
-/**
- * Tries to build an authentication chain from the given keys down to the queried domain.
- *
- * If we find a valid trust path, return the valid keys for the domain.
- *
- * \param[in] res the current resolver
- * \param[in] domain the domain we want valid keys for
- * \param[in] keys the current set of trusted keys
- * \param[out] status pointer to the status variable where the result code will be stored
- * \return the set of trusted keys for the domain, or NULL if no trust path could be built.
- */
-ldns_rr_list *
-ldns_fetch_valid_domain_keys(const ldns_resolver * res, const ldns_rdf * domain, const ldns_rr_list * keys, ldns_status *status);
-
-/**
- * Validates the DNSKEY RRset for the given domain using the provided trusted keys.
- *
- * \param[in] res the current resolver
- * \param[in] domain the domain we want valid keys for
- * \param[in] keys the current set of trusted keys
- * \return the set of trusted keys for the domain, or NULL if the RRSET could not be validated
- */
-ldns_rr_list *
-ldns_validate_domain_dnskey (const ldns_resolver * res, const ldns_rdf * domain, const ldns_rr_list * keys);
-
-/**
- * Validates the DS RRset for the given domain using the provided trusted keys.
- *
- * \param[in] res the current resolver
- * \param[in] domain the domain we want valid keys for
- * \param[in] keys the current set of trusted keys
- * \return the set of trusted keys for the domain, or NULL if the RRSET could not be validated
- */
-ldns_rr_list *
-ldns_validate_domain_ds (const ldns_resolver * res, const ldns_rdf * domain, const ldns_rr_list * keys);
-
-/**
- * Verifies a list of signatures for one RRset using a valid trust path.
- *
- * \param[in] res the current resolver
- * \param[in] rrset the rrset to verify
- * \param[in] rrsigs a list of signatures to check
- * \param[out] validating_keys if this is a (initialized) list, the keys from keys that validate one of the signatures are added to it
- * \return status LDNS_STATUS_OK if there is at least one correct key
- */
-ldns_status
-ldns_verify_trusted(ldns_resolver * res, ldns_rr_list * rrset, ldns_rr_list * rrsigs, ldns_rr_list * validating_keys);
-
-ldns_rr *
-ldns_dnssec_create_nsec(ldns_dnssec_name *from,
- ldns_dnssec_name *to,
- ldns_rr_type nsec_type);
-
-ldns_status
-ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
- ldns_rr_list *new_rrs,
- uint8_t algorithm,
- uint8_t flags,
- uint16_t iterations,
- uint8_t salt_length,
- uint8_t *salt);
-ldns_status
-ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
- ldns_rr_list *nsecs,
- ldns_rr_list *rrsigs,
- ldns_pkt_rcode packet_rcode,
- ldns_rr_type packet_qtype,
- bool packet_nodata);
-
-ldns_status
-ldns_dnssec_verify_denial(ldns_rr *rr,
- ldns_rr_list *nsecs,
- ldns_rr_list *rrsigs);
-
#endif /* LDNS_DNSSEC_H */
const EVP_MD *digest_type);
/**
- * Sign a buffer with the RSA key (hash with MD5)
+ * Sign a buffer with the RSA key (hash with SHA1)
* \param[in] to_sign buffer with the data
* \param[in] key the key to use
* \return a ldns_rdf with the signed data
*/
-ldns_rdf *ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key);
+ldns_rdf *ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key);
+
/**
- * Sign a buffer with the RSA key (hash with SHA1)
+ * Sign a buffer with the RSA key (hash with MD5)
* \param[in] to_sign buffer with the data
* \param[in] key the key to use
* \return a ldns_rdf with the signed data
*/
-ldns_rdf *ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key);
+ldns_rdf *ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key);
#endif /* HAVE_SSL */
+/**
+ * Adds NSEC RRs to the zone
+ */
+ldns_status
+ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
+ ldns_rr_list *new_rrs,
+ ldns_rr_type nsec_type);
+
+/**
+ * remove signatures if callback function tells to
+ */
+ldns_dnssec_rrs *
+ldns_dnssec_remove_signatures(ldns_dnssec_rrs *signatures,
+ ldns_key_list *key_list,
+ int (*func)(ldns_rr *, void *),
+ void *arg);
+
+/**
+ * Adds signatures to the zone
+ */
+ldns_status
+ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
+ ldns_rr_list *new_rrs,
+ ldns_key_list *key_list,
+ int (*func)(ldns_rr *, void*),
+ void *arg);
+
/**
* signs the given zone with the given new zone
*
* \return signed zone
*/
ldns_zone *ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list);
+
/**
* Signs the zone with NSEC3, and returns a newly allocated signed zone
* \param[in] zone the zone to sign
*/
void ldns_dnssec_data_chain_print(FILE *out, const ldns_dnssec_data_chain *chain);
+/**
+ * the data set will be cloned
+ * the pkt is optional, can contain the original packet
+ * (and hence the sigs and maybe the key)
+ */
+ldns_dnssec_data_chain *ldns_dnssec_build_data_chain(ldns_resolver *res,
+ const uint16_t qflags,
+ const ldns_rr_list *data_set,
+ const ldns_pkt *pkt,
+ ldns_rr *orig_rr);
+
#define LDNS_DNSSEC_TRUST_TREE_MAX_PARENTS 10
/**
*/
void ldns_dnssec_trust_tree_free(ldns_dnssec_trust_tree *tree);
-
+/**
+ * returns the depth
+ */
size_t ldns_dnssec_trust_tree_depth(ldns_dnssec_trust_tree *tree);
-
/**
* Prints the dnssec_trust_tree structure to the given file stream
* Each line is prepended by 2*tabs spaces
*/
void ldns_dnssec_trust_tree_print(FILE *out, ldns_dnssec_trust_tree *tree, size_t tabs, bool extended);
-/**
- * Generates a dnssec_trust_ttree for the given rr from the given data_chain
- * Don't free the data_chain before you are done with this tree
- *
- * \param[in] *data_chain The chain to derive the trust tree from
- * \param[in] *rr The RR this tree will be about
- * \return ldns_dnssec_trust_tree *
- */
-ldns_dnssec_trust_tree *ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr);
-
/**
* Adds a trust tree as a parent for the given trust tree
*
const ldns_status parent_status);
/**
- * Returns OK if there is a trusted path in the tree to one of the DNSKEY or DS RRs in the
- * given list
+ * Generates a dnssec_trust_ttree for the given rr from the given data_chain
+ * Don't free the data_chain before you are done with this tree
+ *
+ * \param[in] *data_chain The chain to derive the trust tree from
+ * \param[in] *rr The RR this tree will be about
+ * \return ldns_dnssec_trust_tree *
+ */
+ldns_dnssec_trust_tree *ldns_dnssec_derive_trust_tree(ldns_dnssec_data_chain *data_chain, ldns_rr *rr);
+
+/**
+ * Sub function for derive_trust_tree
+ */
+void
+ldns_dnssec_derive_trust_tree_normal_rrset(ldns_dnssec_trust_tree *new_tree,
+ ldns_dnssec_data_chain *data_chain,
+ ldns_rr *cur_sig_rr);
+
+/**
+ * Sub function for derive_trust_tree
+ */
+void
+ldns_dnssec_derive_trust_tree_dnskey_rrset(ldns_dnssec_trust_tree *new_tree,
+ ldns_dnssec_data_chain *data_chain,
+ ldns_rr *cur_rr,
+ ldns_rr *cur_sig_rr);
+
+/**
+ * Sub function for derive_trust_tree
+ */
+void
+ldns_dnssec_derive_trust_tree_ds_rrset(ldns_dnssec_trust_tree *new_tree,
+ ldns_dnssec_data_chain *data_chain,
+ ldns_rr *cur_rr);
+
+/**
+ * Sub function for derive_trust_tree
+ */
+void
+ldns_dnssec_derive_trust_tree_no_sig(ldns_dnssec_trust_tree *new_tree,
+ ldns_dnssec_data_chain *data_chain);
+
+/**
+ * Returns OK if there is a trusted path in the tree to one of
+ * the DNSKEY or DS RRs in the given list
*
* \param *tree The trust tree so search
* \param *keys A ldns_rr_list of DNSKEY and DS rrs to look for
*/
ldns_status ldns_dnssec_trust_tree_contains_keys(ldns_dnssec_trust_tree *tree, ldns_rr_list *keys);
-
-/**
- * the data set will be cloned
- * the pkt is optional, can contain the original packet (and hence the sigs and maybe the key)
- */
-ldns_dnssec_data_chain *ldns_dnssec_build_data_chain(ldns_resolver *res, const uint16_t qflags, const ldns_rr_list *data_set, const ldns_pkt *pkt, ldns_rr *orig_rr);
-
/**
* Verifies a list of signatures for one rrset.
*
*/
ldns_status ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, const ldns_rr_list *keys, ldns_rr_list *good_keys);
+/**
+ * Tries to build an authentication chain from the given keys down to the queried domain.
+ *
+ * If we find a valid trust path, return the valid keys for the domain.
+ *
+ * \param[in] res the current resolver
+ * \param[in] domain the domain we want valid keys for
+ * \param[in] keys the current set of trusted keys
+ * \param[out] status pointer to the status variable where the result code will be stored
+ * \return the set of trusted keys for the domain, or NULL if no trust path could be built.
+ */
+ldns_rr_list *
+ldns_fetch_valid_domain_keys(const ldns_resolver * res,
+ const ldns_rdf * domain,
+ const ldns_rr_list * keys,
+ ldns_status *status);
+
+/**
+ * Validates the DNSKEY RRset for the given domain using the provided trusted keys.
+ *
+ * \param[in] res the current resolver
+ * \param[in] domain the domain we want valid keys for
+ * \param[in] keys the current set of trusted keys
+ * \return the set of trusted keys for the domain, or NULL if the RRSET could not be validated
+ */
+ldns_rr_list *
+ldns_validate_domain_dnskey (const ldns_resolver *res,
+ const ldns_rdf *domain,
+ const ldns_rr_list *keys);
+
+/**
+ * Validates the DS RRset for the given domain using the provided trusted keys.
+ *
+ * \param[in] res the current resolver
+ * \param[in] domain the domain we want valid keys for
+ * \param[in] keys the current set of trusted keys
+ * \return the set of trusted keys for the domain, or NULL if the RRSET could not be validated
+ */
+ldns_rr_list *
+ldns_validate_domain_ds(const ldns_resolver *res,
+ const ldns_rdf *
+ domain,
+ const ldns_rr_list * keys);
+
+/**
+ * Verifies a list of signatures for one RRset using a valid trust path.
+ *
+ * \param[in] res the current resolver
+ * \param[in] rrset the rrset to verify
+ * \param[in] rrsigs a list of signatures to check
+ * \param[out] validating_keys if this is a (initialized) list, the keys from keys that validate one of the signatures are added to it
+ * \return status LDNS_STATUS_OK if there is at least one correct key
+ */
+ldns_status
+ldns_verify_trusted(ldns_resolver *res,
+ ldns_rr_list *rrset,
+ ldns_rr_list *rrsigs,
+ ldns_rr_list *validating_keys);
+
+/**
+ * denial is not just a river in egypt
+ */
+ldns_status
+ldns_dnssec_verify_denial(ldns_rr *rr,
+ ldns_rr_list *nsecs,
+ ldns_rr_list *rrsigs);
+
+ldns_status
+ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
+ ldns_rr_list *nsecs,
+ ldns_rr_list *rrsigs,
+ ldns_pkt_rcode packet_rcode,
+ ldns_rr_type packet_qtype,
+ bool packet_nodata);
+
/**
* Verifies the already processed data in the buffers
* This function should probably not be used directly.
*/
ldns_status ldns_verify_rrsig_keylist(ldns_rr_list *rrset, ldns_rr *rrsig, const ldns_rr_list *keys, ldns_rr_list *good_keys);
+/**
+ * convert dsa data
+ */
+ldns_status
+ldns_convert_dsa_rrsig_rdata(ldns_buffer *target_buffer,
+ ldns_rdf *sig_rdf);
+
/**
* verify an rrsig with 1 key
* \param[in] rrset the rrset
* \param[in] key the key data
*/
ldns_status ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key);
+
/**
* verifies a buffer with signature data (RSASHA1) for a buffer with rrset data
* with a buffer with key data.
* \param[in] key the key data
*/
ldns_status ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key);
+
/**
* verifies a buffer with signature data (RSAMD5) for a buffer with rrset data
* with a buffer with key data.
* \param[in] key the key data
*/
ldns_status ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key);
+
/**
* Like ldns_verify_rrsig_dsa, but uses raw signature and key data.
* \param[in] sig raw uncompressed wireformat signature data
*/
ldns_status ldns_verify_rrsig_dsa_raw(unsigned char* sig, size_t siglen,
ldns_buffer* rrset, unsigned char* key, size_t keylen);
+
/**
* Like ldns_verify_rrsig_rsasha1, but uses raw signature and key data.
* \param[in] sig raw uncompressed wireformat signature data
* \param[in] key raw uncompressed wireformat key data
* \param[in] keylen length of key data
*/
+
ldns_status ldns_verify_rrsig_rsasha256_raw(unsigned char* sig, size_t siglen,
ldns_buffer* rrset, unsigned char* key, size_t keylen);
+
/**
* Like ldns_verify_rrsig_rsasha512, but uses raw signature and key data.
* \param[in] sig raw uncompressed wireformat signature data
*/
ldns_status ldns_verify_rrsig_rsasha512_raw(unsigned char* sig, size_t siglen,
ldns_buffer* rrset, unsigned char* key, size_t keylen);
+
/**
* Like ldns_verify_rrsig_rsamd5, but uses raw signature and key data.
* \param[in] sig raw uncompressed wireformat signature data
ldns_status ldns_verify_rrsig_rsamd5_raw(unsigned char* sig, size_t siglen,
ldns_buffer* rrset, unsigned char* key, size_t keylen);
-
#endif