xref: /freebsd/contrib/ldns/dnssec_sign.c (revision 39ee7a7a6bdd1557b1c3532abf60d139798ac88b)
1 #include <ldns/config.h>
2 
3 #include <ldns/ldns.h>
4 
5 #include <ldns/dnssec.h>
6 #include <ldns/dnssec_sign.h>
7 
8 #include <strings.h>
9 #include <time.h>
10 
11 #ifdef HAVE_SSL
12 /* this entire file is rather useless when you don't have
13  * crypto...
14  */
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 */
21 
22 ldns_rr *
23 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 	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 --;
38 
39 	current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
40 
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));
44 
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))));
52 
53 	/* fill in what we know of the signature */
54 
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));
83 	}
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));
96 	}
97 
98 	(void)ldns_rr_rrsig_set_keytag(
99 		   current_sig,
100 		   ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
101 		                         ldns_key_keytag(current_key)));
102 
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)));
108 
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;
116 }
117 
118 #ifdef HAVE_SSL
119 ldns_rdf *
120 ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
121 {
122 	ldns_rdf *b64rdf = NULL;
123 
124 	switch(ldns_key_algorithm(current_key)) {
125 	case LDNS_SIGN_DSA:
126 	case LDNS_SIGN_DSA_NSEC3:
127 		b64rdf = ldns_sign_public_evp(
128 				   sign_buf,
129 				   ldns_key_evp_key(current_key),
130 				   EVP_dss1());
131 		break;
132 	case LDNS_SIGN_RSASHA1:
133 	case LDNS_SIGN_RSASHA1_NSEC3:
134 		b64rdf = ldns_sign_public_evp(
135 				   sign_buf,
136 				   ldns_key_evp_key(current_key),
137 				   EVP_sha1());
138 		break;
139 #ifdef USE_SHA2
140 	case LDNS_SIGN_RSASHA256:
141 		b64rdf = ldns_sign_public_evp(
142 				   sign_buf,
143 				   ldns_key_evp_key(current_key),
144 				   EVP_sha256());
145 		break;
146 	case LDNS_SIGN_RSASHA512:
147 		b64rdf = ldns_sign_public_evp(
148 				   sign_buf,
149 				   ldns_key_evp_key(current_key),
150 				   EVP_sha512());
151 		break;
152 #endif /* USE_SHA2 */
153 #ifdef USE_GOST
154 	case LDNS_SIGN_ECC_GOST:
155 		b64rdf = ldns_sign_public_evp(
156 				   sign_buf,
157 				   ldns_key_evp_key(current_key),
158 				   EVP_get_digestbyname("md_gost94"));
159 		break;
160 #endif /* USE_GOST */
161 #ifdef USE_ECDSA
162         case LDNS_SIGN_ECDSAP256SHA256:
163        		b64rdf = ldns_sign_public_evp(
164 				   sign_buf,
165 				   ldns_key_evp_key(current_key),
166 				   EVP_sha256());
167                 break;
168         case LDNS_SIGN_ECDSAP384SHA384:
169        		b64rdf = ldns_sign_public_evp(
170 				   sign_buf,
171 				   ldns_key_evp_key(current_key),
172 				   EVP_sha384());
173                 break;
174 #endif
175 	case LDNS_SIGN_RSAMD5:
176 		b64rdf = ldns_sign_public_evp(
177 				   sign_buf,
178 				   ldns_key_evp_key(current_key),
179 				   EVP_md5());
180 		break;
181 	default:
182 		/* do _you_ know this alg? */
183 		printf("unknown algorithm, ");
184 		printf("is the one used available on this system?\n");
185 		break;
186 	}
187 
188 	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 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 	if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
209 		return NULL;
210 	}
211 
212 	new_owner = NULL;
213 
214 	signatures = ldns_rr_list_new();
215 
216 	/* prepare a signature and add all the know data
217 	 * prepare the rrset. Sign this together.  */
218 	rrset_clone = ldns_rr_list_clone(rrset);
219 	if (!rrset_clone) {
220 		return NULL;
221 	}
222 
223 	/* make it canonical */
224 	for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
225 		ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i),
226 			ldns_rr_ttl(ldns_rr_list_rr(rrset, 0)));
227 		ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
228 	}
229 	/* sort */
230 	ldns_rr_list_sort(rrset_clone);
231 
232 	for (key_count = 0;
233 		key_count < ldns_key_list_key_count(keys);
234 		key_count++) {
235 		if (!ldns_key_use(ldns_key_list_key(keys, key_count))) {
236 			continue;
237 		}
238 		sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
239 		if (!sign_buf) {
240 			ldns_rr_list_free(rrset_clone);
241 			ldns_rr_list_free(signatures);
242 			ldns_rdf_free(new_owner);
243 			return NULL;
244 		}
245 		b64rdf = NULL;
246 
247 		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 		if (ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY) {
251 			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 			if (ldns_rrsig2buffer_wire(sign_buf, current_sig)
259 			    != LDNS_STATUS_OK) {
260 				ldns_buffer_free(sign_buf);
261 				/* ERROR */
262 				ldns_rr_list_deep_free(rrset_clone);
263 				ldns_rr_free(current_sig);
264 				ldns_rr_list_deep_free(signatures);
265 				return NULL;
266 			}
267 
268 			/* add the rrset in sign_buf */
269 			if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone)
270 			    != LDNS_STATUS_OK) {
271 				ldns_buffer_free(sign_buf);
272 				ldns_rr_list_deep_free(rrset_clone);
273 				ldns_rr_free(current_sig);
274 				ldns_rr_list_deep_free(signatures);
275 				return NULL;
276 			}
277 
278 			b64rdf = ldns_sign_public_buffer(sign_buf, current_key);
279 
280 			if (!b64rdf) {
281 				/* signing went wrong */
282 				ldns_rr_list_deep_free(rrset_clone);
283 				ldns_rr_free(current_sig);
284 				ldns_rr_list_deep_free(signatures);
285 				return NULL;
286 			}
287 
288 			ldns_rr_rrsig_set_sig(current_sig, b64rdf);
289 
290 			/* push the signature to the signatures list */
291 			ldns_rr_list_push_rr(signatures, current_sig);
292 		}
293 		ldns_buffer_free(sign_buf); /* restart for the next key */
294 	}
295 	ldns_rr_list_deep_free(rrset_clone);
296 
297 	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 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 	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
320 	if (!b64sig) {
321 		return NULL;
322 	}
323 
324 	sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
325 				  ldns_buffer_position(to_sign), NULL);
326 	if (!sha1_hash) {
327 		ldns_buffer_free(b64sig);
328 		return NULL;
329 	}
330 
331 	sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
332         if(!sig) {
333 		ldns_buffer_free(b64sig);
334 		return NULL;
335         }
336 
337 	data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
338         if(!data) {
339 		ldns_buffer_free(b64sig);
340                 DSA_SIG_free(sig);
341 		return NULL;
342         }
343 
344 	data[0] = 1;
345 	pad = 20 - (size_t) BN_num_bytes(sig->r);
346 	if (pad > 0) {
347 		memset(data + 1, 0, pad);
348 	}
349 	BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad);
350 
351 	pad = 20 - (size_t) BN_num_bytes(sig->s);
352 	if (pad > 0) {
353 		memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
354 	}
355 	BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
356 
357 	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
358 								 1 + 2 * SHA_DIGEST_LENGTH,
359 								 data);
360 
361 	ldns_buffer_free(b64sig);
362 	LDNS_FREE(data);
363         DSA_SIG_free(sig);
364 
365 	return sigdata_rdf;
366 }
367 
368 #ifdef USE_ECDSA
369 #ifndef S_SPLINT_S
370 static int
371 ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
372 {
373         EC_KEY* ec;
374         const EC_GROUP* g;
375         if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC)
376                 return 0;
377         ec = EVP_PKEY_get1_EC_KEY(pkey);
378         g = EC_KEY_get0_group(ec);
379         if(!g) {
380                 EC_KEY_free(ec);
381                 return 0;
382         }
383         if(EC_GROUP_get_curve_name(g) == NID_secp224r1 ||
384                 EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1 ||
385                 EC_GROUP_get_curve_name(g) == NID_secp384r1) {
386                 EC_KEY_free(ec);
387                 return 1;
388         }
389         /* downref the eckey, the original is still inside the pkey */
390         EC_KEY_free(ec);
391         return 0;
392 }
393 #endif /* splint */
394 #endif /* USE_ECDSA */
395 
396 ldns_rdf *
397 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 	siglen = 0;
409 	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
410 	if (!b64sig) {
411 		return NULL;
412 	}
413 
414 	/* initializes a signing context */
415 	md_type = digest_type;
416 	if(!md_type) {
417 		/* unknown message difest */
418 		ldns_buffer_free(b64sig);
419 		return NULL;
420 	}
421 
422 	EVP_MD_CTX_init(&ctx);
423 	r = EVP_SignInit(&ctx, md_type);
424 	if(r == 1) {
425 		r = EVP_SignUpdate(&ctx, (unsigned char*)
426 					    ldns_buffer_begin(to_sign),
427 					    ldns_buffer_position(to_sign));
428 	} else {
429 		ldns_buffer_free(b64sig);
430 		return NULL;
431 	}
432 	if(r == 1) {
433 		r = EVP_SignFinal(&ctx, (unsigned char*)
434 					   ldns_buffer_begin(b64sig), &siglen, key);
435 	} else {
436 		ldns_buffer_free(b64sig);
437 		return NULL;
438 	}
439 	if(r != 1) {
440 		ldns_buffer_free(b64sig);
441 		return NULL;
442 	}
443 
444 	/* unfortunately, OpenSSL output is differenct from DNS DSA format */
445 #ifndef S_SPLINT_S
446 	if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
447 		sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
448 #ifdef USE_ECDSA
449         } else if(EVP_PKEY_type(key->type) == EVP_PKEY_EC &&
450                 ldns_pkey_is_ecdsa(key)) {
451                 sigdata_rdf = ldns_convert_ecdsa_rrsig_asn12rdf(b64sig, siglen);
452 #endif
453 	} else {
454 		/* ok output for other types is the same */
455 		sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
456 									 ldns_buffer_begin(b64sig));
457 	}
458 #endif /* splint */
459 	ldns_buffer_free(b64sig);
460 	EVP_MD_CTX_cleanup(&ctx);
461 	return sigdata_rdf;
462 }
463 
464 ldns_rdf *
465 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 	siglen = 0;
474 	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
475 	if (!b64sig) {
476 		return NULL;
477 	}
478 
479 	sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
480 				  ldns_buffer_position(to_sign), NULL);
481 	if (!sha1_hash) {
482 		ldns_buffer_free(b64sig);
483 		return NULL;
484 	}
485 
486 	result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH,
487 				   (unsigned char*)ldns_buffer_begin(b64sig),
488 				   &siglen, key);
489 	if (result != 1) {
490 		ldns_buffer_free(b64sig);
491 		return NULL;
492 	}
493 
494 	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
495 								 ldns_buffer_begin(b64sig));
496 	ldns_buffer_free(b64sig); /* can't free this buffer ?? */
497 	return sigdata_rdf;
498 }
499 
500 ldns_rdf *
501 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 	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
509 	if (!b64sig) {
510 		return NULL;
511 	}
512 
513 	md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
514 				ldns_buffer_position(to_sign), NULL);
515 	if (!md5_hash) {
516 		ldns_buffer_free(b64sig);
517 		return NULL;
518 	}
519 
520 	RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH,
521 		    (unsigned char*)ldns_buffer_begin(b64sig),
522 		    &siglen, key);
523 
524 	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
525 								 ldns_buffer_begin(b64sig));
526 	ldns_buffer_free(b64sig);
527 	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 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 	while (cur_rrset) {
541 		if (cur_rrset->type == LDNS_RR_TYPE_A
542 				|| cur_rrset->type == LDNS_RR_TYPE_AAAA) {
543 			for (cur_rrs = cur_rrset->rrs;
544 					cur_rrs;
545 					cur_rrs = cur_rrs->next) {
546 				if (cur_rrs->rr) {
547 					if (!ldns_rr_list_push_rr(glue_list,
548 							cur_rrs->rr)) {
549 						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 		cur_rrset = cur_rrset->next;
560 	}
561 	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 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 	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 	int below_delegation = -1; /* init suppresses comiler warning */
590 	ldns_status s;
591 
592 	if (!zone || !zone->names) {
593 		return LDNS_STATUS_NULL;
594 	}
595 	for (node = ldns_rbtree_first(zone->names);
596 			node != LDNS_RBTREE_NULL;
597 			node = ldns_rbtree_next(node)) {
598 		name = (ldns_dnssec_name *) node->data;
599 		owner = ldns_dnssec_name_name(name);
600 
601 		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 			if (ldns_dname_is_subdomain(owner, cut) &&
614 					!ldns_dnssec_rrsets_contains_type(
615 					name->rrsets, LDNS_RR_TYPE_SOA)) {
616 
617 				if (below_delegation && glue_list) {
618 					s = ldns_dnssec_addresses_on_glue_list(
619 						name->rrsets, glue_list);
620 					if (s != LDNS_STATUS_OK) {
621 						return s;
622 					}
623 				}
624 				name->is_glue = true; /* Mark occluded name! */
625 				continue;
626 			} else {
627 				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 		if (ldns_dnssec_rrsets_contains_type(
636 				name->rrsets, LDNS_RR_TYPE_NS)
637 			    && !ldns_dnssec_rrsets_contains_type(
638 				name->rrsets, LDNS_RR_TYPE_SOA)) {
639 			cut = owner;
640 			below_delegation = 1;
641 			if (glue_list) { /* record glue on the zone cut */
642 				s = ldns_dnssec_addresses_on_glue_list(
643 					name->rrsets, glue_list);
644 				if (s != LDNS_STATUS_OK) {
645 					return s;
646 				}
647 			}
648 		} else if (ldns_dnssec_rrsets_contains_type(
649 				name->rrsets, LDNS_RR_TYPE_DNAME)) {
650 			cut = owner;
651 			below_delegation = 0;
652 		}
653 	}
654 	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 ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
669 {
670 	return ldns_dnssec_zone_mark_and_get_glue(zone, NULL);
671 }
672 
673 ldns_rbnode_t *
674 ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
675 {
676 	ldns_rbnode_t *next_node = NULL;
677 	ldns_dnssec_name *next_name = NULL;
678 	bool done = false;
679 
680 	if (node == LDNS_RBTREE_NULL) {
681 		return NULL;
682 	}
683 	next_node = node;
684 	while (!done) {
685 		if (next_node == LDNS_RBTREE_NULL) {
686 			return NULL;
687 		} else {
688 			next_name = (ldns_dnssec_name *)next_node->data;
689 			if (!next_name->is_glue) {
690 				done = true;
691 			} else {
692 				next_node = ldns_rbtree_next(next_node);
693 			}
694 		}
695 	}
696 	return next_node;
697 }
698 
699 ldns_status
700 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 	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 	if (soa && soa->rrs && soa->rrs->rr
719 			&& (ldns_rr_rdf(soa->rrs->rr, 6) != NULL)) {
720 		nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
721 	} else {
722 		nsec_ttl = LDNS_DEFAULT_TTL;
723 	}
724 
725 	first_node = ldns_dnssec_name_node_next_nonglue(
726 			       ldns_rbtree_first(zone->names));
727 	cur_node = first_node;
728 	if (cur_node) {
729 		next_node = ldns_dnssec_name_node_next_nonglue(
730 			           ldns_rbtree_next(cur_node));
731 	} else {
732 		next_node = NULL;
733 	}
734 
735 	while (cur_node && next_node) {
736 		cur_name = (ldns_dnssec_name *)cur_node->data;
737 		next_name = (ldns_dnssec_name *)next_node->data;
738 		nsec_rr = ldns_dnssec_create_nsec(cur_name,
739 		                                  next_name,
740 		                                  LDNS_RR_TYPE_NSEC);
741 		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
742 		if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
743 			ldns_rr_free(nsec_rr);
744 			return LDNS_STATUS_ERR;
745 		}
746 		ldns_rr_list_push_rr(new_rrs, nsec_rr);
747 		cur_node = next_node;
748 		if (cur_node) {
749 			next_node = ldns_dnssec_name_node_next_nonglue(
750                                ldns_rbtree_next(cur_node));
751 		}
752 	}
753 
754 	if (cur_node && !next_node) {
755 		cur_name = (ldns_dnssec_name *)cur_node->data;
756 		next_name = (ldns_dnssec_name *)first_node->data;
757 		nsec_rr = ldns_dnssec_create_nsec(cur_name,
758 		                                  next_name,
759 		                                  LDNS_RR_TYPE_NSEC);
760 		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
761 		if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
762 			ldns_rr_free(nsec_rr);
763 			return LDNS_STATUS_ERR;
764 		}
765 		ldns_rr_list_push_rr(new_rrs, nsec_rr);
766 	} else {
767 		printf("error\n");
768 	}
769 
770 	return LDNS_STATUS_OK;
771 }
772 
773 #ifdef HAVE_SSL
774 static void
775 ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
776 	(void) arg;
777 	LDNS_FREE(node);
778 }
779 
780 static ldns_status
781 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 	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 	if (!zone || !new_rrs || !zone->names) {
801 		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 	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 	if (soa && soa->rrs && soa->rrs->rr
813 			&& ldns_rr_rdf(soa->rrs->rr, 6) != NULL) {
814 		nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
815 	} else {
816 		nsec_ttl = LDNS_DEFAULT_TTL;
817 	}
818 
819 	if (zone->hashed_names) {
820 		ldns_traverse_postorder(zone->hashed_names,
821 				ldns_hashed_names_node_free, NULL);
822 		LDNS_FREE(zone->hashed_names);
823 	}
824 	zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
825 	if (zone->hashed_names && map) {
826 		*map = zone->hashed_names;
827 	}
828 
829 	first_name_node = ldns_dnssec_name_node_next_nonglue(
830 					  ldns_rbtree_first(zone->names));
831 
832 	current_name_node = first_name_node;
833 
834 	while (current_name_node && current_name_node != LDNS_RBTREE_NULL &&
835 			result == LDNS_STATUS_OK) {
836 
837 		current_name = (ldns_dnssec_name *) current_name_node->data;
838 		nsec_rr = ldns_dnssec_create_nsec3(current_name,
839 		                                   NULL,
840 		                                   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 		if (!current_name->rrsets) {
849 			ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
850 		}
851 		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
852 		result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
853 		ldns_rr_list_push_rr(new_rrs, nsec_rr);
854 		if (ldns_rr_owner(nsec_rr)) {
855 			hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
856 			if (hashmap_node == NULL) {
857 				return LDNS_STATUS_MEM_ERR;
858 			}
859 			current_name->hashed_name =
860 				ldns_dname_label(ldns_rr_owner(nsec_rr), 0);
861 
862 			if (current_name->hashed_name == NULL) {
863 				LDNS_FREE(hashmap_node);
864 				return LDNS_STATUS_MEM_ERR;
865 			}
866 			hashmap_node->key  = current_name->hashed_name;
867 			hashmap_node->data = current_name;
868 
869 			if (! ldns_rbtree_insert(zone->hashed_names
870 						, hashmap_node)) {
871 				LDNS_FREE(hashmap_node);
872 			}
873 		}
874 		current_name_node = ldns_dnssec_name_node_next_nonglue(
875 		                   ldns_rbtree_next(current_name_node));
876 	}
877 	if (result != LDNS_STATUS_OK) {
878 		return result;
879 	}
880 
881 	/* Make sorted list of nsec3s (via zone->hashed_names)
882 	 */
883 	nsec3_list = ldns_rr_list_new();
884 	if (nsec3_list == NULL) {
885 		return LDNS_STATUS_MEM_ERR;
886 	}
887 	for ( hashmap_node  = ldns_rbtree_first(zone->hashed_names)
888 	    ; hashmap_node != LDNS_RBTREE_NULL
889 	    ; hashmap_node  = ldns_rbtree_next(hashmap_node)
890 	    ) {
891 		current_name = (ldns_dnssec_name *) hashmap_node->data;
892 		nsec_rr = ((ldns_dnssec_name *) hashmap_node->data)->nsec;
893 		if (nsec_rr) {
894 			ldns_rr_list_push_rr(nsec3_list, nsec_rr);
895 		}
896 	}
897 	result = ldns_dnssec_chain_nsec3_list(nsec3_list);
898 	ldns_rr_list_free(nsec3_list);
899 
900 	return result;
901 }
902 
903 ldns_status
904 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 	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 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 	ldns_dnssec_rrs *base_rrs = signatures;
926 	ldns_dnssec_rrs *cur_rr = base_rrs;
927 	ldns_dnssec_rrs *prev_rr = NULL;
928 	ldns_dnssec_rrs *next_rr;
929 
930 	uint16_t keytag;
931 	size_t i;
932 
933 	if (!cur_rr) {
934 		switch(func(NULL, arg)) {
935 		case LDNS_SIGNATURE_LEAVE_ADD_NEW:
936 		case LDNS_SIGNATURE_REMOVE_ADD_NEW:
937 		break;
938 		case LDNS_SIGNATURE_LEAVE_NO_ADD:
939 		case LDNS_SIGNATURE_REMOVE_NO_ADD:
940 		ldns_key_list_set_use(key_list, false);
941 		break;
942 		default:
943 #ifdef STDERR_MSGS
944 			fprintf(stderr, "[XX] unknown return value from callback\n");
945 #endif
946 			break;
947 		}
948 		return NULL;
949 	}
950 	(void)func(cur_rr->rr, arg);
951 
952 	while (cur_rr) {
953 		next_rr = cur_rr->next;
954 
955 		switch (func(cur_rr->rr, arg)) {
956 		case  LDNS_SIGNATURE_LEAVE_ADD_NEW:
957 			prev_rr = cur_rr;
958 			break;
959 		case LDNS_SIGNATURE_LEAVE_NO_ADD:
960 			keytag = ldns_rdf2native_int16(
961 					   ldns_rr_rrsig_keytag(cur_rr->rr));
962 			for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
963 				if (ldns_key_keytag(ldns_key_list_key(key_list, i)) ==
964 				    keytag) {
965 					ldns_key_set_use(ldns_key_list_key(key_list, i),
966 								  false);
967 				}
968 			}
969 			prev_rr = cur_rr;
970 			break;
971 		case LDNS_SIGNATURE_REMOVE_NO_ADD:
972 			keytag = ldns_rdf2native_int16(
973 					   ldns_rr_rrsig_keytag(cur_rr->rr));
974 			for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
975 				if (ldns_key_keytag(ldns_key_list_key(key_list, i))
976 				    == keytag) {
977 					ldns_key_set_use(ldns_key_list_key(key_list, i),
978 								  false);
979 				}
980 			}
981 			if (prev_rr) {
982 				prev_rr->next = next_rr;
983 			} else {
984 				base_rrs = next_rr;
985 			}
986 			LDNS_FREE(cur_rr);
987 			break;
988 		case LDNS_SIGNATURE_REMOVE_ADD_NEW:
989 			if (prev_rr) {
990 				prev_rr->next = next_rr;
991 			} else {
992 				base_rrs = next_rr;
993 			}
994 			LDNS_FREE(cur_rr);
995 			break;
996 		default:
997 #ifdef STDERR_MSGS
998 			fprintf(stderr, "[XX] unknown return value from callback\n");
999 #endif
1000 			break;
1001 		}
1002 		cur_rr = next_rr;
1003 	}
1004 
1005 	return base_rrs;
1006 }
1007 
1008 #ifdef HAVE_SSL
1009 ldns_status
1010 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 	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 ldns_key_list_filter_for_dnskey(ldns_key_list *key_list)
1023 {
1024 	int saw_ksk = 0;
1025 	size_t i;
1026 	for(i=0; i<ldns_key_list_key_count(key_list); i++)
1027 		if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
1028 			saw_ksk = 1;
1029 			break;
1030 		}
1031 	if(!saw_ksk)
1032 		return;
1033 	for(i=0; i<ldns_key_list_key_count(key_list); i++)
1034 		if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
1035 			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 ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list)
1041 {
1042 	int saw_zsk = 0;
1043 	size_t i;
1044 	for(i=0; i<ldns_key_list_key_count(key_list); i++)
1045 		if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
1046 			saw_zsk = 1;
1047 			break;
1048 		}
1049 	if(!saw_zsk)
1050 		return;
1051 	/* else filter all KSKs */
1052 	for(i=0; i<ldns_key_list_key_count(key_list); i++)
1053 		if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
1054 			ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
1055 }
1056 
1057 ldns_status
1058 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 	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 	int on_delegation_point = 0; /* handle partially occluded names */
1080 
1081 	ldns_rr_list *pubkey_list = ldns_rr_list_new();
1082 	for (i = 0; i<ldns_key_list_key_count(key_list); i++) {
1083 		ldns_rr_list_push_rr( pubkey_list
1084 				    , 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 	cur_node = ldns_rbtree_first(zone->names);
1091 	while (cur_node != LDNS_RBTREE_NULL) {
1092 		cur_name = (ldns_dnssec_name *) cur_node->data;
1093 
1094 		if (!cur_name->is_glue) {
1095 			on_delegation_point = ldns_dnssec_rrsets_contains_type(
1096 					cur_name->rrsets, LDNS_RR_TYPE_NS)
1097 				&& !ldns_dnssec_rrsets_contains_type(
1098 					cur_name->rrsets, LDNS_RR_TYPE_SOA);
1099 			cur_rrset = cur_name->rrsets;
1100 			while (cur_rrset) {
1101 				/* reset keys to use */
1102 				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 				cur_rrset->signatures =
1107 					ldns_dnssec_remove_signatures(cur_rrset->signatures,
1108 											key_list,
1109 											func,
1110 											arg);
1111 				if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) &&
1112 					cur_rrset->type == LDNS_RR_TYPE_DNSKEY)
1113 					ldns_key_list_filter_for_dnskey(key_list);
1114 
1115 				if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY)
1116 					ldns_key_list_filter_for_non_dnskey(key_list);
1117 
1118 				/* TODO: just set count to zero? */
1119 				rr_list = ldns_rr_list_new();
1120 
1121 				cur_rr = cur_rrset->rrs;
1122 				while (cur_rr) {
1123 					ldns_rr_list_push_rr(rr_list, cur_rr->rr);
1124 					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 				if (!on_delegation_point ||
1131 						ldns_rr_list_type(rr_list)
1132 							== LDNS_RR_TYPE_DS ||
1133 						ldns_rr_list_type(rr_list)
1134 							== LDNS_RR_TYPE_NSEC ||
1135 						ldns_rr_list_type(rr_list)
1136 							== LDNS_RR_TYPE_NSEC3) {
1137 					siglist = ldns_sign_public(rr_list, key_list);
1138 					for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
1139 						if (cur_rrset->signatures) {
1140 							result = ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
1141 											   ldns_rr_list_rr(siglist,
1142 														    i));
1143 						} else {
1144 							cur_rrset->signatures = ldns_dnssec_rrs_new();
1145 							cur_rrset->signatures->rr =
1146 								ldns_rr_list_rr(siglist, i);
1147 						}
1148 						if (new_rrs) {
1149 							ldns_rr_list_push_rr(new_rrs,
1150 												 ldns_rr_list_rr(siglist,
1151 															  i));
1152 						}
1153 					}
1154 					ldns_rr_list_free(siglist);
1155 				}
1156 
1157 				ldns_rr_list_free(rr_list);
1158 
1159 				cur_rrset = cur_rrset->next;
1160 			}
1161 
1162 			/* sign the nsec */
1163 			ldns_key_list_set_use(key_list, true);
1164 			cur_name->nsec_signatures =
1165 				ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
1166 										key_list,
1167 										func,
1168 										arg);
1169 			ldns_key_list_filter_for_non_dnskey(key_list);
1170 
1171 			rr_list = ldns_rr_list_new();
1172 			ldns_rr_list_push_rr(rr_list, cur_name->nsec);
1173 			siglist = ldns_sign_public(rr_list, key_list);
1174 
1175 			for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
1176 				if (cur_name->nsec_signatures) {
1177 					result = ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
1178 									   ldns_rr_list_rr(siglist, i));
1179 				} else {
1180 					cur_name->nsec_signatures = ldns_dnssec_rrs_new();
1181 					cur_name->nsec_signatures->rr =
1182 						ldns_rr_list_rr(siglist, i);
1183 				}
1184 				if (new_rrs) {
1185 					ldns_rr_list_push_rr(new_rrs,
1186 								 ldns_rr_list_rr(siglist, i));
1187 				}
1188 			}
1189 
1190 			ldns_rr_list_free(siglist);
1191 			ldns_rr_list_free(rr_list);
1192 		}
1193 		cur_node = ldns_rbtree_next(cur_node);
1194 	}
1195 
1196 	ldns_rr_list_deep_free(pubkey_list);
1197 	return result;
1198 }
1199 
1200 ldns_status
1201 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 	return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0);
1208 }
1209 
1210 ldns_status
1211 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 	ldns_status result = LDNS_STATUS_OK;
1219 
1220 	if (!zone || !new_rrs || !key_list) {
1221 		return LDNS_STATUS_ERR;
1222 	}
1223 
1224 	/* zone is already sorted */
1225 	result = ldns_dnssec_zone_mark_glue(zone);
1226 	if (result != LDNS_STATUS_OK) {
1227 		return result;
1228 	}
1229 
1230 	/* check whether we need to add nsecs */
1231 	if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
1232 		result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
1233 		if (result != LDNS_STATUS_OK) {
1234 			return result;
1235 		}
1236 	}
1237 
1238 	result = ldns_dnssec_zone_create_rrsigs_flg(zone,
1239 					new_rrs,
1240 					key_list,
1241 					func,
1242 					arg,
1243 					flags);
1244 
1245 	return result;
1246 }
1247 
1248 ldns_status
1249 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 	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 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 	ldns_status result = LDNS_STATUS_OK;
1281 
1282 	/* zone is already sorted */
1283 	result = ldns_dnssec_zone_mark_glue(zone);
1284 	if (result != LDNS_STATUS_OK) {
1285 		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 	if (zone->names) {
1292 		/* add empty nonterminals */
1293 		result = ldns_dnssec_zone_add_empty_nonterminals(zone);
1294 		if (result != LDNS_STATUS_OK) {
1295 			return result;
1296 		}
1297 
1298 		nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec;
1299 		if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
1300 			/* no need to recreate */
1301 		} else {
1302 			if (!ldns_dnssec_zone_find_rrset(zone,
1303 									   zone->soa->name,
1304 									   LDNS_RR_TYPE_NSEC3PARAM)) {
1305 				/* create and add the nsec3param rr */
1306 				nsec3param =
1307 					ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAM);
1308 				ldns_rr_set_owner(nsec3param,
1309 							   ldns_rdf_clone(zone->soa->name));
1310 				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 				ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3param, 1)), 0, 0);
1320 				result = ldns_dnssec_zone_add_rr(zone, nsec3param);
1321 				if (result != LDNS_STATUS_OK) {
1322 					return result;
1323 				}
1324 				ldns_rr_list_push_rr(new_rrs, nsec3param);
1325 			}
1326 			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 			if (result != LDNS_STATUS_OK) {
1335 				return result;
1336 			}
1337 		}
1338 
1339 		result = ldns_dnssec_zone_create_rrsigs_flg(zone,
1340 						new_rrs,
1341 						key_list,
1342 						func,
1343 						arg,
1344 						signflags);
1345 	}
1346 
1347 	return result;
1348 }
1349 
1350 ldns_status
1351 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 	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 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 	signed_zone = ldns_zone_new();
1377 	dnssec_zone = ldns_dnssec_zone_new();
1378 
1379 	(void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
1380 	ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
1381 
1382 	for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
1383 		(void) ldns_dnssec_zone_add_rr(dnssec_zone,
1384 								 ldns_rr_list_rr(ldns_zone_rrs(zone),
1385 											  i));
1386 		ldns_zone_push_rr(signed_zone,
1387 					   ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
1388 											   i)));
1389 	}
1390 
1391 	new_rrs = ldns_rr_list_new();
1392 	(void) ldns_dnssec_zone_sign(dnssec_zone,
1393 						    new_rrs,
1394 						    key_list,
1395 						    ldns_dnssec_default_replace_signatures,
1396 						    NULL);
1397 
1398     	for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
1399 		ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
1400 						 ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
1401 	}
1402 
1403 	ldns_rr_list_deep_free(new_rrs);
1404 	ldns_dnssec_zone_free(dnssec_zone);
1405 
1406 	return signed_zone;
1407 }
1408 
1409 ldns_zone *
1410 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 	signed_zone = ldns_zone_new();
1418 	dnssec_zone = ldns_dnssec_zone_new();
1419 
1420 	(void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
1421 	ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
1422 
1423 	for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
1424 		(void) ldns_dnssec_zone_add_rr(dnssec_zone,
1425 								 ldns_rr_list_rr(ldns_zone_rrs(zone),
1426 											  i));
1427 		ldns_zone_push_rr(signed_zone,
1428 					   ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
1429 											   i)));
1430 	}
1431 
1432 	new_rrs = ldns_rr_list_new();
1433 	(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     	for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
1445 		ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
1446 						 ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
1447 	}
1448 
1449 	ldns_rr_list_deep_free(new_rrs);
1450 	ldns_dnssec_zone_free(dnssec_zone);
1451 
1452 	return signed_zone;
1453 }
1454 #endif /* HAVE_SSL */
1455 
1456 
1457