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