00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <ldns/config.h>
00014
00015 #include <ldns/ldns.h>
00016
00017 #include <strings.h>
00018 #include <time.h>
00019
00020 #ifdef HAVE_SSL
00021
00022
00023
00024 #include <openssl/ssl.h>
00025 #include <openssl/rand.h>
00026 #include <openssl/err.h>
00027 #include <openssl/md5.h>
00028
00029
00030 uint16_t
00031 ldns_calc_keytag(const ldns_rr *key)
00032 {
00033 unsigned int i;
00034 uint32_t ac32;
00035 uint16_t ac16;
00036
00037 ldns_buffer *keybuf;
00038 size_t keysize;
00039
00040 if (!key) {
00041 return 0;
00042 }
00043
00044 ac32 = 0;
00045 if (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY &&
00046 ldns_rr_get_type(key) != LDNS_RR_TYPE_KEY
00047 ) {
00048 return 0;
00049 }
00050
00051
00052 keybuf = ldns_buffer_new(LDNS_MIN_BUFLEN);
00053 if (!keybuf) {
00054 return 0;
00055 }
00056 (void)ldns_rr_rdata2buffer_wire(keybuf, key);
00057
00058 keysize= ldns_buffer_position(keybuf);
00059
00060
00061 if (ldns_rdf2native_int8(ldns_rr_rdf(key, 2)) == LDNS_RSAMD5) {
00062 if (keysize > 4) {
00063 ldns_buffer_read_at(keybuf, keysize - 3, &ac16, 2);
00064 }
00065 ldns_buffer_free(keybuf);
00066 ac16 = ntohs(ac16);
00067 return (uint16_t) ac16;
00068 } else {
00069 for (i = 0; (size_t)i < keysize; ++i) {
00070 ac32 += (i & 1) ? *ldns_buffer_at(keybuf, i) :
00071 *ldns_buffer_at(keybuf, i) << 8;
00072 }
00073 ldns_buffer_free(keybuf);
00074 ac32 += (ac32 >> 16) & 0xFFFF;
00075
00076 return (uint16_t) (ac32 & 0xFFFF);
00077 }
00078 }
00079
00080 ldns_status
00081 ldns_verify(ldns_rr_list *rrset, ldns_rr_list *rrsig, ldns_rr_list *keys,
00082 ldns_rr_list *good_keys)
00083 {
00084 uint16_t i;
00085 bool valid;
00086 ldns_status verify_result = LDNS_STATUS_ERR;
00087
00088 if (!rrset || !rrsig || !keys) {
00089 return LDNS_STATUS_ERR;
00090 }
00091
00092 valid = false;
00093
00094 if (ldns_rr_list_rr_count(rrset) < 1) {
00095 return LDNS_STATUS_ERR;
00096 }
00097
00098 if (ldns_rr_list_rr_count(rrsig) < 1) {
00099 return LDNS_STATUS_CRYPTO_NO_RRSIG;
00100 }
00101
00102 if (ldns_rr_list_rr_count(keys) < 1) {
00103 verify_result = LDNS_STATUS_CRYPTO_NO_TRUSTED_DNSKEY;
00104 } else {
00105 for (i = 0; i < ldns_rr_list_rr_count(rrsig); i++) {
00106
00107 if (ldns_verify_rrsig_keylist(rrset,
00108 ldns_rr_list_rr(rrsig, i),
00109 keys, good_keys) == LDNS_STATUS_OK) {
00110 verify_result = LDNS_STATUS_OK;
00111 }
00112 }
00113 }
00114 return verify_result;
00115 }
00116
00117 ldns_status
00118 ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf,
00119 ldns_buffer *key_buf, uint8_t algo)
00120 {
00121
00122 switch(algo) {
00123 case LDNS_DSA:
00124 return ldns_verify_rrsig_dsa(rawsig_buf, verify_buf, key_buf);
00125 break;
00126 case LDNS_RSASHA1:
00127 return ldns_verify_rrsig_rsasha1(rawsig_buf, verify_buf, key_buf);
00128 break;
00129 case LDNS_RSAMD5:
00130 return ldns_verify_rrsig_rsamd5(rawsig_buf, verify_buf, key_buf);
00131 break;
00132 default:
00133
00134 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
00135 }
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 ldns_status
00149 ldns_verify_rrsig_keylist(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr_list *keys,
00150 ldns_rr_list *good_keys)
00151 {
00152 ldns_buffer *rawsig_buf;
00153 ldns_buffer *verify_buf;
00154 ldns_buffer *key_buf;
00155 uint32_t orig_ttl;
00156 uint16_t i;
00157 uint8_t sig_algo;
00158 ldns_status result;
00159 ldns_rr *current_key;
00160 ldns_rr_list *rrset_clone;
00161 ldns_rr_list *validkeys;
00162 time_t now, inception, expiration;
00163 uint8_t label_count;
00164 ldns_rdf *wildcard_name;
00165 ldns_rdf *wildcard_chopped;
00166 ldns_rdf *wildcard_chopped_tmp;
00167
00168
00169 if (!rrset) {
00170 return LDNS_STATUS_ERR;
00171 }
00172
00173 validkeys = ldns_rr_list_new();
00174 if (!validkeys) {
00175 return LDNS_STATUS_MEM_ERR;
00176 }
00177
00178
00179 ldns_dname2canonical(ldns_rr_owner(rrsig));
00180
00181
00182 rrset_clone = ldns_rr_list_clone(rrset);
00183
00184
00185 if (ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rrsig)) !=
00186 ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0))) {
00187 return LDNS_STATUS_CRYPTO_TYPE_COVERED_ERR;
00188 }
00189
00190
00191 rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00192 verify_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00193
00194 sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
00195 result = LDNS_STATUS_ERR;
00196
00197
00198 inception = ldns_rdf2native_time_t(ldns_rr_rrsig_inception(rrsig));
00199 expiration = ldns_rdf2native_time_t(ldns_rr_rrsig_expiration(rrsig));
00200 now = time(NULL);
00201
00202 if (expiration - inception < 0) {
00203
00204 ldns_buffer_free(rawsig_buf);
00205 ldns_buffer_free(verify_buf);
00206 return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
00207 }
00208 if (now - inception < 0) {
00209
00210 ldns_buffer_free(rawsig_buf);
00211 ldns_buffer_free(verify_buf);
00212 return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
00213 }
00214 if (expiration - now < 0) {
00215
00216 ldns_buffer_free(rawsig_buf);
00217 ldns_buffer_free(verify_buf);
00218 return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
00219 }
00220
00221
00222 if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
00223 ldns_buffer_free(rawsig_buf);
00224 ldns_buffer_free(verify_buf);
00225 return LDNS_STATUS_MEM_ERR;
00226 }
00227
00228 orig_ttl = ldns_rdf2native_int32( ldns_rr_rdf(rrsig, 3));
00229 label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
00230
00231
00232
00233 for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
00234 if (label_count <
00235 ldns_dname_label_count(
00236 ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
00237 (void) ldns_str2rdf_dname(&wildcard_name, "*");
00238 wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)));
00239 while (label_count < ldns_dname_label_count(wildcard_chopped)) {
00240 wildcard_chopped_tmp = ldns_dname_left_chop(wildcard_chopped);
00241 ldns_rdf_deep_free(wildcard_chopped);
00242 wildcard_chopped = wildcard_chopped_tmp;
00243 }
00244 (void) ldns_dname_cat(wildcard_name, wildcard_chopped);
00245 ldns_rdf_deep_free(wildcard_chopped);
00246 ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)));
00247 ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i),
00248 wildcard_name);
00249
00250 }
00251 ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), orig_ttl);
00252
00253 ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
00254 }
00255
00256
00257 ldns_rr_list_sort(rrset_clone);
00258
00259
00260 if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK) {
00261 ldns_buffer_free(rawsig_buf);
00262 ldns_buffer_free(verify_buf);
00263 return LDNS_STATUS_MEM_ERR;
00264 }
00265
00266
00267 if (ldns_rr_list2buffer_wire(verify_buf, rrset_clone) != LDNS_STATUS_OK) {
00268 ldns_buffer_free(rawsig_buf);
00269 ldns_buffer_free(verify_buf);
00270 return LDNS_STATUS_MEM_ERR;
00271 }
00272
00273 for(i = 0; i < ldns_rr_list_rr_count(keys); i++) {
00274 current_key = ldns_rr_list_rr(keys, i);
00275
00276 if (ldns_calc_keytag(current_key) ==
00277 ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))) {
00278 key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00279
00280
00281
00282 if (ldns_rdf2buffer_wire(key_buf,
00283 ldns_rr_rdf(current_key, 3)) != LDNS_STATUS_OK) {
00284 ldns_buffer_free(rawsig_buf);
00285 ldns_buffer_free(verify_buf);
00286
00287
00288 return LDNS_STATUS_MEM_ERR;
00289 }
00290
00291
00292 if (sig_algo == ldns_rdf2native_int8(ldns_rr_rdf(current_key,
00293 2))) {
00294 result = ldns_verify_rrsig_buffers(rawsig_buf,
00295 verify_buf, key_buf, sig_algo);
00296 } else {
00297
00298 }
00299
00300 ldns_buffer_free(key_buf);
00301
00302 if (result == LDNS_STATUS_OK) {
00303
00304
00305
00306
00307 if (!ldns_rr_list_push_rr(validkeys, current_key)) {
00308
00309 ldns_buffer_free(rawsig_buf);
00310 ldns_buffer_free(verify_buf);
00311 return LDNS_STATUS_MEM_ERR;
00312 }
00313 }
00314 } else {
00315 result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
00316 }
00317 }
00318
00319
00320 ldns_rr_list_deep_free(rrset_clone);
00321 ldns_buffer_free(rawsig_buf);
00322 ldns_buffer_free(verify_buf);
00323 if (ldns_rr_list_rr_count(validkeys) == 0) {
00324
00325 ldns_rr_list_deep_free(validkeys);
00326 return result;
00327 } else {
00328 ldns_rr_list_cat(good_keys, validkeys);
00329 ldns_rr_list_free(validkeys);
00330 return LDNS_STATUS_OK;
00331 }
00332 }
00333
00334 ldns_status
00335 ldns_verify_rrsig(ldns_rr_list *rrset, ldns_rr *rrsig, ldns_rr *key)
00336 {
00337 ldns_buffer *rawsig_buf;
00338 ldns_buffer *verify_buf;
00339 ldns_buffer *key_buf;
00340 uint32_t orig_ttl;
00341 uint16_t i;
00342 uint8_t sig_algo;
00343 uint16_t label_count;
00344 ldns_status result;
00345 ldns_rr_list *rrset_clone;
00346 time_t now, inception, expiration;
00347 ldns_rdf *wildcard_name;
00348 ldns_rdf *wildcard_chopped;
00349 ldns_rdf *wildcard_chopped_tmp;
00350
00351
00352 if (!rrset) {
00353 return LDNS_STATUS_NO_DATA;
00354 }
00355
00356
00357 ldns_dname2canonical(ldns_rr_owner(rrsig));
00358
00359
00360 inception = ldns_rdf2native_time_t(ldns_rr_rrsig_inception(rrsig));
00361 expiration = ldns_rdf2native_time_t(ldns_rr_rrsig_expiration(rrsig));
00362 now = time(NULL);
00363
00364 if (expiration - inception < 0) {
00365
00366 return LDNS_STATUS_CRYPTO_EXPIRATION_BEFORE_INCEPTION;
00367 }
00368 if (now - inception < 0) {
00369
00370 return LDNS_STATUS_CRYPTO_SIG_NOT_INCEPTED;
00371 }
00372
00373 if (expiration - now < 0) {
00374
00375 return LDNS_STATUS_CRYPTO_SIG_EXPIRED;
00376 }
00377
00378 rrset_clone = ldns_rr_list_clone(rrset);
00379
00380
00381 rawsig_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00382 verify_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00383
00384 sig_algo = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 1));
00385
00386
00387
00388
00389 switch(sig_algo) {
00390 case LDNS_RSAMD5:
00391 case LDNS_RSASHA1:
00392 case LDNS_DSA:
00393 break;
00394 case LDNS_DH:
00395 case LDNS_ECC:
00396 case LDNS_INDIRECT:
00397 ldns_buffer_free(rawsig_buf);
00398 ldns_buffer_free(verify_buf);
00399 return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
00400 default:
00401 ldns_buffer_free(rawsig_buf);
00402 ldns_buffer_free(verify_buf);
00403 return LDNS_STATUS_CRYPTO_UNKNOWN_ALGO;
00404 }
00405
00406 result = LDNS_STATUS_ERR;
00407
00408
00409 if (ldns_rdf2buffer_wire(rawsig_buf,
00410 ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
00411 ldns_buffer_free(rawsig_buf);
00412 ldns_buffer_free(verify_buf);
00413 return LDNS_STATUS_MEM_ERR;
00414 }
00415
00416
00417
00418 label_count = ldns_rdf2native_int8(ldns_rr_rdf(rrsig, 2));
00419
00420 orig_ttl = ldns_rdf2native_int32(
00421 ldns_rr_rdf(rrsig, 3));
00422
00423
00424 for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
00425 if (label_count <
00426 ldns_dname_label_count(
00427 ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)))) {
00428 (void) ldns_str2rdf_dname(&wildcard_name, "*");
00429 wildcard_chopped = ldns_rdf_clone(ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)));
00430 while (label_count < ldns_dname_label_count(wildcard_chopped)) {
00431 wildcard_chopped_tmp = ldns_dname_left_chop(wildcard_chopped);
00432 ldns_rdf_deep_free(wildcard_chopped);
00433 wildcard_chopped = wildcard_chopped_tmp;
00434 }
00435 (void) ldns_dname_cat(wildcard_name, wildcard_chopped);
00436 ldns_rdf_deep_free(wildcard_chopped);
00437 ldns_rdf_deep_free(ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i)));
00438 ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i),
00439 wildcard_name);
00440
00441 }
00442 ldns_rr_set_ttl(
00443 ldns_rr_list_rr(rrset_clone, i),
00444 orig_ttl);
00445
00446 ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
00447 }
00448
00449
00450 ldns_rr_list_sort(rrset_clone);
00451
00452
00453 if (ldns_rrsig2buffer_wire(verify_buf, rrsig) != LDNS_STATUS_OK) {
00454 ldns_rr_list_deep_free(rrset_clone);
00455 ldns_buffer_free(rawsig_buf);
00456 ldns_buffer_free(verify_buf);
00457 return LDNS_STATUS_ERR;
00458 }
00459
00460
00461 if (ldns_rr_list2buffer_wire(verify_buf, rrset_clone) != LDNS_STATUS_OK) {
00462 ldns_rr_list_deep_free(rrset_clone);
00463 ldns_buffer_free(rawsig_buf);
00464 ldns_buffer_free(verify_buf);
00465 return LDNS_STATUS_ERR;
00466 }
00467
00468 if (ldns_calc_keytag(key)
00469 ==
00470 ldns_rdf2native_int16(ldns_rr_rrsig_keytag(rrsig))
00471 ) {
00472 key_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00473
00474
00475
00476
00477
00478 if (ldns_rdf2buffer_wire(key_buf,
00479 ldns_rr_rdf(key, 3)) != LDNS_STATUS_OK) {
00480 ldns_rr_list_deep_free(rrset_clone);
00481 ldns_buffer_free(rawsig_buf);
00482 ldns_buffer_free(verify_buf);
00483
00484
00485
00486 return LDNS_STATUS_ERR;
00487 }
00488
00489 if (sig_algo == ldns_rdf2native_int8(ldns_rr_rdf(key, 2))) {
00490 result = ldns_verify_rrsig_buffers(rawsig_buf, verify_buf, key_buf, sig_algo);
00491 }
00492
00493 ldns_buffer_free(key_buf);
00494 }
00495 else {
00496
00497 result = LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY;
00498 }
00499
00500 ldns_rr_list_deep_free(rrset_clone);
00501 ldns_buffer_free(rawsig_buf);
00502 ldns_buffer_free(verify_buf);
00503 return result;
00504 }
00505
00506 ldns_status
00507 ldns_verify_rrsig_dsa(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
00508 {
00509 DSA *dsakey;
00510 DSA_SIG *dsasig;
00511 BIGNUM *R;
00512 BIGNUM *S;
00513 uint8_t t;
00514 int result;
00515
00516 unsigned char *sha1_hash;
00517
00518 dsakey = ldns_key_buf2dsa(key);
00519 if (!dsakey) {
00520 return LDNS_STATUS_ERR;
00521 }
00522
00523
00524 t = *(ldns_buffer_at(sig, 0));
00525 R = BN_new();
00526 (void) BN_bin2bn((unsigned char*)ldns_buffer_at(sig, 1), SHA_DIGEST_LENGTH, R);
00527 S = BN_new();
00528 (void) BN_bin2bn((unsigned char*)ldns_buffer_at(sig, 21), SHA_DIGEST_LENGTH, S);
00529
00530 dsasig = DSA_SIG_new();
00531 if (!dsasig) {
00532 return LDNS_STATUS_MEM_ERR;
00533 }
00534
00535 dsasig->r = R;
00536 dsasig->s = S;
00537 sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(rrset), ldns_buffer_position(rrset), NULL);
00538 if (!sha1_hash) {
00539 return LDNS_STATUS_ERR;
00540 }
00541
00542 result = DSA_do_verify(sha1_hash, SHA_DIGEST_LENGTH, dsasig, dsakey);
00543
00544 if (result == 1) {
00545 return LDNS_STATUS_OK;
00546 } else {
00547 return LDNS_STATUS_CRYPTO_BOGUS;
00548 }
00549 }
00550
00551 ldns_status
00552 ldns_verify_rrsig_rsasha1(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
00553 {
00554 RSA *rsakey;
00555 unsigned char *sha1_hash;
00556 ldns_status result;
00557
00558 rsakey = ldns_key_buf2rsa(key);
00559 if (!rsakey) {
00560 result = LDNS_STATUS_ERR;
00561 } else {
00562 sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(rrset), ldns_buffer_position(rrset), NULL);
00563 if (!sha1_hash) {
00564 return LDNS_STATUS_ERR;
00565 }
00566 if (RSA_verify(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH,
00567 (unsigned char*)ldns_buffer_begin(sig),
00568 (unsigned int)ldns_buffer_position(sig), rsakey) == 1) {
00569 result = LDNS_STATUS_OK;
00570 } else {
00571 result = LDNS_STATUS_CRYPTO_BOGUS;
00572 }
00573 }
00574
00575 RSA_free(rsakey);
00576
00577 return result;
00578 }
00579
00580
00581 ldns_status
00582 ldns_verify_rrsig_rsamd5(ldns_buffer *sig, ldns_buffer *rrset, ldns_buffer *key)
00583 {
00584 RSA *rsakey;
00585 unsigned char *md5_hash;
00586
00587 rsakey = ldns_key_buf2rsa(key);
00588 if (!rsakey) {
00589 return LDNS_STATUS_ERR;
00590 }
00591 md5_hash = MD5((unsigned char*)ldns_buffer_begin(rrset),
00592 (unsigned int)ldns_buffer_position(rrset), NULL);
00593 if (!md5_hash) {
00594 return LDNS_STATUS_ERR;
00595 }
00596 if (RSA_verify(NID_md5, md5_hash, MD5_DIGEST_LENGTH,
00597 (unsigned char*)ldns_buffer_begin(sig),
00598 (unsigned int)ldns_buffer_position(sig), rsakey) == 1) {
00599 return LDNS_STATUS_OK;
00600 } else {
00601 return LDNS_STATUS_CRYPTO_BOGUS;
00602 }
00603 return true;
00604 }
00605
00606 #ifdef HAVE_SSL
00607 DSA *
00608 ldns_key_buf2dsa(ldns_buffer *key)
00609 {
00610 uint8_t T;
00611 uint16_t length;
00612 uint16_t offset;
00613 DSA *dsa;
00614 BIGNUM *Q; BIGNUM *P;
00615 BIGNUM *G; BIGNUM *Y;
00616
00617 T = *ldns_buffer_at(key, 0);
00618 length = (64 + T * 8);
00619 offset = 1;
00620
00621 if (T > 8) {
00622 return NULL;
00623 }
00624
00625 Q = BN_bin2bn((unsigned char*)ldns_buffer_at(key, offset), SHA_DIGEST_LENGTH, NULL);
00626 offset += SHA_DIGEST_LENGTH;
00627
00628 P = BN_bin2bn((unsigned char*)ldns_buffer_at(key, offset), (int)length, NULL);
00629 offset += length;
00630
00631 G = BN_bin2bn((unsigned char*)ldns_buffer_at(key, offset), (int)length, NULL);
00632 offset += length;
00633
00634 Y = BN_bin2bn((unsigned char*)ldns_buffer_at(key, offset), (int)length, NULL);
00635 offset += length;
00636
00637
00638 dsa = DSA_new();
00639 dsa->p = P;
00640 dsa->q = Q;
00641 dsa->g = G;
00642 dsa->pub_key = Y;
00643
00644 return dsa;
00645 }
00646 #endif
00647
00648 RSA *
00649 ldns_key_buf2rsa(ldns_buffer *key)
00650 {
00651 uint16_t offset;
00652 uint16_t exp;
00653 uint16_t int16;
00654 RSA *rsa;
00655 BIGNUM *modulus;
00656 BIGNUM *exponent;
00657
00658 if ((*ldns_buffer_at(key, 0)) == 0) {
00659
00660
00661
00662 memcpy(&int16, ldns_buffer_at(key, 1), 2);
00663 exp = ntohs(int16);
00664 offset = 3;
00665 } else {
00666 exp = *ldns_buffer_at(key, 0);
00667 offset = 1;
00668 }
00669
00670
00671 exponent = BN_new();
00672 (void) BN_bin2bn(
00673 (unsigned char*)ldns_buffer_at(key, offset), (int)exp, exponent);
00674 offset += exp;
00675
00676
00677 modulus = BN_new();
00678
00679 (void) BN_bin2bn((unsigned char*)ldns_buffer_at(key, offset),
00680 (int)(ldns_buffer_position(key) - offset), modulus);
00681
00682 rsa = RSA_new();
00683 rsa->n = modulus;
00684 rsa->e = exponent;
00685
00686 return rsa;
00687 }
00688
00689 ldns_rr *
00690 ldns_key_rr2ds(const ldns_rr *key, ldns_hash h)
00691 {
00692 ldns_rdf *tmp;
00693 ldns_rr *ds;
00694 uint16_t keytag;
00695 uint8_t sha1hash;
00696 uint8_t *digest;
00697 ldns_buffer *data_buf;
00698
00699 if (ldns_rr_get_type(key) != LDNS_RR_TYPE_DNSKEY) {
00700 return NULL;
00701 }
00702
00703 ds = ldns_rr_new();
00704 if (!ds) {
00705 return NULL;
00706 }
00707 ldns_rr_set_type(ds, LDNS_RR_TYPE_DS);
00708 ldns_rr_set_owner(ds, ldns_rdf_clone(
00709 ldns_rr_owner(key)));
00710 ldns_rr_set_ttl(ds, ldns_rr_ttl(key));
00711 ldns_rr_set_class(ds, ldns_rr_get_class(key));
00712
00713 switch(h) {
00714 default:
00715 case LDNS_SHA1:
00716 digest = LDNS_XMALLOC(uint8_t, SHA_DIGEST_LENGTH);
00717 if (!digest) {
00718 ldns_rr_free(ds);
00719 return NULL;
00720 }
00721 break;
00722 case LDNS_SHA256:
00723 #ifdef SHA256_DIGEST_LENGTH
00724 digest = LDNS_XMALLOC(uint8_t, SHA256_DIGEST_LENGTH);
00725 if (!digest) {
00726 ldns_rr_free(ds);
00727 return NULL;
00728 }
00729 #else
00730 ldns_rr_free(ds);
00731 return NULL;
00732 #endif
00733 break;
00734 }
00735
00736 data_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00737 if (!data_buf) {
00738 LDNS_FREE(digest);
00739 ldns_rr_free(ds);
00740 return NULL;
00741 }
00742
00743
00744 keytag = htons(ldns_calc_keytag((ldns_rr*)key));
00745 tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT16, sizeof(uint16_t), &keytag);
00746 ldns_rr_push_rdf(ds, tmp);
00747
00748
00749 ldns_rr_push_rdf(ds, ldns_rdf_clone( ldns_rr_rdf(key, 2)));
00750
00751
00752 sha1hash = (uint8_t)h;
00753 tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT8, sizeof(uint8_t), &sha1hash);
00754 ldns_rr_push_rdf(ds, tmp);
00755
00756
00757
00758 tmp = ldns_rdf_clone(ldns_rr_owner(key));
00759 ldns_dname2canonical(tmp);
00760 if (ldns_rdf2buffer_wire(data_buf, tmp) != LDNS_STATUS_OK) {
00761 LDNS_FREE(digest);
00762 ldns_buffer_free(data_buf);
00763 ldns_rr_free(ds);
00764 ldns_rdf_deep_free(tmp);
00765 return NULL;
00766 }
00767 ldns_rdf_deep_free(tmp);
00768
00769
00770 if (ldns_rr_rdata2buffer_wire(data_buf, (ldns_rr*)key) != LDNS_STATUS_OK) {
00771 LDNS_FREE(digest);
00772 ldns_buffer_free(data_buf);
00773 ldns_rr_free(ds);
00774 return NULL;
00775 }
00776 switch(h) {
00777 case LDNS_SHA1:
00778 (void) SHA1((unsigned char *) ldns_buffer_begin(data_buf),
00779 ldns_buffer_position(data_buf),
00780 (unsigned char*) digest);
00781
00782 tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX, SHA_DIGEST_LENGTH,
00783 digest);
00784 ldns_rr_push_rdf(ds, tmp);
00785
00786 break;
00787 case LDNS_SHA256:
00788 #ifdef SHA256_DIGEST_LENGTH
00789 (void) SHA256((unsigned char *) ldns_buffer_begin(data_buf),
00790 ldns_buffer_position(data_buf),
00791 (unsigned char*) digest);
00792 tmp = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX, SHA256_DIGEST_LENGTH,
00793 digest);
00794 ldns_rr_push_rdf(ds, tmp);
00795 #endif
00796 break;
00797 }
00798
00799 LDNS_FREE(digest);
00800 ldns_buffer_free(data_buf);
00801 return ds;
00802 }
00803
00804
00805
00806
00807
00808 ldns_rr_list *
00809 ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
00810 {
00811 ldns_rr_list *signatures;
00812 ldns_rr_list *rrset_clone;
00813 ldns_rr *current_sig;
00814 ldns_rdf *b64rdf;
00815 ldns_key *current_key;
00816 size_t key_count;
00817 uint16_t i;
00818 ldns_buffer *sign_buf;
00819 uint32_t orig_ttl;
00820 time_t now;
00821 uint8_t label_count;
00822 ldns_rdf *first_label;
00823 ldns_rdf *wildcard_label;
00824 ldns_rdf *new_owner;
00825
00826 if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
00827 return NULL;
00828 }
00829
00830 key_count = 0;
00831 signatures = ldns_rr_list_new();
00832
00833
00834
00835 rrset_clone = ldns_rr_list_clone(rrset);
00836 if (!rrset_clone) {
00837 return NULL;
00838 }
00839
00840
00841 label_count = ldns_dname_label_count(ldns_rr_owner(ldns_rr_list_rr(rrset, 0)));
00842 (void) ldns_str2rdf_dname(&wildcard_label, "*");
00843 first_label = ldns_dname_label(ldns_rr_owner(ldns_rr_list_rr(rrset, 0)), 0);
00844 if (ldns_rdf_compare(first_label, wildcard_label) == 0) {
00845 label_count--;
00846 for (i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
00847 new_owner = ldns_dname_cat_clone(wildcard_label,
00848 ldns_dname_left_chop(ldns_rr_owner(ldns_rr_list_rr(rrset_clone, i))));
00849 ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i), new_owner);
00850 }
00851 }
00852 ldns_rdf_deep_free(wildcard_label);
00853 ldns_rdf_deep_free(first_label);
00854
00855
00856 for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
00857 ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
00858 }
00859
00860 ldns_rr_list_sort(rrset_clone);
00861
00862 for (key_count = 0; key_count < ldns_key_list_key_count(keys); key_count++) {
00863 sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00864 b64rdf = NULL;
00865
00866 current_key = ldns_key_list_key(keys, key_count);
00867
00868
00869 if (
00870 ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY &&
00871 (!(ldns_key_flags(current_key) & LDNS_KEY_SEP_KEY) ||
00872 ldns_rr_get_type(ldns_rr_list_rr(rrset, 0)) == LDNS_RR_TYPE_DNSKEY)
00873 ) {
00874 current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
00875
00876
00877 orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
00878
00879 ldns_rr_set_ttl(current_sig, orig_ttl);
00880 ldns_rr_set_owner(current_sig,
00881 ldns_rdf_clone(ldns_rr_owner(ldns_rr_list_rr(rrset_clone, 0))));
00882
00883
00884
00885
00886 (void)ldns_rr_rrsig_set_origttl(current_sig,
00887 ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, orig_ttl));
00888
00889
00890 (void)ldns_rr_rrsig_set_signame(current_sig,
00891 ldns_rdf_clone(ldns_key_pubkey_owner(current_key)));
00892
00893 (void)ldns_rr_rrsig_set_labels(current_sig,
00894 ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, label_count));
00895
00896 now = time(NULL);
00897 if (ldns_key_inception(current_key) != 0) {
00898 (void)ldns_rr_rrsig_set_inception(current_sig,
00899 ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME,
00900 ldns_key_inception(current_key)));
00901 } else {
00902 (void)ldns_rr_rrsig_set_inception(current_sig,
00903 ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
00904 }
00905 if (ldns_key_expiration(current_key) != 0) {
00906 (void)ldns_rr_rrsig_set_expiration(current_sig,
00907 ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME,
00908 ldns_key_expiration(current_key)));
00909 } else {
00910 (void)ldns_rr_rrsig_set_expiration(current_sig,
00911 ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME,
00912 now + LDNS_DEFAULT_EXP_TIME));
00913 }
00914
00915
00916
00917 (void)ldns_rr_rrsig_set_keytag(current_sig,
00918 ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
00919 ldns_key_keytag(current_key)));
00920
00921
00922 (void)ldns_rr_rrsig_set_algorithm(current_sig,
00923 ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG,
00924 ldns_key_algorithm(current_key)));
00925
00926 (void)ldns_rr_rrsig_set_typecovered(current_sig,
00927 ldns_native2rdf_int16(LDNS_RDF_TYPE_TYPE,
00928 ldns_rr_get_type(ldns_rr_list_rr(rrset_clone, 0))));
00929
00930
00931
00932
00933 if (ldns_rrsig2buffer_wire(sign_buf, current_sig) != LDNS_STATUS_OK) {
00934 ldns_buffer_free(sign_buf);
00935
00936 ldns_rr_list_deep_free(rrset_clone);
00937 return NULL;
00938 }
00939
00940
00941 if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone) != LDNS_STATUS_OK) {
00942 ldns_buffer_free(sign_buf);
00943 ldns_rr_list_deep_free(rrset_clone);
00944 return NULL;
00945 }
00946
00947 switch(ldns_key_algorithm(current_key)) {
00948 case LDNS_SIGN_DSA:
00949 b64rdf = ldns_sign_public_dsa(sign_buf, ldns_key_dsa_key(current_key));
00950 break;
00951 case LDNS_SIGN_RSASHA1:
00952 b64rdf = ldns_sign_public_rsasha1(sign_buf, ldns_key_rsa_key(current_key));
00953 break;
00954 case LDNS_SIGN_RSAMD5:
00955 b64rdf = ldns_sign_public_rsamd5(sign_buf, ldns_key_rsa_key(current_key));
00956 break;
00957 default:
00958
00959 break;
00960 }
00961 if (!b64rdf) {
00962
00963 ldns_rr_list_deep_free(rrset_clone);
00964 return NULL;
00965 }
00966 ldns_rr_rrsig_set_sig(current_sig, b64rdf);
00967
00968
00969 ldns_rr_list_push_rr(signatures, current_sig);
00970 }
00971 ldns_buffer_free(sign_buf);
00972 }
00973 ldns_rr_list_deep_free(rrset_clone);
00974
00975 return signatures;
00976 }
00977
00978 ldns_rdf *
00979 ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
00980 {
00981 unsigned char *sha1_hash;
00982 ldns_rdf *sigdata_rdf;
00983 ldns_buffer *b64sig;
00984
00985 DSA_SIG *sig;
00986 uint8_t *data;
00987 size_t pad;
00988
00989 b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00990 if (!b64sig) {
00991 return NULL;
00992 }
00993
00994 sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
00995 ldns_buffer_position(to_sign), NULL);
00996 if (!sha1_hash) {
00997 ldns_buffer_free(b64sig);
00998 return NULL;
00999 }
01000
01001
01002 sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
01003
01004 data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
01005
01006 data[0] = 1;
01007 pad = 20 - (size_t) BN_num_bytes(sig->r);
01008 if (pad > 0) {
01009 memset(data + 1, 0, pad);
01010 }
01011 BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad);
01012
01013 pad = 20 - (size_t) BN_num_bytes(sig->s);
01014 if (pad > 0) {
01015 memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
01016 }
01017 BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
01018
01019 sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, 1 + 2 * SHA_DIGEST_LENGTH, data);
01020
01021 ldns_buffer_free(b64sig);
01022 LDNS_FREE(data);
01023
01024 return sigdata_rdf;
01025 }
01026
01027 ldns_rdf *
01028 ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
01029 {
01030 unsigned char *sha1_hash;
01031 unsigned int siglen;
01032 ldns_rdf *sigdata_rdf;
01033 ldns_buffer *b64sig;
01034 int result;
01035
01036 siglen = 0;
01037 b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
01038 if (!b64sig) {
01039 return NULL;
01040 }
01041
01042 sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
01043 ldns_buffer_position(to_sign), NULL);
01044 if (!sha1_hash) {
01045 ldns_buffer_free(b64sig);
01046 return NULL;
01047 }
01048
01049 result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH,
01050 (unsigned char*)ldns_buffer_begin(b64sig),
01051 &siglen, key);
01052 if (result != 1) {
01053 return NULL;
01054 }
01055
01056 sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
01057 ldns_buffer_begin(b64sig));
01058 ldns_buffer_free(b64sig);
01059 return sigdata_rdf;
01060 }
01061
01062 ldns_rdf *
01063 ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
01064 {
01065 unsigned char *md5_hash;
01066 unsigned int siglen;
01067 ldns_rdf *sigdata_rdf;
01068 ldns_buffer *b64sig;
01069
01070 b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
01071 if (!b64sig) {
01072 return NULL;
01073 }
01074
01075 md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
01076 ldns_buffer_position(to_sign), NULL);
01077 if (!md5_hash) {
01078 ldns_buffer_free(b64sig);
01079 return NULL;
01080 }
01081
01082 RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH,
01083 (unsigned char*)ldns_buffer_begin(b64sig),
01084 &siglen, key);
01085
01086 sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
01087 ldns_buffer_begin(b64sig));
01088 ldns_buffer_free(b64sig);
01089 return sigdata_rdf;
01090 }
01091
01092 ldns_rr *
01093 ldns_create_nsec(ldns_rdf *cur_owner, ldns_rdf *next_owner, ldns_rr_list *rrs)
01094 {
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105 uint16_t i;
01106 ldns_rr *i_rr;
01107
01108 uint8_t *bitmap = LDNS_XMALLOC(uint8_t, 2);
01109 uint16_t bm_len = 0;
01110 uint16_t i_type;
01111
01112 ldns_rr *nsec = NULL;
01113
01114 uint8_t *data = NULL;
01115 uint8_t cur_data[32];
01116 uint8_t cur_window = 0;
01117 uint8_t cur_window_max = 0;
01118 uint16_t cur_data_size = 0;
01119
01120 nsec = ldns_rr_new();
01121 ldns_rr_set_type(nsec, LDNS_RR_TYPE_NSEC);
01122 ldns_rr_set_owner(nsec, ldns_rdf_clone(cur_owner));
01123
01124 ldns_rr_push_rdf(nsec, ldns_rdf_clone(next_owner));
01125
01126 bitmap[0] = 0;
01127 for (i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
01128 i_rr = ldns_rr_list_rr(rrs, i);
01129
01130 if (ldns_rdf_compare(cur_owner,
01131 ldns_rr_owner(i_rr)) == 0) {
01132
01133 i_type = ldns_rr_get_type(i_rr);
01134 if ((i_type / 8) + 1 > bm_len) {
01135 bitmap = LDNS_XREALLOC(bitmap, uint8_t, (i_type / 8) + 2);
01136
01137 for (; bm_len <= i_type / 8; bm_len++) {
01138 bitmap[bm_len] = 0;
01139 }
01140 }
01141 ldns_set_bit(bitmap + (int) i_type / 8, (int) (7 - (i_type % 8)), true);
01142 }
01143 }
01144
01145 i_type = LDNS_RR_TYPE_RRSIG;
01146 if (i_type / 8 > bm_len) {
01147 bitmap = LDNS_XREALLOC(bitmap, uint8_t, (i_type / 8) + 2);
01148
01149 for (; bm_len <= i_type / 8; bm_len++) {
01150 bitmap[bm_len] = 0;
01151 }
01152 }
01153 ldns_set_bit(bitmap + (int) i_type / 8, (int) (7 - (i_type % 8)), true);
01154 i_type = LDNS_RR_TYPE_NSEC;
01155
01156 if (i_type / 8 > bm_len) {
01157 bitmap = LDNS_XREALLOC(bitmap, uint8_t, (i_type / 8) + 2);
01158
01159 for (; bm_len <= i_type / 8; bm_len++) {
01160 bitmap[bm_len] = 0;
01161 }
01162 }
01163 ldns_set_bit(bitmap + (int) i_type / 8, (int) (7 - (i_type % 8)), true);
01164
01165 memset(cur_data, 0, 32);
01166 for (i = 0; i < bm_len; i++) {
01167 if (i / 32 > cur_window) {
01168
01169 if (cur_window_max > 0) {
01170
01171 data = LDNS_XREALLOC(data, uint8_t, cur_data_size + cur_window_max + 3);
01172 data[cur_data_size] = cur_window;
01173 data[cur_data_size + 1] = cur_window_max + 1;
01174 memcpy(data + cur_data_size + 2, cur_data, cur_window_max+1);
01175 cur_data_size += cur_window_max + 3;
01176 }
01177 cur_window++;
01178 cur_window_max = 0;
01179 memset(cur_data, 0, 32);
01180 } else {
01181 cur_data[i%32] = bitmap[i];
01182 if (bitmap[i] > 0) {
01183 cur_window_max = i%32;
01184 }
01185 }
01186 }
01187 if (cur_window_max > 0) {
01188
01189 data = LDNS_XREALLOC(data, uint8_t, cur_data_size + cur_window_max + 3);
01190 data[cur_data_size] = cur_window;
01191 data[cur_data_size + 1] = cur_window_max + 1;
01192 memcpy(data + cur_data_size + 2, cur_data, cur_window_max+1);
01193 cur_data_size += cur_window_max + 3;
01194 }
01195
01196 ldns_rr_push_rdf(nsec, ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC, cur_data_size, data));
01197
01198 LDNS_FREE(bitmap);
01199 LDNS_FREE(data);
01200 return nsec;
01201 }
01202
01203 bool
01204 ldns_nsec_bitmap_covers_type(const ldns_rdf *nsec_bitmap, ldns_rr_type type)
01205 {
01206 uint8_t *bitmap;
01207 uint16_t i;
01208 uint8_t window_block_nr;
01209
01210 if (!nsec_bitmap) {
01211 return false;
01212 }
01213
01214
01215 bitmap = ldns_rdf_data(nsec_bitmap);
01216 window_block_nr = (uint8_t) (type / 256);
01217 i = 0;
01218
01219 while (i < ldns_rdf_size(nsec_bitmap)) {
01220 if (bitmap[i] == window_block_nr) {
01221
01222 if ((uint8_t) (type / 8) < bitmap[i + 1] &&
01223 ldns_get_bit(&bitmap[i + 1 + (type / 8)], (size_t) (7 - (type % 8)))) {
01224 return true;
01225 } else {
01226 return false;
01227 }
01228 } else {
01229
01230 i++;
01231 i += bitmap[i];
01232 }
01233 }
01234
01235 return false;
01236 }
01237
01238 bool
01239 ldns_nsec_covers_name(const ldns_rr *nsec, const ldns_rdf *name)
01240 {
01241 ldns_rdf *nsec_owner = ldns_rr_owner(nsec);
01242 ldns_rdf *nsec_next = ldns_rr_rdf(nsec, 0);
01243
01244
01245 if(ldns_dname_compare(nsec_owner, nsec_next) > 0)
01246 return (ldns_dname_compare(nsec_owner, name) <= 0 ||
01247 ldns_dname_compare(name, nsec_next) < 0);
01248
01249 return (ldns_dname_compare(nsec_owner, name) <= 0 &&
01250 ldns_dname_compare(name, nsec_next) < 0);
01251 }
01252
01253
01254 ldns_status
01255 ldns_pkt_verify(ldns_pkt *p, ldns_rr_type t, ldns_rdf *o,
01256 ldns_rr_list *k, ldns_rr_list *s, ldns_rr_list *good_keys)
01257 {
01258 ldns_rr_list *rrset;
01259 ldns_rr_list *sigs;
01260 ldns_rr_list *sigs_covered;
01261 ldns_rdf *rdf_t;
01262 ldns_rr_type t_netorder;
01263
01264 if (!k) {
01265 return LDNS_STATUS_ERR;
01266
01267 }
01268
01269 if (t == LDNS_RR_TYPE_RRSIG) {
01270
01271
01272 return LDNS_STATUS_ERR;
01273 }
01274
01275 if (s) {
01276
01277 sigs = s;
01278 } else {
01279
01280 sigs = ldns_pkt_rr_list_by_name_and_type(p, o, LDNS_RR_TYPE_RRSIG,
01281 LDNS_SECTION_ANY_NOQUESTION);
01282 if (!sigs) {
01283
01284 return LDNS_STATUS_ERR;
01285
01286 }
01287 }
01288
01289
01290
01291
01292 t_netorder = htons(t);
01293 rdf_t = ldns_rdf_new(LDNS_RDF_TYPE_TYPE, sizeof(ldns_rr_type), &t_netorder);
01294 sigs_covered = ldns_rr_list_subtype_by_rdf(sigs, rdf_t, 0);
01295
01296 rrset = ldns_pkt_rr_list_by_name_and_type(p, o, t, LDNS_SECTION_ANY_NOQUESTION);
01297
01298 if (!rrset) {
01299 return LDNS_STATUS_ERR;
01300 }
01301
01302 if (!sigs_covered) {
01303 return LDNS_STATUS_ERR;
01304 }
01305
01306 return ldns_verify(rrset, sigs, k, good_keys);
01307 }
01308
01309 ldns_zone *
01310 ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
01311 {
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323 ldns_zone *signed_zone;
01324 ldns_rr_list *cur_rrset;
01325 ldns_rr_list *cur_rrsigs;
01326 ldns_rr_list *orig_zone_rrs;
01327 ldns_rr_list *signed_zone_rrs;
01328 ldns_rr_list *pubkeys;
01329 ldns_rr_list *glue_rrs;
01330
01331 ldns_rdf *start_dname = NULL;
01332 ldns_rdf *cur_dname = NULL;
01333 ldns_rr *next_rr = NULL;
01334 ldns_rdf *next_dname = NULL;
01335 ldns_rr *nsec;
01336 ldns_rr *ckey;
01337 uint16_t i;
01338 ldns_rr_type cur_rrset_type;
01339
01340 signed_zone = ldns_zone_new();
01341
01342
01343 cur_rrsigs = NULL;
01344 ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
01345
01346
01347 orig_zone_rrs = ldns_rr_list_clone(ldns_zone_rrs(zone));
01348
01349 ldns_rr_list_push_rr(orig_zone_rrs, ldns_rr_clone(ldns_zone_soa(zone)));
01350
01351
01352
01353
01354
01355
01356
01357 glue_rrs = ldns_zone_glue_rr_list(zone);
01358
01359
01360 pubkeys = ldns_rr_list_new();
01361 for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
01362 ckey = ldns_key2rr(ldns_key_list_key(key_list, i));
01363 ldns_rr_list_push_rr(pubkeys, ckey);
01364 }
01365
01366 signed_zone_rrs = ldns_rr_list_new();
01367
01368 ldns_rr_list_sort(orig_zone_rrs);
01369
01370
01371 for (i = 0; i < ldns_rr_list_rr_count(orig_zone_rrs); i++) {
01372 if (!start_dname) {
01373
01374 start_dname = ldns_rr_owner(ldns_rr_list_rr(orig_zone_rrs, i));
01375 cur_dname = start_dname;
01376 } else {
01377 next_rr = ldns_rr_list_rr(orig_zone_rrs, i);
01378 next_dname = ldns_rr_owner(next_rr);
01379 if (ldns_rdf_compare(cur_dname, next_dname) != 0) {
01380
01381 if (ldns_rr_list_contains_rr(glue_rrs, next_rr)) {
01382 cur_dname = next_dname;
01383 } else {
01384 nsec = ldns_create_nsec(cur_dname,
01385 next_dname,
01386 orig_zone_rrs);
01387 ldns_rr_set_ttl(nsec, ldns_rdf2native_int32(ldns_rr_rdf(ldns_zone_soa(zone), 6)));
01388 ldns_rr_list_push_rr(signed_zone_rrs, nsec);
01389
01390 cur_dname = next_dname;
01391 }
01392 }
01393 }
01394 ldns_rr_list_push_rr(signed_zone_rrs, ldns_rr_list_rr(orig_zone_rrs, i));
01395 }
01396 nsec = ldns_create_nsec(cur_dname,
01397 start_dname,
01398 orig_zone_rrs);
01399 ldns_rr_list_push_rr(signed_zone_rrs, nsec);
01400 ldns_rr_list_free(orig_zone_rrs);
01401 ldns_rr_set_ttl(nsec, ldns_rdf2native_int32(ldns_rr_rdf(ldns_zone_soa(zone), 6)));
01402
01403
01404 cur_rrset = ldns_rr_list_pop_rrset(signed_zone_rrs);
01405 while (cur_rrset) {
01406
01407 cur_rrset_type = ldns_rr_get_type(ldns_rr_list_rr(cur_rrset, 0));
01408 cur_dname = ldns_rr_owner(ldns_rr_list_rr(cur_rrset, 0));
01409
01410
01411
01412
01413 if (cur_rrset_type != LDNS_RR_TYPE_RRSIG &&
01414 ((ldns_dname_is_subdomain(cur_dname, ldns_rr_owner(ldns_zone_soa(signed_zone)))
01415 && cur_rrset_type != LDNS_RR_TYPE_NS
01416 ) ||
01417 ldns_rdf_compare(cur_dname, ldns_rr_owner(ldns_zone_soa(signed_zone))) == 0
01418 ) &&
01419 !(ldns_rr_list_contains_rr(glue_rrs, ldns_rr_list_rr(cur_rrset, 0)))
01420 ) {
01421 cur_rrsigs = ldns_sign_public(cur_rrset, key_list);
01422 if (!cur_rrsigs) {
01423 ldns_zone_deep_free(signed_zone);
01424 ldns_rr_list_deep_free(signed_zone_rrs);
01425 ldns_rr_list_deep_free(pubkeys);
01426 ldns_rr_list_free(glue_rrs);
01427 return NULL;
01428 }
01429
01430
01431
01432
01433
01434 ldns_zone_push_rr_list(signed_zone, cur_rrset);
01435 ldns_zone_push_rr_list(signed_zone, cur_rrsigs);
01436 ldns_rr_list_free(cur_rrsigs);
01437 } else {
01438
01439 ldns_zone_push_rr_list(signed_zone, cur_rrset);
01440 }
01441 ldns_rr_list_free(cur_rrset);
01442 cur_rrset = ldns_rr_list_pop_rrset(signed_zone_rrs);
01443 }
01444 ldns_rr_list_deep_free(signed_zone_rrs);
01445 ldns_rr_list_deep_free(pubkeys);
01446 ldns_rr_list_free(glue_rrs);
01447 return signed_zone;
01448
01449 }
01450
01451 #endif