17b5038d7SDag-Erling Smørgrav /* 27b5038d7SDag-Erling Smørgrav * keys.c handle private keys for use in DNSSEC 37b5038d7SDag-Erling Smørgrav * 47b5038d7SDag-Erling Smørgrav * This module should hide some of the openSSL complexities 57b5038d7SDag-Erling Smørgrav * and give a general interface for private keys and hmac 67b5038d7SDag-Erling Smørgrav * handling 77b5038d7SDag-Erling Smørgrav * 87b5038d7SDag-Erling Smørgrav * (c) NLnet Labs, 2004-2006 97b5038d7SDag-Erling Smørgrav * 107b5038d7SDag-Erling Smørgrav * See the file LICENSE for the license 117b5038d7SDag-Erling Smørgrav */ 127b5038d7SDag-Erling Smørgrav 137b5038d7SDag-Erling Smørgrav #include <ldns/config.h> 147b5038d7SDag-Erling Smørgrav 157b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h> 167b5038d7SDag-Erling Smørgrav 177b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 187b5038d7SDag-Erling Smørgrav #include <openssl/ssl.h> 197b5038d7SDag-Erling Smørgrav #include <openssl/engine.h> 207b5038d7SDag-Erling Smørgrav #include <openssl/rand.h> 217b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 227b5038d7SDag-Erling Smørgrav 237b5038d7SDag-Erling Smørgrav ldns_lookup_table ldns_signing_algorithms[] = { 247b5038d7SDag-Erling Smørgrav { LDNS_SIGN_RSAMD5, "RSAMD5" }, 257b5038d7SDag-Erling Smørgrav { LDNS_SIGN_RSASHA1, "RSASHA1" }, 267b5038d7SDag-Erling Smørgrav { LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" }, 277b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 287b5038d7SDag-Erling Smørgrav { LDNS_SIGN_RSASHA256, "RSASHA256" }, 297b5038d7SDag-Erling Smørgrav { LDNS_SIGN_RSASHA512, "RSASHA512" }, 307b5038d7SDag-Erling Smørgrav #endif 317b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 327b5038d7SDag-Erling Smørgrav { LDNS_SIGN_ECC_GOST, "ECC-GOST" }, 337b5038d7SDag-Erling Smørgrav #endif 347b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 357b5038d7SDag-Erling Smørgrav { LDNS_SIGN_ECDSAP256SHA256, "ECDSAP256SHA256" }, 367b5038d7SDag-Erling Smørgrav { LDNS_SIGN_ECDSAP384SHA384, "ECDSAP384SHA384" }, 377b5038d7SDag-Erling Smørgrav #endif 387b5038d7SDag-Erling Smørgrav { LDNS_SIGN_DSA, "DSA" }, 397b5038d7SDag-Erling Smørgrav { LDNS_SIGN_DSA_NSEC3, "DSA-NSEC3-SHA1" }, 407b5038d7SDag-Erling Smørgrav { LDNS_SIGN_HMACMD5, "hmac-md5.sig-alg.reg.int" }, 417b5038d7SDag-Erling Smørgrav { LDNS_SIGN_HMACSHA1, "hmac-sha1" }, 427b5038d7SDag-Erling Smørgrav { LDNS_SIGN_HMACSHA256, "hmac-sha256" }, 437b5038d7SDag-Erling Smørgrav { 0, NULL } 447b5038d7SDag-Erling Smørgrav }; 457b5038d7SDag-Erling Smørgrav 467b5038d7SDag-Erling Smørgrav ldns_key_list * 477b5038d7SDag-Erling Smørgrav ldns_key_list_new(void) 487b5038d7SDag-Erling Smørgrav { 497b5038d7SDag-Erling Smørgrav ldns_key_list *key_list = LDNS_MALLOC(ldns_key_list); 507b5038d7SDag-Erling Smørgrav if (!key_list) { 517b5038d7SDag-Erling Smørgrav return NULL; 527b5038d7SDag-Erling Smørgrav } else { 537b5038d7SDag-Erling Smørgrav key_list->_key_count = 0; 547b5038d7SDag-Erling Smørgrav key_list->_keys = NULL; 557b5038d7SDag-Erling Smørgrav return key_list; 567b5038d7SDag-Erling Smørgrav } 577b5038d7SDag-Erling Smørgrav } 587b5038d7SDag-Erling Smørgrav 597b5038d7SDag-Erling Smørgrav ldns_key * 607b5038d7SDag-Erling Smørgrav ldns_key_new(void) 617b5038d7SDag-Erling Smørgrav { 627b5038d7SDag-Erling Smørgrav ldns_key *newkey; 637b5038d7SDag-Erling Smørgrav 647b5038d7SDag-Erling Smørgrav newkey = LDNS_MALLOC(ldns_key); 657b5038d7SDag-Erling Smørgrav if (!newkey) { 667b5038d7SDag-Erling Smørgrav return NULL; 677b5038d7SDag-Erling Smørgrav } else { 687b5038d7SDag-Erling Smørgrav /* some defaults - not sure wether to do this */ 697b5038d7SDag-Erling Smørgrav ldns_key_set_use(newkey, true); 707b5038d7SDag-Erling Smørgrav ldns_key_set_flags(newkey, LDNS_KEY_ZONE_KEY); 717b5038d7SDag-Erling Smørgrav ldns_key_set_origttl(newkey, 0); 727b5038d7SDag-Erling Smørgrav ldns_key_set_keytag(newkey, 0); 737b5038d7SDag-Erling Smørgrav ldns_key_set_inception(newkey, 0); 747b5038d7SDag-Erling Smørgrav ldns_key_set_expiration(newkey, 0); 757b5038d7SDag-Erling Smørgrav ldns_key_set_pubkey_owner(newkey, NULL); 767b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 777b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(newkey, NULL); 787b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 797b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_key(newkey, NULL); 807b5038d7SDag-Erling Smørgrav ldns_key_set_external_key(newkey, NULL); 817b5038d7SDag-Erling Smørgrav return newkey; 827b5038d7SDag-Erling Smørgrav } 837b5038d7SDag-Erling Smørgrav } 847b5038d7SDag-Erling Smørgrav 857b5038d7SDag-Erling Smørgrav ldns_status 867b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp(ldns_key **k, FILE *fp) 877b5038d7SDag-Erling Smørgrav { 887b5038d7SDag-Erling Smørgrav return ldns_key_new_frm_fp_l(k, fp, NULL); 897b5038d7SDag-Erling Smørgrav } 907b5038d7SDag-Erling Smørgrav 917b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 927b5038d7SDag-Erling Smørgrav ldns_status 937b5038d7SDag-Erling Smørgrav ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm alg) 947b5038d7SDag-Erling Smørgrav { 957b5038d7SDag-Erling Smørgrav ldns_key *k; 967b5038d7SDag-Erling Smørgrav 977b5038d7SDag-Erling Smørgrav k = ldns_key_new(); 987b5038d7SDag-Erling Smørgrav if(!k) return LDNS_STATUS_MEM_ERR; 997b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 1007b5038d7SDag-Erling Smørgrav k->_key.key = ENGINE_load_private_key(e, key_id, UI_OpenSSL(), NULL); 1017b5038d7SDag-Erling Smørgrav if(!k->_key.key) { 1027b5038d7SDag-Erling Smørgrav ldns_key_free(k); 1037b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 1047b5038d7SDag-Erling Smørgrav } 1057b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, (ldns_signing_algorithm) alg); 1067b5038d7SDag-Erling Smørgrav if (!k->_key.key) { 1077b5038d7SDag-Erling Smørgrav ldns_key_free(k); 1087b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ENGINE_KEY_NOT_LOADED; 1097b5038d7SDag-Erling Smørgrav } 1107b5038d7SDag-Erling Smørgrav #endif /* splint */ 1117b5038d7SDag-Erling Smørgrav *key = k; 1127b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 1137b5038d7SDag-Erling Smørgrav } 1147b5038d7SDag-Erling Smørgrav #endif 1157b5038d7SDag-Erling Smørgrav 1167b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 1177b5038d7SDag-Erling Smørgrav /** store GOST engine reference loaded into OpenSSL library */ 1187b5038d7SDag-Erling Smørgrav ENGINE* ldns_gost_engine = NULL; 1197b5038d7SDag-Erling Smørgrav 1207b5038d7SDag-Erling Smørgrav int 1217b5038d7SDag-Erling Smørgrav ldns_key_EVP_load_gost_id(void) 1227b5038d7SDag-Erling Smørgrav { 1237b5038d7SDag-Erling Smørgrav static int gost_id = 0; 1247b5038d7SDag-Erling Smørgrav const EVP_PKEY_ASN1_METHOD* meth; 1257b5038d7SDag-Erling Smørgrav ENGINE* e; 1267b5038d7SDag-Erling Smørgrav 1277b5038d7SDag-Erling Smørgrav if(gost_id) return gost_id; 1287b5038d7SDag-Erling Smørgrav 1297b5038d7SDag-Erling Smørgrav /* see if configuration loaded gost implementation from other engine*/ 1307b5038d7SDag-Erling Smørgrav meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1); 1317b5038d7SDag-Erling Smørgrav if(meth) { 1327b5038d7SDag-Erling Smørgrav EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth); 1337b5038d7SDag-Erling Smørgrav return gost_id; 1347b5038d7SDag-Erling Smørgrav } 1357b5038d7SDag-Erling Smørgrav 1367b5038d7SDag-Erling Smørgrav /* see if engine can be loaded already */ 1377b5038d7SDag-Erling Smørgrav e = ENGINE_by_id("gost"); 1387b5038d7SDag-Erling Smørgrav if(!e) { 1397b5038d7SDag-Erling Smørgrav /* load it ourself, in case statically linked */ 1407b5038d7SDag-Erling Smørgrav ENGINE_load_builtin_engines(); 1417b5038d7SDag-Erling Smørgrav ENGINE_load_dynamic(); 1427b5038d7SDag-Erling Smørgrav e = ENGINE_by_id("gost"); 1437b5038d7SDag-Erling Smørgrav } 1447b5038d7SDag-Erling Smørgrav if(!e) { 1457b5038d7SDag-Erling Smørgrav /* no gost engine in openssl */ 1467b5038d7SDag-Erling Smørgrav return 0; 1477b5038d7SDag-Erling Smørgrav } 1487b5038d7SDag-Erling Smørgrav if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) { 1497b5038d7SDag-Erling Smørgrav ENGINE_finish(e); 1507b5038d7SDag-Erling Smørgrav ENGINE_free(e); 1517b5038d7SDag-Erling Smørgrav return 0; 1527b5038d7SDag-Erling Smørgrav } 1537b5038d7SDag-Erling Smørgrav 1547b5038d7SDag-Erling Smørgrav meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1); 1557b5038d7SDag-Erling Smørgrav if(!meth) { 1567b5038d7SDag-Erling Smørgrav /* algo not found */ 1577b5038d7SDag-Erling Smørgrav ENGINE_finish(e); 1587b5038d7SDag-Erling Smørgrav ENGINE_free(e); 1597b5038d7SDag-Erling Smørgrav return 0; 1607b5038d7SDag-Erling Smørgrav } 1617b5038d7SDag-Erling Smørgrav /* Note: do not ENGINE_finish and ENGINE_free the acquired engine 1627b5038d7SDag-Erling Smørgrav * on some platforms this frees up the meth and unloads gost stuff */ 1637b5038d7SDag-Erling Smørgrav ldns_gost_engine = e; 1647b5038d7SDag-Erling Smørgrav 1657b5038d7SDag-Erling Smørgrav EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth); 1667b5038d7SDag-Erling Smørgrav return gost_id; 1677b5038d7SDag-Erling Smørgrav } 1687b5038d7SDag-Erling Smørgrav 1697b5038d7SDag-Erling Smørgrav void ldns_key_EVP_unload_gost(void) 1707b5038d7SDag-Erling Smørgrav { 1717b5038d7SDag-Erling Smørgrav if(ldns_gost_engine) { 1727b5038d7SDag-Erling Smørgrav ENGINE_finish(ldns_gost_engine); 1737b5038d7SDag-Erling Smørgrav ENGINE_free(ldns_gost_engine); 1747b5038d7SDag-Erling Smørgrav ldns_gost_engine = NULL; 1757b5038d7SDag-Erling Smørgrav } 1767b5038d7SDag-Erling Smørgrav } 1777b5038d7SDag-Erling Smørgrav 1787b5038d7SDag-Erling Smørgrav /** read GOST private key */ 1797b5038d7SDag-Erling Smørgrav static EVP_PKEY* 1807b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_gost_l(FILE* fp, int* line_nr) 1817b5038d7SDag-Erling Smørgrav { 1827b5038d7SDag-Erling Smørgrav char token[16384]; 1837b5038d7SDag-Erling Smørgrav const unsigned char* pp; 1847b5038d7SDag-Erling Smørgrav int gost_id; 1857b5038d7SDag-Erling Smørgrav EVP_PKEY* pkey; 1867b5038d7SDag-Erling Smørgrav ldns_rdf* b64rdf = NULL; 1877b5038d7SDag-Erling Smørgrav 1887b5038d7SDag-Erling Smørgrav gost_id = ldns_key_EVP_load_gost_id(); 1897b5038d7SDag-Erling Smørgrav if(!gost_id) 1907b5038d7SDag-Erling Smørgrav return NULL; 1917b5038d7SDag-Erling Smørgrav 1927b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(fp, "GostAsn1", ": ", token, "\n", 1937b5038d7SDag-Erling Smørgrav sizeof(token), line_nr) == -1) 1947b5038d7SDag-Erling Smørgrav return NULL; 1957b5038d7SDag-Erling Smørgrav while(strlen(token) < 96) { 1967b5038d7SDag-Erling Smørgrav /* read more b64 from the file, b64 split on multiple lines */ 1977b5038d7SDag-Erling Smørgrav if(ldns_fget_token_l(fp, token+strlen(token), "\n", 1987b5038d7SDag-Erling Smørgrav sizeof(token)-strlen(token), line_nr) == -1) 1997b5038d7SDag-Erling Smørgrav return NULL; 2007b5038d7SDag-Erling Smørgrav } 2017b5038d7SDag-Erling Smørgrav if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK) 2027b5038d7SDag-Erling Smørgrav return NULL; 2037b5038d7SDag-Erling Smørgrav pp = (unsigned char*)ldns_rdf_data(b64rdf); 2047b5038d7SDag-Erling Smørgrav pkey = d2i_PrivateKey(gost_id, NULL, &pp, (int)ldns_rdf_size(b64rdf)); 2057b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(b64rdf); 2067b5038d7SDag-Erling Smørgrav return pkey; 2077b5038d7SDag-Erling Smørgrav } 2087b5038d7SDag-Erling Smørgrav #endif 2097b5038d7SDag-Erling Smørgrav 2107b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 2117b5038d7SDag-Erling Smørgrav /** calculate public key from private key */ 2127b5038d7SDag-Erling Smørgrav static int 2137b5038d7SDag-Erling Smørgrav ldns_EC_KEY_calc_public(EC_KEY* ec) 2147b5038d7SDag-Erling Smørgrav { 2157b5038d7SDag-Erling Smørgrav EC_POINT* pub_key; 2167b5038d7SDag-Erling Smørgrav const EC_GROUP* group; 2177b5038d7SDag-Erling Smørgrav group = EC_KEY_get0_group(ec); 2187b5038d7SDag-Erling Smørgrav pub_key = EC_POINT_new(group); 2197b5038d7SDag-Erling Smørgrav if(!pub_key) return 0; 2207b5038d7SDag-Erling Smørgrav if(!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { 2217b5038d7SDag-Erling Smørgrav EC_POINT_free(pub_key); 2227b5038d7SDag-Erling Smørgrav return 0; 2237b5038d7SDag-Erling Smørgrav } 2247b5038d7SDag-Erling Smørgrav if(!EC_POINT_mul(group, pub_key, EC_KEY_get0_private_key(ec), 2257b5038d7SDag-Erling Smørgrav NULL, NULL, NULL)) { 2267b5038d7SDag-Erling Smørgrav EC_POINT_free(pub_key); 2277b5038d7SDag-Erling Smørgrav return 0; 2287b5038d7SDag-Erling Smørgrav } 2297b5038d7SDag-Erling Smørgrav if(EC_KEY_set_public_key(ec, pub_key) == 0) { 2307b5038d7SDag-Erling Smørgrav EC_POINT_free(pub_key); 2317b5038d7SDag-Erling Smørgrav return 0; 2327b5038d7SDag-Erling Smørgrav } 2337b5038d7SDag-Erling Smørgrav EC_POINT_free(pub_key); 2347b5038d7SDag-Erling Smørgrav return 1; 2357b5038d7SDag-Erling Smørgrav } 2367b5038d7SDag-Erling Smørgrav 2377b5038d7SDag-Erling Smørgrav /** read ECDSA private key */ 2387b5038d7SDag-Erling Smørgrav static EVP_PKEY* 2397b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr) 2407b5038d7SDag-Erling Smørgrav { 2417b5038d7SDag-Erling Smørgrav char token[16384]; 2427b5038d7SDag-Erling Smørgrav ldns_rdf* b64rdf = NULL; 2437b5038d7SDag-Erling Smørgrav unsigned char* pp; 2447b5038d7SDag-Erling Smørgrav BIGNUM* bn; 2457b5038d7SDag-Erling Smørgrav EVP_PKEY* evp_key; 2467b5038d7SDag-Erling Smørgrav EC_KEY* ec; 2477b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n", 2487b5038d7SDag-Erling Smørgrav sizeof(token), line_nr) == -1) 2497b5038d7SDag-Erling Smørgrav return NULL; 2507b5038d7SDag-Erling Smørgrav if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK) 2517b5038d7SDag-Erling Smørgrav return NULL; 2527b5038d7SDag-Erling Smørgrav pp = (unsigned char*)ldns_rdf_data(b64rdf); 2537b5038d7SDag-Erling Smørgrav 2547b5038d7SDag-Erling Smørgrav if(alg == LDNS_ECDSAP256SHA256) 2557b5038d7SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 2567b5038d7SDag-Erling Smørgrav else if(alg == LDNS_ECDSAP384SHA384) 2577b5038d7SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_secp384r1); 2587b5038d7SDag-Erling Smørgrav else ec = NULL; 2597b5038d7SDag-Erling Smørgrav if(!ec) { 2607b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(b64rdf); 2617b5038d7SDag-Erling Smørgrav return NULL; 2627b5038d7SDag-Erling Smørgrav } 2637b5038d7SDag-Erling Smørgrav bn = BN_bin2bn(pp, (int)ldns_rdf_size(b64rdf), NULL); 2647b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(b64rdf); 2657b5038d7SDag-Erling Smørgrav if(!bn) { 2667b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 2677b5038d7SDag-Erling Smørgrav return NULL; 2687b5038d7SDag-Erling Smørgrav } 2697b5038d7SDag-Erling Smørgrav EC_KEY_set_private_key(ec, bn); 2707b5038d7SDag-Erling Smørgrav BN_free(bn); 2717b5038d7SDag-Erling Smørgrav if(!ldns_EC_KEY_calc_public(ec)) { 2727b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 2737b5038d7SDag-Erling Smørgrav return NULL; 2747b5038d7SDag-Erling Smørgrav } 2757b5038d7SDag-Erling Smørgrav 2767b5038d7SDag-Erling Smørgrav evp_key = EVP_PKEY_new(); 2777b5038d7SDag-Erling Smørgrav if(!evp_key) { 2787b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 2797b5038d7SDag-Erling Smørgrav return NULL; 2807b5038d7SDag-Erling Smørgrav } 2817b5038d7SDag-Erling Smørgrav if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) { 2827b5038d7SDag-Erling Smørgrav EVP_PKEY_free(evp_key); 2837b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 2847b5038d7SDag-Erling Smørgrav return NULL; 2857b5038d7SDag-Erling Smørgrav } 2867b5038d7SDag-Erling Smørgrav return evp_key; 2877b5038d7SDag-Erling Smørgrav } 2887b5038d7SDag-Erling Smørgrav #endif 2897b5038d7SDag-Erling Smørgrav 2907b5038d7SDag-Erling Smørgrav ldns_status 2917b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr) 2927b5038d7SDag-Erling Smørgrav { 2937b5038d7SDag-Erling Smørgrav ldns_key *k; 2947b5038d7SDag-Erling Smørgrav char *d; 2957b5038d7SDag-Erling Smørgrav ldns_signing_algorithm alg; 2967b5038d7SDag-Erling Smørgrav ldns_rr *key_rr; 2977b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 2987b5038d7SDag-Erling Smørgrav RSA *rsa; 2997b5038d7SDag-Erling Smørgrav DSA *dsa; 3007b5038d7SDag-Erling Smørgrav unsigned char *hmac; 3017b5038d7SDag-Erling Smørgrav size_t hmac_size; 3027b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 3037b5038d7SDag-Erling Smørgrav 3047b5038d7SDag-Erling Smørgrav k = ldns_key_new(); 3057b5038d7SDag-Erling Smørgrav 3067b5038d7SDag-Erling Smørgrav d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); 3077b5038d7SDag-Erling Smørgrav if (!k || !d) { 3087b5038d7SDag-Erling Smørgrav ldns_key_free(k); 3097b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 3107b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 3117b5038d7SDag-Erling Smørgrav } 3127b5038d7SDag-Erling Smørgrav 3137b5038d7SDag-Erling Smørgrav alg = 0; 3147b5038d7SDag-Erling Smørgrav 3157b5038d7SDag-Erling Smørgrav /* the file is highly structured. Do this in sequence */ 3167b5038d7SDag-Erling Smørgrav /* RSA: 3177b5038d7SDag-Erling Smørgrav * Private-key-format: v1.x. 3187b5038d7SDag-Erling Smørgrav * Algorithm: 1 (RSA) 3197b5038d7SDag-Erling Smørgrav 3207b5038d7SDag-Erling Smørgrav */ 3217b5038d7SDag-Erling Smørgrav /* get the key format version number */ 3227b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(fp, "Private-key-format", ": ", d, "\n", 3237b5038d7SDag-Erling Smørgrav LDNS_MAX_LINELEN, line_nr) == -1) { 3247b5038d7SDag-Erling Smørgrav /* no version information */ 3257b5038d7SDag-Erling Smørgrav ldns_key_free(k); 3267b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 3277b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_ERR; 3287b5038d7SDag-Erling Smørgrav } 3297b5038d7SDag-Erling Smørgrav if (strncmp(d, "v1.", 3) != 0) { 3307b5038d7SDag-Erling Smørgrav ldns_key_free(k); 3317b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 3327b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_VERSION_ERR; 3337b5038d7SDag-Erling Smørgrav } 3347b5038d7SDag-Erling Smørgrav 3357b5038d7SDag-Erling Smørgrav /* get the algorithm type, our file function strip ( ) so there are 3367b5038d7SDag-Erling Smørgrav * not in the return string! */ 3377b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(fp, "Algorithm", ": ", d, "\n", 3387b5038d7SDag-Erling Smørgrav LDNS_MAX_LINELEN, line_nr) == -1) { 3397b5038d7SDag-Erling Smørgrav /* no alg information */ 3407b5038d7SDag-Erling Smørgrav ldns_key_free(k); 3417b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 3427b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_ALG_ERR; 3437b5038d7SDag-Erling Smørgrav } 3447b5038d7SDag-Erling Smørgrav 3457b5038d7SDag-Erling Smørgrav if (strncmp(d, "1 RSA", 2) == 0) { 3467b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_RSAMD5; 3477b5038d7SDag-Erling Smørgrav } 3487b5038d7SDag-Erling Smørgrav if (strncmp(d, "2 DH", 2) == 0) { 3497b5038d7SDag-Erling Smørgrav alg = (ldns_signing_algorithm)LDNS_DH; 3507b5038d7SDag-Erling Smørgrav } 3517b5038d7SDag-Erling Smørgrav if (strncmp(d, "3 DSA", 2) == 0) { 3527b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_DSA; 3537b5038d7SDag-Erling Smørgrav } 3547b5038d7SDag-Erling Smørgrav if (strncmp(d, "4 ECC", 2) == 0) { 3557b5038d7SDag-Erling Smørgrav alg = (ldns_signing_algorithm)LDNS_ECC; 3567b5038d7SDag-Erling Smørgrav } 3577b5038d7SDag-Erling Smørgrav if (strncmp(d, "5 RSASHA1", 2) == 0) { 3587b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_RSASHA1; 3597b5038d7SDag-Erling Smørgrav } 3607b5038d7SDag-Erling Smørgrav if (strncmp(d, "6 DSA", 2) == 0) { 3617b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_DSA_NSEC3; 3627b5038d7SDag-Erling Smørgrav } 3637b5038d7SDag-Erling Smørgrav if (strncmp(d, "7 RSASHA1", 2) == 0) { 3647b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_RSASHA1_NSEC3; 3657b5038d7SDag-Erling Smørgrav } 3667b5038d7SDag-Erling Smørgrav 3677b5038d7SDag-Erling Smørgrav if (strncmp(d, "8 RSASHA256", 2) == 0) { 3687b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 3697b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_RSASHA256; 3707b5038d7SDag-Erling Smørgrav #else 3717b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: SHA256 not compiled into this "); 3727b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns\n"); 3737b5038d7SDag-Erling Smørgrav #endif 3747b5038d7SDag-Erling Smørgrav } 3757b5038d7SDag-Erling Smørgrav if (strncmp(d, "10 RSASHA512", 3) == 0) { 3767b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 3777b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_RSASHA512; 3787b5038d7SDag-Erling Smørgrav #else 3797b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: SHA512 not compiled into this "); 3807b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns\n"); 3817b5038d7SDag-Erling Smørgrav #endif 3827b5038d7SDag-Erling Smørgrav } 3837b5038d7SDag-Erling Smørgrav if (strncmp(d, "12 ECC-GOST", 3) == 0) { 3847b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 3857b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_ECC_GOST; 3867b5038d7SDag-Erling Smørgrav #else 3877b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: ECC-GOST not compiled into this "); 3887b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns, use --enable-gost\n"); 3897b5038d7SDag-Erling Smørgrav #endif 3907b5038d7SDag-Erling Smørgrav } 3917b5038d7SDag-Erling Smørgrav if (strncmp(d, "13 ECDSAP256SHA256", 3) == 0) { 3927b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 3937b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_ECDSAP256SHA256; 3947b5038d7SDag-Erling Smørgrav #else 3957b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: ECDSA not compiled into this "); 3967b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns, use --enable-ecdsa\n"); 3977b5038d7SDag-Erling Smørgrav #endif 3987b5038d7SDag-Erling Smørgrav } 3997b5038d7SDag-Erling Smørgrav if (strncmp(d, "14 ECDSAP384SHA384", 3) == 0) { 4007b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 4017b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_ECDSAP384SHA384; 4027b5038d7SDag-Erling Smørgrav #else 4037b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: ECDSA not compiled into this "); 4047b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns, use --enable-ecdsa\n"); 4057b5038d7SDag-Erling Smørgrav #endif 4067b5038d7SDag-Erling Smørgrav } 4077b5038d7SDag-Erling Smørgrav if (strncmp(d, "157 HMAC-MD5", 4) == 0) { 4087b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_HMACMD5; 4097b5038d7SDag-Erling Smørgrav } 4107b5038d7SDag-Erling Smørgrav if (strncmp(d, "158 HMAC-SHA1", 4) == 0) { 4117b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_HMACSHA1; 4127b5038d7SDag-Erling Smørgrav } 4137b5038d7SDag-Erling Smørgrav if (strncmp(d, "159 HMAC-SHA256", 4) == 0) { 4147b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_HMACSHA256; 4157b5038d7SDag-Erling Smørgrav } 4167b5038d7SDag-Erling Smørgrav 4177b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 4187b5038d7SDag-Erling Smørgrav 4197b5038d7SDag-Erling Smørgrav switch(alg) { 4207b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSAMD5: 4217b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1: 4227b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1_NSEC3: 4237b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 4247b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA256: 4257b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA512: 4267b5038d7SDag-Erling Smørgrav #endif 4277b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 4287b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 4297b5038d7SDag-Erling Smørgrav rsa = ldns_key_new_frm_fp_rsa_l(fp, line_nr); 4307b5038d7SDag-Erling Smørgrav if (!rsa) { 4317b5038d7SDag-Erling Smørgrav ldns_key_free(k); 4327b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 4337b5038d7SDag-Erling Smørgrav } 434*2787e39aSDag-Erling Smørgrav ldns_key_assign_rsa_key(k, rsa); 4357b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 4367b5038d7SDag-Erling Smørgrav break; 4377b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA: 4387b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA_NSEC3: 4397b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 4407b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 4417b5038d7SDag-Erling Smørgrav dsa = ldns_key_new_frm_fp_dsa_l(fp, line_nr); 4427b5038d7SDag-Erling Smørgrav if (!dsa) { 4437b5038d7SDag-Erling Smørgrav ldns_key_free(k); 4447b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 4457b5038d7SDag-Erling Smørgrav } 446*2787e39aSDag-Erling Smørgrav ldns_key_assign_dsa_key(k, dsa); 4477b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 4487b5038d7SDag-Erling Smørgrav break; 4497b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACMD5: 4507b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA1: 4517b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA256: 4527b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 4537b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 4547b5038d7SDag-Erling Smørgrav hmac = ldns_key_new_frm_fp_hmac_l(fp, line_nr, &hmac_size); 4557b5038d7SDag-Erling Smørgrav if (!hmac) { 4567b5038d7SDag-Erling Smørgrav ldns_key_free(k); 4577b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 4587b5038d7SDag-Erling Smørgrav } 4597b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_size(k, hmac_size); 4607b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_key(k, hmac); 4617b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 4627b5038d7SDag-Erling Smørgrav break; 4637b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECC_GOST: 4647b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 4657b5038d7SDag-Erling Smørgrav #if defined(HAVE_SSL) && defined(USE_GOST) 4667b5038d7SDag-Erling Smørgrav if(!ldns_key_EVP_load_gost_id()) { 4677b5038d7SDag-Erling Smørgrav ldns_key_free(k); 4687b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL; 4697b5038d7SDag-Erling Smørgrav } 4707b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(k, 4717b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_gost_l(fp, line_nr)); 4727b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 4737b5038d7SDag-Erling Smørgrav if(!k->_key.key) { 4747b5038d7SDag-Erling Smørgrav ldns_key_free(k); 4757b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 4767b5038d7SDag-Erling Smørgrav } 4777b5038d7SDag-Erling Smørgrav #endif /* splint */ 4787b5038d7SDag-Erling Smørgrav #endif 4797b5038d7SDag-Erling Smørgrav break; 4807b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 4817b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP256SHA256: 4827b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP384SHA384: 4837b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 4847b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(k, 4857b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_ecdsa_l(fp, (ldns_algorithm)alg, line_nr)); 4867b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 4877b5038d7SDag-Erling Smørgrav if(!k->_key.key) { 4887b5038d7SDag-Erling Smørgrav ldns_key_free(k); 4897b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 4907b5038d7SDag-Erling Smørgrav } 4917b5038d7SDag-Erling Smørgrav #endif /* splint */ 4927b5038d7SDag-Erling Smørgrav break; 4937b5038d7SDag-Erling Smørgrav #endif 4947b5038d7SDag-Erling Smørgrav default: 4957b5038d7SDag-Erling Smørgrav ldns_key_free(k); 4967b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_ALG_ERR; 4977b5038d7SDag-Erling Smørgrav } 4987b5038d7SDag-Erling Smørgrav key_rr = ldns_key2rr(k); 4997b5038d7SDag-Erling Smørgrav ldns_key_set_keytag(k, ldns_calc_keytag(key_rr)); 5007b5038d7SDag-Erling Smørgrav ldns_rr_free(key_rr); 5017b5038d7SDag-Erling Smørgrav 5027b5038d7SDag-Erling Smørgrav if (key) { 5037b5038d7SDag-Erling Smørgrav *key = k; 5047b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 5057b5038d7SDag-Erling Smørgrav } 506*2787e39aSDag-Erling Smørgrav ldns_key_free(k); 5077b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 5087b5038d7SDag-Erling Smørgrav } 5097b5038d7SDag-Erling Smørgrav 5107b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 5117b5038d7SDag-Erling Smørgrav RSA * 5127b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_rsa(FILE *f) 5137b5038d7SDag-Erling Smørgrav { 5147b5038d7SDag-Erling Smørgrav return ldns_key_new_frm_fp_rsa_l(f, NULL); 5157b5038d7SDag-Erling Smørgrav } 5167b5038d7SDag-Erling Smørgrav 5177b5038d7SDag-Erling Smørgrav RSA * 5187b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr) 5197b5038d7SDag-Erling Smørgrav { 5207b5038d7SDag-Erling Smørgrav /* we parse 5217b5038d7SDag-Erling Smørgrav * Modulus: 5227b5038d7SDag-Erling Smørgrav * PublicExponent: 5237b5038d7SDag-Erling Smørgrav * PrivateExponent: 5247b5038d7SDag-Erling Smørgrav * Prime1: 5257b5038d7SDag-Erling Smørgrav * Prime2: 5267b5038d7SDag-Erling Smørgrav * Exponent1: 5277b5038d7SDag-Erling Smørgrav * Exponent2: 5287b5038d7SDag-Erling Smørgrav * Coefficient: 5297b5038d7SDag-Erling Smørgrav * 5307b5038d7SDag-Erling Smørgrav * man 3 RSA: 5317b5038d7SDag-Erling Smørgrav * 5327b5038d7SDag-Erling Smørgrav * struct 5337b5038d7SDag-Erling Smørgrav * { 5347b5038d7SDag-Erling Smørgrav * BIGNUM *n; // public modulus 5357b5038d7SDag-Erling Smørgrav * BIGNUM *e; // public exponent 5367b5038d7SDag-Erling Smørgrav * BIGNUM *d; // private exponent 5377b5038d7SDag-Erling Smørgrav * BIGNUM *p; // secret prime factor 5387b5038d7SDag-Erling Smørgrav * BIGNUM *q; // secret prime factor 5397b5038d7SDag-Erling Smørgrav * BIGNUM *dmp1; // d mod (p-1) 5407b5038d7SDag-Erling Smørgrav * BIGNUM *dmq1; // d mod (q-1) 5417b5038d7SDag-Erling Smørgrav * BIGNUM *iqmp; // q^-1 mod p 5427b5038d7SDag-Erling Smørgrav * // ... 5437b5038d7SDag-Erling Smørgrav * 5447b5038d7SDag-Erling Smørgrav */ 5457b5038d7SDag-Erling Smørgrav char *d; 5467b5038d7SDag-Erling Smørgrav RSA *rsa; 5477b5038d7SDag-Erling Smørgrav uint8_t *buf; 5487b5038d7SDag-Erling Smørgrav int i; 5497b5038d7SDag-Erling Smørgrav 5507b5038d7SDag-Erling Smørgrav d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); 5517b5038d7SDag-Erling Smørgrav buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN); 5527b5038d7SDag-Erling Smørgrav rsa = RSA_new(); 5537b5038d7SDag-Erling Smørgrav if (!d || !rsa || !buf) { 5547b5038d7SDag-Erling Smørgrav goto error; 5557b5038d7SDag-Erling Smørgrav } 5567b5038d7SDag-Erling Smørgrav 5577b5038d7SDag-Erling Smørgrav /* I could use functions again, but that seems an overkill, 5587b5038d7SDag-Erling Smørgrav * allthough this also looks tedious 5597b5038d7SDag-Erling Smørgrav */ 5607b5038d7SDag-Erling Smørgrav 5617b5038d7SDag-Erling Smørgrav /* Modules, rsa->n */ 5627b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Modulus", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 5637b5038d7SDag-Erling Smørgrav goto error; 5647b5038d7SDag-Erling Smørgrav } 5657b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 5667b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 5677b5038d7SDag-Erling Smørgrav rsa->n = BN_bin2bn((const char unsigned*)buf, i, NULL); 5687b5038d7SDag-Erling Smørgrav if (!rsa->n) { 5697b5038d7SDag-Erling Smørgrav goto error; 5707b5038d7SDag-Erling Smørgrav } 5717b5038d7SDag-Erling Smørgrav 5727b5038d7SDag-Erling Smørgrav /* PublicExponent, rsa->e */ 5737b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 5747b5038d7SDag-Erling Smørgrav goto error; 5757b5038d7SDag-Erling Smørgrav } 5767b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 5777b5038d7SDag-Erling Smørgrav rsa->e = BN_bin2bn((const char unsigned*)buf, i, NULL); 5787b5038d7SDag-Erling Smørgrav if (!rsa->e) { 5797b5038d7SDag-Erling Smørgrav goto error; 5807b5038d7SDag-Erling Smørgrav } 5817b5038d7SDag-Erling Smørgrav 5827b5038d7SDag-Erling Smørgrav /* PrivateExponent, rsa->d */ 5837b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 5847b5038d7SDag-Erling Smørgrav goto error; 5857b5038d7SDag-Erling Smørgrav } 5867b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 5877b5038d7SDag-Erling Smørgrav rsa->d = BN_bin2bn((const char unsigned*)buf, i, NULL); 5887b5038d7SDag-Erling Smørgrav if (!rsa->d) { 5897b5038d7SDag-Erling Smørgrav goto error; 5907b5038d7SDag-Erling Smørgrav } 5917b5038d7SDag-Erling Smørgrav 5927b5038d7SDag-Erling Smørgrav /* Prime1, rsa->p */ 5937b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Prime1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 5947b5038d7SDag-Erling Smørgrav goto error; 5957b5038d7SDag-Erling Smørgrav } 5967b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 5977b5038d7SDag-Erling Smørgrav rsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL); 5987b5038d7SDag-Erling Smørgrav if (!rsa->p) { 5997b5038d7SDag-Erling Smørgrav goto error; 6007b5038d7SDag-Erling Smørgrav } 6017b5038d7SDag-Erling Smørgrav 6027b5038d7SDag-Erling Smørgrav /* Prime2, rsa->q */ 6037b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Prime2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 6047b5038d7SDag-Erling Smørgrav goto error; 6057b5038d7SDag-Erling Smørgrav } 6067b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 6077b5038d7SDag-Erling Smørgrav rsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL); 6087b5038d7SDag-Erling Smørgrav if (!rsa->q) { 6097b5038d7SDag-Erling Smørgrav goto error; 6107b5038d7SDag-Erling Smørgrav } 6117b5038d7SDag-Erling Smørgrav 6127b5038d7SDag-Erling Smørgrav /* Exponent1, rsa->dmp1 */ 6137b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 6147b5038d7SDag-Erling Smørgrav goto error; 6157b5038d7SDag-Erling Smørgrav } 6167b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 6177b5038d7SDag-Erling Smørgrav rsa->dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL); 6187b5038d7SDag-Erling Smørgrav if (!rsa->dmp1) { 6197b5038d7SDag-Erling Smørgrav goto error; 6207b5038d7SDag-Erling Smørgrav } 6217b5038d7SDag-Erling Smørgrav 6227b5038d7SDag-Erling Smørgrav /* Exponent2, rsa->dmq1 */ 6237b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 6247b5038d7SDag-Erling Smørgrav goto error; 6257b5038d7SDag-Erling Smørgrav } 6267b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 6277b5038d7SDag-Erling Smørgrav rsa->dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL); 6287b5038d7SDag-Erling Smørgrav if (!rsa->dmq1) { 6297b5038d7SDag-Erling Smørgrav goto error; 6307b5038d7SDag-Erling Smørgrav } 6317b5038d7SDag-Erling Smørgrav 6327b5038d7SDag-Erling Smørgrav /* Coefficient, rsa->iqmp */ 6337b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 6347b5038d7SDag-Erling Smørgrav goto error; 6357b5038d7SDag-Erling Smørgrav } 6367b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 6377b5038d7SDag-Erling Smørgrav rsa->iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL); 6387b5038d7SDag-Erling Smørgrav if (!rsa->iqmp) { 6397b5038d7SDag-Erling Smørgrav goto error; 6407b5038d7SDag-Erling Smørgrav } 6417b5038d7SDag-Erling Smørgrav #endif /* splint */ 6427b5038d7SDag-Erling Smørgrav 6437b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 6447b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 6457b5038d7SDag-Erling Smørgrav return rsa; 6467b5038d7SDag-Erling Smørgrav 6477b5038d7SDag-Erling Smørgrav error: 6487b5038d7SDag-Erling Smørgrav RSA_free(rsa); 6497b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 6507b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 6517b5038d7SDag-Erling Smørgrav return NULL; 6527b5038d7SDag-Erling Smørgrav } 6537b5038d7SDag-Erling Smørgrav 6547b5038d7SDag-Erling Smørgrav DSA * 6557b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_dsa(FILE *f) 6567b5038d7SDag-Erling Smørgrav { 6577b5038d7SDag-Erling Smørgrav return ldns_key_new_frm_fp_dsa_l(f, NULL); 6587b5038d7SDag-Erling Smørgrav } 6597b5038d7SDag-Erling Smørgrav 6607b5038d7SDag-Erling Smørgrav DSA * 6617b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr)) 6627b5038d7SDag-Erling Smørgrav { 6637b5038d7SDag-Erling Smørgrav int i; 6647b5038d7SDag-Erling Smørgrav char *d; 6657b5038d7SDag-Erling Smørgrav DSA *dsa; 6667b5038d7SDag-Erling Smørgrav uint8_t *buf; 6677b5038d7SDag-Erling Smørgrav 6687b5038d7SDag-Erling Smørgrav d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); 6697b5038d7SDag-Erling Smørgrav buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN); 6707b5038d7SDag-Erling Smørgrav dsa = DSA_new(); 6717b5038d7SDag-Erling Smørgrav if (!d || !dsa || !buf) { 6727b5038d7SDag-Erling Smørgrav goto error; 6737b5038d7SDag-Erling Smørgrav } 6747b5038d7SDag-Erling Smørgrav 6757b5038d7SDag-Erling Smørgrav /* the line parser removes the () from the input... */ 6767b5038d7SDag-Erling Smørgrav 6777b5038d7SDag-Erling Smørgrav /* Prime, dsa->p */ 6787b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Primep", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 6797b5038d7SDag-Erling Smørgrav goto error; 6807b5038d7SDag-Erling Smørgrav } 6817b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 6827b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 6837b5038d7SDag-Erling Smørgrav dsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL); 6847b5038d7SDag-Erling Smørgrav if (!dsa->p) { 6857b5038d7SDag-Erling Smørgrav goto error; 6867b5038d7SDag-Erling Smørgrav } 6877b5038d7SDag-Erling Smørgrav 6887b5038d7SDag-Erling Smørgrav /* Subprime, dsa->q */ 6897b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Subprimeq", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 6907b5038d7SDag-Erling Smørgrav goto error; 6917b5038d7SDag-Erling Smørgrav } 6927b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 6937b5038d7SDag-Erling Smørgrav dsa->q = BN_bin2bn((const char unsigned*)buf, i, NULL); 6947b5038d7SDag-Erling Smørgrav if (!dsa->q) { 6957b5038d7SDag-Erling Smørgrav goto error; 6967b5038d7SDag-Erling Smørgrav } 6977b5038d7SDag-Erling Smørgrav 6987b5038d7SDag-Erling Smørgrav /* Base, dsa->g */ 6997b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Baseg", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 7007b5038d7SDag-Erling Smørgrav goto error; 7017b5038d7SDag-Erling Smørgrav } 7027b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 7037b5038d7SDag-Erling Smørgrav dsa->g = BN_bin2bn((const char unsigned*)buf, i, NULL); 7047b5038d7SDag-Erling Smørgrav if (!dsa->g) { 7057b5038d7SDag-Erling Smørgrav goto error; 7067b5038d7SDag-Erling Smørgrav } 7077b5038d7SDag-Erling Smørgrav 7087b5038d7SDag-Erling Smørgrav /* Private key, dsa->priv_key */ 7097b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Private_valuex", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 7107b5038d7SDag-Erling Smørgrav goto error; 7117b5038d7SDag-Erling Smørgrav } 7127b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 7137b5038d7SDag-Erling Smørgrav dsa->priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL); 7147b5038d7SDag-Erling Smørgrav if (!dsa->priv_key) { 7157b5038d7SDag-Erling Smørgrav goto error; 7167b5038d7SDag-Erling Smørgrav } 7177b5038d7SDag-Erling Smørgrav 7187b5038d7SDag-Erling Smørgrav /* Public key, dsa->priv_key */ 7197b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Public_valuey", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 7207b5038d7SDag-Erling Smørgrav goto error; 7217b5038d7SDag-Erling Smørgrav } 7227b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 7237b5038d7SDag-Erling Smørgrav dsa->pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL); 7247b5038d7SDag-Erling Smørgrav if (!dsa->pub_key) { 7257b5038d7SDag-Erling Smørgrav goto error; 7267b5038d7SDag-Erling Smørgrav } 7277b5038d7SDag-Erling Smørgrav #endif /* splint */ 7287b5038d7SDag-Erling Smørgrav 7297b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 7307b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 7317b5038d7SDag-Erling Smørgrav 7327b5038d7SDag-Erling Smørgrav return dsa; 7337b5038d7SDag-Erling Smørgrav 7347b5038d7SDag-Erling Smørgrav error: 7357b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 7367b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 7377b5038d7SDag-Erling Smørgrav DSA_free(dsa); 7387b5038d7SDag-Erling Smørgrav return NULL; 7397b5038d7SDag-Erling Smørgrav } 7407b5038d7SDag-Erling Smørgrav 7417b5038d7SDag-Erling Smørgrav unsigned char * 7427b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_hmac(FILE *f, size_t *hmac_size) 7437b5038d7SDag-Erling Smørgrav { 7447b5038d7SDag-Erling Smørgrav return ldns_key_new_frm_fp_hmac_l(f, NULL, hmac_size); 7457b5038d7SDag-Erling Smørgrav } 7467b5038d7SDag-Erling Smørgrav 7477b5038d7SDag-Erling Smørgrav unsigned char * 7487b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_hmac_l( FILE *f 7497b5038d7SDag-Erling Smørgrav , ATTR_UNUSED(int *line_nr) 7507b5038d7SDag-Erling Smørgrav , size_t *hmac_size 7517b5038d7SDag-Erling Smørgrav ) 7527b5038d7SDag-Erling Smørgrav { 753*2787e39aSDag-Erling Smørgrav size_t i, bufsz; 754*2787e39aSDag-Erling Smørgrav char d[LDNS_MAX_LINELEN]; 755*2787e39aSDag-Erling Smørgrav unsigned char *buf = NULL; 7567b5038d7SDag-Erling Smørgrav 7577b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 7587b5038d7SDag-Erling Smørgrav goto error; 7597b5038d7SDag-Erling Smørgrav } 760*2787e39aSDag-Erling Smørgrav bufsz = ldns_b64_ntop_calculate_size(strlen(d)); 761*2787e39aSDag-Erling Smørgrav buf = LDNS_XMALLOC(unsigned char, bufsz); 762*2787e39aSDag-Erling Smørgrav i = (size_t) ldns_b64_pton((const char*)d, buf, bufsz); 7637b5038d7SDag-Erling Smørgrav 7647b5038d7SDag-Erling Smørgrav *hmac_size = i; 7657b5038d7SDag-Erling Smørgrav return buf; 7667b5038d7SDag-Erling Smørgrav 7677b5038d7SDag-Erling Smørgrav error: 7687b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 7697b5038d7SDag-Erling Smørgrav *hmac_size = 0; 7707b5038d7SDag-Erling Smørgrav return NULL; 7717b5038d7SDag-Erling Smørgrav } 7727b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 7737b5038d7SDag-Erling Smørgrav 7747b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 7757b5038d7SDag-Erling Smørgrav static EVP_PKEY* 7767b5038d7SDag-Erling Smørgrav ldns_gen_gost_key(void) 7777b5038d7SDag-Erling Smørgrav { 7787b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX* ctx; 7797b5038d7SDag-Erling Smørgrav EVP_PKEY* p = NULL; 7807b5038d7SDag-Erling Smørgrav int gost_id = ldns_key_EVP_load_gost_id(); 7817b5038d7SDag-Erling Smørgrav if(!gost_id) 7827b5038d7SDag-Erling Smørgrav return NULL; 7837b5038d7SDag-Erling Smørgrav ctx = EVP_PKEY_CTX_new_id(gost_id, NULL); 7847b5038d7SDag-Erling Smørgrav if(!ctx) { 7857b5038d7SDag-Erling Smørgrav /* the id should be available now */ 7867b5038d7SDag-Erling Smørgrav return NULL; 7877b5038d7SDag-Erling Smørgrav } 7887b5038d7SDag-Erling Smørgrav if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) { 7897b5038d7SDag-Erling Smørgrav /* cannot set paramset */ 7907b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX_free(ctx); 7917b5038d7SDag-Erling Smørgrav return NULL; 7927b5038d7SDag-Erling Smørgrav } 7937b5038d7SDag-Erling Smørgrav 7947b5038d7SDag-Erling Smørgrav if(EVP_PKEY_keygen_init(ctx) <= 0) { 7957b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX_free(ctx); 7967b5038d7SDag-Erling Smørgrav return NULL; 7977b5038d7SDag-Erling Smørgrav } 7987b5038d7SDag-Erling Smørgrav if(EVP_PKEY_keygen(ctx, &p) <= 0) { 7997b5038d7SDag-Erling Smørgrav EVP_PKEY_free(p); 8007b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX_free(ctx); 8017b5038d7SDag-Erling Smørgrav return NULL; 8027b5038d7SDag-Erling Smørgrav } 8037b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX_free(ctx); 8047b5038d7SDag-Erling Smørgrav return p; 8057b5038d7SDag-Erling Smørgrav } 8067b5038d7SDag-Erling Smørgrav #endif 8077b5038d7SDag-Erling Smørgrav 8087b5038d7SDag-Erling Smørgrav ldns_key * 8097b5038d7SDag-Erling Smørgrav ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) 8107b5038d7SDag-Erling Smørgrav { 8117b5038d7SDag-Erling Smørgrav ldns_key *k; 8127b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 8137b5038d7SDag-Erling Smørgrav DSA *d; 8147b5038d7SDag-Erling Smørgrav RSA *r; 8157b5038d7SDag-Erling Smørgrav # ifdef USE_ECDSA 8167b5038d7SDag-Erling Smørgrav EC_KEY *ec = NULL; 8177b5038d7SDag-Erling Smørgrav # endif 8187b5038d7SDag-Erling Smørgrav #else 8197b5038d7SDag-Erling Smørgrav int i; 8207b5038d7SDag-Erling Smørgrav uint16_t offset = 0; 8217b5038d7SDag-Erling Smørgrav #endif 8227b5038d7SDag-Erling Smørgrav unsigned char *hmac; 8237b5038d7SDag-Erling Smørgrav 8247b5038d7SDag-Erling Smørgrav k = ldns_key_new(); 8257b5038d7SDag-Erling Smørgrav if (!k) { 8267b5038d7SDag-Erling Smørgrav return NULL; 8277b5038d7SDag-Erling Smørgrav } 8287b5038d7SDag-Erling Smørgrav switch(alg) { 8297b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSAMD5: 8307b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1: 8317b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1_NSEC3: 8327b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA256: 8337b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA512: 8347b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 8357b5038d7SDag-Erling Smørgrav r = RSA_generate_key((int)size, RSA_F4, NULL, NULL); 8367b5038d7SDag-Erling Smørgrav if(!r) { 8377b5038d7SDag-Erling Smørgrav ldns_key_free(k); 8387b5038d7SDag-Erling Smørgrav return NULL; 8397b5038d7SDag-Erling Smørgrav } 8407b5038d7SDag-Erling Smørgrav if (RSA_check_key(r) != 1) { 8417b5038d7SDag-Erling Smørgrav ldns_key_free(k); 8427b5038d7SDag-Erling Smørgrav return NULL; 8437b5038d7SDag-Erling Smørgrav } 8447b5038d7SDag-Erling Smørgrav ldns_key_set_rsa_key(k, r); 845*2787e39aSDag-Erling Smørgrav RSA_free(r); 8467b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 8477b5038d7SDag-Erling Smørgrav break; 8487b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA: 8497b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA_NSEC3: 8507b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 8517b5038d7SDag-Erling Smørgrav d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL); 8527b5038d7SDag-Erling Smørgrav if (!d) { 8537b5038d7SDag-Erling Smørgrav ldns_key_free(k); 8547b5038d7SDag-Erling Smørgrav return NULL; 8557b5038d7SDag-Erling Smørgrav } 8567b5038d7SDag-Erling Smørgrav if (DSA_generate_key(d) != 1) { 8577b5038d7SDag-Erling Smørgrav ldns_key_free(k); 8587b5038d7SDag-Erling Smørgrav return NULL; 8597b5038d7SDag-Erling Smørgrav } 8607b5038d7SDag-Erling Smørgrav ldns_key_set_dsa_key(k, d); 861*2787e39aSDag-Erling Smørgrav DSA_free(d); 8627b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 8637b5038d7SDag-Erling Smørgrav break; 8647b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACMD5: 8657b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA1: 8667b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA256: 8677b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 8687b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 8697b5038d7SDag-Erling Smørgrav k->_key.key = NULL; 8707b5038d7SDag-Erling Smørgrav #endif /* splint */ 8717b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 8727b5038d7SDag-Erling Smørgrav size = size / 8; 8737b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_size(k, size); 8747b5038d7SDag-Erling Smørgrav 8757b5038d7SDag-Erling Smørgrav hmac = LDNS_XMALLOC(unsigned char, size); 8767b5038d7SDag-Erling Smørgrav if(!hmac) { 8777b5038d7SDag-Erling Smørgrav ldns_key_free(k); 8787b5038d7SDag-Erling Smørgrav return NULL; 8797b5038d7SDag-Erling Smørgrav } 8807b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 8817b5038d7SDag-Erling Smørgrav if (RAND_bytes(hmac, (int) size) != 1) { 8827b5038d7SDag-Erling Smørgrav LDNS_FREE(hmac); 8837b5038d7SDag-Erling Smørgrav ldns_key_free(k); 8847b5038d7SDag-Erling Smørgrav return NULL; 8857b5038d7SDag-Erling Smørgrav } 8867b5038d7SDag-Erling Smørgrav #else 8877b5038d7SDag-Erling Smørgrav while (offset + sizeof(i) < size) { 8887b5038d7SDag-Erling Smørgrav i = random(); 8897b5038d7SDag-Erling Smørgrav memcpy(&hmac[offset], &i, sizeof(i)); 8907b5038d7SDag-Erling Smørgrav offset += sizeof(i); 8917b5038d7SDag-Erling Smørgrav } 8927b5038d7SDag-Erling Smørgrav if (offset < size) { 8937b5038d7SDag-Erling Smørgrav i = random(); 8947b5038d7SDag-Erling Smørgrav memcpy(&hmac[offset], &i, size - offset); 8957b5038d7SDag-Erling Smørgrav } 8967b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 8977b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_key(k, hmac); 8987b5038d7SDag-Erling Smørgrav 8997b5038d7SDag-Erling Smørgrav ldns_key_set_flags(k, 0); 9007b5038d7SDag-Erling Smørgrav break; 9017b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECC_GOST: 9027b5038d7SDag-Erling Smørgrav #if defined(HAVE_SSL) && defined(USE_GOST) 9037b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(k, ldns_gen_gost_key()); 9047b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 9057b5038d7SDag-Erling Smørgrav if(!k->_key.key) { 9067b5038d7SDag-Erling Smørgrav ldns_key_free(k); 9077b5038d7SDag-Erling Smørgrav return NULL; 9087b5038d7SDag-Erling Smørgrav } 9097b5038d7SDag-Erling Smørgrav #endif /* splint */ 9107b5038d7SDag-Erling Smørgrav #else 9117b5038d7SDag-Erling Smørgrav ldns_key_free(k); 9127b5038d7SDag-Erling Smørgrav return NULL; 9137b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL and USE_GOST */ 9147b5038d7SDag-Erling Smørgrav break; 9157b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP256SHA256: 9167b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP384SHA384: 9177b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 9187b5038d7SDag-Erling Smørgrav if(alg == LDNS_SIGN_ECDSAP256SHA256) 9197b5038d7SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 9207b5038d7SDag-Erling Smørgrav else if(alg == LDNS_SIGN_ECDSAP384SHA384) 9217b5038d7SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_secp384r1); 9227b5038d7SDag-Erling Smørgrav if(!ec) { 9237b5038d7SDag-Erling Smørgrav ldns_key_free(k); 9247b5038d7SDag-Erling Smørgrav return NULL; 9257b5038d7SDag-Erling Smørgrav } 9267b5038d7SDag-Erling Smørgrav if(!EC_KEY_generate_key(ec)) { 9277b5038d7SDag-Erling Smørgrav ldns_key_free(k); 9287b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 9297b5038d7SDag-Erling Smørgrav return NULL; 9307b5038d7SDag-Erling Smørgrav } 9317b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 9327b5038d7SDag-Erling Smørgrav k->_key.key = EVP_PKEY_new(); 9337b5038d7SDag-Erling Smørgrav if(!k->_key.key) { 9347b5038d7SDag-Erling Smørgrav ldns_key_free(k); 9357b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 9367b5038d7SDag-Erling Smørgrav return NULL; 9377b5038d7SDag-Erling Smørgrav } 9387b5038d7SDag-Erling Smørgrav if (!EVP_PKEY_assign_EC_KEY(k->_key.key, ec)) { 9397b5038d7SDag-Erling Smørgrav ldns_key_free(k); 9407b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 9417b5038d7SDag-Erling Smørgrav return NULL; 9427b5038d7SDag-Erling Smørgrav } 9437b5038d7SDag-Erling Smørgrav #endif /* splint */ 9447b5038d7SDag-Erling Smørgrav #else 9457b5038d7SDag-Erling Smørgrav ldns_key_free(k); 9467b5038d7SDag-Erling Smørgrav return NULL; 9477b5038d7SDag-Erling Smørgrav #endif /* ECDSA */ 9487b5038d7SDag-Erling Smørgrav break; 9497b5038d7SDag-Erling Smørgrav } 9507b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 9517b5038d7SDag-Erling Smørgrav return k; 9527b5038d7SDag-Erling Smørgrav } 9537b5038d7SDag-Erling Smørgrav 9547b5038d7SDag-Erling Smørgrav void 9557b5038d7SDag-Erling Smørgrav ldns_key_print(FILE *output, const ldns_key *k) 9567b5038d7SDag-Erling Smørgrav { 9577b5038d7SDag-Erling Smørgrav char *str = ldns_key2str(k); 9587b5038d7SDag-Erling Smørgrav if (str) { 9597b5038d7SDag-Erling Smørgrav fprintf(output, "%s", str); 9607b5038d7SDag-Erling Smørgrav } else { 9617b5038d7SDag-Erling Smørgrav fprintf(output, "Unable to convert private key to string\n"); 9627b5038d7SDag-Erling Smørgrav } 9637b5038d7SDag-Erling Smørgrav LDNS_FREE(str); 9647b5038d7SDag-Erling Smørgrav } 9657b5038d7SDag-Erling Smørgrav 9667b5038d7SDag-Erling Smørgrav 9677b5038d7SDag-Erling Smørgrav void 9687b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l) 9697b5038d7SDag-Erling Smørgrav { 9707b5038d7SDag-Erling Smørgrav k->_alg = l; 9717b5038d7SDag-Erling Smørgrav } 9727b5038d7SDag-Erling Smørgrav 9737b5038d7SDag-Erling Smørgrav void 9747b5038d7SDag-Erling Smørgrav ldns_key_set_flags(ldns_key *k, uint16_t f) 9757b5038d7SDag-Erling Smørgrav { 9767b5038d7SDag-Erling Smørgrav k->_extra.dnssec.flags = f; 9777b5038d7SDag-Erling Smørgrav } 9787b5038d7SDag-Erling Smørgrav 9797b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 9807b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 9817b5038d7SDag-Erling Smørgrav void 9827b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e) 9837b5038d7SDag-Erling Smørgrav { 9847b5038d7SDag-Erling Smørgrav k->_key.key = e; 9857b5038d7SDag-Erling Smørgrav } 9867b5038d7SDag-Erling Smørgrav 9877b5038d7SDag-Erling Smørgrav void 9887b5038d7SDag-Erling Smørgrav ldns_key_set_rsa_key(ldns_key *k, RSA *r) 9897b5038d7SDag-Erling Smørgrav { 9907b5038d7SDag-Erling Smørgrav EVP_PKEY *key = EVP_PKEY_new(); 9917b5038d7SDag-Erling Smørgrav EVP_PKEY_set1_RSA(key, r); 9927b5038d7SDag-Erling Smørgrav k->_key.key = key; 9937b5038d7SDag-Erling Smørgrav } 9947b5038d7SDag-Erling Smørgrav 9957b5038d7SDag-Erling Smørgrav void 9967b5038d7SDag-Erling Smørgrav ldns_key_set_dsa_key(ldns_key *k, DSA *d) 9977b5038d7SDag-Erling Smørgrav { 9987b5038d7SDag-Erling Smørgrav EVP_PKEY *key = EVP_PKEY_new(); 9997b5038d7SDag-Erling Smørgrav EVP_PKEY_set1_DSA(key, d); 10007b5038d7SDag-Erling Smørgrav k->_key.key = key; 10017b5038d7SDag-Erling Smørgrav } 1002*2787e39aSDag-Erling Smørgrav 1003*2787e39aSDag-Erling Smørgrav void 1004*2787e39aSDag-Erling Smørgrav ldns_key_assign_rsa_key(ldns_key *k, RSA *r) 1005*2787e39aSDag-Erling Smørgrav { 1006*2787e39aSDag-Erling Smørgrav EVP_PKEY *key = EVP_PKEY_new(); 1007*2787e39aSDag-Erling Smørgrav EVP_PKEY_assign_RSA(key, r); 1008*2787e39aSDag-Erling Smørgrav k->_key.key = key; 1009*2787e39aSDag-Erling Smørgrav } 1010*2787e39aSDag-Erling Smørgrav 1011*2787e39aSDag-Erling Smørgrav void 1012*2787e39aSDag-Erling Smørgrav ldns_key_assign_dsa_key(ldns_key *k, DSA *d) 1013*2787e39aSDag-Erling Smørgrav { 1014*2787e39aSDag-Erling Smørgrav EVP_PKEY *key = EVP_PKEY_new(); 1015*2787e39aSDag-Erling Smørgrav EVP_PKEY_assign_DSA(key, d); 1016*2787e39aSDag-Erling Smørgrav k->_key.key = key; 1017*2787e39aSDag-Erling Smørgrav } 10187b5038d7SDag-Erling Smørgrav #endif /* splint */ 10197b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 10207b5038d7SDag-Erling Smørgrav 10217b5038d7SDag-Erling Smørgrav void 10227b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac) 10237b5038d7SDag-Erling Smørgrav { 10247b5038d7SDag-Erling Smørgrav k->_key.hmac.key = hmac; 10257b5038d7SDag-Erling Smørgrav } 10267b5038d7SDag-Erling Smørgrav 10277b5038d7SDag-Erling Smørgrav void 10287b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size) 10297b5038d7SDag-Erling Smørgrav { 10307b5038d7SDag-Erling Smørgrav k->_key.hmac.size = hmac_size; 10317b5038d7SDag-Erling Smørgrav } 10327b5038d7SDag-Erling Smørgrav 10337b5038d7SDag-Erling Smørgrav void 10347b5038d7SDag-Erling Smørgrav ldns_key_set_external_key(ldns_key *k, void *external_key) 10357b5038d7SDag-Erling Smørgrav { 10367b5038d7SDag-Erling Smørgrav k->_key.external_key = external_key; 10377b5038d7SDag-Erling Smørgrav } 10387b5038d7SDag-Erling Smørgrav 10397b5038d7SDag-Erling Smørgrav void 10407b5038d7SDag-Erling Smørgrav ldns_key_set_origttl(ldns_key *k, uint32_t t) 10417b5038d7SDag-Erling Smørgrav { 10427b5038d7SDag-Erling Smørgrav k->_extra.dnssec.orig_ttl = t; 10437b5038d7SDag-Erling Smørgrav } 10447b5038d7SDag-Erling Smørgrav 10457b5038d7SDag-Erling Smørgrav void 10467b5038d7SDag-Erling Smørgrav ldns_key_set_inception(ldns_key *k, uint32_t i) 10477b5038d7SDag-Erling Smørgrav { 10487b5038d7SDag-Erling Smørgrav k->_extra.dnssec.inception = i; 10497b5038d7SDag-Erling Smørgrav } 10507b5038d7SDag-Erling Smørgrav 10517b5038d7SDag-Erling Smørgrav void 10527b5038d7SDag-Erling Smørgrav ldns_key_set_expiration(ldns_key *k, uint32_t e) 10537b5038d7SDag-Erling Smørgrav { 10547b5038d7SDag-Erling Smørgrav k->_extra.dnssec.expiration = e; 10557b5038d7SDag-Erling Smørgrav } 10567b5038d7SDag-Erling Smørgrav 10577b5038d7SDag-Erling Smørgrav void 10587b5038d7SDag-Erling Smørgrav ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r) 10597b5038d7SDag-Erling Smørgrav { 10607b5038d7SDag-Erling Smørgrav k->_pubkey_owner = r; 10617b5038d7SDag-Erling Smørgrav } 10627b5038d7SDag-Erling Smørgrav 10637b5038d7SDag-Erling Smørgrav void 10647b5038d7SDag-Erling Smørgrav ldns_key_set_keytag(ldns_key *k, uint16_t tag) 10657b5038d7SDag-Erling Smørgrav { 10667b5038d7SDag-Erling Smørgrav k->_extra.dnssec.keytag = tag; 10677b5038d7SDag-Erling Smørgrav } 10687b5038d7SDag-Erling Smørgrav 10697b5038d7SDag-Erling Smørgrav /* read */ 10707b5038d7SDag-Erling Smørgrav size_t 10717b5038d7SDag-Erling Smørgrav ldns_key_list_key_count(const ldns_key_list *key_list) 10727b5038d7SDag-Erling Smørgrav { 10737b5038d7SDag-Erling Smørgrav return key_list->_key_count; 10747b5038d7SDag-Erling Smørgrav } 10757b5038d7SDag-Erling Smørgrav 10767b5038d7SDag-Erling Smørgrav ldns_key * 10777b5038d7SDag-Erling Smørgrav ldns_key_list_key(const ldns_key_list *key, size_t nr) 10787b5038d7SDag-Erling Smørgrav { 10797b5038d7SDag-Erling Smørgrav if (nr < ldns_key_list_key_count(key)) { 10807b5038d7SDag-Erling Smørgrav return key->_keys[nr]; 10817b5038d7SDag-Erling Smørgrav } else { 10827b5038d7SDag-Erling Smørgrav return NULL; 10837b5038d7SDag-Erling Smørgrav } 10847b5038d7SDag-Erling Smørgrav } 10857b5038d7SDag-Erling Smørgrav 10867b5038d7SDag-Erling Smørgrav ldns_signing_algorithm 10877b5038d7SDag-Erling Smørgrav ldns_key_algorithm(const ldns_key *k) 10887b5038d7SDag-Erling Smørgrav { 10897b5038d7SDag-Erling Smørgrav return k->_alg; 10907b5038d7SDag-Erling Smørgrav } 10917b5038d7SDag-Erling Smørgrav 10927b5038d7SDag-Erling Smørgrav void 10937b5038d7SDag-Erling Smørgrav ldns_key_set_use(ldns_key *k, bool v) 10947b5038d7SDag-Erling Smørgrav { 10957b5038d7SDag-Erling Smørgrav if (k) { 10967b5038d7SDag-Erling Smørgrav k->_use = v; 10977b5038d7SDag-Erling Smørgrav } 10987b5038d7SDag-Erling Smørgrav } 10997b5038d7SDag-Erling Smørgrav 11007b5038d7SDag-Erling Smørgrav bool 11017b5038d7SDag-Erling Smørgrav ldns_key_use(const ldns_key *k) 11027b5038d7SDag-Erling Smørgrav { 11037b5038d7SDag-Erling Smørgrav if (k) { 11047b5038d7SDag-Erling Smørgrav return k->_use; 11057b5038d7SDag-Erling Smørgrav } 11067b5038d7SDag-Erling Smørgrav return false; 11077b5038d7SDag-Erling Smørgrav } 11087b5038d7SDag-Erling Smørgrav 11097b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 11107b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 11117b5038d7SDag-Erling Smørgrav EVP_PKEY * 11127b5038d7SDag-Erling Smørgrav ldns_key_evp_key(const ldns_key *k) 11137b5038d7SDag-Erling Smørgrav { 11147b5038d7SDag-Erling Smørgrav return k->_key.key; 11157b5038d7SDag-Erling Smørgrav } 11167b5038d7SDag-Erling Smørgrav 11177b5038d7SDag-Erling Smørgrav RSA * 11187b5038d7SDag-Erling Smørgrav ldns_key_rsa_key(const ldns_key *k) 11197b5038d7SDag-Erling Smørgrav { 11207b5038d7SDag-Erling Smørgrav if (k->_key.key) { 11217b5038d7SDag-Erling Smørgrav return EVP_PKEY_get1_RSA(k->_key.key); 11227b5038d7SDag-Erling Smørgrav } else { 11237b5038d7SDag-Erling Smørgrav return NULL; 11247b5038d7SDag-Erling Smørgrav } 11257b5038d7SDag-Erling Smørgrav } 11267b5038d7SDag-Erling Smørgrav 11277b5038d7SDag-Erling Smørgrav DSA * 11287b5038d7SDag-Erling Smørgrav ldns_key_dsa_key(const ldns_key *k) 11297b5038d7SDag-Erling Smørgrav { 11307b5038d7SDag-Erling Smørgrav if (k->_key.key) { 11317b5038d7SDag-Erling Smørgrav return EVP_PKEY_get1_DSA(k->_key.key); 11327b5038d7SDag-Erling Smørgrav } else { 11337b5038d7SDag-Erling Smørgrav return NULL; 11347b5038d7SDag-Erling Smørgrav } 11357b5038d7SDag-Erling Smørgrav } 11367b5038d7SDag-Erling Smørgrav #endif /* splint */ 11377b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 11387b5038d7SDag-Erling Smørgrav 11397b5038d7SDag-Erling Smørgrav unsigned char * 11407b5038d7SDag-Erling Smørgrav ldns_key_hmac_key(const ldns_key *k) 11417b5038d7SDag-Erling Smørgrav { 11427b5038d7SDag-Erling Smørgrav if (k->_key.hmac.key) { 11437b5038d7SDag-Erling Smørgrav return k->_key.hmac.key; 11447b5038d7SDag-Erling Smørgrav } else { 11457b5038d7SDag-Erling Smørgrav return NULL; 11467b5038d7SDag-Erling Smørgrav } 11477b5038d7SDag-Erling Smørgrav } 11487b5038d7SDag-Erling Smørgrav 11497b5038d7SDag-Erling Smørgrav size_t 11507b5038d7SDag-Erling Smørgrav ldns_key_hmac_size(const ldns_key *k) 11517b5038d7SDag-Erling Smørgrav { 11527b5038d7SDag-Erling Smørgrav if (k->_key.hmac.size) { 11537b5038d7SDag-Erling Smørgrav return k->_key.hmac.size; 11547b5038d7SDag-Erling Smørgrav } else { 11557b5038d7SDag-Erling Smørgrav return 0; 11567b5038d7SDag-Erling Smørgrav } 11577b5038d7SDag-Erling Smørgrav } 11587b5038d7SDag-Erling Smørgrav 11597b5038d7SDag-Erling Smørgrav void * 11607b5038d7SDag-Erling Smørgrav ldns_key_external_key(const ldns_key *k) 11617b5038d7SDag-Erling Smørgrav { 11627b5038d7SDag-Erling Smørgrav return k->_key.external_key; 11637b5038d7SDag-Erling Smørgrav } 11647b5038d7SDag-Erling Smørgrav 11657b5038d7SDag-Erling Smørgrav uint32_t 11667b5038d7SDag-Erling Smørgrav ldns_key_origttl(const ldns_key *k) 11677b5038d7SDag-Erling Smørgrav { 11687b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.orig_ttl; 11697b5038d7SDag-Erling Smørgrav } 11707b5038d7SDag-Erling Smørgrav 11717b5038d7SDag-Erling Smørgrav uint16_t 11727b5038d7SDag-Erling Smørgrav ldns_key_flags(const ldns_key *k) 11737b5038d7SDag-Erling Smørgrav { 11747b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.flags; 11757b5038d7SDag-Erling Smørgrav } 11767b5038d7SDag-Erling Smørgrav 11777b5038d7SDag-Erling Smørgrav uint32_t 11787b5038d7SDag-Erling Smørgrav ldns_key_inception(const ldns_key *k) 11797b5038d7SDag-Erling Smørgrav { 11807b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.inception; 11817b5038d7SDag-Erling Smørgrav } 11827b5038d7SDag-Erling Smørgrav 11837b5038d7SDag-Erling Smørgrav uint32_t 11847b5038d7SDag-Erling Smørgrav ldns_key_expiration(const ldns_key *k) 11857b5038d7SDag-Erling Smørgrav { 11867b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.expiration; 11877b5038d7SDag-Erling Smørgrav } 11887b5038d7SDag-Erling Smørgrav 11897b5038d7SDag-Erling Smørgrav uint16_t 11907b5038d7SDag-Erling Smørgrav ldns_key_keytag(const ldns_key *k) 11917b5038d7SDag-Erling Smørgrav { 11927b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.keytag; 11937b5038d7SDag-Erling Smørgrav } 11947b5038d7SDag-Erling Smørgrav 11957b5038d7SDag-Erling Smørgrav ldns_rdf * 11967b5038d7SDag-Erling Smørgrav ldns_key_pubkey_owner(const ldns_key *k) 11977b5038d7SDag-Erling Smørgrav { 11987b5038d7SDag-Erling Smørgrav return k->_pubkey_owner; 11997b5038d7SDag-Erling Smørgrav } 12007b5038d7SDag-Erling Smørgrav 12017b5038d7SDag-Erling Smørgrav /* write */ 12027b5038d7SDag-Erling Smørgrav void 12037b5038d7SDag-Erling Smørgrav ldns_key_list_set_use(ldns_key_list *keys, bool v) 12047b5038d7SDag-Erling Smørgrav { 12057b5038d7SDag-Erling Smørgrav size_t i; 12067b5038d7SDag-Erling Smørgrav 12077b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_key_list_key_count(keys); i++) { 12087b5038d7SDag-Erling Smørgrav ldns_key_set_use(ldns_key_list_key(keys, i), v); 12097b5038d7SDag-Erling Smørgrav } 12107b5038d7SDag-Erling Smørgrav } 12117b5038d7SDag-Erling Smørgrav 12127b5038d7SDag-Erling Smørgrav void 12137b5038d7SDag-Erling Smørgrav ldns_key_list_set_key_count(ldns_key_list *key, size_t count) 12147b5038d7SDag-Erling Smørgrav { 12157b5038d7SDag-Erling Smørgrav key->_key_count = count; 12167b5038d7SDag-Erling Smørgrav } 12177b5038d7SDag-Erling Smørgrav 12187b5038d7SDag-Erling Smørgrav bool 12197b5038d7SDag-Erling Smørgrav ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key) 12207b5038d7SDag-Erling Smørgrav { 12217b5038d7SDag-Erling Smørgrav size_t key_count; 12227b5038d7SDag-Erling Smørgrav ldns_key **keys; 12237b5038d7SDag-Erling Smørgrav 12247b5038d7SDag-Erling Smørgrav key_count = ldns_key_list_key_count(key_list); 12257b5038d7SDag-Erling Smørgrav 12267b5038d7SDag-Erling Smørgrav /* grow the array */ 12277b5038d7SDag-Erling Smørgrav keys = LDNS_XREALLOC( 12287b5038d7SDag-Erling Smørgrav key_list->_keys, ldns_key *, key_count + 1); 12297b5038d7SDag-Erling Smørgrav if (!keys) { 12307b5038d7SDag-Erling Smørgrav return false; 12317b5038d7SDag-Erling Smørgrav } 12327b5038d7SDag-Erling Smørgrav 12337b5038d7SDag-Erling Smørgrav /* add the new member */ 12347b5038d7SDag-Erling Smørgrav key_list->_keys = keys; 12357b5038d7SDag-Erling Smørgrav key_list->_keys[key_count] = key; 12367b5038d7SDag-Erling Smørgrav 12377b5038d7SDag-Erling Smørgrav ldns_key_list_set_key_count(key_list, key_count + 1); 12387b5038d7SDag-Erling Smørgrav return true; 12397b5038d7SDag-Erling Smørgrav } 12407b5038d7SDag-Erling Smørgrav 12417b5038d7SDag-Erling Smørgrav ldns_key * 12427b5038d7SDag-Erling Smørgrav ldns_key_list_pop_key(ldns_key_list *key_list) 12437b5038d7SDag-Erling Smørgrav { 12447b5038d7SDag-Erling Smørgrav size_t key_count; 12457b5038d7SDag-Erling Smørgrav ldns_key** a; 12467b5038d7SDag-Erling Smørgrav ldns_key *pop; 12477b5038d7SDag-Erling Smørgrav 12487b5038d7SDag-Erling Smørgrav if (!key_list) { 12497b5038d7SDag-Erling Smørgrav return NULL; 12507b5038d7SDag-Erling Smørgrav } 12517b5038d7SDag-Erling Smørgrav 12527b5038d7SDag-Erling Smørgrav key_count = ldns_key_list_key_count(key_list); 12537b5038d7SDag-Erling Smørgrav if (key_count == 0) { 12547b5038d7SDag-Erling Smørgrav return NULL; 12557b5038d7SDag-Erling Smørgrav } 12567b5038d7SDag-Erling Smørgrav 12577b5038d7SDag-Erling Smørgrav pop = ldns_key_list_key(key_list, key_count); 12587b5038d7SDag-Erling Smørgrav 12597b5038d7SDag-Erling Smørgrav /* shrink the array */ 12607b5038d7SDag-Erling Smørgrav a = LDNS_XREALLOC(key_list->_keys, ldns_key *, key_count - 1); 12617b5038d7SDag-Erling Smørgrav if(a) { 12627b5038d7SDag-Erling Smørgrav key_list->_keys = a; 12637b5038d7SDag-Erling Smørgrav } 12647b5038d7SDag-Erling Smørgrav 12657b5038d7SDag-Erling Smørgrav ldns_key_list_set_key_count(key_list, key_count - 1); 12667b5038d7SDag-Erling Smørgrav 12677b5038d7SDag-Erling Smørgrav return pop; 12687b5038d7SDag-Erling Smørgrav } 12697b5038d7SDag-Erling Smørgrav 12707b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 12717b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 12727b5038d7SDag-Erling Smørgrav /* data pointer must be large enough (LDNS_MAX_KEYLEN) */ 12737b5038d7SDag-Erling Smørgrav static bool 12747b5038d7SDag-Erling Smørgrav ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size) 12757b5038d7SDag-Erling Smørgrav { 12767b5038d7SDag-Erling Smørgrav int i,j; 12777b5038d7SDag-Erling Smørgrav 12787b5038d7SDag-Erling Smørgrav if (!k) { 12797b5038d7SDag-Erling Smørgrav return false; 12807b5038d7SDag-Erling Smørgrav } 12817b5038d7SDag-Erling Smørgrav 12827b5038d7SDag-Erling Smørgrav if (BN_num_bytes(k->e) <= 256) { 12837b5038d7SDag-Erling Smørgrav /* normally only this path is executed (small factors are 12847b5038d7SDag-Erling Smørgrav * more common 12857b5038d7SDag-Erling Smørgrav */ 12867b5038d7SDag-Erling Smørgrav data[0] = (unsigned char) BN_num_bytes(k->e); 12877b5038d7SDag-Erling Smørgrav i = BN_bn2bin(k->e, data + 1); 12887b5038d7SDag-Erling Smørgrav j = BN_bn2bin(k->n, data + i + 1); 12897b5038d7SDag-Erling Smørgrav *size = (uint16_t) i + j; 12907b5038d7SDag-Erling Smørgrav } else if (BN_num_bytes(k->e) <= 65536) { 12917b5038d7SDag-Erling Smørgrav data[0] = 0; 12927b5038d7SDag-Erling Smørgrav /* BN_bn2bin does bigendian, _uint16 also */ 12937b5038d7SDag-Erling Smørgrav ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(k->e)); 12947b5038d7SDag-Erling Smørgrav 12957b5038d7SDag-Erling Smørgrav BN_bn2bin(k->e, data + 3); 12967b5038d7SDag-Erling Smørgrav BN_bn2bin(k->n, data + 4 + BN_num_bytes(k->e)); 12977b5038d7SDag-Erling Smørgrav *size = (uint16_t) BN_num_bytes(k->n) + 6; 12987b5038d7SDag-Erling Smørgrav } else { 12997b5038d7SDag-Erling Smørgrav return false; 13007b5038d7SDag-Erling Smørgrav } 13017b5038d7SDag-Erling Smørgrav return true; 13027b5038d7SDag-Erling Smørgrav } 13037b5038d7SDag-Erling Smørgrav 13047b5038d7SDag-Erling Smørgrav /* data pointer must be large enough (LDNS_MAX_KEYLEN) */ 13057b5038d7SDag-Erling Smørgrav static bool 13067b5038d7SDag-Erling Smørgrav ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size) 13077b5038d7SDag-Erling Smørgrav { 13087b5038d7SDag-Erling Smørgrav uint8_t T; 13097b5038d7SDag-Erling Smørgrav 13107b5038d7SDag-Erling Smørgrav if (!k) { 13117b5038d7SDag-Erling Smørgrav return false; 13127b5038d7SDag-Erling Smørgrav } 13137b5038d7SDag-Erling Smørgrav 13147b5038d7SDag-Erling Smørgrav /* See RFC2536 */ 1315*2787e39aSDag-Erling Smørgrav *size = (uint16_t)BN_num_bytes(k->p); 13167b5038d7SDag-Erling Smørgrav T = (*size - 64) / 8; 13177b5038d7SDag-Erling Smørgrav memcpy(data, &T, 1); 13187b5038d7SDag-Erling Smørgrav 13197b5038d7SDag-Erling Smørgrav if (T > 8) { 13207b5038d7SDag-Erling Smørgrav fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)"); 13217b5038d7SDag-Erling Smørgrav fprintf(stderr, " not implemented\n"); 13227b5038d7SDag-Erling Smørgrav return false; 13237b5038d7SDag-Erling Smørgrav } 13247b5038d7SDag-Erling Smørgrav 13257b5038d7SDag-Erling Smørgrav /* size = 64 + (T * 8); */ 13267b5038d7SDag-Erling Smørgrav data[0] = (unsigned char)T; 13277b5038d7SDag-Erling Smørgrav BN_bn2bin(k->q, data + 1 ); /* 20 octects */ 13287b5038d7SDag-Erling Smørgrav BN_bn2bin(k->p, data + 21 ); /* offset octects */ 13297b5038d7SDag-Erling Smørgrav BN_bn2bin(k->g, data + 21 + *size); /* offset octets */ 13307b5038d7SDag-Erling Smørgrav BN_bn2bin(k->pub_key, data + 21 + *size + *size); /* offset octets */ 13317b5038d7SDag-Erling Smørgrav *size = 21 + (*size * 3); 13327b5038d7SDag-Erling Smørgrav return true; 13337b5038d7SDag-Erling Smørgrav } 13347b5038d7SDag-Erling Smørgrav 13357b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 13367b5038d7SDag-Erling Smørgrav static bool 13377b5038d7SDag-Erling Smørgrav ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size) 13387b5038d7SDag-Erling Smørgrav { 13397b5038d7SDag-Erling Smørgrav int i; 13407b5038d7SDag-Erling Smørgrav unsigned char* pp = NULL; 13417b5038d7SDag-Erling Smørgrav if(i2d_PUBKEY(k, &pp) != 37 + 64) { 13427b5038d7SDag-Erling Smørgrav /* expect 37 byte(ASN header) and 64 byte(X and Y) */ 13437b5038d7SDag-Erling Smørgrav CRYPTO_free(pp); 13447b5038d7SDag-Erling Smørgrav return false; 13457b5038d7SDag-Erling Smørgrav } 13467b5038d7SDag-Erling Smørgrav /* omit ASN header */ 13477b5038d7SDag-Erling Smørgrav for(i=0; i<64; i++) 13487b5038d7SDag-Erling Smørgrav data[i] = pp[i+37]; 13497b5038d7SDag-Erling Smørgrav CRYPTO_free(pp); 13507b5038d7SDag-Erling Smørgrav *size = 64; 13517b5038d7SDag-Erling Smørgrav return true; 13527b5038d7SDag-Erling Smørgrav } 13537b5038d7SDag-Erling Smørgrav #endif /* USE_GOST */ 13547b5038d7SDag-Erling Smørgrav #endif /* splint */ 13557b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 13567b5038d7SDag-Erling Smørgrav 13577b5038d7SDag-Erling Smørgrav ldns_rr * 13587b5038d7SDag-Erling Smørgrav ldns_key2rr(const ldns_key *k) 13597b5038d7SDag-Erling Smørgrav { 13607b5038d7SDag-Erling Smørgrav /* this function will convert a the keydata contained in 13617b5038d7SDag-Erling Smørgrav * rsa/dsa pointers to a DNSKEY rr. It will fill in as 13627b5038d7SDag-Erling Smørgrav * much as it can, but it does not know about key-flags 13637b5038d7SDag-Erling Smørgrav * for instance 13647b5038d7SDag-Erling Smørgrav */ 13657b5038d7SDag-Erling Smørgrav ldns_rr *pubkey; 13667b5038d7SDag-Erling Smørgrav ldns_rdf *keybin; 13677b5038d7SDag-Erling Smørgrav unsigned char *bin = NULL; 13687b5038d7SDag-Erling Smørgrav uint16_t size = 0; 13697b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 13707b5038d7SDag-Erling Smørgrav RSA *rsa = NULL; 13717b5038d7SDag-Erling Smørgrav DSA *dsa = NULL; 13727b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 13737b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 13747b5038d7SDag-Erling Smørgrav EC_KEY* ec; 13757b5038d7SDag-Erling Smørgrav #endif 13767b5038d7SDag-Erling Smørgrav int internal_data = 0; 13777b5038d7SDag-Erling Smørgrav 13787b5038d7SDag-Erling Smørgrav if (!k) { 13797b5038d7SDag-Erling Smørgrav return NULL; 13807b5038d7SDag-Erling Smørgrav } 1381*2787e39aSDag-Erling Smørgrav pubkey = ldns_rr_new(); 13827b5038d7SDag-Erling Smørgrav 13837b5038d7SDag-Erling Smørgrav switch (ldns_key_algorithm(k)) { 13847b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACMD5: 13857b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA1: 13867b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA256: 13877b5038d7SDag-Erling Smørgrav ldns_rr_set_type(pubkey, LDNS_RR_TYPE_KEY); 13887b5038d7SDag-Erling Smørgrav break; 13897b5038d7SDag-Erling Smørgrav default: 13907b5038d7SDag-Erling Smørgrav ldns_rr_set_type(pubkey, LDNS_RR_TYPE_DNSKEY); 13917b5038d7SDag-Erling Smørgrav break; 13927b5038d7SDag-Erling Smørgrav } 13937b5038d7SDag-Erling Smørgrav /* zero-th rdf - flags */ 13947b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 13957b5038d7SDag-Erling Smørgrav ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, 13967b5038d7SDag-Erling Smørgrav ldns_key_flags(k))); 13977b5038d7SDag-Erling Smørgrav /* first - proto */ 13987b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 13997b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, LDNS_DNSSEC_KEYPROTO)); 14007b5038d7SDag-Erling Smørgrav 14017b5038d7SDag-Erling Smørgrav if (ldns_key_pubkey_owner(k)) { 14027b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(pubkey, ldns_rdf_clone(ldns_key_pubkey_owner(k))); 14037b5038d7SDag-Erling Smørgrav } 14047b5038d7SDag-Erling Smørgrav 14057b5038d7SDag-Erling Smørgrav /* third - da algorithm */ 14067b5038d7SDag-Erling Smørgrav switch(ldns_key_algorithm(k)) { 14077b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSAMD5: 14087b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1: 14097b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1_NSEC3: 14107b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA256: 14117b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA512: 14127b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 14137b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); 14147b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 14157b5038d7SDag-Erling Smørgrav rsa = ldns_key_rsa_key(k); 14167b5038d7SDag-Erling Smørgrav if (rsa) { 14177b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 14187b5038d7SDag-Erling Smørgrav if (!bin) { 14197b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14207b5038d7SDag-Erling Smørgrav return NULL; 14217b5038d7SDag-Erling Smørgrav } 14227b5038d7SDag-Erling Smørgrav if (!ldns_key_rsa2bin(bin, rsa, &size)) { 14237b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 14247b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14257b5038d7SDag-Erling Smørgrav return NULL; 14267b5038d7SDag-Erling Smørgrav } 14277b5038d7SDag-Erling Smørgrav RSA_free(rsa); 14287b5038d7SDag-Erling Smørgrav internal_data = 1; 14297b5038d7SDag-Erling Smørgrav } 14307b5038d7SDag-Erling Smørgrav #endif 14317b5038d7SDag-Erling Smørgrav size++; 14327b5038d7SDag-Erling Smørgrav break; 14337b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA: 14347b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 14357b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA)); 14367b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 14377b5038d7SDag-Erling Smørgrav dsa = ldns_key_dsa_key(k); 14387b5038d7SDag-Erling Smørgrav if (dsa) { 14397b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 14407b5038d7SDag-Erling Smørgrav if (!bin) { 14417b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14427b5038d7SDag-Erling Smørgrav return NULL; 14437b5038d7SDag-Erling Smørgrav } 14447b5038d7SDag-Erling Smørgrav if (!ldns_key_dsa2bin(bin, dsa, &size)) { 14457b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 14467b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14477b5038d7SDag-Erling Smørgrav return NULL; 14487b5038d7SDag-Erling Smørgrav } 14497b5038d7SDag-Erling Smørgrav DSA_free(dsa); 14507b5038d7SDag-Erling Smørgrav internal_data = 1; 14517b5038d7SDag-Erling Smørgrav } 14527b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 14537b5038d7SDag-Erling Smørgrav break; 14547b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA_NSEC3: 14557b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 14567b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3)); 14577b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 14587b5038d7SDag-Erling Smørgrav dsa = ldns_key_dsa_key(k); 14597b5038d7SDag-Erling Smørgrav if (dsa) { 14607b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 14617b5038d7SDag-Erling Smørgrav if (!bin) { 14627b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14637b5038d7SDag-Erling Smørgrav return NULL; 14647b5038d7SDag-Erling Smørgrav } 14657b5038d7SDag-Erling Smørgrav if (!ldns_key_dsa2bin(bin, dsa, &size)) { 14667b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 14677b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14687b5038d7SDag-Erling Smørgrav return NULL; 14697b5038d7SDag-Erling Smørgrav } 14707b5038d7SDag-Erling Smørgrav DSA_free(dsa); 14717b5038d7SDag-Erling Smørgrav internal_data = 1; 14727b5038d7SDag-Erling Smørgrav } 14737b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 14747b5038d7SDag-Erling Smørgrav break; 14757b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECC_GOST: 14767b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( 14777b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); 14787b5038d7SDag-Erling Smørgrav #if defined(HAVE_SSL) && defined(USE_GOST) 14797b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 14807b5038d7SDag-Erling Smørgrav if (!bin) { 14817b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14827b5038d7SDag-Erling Smørgrav return NULL; 14837b5038d7SDag-Erling Smørgrav } 14847b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 14857b5038d7SDag-Erling Smørgrav if (!ldns_key_gost2bin(bin, k->_key.key, &size)) { 14867b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 14877b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14887b5038d7SDag-Erling Smørgrav return NULL; 14897b5038d7SDag-Erling Smørgrav } 14907b5038d7SDag-Erling Smørgrav #endif /* splint */ 14917b5038d7SDag-Erling Smørgrav internal_data = 1; 14927b5038d7SDag-Erling Smørgrav #else 14937b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14947b5038d7SDag-Erling Smørgrav return NULL; 14957b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL and USE_GOST */ 14967b5038d7SDag-Erling Smørgrav break; 14977b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP256SHA256: 14987b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP384SHA384: 14997b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 15007b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( 15017b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); 15027b5038d7SDag-Erling Smørgrav bin = NULL; 15037b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 15047b5038d7SDag-Erling Smørgrav ec = EVP_PKEY_get1_EC_KEY(k->_key.key); 15057b5038d7SDag-Erling Smørgrav #endif 15067b5038d7SDag-Erling Smørgrav EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); 15077b5038d7SDag-Erling Smørgrav size = (uint16_t)i2o_ECPublicKey(ec, NULL); 15087b5038d7SDag-Erling Smørgrav if(!i2o_ECPublicKey(ec, &bin)) { 15097b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 15107b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 15117b5038d7SDag-Erling Smørgrav return NULL; 15127b5038d7SDag-Erling Smørgrav } 15137b5038d7SDag-Erling Smørgrav if(size > 1) { 15147b5038d7SDag-Erling Smørgrav /* move back one byte to shave off the 0x02 15157b5038d7SDag-Erling Smørgrav * 'uncompressed' indicator that openssl made 15167b5038d7SDag-Erling Smørgrav * Actually its 0x04 (from implementation). 15177b5038d7SDag-Erling Smørgrav */ 15187b5038d7SDag-Erling Smørgrav assert(bin[0] == POINT_CONVERSION_UNCOMPRESSED); 15197b5038d7SDag-Erling Smørgrav size -= 1; 15207b5038d7SDag-Erling Smørgrav memmove(bin, bin+1, size); 15217b5038d7SDag-Erling Smørgrav } 15227b5038d7SDag-Erling Smørgrav /* down the reference count for ec, its still assigned 15237b5038d7SDag-Erling Smørgrav * to the pkey */ 15247b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 15257b5038d7SDag-Erling Smørgrav internal_data = 1; 15267b5038d7SDag-Erling Smørgrav #else 15277b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 15287b5038d7SDag-Erling Smørgrav return NULL; 15297b5038d7SDag-Erling Smørgrav #endif /* ECDSA */ 15307b5038d7SDag-Erling Smørgrav break; 15317b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACMD5: 15327b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA1: 15337b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA256: 15347b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k)); 15357b5038d7SDag-Erling Smørgrav if (!bin) { 15367b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 15377b5038d7SDag-Erling Smørgrav return NULL; 15387b5038d7SDag-Erling Smørgrav } 15397b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 15407b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, 15417b5038d7SDag-Erling Smørgrav ldns_key_algorithm(k))); 15427b5038d7SDag-Erling Smørgrav size = ldns_key_hmac_size(k); 15437b5038d7SDag-Erling Smørgrav memcpy(bin, ldns_key_hmac_key(k), size); 15447b5038d7SDag-Erling Smørgrav internal_data = 1; 15457b5038d7SDag-Erling Smørgrav break; 15467b5038d7SDag-Erling Smørgrav } 15477b5038d7SDag-Erling Smørgrav /* fourth the key bin material */ 15487b5038d7SDag-Erling Smørgrav if (internal_data) { 15497b5038d7SDag-Erling Smørgrav keybin = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, size, bin); 15507b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 15517b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, keybin); 15527b5038d7SDag-Erling Smørgrav } 15537b5038d7SDag-Erling Smørgrav return pubkey; 15547b5038d7SDag-Erling Smørgrav } 15557b5038d7SDag-Erling Smørgrav 15567b5038d7SDag-Erling Smørgrav void 15577b5038d7SDag-Erling Smørgrav ldns_key_free(ldns_key *key) 15587b5038d7SDag-Erling Smørgrav { 15597b5038d7SDag-Erling Smørgrav LDNS_FREE(key); 15607b5038d7SDag-Erling Smørgrav } 15617b5038d7SDag-Erling Smørgrav 15627b5038d7SDag-Erling Smørgrav void 15637b5038d7SDag-Erling Smørgrav ldns_key_deep_free(ldns_key *key) 15647b5038d7SDag-Erling Smørgrav { 15657b5038d7SDag-Erling Smørgrav unsigned char* hmac; 15667b5038d7SDag-Erling Smørgrav if (ldns_key_pubkey_owner(key)) { 15677b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(ldns_key_pubkey_owner(key)); 15687b5038d7SDag-Erling Smørgrav } 15697b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 15707b5038d7SDag-Erling Smørgrav if (ldns_key_evp_key(key)) { 15717b5038d7SDag-Erling Smørgrav EVP_PKEY_free(ldns_key_evp_key(key)); 15727b5038d7SDag-Erling Smørgrav } 15737b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 15747b5038d7SDag-Erling Smørgrav if (ldns_key_hmac_key(key)) { 15757b5038d7SDag-Erling Smørgrav hmac = ldns_key_hmac_key(key); 15767b5038d7SDag-Erling Smørgrav LDNS_FREE(hmac); 15777b5038d7SDag-Erling Smørgrav } 15787b5038d7SDag-Erling Smørgrav LDNS_FREE(key); 15797b5038d7SDag-Erling Smørgrav } 15807b5038d7SDag-Erling Smørgrav 15817b5038d7SDag-Erling Smørgrav void 15827b5038d7SDag-Erling Smørgrav ldns_key_list_free(ldns_key_list *key_list) 15837b5038d7SDag-Erling Smørgrav { 15847b5038d7SDag-Erling Smørgrav size_t i; 15857b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_key_list_key_count(key_list); i++) { 15867b5038d7SDag-Erling Smørgrav ldns_key_deep_free(ldns_key_list_key(key_list, i)); 15877b5038d7SDag-Erling Smørgrav } 15887b5038d7SDag-Erling Smørgrav LDNS_FREE(key_list->_keys); 15897b5038d7SDag-Erling Smørgrav LDNS_FREE(key_list); 15907b5038d7SDag-Erling Smørgrav } 15917b5038d7SDag-Erling Smørgrav 15927b5038d7SDag-Erling Smørgrav ldns_rr * 15937b5038d7SDag-Erling Smørgrav ldns_read_anchor_file(const char *filename) 15947b5038d7SDag-Erling Smørgrav { 15957b5038d7SDag-Erling Smørgrav FILE *fp; 15967b5038d7SDag-Erling Smørgrav /*char line[LDNS_MAX_PACKETLEN];*/ 15977b5038d7SDag-Erling Smørgrav char *line = LDNS_XMALLOC(char, LDNS_MAX_PACKETLEN); 15987b5038d7SDag-Erling Smørgrav int c; 15997b5038d7SDag-Erling Smørgrav size_t i = 0; 16007b5038d7SDag-Erling Smørgrav ldns_rr *r; 16017b5038d7SDag-Erling Smørgrav ldns_status status; 16027b5038d7SDag-Erling Smørgrav if(!line) { 16037b5038d7SDag-Erling Smørgrav return NULL; 16047b5038d7SDag-Erling Smørgrav } 16057b5038d7SDag-Erling Smørgrav 16067b5038d7SDag-Erling Smørgrav fp = fopen(filename, "r"); 16077b5038d7SDag-Erling Smørgrav if (!fp) { 16087b5038d7SDag-Erling Smørgrav fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno)); 16097b5038d7SDag-Erling Smørgrav LDNS_FREE(line); 16107b5038d7SDag-Erling Smørgrav return NULL; 16117b5038d7SDag-Erling Smørgrav } 16127b5038d7SDag-Erling Smørgrav 16137b5038d7SDag-Erling Smørgrav while ((c = fgetc(fp)) && i+1 < LDNS_MAX_PACKETLEN && c != EOF) { 16147b5038d7SDag-Erling Smørgrav line[i] = c; 16157b5038d7SDag-Erling Smørgrav i++; 16167b5038d7SDag-Erling Smørgrav } 16177b5038d7SDag-Erling Smørgrav line[i] = '\0'; 16187b5038d7SDag-Erling Smørgrav 16197b5038d7SDag-Erling Smørgrav fclose(fp); 16207b5038d7SDag-Erling Smørgrav 16217b5038d7SDag-Erling Smørgrav if (i <= 0) { 16227b5038d7SDag-Erling Smørgrav fprintf(stderr, "nothing read from %s", filename); 16237b5038d7SDag-Erling Smørgrav LDNS_FREE(line); 16247b5038d7SDag-Erling Smørgrav return NULL; 16257b5038d7SDag-Erling Smørgrav } else { 16267b5038d7SDag-Erling Smørgrav status = ldns_rr_new_frm_str(&r, line, 0, NULL, NULL); 16277b5038d7SDag-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)) { 16287b5038d7SDag-Erling Smørgrav LDNS_FREE(line); 16297b5038d7SDag-Erling Smørgrav return r; 16307b5038d7SDag-Erling Smørgrav } else { 16317b5038d7SDag-Erling Smørgrav fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status)); 16327b5038d7SDag-Erling Smørgrav LDNS_FREE(line); 16337b5038d7SDag-Erling Smørgrav return NULL; 16347b5038d7SDag-Erling Smørgrav } 16357b5038d7SDag-Erling Smørgrav } 16367b5038d7SDag-Erling Smørgrav } 16377b5038d7SDag-Erling Smørgrav 16387b5038d7SDag-Erling Smørgrav char * 16397b5038d7SDag-Erling Smørgrav ldns_key_get_file_base_name(ldns_key *key) 16407b5038d7SDag-Erling Smørgrav { 16417b5038d7SDag-Erling Smørgrav ldns_buffer *buffer; 16427b5038d7SDag-Erling Smørgrav char *file_base_name; 16437b5038d7SDag-Erling Smørgrav 16447b5038d7SDag-Erling Smørgrav buffer = ldns_buffer_new(255); 16457b5038d7SDag-Erling Smørgrav ldns_buffer_printf(buffer, "K"); 16467b5038d7SDag-Erling Smørgrav (void)ldns_rdf2buffer_str_dname(buffer, ldns_key_pubkey_owner(key)); 16477b5038d7SDag-Erling Smørgrav ldns_buffer_printf(buffer, 16487b5038d7SDag-Erling Smørgrav "+%03u+%05u", 16497b5038d7SDag-Erling Smørgrav ldns_key_algorithm(key), 16507b5038d7SDag-Erling Smørgrav ldns_key_keytag(key)); 1651*2787e39aSDag-Erling Smørgrav file_base_name = ldns_buffer_export(buffer); 16527b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 16537b5038d7SDag-Erling Smørgrav return file_base_name; 16547b5038d7SDag-Erling Smørgrav } 16557b5038d7SDag-Erling Smørgrav 16567b5038d7SDag-Erling Smørgrav int ldns_key_algo_supported(int algo) 16577b5038d7SDag-Erling Smørgrav { 16587b5038d7SDag-Erling Smørgrav ldns_lookup_table *lt = ldns_signing_algorithms; 16597b5038d7SDag-Erling Smørgrav while(lt->name) { 16607b5038d7SDag-Erling Smørgrav if(lt->id == algo) 16617b5038d7SDag-Erling Smørgrav return 1; 16627b5038d7SDag-Erling Smørgrav lt++; 16637b5038d7SDag-Erling Smørgrav } 16647b5038d7SDag-Erling Smørgrav return 0; 16657b5038d7SDag-Erling Smørgrav } 16667b5038d7SDag-Erling Smørgrav 16677b5038d7SDag-Erling Smørgrav ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name) 16687b5038d7SDag-Erling Smørgrav { 16697b5038d7SDag-Erling Smørgrav /* list of (signing algorithm id, alias_name) */ 16707b5038d7SDag-Erling Smørgrav ldns_lookup_table aliases[] = { 16717b5038d7SDag-Erling Smørgrav /* from bind dnssec-keygen */ 16727b5038d7SDag-Erling Smørgrav {LDNS_SIGN_HMACMD5, "HMAC-MD5"}, 16737b5038d7SDag-Erling Smørgrav {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"}, 16747b5038d7SDag-Erling Smørgrav {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"}, 16757b5038d7SDag-Erling Smørgrav /* old ldns usage, now RFC names */ 16767b5038d7SDag-Erling Smørgrav {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" }, 16777b5038d7SDag-Erling Smørgrav {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" }, 16787b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 16797b5038d7SDag-Erling Smørgrav {LDNS_SIGN_ECC_GOST, "GOST"}, 16807b5038d7SDag-Erling Smørgrav #endif 16817b5038d7SDag-Erling Smørgrav /* compat with possible output */ 16827b5038d7SDag-Erling Smørgrav {LDNS_DH, "DH"}, 16837b5038d7SDag-Erling Smørgrav {LDNS_ECC, "ECC"}, 16847b5038d7SDag-Erling Smørgrav {LDNS_INDIRECT, "INDIRECT"}, 16857b5038d7SDag-Erling Smørgrav {LDNS_PRIVATEDNS, "PRIVATEDNS"}, 16867b5038d7SDag-Erling Smørgrav {LDNS_PRIVATEOID, "PRIVATEOID"}, 16877b5038d7SDag-Erling Smørgrav {0, NULL}}; 16887b5038d7SDag-Erling Smørgrav ldns_lookup_table* lt = ldns_signing_algorithms; 16897b5038d7SDag-Erling Smørgrav while(lt->name) { 16907b5038d7SDag-Erling Smørgrav if(strcasecmp(lt->name, name) == 0) 16917b5038d7SDag-Erling Smørgrav return lt->id; 16927b5038d7SDag-Erling Smørgrav lt++; 16937b5038d7SDag-Erling Smørgrav } 16947b5038d7SDag-Erling Smørgrav lt = aliases; 16957b5038d7SDag-Erling Smørgrav while(lt->name) { 16967b5038d7SDag-Erling Smørgrav if(strcasecmp(lt->name, name) == 0) 16977b5038d7SDag-Erling Smørgrav return lt->id; 16987b5038d7SDag-Erling Smørgrav lt++; 16997b5038d7SDag-Erling Smørgrav } 17007b5038d7SDag-Erling Smørgrav if(atoi(name) != 0) 17017b5038d7SDag-Erling Smørgrav return atoi(name); 17027b5038d7SDag-Erling Smørgrav return 0; 17037b5038d7SDag-Erling Smørgrav } 1704