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