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