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