xref: /dragonfly/contrib/ldns/dnssec_sign.c (revision dcd37f7d)
1 #include <ldns/config.h>
2 
3 #include <ldns/ldns.h>
4 
5 #include <ldns/dnssec.h>
6 #include <ldns/dnssec_sign.h>
7 
8 #include <strings.h>
9 #include <time.h>
10 
11 #ifdef HAVE_SSL
12 /* this entire file is rather useless when you don't have
13  * crypto...
14  */
15 #include <openssl/ssl.h>
16 #include <openssl/evp.h>
17 #include <openssl/rand.h>
18 #include <openssl/err.h>
19 #include <openssl/md5.h>
20 #endif /* HAVE_SSL */
21 
22 ldns_rr *
23 ldns_create_empty_rrsig(ldns_rr_list *rrset,
24                         ldns_key *current_key)
25 {
26 	uint32_t orig_ttl;
27 	ldns_rr_class orig_class;
28 	time_t now;
29 	ldns_rr *current_sig;
30 	uint8_t label_count;
31 
32 	label_count = ldns_dname_label_count(ldns_rr_owner(ldns_rr_list_rr(rrset,
33 	                                                   0)));
34 
35 	current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
36 
37 	/* set the type on the new signature */
38 	orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
39 	orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0));
40 
41 	ldns_rr_set_ttl(current_sig, orig_ttl);
42 	ldns_rr_set_class(current_sig, orig_class);
43 	ldns_rr_set_owner(current_sig,
44 			  ldns_rdf_clone(
45 			       ldns_rr_owner(
46 				    ldns_rr_list_rr(rrset,
47 						    0))));
48 
49 	/* fill in what we know of the signature */
50 
51 	/* set the orig_ttl */
52 	(void)ldns_rr_rrsig_set_origttl(
53 		   current_sig,
54 		   ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
55 					 orig_ttl));
56 	/* the signers name */
57 	(void)ldns_rr_rrsig_set_signame(
58 			current_sig,
59 			ldns_rdf_clone(ldns_key_pubkey_owner(current_key)));
60 	/* label count - get it from the first rr in the rr_list */
61 	(void)ldns_rr_rrsig_set_labels(
62 			current_sig,
63 			ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
64 			                     label_count));
65 	/* inception, expiration */
66 	now = time(NULL);
67 	if (ldns_key_inception(current_key) != 0) {
68 		(void)ldns_rr_rrsig_set_inception(
69 				current_sig,
70 				ldns_native2rdf_int32(
71 				    LDNS_RDF_TYPE_TIME,
72 				    ldns_key_inception(current_key)));
73 	} else {
74 		(void)ldns_rr_rrsig_set_inception(
75 				current_sig,
76 				ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
77 	}
78 	if (ldns_key_expiration(current_key) != 0) {
79 		(void)ldns_rr_rrsig_set_expiration(
80 				current_sig,
81 				ldns_native2rdf_int32(
82 				    LDNS_RDF_TYPE_TIME,
83 				    ldns_key_expiration(current_key)));
84 	} else {
85 		(void)ldns_rr_rrsig_set_expiration(
86 			     current_sig,
87 				ldns_native2rdf_int32(
88 				    LDNS_RDF_TYPE_TIME,
89 				    now + LDNS_DEFAULT_EXP_TIME));
90 	}
91 
92 	(void)ldns_rr_rrsig_set_keytag(
93 		   current_sig,
94 		   ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
95 		                         ldns_key_keytag(current_key)));
96 
97 	(void)ldns_rr_rrsig_set_algorithm(
98 			current_sig,
99 			ldns_native2rdf_int8(
100 			    LDNS_RDF_TYPE_ALG,
101 			    ldns_key_algorithm(current_key)));
102 
103 	(void)ldns_rr_rrsig_set_typecovered(
104 			current_sig,
105 			ldns_native2rdf_int16(
106 			    LDNS_RDF_TYPE_TYPE,
107 			    ldns_rr_get_type(ldns_rr_list_rr(rrset,
108 			                                     0))));
109 	return current_sig;
110 }
111 
112 #ifdef HAVE_SSL
113 ldns_rdf *
114 ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
115 {
116 	ldns_rdf *b64rdf = NULL;
117 
118 	switch(ldns_key_algorithm(current_key)) {
119 	case LDNS_SIGN_DSA:
120 	case LDNS_DSA_NSEC3:
121 		b64rdf = ldns_sign_public_evp(
122 				   sign_buf,
123 				   ldns_key_evp_key(current_key),
124 				   EVP_dss1());
125 		break;
126 	case LDNS_SIGN_RSASHA1:
127 	case LDNS_SIGN_RSASHA1_NSEC3:
128 		b64rdf = ldns_sign_public_evp(
129 				   sign_buf,
130 				   ldns_key_evp_key(current_key),
131 				   EVP_sha1());
132 		break;
133 #ifdef USE_SHA2
134 	case LDNS_SIGN_RSASHA256:
135 		b64rdf = ldns_sign_public_evp(
136 				   sign_buf,
137 				   ldns_key_evp_key(current_key),
138 				   EVP_sha256());
139 		break;
140 	case LDNS_SIGN_RSASHA512:
141 		b64rdf = ldns_sign_public_evp(
142 				   sign_buf,
143 				   ldns_key_evp_key(current_key),
144 				   EVP_sha512());
145 		break;
146 #endif /* USE_SHA2 */
147 #ifdef USE_GOST
148 	case LDNS_SIGN_GOST:
149 		b64rdf = ldns_sign_public_evp(
150 				   sign_buf,
151 				   ldns_key_evp_key(current_key),
152 				   EVP_get_digestbyname("md_gost94"));
153 		break;
154 #endif /* USE_GOST */
155 	case LDNS_SIGN_RSAMD5:
156 		b64rdf = ldns_sign_public_evp(
157 				   sign_buf,
158 				   ldns_key_evp_key(current_key),
159 				   EVP_md5());
160 		break;
161 	default:
162 		/* do _you_ know this alg? */
163 		printf("unknown algorithm, ");
164 		printf("is the one used available on this system?\n");
165 		break;
166 	}
167 
168 	return b64rdf;
169 }
170 
171 /**
172  * use this function to sign with a public/private key alg
173  * return the created signatures
174  */
175 ldns_rr_list *
176 ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
177 {
178 	ldns_rr_list *signatures;
179 	ldns_rr_list *rrset_clone;
180 	ldns_rr *current_sig;
181 	ldns_rdf *b64rdf;
182 	ldns_key *current_key;
183 	size_t key_count;
184 	uint16_t i;
185 	ldns_buffer *sign_buf;
186 	ldns_rdf *new_owner;
187 
188 	if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
189 		return NULL;
190 	}
191 
192 	new_owner = NULL;
193 
194 	key_count = 0;
195 	signatures = ldns_rr_list_new();
196 
197 	/* prepare a signature and add all the know data
198 	 * prepare the rrset. Sign this together.  */
199 	rrset_clone = ldns_rr_list_clone(rrset);
200 	if (!rrset_clone) {
201 		return NULL;
202 	}
203 
204 	/* make it canonical */
205 	for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
206 		ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i),
207 			ldns_rr_ttl(ldns_rr_list_rr(rrset, 0)));
208 		ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
209 	}
210 	/* sort */
211 	ldns_rr_list_sort(rrset_clone);
212 
213 	for (key_count = 0;
214 		key_count < ldns_key_list_key_count(keys);
215 		key_count++) {
216 		if (!ldns_key_use(ldns_key_list_key(keys, key_count))) {
217 			continue;
218 		}
219 		sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
220 		if (!sign_buf) {
221 			ldns_rr_list_free(rrset_clone);
222 			ldns_rr_list_free(signatures);
223 			ldns_rdf_free(new_owner);
224 			return NULL;
225 		}
226 		b64rdf = NULL;
227 
228 		current_key = ldns_key_list_key(keys, key_count);
229 		/* sign all RRs with keys that have ZSKbit, !SEPbit.
230 		   sign DNSKEY RRs with keys that have ZSKbit&SEPbit */
231 		if (
232 		    ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY &&
233 		    (!(ldns_key_flags(current_key) & LDNS_KEY_SEP_KEY)
234 			|| ldns_rr_get_type(ldns_rr_list_rr(rrset, 0))
235 		        == LDNS_RR_TYPE_DNSKEY)
236 		    ) {
237 			current_sig = ldns_create_empty_rrsig(rrset_clone,
238 			                                      current_key);
239 
240 			/* right now, we have: a key, a semi-sig and an rrset. For
241 			 * which we can create the sig and base64 encode that and
242 			 * add that to the signature */
243 
244 			if (ldns_rrsig2buffer_wire(sign_buf, current_sig)
245 			    != LDNS_STATUS_OK) {
246 				ldns_buffer_free(sign_buf);
247 				/* ERROR */
248 				ldns_rr_list_deep_free(rrset_clone);
249 				return NULL;
250 			}
251 
252 			/* add the rrset in sign_buf */
253 			if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone)
254 			    != LDNS_STATUS_OK) {
255 				ldns_buffer_free(sign_buf);
256 				ldns_rr_list_deep_free(rrset_clone);
257 				return NULL;
258 			}
259 
260 			b64rdf = ldns_sign_public_buffer(sign_buf, current_key);
261 
262 			if (!b64rdf) {
263 				/* signing went wrong */
264 				ldns_rr_list_deep_free(rrset_clone);
265 				return NULL;
266 			}
267 
268 			ldns_rr_rrsig_set_sig(current_sig, b64rdf);
269 
270 			/* push the signature to the signatures list */
271 			ldns_rr_list_push_rr(signatures, current_sig);
272 		}
273 		ldns_buffer_free(sign_buf); /* restart for the next key */
274 	}
275 	ldns_rr_list_deep_free(rrset_clone);
276 
277 	return signatures;
278 }
279 
280 /**
281  * Sign data with DSA
282  *
283  * \param[in] to_sign The ldns_buffer containing raw data that is
284  *                    to be signed
285  * \param[in] key The DSA key structure to sign with
286  * \return ldns_rdf for the RRSIG ldns_rr
287  */
288 ldns_rdf *
289 ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
290 {
291 	unsigned char *sha1_hash;
292 	ldns_rdf *sigdata_rdf;
293 	ldns_buffer *b64sig;
294 
295 	DSA_SIG *sig;
296 	uint8_t *data;
297 	size_t pad;
298 
299 	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
300 	if (!b64sig) {
301 		return NULL;
302 	}
303 
304 	sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
305 				  ldns_buffer_position(to_sign), NULL);
306 	if (!sha1_hash) {
307 		ldns_buffer_free(b64sig);
308 		return NULL;
309 	}
310 
311 
312 	sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
313 
314 	data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
315 
316 	data[0] = 1;
317 	pad = 20 - (size_t) BN_num_bytes(sig->r);
318 	if (pad > 0) {
319 		memset(data + 1, 0, pad);
320 	}
321 	BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad);
322 
323 	pad = 20 - (size_t) BN_num_bytes(sig->s);
324 	if (pad > 0) {
325 		memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
326 	}
327 	BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
328 
329 	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
330 								 1 + 2 * SHA_DIGEST_LENGTH,
331 								 data);
332 
333 	ldns_buffer_free(b64sig);
334 	LDNS_FREE(data);
335 
336 	return sigdata_rdf;
337 }
338 
339 ldns_rdf *
340 ldns_sign_public_evp(ldns_buffer *to_sign,
341 				 EVP_PKEY *key,
342 				 const EVP_MD *digest_type)
343 {
344 	unsigned int siglen;
345 	ldns_rdf *sigdata_rdf;
346 	ldns_buffer *b64sig;
347 	EVP_MD_CTX ctx;
348 	const EVP_MD *md_type;
349 	int r;
350 
351 	siglen = 0;
352 	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
353 	if (!b64sig) {
354 		return NULL;
355 	}
356 
357 	/* initializes a signing context */
358 	md_type = digest_type;
359 	if(!md_type) {
360 		/* unknown message difest */
361 		ldns_buffer_free(b64sig);
362 		return NULL;
363 	}
364 
365 	EVP_MD_CTX_init(&ctx);
366 	r = EVP_SignInit(&ctx, md_type);
367 	if(r == 1) {
368 		r = EVP_SignUpdate(&ctx, (unsigned char*)
369 					    ldns_buffer_begin(to_sign),
370 					    ldns_buffer_position(to_sign));
371 	} else {
372 		ldns_buffer_free(b64sig);
373 		return NULL;
374 	}
375 	if(r == 1) {
376 		r = EVP_SignFinal(&ctx, (unsigned char*)
377 					   ldns_buffer_begin(b64sig), &siglen, key);
378 	} else {
379 		ldns_buffer_free(b64sig);
380 		return NULL;
381 	}
382 	if(r != 1) {
383 		ldns_buffer_free(b64sig);
384 		return NULL;
385 	}
386 
387 	/* unfortunately, OpenSSL output is differenct from DNS DSA format */
388 	if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
389 		sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
390 	} else {
391 		/* ok output for other types is the same */
392 		sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
393 									 ldns_buffer_begin(b64sig));
394 	}
395 	ldns_buffer_free(b64sig);
396 	EVP_MD_CTX_cleanup(&ctx);
397 	return sigdata_rdf;
398 }
399 
400 ldns_rdf *
401 ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
402 {
403 	unsigned char *sha1_hash;
404 	unsigned int siglen;
405 	ldns_rdf *sigdata_rdf;
406 	ldns_buffer *b64sig;
407 	int result;
408 
409 	siglen = 0;
410 	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
411 	if (!b64sig) {
412 		return NULL;
413 	}
414 
415 	sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
416 				  ldns_buffer_position(to_sign), NULL);
417 	if (!sha1_hash) {
418 		ldns_buffer_free(b64sig);
419 		return NULL;
420 	}
421 
422 	result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH,
423 				   (unsigned char*)ldns_buffer_begin(b64sig),
424 				   &siglen, key);
425 	if (result != 1) {
426 		return NULL;
427 	}
428 
429 	if (result != 1) {
430 		return NULL;
431 	}
432 
433 	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
434 								 ldns_buffer_begin(b64sig));
435 	ldns_buffer_free(b64sig); /* can't free this buffer ?? */
436 	return sigdata_rdf;
437 }
438 
439 ldns_rdf *
440 ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
441 {
442 	unsigned char *md5_hash;
443 	unsigned int siglen;
444 	ldns_rdf *sigdata_rdf;
445 	ldns_buffer *b64sig;
446 
447 	b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
448 	if (!b64sig) {
449 		return NULL;
450 	}
451 
452 	md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
453 				ldns_buffer_position(to_sign), NULL);
454 	if (!md5_hash) {
455 		ldns_buffer_free(b64sig);
456 		return NULL;
457 	}
458 
459 	RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH,
460 		    (unsigned char*)ldns_buffer_begin(b64sig),
461 		    &siglen, key);
462 
463 	sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
464 								 ldns_buffer_begin(b64sig));
465 	ldns_buffer_free(b64sig);
466 	return sigdata_rdf;
467 }
468 #endif /* HAVE_SSL */
469 
470 static int
471 ldns_dnssec_name_has_only_a(ldns_dnssec_name *cur_name)
472 {
473 	ldns_dnssec_rrsets *cur_rrset;
474 	cur_rrset = cur_name->rrsets;
475 	while (cur_rrset) {
476 		if (cur_rrset->type != LDNS_RR_TYPE_A &&
477 			cur_rrset->type != LDNS_RR_TYPE_AAAA) {
478 			return 0;
479 		} else {
480 			cur_rrset = cur_rrset->next;
481 		}
482 	}
483 	return 1;
484 }
485 
486 ldns_status
487 ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
488 {
489 	ldns_rbnode_t *cur_node;
490 	ldns_dnssec_name *cur_name;
491 	ldns_rdf *cur_owner, *cur_parent;
492 
493 	cur_node = ldns_rbtree_first(zone->names);
494 	while (cur_node != LDNS_RBTREE_NULL) {
495 		cur_name = (ldns_dnssec_name *) cur_node->data;
496 		cur_node = ldns_rbtree_next(cur_node);
497 		if (ldns_dnssec_name_has_only_a(cur_name)) {
498 			/* assume glue XXX check for zone cur */
499 			cur_owner = ldns_rdf_clone(ldns_rr_owner(
500 					      cur_name->rrsets->rrs->rr));
501 			while (ldns_dname_label_count(cur_owner) >
502 				  ldns_dname_label_count(zone->soa->name)) {
503 				if (ldns_dnssec_zone_find_rrset(zone,
504 										  cur_owner,
505 										  LDNS_RR_TYPE_NS)) {
506 					/*
507 					fprintf(stderr, "[XX] Marking as glue: ");
508 					ldns_rdf_print(stderr, cur_name->name);
509 					fprintf(stderr, "\n");
510 					*/
511 					cur_name->is_glue = true;
512 				}
513 				cur_parent = ldns_dname_left_chop(cur_owner);
514 				ldns_rdf_deep_free(cur_owner);
515 				cur_owner = cur_parent;
516 			}
517 			ldns_rdf_deep_free(cur_owner);
518 		}
519 	}
520 	return LDNS_STATUS_OK;
521 }
522 
523 ldns_rbnode_t *
524 ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
525 {
526 	ldns_rbnode_t *next_node = NULL;
527 	ldns_dnssec_name *next_name = NULL;
528 	bool done = false;
529 
530 	if (node == LDNS_RBTREE_NULL) {
531 		return NULL;
532 	}
533 	next_node = node;
534 	while (!done) {
535 		if (next_node == LDNS_RBTREE_NULL) {
536 			return NULL;
537 		} else {
538 			next_name = (ldns_dnssec_name *)next_node->data;
539 			if (!next_name->is_glue) {
540 				done = true;
541 			} else {
542 				next_node = ldns_rbtree_next(next_node);
543 			}
544 		}
545 	}
546 	return next_node;
547 }
548 
549 ldns_status
550 ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
551                               ldns_rr_list *new_rrs)
552 {
553 
554 	ldns_rbnode_t *first_node, *cur_node, *next_node;
555 	ldns_dnssec_name *cur_name, *next_name;
556 	ldns_rr *nsec_rr;
557 	uint32_t nsec_ttl;
558 	ldns_dnssec_rrsets *soa;
559 
560 	/* the TTL of NSEC rrs should be set to the minimum TTL of
561 	 * the zone SOA (RFC4035 Section 2.3)
562 	 */
563 	soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
564 
565 	/* did the caller actually set it? if not,
566 	 * fall back to default ttl
567 	 */
568 	if (soa && soa->rrs && soa->rrs->rr) {
569 		nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(
570 		                                     soa->rrs->rr, 6));
571 	} else {
572 		nsec_ttl = LDNS_DEFAULT_TTL;
573 	}
574 
575 	first_node = ldns_dnssec_name_node_next_nonglue(
576 			       ldns_rbtree_first(zone->names));
577 	cur_node = first_node;
578 	if (cur_node) {
579 		next_node = ldns_dnssec_name_node_next_nonglue(
580 			           ldns_rbtree_next(cur_node));
581 	} else {
582 		next_node = NULL;
583 	}
584 
585 	while (cur_node && next_node) {
586 		cur_name = (ldns_dnssec_name *)cur_node->data;
587 		next_name = (ldns_dnssec_name *)next_node->data;
588 		nsec_rr = ldns_dnssec_create_nsec(cur_name,
589 		                                  next_name,
590 		                                  LDNS_RR_TYPE_NSEC);
591 		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
592 		ldns_dnssec_name_add_rr(cur_name, nsec_rr);
593 		ldns_rr_list_push_rr(new_rrs, nsec_rr);
594 		cur_node = next_node;
595 		if (cur_node) {
596 			next_node = ldns_dnssec_name_node_next_nonglue(
597                                ldns_rbtree_next(cur_node));
598 		}
599 	}
600 
601 	if (cur_node && !next_node) {
602 		cur_name = (ldns_dnssec_name *)cur_node->data;
603 		next_name = (ldns_dnssec_name *)first_node->data;
604 		nsec_rr = ldns_dnssec_create_nsec(cur_name,
605 		                                  next_name,
606 		                                  LDNS_RR_TYPE_NSEC);
607 		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
608 		ldns_dnssec_name_add_rr(cur_name, nsec_rr);
609 		ldns_rr_list_push_rr(new_rrs, nsec_rr);
610 	} else {
611 		printf("error\n");
612 	}
613 
614 	return LDNS_STATUS_OK;
615 }
616 
617 #ifdef HAVE_SSL
618 ldns_status
619 ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
620 						 ldns_rr_list *new_rrs,
621 						 uint8_t algorithm,
622 						 uint8_t flags,
623 						 uint16_t iterations,
624 						 uint8_t salt_length,
625 						 uint8_t *salt)
626 {
627 	ldns_rbnode_t *first_name_node;
628 	ldns_rbnode_t *current_name_node;
629 	ldns_dnssec_name *current_name;
630 	ldns_status result = LDNS_STATUS_OK;
631 	ldns_rr *nsec_rr;
632 	ldns_rr_list *nsec3_list;
633 	uint32_t nsec_ttl;
634 	ldns_dnssec_rrsets *soa;
635 
636 	if (!zone || !new_rrs || !zone->names) {
637 		return LDNS_STATUS_ERR;
638 	}
639 
640 	/* the TTL of NSEC rrs should be set to the minimum TTL of
641 	 * the zone SOA (RFC4035 Section 2.3)
642 	 */
643 	soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
644 
645 	/* did the caller actually set it? if not,
646 	 * fall back to default ttl
647 	 */
648 	if (soa && soa->rrs && soa->rrs->rr) {
649 		nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(
650 		                                     soa->rrs->rr, 6));
651 	} else {
652 		nsec_ttl = LDNS_DEFAULT_TTL;
653 	}
654 
655 	nsec3_list = ldns_rr_list_new();
656 
657 	first_name_node = ldns_dnssec_name_node_next_nonglue(
658 					  ldns_rbtree_first(zone->names));
659 
660 	current_name_node = first_name_node;
661 
662 	while (current_name_node &&
663 	       current_name_node != LDNS_RBTREE_NULL) {
664 		current_name = (ldns_dnssec_name *) current_name_node->data;
665 		nsec_rr = ldns_dnssec_create_nsec3(current_name,
666 		                                   NULL,
667 		                                   zone->soa->name,
668 		                                   algorithm,
669 		                                   flags,
670 		                                   iterations,
671 		                                   salt_length,
672 		                                   salt);
673 		/* by default, our nsec based generator adds rrsigs
674 		 * remove the bitmap for empty nonterminals */
675 		if (!current_name->rrsets) {
676 			ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
677 		}
678 		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
679 		ldns_dnssec_name_add_rr(current_name, nsec_rr);
680 		ldns_rr_list_push_rr(new_rrs, nsec_rr);
681 		ldns_rr_list_push_rr(nsec3_list, nsec_rr);
682 		current_name_node = ldns_dnssec_name_node_next_nonglue(
683 		                   ldns_rbtree_next(current_name_node));
684 	}
685 
686 	ldns_rr_list_sort_nsec3(nsec3_list);
687 	ldns_dnssec_chain_nsec3_list(nsec3_list);
688 	if (result != LDNS_STATUS_OK) {
689 		return result;
690 	}
691 
692 	ldns_rr_list_free(nsec3_list);
693 	return result;
694 }
695 #endif /* HAVE_SSL */
696 
697 ldns_dnssec_rrs *
698 ldns_dnssec_remove_signatures(ldns_dnssec_rrs *signatures,
699 						ldns_key_list *key_list,
700 						int (*func)(ldns_rr *, void *),
701 						void *arg)
702 {
703 	ldns_dnssec_rrs *base_rrs = signatures;
704 	ldns_dnssec_rrs *cur_rr = base_rrs;
705 	ldns_dnssec_rrs *prev_rr = NULL;
706 	ldns_dnssec_rrs *next_rr;
707 
708 	uint16_t keytag;
709 	size_t i;
710 	int v;
711 
712 	key_list = key_list;
713 
714 	if (!cur_rr) {
715 		switch(func(NULL, arg)) {
716 		case LDNS_SIGNATURE_LEAVE_ADD_NEW:
717 		case LDNS_SIGNATURE_REMOVE_ADD_NEW:
718 		break;
719 		case LDNS_SIGNATURE_LEAVE_NO_ADD:
720 		case LDNS_SIGNATURE_REMOVE_NO_ADD:
721 		ldns_key_list_set_use(key_list, false);
722 		break;
723 		default:
724 			fprintf(stderr, "[XX] unknown return value from callback\n");
725 			break;
726 		}
727 		return NULL;
728 	}
729 	v = func(cur_rr->rr, arg);
730 
731 	while (cur_rr) {
732 		next_rr = cur_rr->next;
733 
734 		switch (func(cur_rr->rr, arg)) {
735 		case  LDNS_SIGNATURE_LEAVE_ADD_NEW:
736 			prev_rr = cur_rr;
737 			break;
738 		case LDNS_SIGNATURE_LEAVE_NO_ADD:
739 			keytag = ldns_rdf2native_int16(
740 					   ldns_rr_rrsig_keytag(cur_rr->rr));
741 			for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
742 				if (ldns_key_keytag(ldns_key_list_key(key_list, i)) ==
743 				    keytag) {
744 					ldns_key_set_use(ldns_key_list_key(key_list, i),
745 								  false);
746 				}
747 			}
748 			prev_rr = cur_rr;
749 			break;
750 		case LDNS_SIGNATURE_REMOVE_NO_ADD:
751 			keytag = ldns_rdf2native_int16(
752 					   ldns_rr_rrsig_keytag(cur_rr->rr));
753 			for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
754 				if (ldns_key_keytag(ldns_key_list_key(key_list, i))
755 				    == keytag) {
756 					ldns_key_set_use(ldns_key_list_key(key_list, i),
757 								  false);
758 				}
759 			}
760 			if (prev_rr) {
761 				prev_rr->next = next_rr;
762 			} else {
763 				base_rrs = next_rr;
764 			}
765 			LDNS_FREE(cur_rr);
766 			break;
767 		case LDNS_SIGNATURE_REMOVE_ADD_NEW:
768 			if (prev_rr) {
769 				prev_rr->next = next_rr;
770 			} else {
771 				base_rrs = next_rr;
772 			}
773 			LDNS_FREE(cur_rr);
774 			break;
775 		default:
776 			fprintf(stderr, "[XX] unknown return value from callback\n");
777 			break;
778 		}
779 		cur_rr = next_rr;
780 	}
781 
782 	return base_rrs;
783 }
784 
785 #ifdef HAVE_SSL
786 ldns_status
787 ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
788                                ldns_rr_list *new_rrs,
789                                ldns_key_list *key_list,
790                                int (*func)(ldns_rr *, void*),
791                                void *arg)
792 {
793 	return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list,
794 		func, arg, 0);
795 }
796 
797 /** If there are KSKs use only them and mark ZSKs unused */
798 static void
799 ldns_key_list_filter_for_dnskey(ldns_key_list *key_list)
800 {
801 	int saw_ksk = 0;
802 	size_t i;
803 	for(i=0; i<ldns_key_list_key_count(key_list); i++)
804 		if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
805 			saw_ksk = 1;
806 			break;
807 		}
808 	if(!saw_ksk)
809 		return;
810 	for(i=0; i<ldns_key_list_key_count(key_list); i++)
811 		if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
812 			ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
813 }
814 
815 ldns_status
816 ldns_dnssec_zone_create_rrsigs_flg(ldns_dnssec_zone *zone,
817                                ldns_rr_list *new_rrs,
818                                ldns_key_list *key_list,
819                                int (*func)(ldns_rr *, void*),
820                                void *arg,
821 			       int flags)
822 {
823 	ldns_status result = LDNS_STATUS_OK;
824 
825 	ldns_rbnode_t *cur_node;
826 	ldns_rr_list *rr_list;
827 
828 	ldns_dnssec_name *cur_name;
829 	ldns_dnssec_rrsets *cur_rrset;
830 	ldns_dnssec_rrs *cur_rr;
831 
832 	ldns_rr_list *siglist;
833 
834 	size_t i;
835 
836 	ldns_rr_list *pubkey_list = ldns_rr_list_new();
837 	zone = zone;
838 	new_rrs = new_rrs;
839 	key_list = key_list;
840 	for (i = 0; i<ldns_key_list_key_count(key_list); i++) {
841 		ldns_rr_list_push_rr(pubkey_list,
842 						 ldns_key2rr(ldns_key_list_key(key_list, i)));
843 	}
844 	/* TODO: callback to see is list should be signed */
845 	/* TODO: remove 'old' signatures from signature list */
846 	cur_node = ldns_rbtree_first(zone->names);
847 	while (cur_node != LDNS_RBTREE_NULL) {
848 		cur_name = (ldns_dnssec_name *) cur_node->data;
849 
850 		if (!cur_name->is_glue) {
851 			cur_rrset = cur_name->rrsets;
852 			while (cur_rrset) {
853 				/* reset keys to use */
854 				ldns_key_list_set_use(key_list, true);
855 
856 				/* walk through old sigs, remove the old,
857 				   and mark which keys (not) to use) */
858 				cur_rrset->signatures =
859 					ldns_dnssec_remove_signatures(cur_rrset->signatures,
860 											key_list,
861 											func,
862 											arg);
863 				if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) &&
864 					cur_rrset->type == LDNS_RR_TYPE_DNSKEY)
865 					ldns_key_list_filter_for_dnskey(key_list);
866 
867 				/* TODO: just set count to zero? */
868 				rr_list = ldns_rr_list_new();
869 
870 				cur_rr = cur_rrset->rrs;
871 				while (cur_rr) {
872 					ldns_rr_list_push_rr(rr_list, cur_rr->rr);
873 					cur_rr = cur_rr->next;
874 				}
875 
876 				/* only sign non-delegation RRsets */
877 				/* (glue should have been marked earlier) */
878 				if ((ldns_rr_list_type(rr_list) != LDNS_RR_TYPE_NS ||
879 					ldns_dname_compare(ldns_rr_list_owner(rr_list),
880 					zone->soa->name) == 0) &&
881 					/* OK, there is also the possibility that the record
882 					 * is glue, but at the same owner name as other records that
883 					 * are not NS nor A/AAAA. Bleh, our current data structure
884 					 * doesn't really support that... */
885 					!((ldns_rr_list_type(rr_list) == LDNS_RR_TYPE_A ||
886 					 ldns_rr_list_type(rr_list) == LDNS_RR_TYPE_AAAA) &&
887 					 !ldns_dname_compare(ldns_rr_list_owner(rr_list), zone->soa->name) == 0 &&
888 					 ldns_dnssec_zone_find_rrset(zone, ldns_rr_list_owner(rr_list), LDNS_RR_TYPE_NS)
889 					 )) {
890 
891 					siglist = ldns_sign_public(rr_list, key_list);
892 					for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
893 						if (cur_rrset->signatures) {
894 							ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
895 											   ldns_rr_list_rr(siglist,
896 														    i));
897 						} else {
898 							cur_rrset->signatures = ldns_dnssec_rrs_new();
899 							cur_rrset->signatures->rr =
900 								ldns_rr_list_rr(siglist, i);
901 							ldns_rr_list_push_rr(new_rrs,
902 											 ldns_rr_list_rr(siglist,
903 														  i));
904 						}
905 					}
906 					ldns_rr_list_free(siglist);
907 				}
908 
909 				ldns_rr_list_free(rr_list);
910 
911 				cur_rrset = cur_rrset->next;
912 			}
913 
914 			/* sign the nsec */
915 			cur_name->nsec_signatures =
916 				ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
917 										key_list,
918 										func,
919 										arg);
920 
921 			rr_list = ldns_rr_list_new();
922 			ldns_rr_list_push_rr(rr_list, cur_name->nsec);
923 			siglist = ldns_sign_public(rr_list, key_list);
924 
925 			for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
926 				if (cur_name->nsec_signatures) {
927 					ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
928 									   ldns_rr_list_rr(siglist, i));
929 				} else {
930 					cur_name->nsec_signatures = ldns_dnssec_rrs_new();
931 					cur_name->nsec_signatures->rr =
932 						ldns_rr_list_rr(siglist, i);
933 					ldns_rr_list_push_rr(new_rrs,
934 									 ldns_rr_list_rr(siglist, i));
935 				}
936 			}
937 
938 			ldns_rr_list_free(siglist);
939 			ldns_rr_list_free(rr_list);
940 		}
941 		cur_node = ldns_rbtree_next(cur_node);
942 	}
943 
944 	ldns_rr_list_deep_free(pubkey_list);
945 	return result;
946 }
947 
948 ldns_status
949 ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
950 				  ldns_rr_list *new_rrs,
951 				  ldns_key_list *key_list,
952 				  int (*func)(ldns_rr *, void *),
953 				  void *arg)
954 {
955 	return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0);
956 }
957 
958 ldns_status
959 ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
960 				  ldns_rr_list *new_rrs,
961 				  ldns_key_list *key_list,
962 				  int (*func)(ldns_rr *, void *),
963 				  void *arg,
964 				  int flags)
965 {
966 	ldns_status result = LDNS_STATUS_OK;
967 
968 	if (!zone || !new_rrs || !key_list) {
969 		return LDNS_STATUS_ERR;
970 	}
971 
972 	/* zone is already sorted */
973 	ldns_dnssec_zone_mark_glue(zone);
974 
975 	/* check whether we need to add nsecs */
976 	if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
977 		result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
978 		if (result != LDNS_STATUS_OK) {
979 			return result;
980 		}
981 	}
982 
983 	result = ldns_dnssec_zone_create_rrsigs_flg(zone,
984 					new_rrs,
985 					key_list,
986 					func,
987 					arg,
988 					flags);
989 
990 	return result;
991 }
992 
993 ldns_status
994 ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
995 					   ldns_rr_list *new_rrs,
996 					   ldns_key_list *key_list,
997 					   int (*func)(ldns_rr *, void *),
998 					   void *arg,
999 					   uint8_t algorithm,
1000 					   uint8_t flags,
1001 					   uint16_t iterations,
1002 					   uint8_t salt_length,
1003 					   uint8_t *salt)
1004 {
1005 	return ldns_dnssec_zone_sign_nsec3_flg(zone, new_rrs, key_list,
1006 		func, arg, algorithm, flags, iterations, salt_length, salt, 0);
1007 }
1008 
1009 ldns_status
1010 ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
1011 					   ldns_rr_list *new_rrs,
1012 					   ldns_key_list *key_list,
1013 					   int (*func)(ldns_rr *, void *),
1014 					   void *arg,
1015 					   uint8_t algorithm,
1016 					   uint8_t flags,
1017 					   uint16_t iterations,
1018 					   uint8_t salt_length,
1019 					   uint8_t *salt,
1020 					   int signflags)
1021 {
1022 	ldns_rr *nsec3, *nsec3params;
1023 	ldns_status result = LDNS_STATUS_OK;
1024 
1025 	/* zone is already sorted */
1026 	ldns_dnssec_zone_mark_glue(zone);
1027 
1028 	/* TODO if there are already nsec3s presents and their
1029 	 * parameters are the same as these, we don't have to recreate
1030 	 */
1031 	if (zone->names) {
1032 		/* add empty nonterminals */
1033 		ldns_dnssec_zone_add_empty_nonterminals(zone);
1034 
1035 		nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec;
1036 		if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
1037 			/* no need to recreate */
1038 		} else {
1039 			if (!ldns_dnssec_zone_find_rrset(zone,
1040 									   zone->soa->name,
1041 									   LDNS_RR_TYPE_NSEC3PARAMS)) {
1042 				/* create and add the nsec3params rr */
1043 				nsec3params =
1044 					ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAMS);
1045 				ldns_rr_set_owner(nsec3params,
1046 							   ldns_rdf_clone(zone->soa->name));
1047 				ldns_nsec3_add_param_rdfs(nsec3params,
1048 									 algorithm,
1049 									 flags,
1050 									 iterations,
1051 									 salt_length,
1052 									 salt);
1053 				/* always set bit 7 of the flags to zero, according to
1054 				 * rfc5155 section 11 */
1055 				ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3params, 1)), 7, 0);
1056 				ldns_dnssec_zone_add_rr(zone, nsec3params);
1057 				ldns_rr_list_push_rr(new_rrs, nsec3params);
1058 			}
1059 			result = ldns_dnssec_zone_create_nsec3s(zone,
1060 											new_rrs,
1061 											algorithm,
1062 											flags,
1063 											iterations,
1064 											salt_length,
1065 											salt);
1066 			if (result != LDNS_STATUS_OK) {
1067 				return result;
1068 			}
1069 		}
1070 
1071 		result = ldns_dnssec_zone_create_rrsigs_flg(zone,
1072 						new_rrs,
1073 						key_list,
1074 						func,
1075 						arg,
1076 						signflags);
1077 	}
1078 
1079 	return result;
1080 }
1081 
1082 
1083 ldns_zone *
1084 ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
1085 {
1086 	ldns_dnssec_zone *dnssec_zone;
1087 	ldns_zone *signed_zone;
1088 	ldns_rr_list *new_rrs;
1089 	size_t i;
1090 
1091 	signed_zone = ldns_zone_new();
1092 	dnssec_zone = ldns_dnssec_zone_new();
1093 
1094 	(void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
1095 	ldns_zone_set_soa(signed_zone, ldns_zone_soa(zone));
1096 
1097 	for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
1098 		(void) ldns_dnssec_zone_add_rr(dnssec_zone,
1099 								 ldns_rr_list_rr(ldns_zone_rrs(zone),
1100 											  i));
1101 		ldns_zone_push_rr(signed_zone,
1102 					   ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
1103 											   i)));
1104 	}
1105 
1106 	new_rrs = ldns_rr_list_new();
1107 	(void) ldns_dnssec_zone_sign(dnssec_zone,
1108 						    new_rrs,
1109 						    key_list,
1110 						    ldns_dnssec_default_replace_signatures,
1111 						    NULL);
1112 
1113     	for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
1114 		ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
1115 						 ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
1116 	}
1117 
1118 	ldns_rr_list_deep_free(new_rrs);
1119 	ldns_dnssec_zone_free(dnssec_zone);
1120 
1121 	return signed_zone;
1122 }
1123 
1124 ldns_zone *
1125 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)
1126 {
1127 	ldns_dnssec_zone *dnssec_zone;
1128 	ldns_zone *signed_zone;
1129 	ldns_rr_list *new_rrs;
1130 	size_t i;
1131 
1132 	signed_zone = ldns_zone_new();
1133 	dnssec_zone = ldns_dnssec_zone_new();
1134 
1135 	(void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
1136 	ldns_zone_set_soa(signed_zone, ldns_zone_soa(zone));
1137 
1138 	for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
1139 		(void) ldns_dnssec_zone_add_rr(dnssec_zone,
1140 								 ldns_rr_list_rr(ldns_zone_rrs(zone),
1141 											  i));
1142 		ldns_zone_push_rr(signed_zone,
1143 					   ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
1144 											   i)));
1145 	}
1146 
1147 	new_rrs = ldns_rr_list_new();
1148 	(void) ldns_dnssec_zone_sign_nsec3(dnssec_zone,
1149 								new_rrs,
1150 								key_list,
1151 								ldns_dnssec_default_replace_signatures,
1152 								NULL,
1153 								algorithm,
1154 								flags,
1155 								iterations,
1156 								salt_length,
1157 								salt);
1158 
1159     	for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
1160 		ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
1161 						 ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
1162 	}
1163 
1164 	ldns_rr_list_deep_free(new_rrs);
1165 	ldns_dnssec_zone_free(dnssec_zone);
1166 
1167 	return signed_zone;
1168 }
1169 #endif /* HAVE_SSL */
1170 
1171