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