1*7b5038d7SDag-Erling Smørgrav /* 2*7b5038d7SDag-Erling Smørgrav * keys.c handle private keys for use in DNSSEC 3*7b5038d7SDag-Erling Smørgrav * 4*7b5038d7SDag-Erling Smørgrav * This module should hide some of the openSSL complexities 5*7b5038d7SDag-Erling Smørgrav * and give a general interface for private keys and hmac 6*7b5038d7SDag-Erling Smørgrav * handling 7*7b5038d7SDag-Erling Smørgrav * 8*7b5038d7SDag-Erling Smørgrav * (c) NLnet Labs, 2004-2006 9*7b5038d7SDag-Erling Smørgrav * 10*7b5038d7SDag-Erling Smørgrav * See the file LICENSE for the license 11*7b5038d7SDag-Erling Smørgrav */ 12*7b5038d7SDag-Erling Smørgrav 13*7b5038d7SDag-Erling Smørgrav #include <ldns/config.h> 14*7b5038d7SDag-Erling Smørgrav 15*7b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h> 16*7b5038d7SDag-Erling Smørgrav 17*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 18*7b5038d7SDag-Erling Smørgrav #include <openssl/ssl.h> 19*7b5038d7SDag-Erling Smørgrav #include <openssl/engine.h> 20*7b5038d7SDag-Erling Smørgrav #include <openssl/rand.h> 21*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 22*7b5038d7SDag-Erling Smørgrav 23*7b5038d7SDag-Erling Smørgrav ldns_lookup_table ldns_signing_algorithms[] = { 24*7b5038d7SDag-Erling Smørgrav { LDNS_SIGN_RSAMD5, "RSAMD5" }, 25*7b5038d7SDag-Erling Smørgrav { LDNS_SIGN_RSASHA1, "RSASHA1" }, 26*7b5038d7SDag-Erling Smørgrav { LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" }, 27*7b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 28*7b5038d7SDag-Erling Smørgrav { LDNS_SIGN_RSASHA256, "RSASHA256" }, 29*7b5038d7SDag-Erling Smørgrav { LDNS_SIGN_RSASHA512, "RSASHA512" }, 30*7b5038d7SDag-Erling Smørgrav #endif 31*7b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 32*7b5038d7SDag-Erling Smørgrav { LDNS_SIGN_ECC_GOST, "ECC-GOST" }, 33*7b5038d7SDag-Erling Smørgrav #endif 34*7b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 35*7b5038d7SDag-Erling Smørgrav { LDNS_SIGN_ECDSAP256SHA256, "ECDSAP256SHA256" }, 36*7b5038d7SDag-Erling Smørgrav { LDNS_SIGN_ECDSAP384SHA384, "ECDSAP384SHA384" }, 37*7b5038d7SDag-Erling Smørgrav #endif 38*7b5038d7SDag-Erling Smørgrav { LDNS_SIGN_DSA, "DSA" }, 39*7b5038d7SDag-Erling Smørgrav { LDNS_SIGN_DSA_NSEC3, "DSA-NSEC3-SHA1" }, 40*7b5038d7SDag-Erling Smørgrav { LDNS_SIGN_HMACMD5, "hmac-md5.sig-alg.reg.int" }, 41*7b5038d7SDag-Erling Smørgrav { LDNS_SIGN_HMACSHA1, "hmac-sha1" }, 42*7b5038d7SDag-Erling Smørgrav { LDNS_SIGN_HMACSHA256, "hmac-sha256" }, 43*7b5038d7SDag-Erling Smørgrav { 0, NULL } 44*7b5038d7SDag-Erling Smørgrav }; 45*7b5038d7SDag-Erling Smørgrav 46*7b5038d7SDag-Erling Smørgrav ldns_key_list * 47*7b5038d7SDag-Erling Smørgrav ldns_key_list_new(void) 48*7b5038d7SDag-Erling Smørgrav { 49*7b5038d7SDag-Erling Smørgrav ldns_key_list *key_list = LDNS_MALLOC(ldns_key_list); 50*7b5038d7SDag-Erling Smørgrav if (!key_list) { 51*7b5038d7SDag-Erling Smørgrav return NULL; 52*7b5038d7SDag-Erling Smørgrav } else { 53*7b5038d7SDag-Erling Smørgrav key_list->_key_count = 0; 54*7b5038d7SDag-Erling Smørgrav key_list->_keys = NULL; 55*7b5038d7SDag-Erling Smørgrav return key_list; 56*7b5038d7SDag-Erling Smørgrav } 57*7b5038d7SDag-Erling Smørgrav } 58*7b5038d7SDag-Erling Smørgrav 59*7b5038d7SDag-Erling Smørgrav ldns_key * 60*7b5038d7SDag-Erling Smørgrav ldns_key_new(void) 61*7b5038d7SDag-Erling Smørgrav { 62*7b5038d7SDag-Erling Smørgrav ldns_key *newkey; 63*7b5038d7SDag-Erling Smørgrav 64*7b5038d7SDag-Erling Smørgrav newkey = LDNS_MALLOC(ldns_key); 65*7b5038d7SDag-Erling Smørgrav if (!newkey) { 66*7b5038d7SDag-Erling Smørgrav return NULL; 67*7b5038d7SDag-Erling Smørgrav } else { 68*7b5038d7SDag-Erling Smørgrav /* some defaults - not sure wether to do this */ 69*7b5038d7SDag-Erling Smørgrav ldns_key_set_use(newkey, true); 70*7b5038d7SDag-Erling Smørgrav ldns_key_set_flags(newkey, LDNS_KEY_ZONE_KEY); 71*7b5038d7SDag-Erling Smørgrav ldns_key_set_origttl(newkey, 0); 72*7b5038d7SDag-Erling Smørgrav ldns_key_set_keytag(newkey, 0); 73*7b5038d7SDag-Erling Smørgrav ldns_key_set_inception(newkey, 0); 74*7b5038d7SDag-Erling Smørgrav ldns_key_set_expiration(newkey, 0); 75*7b5038d7SDag-Erling Smørgrav ldns_key_set_pubkey_owner(newkey, NULL); 76*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 77*7b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(newkey, NULL); 78*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 79*7b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_key(newkey, NULL); 80*7b5038d7SDag-Erling Smørgrav ldns_key_set_external_key(newkey, NULL); 81*7b5038d7SDag-Erling Smørgrav return newkey; 82*7b5038d7SDag-Erling Smørgrav } 83*7b5038d7SDag-Erling Smørgrav } 84*7b5038d7SDag-Erling Smørgrav 85*7b5038d7SDag-Erling Smørgrav ldns_status 86*7b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp(ldns_key **k, FILE *fp) 87*7b5038d7SDag-Erling Smørgrav { 88*7b5038d7SDag-Erling Smørgrav return ldns_key_new_frm_fp_l(k, fp, NULL); 89*7b5038d7SDag-Erling Smørgrav } 90*7b5038d7SDag-Erling Smørgrav 91*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 92*7b5038d7SDag-Erling Smørgrav ldns_status 93*7b5038d7SDag-Erling Smørgrav ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm alg) 94*7b5038d7SDag-Erling Smørgrav { 95*7b5038d7SDag-Erling Smørgrav ldns_key *k; 96*7b5038d7SDag-Erling Smørgrav 97*7b5038d7SDag-Erling Smørgrav k = ldns_key_new(); 98*7b5038d7SDag-Erling Smørgrav if(!k) return LDNS_STATUS_MEM_ERR; 99*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 100*7b5038d7SDag-Erling Smørgrav k->_key.key = ENGINE_load_private_key(e, key_id, UI_OpenSSL(), NULL); 101*7b5038d7SDag-Erling Smørgrav if(!k->_key.key) { 102*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 103*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 104*7b5038d7SDag-Erling Smørgrav } 105*7b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, (ldns_signing_algorithm) alg); 106*7b5038d7SDag-Erling Smørgrav if (!k->_key.key) { 107*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 108*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ENGINE_KEY_NOT_LOADED; 109*7b5038d7SDag-Erling Smørgrav } 110*7b5038d7SDag-Erling Smørgrav #endif /* splint */ 111*7b5038d7SDag-Erling Smørgrav *key = k; 112*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 113*7b5038d7SDag-Erling Smørgrav } 114*7b5038d7SDag-Erling Smørgrav #endif 115*7b5038d7SDag-Erling Smørgrav 116*7b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 117*7b5038d7SDag-Erling Smørgrav /** store GOST engine reference loaded into OpenSSL library */ 118*7b5038d7SDag-Erling Smørgrav ENGINE* ldns_gost_engine = NULL; 119*7b5038d7SDag-Erling Smørgrav 120*7b5038d7SDag-Erling Smørgrav int 121*7b5038d7SDag-Erling Smørgrav ldns_key_EVP_load_gost_id(void) 122*7b5038d7SDag-Erling Smørgrav { 123*7b5038d7SDag-Erling Smørgrav static int gost_id = 0; 124*7b5038d7SDag-Erling Smørgrav const EVP_PKEY_ASN1_METHOD* meth; 125*7b5038d7SDag-Erling Smørgrav ENGINE* e; 126*7b5038d7SDag-Erling Smørgrav 127*7b5038d7SDag-Erling Smørgrav if(gost_id) return gost_id; 128*7b5038d7SDag-Erling Smørgrav 129*7b5038d7SDag-Erling Smørgrav /* see if configuration loaded gost implementation from other engine*/ 130*7b5038d7SDag-Erling Smørgrav meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1); 131*7b5038d7SDag-Erling Smørgrav if(meth) { 132*7b5038d7SDag-Erling Smørgrav EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth); 133*7b5038d7SDag-Erling Smørgrav return gost_id; 134*7b5038d7SDag-Erling Smørgrav } 135*7b5038d7SDag-Erling Smørgrav 136*7b5038d7SDag-Erling Smørgrav /* see if engine can be loaded already */ 137*7b5038d7SDag-Erling Smørgrav e = ENGINE_by_id("gost"); 138*7b5038d7SDag-Erling Smørgrav if(!e) { 139*7b5038d7SDag-Erling Smørgrav /* load it ourself, in case statically linked */ 140*7b5038d7SDag-Erling Smørgrav ENGINE_load_builtin_engines(); 141*7b5038d7SDag-Erling Smørgrav ENGINE_load_dynamic(); 142*7b5038d7SDag-Erling Smørgrav e = ENGINE_by_id("gost"); 143*7b5038d7SDag-Erling Smørgrav } 144*7b5038d7SDag-Erling Smørgrav if(!e) { 145*7b5038d7SDag-Erling Smørgrav /* no gost engine in openssl */ 146*7b5038d7SDag-Erling Smørgrav return 0; 147*7b5038d7SDag-Erling Smørgrav } 148*7b5038d7SDag-Erling Smørgrav if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { 149*7b5038d7SDag-Erling Smørgrav ENGINE_finish(e); 150*7b5038d7SDag-Erling Smørgrav ENGINE_free(e); 151*7b5038d7SDag-Erling Smørgrav return 0; 152*7b5038d7SDag-Erling Smørgrav } 153*7b5038d7SDag-Erling Smørgrav 154*7b5038d7SDag-Erling Smørgrav meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1); 155*7b5038d7SDag-Erling Smørgrav if(!meth) { 156*7b5038d7SDag-Erling Smørgrav /* algo not found */ 157*7b5038d7SDag-Erling Smørgrav ENGINE_finish(e); 158*7b5038d7SDag-Erling Smørgrav ENGINE_free(e); 159*7b5038d7SDag-Erling Smørgrav return 0; 160*7b5038d7SDag-Erling Smørgrav } 161*7b5038d7SDag-Erling Smørgrav /* Note: do not ENGINE_finish and ENGINE_free the acquired engine 162*7b5038d7SDag-Erling Smørgrav * on some platforms this frees up the meth and unloads gost stuff */ 163*7b5038d7SDag-Erling Smørgrav ldns_gost_engine = e; 164*7b5038d7SDag-Erling Smørgrav 165*7b5038d7SDag-Erling Smørgrav EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth); 166*7b5038d7SDag-Erling Smørgrav return gost_id; 167*7b5038d7SDag-Erling Smørgrav } 168*7b5038d7SDag-Erling Smørgrav 169*7b5038d7SDag-Erling Smørgrav void ldns_key_EVP_unload_gost(void) 170*7b5038d7SDag-Erling Smørgrav { 171*7b5038d7SDag-Erling Smørgrav if(ldns_gost_engine) { 172*7b5038d7SDag-Erling Smørgrav ENGINE_finish(ldns_gost_engine); 173*7b5038d7SDag-Erling Smørgrav ENGINE_free(ldns_gost_engine); 174*7b5038d7SDag-Erling Smørgrav ldns_gost_engine = NULL; 175*7b5038d7SDag-Erling Smørgrav } 176*7b5038d7SDag-Erling Smørgrav } 177*7b5038d7SDag-Erling Smørgrav 178*7b5038d7SDag-Erling Smørgrav /** read GOST private key */ 179*7b5038d7SDag-Erling Smørgrav static EVP_PKEY* 180*7b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_gost_l(FILE* fp, int* line_nr) 181*7b5038d7SDag-Erling Smørgrav { 182*7b5038d7SDag-Erling Smørgrav char token[16384]; 183*7b5038d7SDag-Erling Smørgrav const unsigned char* pp; 184*7b5038d7SDag-Erling Smørgrav int gost_id; 185*7b5038d7SDag-Erling Smørgrav EVP_PKEY* pkey; 186*7b5038d7SDag-Erling Smørgrav ldns_rdf* b64rdf = NULL; 187*7b5038d7SDag-Erling Smørgrav 188*7b5038d7SDag-Erling Smørgrav gost_id = ldns_key_EVP_load_gost_id(); 189*7b5038d7SDag-Erling Smørgrav if(!gost_id) 190*7b5038d7SDag-Erling Smørgrav return NULL; 191*7b5038d7SDag-Erling Smørgrav 192*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(fp, "GostAsn1", ": ", token, "\n", 193*7b5038d7SDag-Erling Smørgrav sizeof(token), line_nr) == -1) 194*7b5038d7SDag-Erling Smørgrav return NULL; 195*7b5038d7SDag-Erling Smørgrav while(strlen(token) < 96) { 196*7b5038d7SDag-Erling Smørgrav /* read more b64 from the file, b64 split on multiple lines */ 197*7b5038d7SDag-Erling Smørgrav if(ldns_fget_token_l(fp, token+strlen(token), "\n", 198*7b5038d7SDag-Erling Smørgrav sizeof(token)-strlen(token), line_nr) == -1) 199*7b5038d7SDag-Erling Smørgrav return NULL; 200*7b5038d7SDag-Erling Smørgrav } 201*7b5038d7SDag-Erling Smørgrav if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK) 202*7b5038d7SDag-Erling Smørgrav return NULL; 203*7b5038d7SDag-Erling Smørgrav pp = (unsigned char*)ldns_rdf_data(b64rdf); 204*7b5038d7SDag-Erling Smørgrav pkey = d2i_PrivateKey(gost_id, NULL, &pp, (int)ldns_rdf_size(b64rdf)); 205*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(b64rdf); 206*7b5038d7SDag-Erling Smørgrav return pkey; 207*7b5038d7SDag-Erling Smørgrav } 208*7b5038d7SDag-Erling Smørgrav #endif 209*7b5038d7SDag-Erling Smørgrav 210*7b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 211*7b5038d7SDag-Erling Smørgrav /** calculate public key from private key */ 212*7b5038d7SDag-Erling Smørgrav static int 213*7b5038d7SDag-Erling Smørgrav ldns_EC_KEY_calc_public(EC_KEY* ec) 214*7b5038d7SDag-Erling Smørgrav { 215*7b5038d7SDag-Erling Smørgrav EC_POINT* pub_key; 216*7b5038d7SDag-Erling Smørgrav const EC_GROUP* group; 217*7b5038d7SDag-Erling Smørgrav group = EC_KEY_get0_group(ec); 218*7b5038d7SDag-Erling Smørgrav pub_key = EC_POINT_new(group); 219*7b5038d7SDag-Erling Smørgrav if(!pub_key) return 0; 220*7b5038d7SDag-Erling Smørgrav if(!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { 221*7b5038d7SDag-Erling Smørgrav EC_POINT_free(pub_key); 222*7b5038d7SDag-Erling Smørgrav return 0; 223*7b5038d7SDag-Erling Smørgrav } 224*7b5038d7SDag-Erling Smørgrav if(!EC_POINT_mul(group, pub_key, EC_KEY_get0_private_key(ec), 225*7b5038d7SDag-Erling Smørgrav NULL, NULL, NULL)) { 226*7b5038d7SDag-Erling Smørgrav EC_POINT_free(pub_key); 227*7b5038d7SDag-Erling Smørgrav return 0; 228*7b5038d7SDag-Erling Smørgrav } 229*7b5038d7SDag-Erling Smørgrav if(EC_KEY_set_public_key(ec, pub_key) == 0) { 230*7b5038d7SDag-Erling Smørgrav EC_POINT_free(pub_key); 231*7b5038d7SDag-Erling Smørgrav return 0; 232*7b5038d7SDag-Erling Smørgrav } 233*7b5038d7SDag-Erling Smørgrav EC_POINT_free(pub_key); 234*7b5038d7SDag-Erling Smørgrav return 1; 235*7b5038d7SDag-Erling Smørgrav } 236*7b5038d7SDag-Erling Smørgrav 237*7b5038d7SDag-Erling Smørgrav /** read ECDSA private key */ 238*7b5038d7SDag-Erling Smørgrav static EVP_PKEY* 239*7b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr) 240*7b5038d7SDag-Erling Smørgrav { 241*7b5038d7SDag-Erling Smørgrav char token[16384]; 242*7b5038d7SDag-Erling Smørgrav ldns_rdf* b64rdf = NULL; 243*7b5038d7SDag-Erling Smørgrav unsigned char* pp; 244*7b5038d7SDag-Erling Smørgrav BIGNUM* bn; 245*7b5038d7SDag-Erling Smørgrav EVP_PKEY* evp_key; 246*7b5038d7SDag-Erling Smørgrav EC_KEY* ec; 247*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", 248*7b5038d7SDag-Erling Smørgrav sizeof(token), line_nr) == -1) 249*7b5038d7SDag-Erling Smørgrav return NULL; 250*7b5038d7SDag-Erling Smørgrav if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK) 251*7b5038d7SDag-Erling Smørgrav return NULL; 252*7b5038d7SDag-Erling Smørgrav pp = (unsigned char*)ldns_rdf_data(b64rdf); 253*7b5038d7SDag-Erling Smørgrav 254*7b5038d7SDag-Erling Smørgrav if(alg == LDNS_ECDSAP256SHA256) 255*7b5038d7SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 256*7b5038d7SDag-Erling Smørgrav else if(alg == LDNS_ECDSAP384SHA384) 257*7b5038d7SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_secp384r1); 258*7b5038d7SDag-Erling Smørgrav else ec = NULL; 259*7b5038d7SDag-Erling Smørgrav if(!ec) { 260*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(b64rdf); 261*7b5038d7SDag-Erling Smørgrav return NULL; 262*7b5038d7SDag-Erling Smørgrav } 263*7b5038d7SDag-Erling Smørgrav bn = BN_bin2bn(pp, (int)ldns_rdf_size(b64rdf), NULL); 264*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(b64rdf); 265*7b5038d7SDag-Erling Smørgrav if(!bn) { 266*7b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 267*7b5038d7SDag-Erling Smørgrav return NULL; 268*7b5038d7SDag-Erling Smørgrav } 269*7b5038d7SDag-Erling Smørgrav EC_KEY_set_private_key(ec, bn); 270*7b5038d7SDag-Erling Smørgrav BN_free(bn); 271*7b5038d7SDag-Erling Smørgrav if(!ldns_EC_KEY_calc_public(ec)) { 272*7b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 273*7b5038d7SDag-Erling Smørgrav return NULL; 274*7b5038d7SDag-Erling Smørgrav } 275*7b5038d7SDag-Erling Smørgrav 276*7b5038d7SDag-Erling Smørgrav evp_key = EVP_PKEY_new(); 277*7b5038d7SDag-Erling Smørgrav if(!evp_key) { 278*7b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 279*7b5038d7SDag-Erling Smørgrav return NULL; 280*7b5038d7SDag-Erling Smørgrav } 281*7b5038d7SDag-Erling Smørgrav if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) { 282*7b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 283*7b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 284*7b5038d7SDag-Erling Smørgrav return NULL; 285*7b5038d7SDag-Erling Smørgrav } 286*7b5038d7SDag-Erling Smørgrav return evp_key; 287*7b5038d7SDag-Erling Smørgrav } 288*7b5038d7SDag-Erling Smørgrav #endif 289*7b5038d7SDag-Erling Smørgrav 290*7b5038d7SDag-Erling Smørgrav ldns_status 291*7b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr) 292*7b5038d7SDag-Erling Smørgrav { 293*7b5038d7SDag-Erling Smørgrav ldns_key *k; 294*7b5038d7SDag-Erling Smørgrav char *d; 295*7b5038d7SDag-Erling Smørgrav ldns_signing_algorithm alg; 296*7b5038d7SDag-Erling Smørgrav ldns_rr *key_rr; 297*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 298*7b5038d7SDag-Erling Smørgrav RSA *rsa; 299*7b5038d7SDag-Erling Smørgrav DSA *dsa; 300*7b5038d7SDag-Erling Smørgrav unsigned char *hmac; 301*7b5038d7SDag-Erling Smørgrav size_t hmac_size; 302*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 303*7b5038d7SDag-Erling Smørgrav 304*7b5038d7SDag-Erling Smørgrav k = ldns_key_new(); 305*7b5038d7SDag-Erling Smørgrav 306*7b5038d7SDag-Erling Smørgrav d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); 307*7b5038d7SDag-Erling Smørgrav if (!k || !d) { 308*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 309*7b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 310*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 311*7b5038d7SDag-Erling Smørgrav } 312*7b5038d7SDag-Erling Smørgrav 313*7b5038d7SDag-Erling Smørgrav alg = 0; 314*7b5038d7SDag-Erling Smørgrav 315*7b5038d7SDag-Erling Smørgrav /* the file is highly structured. Do this in sequence */ 316*7b5038d7SDag-Erling Smørgrav /* RSA: 317*7b5038d7SDag-Erling Smørgrav * Private-key-format: v1.x. 318*7b5038d7SDag-Erling Smørgrav * Algorithm: 1 (RSA) 319*7b5038d7SDag-Erling Smørgrav 320*7b5038d7SDag-Erling Smørgrav */ 321*7b5038d7SDag-Erling Smørgrav /* get the key format version number */ 322*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(fp, "Private-key-format", ": ", d, "\n", 323*7b5038d7SDag-Erling Smørgrav LDNS_MAX_LINELEN, line_nr) == -1) { 324*7b5038d7SDag-Erling Smørgrav /* no version information */ 325*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 326*7b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 327*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_ERR; 328*7b5038d7SDag-Erling Smørgrav } 329*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "v1.", 3) != 0) { 330*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 331*7b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 332*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_VERSION_ERR; 333*7b5038d7SDag-Erling Smørgrav } 334*7b5038d7SDag-Erling Smørgrav 335*7b5038d7SDag-Erling Smørgrav /* get the algorithm type, our file function strip ( ) so there are 336*7b5038d7SDag-Erling Smørgrav * not in the return string! */ 337*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(fp, "Algorithm", ": ", d, "\n", 338*7b5038d7SDag-Erling Smørgrav LDNS_MAX_LINELEN, line_nr) == -1) { 339*7b5038d7SDag-Erling Smørgrav /* no alg information */ 340*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 341*7b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 342*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_ALG_ERR; 343*7b5038d7SDag-Erling Smørgrav } 344*7b5038d7SDag-Erling Smørgrav 345*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "1 RSA", 2) == 0) { 346*7b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_RSAMD5; 347*7b5038d7SDag-Erling Smørgrav } 348*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "2 DH", 2) == 0) { 349*7b5038d7SDag-Erling Smørgrav alg = (ldns_signing_algorithm)LDNS_DH; 350*7b5038d7SDag-Erling Smørgrav } 351*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "3 DSA", 2) == 0) { 352*7b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_DSA; 353*7b5038d7SDag-Erling Smørgrav } 354*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "4 ECC", 2) == 0) { 355*7b5038d7SDag-Erling Smørgrav alg = (ldns_signing_algorithm)LDNS_ECC; 356*7b5038d7SDag-Erling Smørgrav } 357*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "5 RSASHA1", 2) == 0) { 358*7b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_RSASHA1; 359*7b5038d7SDag-Erling Smørgrav } 360*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "6 DSA", 2) == 0) { 361*7b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_DSA_NSEC3; 362*7b5038d7SDag-Erling Smørgrav } 363*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "7 RSASHA1", 2) == 0) { 364*7b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_RSASHA1_NSEC3; 365*7b5038d7SDag-Erling Smørgrav } 366*7b5038d7SDag-Erling Smørgrav 367*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "8 RSASHA256", 2) == 0) { 368*7b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 369*7b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_RSASHA256; 370*7b5038d7SDag-Erling Smørgrav #else 371*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: SHA256 not compiled into this "); 372*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns\n"); 373*7b5038d7SDag-Erling Smørgrav #endif 374*7b5038d7SDag-Erling Smørgrav } 375*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "10 RSASHA512", 3) == 0) { 376*7b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 377*7b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_RSASHA512; 378*7b5038d7SDag-Erling Smørgrav #else 379*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: SHA512 not compiled into this "); 380*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns\n"); 381*7b5038d7SDag-Erling Smørgrav #endif 382*7b5038d7SDag-Erling Smørgrav } 383*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "12 ECC-GOST", 3) == 0) { 384*7b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 385*7b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_ECC_GOST; 386*7b5038d7SDag-Erling Smørgrav #else 387*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: ECC-GOST not compiled into this "); 388*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns, use --enable-gost\n"); 389*7b5038d7SDag-Erling Smørgrav #endif 390*7b5038d7SDag-Erling Smørgrav } 391*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "13 ECDSAP256SHA256", 3) == 0) { 392*7b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 393*7b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_ECDSAP256SHA256; 394*7b5038d7SDag-Erling Smørgrav #else 395*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: ECDSA not compiled into this "); 396*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns, use --enable-ecdsa\n"); 397*7b5038d7SDag-Erling Smørgrav #endif 398*7b5038d7SDag-Erling Smørgrav } 399*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "14 ECDSAP384SHA384", 3) == 0) { 400*7b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 401*7b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_ECDSAP384SHA384; 402*7b5038d7SDag-Erling Smørgrav #else 403*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: ECDSA not compiled into this "); 404*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns, use --enable-ecdsa\n"); 405*7b5038d7SDag-Erling Smørgrav #endif 406*7b5038d7SDag-Erling Smørgrav } 407*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "157 HMAC-MD5", 4) == 0) { 408*7b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_HMACMD5; 409*7b5038d7SDag-Erling Smørgrav } 410*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "158 HMAC-SHA1", 4) == 0) { 411*7b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_HMACSHA1; 412*7b5038d7SDag-Erling Smørgrav } 413*7b5038d7SDag-Erling Smørgrav if (strncmp(d, "159 HMAC-SHA256", 4) == 0) { 414*7b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_HMACSHA256; 415*7b5038d7SDag-Erling Smørgrav } 416*7b5038d7SDag-Erling Smørgrav 417*7b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 418*7b5038d7SDag-Erling Smørgrav 419*7b5038d7SDag-Erling Smørgrav switch(alg) { 420*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSAMD5: 421*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1: 422*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1_NSEC3: 423*7b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 424*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA256: 425*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA512: 426*7b5038d7SDag-Erling Smørgrav #endif 427*7b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 428*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 429*7b5038d7SDag-Erling Smørgrav rsa = ldns_key_new_frm_fp_rsa_l(fp, line_nr); 430*7b5038d7SDag-Erling Smørgrav if (!rsa) { 431*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 432*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 433*7b5038d7SDag-Erling Smørgrav } 434*7b5038d7SDag-Erling Smørgrav ldns_key_set_rsa_key(k, rsa); 435*7b5038d7SDag-Erling Smørgrav RSA_free(rsa); 436*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 437*7b5038d7SDag-Erling Smørgrav break; 438*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA: 439*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA_NSEC3: 440*7b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 441*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 442*7b5038d7SDag-Erling Smørgrav dsa = ldns_key_new_frm_fp_dsa_l(fp, line_nr); 443*7b5038d7SDag-Erling Smørgrav if (!dsa) { 444*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 445*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 446*7b5038d7SDag-Erling Smørgrav } 447*7b5038d7SDag-Erling Smørgrav ldns_key_set_dsa_key(k, dsa); 448*7b5038d7SDag-Erling Smørgrav DSA_free(dsa); 449*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 450*7b5038d7SDag-Erling Smørgrav break; 451*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACMD5: 452*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA1: 453*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA256: 454*7b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 455*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 456*7b5038d7SDag-Erling Smørgrav hmac = ldns_key_new_frm_fp_hmac_l(fp, line_nr, &hmac_size); 457*7b5038d7SDag-Erling Smørgrav if (!hmac) { 458*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 459*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 460*7b5038d7SDag-Erling Smørgrav } 461*7b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_size(k, hmac_size); 462*7b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_key(k, hmac); 463*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 464*7b5038d7SDag-Erling Smørgrav break; 465*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECC_GOST: 466*7b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 467*7b5038d7SDag-Erling Smørgrav #if defined(HAVE_SSL) && defined(USE_GOST) 468*7b5038d7SDag-Erling Smørgrav if(!ldns_key_EVP_load_gost_id()) { 469*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 470*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL; 471*7b5038d7SDag-Erling Smørgrav } 472*7b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(k, 473*7b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_gost_l(fp, line_nr)); 474*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 475*7b5038d7SDag-Erling Smørgrav if(!k->_key.key) { 476*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 477*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 478*7b5038d7SDag-Erling Smørgrav } 479*7b5038d7SDag-Erling Smørgrav #endif /* splint */ 480*7b5038d7SDag-Erling Smørgrav #endif 481*7b5038d7SDag-Erling Smørgrav break; 482*7b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 483*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP256SHA256: 484*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP384SHA384: 485*7b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 486*7b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(k, 487*7b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_ecdsa_l(fp, (ldns_algorithm)alg, line_nr)); 488*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 489*7b5038d7SDag-Erling Smørgrav if(!k->_key.key) { 490*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 491*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 492*7b5038d7SDag-Erling Smørgrav } 493*7b5038d7SDag-Erling Smørgrav #endif /* splint */ 494*7b5038d7SDag-Erling Smørgrav break; 495*7b5038d7SDag-Erling Smørgrav #endif 496*7b5038d7SDag-Erling Smørgrav default: 497*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 498*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_ALG_ERR; 499*7b5038d7SDag-Erling Smørgrav } 500*7b5038d7SDag-Erling Smørgrav key_rr = ldns_key2rr(k); 501*7b5038d7SDag-Erling Smørgrav ldns_key_set_keytag(k, ldns_calc_keytag(key_rr)); 502*7b5038d7SDag-Erling Smørgrav ldns_rr_free(key_rr); 503*7b5038d7SDag-Erling Smørgrav 504*7b5038d7SDag-Erling Smørgrav if (key) { 505*7b5038d7SDag-Erling Smørgrav *key = k; 506*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 507*7b5038d7SDag-Erling Smørgrav } 508*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 509*7b5038d7SDag-Erling Smørgrav } 510*7b5038d7SDag-Erling Smørgrav 511*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 512*7b5038d7SDag-Erling Smørgrav RSA * 513*7b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_rsa(FILE *f) 514*7b5038d7SDag-Erling Smørgrav { 515*7b5038d7SDag-Erling Smørgrav return ldns_key_new_frm_fp_rsa_l(f, NULL); 516*7b5038d7SDag-Erling Smørgrav } 517*7b5038d7SDag-Erling Smørgrav 518*7b5038d7SDag-Erling Smørgrav RSA * 519*7b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr) 520*7b5038d7SDag-Erling Smørgrav { 521*7b5038d7SDag-Erling Smørgrav /* we parse 522*7b5038d7SDag-Erling Smørgrav * Modulus: 523*7b5038d7SDag-Erling Smørgrav * PublicExponent: 524*7b5038d7SDag-Erling Smørgrav * PrivateExponent: 525*7b5038d7SDag-Erling Smørgrav * Prime1: 526*7b5038d7SDag-Erling Smørgrav * Prime2: 527*7b5038d7SDag-Erling Smørgrav * Exponent1: 528*7b5038d7SDag-Erling Smørgrav * Exponent2: 529*7b5038d7SDag-Erling Smørgrav * Coefficient: 530*7b5038d7SDag-Erling Smørgrav * 531*7b5038d7SDag-Erling Smørgrav * man 3 RSA: 532*7b5038d7SDag-Erling Smørgrav * 533*7b5038d7SDag-Erling Smørgrav * struct 534*7b5038d7SDag-Erling Smørgrav * { 535*7b5038d7SDag-Erling Smørgrav * BIGNUM *n; // public modulus 536*7b5038d7SDag-Erling Smørgrav * BIGNUM *e; // public exponent 537*7b5038d7SDag-Erling Smørgrav * BIGNUM *d; // private exponent 538*7b5038d7SDag-Erling Smørgrav * BIGNUM *p; // secret prime factor 539*7b5038d7SDag-Erling Smørgrav * BIGNUM *q; // secret prime factor 540*7b5038d7SDag-Erling Smørgrav * BIGNUM *dmp1; // d mod (p-1) 541*7b5038d7SDag-Erling Smørgrav * BIGNUM *dmq1; // d mod (q-1) 542*7b5038d7SDag-Erling Smørgrav * BIGNUM *iqmp; // q^-1 mod p 543*7b5038d7SDag-Erling Smørgrav * // ... 544*7b5038d7SDag-Erling Smørgrav * 545*7b5038d7SDag-Erling Smørgrav */ 546*7b5038d7SDag-Erling Smørgrav char *d; 547*7b5038d7SDag-Erling Smørgrav RSA *rsa; 548*7b5038d7SDag-Erling Smørgrav uint8_t *buf; 549*7b5038d7SDag-Erling Smørgrav int i; 550*7b5038d7SDag-Erling Smørgrav 551*7b5038d7SDag-Erling Smørgrav d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); 552*7b5038d7SDag-Erling Smørgrav buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN); 553*7b5038d7SDag-Erling Smørgrav rsa = RSA_new(); 554*7b5038d7SDag-Erling Smørgrav if (!d || !rsa || !buf) { 555*7b5038d7SDag-Erling Smørgrav goto error; 556*7b5038d7SDag-Erling Smørgrav } 557*7b5038d7SDag-Erling Smørgrav 558*7b5038d7SDag-Erling Smørgrav /* I could use functions again, but that seems an overkill, 559*7b5038d7SDag-Erling Smørgrav * allthough this also looks tedious 560*7b5038d7SDag-Erling Smørgrav */ 561*7b5038d7SDag-Erling Smørgrav 562*7b5038d7SDag-Erling Smørgrav /* Modules, rsa->n */ 563*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Modulus", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 564*7b5038d7SDag-Erling Smørgrav goto error; 565*7b5038d7SDag-Erling Smørgrav } 566*7b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 567*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 568*7b5038d7SDag-Erling Smørgrav rsa->n = BN_bin2bn((const char unsigned*)buf, i, NULL); 569*7b5038d7SDag-Erling Smørgrav if (!rsa->n) { 570*7b5038d7SDag-Erling Smørgrav goto error; 571*7b5038d7SDag-Erling Smørgrav } 572*7b5038d7SDag-Erling Smørgrav 573*7b5038d7SDag-Erling Smørgrav /* PublicExponent, rsa->e */ 574*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 575*7b5038d7SDag-Erling Smørgrav goto error; 576*7b5038d7SDag-Erling Smørgrav } 577*7b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 578*7b5038d7SDag-Erling Smørgrav rsa->e = BN_bin2bn((const char unsigned*)buf, i, NULL); 579*7b5038d7SDag-Erling Smørgrav if (!rsa->e) { 580*7b5038d7SDag-Erling Smørgrav goto error; 581*7b5038d7SDag-Erling Smørgrav } 582*7b5038d7SDag-Erling Smørgrav 583*7b5038d7SDag-Erling Smørgrav /* PrivateExponent, rsa->d */ 584*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 585*7b5038d7SDag-Erling Smørgrav goto error; 586*7b5038d7SDag-Erling Smørgrav } 587*7b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 588*7b5038d7SDag-Erling Smørgrav rsa->d = BN_bin2bn((const char unsigned*)buf, i, NULL); 589*7b5038d7SDag-Erling Smørgrav if (!rsa->d) { 590*7b5038d7SDag-Erling Smørgrav goto error; 591*7b5038d7SDag-Erling Smørgrav } 592*7b5038d7SDag-Erling Smørgrav 593*7b5038d7SDag-Erling Smørgrav /* Prime1, rsa->p */ 594*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Prime1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 595*7b5038d7SDag-Erling Smørgrav goto error; 596*7b5038d7SDag-Erling Smørgrav } 597*7b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 598*7b5038d7SDag-Erling Smørgrav rsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL); 599*7b5038d7SDag-Erling Smørgrav if (!rsa->p) { 600*7b5038d7SDag-Erling Smørgrav goto error; 601*7b5038d7SDag-Erling Smørgrav } 602*7b5038d7SDag-Erling Smørgrav 603*7b5038d7SDag-Erling Smørgrav /* Prime2, rsa->q */ 604*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Prime2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 605*7b5038d7SDag-Erling Smørgrav goto error; 606*7b5038d7SDag-Erling Smørgrav } 607*7b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 608*7b5038d7SDag-Erling Smørgrav rsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL); 609*7b5038d7SDag-Erling Smørgrav if (!rsa->q) { 610*7b5038d7SDag-Erling Smørgrav goto error; 611*7b5038d7SDag-Erling Smørgrav } 612*7b5038d7SDag-Erling Smørgrav 613*7b5038d7SDag-Erling Smørgrav /* Exponent1, rsa->dmp1 */ 614*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 615*7b5038d7SDag-Erling Smørgrav goto error; 616*7b5038d7SDag-Erling Smørgrav } 617*7b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 618*7b5038d7SDag-Erling Smørgrav rsa->dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL); 619*7b5038d7SDag-Erling Smørgrav if (!rsa->dmp1) { 620*7b5038d7SDag-Erling Smørgrav goto error; 621*7b5038d7SDag-Erling Smørgrav } 622*7b5038d7SDag-Erling Smørgrav 623*7b5038d7SDag-Erling Smørgrav /* Exponent2, rsa->dmq1 */ 624*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 625*7b5038d7SDag-Erling Smørgrav goto error; 626*7b5038d7SDag-Erling Smørgrav } 627*7b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 628*7b5038d7SDag-Erling Smørgrav rsa->dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL); 629*7b5038d7SDag-Erling Smørgrav if (!rsa->dmq1) { 630*7b5038d7SDag-Erling Smørgrav goto error; 631*7b5038d7SDag-Erling Smørgrav } 632*7b5038d7SDag-Erling Smørgrav 633*7b5038d7SDag-Erling Smørgrav /* Coefficient, rsa->iqmp */ 634*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 635*7b5038d7SDag-Erling Smørgrav goto error; 636*7b5038d7SDag-Erling Smørgrav } 637*7b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 638*7b5038d7SDag-Erling Smørgrav rsa->iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL); 639*7b5038d7SDag-Erling Smørgrav if (!rsa->iqmp) { 640*7b5038d7SDag-Erling Smørgrav goto error; 641*7b5038d7SDag-Erling Smørgrav } 642*7b5038d7SDag-Erling Smørgrav #endif /* splint */ 643*7b5038d7SDag-Erling Smørgrav 644*7b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 645*7b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 646*7b5038d7SDag-Erling Smørgrav return rsa; 647*7b5038d7SDag-Erling Smørgrav 648*7b5038d7SDag-Erling Smørgrav error: 649*7b5038d7SDag-Erling Smørgrav RSA_free(rsa); 650*7b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 651*7b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 652*7b5038d7SDag-Erling Smørgrav return NULL; 653*7b5038d7SDag-Erling Smørgrav } 654*7b5038d7SDag-Erling Smørgrav 655*7b5038d7SDag-Erling Smørgrav DSA * 656*7b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_dsa(FILE *f) 657*7b5038d7SDag-Erling Smørgrav { 658*7b5038d7SDag-Erling Smørgrav return ldns_key_new_frm_fp_dsa_l(f, NULL); 659*7b5038d7SDag-Erling Smørgrav } 660*7b5038d7SDag-Erling Smørgrav 661*7b5038d7SDag-Erling Smørgrav DSA * 662*7b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr)) 663*7b5038d7SDag-Erling Smørgrav { 664*7b5038d7SDag-Erling Smørgrav int i; 665*7b5038d7SDag-Erling Smørgrav char *d; 666*7b5038d7SDag-Erling Smørgrav DSA *dsa; 667*7b5038d7SDag-Erling Smørgrav uint8_t *buf; 668*7b5038d7SDag-Erling Smørgrav 669*7b5038d7SDag-Erling Smørgrav d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); 670*7b5038d7SDag-Erling Smørgrav buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN); 671*7b5038d7SDag-Erling Smørgrav dsa = DSA_new(); 672*7b5038d7SDag-Erling Smørgrav if (!d || !dsa || !buf) { 673*7b5038d7SDag-Erling Smørgrav goto error; 674*7b5038d7SDag-Erling Smørgrav } 675*7b5038d7SDag-Erling Smørgrav 676*7b5038d7SDag-Erling Smørgrav /* the line parser removes the () from the input... */ 677*7b5038d7SDag-Erling Smørgrav 678*7b5038d7SDag-Erling Smørgrav /* Prime, dsa->p */ 679*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Primep", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 680*7b5038d7SDag-Erling Smørgrav goto error; 681*7b5038d7SDag-Erling Smørgrav } 682*7b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 683*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 684*7b5038d7SDag-Erling Smørgrav dsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL); 685*7b5038d7SDag-Erling Smørgrav if (!dsa->p) { 686*7b5038d7SDag-Erling Smørgrav goto error; 687*7b5038d7SDag-Erling Smørgrav } 688*7b5038d7SDag-Erling Smørgrav 689*7b5038d7SDag-Erling Smørgrav /* Subprime, dsa->q */ 690*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Subprimeq", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 691*7b5038d7SDag-Erling Smørgrav goto error; 692*7b5038d7SDag-Erling Smørgrav } 693*7b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 694*7b5038d7SDag-Erling Smørgrav dsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL); 695*7b5038d7SDag-Erling Smørgrav if (!dsa->q) { 696*7b5038d7SDag-Erling Smørgrav goto error; 697*7b5038d7SDag-Erling Smørgrav } 698*7b5038d7SDag-Erling Smørgrav 699*7b5038d7SDag-Erling Smørgrav /* Base, dsa->g */ 700*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Baseg", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 701*7b5038d7SDag-Erling Smørgrav goto error; 702*7b5038d7SDag-Erling Smørgrav } 703*7b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 704*7b5038d7SDag-Erling Smørgrav dsa->g = BN_bin2bn((const char unsigned*)buf, i, NULL); 705*7b5038d7SDag-Erling Smørgrav if (!dsa->g) { 706*7b5038d7SDag-Erling Smørgrav goto error; 707*7b5038d7SDag-Erling Smørgrav } 708*7b5038d7SDag-Erling Smørgrav 709*7b5038d7SDag-Erling Smørgrav /* Private key, dsa->priv_key */ 710*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Private_valuex", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 711*7b5038d7SDag-Erling Smørgrav goto error; 712*7b5038d7SDag-Erling Smørgrav } 713*7b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 714*7b5038d7SDag-Erling Smørgrav dsa->priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL); 715*7b5038d7SDag-Erling Smørgrav if (!dsa->priv_key) { 716*7b5038d7SDag-Erling Smørgrav goto error; 717*7b5038d7SDag-Erling Smørgrav } 718*7b5038d7SDag-Erling Smørgrav 719*7b5038d7SDag-Erling Smørgrav /* Public key, dsa->priv_key */ 720*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Public_valuey", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 721*7b5038d7SDag-Erling Smørgrav goto error; 722*7b5038d7SDag-Erling Smørgrav } 723*7b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 724*7b5038d7SDag-Erling Smørgrav dsa->pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL); 725*7b5038d7SDag-Erling Smørgrav if (!dsa->pub_key) { 726*7b5038d7SDag-Erling Smørgrav goto error; 727*7b5038d7SDag-Erling Smørgrav } 728*7b5038d7SDag-Erling Smørgrav #endif /* splint */ 729*7b5038d7SDag-Erling Smørgrav 730*7b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 731*7b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 732*7b5038d7SDag-Erling Smørgrav 733*7b5038d7SDag-Erling Smørgrav return dsa; 734*7b5038d7SDag-Erling Smørgrav 735*7b5038d7SDag-Erling Smørgrav error: 736*7b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 737*7b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 738*7b5038d7SDag-Erling Smørgrav DSA_free(dsa); 739*7b5038d7SDag-Erling Smørgrav return NULL; 740*7b5038d7SDag-Erling Smørgrav } 741*7b5038d7SDag-Erling Smørgrav 742*7b5038d7SDag-Erling Smørgrav unsigned char * 743*7b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_hmac(FILE *f, size_t *hmac_size) 744*7b5038d7SDag-Erling Smørgrav { 745*7b5038d7SDag-Erling Smørgrav return ldns_key_new_frm_fp_hmac_l(f, NULL, hmac_size); 746*7b5038d7SDag-Erling Smørgrav } 747*7b5038d7SDag-Erling Smørgrav 748*7b5038d7SDag-Erling Smørgrav unsigned char * 749*7b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_hmac_l( FILE *f 750*7b5038d7SDag-Erling Smørgrav , ATTR_UNUSED(int *line_nr) 751*7b5038d7SDag-Erling Smørgrav , size_t *hmac_size 752*7b5038d7SDag-Erling Smørgrav ) 753*7b5038d7SDag-Erling Smørgrav { 754*7b5038d7SDag-Erling Smørgrav size_t i; 755*7b5038d7SDag-Erling Smørgrav char *d; 756*7b5038d7SDag-Erling Smørgrav unsigned char *buf; 757*7b5038d7SDag-Erling Smørgrav 758*7b5038d7SDag-Erling Smørgrav d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); 759*7b5038d7SDag-Erling Smørgrav buf = LDNS_XMALLOC(unsigned char, LDNS_MAX_LINELEN); 760*7b5038d7SDag-Erling Smørgrav if(!d || !buf) { 761*7b5038d7SDag-Erling Smørgrav goto error; 762*7b5038d7SDag-Erling Smørgrav } 763*7b5038d7SDag-Erling Smørgrav 764*7b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 765*7b5038d7SDag-Erling Smørgrav goto error; 766*7b5038d7SDag-Erling Smørgrav } 767*7b5038d7SDag-Erling Smørgrav i = (size_t) ldns_b64_pton((const char*)d, 768*7b5038d7SDag-Erling Smørgrav buf, 769*7b5038d7SDag-Erling Smørgrav ldns_b64_ntop_calculate_size(strlen(d))); 770*7b5038d7SDag-Erling Smørgrav 771*7b5038d7SDag-Erling Smørgrav *hmac_size = i; 772*7b5038d7SDag-Erling Smørgrav return buf; 773*7b5038d7SDag-Erling Smørgrav 774*7b5038d7SDag-Erling Smørgrav error: 775*7b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 776*7b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 777*7b5038d7SDag-Erling Smørgrav *hmac_size = 0; 778*7b5038d7SDag-Erling Smørgrav return NULL; 779*7b5038d7SDag-Erling Smørgrav } 780*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 781*7b5038d7SDag-Erling Smørgrav 782*7b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 783*7b5038d7SDag-Erling Smørgrav static EVP_PKEY* 784*7b5038d7SDag-Erling Smørgrav ldns_gen_gost_key(void) 785*7b5038d7SDag-Erling Smørgrav { 786*7b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX* ctx; 787*7b5038d7SDag-Erling Smørgrav EVP_PKEY* p = NULL; 788*7b5038d7SDag-Erling Smørgrav int gost_id = ldns_key_EVP_load_gost_id(); 789*7b5038d7SDag-Erling Smørgrav if(!gost_id) 790*7b5038d7SDag-Erling Smørgrav return NULL; 791*7b5038d7SDag-Erling Smørgrav ctx = EVP_PKEY_CTX_new_id(gost_id, NULL); 792*7b5038d7SDag-Erling Smørgrav if(!ctx) { 793*7b5038d7SDag-Erling Smørgrav /* the id should be available now */ 794*7b5038d7SDag-Erling Smørgrav return NULL; 795*7b5038d7SDag-Erling Smørgrav } 796*7b5038d7SDag-Erling Smørgrav if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) { 797*7b5038d7SDag-Erling Smørgrav /* cannot set paramset */ 798*7b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX_free(ctx); 799*7b5038d7SDag-Erling Smørgrav return NULL; 800*7b5038d7SDag-Erling Smørgrav } 801*7b5038d7SDag-Erling Smørgrav 802*7b5038d7SDag-Erling Smørgrav if(EVP_PKEY_keygen_init(ctx) <= 0) { 803*7b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX_free(ctx); 804*7b5038d7SDag-Erling Smørgrav return NULL; 805*7b5038d7SDag-Erling Smørgrav } 806*7b5038d7SDag-Erling Smørgrav if(EVP_PKEY_keygen(ctx, &p) <= 0) { 807*7b5038d7SDag-Erling Smørgrav EVP_PKEY_free(p); 808*7b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX_free(ctx); 809*7b5038d7SDag-Erling Smørgrav return NULL; 810*7b5038d7SDag-Erling Smørgrav } 811*7b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX_free(ctx); 812*7b5038d7SDag-Erling Smørgrav return p; 813*7b5038d7SDag-Erling Smørgrav } 814*7b5038d7SDag-Erling Smørgrav #endif 815*7b5038d7SDag-Erling Smørgrav 816*7b5038d7SDag-Erling Smørgrav ldns_key * 817*7b5038d7SDag-Erling Smørgrav ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) 818*7b5038d7SDag-Erling Smørgrav { 819*7b5038d7SDag-Erling Smørgrav ldns_key *k; 820*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 821*7b5038d7SDag-Erling Smørgrav DSA *d; 822*7b5038d7SDag-Erling Smørgrav RSA *r; 823*7b5038d7SDag-Erling Smørgrav # ifdef USE_ECDSA 824*7b5038d7SDag-Erling Smørgrav EC_KEY *ec = NULL; 825*7b5038d7SDag-Erling Smørgrav # endif 826*7b5038d7SDag-Erling Smørgrav #else 827*7b5038d7SDag-Erling Smørgrav int i; 828*7b5038d7SDag-Erling Smørgrav uint16_t offset = 0; 829*7b5038d7SDag-Erling Smørgrav #endif 830*7b5038d7SDag-Erling Smørgrav unsigned char *hmac; 831*7b5038d7SDag-Erling Smørgrav 832*7b5038d7SDag-Erling Smørgrav k = ldns_key_new(); 833*7b5038d7SDag-Erling Smørgrav if (!k) { 834*7b5038d7SDag-Erling Smørgrav return NULL; 835*7b5038d7SDag-Erling Smørgrav } 836*7b5038d7SDag-Erling Smørgrav switch(alg) { 837*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSAMD5: 838*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1: 839*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1_NSEC3: 840*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA256: 841*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA512: 842*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 843*7b5038d7SDag-Erling Smørgrav r = RSA_generate_key((int)size, RSA_F4, NULL, NULL); 844*7b5038d7SDag-Erling Smørgrav if(!r) { 845*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 846*7b5038d7SDag-Erling Smørgrav return NULL; 847*7b5038d7SDag-Erling Smørgrav } 848*7b5038d7SDag-Erling Smørgrav if (RSA_check_key(r) != 1) { 849*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 850*7b5038d7SDag-Erling Smørgrav return NULL; 851*7b5038d7SDag-Erling Smørgrav } 852*7b5038d7SDag-Erling Smørgrav ldns_key_set_rsa_key(k, r); 853*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 854*7b5038d7SDag-Erling Smørgrav break; 855*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA: 856*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA_NSEC3: 857*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 858*7b5038d7SDag-Erling Smørgrav d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL); 859*7b5038d7SDag-Erling Smørgrav if (!d) { 860*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 861*7b5038d7SDag-Erling Smørgrav return NULL; 862*7b5038d7SDag-Erling Smørgrav } 863*7b5038d7SDag-Erling Smørgrav if (DSA_generate_key(d) != 1) { 864*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 865*7b5038d7SDag-Erling Smørgrav return NULL; 866*7b5038d7SDag-Erling Smørgrav } 867*7b5038d7SDag-Erling Smørgrav ldns_key_set_dsa_key(k, d); 868*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 869*7b5038d7SDag-Erling Smørgrav break; 870*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACMD5: 871*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA1: 872*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA256: 873*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 874*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 875*7b5038d7SDag-Erling Smørgrav k->_key.key = NULL; 876*7b5038d7SDag-Erling Smørgrav #endif /* splint */ 877*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 878*7b5038d7SDag-Erling Smørgrav size = size / 8; 879*7b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_size(k, size); 880*7b5038d7SDag-Erling Smørgrav 881*7b5038d7SDag-Erling Smørgrav hmac = LDNS_XMALLOC(unsigned char, size); 882*7b5038d7SDag-Erling Smørgrav if(!hmac) { 883*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 884*7b5038d7SDag-Erling Smørgrav return NULL; 885*7b5038d7SDag-Erling Smørgrav } 886*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 887*7b5038d7SDag-Erling Smørgrav if (RAND_bytes(hmac, (int) size) != 1) { 888*7b5038d7SDag-Erling Smørgrav LDNS_FREE(hmac); 889*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 890*7b5038d7SDag-Erling Smørgrav return NULL; 891*7b5038d7SDag-Erling Smørgrav } 892*7b5038d7SDag-Erling Smørgrav #else 893*7b5038d7SDag-Erling Smørgrav while (offset + sizeof(i) < size) { 894*7b5038d7SDag-Erling Smørgrav i = random(); 895*7b5038d7SDag-Erling Smørgrav memcpy(&hmac[offset], &i, sizeof(i)); 896*7b5038d7SDag-Erling Smørgrav offset += sizeof(i); 897*7b5038d7SDag-Erling Smørgrav } 898*7b5038d7SDag-Erling Smørgrav if (offset < size) { 899*7b5038d7SDag-Erling Smørgrav i = random(); 900*7b5038d7SDag-Erling Smørgrav memcpy(&hmac[offset], &i, size - offset); 901*7b5038d7SDag-Erling Smørgrav } 902*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 903*7b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_key(k, hmac); 904*7b5038d7SDag-Erling Smørgrav 905*7b5038d7SDag-Erling Smørgrav ldns_key_set_flags(k, 0); 906*7b5038d7SDag-Erling Smørgrav break; 907*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECC_GOST: 908*7b5038d7SDag-Erling Smørgrav #if defined(HAVE_SSL) && defined(USE_GOST) 909*7b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(k, ldns_gen_gost_key()); 910*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 911*7b5038d7SDag-Erling Smørgrav if(!k->_key.key) { 912*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 913*7b5038d7SDag-Erling Smørgrav return NULL; 914*7b5038d7SDag-Erling Smørgrav } 915*7b5038d7SDag-Erling Smørgrav #endif /* splint */ 916*7b5038d7SDag-Erling Smørgrav #else 917*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 918*7b5038d7SDag-Erling Smørgrav return NULL; 919*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL and USE_GOST */ 920*7b5038d7SDag-Erling Smørgrav break; 921*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP256SHA256: 922*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP384SHA384: 923*7b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 924*7b5038d7SDag-Erling Smørgrav if(alg == LDNS_SIGN_ECDSAP256SHA256) 925*7b5038d7SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 926*7b5038d7SDag-Erling Smørgrav else if(alg == LDNS_SIGN_ECDSAP384SHA384) 927*7b5038d7SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_secp384r1); 928*7b5038d7SDag-Erling Smørgrav if(!ec) { 929*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 930*7b5038d7SDag-Erling Smørgrav return NULL; 931*7b5038d7SDag-Erling Smørgrav } 932*7b5038d7SDag-Erling Smørgrav if(!EC_KEY_generate_key(ec)) { 933*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 934*7b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 935*7b5038d7SDag-Erling Smørgrav return NULL; 936*7b5038d7SDag-Erling Smørgrav } 937*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 938*7b5038d7SDag-Erling Smørgrav k->_key.key = EVP_PKEY_new(); 939*7b5038d7SDag-Erling Smørgrav if(!k->_key.key) { 940*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 941*7b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 942*7b5038d7SDag-Erling Smørgrav return NULL; 943*7b5038d7SDag-Erling Smørgrav } 944*7b5038d7SDag-Erling Smørgrav if (!EVP_PKEY_assign_EC_KEY(k->_key.key, ec)) { 945*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 946*7b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 947*7b5038d7SDag-Erling Smørgrav return NULL; 948*7b5038d7SDag-Erling Smørgrav } 949*7b5038d7SDag-Erling Smørgrav #endif /* splint */ 950*7b5038d7SDag-Erling Smørgrav #else 951*7b5038d7SDag-Erling Smørgrav ldns_key_free(k); 952*7b5038d7SDag-Erling Smørgrav return NULL; 953*7b5038d7SDag-Erling Smørgrav #endif /* ECDSA */ 954*7b5038d7SDag-Erling Smørgrav break; 955*7b5038d7SDag-Erling Smørgrav } 956*7b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 957*7b5038d7SDag-Erling Smørgrav return k; 958*7b5038d7SDag-Erling Smørgrav } 959*7b5038d7SDag-Erling Smørgrav 960*7b5038d7SDag-Erling Smørgrav void 961*7b5038d7SDag-Erling Smørgrav ldns_key_print(FILE *output, const ldns_key *k) 962*7b5038d7SDag-Erling Smørgrav { 963*7b5038d7SDag-Erling Smørgrav char *str = ldns_key2str(k); 964*7b5038d7SDag-Erling Smørgrav if (str) { 965*7b5038d7SDag-Erling Smørgrav fprintf(output, "%s", str); 966*7b5038d7SDag-Erling Smørgrav } else { 967*7b5038d7SDag-Erling Smørgrav fprintf(output, "Unable to convert private key to string\n"); 968*7b5038d7SDag-Erling Smørgrav } 969*7b5038d7SDag-Erling Smørgrav LDNS_FREE(str); 970*7b5038d7SDag-Erling Smørgrav } 971*7b5038d7SDag-Erling Smørgrav 972*7b5038d7SDag-Erling Smørgrav 973*7b5038d7SDag-Erling Smørgrav void 974*7b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l) 975*7b5038d7SDag-Erling Smørgrav { 976*7b5038d7SDag-Erling Smørgrav k->_alg = l; 977*7b5038d7SDag-Erling Smørgrav } 978*7b5038d7SDag-Erling Smørgrav 979*7b5038d7SDag-Erling Smørgrav void 980*7b5038d7SDag-Erling Smørgrav ldns_key_set_flags(ldns_key *k, uint16_t f) 981*7b5038d7SDag-Erling Smørgrav { 982*7b5038d7SDag-Erling Smørgrav k->_extra.dnssec.flags = f; 983*7b5038d7SDag-Erling Smørgrav } 984*7b5038d7SDag-Erling Smørgrav 985*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 986*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 987*7b5038d7SDag-Erling Smørgrav void 988*7b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e) 989*7b5038d7SDag-Erling Smørgrav { 990*7b5038d7SDag-Erling Smørgrav k->_key.key = e; 991*7b5038d7SDag-Erling Smørgrav } 992*7b5038d7SDag-Erling Smørgrav 993*7b5038d7SDag-Erling Smørgrav void 994*7b5038d7SDag-Erling Smørgrav ldns_key_set_rsa_key(ldns_key *k, RSA *r) 995*7b5038d7SDag-Erling Smørgrav { 996*7b5038d7SDag-Erling Smørgrav EVP_PKEY *key = EVP_PKEY_new(); 997*7b5038d7SDag-Erling Smørgrav EVP_PKEY_set1_RSA(key, r); 998*7b5038d7SDag-Erling Smørgrav k->_key.key = key; 999*7b5038d7SDag-Erling Smørgrav } 1000*7b5038d7SDag-Erling Smørgrav 1001*7b5038d7SDag-Erling Smørgrav void 1002*7b5038d7SDag-Erling Smørgrav ldns_key_set_dsa_key(ldns_key *k, DSA *d) 1003*7b5038d7SDag-Erling Smørgrav { 1004*7b5038d7SDag-Erling Smørgrav EVP_PKEY *key = EVP_PKEY_new(); 1005*7b5038d7SDag-Erling Smørgrav EVP_PKEY_set1_DSA(key, d); 1006*7b5038d7SDag-Erling Smørgrav k->_key.key = key; 1007*7b5038d7SDag-Erling Smørgrav } 1008*7b5038d7SDag-Erling Smørgrav #endif /* splint */ 1009*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 1010*7b5038d7SDag-Erling Smørgrav 1011*7b5038d7SDag-Erling Smørgrav void 1012*7b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac) 1013*7b5038d7SDag-Erling Smørgrav { 1014*7b5038d7SDag-Erling Smørgrav k->_key.hmac.key = hmac; 1015*7b5038d7SDag-Erling Smørgrav } 1016*7b5038d7SDag-Erling Smørgrav 1017*7b5038d7SDag-Erling Smørgrav void 1018*7b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size) 1019*7b5038d7SDag-Erling Smørgrav { 1020*7b5038d7SDag-Erling Smørgrav k->_key.hmac.size = hmac_size; 1021*7b5038d7SDag-Erling Smørgrav } 1022*7b5038d7SDag-Erling Smørgrav 1023*7b5038d7SDag-Erling Smørgrav void 1024*7b5038d7SDag-Erling Smørgrav ldns_key_set_external_key(ldns_key *k, void *external_key) 1025*7b5038d7SDag-Erling Smørgrav { 1026*7b5038d7SDag-Erling Smørgrav k->_key.external_key = external_key; 1027*7b5038d7SDag-Erling Smørgrav } 1028*7b5038d7SDag-Erling Smørgrav 1029*7b5038d7SDag-Erling Smørgrav void 1030*7b5038d7SDag-Erling Smørgrav ldns_key_set_origttl(ldns_key *k, uint32_t t) 1031*7b5038d7SDag-Erling Smørgrav { 1032*7b5038d7SDag-Erling Smørgrav k->_extra.dnssec.orig_ttl = t; 1033*7b5038d7SDag-Erling Smørgrav } 1034*7b5038d7SDag-Erling Smørgrav 1035*7b5038d7SDag-Erling Smørgrav void 1036*7b5038d7SDag-Erling Smørgrav ldns_key_set_inception(ldns_key *k, uint32_t i) 1037*7b5038d7SDag-Erling Smørgrav { 1038*7b5038d7SDag-Erling Smørgrav k->_extra.dnssec.inception = i; 1039*7b5038d7SDag-Erling Smørgrav } 1040*7b5038d7SDag-Erling Smørgrav 1041*7b5038d7SDag-Erling Smørgrav void 1042*7b5038d7SDag-Erling Smørgrav ldns_key_set_expiration(ldns_key *k, uint32_t e) 1043*7b5038d7SDag-Erling Smørgrav { 1044*7b5038d7SDag-Erling Smørgrav k->_extra.dnssec.expiration = e; 1045*7b5038d7SDag-Erling Smørgrav } 1046*7b5038d7SDag-Erling Smørgrav 1047*7b5038d7SDag-Erling Smørgrav void 1048*7b5038d7SDag-Erling Smørgrav ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r) 1049*7b5038d7SDag-Erling Smørgrav { 1050*7b5038d7SDag-Erling Smørgrav k->_pubkey_owner = r; 1051*7b5038d7SDag-Erling Smørgrav } 1052*7b5038d7SDag-Erling Smørgrav 1053*7b5038d7SDag-Erling Smørgrav void 1054*7b5038d7SDag-Erling Smørgrav ldns_key_set_keytag(ldns_key *k, uint16_t tag) 1055*7b5038d7SDag-Erling Smørgrav { 1056*7b5038d7SDag-Erling Smørgrav k->_extra.dnssec.keytag = tag; 1057*7b5038d7SDag-Erling Smørgrav } 1058*7b5038d7SDag-Erling Smørgrav 1059*7b5038d7SDag-Erling Smørgrav /* read */ 1060*7b5038d7SDag-Erling Smørgrav size_t 1061*7b5038d7SDag-Erling Smørgrav ldns_key_list_key_count(const ldns_key_list *key_list) 1062*7b5038d7SDag-Erling Smørgrav { 1063*7b5038d7SDag-Erling Smørgrav return key_list->_key_count; 1064*7b5038d7SDag-Erling Smørgrav } 1065*7b5038d7SDag-Erling Smørgrav 1066*7b5038d7SDag-Erling Smørgrav ldns_key * 1067*7b5038d7SDag-Erling Smørgrav ldns_key_list_key(const ldns_key_list *key, size_t nr) 1068*7b5038d7SDag-Erling Smørgrav { 1069*7b5038d7SDag-Erling Smørgrav if (nr < ldns_key_list_key_count(key)) { 1070*7b5038d7SDag-Erling Smørgrav return key->_keys[nr]; 1071*7b5038d7SDag-Erling Smørgrav } else { 1072*7b5038d7SDag-Erling Smørgrav return NULL; 1073*7b5038d7SDag-Erling Smørgrav } 1074*7b5038d7SDag-Erling Smørgrav } 1075*7b5038d7SDag-Erling Smørgrav 1076*7b5038d7SDag-Erling Smørgrav ldns_signing_algorithm 1077*7b5038d7SDag-Erling Smørgrav ldns_key_algorithm(const ldns_key *k) 1078*7b5038d7SDag-Erling Smørgrav { 1079*7b5038d7SDag-Erling Smørgrav return k->_alg; 1080*7b5038d7SDag-Erling Smørgrav } 1081*7b5038d7SDag-Erling Smørgrav 1082*7b5038d7SDag-Erling Smørgrav void 1083*7b5038d7SDag-Erling Smørgrav ldns_key_set_use(ldns_key *k, bool v) 1084*7b5038d7SDag-Erling Smørgrav { 1085*7b5038d7SDag-Erling Smørgrav if (k) { 1086*7b5038d7SDag-Erling Smørgrav k->_use = v; 1087*7b5038d7SDag-Erling Smørgrav } 1088*7b5038d7SDag-Erling Smørgrav } 1089*7b5038d7SDag-Erling Smørgrav 1090*7b5038d7SDag-Erling Smørgrav bool 1091*7b5038d7SDag-Erling Smørgrav ldns_key_use(const ldns_key *k) 1092*7b5038d7SDag-Erling Smørgrav { 1093*7b5038d7SDag-Erling Smørgrav if (k) { 1094*7b5038d7SDag-Erling Smørgrav return k->_use; 1095*7b5038d7SDag-Erling Smørgrav } 1096*7b5038d7SDag-Erling Smørgrav return false; 1097*7b5038d7SDag-Erling Smørgrav } 1098*7b5038d7SDag-Erling Smørgrav 1099*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 1100*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 1101*7b5038d7SDag-Erling Smørgrav EVP_PKEY * 1102*7b5038d7SDag-Erling Smørgrav ldns_key_evp_key(const ldns_key *k) 1103*7b5038d7SDag-Erling Smørgrav { 1104*7b5038d7SDag-Erling Smørgrav return k->_key.key; 1105*7b5038d7SDag-Erling Smørgrav } 1106*7b5038d7SDag-Erling Smørgrav 1107*7b5038d7SDag-Erling Smørgrav RSA * 1108*7b5038d7SDag-Erling Smørgrav ldns_key_rsa_key(const ldns_key *k) 1109*7b5038d7SDag-Erling Smørgrav { 1110*7b5038d7SDag-Erling Smørgrav if (k->_key.key) { 1111*7b5038d7SDag-Erling Smørgrav return EVP_PKEY_get1_RSA(k->_key.key); 1112*7b5038d7SDag-Erling Smørgrav } else { 1113*7b5038d7SDag-Erling Smørgrav return NULL; 1114*7b5038d7SDag-Erling Smørgrav } 1115*7b5038d7SDag-Erling Smørgrav } 1116*7b5038d7SDag-Erling Smørgrav 1117*7b5038d7SDag-Erling Smørgrav DSA * 1118*7b5038d7SDag-Erling Smørgrav ldns_key_dsa_key(const ldns_key *k) 1119*7b5038d7SDag-Erling Smørgrav { 1120*7b5038d7SDag-Erling Smørgrav if (k->_key.key) { 1121*7b5038d7SDag-Erling Smørgrav return EVP_PKEY_get1_DSA(k->_key.key); 1122*7b5038d7SDag-Erling Smørgrav } else { 1123*7b5038d7SDag-Erling Smørgrav return NULL; 1124*7b5038d7SDag-Erling Smørgrav } 1125*7b5038d7SDag-Erling Smørgrav } 1126*7b5038d7SDag-Erling Smørgrav #endif /* splint */ 1127*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 1128*7b5038d7SDag-Erling Smørgrav 1129*7b5038d7SDag-Erling Smørgrav unsigned char * 1130*7b5038d7SDag-Erling Smørgrav ldns_key_hmac_key(const ldns_key *k) 1131*7b5038d7SDag-Erling Smørgrav { 1132*7b5038d7SDag-Erling Smørgrav if (k->_key.hmac.key) { 1133*7b5038d7SDag-Erling Smørgrav return k->_key.hmac.key; 1134*7b5038d7SDag-Erling Smørgrav } else { 1135*7b5038d7SDag-Erling Smørgrav return NULL; 1136*7b5038d7SDag-Erling Smørgrav } 1137*7b5038d7SDag-Erling Smørgrav } 1138*7b5038d7SDag-Erling Smørgrav 1139*7b5038d7SDag-Erling Smørgrav size_t 1140*7b5038d7SDag-Erling Smørgrav ldns_key_hmac_size(const ldns_key *k) 1141*7b5038d7SDag-Erling Smørgrav { 1142*7b5038d7SDag-Erling Smørgrav if (k->_key.hmac.size) { 1143*7b5038d7SDag-Erling Smørgrav return k->_key.hmac.size; 1144*7b5038d7SDag-Erling Smørgrav } else { 1145*7b5038d7SDag-Erling Smørgrav return 0; 1146*7b5038d7SDag-Erling Smørgrav } 1147*7b5038d7SDag-Erling Smørgrav } 1148*7b5038d7SDag-Erling Smørgrav 1149*7b5038d7SDag-Erling Smørgrav void * 1150*7b5038d7SDag-Erling Smørgrav ldns_key_external_key(const ldns_key *k) 1151*7b5038d7SDag-Erling Smørgrav { 1152*7b5038d7SDag-Erling Smørgrav return k->_key.external_key; 1153*7b5038d7SDag-Erling Smørgrav } 1154*7b5038d7SDag-Erling Smørgrav 1155*7b5038d7SDag-Erling Smørgrav uint32_t 1156*7b5038d7SDag-Erling Smørgrav ldns_key_origttl(const ldns_key *k) 1157*7b5038d7SDag-Erling Smørgrav { 1158*7b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.orig_ttl; 1159*7b5038d7SDag-Erling Smørgrav } 1160*7b5038d7SDag-Erling Smørgrav 1161*7b5038d7SDag-Erling Smørgrav uint16_t 1162*7b5038d7SDag-Erling Smørgrav ldns_key_flags(const ldns_key *k) 1163*7b5038d7SDag-Erling Smørgrav { 1164*7b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.flags; 1165*7b5038d7SDag-Erling Smørgrav } 1166*7b5038d7SDag-Erling Smørgrav 1167*7b5038d7SDag-Erling Smørgrav uint32_t 1168*7b5038d7SDag-Erling Smørgrav ldns_key_inception(const ldns_key *k) 1169*7b5038d7SDag-Erling Smørgrav { 1170*7b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.inception; 1171*7b5038d7SDag-Erling Smørgrav } 1172*7b5038d7SDag-Erling Smørgrav 1173*7b5038d7SDag-Erling Smørgrav uint32_t 1174*7b5038d7SDag-Erling Smørgrav ldns_key_expiration(const ldns_key *k) 1175*7b5038d7SDag-Erling Smørgrav { 1176*7b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.expiration; 1177*7b5038d7SDag-Erling Smørgrav } 1178*7b5038d7SDag-Erling Smørgrav 1179*7b5038d7SDag-Erling Smørgrav uint16_t 1180*7b5038d7SDag-Erling Smørgrav ldns_key_keytag(const ldns_key *k) 1181*7b5038d7SDag-Erling Smørgrav { 1182*7b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.keytag; 1183*7b5038d7SDag-Erling Smørgrav } 1184*7b5038d7SDag-Erling Smørgrav 1185*7b5038d7SDag-Erling Smørgrav ldns_rdf * 1186*7b5038d7SDag-Erling Smørgrav ldns_key_pubkey_owner(const ldns_key *k) 1187*7b5038d7SDag-Erling Smørgrav { 1188*7b5038d7SDag-Erling Smørgrav return k->_pubkey_owner; 1189*7b5038d7SDag-Erling Smørgrav } 1190*7b5038d7SDag-Erling Smørgrav 1191*7b5038d7SDag-Erling Smørgrav /* write */ 1192*7b5038d7SDag-Erling Smørgrav void 1193*7b5038d7SDag-Erling Smørgrav ldns_key_list_set_use(ldns_key_list *keys, bool v) 1194*7b5038d7SDag-Erling Smørgrav { 1195*7b5038d7SDag-Erling Smørgrav size_t i; 1196*7b5038d7SDag-Erling Smørgrav 1197*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_key_list_key_count(keys); i++) { 1198*7b5038d7SDag-Erling Smørgrav ldns_key_set_use(ldns_key_list_key(keys, i), v); 1199*7b5038d7SDag-Erling Smørgrav } 1200*7b5038d7SDag-Erling Smørgrav } 1201*7b5038d7SDag-Erling Smørgrav 1202*7b5038d7SDag-Erling Smørgrav void 1203*7b5038d7SDag-Erling Smørgrav ldns_key_list_set_key_count(ldns_key_list *key, size_t count) 1204*7b5038d7SDag-Erling Smørgrav { 1205*7b5038d7SDag-Erling Smørgrav key->_key_count = count; 1206*7b5038d7SDag-Erling Smørgrav } 1207*7b5038d7SDag-Erling Smørgrav 1208*7b5038d7SDag-Erling Smørgrav bool 1209*7b5038d7SDag-Erling Smørgrav ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key) 1210*7b5038d7SDag-Erling Smørgrav { 1211*7b5038d7SDag-Erling Smørgrav size_t key_count; 1212*7b5038d7SDag-Erling Smørgrav ldns_key **keys; 1213*7b5038d7SDag-Erling Smørgrav 1214*7b5038d7SDag-Erling Smørgrav key_count = ldns_key_list_key_count(key_list); 1215*7b5038d7SDag-Erling Smørgrav 1216*7b5038d7SDag-Erling Smørgrav /* grow the array */ 1217*7b5038d7SDag-Erling Smørgrav keys = LDNS_XREALLOC( 1218*7b5038d7SDag-Erling Smørgrav key_list->_keys, ldns_key *, key_count + 1); 1219*7b5038d7SDag-Erling Smørgrav if (!keys) { 1220*7b5038d7SDag-Erling Smørgrav return false; 1221*7b5038d7SDag-Erling Smørgrav } 1222*7b5038d7SDag-Erling Smørgrav 1223*7b5038d7SDag-Erling Smørgrav /* add the new member */ 1224*7b5038d7SDag-Erling Smørgrav key_list->_keys = keys; 1225*7b5038d7SDag-Erling Smørgrav key_list->_keys[key_count] = key; 1226*7b5038d7SDag-Erling Smørgrav 1227*7b5038d7SDag-Erling Smørgrav ldns_key_list_set_key_count(key_list, key_count + 1); 1228*7b5038d7SDag-Erling Smørgrav return true; 1229*7b5038d7SDag-Erling Smørgrav } 1230*7b5038d7SDag-Erling Smørgrav 1231*7b5038d7SDag-Erling Smørgrav ldns_key * 1232*7b5038d7SDag-Erling Smørgrav ldns_key_list_pop_key(ldns_key_list *key_list) 1233*7b5038d7SDag-Erling Smørgrav { 1234*7b5038d7SDag-Erling Smørgrav size_t key_count; 1235*7b5038d7SDag-Erling Smørgrav ldns_key** a; 1236*7b5038d7SDag-Erling Smørgrav ldns_key *pop; 1237*7b5038d7SDag-Erling Smørgrav 1238*7b5038d7SDag-Erling Smørgrav if (!key_list) { 1239*7b5038d7SDag-Erling Smørgrav return NULL; 1240*7b5038d7SDag-Erling Smørgrav } 1241*7b5038d7SDag-Erling Smørgrav 1242*7b5038d7SDag-Erling Smørgrav key_count = ldns_key_list_key_count(key_list); 1243*7b5038d7SDag-Erling Smørgrav if (key_count == 0) { 1244*7b5038d7SDag-Erling Smørgrav return NULL; 1245*7b5038d7SDag-Erling Smørgrav } 1246*7b5038d7SDag-Erling Smørgrav 1247*7b5038d7SDag-Erling Smørgrav pop = ldns_key_list_key(key_list, key_count); 1248*7b5038d7SDag-Erling Smørgrav 1249*7b5038d7SDag-Erling Smørgrav /* shrink the array */ 1250*7b5038d7SDag-Erling Smørgrav a = LDNS_XREALLOC(key_list->_keys, ldns_key *, key_count - 1); 1251*7b5038d7SDag-Erling Smørgrav if(a) { 1252*7b5038d7SDag-Erling Smørgrav key_list->_keys = a; 1253*7b5038d7SDag-Erling Smørgrav } 1254*7b5038d7SDag-Erling Smørgrav 1255*7b5038d7SDag-Erling Smørgrav ldns_key_list_set_key_count(key_list, key_count - 1); 1256*7b5038d7SDag-Erling Smørgrav 1257*7b5038d7SDag-Erling Smørgrav return pop; 1258*7b5038d7SDag-Erling Smørgrav } 1259*7b5038d7SDag-Erling Smørgrav 1260*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 1261*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 1262*7b5038d7SDag-Erling Smørgrav /* data pointer must be large enough (LDNS_MAX_KEYLEN) */ 1263*7b5038d7SDag-Erling Smørgrav static bool 1264*7b5038d7SDag-Erling Smørgrav ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size) 1265*7b5038d7SDag-Erling Smørgrav { 1266*7b5038d7SDag-Erling Smørgrav int i,j; 1267*7b5038d7SDag-Erling Smørgrav 1268*7b5038d7SDag-Erling Smørgrav if (!k) { 1269*7b5038d7SDag-Erling Smørgrav return false; 1270*7b5038d7SDag-Erling Smørgrav } 1271*7b5038d7SDag-Erling Smørgrav 1272*7b5038d7SDag-Erling Smørgrav if (BN_num_bytes(k->e) <= 256) { 1273*7b5038d7SDag-Erling Smørgrav /* normally only this path is executed (small factors are 1274*7b5038d7SDag-Erling Smørgrav * more common 1275*7b5038d7SDag-Erling Smørgrav */ 1276*7b5038d7SDag-Erling Smørgrav data[0] = (unsigned char) BN_num_bytes(k->e); 1277*7b5038d7SDag-Erling Smørgrav i = BN_bn2bin(k->e, data + 1); 1278*7b5038d7SDag-Erling Smørgrav j = BN_bn2bin(k->n, data + i + 1); 1279*7b5038d7SDag-Erling Smørgrav *size = (uint16_t) i + j; 1280*7b5038d7SDag-Erling Smørgrav } else if (BN_num_bytes(k->e) <= 65536) { 1281*7b5038d7SDag-Erling Smørgrav data[0] = 0; 1282*7b5038d7SDag-Erling Smørgrav /* BN_bn2bin does bigendian, _uint16 also */ 1283*7b5038d7SDag-Erling Smørgrav ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(k->e)); 1284*7b5038d7SDag-Erling Smørgrav 1285*7b5038d7SDag-Erling Smørgrav BN_bn2bin(k->e, data + 3); 1286*7b5038d7SDag-Erling Smørgrav BN_bn2bin(k->n, data + 4 + BN_num_bytes(k->e)); 1287*7b5038d7SDag-Erling Smørgrav *size = (uint16_t) BN_num_bytes(k->n) + 6; 1288*7b5038d7SDag-Erling Smørgrav } else { 1289*7b5038d7SDag-Erling Smørgrav return false; 1290*7b5038d7SDag-Erling Smørgrav } 1291*7b5038d7SDag-Erling Smørgrav return true; 1292*7b5038d7SDag-Erling Smørgrav } 1293*7b5038d7SDag-Erling Smørgrav 1294*7b5038d7SDag-Erling Smørgrav /* data pointer must be large enough (LDNS_MAX_KEYLEN) */ 1295*7b5038d7SDag-Erling Smørgrav static bool 1296*7b5038d7SDag-Erling Smørgrav ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size) 1297*7b5038d7SDag-Erling Smørgrav { 1298*7b5038d7SDag-Erling Smørgrav uint8_t T; 1299*7b5038d7SDag-Erling Smørgrav 1300*7b5038d7SDag-Erling Smørgrav if (!k) { 1301*7b5038d7SDag-Erling Smørgrav return false; 1302*7b5038d7SDag-Erling Smørgrav } 1303*7b5038d7SDag-Erling Smørgrav 1304*7b5038d7SDag-Erling Smørgrav /* See RFC2536 */ 1305*7b5038d7SDag-Erling Smørgrav *size = (uint16_t)BN_num_bytes(k->g); 1306*7b5038d7SDag-Erling Smørgrav T = (*size - 64) / 8; 1307*7b5038d7SDag-Erling Smørgrav memcpy(data, &T, 1); 1308*7b5038d7SDag-Erling Smørgrav 1309*7b5038d7SDag-Erling Smørgrav if (T > 8) { 1310*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)"); 1311*7b5038d7SDag-Erling Smørgrav fprintf(stderr, " not implemented\n"); 1312*7b5038d7SDag-Erling Smørgrav return false; 1313*7b5038d7SDag-Erling Smørgrav } 1314*7b5038d7SDag-Erling Smørgrav 1315*7b5038d7SDag-Erling Smørgrav /* size = 64 + (T * 8); */ 1316*7b5038d7SDag-Erling Smørgrav data[0] = (unsigned char)T; 1317*7b5038d7SDag-Erling Smørgrav BN_bn2bin(k->q, data + 1 ); /* 20 octects */ 1318*7b5038d7SDag-Erling Smørgrav BN_bn2bin(k->p, data + 21 ); /* offset octects */ 1319*7b5038d7SDag-Erling Smørgrav BN_bn2bin(k->g, data + 21 + *size); /* offset octets */ 1320*7b5038d7SDag-Erling Smørgrav BN_bn2bin(k->pub_key, data + 21 + *size + *size); /* offset octets */ 1321*7b5038d7SDag-Erling Smørgrav *size = 21 + (*size * 3); 1322*7b5038d7SDag-Erling Smørgrav return true; 1323*7b5038d7SDag-Erling Smørgrav } 1324*7b5038d7SDag-Erling Smørgrav 1325*7b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 1326*7b5038d7SDag-Erling Smørgrav static bool 1327*7b5038d7SDag-Erling Smørgrav ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size) 1328*7b5038d7SDag-Erling Smørgrav { 1329*7b5038d7SDag-Erling Smørgrav int i; 1330*7b5038d7SDag-Erling Smørgrav unsigned char* pp = NULL; 1331*7b5038d7SDag-Erling Smørgrav if(i2d_PUBKEY(k, &pp) != 37 + 64) { 1332*7b5038d7SDag-Erling Smørgrav /* expect 37 byte(ASN header) and 64 byte(X and Y) */ 1333*7b5038d7SDag-Erling Smørgrav CRYPTO_free(pp); 1334*7b5038d7SDag-Erling Smørgrav return false; 1335*7b5038d7SDag-Erling Smørgrav } 1336*7b5038d7SDag-Erling Smørgrav /* omit ASN header */ 1337*7b5038d7SDag-Erling Smørgrav for(i=0; i<64; i++) 1338*7b5038d7SDag-Erling Smørgrav data[i] = pp[i+37]; 1339*7b5038d7SDag-Erling Smørgrav CRYPTO_free(pp); 1340*7b5038d7SDag-Erling Smørgrav *size = 64; 1341*7b5038d7SDag-Erling Smørgrav return true; 1342*7b5038d7SDag-Erling Smørgrav } 1343*7b5038d7SDag-Erling Smørgrav #endif /* USE_GOST */ 1344*7b5038d7SDag-Erling Smørgrav #endif /* splint */ 1345*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 1346*7b5038d7SDag-Erling Smørgrav 1347*7b5038d7SDag-Erling Smørgrav ldns_rr * 1348*7b5038d7SDag-Erling Smørgrav ldns_key2rr(const ldns_key *k) 1349*7b5038d7SDag-Erling Smørgrav { 1350*7b5038d7SDag-Erling Smørgrav /* this function will convert a the keydata contained in 1351*7b5038d7SDag-Erling Smørgrav * rsa/dsa pointers to a DNSKEY rr. It will fill in as 1352*7b5038d7SDag-Erling Smørgrav * much as it can, but it does not know about key-flags 1353*7b5038d7SDag-Erling Smørgrav * for instance 1354*7b5038d7SDag-Erling Smørgrav */ 1355*7b5038d7SDag-Erling Smørgrav ldns_rr *pubkey; 1356*7b5038d7SDag-Erling Smørgrav ldns_rdf *keybin; 1357*7b5038d7SDag-Erling Smørgrav unsigned char *bin = NULL; 1358*7b5038d7SDag-Erling Smørgrav uint16_t size = 0; 1359*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 1360*7b5038d7SDag-Erling Smørgrav RSA *rsa = NULL; 1361*7b5038d7SDag-Erling Smørgrav DSA *dsa = NULL; 1362*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 1363*7b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 1364*7b5038d7SDag-Erling Smørgrav EC_KEY* ec; 1365*7b5038d7SDag-Erling Smørgrav #endif 1366*7b5038d7SDag-Erling Smørgrav int internal_data = 0; 1367*7b5038d7SDag-Erling Smørgrav 1368*7b5038d7SDag-Erling Smørgrav pubkey = ldns_rr_new(); 1369*7b5038d7SDag-Erling Smørgrav if (!k) { 1370*7b5038d7SDag-Erling Smørgrav return NULL; 1371*7b5038d7SDag-Erling Smørgrav } 1372*7b5038d7SDag-Erling Smørgrav 1373*7b5038d7SDag-Erling Smørgrav switch (ldns_key_algorithm(k)) { 1374*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACMD5: 1375*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA1: 1376*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA256: 1377*7b5038d7SDag-Erling Smørgrav ldns_rr_set_type(pubkey, LDNS_RR_TYPE_KEY); 1378*7b5038d7SDag-Erling Smørgrav break; 1379*7b5038d7SDag-Erling Smørgrav default: 1380*7b5038d7SDag-Erling Smørgrav ldns_rr_set_type(pubkey, LDNS_RR_TYPE_DNSKEY); 1381*7b5038d7SDag-Erling Smørgrav break; 1382*7b5038d7SDag-Erling Smørgrav } 1383*7b5038d7SDag-Erling Smørgrav /* zero-th rdf - flags */ 1384*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 1385*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, 1386*7b5038d7SDag-Erling Smørgrav ldns_key_flags(k))); 1387*7b5038d7SDag-Erling Smørgrav /* first - proto */ 1388*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 1389*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, LDNS_DNSSEC_KEYPROTO)); 1390*7b5038d7SDag-Erling Smørgrav 1391*7b5038d7SDag-Erling Smørgrav if (ldns_key_pubkey_owner(k)) { 1392*7b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(pubkey, ldns_rdf_clone(ldns_key_pubkey_owner(k))); 1393*7b5038d7SDag-Erling Smørgrav } 1394*7b5038d7SDag-Erling Smørgrav 1395*7b5038d7SDag-Erling Smørgrav /* third - da algorithm */ 1396*7b5038d7SDag-Erling Smørgrav switch(ldns_key_algorithm(k)) { 1397*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSAMD5: 1398*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1: 1399*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1_NSEC3: 1400*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA256: 1401*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA512: 1402*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 1403*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); 1404*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 1405*7b5038d7SDag-Erling Smørgrav rsa = ldns_key_rsa_key(k); 1406*7b5038d7SDag-Erling Smørgrav if (rsa) { 1407*7b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 1408*7b5038d7SDag-Erling Smørgrav if (!bin) { 1409*7b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 1410*7b5038d7SDag-Erling Smørgrav return NULL; 1411*7b5038d7SDag-Erling Smørgrav } 1412*7b5038d7SDag-Erling Smørgrav if (!ldns_key_rsa2bin(bin, rsa, &size)) { 1413*7b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 1414*7b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 1415*7b5038d7SDag-Erling Smørgrav return NULL; 1416*7b5038d7SDag-Erling Smørgrav } 1417*7b5038d7SDag-Erling Smørgrav RSA_free(rsa); 1418*7b5038d7SDag-Erling Smørgrav internal_data = 1; 1419*7b5038d7SDag-Erling Smørgrav } 1420*7b5038d7SDag-Erling Smørgrav #endif 1421*7b5038d7SDag-Erling Smørgrav size++; 1422*7b5038d7SDag-Erling Smørgrav break; 1423*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA: 1424*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 1425*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA)); 1426*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 1427*7b5038d7SDag-Erling Smørgrav dsa = ldns_key_dsa_key(k); 1428*7b5038d7SDag-Erling Smørgrav if (dsa) { 1429*7b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 1430*7b5038d7SDag-Erling Smørgrav if (!bin) { 1431*7b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 1432*7b5038d7SDag-Erling Smørgrav return NULL; 1433*7b5038d7SDag-Erling Smørgrav } 1434*7b5038d7SDag-Erling Smørgrav if (!ldns_key_dsa2bin(bin, dsa, &size)) { 1435*7b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 1436*7b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 1437*7b5038d7SDag-Erling Smørgrav return NULL; 1438*7b5038d7SDag-Erling Smørgrav } 1439*7b5038d7SDag-Erling Smørgrav DSA_free(dsa); 1440*7b5038d7SDag-Erling Smørgrav internal_data = 1; 1441*7b5038d7SDag-Erling Smørgrav } 1442*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 1443*7b5038d7SDag-Erling Smørgrav break; 1444*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA_NSEC3: 1445*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 1446*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3)); 1447*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 1448*7b5038d7SDag-Erling Smørgrav dsa = ldns_key_dsa_key(k); 1449*7b5038d7SDag-Erling Smørgrav if (dsa) { 1450*7b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 1451*7b5038d7SDag-Erling Smørgrav if (!bin) { 1452*7b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 1453*7b5038d7SDag-Erling Smørgrav return NULL; 1454*7b5038d7SDag-Erling Smørgrav } 1455*7b5038d7SDag-Erling Smørgrav if (!ldns_key_dsa2bin(bin, dsa, &size)) { 1456*7b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 1457*7b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 1458*7b5038d7SDag-Erling Smørgrav return NULL; 1459*7b5038d7SDag-Erling Smørgrav } 1460*7b5038d7SDag-Erling Smørgrav DSA_free(dsa); 1461*7b5038d7SDag-Erling Smørgrav internal_data = 1; 1462*7b5038d7SDag-Erling Smørgrav } 1463*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 1464*7b5038d7SDag-Erling Smørgrav break; 1465*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECC_GOST: 1466*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( 1467*7b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); 1468*7b5038d7SDag-Erling Smørgrav #if defined(HAVE_SSL) && defined(USE_GOST) 1469*7b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 1470*7b5038d7SDag-Erling Smørgrav if (!bin) { 1471*7b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 1472*7b5038d7SDag-Erling Smørgrav return NULL; 1473*7b5038d7SDag-Erling Smørgrav } 1474*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 1475*7b5038d7SDag-Erling Smørgrav if (!ldns_key_gost2bin(bin, k->_key.key, &size)) { 1476*7b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 1477*7b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 1478*7b5038d7SDag-Erling Smørgrav return NULL; 1479*7b5038d7SDag-Erling Smørgrav } 1480*7b5038d7SDag-Erling Smørgrav #endif /* splint */ 1481*7b5038d7SDag-Erling Smørgrav internal_data = 1; 1482*7b5038d7SDag-Erling Smørgrav #else 1483*7b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 1484*7b5038d7SDag-Erling Smørgrav return NULL; 1485*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL and USE_GOST */ 1486*7b5038d7SDag-Erling Smørgrav break; 1487*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP256SHA256: 1488*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP384SHA384: 1489*7b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 1490*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( 1491*7b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); 1492*7b5038d7SDag-Erling Smørgrav bin = NULL; 1493*7b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 1494*7b5038d7SDag-Erling Smørgrav ec = EVP_PKEY_get1_EC_KEY(k->_key.key); 1495*7b5038d7SDag-Erling Smørgrav #endif 1496*7b5038d7SDag-Erling Smørgrav EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); 1497*7b5038d7SDag-Erling Smørgrav size = (uint16_t)i2o_ECPublicKey(ec, NULL); 1498*7b5038d7SDag-Erling Smørgrav if(!i2o_ECPublicKey(ec, &bin)) { 1499*7b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 1500*7b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 1501*7b5038d7SDag-Erling Smørgrav return NULL; 1502*7b5038d7SDag-Erling Smørgrav } 1503*7b5038d7SDag-Erling Smørgrav if(size > 1) { 1504*7b5038d7SDag-Erling Smørgrav /* move back one byte to shave off the 0x02 1505*7b5038d7SDag-Erling Smørgrav * 'uncompressed' indicator that openssl made 1506*7b5038d7SDag-Erling Smørgrav * Actually its 0x04 (from implementation). 1507*7b5038d7SDag-Erling Smørgrav */ 1508*7b5038d7SDag-Erling Smørgrav assert(bin[0] == POINT_CONVERSION_UNCOMPRESSED); 1509*7b5038d7SDag-Erling Smørgrav size -= 1; 1510*7b5038d7SDag-Erling Smørgrav memmove(bin, bin+1, size); 1511*7b5038d7SDag-Erling Smørgrav } 1512*7b5038d7SDag-Erling Smørgrav /* down the reference count for ec, its still assigned 1513*7b5038d7SDag-Erling Smørgrav * to the pkey */ 1514*7b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 1515*7b5038d7SDag-Erling Smørgrav internal_data = 1; 1516*7b5038d7SDag-Erling Smørgrav #else 1517*7b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 1518*7b5038d7SDag-Erling Smørgrav return NULL; 1519*7b5038d7SDag-Erling Smørgrav #endif /* ECDSA */ 1520*7b5038d7SDag-Erling Smørgrav break; 1521*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACMD5: 1522*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA1: 1523*7b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA256: 1524*7b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k)); 1525*7b5038d7SDag-Erling Smørgrav if (!bin) { 1526*7b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 1527*7b5038d7SDag-Erling Smørgrav return NULL; 1528*7b5038d7SDag-Erling Smørgrav } 1529*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 1530*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, 1531*7b5038d7SDag-Erling Smørgrav ldns_key_algorithm(k))); 1532*7b5038d7SDag-Erling Smørgrav size = ldns_key_hmac_size(k); 1533*7b5038d7SDag-Erling Smørgrav memcpy(bin, ldns_key_hmac_key(k), size); 1534*7b5038d7SDag-Erling Smørgrav internal_data = 1; 1535*7b5038d7SDag-Erling Smørgrav break; 1536*7b5038d7SDag-Erling Smørgrav } 1537*7b5038d7SDag-Erling Smørgrav /* fourth the key bin material */ 1538*7b5038d7SDag-Erling Smørgrav if (internal_data) { 1539*7b5038d7SDag-Erling Smørgrav keybin = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, size, bin); 1540*7b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 1541*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, keybin); 1542*7b5038d7SDag-Erling Smørgrav } 1543*7b5038d7SDag-Erling Smørgrav return pubkey; 1544*7b5038d7SDag-Erling Smørgrav } 1545*7b5038d7SDag-Erling Smørgrav 1546*7b5038d7SDag-Erling Smørgrav void 1547*7b5038d7SDag-Erling Smørgrav ldns_key_free(ldns_key *key) 1548*7b5038d7SDag-Erling Smørgrav { 1549*7b5038d7SDag-Erling Smørgrav LDNS_FREE(key); 1550*7b5038d7SDag-Erling Smørgrav } 1551*7b5038d7SDag-Erling Smørgrav 1552*7b5038d7SDag-Erling Smørgrav void 1553*7b5038d7SDag-Erling Smørgrav ldns_key_deep_free(ldns_key *key) 1554*7b5038d7SDag-Erling Smørgrav { 1555*7b5038d7SDag-Erling Smørgrav unsigned char* hmac; 1556*7b5038d7SDag-Erling Smørgrav if (ldns_key_pubkey_owner(key)) { 1557*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(ldns_key_pubkey_owner(key)); 1558*7b5038d7SDag-Erling Smørgrav } 1559*7b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 1560*7b5038d7SDag-Erling Smørgrav if (ldns_key_evp_key(key)) { 1561*7b5038d7SDag-Erling Smørgrav EVP_PKEY_free(ldns_key_evp_key(key)); 1562*7b5038d7SDag-Erling Smørgrav } 1563*7b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 1564*7b5038d7SDag-Erling Smørgrav if (ldns_key_hmac_key(key)) { 1565*7b5038d7SDag-Erling Smørgrav hmac = ldns_key_hmac_key(key); 1566*7b5038d7SDag-Erling Smørgrav LDNS_FREE(hmac); 1567*7b5038d7SDag-Erling Smørgrav } 1568*7b5038d7SDag-Erling Smørgrav LDNS_FREE(key); 1569*7b5038d7SDag-Erling Smørgrav } 1570*7b5038d7SDag-Erling Smørgrav 1571*7b5038d7SDag-Erling Smørgrav void 1572*7b5038d7SDag-Erling Smørgrav ldns_key_list_free(ldns_key_list *key_list) 1573*7b5038d7SDag-Erling Smørgrav { 1574*7b5038d7SDag-Erling Smørgrav size_t i; 1575*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_key_list_key_count(key_list); i++) { 1576*7b5038d7SDag-Erling Smørgrav ldns_key_deep_free(ldns_key_list_key(key_list, i)); 1577*7b5038d7SDag-Erling Smørgrav } 1578*7b5038d7SDag-Erling Smørgrav LDNS_FREE(key_list->_keys); 1579*7b5038d7SDag-Erling Smørgrav LDNS_FREE(key_list); 1580*7b5038d7SDag-Erling Smørgrav } 1581*7b5038d7SDag-Erling Smørgrav 1582*7b5038d7SDag-Erling Smørgrav ldns_rr * 1583*7b5038d7SDag-Erling Smørgrav ldns_read_anchor_file(const char *filename) 1584*7b5038d7SDag-Erling Smørgrav { 1585*7b5038d7SDag-Erling Smørgrav FILE *fp; 1586*7b5038d7SDag-Erling Smørgrav /*char line[LDNS_MAX_PACKETLEN];*/ 1587*7b5038d7SDag-Erling Smørgrav char *line = LDNS_XMALLOC(char, LDNS_MAX_PACKETLEN); 1588*7b5038d7SDag-Erling Smørgrav int c; 1589*7b5038d7SDag-Erling Smørgrav size_t i = 0; 1590*7b5038d7SDag-Erling Smørgrav ldns_rr *r; 1591*7b5038d7SDag-Erling Smørgrav ldns_status status; 1592*7b5038d7SDag-Erling Smørgrav if(!line) { 1593*7b5038d7SDag-Erling Smørgrav return NULL; 1594*7b5038d7SDag-Erling Smørgrav } 1595*7b5038d7SDag-Erling Smørgrav 1596*7b5038d7SDag-Erling Smørgrav fp = fopen(filename, "r"); 1597*7b5038d7SDag-Erling Smørgrav if (!fp) { 1598*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno)); 1599*7b5038d7SDag-Erling Smørgrav LDNS_FREE(line); 1600*7b5038d7SDag-Erling Smørgrav return NULL; 1601*7b5038d7SDag-Erling Smørgrav } 1602*7b5038d7SDag-Erling Smørgrav 1603*7b5038d7SDag-Erling Smørgrav while ((c = fgetc(fp)) && i+1 < LDNS_MAX_PACKETLEN && c != EOF) { 1604*7b5038d7SDag-Erling Smørgrav line[i] = c; 1605*7b5038d7SDag-Erling Smørgrav i++; 1606*7b5038d7SDag-Erling Smørgrav } 1607*7b5038d7SDag-Erling Smørgrav line[i] = '\0'; 1608*7b5038d7SDag-Erling Smørgrav 1609*7b5038d7SDag-Erling Smørgrav fclose(fp); 1610*7b5038d7SDag-Erling Smørgrav 1611*7b5038d7SDag-Erling Smørgrav if (i <= 0) { 1612*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "nothing read from %s", filename); 1613*7b5038d7SDag-Erling Smørgrav LDNS_FREE(line); 1614*7b5038d7SDag-Erling Smørgrav return NULL; 1615*7b5038d7SDag-Erling Smørgrav } else { 1616*7b5038d7SDag-Erling Smørgrav status = ldns_rr_new_frm_str(&r, line, 0, NULL, NULL); 1617*7b5038d7SDag-Erling Smørgrav if (status == LDNS_STATUS_OK && (ldns_rr_get_type(r) == LDNS_RR_TYPE_DNSKEY || ldns_rr_get_type(r) == LDNS_RR_TYPE_DS)) { 1618*7b5038d7SDag-Erling Smørgrav LDNS_FREE(line); 1619*7b5038d7SDag-Erling Smørgrav return r; 1620*7b5038d7SDag-Erling Smørgrav } else { 1621*7b5038d7SDag-Erling Smørgrav fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status)); 1622*7b5038d7SDag-Erling Smørgrav LDNS_FREE(line); 1623*7b5038d7SDag-Erling Smørgrav return NULL; 1624*7b5038d7SDag-Erling Smørgrav } 1625*7b5038d7SDag-Erling Smørgrav } 1626*7b5038d7SDag-Erling Smørgrav } 1627*7b5038d7SDag-Erling Smørgrav 1628*7b5038d7SDag-Erling Smørgrav char * 1629*7b5038d7SDag-Erling Smørgrav ldns_key_get_file_base_name(ldns_key *key) 1630*7b5038d7SDag-Erling Smørgrav { 1631*7b5038d7SDag-Erling Smørgrav ldns_buffer *buffer; 1632*7b5038d7SDag-Erling Smørgrav char *file_base_name; 1633*7b5038d7SDag-Erling Smørgrav 1634*7b5038d7SDag-Erling Smørgrav buffer = ldns_buffer_new(255); 1635*7b5038d7SDag-Erling Smørgrav ldns_buffer_printf(buffer, "K"); 1636*7b5038d7SDag-Erling Smørgrav (void)ldns_rdf2buffer_str_dname(buffer, ldns_key_pubkey_owner(key)); 1637*7b5038d7SDag-Erling Smørgrav ldns_buffer_printf(buffer, 1638*7b5038d7SDag-Erling Smørgrav "+%03u+%05u", 1639*7b5038d7SDag-Erling Smørgrav ldns_key_algorithm(key), 1640*7b5038d7SDag-Erling Smørgrav ldns_key_keytag(key)); 1641*7b5038d7SDag-Erling Smørgrav file_base_name = strdup(ldns_buffer_export(buffer)); 1642*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 1643*7b5038d7SDag-Erling Smørgrav return file_base_name; 1644*7b5038d7SDag-Erling Smørgrav } 1645*7b5038d7SDag-Erling Smørgrav 1646*7b5038d7SDag-Erling Smørgrav int ldns_key_algo_supported(int algo) 1647*7b5038d7SDag-Erling Smørgrav { 1648*7b5038d7SDag-Erling Smørgrav ldns_lookup_table *lt = ldns_signing_algorithms; 1649*7b5038d7SDag-Erling Smørgrav while(lt->name) { 1650*7b5038d7SDag-Erling Smørgrav if(lt->id == algo) 1651*7b5038d7SDag-Erling Smørgrav return 1; 1652*7b5038d7SDag-Erling Smørgrav lt++; 1653*7b5038d7SDag-Erling Smørgrav } 1654*7b5038d7SDag-Erling Smørgrav return 0; 1655*7b5038d7SDag-Erling Smørgrav } 1656*7b5038d7SDag-Erling Smørgrav 1657*7b5038d7SDag-Erling Smørgrav ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name) 1658*7b5038d7SDag-Erling Smørgrav { 1659*7b5038d7SDag-Erling Smørgrav /* list of (signing algorithm id, alias_name) */ 1660*7b5038d7SDag-Erling Smørgrav ldns_lookup_table aliases[] = { 1661*7b5038d7SDag-Erling Smørgrav /* from bind dnssec-keygen */ 1662*7b5038d7SDag-Erling Smørgrav {LDNS_SIGN_HMACMD5, "HMAC-MD5"}, 1663*7b5038d7SDag-Erling Smørgrav {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"}, 1664*7b5038d7SDag-Erling Smørgrav {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"}, 1665*7b5038d7SDag-Erling Smørgrav /* old ldns usage, now RFC names */ 1666*7b5038d7SDag-Erling Smørgrav {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" }, 1667*7b5038d7SDag-Erling Smørgrav {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" }, 1668*7b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 1669*7b5038d7SDag-Erling Smørgrav {LDNS_SIGN_ECC_GOST, "GOST"}, 1670*7b5038d7SDag-Erling Smørgrav #endif 1671*7b5038d7SDag-Erling Smørgrav /* compat with possible output */ 1672*7b5038d7SDag-Erling Smørgrav {LDNS_DH, "DH"}, 1673*7b5038d7SDag-Erling Smørgrav {LDNS_ECC, "ECC"}, 1674*7b5038d7SDag-Erling Smørgrav {LDNS_INDIRECT, "INDIRECT"}, 1675*7b5038d7SDag-Erling Smørgrav {LDNS_PRIVATEDNS, "PRIVATEDNS"}, 1676*7b5038d7SDag-Erling Smørgrav {LDNS_PRIVATEOID, "PRIVATEOID"}, 1677*7b5038d7SDag-Erling Smørgrav {0, NULL}}; 1678*7b5038d7SDag-Erling Smørgrav ldns_lookup_table* lt = ldns_signing_algorithms; 1679*7b5038d7SDag-Erling Smørgrav while(lt->name) { 1680*7b5038d7SDag-Erling Smørgrav if(strcasecmp(lt->name, name) == 0) 1681*7b5038d7SDag-Erling Smørgrav return lt->id; 1682*7b5038d7SDag-Erling Smørgrav lt++; 1683*7b5038d7SDag-Erling Smørgrav } 1684*7b5038d7SDag-Erling Smørgrav lt = aliases; 1685*7b5038d7SDag-Erling Smørgrav while(lt->name) { 1686*7b5038d7SDag-Erling Smørgrav if(strcasecmp(lt->name, name) == 0) 1687*7b5038d7SDag-Erling Smørgrav return lt->id; 1688*7b5038d7SDag-Erling Smørgrav lt++; 1689*7b5038d7SDag-Erling Smørgrav } 1690*7b5038d7SDag-Erling Smørgrav if(atoi(name) != 0) 1691*7b5038d7SDag-Erling Smørgrav return atoi(name); 1692*7b5038d7SDag-Erling Smørgrav return 0; 1693*7b5038d7SDag-Erling Smørgrav } 1694