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