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