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 #ifdef USE_ECDSA
00392         if (strncmp(d, "13 ECDSAP256SHA256", 3) == 0) {
00393                 alg = LDNS_SIGN_ECDSAP256SHA256;
00394         }
00395         if (strncmp(d, "14 ECDSAP384SHA384", 3) == 0) {
00396                 alg = LDNS_SIGN_ECDSAP384SHA384;
00397         }
00398 #endif
00399         if (strncmp(d, "157 HMAC-MD5", 4) == 0) {
00400                 alg = LDNS_SIGN_HMACMD5;
00401         }
00402         if (strncmp(d, "158 HMAC-SHA1", 4) == 0) {
00403                 alg = LDNS_SIGN_HMACSHA1;
00404         }
00405         if (strncmp(d, "159 HMAC-SHA256", 4) == 0) {
00406                 alg = LDNS_SIGN_HMACSHA256;
00407         }
00408 
00409         LDNS_FREE(d);
00410 
00411         switch(alg) {
00412                 case LDNS_SIGN_RSAMD5:
00413                 case LDNS_SIGN_RSASHA1:
00414                 case LDNS_SIGN_RSASHA1_NSEC3:
00415 #ifdef USE_SHA2
00416                 case LDNS_SIGN_RSASHA256:
00417                 case LDNS_SIGN_RSASHA512:
00418 #endif
00419                         ldns_key_set_algorithm(k, alg);
00420 #ifdef HAVE_SSL
00421                         rsa = ldns_key_new_frm_fp_rsa_l(fp, line_nr);
00422                         if (!rsa) {
00423                                 ldns_key_free(k);
00424                                 return LDNS_STATUS_ERR;
00425                         }
00426                         ldns_key_set_rsa_key(k, rsa);
00427                         RSA_free(rsa);
00428 #endif /* HAVE_SSL */
00429                         break;
00430                 case LDNS_SIGN_DSA:
00431                 case LDNS_SIGN_DSA_NSEC3:
00432                         ldns_key_set_algorithm(k, alg);
00433 #ifdef HAVE_SSL
00434                         dsa = ldns_key_new_frm_fp_dsa_l(fp, line_nr);
00435                         if (!dsa) {
00436                                 ldns_key_free(k);
00437                                 return LDNS_STATUS_ERR;
00438                         }
00439                         ldns_key_set_dsa_key(k, dsa);
00440                         DSA_free(dsa);
00441 #endif /* HAVE_SSL */
00442                         break;
00443                 case LDNS_SIGN_HMACMD5:
00444                 case LDNS_SIGN_HMACSHA1:
00445                 case LDNS_SIGN_HMACSHA256:
00446                         ldns_key_set_algorithm(k, alg);
00447 #ifdef HAVE_SSL
00448                         hmac = ldns_key_new_frm_fp_hmac_l(fp, line_nr, &hmac_size);
00449                         if (!hmac) {
00450                                 ldns_key_free(k);
00451                                 return LDNS_STATUS_ERR;
00452                         }
00453                         ldns_key_set_hmac_size(k, hmac_size);
00454                         ldns_key_set_hmac_key(k, hmac);
00455 #endif /* HAVE_SSL */
00456                         break;
00457                 case LDNS_SIGN_ECC_GOST:
00458                         ldns_key_set_algorithm(k, alg);
00459 #if defined(HAVE_SSL) && defined(USE_GOST)
00460                         if(!ldns_key_EVP_load_gost_id()) {
00461                                 ldns_key_free(k);
00462                                 return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
00463                         }
00464                         ldns_key_set_evp_key(k, 
00465                                 ldns_key_new_frm_fp_gost_l(fp, line_nr));
00466 #ifndef S_SPLINT_S
00467                         if(!k->_key.key) {
00468                                 ldns_key_free(k);
00469                                 return LDNS_STATUS_ERR;
00470                         }
00471 #endif /* splint */
00472 #endif
00473                         break;
00474 #ifdef USE_ECDSA
00475                case LDNS_SIGN_ECDSAP256SHA256:
00476                case LDNS_SIGN_ECDSAP384SHA384:
00477                         ldns_key_set_algorithm(k, alg);
00478                         ldns_key_set_evp_key(k,
00479                                 ldns_key_new_frm_fp_ecdsa_l(fp, (ldns_algorithm)alg, line_nr));
00480 #ifndef S_SPLINT_S
00481                         if(!k->_key.key) {
00482                                 ldns_key_free(k);
00483                                 return LDNS_STATUS_ERR;
00484                         }
00485 #endif /* splint */
00486                         break;
00487 #endif
00488                 default:
00489                         ldns_key_free(k);
00490                         return LDNS_STATUS_SYNTAX_ALG_ERR;
00491         }
00492         key_rr = ldns_key2rr(k);
00493         ldns_key_set_keytag(k, ldns_calc_keytag(key_rr));
00494         ldns_rr_free(key_rr);
00495 
00496         if (key) {
00497                 *key = k;
00498                 return LDNS_STATUS_OK;
00499         }
00500         return LDNS_STATUS_ERR;
00501 }
00502 
00503 #ifdef HAVE_SSL
00504 RSA *
00505 ldns_key_new_frm_fp_rsa(FILE *f)
00506 {
00507         return ldns_key_new_frm_fp_rsa_l(f, NULL);
00508 }
00509 
00510 RSA *
00511 ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr)
00512 {
00513         /* we parse
00514          * Modulus:
00515          * PublicExponent:
00516          * PrivateExponent:
00517          * Prime1:
00518          * Prime2:
00519          * Exponent1:
00520          * Exponent2:
00521          * Coefficient:
00522          *
00523          * man 3 RSA:
00524          *
00525          * struct
00526          *     {
00527          *     BIGNUM *n;              // public modulus
00528          *     BIGNUM *e;              // public exponent
00529          *     BIGNUM *d;              // private exponent
00530          *     BIGNUM *p;              // secret prime factor
00531          *     BIGNUM *q;              // secret prime factor
00532          *     BIGNUM *dmp1;           // d mod (p-1)
00533          *     BIGNUM *dmq1;           // d mod (q-1)
00534          *     BIGNUM *iqmp;           // q^-1 mod p
00535          *     // ...
00536          *
00537          */
00538         char *d;
00539         RSA *rsa;
00540         uint8_t *buf;
00541         int i;
00542 
00543         d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
00544         buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
00545         rsa = RSA_new();
00546         if (!d || !rsa || !buf) {
00547                 goto error;
00548         }
00549 
00550         /* I could use functions again, but that seems an overkill,
00551          * allthough this also looks tedious
00552          */
00553 
00554         /* Modules, rsa->n */
00555         if (ldns_fget_keyword_data_l(f, "Modulus", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00556                 goto error;
00557         }
00558         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00559 #ifndef S_SPLINT_S
00560         rsa->n = BN_bin2bn((const char unsigned*)buf, i, NULL);
00561         if (!rsa->n) {
00562                 goto error;
00563         }
00564 
00565         /* PublicExponent, rsa->e */
00566         if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00567                 goto error;
00568         }
00569         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00570         rsa->e = BN_bin2bn((const char unsigned*)buf, i, NULL);
00571         if (!rsa->e) {
00572                 goto error;
00573         }
00574 
00575         /* PrivateExponent, rsa->d */
00576         if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00577                 goto error;
00578         }
00579         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00580         rsa->d = BN_bin2bn((const char unsigned*)buf, i, NULL);
00581         if (!rsa->d) {
00582                 goto error;
00583         }
00584 
00585         /* Prime1, rsa->p */
00586         if (ldns_fget_keyword_data_l(f, "Prime1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00587                 goto error;
00588         }
00589         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00590         rsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL);
00591         if (!rsa->p) {
00592                 goto error;
00593         }
00594 
00595         /* Prime2, rsa->q */
00596         if (ldns_fget_keyword_data_l(f, "Prime2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00597                 goto error;
00598         }
00599         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00600         rsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL);
00601         if (!rsa->q) {
00602                 goto error;
00603         }
00604 
00605         /* Exponent1, rsa->dmp1 */
00606         if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00607                 goto error;
00608         }
00609         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00610         rsa->dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
00611         if (!rsa->dmp1) {
00612                 goto error;
00613         }
00614 
00615         /* Exponent2, rsa->dmq1 */
00616         if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00617                 goto error;
00618         }
00619         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00620         rsa->dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
00621         if (!rsa->dmq1) {
00622                 goto error;
00623         }
00624 
00625         /* Coefficient, rsa->iqmp */
00626         if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00627                 goto error;
00628         }
00629         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00630         rsa->iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL);
00631         if (!rsa->iqmp) {
00632                 goto error;
00633         }
00634 #endif /* splint */
00635 
00636         LDNS_FREE(buf);
00637         LDNS_FREE(d);
00638         return rsa;
00639 
00640 error:
00641         RSA_free(rsa);
00642         LDNS_FREE(d);
00643         LDNS_FREE(buf);
00644         return NULL;
00645 }
00646 
00647 DSA *
00648 ldns_key_new_frm_fp_dsa(FILE *f)
00649 {
00650         return ldns_key_new_frm_fp_dsa_l(f, NULL);
00651 }
00652 
00653 DSA *
00654 ldns_key_new_frm_fp_dsa_l(FILE *f, int *line_nr)
00655 {
00656         int i;
00657         char *d;
00658         DSA *dsa;
00659         uint8_t *buf;
00660 
00661         line_nr = line_nr;
00662 
00663         d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
00664         buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
00665         dsa = DSA_new();
00666         if (!d || !dsa || !buf) {
00667                 goto error;
00668         }
00669 
00670         /* the line parser removes the () from the input... */
00671 
00672         /* Prime, dsa->p */
00673         if (ldns_fget_keyword_data_l(f, "Primep", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00674                 goto error;
00675         }
00676         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00677 #ifndef S_SPLINT_S
00678         dsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL);
00679         if (!dsa->p) {
00680                 goto error;
00681         }
00682 
00683         /* Subprime, dsa->q */
00684         if (ldns_fget_keyword_data_l(f, "Subprimeq", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00685                 goto error;
00686         }
00687         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00688         dsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL);
00689         if (!dsa->q) {
00690                 goto error;
00691         }
00692 
00693         /* Base, dsa->g */
00694         if (ldns_fget_keyword_data_l(f, "Baseg", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00695                 goto error;
00696         }
00697         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00698         dsa->g = BN_bin2bn((const char unsigned*)buf, i, NULL);
00699         if (!dsa->g) {
00700                 goto error;
00701         }
00702 
00703         /* Private key, dsa->priv_key */
00704         if (ldns_fget_keyword_data_l(f, "Private_valuex", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00705                 goto error;
00706         }
00707         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00708         dsa->priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
00709         if (!dsa->priv_key) {
00710                 goto error;
00711         }
00712 
00713         /* Public key, dsa->priv_key */
00714         if (ldns_fget_keyword_data_l(f, "Public_valuey", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00715                 goto error;
00716         }
00717         i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
00718         dsa->pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
00719         if (!dsa->pub_key) {
00720                 goto error;
00721         }
00722 #endif /* splint */
00723 
00724         LDNS_FREE(buf);
00725         LDNS_FREE(d);
00726 
00727         return dsa;
00728 
00729 error:
00730         LDNS_FREE(d);
00731         LDNS_FREE(buf);
00732         DSA_free(dsa);
00733         return NULL;
00734 }
00735 
00736 unsigned char *
00737 ldns_key_new_frm_fp_hmac(FILE *f, size_t *hmac_size)
00738 {
00739         return ldns_key_new_frm_fp_hmac_l(f, NULL, hmac_size);
00740 }
00741 
00742 unsigned char *
00743 ldns_key_new_frm_fp_hmac_l(FILE *f, int *line_nr, size_t *hmac_size)
00744 {
00745         size_t i;
00746         char *d;
00747         unsigned char *buf;
00748 
00749         line_nr = line_nr;
00750 
00751         d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
00752         buf = LDNS_XMALLOC(unsigned char, LDNS_MAX_LINELEN);
00753         if(!d || !buf) {
00754                 goto error;
00755         }
00756 
00757         if (ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
00758                 goto error;
00759         }
00760         i = (size_t) ldns_b64_pton((const char*)d,
00761                                    buf,
00762                                    ldns_b64_ntop_calculate_size(strlen(d)));
00763 
00764         *hmac_size = i;
00765         return buf;
00766 
00767         error:
00768         LDNS_FREE(d);
00769         LDNS_FREE(buf);
00770         *hmac_size = 0;
00771         return NULL;
00772 }
00773 #endif /* HAVE_SSL */
00774 
00775 #ifdef USE_GOST
00776 static EVP_PKEY*
00777 ldns_gen_gost_key(void)
00778 {
00779         EVP_PKEY_CTX* ctx;
00780         EVP_PKEY* p = NULL;
00781         int gost_id = ldns_key_EVP_load_gost_id();
00782         if(!gost_id)
00783                 return NULL;
00784         ctx = EVP_PKEY_CTX_new_id(gost_id, NULL);
00785         if(!ctx) {
00786                 /* the id should be available now */
00787                 return NULL;
00788         }
00789         if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) {
00790                 /* cannot set paramset */
00791                 EVP_PKEY_CTX_free(ctx);
00792                 return NULL;
00793         }
00794 
00795         if(EVP_PKEY_keygen_init(ctx) <= 0) {
00796                 EVP_PKEY_CTX_free(ctx);
00797                 return NULL;
00798         }
00799         if(EVP_PKEY_keygen(ctx, &p) <= 0) {
00800                 EVP_PKEY_free(p);
00801                 EVP_PKEY_CTX_free(ctx);
00802                 return NULL;
00803         }
00804         EVP_PKEY_CTX_free(ctx);
00805         return p;
00806 }
00807 #endif
00808 
00809 ldns_key *
00810 ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
00811 {
00812         ldns_key *k;
00813 #ifdef HAVE_SSL
00814         DSA *d;
00815         RSA *r;
00816 #  ifdef USE_ECDSA
00817         EC_KEY *ec = NULL;
00818 #  endif
00819 #else
00820         int i;
00821         uint16_t offset = 0;
00822 #endif
00823         unsigned char *hmac;
00824 
00825         k = ldns_key_new();
00826         if (!k) {
00827                 return NULL;
00828         }
00829         switch(alg) {
00830                 case LDNS_SIGN_RSAMD5:
00831                 case LDNS_SIGN_RSASHA1:
00832                 case LDNS_SIGN_RSASHA1_NSEC3:
00833                 case LDNS_SIGN_RSASHA256:
00834                 case LDNS_SIGN_RSASHA512:
00835 #ifdef HAVE_SSL
00836                         r = RSA_generate_key((int)size, RSA_F4, NULL, NULL);
00837                         if(!r) {
00838                                 ldns_key_free(k);
00839                                 return NULL;
00840                         }
00841                         if (RSA_check_key(r) != 1) {
00842                                 ldns_key_free(k);
00843                                 return NULL;
00844                         }
00845                         ldns_key_set_rsa_key(k, r);
00846 #endif /* HAVE_SSL */
00847                         break;
00848                 case LDNS_SIGN_DSA:
00849                 case LDNS_SIGN_DSA_NSEC3:
00850 #ifdef HAVE_SSL
00851                         d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL);
00852                         if (!d) {
00853                                 ldns_key_free(k);
00854                                 return NULL;
00855                         }
00856                         if (DSA_generate_key(d) != 1) {
00857                                 ldns_key_free(k);
00858                                 return NULL;
00859                         }
00860                         ldns_key_set_dsa_key(k, d);
00861 #endif /* HAVE_SSL */
00862                         break;
00863                 case LDNS_SIGN_HMACMD5:
00864                 case LDNS_SIGN_HMACSHA1:
00865                 case LDNS_SIGN_HMACSHA256:
00866 #ifdef HAVE_SSL
00867 #ifndef S_SPLINT_S
00868                         k->_key.key = NULL;
00869 #endif /* splint */
00870 #endif /* HAVE_SSL */
00871                         size = size / 8;
00872                         ldns_key_set_hmac_size(k, size);
00873 
00874                         hmac = LDNS_XMALLOC(unsigned char, size);
00875                         if(!hmac) {
00876                                 ldns_key_free(k);
00877                                 return NULL;
00878                         }
00879 #ifdef HAVE_SSL
00880                         if (RAND_bytes(hmac, (int) size) != 1) {
00881                                 LDNS_FREE(hmac);
00882                                 ldns_key_free(k);
00883                                 return NULL;
00884                         }
00885 #else
00886                         while (offset + sizeof(i) < size) {
00887                           i = random();
00888                           memcpy(&hmac[offset], &i, sizeof(i));
00889                           offset += sizeof(i);
00890                         }
00891                         if (offset < size) {
00892                           i = random();
00893                           memcpy(&hmac[offset], &i, size - offset);
00894                         }
00895 #endif /* HAVE_SSL */
00896                         ldns_key_set_hmac_key(k, hmac);
00897 
00898                         ldns_key_set_flags(k, 0);
00899                         break;
00900                 case LDNS_SIGN_ECC_GOST:
00901 #if defined(HAVE_SSL) && defined(USE_GOST)
00902                         ldns_key_set_evp_key(k, ldns_gen_gost_key());
00903 #ifndef S_SPLINT_S
00904                         if(!k->_key.key) {
00905                                 ldns_key_free(k);
00906                                 return NULL;
00907                         }
00908 #endif /* splint */
00909 #endif /* HAVE_SSL and USE_GOST */
00910                         break;
00911 #ifdef USE_ECDSA
00912                 case LDNS_SIGN_ECDSAP256SHA256:
00913                 case LDNS_SIGN_ECDSAP384SHA384:
00914                         if(alg == LDNS_SIGN_ECDSAP256SHA256)
00915                                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
00916                         else if(alg == LDNS_SIGN_ECDSAP384SHA384)
00917                                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
00918                         if(!ec) {
00919                                 ldns_key_free(k);
00920                                 return NULL;
00921                         }
00922                         if(!EC_KEY_generate_key(ec)) {
00923                                 ldns_key_free(k);
00924                                 EC_KEY_free(ec);
00925                                 return NULL;
00926                         }
00927 #ifndef S_SPLINT_S
00928                         k->_key.key = EVP_PKEY_new();
00929                         if(!k->_key.key) {
00930                                 ldns_key_free(k);
00931                                 EC_KEY_free(ec);
00932                                 return NULL;
00933                         }
00934                         if (!EVP_PKEY_assign_EC_KEY(k->_key.key, ec)) {
00935                                 ldns_key_free(k);
00936                                 EC_KEY_free(ec);
00937                                 return NULL;
00938                         }
00939 #endif /* splint */
00940                         break;
00941 #endif
00942         }
00943         ldns_key_set_algorithm(k, alg);
00944         return k;
00945 }
00946 
00947 void
00948 ldns_key_print(FILE *output, const ldns_key *k)
00949 {
00950         char *str = ldns_key2str(k);
00951         if (str) {
00952                 fprintf(output, "%s", str);
00953         } else {
00954                 fprintf(output, "Unable to convert private key to string\n");
00955         }
00956         LDNS_FREE(str);
00957 }
00958 
00959 
00960 void
00961 ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l)
00962 {
00963         k->_alg = l;
00964 }
00965 
00966 void
00967 ldns_key_set_flags(ldns_key *k, uint16_t f)
00968 {
00969         k->_extra.dnssec.flags = f;
00970 }
00971 
00972 #ifdef HAVE_SSL
00973 #ifndef S_SPLINT_S
00974 void
00975 ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e)
00976 {
00977         k->_key.key = e;
00978 }
00979 
00980 void
00981 ldns_key_set_rsa_key(ldns_key *k, RSA *r)
00982 {
00983         EVP_PKEY *key = EVP_PKEY_new();
00984         EVP_PKEY_set1_RSA(key, r);
00985         k->_key.key = key;
00986 }
00987 
00988 void
00989 ldns_key_set_dsa_key(ldns_key *k, DSA *d)
00990 {
00991         EVP_PKEY *key = EVP_PKEY_new();
00992         EVP_PKEY_set1_DSA(key, d);
00993         k->_key.key  = key;
00994 }
00995 #endif /* splint */
00996 #endif /* HAVE_SSL */
00997 
00998 void
00999 ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac)
01000 {
01001         k->_key.hmac.key = hmac;
01002 }
01003 
01004 void
01005 ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size)
01006 {
01007         k->_key.hmac.size = hmac_size;
01008 }
01009 
01010 void
01011 ldns_key_set_external_key(ldns_key *k, void *external_key)
01012 {
01013         k->_key.external_key = external_key;
01014 }
01015 
01016 void
01017 ldns_key_set_origttl(ldns_key *k, uint32_t t)
01018 {
01019         k->_extra.dnssec.orig_ttl = t;
01020 }
01021 
01022 void
01023 ldns_key_set_inception(ldns_key *k, uint32_t i)
01024 {
01025         k->_extra.dnssec.inception = i;
01026 }
01027 
01028 void
01029 ldns_key_set_expiration(ldns_key *k, uint32_t e)
01030 {
01031         k->_extra.dnssec.expiration = e;
01032 }
01033 
01034 void
01035 ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r)
01036 {
01037         k->_pubkey_owner = r;
01038 }
01039 
01040 void
01041 ldns_key_set_keytag(ldns_key *k, uint16_t tag)
01042 {
01043         k->_extra.dnssec.keytag = tag;
01044 }
01045 
01046 /* read */
01047 size_t
01048 ldns_key_list_key_count(const ldns_key_list *key_list)
01049 {
01050                 return key_list->_key_count;
01051 }       
01052 
01053 ldns_key *
01054 ldns_key_list_key(const ldns_key_list *key, size_t nr)
01055 {       
01056         if (nr < ldns_key_list_key_count(key)) {
01057                 return key->_keys[nr];
01058         } else {
01059                 return NULL;
01060         }
01061 }
01062 
01063 ldns_signing_algorithm
01064 ldns_key_algorithm(const ldns_key *k) 
01065 {
01066         return k->_alg;
01067 }
01068 
01069 void
01070 ldns_key_set_use(ldns_key *k, bool v)
01071 {
01072         if (k) {
01073                 k->_use = v;
01074         }
01075 }
01076 
01077 bool
01078 ldns_key_use(const ldns_key *k)
01079 {
01080         if (k) {
01081                 return k->_use;
01082         }
01083         return false;
01084 }
01085 
01086 #ifdef HAVE_SSL
01087 #ifndef S_SPLINT_S
01088 EVP_PKEY *
01089 ldns_key_evp_key(const ldns_key *k)
01090 {
01091         return k->_key.key;
01092 }
01093 
01094 RSA *
01095 ldns_key_rsa_key(const ldns_key *k)
01096 {
01097         if (k->_key.key) {
01098                 return EVP_PKEY_get1_RSA(k->_key.key);
01099         } else {
01100                 return NULL;
01101         }
01102 }
01103 
01104 DSA *
01105 ldns_key_dsa_key(const ldns_key *k)
01106 {
01107         if (k->_key.key) {
01108                 return EVP_PKEY_get1_DSA(k->_key.key);
01109         } else {
01110                 return NULL;
01111         }
01112 }
01113 #endif /* splint */
01114 #endif /* HAVE_SSL */
01115 
01116 unsigned char *
01117 ldns_key_hmac_key(const ldns_key *k)
01118 {
01119         if (k->_key.hmac.key) {
01120                 return k->_key.hmac.key;
01121         } else {
01122                 return NULL;
01123         }
01124 }
01125 
01126 size_t
01127 ldns_key_hmac_size(const ldns_key *k)
01128 {
01129         if (k->_key.hmac.size) {
01130                 return k->_key.hmac.size;
01131         } else {
01132                 return 0;
01133         }
01134 }
01135 
01136 void *
01137 ldns_key_external_key(const ldns_key *k)
01138 {
01139         return k->_key.external_key;
01140 }
01141 
01142 uint32_t
01143 ldns_key_origttl(const ldns_key *k)
01144 {
01145         return k->_extra.dnssec.orig_ttl;
01146 }
01147 
01148 uint16_t
01149 ldns_key_flags(const ldns_key *k)
01150 {
01151         return k->_extra.dnssec.flags;
01152 }
01153 
01154 uint32_t
01155 ldns_key_inception(const ldns_key *k)
01156 {
01157         return k->_extra.dnssec.inception;
01158 }
01159 
01160 uint32_t
01161 ldns_key_expiration(const ldns_key *k)
01162 {
01163         return k->_extra.dnssec.expiration;
01164 }
01165 
01166 uint16_t
01167 ldns_key_keytag(const ldns_key *k)
01168 {
01169         return k->_extra.dnssec.keytag;
01170 }
01171 
01172 ldns_rdf *
01173 ldns_key_pubkey_owner(const ldns_key *k)
01174 {
01175         return k->_pubkey_owner;
01176 }
01177 
01178 /* write */
01179 void
01180 ldns_key_list_set_use(ldns_key_list *keys, bool v)
01181 {
01182         size_t i;
01183 
01184         for (i = 0; i < ldns_key_list_key_count(keys); i++) {
01185                 ldns_key_set_use(ldns_key_list_key(keys, i), v);
01186         }
01187 }
01188 
01189 void            
01190 ldns_key_list_set_key_count(ldns_key_list *key, size_t count)
01191 {
01192                 key->_key_count = count;
01193 }       
01194 
01195 bool             
01196 ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key)
01197 {       
01198         size_t key_count;
01199         ldns_key **keys;
01200 
01201         key_count = ldns_key_list_key_count(key_list);
01202 
01203         /* grow the array */
01204         keys = LDNS_XREALLOC(
01205                 key_list->_keys, ldns_key *, key_count + 1);
01206         if (!keys) {
01207                 return false;
01208         }
01209 
01210         /* add the new member */
01211         key_list->_keys = keys;
01212         key_list->_keys[key_count] = key;
01213 
01214         ldns_key_list_set_key_count(key_list, key_count + 1);
01215         return true;
01216 }
01217 
01218 ldns_key *
01219 ldns_key_list_pop_key(ldns_key_list *key_list)
01220 {                               
01221         size_t key_count;
01222         ldns_key** a;
01223         ldns_key *pop;
01224 
01225         if (!key_list) {
01226                 return NULL;
01227         }
01228         
01229         key_count = ldns_key_list_key_count(key_list);
01230         if (key_count == 0) {
01231                 return NULL;
01232         }       
01233         
01234         pop = ldns_key_list_key(key_list, key_count);
01235         
01236         /* shrink the array */
01237         a = LDNS_XREALLOC(key_list->_keys, ldns_key *, key_count - 1);
01238         if(a) {
01239                 key_list->_keys = a;
01240         }
01241 
01242         ldns_key_list_set_key_count(key_list, key_count - 1);
01243 
01244         return pop;
01245 }       
01246 
01247 #ifdef HAVE_SSL
01248 #ifndef S_SPLINT_S
01249 /* data pointer must be large enough (LDNS_MAX_KEYLEN) */
01250 static bool
01251 ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size)
01252 {
01253         int i,j;
01254         
01255         if (!k) {
01256                 return false;
01257         }
01258         
01259         if (BN_num_bytes(k->e) <= 256) {
01260                 /* normally only this path is executed (small factors are
01261                  * more common 
01262                  */
01263                 data[0] = (unsigned char) BN_num_bytes(k->e);
01264                 i = BN_bn2bin(k->e, data + 1);  
01265                 j = BN_bn2bin(k->n, data + i + 1);
01266                 *size = (uint16_t) i + j;
01267         } else if (BN_num_bytes(k->e) <= 65536) {
01268                 data[0] = 0;
01269                 /* BN_bn2bin does bigendian, _uint16 also */
01270                 ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(k->e)); 
01271 
01272                 BN_bn2bin(k->e, data + 3); 
01273                 BN_bn2bin(k->n, data + 4 + BN_num_bytes(k->e));
01274                 *size = (uint16_t) BN_num_bytes(k->n) + 6;
01275         } else {
01276                 return false;
01277         }
01278         return true;
01279 }
01280 
01281 /* data pointer must be large enough (LDNS_MAX_KEYLEN) */
01282 static bool
01283 ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size)
01284 {
01285         uint8_t T;
01286 
01287         if (!k) {
01288                 return false;
01289         }
01290         
01291         /* See RFC2536 */
01292         *size = (uint16_t)BN_num_bytes(k->g);
01293         T = (*size - 64) / 8;
01294         memcpy(data, &T, 1);
01295 
01296         if (T > 8) {
01297                 fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)");
01298                 fprintf(stderr, " not implemented\n");
01299                 return false;
01300         }
01301 
01302         /* size = 64 + (T * 8); */
01303         data[0] = (unsigned char)T;
01304         BN_bn2bin(k->q, data + 1 );             /* 20 octects */
01305         BN_bn2bin(k->p, data + 21 );            /* offset octects */
01306         BN_bn2bin(k->g, data + 21 + *size);     /* offset octets */
01307         BN_bn2bin(k->pub_key, data + 21 + *size + *size); /* offset octets */
01308         *size = 21 + (*size * 3);
01309         return true;
01310 }
01311 
01312 #ifdef USE_GOST
01313 static bool
01314 ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
01315 {
01316         int i;
01317         unsigned char* pp = NULL;
01318         if(i2d_PUBKEY(k, &pp) != 37 + 64) {
01319                 /* expect 37 byte(ASN header) and 64 byte(X and Y) */
01320                 CRYPTO_free(pp);
01321                 return false;
01322         }
01323         /* omit ASN header */
01324         for(i=0; i<64; i++)
01325                 data[i] = pp[i+37];
01326         CRYPTO_free(pp);
01327         *size = 64;
01328         return true;
01329 }
01330 #endif /* USE_GOST */
01331 #endif /* splint */
01332 #endif /* HAVE_SSL */
01333 
01334 ldns_rr *
01335 ldns_key2rr(const ldns_key *k)
01336 {
01337         /* this function will convert a the keydata contained in
01338          * rsa/dsa pointers to a DNSKEY rr. It will fill in as
01339          * much as it can, but it does not know about key-flags
01340          * for instance
01341          */
01342         ldns_rr *pubkey;
01343         ldns_rdf *keybin;
01344         unsigned char *bin = NULL;
01345         uint16_t size = 0;
01346 #ifdef HAVE_SSL
01347         RSA *rsa = NULL;
01348         DSA *dsa = NULL;
01349 #endif /* HAVE_SSL */
01350 #ifdef USE_ECDSA
01351         EC_KEY* ec;
01352 #endif
01353         int internal_data = 0;
01354 
01355         pubkey = ldns_rr_new();
01356         if (!k) {
01357                 return NULL;
01358         }
01359 
01360         switch (ldns_key_algorithm(k)) {
01361         case LDNS_SIGN_HMACMD5:
01362         case LDNS_SIGN_HMACSHA1:
01363         case LDNS_SIGN_HMACSHA256:
01364                 ldns_rr_set_type(pubkey, LDNS_RR_TYPE_KEY);
01365                 break;
01366         default:
01367                 ldns_rr_set_type(pubkey, LDNS_RR_TYPE_DNSKEY);
01368                 break;
01369         }
01370         /* zero-th rdf - flags */
01371         ldns_rr_push_rdf(pubkey,
01372                         ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
01373                                 ldns_key_flags(k)));
01374         /* first - proto */
01375         ldns_rr_push_rdf(pubkey,
01376                         ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, LDNS_DNSSEC_KEYPROTO));
01377 
01378         if (ldns_key_pubkey_owner(k)) {
01379                 ldns_rr_set_owner(pubkey, ldns_rdf_clone(ldns_key_pubkey_owner(k)));
01380         }
01381 
01382         /* third - da algorithm */
01383         switch(ldns_key_algorithm(k)) {
01384                 case LDNS_SIGN_RSAMD5:
01385                 case LDNS_SIGN_RSASHA1:
01386                 case LDNS_SIGN_RSASHA1_NSEC3:
01387                 case LDNS_SIGN_RSASHA256:
01388                 case LDNS_SIGN_RSASHA512:
01389                         ldns_rr_push_rdf(pubkey,
01390                                                   ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
01391 #ifdef HAVE_SSL
01392                         rsa =  ldns_key_rsa_key(k);
01393                         if (rsa) {
01394                                 bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
01395                                 if (!bin) {
01396                                         ldns_rr_free(pubkey);
01397                                         return NULL;
01398                                 }
01399                                 if (!ldns_key_rsa2bin(bin, rsa, &size)) {
01400                                         LDNS_FREE(bin);
01401                                         ldns_rr_free(pubkey);
01402                                         return NULL;
01403                                 }
01404                                 RSA_free(rsa);
01405                                 internal_data = 1;
01406                         }
01407 #endif
01408                         size++;
01409                         break;
01410                 case LDNS_SIGN_DSA:
01411                         ldns_rr_push_rdf(pubkey,
01412                                         ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA));
01413 #ifdef HAVE_SSL
01414                         dsa = ldns_key_dsa_key(k);
01415                         if (dsa) {
01416                                 bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
01417                                 if (!bin) {
01418                                         ldns_rr_free(pubkey);
01419                                         return NULL;
01420                                 }
01421                                 if (!ldns_key_dsa2bin(bin, dsa, &size)) {
01422                                         LDNS_FREE(bin);
01423                                         ldns_rr_free(pubkey);
01424                                         return NULL;
01425                                 }
01426                                 DSA_free(dsa);
01427                                 internal_data = 1;
01428                         }
01429 #endif /* HAVE_SSL */
01430                         break;
01431                 case LDNS_SIGN_DSA_NSEC3:
01432                         ldns_rr_push_rdf(pubkey,
01433                                         ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3));
01434 #ifdef HAVE_SSL
01435                         dsa = ldns_key_dsa_key(k);
01436                         if (dsa) {
01437                                 bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
01438                                 if (!bin) {
01439                                         ldns_rr_free(pubkey);
01440                                         return NULL;
01441                                 }
01442                                 if (!ldns_key_dsa2bin(bin, dsa, &size)) {
01443                                         LDNS_FREE(bin);
01444                                         ldns_rr_free(pubkey);
01445                                         return NULL;
01446                                 }
01447                                 DSA_free(dsa);
01448                                 internal_data = 1;
01449                         }
01450 #endif /* HAVE_SSL */
01451                         break;
01452                 case LDNS_SIGN_ECC_GOST:
01453                         ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
01454                                 LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
01455 #if defined(HAVE_SSL) && defined(USE_GOST)
01456                         bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
01457                         if (!bin) {
01458                                 ldns_rr_free(pubkey);
01459                                 return NULL;
01460                         }
01461 #ifndef S_SPLINT_S
01462                         if (!ldns_key_gost2bin(bin, k->_key.key, &size)) {
01463                                 LDNS_FREE(bin);
01464                                 ldns_rr_free(pubkey);
01465                                 return NULL;
01466                         }
01467 #endif /* splint */
01468                         internal_data = 1;
01469 #endif /* HAVE_SSL and USE_GOST */
01470                         break;
01471 #ifdef USE_ECDSA
01472                 case LDNS_SIGN_ECDSAP256SHA256:
01473                 case LDNS_SIGN_ECDSAP384SHA384:
01474                         ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
01475                                 LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
01476                         bin = NULL;
01477 #ifndef S_SPLINT_S
01478                         ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
01479 #endif
01480                         EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
01481                         size = (uint16_t)i2o_ECPublicKey(ec, NULL);
01482                         if(!i2o_ECPublicKey(ec, &bin)) {
01483                                 EC_KEY_free(ec);
01484                                 ldns_rr_free(pubkey);
01485                                 return NULL;
01486                         }
01487                         if(size > 1) {
01488                                 /* move back one byte to shave off the 0x02
01489                                  * 'uncompressed' indicator that openssl made
01490                                  * Actually its 0x04 (from implementation).
01491                                  */
01492                                 assert(bin[0] == POINT_CONVERSION_UNCOMPRESSED);
01493                                 size -= 1;
01494                                 memmove(bin, bin+1, size);
01495                         }
01496                         /* down the reference count for ec, its still assigned
01497                          * to the pkey */
01498                         EC_KEY_free(ec);
01499                         internal_data = 1;
01500                         break;
01501 #endif
01502                 case LDNS_SIGN_HMACMD5:
01503                 case LDNS_SIGN_HMACSHA1:
01504                 case LDNS_SIGN_HMACSHA256:
01505                         bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k));
01506                         if (!bin) {
01507                                 ldns_rr_free(pubkey);
01508                                 return NULL;
01509                         }
01510                         ldns_rr_push_rdf(pubkey,
01511                                          ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG,
01512                                          ldns_key_algorithm(k)));
01513                         size = ldns_key_hmac_size(k);
01514                         memcpy(bin, ldns_key_hmac_key(k), size);
01515                         internal_data = 1;
01516                         break;
01517         }
01518         /* fourth the key bin material */
01519         if (internal_data) {
01520                 keybin = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, size, bin);
01521                 LDNS_FREE(bin);
01522                 ldns_rr_push_rdf(pubkey, keybin);
01523         }
01524         return pubkey;
01525 }
01526 
01527 void
01528 ldns_key_free(ldns_key *key)
01529 {
01530         LDNS_FREE(key);
01531 }
01532 
01533 void
01534 ldns_key_deep_free(ldns_key *key)
01535 {
01536         if (ldns_key_pubkey_owner(key)) {
01537                 ldns_rdf_deep_free(ldns_key_pubkey_owner(key));
01538         }
01539 #ifdef HAVE_SSL
01540         if (ldns_key_evp_key(key)) {
01541                 EVP_PKEY_free(ldns_key_evp_key(key));
01542         }
01543 #endif /* HAVE_SSL */
01544         if (ldns_key_hmac_key(key)) {
01545                 free(ldns_key_hmac_key(key));
01546         }
01547         LDNS_FREE(key);
01548 }
01549 
01550 void
01551 ldns_key_list_free(ldns_key_list *key_list)
01552 {
01553         size_t i;
01554         for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
01555                 ldns_key_deep_free(ldns_key_list_key(key_list, i));
01556         }
01557         LDNS_FREE(key_list->_keys);
01558         LDNS_FREE(key_list);
01559 }
01560 
01561 ldns_rr *
01562 ldns_read_anchor_file(const char *filename)
01563 {
01564         FILE *fp;
01565         /*char line[LDNS_MAX_PACKETLEN];*/
01566         char *line = LDNS_XMALLOC(char, LDNS_MAX_PACKETLEN);
01567         int c;
01568         size_t i = 0;
01569         ldns_rr *r;
01570         ldns_status status;
01571         if(!line) {
01572                 return NULL;
01573         }
01574 
01575         fp = fopen(filename, "r");
01576         if (!fp) {
01577                 fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
01578                 LDNS_FREE(line);
01579                 return NULL;
01580         }
01581         
01582         while ((c = fgetc(fp)) && i+1 < LDNS_MAX_PACKETLEN && c != EOF) {
01583                 line[i] = c;
01584                 i++;
01585         }
01586         line[i] = '\0';
01587         
01588         fclose(fp);
01589         
01590         if (i <= 0) {
01591                 fprintf(stderr, "nothing read from %s", filename);
01592                 LDNS_FREE(line);
01593                 return NULL;
01594         } else {
01595                 status = ldns_rr_new_frm_str(&r, line, 0, NULL, NULL);
01596                 if (status == LDNS_STATUS_OK && (ldns_rr_get_type(r) == LDNS_RR_TYPE_DNSKEY || ldns_rr_get_type(r) == LDNS_RR_TYPE_DS)) {
01597                         LDNS_FREE(line);
01598                         return r;
01599                 } else {
01600                         fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status));
01601                         LDNS_FREE(line);
01602                         return NULL;
01603                 }
01604         }
01605 }
01606 
01607 char *
01608 ldns_key_get_file_base_name(ldns_key *key)
01609 {
01610         ldns_buffer *buffer;
01611         char *file_base_name;
01612         
01613         buffer = ldns_buffer_new(255);
01614         ldns_buffer_printf(buffer, "K");
01615         (void)ldns_rdf2buffer_str_dname(buffer, ldns_key_pubkey_owner(key));
01616         ldns_buffer_printf(buffer,
01617                            "+%03u+%05u",
01618                            ldns_key_algorithm(key),
01619                            ldns_key_keytag(key));
01620         file_base_name = strdup(ldns_buffer_export(buffer));
01621         ldns_buffer_free(buffer);
01622         return file_base_name;
01623 }
01624 
01625 int ldns_key_algo_supported(int algo)
01626 {
01627         ldns_lookup_table *lt = ldns_signing_algorithms;
01628         while(lt->name) {
01629                 if(lt->id == algo)
01630                         return 1;
01631                 lt++;
01632         }
01633         return 0;
01634 }
01635 
01636 ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name)
01637 {
01638         /* list of (signing algorithm id, alias_name) */
01639         ldns_lookup_table aliases[] = {
01640                 /* from bind dnssec-keygen */
01641                 {LDNS_SIGN_HMACMD5, "HMAC-MD5"},
01642                 {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"},
01643                 {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"},
01644                 /* old ldns usage, now RFC names */
01645                 {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" },
01646                 {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" },
01647 #ifdef USE_GOST
01648                 {LDNS_SIGN_ECC_GOST, "GOST"},
01649 #endif
01650                 /* compat with possible output */
01651                 {LDNS_DH, "DH"},
01652                 {LDNS_ECC, "ECC"},
01653                 {LDNS_INDIRECT, "INDIRECT"},
01654                 {LDNS_PRIVATEDNS, "PRIVATEDNS"},
01655                 {LDNS_PRIVATEOID, "PRIVATEOID"},
01656                 {0, NULL}};
01657         ldns_lookup_table* lt = ldns_signing_algorithms;
01658         while(lt->name) {
01659                 if(strcasecmp(lt->name, name) == 0)
01660                         return lt->id;
01661                 lt++;
01662         }
01663         lt = aliases;
01664         while(lt->name) {
01665                 if(strcasecmp(lt->name, name) == 0)
01666                         return lt->id;
01667                 lt++;
01668         }
01669         if(atoi(name) != 0)
01670                 return atoi(name);
01671         return 0;
01672 }

Generated on Thu Apr 5 23:03:55 2012 for ldns by  doxygen 1.4.7