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