<machine/pc/bios.h>: Switch to standard types for a few remaining cases.
[dragonfly.git] / contrib / ldns / dnssec_sign.c
blob22f09816dafe2a270465162496a6816a9cfb6b34
1 #include <ldns/config.h>
3 #include <ldns/ldns.h>
5 #include <ldns/dnssec.h>
6 #include <ldns/dnssec_sign.h>
8 #include <strings.h>
9 #include <time.h>
11 #ifdef HAVE_SSL
12 /* this entire file is rather useless when you don't have
13 * crypto...
15 #include <openssl/ssl.h>
16 #include <openssl/evp.h>
17 #include <openssl/rand.h>
18 #include <openssl/err.h>
19 #include <openssl/md5.h>
20 #endif /* HAVE_SSL */
22 ldns_rr *
23 ldns_create_empty_rrsig(const ldns_rr_list *rrset,
24 const ldns_key *current_key)
26 uint32_t orig_ttl;
27 ldns_rr_class orig_class;
28 time_t now;
29 ldns_rr *current_sig;
30 uint8_t label_count;
31 ldns_rdf *signame;
33 label_count = ldns_dname_label_count(ldns_rr_owner(ldns_rr_list_rr(rrset,
34 0)));
35 /* RFC4035 2.2: not counting the leftmost label if it is a wildcard */
36 if(ldns_dname_is_wildcard(ldns_rr_owner(ldns_rr_list_rr(rrset, 0))))
37 label_count --;
39 current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
41 /* set the type on the new signature */
42 orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
43 orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0));
45 ldns_rr_set_ttl(current_sig, orig_ttl);
46 ldns_rr_set_class(current_sig, orig_class);
47 ldns_rr_set_owner(current_sig,
48 ldns_rdf_clone(
49 ldns_rr_owner(
50 ldns_rr_list_rr(rrset,
51 0))));
53 /* fill in what we know of the signature */
55 /* set the orig_ttl */
56 (void)ldns_rr_rrsig_set_origttl(
57 current_sig,
58 ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
59 orig_ttl));
60 /* the signers name */
61 signame = ldns_rdf_clone(ldns_key_pubkey_owner(current_key));
62 ldns_dname2canonical(signame);
63 (void)ldns_rr_rrsig_set_signame(
64 current_sig,
65 signame);
66 /* label count - get it from the first rr in the rr_list */
67 (void)ldns_rr_rrsig_set_labels(
68 current_sig,
69 ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
70 label_count));
71 /* inception, expiration */
72 now = time(NULL);
73 if (ldns_key_inception(current_key) != 0) {
74 (void)ldns_rr_rrsig_set_inception(
75 current_sig,
76 ldns_native2rdf_int32(
77 LDNS_RDF_TYPE_TIME,
78 ldns_key_inception(current_key)));
79 } else {
80 (void)ldns_rr_rrsig_set_inception(
81 current_sig,
82 ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
84 if (ldns_key_expiration(current_key) != 0) {
85 (void)ldns_rr_rrsig_set_expiration(
86 current_sig,
87 ldns_native2rdf_int32(
88 LDNS_RDF_TYPE_TIME,
89 ldns_key_expiration(current_key)));
90 } else {
91 (void)ldns_rr_rrsig_set_expiration(
92 current_sig,
93 ldns_native2rdf_int32(
94 LDNS_RDF_TYPE_TIME,
95 now + LDNS_DEFAULT_EXP_TIME));
98 (void)ldns_rr_rrsig_set_keytag(
99 current_sig,
100 ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
101 ldns_key_keytag(current_key)));
103 (void)ldns_rr_rrsig_set_algorithm(
104 current_sig,
105 ldns_native2rdf_int8(
106 LDNS_RDF_TYPE_ALG,
107 ldns_key_algorithm(current_key)));
109 (void)ldns_rr_rrsig_set_typecovered(
110 current_sig,
111 ldns_native2rdf_int16(
112 LDNS_RDF_TYPE_TYPE,
113 ldns_rr_get_type(ldns_rr_list_rr(rrset,
114 0))));
115 return current_sig;
118 #ifdef HAVE_SSL
119 ldns_rdf *
120 ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
122 ldns_rdf *b64rdf = NULL;
124 switch(ldns_key_algorithm(current_key)) {
125 #ifdef USE_DSA
126 case LDNS_SIGN_DSA:
127 case LDNS_SIGN_DSA_NSEC3:
128 b64rdf = ldns_sign_public_evp(
129 sign_buf,
130 ldns_key_evp_key(current_key),
131 # ifdef HAVE_EVP_DSS1
132 EVP_dss1()
133 # else
134 EVP_sha1()
135 # endif
137 break;
138 #endif /* USE_DSA */
139 case LDNS_SIGN_RSASHA1:
140 case LDNS_SIGN_RSASHA1_NSEC3:
141 b64rdf = ldns_sign_public_evp(
142 sign_buf,
143 ldns_key_evp_key(current_key),
144 EVP_sha1());
145 break;
146 #ifdef USE_SHA2
147 case LDNS_SIGN_RSASHA256:
148 b64rdf = ldns_sign_public_evp(
149 sign_buf,
150 ldns_key_evp_key(current_key),
151 EVP_sha256());
152 break;
153 case LDNS_SIGN_RSASHA512:
154 b64rdf = ldns_sign_public_evp(
155 sign_buf,
156 ldns_key_evp_key(current_key),
157 EVP_sha512());
158 break;
159 #endif /* USE_SHA2 */
160 #ifdef USE_GOST
161 case LDNS_SIGN_ECC_GOST:
162 b64rdf = ldns_sign_public_evp(
163 sign_buf,
164 ldns_key_evp_key(current_key),
165 EVP_get_digestbyname("md_gost94"));
166 break;
167 #endif /* USE_GOST */
168 #ifdef USE_ECDSA
169 case LDNS_SIGN_ECDSAP256SHA256:
170 b64rdf = ldns_sign_public_evp(
171 sign_buf,
172 ldns_key_evp_key(current_key),
173 EVP_sha256());
174 break;
175 case LDNS_SIGN_ECDSAP384SHA384:
176 b64rdf = ldns_sign_public_evp(
177 sign_buf,
178 ldns_key_evp_key(current_key),
179 EVP_sha384());
180 break;
181 #endif
182 #ifdef USE_ED25519
183 case LDNS_SIGN_ED25519:
184 b64rdf = ldns_sign_public_evp(
185 sign_buf,
186 ldns_key_evp_key(current_key),
187 EVP_sha512());
188 break;
189 #endif
190 #ifdef USE_ED448
191 case LDNS_SIGN_ED448:
192 b64rdf = ldns_sign_public_evp(
193 sign_buf,
194 ldns_key_evp_key(current_key),
195 EVP_sha512());
196 break;
197 #endif
198 case LDNS_SIGN_RSAMD5:
199 b64rdf = ldns_sign_public_evp(
200 sign_buf,
201 ldns_key_evp_key(current_key),
202 EVP_md5());
203 break;
204 default:
205 /* do _you_ know this alg? */
206 printf("unknown algorithm, ");
207 printf("is the one used available on this system?\n");
208 break;
211 return b64rdf;
215 * use this function to sign with a public/private key alg
216 * return the created signatures
218 ldns_rr_list *
219 ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
221 ldns_rr_list *signatures;
222 ldns_rr_list *rrset_clone;
223 ldns_rr *current_sig;
224 ldns_rdf *b64rdf;
225 ldns_key *current_key;
226 size_t key_count;
227 uint16_t i;
228 ldns_buffer *sign_buf;
229 ldns_rdf *new_owner;
231 if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
232 return NULL;
235 new_owner = NULL;
237 signatures = ldns_rr_list_new();
239 /* prepare a signature and add all the know data
240 * prepare the rrset. Sign this together. */
241 rrset_clone = ldns_rr_list_clone(rrset);
242 if (!rrset_clone) {
243 return NULL;
246 /* make it canonical */
247 for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
248 ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i),
249 ldns_rr_ttl(ldns_rr_list_rr(rrset, 0)));
250 ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
252 /* sort */
253 ldns_rr_list_sort(rrset_clone);
255 for (key_count = 0;
256 key_count < ldns_key_list_key_count(keys);
257 key_count++) {
258 if (!ldns_key_use(ldns_key_list_key(keys, key_count))) {
259 continue;
261 sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
262 if (!sign_buf) {
263 ldns_rr_list_free(rrset_clone);
264 ldns_rr_list_free(signatures);
265 ldns_rdf_free(new_owner);
266 return NULL;
268 b64rdf = NULL;
270 current_key = ldns_key_list_key(keys, key_count);
271 /* sign all RRs with keys that have ZSKbit, !SEPbit.
272 sign DNSKEY RRs with keys that have ZSKbit&SEPbit */
273 if (ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY) {
274 current_sig = ldns_create_empty_rrsig(rrset_clone,
275 current_key);
277 /* right now, we have: a key, a semi-sig and an rrset. For
278 * which we can create the sig and base64 encode that and
279 * add that to the signature */
281 if (ldns_rrsig2buffer_wire(sign_buf, current_sig)
282 != LDNS_STATUS_OK) {
283 ldns_buffer_free(sign_buf);
284 /* ERROR */
285 ldns_rr_list_deep_free(rrset_clone);
286 ldns_rr_free(current_sig);
287 ldns_rr_list_deep_free(signatures);
288 return NULL;
291 /* add the rrset in sign_buf */
292 if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone)
293 != LDNS_STATUS_OK) {
294 ldns_buffer_free(sign_buf);
295 ldns_rr_list_deep_free(rrset_clone);
296 ldns_rr_free(current_sig);
297 ldns_rr_list_deep_free(signatures);
298 return NULL;
301 b64rdf = ldns_sign_public_buffer(sign_buf, current_key);
303 if (!b64rdf) {
304 /* signing went wrong */
305 ldns_rr_list_deep_free(rrset_clone);
306 ldns_rr_free(current_sig);
307 ldns_rr_list_deep_free(signatures);
308 return NULL;
311 ldns_rr_rrsig_set_sig(current_sig, b64rdf);
313 /* push the signature to the signatures list */
314 ldns_rr_list_push_rr(signatures, current_sig);
316 ldns_buffer_free(sign_buf); /* restart for the next key */
318 ldns_rr_list_deep_free(rrset_clone);
320 return signatures;
324 * Sign data with DSA
326 * \param[in] to_sign The ldns_buffer containing raw data that is
327 * to be signed
328 * \param[in] key The DSA key structure to sign with
329 * \return ldns_rdf for the RRSIG ldns_rr
331 ldns_rdf *
332 ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
334 #ifdef USE_DSA
335 unsigned char *sha1_hash;
336 ldns_rdf *sigdata_rdf;
337 ldns_buffer *b64sig;
339 DSA_SIG *sig;
340 const BIGNUM *R, *S;
341 uint8_t *data;
342 size_t pad;
344 b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
345 if (!b64sig) {
346 return NULL;
349 sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
350 ldns_buffer_position(to_sign), NULL);
351 if (!sha1_hash) {
352 ldns_buffer_free(b64sig);
353 return NULL;
356 sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
357 if(!sig) {
358 ldns_buffer_free(b64sig);
359 return NULL;
362 data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
363 if(!data) {
364 ldns_buffer_free(b64sig);
365 DSA_SIG_free(sig);
366 return NULL;
369 data[0] = 1;
370 # ifdef HAVE_DSA_SIG_GET0
371 DSA_SIG_get0(sig, &R, &S);
372 # else
373 R = sig->r;
374 S = sig->s;
375 # endif
376 pad = 20 - (size_t) BN_num_bytes(R);
377 if (pad > 0) {
378 memset(data + 1, 0, pad);
380 BN_bn2bin(R, (unsigned char *) (data + 1) + pad);
382 pad = 20 - (size_t) BN_num_bytes(S);
383 if (pad > 0) {
384 memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
386 BN_bn2bin(S, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
388 sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
389 1 + 2 * SHA_DIGEST_LENGTH,
390 data);
392 ldns_buffer_free(b64sig);
393 LDNS_FREE(data);
394 DSA_SIG_free(sig);
396 return sigdata_rdf;
397 #else
398 (void)to_sign; (void)key;
399 return NULL;
400 #endif
403 #ifdef USE_ECDSA
404 #ifndef S_SPLINT_S
405 /** returns the number of bytes per signature-component (i.e. bits/8), or 0. */
406 static int
407 ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
409 EC_KEY* ec;
410 const EC_GROUP* g;
411 #ifdef HAVE_EVP_PKEY_BASE_ID
412 if(EVP_PKEY_base_id(pkey) != EVP_PKEY_EC)
413 return 0;
414 #else
415 if(EVP_PKEY_type(key->type) != EVP_PKEY_EC)
416 return 0;
417 #endif
418 ec = EVP_PKEY_get1_EC_KEY(pkey);
419 g = EC_KEY_get0_group(ec);
420 if(!g) {
421 EC_KEY_free(ec);
422 return 0;
424 if(EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1) {
425 EC_KEY_free(ec);
426 return 32; /* 256/8 */
428 if(EC_GROUP_get_curve_name(g) == NID_secp384r1) {
429 EC_KEY_free(ec);
430 return 48; /* 384/8 */
432 /* downref the eckey, the original is still inside the pkey */
433 EC_KEY_free(ec);
434 return 0;
436 #endif /* splint */
437 #endif /* USE_ECDSA */
439 ldns_rdf *
440 ldns_sign_public_evp(ldns_buffer *to_sign,
441 EVP_PKEY *key,
442 const EVP_MD *digest_type)
444 unsigned int siglen;
445 ldns_rdf *sigdata_rdf = NULL;
446 ldns_buffer *b64sig;
447 EVP_MD_CTX *ctx;
448 const EVP_MD *md_type;
449 int r;
451 siglen = 0;
452 b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
453 if (!b64sig) {
454 return NULL;
457 /* initializes a signing context */
458 md_type = digest_type;
459 if(!md_type) {
460 /* unknown message difest */
461 ldns_buffer_free(b64sig);
462 return NULL;
465 #ifdef HAVE_EVP_MD_CTX_NEW
466 ctx = EVP_MD_CTX_new();
467 #else
468 ctx = (EVP_MD_CTX*)malloc(sizeof(*ctx));
469 if(ctx) EVP_MD_CTX_init(ctx);
470 #endif
471 if(!ctx) {
472 ldns_buffer_free(b64sig);
473 return NULL;
476 r = EVP_SignInit(ctx, md_type);
477 if(r == 1) {
478 r = EVP_SignUpdate(ctx, (unsigned char*)
479 ldns_buffer_begin(to_sign),
480 ldns_buffer_position(to_sign));
481 } else {
482 ldns_buffer_free(b64sig);
483 EVP_MD_CTX_destroy(ctx);
484 return NULL;
486 if(r == 1) {
487 r = EVP_SignFinal(ctx, (unsigned char*)
488 ldns_buffer_begin(b64sig), &siglen, key);
489 } else {
490 ldns_buffer_free(b64sig);
491 EVP_MD_CTX_destroy(ctx);
492 return NULL;
494 if(r != 1) {
495 ldns_buffer_free(b64sig);
496 EVP_MD_CTX_destroy(ctx);
497 return NULL;
500 /* OpenSSL output is different, convert it */
501 r = 0;
502 #ifdef USE_DSA
503 #ifndef S_SPLINT_S
504 /* unfortunately, OpenSSL output is different from DNS DSA format */
505 # ifdef HAVE_EVP_PKEY_BASE_ID
506 if (EVP_PKEY_base_id(key) == EVP_PKEY_DSA) {
507 # else
508 if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
509 # endif
510 r = 1;
511 sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
513 #endif
514 #endif
515 #if defined(USE_ECDSA) || defined(USE_ED25519) || defined(USE_ED448)
517 # ifdef HAVE_EVP_PKEY_BASE_ID
518 EVP_PKEY_base_id(key)
519 # else
520 EVP_PKEY_type(key->type)
521 # endif
522 == EVP_PKEY_EC) {
523 # ifdef USE_ECDSA
524 if(ldns_pkey_is_ecdsa(key)) {
525 r = 1;
526 sigdata_rdf = ldns_convert_ecdsa_rrsig_asn1len2rdf(
527 b64sig, (long)siglen, ldns_pkey_is_ecdsa(key));
529 # endif /* USE_ECDSA */
530 # ifdef USE_ED25519
531 if(EVP_PKEY_id(key) == NID_X25519) {
532 r = 1;
533 sigdata_rdf = ldns_convert_ed25519_rrsig_asn12rdf(
534 b64sig, siglen);
536 # endif /* USE_ED25519 */
537 # ifdef USE_ED448
538 if(EVP_PKEY_id(key) == NID_X448) {
539 r = 1;
540 sigdata_rdf = ldns_convert_ed448_rrsig_asn12rdf(
541 b64sig, siglen);
543 # endif /* USE_ED448 */
545 #endif /* PKEY_EC */
546 if(r == 0) {
547 /* ok output for other types is the same */
548 sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
549 ldns_buffer_begin(b64sig));
551 ldns_buffer_free(b64sig);
552 EVP_MD_CTX_destroy(ctx);
553 return sigdata_rdf;
556 ldns_rdf *
557 ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
559 unsigned char *sha1_hash;
560 unsigned int siglen;
561 ldns_rdf *sigdata_rdf;
562 ldns_buffer *b64sig;
563 int result;
565 siglen = 0;
566 b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
567 if (!b64sig) {
568 return NULL;
571 sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
572 ldns_buffer_position(to_sign), NULL);
573 if (!sha1_hash) {
574 ldns_buffer_free(b64sig);
575 return NULL;
578 result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH,
579 (unsigned char*)ldns_buffer_begin(b64sig),
580 &siglen, key);
581 if (result != 1) {
582 ldns_buffer_free(b64sig);
583 return NULL;
586 sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
587 ldns_buffer_begin(b64sig));
588 ldns_buffer_free(b64sig); /* can't free this buffer ?? */
589 return sigdata_rdf;
592 ldns_rdf *
593 ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
595 unsigned char *md5_hash;
596 unsigned int siglen;
597 ldns_rdf *sigdata_rdf;
598 ldns_buffer *b64sig;
600 b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
601 if (!b64sig) {
602 return NULL;
605 md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
606 ldns_buffer_position(to_sign), NULL);
607 if (!md5_hash) {
608 ldns_buffer_free(b64sig);
609 return NULL;
612 RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH,
613 (unsigned char*)ldns_buffer_begin(b64sig),
614 &siglen, key);
616 sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
617 ldns_buffer_begin(b64sig));
618 ldns_buffer_free(b64sig);
619 return sigdata_rdf;
621 #endif /* HAVE_SSL */
624 * Pushes all rrs from the rrsets of type A and AAAA on gluelist.
626 static ldns_status
627 ldns_dnssec_addresses_on_glue_list(
628 ldns_dnssec_rrsets *cur_rrset,
629 ldns_rr_list *glue_list)
631 ldns_dnssec_rrs *cur_rrs;
632 while (cur_rrset) {
633 if (cur_rrset->type == LDNS_RR_TYPE_A
634 || cur_rrset->type == LDNS_RR_TYPE_AAAA) {
635 for (cur_rrs = cur_rrset->rrs;
636 cur_rrs;
637 cur_rrs = cur_rrs->next) {
638 if (cur_rrs->rr) {
639 if (!ldns_rr_list_push_rr(glue_list,
640 cur_rrs->rr)) {
641 return LDNS_STATUS_MEM_ERR;
642 /* ldns_rr_list_push_rr()
643 * returns false when unable
644 * to increase the capacity
645 * of the ldsn_rr_list
651 cur_rrset = cur_rrset->next;
653 return LDNS_STATUS_OK;
657 * Marks the names in the zone that are occluded. Those names will be skipped
658 * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
659 * function. But watch out! Names that are partially occluded (like glue with
660 * the same name as the delegation) will not be marked and should specifically
661 * be taken into account separately.
663 * When glue_list is given (not NULL), in the process of marking the names, all
664 * glue resource records will be pushed to that list, even glue at delegation names.
666 * \param[in] zone the zone in which to mark the names
667 * \param[in] glue_list the list to which to push the glue rrs
668 * \return LDNS_STATUS_OK on success, an error code otherwise
670 ldns_status
671 ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone,
672 ldns_rr_list *glue_list)
674 ldns_rbnode_t *node;
675 ldns_dnssec_name *name;
676 ldns_rdf *owner;
677 ldns_rdf *cut = NULL; /* keeps track of zone cuts */
678 /* When the cut is caused by a delegation, below_delegation will be 1.
679 * When caused by a DNAME, below_delegation will be 0.
681 int below_delegation = -1; /* init suppresses comiler warning */
682 ldns_status s;
684 if (!zone || !zone->names) {
685 return LDNS_STATUS_NULL;
687 for (node = ldns_rbtree_first(zone->names);
688 node != LDNS_RBTREE_NULL;
689 node = ldns_rbtree_next(node)) {
690 name = (ldns_dnssec_name *) node->data;
691 owner = ldns_dnssec_name_name(name);
693 if (cut) {
694 /* The previous node was a zone cut, or a subdomain
695 * below a zone cut. Is this node (still) a subdomain
696 * below the cut? Then the name is occluded. Unless
697 * the name contains a SOA, after which we are
698 * authoritative again.
700 * FIXME! If there are labels in between the SOA and
701 * the cut, going from the authoritative space (below
702 * the SOA) up into occluded space again, will not be
703 * detected with the contruct below!
705 if (ldns_dname_is_subdomain(owner, cut) &&
706 !ldns_dnssec_rrsets_contains_type(
707 name->rrsets, LDNS_RR_TYPE_SOA)) {
709 if (below_delegation && glue_list) {
710 s = ldns_dnssec_addresses_on_glue_list(
711 name->rrsets, glue_list);
712 if (s != LDNS_STATUS_OK) {
713 return s;
716 name->is_glue = true; /* Mark occluded name! */
717 continue;
718 } else {
719 cut = NULL;
723 /* The node is not below a zone cut. Is it a zone cut itself?
724 * Everything below a SOA is authoritative of course; Except
725 * when the name also contains a DNAME :).
727 if (ldns_dnssec_rrsets_contains_type(
728 name->rrsets, LDNS_RR_TYPE_NS)
729 && !ldns_dnssec_rrsets_contains_type(
730 name->rrsets, LDNS_RR_TYPE_SOA)) {
731 cut = owner;
732 below_delegation = 1;
733 if (glue_list) { /* record glue on the zone cut */
734 s = ldns_dnssec_addresses_on_glue_list(
735 name->rrsets, glue_list);
736 if (s != LDNS_STATUS_OK) {
737 return s;
740 } else if (ldns_dnssec_rrsets_contains_type(
741 name->rrsets, LDNS_RR_TYPE_DNAME)) {
742 cut = owner;
743 below_delegation = 0;
746 return LDNS_STATUS_OK;
750 * Marks the names in the zone that are occluded. Those names will be skipped
751 * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
752 * function. But watch out! Names that are partially occluded (like glue with
753 * the same name as the delegation) will not be marked and should specifically
754 * be taken into account separately.
756 * \param[in] zone the zone in which to mark the names
757 * \return LDNS_STATUS_OK on success, an error code otherwise
759 ldns_status
760 ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
762 return ldns_dnssec_zone_mark_and_get_glue(zone, NULL);
765 ldns_rbnode_t *
766 ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
768 ldns_rbnode_t *next_node = NULL;
769 ldns_dnssec_name *next_name = NULL;
770 bool done = false;
772 if (node == LDNS_RBTREE_NULL) {
773 return NULL;
775 next_node = node;
776 while (!done) {
777 if (next_node == LDNS_RBTREE_NULL) {
778 return NULL;
779 } else {
780 next_name = (ldns_dnssec_name *)next_node->data;
781 if (!next_name->is_glue) {
782 done = true;
783 } else {
784 next_node = ldns_rbtree_next(next_node);
788 return next_node;
791 ldns_status
792 ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
793 ldns_rr_list *new_rrs)
796 ldns_rbnode_t *first_node, *cur_node, *next_node;
797 ldns_dnssec_name *cur_name, *next_name;
798 ldns_rr *nsec_rr;
799 uint32_t nsec_ttl;
800 ldns_dnssec_rrsets *soa;
802 /* the TTL of NSEC rrs should be set to the minimum TTL of
803 * the zone SOA (RFC4035 Section 2.3)
805 soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
807 /* did the caller actually set it? if not,
808 * fall back to default ttl
810 if (soa && soa->rrs && soa->rrs->rr
811 && (ldns_rr_rdf(soa->rrs->rr, 6) != NULL)) {
812 nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
813 } else {
814 nsec_ttl = LDNS_DEFAULT_TTL;
817 first_node = ldns_dnssec_name_node_next_nonglue(
818 ldns_rbtree_first(zone->names));
819 cur_node = first_node;
820 if (cur_node) {
821 next_node = ldns_dnssec_name_node_next_nonglue(
822 ldns_rbtree_next(cur_node));
823 } else {
824 next_node = NULL;
827 while (cur_node && next_node) {
828 cur_name = (ldns_dnssec_name *)cur_node->data;
829 next_name = (ldns_dnssec_name *)next_node->data;
830 nsec_rr = ldns_dnssec_create_nsec(cur_name,
831 next_name,
832 LDNS_RR_TYPE_NSEC);
833 ldns_rr_set_ttl(nsec_rr, nsec_ttl);
834 if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
835 ldns_rr_free(nsec_rr);
836 return LDNS_STATUS_ERR;
838 ldns_rr_list_push_rr(new_rrs, nsec_rr);
839 cur_node = next_node;
840 if (cur_node) {
841 next_node = ldns_dnssec_name_node_next_nonglue(
842 ldns_rbtree_next(cur_node));
846 if (cur_node && !next_node) {
847 cur_name = (ldns_dnssec_name *)cur_node->data;
848 next_name = (ldns_dnssec_name *)first_node->data;
849 nsec_rr = ldns_dnssec_create_nsec(cur_name,
850 next_name,
851 LDNS_RR_TYPE_NSEC);
852 ldns_rr_set_ttl(nsec_rr, nsec_ttl);
853 if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
854 ldns_rr_free(nsec_rr);
855 return LDNS_STATUS_ERR;
857 ldns_rr_list_push_rr(new_rrs, nsec_rr);
858 } else {
859 printf("error\n");
862 return LDNS_STATUS_OK;
865 #ifdef HAVE_SSL
866 static void
867 ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
868 (void) arg;
869 LDNS_FREE(node);
872 static ldns_status
873 ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
874 ldns_rr_list *new_rrs,
875 uint8_t algorithm,
876 uint8_t flags,
877 uint16_t iterations,
878 uint8_t salt_length,
879 uint8_t *salt,
880 ldns_rbtree_t **map)
882 ldns_rbnode_t *first_name_node;
883 ldns_rbnode_t *current_name_node;
884 ldns_dnssec_name *current_name;
885 ldns_status result = LDNS_STATUS_OK;
886 ldns_rr *nsec_rr;
887 ldns_rr_list *nsec3_list;
888 uint32_t nsec_ttl;
889 ldns_dnssec_rrsets *soa;
890 ldns_rbnode_t *hashmap_node;
892 if (!zone || !new_rrs || !zone->names) {
893 return LDNS_STATUS_ERR;
896 /* the TTL of NSEC rrs should be set to the minimum TTL of
897 * the zone SOA (RFC4035 Section 2.3)
899 soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
901 /* did the caller actually set it? if not,
902 * fall back to default ttl
904 if (soa && soa->rrs && soa->rrs->rr
905 && ldns_rr_rdf(soa->rrs->rr, 6) != NULL) {
906 nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
907 } else {
908 nsec_ttl = LDNS_DEFAULT_TTL;
911 if (ldns_rdf_size(zone->soa->name) > 222) {
912 return LDNS_STATUS_NSEC3_DOMAINNAME_OVERFLOW;
915 if (zone->hashed_names) {
916 ldns_traverse_postorder(zone->hashed_names,
917 ldns_hashed_names_node_free, NULL);
918 LDNS_FREE(zone->hashed_names);
920 zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
921 if (zone->hashed_names && map) {
922 *map = zone->hashed_names;
925 first_name_node = ldns_dnssec_name_node_next_nonglue(
926 ldns_rbtree_first(zone->names));
928 current_name_node = first_name_node;
930 while (current_name_node && current_name_node != LDNS_RBTREE_NULL &&
931 result == LDNS_STATUS_OK) {
933 current_name = (ldns_dnssec_name *) current_name_node->data;
934 nsec_rr = ldns_dnssec_create_nsec3(current_name,
935 NULL,
936 zone->soa->name,
937 algorithm,
938 flags,
939 iterations,
940 salt_length,
941 salt);
942 /* by default, our nsec based generator adds rrsigs
943 * remove the bitmap for empty nonterminals */
944 if (!current_name->rrsets) {
945 ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
947 ldns_rr_set_ttl(nsec_rr, nsec_ttl);
948 result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
949 ldns_rr_list_push_rr(new_rrs, nsec_rr);
950 if (ldns_rr_owner(nsec_rr)) {
951 hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
952 if (hashmap_node == NULL) {
953 return LDNS_STATUS_MEM_ERR;
955 current_name->hashed_name =
956 ldns_dname_label(ldns_rr_owner(nsec_rr), 0);
958 if (current_name->hashed_name == NULL) {
959 LDNS_FREE(hashmap_node);
960 return LDNS_STATUS_MEM_ERR;
962 hashmap_node->key = current_name->hashed_name;
963 hashmap_node->data = current_name;
965 if (! ldns_rbtree_insert(zone->hashed_names
966 , hashmap_node)) {
967 LDNS_FREE(hashmap_node);
970 current_name_node = ldns_dnssec_name_node_next_nonglue(
971 ldns_rbtree_next(current_name_node));
973 if (result != LDNS_STATUS_OK) {
974 return result;
977 /* Make sorted list of nsec3s (via zone->hashed_names)
979 nsec3_list = ldns_rr_list_new();
980 if (nsec3_list == NULL) {
981 return LDNS_STATUS_MEM_ERR;
983 for ( hashmap_node = ldns_rbtree_first(zone->hashed_names)
984 ; hashmap_node != LDNS_RBTREE_NULL
985 ; hashmap_node = ldns_rbtree_next(hashmap_node)
987 current_name = (ldns_dnssec_name *) hashmap_node->data;
988 nsec_rr = ((ldns_dnssec_name *) hashmap_node->data)->nsec;
989 if (nsec_rr) {
990 ldns_rr_list_push_rr(nsec3_list, nsec_rr);
993 result = ldns_dnssec_chain_nsec3_list(nsec3_list);
994 ldns_rr_list_free(nsec3_list);
996 return result;
999 ldns_status
1000 ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
1001 ldns_rr_list *new_rrs,
1002 uint8_t algorithm,
1003 uint8_t flags,
1004 uint16_t iterations,
1005 uint8_t salt_length,
1006 uint8_t *salt)
1008 return ldns_dnssec_zone_create_nsec3s_mkmap(zone, new_rrs, algorithm,
1009 flags, iterations, salt_length, salt, NULL);
1012 #endif /* HAVE_SSL */
1014 ldns_dnssec_rrs *
1015 ldns_dnssec_remove_signatures( ldns_dnssec_rrs *signatures
1016 , ATTR_UNUSED(ldns_key_list *key_list)
1017 , int (*func)(ldns_rr *, void *)
1018 , void *arg
1021 ldns_dnssec_rrs *base_rrs = signatures;
1022 ldns_dnssec_rrs *cur_rr = base_rrs;
1023 ldns_dnssec_rrs *prev_rr = NULL;
1024 ldns_dnssec_rrs *next_rr;
1026 uint16_t keytag;
1027 size_t i;
1029 if (!cur_rr) {
1030 switch(func(NULL, arg)) {
1031 case LDNS_SIGNATURE_LEAVE_ADD_NEW:
1032 case LDNS_SIGNATURE_REMOVE_ADD_NEW:
1033 break;
1034 case LDNS_SIGNATURE_LEAVE_NO_ADD:
1035 case LDNS_SIGNATURE_REMOVE_NO_ADD:
1036 ldns_key_list_set_use(key_list, false);
1037 break;
1038 default:
1039 #ifdef STDERR_MSGS
1040 fprintf(stderr, "[XX] unknown return value from callback\n");
1041 #endif
1042 break;
1044 return NULL;
1046 (void)func(cur_rr->rr, arg);
1048 while (cur_rr) {
1049 next_rr = cur_rr->next;
1051 switch (func(cur_rr->rr, arg)) {
1052 case LDNS_SIGNATURE_LEAVE_ADD_NEW:
1053 prev_rr = cur_rr;
1054 break;
1055 case LDNS_SIGNATURE_LEAVE_NO_ADD:
1056 keytag = ldns_rdf2native_int16(
1057 ldns_rr_rrsig_keytag(cur_rr->rr));
1058 for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
1059 if (ldns_key_keytag(ldns_key_list_key(key_list, i)) ==
1060 keytag) {
1061 ldns_key_set_use(ldns_key_list_key(key_list, i),
1062 false);
1065 prev_rr = cur_rr;
1066 break;
1067 case LDNS_SIGNATURE_REMOVE_NO_ADD:
1068 keytag = ldns_rdf2native_int16(
1069 ldns_rr_rrsig_keytag(cur_rr->rr));
1070 for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
1071 if (ldns_key_keytag(ldns_key_list_key(key_list, i))
1072 == keytag) {
1073 ldns_key_set_use(ldns_key_list_key(key_list, i),
1074 false);
1077 if (prev_rr) {
1078 prev_rr->next = next_rr;
1079 } else {
1080 base_rrs = next_rr;
1082 LDNS_FREE(cur_rr);
1083 break;
1084 case LDNS_SIGNATURE_REMOVE_ADD_NEW:
1085 if (prev_rr) {
1086 prev_rr->next = next_rr;
1087 } else {
1088 base_rrs = next_rr;
1090 LDNS_FREE(cur_rr);
1091 break;
1092 default:
1093 #ifdef STDERR_MSGS
1094 fprintf(stderr, "[XX] unknown return value from callback\n");
1095 #endif
1096 break;
1098 cur_rr = next_rr;
1101 return base_rrs;
1104 #ifdef HAVE_SSL
1105 ldns_status
1106 ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
1107 ldns_rr_list *new_rrs,
1108 ldns_key_list *key_list,
1109 int (*func)(ldns_rr *, void*),
1110 void *arg)
1112 return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list,
1113 func, arg, 0);
1116 /** If there are KSKs use only them and mark ZSKs unused */
1117 static void
1118 ldns_key_list_filter_for_dnskey(ldns_key_list *key_list, int flags)
1120 bool algos[256]
1121 #ifndef S_SPLINT_S
1122 = { false }
1123 #endif
1125 ldns_signing_algorithm saw_ksk = 0;
1126 ldns_key *key;
1127 size_t i;
1129 if (!ldns_key_list_key_count(key_list))
1130 return;
1132 for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
1133 key = ldns_key_list_key(key_list, i);
1134 if ((ldns_key_flags(key) & LDNS_KEY_SEP_KEY) && !saw_ksk)
1135 saw_ksk = ldns_key_algorithm(key);
1136 algos[ldns_key_algorithm(key)] = true;
1138 if (!saw_ksk)
1139 return;
1140 else
1141 algos[saw_ksk] = 0;
1143 for (i =0; i < ldns_key_list_key_count(key_list); i++) {
1144 key = ldns_key_list_key(key_list, i);
1145 if (!(ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
1146 /* We have a ZSK.
1147 * Still use it if it has a unique algorithm though!
1149 if ((flags & LDNS_SIGN_WITH_ALL_ALGORITHMS) &&
1150 algos[ldns_key_algorithm(key)])
1151 algos[ldns_key_algorithm(key)] = false;
1152 else
1153 ldns_key_set_use(key, 0);
1158 /** If there are no ZSKs use KSK as ZSK */
1159 static void
1160 ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list, int flags)
1162 bool algos[256]
1163 #ifndef S_SPLINT_S
1164 = { false }
1165 #endif
1167 ldns_signing_algorithm saw_zsk = 0;
1168 ldns_key *key;
1169 size_t i;
1171 if (!ldns_key_list_key_count(key_list))
1172 return;
1174 for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
1175 key = ldns_key_list_key(key_list, i);
1176 if (!(ldns_key_flags(key) & LDNS_KEY_SEP_KEY) && !saw_zsk)
1177 saw_zsk = ldns_key_algorithm(key);
1178 algos[ldns_key_algorithm(key)] = true;
1180 if (!saw_zsk)
1181 return;
1182 else
1183 algos[saw_zsk] = 0;
1185 for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
1186 key = ldns_key_list_key(key_list, i);
1187 if((ldns_key_flags(key) & LDNS_KEY_SEP_KEY)) {
1188 /* We have a KSK.
1189 * Still use it if it has a unique algorithm though!
1191 if ((flags & LDNS_SIGN_WITH_ALL_ALGORITHMS) &&
1192 algos[ldns_key_algorithm(key)])
1193 algos[ldns_key_algorithm(key)] = false;
1194 else
1195 ldns_key_set_use(key, 0);
1200 ldns_status
1201 ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone
1202 , ldns_rr_list *new_rrs
1203 , ldns_key_list *key_list
1204 , int (*func)(ldns_rr *, void*)
1205 , void *arg
1206 , int flags
1209 ldns_status result = LDNS_STATUS_OK;
1211 ldns_rbnode_t *cur_node;
1212 ldns_rr_list *rr_list;
1214 ldns_dnssec_name *cur_name;
1215 ldns_dnssec_rrsets *cur_rrset;
1216 ldns_dnssec_rrs *cur_rr;
1218 ldns_rr_list *siglist;
1220 size_t i;
1222 int on_delegation_point = 0; /* handle partially occluded names */
1224 ldns_rr_list *pubkey_list = ldns_rr_list_new();
1225 for (i = 0; i<ldns_key_list_key_count(key_list); i++) {
1226 ldns_rr_list_push_rr( pubkey_list
1227 , ldns_key2rr(ldns_key_list_key(
1228 key_list, i))
1231 /* TODO: callback to see is list should be signed */
1232 /* TODO: remove 'old' signatures from signature list */
1233 cur_node = ldns_rbtree_first(zone->names);
1234 while (cur_node != LDNS_RBTREE_NULL) {
1235 cur_name = (ldns_dnssec_name *) cur_node->data;
1237 if (!cur_name->is_glue) {
1238 on_delegation_point = ldns_dnssec_rrsets_contains_type(
1239 cur_name->rrsets, LDNS_RR_TYPE_NS)
1240 && !ldns_dnssec_rrsets_contains_type(
1241 cur_name->rrsets, LDNS_RR_TYPE_SOA);
1242 cur_rrset = cur_name->rrsets;
1243 while (cur_rrset) {
1244 /* reset keys to use */
1245 ldns_key_list_set_use(key_list, true);
1247 /* walk through old sigs, remove the old,
1248 and mark which keys (not) to use) */
1249 cur_rrset->signatures =
1250 ldns_dnssec_remove_signatures(cur_rrset->signatures,
1251 key_list,
1252 func,
1253 arg);
1254 if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) &&
1255 cur_rrset->type == LDNS_RR_TYPE_DNSKEY)
1256 ldns_key_list_filter_for_dnskey(key_list, flags);
1258 if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY)
1259 ldns_key_list_filter_for_non_dnskey(key_list, flags);
1261 /* TODO: just set count to zero? */
1262 rr_list = ldns_rr_list_new();
1264 cur_rr = cur_rrset->rrs;
1265 while (cur_rr) {
1266 ldns_rr_list_push_rr(rr_list, cur_rr->rr);
1267 cur_rr = cur_rr->next;
1270 /* only sign non-delegation RRsets */
1271 /* (glue should have been marked earlier,
1272 * except on the delegation points itself) */
1273 if (!on_delegation_point ||
1274 ldns_rr_list_type(rr_list)
1275 == LDNS_RR_TYPE_DS ||
1276 ldns_rr_list_type(rr_list)
1277 == LDNS_RR_TYPE_NSEC ||
1278 ldns_rr_list_type(rr_list)
1279 == LDNS_RR_TYPE_NSEC3) {
1280 siglist = ldns_sign_public(rr_list, key_list);
1281 for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
1282 if (cur_rrset->signatures) {
1283 result = ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
1284 ldns_rr_list_rr(siglist,
1285 i));
1286 } else {
1287 cur_rrset->signatures = ldns_dnssec_rrs_new();
1288 cur_rrset->signatures->rr =
1289 ldns_rr_list_rr(siglist, i);
1291 if (new_rrs) {
1292 ldns_rr_list_push_rr(new_rrs,
1293 ldns_rr_list_rr(siglist,
1294 i));
1297 ldns_rr_list_free(siglist);
1300 ldns_rr_list_free(rr_list);
1302 cur_rrset = cur_rrset->next;
1305 /* sign the nsec */
1306 ldns_key_list_set_use(key_list, true);
1307 cur_name->nsec_signatures =
1308 ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
1309 key_list,
1310 func,
1311 arg);
1312 ldns_key_list_filter_for_non_dnskey(key_list, flags);
1314 rr_list = ldns_rr_list_new();
1315 ldns_rr_list_push_rr(rr_list, cur_name->nsec);
1316 siglist = ldns_sign_public(rr_list, key_list);
1318 for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
1319 if (cur_name->nsec_signatures) {
1320 result = ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
1321 ldns_rr_list_rr(siglist, i));
1322 } else {
1323 cur_name->nsec_signatures = ldns_dnssec_rrs_new();
1324 cur_name->nsec_signatures->rr =
1325 ldns_rr_list_rr(siglist, i);
1327 if (new_rrs) {
1328 ldns_rr_list_push_rr(new_rrs,
1329 ldns_rr_list_rr(siglist, i));
1333 ldns_rr_list_free(siglist);
1334 ldns_rr_list_free(rr_list);
1336 cur_node = ldns_rbtree_next(cur_node);
1339 ldns_rr_list_deep_free(pubkey_list);
1340 return result;
1343 ldns_status
1344 ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
1345 ldns_rr_list *new_rrs,
1346 ldns_key_list *key_list,
1347 int (*func)(ldns_rr *, void *),
1348 void *arg)
1350 return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0);
1353 ldns_status
1354 ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
1355 ldns_rr_list *new_rrs,
1356 ldns_key_list *key_list,
1357 int (*func)(ldns_rr *, void *),
1358 void *arg,
1359 int flags)
1361 ldns_status result = LDNS_STATUS_OK;
1363 if (!zone || !new_rrs || !key_list) {
1364 return LDNS_STATUS_ERR;
1367 /* zone is already sorted */
1368 result = ldns_dnssec_zone_mark_glue(zone);
1369 if (result != LDNS_STATUS_OK) {
1370 return result;
1373 /* check whether we need to add nsecs */
1374 if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
1375 result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
1376 if (result != LDNS_STATUS_OK) {
1377 return result;
1381 result = ldns_dnssec_zone_create_rrsigs_flg(zone,
1382 new_rrs,
1383 key_list,
1384 func,
1385 arg,
1386 flags);
1388 return result;
1391 ldns_status
1392 ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
1393 ldns_rr_list *new_rrs,
1394 ldns_key_list *key_list,
1395 int (*func)(ldns_rr *, void *),
1396 void *arg,
1397 uint8_t algorithm,
1398 uint8_t flags,
1399 uint16_t iterations,
1400 uint8_t salt_length,
1401 uint8_t *salt)
1403 return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
1404 func, arg, algorithm, flags, iterations, salt_length, salt, 0,
1405 NULL);
1408 ldns_status
1409 ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
1410 ldns_rr_list *new_rrs,
1411 ldns_key_list *key_list,
1412 int (*func)(ldns_rr *, void *),
1413 void *arg,
1414 uint8_t algorithm,
1415 uint8_t flags,
1416 uint16_t iterations,
1417 uint8_t salt_length,
1418 uint8_t *salt,
1419 int signflags,
1420 ldns_rbtree_t **map)
1422 ldns_rr *nsec3, *nsec3param;
1423 ldns_status result = LDNS_STATUS_OK;
1425 /* zone is already sorted */
1426 result = ldns_dnssec_zone_mark_glue(zone);
1427 if (result != LDNS_STATUS_OK) {
1428 return result;
1431 /* TODO if there are already nsec3s presents and their
1432 * parameters are the same as these, we don't have to recreate
1434 if (zone->names) {
1435 /* add empty nonterminals */
1436 result = ldns_dnssec_zone_add_empty_nonterminals(zone);
1437 if (result != LDNS_STATUS_OK) {
1438 return result;
1441 nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec;
1442 if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
1443 /* no need to recreate */
1444 } else {
1445 if (!ldns_dnssec_zone_find_rrset(zone,
1446 zone->soa->name,
1447 LDNS_RR_TYPE_NSEC3PARAM)) {
1448 /* create and add the nsec3param rr */
1449 nsec3param =
1450 ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAM);
1451 ldns_rr_set_owner(nsec3param,
1452 ldns_rdf_clone(zone->soa->name));
1453 ldns_nsec3_add_param_rdfs(nsec3param,
1454 algorithm,
1455 flags,
1456 iterations,
1457 salt_length,
1458 salt);
1459 /* always set bit 7 of the flags to zero, according to
1460 * rfc5155 section 11. The bits are counted from right to left,
1461 * so bit 7 in rfc5155 is bit 0 in ldns */
1462 ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3param, 1)), 0, 0);
1463 result = ldns_dnssec_zone_add_rr(zone, nsec3param);
1464 if (result != LDNS_STATUS_OK) {
1465 return result;
1467 ldns_rr_list_push_rr(new_rrs, nsec3param);
1469 result = ldns_dnssec_zone_create_nsec3s_mkmap(zone,
1470 new_rrs,
1471 algorithm,
1472 flags,
1473 iterations,
1474 salt_length,
1475 salt,
1476 map);
1477 if (result != LDNS_STATUS_OK) {
1478 return result;
1482 result = ldns_dnssec_zone_create_rrsigs_flg(zone,
1483 new_rrs,
1484 key_list,
1485 func,
1486 arg,
1487 signflags);
1490 return result;
1493 ldns_status
1494 ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
1495 ldns_rr_list *new_rrs,
1496 ldns_key_list *key_list,
1497 int (*func)(ldns_rr *, void *),
1498 void *arg,
1499 uint8_t algorithm,
1500 uint8_t flags,
1501 uint16_t iterations,
1502 uint8_t salt_length,
1503 uint8_t *salt,
1504 int signflags)
1506 return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
1507 func, arg, algorithm, flags, iterations, salt_length, salt,
1508 signflags, NULL);
1511 ldns_zone *
1512 ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
1514 ldns_dnssec_zone *dnssec_zone;
1515 ldns_zone *signed_zone;
1516 ldns_rr_list *new_rrs;
1517 size_t i;
1519 signed_zone = ldns_zone_new();
1520 dnssec_zone = ldns_dnssec_zone_new();
1522 (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
1523 ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
1525 for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
1526 (void) ldns_dnssec_zone_add_rr(dnssec_zone,
1527 ldns_rr_list_rr(ldns_zone_rrs(zone),
1528 i));
1529 ldns_zone_push_rr(signed_zone,
1530 ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
1531 i)));
1534 new_rrs = ldns_rr_list_new();
1535 (void) ldns_dnssec_zone_sign(dnssec_zone,
1536 new_rrs,
1537 key_list,
1538 ldns_dnssec_default_replace_signatures,
1539 NULL);
1541 for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
1542 ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
1543 ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
1546 ldns_rr_list_deep_free(new_rrs);
1547 ldns_dnssec_zone_free(dnssec_zone);
1549 return signed_zone;
1552 ldns_zone *
1553 ldns_zone_sign_nsec3(ldns_zone *zone, ldns_key_list *key_list, uint8_t algorithm, uint8_t flags, uint16_t iterations, uint8_t salt_length, uint8_t *salt)
1555 ldns_dnssec_zone *dnssec_zone;
1556 ldns_zone *signed_zone;
1557 ldns_rr_list *new_rrs;
1558 size_t i;
1560 signed_zone = ldns_zone_new();
1561 dnssec_zone = ldns_dnssec_zone_new();
1563 (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
1564 ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
1566 for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
1567 (void) ldns_dnssec_zone_add_rr(dnssec_zone,
1568 ldns_rr_list_rr(ldns_zone_rrs(zone),
1569 i));
1570 ldns_zone_push_rr(signed_zone,
1571 ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
1572 i)));
1575 new_rrs = ldns_rr_list_new();
1576 (void) ldns_dnssec_zone_sign_nsec3(dnssec_zone,
1577 new_rrs,
1578 key_list,
1579 ldns_dnssec_default_replace_signatures,
1580 NULL,
1581 algorithm,
1582 flags,
1583 iterations,
1584 salt_length,
1585 salt);
1587 for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
1588 ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
1589 ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
1592 ldns_rr_list_deep_free(new_rrs);
1593 ldns_dnssec_zone_free(dnssec_zone);
1595 return signed_zone;
1597 #endif /* HAVE_SSL */