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