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