dnssec_sign.c

Go to the documentation of this file.
00001 #include <ldns/config.h>
00002 
00003 #include <ldns/ldns.h>
00004 
00005 #include <ldns/dnssec.h>
00006 #include <ldns/dnssec_sign.h>
00007 
00008 #include <strings.h>
00009 #include <time.h>
00010 
00011 #ifdef HAVE_SSL
00012 /* this entire file is rather useless when you don't have
00013  * crypto...
00014  */
00015 #include <openssl/ssl.h>
00016 #include <openssl/evp.h>
00017 #include <openssl/rand.h>
00018 #include <openssl/err.h>
00019 #include <openssl/md5.h>
00020 #endif /* HAVE_SSL */
00021 
00022 ldns_rr *
00023 ldns_create_empty_rrsig(ldns_rr_list *rrset,
00024                         ldns_key *current_key)
00025 {
00026         uint32_t orig_ttl;
00027         ldns_rr_class orig_class;
00028         time_t now;
00029         ldns_rr *current_sig;
00030         uint8_t label_count;
00031         ldns_rdf *signame;
00032 
00033         label_count = ldns_dname_label_count(ldns_rr_owner(ldns_rr_list_rr(rrset,
00034                                                            0)));
00035         /* RFC4035 2.2: not counting the leftmost label if it is a wildcard */
00036         if(ldns_dname_is_wildcard(ldns_rr_owner(ldns_rr_list_rr(rrset, 0))))
00037                 label_count --;
00038 
00039         current_sig = ldns_rr_new_frm_type(LDNS_RR_TYPE_RRSIG);
00040 
00041         /* set the type on the new signature */
00042         orig_ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0));
00043         orig_class = ldns_rr_get_class(ldns_rr_list_rr(rrset, 0));
00044 
00045         ldns_rr_set_ttl(current_sig, orig_ttl);
00046         ldns_rr_set_class(current_sig, orig_class);
00047         ldns_rr_set_owner(current_sig,
00048                           ldns_rdf_clone(
00049                                ldns_rr_owner(
00050                                     ldns_rr_list_rr(rrset,
00051                                                     0))));
00052 
00053         /* fill in what we know of the signature */
00054 
00055         /* set the orig_ttl */
00056         (void)ldns_rr_rrsig_set_origttl(
00057                    current_sig,
00058                    ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
00059                                          orig_ttl));
00060         /* the signers name */
00061         signame = ldns_rdf_clone(ldns_key_pubkey_owner(current_key));
00062         ldns_dname2canonical(signame);
00063         (void)ldns_rr_rrsig_set_signame(
00064                         current_sig,
00065                         signame);
00066         /* label count - get it from the first rr in the rr_list */
00067         (void)ldns_rr_rrsig_set_labels(
00068                         current_sig,
00069                         ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8,
00070                                              label_count));
00071         /* inception, expiration */
00072         now = time(NULL);
00073         if (ldns_key_inception(current_key) != 0) {
00074                 (void)ldns_rr_rrsig_set_inception(
00075                                 current_sig,
00076                                 ldns_native2rdf_int32(
00077                                     LDNS_RDF_TYPE_TIME,
00078                                     ldns_key_inception(current_key)));
00079         } else {
00080                 (void)ldns_rr_rrsig_set_inception(
00081                                 current_sig,
00082                                 ldns_native2rdf_int32(LDNS_RDF_TYPE_TIME, now));
00083         }
00084         if (ldns_key_expiration(current_key) != 0) {
00085                 (void)ldns_rr_rrsig_set_expiration(
00086                                 current_sig,
00087                                 ldns_native2rdf_int32(
00088                                     LDNS_RDF_TYPE_TIME,
00089                                     ldns_key_expiration(current_key)));
00090         } else {
00091                 (void)ldns_rr_rrsig_set_expiration(
00092                              current_sig,
00093                                 ldns_native2rdf_int32(
00094                                     LDNS_RDF_TYPE_TIME,
00095                                     now + LDNS_DEFAULT_EXP_TIME));
00096         }
00097 
00098         (void)ldns_rr_rrsig_set_keytag(
00099                    current_sig,
00100                    ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
00101                                          ldns_key_keytag(current_key)));
00102 
00103         (void)ldns_rr_rrsig_set_algorithm(
00104                         current_sig,
00105                         ldns_native2rdf_int8(
00106                             LDNS_RDF_TYPE_ALG,
00107                             ldns_key_algorithm(current_key)));
00108 
00109         (void)ldns_rr_rrsig_set_typecovered(
00110                         current_sig,
00111                         ldns_native2rdf_int16(
00112                             LDNS_RDF_TYPE_TYPE,
00113                             ldns_rr_get_type(ldns_rr_list_rr(rrset,
00114                                                              0))));
00115         return current_sig;
00116 }
00117 
00118 #ifdef HAVE_SSL
00119 ldns_rdf *
00120 ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
00121 {
00122         ldns_rdf *b64rdf = NULL;
00123 
00124         switch(ldns_key_algorithm(current_key)) {
00125         case LDNS_SIGN_DSA:
00126         case LDNS_SIGN_DSA_NSEC3:
00127                 b64rdf = ldns_sign_public_evp(
00128                                    sign_buf,
00129                                    ldns_key_evp_key(current_key),
00130                                    EVP_dss1());
00131                 break;
00132         case LDNS_SIGN_RSASHA1:
00133         case LDNS_SIGN_RSASHA1_NSEC3:
00134                 b64rdf = ldns_sign_public_evp(
00135                                    sign_buf,
00136                                    ldns_key_evp_key(current_key),
00137                                    EVP_sha1());
00138                 break;
00139 #ifdef USE_SHA2
00140         case LDNS_SIGN_RSASHA256:
00141                 b64rdf = ldns_sign_public_evp(
00142                                    sign_buf,
00143                                    ldns_key_evp_key(current_key),
00144                                    EVP_sha256());
00145                 break;
00146         case LDNS_SIGN_RSASHA512:
00147                 b64rdf = ldns_sign_public_evp(
00148                                    sign_buf,
00149                                    ldns_key_evp_key(current_key),
00150                                    EVP_sha512());
00151                 break;
00152 #endif /* USE_SHA2 */
00153 #ifdef USE_GOST
00154         case LDNS_SIGN_ECC_GOST:
00155                 b64rdf = ldns_sign_public_evp(
00156                                    sign_buf,
00157                                    ldns_key_evp_key(current_key),
00158                                    EVP_get_digestbyname("md_gost94"));
00159                 break;
00160 #endif /* USE_GOST */
00161 #ifdef USE_ECDSA
00162         case LDNS_SIGN_ECDSAP256SHA256:
00163                 b64rdf = ldns_sign_public_evp(
00164                                    sign_buf,
00165                                    ldns_key_evp_key(current_key),
00166                                    EVP_sha256());
00167                 break;
00168         case LDNS_SIGN_ECDSAP384SHA384:
00169                 b64rdf = ldns_sign_public_evp(
00170                                    sign_buf,
00171                                    ldns_key_evp_key(current_key),
00172                                    EVP_sha384());
00173                 break;
00174 #endif
00175         case LDNS_SIGN_RSAMD5:
00176                 b64rdf = ldns_sign_public_evp(
00177                                    sign_buf,
00178                                    ldns_key_evp_key(current_key),
00179                                    EVP_md5());
00180                 break;
00181         default:
00182                 /* do _you_ know this alg? */
00183                 printf("unknown algorithm, ");
00184                 printf("is the one used available on this system?\n");
00185                 break;
00186         }
00187 
00188         return b64rdf;
00189 }
00190 
00195 ldns_rr_list *
00196 ldns_sign_public(ldns_rr_list *rrset, ldns_key_list *keys)
00197 {
00198         ldns_rr_list *signatures;
00199         ldns_rr_list *rrset_clone;
00200         ldns_rr *current_sig;
00201         ldns_rdf *b64rdf;
00202         ldns_key *current_key;
00203         size_t key_count;
00204         uint16_t i;
00205         ldns_buffer *sign_buf;
00206         ldns_rdf *new_owner;
00207 
00208         if (!rrset || ldns_rr_list_rr_count(rrset) < 1 || !keys) {
00209                 return NULL;
00210         }
00211 
00212         new_owner = NULL;
00213 
00214         signatures = ldns_rr_list_new();
00215 
00216         /* prepare a signature and add all the know data
00217          * prepare the rrset. Sign this together.  */
00218         rrset_clone = ldns_rr_list_clone(rrset);
00219         if (!rrset_clone) {
00220                 return NULL;
00221         }
00222 
00223         /* make it canonical */
00224         for(i = 0; i < ldns_rr_list_rr_count(rrset_clone); i++) {
00225                 ldns_rr_set_ttl(ldns_rr_list_rr(rrset_clone, i), 
00226                         ldns_rr_ttl(ldns_rr_list_rr(rrset, 0)));
00227                 ldns_rr2canonical(ldns_rr_list_rr(rrset_clone, i));
00228         }
00229         /* sort */
00230         ldns_rr_list_sort(rrset_clone);
00231 
00232         for (key_count = 0;
00233                 key_count < ldns_key_list_key_count(keys);
00234                 key_count++) {
00235                 if (!ldns_key_use(ldns_key_list_key(keys, key_count))) {
00236                         continue;
00237                 }
00238                 sign_buf = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00239                 if (!sign_buf) {
00240                         ldns_rr_list_free(rrset_clone);
00241                         ldns_rr_list_free(signatures);
00242                         ldns_rdf_free(new_owner);
00243                         return NULL;
00244                 }
00245                 b64rdf = NULL;
00246 
00247                 current_key = ldns_key_list_key(keys, key_count);
00248                 /* sign all RRs with keys that have ZSKbit, !SEPbit.
00249                    sign DNSKEY RRs with keys that have ZSKbit&SEPbit */
00250                 if (ldns_key_flags(current_key) & LDNS_KEY_ZONE_KEY) {
00251                         current_sig = ldns_create_empty_rrsig(rrset_clone,
00252                                                               current_key);
00253 
00254                         /* right now, we have: a key, a semi-sig and an rrset. For
00255                          * which we can create the sig and base64 encode that and
00256                          * add that to the signature */
00257 
00258                         if (ldns_rrsig2buffer_wire(sign_buf, current_sig)
00259                             != LDNS_STATUS_OK) {
00260                                 ldns_buffer_free(sign_buf);
00261                                 /* ERROR */
00262                                 ldns_rr_list_deep_free(rrset_clone);
00263                                 return NULL;
00264                         }
00265 
00266                         /* add the rrset in sign_buf */
00267                         if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone)
00268                             != LDNS_STATUS_OK) {
00269                                 ldns_buffer_free(sign_buf);
00270                                 ldns_rr_list_deep_free(rrset_clone);
00271                                 return NULL;
00272                         }
00273 
00274                         b64rdf = ldns_sign_public_buffer(sign_buf, current_key);
00275 
00276                         if (!b64rdf) {
00277                                 /* signing went wrong */
00278                                 ldns_rr_list_deep_free(rrset_clone);
00279                                 return NULL;
00280                         }
00281 
00282                         ldns_rr_rrsig_set_sig(current_sig, b64rdf);
00283 
00284                         /* push the signature to the signatures list */
00285                         ldns_rr_list_push_rr(signatures, current_sig);
00286                 }
00287                 ldns_buffer_free(sign_buf); /* restart for the next key */
00288         }
00289         ldns_rr_list_deep_free(rrset_clone);
00290 
00291         return signatures;
00292 }
00293 
00302 ldns_rdf *
00303 ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
00304 {
00305         unsigned char *sha1_hash;
00306         ldns_rdf *sigdata_rdf;
00307         ldns_buffer *b64sig;
00308 
00309         DSA_SIG *sig;
00310         uint8_t *data;
00311         size_t pad;
00312 
00313         b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00314         if (!b64sig) {
00315                 return NULL;
00316         }
00317 
00318         sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
00319                                   ldns_buffer_position(to_sign), NULL);
00320         if (!sha1_hash) {
00321                 ldns_buffer_free(b64sig);
00322                 return NULL;
00323         }
00324 
00325         sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
00326         if(!sig) {
00327                 ldns_buffer_free(b64sig);
00328                 return NULL;
00329         }
00330 
00331         data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
00332         if(!data) {
00333                 ldns_buffer_free(b64sig);
00334                 DSA_SIG_free(sig);
00335                 return NULL;
00336         }
00337 
00338         data[0] = 1;
00339         pad = 20 - (size_t) BN_num_bytes(sig->r);
00340         if (pad > 0) {
00341                 memset(data + 1, 0, pad);
00342         }
00343         BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad);
00344 
00345         pad = 20 - (size_t) BN_num_bytes(sig->s);
00346         if (pad > 0) {
00347                 memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
00348         }
00349         BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
00350 
00351         sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
00352                                                                  1 + 2 * SHA_DIGEST_LENGTH,
00353                                                                  data);
00354 
00355         ldns_buffer_free(b64sig);
00356         LDNS_FREE(data);
00357         DSA_SIG_free(sig);
00358 
00359         return sigdata_rdf;
00360 }
00361 
00362 #ifdef USE_ECDSA
00363 #ifndef S_SPLINT_S
00364 static int
00365 ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
00366 {
00367         EC_KEY* ec;
00368         const EC_GROUP* g;
00369         if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC)
00370                 return 0;
00371         ec = EVP_PKEY_get1_EC_KEY(pkey);
00372         g = EC_KEY_get0_group(ec);
00373         if(!g) {
00374                 EC_KEY_free(ec);
00375                 return 0;
00376         }
00377         if(EC_GROUP_get_curve_name(g) == NID_secp224r1 ||
00378                 EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1 ||
00379                 EC_GROUP_get_curve_name(g) == NID_secp384r1) {
00380                 EC_KEY_free(ec);
00381                 return 1;
00382         }
00383         /* downref the eckey, the original is still inside the pkey */
00384         EC_KEY_free(ec);
00385         return 0;
00386 }
00387 #endif /* splint */
00388 #endif /* USE_ECDSA */
00389 
00390 ldns_rdf *
00391 ldns_sign_public_evp(ldns_buffer *to_sign,
00392                                  EVP_PKEY *key,
00393                                  const EVP_MD *digest_type)
00394 {
00395         unsigned int siglen;
00396         ldns_rdf *sigdata_rdf;
00397         ldns_buffer *b64sig;
00398         EVP_MD_CTX ctx;
00399         const EVP_MD *md_type;
00400         int r;
00401 
00402         siglen = 0;
00403         b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00404         if (!b64sig) {
00405                 return NULL;
00406         }
00407 
00408         /* initializes a signing context */
00409         md_type = digest_type;
00410         if(!md_type) {
00411                 /* unknown message difest */
00412                 ldns_buffer_free(b64sig);
00413                 return NULL;
00414         }
00415 
00416         EVP_MD_CTX_init(&ctx);
00417         r = EVP_SignInit(&ctx, md_type);
00418         if(r == 1) {
00419                 r = EVP_SignUpdate(&ctx, (unsigned char*)
00420                                             ldns_buffer_begin(to_sign),
00421                                             ldns_buffer_position(to_sign));
00422         } else {
00423                 ldns_buffer_free(b64sig);
00424                 return NULL;
00425         }
00426         if(r == 1) {
00427                 r = EVP_SignFinal(&ctx, (unsigned char*)
00428                                            ldns_buffer_begin(b64sig), &siglen, key);
00429         } else {
00430                 ldns_buffer_free(b64sig);
00431                 return NULL;
00432         }
00433         if(r != 1) {
00434                 ldns_buffer_free(b64sig);
00435                 return NULL;
00436         }
00437 
00438         /* unfortunately, OpenSSL output is differenct from DNS DSA format */
00439 #ifndef S_SPLINT_S
00440         if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
00441                 sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
00442 #ifdef USE_ECDSA
00443         } else if(EVP_PKEY_type(key->type) == EVP_PKEY_EC &&
00444                 ldns_pkey_is_ecdsa(key)) {
00445                 sigdata_rdf = ldns_convert_ecdsa_rrsig_asn12rdf(b64sig, siglen);
00446 #endif
00447         } else {
00448                 /* ok output for other types is the same */
00449                 sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
00450                                                                          ldns_buffer_begin(b64sig));
00451         }
00452 #endif /* splint */
00453         ldns_buffer_free(b64sig);
00454         EVP_MD_CTX_cleanup(&ctx);
00455         return sigdata_rdf;
00456 }
00457 
00458 ldns_rdf *
00459 ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
00460 {
00461         unsigned char *sha1_hash;
00462         unsigned int siglen;
00463         ldns_rdf *sigdata_rdf;
00464         ldns_buffer *b64sig;
00465         int result;
00466 
00467         siglen = 0;
00468         b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00469         if (!b64sig) {
00470                 return NULL;
00471         }
00472 
00473         sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
00474                                   ldns_buffer_position(to_sign), NULL);
00475         if (!sha1_hash) {
00476                 ldns_buffer_free(b64sig);
00477                 return NULL;
00478         }
00479 
00480         result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH,
00481                                    (unsigned char*)ldns_buffer_begin(b64sig),
00482                                    &siglen, key);
00483         if (result != 1) {
00484                 return NULL;
00485         }
00486 
00487         if (result != 1) {
00488                 return NULL;
00489         }
00490 
00491         sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, 
00492                                                                  ldns_buffer_begin(b64sig));
00493         ldns_buffer_free(b64sig); /* can't free this buffer ?? */
00494         return sigdata_rdf;
00495 }
00496 
00497 ldns_rdf *
00498 ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
00499 {
00500         unsigned char *md5_hash;
00501         unsigned int siglen;
00502         ldns_rdf *sigdata_rdf;
00503         ldns_buffer *b64sig;
00504 
00505         b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00506         if (!b64sig) {
00507                 return NULL;
00508         }
00509 
00510         md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
00511                                 ldns_buffer_position(to_sign), NULL);
00512         if (!md5_hash) {
00513                 ldns_buffer_free(b64sig);
00514                 return NULL;
00515         }
00516 
00517         RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH,
00518                     (unsigned char*)ldns_buffer_begin(b64sig),
00519                     &siglen, key);
00520 
00521         sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
00522                                                                  ldns_buffer_begin(b64sig));
00523         ldns_buffer_free(b64sig);
00524         return sigdata_rdf;
00525 }
00526 #endif /* HAVE_SSL */
00527 
00531 static ldns_status
00532 ldns_dnssec_addresses_on_glue_list(
00533                 ldns_dnssec_rrsets *cur_rrset,
00534                 ldns_rr_list *glue_list)
00535 {
00536         ldns_dnssec_rrs *cur_rrs;
00537         while (cur_rrset) {
00538                 if (cur_rrset->type == LDNS_RR_TYPE_A 
00539                                 || cur_rrset->type == LDNS_RR_TYPE_AAAA) {
00540                         for (cur_rrs = cur_rrset->rrs; 
00541                                         cur_rrs; 
00542                                         cur_rrs = cur_rrs->next) {
00543                                 if (cur_rrs->rr) {
00544                                         if (!ldns_rr_list_push_rr(glue_list, 
00545                                                         cur_rrs->rr)) {
00546                                                 return LDNS_STATUS_MEM_ERR; 
00547                                                 /* ldns_rr_list_push_rr()
00548                                                  * returns false when unable
00549                                                  * to increase the capacity
00550                                                  * of the ldsn_rr_list
00551                                                  */
00552                                         }
00553                                 }
00554                         }
00555                 }
00556                 cur_rrset = cur_rrset->next;
00557         }
00558         return LDNS_STATUS_OK;
00559 }
00560 
00575 ldns_status
00576 ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone, 
00577         ldns_rr_list *glue_list)
00578 {
00579         ldns_rbnode_t    *node;
00580         ldns_dnssec_name *name;
00581         ldns_rdf         *owner;
00582         ldns_rdf         *cut = NULL; /* keeps track of zone cuts */
00583         /* When the cut is caused by a delegation, below_delegation will be 1.
00584          * When caused by a DNAME, below_delegation will be 0.
00585          */
00586         int below_delegation = -1; /* init suppresses comiler warning */
00587         ldns_status s;
00588 
00589         if (!zone || !zone->names) {
00590                 return LDNS_STATUS_NULL;
00591         }
00592         for (node = ldns_rbtree_first(zone->names); 
00593                         node != LDNS_RBTREE_NULL; 
00594                         node = ldns_rbtree_next(node)) {
00595                 name = (ldns_dnssec_name *) node->data;
00596                 owner = ldns_dnssec_name_name(name);
00597 
00598                 if (cut) { 
00599                         /* The previous node was a zone cut, or a subdomain
00600                          * below a zone cut. Is this node (still) a subdomain
00601                          * below the cut? Then the name is occluded. Unless
00602                          * the name contains a SOA, after which we are 
00603                          * authoritative again.
00604                          *
00605                          * FIXME! If there are labels in between the SOA and
00606                          * the cut, going from the authoritative space (below
00607                          * the SOA) up into occluded space again, will not be
00608                          * detected with the contruct below!
00609                          */
00610                         if (ldns_dname_is_subdomain(owner, cut) &&
00611                                         !ldns_dnssec_rrsets_contains_type(
00612                                         name->rrsets, LDNS_RR_TYPE_SOA)) {
00613 
00614                                 if (below_delegation && glue_list) {
00615                                         s = ldns_dnssec_addresses_on_glue_list(
00616                                                 name->rrsets, glue_list);
00617                                         if (s != LDNS_STATUS_OK) {
00618                                                 return s;
00619                                         }
00620                                 }
00621                                 name->is_glue = true; /* Mark occluded name! */
00622                                 continue;
00623                         } else {
00624                                 cut = NULL;
00625                         }
00626                 }
00627 
00628                 /* The node is not below a zone cut. Is it a zone cut itself?
00629                  * Everything below a SOA is authoritative of course; Except
00630                  * when the name also contains a DNAME :).
00631                  */
00632                 if (ldns_dnssec_rrsets_contains_type(
00633                                 name->rrsets, LDNS_RR_TYPE_NS)
00634                             && !ldns_dnssec_rrsets_contains_type(
00635                                 name->rrsets, LDNS_RR_TYPE_SOA)) {
00636                         cut = owner;
00637                         below_delegation = 1;
00638                         if (glue_list) { /* record glue on the zone cut */
00639                                 s = ldns_dnssec_addresses_on_glue_list(
00640                                         name->rrsets, glue_list);
00641                                 if (s != LDNS_STATUS_OK) {
00642                                         return s;
00643                                 }
00644                         }
00645                 } else if (ldns_dnssec_rrsets_contains_type(
00646                                 name->rrsets, LDNS_RR_TYPE_DNAME)) {
00647                         cut = owner;
00648                         below_delegation = 0;
00649                 }
00650         }
00651         return LDNS_STATUS_OK;
00652 }
00653 
00664 ldns_status
00665 ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
00666 {
00667         return ldns_dnssec_zone_mark_and_get_glue(zone, NULL);
00668 }
00669 
00670 ldns_rbnode_t *
00671 ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
00672 {
00673         ldns_rbnode_t *next_node = NULL;
00674         ldns_dnssec_name *next_name = NULL;
00675         bool done = false;
00676 
00677         if (node == LDNS_RBTREE_NULL) {
00678                 return NULL;
00679         }
00680         next_node = node;
00681         while (!done) {
00682                 if (next_node == LDNS_RBTREE_NULL) {
00683                         return NULL;
00684                 } else {
00685                         next_name = (ldns_dnssec_name *)next_node->data;
00686                         if (!next_name->is_glue) {
00687                                 done = true;
00688                         } else {
00689                                 next_node = ldns_rbtree_next(next_node);
00690                         }
00691                 }
00692         }
00693         return next_node;
00694 }
00695 
00696 ldns_status
00697 ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
00698                               ldns_rr_list *new_rrs)
00699 {
00700 
00701         ldns_rbnode_t *first_node, *cur_node, *next_node;
00702         ldns_dnssec_name *cur_name, *next_name;
00703         ldns_rr *nsec_rr;
00704         uint32_t nsec_ttl;
00705         ldns_dnssec_rrsets *soa;
00706 
00707         /* the TTL of NSEC rrs should be set to the minimum TTL of
00708          * the zone SOA (RFC4035 Section 2.3)
00709          */
00710         soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
00711 
00712         /* did the caller actually set it? if not,
00713          * fall back to default ttl
00714          */
00715         if (soa && soa->rrs && soa->rrs->rr
00716                         && (ldns_rr_rdf(soa->rrs->rr, 6) != NULL)) {
00717                 nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
00718         } else {
00719                 nsec_ttl = LDNS_DEFAULT_TTL;
00720         }
00721 
00722         first_node = ldns_dnssec_name_node_next_nonglue(
00723                                ldns_rbtree_first(zone->names));
00724         cur_node = first_node;
00725         if (cur_node) {
00726                 next_node = ldns_dnssec_name_node_next_nonglue(
00727                                    ldns_rbtree_next(cur_node));
00728         } else {
00729                 next_node = NULL;
00730         }
00731 
00732         while (cur_node && next_node) {
00733                 cur_name = (ldns_dnssec_name *)cur_node->data;
00734                 next_name = (ldns_dnssec_name *)next_node->data;
00735                 nsec_rr = ldns_dnssec_create_nsec(cur_name,
00736                                                   next_name,
00737                                                   LDNS_RR_TYPE_NSEC);
00738                 ldns_rr_set_ttl(nsec_rr, nsec_ttl);
00739                 if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
00740                         ldns_rr_free(nsec_rr);
00741                         return LDNS_STATUS_ERR;
00742                 }
00743                 ldns_rr_list_push_rr(new_rrs, nsec_rr);
00744                 cur_node = next_node;
00745                 if (cur_node) {
00746                         next_node = ldns_dnssec_name_node_next_nonglue(
00747                                ldns_rbtree_next(cur_node));
00748                 }
00749         }
00750 
00751         if (cur_node && !next_node) {
00752                 cur_name = (ldns_dnssec_name *)cur_node->data;
00753                 next_name = (ldns_dnssec_name *)first_node->data;
00754                 nsec_rr = ldns_dnssec_create_nsec(cur_name,
00755                                                   next_name,
00756                                                   LDNS_RR_TYPE_NSEC);
00757                 ldns_rr_set_ttl(nsec_rr, nsec_ttl);
00758                 if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
00759                         ldns_rr_free(nsec_rr);
00760                         return LDNS_STATUS_ERR;
00761                 }
00762                 ldns_rr_list_push_rr(new_rrs, nsec_rr);
00763         } else {
00764                 printf("error\n");
00765         }
00766 
00767         return LDNS_STATUS_OK;
00768 }
00769 
00770 #ifdef HAVE_SSL
00771 /* in dnssec_zone.c */
00772 extern int ldns_dname_compare_v(const void *a, const void *b);
00773 
00774 ldns_status
00775 ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
00776                 ldns_rr_list *new_rrs,
00777                 uint8_t algorithm,
00778                 uint8_t flags,
00779                 uint16_t iterations,
00780                 uint8_t salt_length,
00781                 uint8_t *salt,
00782                 ldns_rbtree_t **map)
00783 {
00784         ldns_rbnode_t *first_name_node;
00785         ldns_rbnode_t *current_name_node;
00786         ldns_dnssec_name *current_name;
00787         ldns_status result = LDNS_STATUS_OK;
00788         ldns_rr *nsec_rr;
00789         ldns_rr_list *nsec3_list;
00790         uint32_t nsec_ttl;
00791         ldns_dnssec_rrsets *soa;
00792         ldns_rbnode_t *hashmap_node;
00793 
00794         if (!zone || !new_rrs || !zone->names) {
00795                 return LDNS_STATUS_ERR;
00796         }
00797 
00798         /* the TTL of NSEC rrs should be set to the minimum TTL of
00799          * the zone SOA (RFC4035 Section 2.3)
00800          */
00801         soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
00802 
00803         /* did the caller actually set it? if not,
00804          * fall back to default ttl
00805          */
00806         if (soa && soa->rrs && soa->rrs->rr
00807                         && ldns_rr_rdf(soa->rrs->rr, 6) != NULL) {
00808                 nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
00809         } else {
00810                 nsec_ttl = LDNS_DEFAULT_TTL;
00811         }
00812 
00813         if (map) {
00814                 if ((*map = ldns_rbtree_create(ldns_dname_compare_v)) 
00815                                 == NULL) {
00816                         map = NULL;
00817                 };
00818         }
00819         nsec3_list = ldns_rr_list_new();
00820 
00821         first_name_node = ldns_dnssec_name_node_next_nonglue(
00822                                           ldns_rbtree_first(zone->names));
00823 
00824         current_name_node = first_name_node;
00825 
00826         while (current_name_node &&
00827                current_name_node != LDNS_RBTREE_NULL) {
00828                 current_name = (ldns_dnssec_name *) current_name_node->data;
00829                 nsec_rr = ldns_dnssec_create_nsec3(current_name,
00830                                                    NULL,
00831                                                    zone->soa->name,
00832                                                    algorithm,
00833                                                    flags,
00834                                                    iterations,
00835                                                    salt_length,
00836                                                    salt);
00837                 /* by default, our nsec based generator adds rrsigs
00838                  * remove the bitmap for empty nonterminals */
00839                 if (!current_name->rrsets) {
00840                         ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
00841                 }
00842                 ldns_rr_set_ttl(nsec_rr, nsec_ttl);
00843                 result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
00844                 ldns_rr_list_push_rr(new_rrs, nsec_rr);
00845                 ldns_rr_list_push_rr(nsec3_list, nsec_rr);
00846                 if (map) {
00847                         hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
00848                         if (hashmap_node && ldns_rr_owner(nsec_rr)) {
00849                                 hashmap_node->key = ldns_dname_label(
00850                                         ldns_rr_owner(nsec_rr), 0);
00851                                 if (hashmap_node->key) {
00852                                         hashmap_node->data = current_name->name;
00853                                         (void) ldns_rbtree_insert(
00854                                                         *map, hashmap_node);
00855                                 }
00856                         }
00857                 }
00858                 current_name_node = ldns_dnssec_name_node_next_nonglue(
00859                                    ldns_rbtree_next(current_name_node));
00860         }
00861         if (result != LDNS_STATUS_OK) {
00862                 return result;
00863         }
00864 
00865         ldns_rr_list_sort_nsec3(nsec3_list);
00866         result = ldns_dnssec_chain_nsec3_list(nsec3_list);
00867         if (result != LDNS_STATUS_OK) {
00868                 return result;
00869         }
00870 
00871         ldns_rr_list_free(nsec3_list);
00872         return result;
00873 }
00874 
00875 ldns_status
00876 ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
00877                 ldns_rr_list *new_rrs,
00878                 uint8_t algorithm,
00879                 uint8_t flags,
00880                 uint16_t iterations,
00881                 uint8_t salt_length,
00882                 uint8_t *salt)
00883 {
00884         return ldns_dnssec_zone_create_nsec3s_mkmap(zone, new_rrs, algorithm,
00885                         flags, iterations, salt_length, salt, NULL);
00886 
00887 }
00888 #endif /* HAVE_SSL */
00889 
00890 ldns_dnssec_rrs *
00891 ldns_dnssec_remove_signatures( ldns_dnssec_rrs *signatures
00892                              , ATTR_UNUSED(ldns_key_list *key_list)
00893                              , int (*func)(ldns_rr *, void *)
00894                              , void *arg
00895                              )
00896 {
00897         ldns_dnssec_rrs *base_rrs = signatures;
00898         ldns_dnssec_rrs *cur_rr = base_rrs;
00899         ldns_dnssec_rrs *prev_rr = NULL;
00900         ldns_dnssec_rrs *next_rr;
00901 
00902         uint16_t keytag;
00903         size_t i;
00904 
00905         if (!cur_rr) {
00906                 switch(func(NULL, arg)) {
00907                 case LDNS_SIGNATURE_LEAVE_ADD_NEW:
00908                 case LDNS_SIGNATURE_REMOVE_ADD_NEW:
00909                 break;
00910                 case LDNS_SIGNATURE_LEAVE_NO_ADD:
00911                 case LDNS_SIGNATURE_REMOVE_NO_ADD:
00912                 ldns_key_list_set_use(key_list, false);
00913                 break;
00914                 default:
00915                         fprintf(stderr, "[XX] unknown return value from callback\n");
00916                         break;
00917                 }
00918                 return NULL;
00919         }
00920         (void)func(cur_rr->rr, arg);
00921 
00922         while (cur_rr) {
00923                 next_rr = cur_rr->next;
00924 
00925                 switch (func(cur_rr->rr, arg)) {
00926                 case  LDNS_SIGNATURE_LEAVE_ADD_NEW:
00927                         prev_rr = cur_rr;
00928                         break;
00929                 case LDNS_SIGNATURE_LEAVE_NO_ADD:
00930                         keytag = ldns_rdf2native_int16(
00931                                            ldns_rr_rrsig_keytag(cur_rr->rr));
00932                         for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
00933                                 if (ldns_key_keytag(ldns_key_list_key(key_list, i)) ==
00934                                     keytag) {
00935                                         ldns_key_set_use(ldns_key_list_key(key_list, i),
00936                                                                   false);
00937                                 }
00938                         }
00939                         prev_rr = cur_rr;
00940                         break;
00941                 case LDNS_SIGNATURE_REMOVE_NO_ADD:
00942                         keytag = ldns_rdf2native_int16(
00943                                            ldns_rr_rrsig_keytag(cur_rr->rr));
00944                         for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
00945                                 if (ldns_key_keytag(ldns_key_list_key(key_list, i))
00946                                     == keytag) {
00947                                         ldns_key_set_use(ldns_key_list_key(key_list, i),
00948                                                                   false);
00949                                 }
00950                         }
00951                         if (prev_rr) {
00952                                 prev_rr->next = next_rr;
00953                         } else {
00954                                 base_rrs = next_rr;
00955                         }
00956                         LDNS_FREE(cur_rr);
00957                         break;
00958                 case LDNS_SIGNATURE_REMOVE_ADD_NEW:
00959                         if (prev_rr) {
00960                                 prev_rr->next = next_rr;
00961                         } else {
00962                                 base_rrs = next_rr;
00963                         }
00964                         LDNS_FREE(cur_rr);
00965                         break;
00966                 default:
00967                         fprintf(stderr, "[XX] unknown return value from callback\n");
00968                         break;
00969                 }
00970                 cur_rr = next_rr;
00971         }
00972 
00973         return base_rrs;
00974 }
00975 
00976 #ifdef HAVE_SSL
00977 ldns_status
00978 ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
00979                                ldns_rr_list *new_rrs,
00980                                ldns_key_list *key_list,
00981                                int (*func)(ldns_rr *, void*),
00982                                void *arg)
00983 {
00984         return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list,
00985                 func, arg, 0);
00986 }
00987 
00989 static void
00990 ldns_key_list_filter_for_dnskey(ldns_key_list *key_list)
00991 {
00992         int saw_ksk = 0;
00993         size_t i;
00994         for(i=0; i<ldns_key_list_key_count(key_list); i++)
00995                 if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
00996                         saw_ksk = 1;
00997                         break;
00998                 }
00999         if(!saw_ksk)
01000                 return;
01001         for(i=0; i<ldns_key_list_key_count(key_list); i++)
01002                 if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
01003                         ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
01004 }
01005 
01007 static void
01008 ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list)
01009 {
01010         int saw_zsk = 0;
01011         size_t i;
01012         for(i=0; i<ldns_key_list_key_count(key_list); i++)
01013                 if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
01014                         saw_zsk = 1;
01015                         break;
01016                 }
01017         if(!saw_zsk)
01018                 return;
01019         /* else filter all KSKs */
01020         for(i=0; i<ldns_key_list_key_count(key_list); i++)
01021                 if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
01022                         ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
01023 }
01024 
01025 ldns_status
01026 ldns_dnssec_zone_create_rrsigs_flg( ATTR_UNUSED(ldns_dnssec_zone *zone)
01027                                   , ATTR_UNUSED(ldns_rr_list *new_rrs)
01028                                   , ATTR_UNUSED(ldns_key_list *key_list)
01029                                   , int (*func)(ldns_rr *, void*)
01030                                   , void *arg
01031                                   , int flags
01032                                   )
01033 {
01034         ldns_status result = LDNS_STATUS_OK;
01035 
01036         ldns_rbnode_t *cur_node;
01037         ldns_rr_list *rr_list;
01038 
01039         ldns_dnssec_name *cur_name;
01040         ldns_dnssec_rrsets *cur_rrset;
01041         ldns_dnssec_rrs *cur_rr;
01042 
01043         ldns_rr_list *siglist;
01044 
01045         size_t i;
01046 
01047         int on_delegation_point = 0; /* handle partially occluded names */
01048 
01049         ldns_rr_list *pubkey_list = ldns_rr_list_new();
01050         for (i = 0; i<ldns_key_list_key_count(key_list); i++) {
01051                 ldns_rr_list_push_rr( pubkey_list
01052                                     , ldns_key2rr(ldns_key_list_key(
01053                                                         key_list, i))
01054                                     );
01055         }
01056         /* TODO: callback to see is list should be signed */
01057         /* TODO: remove 'old' signatures from signature list */
01058         cur_node = ldns_rbtree_first(zone->names);
01059         while (cur_node != LDNS_RBTREE_NULL) {
01060                 cur_name = (ldns_dnssec_name *) cur_node->data;
01061 
01062                 if (!cur_name->is_glue) {
01063                         on_delegation_point = ldns_dnssec_rrsets_contains_type(
01064                                         cur_name->rrsets, LDNS_RR_TYPE_NS)
01065                                 && !ldns_dnssec_rrsets_contains_type(
01066                                         cur_name->rrsets, LDNS_RR_TYPE_SOA);
01067                         cur_rrset = cur_name->rrsets;
01068                         while (cur_rrset) {
01069                                 /* reset keys to use */
01070                                 ldns_key_list_set_use(key_list, true);
01071 
01072                                 /* walk through old sigs, remove the old,
01073                                    and mark which keys (not) to use) */
01074                                 cur_rrset->signatures =
01075                                         ldns_dnssec_remove_signatures(cur_rrset->signatures,
01076                                                                                         key_list,
01077                                                                                         func,
01078                                                                                         arg);
01079                                 if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) &&
01080                                         cur_rrset->type == LDNS_RR_TYPE_DNSKEY)
01081                                         ldns_key_list_filter_for_dnskey(key_list);
01082 
01083                                 if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY)
01084                                         ldns_key_list_filter_for_non_dnskey(key_list);
01085 
01086                                 /* TODO: just set count to zero? */
01087                                 rr_list = ldns_rr_list_new();
01088 
01089                                 cur_rr = cur_rrset->rrs;
01090                                 while (cur_rr) {
01091                                         ldns_rr_list_push_rr(rr_list, cur_rr->rr);
01092                                         cur_rr = cur_rr->next;
01093                                 }
01094 
01095                                 /* only sign non-delegation RRsets */
01096                                 /* (glue should have been marked earlier, 
01097                                  *  except on the delegation points itself) */
01098                                 if (!on_delegation_point ||
01099                                                 ldns_rr_list_type(rr_list) 
01100                                                         == LDNS_RR_TYPE_DS ||
01101                                                 ldns_rr_list_type(rr_list) 
01102                                                         == LDNS_RR_TYPE_NSEC ||
01103                                                 ldns_rr_list_type(rr_list) 
01104                                                         == LDNS_RR_TYPE_NSEC3) {
01105                                         siglist = ldns_sign_public(rr_list, key_list);
01106                                         for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
01107                                                 if (cur_rrset->signatures) {
01108                                                         result = ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
01109                                                                                            ldns_rr_list_rr(siglist,
01110                                                                                                                     i));
01111                                                 } else {
01112                                                         cur_rrset->signatures = ldns_dnssec_rrs_new();
01113                                                         cur_rrset->signatures->rr =
01114                                                                 ldns_rr_list_rr(siglist, i);
01115                                                         ldns_rr_list_push_rr(new_rrs,
01116                                                                                          ldns_rr_list_rr(siglist,
01117                                                                                                                   i));
01118                                                 }
01119                                         }
01120                                         ldns_rr_list_free(siglist);
01121                                 }
01122 
01123                                 ldns_rr_list_free(rr_list);
01124 
01125                                 cur_rrset = cur_rrset->next;
01126                         }
01127 
01128                         /* sign the nsec */
01129                         ldns_key_list_set_use(key_list, true);
01130                         cur_name->nsec_signatures =
01131                                 ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
01132                                                                                 key_list,
01133                                                                                 func,
01134                                                                                 arg);
01135                         ldns_key_list_filter_for_non_dnskey(key_list);
01136 
01137                         rr_list = ldns_rr_list_new();
01138                         ldns_rr_list_push_rr(rr_list, cur_name->nsec);
01139                         siglist = ldns_sign_public(rr_list, key_list);
01140 
01141                         for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
01142                                 if (cur_name->nsec_signatures) {
01143                                         result = ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
01144                                                                            ldns_rr_list_rr(siglist, i));
01145                                 } else {
01146                                         cur_name->nsec_signatures = ldns_dnssec_rrs_new();
01147                                         cur_name->nsec_signatures->rr =
01148                                                 ldns_rr_list_rr(siglist, i);
01149                                         ldns_rr_list_push_rr(new_rrs,
01150                                                                          ldns_rr_list_rr(siglist, i));
01151                                 }
01152                         }
01153 
01154                         ldns_rr_list_free(siglist);
01155                         ldns_rr_list_free(rr_list);
01156                 }
01157                 cur_node = ldns_rbtree_next(cur_node);
01158         }
01159 
01160         ldns_rr_list_deep_free(pubkey_list);
01161         return result;
01162 }
01163 
01164 ldns_status
01165 ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
01166                                   ldns_rr_list *new_rrs,
01167                                   ldns_key_list *key_list,
01168                                   int (*func)(ldns_rr *, void *),
01169                                   void *arg)
01170 {
01171         return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0);
01172 }
01173 
01174 ldns_status
01175 ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
01176                                   ldns_rr_list *new_rrs,
01177                                   ldns_key_list *key_list,
01178                                   int (*func)(ldns_rr *, void *),
01179                                   void *arg,
01180                                   int flags)
01181 {
01182         ldns_status result = LDNS_STATUS_OK;
01183 
01184         if (!zone || !new_rrs || !key_list) {
01185                 return LDNS_STATUS_ERR;
01186         }
01187 
01188         /* zone is already sorted */
01189         result = ldns_dnssec_zone_mark_glue(zone);
01190         if (result != LDNS_STATUS_OK) {
01191                 return result;
01192         }
01193 
01194         /* check whether we need to add nsecs */
01195         if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
01196                 result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
01197                 if (result != LDNS_STATUS_OK) {
01198                         return result;
01199                 }
01200         }
01201 
01202         result = ldns_dnssec_zone_create_rrsigs_flg(zone,
01203                                         new_rrs,
01204                                         key_list,
01205                                         func,
01206                                         arg,
01207                                         flags);
01208 
01209         return result;
01210 }
01211 
01212 ldns_status
01213 ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
01214                                            ldns_rr_list *new_rrs,
01215                                            ldns_key_list *key_list,
01216                                            int (*func)(ldns_rr *, void *),
01217                                            void *arg,
01218                                            uint8_t algorithm,
01219                                            uint8_t flags,
01220                                            uint16_t iterations,
01221                                            uint8_t salt_length,
01222                                            uint8_t *salt)
01223 {
01224         return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
01225                 func, arg, algorithm, flags, iterations, salt_length, salt, 0,
01226                 NULL);
01227 }
01228 
01229 ldns_status
01230 ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
01231                 ldns_rr_list *new_rrs,
01232                 ldns_key_list *key_list,
01233                 int (*func)(ldns_rr *, void *),
01234                 void *arg,
01235                 uint8_t algorithm,
01236                 uint8_t flags,
01237                 uint16_t iterations,
01238                 uint8_t salt_length,
01239                 uint8_t *salt,
01240                 int signflags,
01241                 ldns_rbtree_t **map)
01242 {
01243         ldns_rr *nsec3, *nsec3param;
01244         ldns_status result = LDNS_STATUS_OK;
01245 
01246         /* zone is already sorted */
01247         result = ldns_dnssec_zone_mark_glue(zone);
01248         if (result != LDNS_STATUS_OK) {
01249                 return result;
01250         }
01251 
01252         /* TODO if there are already nsec3s presents and their
01253          * parameters are the same as these, we don't have to recreate
01254          */
01255         if (zone->names) {
01256                 /* add empty nonterminals */
01257                 result = ldns_dnssec_zone_add_empty_nonterminals(zone);
01258                 if (result != LDNS_STATUS_OK) {
01259                         return result;
01260                 }
01261 
01262                 nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec;
01263                 if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
01264                         /* no need to recreate */
01265                 } else {
01266                         if (!ldns_dnssec_zone_find_rrset(zone,
01267                                                                            zone->soa->name,
01268                                                                            LDNS_RR_TYPE_NSEC3PARAM)) {
01269                                 /* create and add the nsec3param rr */
01270                                 nsec3param =
01271                                         ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAM);
01272                                 ldns_rr_set_owner(nsec3param,
01273                                                            ldns_rdf_clone(zone->soa->name));
01274                                 ldns_nsec3_add_param_rdfs(nsec3param,
01275                                                                          algorithm,
01276                                                                          flags,
01277                                                                          iterations,
01278                                                                          salt_length,
01279                                                                          salt);
01280                                 /* always set bit 7 of the flags to zero, according to
01281                                  * rfc5155 section 11. The bits are counted from right to left,
01282                                  * so bit 7 in rfc5155 is bit 0 in ldns */
01283                                 ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3param, 1)), 0, 0);
01284                                 result = ldns_dnssec_zone_add_rr(zone, nsec3param);
01285                                 if (result != LDNS_STATUS_OK) {
01286                                         return result;
01287                                 }
01288                                 ldns_rr_list_push_rr(new_rrs, nsec3param);
01289                         }
01290                         result = ldns_dnssec_zone_create_nsec3s_mkmap(zone,
01291                                                                                         new_rrs,
01292                                                                                         algorithm,
01293                                                                                         flags,
01294                                                                                         iterations,
01295                                                                                         salt_length,
01296                                                                                         salt,
01297                                                                                         map);
01298                         if (result != LDNS_STATUS_OK) {
01299                                 return result;
01300                         }
01301                 }
01302 
01303                 result = ldns_dnssec_zone_create_rrsigs_flg(zone,
01304                                                 new_rrs,
01305                                                 key_list,
01306                                                 func,
01307                                                 arg,
01308                                                 signflags);
01309         }
01310 
01311         return result;
01312 }
01313 
01314 ldns_status
01315 ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
01316                 ldns_rr_list *new_rrs,
01317                 ldns_key_list *key_list,
01318                 int (*func)(ldns_rr *, void *),
01319                 void *arg,
01320                 uint8_t algorithm,
01321                 uint8_t flags,
01322                 uint16_t iterations,
01323                 uint8_t salt_length,
01324                 uint8_t *salt,
01325                 int signflags)
01326 {
01327         return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
01328                 func, arg, algorithm, flags, iterations, salt_length, salt,
01329                 signflags, NULL);
01330 }
01331 
01332 ldns_zone *
01333 ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
01334 {
01335         ldns_dnssec_zone *dnssec_zone;
01336         ldns_zone *signed_zone;
01337         ldns_rr_list *new_rrs;
01338         size_t i;
01339 
01340         signed_zone = ldns_zone_new();
01341         dnssec_zone = ldns_dnssec_zone_new();
01342 
01343         (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
01344         ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
01345 
01346         for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
01347                 (void) ldns_dnssec_zone_add_rr(dnssec_zone,
01348                                                                  ldns_rr_list_rr(ldns_zone_rrs(zone),
01349                                                                                           i));
01350                 ldns_zone_push_rr(signed_zone,
01351                                            ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
01352                                                                                            i)));
01353         }
01354 
01355         new_rrs = ldns_rr_list_new();
01356         (void) ldns_dnssec_zone_sign(dnssec_zone,
01357                                                     new_rrs,
01358                                                     key_list,
01359                                                     ldns_dnssec_default_replace_signatures,
01360                                                     NULL);
01361 
01362         for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
01363                 ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
01364                                                  ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
01365         }
01366 
01367         ldns_rr_list_deep_free(new_rrs);
01368         ldns_dnssec_zone_free(dnssec_zone);
01369 
01370         return signed_zone;
01371 }
01372 
01373 ldns_zone *
01374 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)
01375 {
01376         ldns_dnssec_zone *dnssec_zone;
01377         ldns_zone *signed_zone;
01378         ldns_rr_list *new_rrs;
01379         size_t i;
01380 
01381         signed_zone = ldns_zone_new();
01382         dnssec_zone = ldns_dnssec_zone_new();
01383 
01384         (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
01385         ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
01386 
01387         for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
01388                 (void) ldns_dnssec_zone_add_rr(dnssec_zone,
01389                                                                  ldns_rr_list_rr(ldns_zone_rrs(zone),
01390                                                                                           i));
01391                 ldns_zone_push_rr(signed_zone, 
01392                                            ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
01393                                                                                            i)));
01394         }
01395 
01396         new_rrs = ldns_rr_list_new();
01397         (void) ldns_dnssec_zone_sign_nsec3(dnssec_zone,
01398                                                                 new_rrs,
01399                                                                 key_list,
01400                                                                 ldns_dnssec_default_replace_signatures,
01401                                                                 NULL,
01402                                                                 algorithm,
01403                                                                 flags,
01404                                                                 iterations,
01405                                                                 salt_length,
01406                                                                 salt);
01407 
01408         for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
01409                 ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
01410                                                  ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
01411         }
01412 
01413         ldns_rr_list_deep_free(new_rrs);
01414         ldns_dnssec_zone_free(dnssec_zone);
01415 
01416         return signed_zone;
01417 }
01418 #endif /* HAVE_SSL */
01419 
01420 

Generated on Fri Jun 8 17:07:46 2012 for ldns by  doxygen 1.4.7