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