File Coverage

src/ldns/dnssec_sign.c
Criterion Covered Total %
statement 0 585 0.0
branch 0 292 0.0
condition n/a
subroutine n/a
pod n/a
total 0 877 0.0


line stmt bran cond sub pod time code
1             #include
2              
3             #include
4              
5             #include
6             #include
7              
8             #include
9             #include
10              
11             #ifdef HAVE_SSL
12             /* this entire file is rather useless when you don't have
13             * crypto...
14             */
15             #include
16             #include
17             #include
18             #include
19             #include
20             #endif /* HAVE_SSL */
21              
22             ldns_rr *
23 0           ldns_create_empty_rrsig(ldns_rr_list *rrset,
24             ldns_key *current_key)
25             {
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;
32              
33 0           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 0 0         if(ldns_dname_is_wildcard(ldns_rr_owner(ldns_rr_list_rr(rrset, 0))))
37 0           label_count --;
38              
39 0           current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
40              
41             /* set the type on the new signature */
42 0           orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
43 0           orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0));
44              
45 0           ldns_rr_set_ttl(current_sig, orig_ttl);
46 0           ldns_rr_set_class(current_sig, orig_class);
47 0           ldns_rr_set_owner(current_sig,
48             ldns_rdf_clone(
49 0           ldns_rr_owner(
50 0           ldns_rr_list_rr(rrset,
51             0))));
52              
53             /* fill in what we know of the signature */
54              
55             /* set the orig_ttl */
56 0           (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 0           signame = ldns_rdf_clone(ldns_key_pubkey_owner(current_key));
62 0           ldns_dname2canonical(signame);
63 0           (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 0           (void)ldns_rr_rrsig_set_labels(
68             current_sig,
69             ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
70             label_count));
71             /* inception, expiration */
72 0           now = time(NULL);
73 0 0         if (ldns_key_inception(current_key) != 0) {
74 0           (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 0           (void)ldns_rr_rrsig_set_inception(
81             current_sig,
82             ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
83             }
84 0 0         if (ldns_key_expiration(current_key) != 0) {
85 0           (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 0           (void)ldns_rr_rrsig_set_expiration(
92             current_sig,
93             ldns_native2rdf_int32(
94             LDNS_RDF_TYPE_TIME,
95             now + LDNS_DEFAULT_EXP_TIME));
96             }
97              
98 0           (void)ldns_rr_rrsig_set_keytag(
99             current_sig,
100             ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
101 0           ldns_key_keytag(current_key)));
102              
103 0           (void)ldns_rr_rrsig_set_algorithm(
104             current_sig,
105             ldns_native2rdf_int8(
106             LDNS_RDF_TYPE_ALG,
107 0           ldns_key_algorithm(current_key)));
108              
109 0           (void)ldns_rr_rrsig_set_typecovered(
110             current_sig,
111             ldns_native2rdf_int16(
112             LDNS_RDF_TYPE_TYPE,
113 0           ldns_rr_get_type(ldns_rr_list_rr(rrset,
114             0))));
115 0           return current_sig;
116             }
117              
118             #ifdef HAVE_SSL
119             ldns_rdf *
120 0           ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
121             {
122 0           ldns_rdf *b64rdf = NULL;
123              
124 0           switch(ldns_key_algorithm(current_key)) {
125             case LDNS_SIGN_DSA:
126             case LDNS_SIGN_DSA_NSEC3:
127 0           b64rdf = ldns_sign_public_evp(
128             sign_buf,
129             ldns_key_evp_key(current_key),
130             EVP_dss1());
131 0           break;
132             case LDNS_SIGN_RSASHA1:
133             case LDNS_SIGN_RSASHA1_NSEC3:
134 0           b64rdf = ldns_sign_public_evp(
135             sign_buf,
136             ldns_key_evp_key(current_key),
137             EVP_sha1());
138 0           break;
139             #ifdef USE_SHA2
140             case LDNS_SIGN_RSASHA256:
141 0           b64rdf = ldns_sign_public_evp(
142             sign_buf,
143             ldns_key_evp_key(current_key),
144             EVP_sha256());
145 0           break;
146             case LDNS_SIGN_RSASHA512:
147 0           b64rdf = ldns_sign_public_evp(
148             sign_buf,
149             ldns_key_evp_key(current_key),
150             EVP_sha512());
151 0           break;
152             #endif /* USE_SHA2 */
153             #ifdef USE_GOST
154             case LDNS_SIGN_ECC_GOST:
155 0           b64rdf = ldns_sign_public_evp(
156             sign_buf,
157             ldns_key_evp_key(current_key),
158             EVP_get_digestbyname("md_gost94"));
159 0           break;
160             #endif /* USE_GOST */
161             #ifdef USE_ECDSA
162             case LDNS_SIGN_ECDSAP256SHA256:
163 0           b64rdf = ldns_sign_public_evp(
164             sign_buf,
165             ldns_key_evp_key(current_key),
166             EVP_sha256());
167 0           break;
168             case LDNS_SIGN_ECDSAP384SHA384:
169 0           b64rdf = ldns_sign_public_evp(
170             sign_buf,
171             ldns_key_evp_key(current_key),
172             EVP_sha384());
173 0           break;
174             #endif
175             case LDNS_SIGN_RSAMD5:
176 0           b64rdf = ldns_sign_public_evp(
177             sign_buf,
178             ldns_key_evp_key(current_key),
179             EVP_md5());
180 0           break;
181             default:
182             /* do _you_ know this alg? */
183 0           printf("unknown algorithm, ");
184 0           printf("is the one used available on this system?\n");
185 0           break;
186             }
187              
188 0           return b64rdf;
189             }
190              
191             /**
192             * use this function to sign with a public/private key alg
193             * return the created signatures
194             */
195             ldns_rr_list *
196 0           ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
197             {
198             ldns_rr_list *signatures;
199             ldns_rr_list *rrset_clone;
200             ldns_rr *current_sig;
201             ldns_rdf *b64rdf;
202             ldns_key *current_key;
203             size_t key_count;
204             uint16_t i;
205             ldns_buffer *sign_buf;
206             ldns_rdf *new_owner;
207              
208 0 0         if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
    0          
    0          
209 0           return NULL;
210             }
211              
212 0           new_owner = NULL;
213              
214 0           signatures = ldns_rr_list_new();
215              
216             /* prepare a signature and add all the know data
217             * prepare the rrset. Sign this together. */
218 0           rrset_clone = ldns_rr_list_clone(rrset);
219 0 0         if (!rrset_clone) {
220 0           return NULL;
221             }
222              
223             /* make it canonical */
224 0 0         for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
225 0           ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i),
226 0           ldns_rr_ttl(ldns_rr_list_rr(rrset, 0)));
227 0           ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
228             }
229             /* sort */
230 0           ldns_rr_list_sort(rrset_clone);
231              
232 0 0         for (key_count = 0;
233 0           key_count < ldns_key_list_key_count(keys);
234 0           key_count++) {
235 0 0         if (!ldns_key_use(ldns_key_list_key(keys, key_count))) {
236 0           continue;
237             }
238 0           sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
239 0 0         if (!sign_buf) {
240 0           ldns_rr_list_free(rrset_clone);
241 0           ldns_rr_list_free(signatures);
242 0           ldns_rdf_free(new_owner);
243 0           return NULL;
244             }
245 0           b64rdf = NULL;
246              
247 0           current_key = ldns_key_list_key(keys, key_count);
248             /* sign all RRs with keys that have ZSKbit, !SEPbit.
249             sign DNSKEY RRs with keys that have ZSKbit&SEPbit */
250 0 0         if (ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY) {
251 0           current_sig = ldns_create_empty_rrsig(rrset_clone,
252             current_key);
253              
254             /* right now, we have: a key, a semi-sig and an rrset. For
255             * which we can create the sig and base64 encode that and
256             * add that to the signature */
257              
258 0 0         if (ldns_rrsig2buffer_wire(sign_buf, current_sig)
259             != LDNS_STATUS_OK) {
260 0           ldns_buffer_free(sign_buf);
261             /* ERROR */
262 0           ldns_rr_list_deep_free(rrset_clone);
263 0           ldns_rr_free(current_sig);
264 0           ldns_rr_list_deep_free(signatures);
265 0           return NULL;
266             }
267              
268             /* add the rrset in sign_buf */
269 0 0         if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone)
270             != LDNS_STATUS_OK) {
271 0           ldns_buffer_free(sign_buf);
272 0           ldns_rr_list_deep_free(rrset_clone);
273 0           ldns_rr_free(current_sig);
274 0           ldns_rr_list_deep_free(signatures);
275 0           return NULL;
276             }
277              
278 0           b64rdf = ldns_sign_public_buffer(sign_buf, current_key);
279              
280 0 0         if (!b64rdf) {
281             /* signing went wrong */
282 0           ldns_rr_list_deep_free(rrset_clone);
283 0           ldns_rr_free(current_sig);
284 0           ldns_rr_list_deep_free(signatures);
285 0           return NULL;
286             }
287              
288 0           ldns_rr_rrsig_set_sig(current_sig, b64rdf);
289              
290             /* push the signature to the signatures list */
291 0           ldns_rr_list_push_rr(signatures, current_sig);
292             }
293 0           ldns_buffer_free(sign_buf); /* restart for the next key */
294             }
295 0           ldns_rr_list_deep_free(rrset_clone);
296              
297 0           return signatures;
298             }
299              
300             /**
301             * Sign data with DSA
302             *
303             * \param[in] to_sign The ldns_buffer containing raw data that is
304             * to be signed
305             * \param[in] key The DSA key structure to sign with
306             * \return ldns_rdf for the RRSIG ldns_rr
307             */
308             ldns_rdf *
309 0           ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
310             {
311             unsigned char *sha1_hash;
312             ldns_rdf *sigdata_rdf;
313             ldns_buffer *b64sig;
314              
315             DSA_SIG *sig;
316             uint8_t *data;
317             size_t pad;
318              
319 0           b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
320 0 0         if (!b64sig) {
321 0           return NULL;
322             }
323              
324 0           sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
325             ldns_buffer_position(to_sign), NULL);
326 0 0         if (!sha1_hash) {
327 0           ldns_buffer_free(b64sig);
328 0           return NULL;
329             }
330              
331 0           sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
332 0 0         if(!sig) {
333 0           ldns_buffer_free(b64sig);
334 0           return NULL;
335             }
336              
337 0           data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
338 0 0         if(!data) {
339 0           ldns_buffer_free(b64sig);
340 0           DSA_SIG_free(sig);
341 0           return NULL;
342             }
343              
344 0           data[0] = 1;
345 0           pad = 20 - (size_t) BN_num_bytes(sig->r);
346 0 0         if (pad > 0) {
347 0           memset(data + 1, 0, pad);
348             }
349 0           BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad);
350              
351 0           pad = 20 - (size_t) BN_num_bytes(sig->s);
352 0 0         if (pad > 0) {
353 0           memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
354             }
355 0           BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
356              
357 0           sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
358             1 + 2 * SHA_DIGEST_LENGTH,
359             data);
360              
361 0           ldns_buffer_free(b64sig);
362 0           LDNS_FREE(data);
363 0           DSA_SIG_free(sig);
364              
365 0           return sigdata_rdf;
366             }
367              
368             #ifdef USE_ECDSA
369             #ifndef S_SPLINT_S
370             static int
371 0           ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
372             {
373             EC_KEY* ec;
374             const EC_GROUP* g;
375 0 0         if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC)
376 0           return 0;
377 0           ec = EVP_PKEY_get1_EC_KEY(pkey);
378 0           g = EC_KEY_get0_group(ec);
379 0 0         if(!g) {
380 0           EC_KEY_free(ec);
381 0           return 0;
382             }
383 0           if(EC_GROUP_get_curve_name(g) == NID_secp224r1 ||
384 0 0         EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1 ||
385 0           EC_GROUP_get_curve_name(g) == NID_secp384r1) {
386 0           EC_KEY_free(ec);
387 0           return 1;
388             }
389             /* downref the eckey, the original is still inside the pkey */
390 0           EC_KEY_free(ec);
391 0           return 0;
392             }
393             #endif /* splint */
394             #endif /* USE_ECDSA */
395              
396             ldns_rdf *
397 0           ldns_sign_public_evp(ldns_buffer *to_sign,
398             EVP_PKEY *key,
399             const EVP_MD *digest_type)
400             {
401             unsigned int siglen;
402             ldns_rdf *sigdata_rdf;
403             ldns_buffer *b64sig;
404             EVP_MD_CTX ctx;
405             const EVP_MD *md_type;
406             int r;
407              
408 0           siglen = 0;
409 0           b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
410 0 0         if (!b64sig) {
411 0           return NULL;
412             }
413              
414             /* initializes a signing context */
415 0           md_type = digest_type;
416 0 0         if(!md_type) {
417             /* unknown message difest */
418 0           ldns_buffer_free(b64sig);
419 0           return NULL;
420             }
421              
422 0           EVP_MD_CTX_init(&ctx);
423 0           r = EVP_SignInit(&ctx, md_type);
424 0 0         if(r == 1) {
425 0           r = EVP_SignUpdate(&ctx, (unsigned char*)
426             ldns_buffer_begin(to_sign),
427             ldns_buffer_position(to_sign));
428             } else {
429 0           ldns_buffer_free(b64sig);
430 0           return NULL;
431             }
432 0 0         if(r == 1) {
433 0           r = EVP_SignFinal(&ctx, (unsigned char*)
434 0           ldns_buffer_begin(b64sig), &siglen, key);
435             } else {
436 0           ldns_buffer_free(b64sig);
437 0           return NULL;
438             }
439 0 0         if(r != 1) {
440 0           ldns_buffer_free(b64sig);
441 0           return NULL;
442             }
443              
444             /* unfortunately, OpenSSL output is differenct from DNS DSA format */
445             #ifndef S_SPLINT_S
446 0 0         if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
447 0           sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
448             #ifdef USE_ECDSA
449 0           } else if(EVP_PKEY_type(key->type) == EVP_PKEY_EC &&
450 0           ldns_pkey_is_ecdsa(key)) {
451 0           sigdata_rdf = ldns_convert_ecdsa_rrsig_asn12rdf(b64sig, siglen);
452             #endif
453             } else {
454             /* ok output for other types is the same */
455 0           sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
456 0           ldns_buffer_begin(b64sig));
457             }
458             #endif /* splint */
459 0           ldns_buffer_free(b64sig);
460 0           EVP_MD_CTX_cleanup(&ctx);
461 0           return sigdata_rdf;
462             }
463              
464             ldns_rdf *
465 0           ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
466             {
467             unsigned char *sha1_hash;
468             unsigned int siglen;
469             ldns_rdf *sigdata_rdf;
470             ldns_buffer *b64sig;
471             int result;
472              
473 0           siglen = 0;
474 0           b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
475 0 0         if (!b64sig) {
476 0           return NULL;
477             }
478              
479 0           sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
480             ldns_buffer_position(to_sign), NULL);
481 0 0         if (!sha1_hash) {
482 0           ldns_buffer_free(b64sig);
483 0           return NULL;
484             }
485              
486 0           result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH,
487 0           (unsigned char*)ldns_buffer_begin(b64sig),
488             &siglen, key);
489 0 0         if (result != 1) {
490 0           ldns_buffer_free(b64sig);
491 0           return NULL;
492             }
493              
494 0           sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
495 0           ldns_buffer_begin(b64sig));
496 0           ldns_buffer_free(b64sig); /* can't free this buffer ?? */
497 0           return sigdata_rdf;
498             }
499              
500             ldns_rdf *
501 0           ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
502             {
503             unsigned char *md5_hash;
504             unsigned int siglen;
505             ldns_rdf *sigdata_rdf;
506             ldns_buffer *b64sig;
507              
508 0           b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
509 0 0         if (!b64sig) {
510 0           return NULL;
511             }
512              
513 0           md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
514             ldns_buffer_position(to_sign), NULL);
515 0 0         if (!md5_hash) {
516 0           ldns_buffer_free(b64sig);
517 0           return NULL;
518             }
519              
520 0           RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH,
521 0           (unsigned char*)ldns_buffer_begin(b64sig),
522             &siglen, key);
523              
524 0           sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
525 0           ldns_buffer_begin(b64sig));
526 0           ldns_buffer_free(b64sig);
527 0           return sigdata_rdf;
528             }
529             #endif /* HAVE_SSL */
530              
531             /**
532             * Pushes all rrs from the rrsets of type A and AAAA on gluelist.
533             */
534             static ldns_status
535 0           ldns_dnssec_addresses_on_glue_list(
536             ldns_dnssec_rrsets *cur_rrset,
537             ldns_rr_list *glue_list)
538             {
539             ldns_dnssec_rrs *cur_rrs;
540 0 0         while (cur_rrset) {
541 0 0         if (cur_rrset->type == LDNS_RR_TYPE_A
542 0 0         || cur_rrset->type == LDNS_RR_TYPE_AAAA) {
543 0 0         for (cur_rrs = cur_rrset->rrs;
544             cur_rrs;
545 0           cur_rrs = cur_rrs->next) {
546 0 0         if (cur_rrs->rr) {
547 0 0         if (!ldns_rr_list_push_rr(glue_list,
548 0           cur_rrs->rr)) {
549 0           return LDNS_STATUS_MEM_ERR;
550             /* ldns_rr_list_push_rr()
551             * returns false when unable
552             * to increase the capacity
553             * of the ldsn_rr_list
554             */
555             }
556             }
557             }
558             }
559 0           cur_rrset = cur_rrset->next;
560             }
561 0           return LDNS_STATUS_OK;
562             }
563              
564             /**
565             * Marks the names in the zone that are occluded. Those names will be skipped
566             * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
567             * function. But watch out! Names that are partially occluded (like glue with
568             * the same name as the delegation) will not be marked and should specifically
569             * be taken into account separately.
570             *
571             * When glue_list is given (not NULL), in the process of marking the names, all
572             * glue resource records will be pushed to that list, even glue at delegation names.
573             *
574             * \param[in] zone the zone in which to mark the names
575             * \param[in] glue_list the list to which to push the glue rrs
576             * \return LDNS_STATUS_OK on success, an error code otherwise
577             */
578             ldns_status
579 0           ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone,
580             ldns_rr_list *glue_list)
581             {
582             ldns_rbnode_t *node;
583             ldns_dnssec_name *name;
584             ldns_rdf *owner;
585 0           ldns_rdf *cut = NULL; /* keeps track of zone cuts */
586             /* When the cut is caused by a delegation, below_delegation will be 1.
587             * When caused by a DNAME, below_delegation will be 0.
588             */
589 0           int below_delegation = -1; /* init suppresses comiler warning */
590             ldns_status s;
591              
592 0 0         if (!zone || !zone->names) {
    0          
593 0           return LDNS_STATUS_NULL;
594             }
595 0 0         for (node = ldns_rbtree_first(zone->names);
596             node != LDNS_RBTREE_NULL;
597 0           node = ldns_rbtree_next(node)) {
598 0           name = (ldns_dnssec_name *) node->data;
599 0           owner = ldns_dnssec_name_name(name);
600              
601 0 0         if (cut) {
602             /* The previous node was a zone cut, or a subdomain
603             * below a zone cut. Is this node (still) a subdomain
604             * below the cut? Then the name is occluded. Unless
605             * the name contains a SOA, after which we are
606             * authoritative again.
607             *
608             * FIXME! If there are labels in between the SOA and
609             * the cut, going from the authoritative space (below
610             * the SOA) up into occluded space again, will not be
611             * detected with the contruct below!
612             */
613 0           if (ldns_dname_is_subdomain(owner, cut) &&
614 0           !ldns_dnssec_rrsets_contains_type(
615             name->rrsets, LDNS_RR_TYPE_SOA)) {
616              
617 0 0         if (below_delegation && glue_list) {
    0          
618 0           s = ldns_dnssec_addresses_on_glue_list(
619             name->rrsets, glue_list);
620 0 0         if (s != LDNS_STATUS_OK) {
621 0           return s;
622             }
623             }
624 0           name->is_glue = true; /* Mark occluded name! */
625 0           continue;
626             } else {
627 0           cut = NULL;
628             }
629             }
630              
631             /* The node is not below a zone cut. Is it a zone cut itself?
632             * Everything below a SOA is authoritative of course; Except
633             * when the name also contains a DNAME :).
634             */
635 0 0         if (ldns_dnssec_rrsets_contains_type(
636             name->rrsets, LDNS_RR_TYPE_NS)
637 0 0         && !ldns_dnssec_rrsets_contains_type(
638             name->rrsets, LDNS_RR_TYPE_SOA)) {
639 0           cut = owner;
640 0           below_delegation = 1;
641 0 0         if (glue_list) { /* record glue on the zone cut */
642 0           s = ldns_dnssec_addresses_on_glue_list(
643             name->rrsets, glue_list);
644 0 0         if (s != LDNS_STATUS_OK) {
645 0           return s;
646             }
647             }
648 0 0         } else if (ldns_dnssec_rrsets_contains_type(
649             name->rrsets, LDNS_RR_TYPE_DNAME)) {
650 0           cut = owner;
651 0           below_delegation = 0;
652             }
653             }
654 0           return LDNS_STATUS_OK;
655             }
656              
657             /**
658             * Marks the names in the zone that are occluded. Those names will be skipped
659             * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
660             * function. But watch out! Names that are partially occluded (like glue with
661             * the same name as the delegation) will not be marked and should specifically
662             * be taken into account separately.
663             *
664             * \param[in] zone the zone in which to mark the names
665             * \return LDNS_STATUS_OK on success, an error code otherwise
666             */
667             ldns_status
668 0           ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
669             {
670 0           return ldns_dnssec_zone_mark_and_get_glue(zone, NULL);
671             }
672              
673             ldns_rbnode_t *
674 0           ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
675             {
676 0           ldns_rbnode_t *next_node = NULL;
677 0           ldns_dnssec_name *next_name = NULL;
678 0           bool done = false;
679              
680 0 0         if (node == LDNS_RBTREE_NULL) {
681 0           return NULL;
682             }
683 0           next_node = node;
684 0 0         while (!done) {
685 0 0         if (next_node == LDNS_RBTREE_NULL) {
686 0           return NULL;
687             } else {
688 0           next_name = (ldns_dnssec_name *)next_node->data;
689 0 0         if (!next_name->is_glue) {
690 0           done = true;
691             } else {
692 0           next_node = ldns_rbtree_next(next_node);
693             }
694             }
695             }
696 0           return next_node;
697             }
698              
699             ldns_status
700 0           ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
701             ldns_rr_list *new_rrs)
702             {
703              
704             ldns_rbnode_t *first_node, *cur_node, *next_node;
705             ldns_dnssec_name *cur_name, *next_name;
706             ldns_rr *nsec_rr;
707             uint32_t nsec_ttl;
708             ldns_dnssec_rrsets *soa;
709              
710             /* the TTL of NSEC rrs should be set to the minimum TTL of
711             * the zone SOA (RFC4035 Section 2.3)
712             */
713 0           soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
714              
715             /* did the caller actually set it? if not,
716             * fall back to default ttl
717             */
718 0 0         if (soa && soa->rrs && soa->rrs->rr
    0          
    0          
719 0 0         && (ldns_rr_rdf(soa->rrs->rr, 6) != NULL)) {
720 0           nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
721             } else {
722 0           nsec_ttl = LDNS_DEFAULT_TTL;
723             }
724              
725 0           first_node = ldns_dnssec_name_node_next_nonglue(
726             ldns_rbtree_first(zone->names));
727 0           cur_node = first_node;
728 0 0         if (cur_node) {
729 0           next_node = ldns_dnssec_name_node_next_nonglue(
730             ldns_rbtree_next(cur_node));
731             } else {
732 0           next_node = NULL;
733             }
734              
735 0 0         while (cur_node && next_node) {
    0          
736 0           cur_name = (ldns_dnssec_name *)cur_node->data;
737 0           next_name = (ldns_dnssec_name *)next_node->data;
738 0           nsec_rr = ldns_dnssec_create_nsec(cur_name,
739             next_name,
740             LDNS_RR_TYPE_NSEC);
741 0           ldns_rr_set_ttl(nsec_rr, nsec_ttl);
742 0 0         if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
743 0           ldns_rr_free(nsec_rr);
744 0           return LDNS_STATUS_ERR;
745             }
746 0           ldns_rr_list_push_rr(new_rrs, nsec_rr);
747 0           cur_node = next_node;
748 0 0         if (cur_node) {
749 0           next_node = ldns_dnssec_name_node_next_nonglue(
750             ldns_rbtree_next(cur_node));
751             }
752             }
753              
754 0 0         if (cur_node && !next_node) {
    0          
755 0           cur_name = (ldns_dnssec_name *)cur_node->data;
756 0           next_name = (ldns_dnssec_name *)first_node->data;
757 0           nsec_rr = ldns_dnssec_create_nsec(cur_name,
758             next_name,
759             LDNS_RR_TYPE_NSEC);
760 0           ldns_rr_set_ttl(nsec_rr, nsec_ttl);
761 0 0         if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
762 0           ldns_rr_free(nsec_rr);
763 0           return LDNS_STATUS_ERR;
764             }
765 0           ldns_rr_list_push_rr(new_rrs, nsec_rr);
766             } else {
767 0           printf("error\n");
768             }
769              
770 0           return LDNS_STATUS_OK;
771             }
772              
773             #ifdef HAVE_SSL
774             static void
775 0           ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
776             (void) arg;
777 0           LDNS_FREE(node);
778 0           }
779              
780             static ldns_status
781 0           ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
782             ldns_rr_list *new_rrs,
783             uint8_t algorithm,
784             uint8_t flags,
785             uint16_t iterations,
786             uint8_t salt_length,
787             uint8_t *salt,
788             ldns_rbtree_t **map)
789             {
790             ldns_rbnode_t *first_name_node;
791             ldns_rbnode_t *current_name_node;
792             ldns_dnssec_name *current_name;
793 0           ldns_status result = LDNS_STATUS_OK;
794             ldns_rr *nsec_rr;
795             ldns_rr_list *nsec3_list;
796             uint32_t nsec_ttl;
797             ldns_dnssec_rrsets *soa;
798             ldns_rbnode_t *hashmap_node;
799              
800 0 0         if (!zone || !new_rrs || !zone->names) {
    0          
    0          
801 0           return LDNS_STATUS_ERR;
802             }
803              
804             /* the TTL of NSEC rrs should be set to the minimum TTL of
805             * the zone SOA (RFC4035 Section 2.3)
806             */
807 0           soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
808              
809             /* did the caller actually set it? if not,
810             * fall back to default ttl
811             */
812 0 0         if (soa && soa->rrs && soa->rrs->rr
    0          
    0          
813 0 0         && ldns_rr_rdf(soa->rrs->rr, 6) != NULL) {
814 0           nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
815             } else {
816 0           nsec_ttl = LDNS_DEFAULT_TTL;
817             }
818              
819 0 0         if (zone->hashed_names) {
820 0           ldns_traverse_postorder(zone->hashed_names,
821             ldns_hashed_names_node_free, NULL);
822 0           LDNS_FREE(zone->hashed_names);
823             }
824 0           zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
825 0 0         if (zone->hashed_names && map) {
    0          
826 0           *map = zone->hashed_names;
827             }
828              
829 0           first_name_node = ldns_dnssec_name_node_next_nonglue(
830             ldns_rbtree_first(zone->names));
831              
832 0           current_name_node = first_name_node;
833              
834 0 0         while (current_name_node && current_name_node != LDNS_RBTREE_NULL &&
    0          
    0          
835             result == LDNS_STATUS_OK) {
836              
837 0           current_name = (ldns_dnssec_name *) current_name_node->data;
838 0           nsec_rr = ldns_dnssec_create_nsec3(current_name,
839             NULL,
840 0           zone->soa->name,
841             algorithm,
842             flags,
843             iterations,
844             salt_length,
845             salt);
846             /* by default, our nsec based generator adds rrsigs
847             * remove the bitmap for empty nonterminals */
848 0 0         if (!current_name->rrsets) {
849 0           ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
850             }
851 0           ldns_rr_set_ttl(nsec_rr, nsec_ttl);
852 0           result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
853 0           ldns_rr_list_push_rr(new_rrs, nsec_rr);
854 0 0         if (ldns_rr_owner(nsec_rr)) {
855 0           hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
856 0 0         if (hashmap_node == NULL) {
857 0           return LDNS_STATUS_MEM_ERR;
858             }
859 0           current_name->hashed_name =
860 0           ldns_dname_label(ldns_rr_owner(nsec_rr), 0);
861              
862 0 0         if (current_name->hashed_name == NULL) {
863 0           LDNS_FREE(hashmap_node);
864 0           return LDNS_STATUS_MEM_ERR;
865             }
866 0           hashmap_node->key = current_name->hashed_name;
867 0           hashmap_node->data = current_name;
868              
869 0 0         if (! ldns_rbtree_insert(zone->hashed_names
870             , hashmap_node)) {
871 0           LDNS_FREE(hashmap_node);
872             }
873             }
874 0           current_name_node = ldns_dnssec_name_node_next_nonglue(
875             ldns_rbtree_next(current_name_node));
876             }
877 0 0         if (result != LDNS_STATUS_OK) {
878 0           return result;
879             }
880              
881             /* Make sorted list of nsec3s (via zone->hashed_names)
882             */
883 0           nsec3_list = ldns_rr_list_new();
884 0 0         if (nsec3_list == NULL) {
885 0           return LDNS_STATUS_MEM_ERR;
886             }
887 0 0         for ( hashmap_node = ldns_rbtree_first(zone->hashed_names)
888             ; hashmap_node != LDNS_RBTREE_NULL
889 0           ; hashmap_node = ldns_rbtree_next(hashmap_node)
890             ) {
891 0           current_name = (ldns_dnssec_name *) hashmap_node->data;
892 0           nsec_rr = ((ldns_dnssec_name *) hashmap_node->data)->nsec;
893 0 0         if (nsec_rr) {
894 0           ldns_rr_list_push_rr(nsec3_list, nsec_rr);
895             }
896             }
897 0           result = ldns_dnssec_chain_nsec3_list(nsec3_list);
898 0           ldns_rr_list_free(nsec3_list);
899              
900 0           return result;
901             }
902              
903             ldns_status
904 0           ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
905             ldns_rr_list *new_rrs,
906             uint8_t algorithm,
907             uint8_t flags,
908             uint16_t iterations,
909             uint8_t salt_length,
910             uint8_t *salt)
911             {
912 0           return ldns_dnssec_zone_create_nsec3s_mkmap(zone, new_rrs, algorithm,
913             flags, iterations, salt_length, salt, NULL);
914              
915             }
916             #endif /* HAVE_SSL */
917              
918             ldns_dnssec_rrs *
919 0           ldns_dnssec_remove_signatures( ldns_dnssec_rrs *signatures
920             , ATTR_UNUSED(ldns_key_list *key_list)
921             , int (*func)(ldns_rr *, void *)
922             , void *arg
923             )
924             {
925 0           ldns_dnssec_rrs *base_rrs = signatures;
926 0           ldns_dnssec_rrs *cur_rr = base_rrs;
927 0           ldns_dnssec_rrs *prev_rr = NULL;
928             ldns_dnssec_rrs *next_rr;
929              
930             uint16_t keytag;
931             size_t i;
932              
933 0 0         if (!cur_rr) {
934 0           switch(func(NULL, arg)) {
935             case LDNS_SIGNATURE_LEAVE_ADD_NEW:
936             case LDNS_SIGNATURE_REMOVE_ADD_NEW:
937 0           break;
938             case LDNS_SIGNATURE_LEAVE_NO_ADD:
939             case LDNS_SIGNATURE_REMOVE_NO_ADD:
940 0           ldns_key_list_set_use(key_list, false);
941 0           break;
942             default:
943             #ifdef STDERR_MSGS
944             fprintf(stderr, "[XX] unknown return value from callback\n");
945             #endif
946 0           break;
947             }
948 0           return NULL;
949             }
950 0           (void)func(cur_rr->rr, arg);
951              
952 0 0         while (cur_rr) {
953 0           next_rr = cur_rr->next;
954              
955 0           switch (func(cur_rr->rr, arg)) {
956             case LDNS_SIGNATURE_LEAVE_ADD_NEW:
957 0           prev_rr = cur_rr;
958 0           break;
959             case LDNS_SIGNATURE_LEAVE_NO_ADD:
960 0           keytag = ldns_rdf2native_int16(
961 0           ldns_rr_rrsig_keytag(cur_rr->rr));
962 0 0         for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
963 0 0         if (ldns_key_keytag(ldns_key_list_key(key_list, i)) ==
964             keytag) {
965 0           ldns_key_set_use(ldns_key_list_key(key_list, i),
966             false);
967             }
968             }
969 0           prev_rr = cur_rr;
970 0           break;
971             case LDNS_SIGNATURE_REMOVE_NO_ADD:
972 0           keytag = ldns_rdf2native_int16(
973 0           ldns_rr_rrsig_keytag(cur_rr->rr));
974 0 0         for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
975 0 0         if (ldns_key_keytag(ldns_key_list_key(key_list, i))
976             == keytag) {
977 0           ldns_key_set_use(ldns_key_list_key(key_list, i),
978             false);
979             }
980             }
981 0 0         if (prev_rr) {
982 0           prev_rr->next = next_rr;
983             } else {
984 0           base_rrs = next_rr;
985             }
986 0           LDNS_FREE(cur_rr);
987 0           break;
988             case LDNS_SIGNATURE_REMOVE_ADD_NEW:
989 0 0         if (prev_rr) {
990 0           prev_rr->next = next_rr;
991             } else {
992 0           base_rrs = next_rr;
993             }
994 0           LDNS_FREE(cur_rr);
995 0           break;
996             default:
997             #ifdef STDERR_MSGS
998             fprintf(stderr, "[XX] unknown return value from callback\n");
999             #endif
1000 0           break;
1001             }
1002 0           cur_rr = next_rr;
1003             }
1004              
1005 0           return base_rrs;
1006             }
1007              
1008             #ifdef HAVE_SSL
1009             ldns_status
1010 0           ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
1011             ldns_rr_list *new_rrs,
1012             ldns_key_list *key_list,
1013             int (*func)(ldns_rr *, void*),
1014             void *arg)
1015             {
1016 0           return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list,
1017             func, arg, 0);
1018             }
1019              
1020             /** If there are KSKs use only them and mark ZSKs unused */
1021             static void
1022 0           ldns_key_list_filter_for_dnskey(ldns_key_list *key_list)
1023             {
1024 0           int saw_ksk = 0;
1025             size_t i;
1026 0 0         for(i=0; i
1027 0 0         if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
1028 0           saw_ksk = 1;
1029 0           break;
1030             }
1031 0 0         if(!saw_ksk)
1032 0           return;
1033 0 0         for(i=0; i
1034 0 0         if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
1035 0           ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
1036             }
1037              
1038             /** If there are no ZSKs use KSK as ZSK */
1039             static void
1040 0           ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list)
1041             {
1042 0           int saw_zsk = 0;
1043             size_t i;
1044 0 0         for(i=0; i
1045 0 0         if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
1046 0           saw_zsk = 1;
1047 0           break;
1048             }
1049 0 0         if(!saw_zsk)
1050 0           return;
1051             /* else filter all KSKs */
1052 0 0         for(i=0; i
1053 0 0         if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
1054 0           ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
1055             }
1056              
1057             ldns_status
1058 0           ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone
1059             , ldns_rr_list *new_rrs
1060             , ldns_key_list *key_list
1061             , int (*func)(ldns_rr *, void*)
1062             , void *arg
1063             , int flags
1064             )
1065             {
1066 0           ldns_status result = LDNS_STATUS_OK;
1067              
1068             ldns_rbnode_t *cur_node;
1069             ldns_rr_list *rr_list;
1070              
1071             ldns_dnssec_name *cur_name;
1072             ldns_dnssec_rrsets *cur_rrset;
1073             ldns_dnssec_rrs *cur_rr;
1074              
1075             ldns_rr_list *siglist;
1076              
1077             size_t i;
1078              
1079 0           int on_delegation_point = 0; /* handle partially occluded names */
1080              
1081 0           ldns_rr_list *pubkey_list = ldns_rr_list_new();
1082 0 0         for (i = 0; i
1083 0           ldns_rr_list_push_rr( pubkey_list
1084 0           , ldns_key2rr(ldns_key_list_key(
1085             key_list, i))
1086             );
1087             }
1088             /* TODO: callback to see is list should be signed */
1089             /* TODO: remove 'old' signatures from signature list */
1090 0           cur_node = ldns_rbtree_first(zone->names);
1091 0 0         while (cur_node != LDNS_RBTREE_NULL) {
1092 0           cur_name = (ldns_dnssec_name *) cur_node->data;
1093              
1094 0 0         if (!cur_name->is_glue) {
1095 0           on_delegation_point = ldns_dnssec_rrsets_contains_type(
1096             cur_name->rrsets, LDNS_RR_TYPE_NS)
1097 0 0         && !ldns_dnssec_rrsets_contains_type(
    0          
1098             cur_name->rrsets, LDNS_RR_TYPE_SOA);
1099 0           cur_rrset = cur_name->rrsets;
1100 0 0         while (cur_rrset) {
1101             /* reset keys to use */
1102 0           ldns_key_list_set_use(key_list, true);
1103              
1104             /* walk through old sigs, remove the old,
1105             and mark which keys (not) to use) */
1106 0           cur_rrset->signatures =
1107 0           ldns_dnssec_remove_signatures(cur_rrset->signatures,
1108             key_list,
1109             func,
1110             arg);
1111 0 0         if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) &&
    0          
1112 0           cur_rrset->type == LDNS_RR_TYPE_DNSKEY)
1113 0           ldns_key_list_filter_for_dnskey(key_list);
1114              
1115 0 0         if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY)
1116 0           ldns_key_list_filter_for_non_dnskey(key_list);
1117              
1118             /* TODO: just set count to zero? */
1119 0           rr_list = ldns_rr_list_new();
1120              
1121 0           cur_rr = cur_rrset->rrs;
1122 0 0         while (cur_rr) {
1123 0           ldns_rr_list_push_rr(rr_list, cur_rr->rr);
1124 0           cur_rr = cur_rr->next;
1125             }
1126              
1127             /* only sign non-delegation RRsets */
1128             /* (glue should have been marked earlier,
1129             * except on the delegation points itself) */
1130 0           if (!on_delegation_point ||
1131 0           ldns_rr_list_type(rr_list)
1132 0 0         == LDNS_RR_TYPE_DS ||
1133 0           ldns_rr_list_type(rr_list)
1134 0 0         == LDNS_RR_TYPE_NSEC ||
1135 0           ldns_rr_list_type(rr_list)
1136             == LDNS_RR_TYPE_NSEC3) {
1137 0           siglist = ldns_sign_public(rr_list, key_list);
1138 0 0         for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
1139 0 0         if (cur_rrset->signatures) {
1140 0           result = ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
1141             ldns_rr_list_rr(siglist,
1142             i));
1143             } else {
1144 0           cur_rrset->signatures = ldns_dnssec_rrs_new();
1145 0           cur_rrset->signatures->rr =
1146 0           ldns_rr_list_rr(siglist, i);
1147             }
1148 0 0         if (new_rrs) {
1149 0           ldns_rr_list_push_rr(new_rrs,
1150 0           ldns_rr_list_rr(siglist,
1151             i));
1152             }
1153             }
1154 0           ldns_rr_list_free(siglist);
1155             }
1156              
1157 0           ldns_rr_list_free(rr_list);
1158              
1159 0           cur_rrset = cur_rrset->next;
1160             }
1161              
1162             /* sign the nsec */
1163 0           ldns_key_list_set_use(key_list, true);
1164 0           cur_name->nsec_signatures =
1165 0           ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
1166             key_list,
1167             func,
1168             arg);
1169 0           ldns_key_list_filter_for_non_dnskey(key_list);
1170              
1171 0           rr_list = ldns_rr_list_new();
1172 0           ldns_rr_list_push_rr(rr_list, cur_name->nsec);
1173 0           siglist = ldns_sign_public(rr_list, key_list);
1174              
1175 0 0         for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
1176 0 0         if (cur_name->nsec_signatures) {
1177 0           result = ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
1178             ldns_rr_list_rr(siglist, i));
1179             } else {
1180 0           cur_name->nsec_signatures = ldns_dnssec_rrs_new();
1181 0           cur_name->nsec_signatures->rr =
1182 0           ldns_rr_list_rr(siglist, i);
1183             }
1184 0 0         if (new_rrs) {
1185 0           ldns_rr_list_push_rr(new_rrs,
1186 0           ldns_rr_list_rr(siglist, i));
1187             }
1188             }
1189              
1190 0           ldns_rr_list_free(siglist);
1191 0           ldns_rr_list_free(rr_list);
1192             }
1193 0           cur_node = ldns_rbtree_next(cur_node);
1194             }
1195              
1196 0           ldns_rr_list_deep_free(pubkey_list);
1197 0           return result;
1198             }
1199              
1200             ldns_status
1201 0           ldns_dnssec_zone_sign(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             {
1207 0           return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0);
1208             }
1209              
1210             ldns_status
1211 0           ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
1212             ldns_rr_list *new_rrs,
1213             ldns_key_list *key_list,
1214             int (*func)(ldns_rr *, void *),
1215             void *arg,
1216             int flags)
1217             {
1218 0           ldns_status result = LDNS_STATUS_OK;
1219              
1220 0 0         if (!zone || !new_rrs || !key_list) {
    0          
    0          
1221 0           return LDNS_STATUS_ERR;
1222             }
1223              
1224             /* zone is already sorted */
1225 0           result = ldns_dnssec_zone_mark_glue(zone);
1226 0 0         if (result != LDNS_STATUS_OK) {
1227 0           return result;
1228             }
1229              
1230             /* check whether we need to add nsecs */
1231 0 0         if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
    0          
1232 0           result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
1233 0 0         if (result != LDNS_STATUS_OK) {
1234 0           return result;
1235             }
1236             }
1237              
1238 0           result = ldns_dnssec_zone_create_rrsigs_flg(zone,
1239             new_rrs,
1240             key_list,
1241             func,
1242             arg,
1243             flags);
1244              
1245 0           return result;
1246             }
1247              
1248             ldns_status
1249 0           ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
1250             ldns_rr_list *new_rrs,
1251             ldns_key_list *key_list,
1252             int (*func)(ldns_rr *, void *),
1253             void *arg,
1254             uint8_t algorithm,
1255             uint8_t flags,
1256             uint16_t iterations,
1257             uint8_t salt_length,
1258             uint8_t *salt)
1259             {
1260 0           return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
1261             func, arg, algorithm, flags, iterations, salt_length, salt, 0,
1262             NULL);
1263             }
1264              
1265             ldns_status
1266 0           ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
1267             ldns_rr_list *new_rrs,
1268             ldns_key_list *key_list,
1269             int (*func)(ldns_rr *, void *),
1270             void *arg,
1271             uint8_t algorithm,
1272             uint8_t flags,
1273             uint16_t iterations,
1274             uint8_t salt_length,
1275             uint8_t *salt,
1276             int signflags,
1277             ldns_rbtree_t **map)
1278             {
1279             ldns_rr *nsec3, *nsec3param;
1280 0           ldns_status result = LDNS_STATUS_OK;
1281              
1282             /* zone is already sorted */
1283 0           result = ldns_dnssec_zone_mark_glue(zone);
1284 0 0         if (result != LDNS_STATUS_OK) {
1285 0           return result;
1286             }
1287              
1288             /* TODO if there are already nsec3s presents and their
1289             * parameters are the same as these, we don't have to recreate
1290             */
1291 0 0         if (zone->names) {
1292             /* add empty nonterminals */
1293 0           result = ldns_dnssec_zone_add_empty_nonterminals(zone);
1294 0 0         if (result != LDNS_STATUS_OK) {
1295 0           return result;
1296             }
1297              
1298 0           nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec;
1299 0 0         if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
    0          
1300             /* no need to recreate */
1301             } else {
1302 0 0         if (!ldns_dnssec_zone_find_rrset(zone,
1303 0           zone->soa->name,
1304             LDNS_RR_TYPE_NSEC3PARAM)) {
1305             /* create and add the nsec3param rr */
1306 0           nsec3param =
1307             ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAM);
1308 0           ldns_rr_set_owner(nsec3param,
1309 0           ldns_rdf_clone(zone->soa->name));
1310 0           ldns_nsec3_add_param_rdfs(nsec3param,
1311             algorithm,
1312             flags,
1313             iterations,
1314             salt_length,
1315             salt);
1316             /* always set bit 7 of the flags to zero, according to
1317             * rfc5155 section 11. The bits are counted from right to left,
1318             * so bit 7 in rfc5155 is bit 0 in ldns */
1319 0           ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3param, 1)), 0, 0);
1320 0           result = ldns_dnssec_zone_add_rr(zone, nsec3param);
1321 0 0         if (result != LDNS_STATUS_OK) {
1322 0           return result;
1323             }
1324 0           ldns_rr_list_push_rr(new_rrs, nsec3param);
1325             }
1326 0           result = ldns_dnssec_zone_create_nsec3s_mkmap(zone,
1327             new_rrs,
1328             algorithm,
1329             flags,
1330             iterations,
1331             salt_length,
1332             salt,
1333             map);
1334 0 0         if (result != LDNS_STATUS_OK) {
1335 0           return result;
1336             }
1337             }
1338              
1339 0           result = ldns_dnssec_zone_create_rrsigs_flg(zone,
1340             new_rrs,
1341             key_list,
1342             func,
1343             arg,
1344             signflags);
1345             }
1346              
1347 0           return result;
1348             }
1349              
1350             ldns_status
1351 0           ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
1352             ldns_rr_list *new_rrs,
1353             ldns_key_list *key_list,
1354             int (*func)(ldns_rr *, void *),
1355             void *arg,
1356             uint8_t algorithm,
1357             uint8_t flags,
1358             uint16_t iterations,
1359             uint8_t salt_length,
1360             uint8_t *salt,
1361             int signflags)
1362             {
1363 0           return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
1364             func, arg, algorithm, flags, iterations, salt_length, salt,
1365             signflags, NULL);
1366             }
1367              
1368             ldns_zone *
1369 0           ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
1370             {
1371             ldns_dnssec_zone *dnssec_zone;
1372             ldns_zone *signed_zone;
1373             ldns_rr_list *new_rrs;
1374             size_t i;
1375              
1376 0           signed_zone = ldns_zone_new();
1377 0           dnssec_zone = ldns_dnssec_zone_new();
1378              
1379 0           (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
1380 0           ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
1381              
1382 0 0         for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
1383 0           (void) ldns_dnssec_zone_add_rr(dnssec_zone,
1384 0           ldns_rr_list_rr(ldns_zone_rrs(zone),
1385             i));
1386 0           ldns_zone_push_rr(signed_zone,
1387 0           ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
1388             i)));
1389             }
1390              
1391 0           new_rrs = ldns_rr_list_new();
1392 0           (void) ldns_dnssec_zone_sign(dnssec_zone,
1393             new_rrs,
1394             key_list,
1395             ldns_dnssec_default_replace_signatures,
1396             NULL);
1397              
1398 0 0         for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
1399 0           ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
1400 0           ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
1401             }
1402              
1403 0           ldns_rr_list_deep_free(new_rrs);
1404 0           ldns_dnssec_zone_free(dnssec_zone);
1405              
1406 0           return signed_zone;
1407             }
1408              
1409             ldns_zone *
1410 0           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)
1411             {
1412             ldns_dnssec_zone *dnssec_zone;
1413             ldns_zone *signed_zone;
1414             ldns_rr_list *new_rrs;
1415             size_t i;
1416              
1417 0           signed_zone = ldns_zone_new();
1418 0           dnssec_zone = ldns_dnssec_zone_new();
1419              
1420 0           (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
1421 0           ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
1422              
1423 0 0         for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
1424 0           (void) ldns_dnssec_zone_add_rr(dnssec_zone,
1425 0           ldns_rr_list_rr(ldns_zone_rrs(zone),
1426             i));
1427 0           ldns_zone_push_rr(signed_zone,
1428 0           ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
1429             i)));
1430             }
1431              
1432 0           new_rrs = ldns_rr_list_new();
1433 0           (void) ldns_dnssec_zone_sign_nsec3(dnssec_zone,
1434             new_rrs,
1435             key_list,
1436             ldns_dnssec_default_replace_signatures,
1437             NULL,
1438             algorithm,
1439             flags,
1440             iterations,
1441             salt_length,
1442             salt);
1443              
1444 0 0         for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
1445 0           ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
1446 0           ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
1447             }
1448              
1449 0           ldns_rr_list_deep_free(new_rrs);
1450 0           ldns_dnssec_zone_free(dnssec_zone);
1451              
1452 0           return signed_zone;
1453             }
1454             #endif /* HAVE_SSL */
1455              
1456