keyraw.c revision 356345
1/*
2 * keyraw.c - raw key operations and conversions
3 *
4 * (c) NLnet Labs, 2004-2008
5 *
6 * See the file LICENSE for the license
7 */
8/**
9 * \file
10 * Implementation of raw DNSKEY functions (work on wire rdata).
11 */
12
13#include "config.h"
14#include "sldns/keyraw.h"
15#include "sldns/rrdef.h"
16
17#ifdef HAVE_SSL
18#include <openssl/ssl.h>
19#include <openssl/evp.h>
20#include <openssl/rand.h>
21#include <openssl/err.h>
22#include <openssl/md5.h>
23#ifdef HAVE_OPENSSL_ENGINE_H
24#  include <openssl/engine.h>
25#endif
26#ifdef HAVE_OPENSSL_BN_H
27#include <openssl/bn.h>
28#endif
29#ifdef HAVE_OPENSSL_RSA_H
30#include <openssl/rsa.h>
31#endif
32#ifdef HAVE_OPENSSL_DSA_H
33#include <openssl/dsa.h>
34#endif
35#endif /* HAVE_SSL */
36
37size_t
38sldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
39	const size_t len, int alg)
40{
41	/* for DSA keys */
42	uint8_t t;
43
44	/* for RSA keys */
45	uint16_t exp;
46	uint16_t int16;
47
48	switch ((sldns_algorithm)alg) {
49	case LDNS_DSA:
50	case LDNS_DSA_NSEC3:
51		if (len > 0) {
52			t = keydata[0];
53			return (64 + t*8)*8;
54		} else {
55			return 0;
56		}
57		break;
58	case LDNS_RSAMD5:
59	case LDNS_RSASHA1:
60	case LDNS_RSASHA1_NSEC3:
61#ifdef USE_SHA2
62	case LDNS_RSASHA256:
63	case LDNS_RSASHA512:
64#endif
65		if (len > 0) {
66			if (keydata[0] == 0) {
67				/* big exponent */
68				if (len > 3) {
69					memmove(&int16, keydata + 1, 2);
70					exp = ntohs(int16);
71					return (len - exp - 3)*8;
72				} else {
73					return 0;
74				}
75			} else {
76				exp = keydata[0];
77				return (len-exp-1)*8;
78			}
79		} else {
80			return 0;
81		}
82		break;
83#ifdef USE_GOST
84	case LDNS_ECC_GOST:
85		return 512;
86#endif
87#ifdef USE_ECDSA
88        case LDNS_ECDSAP256SHA256:
89                return 256;
90        case LDNS_ECDSAP384SHA384:
91                return 384;
92#endif
93#ifdef USE_ED25519
94	case LDNS_ED25519:
95		return 256;
96#endif
97#ifdef USE_ED448
98	case LDNS_ED448:
99		return 456;
100#endif
101	default:
102		return 0;
103	}
104}
105
106uint16_t sldns_calc_keytag_raw(uint8_t* key, size_t keysize)
107{
108	if(keysize < 4) {
109		return 0;
110	}
111	/* look at the algorithm field, copied from 2535bis */
112	if (key[3] == LDNS_RSAMD5) {
113		uint16_t ac16 = 0;
114		if (keysize > 4) {
115			memmove(&ac16, key + keysize - 3, 2);
116		}
117		ac16 = ntohs(ac16);
118		return (uint16_t) ac16;
119	} else {
120		size_t i;
121		uint32_t ac32 = 0;
122		for (i = 0; i < keysize; ++i) {
123			ac32 += (i & 1) ? key[i] : key[i] << 8;
124		}
125		ac32 += (ac32 >> 16) & 0xFFFF;
126		return (uint16_t) (ac32 & 0xFFFF);
127	}
128}
129
130#ifdef HAVE_SSL
131#ifdef USE_GOST
132/** store GOST engine reference loaded into OpenSSL library */
133ENGINE* sldns_gost_engine = NULL;
134
135int
136sldns_key_EVP_load_gost_id(void)
137{
138	static int gost_id = 0;
139	const EVP_PKEY_ASN1_METHOD* meth;
140	ENGINE* e;
141
142	if(gost_id) return gost_id;
143
144	/* see if configuration loaded gost implementation from other engine*/
145	meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
146	if(meth) {
147		EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
148		return gost_id;
149	}
150
151	/* see if engine can be loaded already */
152	e = ENGINE_by_id("gost");
153	if(!e) {
154		/* load it ourself, in case statically linked */
155		ENGINE_load_builtin_engines();
156		ENGINE_load_dynamic();
157		e = ENGINE_by_id("gost");
158	}
159	if(!e) {
160		/* no gost engine in openssl */
161		return 0;
162	}
163	if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
164		ENGINE_finish(e);
165		ENGINE_free(e);
166		return 0;
167	}
168
169	meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
170	if(!meth) {
171		/* algo not found */
172		ENGINE_finish(e);
173		ENGINE_free(e);
174		return 0;
175	}
176        /* Note: do not ENGINE_finish and ENGINE_free the acquired engine
177         * on some platforms this frees up the meth and unloads gost stuff */
178        sldns_gost_engine = e;
179
180	EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
181	return gost_id;
182}
183
184void sldns_key_EVP_unload_gost(void)
185{
186        if(sldns_gost_engine) {
187                ENGINE_finish(sldns_gost_engine);
188                ENGINE_free(sldns_gost_engine);
189                sldns_gost_engine = NULL;
190        }
191}
192#endif /* USE_GOST */
193
194DSA *
195sldns_key_buf2dsa_raw(unsigned char* key, size_t len)
196{
197	uint8_t T;
198	uint16_t length;
199	uint16_t offset;
200	DSA *dsa;
201	BIGNUM *Q; BIGNUM *P;
202	BIGNUM *G; BIGNUM *Y;
203
204	if(len == 0)
205		return NULL;
206	T = (uint8_t)key[0];
207	length = (64 + T * 8);
208	offset = 1;
209
210	if (T > 8) {
211		return NULL;
212	}
213	if(len < (size_t)1 + SHA_DIGEST_LENGTH + 3*length)
214		return NULL;
215
216	Q = BN_bin2bn(key+offset, SHA_DIGEST_LENGTH, NULL);
217	offset += SHA_DIGEST_LENGTH;
218
219	P = BN_bin2bn(key+offset, (int)length, NULL);
220	offset += length;
221
222	G = BN_bin2bn(key+offset, (int)length, NULL);
223	offset += length;
224
225	Y = BN_bin2bn(key+offset, (int)length, NULL);
226
227	/* create the key and set its properties */
228	if(!Q || !P || !G || !Y || !(dsa = DSA_new())) {
229		BN_free(Q);
230		BN_free(P);
231		BN_free(G);
232		BN_free(Y);
233		return NULL;
234	}
235#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
236#ifndef S_SPLINT_S
237	dsa->p = P;
238	dsa->q = Q;
239	dsa->g = G;
240	dsa->pub_key = Y;
241#endif /* splint */
242
243#else /* OPENSSL_VERSION_NUMBER */
244	if (!DSA_set0_pqg(dsa, P, Q, G)) {
245		/* QPG not yet attached, need to free */
246		BN_free(Q);
247		BN_free(P);
248		BN_free(G);
249
250		DSA_free(dsa);
251		BN_free(Y);
252		return NULL;
253	}
254	if (!DSA_set0_key(dsa, Y, NULL)) {
255		/* QPG attached, cleaned up by DSA_fre() */
256		DSA_free(dsa);
257		BN_free(Y);
258		return NULL;
259	}
260#endif
261
262	return dsa;
263}
264
265RSA *
266sldns_key_buf2rsa_raw(unsigned char* key, size_t len)
267{
268	uint16_t offset;
269	uint16_t exp;
270	uint16_t int16;
271	RSA *rsa;
272	BIGNUM *modulus;
273	BIGNUM *exponent;
274
275	if (len == 0)
276		return NULL;
277	if (key[0] == 0) {
278		if(len < 3)
279			return NULL;
280		memmove(&int16, key+1, 2);
281		exp = ntohs(int16);
282		offset = 3;
283	} else {
284		exp = key[0];
285		offset = 1;
286	}
287
288	/* key length at least one */
289	if(len < (size_t)offset + exp + 1)
290		return NULL;
291
292	/* Exponent */
293	exponent = BN_new();
294	if(!exponent) return NULL;
295	(void) BN_bin2bn(key+offset, (int)exp, exponent);
296	offset += exp;
297
298	/* Modulus */
299	modulus = BN_new();
300	if(!modulus) {
301		BN_free(exponent);
302		return NULL;
303	}
304	/* length of the buffer must match the key length! */
305	(void) BN_bin2bn(key+offset, (int)(len - offset), modulus);
306
307	rsa = RSA_new();
308	if(!rsa) {
309		BN_free(exponent);
310		BN_free(modulus);
311		return NULL;
312	}
313#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
314#ifndef S_SPLINT_S
315	rsa->n = modulus;
316	rsa->e = exponent;
317#endif /* splint */
318
319#else /* OPENSSL_VERSION_NUMBER */
320	if (!RSA_set0_key(rsa, modulus, exponent, NULL)) {
321		BN_free(exponent);
322		BN_free(modulus);
323		RSA_free(rsa);
324		return NULL;
325	}
326#endif
327
328	return rsa;
329}
330
331#ifdef USE_GOST
332EVP_PKEY*
333sldns_gost2pkey_raw(unsigned char* key, size_t keylen)
334{
335	/* prefix header for X509 encoding */
336	uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
337		0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
338		0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
339		0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
340	unsigned char encoded[37+64];
341	const unsigned char* pp;
342	if(keylen != 64) {
343		/* key wrong size */
344		return NULL;
345	}
346
347	/* create evp_key */
348	memmove(encoded, asn, 37);
349	memmove(encoded+37, key, 64);
350	pp = (unsigned char*)&encoded[0];
351
352	return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
353}
354#endif /* USE_GOST */
355
356#ifdef USE_ECDSA
357EVP_PKEY*
358sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo)
359{
360	unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */
361        const unsigned char* pp = buf;
362        EVP_PKEY *evp_key;
363        EC_KEY *ec;
364	/* check length, which uncompressed must be 2 bignums */
365        if(algo == LDNS_ECDSAP256SHA256) {
366		if(keylen != 2*256/8) return NULL;
367                ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
368        } else if(algo == LDNS_ECDSAP384SHA384) {
369		if(keylen != 2*384/8) return NULL;
370                ec = EC_KEY_new_by_curve_name(NID_secp384r1);
371        } else    ec = NULL;
372        if(!ec) return NULL;
373	if(keylen+1 > sizeof(buf)) { /* sanity check */
374                EC_KEY_free(ec);
375		return NULL;
376	}
377	/* prepend the 0x02 (from docs) (or actually 0x04 from implementation
378	 * of openssl) for uncompressed data */
379	buf[0] = POINT_CONVERSION_UNCOMPRESSED;
380	memmove(buf+1, key, keylen);
381        if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) {
382                EC_KEY_free(ec);
383                return NULL;
384        }
385        evp_key = EVP_PKEY_new();
386        if(!evp_key) {
387                EC_KEY_free(ec);
388                return NULL;
389        }
390        if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
391		EVP_PKEY_free(evp_key);
392		EC_KEY_free(ec);
393		return NULL;
394	}
395        return evp_key;
396}
397#endif /* USE_ECDSA */
398
399#ifdef USE_ED25519
400EVP_PKEY*
401sldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
402{
403	/* ASN1 for ED25519 is 302a300506032b6570032100 <32byteskey> */
404	uint8_t pre[] = {0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
405		0x70, 0x03, 0x21, 0x00};
406	int pre_len = 12;
407	uint8_t buf[256];
408	EVP_PKEY *evp_key;
409	/* pp gets modified by d2i() */
410	const unsigned char* pp = (unsigned char*)buf;
411	if(keylen != 32 || keylen + pre_len > sizeof(buf))
412		return NULL; /* wrong length */
413	memmove(buf, pre, pre_len);
414	memmove(buf+pre_len, key, keylen);
415	evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
416	return evp_key;
417}
418#endif /* USE_ED25519 */
419
420#ifdef USE_ED448
421EVP_PKEY*
422sldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
423{
424	/* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
425	uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
426		0x71, 0x03, 0x3a, 0x00};
427        int pre_len = 12;
428	uint8_t buf[256];
429        EVP_PKEY *evp_key;
430	/* pp gets modified by d2i() */
431        const unsigned char* pp = (unsigned char*)buf;
432	if(keylen != 57 || keylen + pre_len > sizeof(buf))
433		return NULL; /* wrong length */
434	memmove(buf, pre, pre_len);
435	memmove(buf+pre_len, key, keylen);
436	evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
437        return evp_key;
438}
439#endif /* USE_ED448 */
440
441int
442sldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
443	const EVP_MD* md)
444{
445	EVP_MD_CTX* ctx;
446	ctx = EVP_MD_CTX_create();
447	if(!ctx)
448		return 0;
449	if(!EVP_DigestInit_ex(ctx, md, NULL) ||
450		!EVP_DigestUpdate(ctx, data, len) ||
451		!EVP_DigestFinal_ex(ctx, dest, NULL)) {
452		EVP_MD_CTX_destroy(ctx);
453		return 0;
454	}
455	EVP_MD_CTX_destroy(ctx);
456	return 1;
457}
458#endif /* HAVE_SSL */
459