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 371*17d15b25SDag-Erling Smørgrav # ifdef STDERR_MSGS 3727b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: SHA256 not compiled into this "); 3737b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns\n"); 3747b5038d7SDag-Erling Smørgrav # endif 375*17d15b25SDag-Erling Smørgrav #endif 3767b5038d7SDag-Erling Smørgrav } 3777b5038d7SDag-Erling Smørgrav if (strncmp(d, "10 RSASHA512", 3) == 0) { 3787b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 3797b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_RSASHA512; 3807b5038d7SDag-Erling Smørgrav #else 381*17d15b25SDag-Erling Smørgrav # ifdef STDERR_MSGS 3827b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: SHA512 not compiled into this "); 3837b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns\n"); 3847b5038d7SDag-Erling Smørgrav # endif 385*17d15b25SDag-Erling Smørgrav #endif 3867b5038d7SDag-Erling Smørgrav } 3877b5038d7SDag-Erling Smørgrav if (strncmp(d, "12 ECC-GOST", 3) == 0) { 3887b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 3897b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_ECC_GOST; 3907b5038d7SDag-Erling Smørgrav #else 391*17d15b25SDag-Erling Smørgrav # ifdef STDERR_MSGS 3927b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: ECC-GOST not compiled into this "); 3937b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns, use --enable-gost\n"); 3947b5038d7SDag-Erling Smørgrav # endif 395*17d15b25SDag-Erling Smørgrav #endif 3967b5038d7SDag-Erling Smørgrav } 3977b5038d7SDag-Erling Smørgrav if (strncmp(d, "13 ECDSAP256SHA256", 3) == 0) { 3987b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 3997b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_ECDSAP256SHA256; 4007b5038d7SDag-Erling Smørgrav #else 401*17d15b25SDag-Erling Smørgrav # ifdef STDERR_MSGS 4027b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: ECDSA not compiled into this "); 4037b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns, use --enable-ecdsa\n"); 4047b5038d7SDag-Erling Smørgrav # endif 405*17d15b25SDag-Erling Smørgrav #endif 4067b5038d7SDag-Erling Smørgrav } 4077b5038d7SDag-Erling Smørgrav if (strncmp(d, "14 ECDSAP384SHA384", 3) == 0) { 4087b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 4097b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_ECDSAP384SHA384; 4107b5038d7SDag-Erling Smørgrav #else 411*17d15b25SDag-Erling Smørgrav # ifdef STDERR_MSGS 4127b5038d7SDag-Erling Smørgrav fprintf(stderr, "Warning: ECDSA not compiled into this "); 4137b5038d7SDag-Erling Smørgrav fprintf(stderr, "version of ldns, use --enable-ecdsa\n"); 4147b5038d7SDag-Erling Smørgrav # endif 415*17d15b25SDag-Erling Smørgrav #endif 4167b5038d7SDag-Erling Smørgrav } 4177b5038d7SDag-Erling Smørgrav if (strncmp(d, "157 HMAC-MD5", 4) == 0) { 4187b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_HMACMD5; 4197b5038d7SDag-Erling Smørgrav } 4207b5038d7SDag-Erling Smørgrav if (strncmp(d, "158 HMAC-SHA1", 4) == 0) { 4217b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_HMACSHA1; 4227b5038d7SDag-Erling Smørgrav } 4237b5038d7SDag-Erling Smørgrav if (strncmp(d, "159 HMAC-SHA256", 4) == 0) { 4247b5038d7SDag-Erling Smørgrav alg = LDNS_SIGN_HMACSHA256; 4257b5038d7SDag-Erling Smørgrav } 4267b5038d7SDag-Erling Smørgrav 4277b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 4287b5038d7SDag-Erling Smørgrav 4297b5038d7SDag-Erling Smørgrav switch(alg) { 4307b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSAMD5: 4317b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1: 4327b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1_NSEC3: 4337b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2 4347b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA256: 4357b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA512: 4367b5038d7SDag-Erling Smørgrav #endif 4377b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 4387b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 4397b5038d7SDag-Erling Smørgrav rsa = ldns_key_new_frm_fp_rsa_l(fp, line_nr); 4407b5038d7SDag-Erling Smørgrav if (!rsa) { 4417b5038d7SDag-Erling Smørgrav ldns_key_free(k); 4427b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 4437b5038d7SDag-Erling Smørgrav } 4442787e39aSDag-Erling Smørgrav ldns_key_assign_rsa_key(k, rsa); 4457b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 4467b5038d7SDag-Erling Smørgrav break; 4477b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA: 4487b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA_NSEC3: 4497b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 4507b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 4517b5038d7SDag-Erling Smørgrav dsa = ldns_key_new_frm_fp_dsa_l(fp, line_nr); 4527b5038d7SDag-Erling Smørgrav if (!dsa) { 4537b5038d7SDag-Erling Smørgrav ldns_key_free(k); 4547b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 4557b5038d7SDag-Erling Smørgrav } 4562787e39aSDag-Erling Smørgrav ldns_key_assign_dsa_key(k, dsa); 4577b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 4587b5038d7SDag-Erling Smørgrav break; 4597b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACMD5: 4607b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA1: 4617b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA256: 4627b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 4637b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 4647b5038d7SDag-Erling Smørgrav hmac = ldns_key_new_frm_fp_hmac_l(fp, line_nr, &hmac_size); 4657b5038d7SDag-Erling Smørgrav if (!hmac) { 4667b5038d7SDag-Erling Smørgrav ldns_key_free(k); 4677b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 4687b5038d7SDag-Erling Smørgrav } 4697b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_size(k, hmac_size); 4707b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_key(k, hmac); 4717b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 4727b5038d7SDag-Erling Smørgrav break; 4737b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECC_GOST: 4747b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 4757b5038d7SDag-Erling Smørgrav #if defined(HAVE_SSL) && defined(USE_GOST) 4767b5038d7SDag-Erling Smørgrav if(!ldns_key_EVP_load_gost_id()) { 4777b5038d7SDag-Erling Smørgrav ldns_key_free(k); 4787b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL; 4797b5038d7SDag-Erling Smørgrav } 4807b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(k, 4817b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_gost_l(fp, line_nr)); 4827b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 4837b5038d7SDag-Erling Smørgrav if(!k->_key.key) { 4847b5038d7SDag-Erling Smørgrav ldns_key_free(k); 4857b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 4867b5038d7SDag-Erling Smørgrav } 4877b5038d7SDag-Erling Smørgrav #endif /* splint */ 4887b5038d7SDag-Erling Smørgrav #endif 4897b5038d7SDag-Erling Smørgrav break; 4907b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 4917b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP256SHA256: 4927b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP384SHA384: 4937b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 4947b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(k, 4957b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_ecdsa_l(fp, (ldns_algorithm)alg, line_nr)); 4967b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 4977b5038d7SDag-Erling Smørgrav if(!k->_key.key) { 4987b5038d7SDag-Erling Smørgrav ldns_key_free(k); 4997b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 5007b5038d7SDag-Erling Smørgrav } 5017b5038d7SDag-Erling Smørgrav #endif /* splint */ 5027b5038d7SDag-Erling Smørgrav break; 5037b5038d7SDag-Erling Smørgrav #endif 5047b5038d7SDag-Erling Smørgrav default: 5057b5038d7SDag-Erling Smørgrav ldns_key_free(k); 5067b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_ALG_ERR; 5077b5038d7SDag-Erling Smørgrav } 5087b5038d7SDag-Erling Smørgrav key_rr = ldns_key2rr(k); 5097b5038d7SDag-Erling Smørgrav ldns_key_set_keytag(k, ldns_calc_keytag(key_rr)); 5107b5038d7SDag-Erling Smørgrav ldns_rr_free(key_rr); 5117b5038d7SDag-Erling Smørgrav 5127b5038d7SDag-Erling Smørgrav if (key) { 5137b5038d7SDag-Erling Smørgrav *key = k; 5147b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 5157b5038d7SDag-Erling Smørgrav } 5162787e39aSDag-Erling Smørgrav ldns_key_free(k); 5177b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 5187b5038d7SDag-Erling Smørgrav } 5197b5038d7SDag-Erling Smørgrav 5207b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 5217b5038d7SDag-Erling Smørgrav RSA * 5227b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_rsa(FILE *f) 5237b5038d7SDag-Erling Smørgrav { 5247b5038d7SDag-Erling Smørgrav return ldns_key_new_frm_fp_rsa_l(f, NULL); 5257b5038d7SDag-Erling Smørgrav } 5267b5038d7SDag-Erling Smørgrav 5277b5038d7SDag-Erling Smørgrav RSA * 5287b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr) 5297b5038d7SDag-Erling Smørgrav { 5307b5038d7SDag-Erling Smørgrav /* we parse 5317b5038d7SDag-Erling Smørgrav * Modulus: 5327b5038d7SDag-Erling Smørgrav * PublicExponent: 5337b5038d7SDag-Erling Smørgrav * PrivateExponent: 5347b5038d7SDag-Erling Smørgrav * Prime1: 5357b5038d7SDag-Erling Smørgrav * Prime2: 5367b5038d7SDag-Erling Smørgrav * Exponent1: 5377b5038d7SDag-Erling Smørgrav * Exponent2: 5387b5038d7SDag-Erling Smørgrav * Coefficient: 5397b5038d7SDag-Erling Smørgrav * 5407b5038d7SDag-Erling Smørgrav * man 3 RSA: 5417b5038d7SDag-Erling Smørgrav * 5427b5038d7SDag-Erling Smørgrav * struct 5437b5038d7SDag-Erling Smørgrav * { 5447b5038d7SDag-Erling Smørgrav * BIGNUM *n; // public modulus 5457b5038d7SDag-Erling Smørgrav * BIGNUM *e; // public exponent 5467b5038d7SDag-Erling Smørgrav * BIGNUM *d; // private exponent 5477b5038d7SDag-Erling Smørgrav * BIGNUM *p; // secret prime factor 5487b5038d7SDag-Erling Smørgrav * BIGNUM *q; // secret prime factor 5497b5038d7SDag-Erling Smørgrav * BIGNUM *dmp1; // d mod (p-1) 5507b5038d7SDag-Erling Smørgrav * BIGNUM *dmq1; // d mod (q-1) 5517b5038d7SDag-Erling Smørgrav * BIGNUM *iqmp; // q^-1 mod p 5527b5038d7SDag-Erling Smørgrav * // ... 5537b5038d7SDag-Erling Smørgrav * 5547b5038d7SDag-Erling Smørgrav */ 5557b5038d7SDag-Erling Smørgrav char *d; 5567b5038d7SDag-Erling Smørgrav RSA *rsa; 5577b5038d7SDag-Erling Smørgrav uint8_t *buf; 5587b5038d7SDag-Erling Smørgrav int i; 5597b5038d7SDag-Erling Smørgrav 5607b5038d7SDag-Erling Smørgrav d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); 5617b5038d7SDag-Erling Smørgrav buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN); 5627b5038d7SDag-Erling Smørgrav rsa = RSA_new(); 5637b5038d7SDag-Erling Smørgrav if (!d || !rsa || !buf) { 5647b5038d7SDag-Erling Smørgrav goto error; 5657b5038d7SDag-Erling Smørgrav } 5667b5038d7SDag-Erling Smørgrav 5677b5038d7SDag-Erling Smørgrav /* I could use functions again, but that seems an overkill, 5687b5038d7SDag-Erling Smørgrav * allthough this also looks tedious 5697b5038d7SDag-Erling Smørgrav */ 5707b5038d7SDag-Erling Smørgrav 5717b5038d7SDag-Erling Smørgrav /* Modules, rsa->n */ 5727b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Modulus", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 5737b5038d7SDag-Erling Smørgrav goto error; 5747b5038d7SDag-Erling Smørgrav } 5757b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 5767b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 5777b5038d7SDag-Erling Smørgrav rsa->n = BN_bin2bn((const char unsigned*)buf, i, NULL); 5787b5038d7SDag-Erling Smørgrav if (!rsa->n) { 5797b5038d7SDag-Erling Smørgrav goto error; 5807b5038d7SDag-Erling Smørgrav } 5817b5038d7SDag-Erling Smørgrav 5827b5038d7SDag-Erling Smørgrav /* PublicExponent, rsa->e */ 5837b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", 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->e = BN_bin2bn((const char unsigned*)buf, i, NULL); 5887b5038d7SDag-Erling Smørgrav if (!rsa->e) { 5897b5038d7SDag-Erling Smørgrav goto error; 5907b5038d7SDag-Erling Smørgrav } 5917b5038d7SDag-Erling Smørgrav 5927b5038d7SDag-Erling Smørgrav /* PrivateExponent, rsa->d */ 5937b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", 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->d = BN_bin2bn((const char unsigned*)buf, i, NULL); 5987b5038d7SDag-Erling Smørgrav if (!rsa->d) { 5997b5038d7SDag-Erling Smørgrav goto error; 6007b5038d7SDag-Erling Smørgrav } 6017b5038d7SDag-Erling Smørgrav 6027b5038d7SDag-Erling Smørgrav /* Prime1, rsa->p */ 6037b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Prime1", ": ", 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->p = BN_bin2bn((const char unsigned*)buf, i, NULL); 6087b5038d7SDag-Erling Smørgrav if (!rsa->p) { 6097b5038d7SDag-Erling Smørgrav goto error; 6107b5038d7SDag-Erling Smørgrav } 6117b5038d7SDag-Erling Smørgrav 6127b5038d7SDag-Erling Smørgrav /* Prime2, rsa->q */ 6137b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Prime2", ": ", 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->q = BN_bin2bn((const char unsigned*)buf, i, NULL); 6187b5038d7SDag-Erling Smørgrav if (!rsa->q) { 6197b5038d7SDag-Erling Smørgrav goto error; 6207b5038d7SDag-Erling Smørgrav } 6217b5038d7SDag-Erling Smørgrav 6227b5038d7SDag-Erling Smørgrav /* Exponent1, rsa->dmp1 */ 6237b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", 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->dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL); 6287b5038d7SDag-Erling Smørgrav if (!rsa->dmp1) { 6297b5038d7SDag-Erling Smørgrav goto error; 6307b5038d7SDag-Erling Smørgrav } 6317b5038d7SDag-Erling Smørgrav 6327b5038d7SDag-Erling Smørgrav /* Exponent2, rsa->dmq1 */ 6337b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", 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->dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL); 6387b5038d7SDag-Erling Smørgrav if (!rsa->dmq1) { 6397b5038d7SDag-Erling Smørgrav goto error; 6407b5038d7SDag-Erling Smørgrav } 6417b5038d7SDag-Erling Smørgrav 6427b5038d7SDag-Erling Smørgrav /* Coefficient, rsa->iqmp */ 6437b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 6447b5038d7SDag-Erling Smørgrav goto error; 6457b5038d7SDag-Erling Smørgrav } 6467b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 6477b5038d7SDag-Erling Smørgrav rsa->iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL); 6487b5038d7SDag-Erling Smørgrav if (!rsa->iqmp) { 6497b5038d7SDag-Erling Smørgrav goto error; 6507b5038d7SDag-Erling Smørgrav } 6517b5038d7SDag-Erling Smørgrav #endif /* splint */ 6527b5038d7SDag-Erling Smørgrav 6537b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 6547b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 6557b5038d7SDag-Erling Smørgrav return rsa; 6567b5038d7SDag-Erling Smørgrav 6577b5038d7SDag-Erling Smørgrav error: 6587b5038d7SDag-Erling Smørgrav RSA_free(rsa); 6597b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 6607b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 6617b5038d7SDag-Erling Smørgrav return NULL; 6627b5038d7SDag-Erling Smørgrav } 6637b5038d7SDag-Erling Smørgrav 6647b5038d7SDag-Erling Smørgrav DSA * 6657b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_dsa(FILE *f) 6667b5038d7SDag-Erling Smørgrav { 6677b5038d7SDag-Erling Smørgrav return ldns_key_new_frm_fp_dsa_l(f, NULL); 6687b5038d7SDag-Erling Smørgrav } 6697b5038d7SDag-Erling Smørgrav 6707b5038d7SDag-Erling Smørgrav DSA * 6717b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr)) 6727b5038d7SDag-Erling Smørgrav { 6737b5038d7SDag-Erling Smørgrav int i; 6747b5038d7SDag-Erling Smørgrav char *d; 6757b5038d7SDag-Erling Smørgrav DSA *dsa; 6767b5038d7SDag-Erling Smørgrav uint8_t *buf; 6777b5038d7SDag-Erling Smørgrav 6787b5038d7SDag-Erling Smørgrav d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN); 6797b5038d7SDag-Erling Smørgrav buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN); 6807b5038d7SDag-Erling Smørgrav dsa = DSA_new(); 6817b5038d7SDag-Erling Smørgrav if (!d || !dsa || !buf) { 6827b5038d7SDag-Erling Smørgrav goto error; 6837b5038d7SDag-Erling Smørgrav } 6847b5038d7SDag-Erling Smørgrav 6857b5038d7SDag-Erling Smørgrav /* the line parser removes the () from the input... */ 6867b5038d7SDag-Erling Smørgrav 6877b5038d7SDag-Erling Smørgrav /* Prime, dsa->p */ 6887b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Primep", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 6897b5038d7SDag-Erling Smørgrav goto error; 6907b5038d7SDag-Erling Smørgrav } 6917b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 6927b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 6937b5038d7SDag-Erling Smørgrav dsa->p = BN_bin2bn((const char unsigned*)buf, i, NULL); 6947b5038d7SDag-Erling Smørgrav if (!dsa->p) { 6957b5038d7SDag-Erling Smørgrav goto error; 6967b5038d7SDag-Erling Smørgrav } 6977b5038d7SDag-Erling Smørgrav 6987b5038d7SDag-Erling Smørgrav /* Subprime, dsa->q */ 6997b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Subprimeq", ": ", 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->q = BN_bin2bn((const char unsigned*)buf, i, NULL); 7047b5038d7SDag-Erling Smørgrav if (!dsa->q) { 7057b5038d7SDag-Erling Smørgrav goto error; 7067b5038d7SDag-Erling Smørgrav } 7077b5038d7SDag-Erling Smørgrav 7087b5038d7SDag-Erling Smørgrav /* Base, dsa->g */ 7097b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Baseg", ": ", 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->g = BN_bin2bn((const char unsigned*)buf, i, NULL); 7147b5038d7SDag-Erling Smørgrav if (!dsa->g) { 7157b5038d7SDag-Erling Smørgrav goto error; 7167b5038d7SDag-Erling Smørgrav } 7177b5038d7SDag-Erling Smørgrav 7187b5038d7SDag-Erling Smørgrav /* Private key, dsa->priv_key */ 7197b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Private_valuex", ": ", 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->priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL); 7247b5038d7SDag-Erling Smørgrav if (!dsa->priv_key) { 7257b5038d7SDag-Erling Smørgrav goto error; 7267b5038d7SDag-Erling Smørgrav } 7277b5038d7SDag-Erling Smørgrav 7287b5038d7SDag-Erling Smørgrav /* Public key, dsa->priv_key */ 7297b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Public_valuey", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 7307b5038d7SDag-Erling Smørgrav goto error; 7317b5038d7SDag-Erling Smørgrav } 7327b5038d7SDag-Erling Smørgrav i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d))); 7337b5038d7SDag-Erling Smørgrav dsa->pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL); 7347b5038d7SDag-Erling Smørgrav if (!dsa->pub_key) { 7357b5038d7SDag-Erling Smørgrav goto error; 7367b5038d7SDag-Erling Smørgrav } 7377b5038d7SDag-Erling Smørgrav #endif /* splint */ 7387b5038d7SDag-Erling Smørgrav 7397b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 7407b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 7417b5038d7SDag-Erling Smørgrav 7427b5038d7SDag-Erling Smørgrav return dsa; 7437b5038d7SDag-Erling Smørgrav 7447b5038d7SDag-Erling Smørgrav error: 7457b5038d7SDag-Erling Smørgrav LDNS_FREE(d); 7467b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 7477b5038d7SDag-Erling Smørgrav DSA_free(dsa); 7487b5038d7SDag-Erling Smørgrav return NULL; 7497b5038d7SDag-Erling Smørgrav } 7507b5038d7SDag-Erling Smørgrav 7517b5038d7SDag-Erling Smørgrav unsigned char * 7527b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_hmac(FILE *f, size_t *hmac_size) 7537b5038d7SDag-Erling Smørgrav { 7547b5038d7SDag-Erling Smørgrav return ldns_key_new_frm_fp_hmac_l(f, NULL, hmac_size); 7557b5038d7SDag-Erling Smørgrav } 7567b5038d7SDag-Erling Smørgrav 7577b5038d7SDag-Erling Smørgrav unsigned char * 7587b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_hmac_l( FILE *f 7597b5038d7SDag-Erling Smørgrav , ATTR_UNUSED(int *line_nr) 7607b5038d7SDag-Erling Smørgrav , size_t *hmac_size 7617b5038d7SDag-Erling Smørgrav ) 7627b5038d7SDag-Erling Smørgrav { 7632787e39aSDag-Erling Smørgrav size_t i, bufsz; 7642787e39aSDag-Erling Smørgrav char d[LDNS_MAX_LINELEN]; 7652787e39aSDag-Erling Smørgrav unsigned char *buf = NULL; 7667b5038d7SDag-Erling Smørgrav 7677b5038d7SDag-Erling Smørgrav if (ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) { 7687b5038d7SDag-Erling Smørgrav goto error; 7697b5038d7SDag-Erling Smørgrav } 7702787e39aSDag-Erling Smørgrav bufsz = ldns_b64_ntop_calculate_size(strlen(d)); 7712787e39aSDag-Erling Smørgrav buf = LDNS_XMALLOC(unsigned char, bufsz); 7722787e39aSDag-Erling Smørgrav i = (size_t) ldns_b64_pton((const char*)d, buf, bufsz); 7737b5038d7SDag-Erling Smørgrav 7747b5038d7SDag-Erling Smørgrav *hmac_size = i; 7757b5038d7SDag-Erling Smørgrav return buf; 7767b5038d7SDag-Erling Smørgrav 7777b5038d7SDag-Erling Smørgrav error: 7787b5038d7SDag-Erling Smørgrav LDNS_FREE(buf); 7797b5038d7SDag-Erling Smørgrav *hmac_size = 0; 7807b5038d7SDag-Erling Smørgrav return NULL; 7817b5038d7SDag-Erling Smørgrav } 7827b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 7837b5038d7SDag-Erling Smørgrav 7847b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 7857b5038d7SDag-Erling Smørgrav static EVP_PKEY* 7867b5038d7SDag-Erling Smørgrav ldns_gen_gost_key(void) 7877b5038d7SDag-Erling Smørgrav { 7887b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX* ctx; 7897b5038d7SDag-Erling Smørgrav EVP_PKEY* p = NULL; 7907b5038d7SDag-Erling Smørgrav int gost_id = ldns_key_EVP_load_gost_id(); 7917b5038d7SDag-Erling Smørgrav if(!gost_id) 7927b5038d7SDag-Erling Smørgrav return NULL; 7937b5038d7SDag-Erling Smørgrav ctx = EVP_PKEY_CTX_new_id(gost_id, NULL); 7947b5038d7SDag-Erling Smørgrav if(!ctx) { 7957b5038d7SDag-Erling Smørgrav /* the id should be available now */ 7967b5038d7SDag-Erling Smørgrav return NULL; 7977b5038d7SDag-Erling Smørgrav } 7987b5038d7SDag-Erling Smørgrav if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) { 7997b5038d7SDag-Erling Smørgrav /* cannot set paramset */ 8007b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX_free(ctx); 8017b5038d7SDag-Erling Smørgrav return NULL; 8027b5038d7SDag-Erling Smørgrav } 8037b5038d7SDag-Erling Smørgrav 8047b5038d7SDag-Erling Smørgrav if(EVP_PKEY_keygen_init(ctx) <= 0) { 8057b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX_free(ctx); 8067b5038d7SDag-Erling Smørgrav return NULL; 8077b5038d7SDag-Erling Smørgrav } 8087b5038d7SDag-Erling Smørgrav if(EVP_PKEY_keygen(ctx, &p) <= 0) { 8097b5038d7SDag-Erling Smørgrav EVP_PKEY_free(p); 8107b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX_free(ctx); 8117b5038d7SDag-Erling Smørgrav return NULL; 8127b5038d7SDag-Erling Smørgrav } 8137b5038d7SDag-Erling Smørgrav EVP_PKEY_CTX_free(ctx); 8147b5038d7SDag-Erling Smørgrav return p; 8157b5038d7SDag-Erling Smørgrav } 8167b5038d7SDag-Erling Smørgrav #endif 8177b5038d7SDag-Erling Smørgrav 8187b5038d7SDag-Erling Smørgrav ldns_key * 8197b5038d7SDag-Erling Smørgrav ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size) 8207b5038d7SDag-Erling Smørgrav { 8217b5038d7SDag-Erling Smørgrav ldns_key *k; 8227b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 8237b5038d7SDag-Erling Smørgrav DSA *d; 8247b5038d7SDag-Erling Smørgrav RSA *r; 8257b5038d7SDag-Erling Smørgrav # ifdef USE_ECDSA 8267b5038d7SDag-Erling Smørgrav EC_KEY *ec = NULL; 8277b5038d7SDag-Erling Smørgrav # endif 8287b5038d7SDag-Erling Smørgrav #else 8297b5038d7SDag-Erling Smørgrav int i; 8307b5038d7SDag-Erling Smørgrav uint16_t offset = 0; 8317b5038d7SDag-Erling Smørgrav #endif 8327b5038d7SDag-Erling Smørgrav unsigned char *hmac; 8337b5038d7SDag-Erling Smørgrav 8347b5038d7SDag-Erling Smørgrav k = ldns_key_new(); 8357b5038d7SDag-Erling Smørgrav if (!k) { 8367b5038d7SDag-Erling Smørgrav return NULL; 8377b5038d7SDag-Erling Smørgrav } 8387b5038d7SDag-Erling Smørgrav switch(alg) { 8397b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSAMD5: 8407b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1: 8417b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1_NSEC3: 8427b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA256: 8437b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA512: 8447b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 8457b5038d7SDag-Erling Smørgrav r = RSA_generate_key((int)size, RSA_F4, NULL, NULL); 8467b5038d7SDag-Erling Smørgrav if(!r) { 8477b5038d7SDag-Erling Smørgrav ldns_key_free(k); 8487b5038d7SDag-Erling Smørgrav return NULL; 8497b5038d7SDag-Erling Smørgrav } 8507b5038d7SDag-Erling Smørgrav if (RSA_check_key(r) != 1) { 8517b5038d7SDag-Erling Smørgrav ldns_key_free(k); 8527b5038d7SDag-Erling Smørgrav return NULL; 8537b5038d7SDag-Erling Smørgrav } 8547b5038d7SDag-Erling Smørgrav ldns_key_set_rsa_key(k, r); 8552787e39aSDag-Erling Smørgrav RSA_free(r); 8567b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 8577b5038d7SDag-Erling Smørgrav break; 8587b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA: 8597b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA_NSEC3: 8607b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 8617b5038d7SDag-Erling Smørgrav d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL); 8627b5038d7SDag-Erling Smørgrav if (!d) { 8637b5038d7SDag-Erling Smørgrav ldns_key_free(k); 8647b5038d7SDag-Erling Smørgrav return NULL; 8657b5038d7SDag-Erling Smørgrav } 8667b5038d7SDag-Erling Smørgrav if (DSA_generate_key(d) != 1) { 8677b5038d7SDag-Erling Smørgrav ldns_key_free(k); 8687b5038d7SDag-Erling Smørgrav return NULL; 8697b5038d7SDag-Erling Smørgrav } 8707b5038d7SDag-Erling Smørgrav ldns_key_set_dsa_key(k, d); 8712787e39aSDag-Erling Smørgrav DSA_free(d); 8727b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 8737b5038d7SDag-Erling Smørgrav break; 8747b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACMD5: 8757b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA1: 8767b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA256: 8777b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 8787b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 8797b5038d7SDag-Erling Smørgrav k->_key.key = NULL; 8807b5038d7SDag-Erling Smørgrav #endif /* splint */ 8817b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 8827b5038d7SDag-Erling Smørgrav size = size / 8; 8837b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_size(k, size); 8847b5038d7SDag-Erling Smørgrav 8857b5038d7SDag-Erling Smørgrav hmac = LDNS_XMALLOC(unsigned char, size); 8867b5038d7SDag-Erling Smørgrav if(!hmac) { 8877b5038d7SDag-Erling Smørgrav ldns_key_free(k); 8887b5038d7SDag-Erling Smørgrav return NULL; 8897b5038d7SDag-Erling Smørgrav } 8907b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 8917b5038d7SDag-Erling Smørgrav if (RAND_bytes(hmac, (int) size) != 1) { 8927b5038d7SDag-Erling Smørgrav LDNS_FREE(hmac); 8937b5038d7SDag-Erling Smørgrav ldns_key_free(k); 8947b5038d7SDag-Erling Smørgrav return NULL; 8957b5038d7SDag-Erling Smørgrav } 8967b5038d7SDag-Erling Smørgrav #else 8977b5038d7SDag-Erling Smørgrav while (offset + sizeof(i) < size) { 8987b5038d7SDag-Erling Smørgrav i = random(); 8997b5038d7SDag-Erling Smørgrav memcpy(&hmac[offset], &i, sizeof(i)); 9007b5038d7SDag-Erling Smørgrav offset += sizeof(i); 9017b5038d7SDag-Erling Smørgrav } 9027b5038d7SDag-Erling Smørgrav if (offset < size) { 9037b5038d7SDag-Erling Smørgrav i = random(); 9047b5038d7SDag-Erling Smørgrav memcpy(&hmac[offset], &i, size - offset); 9057b5038d7SDag-Erling Smørgrav } 9067b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 9077b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_key(k, hmac); 9087b5038d7SDag-Erling Smørgrav 9097b5038d7SDag-Erling Smørgrav ldns_key_set_flags(k, 0); 9107b5038d7SDag-Erling Smørgrav break; 9117b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECC_GOST: 9127b5038d7SDag-Erling Smørgrav #if defined(HAVE_SSL) && defined(USE_GOST) 9137b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(k, ldns_gen_gost_key()); 9147b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 9157b5038d7SDag-Erling Smørgrav if(!k->_key.key) { 9167b5038d7SDag-Erling Smørgrav ldns_key_free(k); 9177b5038d7SDag-Erling Smørgrav return NULL; 9187b5038d7SDag-Erling Smørgrav } 9197b5038d7SDag-Erling Smørgrav #endif /* splint */ 9207b5038d7SDag-Erling Smørgrav #else 9217b5038d7SDag-Erling Smørgrav ldns_key_free(k); 9227b5038d7SDag-Erling Smørgrav return NULL; 9237b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL and USE_GOST */ 9247b5038d7SDag-Erling Smørgrav break; 9257b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP256SHA256: 9267b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP384SHA384: 9277b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 9287b5038d7SDag-Erling Smørgrav if(alg == LDNS_SIGN_ECDSAP256SHA256) 9297b5038d7SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 9307b5038d7SDag-Erling Smørgrav else if(alg == LDNS_SIGN_ECDSAP384SHA384) 9317b5038d7SDag-Erling Smørgrav ec = EC_KEY_new_by_curve_name(NID_secp384r1); 9327b5038d7SDag-Erling Smørgrav if(!ec) { 9337b5038d7SDag-Erling Smørgrav ldns_key_free(k); 9347b5038d7SDag-Erling Smørgrav return NULL; 9357b5038d7SDag-Erling Smørgrav } 9367b5038d7SDag-Erling Smørgrav if(!EC_KEY_generate_key(ec)) { 9377b5038d7SDag-Erling Smørgrav ldns_key_free(k); 9387b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 9397b5038d7SDag-Erling Smørgrav return NULL; 9407b5038d7SDag-Erling Smørgrav } 9417b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 9427b5038d7SDag-Erling Smørgrav k->_key.key = EVP_PKEY_new(); 9437b5038d7SDag-Erling Smørgrav if(!k->_key.key) { 9447b5038d7SDag-Erling Smørgrav ldns_key_free(k); 9457b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 9467b5038d7SDag-Erling Smørgrav return NULL; 9477b5038d7SDag-Erling Smørgrav } 9487b5038d7SDag-Erling Smørgrav if (!EVP_PKEY_assign_EC_KEY(k->_key.key, ec)) { 9497b5038d7SDag-Erling Smørgrav ldns_key_free(k); 9507b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 9517b5038d7SDag-Erling Smørgrav return NULL; 9527b5038d7SDag-Erling Smørgrav } 9537b5038d7SDag-Erling Smørgrav #endif /* splint */ 9547b5038d7SDag-Erling Smørgrav #else 9557b5038d7SDag-Erling Smørgrav ldns_key_free(k); 9567b5038d7SDag-Erling Smørgrav return NULL; 9577b5038d7SDag-Erling Smørgrav #endif /* ECDSA */ 9587b5038d7SDag-Erling Smørgrav break; 9597b5038d7SDag-Erling Smørgrav } 9607b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(k, alg); 9617b5038d7SDag-Erling Smørgrav return k; 9627b5038d7SDag-Erling Smørgrav } 9637b5038d7SDag-Erling Smørgrav 9647b5038d7SDag-Erling Smørgrav void 9657b5038d7SDag-Erling Smørgrav ldns_key_print(FILE *output, const ldns_key *k) 9667b5038d7SDag-Erling Smørgrav { 9677b5038d7SDag-Erling Smørgrav char *str = ldns_key2str(k); 9687b5038d7SDag-Erling Smørgrav if (str) { 9697b5038d7SDag-Erling Smørgrav fprintf(output, "%s", str); 9707b5038d7SDag-Erling Smørgrav } else { 9717b5038d7SDag-Erling Smørgrav fprintf(output, "Unable to convert private key to string\n"); 9727b5038d7SDag-Erling Smørgrav } 9737b5038d7SDag-Erling Smørgrav LDNS_FREE(str); 9747b5038d7SDag-Erling Smørgrav } 9757b5038d7SDag-Erling Smørgrav 9767b5038d7SDag-Erling Smørgrav 9777b5038d7SDag-Erling Smørgrav void 9787b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l) 9797b5038d7SDag-Erling Smørgrav { 9807b5038d7SDag-Erling Smørgrav k->_alg = l; 9817b5038d7SDag-Erling Smørgrav } 9827b5038d7SDag-Erling Smørgrav 9837b5038d7SDag-Erling Smørgrav void 9847b5038d7SDag-Erling Smørgrav ldns_key_set_flags(ldns_key *k, uint16_t f) 9857b5038d7SDag-Erling Smørgrav { 9867b5038d7SDag-Erling Smørgrav k->_extra.dnssec.flags = f; 9877b5038d7SDag-Erling Smørgrav } 9887b5038d7SDag-Erling Smørgrav 9897b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 9907b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 9917b5038d7SDag-Erling Smørgrav void 9927b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e) 9937b5038d7SDag-Erling Smørgrav { 9947b5038d7SDag-Erling Smørgrav k->_key.key = e; 9957b5038d7SDag-Erling Smørgrav } 9967b5038d7SDag-Erling Smørgrav 9977b5038d7SDag-Erling Smørgrav void 9987b5038d7SDag-Erling Smørgrav ldns_key_set_rsa_key(ldns_key *k, RSA *r) 9997b5038d7SDag-Erling Smørgrav { 10007b5038d7SDag-Erling Smørgrav EVP_PKEY *key = EVP_PKEY_new(); 10017b5038d7SDag-Erling Smørgrav EVP_PKEY_set1_RSA(key, r); 10027b5038d7SDag-Erling Smørgrav k->_key.key = key; 10037b5038d7SDag-Erling Smørgrav } 10047b5038d7SDag-Erling Smørgrav 10057b5038d7SDag-Erling Smørgrav void 10067b5038d7SDag-Erling Smørgrav ldns_key_set_dsa_key(ldns_key *k, DSA *d) 10077b5038d7SDag-Erling Smørgrav { 10087b5038d7SDag-Erling Smørgrav EVP_PKEY *key = EVP_PKEY_new(); 10097b5038d7SDag-Erling Smørgrav EVP_PKEY_set1_DSA(key, d); 10107b5038d7SDag-Erling Smørgrav k->_key.key = key; 10117b5038d7SDag-Erling Smørgrav } 10122787e39aSDag-Erling Smørgrav 10132787e39aSDag-Erling Smørgrav void 10142787e39aSDag-Erling Smørgrav ldns_key_assign_rsa_key(ldns_key *k, RSA *r) 10152787e39aSDag-Erling Smørgrav { 10162787e39aSDag-Erling Smørgrav EVP_PKEY *key = EVP_PKEY_new(); 10172787e39aSDag-Erling Smørgrav EVP_PKEY_assign_RSA(key, r); 10182787e39aSDag-Erling Smørgrav k->_key.key = key; 10192787e39aSDag-Erling Smørgrav } 10202787e39aSDag-Erling Smørgrav 10212787e39aSDag-Erling Smørgrav void 10222787e39aSDag-Erling Smørgrav ldns_key_assign_dsa_key(ldns_key *k, DSA *d) 10232787e39aSDag-Erling Smørgrav { 10242787e39aSDag-Erling Smørgrav EVP_PKEY *key = EVP_PKEY_new(); 10252787e39aSDag-Erling Smørgrav EVP_PKEY_assign_DSA(key, d); 10262787e39aSDag-Erling Smørgrav k->_key.key = key; 10272787e39aSDag-Erling Smørgrav } 10287b5038d7SDag-Erling Smørgrav #endif /* splint */ 10297b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 10307b5038d7SDag-Erling Smørgrav 10317b5038d7SDag-Erling Smørgrav void 10327b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac) 10337b5038d7SDag-Erling Smørgrav { 10347b5038d7SDag-Erling Smørgrav k->_key.hmac.key = hmac; 10357b5038d7SDag-Erling Smørgrav } 10367b5038d7SDag-Erling Smørgrav 10377b5038d7SDag-Erling Smørgrav void 10387b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size) 10397b5038d7SDag-Erling Smørgrav { 10407b5038d7SDag-Erling Smørgrav k->_key.hmac.size = hmac_size; 10417b5038d7SDag-Erling Smørgrav } 10427b5038d7SDag-Erling Smørgrav 10437b5038d7SDag-Erling Smørgrav void 10447b5038d7SDag-Erling Smørgrav ldns_key_set_external_key(ldns_key *k, void *external_key) 10457b5038d7SDag-Erling Smørgrav { 10467b5038d7SDag-Erling Smørgrav k->_key.external_key = external_key; 10477b5038d7SDag-Erling Smørgrav } 10487b5038d7SDag-Erling Smørgrav 10497b5038d7SDag-Erling Smørgrav void 10507b5038d7SDag-Erling Smørgrav ldns_key_set_origttl(ldns_key *k, uint32_t t) 10517b5038d7SDag-Erling Smørgrav { 10527b5038d7SDag-Erling Smørgrav k->_extra.dnssec.orig_ttl = t; 10537b5038d7SDag-Erling Smørgrav } 10547b5038d7SDag-Erling Smørgrav 10557b5038d7SDag-Erling Smørgrav void 10567b5038d7SDag-Erling Smørgrav ldns_key_set_inception(ldns_key *k, uint32_t i) 10577b5038d7SDag-Erling Smørgrav { 10587b5038d7SDag-Erling Smørgrav k->_extra.dnssec.inception = i; 10597b5038d7SDag-Erling Smørgrav } 10607b5038d7SDag-Erling Smørgrav 10617b5038d7SDag-Erling Smørgrav void 10627b5038d7SDag-Erling Smørgrav ldns_key_set_expiration(ldns_key *k, uint32_t e) 10637b5038d7SDag-Erling Smørgrav { 10647b5038d7SDag-Erling Smørgrav k->_extra.dnssec.expiration = e; 10657b5038d7SDag-Erling Smørgrav } 10667b5038d7SDag-Erling Smørgrav 10677b5038d7SDag-Erling Smørgrav void 10687b5038d7SDag-Erling Smørgrav ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r) 10697b5038d7SDag-Erling Smørgrav { 10707b5038d7SDag-Erling Smørgrav k->_pubkey_owner = r; 10717b5038d7SDag-Erling Smørgrav } 10727b5038d7SDag-Erling Smørgrav 10737b5038d7SDag-Erling Smørgrav void 10747b5038d7SDag-Erling Smørgrav ldns_key_set_keytag(ldns_key *k, uint16_t tag) 10757b5038d7SDag-Erling Smørgrav { 10767b5038d7SDag-Erling Smørgrav k->_extra.dnssec.keytag = tag; 10777b5038d7SDag-Erling Smørgrav } 10787b5038d7SDag-Erling Smørgrav 10797b5038d7SDag-Erling Smørgrav /* read */ 10807b5038d7SDag-Erling Smørgrav size_t 10817b5038d7SDag-Erling Smørgrav ldns_key_list_key_count(const ldns_key_list *key_list) 10827b5038d7SDag-Erling Smørgrav { 10837b5038d7SDag-Erling Smørgrav return key_list->_key_count; 10847b5038d7SDag-Erling Smørgrav } 10857b5038d7SDag-Erling Smørgrav 10867b5038d7SDag-Erling Smørgrav ldns_key * 10877b5038d7SDag-Erling Smørgrav ldns_key_list_key(const ldns_key_list *key, size_t nr) 10887b5038d7SDag-Erling Smørgrav { 10897b5038d7SDag-Erling Smørgrav if (nr < ldns_key_list_key_count(key)) { 10907b5038d7SDag-Erling Smørgrav return key->_keys[nr]; 10917b5038d7SDag-Erling Smørgrav } else { 10927b5038d7SDag-Erling Smørgrav return NULL; 10937b5038d7SDag-Erling Smørgrav } 10947b5038d7SDag-Erling Smørgrav } 10957b5038d7SDag-Erling Smørgrav 10967b5038d7SDag-Erling Smørgrav ldns_signing_algorithm 10977b5038d7SDag-Erling Smørgrav ldns_key_algorithm(const ldns_key *k) 10987b5038d7SDag-Erling Smørgrav { 10997b5038d7SDag-Erling Smørgrav return k->_alg; 11007b5038d7SDag-Erling Smørgrav } 11017b5038d7SDag-Erling Smørgrav 11027b5038d7SDag-Erling Smørgrav void 11037b5038d7SDag-Erling Smørgrav ldns_key_set_use(ldns_key *k, bool v) 11047b5038d7SDag-Erling Smørgrav { 11057b5038d7SDag-Erling Smørgrav if (k) { 11067b5038d7SDag-Erling Smørgrav k->_use = v; 11077b5038d7SDag-Erling Smørgrav } 11087b5038d7SDag-Erling Smørgrav } 11097b5038d7SDag-Erling Smørgrav 11107b5038d7SDag-Erling Smørgrav bool 11117b5038d7SDag-Erling Smørgrav ldns_key_use(const ldns_key *k) 11127b5038d7SDag-Erling Smørgrav { 11137b5038d7SDag-Erling Smørgrav if (k) { 11147b5038d7SDag-Erling Smørgrav return k->_use; 11157b5038d7SDag-Erling Smørgrav } 11167b5038d7SDag-Erling Smørgrav return false; 11177b5038d7SDag-Erling Smørgrav } 11187b5038d7SDag-Erling Smørgrav 11197b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 11207b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 11217b5038d7SDag-Erling Smørgrav EVP_PKEY * 11227b5038d7SDag-Erling Smørgrav ldns_key_evp_key(const ldns_key *k) 11237b5038d7SDag-Erling Smørgrav { 11247b5038d7SDag-Erling Smørgrav return k->_key.key; 11257b5038d7SDag-Erling Smørgrav } 11267b5038d7SDag-Erling Smørgrav 11277b5038d7SDag-Erling Smørgrav RSA * 11287b5038d7SDag-Erling Smørgrav ldns_key_rsa_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_RSA(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 11377b5038d7SDag-Erling Smørgrav DSA * 11387b5038d7SDag-Erling Smørgrav ldns_key_dsa_key(const ldns_key *k) 11397b5038d7SDag-Erling Smørgrav { 11407b5038d7SDag-Erling Smørgrav if (k->_key.key) { 11417b5038d7SDag-Erling Smørgrav return EVP_PKEY_get1_DSA(k->_key.key); 11427b5038d7SDag-Erling Smørgrav } else { 11437b5038d7SDag-Erling Smørgrav return NULL; 11447b5038d7SDag-Erling Smørgrav } 11457b5038d7SDag-Erling Smørgrav } 11467b5038d7SDag-Erling Smørgrav #endif /* splint */ 11477b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 11487b5038d7SDag-Erling Smørgrav 11497b5038d7SDag-Erling Smørgrav unsigned char * 11507b5038d7SDag-Erling Smørgrav ldns_key_hmac_key(const ldns_key *k) 11517b5038d7SDag-Erling Smørgrav { 11527b5038d7SDag-Erling Smørgrav if (k->_key.hmac.key) { 11537b5038d7SDag-Erling Smørgrav return k->_key.hmac.key; 11547b5038d7SDag-Erling Smørgrav } else { 11557b5038d7SDag-Erling Smørgrav return NULL; 11567b5038d7SDag-Erling Smørgrav } 11577b5038d7SDag-Erling Smørgrav } 11587b5038d7SDag-Erling Smørgrav 11597b5038d7SDag-Erling Smørgrav size_t 11607b5038d7SDag-Erling Smørgrav ldns_key_hmac_size(const ldns_key *k) 11617b5038d7SDag-Erling Smørgrav { 11627b5038d7SDag-Erling Smørgrav if (k->_key.hmac.size) { 11637b5038d7SDag-Erling Smørgrav return k->_key.hmac.size; 11647b5038d7SDag-Erling Smørgrav } else { 11657b5038d7SDag-Erling Smørgrav return 0; 11667b5038d7SDag-Erling Smørgrav } 11677b5038d7SDag-Erling Smørgrav } 11687b5038d7SDag-Erling Smørgrav 11697b5038d7SDag-Erling Smørgrav void * 11707b5038d7SDag-Erling Smørgrav ldns_key_external_key(const ldns_key *k) 11717b5038d7SDag-Erling Smørgrav { 11727b5038d7SDag-Erling Smørgrav return k->_key.external_key; 11737b5038d7SDag-Erling Smørgrav } 11747b5038d7SDag-Erling Smørgrav 11757b5038d7SDag-Erling Smørgrav uint32_t 11767b5038d7SDag-Erling Smørgrav ldns_key_origttl(const ldns_key *k) 11777b5038d7SDag-Erling Smørgrav { 11787b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.orig_ttl; 11797b5038d7SDag-Erling Smørgrav } 11807b5038d7SDag-Erling Smørgrav 11817b5038d7SDag-Erling Smørgrav uint16_t 11827b5038d7SDag-Erling Smørgrav ldns_key_flags(const ldns_key *k) 11837b5038d7SDag-Erling Smørgrav { 11847b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.flags; 11857b5038d7SDag-Erling Smørgrav } 11867b5038d7SDag-Erling Smørgrav 11877b5038d7SDag-Erling Smørgrav uint32_t 11887b5038d7SDag-Erling Smørgrav ldns_key_inception(const ldns_key *k) 11897b5038d7SDag-Erling Smørgrav { 11907b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.inception; 11917b5038d7SDag-Erling Smørgrav } 11927b5038d7SDag-Erling Smørgrav 11937b5038d7SDag-Erling Smørgrav uint32_t 11947b5038d7SDag-Erling Smørgrav ldns_key_expiration(const ldns_key *k) 11957b5038d7SDag-Erling Smørgrav { 11967b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.expiration; 11977b5038d7SDag-Erling Smørgrav } 11987b5038d7SDag-Erling Smørgrav 11997b5038d7SDag-Erling Smørgrav uint16_t 12007b5038d7SDag-Erling Smørgrav ldns_key_keytag(const ldns_key *k) 12017b5038d7SDag-Erling Smørgrav { 12027b5038d7SDag-Erling Smørgrav return k->_extra.dnssec.keytag; 12037b5038d7SDag-Erling Smørgrav } 12047b5038d7SDag-Erling Smørgrav 12057b5038d7SDag-Erling Smørgrav ldns_rdf * 12067b5038d7SDag-Erling Smørgrav ldns_key_pubkey_owner(const ldns_key *k) 12077b5038d7SDag-Erling Smørgrav { 12087b5038d7SDag-Erling Smørgrav return k->_pubkey_owner; 12097b5038d7SDag-Erling Smørgrav } 12107b5038d7SDag-Erling Smørgrav 12117b5038d7SDag-Erling Smørgrav /* write */ 12127b5038d7SDag-Erling Smørgrav void 12137b5038d7SDag-Erling Smørgrav ldns_key_list_set_use(ldns_key_list *keys, bool v) 12147b5038d7SDag-Erling Smørgrav { 12157b5038d7SDag-Erling Smørgrav size_t i; 12167b5038d7SDag-Erling Smørgrav 12177b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_key_list_key_count(keys); i++) { 12187b5038d7SDag-Erling Smørgrav ldns_key_set_use(ldns_key_list_key(keys, i), v); 12197b5038d7SDag-Erling Smørgrav } 12207b5038d7SDag-Erling Smørgrav } 12217b5038d7SDag-Erling Smørgrav 12227b5038d7SDag-Erling Smørgrav void 12237b5038d7SDag-Erling Smørgrav ldns_key_list_set_key_count(ldns_key_list *key, size_t count) 12247b5038d7SDag-Erling Smørgrav { 12257b5038d7SDag-Erling Smørgrav key->_key_count = count; 12267b5038d7SDag-Erling Smørgrav } 12277b5038d7SDag-Erling Smørgrav 12287b5038d7SDag-Erling Smørgrav bool 12297b5038d7SDag-Erling Smørgrav ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key) 12307b5038d7SDag-Erling Smørgrav { 12317b5038d7SDag-Erling Smørgrav size_t key_count; 12327b5038d7SDag-Erling Smørgrav ldns_key **keys; 12337b5038d7SDag-Erling Smørgrav 12347b5038d7SDag-Erling Smørgrav key_count = ldns_key_list_key_count(key_list); 12357b5038d7SDag-Erling Smørgrav 12367b5038d7SDag-Erling Smørgrav /* grow the array */ 12377b5038d7SDag-Erling Smørgrav keys = LDNS_XREALLOC( 12387b5038d7SDag-Erling Smørgrav key_list->_keys, ldns_key *, key_count + 1); 12397b5038d7SDag-Erling Smørgrav if (!keys) { 12407b5038d7SDag-Erling Smørgrav return false; 12417b5038d7SDag-Erling Smørgrav } 12427b5038d7SDag-Erling Smørgrav 12437b5038d7SDag-Erling Smørgrav /* add the new member */ 12447b5038d7SDag-Erling Smørgrav key_list->_keys = keys; 12457b5038d7SDag-Erling Smørgrav key_list->_keys[key_count] = key; 12467b5038d7SDag-Erling Smørgrav 12477b5038d7SDag-Erling Smørgrav ldns_key_list_set_key_count(key_list, key_count + 1); 12487b5038d7SDag-Erling Smørgrav return true; 12497b5038d7SDag-Erling Smørgrav } 12507b5038d7SDag-Erling Smørgrav 12517b5038d7SDag-Erling Smørgrav ldns_key * 12527b5038d7SDag-Erling Smørgrav ldns_key_list_pop_key(ldns_key_list *key_list) 12537b5038d7SDag-Erling Smørgrav { 12547b5038d7SDag-Erling Smørgrav size_t key_count; 12557b5038d7SDag-Erling Smørgrav ldns_key** a; 12567b5038d7SDag-Erling Smørgrav ldns_key *pop; 12577b5038d7SDag-Erling Smørgrav 12587b5038d7SDag-Erling Smørgrav if (!key_list) { 12597b5038d7SDag-Erling Smørgrav return NULL; 12607b5038d7SDag-Erling Smørgrav } 12617b5038d7SDag-Erling Smørgrav 12627b5038d7SDag-Erling Smørgrav key_count = ldns_key_list_key_count(key_list); 12637b5038d7SDag-Erling Smørgrav if (key_count == 0) { 12647b5038d7SDag-Erling Smørgrav return NULL; 12657b5038d7SDag-Erling Smørgrav } 12667b5038d7SDag-Erling Smørgrav 12677b5038d7SDag-Erling Smørgrav pop = ldns_key_list_key(key_list, key_count); 12687b5038d7SDag-Erling Smørgrav 12697b5038d7SDag-Erling Smørgrav /* shrink the array */ 12707b5038d7SDag-Erling Smørgrav a = LDNS_XREALLOC(key_list->_keys, ldns_key *, key_count - 1); 12717b5038d7SDag-Erling Smørgrav if(a) { 12727b5038d7SDag-Erling Smørgrav key_list->_keys = a; 12737b5038d7SDag-Erling Smørgrav } 12747b5038d7SDag-Erling Smørgrav 12757b5038d7SDag-Erling Smørgrav ldns_key_list_set_key_count(key_list, key_count - 1); 12767b5038d7SDag-Erling Smørgrav 12777b5038d7SDag-Erling Smørgrav return pop; 12787b5038d7SDag-Erling Smørgrav } 12797b5038d7SDag-Erling Smørgrav 12807b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 12817b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 12827b5038d7SDag-Erling Smørgrav /* data pointer must be large enough (LDNS_MAX_KEYLEN) */ 12837b5038d7SDag-Erling Smørgrav static bool 12847b5038d7SDag-Erling Smørgrav ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size) 12857b5038d7SDag-Erling Smørgrav { 12867b5038d7SDag-Erling Smørgrav int i,j; 12877b5038d7SDag-Erling Smørgrav 12887b5038d7SDag-Erling Smørgrav if (!k) { 12897b5038d7SDag-Erling Smørgrav return false; 12907b5038d7SDag-Erling Smørgrav } 12917b5038d7SDag-Erling Smørgrav 12927b5038d7SDag-Erling Smørgrav if (BN_num_bytes(k->e) <= 256) { 12937b5038d7SDag-Erling Smørgrav /* normally only this path is executed (small factors are 12947b5038d7SDag-Erling Smørgrav * more common 12957b5038d7SDag-Erling Smørgrav */ 12967b5038d7SDag-Erling Smørgrav data[0] = (unsigned char) BN_num_bytes(k->e); 12977b5038d7SDag-Erling Smørgrav i = BN_bn2bin(k->e, data + 1); 12987b5038d7SDag-Erling Smørgrav j = BN_bn2bin(k->n, data + i + 1); 12997b5038d7SDag-Erling Smørgrav *size = (uint16_t) i + j; 13007b5038d7SDag-Erling Smørgrav } else if (BN_num_bytes(k->e) <= 65536) { 13017b5038d7SDag-Erling Smørgrav data[0] = 0; 13027b5038d7SDag-Erling Smørgrav /* BN_bn2bin does bigendian, _uint16 also */ 13037b5038d7SDag-Erling Smørgrav ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(k->e)); 13047b5038d7SDag-Erling Smørgrav 13057b5038d7SDag-Erling Smørgrav BN_bn2bin(k->e, data + 3); 13067b5038d7SDag-Erling Smørgrav BN_bn2bin(k->n, data + 4 + BN_num_bytes(k->e)); 13077b5038d7SDag-Erling Smørgrav *size = (uint16_t) BN_num_bytes(k->n) + 6; 13087b5038d7SDag-Erling Smørgrav } else { 13097b5038d7SDag-Erling Smørgrav return false; 13107b5038d7SDag-Erling Smørgrav } 13117b5038d7SDag-Erling Smørgrav return true; 13127b5038d7SDag-Erling Smørgrav } 13137b5038d7SDag-Erling Smørgrav 13147b5038d7SDag-Erling Smørgrav /* data pointer must be large enough (LDNS_MAX_KEYLEN) */ 13157b5038d7SDag-Erling Smørgrav static bool 13167b5038d7SDag-Erling Smørgrav ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size) 13177b5038d7SDag-Erling Smørgrav { 13187b5038d7SDag-Erling Smørgrav uint8_t T; 13197b5038d7SDag-Erling Smørgrav 13207b5038d7SDag-Erling Smørgrav if (!k) { 13217b5038d7SDag-Erling Smørgrav return false; 13227b5038d7SDag-Erling Smørgrav } 13237b5038d7SDag-Erling Smørgrav 13247b5038d7SDag-Erling Smørgrav /* See RFC2536 */ 13252787e39aSDag-Erling Smørgrav *size = (uint16_t)BN_num_bytes(k->p); 13267b5038d7SDag-Erling Smørgrav T = (*size - 64) / 8; 13277b5038d7SDag-Erling Smørgrav memcpy(data, &T, 1); 13287b5038d7SDag-Erling Smørgrav 13297b5038d7SDag-Erling Smørgrav if (T > 8) { 1330*17d15b25SDag-Erling Smørgrav #ifdef STDERR_MSGS 13317b5038d7SDag-Erling Smørgrav fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)"); 13327b5038d7SDag-Erling Smørgrav fprintf(stderr, " not implemented\n"); 1333*17d15b25SDag-Erling Smørgrav #endif 13347b5038d7SDag-Erling Smørgrav return false; 13357b5038d7SDag-Erling Smørgrav } 13367b5038d7SDag-Erling Smørgrav 13377b5038d7SDag-Erling Smørgrav /* size = 64 + (T * 8); */ 13387b5038d7SDag-Erling Smørgrav data[0] = (unsigned char)T; 13397b5038d7SDag-Erling Smørgrav BN_bn2bin(k->q, data + 1 ); /* 20 octects */ 13407b5038d7SDag-Erling Smørgrav BN_bn2bin(k->p, data + 21 ); /* offset octects */ 13417b5038d7SDag-Erling Smørgrav BN_bn2bin(k->g, data + 21 + *size); /* offset octets */ 13427b5038d7SDag-Erling Smørgrav BN_bn2bin(k->pub_key, data + 21 + *size + *size); /* offset octets */ 13437b5038d7SDag-Erling Smørgrav *size = 21 + (*size * 3); 13447b5038d7SDag-Erling Smørgrav return true; 13457b5038d7SDag-Erling Smørgrav } 13467b5038d7SDag-Erling Smørgrav 13477b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 13487b5038d7SDag-Erling Smørgrav static bool 13497b5038d7SDag-Erling Smørgrav ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size) 13507b5038d7SDag-Erling Smørgrav { 13517b5038d7SDag-Erling Smørgrav int i; 13527b5038d7SDag-Erling Smørgrav unsigned char* pp = NULL; 13537b5038d7SDag-Erling Smørgrav if(i2d_PUBKEY(k, &pp) != 37 + 64) { 13547b5038d7SDag-Erling Smørgrav /* expect 37 byte(ASN header) and 64 byte(X and Y) */ 13557b5038d7SDag-Erling Smørgrav CRYPTO_free(pp); 13567b5038d7SDag-Erling Smørgrav return false; 13577b5038d7SDag-Erling Smørgrav } 13587b5038d7SDag-Erling Smørgrav /* omit ASN header */ 13597b5038d7SDag-Erling Smørgrav for(i=0; i<64; i++) 13607b5038d7SDag-Erling Smørgrav data[i] = pp[i+37]; 13617b5038d7SDag-Erling Smørgrav CRYPTO_free(pp); 13627b5038d7SDag-Erling Smørgrav *size = 64; 13637b5038d7SDag-Erling Smørgrav return true; 13647b5038d7SDag-Erling Smørgrav } 13657b5038d7SDag-Erling Smørgrav #endif /* USE_GOST */ 13667b5038d7SDag-Erling Smørgrav #endif /* splint */ 13677b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 13687b5038d7SDag-Erling Smørgrav 13697b5038d7SDag-Erling Smørgrav ldns_rr * 13707b5038d7SDag-Erling Smørgrav ldns_key2rr(const ldns_key *k) 13717b5038d7SDag-Erling Smørgrav { 13727b5038d7SDag-Erling Smørgrav /* this function will convert a the keydata contained in 13737b5038d7SDag-Erling Smørgrav * rsa/dsa pointers to a DNSKEY rr. It will fill in as 13747b5038d7SDag-Erling Smørgrav * much as it can, but it does not know about key-flags 13757b5038d7SDag-Erling Smørgrav * for instance 13767b5038d7SDag-Erling Smørgrav */ 13777b5038d7SDag-Erling Smørgrav ldns_rr *pubkey; 13787b5038d7SDag-Erling Smørgrav ldns_rdf *keybin; 13797b5038d7SDag-Erling Smørgrav unsigned char *bin = NULL; 13807b5038d7SDag-Erling Smørgrav uint16_t size = 0; 13817b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 13827b5038d7SDag-Erling Smørgrav RSA *rsa = NULL; 13837b5038d7SDag-Erling Smørgrav DSA *dsa = NULL; 13847b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 13857b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 13867b5038d7SDag-Erling Smørgrav EC_KEY* ec; 13877b5038d7SDag-Erling Smørgrav #endif 13887b5038d7SDag-Erling Smørgrav int internal_data = 0; 13897b5038d7SDag-Erling Smørgrav 13907b5038d7SDag-Erling Smørgrav if (!k) { 13917b5038d7SDag-Erling Smørgrav return NULL; 13927b5038d7SDag-Erling Smørgrav } 13932787e39aSDag-Erling Smørgrav pubkey = ldns_rr_new(); 13947b5038d7SDag-Erling Smørgrav 13957b5038d7SDag-Erling Smørgrav switch (ldns_key_algorithm(k)) { 13967b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACMD5: 13977b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA1: 13987b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA256: 13997b5038d7SDag-Erling Smørgrav ldns_rr_set_type(pubkey, LDNS_RR_TYPE_KEY); 14007b5038d7SDag-Erling Smørgrav break; 14017b5038d7SDag-Erling Smørgrav default: 14027b5038d7SDag-Erling Smørgrav ldns_rr_set_type(pubkey, LDNS_RR_TYPE_DNSKEY); 14037b5038d7SDag-Erling Smørgrav break; 14047b5038d7SDag-Erling Smørgrav } 14057b5038d7SDag-Erling Smørgrav /* zero-th rdf - flags */ 14067b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 14077b5038d7SDag-Erling Smørgrav ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16, 14087b5038d7SDag-Erling Smørgrav ldns_key_flags(k))); 14097b5038d7SDag-Erling Smørgrav /* first - proto */ 14107b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 14117b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, LDNS_DNSSEC_KEYPROTO)); 14127b5038d7SDag-Erling Smørgrav 14137b5038d7SDag-Erling Smørgrav if (ldns_key_pubkey_owner(k)) { 14147b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(pubkey, ldns_rdf_clone(ldns_key_pubkey_owner(k))); 14157b5038d7SDag-Erling Smørgrav } 14167b5038d7SDag-Erling Smørgrav 14177b5038d7SDag-Erling Smørgrav /* third - da algorithm */ 14187b5038d7SDag-Erling Smørgrav switch(ldns_key_algorithm(k)) { 14197b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSAMD5: 14207b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1: 14217b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA1_NSEC3: 14227b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA256: 14237b5038d7SDag-Erling Smørgrav case LDNS_SIGN_RSASHA512: 14247b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 14257b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); 14267b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 14277b5038d7SDag-Erling Smørgrav rsa = ldns_key_rsa_key(k); 14287b5038d7SDag-Erling Smørgrav if (rsa) { 14297b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 14307b5038d7SDag-Erling Smørgrav if (!bin) { 14317b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14327b5038d7SDag-Erling Smørgrav return NULL; 14337b5038d7SDag-Erling Smørgrav } 14347b5038d7SDag-Erling Smørgrav if (!ldns_key_rsa2bin(bin, rsa, &size)) { 14357b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 14367b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14377b5038d7SDag-Erling Smørgrav return NULL; 14387b5038d7SDag-Erling Smørgrav } 14397b5038d7SDag-Erling Smørgrav RSA_free(rsa); 14407b5038d7SDag-Erling Smørgrav internal_data = 1; 14417b5038d7SDag-Erling Smørgrav } 14427b5038d7SDag-Erling Smørgrav #endif 14437b5038d7SDag-Erling Smørgrav size++; 14447b5038d7SDag-Erling Smørgrav break; 14457b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA: 14467b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 14477b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA)); 14487b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 14497b5038d7SDag-Erling Smørgrav dsa = ldns_key_dsa_key(k); 14507b5038d7SDag-Erling Smørgrav if (dsa) { 14517b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 14527b5038d7SDag-Erling Smørgrav if (!bin) { 14537b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14547b5038d7SDag-Erling Smørgrav return NULL; 14557b5038d7SDag-Erling Smørgrav } 14567b5038d7SDag-Erling Smørgrav if (!ldns_key_dsa2bin(bin, dsa, &size)) { 14577b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 14587b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14597b5038d7SDag-Erling Smørgrav return NULL; 14607b5038d7SDag-Erling Smørgrav } 14617b5038d7SDag-Erling Smørgrav DSA_free(dsa); 14627b5038d7SDag-Erling Smørgrav internal_data = 1; 14637b5038d7SDag-Erling Smørgrav } 14647b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 14657b5038d7SDag-Erling Smørgrav break; 14667b5038d7SDag-Erling Smørgrav case LDNS_SIGN_DSA_NSEC3: 14677b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 14687b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3)); 14697b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 14707b5038d7SDag-Erling Smørgrav dsa = ldns_key_dsa_key(k); 14717b5038d7SDag-Erling Smørgrav if (dsa) { 14727b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 14737b5038d7SDag-Erling Smørgrav if (!bin) { 14747b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14757b5038d7SDag-Erling Smørgrav return NULL; 14767b5038d7SDag-Erling Smørgrav } 14777b5038d7SDag-Erling Smørgrav if (!ldns_key_dsa2bin(bin, dsa, &size)) { 14787b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 14797b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14807b5038d7SDag-Erling Smørgrav return NULL; 14817b5038d7SDag-Erling Smørgrav } 14827b5038d7SDag-Erling Smørgrav DSA_free(dsa); 14837b5038d7SDag-Erling Smørgrav internal_data = 1; 14847b5038d7SDag-Erling Smørgrav } 14857b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 14867b5038d7SDag-Erling Smørgrav break; 14877b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECC_GOST: 14887b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( 14897b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); 14907b5038d7SDag-Erling Smørgrav #if defined(HAVE_SSL) && defined(USE_GOST) 14917b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN); 14927b5038d7SDag-Erling Smørgrav if (!bin) { 14937b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 14947b5038d7SDag-Erling Smørgrav return NULL; 14957b5038d7SDag-Erling Smørgrav } 14967b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 14977b5038d7SDag-Erling Smørgrav if (!ldns_key_gost2bin(bin, k->_key.key, &size)) { 14987b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 14997b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 15007b5038d7SDag-Erling Smørgrav return NULL; 15017b5038d7SDag-Erling Smørgrav } 15027b5038d7SDag-Erling Smørgrav #endif /* splint */ 15037b5038d7SDag-Erling Smørgrav internal_data = 1; 15047b5038d7SDag-Erling Smørgrav #else 15057b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 15067b5038d7SDag-Erling Smørgrav return NULL; 15077b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL and USE_GOST */ 15087b5038d7SDag-Erling Smørgrav break; 15097b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP256SHA256: 15107b5038d7SDag-Erling Smørgrav case LDNS_SIGN_ECDSAP384SHA384: 15117b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA 15127b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8( 15137b5038d7SDag-Erling Smørgrav LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k))); 15147b5038d7SDag-Erling Smørgrav bin = NULL; 15157b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S 15167b5038d7SDag-Erling Smørgrav ec = EVP_PKEY_get1_EC_KEY(k->_key.key); 15177b5038d7SDag-Erling Smørgrav #endif 15187b5038d7SDag-Erling Smørgrav EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); 15197b5038d7SDag-Erling Smørgrav size = (uint16_t)i2o_ECPublicKey(ec, NULL); 15207b5038d7SDag-Erling Smørgrav if(!i2o_ECPublicKey(ec, &bin)) { 15217b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 15227b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 15237b5038d7SDag-Erling Smørgrav return NULL; 15247b5038d7SDag-Erling Smørgrav } 15257b5038d7SDag-Erling Smørgrav if(size > 1) { 15267b5038d7SDag-Erling Smørgrav /* move back one byte to shave off the 0x02 15277b5038d7SDag-Erling Smørgrav * 'uncompressed' indicator that openssl made 15287b5038d7SDag-Erling Smørgrav * Actually its 0x04 (from implementation). 15297b5038d7SDag-Erling Smørgrav */ 15307b5038d7SDag-Erling Smørgrav assert(bin[0] == POINT_CONVERSION_UNCOMPRESSED); 15317b5038d7SDag-Erling Smørgrav size -= 1; 15327b5038d7SDag-Erling Smørgrav memmove(bin, bin+1, size); 15337b5038d7SDag-Erling Smørgrav } 15347b5038d7SDag-Erling Smørgrav /* down the reference count for ec, its still assigned 15357b5038d7SDag-Erling Smørgrav * to the pkey */ 15367b5038d7SDag-Erling Smørgrav EC_KEY_free(ec); 15377b5038d7SDag-Erling Smørgrav internal_data = 1; 15387b5038d7SDag-Erling Smørgrav #else 15397b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 15407b5038d7SDag-Erling Smørgrav return NULL; 15417b5038d7SDag-Erling Smørgrav #endif /* ECDSA */ 15427b5038d7SDag-Erling Smørgrav break; 15437b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACMD5: 15447b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA1: 15457b5038d7SDag-Erling Smørgrav case LDNS_SIGN_HMACSHA256: 15467b5038d7SDag-Erling Smørgrav bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k)); 15477b5038d7SDag-Erling Smørgrav if (!bin) { 15487b5038d7SDag-Erling Smørgrav ldns_rr_free(pubkey); 15497b5038d7SDag-Erling Smørgrav return NULL; 15507b5038d7SDag-Erling Smørgrav } 15517b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, 15527b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, 15537b5038d7SDag-Erling Smørgrav ldns_key_algorithm(k))); 15547b5038d7SDag-Erling Smørgrav size = ldns_key_hmac_size(k); 15557b5038d7SDag-Erling Smørgrav memcpy(bin, ldns_key_hmac_key(k), size); 15567b5038d7SDag-Erling Smørgrav internal_data = 1; 15577b5038d7SDag-Erling Smørgrav break; 15587b5038d7SDag-Erling Smørgrav } 15597b5038d7SDag-Erling Smørgrav /* fourth the key bin material */ 15607b5038d7SDag-Erling Smørgrav if (internal_data) { 15617b5038d7SDag-Erling Smørgrav keybin = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, size, bin); 15627b5038d7SDag-Erling Smørgrav LDNS_FREE(bin); 15637b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf(pubkey, keybin); 15647b5038d7SDag-Erling Smørgrav } 15657b5038d7SDag-Erling Smørgrav return pubkey; 15667b5038d7SDag-Erling Smørgrav } 15677b5038d7SDag-Erling Smørgrav 15687b5038d7SDag-Erling Smørgrav void 15697b5038d7SDag-Erling Smørgrav ldns_key_free(ldns_key *key) 15707b5038d7SDag-Erling Smørgrav { 15717b5038d7SDag-Erling Smørgrav LDNS_FREE(key); 15727b5038d7SDag-Erling Smørgrav } 15737b5038d7SDag-Erling Smørgrav 15747b5038d7SDag-Erling Smørgrav void 15757b5038d7SDag-Erling Smørgrav ldns_key_deep_free(ldns_key *key) 15767b5038d7SDag-Erling Smørgrav { 15777b5038d7SDag-Erling Smørgrav unsigned char* hmac; 15787b5038d7SDag-Erling Smørgrav if (ldns_key_pubkey_owner(key)) { 15797b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(ldns_key_pubkey_owner(key)); 15807b5038d7SDag-Erling Smørgrav } 15817b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 15827b5038d7SDag-Erling Smørgrav if (ldns_key_evp_key(key)) { 15837b5038d7SDag-Erling Smørgrav EVP_PKEY_free(ldns_key_evp_key(key)); 15847b5038d7SDag-Erling Smørgrav } 15857b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 15867b5038d7SDag-Erling Smørgrav if (ldns_key_hmac_key(key)) { 15877b5038d7SDag-Erling Smørgrav hmac = ldns_key_hmac_key(key); 15887b5038d7SDag-Erling Smørgrav LDNS_FREE(hmac); 15897b5038d7SDag-Erling Smørgrav } 15907b5038d7SDag-Erling Smørgrav LDNS_FREE(key); 15917b5038d7SDag-Erling Smørgrav } 15927b5038d7SDag-Erling Smørgrav 15937b5038d7SDag-Erling Smørgrav void 15947b5038d7SDag-Erling Smørgrav ldns_key_list_free(ldns_key_list *key_list) 15957b5038d7SDag-Erling Smørgrav { 15967b5038d7SDag-Erling Smørgrav size_t i; 15977b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_key_list_key_count(key_list); i++) { 15987b5038d7SDag-Erling Smørgrav ldns_key_deep_free(ldns_key_list_key(key_list, i)); 15997b5038d7SDag-Erling Smørgrav } 16007b5038d7SDag-Erling Smørgrav LDNS_FREE(key_list->_keys); 16017b5038d7SDag-Erling Smørgrav LDNS_FREE(key_list); 16027b5038d7SDag-Erling Smørgrav } 16037b5038d7SDag-Erling Smørgrav 16047b5038d7SDag-Erling Smørgrav ldns_rr * 16057b5038d7SDag-Erling Smørgrav ldns_read_anchor_file(const char *filename) 16067b5038d7SDag-Erling Smørgrav { 16077b5038d7SDag-Erling Smørgrav FILE *fp; 16087b5038d7SDag-Erling Smørgrav /*char line[LDNS_MAX_PACKETLEN];*/ 16097b5038d7SDag-Erling Smørgrav char *line = LDNS_XMALLOC(char, LDNS_MAX_PACKETLEN); 16107b5038d7SDag-Erling Smørgrav int c; 16117b5038d7SDag-Erling Smørgrav size_t i = 0; 16127b5038d7SDag-Erling Smørgrav ldns_rr *r; 16137b5038d7SDag-Erling Smørgrav ldns_status status; 16147b5038d7SDag-Erling Smørgrav if(!line) { 16157b5038d7SDag-Erling Smørgrav return NULL; 16167b5038d7SDag-Erling Smørgrav } 16177b5038d7SDag-Erling Smørgrav 16187b5038d7SDag-Erling Smørgrav fp = fopen(filename, "r"); 16197b5038d7SDag-Erling Smørgrav if (!fp) { 1620*17d15b25SDag-Erling Smørgrav #ifdef STDERR_MSGS 16217b5038d7SDag-Erling Smørgrav fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno)); 1622*17d15b25SDag-Erling Smørgrav #endif 16237b5038d7SDag-Erling Smørgrav LDNS_FREE(line); 16247b5038d7SDag-Erling Smørgrav return NULL; 16257b5038d7SDag-Erling Smørgrav } 16267b5038d7SDag-Erling Smørgrav 16277b5038d7SDag-Erling Smørgrav while ((c = fgetc(fp)) && i+1 < LDNS_MAX_PACKETLEN && c != EOF) { 16287b5038d7SDag-Erling Smørgrav line[i] = c; 16297b5038d7SDag-Erling Smørgrav i++; 16307b5038d7SDag-Erling Smørgrav } 16317b5038d7SDag-Erling Smørgrav line[i] = '\0'; 16327b5038d7SDag-Erling Smørgrav 16337b5038d7SDag-Erling Smørgrav fclose(fp); 16347b5038d7SDag-Erling Smørgrav 16357b5038d7SDag-Erling Smørgrav if (i <= 0) { 1636*17d15b25SDag-Erling Smørgrav #ifdef STDERR_MSGS 16377b5038d7SDag-Erling Smørgrav fprintf(stderr, "nothing read from %s", filename); 1638*17d15b25SDag-Erling Smørgrav #endif 16397b5038d7SDag-Erling Smørgrav LDNS_FREE(line); 16407b5038d7SDag-Erling Smørgrav return NULL; 16417b5038d7SDag-Erling Smørgrav } else { 16427b5038d7SDag-Erling Smørgrav status = ldns_rr_new_frm_str(&r, line, 0, NULL, NULL); 16437b5038d7SDag-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)) { 16447b5038d7SDag-Erling Smørgrav LDNS_FREE(line); 16457b5038d7SDag-Erling Smørgrav return r; 16467b5038d7SDag-Erling Smørgrav } else { 1647*17d15b25SDag-Erling Smørgrav #ifdef STDERR_MSGS 16487b5038d7SDag-Erling Smørgrav fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status)); 1649*17d15b25SDag-Erling Smørgrav #endif 16507b5038d7SDag-Erling Smørgrav LDNS_FREE(line); 16517b5038d7SDag-Erling Smørgrav return NULL; 16527b5038d7SDag-Erling Smørgrav } 16537b5038d7SDag-Erling Smørgrav } 16547b5038d7SDag-Erling Smørgrav } 16557b5038d7SDag-Erling Smørgrav 16567b5038d7SDag-Erling Smørgrav char * 16577b5038d7SDag-Erling Smørgrav ldns_key_get_file_base_name(ldns_key *key) 16587b5038d7SDag-Erling Smørgrav { 16597b5038d7SDag-Erling Smørgrav ldns_buffer *buffer; 16607b5038d7SDag-Erling Smørgrav char *file_base_name; 16617b5038d7SDag-Erling Smørgrav 16627b5038d7SDag-Erling Smørgrav buffer = ldns_buffer_new(255); 16637b5038d7SDag-Erling Smørgrav ldns_buffer_printf(buffer, "K"); 16647b5038d7SDag-Erling Smørgrav (void)ldns_rdf2buffer_str_dname(buffer, ldns_key_pubkey_owner(key)); 16657b5038d7SDag-Erling Smørgrav ldns_buffer_printf(buffer, 16667b5038d7SDag-Erling Smørgrav "+%03u+%05u", 16677b5038d7SDag-Erling Smørgrav ldns_key_algorithm(key), 16687b5038d7SDag-Erling Smørgrav ldns_key_keytag(key)); 16692787e39aSDag-Erling Smørgrav file_base_name = ldns_buffer_export(buffer); 16707b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 16717b5038d7SDag-Erling Smørgrav return file_base_name; 16727b5038d7SDag-Erling Smørgrav } 16737b5038d7SDag-Erling Smørgrav 16747b5038d7SDag-Erling Smørgrav int ldns_key_algo_supported(int algo) 16757b5038d7SDag-Erling Smørgrav { 16767b5038d7SDag-Erling Smørgrav ldns_lookup_table *lt = ldns_signing_algorithms; 16777b5038d7SDag-Erling Smørgrav while(lt->name) { 16787b5038d7SDag-Erling Smørgrav if(lt->id == algo) 16797b5038d7SDag-Erling Smørgrav return 1; 16807b5038d7SDag-Erling Smørgrav lt++; 16817b5038d7SDag-Erling Smørgrav } 16827b5038d7SDag-Erling Smørgrav return 0; 16837b5038d7SDag-Erling Smørgrav } 16847b5038d7SDag-Erling Smørgrav 16857b5038d7SDag-Erling Smørgrav ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name) 16867b5038d7SDag-Erling Smørgrav { 16877b5038d7SDag-Erling Smørgrav /* list of (signing algorithm id, alias_name) */ 16887b5038d7SDag-Erling Smørgrav ldns_lookup_table aliases[] = { 16897b5038d7SDag-Erling Smørgrav /* from bind dnssec-keygen */ 16907b5038d7SDag-Erling Smørgrav {LDNS_SIGN_HMACMD5, "HMAC-MD5"}, 16917b5038d7SDag-Erling Smørgrav {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"}, 16927b5038d7SDag-Erling Smørgrav {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"}, 16937b5038d7SDag-Erling Smørgrav /* old ldns usage, now RFC names */ 16947b5038d7SDag-Erling Smørgrav {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" }, 16957b5038d7SDag-Erling Smørgrav {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" }, 16967b5038d7SDag-Erling Smørgrav #ifdef USE_GOST 16977b5038d7SDag-Erling Smørgrav {LDNS_SIGN_ECC_GOST, "GOST"}, 16987b5038d7SDag-Erling Smørgrav #endif 16997b5038d7SDag-Erling Smørgrav /* compat with possible output */ 17007b5038d7SDag-Erling Smørgrav {LDNS_DH, "DH"}, 17017b5038d7SDag-Erling Smørgrav {LDNS_ECC, "ECC"}, 17027b5038d7SDag-Erling Smørgrav {LDNS_INDIRECT, "INDIRECT"}, 17037b5038d7SDag-Erling Smørgrav {LDNS_PRIVATEDNS, "PRIVATEDNS"}, 17047b5038d7SDag-Erling Smørgrav {LDNS_PRIVATEOID, "PRIVATEOID"}, 17057b5038d7SDag-Erling Smørgrav {0, NULL}}; 17067b5038d7SDag-Erling Smørgrav ldns_lookup_table* lt = ldns_signing_algorithms; 17077b5038d7SDag-Erling Smørgrav while(lt->name) { 17087b5038d7SDag-Erling Smørgrav if(strcasecmp(lt->name, name) == 0) 17097b5038d7SDag-Erling Smørgrav return lt->id; 17107b5038d7SDag-Erling Smørgrav lt++; 17117b5038d7SDag-Erling Smørgrav } 17127b5038d7SDag-Erling Smørgrav lt = aliases; 17137b5038d7SDag-Erling Smørgrav while(lt->name) { 17147b5038d7SDag-Erling Smørgrav if(strcasecmp(lt->name, name) == 0) 17157b5038d7SDag-Erling Smørgrav return lt->id; 17167b5038d7SDag-Erling Smørgrav lt++; 17177b5038d7SDag-Erling Smørgrav } 17187b5038d7SDag-Erling Smørgrav if(atoi(name) != 0) 17197b5038d7SDag-Erling Smørgrav return atoi(name); 17207b5038d7SDag-Erling Smørgrav return 0; 17217b5038d7SDag-Erling Smørgrav } 1722