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