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