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