Developer Area

root/apps/iphone/sampleTelApp/trunk/DotTel_SDK/ldns_sources/dnssec_sign.c @ 913

Revision 82, 23.5 kB (checked in by henri, 6 years ago)

Added the iPhone sampleTelApp

Line 
1#include "ldns/config.h"
2#include "ldns.h"
3
4
5#include <strings.h>
6#include <time.h>
7
8#ifdef HAVE_SSL
9/* this entire file is rather useless when you don't have
10 * crypto...
11 */
12#include <openssl/ssl.h>
13#include <openssl/evp.h>
14#include <openssl/rand.h>
15#include <openssl/err.h>
16#include <openssl/md5.h>
17
18
19/**
20 * use this function to sign with a public/private key alg
21 * return the created signatures
22 */
23ldns_rr_list *
24ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
25{
26        ldns_rr_list *signatures;
27        ldns_rr_list *rrset_clone;
28        ldns_rr *current_sig;
29        ldns_rdf *b64rdf;
30        ldns_key *current_key;
31        size_t key_count;
32        uint16_t i;
33        ldns_buffer *sign_buf;
34        uint32_t orig_ttl;
35        time_t now;
36        uint8_t label_count;
37        ldns_rdf *first_label;
38        ldns_rdf *wildcard_label;
39        ldns_rdf *new_owner;
40
41        if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
42                return NULL;
43        }
44
45        key_count = 0;
46        signatures = ldns_rr_list_new();
47
48        /* prepare a signature and add all the know data
49         * prepare the rrset. Sign this together.  */
50        rrset_clone = ldns_rr_list_clone(rrset);
51        if (!rrset_clone) {
52                return NULL;
53        }
54
55        /* check for label count and wildcard */
56        label_count = ldns_dname_label_count(ldns_rr_owner(ldns_rr_list_rr(rrset,
57                                                                                                                  0)));
58        (void) ldns_str2rdf_dname(&wildcard_label, "*");
59        first_label = ldns_dname_label(ldns_rr_owner(ldns_rr_list_rr(rrset, 0)),
60                                                         0);
61        if (ldns_rdf_compare(first_label, wildcard_label) == 0) {
62                label_count--;
63                for (i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
64                        new_owner = ldns_dname_cat_clone(
65                                                 wildcard_label, 
66                                                 ldns_dname_left_chop(
67                                                        ldns_rr_owner(ldns_rr_list_rr(rrset_clone,
68                                                                                                        i))));
69                        ldns_rr_set_owner(ldns_rr_list_rr(rrset_clone, i), new_owner);
70                }
71        }
72        ldns_rdf_deep_free(wildcard_label);
73        ldns_rdf_deep_free(first_label);
74
75        /* make it canonical */
76        for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
77                ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
78        }
79        /* sort */
80        ldns_rr_list_sort(rrset_clone);
81       
82        for (key_count = 0;
83                key_count < ldns_key_list_key_count(keys);
84                key_count++) {
85                if (!ldns_key_use(ldns_key_list_key(keys, key_count))) {
86                        continue;
87                }
88                sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
89                if (!sign_buf) {
90                        printf("[XX]ERROR NO SIGN BUG, OUT OF MEM?\n");
91                        ldns_rr_list_print(stdout, rrset_clone);
92                        fflush(stdout);
93                        exit(123);
94                }
95                b64rdf = NULL;
96
97                current_key = ldns_key_list_key(keys, key_count);
98                /* sign all RRs with keys that have ZSKbit, !SEPbit.
99                   sign DNSKEY RRs with keys that have ZSKbit&SEPbit */
100                if (
101                    ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY &&
102                    (!(ldns_key_flags(current_key) & LDNS_KEY_SEP_KEY)
103                        || ldns_rr_get_type(ldns_rr_list_rr(rrset, 0))
104                        == LDNS_RR_TYPE_DNSKEY)
105                    ) {
106                        current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
107                       
108                        /* set the type on the new signature */
109                        orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
110
111                        ldns_rr_set_ttl(current_sig, orig_ttl);
112                        ldns_rr_set_owner(current_sig, 
113                                                   ldns_rdf_clone(
114                                                          ldns_rr_owner(ldns_rr_list_rr(rrset_clone,
115                                                                                                          0))));
116
117                        /* fill in what we know of the signature */
118
119                        /* set the orig_ttl */
120                        (void)ldns_rr_rrsig_set_origttl(
121                                        current_sig, 
122                                        ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, orig_ttl));
123                        /* the signers name */
124
125                        (void)ldns_rr_rrsig_set_signame(
126                                        current_sig, 
127                                        ldns_rdf_clone(ldns_key_pubkey_owner(current_key)));
128                        /* label count - get it from the first rr in the rr_list */
129                        (void)ldns_rr_rrsig_set_labels(
130                                        current_sig, 
131                                        ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
132                                                                         label_count));
133                        /* inception, expiration */
134                        now = time(NULL);
135                        if (ldns_key_inception(current_key) != 0) {
136                                (void)ldns_rr_rrsig_set_inception(
137                                                current_sig,
138                                                ldns_native2rdf_int32(
139                                                    LDNS_RDF_TYPE_TIME, 
140                                                    ldns_key_inception(current_key)));
141                        } else {
142                                (void)ldns_rr_rrsig_set_inception(
143                                                current_sig,
144                                                ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
145                        }
146                        if (ldns_key_expiration(current_key) != 0) {
147                                (void)ldns_rr_rrsig_set_expiration(
148                                                current_sig,
149                                                ldns_native2rdf_int32(
150                                                    LDNS_RDF_TYPE_TIME, 
151                                                    ldns_key_expiration(current_key)));
152                        } else {
153                                (void)ldns_rr_rrsig_set_expiration(
154                                             current_sig,
155                                                ldns_native2rdf_int32(
156                                                    LDNS_RDF_TYPE_TIME, 
157                                                    now + LDNS_DEFAULT_EXP_TIME));
158                        }
159
160                        /* key-tag */
161                        (void)ldns_rr_rrsig_set_keytag(
162                                     current_sig,
163                                        ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, 
164                                                                          ldns_key_keytag(current_key)));
165
166                        /* algorithm - check the key and substitute that */
167                        (void)ldns_rr_rrsig_set_algorithm(
168                                        current_sig,
169                                        ldns_native2rdf_int8(
170                                            LDNS_RDF_TYPE_ALG, 
171                                            ldns_key_algorithm(current_key)));
172                        /* type-covered */
173                        (void)ldns_rr_rrsig_set_typecovered(
174                                        current_sig,
175                                        ldns_native2rdf_int16(
176                                            LDNS_RDF_TYPE_TYPE,
177                                            ldns_rr_get_type(ldns_rr_list_rr(rrset_clone,
178                                                                                                  0))));
179                        /* right now, we have: a key, a semi-sig and an rrset. For
180                         * which we can create the sig and base64 encode that and
181                         * add that to the signature */
182                       
183                        if (ldns_rrsig2buffer_wire(sign_buf, current_sig)
184                            != LDNS_STATUS_OK) {
185                                ldns_buffer_free(sign_buf);
186                                /* ERROR */
187                                ldns_rr_list_deep_free(rrset_clone);
188                                return NULL;
189                        }
190
191                        /* add the rrset in sign_buf */
192                        if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone)
193                            != LDNS_STATUS_OK) {
194                                ldns_buffer_free(sign_buf);
195                                ldns_rr_list_deep_free(rrset_clone);
196                                return NULL;
197                        }
198                       
199                        switch(ldns_key_algorithm(current_key)) {
200                        case LDNS_SIGN_DSA:
201                        case LDNS_DSA_NSEC3:
202                                b64rdf = ldns_sign_public_evp(
203                                                   sign_buf,
204                                                   ldns_key_evp_key(current_key),
205                                                   EVP_dss1());
206                                break;
207                        case LDNS_SIGN_RSASHA1:
208                        case LDNS_SIGN_RSASHA1_NSEC3:
209                                b64rdf = ldns_sign_public_evp(
210                                                   sign_buf,
211                                                   ldns_key_evp_key(current_key),
212                                                   EVP_sha1());
213                                break;
214#ifdef USE_SHA2
215                        case LDNS_SIGN_RSASHA256:
216                                b64rdf = ldns_sign_public_evp(
217                                                   sign_buf,
218                                                   ldns_key_evp_key(current_key),
219                                                   EVP_sha256());
220                                break;
221                        case LDNS_SIGN_RSASHA512:
222                                b64rdf = ldns_sign_public_evp(
223                                                   sign_buf,
224                                                   ldns_key_evp_key(current_key),
225                                                   EVP_sha512());
226                                break;
227#endif /* USE_SHA2 */
228                        case LDNS_SIGN_RSAMD5:
229                                b64rdf = ldns_sign_public_evp(
230                                                   sign_buf,
231                                                   ldns_key_evp_key(current_key),
232                                                   EVP_md5());
233                                break;
234                        default:
235                                /* do _you_ know this alg? */
236                                printf("unknown algorithm, ");
237                                printf("is the one used available on this system?\n");
238                                break;
239                        }
240                        if (!b64rdf) {
241                                /* signing went wrong */
242                                ldns_rr_list_deep_free(rrset_clone);
243                                return NULL;
244                        }
245                        ldns_rr_rrsig_set_sig(current_sig, b64rdf);
246
247                        /* push the signature to the signatures list */
248                        ldns_rr_list_push_rr(signatures, current_sig);
249                }
250                ldns_buffer_free(sign_buf); /* restart for the next key */
251        }
252        ldns_rr_list_deep_free(rrset_clone);
253
254        return signatures;
255}
256
257/**
258 * Sign data with DSA
259 *
260 * \param[in] to_sign The ldns_buffer containing raw data that is
261 *                    to be signed
262 * \param[in] key The DSA key structure to sign with
263 * \return ldns_rdf for the RRSIG ldns_rr
264 */
265ldns_rdf *
266ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
267{
268        unsigned char *sha1_hash;
269        ldns_rdf *sigdata_rdf;
270        ldns_buffer *b64sig;
271
272        DSA_SIG *sig;
273        uint8_t *data;
274        size_t pad;
275
276        b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
277        if (!b64sig) {
278                return NULL;
279        }
280       
281        sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
282                                  ldns_buffer_position(to_sign), NULL);
283        if (!sha1_hash) {
284                ldns_buffer_free(b64sig);
285                return NULL;
286        }
287
288
289        sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
290
291        data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
292
293        data[0] = 1;
294        pad = 20 - (size_t) BN_num_bytes(sig->r);
295        if (pad > 0) {
296                memset(data + 1, 0, pad);
297        }
298        BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad);
299
300        pad = 20 - (size_t) BN_num_bytes(sig->s);
301        if (pad > 0) {
302                memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
303        }
304        BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
305
306        sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
307                                                                 1 + 2 * SHA_DIGEST_LENGTH,
308                                                                 data);
309
310        ldns_buffer_free(b64sig);
311        LDNS_FREE(data);
312
313        return sigdata_rdf;
314}
315
316ldns_rdf *
317ldns_sign_public_evp(ldns_buffer *to_sign,
318                                 EVP_PKEY *key,
319                                 const EVP_MD *digest_type)
320{
321        unsigned int siglen;
322        ldns_rdf *sigdata_rdf;
323        ldns_buffer *b64sig;
324        EVP_MD_CTX ctx;
325        const EVP_MD *md_type;
326        int r;
327
328        siglen = 0;
329        b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
330        if (!b64sig) {
331                return NULL;
332        }
333
334        /* initializes a signing context */
335        md_type = digest_type;
336        if(!md_type) {
337                printf("Unknown message digest");
338                exit(1);
339        }
340
341        EVP_MD_CTX_init(&ctx);
342        r = EVP_SignInit(&ctx, md_type);
343        if(r == 1) {
344                r = EVP_SignUpdate(&ctx, (unsigned char*)
345                                            ldns_buffer_begin(to_sign), 
346                                            ldns_buffer_position(to_sign));
347        } else {
348                ldns_buffer_free(b64sig);
349                return NULL;
350        }
351        if(r == 1) {
352                r = EVP_SignFinal(&ctx, (unsigned char*)
353                                           ldns_buffer_begin(b64sig), &siglen, key);
354        } else {
355                ldns_buffer_free(b64sig);
356                return NULL;
357        }
358        if(r != 1) {
359                ldns_buffer_free(b64sig);
360                return NULL;
361        }
362
363        /* unfortunately, OpenSSL output is differenct from DNS DSA format */
364        if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
365                sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
366        } else {
367                /* ok output for other types is the same */
368                sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
369                                                                         ldns_buffer_begin(b64sig));
370        }
371        ldns_buffer_free(b64sig);
372        EVP_MD_CTX_cleanup(&ctx);
373        return sigdata_rdf;
374}
375
376
377ldns_rdf *
378ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
379{
380        unsigned char *sha1_hash;
381        unsigned int siglen;
382        ldns_rdf *sigdata_rdf;
383        ldns_buffer *b64sig;
384        int result;
385
386        siglen = 0;
387        b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
388        if (!b64sig) {
389                return NULL;
390        }
391
392        sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
393                                  ldns_buffer_position(to_sign), NULL);
394        if (!sha1_hash) {
395                ldns_buffer_free(b64sig);
396                return NULL;
397        }
398
399        result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH,
400                                   (unsigned char*)ldns_buffer_begin(b64sig),
401                                   &siglen, key);
402        if (result != 1) {
403                return NULL;
404        }
405
406        if (result != 1) {
407                return NULL;
408        }
409
410        sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, 
411                                                                 ldns_buffer_begin(b64sig));
412        ldns_buffer_free(b64sig); /* can't free this buffer ?? */
413        return sigdata_rdf;
414}
415
416ldns_rdf *
417ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
418{
419        unsigned char *md5_hash;
420        unsigned int siglen;
421        ldns_rdf *sigdata_rdf;
422        ldns_buffer *b64sig;
423
424        b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
425        if (!b64sig) {
426                return NULL;
427        }
428       
429        md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
430                                ldns_buffer_position(to_sign), NULL);
431        if (!md5_hash) {
432                ldns_buffer_free(b64sig);
433                return NULL;
434        }
435
436        RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH,
437                    (unsigned char*)ldns_buffer_begin(b64sig),
438                    &siglen, key);
439
440        sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, 
441                                                                 ldns_buffer_begin(b64sig));
442        ldns_buffer_free(b64sig);
443        return sigdata_rdf;
444}
445
446ldns_status
447ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
448{
449        ldns_rbnode_t *cur_node;
450        ldns_dnssec_name *cur_name;
451        ldns_rdf *cur_owner, *cur_parent;
452
453        cur_node = ldns_rbtree_first(zone->names);
454        while (cur_node != LDNS_RBTREE_NULL) {
455                cur_name = (ldns_dnssec_name *) cur_node->data;
456                cur_node = ldns_rbtree_next(cur_node);
457
458                if (cur_name->rrsets && !cur_name->rrsets->next &&
459                    (cur_name->rrsets->type == LDNS_RR_TYPE_A ||
460                        cur_name->rrsets->type == LDNS_RR_TYPE_AAAA
461                        )) {
462                        /* assume glue XXX check for zone cur */
463                        cur_owner = ldns_rdf_clone(ldns_rr_owner(
464                                              cur_name->rrsets->rrs->rr));
465                        while (ldns_dname_label_count(cur_owner) >
466                                  ldns_dname_label_count(zone->soa->name)) {
467                                if (ldns_dnssec_zone_find_rrset(zone,
468                                                                                  cur_owner,
469                                                                                  LDNS_RR_TYPE_NS)) {
470                                        cur_name->is_glue = true;
471                                }
472                                cur_parent = ldns_dname_left_chop(cur_owner);
473                                ldns_rdf_deep_free(cur_owner);
474                                cur_owner = cur_parent;
475                        }
476                        ldns_rdf_deep_free(cur_owner);
477                }
478        }
479        return LDNS_STATUS_OK;
480}
481
482ldns_rbnode_t *
483ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
484{
485        ldns_rbnode_t *next_node = NULL;
486        ldns_dnssec_name *next_name = NULL;
487        bool done = false;
488
489        if (node == LDNS_RBTREE_NULL) {
490                return NULL;
491        }
492        next_node = node;
493        while (!done) {
494                if (next_node == LDNS_RBTREE_NULL) {
495                        return NULL;
496                } else {
497                        next_name = (ldns_dnssec_name *)next_node->data;
498                        if (!next_name->is_glue) {
499                                done = true;
500                        } else {
501                                next_node = ldns_rbtree_next(next_node);
502                        }
503                }
504        }
505        return next_node;
506}
507
508ldns_status
509ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
510                                                ldns_rr_list *new_rrs)
511{
512
513        ldns_rbnode_t *first_node, *cur_node, *next_node;
514        ldns_dnssec_name *cur_name, *next_name;
515        ldns_rr *nsec_rr;
516
517        first_node = ldns_dnssec_name_node_next_nonglue(
518                               ldns_rbtree_first(zone->names));
519        cur_node = first_node;
520        if (cur_node) {
521                next_node = ldns_dnssec_name_node_next_nonglue(
522                                   ldns_rbtree_next(cur_node));
523        } else {
524                next_node = NULL;
525        }
526
527        while (cur_node && next_node) {
528                cur_name = (ldns_dnssec_name *)cur_node->data;
529                next_name = (ldns_dnssec_name *)next_node->data;
530                nsec_rr = ldns_dnssec_create_nsec(cur_name,
531                                                                    next_name,
532                                                                    LDNS_RR_TYPE_NSEC);
533                ldns_dnssec_name_add_rr(cur_name, nsec_rr);
534                ldns_rr_list_push_rr(new_rrs, nsec_rr);
535                cur_node = next_node;
536                if (cur_node) {
537                        next_node = ldns_dnssec_name_node_next_nonglue(
538                               ldns_rbtree_next(cur_node));
539                }
540        }
541
542        if (cur_node && !next_node) {
543                cur_name = (ldns_dnssec_name *)cur_node->data;
544                next_name = (ldns_dnssec_name *)first_node->data;
545                nsec_rr = ldns_dnssec_create_nsec(cur_name,
546                                                                    next_name,
547                                                                    LDNS_RR_TYPE_NSEC);
548                ldns_dnssec_name_add_rr(cur_name, nsec_rr);
549                ldns_rr_list_push_rr(new_rrs, nsec_rr);
550        } else {
551                printf("error\n");
552        }
553
554        return LDNS_STATUS_OK;
555}
556
557ldns_dnssec_rrs *
558ldns_dnssec_remove_signatures(ldns_dnssec_rrs *signatures,
559                                                ldns_key_list *key_list,
560                                                int (*func)(ldns_rr *, void *),
561                                                void *arg)
562{
563        ldns_dnssec_rrs *base_rrs = signatures;
564        ldns_dnssec_rrs *cur_rr = base_rrs;
565        ldns_dnssec_rrs *prev_rr = NULL;
566        ldns_dnssec_rrs *next_rr;
567
568        uint16_t keytag;
569        size_t i;
570        int v;
571
572        key_list = key_list;
573
574        if (!cur_rr) {
575                switch(func(NULL, arg)) {
576                case LDNS_SIGNATURE_LEAVE_ADD_NEW:
577                case LDNS_SIGNATURE_REMOVE_ADD_NEW:
578                break;
579                case LDNS_SIGNATURE_LEAVE_NO_ADD:
580                case LDNS_SIGNATURE_REMOVE_NO_ADD:
581                ldns_key_list_set_use(key_list, false);
582                break;
583                default:
584                        fprintf(stderr, "[XX] unknown return value from callback\n");
585                        break;
586                }
587                return NULL;
588        }
589        v = func(cur_rr->rr, arg);
590
591        while (cur_rr) {
592                next_rr = cur_rr->next;
593               
594                switch (func(cur_rr->rr, arg)) {
595                case  LDNS_SIGNATURE_LEAVE_ADD_NEW:
596                        prev_rr = cur_rr;
597                        break;
598                case LDNS_SIGNATURE_LEAVE_NO_ADD:
599                        keytag = ldns_rdf2native_int16(
600                                           ldns_rr_rrsig_keytag(cur_rr->rr));
601                        for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
602                                if (ldns_key_keytag(ldns_key_list_key(key_list, i)) ==
603                                    keytag) {
604                                        ldns_key_set_use(ldns_key_list_key(key_list, i),
605                                                                  false);
606                                }
607                        }
608                        prev_rr = cur_rr;
609                        break;
610                case LDNS_SIGNATURE_REMOVE_NO_ADD:
611                        keytag = ldns_rdf2native_int16(
612                                           ldns_rr_rrsig_keytag(cur_rr->rr));
613                        for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
614                                if (ldns_key_keytag(ldns_key_list_key(key_list, i))
615                                    == keytag) {
616                                        ldns_key_set_use(ldns_key_list_key(key_list, i),
617                                                                  false);
618                                }
619                        }
620                        if (prev_rr) {
621                                prev_rr->next = next_rr;
622                        } else {
623                                base_rrs = next_rr;
624                        }
625                        LDNS_FREE(cur_rr);
626                        break;
627                case LDNS_SIGNATURE_REMOVE_ADD_NEW:
628                        if (prev_rr) {
629                                prev_rr->next = next_rr;
630                        } else {
631                                base_rrs = next_rr;
632                        }
633                        LDNS_FREE(cur_rr);
634                        break;
635                default:
636                        fprintf(stderr, "[XX] unknown return value from callback\n");
637                        break;
638                }
639                cur_rr = next_rr;
640        }
641
642        return base_rrs;
643}
644
645ldns_status
646ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
647                                                 ldns_rr_list *new_rrs,
648                                                 ldns_key_list *key_list,
649                                                 int (*func)(ldns_rr *, void*),
650                                                 void *arg)
651{
652        ldns_status result = LDNS_STATUS_OK;
653
654        ldns_rbnode_t *cur_node;
655        ldns_rr_list *rr_list;
656
657        ldns_dnssec_name *cur_name;
658        ldns_dnssec_rrsets *cur_rrset;
659        ldns_dnssec_rrs *cur_rr;
660
661        ldns_rr_list *siglist;
662       
663        size_t i;
664
665        ldns_rr_list *pubkey_list = ldns_rr_list_new();
666        zone = zone;
667        new_rrs = new_rrs;
668        key_list = key_list;
669        for (i = 0; i<ldns_key_list_key_count(key_list); i++) {
670                ldns_rr_list_push_rr(pubkey_list,
671                                                 ldns_key2rr(ldns_key_list_key(key_list, i)));
672        }
673        /* TODO: callback to see is list should be signed */
674        /* TODO: remove 'old' signatures from signature list */
675        cur_node = ldns_rbtree_first(zone->names);
676        while (cur_node != LDNS_RBTREE_NULL) {
677                cur_name = (ldns_dnssec_name *) cur_node->data;
678
679                if (!cur_name->is_glue) {
680                        cur_rrset = cur_name->rrsets;
681                        while (cur_rrset) {
682                                /* reset keys to use */
683                                ldns_key_list_set_use(key_list, true);
684                               
685                                /* walk through old sigs, remove the old,
686                                   and mark which keys (not) to use) */
687                                cur_rrset->signatures =
688                                        ldns_dnssec_remove_signatures(cur_rrset->signatures,
689                                                                                        key_list,
690                                                                                        func,
691                                                                                        arg);
692                               
693                                /* TODO: just set count to zero? */
694                                rr_list = ldns_rr_list_new();
695                               
696                                cur_rr = cur_rrset->rrs;
697                                while (cur_rr) {
698                                        ldns_rr_list_push_rr(rr_list, cur_rr->rr);
699                                        cur_rr = cur_rr->next;
700                                }
701                               
702                                siglist = ldns_sign_public(rr_list, key_list);
703                                for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
704                                        if (cur_rrset->signatures) {
705                                                ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
706                                                                                   ldns_rr_list_rr(siglist,
707                                                                                                            i));
708                                        } else {
709                                                cur_rrset->signatures = ldns_dnssec_rrs_new();
710                                                cur_rrset->signatures->rr =
711                                                        ldns_rr_list_rr(siglist, i);
712                                                ldns_rr_list_push_rr(new_rrs,
713                                                                                 ldns_rr_list_rr(siglist,
714                                                                                                          i));
715                                        }
716                                }
717                               
718                               
719                                ldns_rr_list_free(siglist);
720                                ldns_rr_list_free(rr_list);
721                               
722                                cur_rrset = cur_rrset->next;
723                        }
724                       
725                        /* sign the nsec */
726                        cur_name->nsec_signatures =
727                                ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
728                                                                                key_list,
729                                                                                func,
730                                                                                arg);
731                       
732                        rr_list = ldns_rr_list_new();
733                        ldns_rr_list_push_rr(rr_list, cur_name->nsec);
734                        siglist = ldns_sign_public(rr_list, key_list);
735                       
736                        for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
737                                if (cur_name->nsec_signatures) {
738                                        ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
739                                                                           ldns_rr_list_rr(siglist, i));
740                                } else {
741                                        cur_name->nsec_signatures = ldns_dnssec_rrs_new();
742                                        cur_name->nsec_signatures->rr =
743                                                ldns_rr_list_rr(siglist, i);
744                                        ldns_rr_list_push_rr(new_rrs,
745                                                                         ldns_rr_list_rr(siglist, i));
746                                }
747                        }
748                       
749                        ldns_rr_list_free(siglist);
750                        ldns_rr_list_free(rr_list);
751                }
752                cur_node = ldns_rbtree_next(cur_node);
753        }
754
755        ldns_rr_list_deep_free(pubkey_list);
756        return result;
757}
758
759ldns_status
760ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
761                                  ldns_rr_list *new_rrs,
762                                  ldns_key_list *key_list,
763                                  int (*func)(ldns_rr *, void *),
764                                  void *arg)
765{
766        ldns_status result = LDNS_STATUS_OK;
767
768        if (!zone || !new_rrs || !key_list) {
769                return LDNS_STATUS_ERR;
770        }
771
772        /* zone is already sorted */
773        ldns_dnssec_zone_mark_glue(zone);
774       
775        /* check whether we need to add nsecs */
776        if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
777                result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
778                if (result != LDNS_STATUS_OK) {
779                        return result;
780                }
781        }
782
783        result = ldns_dnssec_zone_create_rrsigs(zone,
784                                                                        new_rrs,
785                                                                        key_list,
786                                                                        func,
787                                                                        arg);
788
789        return result;
790}
791
792ldns_status
793ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
794                                           ldns_rr_list *new_rrs,
795                                           ldns_key_list *key_list,
796                                           int (*func)(ldns_rr *, void *),
797                                           void *arg,
798                                           uint8_t algorithm,
799                                           uint8_t flags,
800                                           uint16_t iterations,
801                                           uint8_t salt_length,
802                                           uint8_t *salt)
803{
804        ldns_rr *nsec3, *nsec3params;
805        ldns_status result = LDNS_STATUS_OK;
806
807        /* zone is already sorted */
808        ldns_dnssec_zone_mark_glue(zone);
809
810        /* TODO if there are already nsec3s presents and their
811         * parameters are the same as these, we don't have to recreate
812         */
813        if (zone->names) {
814                /* add empty nonterminals */
815                ldns_dnssec_zone_add_empty_nonterminals(zone);
816
817                nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec;
818                if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
819                        // no need to recreate
820                } else {
821                        if (!ldns_dnssec_zone_find_rrset(zone,
822                                                                           zone->soa->name,
823                                                                           LDNS_RR_TYPE_NSEC3PARAMS)) {
824                                /* create and add the nsec3params rr */
825                                nsec3params =
826                                        ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAMS);
827                                ldns_rr_set_owner(nsec3params,
828                                                           ldns_rdf_clone(zone->soa->name));
829                                ldns_nsec3_add_param_rdfs(nsec3params,
830                                                                         algorithm,
831                                                                         flags,
832                                                                         iterations,
833                                                                         salt_length,
834                                                                         salt);
835                                ldns_dnssec_zone_add_rr(zone, nsec3params);
836                                ldns_rr_list_push_rr(new_rrs, nsec3params);
837                        }
838                        result = ldns_dnssec_zone_create_nsec3s(zone,
839                                                                                        new_rrs,
840                                                                                        algorithm,
841                                                                                        flags,
842                                                                                        iterations,
843                                                                                        salt_length,
844                                                                                        salt);
845                        if (result != LDNS_STATUS_OK) {
846                                return result;
847                        }
848                }
849
850                result = ldns_dnssec_zone_create_rrsigs(zone,
851                                                                                new_rrs,
852                                                                                key_list,
853                                                                                func,
854                                                                                arg);
855        }
856       
857        return result;
858}
859
860
861ldns_zone *
862ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
863{
864        ldns_dnssec_zone *dnssec_zone;
865        ldns_zone *signed_zone;
866        ldns_rr_list *new_rrs;
867        size_t i;
868
869        signed_zone = ldns_zone_new();
870        dnssec_zone = ldns_dnssec_zone_new();;
871
872        (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
873        ldns_zone_set_soa(signed_zone, ldns_zone_soa(zone));
874       
875        for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
876                (void) ldns_dnssec_zone_add_rr(dnssec_zone,
877                                                                 ldns_rr_list_rr(ldns_zone_rrs(zone),
878                                                                                          i));
879                ldns_zone_push_rr(signed_zone, 
880                                           ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
881                                                                                           i)));
882        }
883
884        new_rrs = ldns_rr_list_new();
885        (void) ldns_dnssec_zone_sign(dnssec_zone,
886                                                    new_rrs,
887                                                    key_list,
888                                                    ldns_dnssec_default_replace_signatures,
889                                                    NULL);
890
891        for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
892                ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
893                                                 ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
894        }
895
896        ldns_rr_list_deep_free(new_rrs);
897        ldns_dnssec_zone_free(dnssec_zone);
898
899        return signed_zone;
900}
901
902ldns_zone *
903ldns_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)
904{
905        ldns_dnssec_zone *dnssec_zone;
906        ldns_zone *signed_zone;
907        ldns_rr_list *new_rrs;
908        size_t i;
909
910        signed_zone = ldns_zone_new();
911        dnssec_zone = ldns_dnssec_zone_new();;
912
913        (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
914        ldns_zone_set_soa(signed_zone, ldns_zone_soa(zone));
915       
916        for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
917                (void) ldns_dnssec_zone_add_rr(dnssec_zone,
918                                                                 ldns_rr_list_rr(ldns_zone_rrs(zone),
919                                                                                          i));
920                ldns_zone_push_rr(signed_zone, 
921                                           ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
922                                                                                           i)));
923        }
924
925        new_rrs = ldns_rr_list_new();
926        (void) ldns_dnssec_zone_sign_nsec3(dnssec_zone,
927                                                                new_rrs,
928                                                                key_list,
929                                                                ldns_dnssec_default_replace_signatures,
930                                                                NULL,
931                                                                algorithm,
932                                                                flags,
933                                                                iterations,
934                                                                salt_length,
935                                                                salt);
936
937        for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
938                ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
939                                                 ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
940        }
941
942        ldns_rr_list_deep_free(new_rrs);
943        ldns_dnssec_zone_free(dnssec_zone);
944
945        return signed_zone;
946}
947
948#endif
Note: See TracBrowser for help on using the browser.
Telnic
Search This Site
Partners
Neustar
ICANN
Main site | WHOIS | Sell .tel | FAQ | Archived Site | About Telnic | Contact Us