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 static void
00775 ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
00776         (void) arg;
00777         LDNS_FREE(node);
00778 }
00779 
00780 static ldns_status
00781 ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
00782                 ldns_rr_list *new_rrs,
00783                 uint8_t algorithm,
00784                 uint8_t flags,
00785                 uint16_t iterations,
00786                 uint8_t salt_length,
00787                 uint8_t *salt,
00788                 ldns_rbtree_t **map)
00789 {
00790         ldns_rbnode_t *first_name_node;
00791         ldns_rbnode_t *current_name_node;
00792         ldns_dnssec_name *current_name;
00793         ldns_status result = LDNS_STATUS_OK;
00794         ldns_rr *nsec_rr;
00795         ldns_rr_list *nsec3_list;
00796         uint32_t nsec_ttl;
00797         ldns_dnssec_rrsets *soa;
00798         ldns_rbnode_t *hashmap_node;
00799 
00800         if (!zone || !new_rrs || !zone->names) {
00801                 return LDNS_STATUS_ERR;
00802         }
00803 
00804         /* the TTL of NSEC rrs should be set to the minimum TTL of
00805          * the zone SOA (RFC4035 Section 2.3)
00806          */
00807         soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
00808 
00809         /* did the caller actually set it? if not,
00810          * fall back to default ttl
00811          */
00812         if (soa && soa->rrs && soa->rrs->rr
00813                         && ldns_rr_rdf(soa->rrs->rr, 6) != NULL) {
00814                 nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
00815         } else {
00816                 nsec_ttl = LDNS_DEFAULT_TTL;
00817         }
00818 
00819         if (zone->hashed_names) {
00820                 ldns_traverse_postorder(zone->hashed_names,
00821                                 ldns_hashed_names_node_free, NULL);
00822                 LDNS_FREE(zone->hashed_names);
00823         }
00824         zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
00825         if (zone->hashed_names && map) {
00826                 *map = zone->hashed_names;
00827         }
00828 
00829         first_name_node = ldns_dnssec_name_node_next_nonglue(
00830                                           ldns_rbtree_first(zone->names));
00831 
00832         current_name_node = first_name_node;
00833 
00834         while (current_name_node && current_name_node != LDNS_RBTREE_NULL &&
00835                         result == LDNS_STATUS_OK) {
00836 
00837                 current_name = (ldns_dnssec_name *) current_name_node->data;
00838                 nsec_rr = ldns_dnssec_create_nsec3(current_name,
00839                                                    NULL,
00840                                                    zone->soa->name,
00841                                                    algorithm,
00842                                                    flags,
00843                                                    iterations,
00844                                                    salt_length,
00845                                                    salt);
00846                 /* by default, our nsec based generator adds rrsigs
00847                  * remove the bitmap for empty nonterminals */
00848                 if (!current_name->rrsets) {
00849                         ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
00850                 }
00851                 ldns_rr_set_ttl(nsec_rr, nsec_ttl);
00852                 result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
00853                 ldns_rr_list_push_rr(new_rrs, nsec_rr);
00854                 if (ldns_rr_owner(nsec_rr)) {
00855                         hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
00856                         if (hashmap_node == NULL) {
00857                                 return LDNS_STATUS_MEM_ERR;
00858                         }
00859                         current_name->hashed_name = 
00860                                 ldns_dname_label(ldns_rr_owner(nsec_rr), 0);
00861 
00862                         if (current_name->hashed_name == NULL) {
00863                                 LDNS_FREE(hashmap_node);
00864                                 return LDNS_STATUS_MEM_ERR;
00865                         }
00866                         hashmap_node->key  = current_name->hashed_name;
00867                         hashmap_node->data = current_name;
00868 
00869                         if (! ldns_rbtree_insert(zone->hashed_names
00870                                                 , hashmap_node)) {
00871                                 LDNS_FREE(hashmap_node);
00872                         }
00873                 }
00874                 current_name_node = ldns_dnssec_name_node_next_nonglue(
00875                                    ldns_rbtree_next(current_name_node));
00876         }
00877         if (result != LDNS_STATUS_OK) {
00878                 return result;
00879         }
00880 
00881         /* Make sorted list of nsec3s (via zone->hashed_names)
00882          */
00883         nsec3_list = ldns_rr_list_new();
00884         if (nsec3_list == NULL) {
00885                 return LDNS_STATUS_MEM_ERR;
00886         }
00887         for ( hashmap_node  = ldns_rbtree_first(zone->hashed_names)
00888             ; hashmap_node != LDNS_RBTREE_NULL
00889             ; hashmap_node  = ldns_rbtree_next(hashmap_node)
00890             ) {
00891                 current_name = (ldns_dnssec_name *) hashmap_node->data;
00892                 nsec_rr = ((ldns_dnssec_name *) hashmap_node->data)->nsec;
00893                 if (nsec_rr) {
00894                         ldns_rr_list_push_rr(nsec3_list, nsec_rr);
00895                 }
00896         }
00897         result = ldns_dnssec_chain_nsec3_list(nsec3_list);
00898         ldns_rr_list_free(nsec3_list);
00899 
00900         return result;
00901 }
00902 
00903 ldns_status
00904 ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
00905                 ldns_rr_list *new_rrs,
00906                 uint8_t algorithm,
00907                 uint8_t flags,
00908                 uint16_t iterations,
00909                 uint8_t salt_length,
00910                 uint8_t *salt)
00911 {
00912         return ldns_dnssec_zone_create_nsec3s_mkmap(zone, new_rrs, algorithm,
00913                         flags, iterations, salt_length, salt, NULL);
00914 
00915 }
00916 #endif /* HAVE_SSL */
00917 
00918 ldns_dnssec_rrs *
00919 ldns_dnssec_remove_signatures( ldns_dnssec_rrs *signatures
00920                              , ATTR_UNUSED(ldns_key_list *key_list)
00921                              , int (*func)(ldns_rr *, void *)
00922                              , void *arg
00923                              )
00924 {
00925         ldns_dnssec_rrs *base_rrs = signatures;
00926         ldns_dnssec_rrs *cur_rr = base_rrs;
00927         ldns_dnssec_rrs *prev_rr = NULL;
00928         ldns_dnssec_rrs *next_rr;
00929 
00930         uint16_t keytag;
00931         size_t i;
00932 
00933         if (!cur_rr) {
00934                 switch(func(NULL, arg)) {
00935                 case LDNS_SIGNATURE_LEAVE_ADD_NEW:
00936                 case LDNS_SIGNATURE_REMOVE_ADD_NEW:
00937                 break;
00938                 case LDNS_SIGNATURE_LEAVE_NO_ADD:
00939                 case LDNS_SIGNATURE_REMOVE_NO_ADD:
00940                 ldns_key_list_set_use(key_list, false);
00941                 break;
00942                 default:
00943 #ifdef STDERR_MSGS
00944                         fprintf(stderr, "[XX] unknown return value from callback\n");
00945 #endif
00946                         break;
00947                 }
00948                 return NULL;
00949         }
00950         (void)func(cur_rr->rr, arg);
00951 
00952         while (cur_rr) {
00953                 next_rr = cur_rr->next;
00954 
00955                 switch (func(cur_rr->rr, arg)) {
00956                 case  LDNS_SIGNATURE_LEAVE_ADD_NEW:
00957                         prev_rr = cur_rr;
00958                         break;
00959                 case LDNS_SIGNATURE_LEAVE_NO_ADD:
00960                         keytag = ldns_rdf2native_int16(
00961                                            ldns_rr_rrsig_keytag(cur_rr->rr));
00962                         for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
00963                                 if (ldns_key_keytag(ldns_key_list_key(key_list, i)) ==
00964                                     keytag) {
00965                                         ldns_key_set_use(ldns_key_list_key(key_list, i),
00966                                                                   false);
00967                                 }
00968                         }
00969                         prev_rr = cur_rr;
00970                         break;
00971                 case LDNS_SIGNATURE_REMOVE_NO_ADD:
00972                         keytag = ldns_rdf2native_int16(
00973                                            ldns_rr_rrsig_keytag(cur_rr->rr));
00974                         for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
00975                                 if (ldns_key_keytag(ldns_key_list_key(key_list, i))
00976                                     == keytag) {
00977                                         ldns_key_set_use(ldns_key_list_key(key_list, i),
00978                                                                   false);
00979                                 }
00980                         }
00981                         if (prev_rr) {
00982                                 prev_rr->next = next_rr;
00983                         } else {
00984                                 base_rrs = next_rr;
00985                         }
00986                         LDNS_FREE(cur_rr);
00987                         break;
00988                 case LDNS_SIGNATURE_REMOVE_ADD_NEW:
00989                         if (prev_rr) {
00990                                 prev_rr->next = next_rr;
00991                         } else {
00992                                 base_rrs = next_rr;
00993                         }
00994                         LDNS_FREE(cur_rr);
00995                         break;
00996                 default:
00997 #ifdef STDERR_MSGS
00998                         fprintf(stderr, "[XX] unknown return value from callback\n");
00999 #endif
01000                         break;
01001                 }
01002                 cur_rr = next_rr;
01003         }
01004 
01005         return base_rrs;
01006 }
01007 
01008 #ifdef HAVE_SSL
01009 ldns_status
01010 ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
01011                                ldns_rr_list *new_rrs,
01012                                ldns_key_list *key_list,
01013                                int (*func)(ldns_rr *, void*),
01014                                void *arg)
01015 {
01016         return ldns_dnssec_zone_create_rrsigs_flg(zone, new_rrs, key_list,
01017                 func, arg, 0);
01018 }
01019 
01021 static void
01022 ldns_key_list_filter_for_dnskey(ldns_key_list *key_list)
01023 {
01024         int saw_ksk = 0;
01025         size_t i;
01026         for(i=0; i<ldns_key_list_key_count(key_list); i++)
01027                 if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
01028                         saw_ksk = 1;
01029                         break;
01030                 }
01031         if(!saw_ksk)
01032                 return;
01033         for(i=0; i<ldns_key_list_key_count(key_list); i++)
01034                 if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
01035                         ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
01036 }
01037 
01039 static void
01040 ldns_key_list_filter_for_non_dnskey(ldns_key_list *key_list)
01041 {
01042         int saw_zsk = 0;
01043         size_t i;
01044         for(i=0; i<ldns_key_list_key_count(key_list); i++)
01045                 if(!(ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY)) {
01046                         saw_zsk = 1;
01047                         break;
01048                 }
01049         if(!saw_zsk)
01050                 return;
01051         /* else filter all KSKs */
01052         for(i=0; i<ldns_key_list_key_count(key_list); i++)
01053                 if((ldns_key_flags(ldns_key_list_key(key_list, i))&LDNS_KEY_SEP_KEY))
01054                         ldns_key_set_use(ldns_key_list_key(key_list, i), 0);
01055 }
01056 
01057 ldns_status
01058 ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone
01059                                   , ldns_rr_list *new_rrs
01060                                   , ldns_key_list *key_list
01061                                   , int (*func)(ldns_rr *, void*)
01062                                   , void *arg
01063                                   , int flags
01064                                   )
01065 {
01066         ldns_status result = LDNS_STATUS_OK;
01067 
01068         ldns_rbnode_t *cur_node;
01069         ldns_rr_list *rr_list;
01070 
01071         ldns_dnssec_name *cur_name;
01072         ldns_dnssec_rrsets *cur_rrset;
01073         ldns_dnssec_rrs *cur_rr;
01074 
01075         ldns_rr_list *siglist;
01076 
01077         size_t i;
01078 
01079         int on_delegation_point = 0; /* handle partially occluded names */
01080 
01081         ldns_rr_list *pubkey_list = ldns_rr_list_new();
01082         for (i = 0; i<ldns_key_list_key_count(key_list); i++) {
01083                 ldns_rr_list_push_rr( pubkey_list
01084                                     , ldns_key2rr(ldns_key_list_key(
01085                                                         key_list, i))
01086                                     );
01087         }
01088         /* TODO: callback to see is list should be signed */
01089         /* TODO: remove 'old' signatures from signature list */
01090         cur_node = ldns_rbtree_first(zone->names);
01091         while (cur_node != LDNS_RBTREE_NULL) {
01092                 cur_name = (ldns_dnssec_name *) cur_node->data;
01093 
01094                 if (!cur_name->is_glue) {
01095                         on_delegation_point = ldns_dnssec_rrsets_contains_type(
01096                                         cur_name->rrsets, LDNS_RR_TYPE_NS)
01097                                 && !ldns_dnssec_rrsets_contains_type(
01098                                         cur_name->rrsets, LDNS_RR_TYPE_SOA);
01099                         cur_rrset = cur_name->rrsets;
01100                         while (cur_rrset) {
01101                                 /* reset keys to use */
01102                                 ldns_key_list_set_use(key_list, true);
01103 
01104                                 /* walk through old sigs, remove the old,
01105                                    and mark which keys (not) to use) */
01106                                 cur_rrset->signatures =
01107                                         ldns_dnssec_remove_signatures(cur_rrset->signatures,
01108                                                                                         key_list,
01109                                                                                         func,
01110                                                                                         arg);
01111                                 if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) &&
01112                                         cur_rrset->type == LDNS_RR_TYPE_DNSKEY)
01113                                         ldns_key_list_filter_for_dnskey(key_list);
01114 
01115                                 if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY)
01116                                         ldns_key_list_filter_for_non_dnskey(key_list);
01117 
01118                                 /* TODO: just set count to zero? */
01119                                 rr_list = ldns_rr_list_new();
01120 
01121                                 cur_rr = cur_rrset->rrs;
01122                                 while (cur_rr) {
01123                                         ldns_rr_list_push_rr(rr_list, cur_rr->rr);
01124                                         cur_rr = cur_rr->next;
01125                                 }
01126 
01127                                 /* only sign non-delegation RRsets */
01128                                 /* (glue should have been marked earlier, 
01129                                  *  except on the delegation points itself) */
01130                                 if (!on_delegation_point ||
01131                                                 ldns_rr_list_type(rr_list) 
01132                                                         == LDNS_RR_TYPE_DS ||
01133                                                 ldns_rr_list_type(rr_list) 
01134                                                         == LDNS_RR_TYPE_NSEC ||
01135                                                 ldns_rr_list_type(rr_list) 
01136                                                         == LDNS_RR_TYPE_NSEC3) {
01137                                         siglist = ldns_sign_public(rr_list, key_list);
01138                                         for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
01139                                                 if (cur_rrset->signatures) {
01140                                                         result = ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
01141                                                                                            ldns_rr_list_rr(siglist,
01142                                                                                                                     i));
01143                                                 } else {
01144                                                         cur_rrset->signatures = ldns_dnssec_rrs_new();
01145                                                         cur_rrset->signatures->rr =
01146                                                                 ldns_rr_list_rr(siglist, i);
01147                                                 }
01148                                                 if (new_rrs) {
01149                                                         ldns_rr_list_push_rr(new_rrs,
01150                                                                                                  ldns_rr_list_rr(siglist,
01151                                                                                                                           i));
01152                                                 }
01153                                         }
01154                                         ldns_rr_list_free(siglist);
01155                                 }
01156 
01157                                 ldns_rr_list_free(rr_list);
01158 
01159                                 cur_rrset = cur_rrset->next;
01160                         }
01161 
01162                         /* sign the nsec */
01163                         ldns_key_list_set_use(key_list, true);
01164                         cur_name->nsec_signatures =
01165                                 ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
01166                                                                                 key_list,
01167                                                                                 func,
01168                                                                                 arg);
01169                         ldns_key_list_filter_for_non_dnskey(key_list);
01170 
01171                         rr_list = ldns_rr_list_new();
01172                         ldns_rr_list_push_rr(rr_list, cur_name->nsec);
01173                         siglist = ldns_sign_public(rr_list, key_list);
01174 
01175                         for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
01176                                 if (cur_name->nsec_signatures) {
01177                                         result = ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
01178                                                                            ldns_rr_list_rr(siglist, i));
01179                                 } else {
01180                                         cur_name->nsec_signatures = ldns_dnssec_rrs_new();
01181                                         cur_name->nsec_signatures->rr =
01182                                                 ldns_rr_list_rr(siglist, i);
01183                                 }
01184                                 if (new_rrs) {
01185                                         ldns_rr_list_push_rr(new_rrs,
01186                                                                  ldns_rr_list_rr(siglist, i));
01187                                 }
01188                         }
01189 
01190                         ldns_rr_list_free(siglist);
01191                         ldns_rr_list_free(rr_list);
01192                 }
01193                 cur_node = ldns_rbtree_next(cur_node);
01194         }
01195 
01196         ldns_rr_list_deep_free(pubkey_list);
01197         return result;
01198 }
01199 
01200 ldns_status
01201 ldns_dnssec_zone_sign(ldns_dnssec_zone *zone,
01202                                   ldns_rr_list *new_rrs,
01203                                   ldns_key_list *key_list,
01204                                   int (*func)(ldns_rr *, void *),
01205                                   void *arg)
01206 {
01207         return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0);
01208 }
01209 
01210 ldns_status
01211 ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
01212                                   ldns_rr_list *new_rrs,
01213                                   ldns_key_list *key_list,
01214                                   int (*func)(ldns_rr *, void *),
01215                                   void *arg,
01216                                   int flags)
01217 {
01218         ldns_status result = LDNS_STATUS_OK;
01219 
01220         if (!zone || !new_rrs || !key_list) {
01221                 return LDNS_STATUS_ERR;
01222         }
01223 
01224         /* zone is already sorted */
01225         result = ldns_dnssec_zone_mark_glue(zone);
01226         if (result != LDNS_STATUS_OK) {
01227                 return result;
01228         }
01229 
01230         /* check whether we need to add nsecs */
01231         if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
01232                 result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
01233                 if (result != LDNS_STATUS_OK) {
01234                         return result;
01235                 }
01236         }
01237 
01238         result = ldns_dnssec_zone_create_rrsigs_flg(zone,
01239                                         new_rrs,
01240                                         key_list,
01241                                         func,
01242                                         arg,
01243                                         flags);
01244 
01245         return result;
01246 }
01247 
01248 ldns_status
01249 ldns_dnssec_zone_sign_nsec3(ldns_dnssec_zone *zone,
01250                                            ldns_rr_list *new_rrs,
01251                                            ldns_key_list *key_list,
01252                                            int (*func)(ldns_rr *, void *),
01253                                            void *arg,
01254                                            uint8_t algorithm,
01255                                            uint8_t flags,
01256                                            uint16_t iterations,
01257                                            uint8_t salt_length,
01258                                            uint8_t *salt)
01259 {
01260         return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
01261                 func, arg, algorithm, flags, iterations, salt_length, salt, 0,
01262                 NULL);
01263 }
01264 
01265 ldns_status
01266 ldns_dnssec_zone_sign_nsec3_flg_mkmap(ldns_dnssec_zone *zone,
01267                 ldns_rr_list *new_rrs,
01268                 ldns_key_list *key_list,
01269                 int (*func)(ldns_rr *, void *),
01270                 void *arg,
01271                 uint8_t algorithm,
01272                 uint8_t flags,
01273                 uint16_t iterations,
01274                 uint8_t salt_length,
01275                 uint8_t *salt,
01276                 int signflags,
01277                 ldns_rbtree_t **map)
01278 {
01279         ldns_rr *nsec3, *nsec3param;
01280         ldns_status result = LDNS_STATUS_OK;
01281 
01282         /* zone is already sorted */
01283         result = ldns_dnssec_zone_mark_glue(zone);
01284         if (result != LDNS_STATUS_OK) {
01285                 return result;
01286         }
01287 
01288         /* TODO if there are already nsec3s presents and their
01289          * parameters are the same as these, we don't have to recreate
01290          */
01291         if (zone->names) {
01292                 /* add empty nonterminals */
01293                 result = ldns_dnssec_zone_add_empty_nonterminals(zone);
01294                 if (result != LDNS_STATUS_OK) {
01295                         return result;
01296                 }
01297 
01298                 nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec;
01299                 if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
01300                         /* no need to recreate */
01301                 } else {
01302                         if (!ldns_dnssec_zone_find_rrset(zone,
01303                                                                            zone->soa->name,
01304                                                                            LDNS_RR_TYPE_NSEC3PARAM)) {
01305                                 /* create and add the nsec3param rr */
01306                                 nsec3param =
01307                                         ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAM);
01308                                 ldns_rr_set_owner(nsec3param,
01309                                                            ldns_rdf_clone(zone->soa->name));
01310                                 ldns_nsec3_add_param_rdfs(nsec3param,
01311                                                                          algorithm,
01312                                                                          flags,
01313                                                                          iterations,
01314                                                                          salt_length,
01315                                                                          salt);
01316                                 /* always set bit 7 of the flags to zero, according to
01317                                  * rfc5155 section 11. The bits are counted from right to left,
01318                                  * so bit 7 in rfc5155 is bit 0 in ldns */
01319                                 ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(nsec3param, 1)), 0, 0);
01320                                 result = ldns_dnssec_zone_add_rr(zone, nsec3param);
01321                                 if (result != LDNS_STATUS_OK) {
01322                                         return result;
01323                                 }
01324                                 ldns_rr_list_push_rr(new_rrs, nsec3param);
01325                         }
01326                         result = ldns_dnssec_zone_create_nsec3s_mkmap(zone,
01327                                                                                         new_rrs,
01328                                                                                         algorithm,
01329                                                                                         flags,
01330                                                                                         iterations,
01331                                                                                         salt_length,
01332                                                                                         salt,
01333                                                                                         map);
01334                         if (result != LDNS_STATUS_OK) {
01335                                 return result;
01336                         }
01337                 }
01338 
01339                 result = ldns_dnssec_zone_create_rrsigs_flg(zone,
01340                                                 new_rrs,
01341                                                 key_list,
01342                                                 func,
01343                                                 arg,
01344                                                 signflags);
01345         }
01346 
01347         return result;
01348 }
01349 
01350 ldns_status
01351 ldns_dnssec_zone_sign_nsec3_flg(ldns_dnssec_zone *zone,
01352                 ldns_rr_list *new_rrs,
01353                 ldns_key_list *key_list,
01354                 int (*func)(ldns_rr *, void *),
01355                 void *arg,
01356                 uint8_t algorithm,
01357                 uint8_t flags,
01358                 uint16_t iterations,
01359                 uint8_t salt_length,
01360                 uint8_t *salt,
01361                 int signflags)
01362 {
01363         return ldns_dnssec_zone_sign_nsec3_flg_mkmap(zone, new_rrs, key_list,
01364                 func, arg, algorithm, flags, iterations, salt_length, salt,
01365                 signflags, NULL);
01366 }
01367 
01368 ldns_zone *
01369 ldns_zone_sign(const ldns_zone *zone, ldns_key_list *key_list)
01370 {
01371         ldns_dnssec_zone *dnssec_zone;
01372         ldns_zone *signed_zone;
01373         ldns_rr_list *new_rrs;
01374         size_t i;
01375 
01376         signed_zone = ldns_zone_new();
01377         dnssec_zone = ldns_dnssec_zone_new();
01378 
01379         (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
01380         ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
01381 
01382         for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
01383                 (void) ldns_dnssec_zone_add_rr(dnssec_zone,
01384                                                                  ldns_rr_list_rr(ldns_zone_rrs(zone),
01385                                                                                           i));
01386                 ldns_zone_push_rr(signed_zone,
01387                                            ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
01388                                                                                            i)));
01389         }
01390 
01391         new_rrs = ldns_rr_list_new();
01392         (void) ldns_dnssec_zone_sign(dnssec_zone,
01393                                                     new_rrs,
01394                                                     key_list,
01395                                                     ldns_dnssec_default_replace_signatures,
01396                                                     NULL);
01397 
01398         for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
01399                 ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
01400                                                  ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
01401         }
01402 
01403         ldns_rr_list_deep_free(new_rrs);
01404         ldns_dnssec_zone_free(dnssec_zone);
01405 
01406         return signed_zone;
01407 }
01408 
01409 ldns_zone *
01410 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)
01411 {
01412         ldns_dnssec_zone *dnssec_zone;
01413         ldns_zone *signed_zone;
01414         ldns_rr_list *new_rrs;
01415         size_t i;
01416 
01417         signed_zone = ldns_zone_new();
01418         dnssec_zone = ldns_dnssec_zone_new();
01419 
01420         (void) ldns_dnssec_zone_add_rr(dnssec_zone, ldns_zone_soa(zone));
01421         ldns_zone_set_soa(signed_zone, ldns_rr_clone(ldns_zone_soa(zone)));
01422 
01423         for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) {
01424                 (void) ldns_dnssec_zone_add_rr(dnssec_zone,
01425                                                                  ldns_rr_list_rr(ldns_zone_rrs(zone),
01426                                                                                           i));
01427                 ldns_zone_push_rr(signed_zone, 
01428                                            ldns_rr_clone(ldns_rr_list_rr(ldns_zone_rrs(zone),
01429                                                                                            i)));
01430         }
01431 
01432         new_rrs = ldns_rr_list_new();
01433         (void) ldns_dnssec_zone_sign_nsec3(dnssec_zone,
01434                                                                 new_rrs,
01435                                                                 key_list,
01436                                                                 ldns_dnssec_default_replace_signatures,
01437                                                                 NULL,
01438                                                                 algorithm,
01439                                                                 flags,
01440                                                                 iterations,
01441                                                                 salt_length,
01442                                                                 salt);
01443 
01444         for (i = 0; i < ldns_rr_list_rr_count(new_rrs); i++) {
01445                 ldns_rr_list_push_rr(ldns_zone_rrs(signed_zone),
01446                                                  ldns_rr_clone(ldns_rr_list_rr(new_rrs, i)));
01447         }
01448 
01449         ldns_rr_list_deep_free(new_rrs);
01450         ldns_dnssec_zone_free(dnssec_zone);
01451 
01452         return signed_zone;
01453 }
01454 #endif /* HAVE_SSL */
01455 
01456