00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <ldns/config.h>
00014
00015 #include <ldns/ldns.h>
00016 #include <ldns/dnssec.h>
00017
00018 #include <strings.h>
00019 #include <time.h>
00020
00021 #ifdef HAVE_SSL
00022
00023
00024
00025 #include <openssl/ssl.h>
00026 #include <openssl/evp.h>
00027 #include <openssl/rand.h>
00028 #include <openssl/err.h>
00029 #include <openssl/md5.h>
00030
00031 ldns_rr *
00032 ldns_dnssec_get_rrsig_for_name_and_type(const ldns_rdf *name,
00033 const ldns_rr_type type,
00034 const ldns_rr_list *rrs)
00035 {
00036 size_t i;
00037 ldns_rr *candidate;
00038
00039 if (!name || !rrs) {
00040 return NULL;
00041 }
00042
00043 for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
00044 candidate = ldns_rr_list_rr(rrs, i);
00045 if (ldns_rr_get_type(candidate) == LDNS_RR_TYPE_RRSIG) {
00046 if (ldns_dname_compare(ldns_rr_owner(candidate),
00047 name) == 0 &&
00048 ldns_rdf2native_int8(ldns_rr_rrsig_typecovered(candidate)) ==
00049 type
00050 ) {
00051 return candidate;
00052 }
00053 }
00054 }
00055
00056 return NULL;
00057 }
00058
00059 ldns_rr *
00060 ldns_dnssec_get_dnskey_for_rrsig(const ldns_rr *rrsig, const ldns_rr_list *rrs)
00061 {
00062 size_t i;
00063 ldns_rr *candidate;
00064
00065 if (!rrsig || !rrs) {
00066 return NULL;
00067 }
00068
00069 for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
00070 candidate = ldns_rr_list_rr(rrs, i);
00071 if (ldns_rr_get_type(candidate) == LDNS_RR_TYPE_DNSKEY) {
00072 if (ldns_dname_compare(ldns_rr_owner(candidate),
00073 ldns_rr_rrsig_signame(rrsig)) == 0 &&
00074 ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig)) ==
00075 ldns_calc_keytag(candidate)
00076 ) {
00077 return candidate;
00078 }
00079 }
00080 }
00081
00082 return NULL;
00083 }
00084
00085 ldns_rdf *
00086 ldns_nsec_get_bitmap(ldns_rr *nsec) {
00087 if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC) {
00088 return ldns_rr_rdf(nsec, 1);
00089 } else if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC3) {
00090 return ldns_rr_rdf(nsec, 5);
00091 } else {
00092 return NULL;
00093 }
00094 }
00095
00096
00097
00098
00099 static int verbosity = 5;
00100
00101 ldns_rdf *
00102 ldns_dnssec_nsec3_closest_encloser(ldns_rdf *qname,
00103 ldns_rr_type qtype,
00104 ldns_rr_list *nsec3s)
00105 {
00106
00107 uint8_t algorithm;
00108 uint32_t iterations;
00109 uint8_t salt_length;
00110 uint8_t *salt;
00111
00112 ldns_rdf *sname, *hashed_sname, *tmp;
00113 ldns_rr *ce;
00114 bool flag;
00115
00116 bool exact_match_found;
00117 bool in_range_found;
00118
00119 ldns_status status;
00120 ldns_rdf *zone_name;
00121
00122 size_t nsec_i;
00123 ldns_rr *nsec;
00124 ldns_rdf *result = NULL;
00125
00126 if (!qname || !nsec3s || ldns_rr_list_rr_count(nsec3s) < 1) {
00127 return NULL;
00128 }
00129
00130 if (verbosity >= 4) {
00131 printf(";; finding closest encloser for type %d ", qtype);
00132 ldns_rdf_print(stdout, qname);
00133 printf("\n");
00134 }
00135
00136 nsec = ldns_rr_list_rr(nsec3s, 0);
00137 algorithm = ldns_nsec3_algorithm(nsec);
00138 salt_length = ldns_nsec3_salt_length(nsec);
00139 salt = ldns_nsec3_salt_data(nsec);
00140 iterations = ldns_nsec3_iterations(nsec);
00141
00142 sname = ldns_rdf_clone(qname);
00143
00144 ce = NULL;
00145 flag = false;
00146
00147 zone_name = ldns_dname_left_chop(ldns_rr_owner(nsec));
00148
00149
00150 while (ldns_dname_label_count(sname) > 0) {
00151 exact_match_found = false;
00152 in_range_found = false;
00153
00154 if (verbosity >= 3) {
00155 printf(";; ");
00156 ldns_rdf_print(stdout, sname);
00157 printf(" hashes to: ");
00158 }
00159 hashed_sname = ldns_nsec3_hash_name(sname, algorithm, iterations, salt_length, salt);
00160
00161 status = ldns_dname_cat(hashed_sname, zone_name);
00162
00163 if (verbosity >= 3) {
00164 ldns_rdf_print(stdout, hashed_sname);
00165 printf("\n");
00166 }
00167
00168 for (nsec_i = 0; nsec_i < ldns_rr_list_rr_count(nsec3s); nsec_i++) {
00169 nsec = ldns_rr_list_rr(nsec3s, nsec_i);
00170
00171
00172
00173
00174 if (ldns_dname_compare(ldns_rr_owner(nsec), hashed_sname) == 0) {
00175 if (verbosity >= 4) {
00176 printf(";; exact match found\n");
00177 }
00178 exact_match_found = true;
00179 } else if (ldns_nsec_covers_name(nsec, hashed_sname)) {
00180 if (verbosity >= 4) {
00181 printf(";; in range of an nsec\n");
00182 }
00183 in_range_found = true;
00184 }
00185
00186 }
00187 if (!exact_match_found && in_range_found) {
00188 flag = true;
00189 } else if (exact_match_found && flag) {
00190 result = ldns_rdf_clone(sname);
00191 } else if (exact_match_found && !flag) {
00192
00193 if (verbosity >= 4) {
00194 printf(";; the closest encloser is the same name (ie. this is an exact match, ie there is no closest encloser)\n");
00195 }
00196 ldns_rdf_deep_free(hashed_sname);
00197 goto done;
00198 } else {
00199 flag = false;
00200 }
00201
00202 ldns_rdf_deep_free(hashed_sname);
00203 tmp = sname;
00204 sname = ldns_dname_left_chop(sname);
00205 ldns_rdf_deep_free(tmp);
00206 }
00207
00208 done:
00209 LDNS_FREE(salt);
00210 ldns_rdf_deep_free(zone_name);
00211 ldns_rdf_deep_free(sname);
00212
00213 if (!result) {
00214 if (verbosity >= 4) {
00215 printf(";; no closest encloser found\n");
00216 }
00217 }
00218
00219 return result;
00220 }
00221
00222 bool
00223 ldns_dnssec_pkt_has_rrsigs(const ldns_pkt *pkt)
00224 {
00225 size_t i;
00226 for (i = 0; i < ldns_pkt_ancount(pkt); i++) {
00227 if (ldns_rr_get_type(ldns_rr_list_rr(ldns_pkt_answer(pkt), i)) ==
00228 LDNS_RR_TYPE_RRSIG) {
00229 return true;
00230 }
00231 }
00232 for (i = 0; i < ldns_pkt_nscount(pkt); i++) {
00233 if (ldns_rr_get_type(ldns_rr_list_rr(ldns_pkt_authority(pkt), i)) ==
00234 LDNS_RR_TYPE_RRSIG) {
00235 return true;
00236 }
00237 }
00238 return false;
00239 }
00240
00241 ldns_rr_list *
00242 ldns_dnssec_pkt_get_rrsigs_for_name_and_type(const ldns_pkt *pkt, ldns_rdf *name, ldns_rr_type type)
00243 {
00244 uint16_t t_netorder;
00245 ldns_rr_list *sigs;
00246 ldns_rr_list *sigs_covered;
00247 ldns_rdf *rdf_t;
00248
00249 sigs = ldns_pkt_rr_list_by_name_and_type(pkt,
00250 name,
00251 LDNS_RR_TYPE_RRSIG,
00252 LDNS_SECTION_ANY_NOQUESTION
00253 );
00254
00255 t_netorder = htons(type);
00256 rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE, sizeof(ldns_rr_type), &t_netorder);
00257 sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0);
00258
00259 ldns_rdf_free(rdf_t);
00260 ldns_rr_list_deep_free(sigs);
00261
00262 return sigs_covered;
00263
00264 }
00265
00266 ldns_rr_list *
00267 ldns_dnssec_pkt_get_rrsigs_for_type(const ldns_pkt *pkt, ldns_rr_type type)
00268 {
00269 uint16_t t_netorder;
00270 ldns_rr_list *sigs;
00271 ldns_rr_list *sigs_covered;
00272 ldns_rdf *rdf_t;
00273
00274 sigs = ldns_pkt_rr_list_by_type(pkt,
00275 LDNS_RR_TYPE_RRSIG,
00276 LDNS_SECTION_ANY_NOQUESTION
00277 );
00278
00279 t_netorder = htons(type);
00280 rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE, sizeof(ldns_rr_type), &t_netorder);
00281 sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0);
00282
00283 ldns_rdf_free(rdf_t);
00284 ldns_rr_list_deep_free(sigs);
00285
00286 return sigs_covered;
00287
00288 }
00289
00290
00291 uint16_t
00292 ldns_calc_keytag(const ldns_rr *key)
00293 {
00294 uint16_t ac16;
00295 ldns_buffer *keybuf;
00296 size_t keysize;
00297
00298 if (!key) {
00299 return 0;
00300 }
00301
00302
00303
00304
00305
00306 if (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY &&
00307 ldns_rr_get_type(key) != LDNS_RR_TYPE_KEY
00308 ) {
00309 return 0;
00310 }
00311
00312
00313 keybuf = ldns_buffer_new(LDNS_MIN_BUFLEN);
00314 if (!keybuf) {
00315 return 0;
00316 }
00317 (void)ldns_rr_rdata2buffer_wire(keybuf, key);
00318
00319 keysize= ldns_buffer_position(keybuf);
00320
00321 ac16 = ldns_calc_keytag_raw(ldns_buffer_begin(keybuf), keysize);
00322 ldns_buffer_free(keybuf);
00323 return ac16;
00324 }
00325
00326 uint16_t ldns_calc_keytag_raw(uint8_t* key, size_t keysize)
00327 {
00328 unsigned int i;
00329 uint32_t ac32;
00330 uint16_t ac16;
00331
00332 if(keysize < 4) {
00333 return 0;
00334 }
00335
00336 if (key[3] == LDNS_RSAMD5) {
00337 ac16 = 0;
00338 if (keysize > 4) {
00339 memmove(&ac16, key + keysize - 3, 2);
00340 }
00341 ac16 = ntohs(ac16);
00342 return (uint16_t) ac16;
00343 } else {
00344 ac32 = 0;
00345 for (i = 0; (size_t)i < keysize; ++i) {
00346 ac32 += (i & 1) ? key[i] : key[i] << 8;
00347 }
00348 ac32 += (ac32 >> 16) & 0xFFFF;
00349 return (uint16_t) (ac32 & 0xFFFF);
00350 }
00351 }
00352
00353 DSA *
00354 ldns_key_buf2dsa(ldns_buffer *key)
00355 {
00356 return ldns_key_buf2dsa_raw((unsigned char*)ldns_buffer_begin(key),
00357 ldns_buffer_position(key));
00358 }
00359
00360 DSA *
00361 ldns_key_buf2dsa_raw(unsigned char* key, size_t len)
00362 {
00363 uint8_t T;
00364 uint16_t length;
00365 uint16_t offset;
00366 DSA *dsa;
00367 BIGNUM *Q; BIGNUM *P;
00368 BIGNUM *G; BIGNUM *Y;
00369
00370 if(len == 0)
00371 return NULL;
00372 T = (uint8_t)key[0];
00373 length = (64 + T * 8);
00374 offset = 1;
00375
00376 if (T > 8) {
00377 return NULL;
00378 }
00379 if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
00380 return NULL;
00381
00382 Q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
00383 offset += SHA_DIGEST_LENGTH;
00384
00385 P = BN_bin2bn(key+offset, (int)length, NULL);
00386 offset += length;
00387
00388 G = BN_bin2bn(key+offset, (int)length, NULL);
00389 offset += length;
00390
00391 Y = BN_bin2bn(key+offset, (int)length, NULL);
00392 offset += length;
00393
00394
00395 dsa = DSA_new();
00396 dsa->p = P;
00397 dsa->q = Q;
00398 dsa->g = G;
00399 dsa->pub_key = Y;
00400
00401 return dsa;
00402 }
00403
00404 RSA *
00405 ldns_key_buf2rsa(ldns_buffer *key)
00406 {
00407 return ldns_key_buf2rsa_raw((unsigned char*)ldns_buffer_begin(key),
00408 ldns_buffer_position(key));
00409 }
00410
00411 RSA *
00412 ldns_key_buf2rsa_raw(unsigned char* key, size_t len)
00413 {
00414 uint16_t offset;
00415 uint16_t exp;
00416 uint16_t int16;
00417 RSA *rsa;
00418 BIGNUM *modulus;
00419 BIGNUM *exponent;
00420
00421 if (len == 0)
00422 return NULL;
00423 if (key[0] == 0) {
00424 if(len < 3)
00425 return NULL;
00426
00427
00428
00429 memmove(&int16, key+1, 2);
00430 exp = ntohs(int16);
00431 offset = 3;
00432 } else {
00433 exp = key[0];
00434 offset = 1;
00435 }
00436
00437
00438 if(len < (size_t)offset + exp + 1)
00439 return NULL;
00440
00441
00442 exponent = BN_new();
00443 (void) BN_bin2bn(key+offset, (int)exp, exponent);
00444 offset += exp;
00445
00446
00447 modulus = BN_new();
00448
00449 (void) BN_bin2bn(key+offset, (int)(len - offset), modulus);
00450
00451 rsa = RSA_new();
00452 rsa->n = modulus;
00453 rsa->e = exponent;
00454
00455 return rsa;
00456 }
00457
00458 ldns_rr *
00459 ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
00460 {
00461 ldns_rdf *tmp;
00462 ldns_rr *ds;
00463 uint16_t keytag;
00464 uint8_t sha1hash;
00465 uint8_t *digest;
00466 ldns_buffer *data_buf;
00467
00468 if (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY) {
00469 return NULL;
00470 }
00471
00472 ds = ldns_rr_new();
00473 if (!ds) {
00474 return NULL;
00475 }
00476 ldns_rr_set_type(ds, LDNS_RR_TYPE_DS);
00477 ldns_rr_set_owner(ds, ldns_rdf_clone(
00478 ldns_rr_owner(key)));
00479 ldns_rr_set_ttl(ds, ldns_rr_ttl(key));
00480 ldns_rr_set_class(ds, ldns_rr_get_class(key));
00481
00482 switch(h) {
00483 default:
00484 case LDNS_SHA1:
00485 digest = LDNS_XMALLOC(uint8_t, SHA_DIGEST_LENGTH);
00486 if (!digest) {
00487 ldns_rr_free(ds);
00488 return NULL;
00489 }
00490 break;
00491 case LDNS_SHA256:
00492 #ifdef SHA256_DIGEST_LENGTH
00493 digest = LDNS_XMALLOC(uint8_t, SHA256_DIGEST_LENGTH);
00494 if (!digest) {
00495 ldns_rr_free(ds);
00496 return NULL;
00497 }
00498 #else
00499 return NULL;
00500 #endif
00501 break;
00502 }
00503
00504 data_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00505 if (!data_buf) {
00506 LDNS_FREE(digest);
00507 ldns_rr_free(ds);
00508 return NULL;
00509 }
00510
00511
00512 keytag = htons(ldns_calc_keytag((ldns_rr*)key));
00513 tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT16, sizeof(uint16_t), &keytag);
00514 ldns_rr_push_rdf(ds, tmp);
00515
00516
00517 ldns_rr_push_rdf(ds, ldns_rdf_clone( ldns_rr_rdf(key, 2)));
00518
00519
00520 sha1hash = (uint8_t)h;
00521 tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8, sizeof(uint8_t), &sha1hash);
00522 ldns_rr_push_rdf(ds, tmp);
00523
00524
00525
00526 tmp = ldns_rdf_clone(ldns_rr_owner(key));
00527 ldns_dname2canonical(tmp);
00528 if (ldns_rdf2buffer_wire(data_buf, tmp) != LDNS_STATUS_OK) {
00529 LDNS_FREE(digest);
00530 ldns_buffer_free(data_buf);
00531 ldns_rr_free(ds);
00532 ldns_rdf_deep_free(tmp);
00533 return NULL;
00534 }
00535 ldns_rdf_deep_free(tmp);
00536
00537
00538 if (ldns_rr_rdata2buffer_wire(data_buf, (ldns_rr*)key) != LDNS_STATUS_OK) {
00539 LDNS_FREE(digest);
00540 ldns_buffer_free(data_buf);
00541 ldns_rr_free(ds);
00542 return NULL;
00543 }
00544 switch(h) {
00545 case LDNS_SHA1:
00546 (void) SHA1((unsigned char *) ldns_buffer_begin(data_buf),
00547 ldns_buffer_position(data_buf),
00548 (unsigned char*) digest);
00549
00550 tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX, SHA_DIGEST_LENGTH,
00551 digest);
00552 ldns_rr_push_rdf(ds, tmp);
00553
00554 break;
00555 case LDNS_SHA256:
00556 #ifdef SHA256_DIGEST_LENGTH
00557 (void) SHA256((unsigned char *) ldns_buffer_begin(data_buf),
00558 ldns_buffer_position(data_buf),
00559 (unsigned char*) digest);
00560 tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX, SHA256_DIGEST_LENGTH,
00561 digest);
00562 ldns_rr_push_rdf(ds, tmp);
00563 #endif
00564 break;
00565 }
00566
00567 LDNS_FREE(digest);
00568 ldns_buffer_free(data_buf);
00569 return ds;
00570 }
00571
00572 ldns_rdf *
00573 ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[],
00574 size_t size,
00575 ldns_rr_type nsec_type)
00576 {
00577 size_t i;
00578 uint8_t *bitmap;
00579 uint16_t bm_len = 0;
00580 uint16_t i_type;
00581 ldns_rdf *bitmap_rdf;
00582
00583 uint8_t *data = NULL;
00584 uint8_t cur_data[32];
00585 uint8_t cur_window = 0;
00586 uint8_t cur_window_max = 0;
00587 uint16_t cur_data_size = 0;
00588
00589 if (nsec_type != LDNS_RR_TYPE_NSEC &&
00590 nsec_type != LDNS_RR_TYPE_NSEC3) {
00591 return NULL;
00592 }
00593
00594
00595
00596 i_type = rr_type_list[size-1];
00597 if (i_type < nsec_type) {
00598 i_type = nsec_type;
00599 }
00600 bm_len = i_type / 8 + 2;
00601 bitmap = LDNS_XMALLOC(uint8_t, bm_len);
00602 for (i = 0; i < bm_len; i++) {
00603 bitmap[i] = 0;
00604 }
00605
00606 for (i = 0; i < size; i++) {
00607 i_type = rr_type_list[i];
00608 ldns_set_bit(bitmap + (int) i_type / 8, (int) (7 - (i_type % 8)), true);
00609 }
00610
00611 i_type = LDNS_RR_TYPE_RRSIG;
00612 ldns_set_bit(bitmap + (int) i_type / 8, (int) (7 - (i_type % 8)), true);
00613 i_type = nsec_type;
00614 if (i_type != LDNS_RR_TYPE_NSEC3) {
00615 ldns_set_bit(bitmap + (int) i_type / 8, (int) (7 - (i_type % 8)), true);
00616 }
00617
00618
00619 memset(cur_data, 0, 32);
00620 for (i = 0; i < bm_len; i++) {
00621 if (i / 32 > cur_window) {
00622
00623 if (cur_window_max > 0) {
00624
00625 data = LDNS_XREALLOC(data, uint8_t, cur_data_size + cur_window_max + 3);
00626 data[cur_data_size] = cur_window;
00627 data[cur_data_size + 1] = cur_window_max + 1;
00628 memcpy(data + cur_data_size + 2, cur_data, cur_window_max+1);
00629 cur_data_size += cur_window_max + 3;
00630 }
00631 cur_window++;
00632 cur_window_max = 0;
00633 memset(cur_data, 0, 32);
00634 } else {
00635 cur_data[i%32] = bitmap[i];
00636 if (bitmap[i] > 0) {
00637 cur_window_max = i%32;
00638 }
00639 }
00640 }
00641 if (cur_window_max > 0) {
00642
00643 data = LDNS_XREALLOC(data,
00644 uint8_t,
00645 cur_data_size + cur_window_max + 3);
00646 data[cur_data_size] = cur_window;
00647 data[cur_data_size + 1] = cur_window_max + 1;
00648 memcpy(data + cur_data_size + 2, cur_data, cur_window_max+1);
00649 cur_data_size += cur_window_max + 3;
00650 }
00651
00652 bitmap_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC,
00653 cur_data_size,
00654 data);
00655
00656 LDNS_FREE(bitmap);
00657 LDNS_FREE(data);
00658
00659 return bitmap_rdf;
00660 }
00661
00662 ldns_rr *
00663 ldns_dnssec_create_nsec(ldns_dnssec_name *from, ldns_dnssec_name *to, ldns_rr_type nsec_type)
00664 {
00665 ldns_rr *nsec_rr;
00666 ldns_rr_type types[1024];
00667 size_t type_count = 0;
00668 ldns_dnssec_rrsets *cur_rrsets;
00669
00670 if (!from || !to || (nsec_type != LDNS_RR_TYPE_NSEC &&
00671 nsec_type != LDNS_RR_TYPE_NSEC3)) {
00672 return NULL;
00673 }
00674
00675 nsec_rr = ldns_rr_new();
00676 ldns_rr_set_type(nsec_rr, nsec_type);
00677 ldns_rr_set_owner(nsec_rr, ldns_rdf_clone(ldns_dnssec_name_name(from)));
00678 ldns_rr_push_rdf(nsec_rr, ldns_rdf_clone(ldns_dnssec_name_name(to)));
00679
00680 cur_rrsets = from->rrsets;
00681 while (cur_rrsets) {
00682 types[type_count] = cur_rrsets->type;
00683 type_count++;
00684 cur_rrsets = cur_rrsets->next;
00685 }
00686
00687 ldns_rr_push_rdf(nsec_rr, ldns_dnssec_create_nsec_bitmap(types,
00688 type_count,
00689 nsec_type));
00690
00691 return nsec_rr;
00692 }
00693
00694 ldns_rr *
00695 ldns_dnssec_create_nsec3(ldns_dnssec_name *from,
00696 ldns_dnssec_name *to,
00697 ldns_rdf *zone_name,
00698 uint8_t algorithm,
00699 uint8_t flags,
00700 uint16_t iterations,
00701 uint8_t salt_length,
00702 uint8_t *salt)
00703 {
00704 ldns_rr *nsec_rr;
00705 ldns_rr_type types[1024];
00706 size_t type_count = 0;
00707 ldns_dnssec_rrsets *cur_rrsets;
00708 ldns_status status;
00709
00710 flags = flags;
00711
00712 if (!from || !to) {
00713 return NULL;
00714 }
00715
00716 nsec_rr = ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3);
00717 ldns_rr_set_owner(nsec_rr, ldns_nsec3_hash_name(ldns_dnssec_name_name(from), algorithm, iterations, salt_length, salt));
00718
00719 status = ldns_dname_cat(ldns_rr_owner(nsec_rr), zone_name);
00720 ldns_nsec3_add_param_rdfs(nsec_rr, algorithm, flags, iterations, salt_length, salt);
00721
00722
00723 cur_rrsets = from->rrsets;
00724 while (cur_rrsets) {
00725 types[type_count] = cur_rrsets->type;
00726 type_count++;
00727 cur_rrsets = cur_rrsets->next;
00728 }
00729
00730 ldns_rr_set_rdf(nsec_rr, NULL, 4);
00731 ldns_rr_set_rdf(nsec_rr,
00732 ldns_dnssec_create_nsec_bitmap(types,
00733 type_count,
00734 LDNS_RR_TYPE_NSEC3), 5);
00735
00736 return nsec_rr;
00737 }
00738
00739 ldns_rr *
00740 ldns_create_nsec(ldns_rdf *cur_owner, ldns_rdf *next_owner, ldns_rr_list *rrs)
00741 {
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752 uint16_t i;
00753 ldns_rr *i_rr;
00754
00755 uint8_t *bitmap = LDNS_XMALLOC(uint8_t, 2);
00756 uint16_t bm_len = 0;
00757 uint16_t i_type;
00758
00759 ldns_rr *nsec = NULL;
00760
00761 uint8_t *data = NULL;
00762 uint8_t cur_data[32];
00763 uint8_t cur_window = 0;
00764 uint8_t cur_window_max = 0;
00765 uint16_t cur_data_size = 0;
00766
00767 nsec = ldns_rr_new();
00768 ldns_rr_set_type(nsec, LDNS_RR_TYPE_NSEC);
00769 ldns_rr_set_owner(nsec, ldns_rdf_clone(cur_owner));
00770
00771 ldns_rr_push_rdf(nsec, ldns_rdf_clone(next_owner));
00772
00773 bitmap[0] = 0;
00774 for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
00775 i_rr = ldns_rr_list_rr(rrs, i);
00776
00777 if (ldns_rdf_compare(cur_owner,
00778 ldns_rr_owner(i_rr)) == 0) {
00779
00780 i_type = ldns_rr_get_type(i_rr);
00781 if ((i_type / 8) + 1 > bm_len) {
00782 bitmap = LDNS_XREALLOC(bitmap, uint8_t, (i_type / 8) + 2);
00783
00784 for (; bm_len <= i_type / 8; bm_len++) {
00785 bitmap[bm_len] = 0;
00786 }
00787 }
00788 ldns_set_bit(bitmap + (int) i_type / 8, (int) (7 - (i_type % 8)), true);
00789 }
00790 }
00791
00792 i_type = LDNS_RR_TYPE_RRSIG;
00793 if (i_type / 8 > bm_len) {
00794 bitmap = LDNS_XREALLOC(bitmap, uint8_t, (i_type / 8) + 2);
00795
00796 for (; bm_len <= i_type / 8; bm_len++) {
00797 bitmap[bm_len] = 0;
00798 }
00799 }
00800 ldns_set_bit(bitmap + (int) i_type / 8, (int) (7 - (i_type % 8)), true);
00801 i_type = LDNS_RR_TYPE_NSEC;
00802
00803 if (i_type / 8 > bm_len) {
00804 bitmap = LDNS_XREALLOC(bitmap, uint8_t, (i_type / 8) + 2);
00805
00806 for (; bm_len <= i_type / 8; bm_len++) {
00807 bitmap[bm_len] = 0;
00808 }
00809 }
00810 ldns_set_bit(bitmap + (int) i_type / 8, (int) (7 - (i_type % 8)), true);
00811
00812 memset(cur_data, 0, 32);
00813 for (i = 0; i < bm_len; i++) {
00814 if (i / 32 > cur_window) {
00815
00816 if (cur_window_max > 0) {
00817
00818 data = LDNS_XREALLOC(data, uint8_t, cur_data_size + cur_window_max + 3);
00819 data[cur_data_size] = cur_window;
00820 data[cur_data_size + 1] = cur_window_max + 1;
00821 memcpy(data + cur_data_size + 2, cur_data, cur_window_max+1);
00822 cur_data_size += cur_window_max + 3;
00823 }
00824 cur_window++;
00825 cur_window_max = 0;
00826 memset(cur_data, 0, 32);
00827 } else {
00828 cur_data[i%32] = bitmap[i];
00829 if (bitmap[i] > 0) {
00830 cur_window_max = i%32;
00831 }
00832 }
00833 }
00834 if (cur_window_max > 0) {
00835
00836 data = LDNS_XREALLOC(data, uint8_t, cur_data_size + cur_window_max + 3);
00837 data[cur_data_size] = cur_window;
00838 data[cur_data_size + 1] = cur_window_max + 1;
00839 memcpy(data + cur_data_size + 2, cur_data, cur_window_max+1);
00840 cur_data_size += cur_window_max + 3;
00841 }
00842
00843 ldns_rr_push_rdf(nsec, ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC, cur_data_size, data));
00844
00845 LDNS_FREE(bitmap);
00846 LDNS_FREE(data);
00847 return nsec;
00848 }
00849
00850 ldns_rdf *
00851 ldns_nsec3_hash_name(ldns_rdf *name, uint8_t algorithm, uint16_t iterations, uint8_t salt_length, uint8_t *salt)
00852 {
00853 char *orig_owner_str;
00854 size_t hashed_owner_str_len;
00855 ldns_rdf *hashed_owner;
00856 char *hashed_owner_str;
00857 char *hashed_owner_b32;
00858 int hashed_owner_b32_len;
00859 uint32_t cur_it;
00860 char *hash = NULL;
00861 ldns_status status;
00862
00863
00864 orig_owner_str = ldns_rdf2str(name);
00865
00866
00867 algorithm = algorithm;
00868
00869 hashed_owner_str_len = salt_length + ldns_rdf_size(name);
00870 hashed_owner_str = LDNS_XMALLOC(char, hashed_owner_str_len);
00871 memcpy(hashed_owner_str, ldns_rdf_data(name), ldns_rdf_size(name));
00872 memcpy(hashed_owner_str + ldns_rdf_size(name), salt, salt_length);
00873
00874 for (cur_it = iterations + 1; cur_it > 0; cur_it--) {
00875
00876 hash = (char *) SHA1((unsigned char *) hashed_owner_str, hashed_owner_str_len, NULL);
00877
00878 LDNS_FREE(hashed_owner_str);
00879 hashed_owner_str_len = salt_length + SHA_DIGEST_LENGTH;
00880 hashed_owner_str = LDNS_XMALLOC(char, hashed_owner_str_len);
00881 if (!hashed_owner_str) {
00882 fprintf(stderr, "Memory error\n");
00883 abort();
00884 }
00885 memcpy(hashed_owner_str, hash, SHA_DIGEST_LENGTH);
00886 memcpy(hashed_owner_str + SHA_DIGEST_LENGTH, salt, salt_length);
00887 hashed_owner_str_len = SHA_DIGEST_LENGTH + salt_length;
00888 }
00889
00890 LDNS_FREE(orig_owner_str);
00891 LDNS_FREE(hashed_owner_str);
00892 hashed_owner_str = hash;
00893 hashed_owner_str_len = SHA_DIGEST_LENGTH;
00894
00895 hashed_owner_b32 = LDNS_XMALLOC(char, b32_ntop_calculate_size(hashed_owner_str_len) + 1);
00896 hashed_owner_b32_len = (size_t) b32_ntop_extended_hex((uint8_t *) hashed_owner_str, hashed_owner_str_len, hashed_owner_b32, b32_ntop_calculate_size(hashed_owner_str_len));
00897 if (hashed_owner_b32_len < 1) {
00898 fprintf(stderr, "Error in base32 extended hex encoding of hashed owner name (name: ");
00899 ldns_rdf_print(stderr, name);
00900 fprintf(stderr, ", return code: %d)\n", hashed_owner_b32_len);
00901 exit(4);
00902 }
00903 hashed_owner_str_len = hashed_owner_b32_len;
00904 hashed_owner_b32[hashed_owner_b32_len] = '\0';
00905
00906 status = ldns_str2rdf_dname(&hashed_owner, hashed_owner_b32);
00907 if (status != LDNS_STATUS_OK) {
00908 fprintf(stderr, "Error creating rdf from %s\n", hashed_owner_b32);
00909 exit(1);
00910 }
00911
00912 LDNS_FREE(hashed_owner_b32);
00913 return hashed_owner;
00914 }
00915
00916 void
00917 ldns_nsec3_add_param_rdfs(ldns_rr *rr,
00918 uint8_t algorithm,
00919 uint8_t flags,
00920 uint16_t iterations,
00921 uint8_t salt_length,
00922 uint8_t *salt)
00923 {
00924 ldns_rdf *salt_rdf = NULL;
00925 uint8_t *salt_data = NULL;
00926
00927 ldns_rr_set_rdf(rr, ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8, 1, (void*)&algorithm), 0);
00928 ldns_rr_set_rdf(rr, ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8, 1, (void*)&flags), 1);
00929 ldns_rr_set_rdf(rr, ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, iterations), 2);
00930
00931 salt_data = LDNS_XMALLOC(uint8_t, salt_length + 1);
00932 salt_data[0] = salt_length;
00933 memcpy(salt_data + 1, salt, salt_length);
00934 salt_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC3_SALT, salt_length + 1, salt_data);
00935
00936 ldns_rr_set_rdf(rr, salt_rdf, 3);
00937 LDNS_FREE(salt_data);
00938 }
00939
00940
00941
00942 ldns_rr *
00943 ldns_create_nsec3(ldns_rdf *cur_owner,
00944 ldns_rdf *cur_zone,
00945 ldns_rr_list *rrs,
00946 uint8_t algorithm,
00947 uint8_t flags,
00948 uint16_t iterations,
00949 uint8_t salt_length,
00950 uint8_t *salt,
00951 bool emptynonterminal)
00952 {
00953 size_t i;
00954 ldns_rr *i_rr;
00955
00956 uint8_t *bitmap = LDNS_XMALLOC(uint8_t, 1);
00957 uint16_t bm_len = 0;
00958 uint16_t i_type;
00959
00960 ldns_rr *nsec = NULL;
00961 ldns_rdf *hashed_owner = NULL;
00962
00963 uint8_t *data = NULL;
00964 uint8_t cur_data[32];
00965 uint8_t cur_window = 0;
00966 uint8_t cur_window_max = 0;
00967 uint16_t cur_data_size = 0;
00968
00969 ldns_status status;
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983 hashed_owner = ldns_nsec3_hash_name(cur_owner, algorithm, iterations, salt_length, salt);
00984 status = ldns_dname_cat(hashed_owner, cur_zone);
00985
00986 nsec = ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3);
00987 ldns_rr_set_type(nsec, LDNS_RR_TYPE_NSEC3);
00988 ldns_rr_set_owner(nsec, hashed_owner);
00989
00990
00991 ldns_nsec3_add_param_rdfs(nsec, algorithm, flags, iterations, salt_length, salt);
00992 ldns_rr_set_rdf(nsec, NULL, 4);
00993
00994 bitmap[0] = 0;
00995 for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
00996 i_rr = ldns_rr_list_rr(rrs, i);
00997
00998 if (ldns_rdf_compare(cur_owner,
00999 ldns_rr_owner(i_rr)) == 0) {
01000
01001 i_type = ldns_rr_get_type(i_rr);
01002 if ((i_type / 8) + 1 > bm_len) {
01003 bitmap = LDNS_XREALLOC(bitmap, uint8_t, (i_type / 8) + 1);
01004
01005 for (; bm_len <= i_type / 8; bm_len++) {
01006 bitmap[bm_len] = 0;
01007 }
01008 }
01009 ldns_set_bit(bitmap + (int) i_type / 8, (int) (7 - (i_type % 8)), true);
01010 }
01011 }
01012
01013 if (!emptynonterminal) {
01014 i_type = LDNS_RR_TYPE_RRSIG;
01015 if (i_type / 8 > bm_len) {
01016 bitmap = LDNS_XREALLOC(bitmap, uint8_t, (i_type / 8) + 1);
01017
01018 for (; bm_len <= i_type / 8; bm_len++) {
01019 bitmap[bm_len] = 0;
01020 }
01021 }
01022 ldns_set_bit(bitmap + (int) i_type / 8, (int) (7 - (i_type % 8)), true);
01023 }
01024
01025
01026 if (ldns_dname_compare(cur_zone, cur_owner) == 0) {
01027 i_type = LDNS_RR_TYPE_SOA;
01028 if (i_type / 8 > bm_len) {
01029 bitmap = LDNS_XREALLOC(bitmap, uint8_t, (i_type / 8) + 1);
01030
01031 for (; bm_len <= i_type / 8; bm_len++) {
01032 bitmap[bm_len] = 0;
01033 }
01034 }
01035 ldns_set_bit(bitmap + (int) i_type / 8, (int) (7 - (i_type % 8)), true);
01036 }
01037
01038 memset(cur_data, 0, 32);
01039 for (i = 0; i < bm_len; i++) {
01040 if (i / 32 > cur_window) {
01041
01042 if (cur_window_max > 0) {
01043
01044 data = LDNS_XREALLOC(data, uint8_t, cur_data_size + cur_window_max + 3);
01045 data[cur_data_size] = cur_window;
01046 data[cur_data_size + 1] = cur_window_max + 1;
01047 memcpy(data + cur_data_size + 2, cur_data, cur_window_max+1);
01048 cur_data_size += cur_window_max + 3;
01049 }
01050 cur_window++;
01051 cur_window_max = 0;
01052 memset(cur_data, 0, 32);
01053 } else {
01054 cur_data[i%32] = bitmap[i];
01055 if (bitmap[i] > 0) {
01056 cur_window_max = i%32;
01057 }
01058 }
01059 }
01060 if (cur_window_max > 0) {
01061
01062 data = LDNS_XREALLOC(data, uint8_t, cur_data_size + cur_window_max + 3);
01063 data[cur_data_size] = cur_window;
01064 data[cur_data_size + 1] = cur_window_max + 1;
01065 memcpy(data + cur_data_size + 2, cur_data, cur_window_max+1);
01066 cur_data_size += cur_window_max + 3;
01067 }
01068
01069 ldns_rr_set_rdf(nsec, ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC, cur_data_size, data), 5);
01070
01071 LDNS_FREE(bitmap);
01072 LDNS_FREE(data);
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082 return nsec;
01083 }
01084
01085 uint8_t
01086 ldns_nsec3_algorithm(const ldns_rr *nsec3_rr)
01087 {
01088 if (nsec3_rr && ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 &&
01089 ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 0)) > 0
01090 ) {
01091
01092 return ldns_rdf2native_int8(ldns_rr_rdf(nsec3_rr, 0));
01093 }
01094 return 0;
01095 }
01096
01097 uint8_t
01098 ldns_nsec3_flags(const ldns_rr *nsec3_rr)
01099 {
01100 if (nsec3_rr && ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 &&
01101 ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 1)) > 0
01102 ) {
01103
01104 return ldns_rdf2native_int8(ldns_rr_rdf(nsec3_rr, 0));
01105 }
01106 return 0;
01107 }
01108
01109 bool
01110 ldns_nsec3_optout(const ldns_rr *nsec3_rr)
01111 {
01112 return (ldns_nsec3_flags(nsec3_rr) & LDNS_NSEC3_VARS_OPTOUT_MASK);
01113 }
01114
01115 uint16_t
01116 ldns_nsec3_iterations(const ldns_rr *nsec3_rr)
01117 {
01118 if (nsec3_rr && ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3 &&
01119 ldns_rdf_size(ldns_rr_rdf(nsec3_rr, 2)) > 0
01120 ) {
01121 return ldns_rdf2native_int16(ldns_rr_rdf(nsec3_rr, 2));
01122 }
01123 return 0;
01124
01125 }
01126
01127 ldns_rdf *
01128 ldns_nsec3_salt(const ldns_rr *nsec3_rr)
01129 {
01130 if (nsec3_rr && ldns_rr_get_type(nsec3_rr) == LDNS_RR_TYPE_NSEC3) {
01131 return ldns_rr_rdf(nsec3_rr, 3);
01132 }
01133 return NULL;
01134 }
01135
01136 uint8_t
01137 ldns_nsec3_salt_length(const ldns_rr *nsec3_rr)
01138 {
01139 ldns_rdf *salt_rdf = ldns_nsec3_salt(nsec3_rr);
01140 if (salt_rdf && ldns_rdf_size(salt_rdf) > 0) {
01141 return (uint8_t) ldns_rdf_data(salt_rdf)[0];
01142 }
01143 return 0;
01144 }
01145
01146
01147 uint8_t *
01148 ldns_nsec3_salt_data(const ldns_rr *nsec3_rr)
01149 {
01150 uint8_t salt_length;
01151 uint8_t *salt;
01152
01153 ldns_rdf *salt_rdf = ldns_nsec3_salt(nsec3_rr);
01154 if (salt_rdf && ldns_rdf_size(salt_rdf) > 0) {
01155 salt_length = ldns_rdf_data(salt_rdf)[0];
01156 salt = LDNS_XMALLOC(uint8_t, salt_length);
01157 memcpy(salt, &ldns_rdf_data(salt_rdf)[1], salt_length);
01158 return salt;
01159 }
01160 return NULL;
01161 }
01162
01163 ldns_rdf *
01164 ldns_nsec3_next_owner(const ldns_rr *nsec3_rr)
01165 {
01166 if (!nsec3_rr || ldns_rr_get_type(nsec3_rr) != LDNS_RR_TYPE_NSEC3) {
01167 return NULL;
01168 } else {
01169 return ldns_rr_rdf(nsec3_rr, 4);
01170 }
01171 }
01172
01173 ldns_rdf *
01174 ldns_nsec3_bitmap(const ldns_rr *nsec3_rr)
01175 {
01176 if (!nsec3_rr || ldns_rr_get_type(nsec3_rr) != LDNS_RR_TYPE_NSEC3) {
01177 return NULL;
01178 } else {
01179 return ldns_rr_rdf(nsec3_rr, 5);
01180 }
01181 }
01182
01183 ldns_rdf *
01184 ldns_nsec3_hash_name_frm_nsec3(const ldns_rr *nsec, ldns_rdf *name)
01185 {
01186 uint8_t algorithm;
01187 uint16_t iterations;
01188
01189 uint8_t salt_length;
01190 uint8_t *salt = 0;
01191
01192
01193 ldns_rdf *hashed_owner;
01194
01195
01196
01197
01198
01199
01200 algorithm = ldns_nsec3_algorithm(nsec);
01201 salt_length = ldns_nsec3_salt_length(nsec);
01202 salt = ldns_nsec3_salt_data(nsec);
01203 iterations = ldns_nsec3_iterations(nsec);
01204
01205 hashed_owner = ldns_nsec3_hash_name(name, algorithm, iterations, salt_length, salt);
01206
01207
01208
01209
01210
01211
01212
01213
01214 LDNS_FREE(salt);
01215 return hashed_owner;
01216 }
01217
01218 bool
01219 ldns_nsec_bitmap_covers_type(const ldns_rdf *nsec_bitmap, ldns_rr_type type)
01220 {
01221 uint8_t window_block_nr;
01222 uint8_t bitmap_length;
01223 uint16_t cur_type;
01224 uint16_t pos = 0;
01225 uint16_t bit_pos;
01226 uint8_t *data = ldns_rdf_data(nsec_bitmap);
01227
01228 while(pos < ldns_rdf_size(nsec_bitmap)) {
01229 window_block_nr = data[pos];
01230 bitmap_length = data[pos + 1];
01231 pos += 2;
01232
01233 for (bit_pos = 0; bit_pos < (bitmap_length) * 8; bit_pos++) {
01234 if (ldns_get_bit(&data[pos], bit_pos)) {
01235 cur_type = 256 * (uint16_t) window_block_nr + bit_pos;
01236 if (cur_type == type) {
01237 return true;
01238 }
01239 }
01240 }
01241
01242 pos += (uint16_t) bitmap_length;
01243 }
01244 return false;
01245 }
01246
01247 bool
01248 ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name)
01249 {
01250 ldns_rdf *nsec_owner = ldns_rr_owner(nsec);
01251 ldns_rdf *hash_next;
01252 char *next_hash_str;
01253 ldns_rdf *nsec_next = NULL;
01254 ldns_status status;
01255 ldns_rdf *chopped_dname;
01256 bool result;
01257
01258 if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC) {
01259 nsec_next = ldns_rdf_clone(ldns_rr_rdf(nsec, 0));
01260 } else if (ldns_rr_get_type(nsec) == LDNS_RR_TYPE_NSEC3) {
01261 hash_next = ldns_nsec3_next_owner(nsec);
01262 next_hash_str = ldns_rdf2str(hash_next);
01263 nsec_next = ldns_dname_new_frm_str(next_hash_str);
01264 LDNS_FREE(next_hash_str);
01265 chopped_dname = ldns_dname_left_chop(nsec_owner);
01266 status = ldns_dname_cat(nsec_next, chopped_dname);
01267 ldns_rdf_deep_free(chopped_dname);
01268 if (status != LDNS_STATUS_OK) {
01269 printf("error catting: %s\n", ldns_get_errorstr_by_id(status));
01270 }
01271 } else {
01272 ldns_rdf_deep_free(nsec_next);
01273 return false;
01274 }
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286 if(ldns_dname_compare(nsec_owner, nsec_next) > 0) {
01287 result = (ldns_dname_compare(nsec_owner, name) <= 0 ||
01288 ldns_dname_compare(name, nsec_next) < 0);
01289 } else {
01290 result = (ldns_dname_compare(nsec_owner, name) <= 0 &&
01291 ldns_dname_compare(name, nsec_next) < 0);
01292 }
01293
01294 ldns_rdf_deep_free(nsec_next);
01295 return result;
01296 }
01297
01298
01299 ldns_status
01300 ldns_pkt_verify(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o,
01301 ldns_rr_list *k, ldns_rr_list *s, ldns_rr_list *good_keys)
01302 {
01303 ldns_rr_list *rrset;
01304 ldns_rr_list *sigs;
01305 ldns_rr_list *sigs_covered;
01306 ldns_rdf *rdf_t;
01307 ldns_rr_type t_netorder;
01308
01309 if (!k) {
01310 return LDNS_STATUS_ERR;
01311
01312 }
01313
01314 if (t == LDNS_RR_TYPE_RRSIG) {
01315
01316
01317 return LDNS_STATUS_ERR;
01318 }
01319
01320 if (s) {
01321
01322 sigs = s;
01323 } else {
01324
01325 sigs = ldns_pkt_rr_list_by_name_and_type(p, o, LDNS_RR_TYPE_RRSIG,
01326 LDNS_SECTION_ANY_NOQUESTION);
01327 if (!sigs) {
01328
01329 return LDNS_STATUS_ERR;
01330
01331 }
01332 }
01333
01334
01335
01336
01337 t_netorder = htons(t);
01338 rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE, sizeof(ldns_rr_type), &t_netorder);
01339 sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0);
01340
01341 rrset = ldns_pkt_rr_list_by_name_and_type(p, o, t, LDNS_SECTION_ANY_NOQUESTION);
01342
01343 if (!rrset) {
01344 return LDNS_STATUS_ERR;
01345 }
01346
01347 if (!sigs_covered) {
01348 return LDNS_STATUS_ERR;
01349 }
01350
01351 return ldns_verify(rrset, sigs, k, good_keys);
01352 }
01353
01354 #if 0
01355 ldns_rr_list *
01356 ldns_zone_create_nsecs(const ldns_zone *zone, ldns_rr_list *orig_zone_rrs, ldns_rr_list *glue_rrs)
01357 {
01358 ldns_rr_list *nsec_rrs = ldns_rr_list_new();
01359 ldns_rdf *start_dname = NULL;
01360 ldns_rdf *next_dname = NULL;
01361 ldns_rdf *cur_dname = NULL;
01362
01363 ldns_rr *nsec = NULL;
01364 ldns_rr *next_rr = NULL;
01365 size_t i;
01366
01367
01368 for (i = 0; i < ldns_rr_list_rr_count(orig_zone_rrs); i++) {
01369 if (!start_dname) {
01370
01371 start_dname = ldns_rr_owner(ldns_rr_list_rr(orig_zone_rrs, i));
01372 cur_dname = start_dname;
01373 } else {
01374 next_rr = ldns_rr_list_rr(orig_zone_rrs, i);
01375 next_dname = ldns_rr_owner(next_rr);
01376 if (ldns_rdf_compare(cur_dname, next_dname) != 0) {
01377
01378 if (ldns_rr_list_contains_rr(glue_rrs, next_rr)) {
01379 cur_dname = next_dname;
01380 } else {
01381 nsec = ldns_create_nsec(cur_dname,
01382 next_dname,
01383 orig_zone_rrs);
01384 ldns_rr_set_ttl(nsec, ldns_rdf2native_int32(ldns_rr_rdf(ldns_zone_soa(zone), 6)));
01385 ldns_rr_list_push_rr(nsec_rrs, nsec);
01386
01387 cur_dname = next_dname;
01388 }
01389 }
01390 }
01391 }
01392 nsec = ldns_create_nsec(cur_dname,
01393 start_dname,
01394 orig_zone_rrs);
01395 ldns_rr_list_push_rr(nsec_rrs, nsec);
01396 ldns_rr_set_ttl(nsec, ldns_rdf2native_int32(ldns_rr_rdf(ldns_zone_soa(zone), 6)));
01397
01398 return nsec_rrs;
01399 }
01400
01401
01402
01403
01404 ldns_rr_list *
01405 ldns_rr_list_strip_dnssec(ldns_rr_list *rr_list, ldns_rr_list *removed_rrs)
01406 {
01407 size_t i;
01408 ldns_rr_list *new_list;
01409 ldns_rr *cur_rr;
01410
01411 if (!rr_list) {
01412 return NULL;
01413 }
01414
01415 new_list = ldns_rr_list_new();
01416
01417 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
01418 cur_rr = ldns_rr_list_rr(rr_list, i);
01419 if (ldns_rr_get_type(cur_rr) != LDNS_RR_TYPE_RRSIG &&
01420 ldns_rr_get_type(cur_rr) != LDNS_RR_TYPE_NSEC &&
01421 ldns_rr_get_type(cur_rr) != LDNS_RR_TYPE_NSEC3) {
01422 ldns_rr_list_push_rr(new_list, ldns_rr_clone(cur_rr));
01423 } else {
01424 if (removed_rrs) {
01425 ldns_rr_list_push_rr(removed_rrs, ldns_rr_clone(cur_rr));
01426 }
01427 }
01428 }
01429
01430 return new_list;
01431 }
01432 #endif
01433
01434 ldns_status
01435 ldns_dnssec_chain_nsec3_list(ldns_rr_list *nsec3_rrs)
01436 {
01437 size_t i;
01438 char *next_nsec_owner_str;
01439 ldns_rdf *next_nsec_owner_label;
01440 ldns_rdf *next_nsec_rdf;
01441 ldns_status status = LDNS_STATUS_OK;
01442
01443 for (i = 0; i < ldns_rr_list_rr_count(nsec3_rrs); i++) {
01444 if (i == ldns_rr_list_rr_count(nsec3_rrs) - 1) {
01445 next_nsec_owner_label = ldns_dname_label(ldns_rr_owner(ldns_rr_list_rr(nsec3_rrs, 0)), 0);
01446 next_nsec_owner_str = ldns_rdf2str(next_nsec_owner_label);
01447 if (next_nsec_owner_str[strlen(next_nsec_owner_str) - 1] == '.') {
01448 next_nsec_owner_str[strlen(next_nsec_owner_str) - 1] = '\0';
01449 }
01450 status = ldns_str2rdf_b32_ext(&next_nsec_rdf, next_nsec_owner_str);
01451 if (!ldns_rr_set_rdf(ldns_rr_list_rr(nsec3_rrs, i), next_nsec_rdf, 4)) {
01452
01453 }
01454
01455 ldns_rdf_deep_free(next_nsec_owner_label);
01456 LDNS_FREE(next_nsec_owner_str);
01457 } else {
01458 next_nsec_owner_label = ldns_dname_label(ldns_rr_owner(ldns_rr_list_rr(nsec3_rrs, i + 1)), 0);
01459 next_nsec_owner_str = ldns_rdf2str(next_nsec_owner_label);
01460 if (next_nsec_owner_str[strlen(next_nsec_owner_str) - 1] == '.') {
01461 next_nsec_owner_str[strlen(next_nsec_owner_str) - 1] = '\0';
01462 }
01463 status = ldns_str2rdf_b32_ext(&next_nsec_rdf, next_nsec_owner_str);
01464 ldns_rdf_deep_free(next_nsec_owner_label);
01465 LDNS_FREE(next_nsec_owner_str);
01466 if (!ldns_rr_set_rdf(ldns_rr_list_rr(nsec3_rrs, i), next_nsec_rdf, 4)) {
01467
01468 }
01469 }
01470 }
01471 return status;
01472 }
01473
01474 int
01475 qsort_rr_compare_nsec3(const void *a, const void *b)
01476 {
01477 const ldns_rr *rr1 = * (const ldns_rr **) a;
01478 const ldns_rr *rr2 = * (const ldns_rr **) b;
01479 if (rr1 == NULL && rr2 == NULL) {
01480 return 0;
01481 }
01482 if (rr1 == NULL) {
01483 return -1;
01484 }
01485 if (rr2 == NULL) {
01486 return 1;
01487 }
01488 return ldns_rdf_compare(ldns_rr_owner(rr1), ldns_rr_owner(rr2));
01489 }
01490
01491 void
01492 ldns_rr_list_sort_nsec3(ldns_rr_list *unsorted)
01493 {
01494 qsort(unsorted->_rrs,
01495 ldns_rr_list_rr_count(unsorted),
01496 sizeof(ldns_rr *),
01497 qsort_rr_compare_nsec3);
01498 }
01499
01500 ldns_status
01501 ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
01502 ldns_rr_list *new_rrs,
01503 uint8_t algorithm,
01504 uint8_t flags,
01505 uint16_t iterations,
01506 uint8_t salt_length,
01507 uint8_t *salt)
01508 {
01509 ldns_rbnode_t *first_name_node;
01510 ldns_rbnode_t *current_name_node;
01511 ldns_dnssec_name *first_name;
01512 ldns_dnssec_name *current_name;
01513 ldns_status result = LDNS_STATUS_OK;
01514 ldns_rr *nsec_rr;
01515 ldns_rr_list *nsec3_list;
01516
01517 if (!zone || !new_rrs || !zone->names) {
01518 return LDNS_STATUS_ERR;
01519 }
01520
01521 nsec3_list = ldns_rr_list_new();
01522
01523 first_name_node = ldns_rbtree_first(zone->names);
01524 first_name = (ldns_dnssec_name *) first_name_node->data;
01525
01526 current_name_node = first_name_node;
01527 current_name = first_name;
01528
01529 while (ldns_rbtree_next(current_name_node) != LDNS_RBTREE_NULL) {
01530 nsec_rr = ldns_dnssec_create_nsec3(current_name,
01531 (ldns_dnssec_name *) ldns_rbtree_next(current_name_node)->data,
01532 zone->soa->name,
01533 algorithm,
01534 flags,
01535 iterations,
01536 salt_length,
01537 salt);
01538 ldns_dnssec_name_add_rr(current_name, nsec_rr);
01539 ldns_rr_list_push_rr(new_rrs, nsec_rr);
01540 ldns_rr_list_push_rr(nsec3_list, nsec_rr);
01541 current_name_node = ldns_rbtree_next(current_name_node);
01542 current_name = (ldns_dnssec_name *) current_name_node->data;
01543 }
01544 nsec_rr = ldns_dnssec_create_nsec3(current_name,
01545 first_name,
01546 zone->soa->name,
01547 algorithm,
01548 flags,
01549 iterations,
01550 salt_length,
01551 salt);
01552 result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
01553 ldns_rr_list_push_rr(new_rrs, nsec_rr);
01554 ldns_rr_list_push_rr(nsec3_list, nsec_rr);
01555
01556 ldns_rr_list_sort_nsec3(nsec3_list);
01557 ldns_dnssec_chain_nsec3_list(nsec3_list);
01558 if (result != LDNS_STATUS_OK) {
01559 return result;
01560 }
01561
01562 ldns_rr_list_free(nsec3_list);
01563 return result;
01564 }
01565
01566 int
01567 ldns_dnssec_default_add_to_signatures(ldns_rr *sig, void *n)
01568 {
01569 sig = sig;
01570 n = n;
01571 return LDNS_SIGNATURE_LEAVE_ADD_NEW;
01572 }
01573
01574 int
01575 ldns_dnssec_default_leave_signatures(ldns_rr *sig, void *n)
01576 {
01577 sig = sig;
01578 n = n;
01579 return LDNS_SIGNATURE_LEAVE_NO_ADD;
01580 }
01581
01582 int
01583 ldns_dnssec_default_delete_signatures(ldns_rr *sig, void *n)
01584 {
01585 sig = sig;
01586 n = n;
01587 return LDNS_SIGNATURE_REMOVE_NO_ADD;
01588 }
01589
01590 int
01591 ldns_dnssec_default_replace_signatures(ldns_rr *sig, void *n)
01592 {
01593 sig = sig;
01594 n = n;
01595 return LDNS_SIGNATURE_REMOVE_ADD_NEW;
01596 }
01597
01598 #endif