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