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                                 ldns_rr_free(current_sig);
00264                                 ldns_rr_list_deep_free(signatures);
00265                                 return NULL;
00266                         }
00267 
00268                         /* add the rrset in sign_buf */
00269                         if (ldns_rr_list2buffer_wire(sign_buf, rrset_clone)
00270                             != LDNS_STATUS_OK) {
00271                                 ldns_buffer_free(sign_buf);
00272                                 ldns_rr_list_deep_free(rrset_clone);
00273                                 ldns_rr_free(current_sig);
00274                                 ldns_rr_list_deep_free(signatures);
00275                                 return NULL;
00276                         }
00277 
00278                         b64rdf = ldns_sign_public_buffer(sign_buf, current_key);
00279 
00280                         if (!b64rdf) {
00281                                 /* signing went wrong */
00282                                 ldns_rr_list_deep_free(rrset_clone);
00283                                 ldns_rr_free(current_sig);
00284                                 ldns_rr_list_deep_free(signatures);
00285                                 return NULL;
00286                         }
00287 
00288                         ldns_rr_rrsig_set_sig(current_sig, b64rdf);
00289 
00290                         /* push the signature to the signatures list */
00291                         ldns_rr_list_push_rr(signatures, current_sig);
00292                 }
00293                 ldns_buffer_free(sign_buf); /* restart for the next key */
00294         }
00295         ldns_rr_list_deep_free(rrset_clone);
00296 
00297         return signatures;
00298 }
00299 
00308 ldns_rdf *
00309 ldns_sign_public_dsa(ldns_buffer *to_sign, DSA *key)
00310 {
00311         unsigned char *sha1_hash;
00312         ldns_rdf *sigdata_rdf;
00313         ldns_buffer *b64sig;
00314 
00315         DSA_SIG *sig;
00316         uint8_t *data;
00317         size_t pad;
00318 
00319         b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00320         if (!b64sig) {
00321                 return NULL;
00322         }
00323 
00324         sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
00325                                   ldns_buffer_position(to_sign), NULL);
00326         if (!sha1_hash) {
00327                 ldns_buffer_free(b64sig);
00328                 return NULL;
00329         }
00330 
00331         sig = DSA_do_sign(sha1_hash, SHA_DIGEST_LENGTH, key);
00332         if(!sig) {
00333                 ldns_buffer_free(b64sig);
00334                 return NULL;
00335         }
00336 
00337         data = LDNS_XMALLOC(uint8_t, 1 + 2 * SHA_DIGEST_LENGTH);
00338         if(!data) {
00339                 ldns_buffer_free(b64sig);
00340                 DSA_SIG_free(sig);
00341                 return NULL;
00342         }
00343 
00344         data[0] = 1;
00345         pad = 20 - (size_t) BN_num_bytes(sig->r);
00346         if (pad > 0) {
00347                 memset(data + 1, 0, pad);
00348         }
00349         BN_bn2bin(sig->r, (unsigned char *) (data + 1) + pad);
00350 
00351         pad = 20 - (size_t) BN_num_bytes(sig->s);
00352         if (pad > 0) {
00353                 memset(data + 1 + SHA_DIGEST_LENGTH, 0, pad);
00354         }
00355         BN_bn2bin(sig->s, (unsigned char *) (data + 1 + SHA_DIGEST_LENGTH + pad));
00356 
00357         sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64,
00358                                                                  1 + 2 * SHA_DIGEST_LENGTH,
00359                                                                  data);
00360 
00361         ldns_buffer_free(b64sig);
00362         LDNS_FREE(data);
00363         DSA_SIG_free(sig);
00364 
00365         return sigdata_rdf;
00366 }
00367 
00368 #ifdef USE_ECDSA
00369 #ifndef S_SPLINT_S
00370 static int
00371 ldns_pkey_is_ecdsa(EVP_PKEY* pkey)
00372 {
00373         EC_KEY* ec;
00374         const EC_GROUP* g;
00375         if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC)
00376                 return 0;
00377         ec = EVP_PKEY_get1_EC_KEY(pkey);
00378         g = EC_KEY_get0_group(ec);
00379         if(!g) {
00380                 EC_KEY_free(ec);
00381                 return 0;
00382         }
00383         if(EC_GROUP_get_curve_name(g) == NID_secp224r1 ||
00384                 EC_GROUP_get_curve_name(g) == NID_X9_62_prime256v1 ||
00385                 EC_GROUP_get_curve_name(g) == NID_secp384r1) {
00386                 EC_KEY_free(ec);
00387                 return 1;
00388         }
00389         /* downref the eckey, the original is still inside the pkey */
00390         EC_KEY_free(ec);
00391         return 0;
00392 }
00393 #endif /* splint */
00394 #endif /* USE_ECDSA */
00395 
00396 ldns_rdf *
00397 ldns_sign_public_evp(ldns_buffer *to_sign,
00398                                  EVP_PKEY *key,
00399                                  const EVP_MD *digest_type)
00400 {
00401         unsigned int siglen;
00402         ldns_rdf *sigdata_rdf;
00403         ldns_buffer *b64sig;
00404         EVP_MD_CTX ctx;
00405         const EVP_MD *md_type;
00406         int r;
00407 
00408         siglen = 0;
00409         b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00410         if (!b64sig) {
00411                 return NULL;
00412         }
00413 
00414         /* initializes a signing context */
00415         md_type = digest_type;
00416         if(!md_type) {
00417                 /* unknown message difest */
00418                 ldns_buffer_free(b64sig);
00419                 return NULL;
00420         }
00421 
00422         EVP_MD_CTX_init(&ctx);
00423         r = EVP_SignInit(&ctx, md_type);
00424         if(r == 1) {
00425                 r = EVP_SignUpdate(&ctx, (unsigned char*)
00426                                             ldns_buffer_begin(to_sign),
00427                                             ldns_buffer_position(to_sign));
00428         } else {
00429                 ldns_buffer_free(b64sig);
00430                 return NULL;
00431         }
00432         if(r == 1) {
00433                 r = EVP_SignFinal(&ctx, (unsigned char*)
00434                                            ldns_buffer_begin(b64sig), &siglen, key);
00435         } else {
00436                 ldns_buffer_free(b64sig);
00437                 return NULL;
00438         }
00439         if(r != 1) {
00440                 ldns_buffer_free(b64sig);
00441                 return NULL;
00442         }
00443 
00444         /* unfortunately, OpenSSL output is differenct from DNS DSA format */
00445 #ifndef S_SPLINT_S
00446         if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
00447                 sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
00448 #ifdef USE_ECDSA
00449         } else if(EVP_PKEY_type(key->type) == EVP_PKEY_EC &&
00450                 ldns_pkey_is_ecdsa(key)) {
00451                 sigdata_rdf = ldns_convert_ecdsa_rrsig_asn12rdf(b64sig, siglen);
00452 #endif
00453         } else {
00454                 /* ok output for other types is the same */
00455                 sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
00456                                                                          ldns_buffer_begin(b64sig));
00457         }
00458 #endif /* splint */
00459         ldns_buffer_free(b64sig);
00460         EVP_MD_CTX_cleanup(&ctx);
00461         return sigdata_rdf;
00462 }
00463 
00464 ldns_rdf *
00465 ldns_sign_public_rsasha1(ldns_buffer *to_sign, RSA *key)
00466 {
00467         unsigned char *sha1_hash;
00468         unsigned int siglen;
00469         ldns_rdf *sigdata_rdf;
00470         ldns_buffer *b64sig;
00471         int result;
00472 
00473         siglen = 0;
00474         b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00475         if (!b64sig) {
00476                 return NULL;
00477         }
00478 
00479         sha1_hash = SHA1((unsigned char*)ldns_buffer_begin(to_sign),
00480                                   ldns_buffer_position(to_sign), NULL);
00481         if (!sha1_hash) {
00482                 ldns_buffer_free(b64sig);
00483                 return NULL;
00484         }
00485 
00486         result = RSA_sign(NID_sha1, sha1_hash, SHA_DIGEST_LENGTH,
00487                                    (unsigned char*)ldns_buffer_begin(b64sig),
00488                                    &siglen, key);
00489         if (result != 1) {
00490                 ldns_buffer_free(b64sig);
00491                 return NULL;
00492         }
00493 
00494         sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen, 
00495                                                                  ldns_buffer_begin(b64sig));
00496         ldns_buffer_free(b64sig); /* can't free this buffer ?? */
00497         return sigdata_rdf;
00498 }
00499 
00500 ldns_rdf *
00501 ldns_sign_public_rsamd5(ldns_buffer *to_sign, RSA *key)
00502 {
00503         unsigned char *md5_hash;
00504         unsigned int siglen;
00505         ldns_rdf *sigdata_rdf;
00506         ldns_buffer *b64sig;
00507 
00508         b64sig = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00509         if (!b64sig) {
00510                 return NULL;
00511         }
00512 
00513         md5_hash = MD5((unsigned char*)ldns_buffer_begin(to_sign),
00514                                 ldns_buffer_position(to_sign), NULL);
00515         if (!md5_hash) {
00516                 ldns_buffer_free(b64sig);
00517                 return NULL;
00518         }
00519 
00520         RSA_sign(NID_md5, md5_hash, MD5_DIGEST_LENGTH,
00521                     (unsigned char*)ldns_buffer_begin(b64sig),
00522                     &siglen, key);
00523 
00524         sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
00525                                                                  ldns_buffer_begin(b64sig));
00526         ldns_buffer_free(b64sig);
00527         return sigdata_rdf;
00528 }
00529 #endif /* HAVE_SSL */
00530 
00534 static ldns_status
00535 ldns_dnssec_addresses_on_glue_list(
00536                 ldns_dnssec_rrsets *cur_rrset,
00537                 ldns_rr_list *glue_list)
00538 {
00539         ldns_dnssec_rrs *cur_rrs;
00540         while (cur_rrset) {
00541                 if (cur_rrset->type == LDNS_RR_TYPE_A 
00542                                 || cur_rrset->type == LDNS_RR_TYPE_AAAA) {
00543                         for (cur_rrs = cur_rrset->rrs; 
00544                                         cur_rrs; 
00545                                         cur_rrs = cur_rrs->next) {
00546                                 if (cur_rrs->rr) {
00547                                         if (!ldns_rr_list_push_rr(glue_list, 
00548                                                         cur_rrs->rr)) {
00549                                                 return LDNS_STATUS_MEM_ERR; 
00550                                                 /* ldns_rr_list_push_rr()
00551                                                  * returns false when unable
00552                                                  * to increase the capacity
00553                                                  * of the ldsn_rr_list
00554                                                  */
00555                                         }
00556                                 }
00557                         }
00558                 }
00559                 cur_rrset = cur_rrset->next;
00560         }
00561         return LDNS_STATUS_OK;
00562 }
00563 
00578 ldns_status
00579 ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone, 
00580         ldns_rr_list *glue_list)
00581 {
00582         ldns_rbnode_t    *node;
00583         ldns_dnssec_name *name;
00584         ldns_rdf         *owner;
00585         ldns_rdf         *cut = NULL; /* keeps track of zone cuts */
00586         /* When the cut is caused by a delegation, below_delegation will be 1.
00587          * When caused by a DNAME, below_delegation will be 0.
00588          */
00589         int below_delegation = -1; /* init suppresses comiler warning */
00590         ldns_status s;
00591 
00592         if (!zone || !zone->names) {
00593                 return LDNS_STATUS_NULL;
00594         }
00595         for (node = ldns_rbtree_first(zone->names); 
00596                         node != LDNS_RBTREE_NULL; 
00597                         node = ldns_rbtree_next(node)) {
00598                 name = (ldns_dnssec_name *) node->data;
00599                 owner = ldns_dnssec_name_name(name);
00600 
00601                 if (cut) { 
00602                         /* The previous node was a zone cut, or a subdomain
00603                          * below a zone cut. Is this node (still) a subdomain
00604                          * below the cut? Then the name is occluded. Unless
00605                          * the name contains a SOA, after which we are 
00606                          * authoritative again.
00607                          *
00608                          * FIXME! If there are labels in between the SOA and
00609                          * the cut, going from the authoritative space (below
00610                          * the SOA) up into occluded space again, will not be
00611                          * detected with the contruct below!
00612                          */
00613                         if (ldns_dname_is_subdomain(owner, cut) &&
00614                                         !ldns_dnssec_rrsets_contains_type(
00615                                         name->rrsets, LDNS_RR_TYPE_SOA)) {
00616 
00617                                 if (below_delegation && glue_list) {
00618                                         s = ldns_dnssec_addresses_on_glue_list(
00619                                                 name->rrsets, glue_list);
00620                                         if (s != LDNS_STATUS_OK) {
00621                                                 return s;
00622                                         }
00623                                 }
00624                                 name->is_glue = true; /* Mark occluded name! */
00625                                 continue;
00626                         } else {
00627                                 cut = NULL;
00628                         }
00629                 }
00630 
00631                 /* The node is not below a zone cut. Is it a zone cut itself?
00632                  * Everything below a SOA is authoritative of course; Except
00633                  * when the name also contains a DNAME :).
00634                  */
00635                 if (ldns_dnssec_rrsets_contains_type(
00636                                 name->rrsets, LDNS_RR_TYPE_NS)
00637                             && !ldns_dnssec_rrsets_contains_type(
00638                                 name->rrsets, LDNS_RR_TYPE_SOA)) {
00639                         cut = owner;
00640                         below_delegation = 1;
00641                         if (glue_list) { /* record glue on the zone cut */
00642                                 s = ldns_dnssec_addresses_on_glue_list(
00643                                         name->rrsets, glue_list);
00644                                 if (s != LDNS_STATUS_OK) {
00645                                         return s;
00646                                 }
00647                         }
00648                 } else if (ldns_dnssec_rrsets_contains_type(
00649                                 name->rrsets, LDNS_RR_TYPE_DNAME)) {
00650                         cut = owner;
00651                         below_delegation = 0;
00652                 }
00653         }
00654         return LDNS_STATUS_OK;
00655 }
00656 
00667 ldns_status
00668 ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
00669 {
00670         return ldns_dnssec_zone_mark_and_get_glue(zone, NULL);
00671 }
00672 
00673 ldns_rbnode_t *
00674 ldns_dnssec_name_node_next_nonglue(ldns_rbnode_t *node)
00675 {
00676         ldns_rbnode_t *next_node = NULL;
00677         ldns_dnssec_name *next_name = NULL;
00678         bool done = false;
00679 
00680         if (node == LDNS_RBTREE_NULL) {
00681                 return NULL;
00682         }
00683         next_node = node;
00684         while (!done) {
00685                 if (next_node == LDNS_RBTREE_NULL) {
00686                         return NULL;
00687                 } else {
00688                         next_name = (ldns_dnssec_name *)next_node->data;
00689                         if (!next_name->is_glue) {
00690                                 done = true;
00691                         } else {
00692                                 next_node = ldns_rbtree_next(next_node);
00693                         }
00694                 }
00695         }
00696         return next_node;
00697 }
00698 
00699 ldns_status
00700 ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
00701                               ldns_rr_list *new_rrs)
00702 {
00703 
00704         ldns_rbnode_t *first_node, *cur_node, *next_node;
00705         ldns_dnssec_name *cur_name, *next_name;
00706         ldns_rr *nsec_rr;
00707         uint32_t nsec_ttl;
00708         ldns_dnssec_rrsets *soa;
00709 
00710         /* the TTL of NSEC rrs should be set to the minimum TTL of
00711          * the zone SOA (RFC4035 Section 2.3)
00712          */
00713         soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
00714 
00715         /* did the caller actually set it? if not,
00716          * fall back to default ttl
00717          */
00718         if (soa && soa->rrs && soa->rrs->rr
00719                         && (ldns_rr_rdf(soa->rrs->rr, 6) != NULL)) {
00720                 nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
00721         } else {
00722                 nsec_ttl = LDNS_DEFAULT_TTL;
00723         }
00724 
00725         first_node = ldns_dnssec_name_node_next_nonglue(
00726                                ldns_rbtree_first(zone->names));
00727         cur_node = first_node;
00728         if (cur_node) {
00729                 next_node = ldns_dnssec_name_node_next_nonglue(
00730                                    ldns_rbtree_next(cur_node));
00731         } else {
00732                 next_node = NULL;
00733         }
00734 
00735         while (cur_node && next_node) {
00736                 cur_name = (ldns_dnssec_name *)cur_node->data;
00737                 next_name = (ldns_dnssec_name *)next_node->data;
00738                 nsec_rr = ldns_dnssec_create_nsec(cur_name,
00739                                                   next_name,
00740                                                   LDNS_RR_TYPE_NSEC);
00741                 ldns_rr_set_ttl(nsec_rr, nsec_ttl);
00742                 if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
00743                         ldns_rr_free(nsec_rr);
00744                         return LDNS_STATUS_ERR;
00745                 }
00746                 ldns_rr_list_push_rr(new_rrs, nsec_rr);
00747                 cur_node = next_node;
00748                 if (cur_node) {
00749                         next_node = ldns_dnssec_name_node_next_nonglue(
00750                                ldns_rbtree_next(cur_node));
00751                 }
00752         }
00753 
00754         if (cur_node && !next_node) {
00755                 cur_name = (ldns_dnssec_name *)cur_node->data;
00756                 next_name = (ldns_dnssec_name *)first_node->data;
00757                 nsec_rr = ldns_dnssec_create_nsec(cur_name,
00758                                                   next_name,
00759                                                   LDNS_RR_TYPE_NSEC);
00760                 ldns_rr_set_ttl(nsec_rr, nsec_ttl);
00761                 if(ldns_dnssec_name_add_rr(cur_name, nsec_rr)!=LDNS_STATUS_OK){
00762                         ldns_rr_free(nsec_rr);
00763                         return LDNS_STATUS_ERR;
00764                 }
00765                 ldns_rr_list_push_rr(new_rrs, nsec_rr);
00766         } else {
00767                 printf("error\n");
00768         }
00769 
00770         return LDNS_STATUS_OK;
00771 }
00772 
00773 #ifdef HAVE_SSL
00774 /* in dnssec_zone.c */
00775 extern int ldns_dname_compare_v(const void *a, const void *b);
00776 
00777 ldns_status
00778 ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
00779                 ldns_rr_list *new_rrs,
00780                 uint8_t algorithm,
00781                 uint8_t flags,
00782                 uint16_t iterations,
00783                 uint8_t salt_length,
00784                 uint8_t *salt,
00785                 ldns_rbtree_t **map)
00786 {
00787         ldns_rbnode_t *first_name_node;
00788         ldns_rbnode_t *current_name_node;
00789         ldns_dnssec_name *current_name;
00790         ldns_status result = LDNS_STATUS_OK;
00791         ldns_rr *nsec_rr;
00792         ldns_rr_list *nsec3_list;
00793         uint32_t nsec_ttl;
00794         ldns_dnssec_rrsets *soa;
00795         ldns_rbnode_t *hashmap_node;
00796 
00797         if (!zone || !new_rrs || !zone->names) {
00798                 return LDNS_STATUS_ERR;
00799         }
00800 
00801         /* the TTL of NSEC rrs should be set to the minimum TTL of
00802          * the zone SOA (RFC4035 Section 2.3)
00803          */
00804         soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
00805 
00806         /* did the caller actually set it? if not,
00807          * fall back to default ttl
00808          */
00809         if (soa && soa->rrs && soa->rrs->rr
00810                         && ldns_rr_rdf(soa->rrs->rr, 6) != NULL) {
00811                 nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
00812         } else {
00813                 nsec_ttl = LDNS_DEFAULT_TTL;
00814         }
00815 
00816         if (map) {
00817                 if ((*map = ldns_rbtree_create(ldns_dname_compare_v)) 
00818                                 == NULL) {
00819                         map = NULL;
00820                 };
00821         }
00822         nsec3_list = ldns_rr_list_new();
00823 
00824         first_name_node = ldns_dnssec_name_node_next_nonglue(
00825                                           ldns_rbtree_first(zone->names));
00826 
00827         current_name_node = first_name_node;
00828 
00829         while (current_name_node &&
00830                current_name_node != LDNS_RBTREE_NULL) {
00831                 current_name = (ldns_dnssec_name *) current_name_node->data;
00832                 nsec_rr = ldns_dnssec_create_nsec3(current_name,
00833                                                    NULL,
00834                                                    zone->soa->name,
00835                                                    algorithm,
00836                                                    flags,
00837                                                    iterations,
00838                                                    salt_length,
00839                                                    salt);
00840                 /* by default, our nsec based generator adds rrsigs
00841                  * remove the bitmap for empty nonterminals */
00842                 if (!current_name->rrsets) {
00843                         ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
00844                 }
00845                 ldns_rr_set_ttl(nsec_rr, nsec_ttl);
00846                 result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
00847                 ldns_rr_list_push_rr(new_rrs, nsec_rr);
00848                 ldns_rr_list_push_rr(nsec3_list, nsec_rr);
00849                 if (map) {
00850                         hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
00851                         if (hashmap_node && ldns_rr_owner(nsec_rr)) {
00852                                 hashmap_node->key = ldns_dname_label(
00853                                         ldns_rr_owner(nsec_rr), 0);
00854                                 if (hashmap_node->key) {
00855                                         hashmap_node->data = current_name->name;
00856                                         (void) ldns_rbtree_insert(
00857                                                         *map, hashmap_node);
00858                                 }
00859                         }
00860                 }
00861                 current_name_node = ldns_dnssec_name_node_next_nonglue(
00862                                    ldns_rbtree_next(current_name_node));
00863         }
00864         if (result != LDNS_STATUS_OK) {
00865                 ldns_rr_list_free(nsec3_list);
00866                 return result;
00867         }
00868 
00869         ldns_rr_list_sort_nsec3(nsec3_list);
00870         result = ldns_dnssec_chain_nsec3_list(nsec3_list);
00871         ldns_rr_list_free(nsec3_list);
00872 
00873         return result;
00874 }
00875 
00876 ldns_status
00877 ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
00878                 ldns_rr_list *new_rrs,
00879                 uint8_t algorithm,
00880                 uint8_t flags,
00881                 uint16_t iterations,
00882                 uint8_t salt_length,
00883                 uint8_t *salt)
00884 {
00885         return ldns_dnssec_zone_create_nsec3s_mkmap(zone, new_rrs, algorithm,
00886                         flags, iterations, salt_length, salt, NULL);
00887 
00888 }
00889 #endif /* HAVE_SSL */
00890 
00891 ldns_dnssec_rrs *
00892 ldns_dnssec_remove_signatures( ldns_dnssec_rrs *signatures
00893                              , ATTR_UNUSED(ldns_key_list *key_list)
00894                              , int (*func)(ldns_rr *, void *)
00895                              , void *arg
00896                              )
00897 {
00898         ldns_dnssec_rrs *base_rrs = signatures;
00899         ldns_dnssec_rrs *cur_rr = base_rrs;
00900         ldns_dnssec_rrs *prev_rr = NULL;
00901         ldns_dnssec_rrs *next_rr;
00902 
00903         uint16_t keytag;
00904         size_t i;
00905 
00906         if (!cur_rr) {
00907                 switch(func(NULL, arg)) {
00908                 case LDNS_SIGNATURE_LEAVE_ADD_NEW:
00909                 case LDNS_SIGNATURE_REMOVE_ADD_NEW:
00910                 break;
00911                 case LDNS_SIGNATURE_LEAVE_NO_ADD:
00912                 case LDNS_SIGNATURE_REMOVE_NO_ADD:
00913                 ldns_key_list_set_use(key_list, false);
00914                 break;
00915                 default:
00916                         fprintf(stderr, "[XX] unknown return value from callback\n");
00917                         break;
00918                 }
00919                 return NULL;
00920         }
00921         (void)func(cur_rr->rr, arg);
00922 
00923         while (cur_rr) {
00924                 next_rr = cur_rr->next;
00925 
00926                 switch (func(cur_rr->rr, arg)) {
00927                 case  LDNS_SIGNATURE_LEAVE_ADD_NEW:
00928                         prev_rr = cur_rr;
00929                         break;
00930                 case LDNS_SIGNATURE_LEAVE_NO_ADD:
00931                         keytag = ldns_rdf2native_int16(
00932                                            ldns_rr_rrsig_keytag(cur_rr->rr));
00933                         for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
00934                                 if (ldns_key_keytag(ldns_key_list_key(key_list, i)) ==
00935                                     keytag) {
00936                                         ldns_key_set_use(ldns_key_list_key(key_list, i),
00937                                                                   false);
00938                                 }
00939                         }
00940                         prev_rr = cur_rr;
00941                         break;
00942                 case LDNS_SIGNATURE_REMOVE_NO_ADD:
00943                         keytag = ldns_rdf2native_int16(
00944                                            ldns_rr_rrsig_keytag(cur_rr->rr));
00945                         for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
00946                                 if (ldns_key_keytag(ldns_key_list_key(key_list, i))
00947                                     == keytag) {
00948                                         ldns_key_set_use(ldns_key_list_key(key_list, i),
00949                                                                   false);
00950                                 }
00951                         }
00952                         if (prev_rr) {
00953                                 prev_rr->next = next_rr;
00954                         } else {
00955                                 base_rrs = next_rr;
00956                         }
00957                         LDNS_FREE(cur_rr);
00958                         break;
00959                 case LDNS_SIGNATURE_REMOVE_ADD_NEW:
00960                         if (prev_rr) {
00961                                 prev_rr->next = next_rr;
00962                         } else {
00963                                 base_rrs = next_rr;
00964                         }
00965                         LDNS_FREE(cur_rr);
00966                         break;
00967                 default:
00968                         fprintf(stderr, "[XX] unknown return value from callback\n");
00969                         break;
00970                 }
00971                 cur_rr = next_rr;
00972         }
00973 
00974         return base_rrs;
00975 }
00976 
00977 #ifdef HAVE_SSL
00978 ldns_status
00979 ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
00980                                ldns_rr_list *new_rrs,
00981                                ldns_key_list *key_list,
00982                                int (*func)(ldns_rr *, void*),
00983                                void *arg)
00984 {
00985         return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list,
00986                 func, arg, 0);
00987 }
00988 
00990 static void
00991 ldns_key_list_filter_for_dnskey(ldns_key_list *key_list)
00992 {
00993         int saw_ksk = 0;
00994         size_t i;
00995         for(i=0; i<ldns_key_list_key_count(key_list); i++)
00996                 if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
00997                         saw_ksk = 1;
00998                         break;
00999                 }
01000         if(!saw_ksk)
01001                 return;
01002         for(i=0; i<ldns_key_list_key_count(key_list); i++)
01003                 if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
01004                         ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
01005 }
01006 
01008 static void
01009 ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list)
01010 {
01011         int saw_zsk = 0;
01012         size_t i;
01013         for(i=0; i<ldns_key_list_key_count(key_list); i++)
01014                 if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
01015                         saw_zsk = 1;
01016                         break;
01017                 }
01018         if(!saw_zsk)
01019                 return;
01020         /* else filter all KSKs */
01021         for(i=0; i<ldns_key_list_key_count(key_list); i++)
01022                 if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
01023                         ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
01024 }
01025 
01026 ldns_status
01027 ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone
01028                                   , ldns_rr_list *new_rrs
01029                                   , ldns_key_list *key_list
01030                                   , int (*func)(ldns_rr *, void*)
01031                                   , void *arg
01032                                   , int flags
01033                                   )
01034 {
01035         ldns_status result = LDNS_STATUS_OK;
01036 
01037         ldns_rbnode_t *cur_node;
01038         ldns_rr_list *rr_list;
01039 
01040         ldns_dnssec_name *cur_name;
01041         ldns_dnssec_rrsets *cur_rrset;
01042         ldns_dnssec_rrs *cur_rr;
01043 
01044         ldns_rr_list *siglist;
01045 
01046         size_t i;
01047 
01048         int on_delegation_point = 0; /* handle partially occluded names */
01049 
01050         ldns_rr_list *pubkey_list = ldns_rr_list_new();
01051         for (i = 0; i<ldns_key_list_key_count(key_list); i++) {
01052                 ldns_rr_list_push_rr( pubkey_list
01053                                     , ldns_key2rr(ldns_key_list_key(
01054                                                         key_list, i))
01055                                     );
01056         }
01057         /* TODO: callback to see is list should be signed */
01058         /* TODO: remove 'old' signatures from signature list */
01059         cur_node = ldns_rbtree_first(zone->names);
01060         while (cur_node != LDNS_RBTREE_NULL) {
01061                 cur_name = (ldns_dnssec_name *) cur_node->data;
01062 
01063                 if (!cur_name->is_glue) {
01064                         on_delegation_point = ldns_dnssec_rrsets_contains_type(
01065                                         cur_name->rrsets, LDNS_RR_TYPE_NS)
01066                                 && !ldns_dnssec_rrsets_contains_type(
01067                                         cur_name->rrsets, LDNS_RR_TYPE_SOA);
01068                         cur_rrset = cur_name->rrsets;
01069                         while (cur_rrset) {
01070                                 /* reset keys to use */
01071                                 ldns_key_list_set_use(key_list, true);
01072 
01073                                 /* walk through old sigs, remove the old,
01074                                    and mark which keys (not) to use) */
01075                                 cur_rrset->signatures =
01076                                         ldns_dnssec_remove_signatures(cur_rrset->signatures,
01077                                                                                         key_list,
01078                                                                                         func,
01079                                                                                         arg);
01080                                 if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) &&
01081                                         cur_rrset->type == LDNS_RR_TYPE_DNSKEY)
01082                                         ldns_key_list_filter_for_dnskey(key_list);
01083 
01084                                 if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY)
01085                                         ldns_key_list_filter_for_non_dnskey(key_list);
01086 
01087                                 /* TODO: just set count to zero? */
01088                                 rr_list = ldns_rr_list_new();
01089 
01090                                 cur_rr = cur_rrset->rrs;
01091                                 while (cur_rr) {
01092                                         ldns_rr_list_push_rr(rr_list, cur_rr->rr);
01093                                         cur_rr = cur_rr->next;
01094                                 }
01095 
01096                                 /* only sign non-delegation RRsets */
01097                                 /* (glue should have been marked earlier, 
01098                                  *  except on the delegation points itself) */
01099                                 if (!on_delegation_point ||
01100                                                 ldns_rr_list_type(rr_list) 
01101                                                         == LDNS_RR_TYPE_DS ||
01102                                                 ldns_rr_list_type(rr_list) 
01103                                                         == LDNS_RR_TYPE_NSEC ||
01104                                                 ldns_rr_list_type(rr_list) 
01105                                                         == LDNS_RR_TYPE_NSEC3) {
01106                                         siglist = ldns_sign_public(rr_list, key_list);
01107                                         for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
01108                                                 if (cur_rrset->signatures) {
01109                                                         result = ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
01110                                                                                            ldns_rr_list_rr(siglist,
01111                                                                                                                     i));
01112                                                 } else {
01113                                                         cur_rrset->signatures = ldns_dnssec_rrs_new();
01114                                                         cur_rrset->signatures->rr =
01115                                                                 ldns_rr_list_rr(siglist, i);
01116                                                 }
01117                                                 if (new_rrs) {
01118                                                         ldns_rr_list_push_rr(new_rrs,
01119                                                                                                  ldns_rr_list_rr(siglist,
01120                                                                                                                           i));
01121                                                 }
01122                                         }
01123                                         ldns_rr_list_free(siglist);
01124                                 }
01125 
01126                                 ldns_rr_list_free(rr_list);
01127 
01128                                 cur_rrset = cur_rrset->next;
01129                         }
01130 
01131                         /* sign the nsec */
01132                         ldns_key_list_set_use(key_list, true);
01133                         cur_name->nsec_signatures =
01134                                 ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
01135                                                                                 key_list,
01136                                                                                 func,
01137                                                                                 arg);
01138                         ldns_key_list_filter_for_non_dnskey(key_list);
01139 
01140                         rr_list = ldns_rr_list_new();
01141                         ldns_rr_list_push_rr(rr_list, cur_name->nsec);
01142                         siglist = ldns_sign_public(rr_list, key_list);
01143 
01144                         for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
01145                                 if (cur_name->nsec_signatures) {
01146                                         result = ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
01147                                                                            ldns_rr_list_rr(siglist, i));
01148                                 } else {
01149                                         cur_name->nsec_signatures = ldns_dnssec_rrs_new();
01150                                         cur_name->nsec_signatures->rr =
01151                                                 ldns_rr_list_rr(siglist, i);
01152                                 }
01153                                 if (new_rrs) {
01154                                         ldns_rr_list_push_rr(new_rrs,
01155                                                                  ldns_rr_list_rr(siglist, i));
01156                                 }
01157                         }
01158 
01159                         ldns_rr_list_free(siglist);
01160                         ldns_rr_list_free(rr_list);
01161                 }
01162                 cur_node = ldns_rbtree_next(cur_node);
01163         }
01164 
01165         ldns_rr_list_deep_free(pubkey_list);
01166         return result;
01167 }
01168 
01169 ldns_status
01170 ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
01171                                   ldns_rr_list *new_rrs,
01172                                   ldns_key_list *key_list,
01173                                   int (*func)(ldns_rr *, void *),
01174                                   void *arg)
01175 {
01176         return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0);
01177 }
01178 
01179 ldns_status
01180 ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
01181                                   ldns_rr_list *new_rrs,
01182                                   ldns_key_list *key_list,
01183                                   int (*func)(ldns_rr *, void *),
01184                                   void *arg,
01185                                   int flags)
01186 {
01187         ldns_status result = LDNS_STATUS_OK;
01188 
01189         if (!zone || !new_rrs || !key_list) {
01190                 return LDNS_STATUS_ERR;
01191         }
01192 
01193         /* zone is already sorted */
01194         result = ldns_dnssec_zone_mark_glue(zone);
01195         if (result != LDNS_STATUS_OK) {
01196                 return result;
01197         }
01198 
01199         /* check whether we need to add nsecs */
01200         if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
01201                 result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
01202                 if (result != LDNS_STATUS_OK) {
01203                         return result;
01204                 }
01205         }
01206 
01207         result = ldns_dnssec_zone_create_rrsigs_flg(zone,
01208                                         new_rrs,
01209                                         key_list,
01210                                         func,
01211                                         arg,
01212                                         flags);
01213 
01214         return result;
01215 }
01216 
01217 ldns_status
01218 ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
01219                                            ldns_rr_list *new_rrs,
01220                                            ldns_key_list *key_list,
01221                                            int (*func)(ldns_rr *, void *),
01222                                            void *arg,
01223                                            uint8_t algorithm,
01224                                            uint8_t flags,
01225                                            uint16_t iterations,
01226                                            uint8_t salt_length,
01227                                            uint8_t *salt)
01228 {
01229         return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
01230                 func, arg, algorithm, flags, iterations, salt_length, salt, 0,
01231                 NULL);
01232 }
01233 
01234 ldns_status
01235 ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
01236                 ldns_rr_list *new_rrs,
01237                 ldns_key_list *key_list,
01238                 int (*func)(ldns_rr *, void *),
01239                 void *arg,
01240                 uint8_t algorithm,
01241                 uint8_t flags,
01242                 uint16_t iterations,
01243                 uint8_t salt_length,
01244                 uint8_t *salt,
01245                 int signflags,
01246                 ldns_rbtree_t **map)
01247 {
01248         ldns_rr *nsec3, *nsec3param;
01249         ldns_status result = LDNS_STATUS_OK;
01250 
01251         /* zone is already sorted */
01252         result = ldns_dnssec_zone_mark_glue(zone);
01253         if (result != LDNS_STATUS_OK) {
01254                 return result;
01255         }
01256 
01257         /* TODO if there are already nsec3s presents and their
01258          * parameters are the same as these, we don't have to recreate
01259          */
01260         if (zone->names) {
01261                 /* add empty nonterminals */
01262                 result = ldns_dnssec_zone_add_empty_nonterminals(zone);
01263                 if (result != LDNS_STATUS_OK) {
01264                         return result;
01265                 }
01266 
01267                 nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec;
01268                 if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
01269                         /* no need to recreate */
01270                 } else {
01271                         if (!ldns_dnssec_zone_find_rrset(zone,
01272                                                                            zone->soa->name,
01273                                                                            LDNS_RR_TYPE_NSEC3PARAM)) {
01274                                 /* create and add the nsec3param rr */
01275                                 nsec3param =
01276                                         ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAM);
01277                                 ldns_rr_set_owner(nsec3param,
01278                                                            ldns_rdf_clone(zone->soa->name));
01279                                 ldns_nsec3_add_param_rdfs(nsec3param,
01280                                                                          algorithm,
01281                                                                          flags,
01282                                                                          iterations,
01283                                                                          salt_length,
01284                                                                          salt);
01285                                 /* always set bit 7 of the flags to zero, according to
01286                                  * rfc5155 section 11. The bits are counted from right to left,
01287                                  * so bit 7 in rfc5155 is bit 0 in ldns */
01288                                 ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3param, 1)), 0, 0);
01289                                 result = ldns_dnssec_zone_add_rr(zone, nsec3param);
01290                                 if (result != LDNS_STATUS_OK) {
01291                                         return result;
01292                                 }
01293                                 ldns_rr_list_push_rr(new_rrs, nsec3param);
01294                         }
01295                         result = ldns_dnssec_zone_create_nsec3s_mkmap(zone,
01296                                                                                         new_rrs,
01297                                                                                         algorithm,
01298                                                                                         flags,
01299                                                                                         iterations,
01300                                                                                         salt_length,
01301                                                                                         salt,
01302                                                                                         map);
01303                         if (result != LDNS_STATUS_OK) {
01304                                 return result;
01305                         }
01306                 }
01307 
01308                 result = ldns_dnssec_zone_create_rrsigs_flg(zone,
01309                                                 new_rrs,
01310                                                 key_list,
01311                                                 func,
01312                                                 arg,
01313                                                 signflags);
01314         }
01315 
01316         return result;
01317 }
01318 
01319 ldns_status
01320 ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
01321                 ldns_rr_list *new_rrs,
01322                 ldns_key_list *key_list,
01323                 int (*func)(ldns_rr *, void *),
01324                 void *arg,
01325                 uint8_t algorithm,
01326                 uint8_t flags,
01327                 uint16_t iterations,
01328                 uint8_t salt_length,
01329                 uint8_t *salt,
01330                 int signflags)
01331 {
01332         return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
01333                 func, arg, algorithm, flags, iterations, salt_length, salt,
01334                 signflags, NULL);
01335 }
01336 
01337 ldns_zone *
01338 ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
01339 {
01340         ldns_dnssec_zone *dnssec_zone;
01341         ldns_zone *signed_zone;
01342         ldns_rr_list *new_rrs;
01343         size_t i;
01344 
01345         signed_zone = ldns_zone_new();
01346         dnssec_zone = ldns_dnssec_zone_new();
01347 
01348         (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
01349         ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
01350 
01351         for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
01352                 (void) ldns_dnssec_zone_add_rr(dnssec_zone,
01353                                                                  ldns_rr_list_rr(ldns_zone_rrs(zone),
01354                                                                                           i));
01355                 ldns_zone_push_rr(signed_zone,
01356                                            ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
01357                                                                                            i)));
01358         }
01359 
01360         new_rrs = ldns_rr_list_new();
01361         (void) ldns_dnssec_zone_sign(dnssec_zone,
01362                                                     new_rrs,
01363                                                     key_list,
01364                                                     ldns_dnssec_default_replace_signatures,
01365                                                     NULL);
01366 
01367         for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
01368                 ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
01369                                                  ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
01370         }
01371 
01372         ldns_rr_list_deep_free(new_rrs);
01373         ldns_dnssec_zone_free(dnssec_zone);
01374 
01375         return signed_zone;
01376 }
01377 
01378 ldns_zone *
01379 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)
01380 {
01381         ldns_dnssec_zone *dnssec_zone;
01382         ldns_zone *signed_zone;
01383         ldns_rr_list *new_rrs;
01384         size_t i;
01385 
01386         signed_zone = ldns_zone_new();
01387         dnssec_zone = ldns_dnssec_zone_new();
01388 
01389         (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
01390         ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
01391 
01392         for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
01393                 (void) ldns_dnssec_zone_add_rr(dnssec_zone,
01394                                                                  ldns_rr_list_rr(ldns_zone_rrs(zone),
01395                                                                                           i));
01396                 ldns_zone_push_rr(signed_zone, 
01397                                            ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
01398                                                                                            i)));
01399         }
01400 
01401         new_rrs = ldns_rr_list_new();
01402         (void) ldns_dnssec_zone_sign_nsec3(dnssec_zone,
01403                                                                 new_rrs,
01404                                                                 key_list,
01405                                                                 ldns_dnssec_default_replace_signatures,
01406                                                                 NULL,
01407                                                                 algorithm,
01408                                                                 flags,
01409                                                                 iterations,
01410                                                                 salt_length,
01411                                                                 salt);
01412 
01413         for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
01414                 ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
01415                                                  ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
01416         }
01417 
01418         ldns_rr_list_deep_free(new_rrs);
01419         ldns_dnssec_zone_free(dnssec_zone);
01420 
01421         return signed_zone;
01422 }
01423 #endif /* HAVE_SSL */
01424 
01425 

Generated on Wed Dec 19 16:56:49 2012 for ldns by  doxygen 1.4.7