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