xref: /freebsd/contrib/ldns/keys.c (revision 5afab0e5e56fe90a378fb57249600e7924e1cab2)
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
18*5afab0e5SDag-Erling Smørgrav #include <openssl/ui.h>
197b5038d7SDag-Erling Smørgrav #include <openssl/ssl.h>
207b5038d7SDag-Erling Smørgrav #include <openssl/rand.h>
21*5afab0e5SDag-Erling Smørgrav #include <openssl/bn.h>
22*5afab0e5SDag-Erling Smørgrav #include <openssl/rsa.h>
23*5afab0e5SDag-Erling Smørgrav #ifdef USE_DSA
24*5afab0e5SDag-Erling Smørgrav #include <openssl/dsa.h>
25*5afab0e5SDag-Erling Smørgrav #endif
26*5afab0e5SDag-Erling Smørgrav #ifndef OPENSSL_NO_ENGINE
27*5afab0e5SDag-Erling Smørgrav #include <openssl/engine.h>
28*5afab0e5SDag-Erling Smørgrav #endif
297b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
307b5038d7SDag-Erling Smørgrav 
317b5038d7SDag-Erling Smørgrav ldns_lookup_table ldns_signing_algorithms[] = {
327b5038d7SDag-Erling Smørgrav         { LDNS_SIGN_RSAMD5, "RSAMD5" },
337b5038d7SDag-Erling Smørgrav         { LDNS_SIGN_RSASHA1, "RSASHA1" },
347b5038d7SDag-Erling Smørgrav         { LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
357b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2
367b5038d7SDag-Erling Smørgrav         { LDNS_SIGN_RSASHA256, "RSASHA256" },
377b5038d7SDag-Erling Smørgrav         { LDNS_SIGN_RSASHA512, "RSASHA512" },
387b5038d7SDag-Erling Smørgrav #endif
397b5038d7SDag-Erling Smørgrav #ifdef USE_GOST
407b5038d7SDag-Erling Smørgrav         { LDNS_SIGN_ECC_GOST, "ECC-GOST" },
417b5038d7SDag-Erling Smørgrav #endif
427b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA
437b5038d7SDag-Erling Smørgrav         { LDNS_SIGN_ECDSAP256SHA256, "ECDSAP256SHA256" },
447b5038d7SDag-Erling Smørgrav         { LDNS_SIGN_ECDSAP384SHA384, "ECDSAP384SHA384" },
457b5038d7SDag-Erling Smørgrav #endif
46986ba33cSDag-Erling Smørgrav #ifdef USE_ED25519
47986ba33cSDag-Erling Smørgrav 	{ LDNS_SIGN_ED25519, "ED25519" },
48986ba33cSDag-Erling Smørgrav #endif
49986ba33cSDag-Erling Smørgrav #ifdef USE_ED448
50986ba33cSDag-Erling Smørgrav 	{ LDNS_SIGN_ED448, "ED448" },
51986ba33cSDag-Erling Smørgrav #endif
52986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
537b5038d7SDag-Erling Smørgrav         { LDNS_SIGN_DSA, "DSA" },
547b5038d7SDag-Erling Smørgrav         { LDNS_SIGN_DSA_NSEC3, "DSA-NSEC3-SHA1" },
55986ba33cSDag-Erling Smørgrav #endif
567b5038d7SDag-Erling Smørgrav         { LDNS_SIGN_HMACMD5, "hmac-md5.sig-alg.reg.int" },
577b5038d7SDag-Erling Smørgrav         { LDNS_SIGN_HMACSHA1, "hmac-sha1" },
587b5038d7SDag-Erling Smørgrav         { LDNS_SIGN_HMACSHA256, "hmac-sha256" },
59986ba33cSDag-Erling Smørgrav         { LDNS_SIGN_HMACSHA224, "hmac-sha224" },
60986ba33cSDag-Erling Smørgrav         { LDNS_SIGN_HMACSHA384, "hmac-sha384" },
61986ba33cSDag-Erling Smørgrav         { LDNS_SIGN_HMACSHA512, "hmac-sha512" },
627b5038d7SDag-Erling Smørgrav         { 0, NULL }
637b5038d7SDag-Erling Smørgrav };
647b5038d7SDag-Erling Smørgrav 
657b5038d7SDag-Erling Smørgrav ldns_key_list *
ldns_key_list_new(void)667b5038d7SDag-Erling Smørgrav ldns_key_list_new(void)
677b5038d7SDag-Erling Smørgrav {
687b5038d7SDag-Erling Smørgrav 	ldns_key_list *key_list = LDNS_MALLOC(ldns_key_list);
697b5038d7SDag-Erling Smørgrav 	if (!key_list) {
707b5038d7SDag-Erling Smørgrav 		return NULL;
717b5038d7SDag-Erling Smørgrav 	} else {
727b5038d7SDag-Erling Smørgrav 		key_list->_key_count = 0;
737b5038d7SDag-Erling Smørgrav 		key_list->_keys = NULL;
747b5038d7SDag-Erling Smørgrav 		return key_list;
757b5038d7SDag-Erling Smørgrav 	}
767b5038d7SDag-Erling Smørgrav }
777b5038d7SDag-Erling Smørgrav 
787b5038d7SDag-Erling Smørgrav ldns_key *
ldns_key_new(void)797b5038d7SDag-Erling Smørgrav ldns_key_new(void)
807b5038d7SDag-Erling Smørgrav {
817b5038d7SDag-Erling Smørgrav 	ldns_key *newkey;
827b5038d7SDag-Erling Smørgrav 
837b5038d7SDag-Erling Smørgrav 	newkey = LDNS_MALLOC(ldns_key);
847b5038d7SDag-Erling Smørgrav 	if (!newkey) {
857b5038d7SDag-Erling Smørgrav 		return NULL;
867b5038d7SDag-Erling Smørgrav 	} else {
87*5afab0e5SDag-Erling Smørgrav 		/* some defaults - not sure whether to do this */
887b5038d7SDag-Erling Smørgrav 		ldns_key_set_use(newkey, true);
897b5038d7SDag-Erling Smørgrav 		ldns_key_set_flags(newkey, LDNS_KEY_ZONE_KEY);
907b5038d7SDag-Erling Smørgrav 		ldns_key_set_origttl(newkey, 0);
917b5038d7SDag-Erling Smørgrav 		ldns_key_set_keytag(newkey, 0);
927b5038d7SDag-Erling Smørgrav 		ldns_key_set_inception(newkey, 0);
937b5038d7SDag-Erling Smørgrav 		ldns_key_set_expiration(newkey, 0);
947b5038d7SDag-Erling Smørgrav 		ldns_key_set_pubkey_owner(newkey, NULL);
957b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
967b5038d7SDag-Erling Smørgrav 		ldns_key_set_evp_key(newkey, NULL);
977b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
987b5038d7SDag-Erling Smørgrav 		ldns_key_set_hmac_key(newkey, NULL);
997b5038d7SDag-Erling Smørgrav 		ldns_key_set_external_key(newkey, NULL);
1007b5038d7SDag-Erling Smørgrav 		return newkey;
1017b5038d7SDag-Erling Smørgrav 	}
1027b5038d7SDag-Erling Smørgrav }
1037b5038d7SDag-Erling Smørgrav 
1047b5038d7SDag-Erling Smørgrav ldns_status
ldns_key_new_frm_fp(ldns_key ** k,FILE * fp)1057b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp(ldns_key **k, FILE *fp)
1067b5038d7SDag-Erling Smørgrav {
1077b5038d7SDag-Erling Smørgrav 	return ldns_key_new_frm_fp_l(k, fp, NULL);
1087b5038d7SDag-Erling Smørgrav }
1097b5038d7SDag-Erling Smørgrav 
110*5afab0e5SDag-Erling Smørgrav #if defined(HAVE_SSL) && !defined(OPENSSL_NO_ENGINE)
1117b5038d7SDag-Erling Smørgrav ldns_status
ldns_key_new_frm_engine(ldns_key ** key,ENGINE * e,char * key_id,ldns_algorithm alg)1127b5038d7SDag-Erling Smørgrav ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm alg)
1137b5038d7SDag-Erling Smørgrav {
1147b5038d7SDag-Erling Smørgrav 	ldns_key *k;
1157b5038d7SDag-Erling Smørgrav 
1167b5038d7SDag-Erling Smørgrav 	k = ldns_key_new();
1177b5038d7SDag-Erling Smørgrav         if(!k) return LDNS_STATUS_MEM_ERR;
1187b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S
1197b5038d7SDag-Erling Smørgrav 	k->_key.key = ENGINE_load_private_key(e, key_id, UI_OpenSSL(), NULL);
1207b5038d7SDag-Erling Smørgrav         if(!k->_key.key) {
1217b5038d7SDag-Erling Smørgrav                 ldns_key_free(k);
1227b5038d7SDag-Erling Smørgrav                 return LDNS_STATUS_ERR;
1237b5038d7SDag-Erling Smørgrav         }
1247b5038d7SDag-Erling Smørgrav 	ldns_key_set_algorithm(k, (ldns_signing_algorithm) alg);
1257b5038d7SDag-Erling Smørgrav 	if (!k->_key.key) {
1267b5038d7SDag-Erling Smørgrav                 ldns_key_free(k);
1277b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_ENGINE_KEY_NOT_LOADED;
1287b5038d7SDag-Erling Smørgrav 	}
1297b5038d7SDag-Erling Smørgrav #endif /* splint */
1307b5038d7SDag-Erling Smørgrav 	*key = k;
1317b5038d7SDag-Erling Smørgrav 	return LDNS_STATUS_OK;
1327b5038d7SDag-Erling Smørgrav }
1337b5038d7SDag-Erling Smørgrav #endif
1347b5038d7SDag-Erling Smørgrav 
1357b5038d7SDag-Erling Smørgrav #ifdef USE_GOST
1367b5038d7SDag-Erling Smørgrav /** store GOST engine reference loaded into OpenSSL library */
1377b5038d7SDag-Erling Smørgrav ENGINE* ldns_gost_engine = NULL;
1387b5038d7SDag-Erling Smørgrav 
1397b5038d7SDag-Erling Smørgrav int
ldns_key_EVP_load_gost_id(void)1407b5038d7SDag-Erling Smørgrav ldns_key_EVP_load_gost_id(void)
1417b5038d7SDag-Erling Smørgrav {
1427b5038d7SDag-Erling Smørgrav 	static int gost_id = 0;
1437b5038d7SDag-Erling Smørgrav 	const EVP_PKEY_ASN1_METHOD* meth;
1447b5038d7SDag-Erling Smørgrav 	ENGINE* e;
1457b5038d7SDag-Erling Smørgrav 
1467b5038d7SDag-Erling Smørgrav 	if(gost_id) return gost_id;
1477b5038d7SDag-Erling Smørgrav 
1487b5038d7SDag-Erling Smørgrav 	/* see if configuration loaded gost implementation from other engine*/
1497b5038d7SDag-Erling Smørgrav 	meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
1507b5038d7SDag-Erling Smørgrav 	if(meth) {
1517b5038d7SDag-Erling Smørgrav 		EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
1527b5038d7SDag-Erling Smørgrav 		return gost_id;
1537b5038d7SDag-Erling Smørgrav 	}
1547b5038d7SDag-Erling Smørgrav 
1557b5038d7SDag-Erling Smørgrav 	/* see if engine can be loaded already */
1567b5038d7SDag-Erling Smørgrav 	e = ENGINE_by_id("gost");
1577b5038d7SDag-Erling Smørgrav 	if(!e) {
1587b5038d7SDag-Erling Smørgrav 		/* load it ourself, in case statically linked */
1597b5038d7SDag-Erling Smørgrav 		ENGINE_load_builtin_engines();
1607b5038d7SDag-Erling Smørgrav 		ENGINE_load_dynamic();
1617b5038d7SDag-Erling Smørgrav 		e = ENGINE_by_id("gost");
1627b5038d7SDag-Erling Smørgrav 	}
1637b5038d7SDag-Erling Smørgrav 	if(!e) {
1647b5038d7SDag-Erling Smørgrav 		/* no gost engine in openssl */
1657b5038d7SDag-Erling Smørgrav 		return 0;
1667b5038d7SDag-Erling Smørgrav 	}
1677b5038d7SDag-Erling Smørgrav 	if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
1687b5038d7SDag-Erling Smørgrav 		ENGINE_finish(e);
1697b5038d7SDag-Erling Smørgrav 		ENGINE_free(e);
1707b5038d7SDag-Erling Smørgrav 		return 0;
1717b5038d7SDag-Erling Smørgrav 	}
1727b5038d7SDag-Erling Smørgrav 
1737b5038d7SDag-Erling Smørgrav 	meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
1747b5038d7SDag-Erling Smørgrav 	if(!meth) {
1757b5038d7SDag-Erling Smørgrav 		/* algo not found */
1767b5038d7SDag-Erling Smørgrav 		ENGINE_finish(e);
1777b5038d7SDag-Erling Smørgrav 		ENGINE_free(e);
1787b5038d7SDag-Erling Smørgrav 		return 0;
1797b5038d7SDag-Erling Smørgrav 	}
1807b5038d7SDag-Erling Smørgrav         /* Note: do not ENGINE_finish and ENGINE_free the acquired engine
1817b5038d7SDag-Erling Smørgrav          * on some platforms this frees up the meth and unloads gost stuff */
1827b5038d7SDag-Erling Smørgrav         ldns_gost_engine = e;
1837b5038d7SDag-Erling Smørgrav 
1847b5038d7SDag-Erling Smørgrav 	EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
1857b5038d7SDag-Erling Smørgrav 	return gost_id;
1867b5038d7SDag-Erling Smørgrav }
1877b5038d7SDag-Erling Smørgrav 
ldns_key_EVP_unload_gost(void)1887b5038d7SDag-Erling Smørgrav void ldns_key_EVP_unload_gost(void)
1897b5038d7SDag-Erling Smørgrav {
1907b5038d7SDag-Erling Smørgrav         if(ldns_gost_engine) {
1917b5038d7SDag-Erling Smørgrav                 ENGINE_finish(ldns_gost_engine);
1927b5038d7SDag-Erling Smørgrav                 ENGINE_free(ldns_gost_engine);
1937b5038d7SDag-Erling Smørgrav                 ldns_gost_engine = NULL;
1947b5038d7SDag-Erling Smørgrav         }
1957b5038d7SDag-Erling Smørgrav }
1967b5038d7SDag-Erling Smørgrav 
1977b5038d7SDag-Erling Smørgrav /** read GOST private key */
1987b5038d7SDag-Erling Smørgrav static EVP_PKEY*
ldns_key_new_frm_fp_gost_l(FILE * fp,int * line_nr)1997b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_gost_l(FILE* fp, int* line_nr)
2007b5038d7SDag-Erling Smørgrav {
2017b5038d7SDag-Erling Smørgrav 	char token[16384];
2027b5038d7SDag-Erling Smørgrav 	const unsigned char* pp;
2037b5038d7SDag-Erling Smørgrav 	int gost_id;
2047b5038d7SDag-Erling Smørgrav 	EVP_PKEY* pkey;
2057b5038d7SDag-Erling Smørgrav 	ldns_rdf* b64rdf = NULL;
2067b5038d7SDag-Erling Smørgrav 
2077b5038d7SDag-Erling Smørgrav 	gost_id = ldns_key_EVP_load_gost_id();
2087b5038d7SDag-Erling Smørgrav 	if(!gost_id)
2097b5038d7SDag-Erling Smørgrav 		return NULL;
2107b5038d7SDag-Erling Smørgrav 
2117b5038d7SDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(fp, "GostAsn1", ": ", token, "\n",
2127b5038d7SDag-Erling Smørgrav 		sizeof(token), line_nr) == -1)
2137b5038d7SDag-Erling Smørgrav 		return NULL;
2147b5038d7SDag-Erling Smørgrav 	while(strlen(token) < 96) {
2157b5038d7SDag-Erling Smørgrav 		/* read more b64 from the file, b64 split on multiple lines */
2167b5038d7SDag-Erling Smørgrav 		if(ldns_fget_token_l(fp, token+strlen(token), "\n",
2177b5038d7SDag-Erling Smørgrav 			sizeof(token)-strlen(token), line_nr) == -1)
2187b5038d7SDag-Erling Smørgrav 			return NULL;
2197b5038d7SDag-Erling Smørgrav 	}
2207b5038d7SDag-Erling Smørgrav 	if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
2217b5038d7SDag-Erling Smørgrav 		return NULL;
2227b5038d7SDag-Erling Smørgrav 	pp = (unsigned char*)ldns_rdf_data(b64rdf);
2237b5038d7SDag-Erling Smørgrav 	pkey = d2i_PrivateKey(gost_id, NULL, &pp, (int)ldns_rdf_size(b64rdf));
2247b5038d7SDag-Erling Smørgrav 	ldns_rdf_deep_free(b64rdf);
2257b5038d7SDag-Erling Smørgrav 	return pkey;
2267b5038d7SDag-Erling Smørgrav }
2277b5038d7SDag-Erling Smørgrav #endif
2287b5038d7SDag-Erling Smørgrav 
2297b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA
2307b5038d7SDag-Erling Smørgrav /** calculate public key from private key */
2317b5038d7SDag-Erling Smørgrav static int
ldns_EC_KEY_calc_public(EC_KEY * ec)2327b5038d7SDag-Erling Smørgrav ldns_EC_KEY_calc_public(EC_KEY* ec)
2337b5038d7SDag-Erling Smørgrav {
2347b5038d7SDag-Erling Smørgrav         EC_POINT* pub_key;
2357b5038d7SDag-Erling Smørgrav         const EC_GROUP* group;
2367b5038d7SDag-Erling Smørgrav         group = EC_KEY_get0_group(ec);
2377b5038d7SDag-Erling Smørgrav         pub_key = EC_POINT_new(group);
2387b5038d7SDag-Erling Smørgrav         if(!pub_key) return 0;
2397b5038d7SDag-Erling Smørgrav         if(!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
2407b5038d7SDag-Erling Smørgrav                 EC_POINT_free(pub_key);
2417b5038d7SDag-Erling Smørgrav                 return 0;
2427b5038d7SDag-Erling Smørgrav         }
2437b5038d7SDag-Erling Smørgrav         if(!EC_POINT_mul(group, pub_key, EC_KEY_get0_private_key(ec),
2447b5038d7SDag-Erling Smørgrav                 NULL, NULL, NULL)) {
2457b5038d7SDag-Erling Smørgrav                 EC_POINT_free(pub_key);
2467b5038d7SDag-Erling Smørgrav                 return 0;
2477b5038d7SDag-Erling Smørgrav         }
2487b5038d7SDag-Erling Smørgrav         if(EC_KEY_set_public_key(ec, pub_key) == 0) {
2497b5038d7SDag-Erling Smørgrav                 EC_POINT_free(pub_key);
2507b5038d7SDag-Erling Smørgrav                 return 0;
2517b5038d7SDag-Erling Smørgrav         }
2527b5038d7SDag-Erling Smørgrav         EC_POINT_free(pub_key);
2537b5038d7SDag-Erling Smørgrav         return 1;
2547b5038d7SDag-Erling Smørgrav }
2557b5038d7SDag-Erling Smørgrav 
2567b5038d7SDag-Erling Smørgrav /** read ECDSA private key */
2577b5038d7SDag-Erling Smørgrav static EVP_PKEY*
ldns_key_new_frm_fp_ecdsa_l(FILE * fp,ldns_algorithm alg,int * line_nr)2587b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_ecdsa_l(FILE* fp, ldns_algorithm alg, int* line_nr)
2597b5038d7SDag-Erling Smørgrav {
2607b5038d7SDag-Erling Smørgrav 	char token[16384];
2617b5038d7SDag-Erling Smørgrav         ldns_rdf* b64rdf = NULL;
2627b5038d7SDag-Erling Smørgrav         unsigned char* pp;
2637b5038d7SDag-Erling Smørgrav         BIGNUM* bn;
2647b5038d7SDag-Erling Smørgrav         EVP_PKEY* evp_key;
2657b5038d7SDag-Erling Smørgrav         EC_KEY* ec;
2667b5038d7SDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n",
2677b5038d7SDag-Erling Smørgrav 		sizeof(token), line_nr) == -1)
2687b5038d7SDag-Erling Smørgrav 		return NULL;
2697b5038d7SDag-Erling Smørgrav 	if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
2707b5038d7SDag-Erling Smørgrav 		return NULL;
2717b5038d7SDag-Erling Smørgrav         pp = (unsigned char*)ldns_rdf_data(b64rdf);
2727b5038d7SDag-Erling Smørgrav 
2737b5038d7SDag-Erling Smørgrav         if(alg == LDNS_ECDSAP256SHA256)
2747b5038d7SDag-Erling Smørgrav                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
2757b5038d7SDag-Erling Smørgrav         else if(alg == LDNS_ECDSAP384SHA384)
2767b5038d7SDag-Erling Smørgrav                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
2777b5038d7SDag-Erling Smørgrav         else    ec = NULL;
2787b5038d7SDag-Erling Smørgrav         if(!ec) {
2797b5038d7SDag-Erling Smørgrav 	        ldns_rdf_deep_free(b64rdf);
2807b5038d7SDag-Erling Smørgrav                 return NULL;
2817b5038d7SDag-Erling Smørgrav         }
2827b5038d7SDag-Erling Smørgrav 	bn = BN_bin2bn(pp, (int)ldns_rdf_size(b64rdf), NULL);
2837b5038d7SDag-Erling Smørgrav 	ldns_rdf_deep_free(b64rdf);
2847b5038d7SDag-Erling Smørgrav         if(!bn) {
2857b5038d7SDag-Erling Smørgrav                 EC_KEY_free(ec);
2867b5038d7SDag-Erling Smørgrav                 return NULL;
2877b5038d7SDag-Erling Smørgrav         }
2887b5038d7SDag-Erling Smørgrav         EC_KEY_set_private_key(ec, bn);
2897b5038d7SDag-Erling Smørgrav         BN_free(bn);
2907b5038d7SDag-Erling Smørgrav         if(!ldns_EC_KEY_calc_public(ec)) {
2917b5038d7SDag-Erling Smørgrav                 EC_KEY_free(ec);
2927b5038d7SDag-Erling Smørgrav                 return NULL;
2937b5038d7SDag-Erling Smørgrav         }
2947b5038d7SDag-Erling Smørgrav 
2957b5038d7SDag-Erling Smørgrav         evp_key = EVP_PKEY_new();
2967b5038d7SDag-Erling Smørgrav         if(!evp_key) {
2977b5038d7SDag-Erling Smørgrav                 EC_KEY_free(ec);
2987b5038d7SDag-Erling Smørgrav                 return NULL;
2997b5038d7SDag-Erling Smørgrav         }
3007b5038d7SDag-Erling Smørgrav         if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
3017b5038d7SDag-Erling Smørgrav 		EVP_PKEY_free(evp_key);
3027b5038d7SDag-Erling Smørgrav                 EC_KEY_free(ec);
3037b5038d7SDag-Erling Smørgrav                 return NULL;
3047b5038d7SDag-Erling Smørgrav 	}
3057b5038d7SDag-Erling Smørgrav         return evp_key;
3067b5038d7SDag-Erling Smørgrav }
3077b5038d7SDag-Erling Smørgrav #endif
3087b5038d7SDag-Erling Smørgrav 
309986ba33cSDag-Erling Smørgrav #ifdef USE_ED25519
310986ba33cSDag-Erling Smørgrav /** turn private key buffer into EC_KEY structure */
311*5afab0e5SDag-Erling Smørgrav static EVP_PKEY*
ldns_ed25519_priv_raw(uint8_t * pkey,int plen)312986ba33cSDag-Erling Smørgrav ldns_ed25519_priv_raw(uint8_t* pkey, int plen)
313986ba33cSDag-Erling Smørgrav {
314986ba33cSDag-Erling Smørgrav 	const unsigned char* pp;
315986ba33cSDag-Erling Smørgrav 	uint8_t buf[256];
316986ba33cSDag-Erling Smørgrav 	int buflen = 0;
317*5afab0e5SDag-Erling Smørgrav 	uint8_t pre[] = {0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06,
318*5afab0e5SDag-Erling Smørgrav 		0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20};
319*5afab0e5SDag-Erling Smørgrav 	int pre_len = 16;
320*5afab0e5SDag-Erling Smørgrav 	/* ASN looks like this for ED25519 public key
321*5afab0e5SDag-Erling Smørgrav 	 * 302a300506032b6570032100 <32byteskey>
322*5afab0e5SDag-Erling Smørgrav 	 * for ED25519 private key
323*5afab0e5SDag-Erling Smørgrav 	 * 302e020100300506032b657004220420 <32bytes>
324*5afab0e5SDag-Erling Smørgrav 	 *
325*5afab0e5SDag-Erling Smørgrav 	 * for X25519 this was
326986ba33cSDag-Erling Smørgrav 	 * 30320201010420 <32byteskey>
327986ba33cSDag-Erling Smørgrav 	 * andparameters a00b06092b06010401da470f01
328986ba33cSDag-Erling Smørgrav 	 * (noparameters, preamble is 30250201010420).
329986ba33cSDag-Erling Smørgrav 	 * the key is reversed (little endian).
330986ba33cSDag-Erling Smørgrav 	 */
331*5afab0e5SDag-Erling Smørgrav 	buflen = pre_len + plen;
332986ba33cSDag-Erling Smørgrav 	if((size_t)buflen > sizeof(buf))
333986ba33cSDag-Erling Smørgrav 		return NULL;
334986ba33cSDag-Erling Smørgrav 	memmove(buf, pre, pre_len);
335*5afab0e5SDag-Erling Smørgrav 	memmove(buf+pre_len, pkey, plen);
336*5afab0e5SDag-Erling Smørgrav 	/* reverse the pkey into the buf - key is not reversed it seems */
337*5afab0e5SDag-Erling Smørgrav 	/* for(i=0; i<plen; i++)
338*5afab0e5SDag-Erling Smørgrav 		buf[pre_len+i] = pkey[plen-1-i]; */
339986ba33cSDag-Erling Smørgrav 	pp = buf;
340*5afab0e5SDag-Erling Smørgrav 	return d2i_PrivateKey(NID_ED25519, NULL, &pp, buflen);
341986ba33cSDag-Erling Smørgrav }
342986ba33cSDag-Erling Smørgrav 
343986ba33cSDag-Erling Smørgrav /** read ED25519 private key */
344986ba33cSDag-Erling Smørgrav static EVP_PKEY*
ldns_key_new_frm_fp_ed25519_l(FILE * fp,int * line_nr)345986ba33cSDag-Erling Smørgrav ldns_key_new_frm_fp_ed25519_l(FILE* fp, int* line_nr)
346986ba33cSDag-Erling Smørgrav {
347986ba33cSDag-Erling Smørgrav 	char token[16384];
348986ba33cSDag-Erling Smørgrav         ldns_rdf* b64rdf = NULL;
349986ba33cSDag-Erling Smørgrav         EVP_PKEY* evp_key;
350986ba33cSDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n",
351986ba33cSDag-Erling Smørgrav 		sizeof(token), line_nr) == -1)
352986ba33cSDag-Erling Smørgrav 		return NULL;
353986ba33cSDag-Erling Smørgrav 	if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
354986ba33cSDag-Erling Smørgrav 		return NULL;
355986ba33cSDag-Erling Smørgrav 
356986ba33cSDag-Erling Smørgrav 	/* we use d2i_ECPrivateKey because it calculates the public key
357986ba33cSDag-Erling Smørgrav 	 * from the private part, which others, EC_KEY_set_private_key,
358986ba33cSDag-Erling Smørgrav 	 * and o2i methods, do not do */
359986ba33cSDag-Erling Smørgrav 	/* for that the private key has to be encoded in ASN1 notation
360*5afab0e5SDag-Erling Smørgrav 	 * with a ED25519 prefix on it */
361986ba33cSDag-Erling Smørgrav 
362*5afab0e5SDag-Erling Smørgrav 	evp_key = ldns_ed25519_priv_raw(ldns_rdf_data(b64rdf),
363986ba33cSDag-Erling Smørgrav 		(int)ldns_rdf_size(b64rdf));
364986ba33cSDag-Erling Smørgrav 	ldns_rdf_deep_free(b64rdf);
365986ba33cSDag-Erling Smørgrav         return evp_key;
366986ba33cSDag-Erling Smørgrav }
367986ba33cSDag-Erling Smørgrav #endif
368986ba33cSDag-Erling Smørgrav 
369986ba33cSDag-Erling Smørgrav #ifdef USE_ED448
370986ba33cSDag-Erling Smørgrav /** turn private key buffer into EC_KEY structure */
371*5afab0e5SDag-Erling Smørgrav static EVP_PKEY*
ldns_ed448_priv_raw(uint8_t * pkey,int plen)372986ba33cSDag-Erling Smørgrav ldns_ed448_priv_raw(uint8_t* pkey, int plen)
373986ba33cSDag-Erling Smørgrav {
374986ba33cSDag-Erling Smørgrav 	const unsigned char* pp;
375986ba33cSDag-Erling Smørgrav 	uint8_t buf[256];
376986ba33cSDag-Erling Smørgrav 	int buflen = 0;
377*5afab0e5SDag-Erling Smørgrav 	uint8_t pre[] = {0x30, 0x47, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x71, 0x04, 0x3b, 0x04, 0x39};
378*5afab0e5SDag-Erling Smørgrav 	int pre_len = 16;
379*5afab0e5SDag-Erling Smørgrav 	/* ASN looks like this for ED448
380*5afab0e5SDag-Erling Smørgrav 	 * 3047020100300506032b6571043b0439 <57bytekey>
381986ba33cSDag-Erling Smørgrav 	 * the key is reversed (little endian).
382986ba33cSDag-Erling Smørgrav 	 */
383*5afab0e5SDag-Erling Smørgrav 	buflen = pre_len + plen;
384986ba33cSDag-Erling Smørgrav 	if((size_t)buflen > sizeof(buf))
385986ba33cSDag-Erling Smørgrav 		return NULL;
386986ba33cSDag-Erling Smørgrav 	memmove(buf, pre, pre_len);
387*5afab0e5SDag-Erling Smørgrav 	memmove(buf+pre_len, pkey, plen);
388*5afab0e5SDag-Erling Smørgrav 	/* reverse the pkey into the buf - key is not reversed it seems */
389*5afab0e5SDag-Erling Smørgrav 	/* for(i=0; i<plen; i++)
390*5afab0e5SDag-Erling Smørgrav 		buf[pre_len+i] = pkey[plen-1-i]; */
391986ba33cSDag-Erling Smørgrav 	pp = buf;
392*5afab0e5SDag-Erling Smørgrav 	return d2i_PrivateKey(NID_ED448, NULL, &pp, buflen);
393986ba33cSDag-Erling Smørgrav }
394986ba33cSDag-Erling Smørgrav 
395986ba33cSDag-Erling Smørgrav /** read ED448 private key */
396986ba33cSDag-Erling Smørgrav static EVP_PKEY*
ldns_key_new_frm_fp_ed448_l(FILE * fp,int * line_nr)397986ba33cSDag-Erling Smørgrav ldns_key_new_frm_fp_ed448_l(FILE* fp, int* line_nr)
398986ba33cSDag-Erling Smørgrav {
399986ba33cSDag-Erling Smørgrav 	char token[16384];
400986ba33cSDag-Erling Smørgrav         ldns_rdf* b64rdf = NULL;
401986ba33cSDag-Erling Smørgrav         EVP_PKEY* evp_key;
402986ba33cSDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(fp, "PrivateKey", ": ", token, "\n",
403986ba33cSDag-Erling Smørgrav 		sizeof(token), line_nr) == -1)
404986ba33cSDag-Erling Smørgrav 		return NULL;
405986ba33cSDag-Erling Smørgrav 	if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
406986ba33cSDag-Erling Smørgrav 		return NULL;
407986ba33cSDag-Erling Smørgrav 
408986ba33cSDag-Erling Smørgrav 	/* convert private key into ASN notation and then convert that */
409*5afab0e5SDag-Erling Smørgrav 	evp_key = ldns_ed448_priv_raw(ldns_rdf_data(b64rdf),
410986ba33cSDag-Erling Smørgrav 		(int)ldns_rdf_size(b64rdf));
411986ba33cSDag-Erling Smørgrav 	ldns_rdf_deep_free(b64rdf);
412986ba33cSDag-Erling Smørgrav 	return evp_key;
413986ba33cSDag-Erling Smørgrav }
414986ba33cSDag-Erling Smørgrav #endif
415986ba33cSDag-Erling Smørgrav 
4167b5038d7SDag-Erling Smørgrav ldns_status
ldns_key_new_frm_fp_l(ldns_key ** key,FILE * fp,int * line_nr)4177b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
4187b5038d7SDag-Erling Smørgrav {
4197b5038d7SDag-Erling Smørgrav 	ldns_key *k;
4207b5038d7SDag-Erling Smørgrav 	char *d;
4217b5038d7SDag-Erling Smørgrav 	ldns_signing_algorithm alg;
4227b5038d7SDag-Erling Smørgrav 	ldns_rr *key_rr;
4237b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
4247b5038d7SDag-Erling Smørgrav 	RSA *rsa;
425986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
4267b5038d7SDag-Erling Smørgrav 	DSA *dsa;
427986ba33cSDag-Erling Smørgrav #endif
4287b5038d7SDag-Erling Smørgrav 	unsigned char *hmac;
4297b5038d7SDag-Erling Smørgrav 	size_t hmac_size;
4307b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
4317b5038d7SDag-Erling Smørgrav 
4327b5038d7SDag-Erling Smørgrav 	k = ldns_key_new();
4337b5038d7SDag-Erling Smørgrav 
4347b5038d7SDag-Erling Smørgrav 	d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
4357b5038d7SDag-Erling Smørgrav 	if (!k || !d) {
4367b5038d7SDag-Erling Smørgrav                 ldns_key_free(k);
4377b5038d7SDag-Erling Smørgrav                 LDNS_FREE(d);
4387b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_MEM_ERR;
4397b5038d7SDag-Erling Smørgrav 	}
4407b5038d7SDag-Erling Smørgrav 
4417b5038d7SDag-Erling Smørgrav 	alg = 0;
4427b5038d7SDag-Erling Smørgrav 
4437b5038d7SDag-Erling Smørgrav 	/* the file is highly structured. Do this in sequence */
4447b5038d7SDag-Erling Smørgrav 	/* RSA:
4457b5038d7SDag-Erling Smørgrav 	 * Private-key-format: v1.x.
4467b5038d7SDag-Erling Smørgrav  	 * Algorithm: 1 (RSA)
4477b5038d7SDag-Erling Smørgrav 
4487b5038d7SDag-Erling Smørgrav 	 */
4497b5038d7SDag-Erling Smørgrav 	/* get the key format version number */
4507b5038d7SDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(fp, "Private-key-format", ": ", d, "\n",
4517b5038d7SDag-Erling Smørgrav 				LDNS_MAX_LINELEN, line_nr) == -1) {
4527b5038d7SDag-Erling Smørgrav 		/* no version information */
4537b5038d7SDag-Erling Smørgrav                 ldns_key_free(k);
4547b5038d7SDag-Erling Smørgrav                 LDNS_FREE(d);
4557b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_SYNTAX_ERR;
4567b5038d7SDag-Erling Smørgrav 	}
4577b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "v1.", 3) != 0) {
4587b5038d7SDag-Erling Smørgrav                 ldns_key_free(k);
4597b5038d7SDag-Erling Smørgrav                 LDNS_FREE(d);
4607b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_SYNTAX_VERSION_ERR;
4617b5038d7SDag-Erling Smørgrav 	}
4627b5038d7SDag-Erling Smørgrav 
4637b5038d7SDag-Erling Smørgrav 	/* get the algorithm type, our file function strip ( ) so there are
4647b5038d7SDag-Erling Smørgrav 	 * not in the return string! */
4657b5038d7SDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(fp, "Algorithm", ": ", d, "\n",
4667b5038d7SDag-Erling Smørgrav 				LDNS_MAX_LINELEN, line_nr) == -1) {
4677b5038d7SDag-Erling Smørgrav 		/* no alg information */
4687b5038d7SDag-Erling Smørgrav                 ldns_key_free(k);
4697b5038d7SDag-Erling Smørgrav                 LDNS_FREE(d);
4707b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_SYNTAX_ALG_ERR;
4717b5038d7SDag-Erling Smørgrav 	}
4727b5038d7SDag-Erling Smørgrav 
4737b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "1 RSA", 2) == 0) {
4747b5038d7SDag-Erling Smørgrav 		alg = LDNS_SIGN_RSAMD5;
4757b5038d7SDag-Erling Smørgrav 	}
4767b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "2 DH", 2) == 0) {
4777b5038d7SDag-Erling Smørgrav 		alg = (ldns_signing_algorithm)LDNS_DH;
4787b5038d7SDag-Erling Smørgrav 	}
4797b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "3 DSA", 2) == 0) {
480986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
4817b5038d7SDag-Erling Smørgrav 		alg = LDNS_SIGN_DSA;
482986ba33cSDag-Erling Smørgrav #else
483986ba33cSDag-Erling Smørgrav # ifdef STDERR_MSGS
484986ba33cSDag-Erling Smørgrav 		fprintf(stderr, "Warning: DSA not compiled into this ");
485986ba33cSDag-Erling Smørgrav 		fprintf(stderr, "version of ldns\n");
486986ba33cSDag-Erling Smørgrav # endif
487986ba33cSDag-Erling Smørgrav #endif
4887b5038d7SDag-Erling Smørgrav 	}
4897b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "4 ECC", 2) == 0) {
4907b5038d7SDag-Erling Smørgrav 		alg = (ldns_signing_algorithm)LDNS_ECC;
4917b5038d7SDag-Erling Smørgrav 	}
4927b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "5 RSASHA1", 2) == 0) {
4937b5038d7SDag-Erling Smørgrav 		alg = LDNS_SIGN_RSASHA1;
4947b5038d7SDag-Erling Smørgrav 	}
4957b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "6 DSA", 2) == 0) {
496986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
4977b5038d7SDag-Erling Smørgrav 		alg = LDNS_SIGN_DSA_NSEC3;
498986ba33cSDag-Erling Smørgrav #else
499986ba33cSDag-Erling Smørgrav # ifdef STDERR_MSGS
500986ba33cSDag-Erling Smørgrav 		fprintf(stderr, "Warning: DSA not compiled into this ");
501986ba33cSDag-Erling Smørgrav 		fprintf(stderr, "version of ldns\n");
502986ba33cSDag-Erling Smørgrav # endif
503986ba33cSDag-Erling Smørgrav #endif
5047b5038d7SDag-Erling Smørgrav 	}
5057b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "7 RSASHA1", 2) == 0) {
5067b5038d7SDag-Erling Smørgrav 		alg = LDNS_SIGN_RSASHA1_NSEC3;
5077b5038d7SDag-Erling Smørgrav 	}
5087b5038d7SDag-Erling Smørgrav 
5097b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "8 RSASHA256", 2) == 0) {
5107b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2
5117b5038d7SDag-Erling Smørgrav 		alg = LDNS_SIGN_RSASHA256;
5127b5038d7SDag-Erling Smørgrav #else
51317d15b25SDag-Erling Smørgrav # ifdef STDERR_MSGS
5147b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "Warning: SHA256 not compiled into this ");
5157b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "version of ldns\n");
5167b5038d7SDag-Erling Smørgrav # endif
51717d15b25SDag-Erling Smørgrav #endif
5187b5038d7SDag-Erling Smørgrav 	}
5197b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "10 RSASHA512", 3) == 0) {
5207b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2
5217b5038d7SDag-Erling Smørgrav 		alg = LDNS_SIGN_RSASHA512;
5227b5038d7SDag-Erling Smørgrav #else
52317d15b25SDag-Erling Smørgrav # ifdef STDERR_MSGS
5247b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "Warning: SHA512 not compiled into this ");
5257b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "version of ldns\n");
5267b5038d7SDag-Erling Smørgrav # endif
52717d15b25SDag-Erling Smørgrav #endif
5287b5038d7SDag-Erling Smørgrav 	}
5297b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "12 ECC-GOST", 3) == 0) {
5307b5038d7SDag-Erling Smørgrav #ifdef USE_GOST
5317b5038d7SDag-Erling Smørgrav 		alg = LDNS_SIGN_ECC_GOST;
5327b5038d7SDag-Erling Smørgrav #else
53317d15b25SDag-Erling Smørgrav # ifdef STDERR_MSGS
5347b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "Warning: ECC-GOST not compiled into this ");
5357b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "version of ldns, use --enable-gost\n");
5367b5038d7SDag-Erling Smørgrav # endif
53717d15b25SDag-Erling Smørgrav #endif
5387b5038d7SDag-Erling Smørgrav 	}
5397b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "13 ECDSAP256SHA256", 3) == 0) {
5407b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA
5417b5038d7SDag-Erling Smørgrav                 alg = LDNS_SIGN_ECDSAP256SHA256;
5427b5038d7SDag-Erling Smørgrav #else
54317d15b25SDag-Erling Smørgrav # ifdef STDERR_MSGS
5447b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "Warning: ECDSA not compiled into this ");
5457b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "version of ldns, use --enable-ecdsa\n");
5467b5038d7SDag-Erling Smørgrav # endif
54717d15b25SDag-Erling Smørgrav #endif
5487b5038d7SDag-Erling Smørgrav         }
5497b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "14 ECDSAP384SHA384", 3) == 0) {
5507b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA
5517b5038d7SDag-Erling Smørgrav                 alg = LDNS_SIGN_ECDSAP384SHA384;
5527b5038d7SDag-Erling Smørgrav #else
55317d15b25SDag-Erling Smørgrav # ifdef STDERR_MSGS
5547b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "Warning: ECDSA not compiled into this ");
5557b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "version of ldns, use --enable-ecdsa\n");
5567b5038d7SDag-Erling Smørgrav # endif
55717d15b25SDag-Erling Smørgrav #endif
5587b5038d7SDag-Erling Smørgrav         }
559986ba33cSDag-Erling Smørgrav 	if (strncmp(d, "15 ED25519", 3) == 0) {
560986ba33cSDag-Erling Smørgrav #ifdef USE_ED25519
561986ba33cSDag-Erling Smørgrav                 alg = LDNS_SIGN_ED25519;
562986ba33cSDag-Erling Smørgrav #else
563986ba33cSDag-Erling Smørgrav # ifdef STDERR_MSGS
564986ba33cSDag-Erling Smørgrav 		fprintf(stderr, "Warning: ED25519 not compiled into this ");
565986ba33cSDag-Erling Smørgrav 		fprintf(stderr, "version of ldns, use --enable-ed25519\n");
566986ba33cSDag-Erling Smørgrav # endif
567986ba33cSDag-Erling Smørgrav #endif
568986ba33cSDag-Erling Smørgrav         }
569986ba33cSDag-Erling Smørgrav 	if (strncmp(d, "16 ED448", 3) == 0) {
570986ba33cSDag-Erling Smørgrav #ifdef USE_ED448
571986ba33cSDag-Erling Smørgrav                 alg = LDNS_SIGN_ED448;
572986ba33cSDag-Erling Smørgrav #else
573986ba33cSDag-Erling Smørgrav # ifdef STDERR_MSGS
574986ba33cSDag-Erling Smørgrav 		fprintf(stderr, "Warning: ED448 not compiled into this ");
575986ba33cSDag-Erling Smørgrav 		fprintf(stderr, "version of ldns, use --enable-ed448\n");
576986ba33cSDag-Erling Smørgrav # endif
577986ba33cSDag-Erling Smørgrav #endif
578986ba33cSDag-Erling Smørgrav         }
5797b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "157 HMAC-MD5", 4) == 0) {
5807b5038d7SDag-Erling Smørgrav 		alg = LDNS_SIGN_HMACMD5;
5817b5038d7SDag-Erling Smørgrav 	}
5827b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "158 HMAC-SHA1", 4) == 0) {
5837b5038d7SDag-Erling Smørgrav 		alg = LDNS_SIGN_HMACSHA1;
5847b5038d7SDag-Erling Smørgrav 	}
5857b5038d7SDag-Erling Smørgrav 	if (strncmp(d, "159 HMAC-SHA256", 4) == 0) {
5867b5038d7SDag-Erling Smørgrav 		alg = LDNS_SIGN_HMACSHA256;
5877b5038d7SDag-Erling Smørgrav 	}
588986ba33cSDag-Erling Smørgrav 	/* For compatibility with dnssec-keygen */
589986ba33cSDag-Erling Smørgrav 	if (strncmp(d, "161 ", 4) == 0) {
590986ba33cSDag-Erling Smørgrav 		alg = LDNS_SIGN_HMACSHA1;
591986ba33cSDag-Erling Smørgrav 	}
592986ba33cSDag-Erling Smørgrav 	if (strncmp(d, "162 HMAC-SHA224", 4) == 0) {
593986ba33cSDag-Erling Smørgrav 		alg = LDNS_SIGN_HMACSHA224;
594986ba33cSDag-Erling Smørgrav 	}
595986ba33cSDag-Erling Smørgrav 	/* For compatibility with dnssec-keygen */
596986ba33cSDag-Erling Smørgrav 	if (strncmp(d, "163 ", 4) == 0) {
597986ba33cSDag-Erling Smørgrav 		alg = LDNS_SIGN_HMACSHA256;
598986ba33cSDag-Erling Smørgrav 	}
599986ba33cSDag-Erling Smørgrav 	if (strncmp(d, "164 HMAC-SHA384", 4) == 0) {
600986ba33cSDag-Erling Smørgrav 		alg = LDNS_SIGN_HMACSHA384;
601986ba33cSDag-Erling Smørgrav 	}
602986ba33cSDag-Erling Smørgrav 	if (strncmp(d, "165 HMAC-SHA512", 4) == 0) {
603986ba33cSDag-Erling Smørgrav 		alg = LDNS_SIGN_HMACSHA512;
604986ba33cSDag-Erling Smørgrav 	}
6057b5038d7SDag-Erling Smørgrav 	LDNS_FREE(d);
6067b5038d7SDag-Erling Smørgrav 
6077b5038d7SDag-Erling Smørgrav 	switch(alg) {
6087b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSAMD5:
6097b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSASHA1:
6107b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSASHA1_NSEC3:
6117b5038d7SDag-Erling Smørgrav #ifdef USE_SHA2
6127b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSASHA256:
6137b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSASHA512:
6147b5038d7SDag-Erling Smørgrav #endif
6157b5038d7SDag-Erling Smørgrav 			ldns_key_set_algorithm(k, alg);
6167b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
6177b5038d7SDag-Erling Smørgrav 			rsa = ldns_key_new_frm_fp_rsa_l(fp, line_nr);
6187b5038d7SDag-Erling Smørgrav 			if (!rsa) {
6197b5038d7SDag-Erling Smørgrav 				ldns_key_free(k);
6207b5038d7SDag-Erling Smørgrav 				return LDNS_STATUS_ERR;
6217b5038d7SDag-Erling Smørgrav 			}
6222787e39aSDag-Erling Smørgrav 			ldns_key_assign_rsa_key(k, rsa);
6237b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
6247b5038d7SDag-Erling Smørgrav 			break;
625986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
6267b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_DSA:
6277b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_DSA_NSEC3:
6287b5038d7SDag-Erling Smørgrav 			ldns_key_set_algorithm(k, alg);
6297b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
6307b5038d7SDag-Erling Smørgrav 			dsa = ldns_key_new_frm_fp_dsa_l(fp, line_nr);
6317b5038d7SDag-Erling Smørgrav 			if (!dsa) {
6327b5038d7SDag-Erling Smørgrav 				ldns_key_free(k);
6337b5038d7SDag-Erling Smørgrav 				return LDNS_STATUS_ERR;
6347b5038d7SDag-Erling Smørgrav 			}
6352787e39aSDag-Erling Smørgrav 			ldns_key_assign_dsa_key(k, dsa);
6367b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
6377b5038d7SDag-Erling Smørgrav 			break;
638986ba33cSDag-Erling Smørgrav #endif /* USE_DSA */
6397b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_HMACMD5:
6407b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA1:
641986ba33cSDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA224:
6427b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA256:
643986ba33cSDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA384:
644986ba33cSDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA512:
6457b5038d7SDag-Erling Smørgrav 			ldns_key_set_algorithm(k, alg);
6467b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
6477b5038d7SDag-Erling Smørgrav 			hmac = ldns_key_new_frm_fp_hmac_l(fp, line_nr, &hmac_size);
6487b5038d7SDag-Erling Smørgrav 			if (!hmac) {
6497b5038d7SDag-Erling Smørgrav 				ldns_key_free(k);
6507b5038d7SDag-Erling Smørgrav 				return LDNS_STATUS_ERR;
6517b5038d7SDag-Erling Smørgrav 			}
6527b5038d7SDag-Erling Smørgrav 			ldns_key_set_hmac_size(k, hmac_size);
6537b5038d7SDag-Erling Smørgrav 			ldns_key_set_hmac_key(k, hmac);
6547b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
6557b5038d7SDag-Erling Smørgrav 			break;
6567b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_ECC_GOST:
6577b5038d7SDag-Erling Smørgrav 			ldns_key_set_algorithm(k, alg);
6587b5038d7SDag-Erling Smørgrav #if defined(HAVE_SSL) && defined(USE_GOST)
6597b5038d7SDag-Erling Smørgrav                         if(!ldns_key_EVP_load_gost_id()) {
6607b5038d7SDag-Erling Smørgrav 				ldns_key_free(k);
6617b5038d7SDag-Erling Smørgrav                                 return LDNS_STATUS_CRYPTO_ALGO_NOT_IMPL;
6627b5038d7SDag-Erling Smørgrav                         }
6637b5038d7SDag-Erling Smørgrav 			ldns_key_set_evp_key(k,
6647b5038d7SDag-Erling Smørgrav 				ldns_key_new_frm_fp_gost_l(fp, line_nr));
6657b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S
6667b5038d7SDag-Erling Smørgrav 			if(!k->_key.key) {
6677b5038d7SDag-Erling Smørgrav 				ldns_key_free(k);
6687b5038d7SDag-Erling Smørgrav 				return LDNS_STATUS_ERR;
6697b5038d7SDag-Erling Smørgrav 			}
6707b5038d7SDag-Erling Smørgrav #endif /* splint */
6717b5038d7SDag-Erling Smørgrav #endif
6727b5038d7SDag-Erling Smørgrav 			break;
6737b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA
6747b5038d7SDag-Erling Smørgrav                case LDNS_SIGN_ECDSAP256SHA256:
6757b5038d7SDag-Erling Smørgrav                case LDNS_SIGN_ECDSAP384SHA384:
6767b5038d7SDag-Erling Smørgrav                         ldns_key_set_algorithm(k, alg);
6777b5038d7SDag-Erling Smørgrav                         ldns_key_set_evp_key(k,
6787b5038d7SDag-Erling Smørgrav                                 ldns_key_new_frm_fp_ecdsa_l(fp, (ldns_algorithm)alg, line_nr));
6797b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S
6807b5038d7SDag-Erling Smørgrav 			if(!k->_key.key) {
6817b5038d7SDag-Erling Smørgrav 				ldns_key_free(k);
6827b5038d7SDag-Erling Smørgrav 				return LDNS_STATUS_ERR;
6837b5038d7SDag-Erling Smørgrav 			}
6847b5038d7SDag-Erling Smørgrav #endif /* splint */
6857b5038d7SDag-Erling Smørgrav 			break;
6867b5038d7SDag-Erling Smørgrav #endif
687986ba33cSDag-Erling Smørgrav #ifdef USE_ED25519
688986ba33cSDag-Erling Smørgrav 		case LDNS_SIGN_ED25519:
689986ba33cSDag-Erling Smørgrav                         ldns_key_set_algorithm(k, alg);
690986ba33cSDag-Erling Smørgrav                         ldns_key_set_evp_key(k,
691986ba33cSDag-Erling Smørgrav                                 ldns_key_new_frm_fp_ed25519_l(fp, line_nr));
692986ba33cSDag-Erling Smørgrav #ifndef S_SPLINT_S
693986ba33cSDag-Erling Smørgrav 			if(!k->_key.key) {
694986ba33cSDag-Erling Smørgrav 				ldns_key_free(k);
695986ba33cSDag-Erling Smørgrav 				return LDNS_STATUS_ERR;
696986ba33cSDag-Erling Smørgrav 			}
697986ba33cSDag-Erling Smørgrav #endif /* splint */
698986ba33cSDag-Erling Smørgrav 			break;
699986ba33cSDag-Erling Smørgrav #endif
700986ba33cSDag-Erling Smørgrav #ifdef USE_ED448
701986ba33cSDag-Erling Smørgrav 		case LDNS_SIGN_ED448:
702986ba33cSDag-Erling Smørgrav                         ldns_key_set_algorithm(k, alg);
703986ba33cSDag-Erling Smørgrav                         ldns_key_set_evp_key(k,
704986ba33cSDag-Erling Smørgrav                                 ldns_key_new_frm_fp_ed448_l(fp, line_nr));
705986ba33cSDag-Erling Smørgrav #ifndef S_SPLINT_S
706986ba33cSDag-Erling Smørgrav 			if(!k->_key.key) {
707986ba33cSDag-Erling Smørgrav 				ldns_key_free(k);
708986ba33cSDag-Erling Smørgrav 				return LDNS_STATUS_ERR;
709986ba33cSDag-Erling Smørgrav 			}
710986ba33cSDag-Erling Smørgrav #endif /* splint */
711986ba33cSDag-Erling Smørgrav 			break;
712986ba33cSDag-Erling Smørgrav #endif
7137b5038d7SDag-Erling Smørgrav 		default:
7147b5038d7SDag-Erling Smørgrav 			ldns_key_free(k);
7157b5038d7SDag-Erling Smørgrav 			return LDNS_STATUS_SYNTAX_ALG_ERR;
7167b5038d7SDag-Erling Smørgrav 	}
7177b5038d7SDag-Erling Smørgrav 	key_rr = ldns_key2rr(k);
7187b5038d7SDag-Erling Smørgrav 	ldns_key_set_keytag(k, ldns_calc_keytag(key_rr));
7197b5038d7SDag-Erling Smørgrav 	ldns_rr_free(key_rr);
7207b5038d7SDag-Erling Smørgrav 
7217b5038d7SDag-Erling Smørgrav 	if (key) {
7227b5038d7SDag-Erling Smørgrav 		*key = k;
7237b5038d7SDag-Erling Smørgrav 		return LDNS_STATUS_OK;
7247b5038d7SDag-Erling Smørgrav 	}
7252787e39aSDag-Erling Smørgrav 	ldns_key_free(k);
7267b5038d7SDag-Erling Smørgrav 	return LDNS_STATUS_ERR;
7277b5038d7SDag-Erling Smørgrav }
7287b5038d7SDag-Erling Smørgrav 
7297b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
7307b5038d7SDag-Erling Smørgrav RSA *
ldns_key_new_frm_fp_rsa(FILE * f)7317b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_rsa(FILE *f)
7327b5038d7SDag-Erling Smørgrav {
7337b5038d7SDag-Erling Smørgrav 	return ldns_key_new_frm_fp_rsa_l(f, NULL);
7347b5038d7SDag-Erling Smørgrav }
7357b5038d7SDag-Erling Smørgrav 
7367b5038d7SDag-Erling Smørgrav RSA *
ldns_key_new_frm_fp_rsa_l(FILE * f,int * line_nr)7377b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_rsa_l(FILE *f, int *line_nr)
7387b5038d7SDag-Erling Smørgrav {
7397b5038d7SDag-Erling Smørgrav 	/* we parse
7407b5038d7SDag-Erling Smørgrav  	 * Modulus:
7417b5038d7SDag-Erling Smørgrav  	 * PublicExponent:
7427b5038d7SDag-Erling Smørgrav  	 * PrivateExponent:
7437b5038d7SDag-Erling Smørgrav  	 * Prime1:
7447b5038d7SDag-Erling Smørgrav  	 * Prime2:
7457b5038d7SDag-Erling Smørgrav  	 * Exponent1:
7467b5038d7SDag-Erling Smørgrav  	 * Exponent2:
7477b5038d7SDag-Erling Smørgrav  	 * Coefficient:
7487b5038d7SDag-Erling Smørgrav 	 *
7497b5038d7SDag-Erling Smørgrav 	 * man 3 RSA:
7507b5038d7SDag-Erling Smørgrav 	 *
7517b5038d7SDag-Erling Smørgrav 	 * struct
7527b5038d7SDag-Erling Smørgrav          *     {
7537b5038d7SDag-Erling Smørgrav          *     BIGNUM *n;              // public modulus
7547b5038d7SDag-Erling Smørgrav          *     BIGNUM *e;              // public exponent
7557b5038d7SDag-Erling Smørgrav          *     BIGNUM *d;              // private exponent
7567b5038d7SDag-Erling Smørgrav          *     BIGNUM *p;              // secret prime factor
7577b5038d7SDag-Erling Smørgrav          *     BIGNUM *q;              // secret prime factor
7587b5038d7SDag-Erling Smørgrav          *     BIGNUM *dmp1;           // d mod (p-1)
7597b5038d7SDag-Erling Smørgrav          *     BIGNUM *dmq1;           // d mod (q-1)
7607b5038d7SDag-Erling Smørgrav          *     BIGNUM *iqmp;           // q^-1 mod p
7617b5038d7SDag-Erling Smørgrav          *     // ...
7627b5038d7SDag-Erling Smørgrav 	 *
7637b5038d7SDag-Erling Smørgrav 	 */
764986ba33cSDag-Erling Smørgrav 	char *b;
7657b5038d7SDag-Erling Smørgrav 	RSA *rsa;
7667b5038d7SDag-Erling Smørgrav 	uint8_t *buf;
7677b5038d7SDag-Erling Smørgrav 	int i;
768986ba33cSDag-Erling Smørgrav 	BIGNUM *n=NULL, *e=NULL, *d=NULL, *p=NULL, *q=NULL,
769986ba33cSDag-Erling Smørgrav 		*dmp1=NULL, *dmq1=NULL, *iqmp=NULL;
7707b5038d7SDag-Erling Smørgrav 
771986ba33cSDag-Erling Smørgrav 	b = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
7727b5038d7SDag-Erling Smørgrav 	buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
7737b5038d7SDag-Erling Smørgrav 	rsa = RSA_new();
774986ba33cSDag-Erling Smørgrav 	if (!b || !rsa || !buf) {
7757b5038d7SDag-Erling Smørgrav                 goto error;
7767b5038d7SDag-Erling Smørgrav 	}
7777b5038d7SDag-Erling Smørgrav 
7787b5038d7SDag-Erling Smørgrav 	/* I could use functions again, but that seems an overkill,
779*5afab0e5SDag-Erling Smørgrav 	 * although this also looks tedious
7807b5038d7SDag-Erling Smørgrav 	 */
7817b5038d7SDag-Erling Smørgrav 
7827b5038d7SDag-Erling Smørgrav 	/* Modules, rsa->n */
783986ba33cSDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(f, "Modulus", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
7847b5038d7SDag-Erling Smørgrav 		goto error;
7857b5038d7SDag-Erling Smørgrav 	}
786986ba33cSDag-Erling Smørgrav 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
7877b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S
788986ba33cSDag-Erling Smørgrav 	n = BN_bin2bn((const char unsigned*)buf, i, NULL);
789986ba33cSDag-Erling Smørgrav 	if (!n) {
7907b5038d7SDag-Erling Smørgrav 		goto error;
7917b5038d7SDag-Erling Smørgrav 	}
7927b5038d7SDag-Erling Smørgrav 
7937b5038d7SDag-Erling Smørgrav 	/* PublicExponent, rsa->e */
794986ba33cSDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(f, "PublicExponent", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
7957b5038d7SDag-Erling Smørgrav 		goto error;
7967b5038d7SDag-Erling Smørgrav 	}
797986ba33cSDag-Erling Smørgrav 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
798986ba33cSDag-Erling Smørgrav 	e = BN_bin2bn((const char unsigned*)buf, i, NULL);
799986ba33cSDag-Erling Smørgrav 	if (!e) {
8007b5038d7SDag-Erling Smørgrav 		goto error;
8017b5038d7SDag-Erling Smørgrav 	}
8027b5038d7SDag-Erling Smørgrav 
8037b5038d7SDag-Erling Smørgrav 	/* PrivateExponent, rsa->d */
804986ba33cSDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(f, "PrivateExponent", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
8057b5038d7SDag-Erling Smørgrav 		goto error;
8067b5038d7SDag-Erling Smørgrav 	}
807986ba33cSDag-Erling Smørgrav 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
808986ba33cSDag-Erling Smørgrav 	d = BN_bin2bn((const char unsigned*)buf, i, NULL);
809986ba33cSDag-Erling Smørgrav 	if (!d) {
8107b5038d7SDag-Erling Smørgrav 		goto error;
8117b5038d7SDag-Erling Smørgrav 	}
8127b5038d7SDag-Erling Smørgrav 
8137b5038d7SDag-Erling Smørgrav 	/* Prime1, rsa->p */
814986ba33cSDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(f, "Prime1", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
8157b5038d7SDag-Erling Smørgrav 		goto error;
8167b5038d7SDag-Erling Smørgrav 	}
817986ba33cSDag-Erling Smørgrav 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
818986ba33cSDag-Erling Smørgrav 	p = BN_bin2bn((const char unsigned*)buf, i, NULL);
819986ba33cSDag-Erling Smørgrav 	if (!p) {
8207b5038d7SDag-Erling Smørgrav 		goto error;
8217b5038d7SDag-Erling Smørgrav 	}
8227b5038d7SDag-Erling Smørgrav 
8237b5038d7SDag-Erling Smørgrav 	/* Prime2, rsa->q */
824986ba33cSDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(f, "Prime2", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
8257b5038d7SDag-Erling Smørgrav 		goto error;
8267b5038d7SDag-Erling Smørgrav 	}
827986ba33cSDag-Erling Smørgrav 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
828986ba33cSDag-Erling Smørgrav 	q = BN_bin2bn((const char unsigned*)buf, i, NULL);
829986ba33cSDag-Erling Smørgrav 	if (!q) {
8307b5038d7SDag-Erling Smørgrav 		goto error;
8317b5038d7SDag-Erling Smørgrav 	}
8327b5038d7SDag-Erling Smørgrav 
8337b5038d7SDag-Erling Smørgrav 	/* Exponent1, rsa->dmp1 */
834986ba33cSDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(f, "Exponent1", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
8357b5038d7SDag-Erling Smørgrav 		goto error;
8367b5038d7SDag-Erling Smørgrav 	}
837986ba33cSDag-Erling Smørgrav 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
838986ba33cSDag-Erling Smørgrav 	dmp1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
839986ba33cSDag-Erling Smørgrav 	if (!dmp1) {
8407b5038d7SDag-Erling Smørgrav 		goto error;
8417b5038d7SDag-Erling Smørgrav 	}
8427b5038d7SDag-Erling Smørgrav 
8437b5038d7SDag-Erling Smørgrav 	/* Exponent2, rsa->dmq1 */
844986ba33cSDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(f, "Exponent2", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
8457b5038d7SDag-Erling Smørgrav 		goto error;
8467b5038d7SDag-Erling Smørgrav 	}
847986ba33cSDag-Erling Smørgrav 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
848986ba33cSDag-Erling Smørgrav 	dmq1 = BN_bin2bn((const char unsigned*)buf, i, NULL);
849986ba33cSDag-Erling Smørgrav 	if (!dmq1) {
8507b5038d7SDag-Erling Smørgrav 		goto error;
8517b5038d7SDag-Erling Smørgrav 	}
8527b5038d7SDag-Erling Smørgrav 
8537b5038d7SDag-Erling Smørgrav 	/* Coefficient, rsa->iqmp */
854986ba33cSDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(f, "Coefficient", ": ", b, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
8557b5038d7SDag-Erling Smørgrav 		goto error;
8567b5038d7SDag-Erling Smørgrav 	}
857986ba33cSDag-Erling Smørgrav 	i = ldns_b64_pton((const char*)b, buf, ldns_b64_ntop_calculate_size(strlen(b)));
858986ba33cSDag-Erling Smørgrav 	iqmp = BN_bin2bn((const char unsigned*)buf, i, NULL);
859986ba33cSDag-Erling Smørgrav 	if (!iqmp) {
8607b5038d7SDag-Erling Smørgrav 		goto error;
8617b5038d7SDag-Erling Smørgrav 	}
8627b5038d7SDag-Erling Smørgrav #endif /* splint */
8637b5038d7SDag-Erling Smørgrav 
864*5afab0e5SDag-Erling Smørgrav #if OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x20700000)
865986ba33cSDag-Erling Smørgrav # ifndef S_SPLINT_S
866986ba33cSDag-Erling Smørgrav 	rsa->n = n;
867986ba33cSDag-Erling Smørgrav 	rsa->e = e;
868986ba33cSDag-Erling Smørgrav 	rsa->d = d;
869986ba33cSDag-Erling Smørgrav 	rsa->p = p;
870986ba33cSDag-Erling Smørgrav 	rsa->q = q;
871986ba33cSDag-Erling Smørgrav 	rsa->dmp1 = dmp1;
872986ba33cSDag-Erling Smørgrav 	rsa->dmq1 = dmq1;
873986ba33cSDag-Erling Smørgrav 	rsa->iqmp = iqmp;
874986ba33cSDag-Erling Smørgrav # endif
875986ba33cSDag-Erling Smørgrav #else
876986ba33cSDag-Erling Smørgrav 	if(!RSA_set0_key(rsa, n, e, d))
877986ba33cSDag-Erling Smørgrav 		goto error;
878986ba33cSDag-Erling Smørgrav 	n = NULL;
879986ba33cSDag-Erling Smørgrav 	e = NULL;
880986ba33cSDag-Erling Smørgrav 	d = NULL;
881986ba33cSDag-Erling Smørgrav 	if(!RSA_set0_factors(rsa, p, q))
882986ba33cSDag-Erling Smørgrav 		goto error;
883986ba33cSDag-Erling Smørgrav 	p = NULL;
884986ba33cSDag-Erling Smørgrav 	q = NULL;
885986ba33cSDag-Erling Smørgrav 	if(!RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp))
886986ba33cSDag-Erling Smørgrav 		goto error;
887986ba33cSDag-Erling Smørgrav #endif
888986ba33cSDag-Erling Smørgrav 
8897b5038d7SDag-Erling Smørgrav 	LDNS_FREE(buf);
890986ba33cSDag-Erling Smørgrav 	LDNS_FREE(b);
8917b5038d7SDag-Erling Smørgrav 	return rsa;
8927b5038d7SDag-Erling Smørgrav 
8937b5038d7SDag-Erling Smørgrav error:
8947b5038d7SDag-Erling Smørgrav 	RSA_free(rsa);
895986ba33cSDag-Erling Smørgrav 	LDNS_FREE(b);
8967b5038d7SDag-Erling Smørgrav 	LDNS_FREE(buf);
897986ba33cSDag-Erling Smørgrav 	BN_free(n);
898986ba33cSDag-Erling Smørgrav 	BN_free(e);
899986ba33cSDag-Erling Smørgrav 	BN_free(d);
900986ba33cSDag-Erling Smørgrav 	BN_free(p);
901986ba33cSDag-Erling Smørgrav 	BN_free(q);
902986ba33cSDag-Erling Smørgrav 	BN_free(dmp1);
903986ba33cSDag-Erling Smørgrav 	BN_free(dmq1);
904986ba33cSDag-Erling Smørgrav 	BN_free(iqmp);
9057b5038d7SDag-Erling Smørgrav 	return NULL;
9067b5038d7SDag-Erling Smørgrav }
9077b5038d7SDag-Erling Smørgrav 
908*5afab0e5SDag-Erling Smørgrav #ifdef USE_DSA
9097b5038d7SDag-Erling Smørgrav DSA *
ldns_key_new_frm_fp_dsa(FILE * f)9107b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_dsa(FILE *f)
9117b5038d7SDag-Erling Smørgrav {
9127b5038d7SDag-Erling Smørgrav 	return ldns_key_new_frm_fp_dsa_l(f, NULL);
9137b5038d7SDag-Erling Smørgrav }
9147b5038d7SDag-Erling Smørgrav 
9157b5038d7SDag-Erling Smørgrav DSA *
ldns_key_new_frm_fp_dsa_l(FILE * f,ATTR_UNUSED (int * line_nr))9167b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_dsa_l(FILE *f, ATTR_UNUSED(int *line_nr))
9177b5038d7SDag-Erling Smørgrav {
9187b5038d7SDag-Erling Smørgrav 	int i;
9197b5038d7SDag-Erling Smørgrav 	char *d;
9207b5038d7SDag-Erling Smørgrav 	DSA *dsa;
9217b5038d7SDag-Erling Smørgrav 	uint8_t *buf;
922986ba33cSDag-Erling Smørgrav 	BIGNUM *p=NULL, *q=NULL, *g=NULL, *priv_key=NULL, *pub_key=NULL;
9237b5038d7SDag-Erling Smørgrav 
9247b5038d7SDag-Erling Smørgrav 	d = LDNS_XMALLOC(char, LDNS_MAX_LINELEN);
9257b5038d7SDag-Erling Smørgrav 	buf = LDNS_XMALLOC(uint8_t, LDNS_MAX_LINELEN);
9267b5038d7SDag-Erling Smørgrav 	dsa = DSA_new();
9277b5038d7SDag-Erling Smørgrav 	if (!d || !dsa || !buf) {
9287b5038d7SDag-Erling Smørgrav                 goto error;
9297b5038d7SDag-Erling Smørgrav 	}
9307b5038d7SDag-Erling Smørgrav 
9317b5038d7SDag-Erling Smørgrav 	/* the line parser removes the () from the input... */
9327b5038d7SDag-Erling Smørgrav 
9337b5038d7SDag-Erling Smørgrav 	/* Prime, dsa->p */
9347b5038d7SDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(f, "Primep", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
9357b5038d7SDag-Erling Smørgrav 		goto error;
9367b5038d7SDag-Erling Smørgrav 	}
9377b5038d7SDag-Erling Smørgrav 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
9387b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S
939986ba33cSDag-Erling Smørgrav 	p = BN_bin2bn((const char unsigned*)buf, i, NULL);
940986ba33cSDag-Erling Smørgrav 	if (!p) {
9417b5038d7SDag-Erling Smørgrav 		goto error;
9427b5038d7SDag-Erling Smørgrav 	}
9437b5038d7SDag-Erling Smørgrav 
9447b5038d7SDag-Erling Smørgrav 	/* Subprime, dsa->q */
9457b5038d7SDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(f, "Subprimeq", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
9467b5038d7SDag-Erling Smørgrav 		goto error;
9477b5038d7SDag-Erling Smørgrav 	}
9487b5038d7SDag-Erling Smørgrav 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
949986ba33cSDag-Erling Smørgrav 	q = BN_bin2bn((const char unsigned*)buf, i, NULL);
950986ba33cSDag-Erling Smørgrav 	if (!q) {
9517b5038d7SDag-Erling Smørgrav 		goto error;
9527b5038d7SDag-Erling Smørgrav 	}
9537b5038d7SDag-Erling Smørgrav 
9547b5038d7SDag-Erling Smørgrav 	/* Base, dsa->g */
9557b5038d7SDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(f, "Baseg", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
9567b5038d7SDag-Erling Smørgrav 		goto error;
9577b5038d7SDag-Erling Smørgrav 	}
9587b5038d7SDag-Erling Smørgrav 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
959986ba33cSDag-Erling Smørgrav 	g = BN_bin2bn((const char unsigned*)buf, i, NULL);
960986ba33cSDag-Erling Smørgrav 	if (!g) {
9617b5038d7SDag-Erling Smørgrav 		goto error;
9627b5038d7SDag-Erling Smørgrav 	}
9637b5038d7SDag-Erling Smørgrav 
9647b5038d7SDag-Erling Smørgrav 	/* Private key, dsa->priv_key */
9657b5038d7SDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(f, "Private_valuex", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
9667b5038d7SDag-Erling Smørgrav 		goto error;
9677b5038d7SDag-Erling Smørgrav 	}
9687b5038d7SDag-Erling Smørgrav 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
969986ba33cSDag-Erling Smørgrav 	priv_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
970986ba33cSDag-Erling Smørgrav 	if (!priv_key) {
9717b5038d7SDag-Erling Smørgrav 		goto error;
9727b5038d7SDag-Erling Smørgrav 	}
9737b5038d7SDag-Erling Smørgrav 
9747b5038d7SDag-Erling Smørgrav 	/* Public key, dsa->priv_key */
9757b5038d7SDag-Erling Smørgrav 	if (ldns_fget_keyword_data_l(f, "Public_valuey", ": ", d, "\n", LDNS_MAX_LINELEN, line_nr) == -1) {
9767b5038d7SDag-Erling Smørgrav 		goto error;
9777b5038d7SDag-Erling Smørgrav 	}
9787b5038d7SDag-Erling Smørgrav 	i = ldns_b64_pton((const char*)d, buf, ldns_b64_ntop_calculate_size(strlen(d)));
979986ba33cSDag-Erling Smørgrav 	pub_key = BN_bin2bn((const char unsigned*)buf, i, NULL);
980986ba33cSDag-Erling Smørgrav 	if (!pub_key) {
9817b5038d7SDag-Erling Smørgrav 		goto error;
9827b5038d7SDag-Erling Smørgrav 	}
9837b5038d7SDag-Erling Smørgrav #endif /* splint */
9847b5038d7SDag-Erling Smørgrav 
985*5afab0e5SDag-Erling Smørgrav #if OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x20700000)
986986ba33cSDag-Erling Smørgrav # ifndef S_SPLINT_S
987986ba33cSDag-Erling Smørgrav 	dsa->p = p;
988986ba33cSDag-Erling Smørgrav 	dsa->q = q;
989986ba33cSDag-Erling Smørgrav 	dsa->g = g;
990986ba33cSDag-Erling Smørgrav 	dsa->priv_key = priv_key;
991986ba33cSDag-Erling Smørgrav 	dsa->pub_key = pub_key;
992986ba33cSDag-Erling Smørgrav # endif
993986ba33cSDag-Erling Smørgrav #else
994986ba33cSDag-Erling Smørgrav 	if(!DSA_set0_pqg(dsa, p, q, g))
995986ba33cSDag-Erling Smørgrav 		goto error;
996986ba33cSDag-Erling Smørgrav 	p = NULL;
997986ba33cSDag-Erling Smørgrav 	q = NULL;
998986ba33cSDag-Erling Smørgrav 	g = NULL;
999986ba33cSDag-Erling Smørgrav 	if(!DSA_set0_key(dsa, pub_key, priv_key))
1000986ba33cSDag-Erling Smørgrav 		goto error;
1001986ba33cSDag-Erling Smørgrav #endif
1002986ba33cSDag-Erling Smørgrav 
10037b5038d7SDag-Erling Smørgrav 	LDNS_FREE(buf);
10047b5038d7SDag-Erling Smørgrav 	LDNS_FREE(d);
10057b5038d7SDag-Erling Smørgrav 
10067b5038d7SDag-Erling Smørgrav 	return dsa;
10077b5038d7SDag-Erling Smørgrav 
10087b5038d7SDag-Erling Smørgrav error:
10097b5038d7SDag-Erling Smørgrav 	LDNS_FREE(d);
10107b5038d7SDag-Erling Smørgrav 	LDNS_FREE(buf);
10117b5038d7SDag-Erling Smørgrav         DSA_free(dsa);
1012986ba33cSDag-Erling Smørgrav 	BN_free(p);
1013986ba33cSDag-Erling Smørgrav 	BN_free(q);
1014986ba33cSDag-Erling Smørgrav 	BN_free(g);
1015986ba33cSDag-Erling Smørgrav 	BN_free(priv_key);
1016986ba33cSDag-Erling Smørgrav 	BN_free(pub_key);
10177b5038d7SDag-Erling Smørgrav 	return NULL;
10187b5038d7SDag-Erling Smørgrav }
1019*5afab0e5SDag-Erling Smørgrav #endif /* USE_DSA */
10207b5038d7SDag-Erling Smørgrav 
10217b5038d7SDag-Erling Smørgrav unsigned char *
ldns_key_new_frm_fp_hmac(FILE * f,size_t * hmac_size)10227b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_hmac(FILE *f, size_t *hmac_size)
10237b5038d7SDag-Erling Smørgrav {
10247b5038d7SDag-Erling Smørgrav 	return ldns_key_new_frm_fp_hmac_l(f, NULL, hmac_size);
10257b5038d7SDag-Erling Smørgrav }
10267b5038d7SDag-Erling Smørgrav 
10277b5038d7SDag-Erling Smørgrav unsigned char *
ldns_key_new_frm_fp_hmac_l(FILE * f,ATTR_UNUSED (int * line_nr),size_t * hmac_size)10287b5038d7SDag-Erling Smørgrav ldns_key_new_frm_fp_hmac_l( FILE *f
10297b5038d7SDag-Erling Smørgrav 			  , ATTR_UNUSED(int *line_nr)
10307b5038d7SDag-Erling Smørgrav 			  , size_t *hmac_size
10317b5038d7SDag-Erling Smørgrav 			  )
10327b5038d7SDag-Erling Smørgrav {
1033*5afab0e5SDag-Erling Smørgrav 	size_t bufsz;
10342787e39aSDag-Erling Smørgrav 	char d[LDNS_MAX_LINELEN];
10352787e39aSDag-Erling Smørgrav 	unsigned char *buf = NULL;
10367b5038d7SDag-Erling Smørgrav 
1037*5afab0e5SDag-Erling Smørgrav 	*hmac_size = ldns_fget_keyword_data_l(f, "Key", ": ", d, "\n",
1038*5afab0e5SDag-Erling Smørgrav 	                                      LDNS_MAX_LINELEN, line_nr) == -1
1039*5afab0e5SDag-Erling Smørgrav 	           ? 0
1040*5afab0e5SDag-Erling Smørgrav 		   : (buf = LDNS_XMALLOC( unsigned char, (bufsz =
1041*5afab0e5SDag-Erling Smørgrav 	                    ldns_b64_ntop_calculate_size(strlen(d))))) == NULL
1042*5afab0e5SDag-Erling Smørgrav 		   ? 0
1043*5afab0e5SDag-Erling Smørgrav 	           : (size_t) ldns_b64_pton((const char*)d, buf, bufsz);
10447b5038d7SDag-Erling Smørgrav 	return buf;
10457b5038d7SDag-Erling Smørgrav }
10467b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
10477b5038d7SDag-Erling Smørgrav 
10487b5038d7SDag-Erling Smørgrav #ifdef USE_GOST
10497b5038d7SDag-Erling Smørgrav static EVP_PKEY*
ldns_gen_gost_key(void)10507b5038d7SDag-Erling Smørgrav ldns_gen_gost_key(void)
10517b5038d7SDag-Erling Smørgrav {
10527b5038d7SDag-Erling Smørgrav 	EVP_PKEY_CTX* ctx;
10537b5038d7SDag-Erling Smørgrav 	EVP_PKEY* p = NULL;
10547b5038d7SDag-Erling Smørgrav 	int gost_id = ldns_key_EVP_load_gost_id();
10557b5038d7SDag-Erling Smørgrav 	if(!gost_id)
10567b5038d7SDag-Erling Smørgrav 		return NULL;
10577b5038d7SDag-Erling Smørgrav 	ctx = EVP_PKEY_CTX_new_id(gost_id, NULL);
10587b5038d7SDag-Erling Smørgrav 	if(!ctx) {
10597b5038d7SDag-Erling Smørgrav 		/* the id should be available now */
10607b5038d7SDag-Erling Smørgrav 		return NULL;
10617b5038d7SDag-Erling Smørgrav 	}
10627b5038d7SDag-Erling Smørgrav 	if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) {
10637b5038d7SDag-Erling Smørgrav 		/* cannot set paramset */
10647b5038d7SDag-Erling Smørgrav 		EVP_PKEY_CTX_free(ctx);
10657b5038d7SDag-Erling Smørgrav 		return NULL;
10667b5038d7SDag-Erling Smørgrav 	}
10677b5038d7SDag-Erling Smørgrav 
10687b5038d7SDag-Erling Smørgrav 	if(EVP_PKEY_keygen_init(ctx) <= 0) {
10697b5038d7SDag-Erling Smørgrav 		EVP_PKEY_CTX_free(ctx);
10707b5038d7SDag-Erling Smørgrav 		return NULL;
10717b5038d7SDag-Erling Smørgrav 	}
10727b5038d7SDag-Erling Smørgrav 	if(EVP_PKEY_keygen(ctx, &p) <= 0) {
10737b5038d7SDag-Erling Smørgrav 		EVP_PKEY_free(p);
10747b5038d7SDag-Erling Smørgrav 		EVP_PKEY_CTX_free(ctx);
10757b5038d7SDag-Erling Smørgrav 		return NULL;
10767b5038d7SDag-Erling Smørgrav 	}
10777b5038d7SDag-Erling Smørgrav 	EVP_PKEY_CTX_free(ctx);
10787b5038d7SDag-Erling Smørgrav 	return p;
10797b5038d7SDag-Erling Smørgrav }
10807b5038d7SDag-Erling Smørgrav #endif
10817b5038d7SDag-Erling Smørgrav 
10827b5038d7SDag-Erling Smørgrav ldns_key *
ldns_key_new_frm_algorithm(ldns_signing_algorithm alg,uint16_t size)10837b5038d7SDag-Erling Smørgrav ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
10847b5038d7SDag-Erling Smørgrav {
10857b5038d7SDag-Erling Smørgrav 	ldns_key *k;
10867b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
1087986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
10887b5038d7SDag-Erling Smørgrav 	DSA *d;
1089986ba33cSDag-Erling Smørgrav #endif /* USE_DSA */
10907b5038d7SDag-Erling Smørgrav #  ifdef USE_ECDSA
10917b5038d7SDag-Erling Smørgrav         EC_KEY *ec = NULL;
10927b5038d7SDag-Erling Smørgrav #  endif
1093986ba33cSDag-Erling Smørgrav #  ifdef HAVE_EVP_PKEY_KEYGEN
1094986ba33cSDag-Erling Smørgrav 	EVP_PKEY_CTX *ctx;
1095986ba33cSDag-Erling Smørgrav #  else
1096986ba33cSDag-Erling Smørgrav 	RSA *r;
1097986ba33cSDag-Erling Smørgrav #  endif
10987b5038d7SDag-Erling Smørgrav #else
10997b5038d7SDag-Erling Smørgrav 	int i;
11007b5038d7SDag-Erling Smørgrav 	uint16_t offset = 0;
11017b5038d7SDag-Erling Smørgrav #endif
11027b5038d7SDag-Erling Smørgrav 	unsigned char *hmac;
11037b5038d7SDag-Erling Smørgrav 
11047b5038d7SDag-Erling Smørgrav 	k = ldns_key_new();
11057b5038d7SDag-Erling Smørgrav 	if (!k) {
11067b5038d7SDag-Erling Smørgrav 		return NULL;
11077b5038d7SDag-Erling Smørgrav 	}
11087b5038d7SDag-Erling Smørgrav 	switch(alg) {
11097b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSAMD5:
11107b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSASHA1:
11117b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSASHA1_NSEC3:
11127b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSASHA256:
11137b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSASHA512:
11147b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
1115986ba33cSDag-Erling Smørgrav #ifdef HAVE_EVP_PKEY_KEYGEN
1116986ba33cSDag-Erling Smørgrav 			ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
1117986ba33cSDag-Erling Smørgrav 			if(!ctx) {
1118986ba33cSDag-Erling Smørgrav 				ldns_key_free(k);
1119986ba33cSDag-Erling Smørgrav 				return NULL;
1120986ba33cSDag-Erling Smørgrav 			}
1121986ba33cSDag-Erling Smørgrav 			if(EVP_PKEY_keygen_init(ctx) <= 0) {
1122986ba33cSDag-Erling Smørgrav 				ldns_key_free(k);
1123986ba33cSDag-Erling Smørgrav 				EVP_PKEY_CTX_free(ctx);
1124986ba33cSDag-Erling Smørgrav 				return NULL;
1125986ba33cSDag-Erling Smørgrav 			}
1126986ba33cSDag-Erling Smørgrav 			if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, size) <= 0) {
1127986ba33cSDag-Erling Smørgrav 				ldns_key_free(k);
1128986ba33cSDag-Erling Smørgrav 				EVP_PKEY_CTX_free(ctx);
1129986ba33cSDag-Erling Smørgrav 				return NULL;
1130986ba33cSDag-Erling Smørgrav 			}
1131986ba33cSDag-Erling Smørgrav #ifndef S_SPLINT_S
1132986ba33cSDag-Erling Smørgrav 			if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) {
1133986ba33cSDag-Erling Smørgrav 				ldns_key_free(k);
1134986ba33cSDag-Erling Smørgrav 				EVP_PKEY_CTX_free(ctx);
1135986ba33cSDag-Erling Smørgrav 				return NULL;
1136986ba33cSDag-Erling Smørgrav 			}
1137986ba33cSDag-Erling Smørgrav #endif
1138986ba33cSDag-Erling Smørgrav 			EVP_PKEY_CTX_free(ctx);
1139986ba33cSDag-Erling Smørgrav #else /* HAVE_EVP_PKEY_KEYGEN */
11407b5038d7SDag-Erling Smørgrav 			r = RSA_generate_key((int)size, RSA_F4, NULL, NULL);
11417b5038d7SDag-Erling Smørgrav                         if(!r) {
11427b5038d7SDag-Erling Smørgrav 				ldns_key_free(k);
11437b5038d7SDag-Erling Smørgrav 				return NULL;
11447b5038d7SDag-Erling Smørgrav 			}
11457b5038d7SDag-Erling Smørgrav 			if (RSA_check_key(r) != 1) {
11467b5038d7SDag-Erling Smørgrav 				ldns_key_free(k);
11477b5038d7SDag-Erling Smørgrav 				return NULL;
11487b5038d7SDag-Erling Smørgrav 			}
11497b5038d7SDag-Erling Smørgrav 			ldns_key_set_rsa_key(k, r);
11502787e39aSDag-Erling Smørgrav 			RSA_free(r);
1151986ba33cSDag-Erling Smørgrav #endif /* HAVE_EVP_PKEY_KEYGEN */
11527b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
11537b5038d7SDag-Erling Smørgrav 			break;
1154*5afab0e5SDag-Erling Smørgrav #ifdef USE_DSA
11557b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_DSA:
11567b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_DSA_NSEC3:
11577b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
1158986ba33cSDag-Erling Smørgrav # if OPENSSL_VERSION_NUMBER < 0x00908000L
11597b5038d7SDag-Erling Smørgrav 			d = DSA_generate_parameters((int)size, NULL, 0, NULL, NULL, NULL, NULL);
11607b5038d7SDag-Erling Smørgrav 			if (!d) {
11617b5038d7SDag-Erling Smørgrav 				ldns_key_free(k);
11627b5038d7SDag-Erling Smørgrav 				return NULL;
11637b5038d7SDag-Erling Smørgrav 			}
1164986ba33cSDag-Erling Smørgrav 
1165986ba33cSDag-Erling Smørgrav # else
1166986ba33cSDag-Erling Smørgrav 			if (! (d = DSA_new())) {
1167986ba33cSDag-Erling Smørgrav 				ldns_key_free(k);
1168986ba33cSDag-Erling Smørgrav 				return NULL;
1169986ba33cSDag-Erling Smørgrav 			}
1170986ba33cSDag-Erling Smørgrav 			if (! DSA_generate_parameters_ex(d, (int)size, NULL, 0, NULL, NULL, NULL)) {
1171986ba33cSDag-Erling Smørgrav 				DSA_free(d);
1172986ba33cSDag-Erling Smørgrav 				ldns_key_free(k);
1173986ba33cSDag-Erling Smørgrav 				return NULL;
1174986ba33cSDag-Erling Smørgrav 			}
1175986ba33cSDag-Erling Smørgrav # endif
11767b5038d7SDag-Erling Smørgrav 			if (DSA_generate_key(d) != 1) {
11777b5038d7SDag-Erling Smørgrav 				ldns_key_free(k);
11787b5038d7SDag-Erling Smørgrav 				return NULL;
11797b5038d7SDag-Erling Smørgrav 			}
11807b5038d7SDag-Erling Smørgrav 			ldns_key_set_dsa_key(k, d);
11812787e39aSDag-Erling Smørgrav 			DSA_free(d);
11827b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
1183986ba33cSDag-Erling Smørgrav #endif /* USE_DSA */
11847b5038d7SDag-Erling Smørgrav 			break;
11857b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_HMACMD5:
11867b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA1:
1187986ba33cSDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA224:
11887b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA256:
1189986ba33cSDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA384:
1190986ba33cSDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA512:
11917b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
11927b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S
11937b5038d7SDag-Erling Smørgrav 			k->_key.key = NULL;
11947b5038d7SDag-Erling Smørgrav #endif /* splint */
11957b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
11967b5038d7SDag-Erling Smørgrav 			size = size / 8;
11977b5038d7SDag-Erling Smørgrav 			ldns_key_set_hmac_size(k, size);
11987b5038d7SDag-Erling Smørgrav 
11997b5038d7SDag-Erling Smørgrav 			hmac = LDNS_XMALLOC(unsigned char, size);
12007b5038d7SDag-Erling Smørgrav                         if(!hmac) {
12017b5038d7SDag-Erling Smørgrav 				ldns_key_free(k);
12027b5038d7SDag-Erling Smørgrav 				return NULL;
12037b5038d7SDag-Erling Smørgrav                         }
12047b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
12057b5038d7SDag-Erling Smørgrav 			if (RAND_bytes(hmac, (int) size) != 1) {
12067b5038d7SDag-Erling Smørgrav 				LDNS_FREE(hmac);
12077b5038d7SDag-Erling Smørgrav 				ldns_key_free(k);
12087b5038d7SDag-Erling Smørgrav 				return NULL;
12097b5038d7SDag-Erling Smørgrav 			}
12107b5038d7SDag-Erling Smørgrav #else
12117b5038d7SDag-Erling Smørgrav 			while (offset + sizeof(i) < size) {
12127b5038d7SDag-Erling Smørgrav 			  i = random();
12137b5038d7SDag-Erling Smørgrav 			  memcpy(&hmac[offset], &i, sizeof(i));
12147b5038d7SDag-Erling Smørgrav 			  offset += sizeof(i);
12157b5038d7SDag-Erling Smørgrav 			}
12167b5038d7SDag-Erling Smørgrav 			if (offset < size) {
12177b5038d7SDag-Erling Smørgrav 			  i = random();
12187b5038d7SDag-Erling Smørgrav 			  memcpy(&hmac[offset], &i, size - offset);
12197b5038d7SDag-Erling Smørgrav 			}
12207b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
12217b5038d7SDag-Erling Smørgrav 			ldns_key_set_hmac_key(k, hmac);
12227b5038d7SDag-Erling Smørgrav 
12237b5038d7SDag-Erling Smørgrav 			ldns_key_set_flags(k, 0);
12247b5038d7SDag-Erling Smørgrav 			break;
12257b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_ECC_GOST:
12267b5038d7SDag-Erling Smørgrav #if defined(HAVE_SSL) && defined(USE_GOST)
12277b5038d7SDag-Erling Smørgrav 			ldns_key_set_evp_key(k, ldns_gen_gost_key());
12287b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S
12297b5038d7SDag-Erling Smørgrav                         if(!k->_key.key) {
12307b5038d7SDag-Erling Smørgrav                                 ldns_key_free(k);
12317b5038d7SDag-Erling Smørgrav                                 return NULL;
12327b5038d7SDag-Erling Smørgrav                         }
12337b5038d7SDag-Erling Smørgrav #endif /* splint */
12347b5038d7SDag-Erling Smørgrav #else
12357b5038d7SDag-Erling Smørgrav 			ldns_key_free(k);
12367b5038d7SDag-Erling Smørgrav 			return NULL;
12377b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL and USE_GOST */
12387b5038d7SDag-Erling Smørgrav                         break;
12397b5038d7SDag-Erling Smørgrav                 case LDNS_SIGN_ECDSAP256SHA256:
12407b5038d7SDag-Erling Smørgrav                 case LDNS_SIGN_ECDSAP384SHA384:
12417b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA
12427b5038d7SDag-Erling Smørgrav                         if(alg == LDNS_SIGN_ECDSAP256SHA256)
12437b5038d7SDag-Erling Smørgrav                                 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
12447b5038d7SDag-Erling Smørgrav                         else if(alg == LDNS_SIGN_ECDSAP384SHA384)
12457b5038d7SDag-Erling Smørgrav                                 ec = EC_KEY_new_by_curve_name(NID_secp384r1);
12467b5038d7SDag-Erling Smørgrav                         if(!ec) {
12477b5038d7SDag-Erling Smørgrav                                 ldns_key_free(k);
12487b5038d7SDag-Erling Smørgrav                                 return NULL;
12497b5038d7SDag-Erling Smørgrav                         }
12507b5038d7SDag-Erling Smørgrav                         if(!EC_KEY_generate_key(ec)) {
12517b5038d7SDag-Erling Smørgrav                                 ldns_key_free(k);
12527b5038d7SDag-Erling Smørgrav                                 EC_KEY_free(ec);
12537b5038d7SDag-Erling Smørgrav                                 return NULL;
12547b5038d7SDag-Erling Smørgrav                         }
12557b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S
12567b5038d7SDag-Erling Smørgrav                         k->_key.key = EVP_PKEY_new();
12577b5038d7SDag-Erling Smørgrav                         if(!k->_key.key) {
12587b5038d7SDag-Erling Smørgrav                                 ldns_key_free(k);
12597b5038d7SDag-Erling Smørgrav                                 EC_KEY_free(ec);
12607b5038d7SDag-Erling Smørgrav                                 return NULL;
12617b5038d7SDag-Erling Smørgrav                         }
12627b5038d7SDag-Erling Smørgrav                         if (!EVP_PKEY_assign_EC_KEY(k->_key.key, ec)) {
12637b5038d7SDag-Erling Smørgrav                                 ldns_key_free(k);
12647b5038d7SDag-Erling Smørgrav                                 EC_KEY_free(ec);
12657b5038d7SDag-Erling Smørgrav                                 return NULL;
12667b5038d7SDag-Erling Smørgrav 			}
12677b5038d7SDag-Erling Smørgrav #endif /* splint */
12687b5038d7SDag-Erling Smørgrav #else
12697b5038d7SDag-Erling Smørgrav 			ldns_key_free(k);
12707b5038d7SDag-Erling Smørgrav 			return NULL;
12717b5038d7SDag-Erling Smørgrav #endif /* ECDSA */
12727b5038d7SDag-Erling Smørgrav 			break;
1273986ba33cSDag-Erling Smørgrav #ifdef USE_ED25519
1274986ba33cSDag-Erling Smørgrav 		case LDNS_SIGN_ED25519:
1275986ba33cSDag-Erling Smørgrav #ifdef HAVE_EVP_PKEY_KEYGEN
1276*5afab0e5SDag-Erling Smørgrav 			ctx = EVP_PKEY_CTX_new_id(NID_ED25519, NULL);
1277986ba33cSDag-Erling Smørgrav 			if(!ctx) {
1278986ba33cSDag-Erling Smørgrav 				ldns_key_free(k);
1279986ba33cSDag-Erling Smørgrav 				return NULL;
1280986ba33cSDag-Erling Smørgrav 			}
1281986ba33cSDag-Erling Smørgrav 			if(EVP_PKEY_keygen_init(ctx) <= 0) {
1282986ba33cSDag-Erling Smørgrav 				ldns_key_free(k);
1283986ba33cSDag-Erling Smørgrav 				EVP_PKEY_CTX_free(ctx);
1284986ba33cSDag-Erling Smørgrav 				return NULL;
1285986ba33cSDag-Erling Smørgrav 			}
1286986ba33cSDag-Erling Smørgrav 			if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) {
1287986ba33cSDag-Erling Smørgrav 				ldns_key_free(k);
1288986ba33cSDag-Erling Smørgrav 				EVP_PKEY_CTX_free(ctx);
1289986ba33cSDag-Erling Smørgrav 				return NULL;
1290986ba33cSDag-Erling Smørgrav 			}
1291986ba33cSDag-Erling Smørgrav 			EVP_PKEY_CTX_free(ctx);
1292986ba33cSDag-Erling Smørgrav #endif
1293986ba33cSDag-Erling Smørgrav 			break;
1294986ba33cSDag-Erling Smørgrav #endif /* ED25519 */
1295986ba33cSDag-Erling Smørgrav #ifdef USE_ED448
1296986ba33cSDag-Erling Smørgrav 		case LDNS_SIGN_ED448:
1297986ba33cSDag-Erling Smørgrav #ifdef HAVE_EVP_PKEY_KEYGEN
1298*5afab0e5SDag-Erling Smørgrav 			ctx = EVP_PKEY_CTX_new_id(NID_ED448, NULL);
1299986ba33cSDag-Erling Smørgrav 			if(!ctx) {
1300986ba33cSDag-Erling Smørgrav 				ldns_key_free(k);
1301986ba33cSDag-Erling Smørgrav 				return NULL;
1302986ba33cSDag-Erling Smørgrav 			}
1303986ba33cSDag-Erling Smørgrav 			if(EVP_PKEY_keygen_init(ctx) <= 0) {
1304986ba33cSDag-Erling Smørgrav 				ldns_key_free(k);
1305986ba33cSDag-Erling Smørgrav 				EVP_PKEY_CTX_free(ctx);
1306986ba33cSDag-Erling Smørgrav 				return NULL;
1307986ba33cSDag-Erling Smørgrav 			}
1308986ba33cSDag-Erling Smørgrav 			if (EVP_PKEY_keygen(ctx, &k->_key.key) <= 0) {
1309986ba33cSDag-Erling Smørgrav 				ldns_key_free(k);
1310986ba33cSDag-Erling Smørgrav 				EVP_PKEY_CTX_free(ctx);
1311986ba33cSDag-Erling Smørgrav 				return NULL;
1312986ba33cSDag-Erling Smørgrav 			}
1313986ba33cSDag-Erling Smørgrav 			EVP_PKEY_CTX_free(ctx);
1314986ba33cSDag-Erling Smørgrav #endif
1315986ba33cSDag-Erling Smørgrav 			break;
1316986ba33cSDag-Erling Smørgrav #endif /* ED448 */
13177b5038d7SDag-Erling Smørgrav 	}
13187b5038d7SDag-Erling Smørgrav 	ldns_key_set_algorithm(k, alg);
13197b5038d7SDag-Erling Smørgrav 	return k;
13207b5038d7SDag-Erling Smørgrav }
13217b5038d7SDag-Erling Smørgrav 
13227b5038d7SDag-Erling Smørgrav void
ldns_key_print(FILE * output,const ldns_key * k)13237b5038d7SDag-Erling Smørgrav ldns_key_print(FILE *output, const ldns_key *k)
13247b5038d7SDag-Erling Smørgrav {
13257b5038d7SDag-Erling Smørgrav 	char *str = ldns_key2str(k);
13267b5038d7SDag-Erling Smørgrav 	if (str) {
13277b5038d7SDag-Erling Smørgrav                 fprintf(output, "%s", str);
13287b5038d7SDag-Erling Smørgrav         } else {
13297b5038d7SDag-Erling Smørgrav                 fprintf(output, "Unable to convert private key to string\n");
13307b5038d7SDag-Erling Smørgrav         }
13317b5038d7SDag-Erling Smørgrav         LDNS_FREE(str);
13327b5038d7SDag-Erling Smørgrav }
13337b5038d7SDag-Erling Smørgrav 
13347b5038d7SDag-Erling Smørgrav 
13357b5038d7SDag-Erling Smørgrav void
ldns_key_set_algorithm(ldns_key * k,ldns_signing_algorithm l)13367b5038d7SDag-Erling Smørgrav ldns_key_set_algorithm(ldns_key *k, ldns_signing_algorithm l)
13377b5038d7SDag-Erling Smørgrav {
13387b5038d7SDag-Erling Smørgrav 	k->_alg = l;
13397b5038d7SDag-Erling Smørgrav }
13407b5038d7SDag-Erling Smørgrav 
13417b5038d7SDag-Erling Smørgrav void
ldns_key_set_flags(ldns_key * k,uint16_t f)13427b5038d7SDag-Erling Smørgrav ldns_key_set_flags(ldns_key *k, uint16_t f)
13437b5038d7SDag-Erling Smørgrav {
13447b5038d7SDag-Erling Smørgrav 	k->_extra.dnssec.flags = f;
13457b5038d7SDag-Erling Smørgrav }
13467b5038d7SDag-Erling Smørgrav 
13477b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
13487b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S
13497b5038d7SDag-Erling Smørgrav void
ldns_key_set_evp_key(ldns_key * k,EVP_PKEY * e)13507b5038d7SDag-Erling Smørgrav ldns_key_set_evp_key(ldns_key *k, EVP_PKEY *e)
13517b5038d7SDag-Erling Smørgrav {
13527b5038d7SDag-Erling Smørgrav 	k->_key.key = e;
13537b5038d7SDag-Erling Smørgrav }
13547b5038d7SDag-Erling Smørgrav 
13557b5038d7SDag-Erling Smørgrav void
ldns_key_set_rsa_key(ldns_key * k,RSA * r)13567b5038d7SDag-Erling Smørgrav ldns_key_set_rsa_key(ldns_key *k, RSA *r)
13577b5038d7SDag-Erling Smørgrav {
13587b5038d7SDag-Erling Smørgrav 	EVP_PKEY *key = EVP_PKEY_new();
13597b5038d7SDag-Erling Smørgrav 	EVP_PKEY_set1_RSA(key, r);
13607b5038d7SDag-Erling Smørgrav 	k->_key.key = key;
13617b5038d7SDag-Erling Smørgrav }
13627b5038d7SDag-Erling Smørgrav 
13637b5038d7SDag-Erling Smørgrav void
ldns_key_set_dsa_key(ldns_key * k,DSA * d)13647b5038d7SDag-Erling Smørgrav ldns_key_set_dsa_key(ldns_key *k, DSA *d)
13657b5038d7SDag-Erling Smørgrav {
1366986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
13677b5038d7SDag-Erling Smørgrav 	EVP_PKEY *key = EVP_PKEY_new();
13687b5038d7SDag-Erling Smørgrav 	EVP_PKEY_set1_DSA(key, d);
13697b5038d7SDag-Erling Smørgrav 	k->_key.key  = key;
1370986ba33cSDag-Erling Smørgrav #else
1371986ba33cSDag-Erling Smørgrav 	(void)k; (void)d;
1372986ba33cSDag-Erling Smørgrav #endif
13737b5038d7SDag-Erling Smørgrav }
13742787e39aSDag-Erling Smørgrav 
13752787e39aSDag-Erling Smørgrav void
ldns_key_assign_rsa_key(ldns_key * k,RSA * r)13762787e39aSDag-Erling Smørgrav ldns_key_assign_rsa_key(ldns_key *k, RSA *r)
13772787e39aSDag-Erling Smørgrav {
13782787e39aSDag-Erling Smørgrav 	EVP_PKEY *key = EVP_PKEY_new();
13792787e39aSDag-Erling Smørgrav 	EVP_PKEY_assign_RSA(key, r);
13802787e39aSDag-Erling Smørgrav 	k->_key.key = key;
13812787e39aSDag-Erling Smørgrav }
13822787e39aSDag-Erling Smørgrav 
13832787e39aSDag-Erling Smørgrav void
ldns_key_assign_dsa_key(ldns_key * k,DSA * d)13842787e39aSDag-Erling Smørgrav ldns_key_assign_dsa_key(ldns_key *k, DSA *d)
13852787e39aSDag-Erling Smørgrav {
1386986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
13872787e39aSDag-Erling Smørgrav 	EVP_PKEY *key = EVP_PKEY_new();
13882787e39aSDag-Erling Smørgrav 	EVP_PKEY_assign_DSA(key, d);
13892787e39aSDag-Erling Smørgrav 	k->_key.key  = key;
1390986ba33cSDag-Erling Smørgrav #else
1391986ba33cSDag-Erling Smørgrav 	(void)k; (void)d;
1392986ba33cSDag-Erling Smørgrav #endif
13932787e39aSDag-Erling Smørgrav }
13947b5038d7SDag-Erling Smørgrav #endif /* splint */
13957b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
13967b5038d7SDag-Erling Smørgrav 
13977b5038d7SDag-Erling Smørgrav void
ldns_key_set_hmac_key(ldns_key * k,unsigned char * hmac)13987b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_key(ldns_key *k, unsigned char *hmac)
13997b5038d7SDag-Erling Smørgrav {
14007b5038d7SDag-Erling Smørgrav 	k->_key.hmac.key = hmac;
14017b5038d7SDag-Erling Smørgrav }
14027b5038d7SDag-Erling Smørgrav 
14037b5038d7SDag-Erling Smørgrav void
ldns_key_set_hmac_size(ldns_key * k,size_t hmac_size)14047b5038d7SDag-Erling Smørgrav ldns_key_set_hmac_size(ldns_key *k, size_t hmac_size)
14057b5038d7SDag-Erling Smørgrav {
14067b5038d7SDag-Erling Smørgrav 	k->_key.hmac.size = hmac_size;
14077b5038d7SDag-Erling Smørgrav }
14087b5038d7SDag-Erling Smørgrav 
14097b5038d7SDag-Erling Smørgrav void
ldns_key_set_external_key(ldns_key * k,void * external_key)14107b5038d7SDag-Erling Smørgrav ldns_key_set_external_key(ldns_key *k, void *external_key)
14117b5038d7SDag-Erling Smørgrav {
14127b5038d7SDag-Erling Smørgrav 	k->_key.external_key = external_key;
14137b5038d7SDag-Erling Smørgrav }
14147b5038d7SDag-Erling Smørgrav 
14157b5038d7SDag-Erling Smørgrav void
ldns_key_set_origttl(ldns_key * k,uint32_t t)14167b5038d7SDag-Erling Smørgrav ldns_key_set_origttl(ldns_key *k, uint32_t t)
14177b5038d7SDag-Erling Smørgrav {
14187b5038d7SDag-Erling Smørgrav 	k->_extra.dnssec.orig_ttl = t;
14197b5038d7SDag-Erling Smørgrav }
14207b5038d7SDag-Erling Smørgrav 
14217b5038d7SDag-Erling Smørgrav void
ldns_key_set_inception(ldns_key * k,uint32_t i)14227b5038d7SDag-Erling Smørgrav ldns_key_set_inception(ldns_key *k, uint32_t i)
14237b5038d7SDag-Erling Smørgrav {
14247b5038d7SDag-Erling Smørgrav 	k->_extra.dnssec.inception = i;
14257b5038d7SDag-Erling Smørgrav }
14267b5038d7SDag-Erling Smørgrav 
14277b5038d7SDag-Erling Smørgrav void
ldns_key_set_expiration(ldns_key * k,uint32_t e)14287b5038d7SDag-Erling Smørgrav ldns_key_set_expiration(ldns_key *k, uint32_t e)
14297b5038d7SDag-Erling Smørgrav {
14307b5038d7SDag-Erling Smørgrav 	k->_extra.dnssec.expiration = e;
14317b5038d7SDag-Erling Smørgrav }
14327b5038d7SDag-Erling Smørgrav 
14337b5038d7SDag-Erling Smørgrav void
ldns_key_set_pubkey_owner(ldns_key * k,ldns_rdf * r)14347b5038d7SDag-Erling Smørgrav ldns_key_set_pubkey_owner(ldns_key *k, ldns_rdf *r)
14357b5038d7SDag-Erling Smørgrav {
14367b5038d7SDag-Erling Smørgrav 	k->_pubkey_owner = r;
14377b5038d7SDag-Erling Smørgrav }
14387b5038d7SDag-Erling Smørgrav 
14397b5038d7SDag-Erling Smørgrav void
ldns_key_set_keytag(ldns_key * k,uint16_t tag)14407b5038d7SDag-Erling Smørgrav ldns_key_set_keytag(ldns_key *k, uint16_t tag)
14417b5038d7SDag-Erling Smørgrav {
14427b5038d7SDag-Erling Smørgrav 	k->_extra.dnssec.keytag = tag;
14437b5038d7SDag-Erling Smørgrav }
14447b5038d7SDag-Erling Smørgrav 
14457b5038d7SDag-Erling Smørgrav /* read */
14467b5038d7SDag-Erling Smørgrav size_t
ldns_key_list_key_count(const ldns_key_list * key_list)14477b5038d7SDag-Erling Smørgrav ldns_key_list_key_count(const ldns_key_list *key_list)
14487b5038d7SDag-Erling Smørgrav {
1449*5afab0e5SDag-Erling Smørgrav 	return key_list ? key_list->_key_count : 0;
14507b5038d7SDag-Erling Smørgrav }
14517b5038d7SDag-Erling Smørgrav 
14527b5038d7SDag-Erling Smørgrav ldns_key *
ldns_key_list_key(const ldns_key_list * key,size_t nr)14537b5038d7SDag-Erling Smørgrav ldns_key_list_key(const ldns_key_list *key, size_t nr)
14547b5038d7SDag-Erling Smørgrav {
14557b5038d7SDag-Erling Smørgrav 	if (nr < ldns_key_list_key_count(key)) {
14567b5038d7SDag-Erling Smørgrav 		return key->_keys[nr];
14577b5038d7SDag-Erling Smørgrav 	} else {
14587b5038d7SDag-Erling Smørgrav 		return NULL;
14597b5038d7SDag-Erling Smørgrav 	}
14607b5038d7SDag-Erling Smørgrav }
14617b5038d7SDag-Erling Smørgrav 
14627b5038d7SDag-Erling Smørgrav ldns_signing_algorithm
ldns_key_algorithm(const ldns_key * k)14637b5038d7SDag-Erling Smørgrav ldns_key_algorithm(const ldns_key *k)
14647b5038d7SDag-Erling Smørgrav {
14657b5038d7SDag-Erling Smørgrav 	return k->_alg;
14667b5038d7SDag-Erling Smørgrav }
14677b5038d7SDag-Erling Smørgrav 
14687b5038d7SDag-Erling Smørgrav void
ldns_key_set_use(ldns_key * k,bool v)14697b5038d7SDag-Erling Smørgrav ldns_key_set_use(ldns_key *k, bool v)
14707b5038d7SDag-Erling Smørgrav {
14717b5038d7SDag-Erling Smørgrav 	if (k) {
14727b5038d7SDag-Erling Smørgrav 		k->_use = v;
14737b5038d7SDag-Erling Smørgrav 	}
14747b5038d7SDag-Erling Smørgrav }
14757b5038d7SDag-Erling Smørgrav 
14767b5038d7SDag-Erling Smørgrav bool
ldns_key_use(const ldns_key * k)14777b5038d7SDag-Erling Smørgrav ldns_key_use(const ldns_key *k)
14787b5038d7SDag-Erling Smørgrav {
14797b5038d7SDag-Erling Smørgrav 	if (k) {
14807b5038d7SDag-Erling Smørgrav 		return k->_use;
14817b5038d7SDag-Erling Smørgrav 	}
14827b5038d7SDag-Erling Smørgrav 	return false;
14837b5038d7SDag-Erling Smørgrav }
14847b5038d7SDag-Erling Smørgrav 
14857b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
14867b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S
14877b5038d7SDag-Erling Smørgrav EVP_PKEY *
ldns_key_evp_key(const ldns_key * k)14887b5038d7SDag-Erling Smørgrav ldns_key_evp_key(const ldns_key *k)
14897b5038d7SDag-Erling Smørgrav {
14907b5038d7SDag-Erling Smørgrav 	return k->_key.key;
14917b5038d7SDag-Erling Smørgrav }
14927b5038d7SDag-Erling Smørgrav 
14937b5038d7SDag-Erling Smørgrav RSA *
ldns_key_rsa_key(const ldns_key * k)14947b5038d7SDag-Erling Smørgrav ldns_key_rsa_key(const ldns_key *k)
14957b5038d7SDag-Erling Smørgrav {
14967b5038d7SDag-Erling Smørgrav 	if (k->_key.key) {
14977b5038d7SDag-Erling Smørgrav 		return EVP_PKEY_get1_RSA(k->_key.key);
14987b5038d7SDag-Erling Smørgrav 	} else {
14997b5038d7SDag-Erling Smørgrav 		return NULL;
15007b5038d7SDag-Erling Smørgrav 	}
15017b5038d7SDag-Erling Smørgrav }
15027b5038d7SDag-Erling Smørgrav 
15037b5038d7SDag-Erling Smørgrav DSA *
ldns_key_dsa_key(const ldns_key * k)15047b5038d7SDag-Erling Smørgrav ldns_key_dsa_key(const ldns_key *k)
15057b5038d7SDag-Erling Smørgrav {
1506986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
15077b5038d7SDag-Erling Smørgrav 	if (k->_key.key) {
15087b5038d7SDag-Erling Smørgrav 		return EVP_PKEY_get1_DSA(k->_key.key);
15097b5038d7SDag-Erling Smørgrav 	} else {
15107b5038d7SDag-Erling Smørgrav 		return NULL;
15117b5038d7SDag-Erling Smørgrav 	}
1512986ba33cSDag-Erling Smørgrav #else
1513986ba33cSDag-Erling Smørgrav 	(void)k;
1514986ba33cSDag-Erling Smørgrav 	return NULL;
1515986ba33cSDag-Erling Smørgrav #endif
15167b5038d7SDag-Erling Smørgrav }
15177b5038d7SDag-Erling Smørgrav #endif /* splint */
15187b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
15197b5038d7SDag-Erling Smørgrav 
15207b5038d7SDag-Erling Smørgrav unsigned char *
ldns_key_hmac_key(const ldns_key * k)15217b5038d7SDag-Erling Smørgrav ldns_key_hmac_key(const ldns_key *k)
15227b5038d7SDag-Erling Smørgrav {
15237b5038d7SDag-Erling Smørgrav 	if (k->_key.hmac.key) {
15247b5038d7SDag-Erling Smørgrav 		return k->_key.hmac.key;
15257b5038d7SDag-Erling Smørgrav 	} else {
15267b5038d7SDag-Erling Smørgrav 		return NULL;
15277b5038d7SDag-Erling Smørgrav 	}
15287b5038d7SDag-Erling Smørgrav }
15297b5038d7SDag-Erling Smørgrav 
15307b5038d7SDag-Erling Smørgrav size_t
ldns_key_hmac_size(const ldns_key * k)15317b5038d7SDag-Erling Smørgrav ldns_key_hmac_size(const ldns_key *k)
15327b5038d7SDag-Erling Smørgrav {
15337b5038d7SDag-Erling Smørgrav 	if (k->_key.hmac.size) {
15347b5038d7SDag-Erling Smørgrav 		return k->_key.hmac.size;
15357b5038d7SDag-Erling Smørgrav 	} else {
15367b5038d7SDag-Erling Smørgrav 		return 0;
15377b5038d7SDag-Erling Smørgrav 	}
15387b5038d7SDag-Erling Smørgrav }
15397b5038d7SDag-Erling Smørgrav 
15407b5038d7SDag-Erling Smørgrav void *
ldns_key_external_key(const ldns_key * k)15417b5038d7SDag-Erling Smørgrav ldns_key_external_key(const ldns_key *k)
15427b5038d7SDag-Erling Smørgrav {
15437b5038d7SDag-Erling Smørgrav 	return k->_key.external_key;
15447b5038d7SDag-Erling Smørgrav }
15457b5038d7SDag-Erling Smørgrav 
15467b5038d7SDag-Erling Smørgrav uint32_t
ldns_key_origttl(const ldns_key * k)15477b5038d7SDag-Erling Smørgrav ldns_key_origttl(const ldns_key *k)
15487b5038d7SDag-Erling Smørgrav {
15497b5038d7SDag-Erling Smørgrav 	return k->_extra.dnssec.orig_ttl;
15507b5038d7SDag-Erling Smørgrav }
15517b5038d7SDag-Erling Smørgrav 
15527b5038d7SDag-Erling Smørgrav uint16_t
ldns_key_flags(const ldns_key * k)15537b5038d7SDag-Erling Smørgrav ldns_key_flags(const ldns_key *k)
15547b5038d7SDag-Erling Smørgrav {
15557b5038d7SDag-Erling Smørgrav 	return k->_extra.dnssec.flags;
15567b5038d7SDag-Erling Smørgrav }
15577b5038d7SDag-Erling Smørgrav 
15587b5038d7SDag-Erling Smørgrav uint32_t
ldns_key_inception(const ldns_key * k)15597b5038d7SDag-Erling Smørgrav ldns_key_inception(const ldns_key *k)
15607b5038d7SDag-Erling Smørgrav {
15617b5038d7SDag-Erling Smørgrav 	return k->_extra.dnssec.inception;
15627b5038d7SDag-Erling Smørgrav }
15637b5038d7SDag-Erling Smørgrav 
15647b5038d7SDag-Erling Smørgrav uint32_t
ldns_key_expiration(const ldns_key * k)15657b5038d7SDag-Erling Smørgrav ldns_key_expiration(const ldns_key *k)
15667b5038d7SDag-Erling Smørgrav {
15677b5038d7SDag-Erling Smørgrav 	return k->_extra.dnssec.expiration;
15687b5038d7SDag-Erling Smørgrav }
15697b5038d7SDag-Erling Smørgrav 
15707b5038d7SDag-Erling Smørgrav uint16_t
ldns_key_keytag(const ldns_key * k)15717b5038d7SDag-Erling Smørgrav ldns_key_keytag(const ldns_key *k)
15727b5038d7SDag-Erling Smørgrav {
15737b5038d7SDag-Erling Smørgrav 	return k->_extra.dnssec.keytag;
15747b5038d7SDag-Erling Smørgrav }
15757b5038d7SDag-Erling Smørgrav 
15767b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_key_pubkey_owner(const ldns_key * k)15777b5038d7SDag-Erling Smørgrav ldns_key_pubkey_owner(const ldns_key *k)
15787b5038d7SDag-Erling Smørgrav {
15797b5038d7SDag-Erling Smørgrav 	return k->_pubkey_owner;
15807b5038d7SDag-Erling Smørgrav }
15817b5038d7SDag-Erling Smørgrav 
15827b5038d7SDag-Erling Smørgrav /* write */
15837b5038d7SDag-Erling Smørgrav void
ldns_key_list_set_use(ldns_key_list * keys,bool v)15847b5038d7SDag-Erling Smørgrav ldns_key_list_set_use(ldns_key_list *keys, bool v)
15857b5038d7SDag-Erling Smørgrav {
15867b5038d7SDag-Erling Smørgrav 	size_t i;
15877b5038d7SDag-Erling Smørgrav 
15887b5038d7SDag-Erling Smørgrav 	for (i = 0; i < ldns_key_list_key_count(keys); i++) {
15897b5038d7SDag-Erling Smørgrav 		ldns_key_set_use(ldns_key_list_key(keys, i), v);
15907b5038d7SDag-Erling Smørgrav 	}
15917b5038d7SDag-Erling Smørgrav }
15927b5038d7SDag-Erling Smørgrav 
15937b5038d7SDag-Erling Smørgrav void
ldns_key_list_set_key_count(ldns_key_list * key,size_t count)15947b5038d7SDag-Erling Smørgrav ldns_key_list_set_key_count(ldns_key_list *key, size_t count)
15957b5038d7SDag-Erling Smørgrav {
15967b5038d7SDag-Erling Smørgrav 	        key->_key_count = count;
15977b5038d7SDag-Erling Smørgrav }
15987b5038d7SDag-Erling Smørgrav 
15997b5038d7SDag-Erling Smørgrav bool
ldns_key_list_push_key(ldns_key_list * key_list,ldns_key * key)16007b5038d7SDag-Erling Smørgrav ldns_key_list_push_key(ldns_key_list *key_list, ldns_key *key)
16017b5038d7SDag-Erling Smørgrav {
16027b5038d7SDag-Erling Smørgrav         size_t key_count;
16037b5038d7SDag-Erling Smørgrav         ldns_key **keys;
16047b5038d7SDag-Erling Smørgrav 
16057b5038d7SDag-Erling Smørgrav         key_count = ldns_key_list_key_count(key_list);
16067b5038d7SDag-Erling Smørgrav 
16077b5038d7SDag-Erling Smørgrav         /* grow the array */
16087b5038d7SDag-Erling Smørgrav         keys = LDNS_XREALLOC(
16097b5038d7SDag-Erling Smørgrav                 key_list->_keys, ldns_key *, key_count + 1);
16107b5038d7SDag-Erling Smørgrav         if (!keys) {
16117b5038d7SDag-Erling Smørgrav                 return false;
16127b5038d7SDag-Erling Smørgrav         }
16137b5038d7SDag-Erling Smørgrav 
16147b5038d7SDag-Erling Smørgrav         /* add the new member */
16157b5038d7SDag-Erling Smørgrav         key_list->_keys = keys;
16167b5038d7SDag-Erling Smørgrav         key_list->_keys[key_count] = key;
16177b5038d7SDag-Erling Smørgrav 
16187b5038d7SDag-Erling Smørgrav         ldns_key_list_set_key_count(key_list, key_count + 1);
16197b5038d7SDag-Erling Smørgrav         return true;
16207b5038d7SDag-Erling Smørgrav }
16217b5038d7SDag-Erling Smørgrav 
16227b5038d7SDag-Erling Smørgrav ldns_key *
ldns_key_list_pop_key(ldns_key_list * key_list)16237b5038d7SDag-Erling Smørgrav ldns_key_list_pop_key(ldns_key_list *key_list)
16247b5038d7SDag-Erling Smørgrav {
16257b5038d7SDag-Erling Smørgrav         size_t key_count;
16267b5038d7SDag-Erling Smørgrav         ldns_key** a;
16277b5038d7SDag-Erling Smørgrav         ldns_key *pop;
16287b5038d7SDag-Erling Smørgrav 
16297b5038d7SDag-Erling Smørgrav 	if (!key_list) {
16307b5038d7SDag-Erling Smørgrav 		return NULL;
16317b5038d7SDag-Erling Smørgrav 	}
16327b5038d7SDag-Erling Smørgrav 
16337b5038d7SDag-Erling Smørgrav         key_count = ldns_key_list_key_count(key_list);
16347b5038d7SDag-Erling Smørgrav         if (key_count == 0) {
16357b5038d7SDag-Erling Smørgrav                 return NULL;
16367b5038d7SDag-Erling Smørgrav         }
16377b5038d7SDag-Erling Smørgrav 
16387b5038d7SDag-Erling Smørgrav         pop = ldns_key_list_key(key_list, key_count);
16397b5038d7SDag-Erling Smørgrav 
16407b5038d7SDag-Erling Smørgrav         /* shrink the array */
16417b5038d7SDag-Erling Smørgrav         a = LDNS_XREALLOC(key_list->_keys, ldns_key *, key_count - 1);
16427b5038d7SDag-Erling Smørgrav         if(a) {
16437b5038d7SDag-Erling Smørgrav                 key_list->_keys = a;
16447b5038d7SDag-Erling Smørgrav         }
16457b5038d7SDag-Erling Smørgrav 
16467b5038d7SDag-Erling Smørgrav         ldns_key_list_set_key_count(key_list, key_count - 1);
16477b5038d7SDag-Erling Smørgrav 
16487b5038d7SDag-Erling Smørgrav         return pop;
16497b5038d7SDag-Erling Smørgrav }
16507b5038d7SDag-Erling Smørgrav 
16517b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
16527b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S
16537b5038d7SDag-Erling Smørgrav /* data pointer must be large enough (LDNS_MAX_KEYLEN) */
16547b5038d7SDag-Erling Smørgrav static bool
ldns_key_rsa2bin(unsigned char * data,RSA * k,uint16_t * size)16557b5038d7SDag-Erling Smørgrav ldns_key_rsa2bin(unsigned char *data, RSA *k, uint16_t *size)
16567b5038d7SDag-Erling Smørgrav {
16577b5038d7SDag-Erling Smørgrav 	int i,j;
1658986ba33cSDag-Erling Smørgrav 	const BIGNUM *n=NULL, *e=NULL;
16597b5038d7SDag-Erling Smørgrav 
16607b5038d7SDag-Erling Smørgrav 	if (!k) {
16617b5038d7SDag-Erling Smørgrav 		return false;
16627b5038d7SDag-Erling Smørgrav 	}
1663*5afab0e5SDag-Erling Smørgrav #if OPENSSL_VERSION_NUMBER < 0x10100000 || (defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x20700000)
1664986ba33cSDag-Erling Smørgrav 	n = k->n;
1665986ba33cSDag-Erling Smørgrav 	e = k->e;
1666986ba33cSDag-Erling Smørgrav #else
1667986ba33cSDag-Erling Smørgrav 	RSA_get0_key(k, &n, &e, NULL);
1668986ba33cSDag-Erling Smørgrav #endif
16697b5038d7SDag-Erling Smørgrav 
1670986ba33cSDag-Erling Smørgrav 	if (BN_num_bytes(e) <= 256) {
16717b5038d7SDag-Erling Smørgrav 		/* normally only this path is executed (small factors are
16727b5038d7SDag-Erling Smørgrav 		 * more common
16737b5038d7SDag-Erling Smørgrav 		 */
1674986ba33cSDag-Erling Smørgrav 		data[0] = (unsigned char) BN_num_bytes(e);
1675986ba33cSDag-Erling Smørgrav 		i = BN_bn2bin(e, data + 1);
1676986ba33cSDag-Erling Smørgrav 		j = BN_bn2bin(n, data + i + 1);
16777b5038d7SDag-Erling Smørgrav 		*size = (uint16_t) i + j;
1678986ba33cSDag-Erling Smørgrav 	} else if (BN_num_bytes(e) <= 65536) {
16797b5038d7SDag-Erling Smørgrav 		data[0] = 0;
16807b5038d7SDag-Erling Smørgrav 		/* BN_bn2bin does bigendian, _uint16 also */
1681986ba33cSDag-Erling Smørgrav 		ldns_write_uint16(data + 1, (uint16_t) BN_num_bytes(e));
16827b5038d7SDag-Erling Smørgrav 
1683986ba33cSDag-Erling Smørgrav 		BN_bn2bin(e, data + 3);
1684986ba33cSDag-Erling Smørgrav 		BN_bn2bin(n, data + 4 + BN_num_bytes(e));
1685986ba33cSDag-Erling Smørgrav 		*size = (uint16_t) BN_num_bytes(n) + 6;
16867b5038d7SDag-Erling Smørgrav 	} else {
16877b5038d7SDag-Erling Smørgrav 		return false;
16887b5038d7SDag-Erling Smørgrav 	}
16897b5038d7SDag-Erling Smørgrav 	return true;
16907b5038d7SDag-Erling Smørgrav }
16917b5038d7SDag-Erling Smørgrav 
1692986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
16937b5038d7SDag-Erling Smørgrav /* data pointer must be large enough (LDNS_MAX_KEYLEN) */
16947b5038d7SDag-Erling Smørgrav static bool
ldns_key_dsa2bin(unsigned char * data,DSA * k,uint16_t * size)16957b5038d7SDag-Erling Smørgrav ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size)
16967b5038d7SDag-Erling Smørgrav {
16977b5038d7SDag-Erling Smørgrav 	uint8_t T;
1698986ba33cSDag-Erling Smørgrav 	const BIGNUM *p, *q, *g;
1699986ba33cSDag-Erling Smørgrav 	const BIGNUM *pub_key, *priv_key;
17007b5038d7SDag-Erling Smørgrav 
17017b5038d7SDag-Erling Smørgrav 	if (!k) {
17027b5038d7SDag-Erling Smørgrav 		return false;
17037b5038d7SDag-Erling Smørgrav 	}
17047b5038d7SDag-Erling Smørgrav 
17057b5038d7SDag-Erling Smørgrav 	/* See RFC2536 */
1706986ba33cSDag-Erling Smørgrav # ifdef HAVE_DSA_GET0_PQG
1707986ba33cSDag-Erling Smørgrav 	DSA_get0_pqg(k, &p, &q, &g);
1708986ba33cSDag-Erling Smørgrav # else
1709986ba33cSDag-Erling Smørgrav 	p = k->p; q = k->q; g = k->g;
1710986ba33cSDag-Erling Smørgrav # endif
1711986ba33cSDag-Erling Smørgrav # ifdef HAVE_DSA_GET0_KEY
1712986ba33cSDag-Erling Smørgrav 	DSA_get0_key(k, &pub_key, &priv_key);
1713986ba33cSDag-Erling Smørgrav # else
1714986ba33cSDag-Erling Smørgrav 	pub_key = k->pub_key; priv_key = k->priv_key;
1715986ba33cSDag-Erling Smørgrav # endif
1716986ba33cSDag-Erling Smørgrav 	(void)priv_key;
1717986ba33cSDag-Erling Smørgrav 	*size = (uint16_t)BN_num_bytes(p);
17187b5038d7SDag-Erling Smørgrav 	T = (*size - 64) / 8;
17197b5038d7SDag-Erling Smørgrav 
17207b5038d7SDag-Erling Smørgrav 	if (T > 8) {
172117d15b25SDag-Erling Smørgrav #ifdef STDERR_MSGS
17227b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)");
17237b5038d7SDag-Erling Smørgrav 		fprintf(stderr, " not implemented\n");
172417d15b25SDag-Erling Smørgrav #endif
17257b5038d7SDag-Erling Smørgrav 		return false;
17267b5038d7SDag-Erling Smørgrav 	}
17277b5038d7SDag-Erling Smørgrav 
17287b5038d7SDag-Erling Smørgrav 	/* size = 64 + (T * 8); */
1729986ba33cSDag-Erling Smørgrav 	memset(data, 0, 21 + *size * 3);
17307b5038d7SDag-Erling Smørgrav 	data[0] = (unsigned char)T;
1731986ba33cSDag-Erling Smørgrav 	BN_bn2bin(q, data + 1 ); 		/* 20 octects */
1732986ba33cSDag-Erling Smørgrav 	BN_bn2bin(p, data + 21 ); 		/* offset octects */
1733986ba33cSDag-Erling Smørgrav 	BN_bn2bin(g, data + 21 + *size * 2 - BN_num_bytes(g));
1734986ba33cSDag-Erling Smørgrav 	BN_bn2bin(pub_key,data + 21 + *size * 3 - BN_num_bytes(pub_key));
1735986ba33cSDag-Erling Smørgrav 	*size = 21 + *size * 3;
17367b5038d7SDag-Erling Smørgrav 	return true;
17377b5038d7SDag-Erling Smørgrav }
1738986ba33cSDag-Erling Smørgrav #endif /* USE_DSA */
17397b5038d7SDag-Erling Smørgrav 
17407b5038d7SDag-Erling Smørgrav #ifdef USE_GOST
17417b5038d7SDag-Erling Smørgrav static bool
ldns_key_gost2bin(unsigned char * data,EVP_PKEY * k,uint16_t * size)17427b5038d7SDag-Erling Smørgrav ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
17437b5038d7SDag-Erling Smørgrav {
17447b5038d7SDag-Erling Smørgrav 	int i;
17457b5038d7SDag-Erling Smørgrav 	unsigned char* pp = NULL;
17467b5038d7SDag-Erling Smørgrav 	if(i2d_PUBKEY(k, &pp) != 37 + 64) {
17477b5038d7SDag-Erling Smørgrav 		/* expect 37 byte(ASN header) and 64 byte(X and Y) */
1748986ba33cSDag-Erling Smørgrav 		free(pp);
17497b5038d7SDag-Erling Smørgrav 		return false;
17507b5038d7SDag-Erling Smørgrav 	}
17517b5038d7SDag-Erling Smørgrav 	/* omit ASN header */
17527b5038d7SDag-Erling Smørgrav 	for(i=0; i<64; i++)
17537b5038d7SDag-Erling Smørgrav 		data[i] = pp[i+37];
1754986ba33cSDag-Erling Smørgrav 	free(pp);
17557b5038d7SDag-Erling Smørgrav 	*size = 64;
17567b5038d7SDag-Erling Smørgrav 	return true;
17577b5038d7SDag-Erling Smørgrav }
17587b5038d7SDag-Erling Smørgrav #endif /* USE_GOST */
1759*5afab0e5SDag-Erling Smørgrav 
1760*5afab0e5SDag-Erling Smørgrav #ifdef USE_ED25519
1761*5afab0e5SDag-Erling Smørgrav static bool
ldns_key_ed255192bin(unsigned char * data,EVP_PKEY * k,uint16_t * size)1762*5afab0e5SDag-Erling Smørgrav ldns_key_ed255192bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
1763*5afab0e5SDag-Erling Smørgrav {
1764*5afab0e5SDag-Erling Smørgrav 	int i;
1765*5afab0e5SDag-Erling Smørgrav 	unsigned char* pp = NULL;
1766*5afab0e5SDag-Erling Smørgrav 	if(i2d_PUBKEY(k, &pp) != 12 + 32) {
1767*5afab0e5SDag-Erling Smørgrav 		/* expect 12 byte(ASN header) and 32 byte(pubkey) */
1768*5afab0e5SDag-Erling Smørgrav 		free(pp);
1769*5afab0e5SDag-Erling Smørgrav 		return false;
1770*5afab0e5SDag-Erling Smørgrav 	}
1771*5afab0e5SDag-Erling Smørgrav 	/* omit ASN header */
1772*5afab0e5SDag-Erling Smørgrav 	for(i=0; i<32; i++)
1773*5afab0e5SDag-Erling Smørgrav 		data[i] = pp[i+12];
1774*5afab0e5SDag-Erling Smørgrav 	free(pp);
1775*5afab0e5SDag-Erling Smørgrav 	*size = 32;
1776*5afab0e5SDag-Erling Smørgrav 	return true;
1777*5afab0e5SDag-Erling Smørgrav }
1778*5afab0e5SDag-Erling Smørgrav #endif /* USE_ED25519 */
1779*5afab0e5SDag-Erling Smørgrav 
1780*5afab0e5SDag-Erling Smørgrav #ifdef USE_ED448
1781*5afab0e5SDag-Erling Smørgrav static bool
ldns_key_ed4482bin(unsigned char * data,EVP_PKEY * k,uint16_t * size)1782*5afab0e5SDag-Erling Smørgrav ldns_key_ed4482bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
1783*5afab0e5SDag-Erling Smørgrav {
1784*5afab0e5SDag-Erling Smørgrav 	int i;
1785*5afab0e5SDag-Erling Smørgrav 	unsigned char* pp = NULL;
1786*5afab0e5SDag-Erling Smørgrav 	if(i2d_PUBKEY(k, &pp) != 12 + 57) {
1787*5afab0e5SDag-Erling Smørgrav 		/* expect 12 byte(ASN header) and 57 byte(pubkey) */
1788*5afab0e5SDag-Erling Smørgrav 		free(pp);
1789*5afab0e5SDag-Erling Smørgrav 		return false;
1790*5afab0e5SDag-Erling Smørgrav 	}
1791*5afab0e5SDag-Erling Smørgrav 	/* omit ASN header */
1792*5afab0e5SDag-Erling Smørgrav 	for(i=0; i<57; i++)
1793*5afab0e5SDag-Erling Smørgrav 		data[i] = pp[i+12];
1794*5afab0e5SDag-Erling Smørgrav 	free(pp);
1795*5afab0e5SDag-Erling Smørgrav 	*size = 57;
1796*5afab0e5SDag-Erling Smørgrav 	return true;
1797*5afab0e5SDag-Erling Smørgrav }
1798*5afab0e5SDag-Erling Smørgrav #endif /* USE_ED448 */
17997b5038d7SDag-Erling Smørgrav #endif /* splint */
18007b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
18017b5038d7SDag-Erling Smørgrav 
18027b5038d7SDag-Erling Smørgrav ldns_rr *
ldns_key2rr(const ldns_key * k)18037b5038d7SDag-Erling Smørgrav ldns_key2rr(const ldns_key *k)
18047b5038d7SDag-Erling Smørgrav {
18057b5038d7SDag-Erling Smørgrav 	/* this function will convert a the keydata contained in
18067b5038d7SDag-Erling Smørgrav 	 * rsa/dsa pointers to a DNSKEY rr. It will fill in as
18077b5038d7SDag-Erling Smørgrav 	 * much as it can, but it does not know about key-flags
18087b5038d7SDag-Erling Smørgrav 	 * for instance
18097b5038d7SDag-Erling Smørgrav 	 */
18107b5038d7SDag-Erling Smørgrav 	ldns_rr *pubkey;
18117b5038d7SDag-Erling Smørgrav 	ldns_rdf *keybin;
18127b5038d7SDag-Erling Smørgrav 	unsigned char *bin = NULL;
18137b5038d7SDag-Erling Smørgrav 	uint16_t size = 0;
18147b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
18157b5038d7SDag-Erling Smørgrav 	RSA *rsa = NULL;
1816986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
18177b5038d7SDag-Erling Smørgrav 	DSA *dsa = NULL;
1818986ba33cSDag-Erling Smørgrav #endif /* USE_DSA */
18197b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
18207b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA
18217b5038d7SDag-Erling Smørgrav         EC_KEY* ec;
18227b5038d7SDag-Erling Smørgrav #endif
18237b5038d7SDag-Erling Smørgrav 	int internal_data = 0;
18247b5038d7SDag-Erling Smørgrav 
18257b5038d7SDag-Erling Smørgrav 	if (!k) {
18267b5038d7SDag-Erling Smørgrav 		return NULL;
18277b5038d7SDag-Erling Smørgrav 	}
18282787e39aSDag-Erling Smørgrav 	pubkey = ldns_rr_new();
18297b5038d7SDag-Erling Smørgrav 
18307b5038d7SDag-Erling Smørgrav 	switch (ldns_key_algorithm(k)) {
18317b5038d7SDag-Erling Smørgrav 	case LDNS_SIGN_HMACMD5:
18327b5038d7SDag-Erling Smørgrav 	case LDNS_SIGN_HMACSHA1:
1833986ba33cSDag-Erling Smørgrav 	case LDNS_SIGN_HMACSHA224:
18347b5038d7SDag-Erling Smørgrav 	case LDNS_SIGN_HMACSHA256:
1835986ba33cSDag-Erling Smørgrav 	case LDNS_SIGN_HMACSHA384:
1836986ba33cSDag-Erling Smørgrav 	case LDNS_SIGN_HMACSHA512:
18377b5038d7SDag-Erling Smørgrav 		ldns_rr_set_type(pubkey, LDNS_RR_TYPE_KEY);
18387b5038d7SDag-Erling Smørgrav         	break;
18397b5038d7SDag-Erling Smørgrav 	default:
18407b5038d7SDag-Erling Smørgrav 		ldns_rr_set_type(pubkey, LDNS_RR_TYPE_DNSKEY);
18417b5038d7SDag-Erling Smørgrav 		break;
18427b5038d7SDag-Erling Smørgrav         }
18437b5038d7SDag-Erling Smørgrav 	/* zero-th rdf - flags */
18447b5038d7SDag-Erling Smørgrav 	ldns_rr_push_rdf(pubkey,
18457b5038d7SDag-Erling Smørgrav 			ldns_native2rdf_int16(LDNS_RDF_TYPE_INT16,
18467b5038d7SDag-Erling Smørgrav 				ldns_key_flags(k)));
18477b5038d7SDag-Erling Smørgrav 	/* first - proto */
18487b5038d7SDag-Erling Smørgrav 	ldns_rr_push_rdf(pubkey,
18497b5038d7SDag-Erling Smørgrav 			ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, LDNS_DNSSEC_KEYPROTO));
18507b5038d7SDag-Erling Smørgrav 
18517b5038d7SDag-Erling Smørgrav 	if (ldns_key_pubkey_owner(k)) {
18527b5038d7SDag-Erling Smørgrav 		ldns_rr_set_owner(pubkey, ldns_rdf_clone(ldns_key_pubkey_owner(k)));
18537b5038d7SDag-Erling Smørgrav 	}
18547b5038d7SDag-Erling Smørgrav 
18557b5038d7SDag-Erling Smørgrav 	/* third - da algorithm */
18567b5038d7SDag-Erling Smørgrav 	switch(ldns_key_algorithm(k)) {
18577b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSAMD5:
18587b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSASHA1:
18597b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSASHA1_NSEC3:
18607b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSASHA256:
18617b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_RSASHA512:
18627b5038d7SDag-Erling Smørgrav 			ldns_rr_push_rdf(pubkey,
18637b5038d7SDag-Erling Smørgrav 						  ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
18647b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
18657b5038d7SDag-Erling Smørgrav 			rsa =  ldns_key_rsa_key(k);
18667b5038d7SDag-Erling Smørgrav 			if (rsa) {
18677b5038d7SDag-Erling Smørgrav 				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
18687b5038d7SDag-Erling Smørgrav 				if (!bin) {
18697b5038d7SDag-Erling Smørgrav                                         ldns_rr_free(pubkey);
18707b5038d7SDag-Erling Smørgrav 					return NULL;
18717b5038d7SDag-Erling Smørgrav 				}
18727b5038d7SDag-Erling Smørgrav 				if (!ldns_key_rsa2bin(bin, rsa, &size)) {
18737b5038d7SDag-Erling Smørgrav 		                        LDNS_FREE(bin);
18747b5038d7SDag-Erling Smørgrav                                         ldns_rr_free(pubkey);
18757b5038d7SDag-Erling Smørgrav 					return NULL;
18767b5038d7SDag-Erling Smørgrav 				}
18777b5038d7SDag-Erling Smørgrav 				RSA_free(rsa);
18787b5038d7SDag-Erling Smørgrav 				internal_data = 1;
18797b5038d7SDag-Erling Smørgrav 			}
18807b5038d7SDag-Erling Smørgrav #endif
18817b5038d7SDag-Erling Smørgrav 			size++;
18827b5038d7SDag-Erling Smørgrav 			break;
1883*5afab0e5SDag-Erling Smørgrav #ifdef USE_DSA
18847b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_DSA:
18857b5038d7SDag-Erling Smørgrav 			ldns_rr_push_rdf(pubkey,
18867b5038d7SDag-Erling Smørgrav 					ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA));
18877b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
18887b5038d7SDag-Erling Smørgrav 			dsa = ldns_key_dsa_key(k);
18897b5038d7SDag-Erling Smørgrav 			if (dsa) {
18907b5038d7SDag-Erling Smørgrav 				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
18917b5038d7SDag-Erling Smørgrav 				if (!bin) {
18927b5038d7SDag-Erling Smørgrav                                         ldns_rr_free(pubkey);
18937b5038d7SDag-Erling Smørgrav 					return NULL;
18947b5038d7SDag-Erling Smørgrav 				}
18957b5038d7SDag-Erling Smørgrav 				if (!ldns_key_dsa2bin(bin, dsa, &size)) {
18967b5038d7SDag-Erling Smørgrav 		                        LDNS_FREE(bin);
18977b5038d7SDag-Erling Smørgrav                                         ldns_rr_free(pubkey);
18987b5038d7SDag-Erling Smørgrav 					return NULL;
18997b5038d7SDag-Erling Smørgrav 				}
19007b5038d7SDag-Erling Smørgrav 				DSA_free(dsa);
19017b5038d7SDag-Erling Smørgrav 				internal_data = 1;
19027b5038d7SDag-Erling Smørgrav 			}
19037b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
1904986ba33cSDag-Erling Smørgrav #endif /* USE_DSA */
19057b5038d7SDag-Erling Smørgrav 			break;
1906*5afab0e5SDag-Erling Smørgrav #ifdef USE_DSA
19077b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_DSA_NSEC3:
19087b5038d7SDag-Erling Smørgrav 			ldns_rr_push_rdf(pubkey,
19097b5038d7SDag-Erling Smørgrav 					ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG, LDNS_DSA_NSEC3));
19107b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
19117b5038d7SDag-Erling Smørgrav 			dsa = ldns_key_dsa_key(k);
19127b5038d7SDag-Erling Smørgrav 			if (dsa) {
19137b5038d7SDag-Erling Smørgrav 				bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
19147b5038d7SDag-Erling Smørgrav 				if (!bin) {
19157b5038d7SDag-Erling Smørgrav                                         ldns_rr_free(pubkey);
19167b5038d7SDag-Erling Smørgrav 					return NULL;
19177b5038d7SDag-Erling Smørgrav 				}
19187b5038d7SDag-Erling Smørgrav 				if (!ldns_key_dsa2bin(bin, dsa, &size)) {
19197b5038d7SDag-Erling Smørgrav 		                        LDNS_FREE(bin);
19207b5038d7SDag-Erling Smørgrav                                         ldns_rr_free(pubkey);
19217b5038d7SDag-Erling Smørgrav 					return NULL;
19227b5038d7SDag-Erling Smørgrav 				}
19237b5038d7SDag-Erling Smørgrav 				DSA_free(dsa);
19247b5038d7SDag-Erling Smørgrav 				internal_data = 1;
19257b5038d7SDag-Erling Smørgrav 			}
19267b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
1927986ba33cSDag-Erling Smørgrav #endif /* USE_DSA */
19287b5038d7SDag-Erling Smørgrav 			break;
19297b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_ECC_GOST:
19307b5038d7SDag-Erling Smørgrav 			ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
19317b5038d7SDag-Erling Smørgrav 				LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
19327b5038d7SDag-Erling Smørgrav #if defined(HAVE_SSL) && defined(USE_GOST)
19337b5038d7SDag-Erling Smørgrav 			bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
19347b5038d7SDag-Erling Smørgrav 			if (!bin) {
19357b5038d7SDag-Erling Smørgrav                                 ldns_rr_free(pubkey);
19367b5038d7SDag-Erling Smørgrav 				return NULL;
19377b5038d7SDag-Erling Smørgrav                         }
19387b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S
19397b5038d7SDag-Erling Smørgrav 			if (!ldns_key_gost2bin(bin, k->_key.key, &size)) {
19407b5038d7SDag-Erling Smørgrav 		                LDNS_FREE(bin);
19417b5038d7SDag-Erling Smørgrav                                 ldns_rr_free(pubkey);
19427b5038d7SDag-Erling Smørgrav 				return NULL;
19437b5038d7SDag-Erling Smørgrav 			}
19447b5038d7SDag-Erling Smørgrav #endif /* splint */
19457b5038d7SDag-Erling Smørgrav 			internal_data = 1;
19467b5038d7SDag-Erling Smørgrav #else
19477b5038d7SDag-Erling Smørgrav                         ldns_rr_free(pubkey);
19487b5038d7SDag-Erling Smørgrav 			return NULL;
19497b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL and USE_GOST */
19507b5038d7SDag-Erling Smørgrav 			break;
19517b5038d7SDag-Erling Smørgrav                 case LDNS_SIGN_ECDSAP256SHA256:
19527b5038d7SDag-Erling Smørgrav                 case LDNS_SIGN_ECDSAP384SHA384:
19537b5038d7SDag-Erling Smørgrav #ifdef USE_ECDSA
19547b5038d7SDag-Erling Smørgrav 			ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
19557b5038d7SDag-Erling Smørgrav 				LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
19567b5038d7SDag-Erling Smørgrav                         bin = NULL;
19577b5038d7SDag-Erling Smørgrav #ifndef S_SPLINT_S
19587b5038d7SDag-Erling Smørgrav                         ec = EVP_PKEY_get1_EC_KEY(k->_key.key);
19597b5038d7SDag-Erling Smørgrav #endif
19607b5038d7SDag-Erling Smørgrav                         EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED);
19617b5038d7SDag-Erling Smørgrav                         size = (uint16_t)i2o_ECPublicKey(ec, NULL);
19627b5038d7SDag-Erling Smørgrav                         if(!i2o_ECPublicKey(ec, &bin)) {
19637b5038d7SDag-Erling Smørgrav                                 EC_KEY_free(ec);
19647b5038d7SDag-Erling Smørgrav                                 ldns_rr_free(pubkey);
19657b5038d7SDag-Erling Smørgrav                                 return NULL;
19667b5038d7SDag-Erling Smørgrav                         }
19677b5038d7SDag-Erling Smørgrav 			if(size > 1) {
19687b5038d7SDag-Erling Smørgrav 				/* move back one byte to shave off the 0x02
19697b5038d7SDag-Erling Smørgrav 				 * 'uncompressed' indicator that openssl made
19707b5038d7SDag-Erling Smørgrav 				 * Actually its 0x04 (from implementation).
19717b5038d7SDag-Erling Smørgrav 				 */
19727b5038d7SDag-Erling Smørgrav 				assert(bin[0] == POINT_CONVERSION_UNCOMPRESSED);
19737b5038d7SDag-Erling Smørgrav 				size -= 1;
19747b5038d7SDag-Erling Smørgrav 				memmove(bin, bin+1, size);
19757b5038d7SDag-Erling Smørgrav 			}
19767b5038d7SDag-Erling Smørgrav                         /* down the reference count for ec, its still assigned
19777b5038d7SDag-Erling Smørgrav                          * to the pkey */
19787b5038d7SDag-Erling Smørgrav                         EC_KEY_free(ec);
19797b5038d7SDag-Erling Smørgrav 			internal_data = 1;
19807b5038d7SDag-Erling Smørgrav #else
19817b5038d7SDag-Erling Smørgrav                         ldns_rr_free(pubkey);
19827b5038d7SDag-Erling Smørgrav 			return NULL;
19837b5038d7SDag-Erling Smørgrav #endif /* ECDSA */
19847b5038d7SDag-Erling Smørgrav                         break;
1985986ba33cSDag-Erling Smørgrav #ifdef USE_ED25519
1986986ba33cSDag-Erling Smørgrav                 case LDNS_SIGN_ED25519:
1987986ba33cSDag-Erling Smørgrav 			ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
1988986ba33cSDag-Erling Smørgrav 				LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
1989*5afab0e5SDag-Erling Smørgrav 			bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
1990*5afab0e5SDag-Erling Smørgrav 			if (!bin) {
1991986ba33cSDag-Erling Smørgrav                                 ldns_rr_free(pubkey);
1992986ba33cSDag-Erling Smørgrav 				return NULL;
1993986ba33cSDag-Erling Smørgrav                         }
1994*5afab0e5SDag-Erling Smørgrav 			if (!ldns_key_ed255192bin(bin, k->_key.key, &size)) {
1995*5afab0e5SDag-Erling Smørgrav 		                LDNS_FREE(bin);
1996*5afab0e5SDag-Erling Smørgrav                                 ldns_rr_free(pubkey);
1997*5afab0e5SDag-Erling Smørgrav 				return NULL;
1998*5afab0e5SDag-Erling Smørgrav 			}
1999986ba33cSDag-Erling Smørgrav 			internal_data = 1;
2000986ba33cSDag-Erling Smørgrav 			break;
2001986ba33cSDag-Erling Smørgrav #endif
2002986ba33cSDag-Erling Smørgrav #ifdef USE_ED448
2003986ba33cSDag-Erling Smørgrav                 case LDNS_SIGN_ED448:
2004986ba33cSDag-Erling Smørgrav 			ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
2005986ba33cSDag-Erling Smørgrav 				LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
2006*5afab0e5SDag-Erling Smørgrav 			bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
2007*5afab0e5SDag-Erling Smørgrav 			if (!bin) {
2008986ba33cSDag-Erling Smørgrav                                 ldns_rr_free(pubkey);
2009986ba33cSDag-Erling Smørgrav 				return NULL;
2010986ba33cSDag-Erling Smørgrav                         }
2011*5afab0e5SDag-Erling Smørgrav 			if (!ldns_key_ed4482bin(bin, k->_key.key, &size)) {
2012*5afab0e5SDag-Erling Smørgrav 		                LDNS_FREE(bin);
2013*5afab0e5SDag-Erling Smørgrav                                 ldns_rr_free(pubkey);
2014*5afab0e5SDag-Erling Smørgrav 				return NULL;
2015*5afab0e5SDag-Erling Smørgrav 			}
2016986ba33cSDag-Erling Smørgrav 			internal_data = 1;
2017986ba33cSDag-Erling Smørgrav 			break;
2018986ba33cSDag-Erling Smørgrav #endif
20197b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_HMACMD5:
20207b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA1:
2021986ba33cSDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA224:
20227b5038d7SDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA256:
2023986ba33cSDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA384:
2024986ba33cSDag-Erling Smørgrav 		case LDNS_SIGN_HMACSHA512:
20257b5038d7SDag-Erling Smørgrav 			bin = LDNS_XMALLOC(unsigned char, ldns_key_hmac_size(k));
20267b5038d7SDag-Erling Smørgrav 			if (!bin) {
20277b5038d7SDag-Erling Smørgrav                                 ldns_rr_free(pubkey);
20287b5038d7SDag-Erling Smørgrav 				return NULL;
20297b5038d7SDag-Erling Smørgrav 			}
20307b5038d7SDag-Erling Smørgrav 			ldns_rr_push_rdf(pubkey,
20317b5038d7SDag-Erling Smørgrav 			                 ldns_native2rdf_int8(LDNS_RDF_TYPE_ALG,
20327b5038d7SDag-Erling Smørgrav 			                 ldns_key_algorithm(k)));
20337b5038d7SDag-Erling Smørgrav 			size = ldns_key_hmac_size(k);
20347b5038d7SDag-Erling Smørgrav 			memcpy(bin, ldns_key_hmac_key(k), size);
20357b5038d7SDag-Erling Smørgrav 			internal_data = 1;
20367b5038d7SDag-Erling Smørgrav 			break;
20377b5038d7SDag-Erling Smørgrav 	}
20387b5038d7SDag-Erling Smørgrav 	/* fourth the key bin material */
20397b5038d7SDag-Erling Smørgrav 	if (internal_data) {
20407b5038d7SDag-Erling Smørgrav 		keybin = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, size, bin);
20417b5038d7SDag-Erling Smørgrav 		LDNS_FREE(bin);
20427b5038d7SDag-Erling Smørgrav 		ldns_rr_push_rdf(pubkey, keybin);
20437b5038d7SDag-Erling Smørgrav 	}
20447b5038d7SDag-Erling Smørgrav 	return pubkey;
20457b5038d7SDag-Erling Smørgrav }
20467b5038d7SDag-Erling Smørgrav 
20477b5038d7SDag-Erling Smørgrav void
ldns_key_free(ldns_key * key)20487b5038d7SDag-Erling Smørgrav ldns_key_free(ldns_key *key)
20497b5038d7SDag-Erling Smørgrav {
20507b5038d7SDag-Erling Smørgrav 	LDNS_FREE(key);
20517b5038d7SDag-Erling Smørgrav }
20527b5038d7SDag-Erling Smørgrav 
20537b5038d7SDag-Erling Smørgrav void
ldns_key_deep_free(ldns_key * key)20547b5038d7SDag-Erling Smørgrav ldns_key_deep_free(ldns_key *key)
20557b5038d7SDag-Erling Smørgrav {
20567b5038d7SDag-Erling Smørgrav 	unsigned char* hmac;
20577b5038d7SDag-Erling Smørgrav 	if (ldns_key_pubkey_owner(key)) {
20587b5038d7SDag-Erling Smørgrav 		ldns_rdf_deep_free(ldns_key_pubkey_owner(key));
20597b5038d7SDag-Erling Smørgrav 	}
20607b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
20617b5038d7SDag-Erling Smørgrav 	if (ldns_key_evp_key(key)) {
20627b5038d7SDag-Erling Smørgrav 		EVP_PKEY_free(ldns_key_evp_key(key));
20637b5038d7SDag-Erling Smørgrav 	}
20647b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
20657b5038d7SDag-Erling Smørgrav 	if (ldns_key_hmac_key(key)) {
20667b5038d7SDag-Erling Smørgrav 		hmac = ldns_key_hmac_key(key);
20677b5038d7SDag-Erling Smørgrav 		LDNS_FREE(hmac);
20687b5038d7SDag-Erling Smørgrav 	}
20697b5038d7SDag-Erling Smørgrav 	LDNS_FREE(key);
20707b5038d7SDag-Erling Smørgrav }
20717b5038d7SDag-Erling Smørgrav 
20727b5038d7SDag-Erling Smørgrav void
ldns_key_list_free(ldns_key_list * key_list)20737b5038d7SDag-Erling Smørgrav ldns_key_list_free(ldns_key_list *key_list)
20747b5038d7SDag-Erling Smørgrav {
20757b5038d7SDag-Erling Smørgrav 	size_t i;
20767b5038d7SDag-Erling Smørgrav 	for (i = 0; i < ldns_key_list_key_count(key_list); i++) {
20777b5038d7SDag-Erling Smørgrav 		ldns_key_deep_free(ldns_key_list_key(key_list, i));
20787b5038d7SDag-Erling Smørgrav 	}
20797b5038d7SDag-Erling Smørgrav 	LDNS_FREE(key_list->_keys);
20807b5038d7SDag-Erling Smørgrav 	LDNS_FREE(key_list);
20817b5038d7SDag-Erling Smørgrav }
20827b5038d7SDag-Erling Smørgrav 
20837b5038d7SDag-Erling Smørgrav ldns_rr *
ldns_read_anchor_file(const char * filename)20847b5038d7SDag-Erling Smørgrav ldns_read_anchor_file(const char *filename)
20857b5038d7SDag-Erling Smørgrav {
20867b5038d7SDag-Erling Smørgrav 	FILE *fp;
20877b5038d7SDag-Erling Smørgrav 	/*char line[LDNS_MAX_PACKETLEN];*/
20887b5038d7SDag-Erling Smørgrav 	char *line = LDNS_XMALLOC(char, LDNS_MAX_PACKETLEN);
20897b5038d7SDag-Erling Smørgrav 	int c;
20907b5038d7SDag-Erling Smørgrav 	size_t i = 0;
20917b5038d7SDag-Erling Smørgrav 	ldns_rr *r;
20927b5038d7SDag-Erling Smørgrav 	ldns_status status;
20937b5038d7SDag-Erling Smørgrav         if(!line) {
20947b5038d7SDag-Erling Smørgrav                 return NULL;
20957b5038d7SDag-Erling Smørgrav         }
20967b5038d7SDag-Erling Smørgrav 
20977b5038d7SDag-Erling Smørgrav 	fp = fopen(filename, "r");
20987b5038d7SDag-Erling Smørgrav 	if (!fp) {
209917d15b25SDag-Erling Smørgrav #ifdef STDERR_MSGS
21007b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
210117d15b25SDag-Erling Smørgrav #endif
21027b5038d7SDag-Erling Smørgrav 		LDNS_FREE(line);
21037b5038d7SDag-Erling Smørgrav 		return NULL;
21047b5038d7SDag-Erling Smørgrav 	}
21057b5038d7SDag-Erling Smørgrav 
21067b5038d7SDag-Erling Smørgrav 	while ((c = fgetc(fp)) && i+1 < LDNS_MAX_PACKETLEN && c != EOF) {
21077b5038d7SDag-Erling Smørgrav 		line[i] = c;
21087b5038d7SDag-Erling Smørgrav 		i++;
21097b5038d7SDag-Erling Smørgrav 	}
21107b5038d7SDag-Erling Smørgrav 	line[i] = '\0';
21117b5038d7SDag-Erling Smørgrav 
21127b5038d7SDag-Erling Smørgrav 	fclose(fp);
21137b5038d7SDag-Erling Smørgrav 
21147b5038d7SDag-Erling Smørgrav 	if (i <= 0) {
211517d15b25SDag-Erling Smørgrav #ifdef STDERR_MSGS
21167b5038d7SDag-Erling Smørgrav 		fprintf(stderr, "nothing read from %s", filename);
211717d15b25SDag-Erling Smørgrav #endif
21187b5038d7SDag-Erling Smørgrav 		LDNS_FREE(line);
21197b5038d7SDag-Erling Smørgrav 		return NULL;
21207b5038d7SDag-Erling Smørgrav 	} else {
21217b5038d7SDag-Erling Smørgrav 		status = ldns_rr_new_frm_str(&r, line, 0, NULL, NULL);
21227b5038d7SDag-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)) {
21237b5038d7SDag-Erling Smørgrav 			LDNS_FREE(line);
21247b5038d7SDag-Erling Smørgrav 			return r;
21257b5038d7SDag-Erling Smørgrav 		} else {
212617d15b25SDag-Erling Smørgrav #ifdef STDERR_MSGS
21277b5038d7SDag-Erling Smørgrav 			fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status));
212817d15b25SDag-Erling Smørgrav #endif
21297b5038d7SDag-Erling Smørgrav 			LDNS_FREE(line);
21307b5038d7SDag-Erling Smørgrav 			return NULL;
21317b5038d7SDag-Erling Smørgrav 		}
21327b5038d7SDag-Erling Smørgrav 	}
21337b5038d7SDag-Erling Smørgrav }
21347b5038d7SDag-Erling Smørgrav 
21357b5038d7SDag-Erling Smørgrav char *
ldns_key_get_file_base_name(const ldns_key * key)2136986ba33cSDag-Erling Smørgrav ldns_key_get_file_base_name(const ldns_key *key)
21377b5038d7SDag-Erling Smørgrav {
21387b5038d7SDag-Erling Smørgrav 	ldns_buffer *buffer;
21397b5038d7SDag-Erling Smørgrav 	char *file_base_name;
21407b5038d7SDag-Erling Smørgrav 
21417b5038d7SDag-Erling Smørgrav 	buffer = ldns_buffer_new(255);
21427b5038d7SDag-Erling Smørgrav 	ldns_buffer_printf(buffer, "K");
21437b5038d7SDag-Erling Smørgrav 	(void)ldns_rdf2buffer_str_dname(buffer, ldns_key_pubkey_owner(key));
21447b5038d7SDag-Erling Smørgrav 	ldns_buffer_printf(buffer,
21457b5038d7SDag-Erling Smørgrav 	                   "+%03u+%05u",
21467b5038d7SDag-Erling Smørgrav 			   ldns_key_algorithm(key),
21477b5038d7SDag-Erling Smørgrav 			   ldns_key_keytag(key));
21482787e39aSDag-Erling Smørgrav 	file_base_name = ldns_buffer_export(buffer);
21497b5038d7SDag-Erling Smørgrav 	ldns_buffer_free(buffer);
21507b5038d7SDag-Erling Smørgrav 	return file_base_name;
21517b5038d7SDag-Erling Smørgrav }
21527b5038d7SDag-Erling Smørgrav 
ldns_key_algo_supported(int algo)21537b5038d7SDag-Erling Smørgrav int ldns_key_algo_supported(int algo)
21547b5038d7SDag-Erling Smørgrav {
21557b5038d7SDag-Erling Smørgrav 	ldns_lookup_table *lt = ldns_signing_algorithms;
21567b5038d7SDag-Erling Smørgrav 	while(lt->name) {
21577b5038d7SDag-Erling Smørgrav 		if(lt->id == algo)
21587b5038d7SDag-Erling Smørgrav 			return 1;
21597b5038d7SDag-Erling Smørgrav 		lt++;
21607b5038d7SDag-Erling Smørgrav 	}
21617b5038d7SDag-Erling Smørgrav 	return 0;
21627b5038d7SDag-Erling Smørgrav }
21637b5038d7SDag-Erling Smørgrav 
ldns_get_signing_algorithm_by_name(const char * name)21647b5038d7SDag-Erling Smørgrav ldns_signing_algorithm ldns_get_signing_algorithm_by_name(const char* name)
21657b5038d7SDag-Erling Smørgrav {
21667b5038d7SDag-Erling Smørgrav         /* list of (signing algorithm id, alias_name) */
21677b5038d7SDag-Erling Smørgrav         ldns_lookup_table aliases[] = {
21687b5038d7SDag-Erling Smørgrav                 /* from bind dnssec-keygen */
21697b5038d7SDag-Erling Smørgrav                 {LDNS_SIGN_HMACMD5, "HMAC-MD5"},
2170*5afab0e5SDag-Erling Smørgrav #ifdef USE_DSA
21717b5038d7SDag-Erling Smørgrav                 {LDNS_SIGN_DSA_NSEC3, "NSEC3DSA"},
2172*5afab0e5SDag-Erling Smørgrav #endif /* USE_DSA */
21737b5038d7SDag-Erling Smørgrav                 {LDNS_SIGN_RSASHA1_NSEC3, "NSEC3RSASHA1"},
21747b5038d7SDag-Erling Smørgrav                 /* old ldns usage, now RFC names */
2175986ba33cSDag-Erling Smørgrav #ifdef USE_DSA
21767b5038d7SDag-Erling Smørgrav                 {LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" },
2177986ba33cSDag-Erling Smørgrav #endif
21787b5038d7SDag-Erling Smørgrav                 {LDNS_SIGN_RSASHA1_NSEC3, "RSASHA1_NSEC3" },
21797b5038d7SDag-Erling Smørgrav #ifdef USE_GOST
21807b5038d7SDag-Erling Smørgrav                 {LDNS_SIGN_ECC_GOST, "GOST"},
21817b5038d7SDag-Erling Smørgrav #endif
21827b5038d7SDag-Erling Smørgrav                 /* compat with possible output */
21837b5038d7SDag-Erling Smørgrav                 {LDNS_DH, "DH"},
21847b5038d7SDag-Erling Smørgrav                 {LDNS_ECC, "ECC"},
21857b5038d7SDag-Erling Smørgrav                 {LDNS_INDIRECT, "INDIRECT"},
21867b5038d7SDag-Erling Smørgrav                 {LDNS_PRIVATEDNS, "PRIVATEDNS"},
21877b5038d7SDag-Erling Smørgrav                 {LDNS_PRIVATEOID, "PRIVATEOID"},
21887b5038d7SDag-Erling Smørgrav                 {0, NULL}};
21897b5038d7SDag-Erling Smørgrav         ldns_lookup_table* lt = ldns_signing_algorithms;
2190986ba33cSDag-Erling Smørgrav 	ldns_signing_algorithm a;
2191986ba33cSDag-Erling Smørgrav 	char *endptr;
2192986ba33cSDag-Erling Smørgrav 
21937b5038d7SDag-Erling Smørgrav         while(lt->name) {
21947b5038d7SDag-Erling Smørgrav                 if(strcasecmp(lt->name, name) == 0)
21957b5038d7SDag-Erling Smørgrav                         return lt->id;
21967b5038d7SDag-Erling Smørgrav                 lt++;
21977b5038d7SDag-Erling Smørgrav         }
21987b5038d7SDag-Erling Smørgrav         lt = aliases;
21997b5038d7SDag-Erling Smørgrav         while(lt->name) {
22007b5038d7SDag-Erling Smørgrav                 if(strcasecmp(lt->name, name) == 0)
22017b5038d7SDag-Erling Smørgrav                         return lt->id;
22027b5038d7SDag-Erling Smørgrav                 lt++;
22037b5038d7SDag-Erling Smørgrav         }
2204986ba33cSDag-Erling Smørgrav 	a = strtol(name, &endptr, 10);
2205986ba33cSDag-Erling Smørgrav 	if (*name && !*endptr)
2206986ba33cSDag-Erling Smørgrav 		return a;
2207986ba33cSDag-Erling Smørgrav 
22087b5038d7SDag-Erling Smørgrav         return 0;
22097b5038d7SDag-Erling Smørgrav }
2210