keys.c
Go to the documentation of this file.
00001 /*
00002  * keys.c handle private keys for use in DNSSEC
00003  *
00004  * This module should hide some of the openSSL complexities
00005  * and give a general interface for private keys and hmac
00006  * handling
00007  *
00008  * (c) NLnet Labs, 2004-2006
00009  *
00010  * See the file LICENSE for the license
00011  */
00012 
00013 #include <ldns/config.h>
00014 
00015 #include <ldns/ldns.h>
00016 
00017 #ifdef HAVE_SSL
00018 #include <openssl/ssl.h>
00019 #include <openssl/engine.h>
00020 #include <openssl/rand.h>
00021 #endif /* HAVE_SSL */
00022 
00023 ldns_lookup_table ldns_signing_algorithms[] = {
00024         { LDNS_SIGN_RSAMD5, "RSAMD5" },
00025         { LDNS_SIGN_RSASHA1, "RSASHA1" },
00026         { LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
00027 #ifdef USE_SHA2
00028         { LDNS_SIGN_RSASHA256, "RSASHA256" },
00029         { LDNS_SIGN_RSASHA512, "RSASHA512" },
00030 #endif
00031 #ifdef USE_GOST
00032         { LDNS_SIGN_ECC_GOST, "ECC-GOST" },
00033 #endif
00034 #ifdef USE_ECDSA
00035         { LDNS_SIGN_ECDSAP256SHA256, "ECDSAP256SHA256" },
00036         { LDNS_SIGN_ECDSAP384SHA384, "ECDSAP384SHA384" },
00037 #endif
00038         { LDNS_SIGN_DSA, "DSA" },
00039         { LDNS_SIGN_DSA_NSEC3, "DSA-NSEC3-SHA1" },
00040         { LDNS_SIGN_HMACMD5, "hmac-md5.sig-alg.reg.int" },
00041         { LDNS_SIGN_HMACSHA1, "hmac-sha1" },
00042         { LDNS_SIGN_HMACSHA256, "hmac-sha256" },
00043         { 0, NULL }
00044 };
00045 
00046 ldns_key_list *
00047 ldns_key_list_new()
00048 {
00049         ldns_key_list *key_list = LDNS_MALLOC(ldns_key_list);
00050         if (!key_list) {
00051                 return NULL;
00052         } else {
00053                 key_list->_key_count = 0;
00054                 key_list->_keys = NULL;
00055                 return key_list;
00056         }
00057 }
00058 
00059 ldns_key *
00060 ldns_key_new()
00061 {
00062         ldns_key *newkey;
00063 
00064         newkey = LDNS_MALLOC(ldns_key);
00065         if (!newkey) {
00066                 return NULL;
00067         } else {
00068                 /* some defaults - not sure wether to do this */
00069                 ldns_key_set_use(newkey, true);
00070                 ldns_key_set_flags(newkey, LDNS_KEY_ZONE_KEY);
00071                 ldns_key_set_origttl(newkey, 0);
00072                 ldns_key_set_keytag(newkey, 0);
00073                 ldns_key_set_inception(newkey, 0);
00074                 ldns_key_set_expiration(newkey, 0);
00075                 ldns_key_set_pubkey_owner(newkey, NULL);
00076 #ifdef HAVE_SSL
00077                 ldns_key_set_evp_key(newkey, NULL);
00078 #endif /* HAVE_SSL */
00079                 ldns_key_set_hmac_key(newkey, NULL);
00080                 ldns_key_set_external_key(newkey, NULL);
00081                 return newkey;
00082         }
00083 }
00084 
00085 ldns_status
00086 ldns_key_new_frm_fp(ldns_key **k, FILE *fp)
00087 {
00088         return ldns_key_new_frm_fp_l(k, fp, NULL);
00089 }
00090 
00091 #ifdef HAVE_SSL
00092 ldns_status
00093 ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm alg)
00094 {
00095         ldns_key *k;
00096 
00097         k = ldns_key_new();
00098         if(!k) return LDNS_STATUS_MEM_ERR;
00099 #ifndef S_SPLINT_S
00100         k->_key.key = ENGINE_load_private_key(e, key_id, UI_OpenSSL(), NULL);
00101         if(!k->_key.key) {
00102                 ldns_key_free(k);
00103                 return LDNS_STATUS_ERR;
00104         }
00105         ldns_key_set_algorithm(k, (ldns_signing_algorithm) alg);
00106         if (!k->_key.key) {
00107                 ldns_key_free(k);
00108                 return LDNS_STATUS_ENGINE_KEY_NOT_LOADED;
00109         } 
00110 #endif /* splint */
00111         *key = k;
00112         return LDNS_STATUS_OK;
00113 }
00114 #endif
00115 
00116 #ifdef USE_GOST
00117 
00118 ENGINE* ldns_gost_engine = NULL;
00119 
00120 int
00121 ldns_key_EVP_load_gost_id(void)
00122 {
00123         static int gost_id = 0;
00124         const EVP_PKEY_ASN1_METHOD* meth;
00125         ENGINE* e;
00126 
00127         if(gost_id) return gost_id;
00128 
00129         /* see if configuration loaded gost implementation from other engine*/
00130         meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
00131         if(meth) {
00132                 EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
00133                 return gost_id;
00134         }
00135 
00136         /* see if engine can be loaded already */
00137         e = ENGINE_by_id("gost");
00138         if(!e) {
00139                 /* load it ourself, in case statically linked */
00140                 ENGINE_load_builtin_engines();
00141                 ENGINE_load_dynamic();
00142                 e = ENGINE_by_id("gost");
00143         }
00144         if(!e) {
00145                 /* no gost engine in openssl */
00146                 return 0;
00147         }
00148         if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
00149                 ENGINE_finish(e);
00150                 ENGINE_free(e);
00151                 return 0;
00152         }
00153 
00154         meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
00155         if(!meth) {
00156                 /* algo not found */
00157                 ENGINE_finish(e);
00158                 ENGINE_free(e);
00159                 return 0;
00160         }
00161         /* Note: do not ENGINE_finish and ENGINE_free the acquired engine
00162          * on some platforms this frees up the meth and unloads gost stuff */
00163         ldns_gost_engine = e;
00164         
00165         EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
00166         return gost_id;
00167 } 
00168 
00169 void ldns_key_EVP_unload_gost(void)
00170 {
00171         if(ldns_gost_engine) {
00172                 ENGINE_finish(ldns_gost_engine);
00173                 ENGINE_free(ldns_gost_engine);
00174                 ldns_gost_engine = NULL;
00175         }
00176 }
00177 
00179 static EVP_PKEY*
00180 ldns_key_new_frm_fp_gost_l(FILE* fp, int* line_nr)
00181 {
00182         char token[16384];
00183         const unsigned char* pp;
00184         int gost_id;
00185         EVP_PKEY* pkey;
00186         ldns_rdf* b64rdf = NULL;
00187 
00188         gost_id = ldns_key_EVP_load_gost_id();
00189         if(!gost_id)
00190                 return NULL;
00191 
00192         if (ldns_fget_keyword_data_l(fp, "GostAsn1", ": ", token, "\n", 
00193                 sizeof(token), line_nr) == -1)
00194                 return NULL;
00195         while(strlen(token) < 96) {
00196                 /* read more b64 from the file, b64 split on multiple lines */
00197                 if(ldns_fget_token_l(fp, token+strlen(token), "\n",
00198                         sizeof(token)-strlen(token), line_nr) == -1)
00199                         return NULL;
00200         }
00201         if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
00202                 return NULL;
00203         pp = (unsigned char*)ldns_rdf_data(b64rdf);
00204         pkey = d2i_PrivateKey(gost_id, NULL, &pp, (int)ldns_rdf_size(b64rdf));
00205         ldns_rdf_deep_free(b64rdf);
00206         return pkey;
00207 }
00208 #endif
00209 
00210 #ifdef USE_ECDSA
00211 
00212 static int
00213 ldns_EC_KEY_calc_public(EC_KEY* ec)
00214 {
00215         EC_POINT* pub_key;
00216         const EC_GROUP* group;
00217         group = EC_KEY_get0_group(ec);
00218         pub_key = EC_POINT_new(group);
00219         if(!pub_key) return 0;
00220         if(!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
00221                 EC_POINT_free(pub_key);
00222                 return 0;
00223         }
00224         if(!EC_POINT_mul(group, pub_key, EC_KEY_get0_private_key(ec),
00225                 NULL, NULL, NULL)) {
00226                 EC_POINT_free(pub_key);
00227                 return 0;
00228         }
00229         if(EC_KEY_set_public_key(ec, pub_key) == 0) {
00230                 EC_POINT_free(pub_key);
00231                 return 0;
00232         }
00233         EC_POINT_free(pub_key);
00234         return 1;
00235 }
00236 
00238 static EVP_PKEY*
00239 ldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr)
00240 {
00241         char token[16384];
00242         ldns_rdf* b64rdf = NULL;
00243         unsigned char* pp;
00244         BIGNUM* bn;
00245         EVP_PKEY* evp_key;
00246         EC_KEY* ec;
00247         if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", 
00248                 sizeof(token), line_nr) == -1)
00249                 return NULL;
00250         if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
00251                 return NULL;
00252         pp = (unsigned char*)ldns_rdf_data(b64rdf);
00253 
00254         if(alg == LDNS_ECDSAP256SHA256)
00255                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
00256         else if(alg == LDNS_ECDSAP384SHA384)
00257                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
00258         else    ec = NULL;
00259         if(!ec) {
00260                 ldns_rdf_deep_free(b64rdf);
00261                 return NULL;
00262         }
00263         bn = BN_bin2bn(pp, (int)ldns_rdf_size(b64rdf), NULL);
00264         ldns_rdf_deep_free(b64rdf);
00265         if(!bn) {
00266                 EC_KEY_free(ec);
00267                 return NULL;
00268         }
00269         EC_KEY_set_private_key(ec, bn);
00270         BN_free(bn);
00271         if(!ldns_EC_KEY_calc_public(ec)) {
00272                 EC_KEY_free(ec);
00273                 return NULL;
00274         }
00275 
00276         evp_key = EVP_PKEY_new();
00277         if(!evp_key) {
00278                 EC_KEY_free(ec);
00279                 return NULL;
00280         }
00281         if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
00282                 EVP_PKEY_free(evp_key);
00283                 EC_KEY_free(ec);
00284                 return NULL;
00285         }
00286         return evp_key;
00287 }
00288 #endif
00289         
00290 ldns_status
00291 ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
00292 {
00293         ldns_key *k;
00294         char *d;
00295         ldns_signing_algorithm alg;
00296         ldns_rr *key_rr;
00297 #ifdef HAVE_SSL
00298         RSA *rsa;
00299         DSA *dsa;
00300         unsigned char *hmac;
00301         size_t hmac_size;
00302 #endif /* HAVE_SSL */
00303 
00304         k = ldns_key_new();
00305 
00306         d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
00307         if (!k || !d) {
00308                 ldns_key_free(k);
00309                 LDNS_FREE(d);
00310                 return LDNS_STATUS_MEM_ERR;
00311         }
00312 
00313         alg = 0;
00314 
00315         /* the file is highly structured. Do this in sequence */
00316         /* RSA:
00317          * Private-key-format: v1.x.
00318          * Algorithm: 1 (RSA)
00319 
00320          */
00321         /* get the key format version number */
00322         if (ldns_fget_keyword_data_l(fp, "Private-key-format", ": ", d, "\n",
00323                                 LDNS_MAX_LINELEN, line_nr) == -1) {
00324                 /* no version information */
00325                 ldns_key_free(k);
00326                 LDNS_FREE(d);
00327                 return LDNS_STATUS_SYNTAX_ERR;
00328         }
00329         if (strncmp(d, "v1.", 3) != 0) {
00330                 ldns_key_free(k);
00331                 LDNS_FREE(d);
00332                 return LDNS_STATUS_SYNTAX_VERSION_ERR;
00333         }
00334 
00335         /* get the algorithm type, our file function strip ( ) so there are
00336          * not in the return string! */
00337         if (ldns_fget_keyword_data_l(fp, "Algorithm", ": ", d, "\n",
00338                                 LDNS_MAX_LINELEN, line_nr) == -1) {
00339                 /* no alg information */
00340                 ldns_key_free(k);
00341                 LDNS_FREE(d);
00342                 return LDNS_STATUS_SYNTAX_ALG_ERR;
00343         }
00344 
00345         if (strncmp(d, "1 RSA", 2) == 0) {
00346                 alg = LDNS_SIGN_RSAMD5;
00347         }
00348         if (strncmp(d, "2 DH", 2) == 0) {
00349                 alg = (ldns_signing_algorithm)LDNS_DH;
00350         }
00351         if (strncmp(d, "3 DSA", 2) == 0) {
00352                 alg = LDNS_SIGN_DSA;
00353         }
00354         if (strncmp(d, "4 ECC", 2) == 0) {
00355                 alg = (ldns_signing_algorithm)LDNS_ECC;
00356         }
00357         if (strncmp(d, "5 RSASHA1", 2) == 0) {
00358                 alg = LDNS_SIGN_RSASHA1;
00359         }
00360         if (strncmp(d, "6 DSA", 2) == 0) {
00361                 alg = LDNS_SIGN_DSA_NSEC3;
00362         }
00363         if (strncmp(d, "7 RSASHA1", 2) == 0) {
00364                 alg = LDNS_SIGN_RSASHA1_NSEC3;
00365         }
00366 
00367         if (strncmp(d, "8 RSASHA256", 2) == 0) {
00368 #ifdef USE_SHA2
00369                 alg = LDNS_SIGN_RSASHA256;
00370 #else
00371                 fprintf(stderr, "Warning: SHA256 not compiled into this ");
00372                 fprintf(stderr, "version of ldns\n");
00373 #endif
00374         }
00375         if (strncmp(d, "10 RSASHA512", 3) == 0) {
00376 #ifdef USE_SHA2
00377                 alg = LDNS_SIGN_RSASHA512;
00378 #else
00379                 fprintf(stderr, "Warning: SHA512 not compiled into this ");
00380                 fprintf(stderr, "version of ldns\n");
00381 #endif
00382         }
00383         if (strncmp(d, "12 ECC-GOST", 3) == 0) {
00384 #ifdef USE_GOST
00385                 alg = LDNS_SIGN_ECC_GOST;
00386 #else
00387                 fprintf(stderr, "Warning: ECC-GOST not compiled into this ");
00388                 fprintf(stderr, "version of ldns, use --enable-gost\n");
00389 #endif
00390         }
00391         if (strncmp(d, "13 ECDSAP256SHA256", 3) == 0) {
00392 #ifdef USE_ECDSA
00393                 alg = LDNS_SIGN_ECDSAP256SHA256;
00394 #else
00395                 fprintf(stderr, "Warning: ECDSA not compiled into this ");
00396                 fprintf(stderr, "version of ldns, use --enable-ecdsa\n");
00397 #endif
00398         }
00399         if (strncmp(d, "14 ECDSAP384SHA384", 3) == 0) {
00400 #ifdef USE_ECDSA
00401                 alg = LDNS_SIGN_ECDSAP384SHA384;
00402 #else
00403                 fprintf(stderr, "Warning: ECDSA not compiled into this ");
00404                 fprintf(stderr, "version of ldns, use --enable-ecdsa\n");
00405 #endif
00406         }
00407         if (strncmp(d, "157 HMAC-MD5", 4) == 0) {
00408                 alg = LDNS_SIGN_HMACMD5;
00409         }
00410         if (strncmp(d, "158 HMAC-SHA1", 4) == 0) {
00411                 alg = LDNS_SIGN_HMACSHA1;
00412         }
00413         if (strncmp(d, "159 HMAC-SHA256", 4) == 0) {
00414                 alg = LDNS_SIGN_HMACSHA256;
00415         }
00416 
00417         LDNS_FREE(d);
00418 
00419         switch(alg) {
00420                 case LDNS_SIGN_RSAMD5:
00421                 case LDNS_SIGN_RSASHA1:
00422                 case LDNS_SIGN_RSASHA1_NSEC3:
00423 #ifdef USE_SHA2
00424                 case LDNS_SIGN_RSASHA256:
00425                 case LDNS_SIGN_RSASHA512:
00426 #endif
00427                         ldns_key_set_algorithm(k, alg);
00428 #ifdef HAVE_SSL
00429                         rsa = ldns_key_new_frm_fp_rsa_l(fp, line_nr);
00430                         if (!rsa) {
00431                                 ldns_key_free(k);
00432                                 return LDNS_STATUS_ERR;
00433                         }
00434                         ldns_key_set_rsa_key(k, rsa);
00435                         RSA_free(rsa);
00436 #endif /* HAVE_SSL */
00437                         break;
00438                 case LDNS_SIGN_DSA:
00439                 case LDNS_SIGN_DSA_NSEC3:
00440                         ldns_key_set_algorithm(k, alg);
00441 #ifdef HAVE_SSL
00442                         dsa = ldns_key_new_frm_fp_dsa_l(fp, line_nr);
00443                         if (!dsa) {
00444                                 ldns_key_free(k);
00445                                 return LDNS_STATUS_ERR;
00446                         }
00447                         ldns_key_set_dsa_key(k, dsa);
00448                         DSA_free(dsa);
00449 #endif /* HAVE_SSL */
00450                         break;
00451                 case LDNS_SIGN_HMACMD5:
00452                 case LDNS_SIGN_HMACSHA1:
00453                 case LDNS_SIGN_HMACSHA256:
00454                         ldns_key_set_algorithm(k, alg);
00455 #ifdef HAVE_SSL
00456                         hmac = ldns_key_new_frm_fp_hmac_l(fp, line_nr, &hmac_size);
00457                         if (!hmac) {
00458                                 ldns_key_free(k);
00459                                 return LDNS_STATUS_ERR;
00460                         }
00461                         ldns_key_set_hmac_size(k, hmac_size);
00462                         ldns_key_set_hmac_key(k, hmac);
00463 #endif /* HAVE_SSL */
00464                         break;
00465                 case LDNS_SIGN_ECC_GOST:
00466                         ldns_key_set_algorithm(k, alg);
00467 #if defined(HAVE_SSL) && defined(USE_GOST)
00468                         if(!ldns_key_EVP_load_gost_id()) {
00469                                 ldns_key_free(k);
00470                                 return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
00471                         }
00472                         ldns_key_set_evp_key(k, 
00473                                 ldns_key_new_frm_fp_gost_l(fp, line_nr));
00474 #ifndef S_SPLINT_S
00475                         if(!k->_key.key) {
00476                                 ldns_key_free(k);
00477                                 return LDNS_STATUS_ERR;
00478                         }
00479 #endif /* splint */
00480 #endif
00481                         break;
00482 #ifdef USE_ECDSA
00483                case LDNS_SIGN_ECDSAP256SHA256:
00484                case LDNS_SIGN_ECDSAP384SHA384:
00485                         ldns_key_set_algorithm(k, alg);
00486                         ldns_key_set_evp_key(k,
00487                                 ldns_key_new_frm_fp_ecdsa_l(fp, (ldns_algorithm)alg, line_nr));
00488 #ifndef S_SPLINT_S
00489                         if(!k->_key.key) {
00490                                 ldns_key_free(k);
00491                                 return LDNS_STATUS_ERR;
00492                         }
00493 #endif /* splint */
00494                         break;
00495 #endif
00496                 default:
00497                         ldns_key_free(k);
00498                         return LDNS_STATUS_SYNTAX_ALG_ERR;
00499         }
00500         key_rr = ldns_key2rr(k);
00501         ldns_key_set_keytag(k, ldns_calc_keytag(key_rr));
00502         ldns_rr_free(key_rr);
00503 
00504         if (key) {
00505                 *key = k;
00506                 return LDNS_STATUS_OK;
00507         }
00508         return LDNS_STATUS_ERR;
00509 }
00510 
00511 #ifdef HAVE_SSL
00512 RSA *
00513 ldns_key_new_frm_fp_rsa(FILE *f)
00514 {
00515         return ldns_key_new_frm_fp_rsa_l(f, NULL);
00516 }
00517 
00518 RSA *
00519 ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr)
00520 {
00521         /* we parse
00522          * Modulus:
00523          * PublicExponent:
00524          * PrivateExponent:
00525          * Prime1:
00526          * Prime2:
00527          * Exponent1:
00528          * Exponent2:
00529          * Coefficient:
00530          *
00531          * man 3 RSA:
00532          *
00533          * struct
00534          *     {
00535          *     BIGNUM *n;              // public modulus
00536          *     BIGNUM *e;              // public exponent
00537          *     BIGNUM *d;              // private exponent
00538          *     BIGNUM *p;              // secret prime factor
00539          *     BIGNUM *q;              // secret prime factor
00540          *     BIGNUM *dmp1;           // d mod (p-1)
00541          *     BIGNUM *dmq1;           // d mod (q-1)
00542          *     BIGNUM *iqmp;           // q^-1 mod p
00543          *     // ...
00544          *
00545          */
00546         char *d;
00547         RSA *rsa;
00548         uint8_t *buf;
00549         int i;
00550 
00551         d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
00552         buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
00553         rsa = RSA_new();
00554         if (!d || !rsa || !buf) {
00555                 goto error;
00556         }
00557 
00558         /* I could use functions again, but that seems an overkill,
00559          * allthough this also looks tedious
00560          */
00561 
00562         /* Modules, rsa->n */
00563         if (ldns_fget_keyword_data_l(f, "Modulus", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00564                 goto error;
00565         }
00566         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00567 #ifndef S_SPLINT_S
00568         rsa->n = BN_bin2bn((const char unsigned*)buf, i, NULL);
00569         if (!rsa->n) {
00570                 goto error;
00571         }
00572 
00573         /* PublicExponent, rsa->e */
00574         if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00575                 goto error;
00576         }
00577         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00578         rsa->e = BN_bin2bn((const char unsigned*)buf, i, NULL);
00579         if (!rsa->e) {
00580                 goto error;
00581         }
00582 
00583         /* PrivateExponent, rsa->d */
00584         if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00585                 goto error;
00586         }
00587         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00588         rsa->d = BN_bin2bn((const char unsigned*)buf, i, NULL);
00589         if (!rsa->d) {
00590                 goto error;
00591         }
00592 
00593         /* Prime1, rsa->p */
00594         if (ldns_fget_keyword_data_l(f, "Prime1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00595                 goto error;
00596         }
00597         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00598         rsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL);
00599         if (!rsa->p) {
00600                 goto error;
00601         }
00602 
00603         /* Prime2, rsa->q */
00604         if (ldns_fget_keyword_data_l(f, "Prime2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00605                 goto error;
00606         }
00607         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00608         rsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL);
00609         if (!rsa->q) {
00610                 goto error;
00611         }
00612 
00613         /* Exponent1, rsa->dmp1 */
00614         if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00615                 goto error;
00616         }
00617         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00618         rsa->dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
00619         if (!rsa->dmp1) {
00620                 goto error;
00621         }
00622 
00623         /* Exponent2, rsa->dmq1 */
00624         if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00625                 goto error;
00626         }
00627         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00628         rsa->dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
00629         if (!rsa->dmq1) {
00630                 goto error;
00631         }
00632 
00633         /* Coefficient, rsa->iqmp */
00634         if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00635                 goto error;
00636         }
00637         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00638         rsa->iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL);
00639         if (!rsa->iqmp) {
00640                 goto error;
00641         }
00642 #endif /* splint */
00643 
00644         LDNS_FREE(buf);
00645         LDNS_FREE(d);
00646         return rsa;
00647 
00648 error:
00649         RSA_free(rsa);
00650         LDNS_FREE(d);
00651         LDNS_FREE(buf);
00652         return NULL;
00653 }
00654 
00655 DSA *
00656 ldns_key_new_frm_fp_dsa(FILE *f)
00657 {
00658         return ldns_key_new_frm_fp_dsa_l(f, NULL);
00659 }
00660 
00661 DSA *
00662 ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr))
00663 {
00664         int i;
00665         char *d;
00666         DSA *dsa;
00667         uint8_t *buf;
00668 
00669         d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
00670         buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
00671         dsa = DSA_new();
00672         if (!d || !dsa || !buf) {
00673                 goto error;
00674         }
00675 
00676         /* the line parser removes the () from the input... */
00677 
00678         /* Prime, dsa->p */
00679         if (ldns_fget_keyword_data_l(f, "Primep", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00680                 goto error;
00681         }
00682         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00683 #ifndef S_SPLINT_S
00684         dsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL);
00685         if (!dsa->p) {
00686                 goto error;
00687         }
00688 
00689         /* Subprime, dsa->q */
00690         if (ldns_fget_keyword_data_l(f, "Subprimeq", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00691                 goto error;
00692         }
00693         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00694         dsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL);
00695         if (!dsa->q) {
00696                 goto error;
00697         }
00698 
00699         /* Base, dsa->g */
00700         if (ldns_fget_keyword_data_l(f, "Baseg", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00701                 goto error;
00702         }
00703         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00704         dsa->g = BN_bin2bn((const char unsigned*)buf, i, NULL);
00705         if (!dsa->g) {
00706                 goto error;
00707         }
00708 
00709         /* Private key, dsa->priv_key */
00710         if (ldns_fget_keyword_data_l(f, "Private_valuex", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00711                 goto error;
00712         }
00713         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00714         dsa->priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
00715         if (!dsa->priv_key) {
00716                 goto error;
00717         }
00718 
00719         /* Public key, dsa->priv_key */
00720         if (ldns_fget_keyword_data_l(f, "Public_valuey", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00721                 goto error;
00722         }
00723         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00724         dsa->pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
00725         if (!dsa->pub_key) {
00726                 goto error;
00727         }
00728 #endif /* splint */
00729 
00730         LDNS_FREE(buf);
00731         LDNS_FREE(d);
00732 
00733         return dsa;
00734 
00735 error:
00736         LDNS_FREE(d);
00737         LDNS_FREE(buf);
00738         DSA_free(dsa);
00739         return NULL;
00740 }
00741 
00742 unsigned char *
00743 ldns_key_new_frm_fp_hmac(FILE *f, size_t *hmac_size)
00744 {
00745         return ldns_key_new_frm_fp_hmac_l(f, NULL, hmac_size);
00746 }
00747 
00748 unsigned char *
00749 ldns_key_new_frm_fp_hmac_l( FILE *f
00750                           , ATTR_UNUSED(int *line_nr)
00751                           , size_t *hmac_size
00752                           )
00753 {
00754         size_t i;
00755         char *d;
00756         unsigned char *buf;
00757 
00758         d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
00759         buf = LDNS_XMALLOC(unsigned char, LDNS_MAX_LINELEN);
00760         if(!d || !buf) {
00761                 goto error;
00762         }
00763 
00764         if (ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00765                 goto error;
00766         }
00767         i = (size_t) ldns_b64_pton((const char*)d,
00768                                    buf,
00769                                    ldns_b64_ntop_calculate_size(strlen(d)));
00770 
00771         *hmac_size = i;
00772         return buf;
00773 
00774         error:
00775         LDNS_FREE(d);
00776         LDNS_FREE(buf);
00777         *hmac_size = 0;
00778         return NULL;
00779 }
00780 #endif /* HAVE_SSL */
00781 
00782 #ifdef USE_GOST
00783 static EVP_PKEY*
00784 ldns_gen_gost_key(void)
00785 {
00786         EVP_PKEY_CTX* ctx;
00787         EVP_PKEY* p = NULL;
00788         int gost_id = ldns_key_EVP_load_gost_id();
00789         if(!gost_id)
00790                 return NULL;
00791         ctx = EVP_PKEY_CTX_new_id(gost_id, NULL);
00792         if(!ctx) {
00793                 /* the id should be available now */
00794                 return NULL;
00795         }
00796         if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) {
00797                 /* cannot set paramset */
00798                 EVP_PKEY_CTX_free(ctx);
00799                 return NULL;
00800         }
00801 
00802         if(EVP_PKEY_keygen_init(ctx) <= 0) {
00803                 EVP_PKEY_CTX_free(ctx);
00804                 return NULL;
00805         }
00806         if(EVP_PKEY_keygen(ctx, &p) <= 0) {
00807                 EVP_PKEY_free(p);
00808                 EVP_PKEY_CTX_free(ctx);
00809                 return NULL;
00810         }
00811         EVP_PKEY_CTX_free(ctx);
00812         return p;
00813 }
00814 #endif
00815 
00816 ldns_key *
00817 ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
00818 {
00819         ldns_key *k;
00820 #ifdef HAVE_SSL
00821         DSA *d;
00822         RSA *r;
00823 #  ifdef USE_ECDSA
00824         EC_KEY *ec = NULL;
00825 #  endif
00826 #else
00827         int i;
00828         uint16_t offset = 0;
00829 #endif
00830         unsigned char *hmac;
00831 
00832         k = ldns_key_new();
00833         if (!k) {
00834                 return NULL;
00835         }
00836         switch(alg) {
00837                 case LDNS_SIGN_RSAMD5:
00838                 case LDNS_SIGN_RSASHA1:
00839                 case LDNS_SIGN_RSASHA1_NSEC3:
00840                 case LDNS_SIGN_RSASHA256:
00841                 case LDNS_SIGN_RSASHA512:
00842 #ifdef HAVE_SSL
00843                         r = RSA_generate_key((int)size, RSA_F4, NULL, NULL);
00844                         if(!r) {
00845                                 ldns_key_free(k);
00846                                 return NULL;
00847                         }
00848                         if (RSA_check_key(r) != 1) {
00849                                 ldns_key_free(k);
00850                                 return NULL;
00851                         }
00852                         ldns_key_set_rsa_key(k, r);
00853 #endif /* HAVE_SSL */
00854                         break;
00855                 case LDNS_SIGN_DSA:
00856                 case LDNS_SIGN_DSA_NSEC3:
00857 #ifdef HAVE_SSL
00858                         d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL);
00859                         if (!d) {
00860                                 ldns_key_free(k);
00861                                 return NULL;
00862                         }
00863                         if (DSA_generate_key(d) != 1) {
00864                                 ldns_key_free(k);
00865                                 return NULL;
00866                         }
00867                         ldns_key_set_dsa_key(k, d);
00868 #endif /* HAVE_SSL */
00869                         break;
00870                 case LDNS_SIGN_HMACMD5:
00871                 case LDNS_SIGN_HMACSHA1:
00872                 case LDNS_SIGN_HMACSHA256:
00873 #ifdef HAVE_SSL
00874 #ifndef S_SPLINT_S
00875                         k->_key.key = NULL;
00876 #endif /* splint */
00877 #endif /* HAVE_SSL */
00878                         size = size / 8;
00879                         ldns_key_set_hmac_size(k, size);
00880 
00881                         hmac = LDNS_XMALLOC(unsigned char, size);
00882                         if(!hmac) {
00883                                 ldns_key_free(k);
00884                                 return NULL;
00885                         }
00886 #ifdef HAVE_SSL
00887                         if (RAND_bytes(hmac, (int) size) != 1) {
00888                                 LDNS_FREE(hmac);
00889                                 ldns_key_free(k);
00890                                 return NULL;
00891                         }
00892 #else
00893                         while (offset + sizeof(i) < size) {
00894                           i = random();
00895                           memcpy(&hmac[offset], &i, sizeof(i));
00896                           offset += sizeof(i);
00897                         }
00898                         if (offset < size) {
00899                           i = random();
00900                           memcpy(&hmac[offset], &i, size - offset);
00901                         }
00902 #endif /* HAVE_SSL */
00903                         ldns_key_set_hmac_key(k, hmac);
00904 
00905                         ldns_key_set_flags(k, 0);
00906                         break;
00907                 case LDNS_SIGN_ECC_GOST:
00908 #if defined(HAVE_SSL) && defined(USE_GOST)
00909                         ldns_key_set_evp_key(k, ldns_gen_gost_key());
00910 #ifndef S_SPLINT_S
00911                         if(!k->_key.key) {
00912                                 ldns_key_free(k);
00913                                 return NULL;
00914                         }
00915 #endif /* splint */
00916 #else
00917                         ldns_key_free(k);
00918                         return NULL;
00919 #endif /* HAVE_SSL and USE_GOST */
00920                         break;
00921                 case LDNS_SIGN_ECDSAP256SHA256:
00922                 case LDNS_SIGN_ECDSAP384SHA384:
00923 #ifdef USE_ECDSA
00924                         if(alg == LDNS_SIGN_ECDSAP256SHA256)
00925                                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
00926                         else if(alg == LDNS_SIGN_ECDSAP384SHA384)
00927                                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
00928                         if(!ec) {
00929                                 ldns_key_free(k);
00930                                 return NULL;
00931                         }
00932                         if(!EC_KEY_generate_key(ec)) {
00933                                 ldns_key_free(k);
00934                                 EC_KEY_free(ec);
00935                                 return NULL;
00936                         }
00937 #ifndef S_SPLINT_S
00938                         k->_key.key = EVP_PKEY_new();
00939                         if(!k->_key.key) {
00940                                 ldns_key_free(k);
00941                                 EC_KEY_free(ec);
00942                                 return NULL;
00943                         }
00944                         if (!EVP_PKEY_assign_EC_KEY(k->_key.key, ec)) {
00945                                 ldns_key_free(k);
00946                                 EC_KEY_free(ec);
00947                                 return NULL;
00948                         }
00949 #endif /* splint */
00950 #else
00951                         ldns_key_free(k);
00952                         return NULL;
00953 #endif /* ECDSA */
00954                         break;
00955         }
00956         ldns_key_set_algorithm(k, alg);
00957         return k;
00958 }
00959 
00960 void
00961 ldns_key_print(FILE *output, const ldns_key *k)
00962 {
00963         char *str = ldns_key2str(k);
00964         if (str) {
00965                 fprintf(output, "%s", str);
00966         } else {
00967                 fprintf(output, "Unable to convert private key to string\n");
00968         }
00969         LDNS_FREE(str);
00970 }
00971 
00972 
00973 void
00974 ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l)
00975 {
00976         k->_alg = l;
00977 }
00978 
00979 void
00980 ldns_key_set_flags(ldns_key *k, uint16_t f)
00981 {
00982         k->_extra.dnssec.flags = f;
00983 }
00984 
00985 #ifdef HAVE_SSL
00986 #ifndef S_SPLINT_S
00987 void
00988 ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e)
00989 {
00990         k->_key.key = e;
00991 }
00992 
00993 void
00994 ldns_key_set_rsa_key(ldns_key *k, RSA *r)
00995 {
00996         EVP_PKEY *key = EVP_PKEY_new();
00997         EVP_PKEY_set1_RSA(key, r);
00998         k->_key.key = key;
00999 }
01000 
01001 void
01002 ldns_key_set_dsa_key(ldns_key *k, DSA *d)
01003 {
01004         EVP_PKEY *key = EVP_PKEY_new();
01005         EVP_PKEY_set1_DSA(key, d);
01006         k->_key.key  = key;
01007 }
01008 #endif /* splint */
01009 #endif /* HAVE_SSL */
01010 
01011 void
01012 ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac)
01013 {
01014         k->_key.hmac.key = hmac;
01015 }
01016 
01017 void
01018 ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size)
01019 {
01020         k->_key.hmac.size = hmac_size;
01021 }
01022 
01023 void
01024 ldns_key_set_external_key(ldns_key *k, void *external_key)
01025 {
01026         k->_key.external_key = external_key;
01027 }
01028 
01029 void
01030 ldns_key_set_origttl(ldns_key *k, uint32_t t)
01031 {
01032         k->_extra.dnssec.orig_ttl = t;
01033 }
01034 
01035 void
01036 ldns_key_set_inception(ldns_key *k, uint32_t i)
01037 {
01038         k->_extra.dnssec.inception = i;
01039 }
01040 
01041 void
01042 ldns_key_set_expiration(ldns_key *k, uint32_t e)
01043 {
01044         k->_extra.dnssec.expiration = e;
01045 }
01046 
01047 void
01048 ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r)
01049 {
01050         k->_pubkey_owner = r;
01051 }
01052 
01053 void
01054 ldns_key_set_keytag(ldns_key *k, uint16_t tag)
01055 {
01056         k->_extra.dnssec.keytag = tag;
01057 }
01058 
01059 /* read */
01060 size_t
01061 ldns_key_list_key_count(const ldns_key_list *key_list)
01062 {
01063                 return key_list->_key_count;
01064 }       
01065 
01066 ldns_key *
01067 ldns_key_list_key(const ldns_key_list *key, size_t nr)
01068 {       
01069         if (nr < ldns_key_list_key_count(key)) {
01070                 return key->_keys[nr];
01071         } else {
01072                 return NULL;
01073         }
01074 }
01075 
01076 ldns_signing_algorithm
01077 ldns_key_algorithm(const ldns_key *k) 
01078 {
01079         return k->_alg;
01080 }
01081 
01082 void
01083 ldns_key_set_use(ldns_key *k, bool v)
01084 {
01085         if (k) {
01086                 k->_use = v;
01087         }
01088 }
01089 
01090 bool
01091 ldns_key_use(const ldns_key *k)
01092 {
01093         if (k) {
01094                 return k->_use;
01095         }
01096         return false;
01097 }
01098 
01099 #ifdef HAVE_SSL
01100 #ifndef S_SPLINT_S
01101 EVP_PKEY *
01102 ldns_key_evp_key(const ldns_key *k)
01103 {
01104         return k->_key.key;
01105 }
01106 
01107 RSA *
01108 ldns_key_rsa_key(const ldns_key *k)
01109 {
01110         if (k->_key.key) {
01111                 return EVP_PKEY_get1_RSA(k->_key.key);
01112         } else {
01113                 return NULL;
01114         }
01115 }
01116 
01117 DSA *
01118 ldns_key_dsa_key(const ldns_key *k)
01119 {
01120         if (k->_key.key) {
01121                 return EVP_PKEY_get1_DSA(k->_key.key);
01122         } else {
01123                 return NULL;
01124         }
01125 }
01126 #endif /* splint */
01127 #endif /* HAVE_SSL */
01128 
01129 unsigned char *
01130 ldns_key_hmac_key(const ldns_key *k)
01131 {
01132         if (k->_key.hmac.key) {
01133                 return k->_key.hmac.key;
01134         } else {
01135                 return NULL;
01136         }
01137 }
01138 
01139 size_t
01140 ldns_key_hmac_size(const ldns_key *k)
01141 {
01142         if (k->_key.hmac.size) {
01143                 return k->_key.hmac.size;
01144         } else {
01145                 return 0;
01146         }
01147 }
01148 
01149 void *
01150 ldns_key_external_key(const ldns_key *k)
01151 {
01152         return k->_key.external_key;
01153 }
01154 
01155 uint32_t
01156 ldns_key_origttl(const ldns_key *k)
01157 {
01158         return k->_extra.dnssec.orig_ttl;
01159 }
01160 
01161 uint16_t
01162 ldns_key_flags(const ldns_key *k)
01163 {
01164         return k->_extra.dnssec.flags;
01165 }
01166 
01167 uint32_t
01168 ldns_key_inception(const ldns_key *k)
01169 {
01170         return k->_extra.dnssec.inception;
01171 }
01172 
01173 uint32_t
01174 ldns_key_expiration(const ldns_key *k)
01175 {
01176         return k->_extra.dnssec.expiration;
01177 }
01178 
01179 uint16_t
01180 ldns_key_keytag(const ldns_key *k)
01181 {
01182         return k->_extra.dnssec.keytag;
01183 }
01184 
01185 ldns_rdf *
01186 ldns_key_pubkey_owner(const ldns_key *k)
01187 {
01188         return k->_pubkey_owner;
01189 }
01190 
01191 /* write */
01192 void
01193 ldns_key_list_set_use(ldns_key_list *keys, bool v)
01194 {
01195         size_t i;
01196 
01197         for (i = 0; i < ldns_key_list_key_count(keys); i++) {
01198                 ldns_key_set_use(ldns_key_list_key(keys, i), v);
01199         }
01200 }
01201 
01202 void            
01203 ldns_key_list_set_key_count(ldns_key_list *key, size_t count)
01204 {
01205                 key->_key_count = count;
01206 }       
01207 
01208 bool             
01209 ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key)
01210 {       
01211         size_t key_count;
01212         ldns_key **keys;
01213 
01214         key_count = ldns_key_list_key_count(key_list);
01215 
01216         /* grow the array */
01217         keys = LDNS_XREALLOC(
01218                 key_list->_keys, ldns_key *, key_count + 1);
01219         if (!keys) {
01220                 return false;
01221         }
01222 
01223         /* add the new member */
01224         key_list->_keys = keys;
01225         key_list->_keys[key_count] = key;
01226 
01227         ldns_key_list_set_key_count(key_list, key_count + 1);
01228         return true;
01229 }
01230 
01231 ldns_key *
01232 ldns_key_list_pop_key(ldns_key_list *key_list)
01233 {                               
01234         size_t key_count;
01235         ldns_key** a;
01236         ldns_key *pop;
01237 
01238         if (!key_list) {
01239                 return NULL;
01240         }
01241         
01242         key_count = ldns_key_list_key_count(key_list);
01243         if (key_count == 0) {
01244                 return NULL;
01245         }       
01246         
01247         pop = ldns_key_list_key(key_list, key_count);
01248         
01249         /* shrink the array */
01250         a = LDNS_XREALLOC(key_list->_keys, ldns_key *, key_count - 1);
01251         if(a) {
01252                 key_list->_keys = a;
01253         }
01254 
01255         ldns_key_list_set_key_count(key_list, key_count - 1);
01256 
01257         return pop;
01258 }       
01259 
01260 #ifdef HAVE_SSL
01261 #ifndef S_SPLINT_S
01262 /* data pointer must be large enough (LDNS_MAX_KEYLEN) */
01263 static bool
01264 ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size)
01265 {
01266         int i,j;
01267         
01268         if (!k) {
01269                 return false;
01270         }
01271         
01272         if (BN_num_bytes(k->e) <= 256) {
01273                 /* normally only this path is executed (small factors are
01274                  * more common 
01275                  */
01276                 data[0] = (unsigned char) BN_num_bytes(k->e);
01277                 i = BN_bn2bin(k->e, data + 1);  
01278                 j = BN_bn2bin(k->n, data + i + 1);
01279                 *size = (uint16_t) i + j;
01280         } else if (BN_num_bytes(k->e) <= 65536) {
01281                 data[0] = 0;
01282                 /* BN_bn2bin does bigendian, _uint16 also */
01283                 ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(k->e)); 
01284 
01285                 BN_bn2bin(k->e, data + 3); 
01286                 BN_bn2bin(k->n, data + 4 + BN_num_bytes(k->e));
01287                 *size = (uint16_t) BN_num_bytes(k->n) + 6;
01288         } else {
01289                 return false;
01290         }
01291         return true;
01292 }
01293 
01294 /* data pointer must be large enough (LDNS_MAX_KEYLEN) */
01295 static bool
01296 ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size)
01297 {
01298         uint8_t T;
01299 
01300         if (!k) {
01301                 return false;
01302         }
01303         
01304         /* See RFC2536 */
01305         *size = (uint16_t)BN_num_bytes(k->g);
01306         T = (*size - 64) / 8;
01307         memcpy(data, &T, 1);
01308 
01309         if (T > 8) {
01310                 fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)");
01311                 fprintf(stderr, " not implemented\n");
01312                 return false;
01313         }
01314 
01315         /* size = 64 + (T * 8); */
01316         data[0] = (unsigned char)T;
01317         BN_bn2bin(k->q, data + 1 );             /* 20 octects */
01318         BN_bn2bin(k->p, data + 21 );            /* offset octects */
01319         BN_bn2bin(k->g, data + 21 + *size);     /* offset octets */
01320         BN_bn2bin(k->pub_key, data + 21 + *size + *size); /* offset octets */
01321         *size = 21 + (*size * 3);
01322         return true;
01323 }
01324 
01325 #ifdef USE_GOST
01326 static bool
01327 ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
01328 {
01329         int i;
01330         unsigned char* pp = NULL;
01331         if(i2d_PUBKEY(k, &pp) != 37 + 64) {
01332                 /* expect 37 byte(ASN header) and 64 byte(X and Y) */
01333                 CRYPTO_free(pp);
01334                 return false;
01335         }
01336         /* omit ASN header */
01337         for(i=0; i<64; i++)
01338                 data[i] = pp[i+37];
01339         CRYPTO_free(pp);
01340         *size = 64;
01341         return true;
01342 }
01343 #endif /* USE_GOST */
01344 #endif /* splint */
01345 #endif /* HAVE_SSL */
01346 
01347 ldns_rr *
01348 ldns_key2rr(const ldns_key *k)
01349 {
01350         /* this function will convert a the keydata contained in
01351          * rsa/dsa pointers to a DNSKEY rr. It will fill in as
01352          * much as it can, but it does not know about key-flags
01353          * for instance
01354          */
01355         ldns_rr *pubkey;
01356         ldns_rdf *keybin;
01357         unsigned char *bin = NULL;
01358         uint16_t size = 0;
01359 #ifdef HAVE_SSL
01360         RSA *rsa = NULL;
01361         DSA *dsa = NULL;
01362 #endif /* HAVE_SSL */
01363 #ifdef USE_ECDSA
01364         EC_KEY* ec;
01365 #endif
01366         int internal_data = 0;
01367 
01368         pubkey = ldns_rr_new();
01369         if (!k) {
01370                 return NULL;
01371         }
01372 
01373         switch (ldns_key_algorithm(k)) {
01374         case LDNS_SIGN_HMACMD5:
01375         case LDNS_SIGN_HMACSHA1:
01376         case LDNS_SIGN_HMACSHA256:
01377                 ldns_rr_set_type(pubkey, LDNS_RR_TYPE_KEY);
01378                 break;
01379         default:
01380                 ldns_rr_set_type(pubkey, LDNS_RR_TYPE_DNSKEY);
01381                 break;
01382         }
01383         /* zero-th rdf - flags */
01384         ldns_rr_push_rdf(pubkey,
01385                         ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
01386                                 ldns_key_flags(k)));
01387         /* first - proto */
01388         ldns_rr_push_rdf(pubkey,
01389                         ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, LDNS_DNSSEC_KEYPROTO));
01390 
01391         if (ldns_key_pubkey_owner(k)) {
01392                 ldns_rr_set_owner(pubkey, ldns_rdf_clone(ldns_key_pubkey_owner(k)));
01393         }
01394 
01395         /* third - da algorithm */
01396         switch(ldns_key_algorithm(k)) {
01397                 case LDNS_SIGN_RSAMD5:
01398                 case LDNS_SIGN_RSASHA1:
01399                 case LDNS_SIGN_RSASHA1_NSEC3:
01400                 case LDNS_SIGN_RSASHA256:
01401                 case LDNS_SIGN_RSASHA512:
01402                         ldns_rr_push_rdf(pubkey,
01403                                                   ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
01404 #ifdef HAVE_SSL
01405                         rsa =  ldns_key_rsa_key(k);
01406                         if (rsa) {
01407                                 bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
01408                                 if (!bin) {
01409                                         ldns_rr_free(pubkey);
01410                                         return NULL;
01411                                 }
01412                                 if (!ldns_key_rsa2bin(bin, rsa, &size)) {
01413                                         LDNS_FREE(bin);
01414                                         ldns_rr_free(pubkey);
01415                                         return NULL;
01416                                 }
01417                                 RSA_free(rsa);
01418                                 internal_data = 1;
01419                         }
01420 #endif
01421                         size++;
01422                         break;
01423                 case LDNS_SIGN_DSA:
01424                         ldns_rr_push_rdf(pubkey,
01425                                         ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA));
01426 #ifdef HAVE_SSL
01427                         dsa = ldns_key_dsa_key(k);
01428                         if (dsa) {
01429                                 bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
01430                                 if (!bin) {
01431                                         ldns_rr_free(pubkey);
01432                                         return NULL;
01433                                 }
01434                                 if (!ldns_key_dsa2bin(bin, dsa, &size)) {
01435                                         LDNS_FREE(bin);
01436                                         ldns_rr_free(pubkey);
01437                                         return NULL;
01438                                 }
01439                                 DSA_free(dsa);
01440                                 internal_data = 1;
01441                         }
01442 #endif /* HAVE_SSL */
01443                         break;
01444                 case LDNS_SIGN_DSA_NSEC3:
01445                         ldns_rr_push_rdf(pubkey,
01446                                         ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3));
01447 #ifdef HAVE_SSL
01448                         dsa = ldns_key_dsa_key(k);
01449                         if (dsa) {
01450                                 bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
01451                                 if (!bin) {
01452                                         ldns_rr_free(pubkey);
01453                                         return NULL;
01454                                 }
01455                                 if (!ldns_key_dsa2bin(bin, dsa, &size)) {
01456                                         LDNS_FREE(bin);
01457                                         ldns_rr_free(pubkey);
01458                                         return NULL;
01459                                 }
01460                                 DSA_free(dsa);
01461                                 internal_data = 1;
01462                         }
01463 #endif /* HAVE_SSL */
01464                         break;
01465                 case LDNS_SIGN_ECC_GOST:
01466                         ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
01467                                 LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
01468 #if defined(HAVE_SSL) && defined(USE_GOST)
01469                         bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
01470                         if (!bin) {
01471                                 ldns_rr_free(pubkey);
01472                                 return NULL;
01473                         }
01474 #ifndef S_SPLINT_S
01475                         if (!ldns_key_gost2bin(bin, k->_key.key, &size)) {
01476                                 LDNS_FREE(bin);
01477                                 ldns_rr_free(pubkey);
01478                                 return NULL;
01479                         }
01480 #endif /* splint */
01481                         internal_data = 1;
01482 #else
01483                         ldns_rr_free(pubkey);
01484                         return NULL;
01485 #endif /* HAVE_SSL and USE_GOST */
01486                         break;
01487                 case LDNS_SIGN_ECDSAP256SHA256:
01488                 case LDNS_SIGN_ECDSAP384SHA384:
01489 #ifdef USE_ECDSA
01490                         ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
01491                                 LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
01492                         bin = NULL;
01493 #ifndef S_SPLINT_S
01494                         ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
01495 #endif
01496                         EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
01497                         size = (uint16_t)i2o_ECPublicKey(ec, NULL);
01498                         if(!i2o_ECPublicKey(ec, &bin)) {
01499                                 EC_KEY_free(ec);
01500                                 ldns_rr_free(pubkey);
01501                                 return NULL;
01502                         }
01503                         if(size > 1) {
01504                                 /* move back one byte to shave off the 0x02
01505                                  * 'uncompressed' indicator that openssl made
01506                                  * Actually its 0x04 (from implementation).
01507                                  */
01508                                 assert(bin[0] == POINT_CONVERSION_UNCOMPRESSED);
01509                                 size -= 1;
01510                                 memmove(bin, bin+1, size);
01511                         }
01512                         /* down the reference count for ec, its still assigned
01513                          * to the pkey */
01514                         EC_KEY_free(ec);
01515                         internal_data = 1;
01516 #else
01517                         ldns_rr_free(pubkey);
01518                         return NULL;
01519 #endif /* ECDSA */
01520                         break;
01521                 case LDNS_SIGN_HMACMD5:
01522                 case LDNS_SIGN_HMACSHA1:
01523                 case LDNS_SIGN_HMACSHA256:
01524                         bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k));
01525                         if (!bin) {
01526                                 ldns_rr_free(pubkey);
01527                                 return NULL;
01528                         }
01529                         ldns_rr_push_rdf(pubkey,
01530                                          ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG,
01531                                          ldns_key_algorithm(k)));
01532                         size = ldns_key_hmac_size(k);
01533                         memcpy(bin, ldns_key_hmac_key(k), size);
01534                         internal_data = 1;
01535                         break;
01536         }
01537         /* fourth the key bin material */
01538         if (internal_data) {
01539                 keybin = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, size, bin);
01540                 LDNS_FREE(bin);
01541                 ldns_rr_push_rdf(pubkey, keybin);
01542         }
01543         return pubkey;
01544 }
01545 
01546 void
01547 ldns_key_free(ldns_key *key)
01548 {
01549         LDNS_FREE(key);
01550 }
01551 
01552 void
01553 ldns_key_deep_free(ldns_key *key)
01554 {
01555         unsigned char* hmac;
01556         if (ldns_key_pubkey_owner(key)) {
01557                 ldns_rdf_deep_free(ldns_key_pubkey_owner(key));
01558         }
01559 #ifdef HAVE_SSL
01560         if (ldns_key_evp_key(key)) {
01561                 EVP_PKEY_free(ldns_key_evp_key(key));
01562         }
01563 #endif /* HAVE_SSL */
01564         if (ldns_key_hmac_key(key)) {
01565                 hmac = ldns_key_hmac_key(key);
01566                 LDNS_FREE(hmac);
01567         }
01568         LDNS_FREE(key);
01569 }
01570 
01571 void
01572 ldns_key_list_free(ldns_key_list *key_list)
01573 {
01574         size_t i;
01575         for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
01576                 ldns_key_deep_free(ldns_key_list_key(key_list, i));
01577         }
01578         LDNS_FREE(key_list->_keys);
01579         LDNS_FREE(key_list);
01580 }
01581 
01582 ldns_rr *
01583 ldns_read_anchor_file(const char *filename)
01584 {
01585         FILE *fp;
01586         /*char line[LDNS_MAX_PACKETLEN];*/
01587         char *line = LDNS_XMALLOC(char, LDNS_MAX_PACKETLEN);
01588         int c;
01589         size_t i = 0;
01590         ldns_rr *r;
01591         ldns_status status;
01592         if(!line) {
01593                 return NULL;
01594         }
01595 
01596         fp = fopen(filename, "r");
01597         if (!fp) {
01598                 fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
01599                 LDNS_FREE(line);
01600                 return NULL;
01601         }
01602         
01603         while ((c = fgetc(fp)) && i+1 < LDNS_MAX_PACKETLEN && c != EOF) {
01604                 line[i] = c;
01605                 i++;
01606         }
01607         line[i] = '\0';
01608         
01609         fclose(fp);
01610         
01611         if (i <= 0) {
01612                 fprintf(stderr, "nothing read from %s", filename);
01613                 LDNS_FREE(line);
01614                 return NULL;
01615         } else {
01616                 status = ldns_rr_new_frm_str(&r, line, 0, NULL, NULL);
01617                 if (status == LDNS_STATUS_OK && (ldns_rr_get_type(r) == LDNS_RR_TYPE_DNSKEY || ldns_rr_get_type(r) == LDNS_RR_TYPE_DS)) {
01618                         LDNS_FREE(line);
01619                         return r;
01620                 } else {
01621                         fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status));
01622                         LDNS_FREE(line);
01623                         return NULL;
01624                 }
01625         }
01626 }
01627 
01628 char *
01629 ldns_key_get_file_base_name(ldns_key *key)
01630 {
01631         ldns_buffer *buffer;
01632         char *file_base_name;
01633         
01634         buffer = ldns_buffer_new(255);
01635         ldns_buffer_printf(buffer, "K");
01636         (void)ldns_rdf2buffer_str_dname(buffer, ldns_key_pubkey_owner(key));
01637         ldns_buffer_printf(buffer,
01638                            "+%03u+%05u",
01639                            ldns_key_algorithm(key),
01640                            ldns_key_keytag(key));
01641         file_base_name = strdup(ldns_buffer_export(buffer));
01642         ldns_buffer_free(buffer);
01643         return file_base_name;
01644 }
01645 
01646 int ldns_key_algo_supported(int algo)
01647 {
01648         ldns_lookup_table *lt = ldns_signing_algorithms;
01649         while(lt->name) {
01650                 if(lt->id == algo)
01651                         return 1;
01652                 lt++;
01653         }
01654         return 0;
01655 }
01656 
01657 ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name)
01658 {
01659         /* list of (signing algorithm id, alias_name) */
01660         ldns_lookup_table aliases[] = {
01661                 /* from bind dnssec-keygen */
01662                 {LDNS_SIGN_HMACMD5, "HMAC-MD5"},
01663                 {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"},
01664                 {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"},
01665                 /* old ldns usage, now RFC names */
01666                 {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" },
01667                 {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" },
01668 #ifdef USE_GOST
01669                 {LDNS_SIGN_ECC_GOST, "GOST"},
01670 #endif
01671                 /* compat with possible output */
01672                 {LDNS_DH, "DH"},
01673                 {LDNS_ECC, "ECC"},
01674                 {LDNS_INDIRECT, "INDIRECT"},
01675                 {LDNS_PRIVATEDNS, "PRIVATEDNS"},
01676                 {LDNS_PRIVATEOID, "PRIVATEOID"},
01677                 {0, NULL}};
01678         ldns_lookup_table* lt = ldns_signing_algorithms;
01679         while(lt->name) {
01680                 if(strcasecmp(lt->name, name) == 0)
01681                         return lt->id;
01682                 lt++;
01683         }
01684         lt = aliases;
01685         while(lt->name) {
01686                 if(strcasecmp(lt->name, name) == 0)
01687                         return lt->id;
01688                 lt++;
01689         }
01690         if(atoi(name) != 0)
01691                 return atoi(name);
01692         return 0;
01693 }