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