keys.c

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

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