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