1238104Sdes/* 2238104Sdes * keys.c handle private keys for use in DNSSEC 3238104Sdes * 4238104Sdes * This module should hide some of the openSSL complexities 5238104Sdes * and give a general interface for private keys and hmac 6238104Sdes * handling 7238104Sdes * 8238104Sdes * (c) NLnet Labs, 2004-2006 9238104Sdes * 10238104Sdes * See the file LICENSE for the license 11238104Sdes */ 12238104Sdes 13238104Sdes#include <ldns/config.h> 14238104Sdes 15238104Sdes#include <ldns/ldns.h> 16238104Sdes 17238104Sdes#ifdef HAVE_SSL 18238104Sdes#include <openssl/ssl.h> 19238104Sdes#include <openssl/engine.h> 20238104Sdes#include <openssl/rand.h> 21238104Sdes#endif /* HAVE_SSL */ 22238104Sdes 23238104Sdesldns_lookup_table ldns_signing_algorithms[] = { 24238104Sdes { LDNS_SIGN_RSAMD5, "RSAMD5" }, 25238104Sdes { LDNS_SIGN_RSASHA1, "RSASHA1" }, 26238104Sdes { LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" }, 27238104Sdes#ifdef USE_SHA2 28238104Sdes { LDNS_SIGN_RSASHA256, "RSASHA256" }, 29238104Sdes { LDNS_SIGN_RSASHA512, "RSASHA512" }, 30238104Sdes#endif 31238104Sdes#ifdef USE_GOST 32238104Sdes { LDNS_SIGN_ECC_GOST, "ECC-GOST" }, 33238104Sdes#endif 34238104Sdes#ifdef USE_ECDSA 35238104Sdes { LDNS_SIGN_ECDSAP256SHA256, "ECDSAP256SHA256" }, 36238104Sdes { LDNS_SIGN_ECDSAP384SHA384, "ECDSAP384SHA384" }, 37238104Sdes#endif 38238104Sdes { LDNS_SIGN_DSA, "DSA" }, 39238104Sdes { LDNS_SIGN_DSA_NSEC3, "DSA-NSEC3-SHA1" }, 40238104Sdes { LDNS_SIGN_HMACMD5, "hmac-md5.sig-alg.reg.int" }, 41238104Sdes { LDNS_SIGN_HMACSHA1, "hmac-sha1" }, 42238104Sdes { LDNS_SIGN_HMACSHA256, "hmac-sha256" }, 43238104Sdes { 0, NULL } 44238104Sdes}; 45238104Sdes 46238104Sdesldns_key_list * 47246827Sdesldns_key_list_new(void) 48238104Sdes{ 49238104Sdes ldns_key_list *key_list = LDNS_MALLOC(ldns_key_list); 50238104Sdes if (!key_list) { 51238104Sdes return NULL; 52238104Sdes } else { 53238104Sdes key_list->_key_count = 0; 54238104Sdes key_list->_keys = NULL; 55238104Sdes return key_list; 56238104Sdes } 57238104Sdes} 58238104Sdes 59238104Sdesldns_key * 60246827Sdesldns_key_new(void) 61238104Sdes{ 62238104Sdes ldns_key *newkey; 63238104Sdes 64238104Sdes newkey = LDNS_MALLOC(ldns_key); 65238104Sdes if (!newkey) { 66238104Sdes return NULL; 67238104Sdes } else { 68238104Sdes /* some defaults - not sure wether to do this */ 69238104Sdes ldns_key_set_use(newkey, true); 70238104Sdes ldns_key_set_flags(newkey, LDNS_KEY_ZONE_KEY); 71238104Sdes ldns_key_set_origttl(newkey, 0); 72238104Sdes ldns_key_set_keytag(newkey, 0); 73238104Sdes ldns_key_set_inception(newkey, 0); 74238104Sdes ldns_key_set_expiration(newkey, 0); 75238104Sdes ldns_key_set_pubkey_owner(newkey, NULL); 76238104Sdes#ifdef HAVE_SSL 77238104Sdes ldns_key_set_evp_key(newkey, NULL); 78238104Sdes#endif /* HAVE_SSL */ 79238104Sdes ldns_key_set_hmac_key(newkey, NULL); 80238104Sdes ldns_key_set_external_key(newkey, NULL); 81238104Sdes return newkey; 82238104Sdes } 83238104Sdes} 84238104Sdes 85238104Sdesldns_status 86238104Sdesldns_key_new_frm_fp(ldns_key **k, FILE *fp) 87238104Sdes{ 88238104Sdes return ldns_key_new_frm_fp_l(k, fp, NULL); 89238104Sdes} 90238104Sdes 91238104Sdes#ifdef HAVE_SSL 92238104Sdesldns_status 93238104Sdesldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm alg) 94238104Sdes{ 95238104Sdes ldns_key *k; 96238104Sdes 97238104Sdes k = ldns_key_new(); 98238104Sdes if(!k) return LDNS_STATUS_MEM_ERR; 99238104Sdes#ifndef S_SPLINT_S 100238104Sdes k->_key.key = ENGINE_load_private_key(e, key_id, UI_OpenSSL(), NULL); 101238104Sdes if(!k->_key.key) { 102238104Sdes ldns_key_free(k); 103238104Sdes return LDNS_STATUS_ERR; 104238104Sdes } 105238104Sdes ldns_key_set_algorithm(k, (ldns_signing_algorithm) alg); 106238104Sdes if (!k->_key.key) { 107238104Sdes ldns_key_free(k); 108238104Sdes return LDNS_STATUS_ENGINE_KEY_NOT_LOADED; 109238104Sdes } 110238104Sdes#endif /* splint */ 111238104Sdes *key = k; 112238104Sdes return LDNS_STATUS_OK; 113238104Sdes} 114238104Sdes#endif 115238104Sdes 116238104Sdes#ifdef USE_GOST 117238104Sdes/** store GOST engine reference loaded into OpenSSL library */ 118238104SdesENGINE* ldns_gost_engine = NULL; 119238104Sdes 120238104Sdesint 121238104Sdesldns_key_EVP_load_gost_id(void) 122238104Sdes{ 123238104Sdes static int gost_id = 0; 124238104Sdes const EVP_PKEY_ASN1_METHOD* meth; 125238104Sdes ENGINE* e; 126238104Sdes 127238104Sdes if(gost_id) return gost_id; 128238104Sdes 129238104Sdes /* see if configuration loaded gost implementation from other engine*/ 130238104Sdes meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1); 131238104Sdes if(meth) { 132238104Sdes EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth); 133238104Sdes return gost_id; 134238104Sdes } 135238104Sdes 136238104Sdes /* see if engine can be loaded already */ 137238104Sdes e = ENGINE_by_id("gost"); 138238104Sdes if(!e) { 139238104Sdes /* load it ourself, in case statically linked */ 140238104Sdes ENGINE_load_builtin_engines(); 141238104Sdes ENGINE_load_dynamic(); 142238104Sdes e = ENGINE_by_id("gost"); 143238104Sdes } 144238104Sdes if(!e) { 145238104Sdes /* no gost engine in openssl */ 146238104Sdes return 0; 147238104Sdes } 148238104Sdes if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { 149238104Sdes ENGINE_finish(e); 150238104Sdes ENGINE_free(e); 151238104Sdes return 0; 152238104Sdes } 153238104Sdes 154238104Sdes meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1); 155238104Sdes if(!meth) { 156238104Sdes /* algo not found */ 157238104Sdes ENGINE_finish(e); 158238104Sdes ENGINE_free(e); 159238104Sdes return 0; 160238104Sdes } 161238104Sdes /* Note: do not ENGINE_finish and ENGINE_free the acquired engine 162238104Sdes * on some platforms this frees up the meth and unloads gost stuff */ 163238104Sdes ldns_gost_engine = e; 164238104Sdes 165238104Sdes EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth); 166238104Sdes return gost_id; 167238104Sdes} 168238104Sdes 169238104Sdesvoid ldns_key_EVP_unload_gost(void) 170238104Sdes{ 171238104Sdes if(ldns_gost_engine) { 172238104Sdes ENGINE_finish(ldns_gost_engine); 173238104Sdes ENGINE_free(ldns_gost_engine); 174238104Sdes ldns_gost_engine = NULL; 175238104Sdes } 176238104Sdes} 177238104Sdes 178238104Sdes/** read GOST private key */ 179238104Sdesstatic EVP_PKEY* 180238104Sdesldns_key_new_frm_fp_gost_l(FILE* fp, int* line_nr) 181238104Sdes{ 182238104Sdes char token[16384]; 183238104Sdes const unsigned char* pp; 184238104Sdes int gost_id; 185238104Sdes EVP_PKEY* pkey; 186238104Sdes ldns_rdf* b64rdf = NULL; 187238104Sdes 188238104Sdes gost_id = ldns_key_EVP_load_gost_id(); 189238104Sdes if(!gost_id) 190238104Sdes return NULL; 191238104Sdes 192238104Sdes if (ldns_fget_keyword_data_l(fp, "GostAsn1", ": ", token, "\n", 193238104Sdes sizeof(token), line_nr) == -1) 194238104Sdes return NULL; 195238104Sdes while(strlen(token) < 96) { 196238104Sdes /* read more b64 from the file, b64 split on multiple lines */ 197238104Sdes if(ldns_fget_token_l(fp, token+strlen(token), "\n", 198238104Sdes sizeof(token)-strlen(token), line_nr) == -1) 199238104Sdes return NULL; 200238104Sdes } 201238104Sdes if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK) 202238104Sdes return NULL; 203238104Sdes pp = (unsigned char*)ldns_rdf_data(b64rdf); 204238104Sdes pkey = d2i_PrivateKey(gost_id, NULL, &pp, (int)ldns_rdf_size(b64rdf)); 205238104Sdes ldns_rdf_deep_free(b64rdf); 206238104Sdes return pkey; 207238104Sdes} 208238104Sdes#endif 209238104Sdes 210238104Sdes#ifdef USE_ECDSA 211238104Sdes/** calculate public key from private key */ 212238104Sdesstatic int 213238104Sdesldns_EC_KEY_calc_public(EC_KEY* ec) 214238104Sdes{ 215238104Sdes EC_POINT* pub_key; 216238104Sdes const EC_GROUP* group; 217238104Sdes group = EC_KEY_get0_group(ec); 218238104Sdes pub_key = EC_POINT_new(group); 219238104Sdes if(!pub_key) return 0; 220238104Sdes if(!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { 221238104Sdes EC_POINT_free(pub_key); 222238104Sdes return 0; 223238104Sdes } 224238104Sdes if(!EC_POINT_mul(group, pub_key, EC_KEY_get0_private_key(ec), 225238104Sdes NULL, NULL, NULL)) { 226238104Sdes EC_POINT_free(pub_key); 227238104Sdes return 0; 228238104Sdes } 229238104Sdes if(EC_KEY_set_public_key(ec, pub_key) == 0) { 230238104Sdes EC_POINT_free(pub_key); 231238104Sdes return 0; 232238104Sdes } 233238104Sdes EC_POINT_free(pub_key); 234238104Sdes return 1; 235238104Sdes} 236238104Sdes 237238104Sdes/** read ECDSA private key */ 238238104Sdesstatic EVP_PKEY* 239238104Sdesldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr) 240238104Sdes{ 241238104Sdes char token[16384]; 242238104Sdes ldns_rdf* b64rdf = NULL; 243238104Sdes unsigned char* pp; 244238104Sdes BIGNUM* bn; 245238104Sdes EVP_PKEY* evp_key; 246238104Sdes EC_KEY* ec; 247238104Sdes if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", 248238104Sdes sizeof(token), line_nr) == -1) 249238104Sdes return NULL; 250238104Sdes if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK) 251238104Sdes return NULL; 252238104Sdes pp = (unsigned char*)ldns_rdf_data(b64rdf); 253238104Sdes 254238104Sdes if(alg == LDNS_ECDSAP256SHA256) 255238104Sdes ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 256238104Sdes else if(alg == LDNS_ECDSAP384SHA384) 257238104Sdes ec = EC_KEY_new_by_curve_name(NID_secp384r1); 258238104Sdes else ec = NULL; 259238104Sdes if(!ec) { 260238104Sdes ldns_rdf_deep_free(b64rdf); 261238104Sdes return NULL; 262238104Sdes } 263238104Sdes bn = BN_bin2bn(pp, (int)ldns_rdf_size(b64rdf), NULL); 264238104Sdes ldns_rdf_deep_free(b64rdf); 265238104Sdes if(!bn) { 266238104Sdes EC_KEY_free(ec); 267238104Sdes return NULL; 268238104Sdes } 269238104Sdes EC_KEY_set_private_key(ec, bn); 270238104Sdes BN_free(bn); 271238104Sdes if(!ldns_EC_KEY_calc_public(ec)) { 272238104Sdes EC_KEY_free(ec); 273238104Sdes return NULL; 274238104Sdes } 275238104Sdes 276238104Sdes evp_key = EVP_PKEY_new(); 277238104Sdes if(!evp_key) { 278238104Sdes EC_KEY_free(ec); 279238104Sdes return NULL; 280238104Sdes } 281238104Sdes if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) { 282238104Sdes EVP_PKEY_free(evp_key); 283238104Sdes EC_KEY_free(ec); 284238104Sdes return NULL; 285238104Sdes } 286238104Sdes return evp_key; 287238104Sdes} 288238104Sdes#endif 289238104Sdes 290238104Sdesldns_status 291238104Sdesldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr) 292238104Sdes{ 293238104Sdes ldns_key *k; 294238104Sdes char *d; 295238104Sdes ldns_signing_algorithm alg; 296238104Sdes ldns_rr *key_rr; 297238104Sdes#ifdef HAVE_SSL 298238104Sdes RSA *rsa; 299238104Sdes DSA *dsa; 300238104Sdes unsigned char *hmac; 301238104Sdes size_t hmac_size; 302238104Sdes#endif /* HAVE_SSL */ 303238104Sdes 304238104Sdes k = ldns_key_new(); 305238104Sdes 306238104Sdes d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); 307238104Sdes if (!k || !d) { 308238104Sdes ldns_key_free(k); 309238104Sdes LDNS_FREE(d); 310238104Sdes return LDNS_STATUS_MEM_ERR; 311238104Sdes } 312238104Sdes 313238104Sdes alg = 0; 314238104Sdes 315238104Sdes /* the file is highly structured. Do this in sequence */ 316238104Sdes /* RSA: 317238104Sdes * Private-key-format: v1.x. 318238104Sdes * Algorithm: 1 (RSA) 319238104Sdes 320238104Sdes */ 321238104Sdes /* get the key format version number */ 322238104Sdes if (ldns_fget_keyword_data_l(fp, "Private-key-format", ": ", d, "\n", 323238104Sdes LDNS_MAX_LINELEN, line_nr) == -1) { 324238104Sdes /* no version information */ 325238104Sdes ldns_key_free(k); 326238104Sdes LDNS_FREE(d); 327238104Sdes return LDNS_STATUS_SYNTAX_ERR; 328238104Sdes } 329238104Sdes if (strncmp(d, "v1.", 3) != 0) { 330238104Sdes ldns_key_free(k); 331238104Sdes LDNS_FREE(d); 332238104Sdes return LDNS_STATUS_SYNTAX_VERSION_ERR; 333238104Sdes } 334238104Sdes 335238104Sdes /* get the algorithm type, our file function strip ( ) so there are 336238104Sdes * not in the return string! */ 337238104Sdes if (ldns_fget_keyword_data_l(fp, "Algorithm", ": ", d, "\n", 338238104Sdes LDNS_MAX_LINELEN, line_nr) == -1) { 339238104Sdes /* no alg information */ 340238104Sdes ldns_key_free(k); 341238104Sdes LDNS_FREE(d); 342238104Sdes return LDNS_STATUS_SYNTAX_ALG_ERR; 343238104Sdes } 344238104Sdes 345238104Sdes if (strncmp(d, "1 RSA", 2) == 0) { 346238104Sdes alg = LDNS_SIGN_RSAMD5; 347238104Sdes } 348238104Sdes if (strncmp(d, "2 DH", 2) == 0) { 349238104Sdes alg = (ldns_signing_algorithm)LDNS_DH; 350238104Sdes } 351238104Sdes if (strncmp(d, "3 DSA", 2) == 0) { 352238104Sdes alg = LDNS_SIGN_DSA; 353238104Sdes } 354238104Sdes if (strncmp(d, "4 ECC", 2) == 0) { 355238104Sdes alg = (ldns_signing_algorithm)LDNS_ECC; 356238104Sdes } 357238104Sdes if (strncmp(d, "5 RSASHA1", 2) == 0) { 358238104Sdes alg = LDNS_SIGN_RSASHA1; 359238104Sdes } 360238104Sdes if (strncmp(d, "6 DSA", 2) == 0) { 361238104Sdes alg = LDNS_SIGN_DSA_NSEC3; 362238104Sdes } 363238104Sdes if (strncmp(d, "7 RSASHA1", 2) == 0) { 364238104Sdes alg = LDNS_SIGN_RSASHA1_NSEC3; 365238104Sdes } 366238104Sdes 367238104Sdes if (strncmp(d, "8 RSASHA256", 2) == 0) { 368238104Sdes#ifdef USE_SHA2 369238104Sdes alg = LDNS_SIGN_RSASHA256; 370238104Sdes#else 371266114Sdes# ifdef STDERR_MSGS 372238104Sdes fprintf(stderr, "Warning: SHA256 not compiled into this "); 373238104Sdes fprintf(stderr, "version of ldns\n"); 374266114Sdes# endif 375238104Sdes#endif 376238104Sdes } 377238104Sdes if (strncmp(d, "10 RSASHA512", 3) == 0) { 378238104Sdes#ifdef USE_SHA2 379238104Sdes alg = LDNS_SIGN_RSASHA512; 380238104Sdes#else 381266114Sdes# ifdef STDERR_MSGS 382238104Sdes fprintf(stderr, "Warning: SHA512 not compiled into this "); 383238104Sdes fprintf(stderr, "version of ldns\n"); 384266114Sdes# endif 385238104Sdes#endif 386238104Sdes } 387238104Sdes if (strncmp(d, "12 ECC-GOST", 3) == 0) { 388238104Sdes#ifdef USE_GOST 389238104Sdes alg = LDNS_SIGN_ECC_GOST; 390238104Sdes#else 391266114Sdes# ifdef STDERR_MSGS 392238104Sdes fprintf(stderr, "Warning: ECC-GOST not compiled into this "); 393238104Sdes fprintf(stderr, "version of ldns, use --enable-gost\n"); 394266114Sdes# endif 395238104Sdes#endif 396238104Sdes } 397238104Sdes if (strncmp(d, "13 ECDSAP256SHA256", 3) == 0) { 398238104Sdes#ifdef USE_ECDSA 399238104Sdes alg = LDNS_SIGN_ECDSAP256SHA256; 400238104Sdes#else 401266114Sdes# ifdef STDERR_MSGS 402238104Sdes fprintf(stderr, "Warning: ECDSA not compiled into this "); 403238104Sdes fprintf(stderr, "version of ldns, use --enable-ecdsa\n"); 404266114Sdes# endif 405238104Sdes#endif 406238104Sdes } 407238104Sdes if (strncmp(d, "14 ECDSAP384SHA384", 3) == 0) { 408238104Sdes#ifdef USE_ECDSA 409238104Sdes alg = LDNS_SIGN_ECDSAP384SHA384; 410238104Sdes#else 411266114Sdes# ifdef STDERR_MSGS 412238104Sdes fprintf(stderr, "Warning: ECDSA not compiled into this "); 413238104Sdes fprintf(stderr, "version of ldns, use --enable-ecdsa\n"); 414266114Sdes# endif 415238104Sdes#endif 416238104Sdes } 417238104Sdes if (strncmp(d, "157 HMAC-MD5", 4) == 0) { 418238104Sdes alg = LDNS_SIGN_HMACMD5; 419238104Sdes } 420238104Sdes if (strncmp(d, "158 HMAC-SHA1", 4) == 0) { 421238104Sdes alg = LDNS_SIGN_HMACSHA1; 422238104Sdes } 423238104Sdes if (strncmp(d, "159 HMAC-SHA256", 4) == 0) { 424238104Sdes alg = LDNS_SIGN_HMACSHA256; 425238104Sdes } 426238104Sdes 427238104Sdes LDNS_FREE(d); 428238104Sdes 429238104Sdes switch(alg) { 430238104Sdes case LDNS_SIGN_RSAMD5: 431238104Sdes case LDNS_SIGN_RSASHA1: 432238104Sdes case LDNS_SIGN_RSASHA1_NSEC3: 433238104Sdes#ifdef USE_SHA2 434238104Sdes case LDNS_SIGN_RSASHA256: 435238104Sdes case LDNS_SIGN_RSASHA512: 436238104Sdes#endif 437238104Sdes ldns_key_set_algorithm(k, alg); 438238104Sdes#ifdef HAVE_SSL 439238104Sdes rsa = ldns_key_new_frm_fp_rsa_l(fp, line_nr); 440238104Sdes if (!rsa) { 441238104Sdes ldns_key_free(k); 442238104Sdes return LDNS_STATUS_ERR; 443238104Sdes } 444246854Sdes ldns_key_assign_rsa_key(k, rsa); 445238104Sdes#endif /* HAVE_SSL */ 446238104Sdes break; 447238104Sdes case LDNS_SIGN_DSA: 448238104Sdes case LDNS_SIGN_DSA_NSEC3: 449238104Sdes ldns_key_set_algorithm(k, alg); 450238104Sdes#ifdef HAVE_SSL 451238104Sdes dsa = ldns_key_new_frm_fp_dsa_l(fp, line_nr); 452238104Sdes if (!dsa) { 453238104Sdes ldns_key_free(k); 454238104Sdes return LDNS_STATUS_ERR; 455238104Sdes } 456246854Sdes ldns_key_assign_dsa_key(k, dsa); 457238104Sdes#endif /* HAVE_SSL */ 458238104Sdes break; 459238104Sdes case LDNS_SIGN_HMACMD5: 460238104Sdes case LDNS_SIGN_HMACSHA1: 461238104Sdes case LDNS_SIGN_HMACSHA256: 462238104Sdes ldns_key_set_algorithm(k, alg); 463238104Sdes#ifdef HAVE_SSL 464238104Sdes hmac = ldns_key_new_frm_fp_hmac_l(fp, line_nr, &hmac_size); 465238104Sdes if (!hmac) { 466238104Sdes ldns_key_free(k); 467238104Sdes return LDNS_STATUS_ERR; 468238104Sdes } 469238104Sdes ldns_key_set_hmac_size(k, hmac_size); 470238104Sdes ldns_key_set_hmac_key(k, hmac); 471238104Sdes#endif /* HAVE_SSL */ 472238104Sdes break; 473238104Sdes case LDNS_SIGN_ECC_GOST: 474238104Sdes ldns_key_set_algorithm(k, alg); 475238104Sdes#if defined(HAVE_SSL) && defined(USE_GOST) 476238104Sdes if(!ldns_key_EVP_load_gost_id()) { 477238104Sdes ldns_key_free(k); 478238104Sdes return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL; 479238104Sdes } 480238104Sdes ldns_key_set_evp_key(k, 481238104Sdes ldns_key_new_frm_fp_gost_l(fp, line_nr)); 482238104Sdes#ifndef S_SPLINT_S 483238104Sdes if(!k->_key.key) { 484238104Sdes ldns_key_free(k); 485238104Sdes return LDNS_STATUS_ERR; 486238104Sdes } 487238104Sdes#endif /* splint */ 488238104Sdes#endif 489238104Sdes break; 490238104Sdes#ifdef USE_ECDSA 491238104Sdes case LDNS_SIGN_ECDSAP256SHA256: 492238104Sdes case LDNS_SIGN_ECDSAP384SHA384: 493238104Sdes ldns_key_set_algorithm(k, alg); 494238104Sdes ldns_key_set_evp_key(k, 495238104Sdes ldns_key_new_frm_fp_ecdsa_l(fp, (ldns_algorithm)alg, line_nr)); 496238104Sdes#ifndef S_SPLINT_S 497238104Sdes if(!k->_key.key) { 498238104Sdes ldns_key_free(k); 499238104Sdes return LDNS_STATUS_ERR; 500238104Sdes } 501238104Sdes#endif /* splint */ 502238104Sdes break; 503238104Sdes#endif 504238104Sdes default: 505238104Sdes ldns_key_free(k); 506238104Sdes return LDNS_STATUS_SYNTAX_ALG_ERR; 507238104Sdes } 508238104Sdes key_rr = ldns_key2rr(k); 509238104Sdes ldns_key_set_keytag(k, ldns_calc_keytag(key_rr)); 510238104Sdes ldns_rr_free(key_rr); 511238104Sdes 512238104Sdes if (key) { 513238104Sdes *key = k; 514238104Sdes return LDNS_STATUS_OK; 515238104Sdes } 516246854Sdes ldns_key_free(k); 517238104Sdes return LDNS_STATUS_ERR; 518238104Sdes} 519238104Sdes 520238104Sdes#ifdef HAVE_SSL 521238104SdesRSA * 522238104Sdesldns_key_new_frm_fp_rsa(FILE *f) 523238104Sdes{ 524238104Sdes return ldns_key_new_frm_fp_rsa_l(f, NULL); 525238104Sdes} 526238104Sdes 527238104SdesRSA * 528238104Sdesldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr) 529238104Sdes{ 530238104Sdes /* we parse 531238104Sdes * Modulus: 532238104Sdes * PublicExponent: 533238104Sdes * PrivateExponent: 534238104Sdes * Prime1: 535238104Sdes * Prime2: 536238104Sdes * Exponent1: 537238104Sdes * Exponent2: 538238104Sdes * Coefficient: 539238104Sdes * 540238104Sdes * man 3 RSA: 541238104Sdes * 542238104Sdes * struct 543238104Sdes * { 544238104Sdes * BIGNUM *n; // public modulus 545238104Sdes * BIGNUM *e; // public exponent 546238104Sdes * BIGNUM *d; // private exponent 547238104Sdes * BIGNUM *p; // secret prime factor 548238104Sdes * BIGNUM *q; // secret prime factor 549238104Sdes * BIGNUM *dmp1; // d mod (p-1) 550238104Sdes * BIGNUM *dmq1; // d mod (q-1) 551238104Sdes * BIGNUM *iqmp; // q^-1 mod p 552238104Sdes * // ... 553238104Sdes * 554238104Sdes */ 555238104Sdes char *d; 556238104Sdes RSA *rsa; 557238104Sdes uint8_t *buf; 558238104Sdes int i; 559238104Sdes 560238104Sdes d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); 561238104Sdes buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN); 562238104Sdes rsa = RSA_new(); 563238104Sdes if (!d || !rsa || !buf) { 564238104Sdes goto error; 565238104Sdes } 566238104Sdes 567238104Sdes /* I could use functions again, but that seems an overkill, 568238104Sdes * allthough this also looks tedious 569238104Sdes */ 570238104Sdes 571238104Sdes /* Modules, rsa->n */ 572238104Sdes if (ldns_fget_keyword_data_l(f, "Modulus", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 573238104Sdes goto error; 574238104Sdes } 575238104Sdes i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 576238104Sdes#ifndef S_SPLINT_S 577238104Sdes rsa->n = BN_bin2bn((const char unsigned*)buf, i, NULL); 578238104Sdes if (!rsa->n) { 579238104Sdes goto error; 580238104Sdes } 581238104Sdes 582238104Sdes /* PublicExponent, rsa->e */ 583238104Sdes if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 584238104Sdes goto error; 585238104Sdes } 586238104Sdes i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 587238104Sdes rsa->e = BN_bin2bn((const char unsigned*)buf, i, NULL); 588238104Sdes if (!rsa->e) { 589238104Sdes goto error; 590238104Sdes } 591238104Sdes 592238104Sdes /* PrivateExponent, rsa->d */ 593238104Sdes if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 594238104Sdes goto error; 595238104Sdes } 596238104Sdes i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 597238104Sdes rsa->d = BN_bin2bn((const char unsigned*)buf, i, NULL); 598238104Sdes if (!rsa->d) { 599238104Sdes goto error; 600238104Sdes } 601238104Sdes 602238104Sdes /* Prime1, rsa->p */ 603238104Sdes if (ldns_fget_keyword_data_l(f, "Prime1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 604238104Sdes goto error; 605238104Sdes } 606238104Sdes i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 607238104Sdes rsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL); 608238104Sdes if (!rsa->p) { 609238104Sdes goto error; 610238104Sdes } 611238104Sdes 612238104Sdes /* Prime2, rsa->q */ 613238104Sdes if (ldns_fget_keyword_data_l(f, "Prime2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 614238104Sdes goto error; 615238104Sdes } 616238104Sdes i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 617238104Sdes rsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL); 618238104Sdes if (!rsa->q) { 619238104Sdes goto error; 620238104Sdes } 621238104Sdes 622238104Sdes /* Exponent1, rsa->dmp1 */ 623238104Sdes if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 624238104Sdes goto error; 625238104Sdes } 626238104Sdes i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 627238104Sdes rsa->dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL); 628238104Sdes if (!rsa->dmp1) { 629238104Sdes goto error; 630238104Sdes } 631238104Sdes 632238104Sdes /* Exponent2, rsa->dmq1 */ 633238104Sdes if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 634238104Sdes goto error; 635238104Sdes } 636238104Sdes i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 637238104Sdes rsa->dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL); 638238104Sdes if (!rsa->dmq1) { 639238104Sdes goto error; 640238104Sdes } 641238104Sdes 642238104Sdes /* Coefficient, rsa->iqmp */ 643238104Sdes if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 644238104Sdes goto error; 645238104Sdes } 646238104Sdes i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 647238104Sdes rsa->iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL); 648238104Sdes if (!rsa->iqmp) { 649238104Sdes goto error; 650238104Sdes } 651238104Sdes#endif /* splint */ 652238104Sdes 653238104Sdes LDNS_FREE(buf); 654238104Sdes LDNS_FREE(d); 655238104Sdes return rsa; 656238104Sdes 657238104Sdeserror: 658238104Sdes RSA_free(rsa); 659238104Sdes LDNS_FREE(d); 660238104Sdes LDNS_FREE(buf); 661238104Sdes return NULL; 662238104Sdes} 663238104Sdes 664238104SdesDSA * 665238104Sdesldns_key_new_frm_fp_dsa(FILE *f) 666238104Sdes{ 667238104Sdes return ldns_key_new_frm_fp_dsa_l(f, NULL); 668238104Sdes} 669238104Sdes 670238104SdesDSA * 671238104Sdesldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr)) 672238104Sdes{ 673238104Sdes int i; 674238104Sdes char *d; 675238104Sdes DSA *dsa; 676238104Sdes uint8_t *buf; 677238104Sdes 678238104Sdes d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); 679238104Sdes buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN); 680238104Sdes dsa = DSA_new(); 681238104Sdes if (!d || !dsa || !buf) { 682238104Sdes goto error; 683238104Sdes } 684238104Sdes 685238104Sdes /* the line parser removes the () from the input... */ 686238104Sdes 687238104Sdes /* Prime, dsa->p */ 688238104Sdes if (ldns_fget_keyword_data_l(f, "Primep", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 689238104Sdes goto error; 690238104Sdes } 691238104Sdes i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 692238104Sdes#ifndef S_SPLINT_S 693238104Sdes dsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL); 694238104Sdes if (!dsa->p) { 695238104Sdes goto error; 696238104Sdes } 697238104Sdes 698238104Sdes /* Subprime, dsa->q */ 699238104Sdes if (ldns_fget_keyword_data_l(f, "Subprimeq", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 700238104Sdes goto error; 701238104Sdes } 702238104Sdes i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 703238104Sdes dsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL); 704238104Sdes if (!dsa->q) { 705238104Sdes goto error; 706238104Sdes } 707238104Sdes 708238104Sdes /* Base, dsa->g */ 709238104Sdes if (ldns_fget_keyword_data_l(f, "Baseg", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 710238104Sdes goto error; 711238104Sdes } 712238104Sdes i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 713238104Sdes dsa->g = BN_bin2bn((const char unsigned*)buf, i, NULL); 714238104Sdes if (!dsa->g) { 715238104Sdes goto error; 716238104Sdes } 717238104Sdes 718238104Sdes /* Private key, dsa->priv_key */ 719238104Sdes if (ldns_fget_keyword_data_l(f, "Private_valuex", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 720238104Sdes goto error; 721238104Sdes } 722238104Sdes i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 723238104Sdes dsa->priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL); 724238104Sdes if (!dsa->priv_key) { 725238104Sdes goto error; 726238104Sdes } 727238104Sdes 728238104Sdes /* Public key, dsa->priv_key */ 729238104Sdes if (ldns_fget_keyword_data_l(f, "Public_valuey", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 730238104Sdes goto error; 731238104Sdes } 732238104Sdes i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 733238104Sdes dsa->pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL); 734238104Sdes if (!dsa->pub_key) { 735238104Sdes goto error; 736238104Sdes } 737238104Sdes#endif /* splint */ 738238104Sdes 739238104Sdes LDNS_FREE(buf); 740238104Sdes LDNS_FREE(d); 741238104Sdes 742238104Sdes return dsa; 743238104Sdes 744238104Sdeserror: 745238104Sdes LDNS_FREE(d); 746238104Sdes LDNS_FREE(buf); 747238104Sdes DSA_free(dsa); 748238104Sdes return NULL; 749238104Sdes} 750238104Sdes 751238104Sdesunsigned char * 752238104Sdesldns_key_new_frm_fp_hmac(FILE *f, size_t *hmac_size) 753238104Sdes{ 754238104Sdes return ldns_key_new_frm_fp_hmac_l(f, NULL, hmac_size); 755238104Sdes} 756238104Sdes 757238104Sdesunsigned char * 758238104Sdesldns_key_new_frm_fp_hmac_l( FILE *f 759238104Sdes , ATTR_UNUSED(int *line_nr) 760238104Sdes , size_t *hmac_size 761238104Sdes ) 762238104Sdes{ 763246854Sdes size_t i, bufsz; 764246854Sdes char d[LDNS_MAX_LINELEN]; 765246854Sdes unsigned char *buf = NULL; 766238104Sdes 767238104Sdes if (ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 768238104Sdes goto error; 769238104Sdes } 770246854Sdes bufsz = ldns_b64_ntop_calculate_size(strlen(d)); 771246854Sdes buf = LDNS_XMALLOC(unsigned char, bufsz); 772246854Sdes i = (size_t) ldns_b64_pton((const char*)d, buf, bufsz); 773238104Sdes 774238104Sdes *hmac_size = i; 775238104Sdes return buf; 776238104Sdes 777238104Sdes error: 778238104Sdes LDNS_FREE(buf); 779238104Sdes *hmac_size = 0; 780238104Sdes return NULL; 781238104Sdes} 782238104Sdes#endif /* HAVE_SSL */ 783238104Sdes 784238104Sdes#ifdef USE_GOST 785238104Sdesstatic EVP_PKEY* 786238104Sdesldns_gen_gost_key(void) 787238104Sdes{ 788238104Sdes EVP_PKEY_CTX* ctx; 789238104Sdes EVP_PKEY* p = NULL; 790238104Sdes int gost_id = ldns_key_EVP_load_gost_id(); 791238104Sdes if(!gost_id) 792238104Sdes return NULL; 793238104Sdes ctx = EVP_PKEY_CTX_new_id(gost_id, NULL); 794238104Sdes if(!ctx) { 795238104Sdes /* the id should be available now */ 796238104Sdes return NULL; 797238104Sdes } 798238104Sdes if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) { 799238104Sdes /* cannot set paramset */ 800238104Sdes EVP_PKEY_CTX_free(ctx); 801238104Sdes return NULL; 802238104Sdes } 803238104Sdes 804238104Sdes if(EVP_PKEY_keygen_init(ctx) <= 0) { 805238104Sdes EVP_PKEY_CTX_free(ctx); 806238104Sdes return NULL; 807238104Sdes } 808238104Sdes if(EVP_PKEY_keygen(ctx, &p) <= 0) { 809238104Sdes EVP_PKEY_free(p); 810238104Sdes EVP_PKEY_CTX_free(ctx); 811238104Sdes return NULL; 812238104Sdes } 813238104Sdes EVP_PKEY_CTX_free(ctx); 814238104Sdes return p; 815238104Sdes} 816238104Sdes#endif 817238104Sdes 818238104Sdesldns_key * 819238104Sdesldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) 820238104Sdes{ 821238104Sdes ldns_key *k; 822238104Sdes#ifdef HAVE_SSL 823238104Sdes DSA *d; 824238104Sdes RSA *r; 825238104Sdes# ifdef USE_ECDSA 826238104Sdes EC_KEY *ec = NULL; 827238104Sdes# endif 828238104Sdes#else 829238104Sdes int i; 830238104Sdes uint16_t offset = 0; 831238104Sdes#endif 832238104Sdes unsigned char *hmac; 833238104Sdes 834238104Sdes k = ldns_key_new(); 835238104Sdes if (!k) { 836238104Sdes return NULL; 837238104Sdes } 838238104Sdes switch(alg) { 839238104Sdes case LDNS_SIGN_RSAMD5: 840238104Sdes case LDNS_SIGN_RSASHA1: 841238104Sdes case LDNS_SIGN_RSASHA1_NSEC3: 842238104Sdes case LDNS_SIGN_RSASHA256: 843238104Sdes case LDNS_SIGN_RSASHA512: 844238104Sdes#ifdef HAVE_SSL 845238104Sdes r = RSA_generate_key((int)size, RSA_F4, NULL, NULL); 846238104Sdes if(!r) { 847238104Sdes ldns_key_free(k); 848238104Sdes return NULL; 849238104Sdes } 850238104Sdes if (RSA_check_key(r) != 1) { 851238104Sdes ldns_key_free(k); 852238104Sdes return NULL; 853238104Sdes } 854238104Sdes ldns_key_set_rsa_key(k, r); 855246854Sdes RSA_free(r); 856238104Sdes#endif /* HAVE_SSL */ 857238104Sdes break; 858238104Sdes case LDNS_SIGN_DSA: 859238104Sdes case LDNS_SIGN_DSA_NSEC3: 860238104Sdes#ifdef HAVE_SSL 861238104Sdes d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL); 862238104Sdes if (!d) { 863238104Sdes ldns_key_free(k); 864238104Sdes return NULL; 865238104Sdes } 866238104Sdes if (DSA_generate_key(d) != 1) { 867238104Sdes ldns_key_free(k); 868238104Sdes return NULL; 869238104Sdes } 870238104Sdes ldns_key_set_dsa_key(k, d); 871246854Sdes DSA_free(d); 872238104Sdes#endif /* HAVE_SSL */ 873238104Sdes break; 874238104Sdes case LDNS_SIGN_HMACMD5: 875238104Sdes case LDNS_SIGN_HMACSHA1: 876238104Sdes case LDNS_SIGN_HMACSHA256: 877238104Sdes#ifdef HAVE_SSL 878238104Sdes#ifndef S_SPLINT_S 879238104Sdes k->_key.key = NULL; 880238104Sdes#endif /* splint */ 881238104Sdes#endif /* HAVE_SSL */ 882238104Sdes size = size / 8; 883238104Sdes ldns_key_set_hmac_size(k, size); 884238104Sdes 885238104Sdes hmac = LDNS_XMALLOC(unsigned char, size); 886238104Sdes if(!hmac) { 887238104Sdes ldns_key_free(k); 888238104Sdes return NULL; 889238104Sdes } 890238104Sdes#ifdef HAVE_SSL 891238104Sdes if (RAND_bytes(hmac, (int) size) != 1) { 892238104Sdes LDNS_FREE(hmac); 893238104Sdes ldns_key_free(k); 894238104Sdes return NULL; 895238104Sdes } 896238104Sdes#else 897238104Sdes while (offset + sizeof(i) < size) { 898238104Sdes i = random(); 899238104Sdes memcpy(&hmac[offset], &i, sizeof(i)); 900238104Sdes offset += sizeof(i); 901238104Sdes } 902238104Sdes if (offset < size) { 903238104Sdes i = random(); 904238104Sdes memcpy(&hmac[offset], &i, size - offset); 905238104Sdes } 906238104Sdes#endif /* HAVE_SSL */ 907238104Sdes ldns_key_set_hmac_key(k, hmac); 908238104Sdes 909238104Sdes ldns_key_set_flags(k, 0); 910238104Sdes break; 911238104Sdes case LDNS_SIGN_ECC_GOST: 912238104Sdes#if defined(HAVE_SSL) && defined(USE_GOST) 913238104Sdes ldns_key_set_evp_key(k, ldns_gen_gost_key()); 914238104Sdes#ifndef S_SPLINT_S 915238104Sdes if(!k->_key.key) { 916238104Sdes ldns_key_free(k); 917238104Sdes return NULL; 918238104Sdes } 919238104Sdes#endif /* splint */ 920238104Sdes#else 921238104Sdes ldns_key_free(k); 922238104Sdes return NULL; 923238104Sdes#endif /* HAVE_SSL and USE_GOST */ 924238104Sdes break; 925238104Sdes case LDNS_SIGN_ECDSAP256SHA256: 926238104Sdes case LDNS_SIGN_ECDSAP384SHA384: 927238104Sdes#ifdef USE_ECDSA 928238104Sdes if(alg == LDNS_SIGN_ECDSAP256SHA256) 929238104Sdes ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 930238104Sdes else if(alg == LDNS_SIGN_ECDSAP384SHA384) 931238104Sdes ec = EC_KEY_new_by_curve_name(NID_secp384r1); 932238104Sdes if(!ec) { 933238104Sdes ldns_key_free(k); 934238104Sdes return NULL; 935238104Sdes } 936238104Sdes if(!EC_KEY_generate_key(ec)) { 937238104Sdes ldns_key_free(k); 938238104Sdes EC_KEY_free(ec); 939238104Sdes return NULL; 940238104Sdes } 941238104Sdes#ifndef S_SPLINT_S 942238104Sdes k->_key.key = EVP_PKEY_new(); 943238104Sdes if(!k->_key.key) { 944238104Sdes ldns_key_free(k); 945238104Sdes EC_KEY_free(ec); 946238104Sdes return NULL; 947238104Sdes } 948238104Sdes if (!EVP_PKEY_assign_EC_KEY(k->_key.key, ec)) { 949238104Sdes ldns_key_free(k); 950238104Sdes EC_KEY_free(ec); 951238104Sdes return NULL; 952238104Sdes } 953238104Sdes#endif /* splint */ 954238104Sdes#else 955238104Sdes ldns_key_free(k); 956238104Sdes return NULL; 957238104Sdes#endif /* ECDSA */ 958238104Sdes break; 959238104Sdes } 960238104Sdes ldns_key_set_algorithm(k, alg); 961238104Sdes return k; 962238104Sdes} 963238104Sdes 964238104Sdesvoid 965238104Sdesldns_key_print(FILE *output, const ldns_key *k) 966238104Sdes{ 967238104Sdes char *str = ldns_key2str(k); 968238104Sdes if (str) { 969238104Sdes fprintf(output, "%s", str); 970238104Sdes } else { 971238104Sdes fprintf(output, "Unable to convert private key to string\n"); 972238104Sdes } 973238104Sdes LDNS_FREE(str); 974238104Sdes} 975238104Sdes 976238104Sdes 977238104Sdesvoid 978238104Sdesldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l) 979238104Sdes{ 980238104Sdes k->_alg = l; 981238104Sdes} 982238104Sdes 983238104Sdesvoid 984238104Sdesldns_key_set_flags(ldns_key *k, uint16_t f) 985238104Sdes{ 986238104Sdes k->_extra.dnssec.flags = f; 987238104Sdes} 988238104Sdes 989238104Sdes#ifdef HAVE_SSL 990238104Sdes#ifndef S_SPLINT_S 991238104Sdesvoid 992238104Sdesldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e) 993238104Sdes{ 994238104Sdes k->_key.key = e; 995238104Sdes} 996238104Sdes 997238104Sdesvoid 998238104Sdesldns_key_set_rsa_key(ldns_key *k, RSA *r) 999238104Sdes{ 1000238104Sdes EVP_PKEY *key = EVP_PKEY_new(); 1001238104Sdes EVP_PKEY_set1_RSA(key, r); 1002238104Sdes k->_key.key = key; 1003238104Sdes} 1004238104Sdes 1005238104Sdesvoid 1006238104Sdesldns_key_set_dsa_key(ldns_key *k, DSA *d) 1007238104Sdes{ 1008238104Sdes EVP_PKEY *key = EVP_PKEY_new(); 1009238104Sdes EVP_PKEY_set1_DSA(key, d); 1010238104Sdes k->_key.key = key; 1011238104Sdes} 1012246854Sdes 1013246854Sdesvoid 1014246854Sdesldns_key_assign_rsa_key(ldns_key *k, RSA *r) 1015246854Sdes{ 1016246854Sdes EVP_PKEY *key = EVP_PKEY_new(); 1017246854Sdes EVP_PKEY_assign_RSA(key, r); 1018246854Sdes k->_key.key = key; 1019246854Sdes} 1020246854Sdes 1021246854Sdesvoid 1022246854Sdesldns_key_assign_dsa_key(ldns_key *k, DSA *d) 1023246854Sdes{ 1024246854Sdes EVP_PKEY *key = EVP_PKEY_new(); 1025246854Sdes EVP_PKEY_assign_DSA(key, d); 1026246854Sdes k->_key.key = key; 1027246854Sdes} 1028238104Sdes#endif /* splint */ 1029238104Sdes#endif /* HAVE_SSL */ 1030238104Sdes 1031238104Sdesvoid 1032238104Sdesldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac) 1033238104Sdes{ 1034238104Sdes k->_key.hmac.key = hmac; 1035238104Sdes} 1036238104Sdes 1037238104Sdesvoid 1038238104Sdesldns_key_set_hmac_size(ldns_key *k, size_t hmac_size) 1039238104Sdes{ 1040238104Sdes k->_key.hmac.size = hmac_size; 1041238104Sdes} 1042238104Sdes 1043238104Sdesvoid 1044238104Sdesldns_key_set_external_key(ldns_key *k, void *external_key) 1045238104Sdes{ 1046238104Sdes k->_key.external_key = external_key; 1047238104Sdes} 1048238104Sdes 1049238104Sdesvoid 1050238104Sdesldns_key_set_origttl(ldns_key *k, uint32_t t) 1051238104Sdes{ 1052238104Sdes k->_extra.dnssec.orig_ttl = t; 1053238104Sdes} 1054238104Sdes 1055238104Sdesvoid 1056238104Sdesldns_key_set_inception(ldns_key *k, uint32_t i) 1057238104Sdes{ 1058238104Sdes k->_extra.dnssec.inception = i; 1059238104Sdes} 1060238104Sdes 1061238104Sdesvoid 1062238104Sdesldns_key_set_expiration(ldns_key *k, uint32_t e) 1063238104Sdes{ 1064238104Sdes k->_extra.dnssec.expiration = e; 1065238104Sdes} 1066238104Sdes 1067238104Sdesvoid 1068238104Sdesldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r) 1069238104Sdes{ 1070238104Sdes k->_pubkey_owner = r; 1071238104Sdes} 1072238104Sdes 1073238104Sdesvoid 1074238104Sdesldns_key_set_keytag(ldns_key *k, uint16_t tag) 1075238104Sdes{ 1076238104Sdes k->_extra.dnssec.keytag = tag; 1077238104Sdes} 1078238104Sdes 1079238104Sdes/* read */ 1080238104Sdessize_t 1081238104Sdesldns_key_list_key_count(const ldns_key_list *key_list) 1082238104Sdes{ 1083238104Sdes return key_list->_key_count; 1084238104Sdes} 1085238104Sdes 1086238104Sdesldns_key * 1087238104Sdesldns_key_list_key(const ldns_key_list *key, size_t nr) 1088238104Sdes{ 1089238104Sdes if (nr < ldns_key_list_key_count(key)) { 1090238104Sdes return key->_keys[nr]; 1091238104Sdes } else { 1092238104Sdes return NULL; 1093238104Sdes } 1094238104Sdes} 1095238104Sdes 1096238104Sdesldns_signing_algorithm 1097238104Sdesldns_key_algorithm(const ldns_key *k) 1098238104Sdes{ 1099238104Sdes return k->_alg; 1100238104Sdes} 1101238104Sdes 1102238104Sdesvoid 1103238104Sdesldns_key_set_use(ldns_key *k, bool v) 1104238104Sdes{ 1105238104Sdes if (k) { 1106238104Sdes k->_use = v; 1107238104Sdes } 1108238104Sdes} 1109238104Sdes 1110238104Sdesbool 1111238104Sdesldns_key_use(const ldns_key *k) 1112238104Sdes{ 1113238104Sdes if (k) { 1114238104Sdes return k->_use; 1115238104Sdes } 1116238104Sdes return false; 1117238104Sdes} 1118238104Sdes 1119238104Sdes#ifdef HAVE_SSL 1120238104Sdes#ifndef S_SPLINT_S 1121238104SdesEVP_PKEY * 1122238104Sdesldns_key_evp_key(const ldns_key *k) 1123238104Sdes{ 1124238104Sdes return k->_key.key; 1125238104Sdes} 1126238104Sdes 1127238104SdesRSA * 1128238104Sdesldns_key_rsa_key(const ldns_key *k) 1129238104Sdes{ 1130238104Sdes if (k->_key.key) { 1131238104Sdes return EVP_PKEY_get1_RSA(k->_key.key); 1132238104Sdes } else { 1133238104Sdes return NULL; 1134238104Sdes } 1135238104Sdes} 1136238104Sdes 1137238104SdesDSA * 1138238104Sdesldns_key_dsa_key(const ldns_key *k) 1139238104Sdes{ 1140238104Sdes if (k->_key.key) { 1141238104Sdes return EVP_PKEY_get1_DSA(k->_key.key); 1142238104Sdes } else { 1143238104Sdes return NULL; 1144238104Sdes } 1145238104Sdes} 1146238104Sdes#endif /* splint */ 1147238104Sdes#endif /* HAVE_SSL */ 1148238104Sdes 1149238104Sdesunsigned char * 1150238104Sdesldns_key_hmac_key(const ldns_key *k) 1151238104Sdes{ 1152238104Sdes if (k->_key.hmac.key) { 1153238104Sdes return k->_key.hmac.key; 1154238104Sdes } else { 1155238104Sdes return NULL; 1156238104Sdes } 1157238104Sdes} 1158238104Sdes 1159238104Sdessize_t 1160238104Sdesldns_key_hmac_size(const ldns_key *k) 1161238104Sdes{ 1162238104Sdes if (k->_key.hmac.size) { 1163238104Sdes return k->_key.hmac.size; 1164238104Sdes } else { 1165238104Sdes return 0; 1166238104Sdes } 1167238104Sdes} 1168238104Sdes 1169238104Sdesvoid * 1170238104Sdesldns_key_external_key(const ldns_key *k) 1171238104Sdes{ 1172238104Sdes return k->_key.external_key; 1173238104Sdes} 1174238104Sdes 1175238104Sdesuint32_t 1176238104Sdesldns_key_origttl(const ldns_key *k) 1177238104Sdes{ 1178238104Sdes return k->_extra.dnssec.orig_ttl; 1179238104Sdes} 1180238104Sdes 1181238104Sdesuint16_t 1182238104Sdesldns_key_flags(const ldns_key *k) 1183238104Sdes{ 1184238104Sdes return k->_extra.dnssec.flags; 1185238104Sdes} 1186238104Sdes 1187238104Sdesuint32_t 1188238104Sdesldns_key_inception(const ldns_key *k) 1189238104Sdes{ 1190238104Sdes return k->_extra.dnssec.inception; 1191238104Sdes} 1192238104Sdes 1193238104Sdesuint32_t 1194238104Sdesldns_key_expiration(const ldns_key *k) 1195238104Sdes{ 1196238104Sdes return k->_extra.dnssec.expiration; 1197238104Sdes} 1198238104Sdes 1199238104Sdesuint16_t 1200238104Sdesldns_key_keytag(const ldns_key *k) 1201238104Sdes{ 1202238104Sdes return k->_extra.dnssec.keytag; 1203238104Sdes} 1204238104Sdes 1205238104Sdesldns_rdf * 1206238104Sdesldns_key_pubkey_owner(const ldns_key *k) 1207238104Sdes{ 1208238104Sdes return k->_pubkey_owner; 1209238104Sdes} 1210238104Sdes 1211238104Sdes/* write */ 1212238104Sdesvoid 1213238104Sdesldns_key_list_set_use(ldns_key_list *keys, bool v) 1214238104Sdes{ 1215238104Sdes size_t i; 1216238104Sdes 1217238104Sdes for (i = 0; i < ldns_key_list_key_count(keys); i++) { 1218238104Sdes ldns_key_set_use(ldns_key_list_key(keys, i), v); 1219238104Sdes } 1220238104Sdes} 1221238104Sdes 1222238104Sdesvoid 1223238104Sdesldns_key_list_set_key_count(ldns_key_list *key, size_t count) 1224238104Sdes{ 1225238104Sdes key->_key_count = count; 1226238104Sdes} 1227238104Sdes 1228238104Sdesbool 1229238104Sdesldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key) 1230238104Sdes{ 1231238104Sdes size_t key_count; 1232238104Sdes ldns_key **keys; 1233238104Sdes 1234238104Sdes key_count = ldns_key_list_key_count(key_list); 1235238104Sdes 1236238104Sdes /* grow the array */ 1237238104Sdes keys = LDNS_XREALLOC( 1238238104Sdes key_list->_keys, ldns_key *, key_count + 1); 1239238104Sdes if (!keys) { 1240238104Sdes return false; 1241238104Sdes } 1242238104Sdes 1243238104Sdes /* add the new member */ 1244238104Sdes key_list->_keys = keys; 1245238104Sdes key_list->_keys[key_count] = key; 1246238104Sdes 1247238104Sdes ldns_key_list_set_key_count(key_list, key_count + 1); 1248238104Sdes return true; 1249238104Sdes} 1250238104Sdes 1251238104Sdesldns_key * 1252238104Sdesldns_key_list_pop_key(ldns_key_list *key_list) 1253238104Sdes{ 1254238104Sdes size_t key_count; 1255238104Sdes ldns_key** a; 1256238104Sdes ldns_key *pop; 1257238104Sdes 1258238104Sdes if (!key_list) { 1259238104Sdes return NULL; 1260238104Sdes } 1261238104Sdes 1262238104Sdes key_count = ldns_key_list_key_count(key_list); 1263238104Sdes if (key_count == 0) { 1264238104Sdes return NULL; 1265238104Sdes } 1266238104Sdes 1267238104Sdes pop = ldns_key_list_key(key_list, key_count); 1268238104Sdes 1269238104Sdes /* shrink the array */ 1270238104Sdes a = LDNS_XREALLOC(key_list->_keys, ldns_key *, key_count - 1); 1271238104Sdes if(a) { 1272238104Sdes key_list->_keys = a; 1273238104Sdes } 1274238104Sdes 1275238104Sdes ldns_key_list_set_key_count(key_list, key_count - 1); 1276238104Sdes 1277238104Sdes return pop; 1278238104Sdes} 1279238104Sdes 1280238104Sdes#ifdef HAVE_SSL 1281238104Sdes#ifndef S_SPLINT_S 1282238104Sdes/* data pointer must be large enough (LDNS_MAX_KEYLEN) */ 1283238104Sdesstatic bool 1284238104Sdesldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size) 1285238104Sdes{ 1286238104Sdes int i,j; 1287238104Sdes 1288238104Sdes if (!k) { 1289238104Sdes return false; 1290238104Sdes } 1291238104Sdes 1292238104Sdes if (BN_num_bytes(k->e) <= 256) { 1293238104Sdes /* normally only this path is executed (small factors are 1294238104Sdes * more common 1295238104Sdes */ 1296238104Sdes data[0] = (unsigned char) BN_num_bytes(k->e); 1297238104Sdes i = BN_bn2bin(k->e, data + 1); 1298238104Sdes j = BN_bn2bin(k->n, data + i + 1); 1299238104Sdes *size = (uint16_t) i + j; 1300238104Sdes } else if (BN_num_bytes(k->e) <= 65536) { 1301238104Sdes data[0] = 0; 1302238104Sdes /* BN_bn2bin does bigendian, _uint16 also */ 1303238104Sdes ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(k->e)); 1304238104Sdes 1305238104Sdes BN_bn2bin(k->e, data + 3); 1306238104Sdes BN_bn2bin(k->n, data + 4 + BN_num_bytes(k->e)); 1307238104Sdes *size = (uint16_t) BN_num_bytes(k->n) + 6; 1308238104Sdes } else { 1309238104Sdes return false; 1310238104Sdes } 1311238104Sdes return true; 1312238104Sdes} 1313238104Sdes 1314238104Sdes/* data pointer must be large enough (LDNS_MAX_KEYLEN) */ 1315238104Sdesstatic bool 1316238104Sdesldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size) 1317238104Sdes{ 1318238104Sdes uint8_t T; 1319238104Sdes 1320238104Sdes if (!k) { 1321238104Sdes return false; 1322238104Sdes } 1323238104Sdes 1324238104Sdes /* See RFC2536 */ 1325246854Sdes *size = (uint16_t)BN_num_bytes(k->p); 1326238104Sdes T = (*size - 64) / 8; 1327238104Sdes memcpy(data, &T, 1); 1328238104Sdes 1329238104Sdes if (T > 8) { 1330266114Sdes#ifdef STDERR_MSGS 1331238104Sdes fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)"); 1332238104Sdes fprintf(stderr, " not implemented\n"); 1333266114Sdes#endif 1334238104Sdes return false; 1335238104Sdes } 1336238104Sdes 1337238104Sdes /* size = 64 + (T * 8); */ 1338238104Sdes data[0] = (unsigned char)T; 1339238104Sdes BN_bn2bin(k->q, data + 1 ); /* 20 octects */ 1340238104Sdes BN_bn2bin(k->p, data + 21 ); /* offset octects */ 1341238104Sdes BN_bn2bin(k->g, data + 21 + *size); /* offset octets */ 1342238104Sdes BN_bn2bin(k->pub_key, data + 21 + *size + *size); /* offset octets */ 1343238104Sdes *size = 21 + (*size * 3); 1344238104Sdes return true; 1345238104Sdes} 1346238104Sdes 1347238104Sdes#ifdef USE_GOST 1348238104Sdesstatic bool 1349238104Sdesldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size) 1350238104Sdes{ 1351238104Sdes int i; 1352238104Sdes unsigned char* pp = NULL; 1353238104Sdes if(i2d_PUBKEY(k, &pp) != 37 + 64) { 1354238104Sdes /* expect 37 byte(ASN header) and 64 byte(X and Y) */ 1355238104Sdes CRYPTO_free(pp); 1356238104Sdes return false; 1357238104Sdes } 1358238104Sdes /* omit ASN header */ 1359238104Sdes for(i=0; i<64; i++) 1360238104Sdes data[i] = pp[i+37]; 1361238104Sdes CRYPTO_free(pp); 1362238104Sdes *size = 64; 1363238104Sdes return true; 1364238104Sdes} 1365238104Sdes#endif /* USE_GOST */ 1366238104Sdes#endif /* splint */ 1367238104Sdes#endif /* HAVE_SSL */ 1368238104Sdes 1369238104Sdesldns_rr * 1370238104Sdesldns_key2rr(const ldns_key *k) 1371238104Sdes{ 1372238104Sdes /* this function will convert a the keydata contained in 1373238104Sdes * rsa/dsa pointers to a DNSKEY rr. It will fill in as 1374238104Sdes * much as it can, but it does not know about key-flags 1375238104Sdes * for instance 1376238104Sdes */ 1377238104Sdes ldns_rr *pubkey; 1378238104Sdes ldns_rdf *keybin; 1379238104Sdes unsigned char *bin = NULL; 1380238104Sdes uint16_t size = 0; 1381238104Sdes#ifdef HAVE_SSL 1382238104Sdes RSA *rsa = NULL; 1383238104Sdes DSA *dsa = NULL; 1384238104Sdes#endif /* HAVE_SSL */ 1385238104Sdes#ifdef USE_ECDSA 1386238104Sdes EC_KEY* ec; 1387238104Sdes#endif 1388238104Sdes int internal_data = 0; 1389238104Sdes 1390238104Sdes if (!k) { 1391238104Sdes return NULL; 1392238104Sdes } 1393246854Sdes pubkey = ldns_rr_new(); 1394238104Sdes 1395238104Sdes switch (ldns_key_algorithm(k)) { 1396238104Sdes case LDNS_SIGN_HMACMD5: 1397238104Sdes case LDNS_SIGN_HMACSHA1: 1398238104Sdes case LDNS_SIGN_HMACSHA256: 1399238104Sdes ldns_rr_set_type(pubkey, LDNS_RR_TYPE_KEY); 1400238104Sdes break; 1401238104Sdes default: 1402238104Sdes ldns_rr_set_type(pubkey, LDNS_RR_TYPE_DNSKEY); 1403238104Sdes break; 1404238104Sdes } 1405238104Sdes /* zero-th rdf - flags */ 1406238104Sdes ldns_rr_push_rdf(pubkey, 1407238104Sdes ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, 1408238104Sdes ldns_key_flags(k))); 1409238104Sdes /* first - proto */ 1410238104Sdes ldns_rr_push_rdf(pubkey, 1411238104Sdes ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, LDNS_DNSSEC_KEYPROTO)); 1412238104Sdes 1413238104Sdes if (ldns_key_pubkey_owner(k)) { 1414238104Sdes ldns_rr_set_owner(pubkey, ldns_rdf_clone(ldns_key_pubkey_owner(k))); 1415238104Sdes } 1416238104Sdes 1417238104Sdes /* third - da algorithm */ 1418238104Sdes switch(ldns_key_algorithm(k)) { 1419238104Sdes case LDNS_SIGN_RSAMD5: 1420238104Sdes case LDNS_SIGN_RSASHA1: 1421238104Sdes case LDNS_SIGN_RSASHA1_NSEC3: 1422238104Sdes case LDNS_SIGN_RSASHA256: 1423238104Sdes case LDNS_SIGN_RSASHA512: 1424238104Sdes ldns_rr_push_rdf(pubkey, 1425238104Sdes ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); 1426238104Sdes#ifdef HAVE_SSL 1427238104Sdes rsa = ldns_key_rsa_key(k); 1428238104Sdes if (rsa) { 1429238104Sdes bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 1430238104Sdes if (!bin) { 1431238104Sdes ldns_rr_free(pubkey); 1432238104Sdes return NULL; 1433238104Sdes } 1434238104Sdes if (!ldns_key_rsa2bin(bin, rsa, &size)) { 1435238104Sdes LDNS_FREE(bin); 1436238104Sdes ldns_rr_free(pubkey); 1437238104Sdes return NULL; 1438238104Sdes } 1439238104Sdes RSA_free(rsa); 1440238104Sdes internal_data = 1; 1441238104Sdes } 1442238104Sdes#endif 1443238104Sdes size++; 1444238104Sdes break; 1445238104Sdes case LDNS_SIGN_DSA: 1446238104Sdes ldns_rr_push_rdf(pubkey, 1447238104Sdes ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA)); 1448238104Sdes#ifdef HAVE_SSL 1449238104Sdes dsa = ldns_key_dsa_key(k); 1450238104Sdes if (dsa) { 1451238104Sdes bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 1452238104Sdes if (!bin) { 1453238104Sdes ldns_rr_free(pubkey); 1454238104Sdes return NULL; 1455238104Sdes } 1456238104Sdes if (!ldns_key_dsa2bin(bin, dsa, &size)) { 1457238104Sdes LDNS_FREE(bin); 1458238104Sdes ldns_rr_free(pubkey); 1459238104Sdes return NULL; 1460238104Sdes } 1461238104Sdes DSA_free(dsa); 1462238104Sdes internal_data = 1; 1463238104Sdes } 1464238104Sdes#endif /* HAVE_SSL */ 1465238104Sdes break; 1466238104Sdes case LDNS_SIGN_DSA_NSEC3: 1467238104Sdes ldns_rr_push_rdf(pubkey, 1468238104Sdes ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3)); 1469238104Sdes#ifdef HAVE_SSL 1470238104Sdes dsa = ldns_key_dsa_key(k); 1471238104Sdes if (dsa) { 1472238104Sdes bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 1473238104Sdes if (!bin) { 1474238104Sdes ldns_rr_free(pubkey); 1475238104Sdes return NULL; 1476238104Sdes } 1477238104Sdes if (!ldns_key_dsa2bin(bin, dsa, &size)) { 1478238104Sdes LDNS_FREE(bin); 1479238104Sdes ldns_rr_free(pubkey); 1480238104Sdes return NULL; 1481238104Sdes } 1482238104Sdes DSA_free(dsa); 1483238104Sdes internal_data = 1; 1484238104Sdes } 1485238104Sdes#endif /* HAVE_SSL */ 1486238104Sdes break; 1487238104Sdes case LDNS_SIGN_ECC_GOST: 1488238104Sdes ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( 1489238104Sdes LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); 1490238104Sdes#if defined(HAVE_SSL) && defined(USE_GOST) 1491238104Sdes bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 1492238104Sdes if (!bin) { 1493238104Sdes ldns_rr_free(pubkey); 1494238104Sdes return NULL; 1495238104Sdes } 1496238104Sdes#ifndef S_SPLINT_S 1497238104Sdes if (!ldns_key_gost2bin(bin, k->_key.key, &size)) { 1498238104Sdes LDNS_FREE(bin); 1499238104Sdes ldns_rr_free(pubkey); 1500238104Sdes return NULL; 1501238104Sdes } 1502238104Sdes#endif /* splint */ 1503238104Sdes internal_data = 1; 1504238104Sdes#else 1505238104Sdes ldns_rr_free(pubkey); 1506238104Sdes return NULL; 1507238104Sdes#endif /* HAVE_SSL and USE_GOST */ 1508238104Sdes break; 1509238104Sdes case LDNS_SIGN_ECDSAP256SHA256: 1510238104Sdes case LDNS_SIGN_ECDSAP384SHA384: 1511238104Sdes#ifdef USE_ECDSA 1512238104Sdes ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( 1513238104Sdes LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); 1514238104Sdes bin = NULL; 1515238104Sdes#ifndef S_SPLINT_S 1516238104Sdes ec = EVP_PKEY_get1_EC_KEY(k->_key.key); 1517238104Sdes#endif 1518238104Sdes EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); 1519238104Sdes size = (uint16_t)i2o_ECPublicKey(ec, NULL); 1520238104Sdes if(!i2o_ECPublicKey(ec, &bin)) { 1521238104Sdes EC_KEY_free(ec); 1522238104Sdes ldns_rr_free(pubkey); 1523238104Sdes return NULL; 1524238104Sdes } 1525238104Sdes if(size > 1) { 1526238104Sdes /* move back one byte to shave off the 0x02 1527238104Sdes * 'uncompressed' indicator that openssl made 1528238104Sdes * Actually its 0x04 (from implementation). 1529238104Sdes */ 1530238104Sdes assert(bin[0] == POINT_CONVERSION_UNCOMPRESSED); 1531238104Sdes size -= 1; 1532238104Sdes memmove(bin, bin+1, size); 1533238104Sdes } 1534238104Sdes /* down the reference count for ec, its still assigned 1535238104Sdes * to the pkey */ 1536238104Sdes EC_KEY_free(ec); 1537238104Sdes internal_data = 1; 1538238104Sdes#else 1539238104Sdes ldns_rr_free(pubkey); 1540238104Sdes return NULL; 1541238104Sdes#endif /* ECDSA */ 1542238104Sdes break; 1543238104Sdes case LDNS_SIGN_HMACMD5: 1544238104Sdes case LDNS_SIGN_HMACSHA1: 1545238104Sdes case LDNS_SIGN_HMACSHA256: 1546238104Sdes bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k)); 1547238104Sdes if (!bin) { 1548238104Sdes ldns_rr_free(pubkey); 1549238104Sdes return NULL; 1550238104Sdes } 1551238104Sdes ldns_rr_push_rdf(pubkey, 1552238104Sdes ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, 1553238104Sdes ldns_key_algorithm(k))); 1554238104Sdes size = ldns_key_hmac_size(k); 1555238104Sdes memcpy(bin, ldns_key_hmac_key(k), size); 1556238104Sdes internal_data = 1; 1557238104Sdes break; 1558238104Sdes } 1559238104Sdes /* fourth the key bin material */ 1560238104Sdes if (internal_data) { 1561238104Sdes keybin = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, size, bin); 1562238104Sdes LDNS_FREE(bin); 1563238104Sdes ldns_rr_push_rdf(pubkey, keybin); 1564238104Sdes } 1565238104Sdes return pubkey; 1566238104Sdes} 1567238104Sdes 1568238104Sdesvoid 1569238104Sdesldns_key_free(ldns_key *key) 1570238104Sdes{ 1571238104Sdes LDNS_FREE(key); 1572238104Sdes} 1573238104Sdes 1574238104Sdesvoid 1575238104Sdesldns_key_deep_free(ldns_key *key) 1576238104Sdes{ 1577238104Sdes unsigned char* hmac; 1578238104Sdes if (ldns_key_pubkey_owner(key)) { 1579238104Sdes ldns_rdf_deep_free(ldns_key_pubkey_owner(key)); 1580238104Sdes } 1581238104Sdes#ifdef HAVE_SSL 1582238104Sdes if (ldns_key_evp_key(key)) { 1583238104Sdes EVP_PKEY_free(ldns_key_evp_key(key)); 1584238104Sdes } 1585238104Sdes#endif /* HAVE_SSL */ 1586238104Sdes if (ldns_key_hmac_key(key)) { 1587238104Sdes hmac = ldns_key_hmac_key(key); 1588238104Sdes LDNS_FREE(hmac); 1589238104Sdes } 1590238104Sdes LDNS_FREE(key); 1591238104Sdes} 1592238104Sdes 1593238104Sdesvoid 1594238104Sdesldns_key_list_free(ldns_key_list *key_list) 1595238104Sdes{ 1596238104Sdes size_t i; 1597238104Sdes for (i = 0; i < ldns_key_list_key_count(key_list); i++) { 1598238104Sdes ldns_key_deep_free(ldns_key_list_key(key_list, i)); 1599238104Sdes } 1600238104Sdes LDNS_FREE(key_list->_keys); 1601238104Sdes LDNS_FREE(key_list); 1602238104Sdes} 1603238104Sdes 1604238104Sdesldns_rr * 1605238104Sdesldns_read_anchor_file(const char *filename) 1606238104Sdes{ 1607238104Sdes FILE *fp; 1608238104Sdes /*char line[LDNS_MAX_PACKETLEN];*/ 1609238104Sdes char *line = LDNS_XMALLOC(char, LDNS_MAX_PACKETLEN); 1610238104Sdes int c; 1611238104Sdes size_t i = 0; 1612238104Sdes ldns_rr *r; 1613238104Sdes ldns_status status; 1614238104Sdes if(!line) { 1615238104Sdes return NULL; 1616238104Sdes } 1617238104Sdes 1618238104Sdes fp = fopen(filename, "r"); 1619238104Sdes if (!fp) { 1620266114Sdes#ifdef STDERR_MSGS 1621238104Sdes fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno)); 1622266114Sdes#endif 1623238104Sdes LDNS_FREE(line); 1624238104Sdes return NULL; 1625238104Sdes } 1626238104Sdes 1627238104Sdes while ((c = fgetc(fp)) && i+1 < LDNS_MAX_PACKETLEN && c != EOF) { 1628238104Sdes line[i] = c; 1629238104Sdes i++; 1630238104Sdes } 1631238104Sdes line[i] = '\0'; 1632238104Sdes 1633238104Sdes fclose(fp); 1634238104Sdes 1635238104Sdes if (i <= 0) { 1636266114Sdes#ifdef STDERR_MSGS 1637238104Sdes fprintf(stderr, "nothing read from %s", filename); 1638266114Sdes#endif 1639238104Sdes LDNS_FREE(line); 1640238104Sdes return NULL; 1641238104Sdes } else { 1642238104Sdes status = ldns_rr_new_frm_str(&r, line, 0, NULL, NULL); 1643238104Sdes if (status == LDNS_STATUS_OK && (ldns_rr_get_type(r) == LDNS_RR_TYPE_DNSKEY || ldns_rr_get_type(r) == LDNS_RR_TYPE_DS)) { 1644238104Sdes LDNS_FREE(line); 1645238104Sdes return r; 1646238104Sdes } else { 1647266114Sdes#ifdef STDERR_MSGS 1648238104Sdes fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status)); 1649266114Sdes#endif 1650238104Sdes LDNS_FREE(line); 1651238104Sdes return NULL; 1652238104Sdes } 1653238104Sdes } 1654238104Sdes} 1655238104Sdes 1656238104Sdeschar * 1657238104Sdesldns_key_get_file_base_name(ldns_key *key) 1658238104Sdes{ 1659238104Sdes ldns_buffer *buffer; 1660238104Sdes char *file_base_name; 1661238104Sdes 1662238104Sdes buffer = ldns_buffer_new(255); 1663238104Sdes ldns_buffer_printf(buffer, "K"); 1664238104Sdes (void)ldns_rdf2buffer_str_dname(buffer, ldns_key_pubkey_owner(key)); 1665238104Sdes ldns_buffer_printf(buffer, 1666238104Sdes "+%03u+%05u", 1667238104Sdes ldns_key_algorithm(key), 1668238104Sdes ldns_key_keytag(key)); 1669246854Sdes file_base_name = ldns_buffer_export(buffer); 1670238104Sdes ldns_buffer_free(buffer); 1671238104Sdes return file_base_name; 1672238104Sdes} 1673238104Sdes 1674238104Sdesint ldns_key_algo_supported(int algo) 1675238104Sdes{ 1676238104Sdes ldns_lookup_table *lt = ldns_signing_algorithms; 1677238104Sdes while(lt->name) { 1678238104Sdes if(lt->id == algo) 1679238104Sdes return 1; 1680238104Sdes lt++; 1681238104Sdes } 1682238104Sdes return 0; 1683238104Sdes} 1684238104Sdes 1685238104Sdesldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name) 1686238104Sdes{ 1687238104Sdes /* list of (signing algorithm id, alias_name) */ 1688238104Sdes ldns_lookup_table aliases[] = { 1689238104Sdes /* from bind dnssec-keygen */ 1690238104Sdes {LDNS_SIGN_HMACMD5, "HMAC-MD5"}, 1691238104Sdes {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"}, 1692238104Sdes {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"}, 1693238104Sdes /* old ldns usage, now RFC names */ 1694238104Sdes {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" }, 1695238104Sdes {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" }, 1696238104Sdes#ifdef USE_GOST 1697238104Sdes {LDNS_SIGN_ECC_GOST, "GOST"}, 1698238104Sdes#endif 1699238104Sdes /* compat with possible output */ 1700238104Sdes {LDNS_DH, "DH"}, 1701238104Sdes {LDNS_ECC, "ECC"}, 1702238104Sdes {LDNS_INDIRECT, "INDIRECT"}, 1703238104Sdes {LDNS_PRIVATEDNS, "PRIVATEDNS"}, 1704238104Sdes {LDNS_PRIVATEOID, "PRIVATEOID"}, 1705238104Sdes {0, NULL}}; 1706238104Sdes ldns_lookup_table* lt = ldns_signing_algorithms; 1707238104Sdes while(lt->name) { 1708238104Sdes if(strcasecmp(lt->name, name) == 0) 1709238104Sdes return lt->id; 1710238104Sdes lt++; 1711238104Sdes } 1712238104Sdes lt = aliases; 1713238104Sdes while(lt->name) { 1714238104Sdes if(strcasecmp(lt->name, name) == 0) 1715238104Sdes return lt->id; 1716238104Sdes lt++; 1717238104Sdes } 1718238104Sdes if(atoi(name) != 0) 1719238104Sdes return atoi(name); 1720238104Sdes return 0; 1721238104Sdes} 1722