1/*	$NetBSD: crypto_openssl.c,v 1.19 2009/04/29 10:50:01 tteras Exp $	*/
2
3/* Id: crypto_openssl.c,v 1.47 2006/05/06 20:42:09 manubsd Exp */
4
5/*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "config.h"
35
36#include <sys/types.h>
37#include <sys/param.h>
38
39#include <stdlib.h>
40#include <stdio.h>
41#include <limits.h>
42#include <string.h>
43
44/* get openssl/ssleay version number */
45#include <openssl/opensslv.h>
46
47#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090602fL)
48#error OpenSSL version 0.9.6 or later required.
49#endif
50
51#include <openssl/pem.h>
52#include <openssl/evp.h>
53#include <openssl/x509.h>
54#include <openssl/x509v3.h>
55#include <openssl/x509_vfy.h>
56#include <openssl/bn.h>
57#include <openssl/dh.h>
58#include <openssl/md5.h>
59#include <openssl/sha.h>
60#include <openssl/hmac.h>
61#include <openssl/des.h>
62#include <openssl/crypto.h>
63#ifdef HAVE_OPENSSL_ENGINE_H
64#include <openssl/engine.h>
65#endif
66#include <openssl/blowfish.h>
67#include <openssl/cast.h>
68#include <openssl/err.h>
69#ifdef HAVE_OPENSSL_RC5_H
70#include <openssl/rc5.h>
71#endif
72#ifdef HAVE_OPENSSL_IDEA_H
73#include <openssl/idea.h>
74#endif
75#if defined(HAVE_OPENSSL_AES_H)
76#include <openssl/aes.h>
77#elif defined(HAVE_OPENSSL_RIJNDAEL_H)
78#include <openssl/rijndael.h>
79#else
80#include "crypto/rijndael/rijndael-api-fst.h"
81#endif
82#if defined(HAVE_OPENSSL_CAMELLIA_H)
83#include <openssl/camellia.h>
84#endif
85#ifdef WITH_SHA2
86#ifdef HAVE_OPENSSL_SHA2_H
87#include <openssl/sha2.h>
88#else
89#include "crypto/sha2/sha2.h"
90#endif
91#endif
92#include "plog.h"
93
94/* 0.9.7 stuff? */
95#if OPENSSL_VERSION_NUMBER < 0x0090700fL
96typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
97#else
98#define USE_NEW_DES_API
99#endif
100
101#define OpenSSL_BUG()	do { plog(LLV_ERROR, LOCATION, NULL, "OpenSSL function failed\n"); } while(0)
102
103#include "var.h"
104#include "misc.h"
105#include "vmbuf.h"
106#include "plog.h"
107#include "crypto_openssl.h"
108#include "debug.h"
109#include "gcmalloc.h"
110#include "isakmp.h"
111
112/*
113 * I hate to cast every parameter to des_xx into void *, but it is
114 * necessary for SSLeay/OpenSSL portability.  It sucks.
115 */
116
117static int cb_check_cert_local __P((int, X509_STORE_CTX *));
118static int cb_check_cert_remote __P((int, X509_STORE_CTX *));
119static X509 *mem2x509 __P((vchar_t *));
120
121static caddr_t eay_hmac_init __P((vchar_t *, const EVP_MD *));
122
123/* X509 Certificate */
124/*
125 * convert the string of the subject name into DER
126 * e.g. str = "C=JP, ST=Kanagawa";
127 */
128vchar_t *
129eay_str2asn1dn(str, len)
130	const char *str;
131	int len;
132{
133	X509_NAME *name;
134	char *buf, *dst;
135	char *field, *value;
136	int i;
137	vchar_t *ret = NULL;
138	caddr_t p;
139
140	if (len == -1)
141		len = strlen(str);
142
143	buf = racoon_malloc(len + 1);
144	if (!buf) {
145		plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n");
146		return NULL;
147	}
148	memcpy(buf, str, len);
149
150	name = X509_NAME_new();
151
152	dst = field = &buf[0];
153	value = NULL;
154	for (i = 0; i < len; i++) {
155		if (buf[i] == '\\') {
156			/* Escape characters specified in RFC 2253 */
157			if (i < len - 1 &&
158			    strchr("\\,=+<>#;", buf[i+1]) != NULL) {
159				*dst++ = buf[++i];
160				continue;
161			} else if (i < len - 2) {
162				/* RFC 2253 hexpair character escape */
163				long u;
164				char esc_str[3];
165				char *endptr;
166
167				esc_str[0] = buf[++i];
168				esc_str[1] = buf[++i];
169				esc_str[2] = '\0';
170				u = strtol(esc_str, &endptr, 16);
171				if (*endptr != '\0' || u < 0 || u > 255)
172					goto err;
173				*dst++ = u;
174				continue;
175			} else
176				goto err;
177		}
178		if (!value && buf[i] == '=') {
179			*dst = '\0';
180			dst = value = &buf[i + 1];
181			continue;
182		} else if (buf[i] == ',' || buf[i] == '/') {
183			*dst = '\0';
184
185			plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n",
186			     field, value);
187
188			if (!value) goto err;
189			if (!X509_NAME_add_entry_by_txt(name, field,
190					(value[0] == '*' && value[1] == 0) ?
191						V_ASN1_PRINTABLESTRING : MBSTRING_ASC,
192					(unsigned char *) value, -1, -1, 0)) {
193				plog(LLV_ERROR, LOCATION, NULL,
194				     "Invalid DN field: %s=%s\n",
195				     field, value);
196				plog(LLV_ERROR, LOCATION, NULL,
197				     "%s\n", eay_strerror());
198				goto err;
199			}
200
201			while (i + 1 < len && buf[i + 1] == ' ') i++;
202			dst = field = &buf[i + 1];
203			value = NULL;
204			continue;
205		} else {
206			*dst++  = buf[i];
207		}
208	}
209	*dst = '\0';
210
211	plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n",
212	     field, value);
213
214	if (!value) goto err;
215	if (!X509_NAME_add_entry_by_txt(name, field,
216			(value[0] == '*' && value[1] == 0) ?
217				V_ASN1_PRINTABLESTRING : MBSTRING_ASC,
218			(unsigned char *) value, -1, -1, 0)) {
219		plog(LLV_ERROR, LOCATION, NULL,
220		     "Invalid DN field: %s=%s\n",
221		     field, value);
222		plog(LLV_ERROR, LOCATION, NULL,
223		     "%s\n", eay_strerror());
224		goto err;
225	}
226
227	i = i2d_X509_NAME(name, NULL);
228	if (!i)
229		goto err;
230	ret = vmalloc(i);
231	if (!ret)
232		goto err;
233	p = ret->v;
234	i = i2d_X509_NAME(name, (void *)&p);
235	if (!i)
236		goto err;
237
238	return ret;
239
240    err:
241	if (buf)
242		racoon_free(buf);
243	if (name)
244		X509_NAME_free(name);
245	if (ret)
246		vfree(ret);
247	return NULL;
248}
249
250/*
251 * convert the hex string of the subject name into DER
252 */
253vchar_t *
254eay_hex2asn1dn(const char *hex, int len)
255{
256	BIGNUM *bn = BN_new();
257	char *binbuf;
258	size_t binlen;
259	vchar_t *ret = NULL;
260
261	if (len == -1)
262		len = strlen(hex);
263
264	if (BN_hex2bn(&bn, hex) != len) {
265		plog(LLV_ERROR, LOCATION, NULL,
266		     "conversion of Hex-encoded ASN1 string to binary failed: %s\n",
267		     eay_strerror());
268		goto out;
269	}
270
271	binlen = BN_num_bytes(bn);
272	ret = vmalloc(binlen);
273	if (!ret) {
274		plog(LLV_WARNING, LOCATION, NULL,"failed to allocate buffer\n");
275		return NULL;
276	}
277	binbuf = ret->v;
278
279	BN_bn2bin(bn, (unsigned char *) binbuf);
280
281out:
282	BN_free(bn);
283
284	return ret;
285}
286
287/*
288 * The following are derived from code in crypto/x509/x509_cmp.c
289 * in OpenSSL0.9.7c:
290 * X509_NAME_wildcmp() adds wildcard matching to the original
291 * X509_NAME_cmp(), nocase_cmp() and nocase_spacenorm_cmp() are as is.
292 */
293#include <ctype.h>
294/* Case insensitive string comparision */
295static int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
296{
297	int i;
298
299	if (a->length != b->length)
300		return (a->length - b->length);
301
302	for (i=0; i<a->length; i++)
303	{
304		int ca, cb;
305
306		ca = tolower(a->data[i]);
307		cb = tolower(b->data[i]);
308
309		if (ca != cb)
310			return(ca-cb);
311	}
312	return 0;
313}
314
315/* Case insensitive string comparision with space normalization
316 * Space normalization - ignore leading, trailing spaces,
317 *       multiple spaces between characters are replaced by single space
318 */
319static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
320{
321	unsigned char *pa = NULL, *pb = NULL;
322	int la, lb;
323
324	la = a->length;
325	lb = b->length;
326	pa = a->data;
327	pb = b->data;
328
329	/* skip leading spaces */
330	while (la > 0 && isspace(*pa))
331	{
332		la--;
333		pa++;
334	}
335	while (lb > 0 && isspace(*pb))
336	{
337		lb--;
338		pb++;
339	}
340
341	/* skip trailing spaces */
342	while (la > 0 && isspace(pa[la-1]))
343		la--;
344	while (lb > 0 && isspace(pb[lb-1]))
345		lb--;
346
347	/* compare strings with space normalization */
348	while (la > 0 && lb > 0)
349	{
350		int ca, cb;
351
352		/* compare character */
353		ca = tolower(*pa);
354		cb = tolower(*pb);
355		if (ca != cb)
356			return (ca - cb);
357
358		pa++; pb++;
359		la--; lb--;
360
361		if (la <= 0 || lb <= 0)
362			break;
363
364		/* is white space next character ? */
365		if (isspace(*pa) && isspace(*pb))
366		{
367			/* skip remaining white spaces */
368			while (la > 0 && isspace(*pa))
369			{
370				la--;
371				pa++;
372			}
373			while (lb > 0 && isspace(*pb))
374			{
375				lb--;
376				pb++;
377			}
378		}
379	}
380	if (la > 0 || lb > 0)
381		return la - lb;
382
383	return 0;
384}
385
386static int X509_NAME_wildcmp(const X509_NAME *a, const X509_NAME *b)
387{
388    int i,j;
389    X509_NAME_ENTRY *na,*nb;
390
391    if (sk_X509_NAME_ENTRY_num(a->entries)
392	!= sk_X509_NAME_ENTRY_num(b->entries))
393	    return sk_X509_NAME_ENTRY_num(a->entries)
394	      -sk_X509_NAME_ENTRY_num(b->entries);
395    for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
396    {
397	    na=sk_X509_NAME_ENTRY_value(a->entries,i);
398	    nb=sk_X509_NAME_ENTRY_value(b->entries,i);
399	    j=OBJ_cmp(na->object,nb->object);
400	    if (j) return(j);
401	    if ((na->value->length == 1 && na->value->data[0] == '*')
402	     || (nb->value->length == 1 && nb->value->data[0] == '*'))
403		    continue;
404	    j=na->value->type-nb->value->type;
405	    if (j) return(j);
406	    if (na->value->type == V_ASN1_PRINTABLESTRING)
407		    j=nocase_spacenorm_cmp(na->value, nb->value);
408	    else if (na->value->type == V_ASN1_IA5STRING
409		    && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress)
410		    j=nocase_cmp(na->value, nb->value);
411	    else
412		    {
413		    j=na->value->length-nb->value->length;
414		    if (j) return(j);
415		    j=memcmp(na->value->data,nb->value->data,
416			    na->value->length);
417		    }
418	    if (j) return(j);
419	    j=na->set-nb->set;
420	    if (j) return(j);
421    }
422
423    return(0);
424}
425
426/*
427 * compare two subjectNames.
428 * OUT:        0: equal
429 *	positive:
430 *	      -1: other error.
431 */
432int
433eay_cmp_asn1dn(n1, n2)
434	vchar_t *n1, *n2;
435{
436	X509_NAME *a = NULL, *b = NULL;
437	caddr_t p;
438	int i = -1;
439
440	p = n1->v;
441	if (!d2i_X509_NAME(&a, (void *)&p, n1->l))
442		goto end;
443	p = n2->v;
444	if (!d2i_X509_NAME(&b, (void *)&p, n2->l))
445		goto end;
446
447	i = X509_NAME_wildcmp(a, b);
448
449    end:
450	if (a)
451		X509_NAME_free(a);
452	if (b)
453		X509_NAME_free(b);
454	return i;
455}
456
457/*
458 * this functions is derived from apps/verify.c in OpenSSL0.9.5
459 */
460int
461eay_check_x509cert(cert, CApath, CAfile, local)
462	vchar_t *cert;
463	char *CApath;
464	char *CAfile;
465	int local;
466{
467	X509_STORE *cert_ctx = NULL;
468	X509_LOOKUP *lookup = NULL;
469	X509 *x509 = NULL;
470	X509_STORE_CTX *csc;
471	int error = -1;
472
473	cert_ctx = X509_STORE_new();
474	if (cert_ctx == NULL)
475		goto end;
476
477	if (local)
478		X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_local);
479	else
480		X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_remote);
481
482	lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
483	if (lookup == NULL)
484		goto end;
485
486	X509_LOOKUP_load_file(lookup, CAfile,
487	    (CAfile == NULL) ? X509_FILETYPE_DEFAULT : X509_FILETYPE_PEM);
488
489	lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
490	if (lookup == NULL)
491		goto end;
492	error = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM);
493	if(!error) {
494		error = -1;
495		goto end;
496	}
497	error = -1;	/* initialized */
498
499	/* read the certificate to be verified */
500	x509 = mem2x509(cert);
501	if (x509 == NULL)
502		goto end;
503
504	csc = X509_STORE_CTX_new();
505	if (csc == NULL)
506		goto end;
507	X509_STORE_CTX_init(csc, cert_ctx, x509, NULL);
508#if OPENSSL_VERSION_NUMBER >= 0x00907000L
509	X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK);
510	X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK_ALL);
511#endif
512	error = X509_verify_cert(csc);
513	X509_STORE_CTX_free(csc);
514
515	/*
516	 * if x509_verify_cert() is successful then the value of error is
517	 * set non-zero.
518	 */
519	error = error ? 0 : -1;
520
521end:
522	if (error)
523		plog(LLV_WARNING, LOCATION, NULL,"%s\n", eay_strerror());
524	if (cert_ctx != NULL)
525		X509_STORE_free(cert_ctx);
526	if (x509 != NULL)
527		X509_free(x509);
528
529	return(error);
530}
531
532/*
533 * callback function for verifing certificate.
534 * this function is derived from cb() in openssl/apps/s_server.c
535 */
536static int
537cb_check_cert_local(ok, ctx)
538	int ok;
539	X509_STORE_CTX *ctx;
540{
541	char buf[256];
542	int log_tag;
543
544	if (!ok) {
545		X509_NAME_oneline(
546				X509_get_subject_name(ctx->current_cert),
547				buf,
548				256);
549		/*
550		 * since we are just checking the certificates, it is
551		 * ok if they are self signed. But we should still warn
552		 * the user.
553 		 */
554		switch (ctx->error) {
555		case X509_V_ERR_CERT_HAS_EXPIRED:
556		case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
557		case X509_V_ERR_INVALID_CA:
558		case X509_V_ERR_PATH_LENGTH_EXCEEDED:
559		case X509_V_ERR_INVALID_PURPOSE:
560		case X509_V_ERR_UNABLE_TO_GET_CRL:
561			ok = 1;
562			log_tag = LLV_WARNING;
563			break;
564		default:
565			log_tag = LLV_ERROR;
566		}
567		plog(log_tag, LOCATION, NULL,
568			"%s(%d) at depth:%d SubjectName:%s\n",
569			X509_verify_cert_error_string(ctx->error),
570			ctx->error,
571			ctx->error_depth,
572			buf);
573	}
574	ERR_clear_error();
575
576	return ok;
577}
578
579/*
580 * callback function for verifing remote certificates.
581 * this function is derived from cb() in openssl/apps/s_server.c
582 */
583static int
584cb_check_cert_remote(ok, ctx)
585	int ok;
586	X509_STORE_CTX *ctx;
587{
588	char buf[256];
589	int log_tag;
590
591	if (!ok) {
592		X509_NAME_oneline(
593				X509_get_subject_name(ctx->current_cert),
594				buf,
595				256);
596		switch (ctx->error) {
597		case X509_V_ERR_UNABLE_TO_GET_CRL:
598			ok = 1;
599			log_tag = LLV_WARNING;
600			break;
601		default:
602			log_tag = LLV_ERROR;
603		}
604		plog(log_tag, LOCATION, NULL,
605			"%s(%d) at depth:%d SubjectName:%s\n",
606			X509_verify_cert_error_string(ctx->error),
607			ctx->error,
608			ctx->error_depth,
609			buf);
610	}
611	ERR_clear_error();
612
613	return ok;
614}
615
616/*
617 * get a subjectName from X509 certificate.
618 */
619vchar_t *
620eay_get_x509asn1subjectname(cert)
621	vchar_t *cert;
622{
623	X509 *x509 = NULL;
624	u_char *bp;
625	vchar_t *name = NULL;
626	int len;
627
628	x509 = mem2x509(cert);
629	if (x509 == NULL)
630		goto error;
631
632	/* get the length of the name */
633	len = i2d_X509_NAME(x509->cert_info->subject, NULL);
634	name = vmalloc(len);
635	if (!name)
636		goto error;
637	/* get the name */
638	bp = (unsigned char *) name->v;
639	len = i2d_X509_NAME(x509->cert_info->subject, &bp);
640
641	X509_free(x509);
642
643	return name;
644
645error:
646	plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
647
648	if (name != NULL)
649		vfree(name);
650
651	if (x509 != NULL)
652		X509_free(x509);
653
654	return NULL;
655}
656
657/*
658 * get the subjectAltName from X509 certificate.
659 * the name must be terminated by '\0'.
660 */
661int
662eay_get_x509subjectaltname(cert, altname, type, pos)
663	vchar_t *cert;
664	char **altname;
665	int *type;
666	int pos;
667{
668	X509 *x509 = NULL;
669	GENERAL_NAMES *gens = NULL;
670	GENERAL_NAME *gen;
671	int len;
672	int error = -1;
673
674	*altname = NULL;
675	*type = GENT_OTHERNAME;
676
677	x509 = mem2x509(cert);
678	if (x509 == NULL)
679		goto end;
680
681	gens = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
682	if (gens == NULL)
683		goto end;
684
685	/* there is no data at "pos" */
686	if (pos > sk_GENERAL_NAME_num(gens))
687		goto end;
688
689	gen = sk_GENERAL_NAME_value(gens, pos - 1);
690
691	/* read DNSName / Email */
692	if (gen->type == GEN_DNS	||
693		gen->type == GEN_EMAIL	||
694		gen->type == GEN_URI )
695	{
696		/* make sure if the data is terminated by '\0'. */
697		if (gen->d.ia5->data[gen->d.ia5->length] != '\0')
698		{
699			plog(LLV_ERROR, LOCATION, NULL,
700				 "data is not terminated by NUL.");
701			racoon_hexdump(gen->d.ia5->data, gen->d.ia5->length + 1);
702			goto end;
703		}
704
705		len = gen->d.ia5->length + 1;
706		*altname = racoon_malloc(len);
707		if (!*altname)
708			goto end;
709
710		strlcpy(*altname, (char *) gen->d.ia5->data, len);
711		*type = gen->type;
712		error = 0;
713	}
714	/* read IP address */
715	else if (gen->type == GEN_IPADD)
716	{
717		unsigned char p[5], *ip;
718		ip = p;
719
720		/* only support IPv4 */
721		if (gen->d.ip->length != 4)
722			goto end;
723
724		/* convert Octet String to String
725		 * XXX ???????
726		 */
727		/*i2d_ASN1_OCTET_STRING(gen->d.ip,&ip);*/
728		ip = gen->d.ip->data;
729
730		/* XXX Magic, enough for an IPv4 address
731		 */
732		*altname = racoon_malloc(20);
733		if (!*altname)
734			goto end;
735
736		sprintf(*altname, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
737		*type = gen->type;
738		error = 0;
739	}
740	/* XXX other possible types ?
741	 * For now, error will be -1 if unsupported type
742	 */
743
744end:
745	if (error) {
746		if (*altname) {
747			racoon_free(*altname);
748			*altname = NULL;
749		}
750		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
751	}
752	if (x509)
753		X509_free(x509);
754	if (gens)
755		/* free the whole stack. */
756		sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
757
758	return error;
759}
760
761/*
762 * get a issuerName from X509 certificate.
763 */
764vchar_t *
765eay_get_x509asn1issuername(cert)
766	vchar_t *cert;
767{
768	X509 *x509 = NULL;
769	u_char *bp;
770	vchar_t *name = NULL;
771	int len;
772
773	x509 = mem2x509(cert);
774	if (x509 == NULL)
775		goto error;
776
777	/* get the length of the name */
778	len = i2d_X509_NAME(x509->cert_info->issuer, NULL);
779	name = vmalloc(len);
780	if (name == NULL)
781		goto error;
782
783	/* get the name */
784	bp = (unsigned char *) name->v;
785	len = i2d_X509_NAME(x509->cert_info->issuer, &bp);
786
787	X509_free(x509);
788
789	return name;
790
791error:
792	plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
793
794	if (name != NULL)
795		vfree(name);
796	if (x509 != NULL)
797		X509_free(x509);
798
799	return NULL;
800}
801
802/*
803 * decode a X509 certificate and make a readable text terminated '\n'.
804 * return the buffer allocated, so must free it later.
805 */
806char *
807eay_get_x509text(cert)
808	vchar_t *cert;
809{
810	X509 *x509 = NULL;
811	BIO *bio = NULL;
812	char *text = NULL;
813	u_char *bp = NULL;
814	int len = 0;
815	int error = -1;
816
817	x509 = mem2x509(cert);
818	if (x509 == NULL)
819		goto end;
820
821	bio = BIO_new(BIO_s_mem());
822	if (bio == NULL)
823		goto end;
824
825	error = X509_print(bio, x509);
826	if (error != 1) {
827		error = -1;
828		goto end;
829	}
830
831	len = BIO_get_mem_data(bio, &bp);
832	text = racoon_malloc(len + 1);
833	if (text == NULL)
834		goto end;
835	memcpy(text, bp, len);
836	text[len] = '\0';
837
838	error = 0;
839
840    end:
841	if (error) {
842		if (text) {
843			racoon_free(text);
844			text = NULL;
845		}
846		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
847	}
848	if (bio)
849		BIO_free(bio);
850	if (x509)
851		X509_free(x509);
852
853	return text;
854}
855
856/* get X509 structure from buffer. */
857static X509 *
858mem2x509(cert)
859	vchar_t *cert;
860{
861	X509 *x509;
862
863#ifndef EAYDEBUG
864    {
865	u_char *bp;
866
867	bp = (unsigned char *) cert->v + 1;
868
869	x509 = d2i_X509(NULL, (void *)&bp, cert->l - 1);
870    }
871#else
872    {
873	BIO *bio;
874	int len;
875
876	bio = BIO_new(BIO_s_mem());
877	if (bio == NULL)
878		return NULL;
879	len = BIO_write(bio, cert->v + 1, cert->l - 1);
880	if (len == -1)
881		return NULL;
882	x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
883	BIO_free(bio);
884    }
885#endif
886	return x509;
887}
888
889/*
890 * get a X509 certificate from local file.
891 * a certificate must be PEM format.
892 * Input:
893 *	path to a certificate.
894 * Output:
895 *	NULL if error occured
896 *	other is the cert.
897 */
898vchar_t *
899eay_get_x509cert(path)
900	char *path;
901{
902	FILE *fp;
903	X509 *x509;
904	vchar_t *cert;
905	u_char *bp;
906	int len;
907	int error;
908
909	/* Read private key */
910	fp = fopen(path, "r");
911	if (fp == NULL)
912		return NULL;
913	x509 = PEM_read_X509(fp, NULL, NULL, NULL);
914	fclose (fp);
915
916	if (x509 == NULL)
917		return NULL;
918
919	len = i2d_X509(x509, NULL);
920	cert = vmalloc(len + 1);
921	if (cert == NULL) {
922		X509_free(x509);
923		return NULL;
924	}
925	cert->v[0] = ISAKMP_CERT_X509SIGN;
926	bp = (unsigned char *) &cert->v[1];
927	error = i2d_X509(x509, &bp);
928	X509_free(x509);
929
930	if (error == 0) {
931		vfree(cert);
932		return NULL;
933	}
934
935	return cert;
936}
937
938/*
939 * check a X509 signature
940 *	XXX: to be get hash type from my cert ?
941 *		to be handled EVP_dss().
942 * OUT: return -1 when error.
943 *	0
944 */
945int
946eay_check_x509sign(source, sig, cert)
947	vchar_t *source;
948	vchar_t *sig;
949	vchar_t *cert;
950{
951	X509 *x509;
952	EVP_PKEY *evp;
953	int res;
954
955	x509 = mem2x509(cert);
956	if (x509 == NULL)
957		return -1;
958
959	evp = X509_get_pubkey(x509);
960	if (! evp) {
961		plog(LLV_ERROR, LOCATION, NULL, "X509_get_pubkey(): %s\n", eay_strerror());
962		X509_free(x509);
963		return -1;
964	}
965
966	res = eay_rsa_verify(source, sig, evp->pkey.rsa);
967
968	EVP_PKEY_free(evp);
969	X509_free(x509);
970
971	return res;
972}
973
974/*
975 * check RSA signature
976 * OUT: return -1 when error.
977 *	0 on success
978 */
979int
980eay_check_rsasign(source, sig, rsa)
981	vchar_t *source;
982	vchar_t *sig;
983	RSA *rsa;
984{
985	return eay_rsa_verify(source, sig, rsa);
986}
987
988/*
989 * get PKCS#1 Private Key of PEM format from local file.
990 */
991vchar_t *
992eay_get_pkcs1privkey(path)
993	char *path;
994{
995	FILE *fp;
996	EVP_PKEY *evp = NULL;
997	vchar_t *pkey = NULL;
998	u_char *bp;
999	int pkeylen;
1000	int error = -1;
1001
1002	/* Read private key */
1003	fp = fopen(path, "r");
1004	if (fp == NULL)
1005		return NULL;
1006
1007	evp = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
1008
1009	fclose (fp);
1010
1011	if (evp == NULL)
1012		return NULL;
1013
1014	pkeylen = i2d_PrivateKey(evp, NULL);
1015	if (pkeylen == 0)
1016		goto end;
1017	pkey = vmalloc(pkeylen);
1018	if (pkey == NULL)
1019		goto end;
1020	bp = (unsigned char *) pkey->v;
1021	pkeylen = i2d_PrivateKey(evp, &bp);
1022	if (pkeylen == 0)
1023		goto end;
1024
1025	error = 0;
1026
1027end:
1028	if (evp != NULL)
1029		EVP_PKEY_free(evp);
1030	if (error != 0 && pkey != NULL) {
1031		vfree(pkey);
1032		pkey = NULL;
1033	}
1034
1035	return pkey;
1036}
1037
1038/*
1039 * get PKCS#1 Public Key of PEM format from local file.
1040 */
1041vchar_t *
1042eay_get_pkcs1pubkey(path)
1043	char *path;
1044{
1045	FILE *fp;
1046	EVP_PKEY *evp = NULL;
1047	vchar_t *pkey = NULL;
1048	X509 *x509 = NULL;
1049	u_char *bp;
1050	int pkeylen;
1051	int error = -1;
1052
1053	/* Read private key */
1054	fp = fopen(path, "r");
1055	if (fp == NULL)
1056		return NULL;
1057
1058	x509 = PEM_read_X509(fp, NULL, NULL, NULL);
1059
1060	fclose (fp);
1061
1062	if (x509 == NULL)
1063		return NULL;
1064
1065	/* Get public key - eay */
1066	evp = X509_get_pubkey(x509);
1067	if (evp == NULL)
1068		return NULL;
1069
1070	pkeylen = i2d_PublicKey(evp, NULL);
1071	if (pkeylen == 0)
1072		goto end;
1073	pkey = vmalloc(pkeylen);
1074	if (pkey == NULL)
1075		goto end;
1076	bp = (unsigned char *) pkey->v;
1077	pkeylen = i2d_PublicKey(evp, &bp);
1078	if (pkeylen == 0)
1079		goto end;
1080
1081	error = 0;
1082end:
1083	if (evp != NULL)
1084		EVP_PKEY_free(evp);
1085	if (error != 0 && pkey != NULL) {
1086		vfree(pkey);
1087		pkey = NULL;
1088	}
1089
1090	return pkey;
1091}
1092
1093vchar_t *
1094eay_get_x509sign(src, privkey)
1095	vchar_t *src, *privkey;
1096{
1097	EVP_PKEY *evp;
1098	u_char *bp = (unsigned char *) privkey->v;
1099	vchar_t *sig = NULL;
1100	int len;
1101	int pad = RSA_PKCS1_PADDING;
1102
1103	/* XXX to be handled EVP_PKEY_DSA */
1104	evp = d2i_PrivateKey(EVP_PKEY_RSA, NULL, (void *)&bp, privkey->l);
1105	if (evp == NULL)
1106		return NULL;
1107
1108	sig = eay_rsa_sign(src, evp->pkey.rsa);
1109
1110	EVP_PKEY_free(evp);
1111
1112	return sig;
1113}
1114
1115vchar_t *
1116eay_get_rsasign(src, rsa)
1117	vchar_t *src;
1118	RSA *rsa;
1119{
1120	return eay_rsa_sign(src, rsa);
1121}
1122
1123vchar_t *
1124eay_rsa_sign(vchar_t *src, RSA *rsa)
1125{
1126	int len;
1127	vchar_t *sig = NULL;
1128	int pad = RSA_PKCS1_PADDING;
1129
1130	len = RSA_size(rsa);
1131
1132	sig = vmalloc(len);
1133	if (sig == NULL)
1134		return NULL;
1135
1136	len = RSA_private_encrypt(src->l, (unsigned char *) src->v,
1137			(unsigned char *) sig->v, rsa, pad);
1138
1139	if (len == 0 || len != sig->l) {
1140		vfree(sig);
1141		sig = NULL;
1142	}
1143
1144	return sig;
1145}
1146
1147int
1148eay_rsa_verify(src, sig, rsa)
1149	vchar_t *src, *sig;
1150	RSA *rsa;
1151{
1152	vchar_t *xbuf = NULL;
1153	int pad = RSA_PKCS1_PADDING;
1154	int len = 0;
1155	int error;
1156
1157	len = RSA_size(rsa);
1158	xbuf = vmalloc(len);
1159	if (xbuf == NULL) {
1160		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
1161		return -1;
1162	}
1163
1164	len = RSA_public_decrypt(sig->l, (unsigned char *) sig->v,
1165			(unsigned char *) xbuf->v, rsa, pad);
1166	if (len == 0 || len != src->l) {
1167		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
1168		vfree(xbuf);
1169		return -1;
1170	}
1171
1172	error = memcmp(src->v, xbuf->v, src->l);
1173	vfree(xbuf);
1174	if (error != 0)
1175		return -1;
1176
1177	return 0;
1178}
1179
1180/*
1181 * get error string
1182 * MUST load ERR_load_crypto_strings() first.
1183 */
1184char *
1185eay_strerror()
1186{
1187	static char ebuf[512];
1188	int len = 0, n;
1189	unsigned long l;
1190	char buf[200];
1191	const char *file, *data;
1192	int line, flags;
1193	unsigned long es;
1194
1195	es = CRYPTO_thread_id();
1196
1197	while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0){
1198		n = snprintf(ebuf + len, sizeof(ebuf) - len,
1199				"%lu:%s:%s:%d:%s ",
1200				es, ERR_error_string(l, buf), file, line,
1201				(flags & ERR_TXT_STRING) ? data : "");
1202		if (n < 0 || n >= sizeof(ebuf) - len)
1203			break;
1204		len += n;
1205		if (sizeof(ebuf) < len)
1206			break;
1207	}
1208
1209	return ebuf;
1210}
1211
1212vchar_t *
1213evp_crypt(vchar_t *data, vchar_t *key, vchar_t *iv, const EVP_CIPHER *e, int enc)
1214{
1215	vchar_t *res;
1216	EVP_CIPHER_CTX ctx;
1217
1218	if (!e)
1219		return NULL;
1220
1221	if (data->l % EVP_CIPHER_block_size(e))
1222		return NULL;
1223
1224	if ((res = vmalloc(data->l)) == NULL)
1225		return NULL;
1226
1227	EVP_CIPHER_CTX_init(&ctx);
1228
1229	switch(EVP_CIPHER_nid(e)){
1230	case NID_bf_cbc:
1231	case NID_bf_ecb:
1232	case NID_bf_cfb64:
1233	case NID_bf_ofb64:
1234	case NID_cast5_cbc:
1235	case NID_cast5_ecb:
1236	case NID_cast5_cfb64:
1237	case NID_cast5_ofb64:
1238		/* XXX: can we do that also for algos with a fixed key size ?
1239		 */
1240		/* init context without key/iv
1241         */
1242        if (!EVP_CipherInit(&ctx, e, NULL, NULL, enc))
1243        {
1244            OpenSSL_BUG();
1245            vfree(res);
1246            return NULL;
1247        }
1248
1249        /* update key size
1250         */
1251        if (!EVP_CIPHER_CTX_set_key_length(&ctx, key->l))
1252        {
1253            OpenSSL_BUG();
1254            vfree(res);
1255            return NULL;
1256        }
1257
1258        /* finalize context init with desired key size
1259         */
1260        if (!EVP_CipherInit(&ctx, NULL, (u_char *) key->v,
1261							(u_char *) iv->v, enc))
1262        {
1263            OpenSSL_BUG();
1264            vfree(res);
1265            return NULL;
1266		}
1267		break;
1268	default:
1269		if (!EVP_CipherInit(&ctx, e, (u_char *) key->v,
1270							(u_char *) iv->v, enc)) {
1271			OpenSSL_BUG();
1272			vfree(res);
1273			return NULL;
1274		}
1275	}
1276
1277	/* disable openssl padding */
1278	EVP_CIPHER_CTX_set_padding(&ctx, 0);
1279
1280	if (!EVP_Cipher(&ctx, (u_char *) res->v, (u_char *) data->v, data->l)) {
1281		OpenSSL_BUG();
1282		vfree(res);
1283		return NULL;
1284	}
1285
1286	EVP_CIPHER_CTX_cleanup(&ctx);
1287
1288	return res;
1289}
1290
1291int
1292evp_weakkey(vchar_t *key, const EVP_CIPHER *e)
1293{
1294	return 0;
1295}
1296
1297int
1298evp_keylen(int len, const EVP_CIPHER *e)
1299{
1300	if (!e)
1301		return -1;
1302	/* EVP functions return lengths in bytes, ipsec-tools
1303	 * uses lengths in bits, therefore conversion is required. --AK
1304	 */
1305	if (len != 0 && len != (EVP_CIPHER_key_length(e) << 3))
1306		return -1;
1307
1308	return EVP_CIPHER_key_length(e) << 3;
1309}
1310
1311/*
1312 * DES-CBC
1313 */
1314vchar_t *
1315eay_des_encrypt(data, key, iv)
1316	vchar_t *data, *key, *iv;
1317{
1318	return evp_crypt(data, key, iv, EVP_des_cbc(), 1);
1319}
1320
1321vchar_t *
1322eay_des_decrypt(data, key, iv)
1323	vchar_t *data, *key, *iv;
1324{
1325	return evp_crypt(data, key, iv, EVP_des_cbc(), 0);
1326}
1327
1328int
1329eay_des_weakkey(key)
1330	vchar_t *key;
1331{
1332#ifdef USE_NEW_DES_API
1333	return DES_is_weak_key((void *)key->v);
1334#else
1335	return des_is_weak_key((void *)key->v);
1336#endif
1337}
1338
1339int
1340eay_des_keylen(len)
1341	int len;
1342{
1343	return evp_keylen(len, EVP_des_cbc());
1344}
1345
1346#ifdef HAVE_OPENSSL_IDEA_H
1347/*
1348 * IDEA-CBC
1349 */
1350vchar_t *
1351eay_idea_encrypt(data, key, iv)
1352	vchar_t *data, *key, *iv;
1353{
1354	vchar_t *res;
1355	IDEA_KEY_SCHEDULE ks;
1356
1357	idea_set_encrypt_key((unsigned char *)key->v, &ks);
1358
1359	/* allocate buffer for result */
1360	if ((res = vmalloc(data->l)) == NULL)
1361		return NULL;
1362
1363	/* decryption data */
1364	idea_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
1365			&ks, (unsigned char *)iv->v, IDEA_ENCRYPT);
1366
1367	return res;
1368}
1369
1370vchar_t *
1371eay_idea_decrypt(data, key, iv)
1372	vchar_t *data, *key, *iv;
1373{
1374	vchar_t *res;
1375	IDEA_KEY_SCHEDULE ks, dks;
1376
1377	idea_set_encrypt_key((unsigned char *)key->v, &ks);
1378	idea_set_decrypt_key(&ks, &dks);
1379
1380	/* allocate buffer for result */
1381	if ((res = vmalloc(data->l)) == NULL)
1382		return NULL;
1383
1384	/* decryption data */
1385	idea_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
1386			&dks, (unsigned char *)iv->v, IDEA_DECRYPT);
1387
1388	return res;
1389}
1390
1391int
1392eay_idea_weakkey(key)
1393	vchar_t *key;
1394{
1395	return 0;       /* XXX */
1396}
1397
1398int
1399eay_idea_keylen(len)
1400	int len;
1401{
1402	if (len != 0 && len != 128)
1403		return -1;
1404	return 128;
1405}
1406#endif
1407
1408/*
1409 * BLOWFISH-CBC
1410 */
1411vchar_t *
1412eay_bf_encrypt(data, key, iv)
1413	vchar_t *data, *key, *iv;
1414{
1415	return evp_crypt(data, key, iv, EVP_bf_cbc(), 1);
1416}
1417
1418vchar_t *
1419eay_bf_decrypt(data, key, iv)
1420	vchar_t *data, *key, *iv;
1421{
1422	return evp_crypt(data, key, iv, EVP_bf_cbc(), 0);
1423}
1424
1425int
1426eay_bf_weakkey(key)
1427	vchar_t *key;
1428{
1429	return 0;	/* XXX to be done. refer to RFC 2451 */
1430}
1431
1432int
1433eay_bf_keylen(len)
1434	int len;
1435{
1436	if (len == 0)
1437		return 448;
1438	if (len < 40 || len > 448)
1439		return -1;
1440	return len;
1441}
1442
1443#ifdef HAVE_OPENSSL_RC5_H
1444/*
1445 * RC5-CBC
1446 */
1447vchar_t *
1448eay_rc5_encrypt(data, key, iv)
1449	vchar_t *data, *key, *iv;
1450{
1451	vchar_t *res;
1452	RC5_32_KEY ks;
1453
1454	/* in RFC 2451, there is information about the number of round. */
1455	RC5_32_set_key(&ks, key->l, (unsigned char *)key->v, 16);
1456
1457	/* allocate buffer for result */
1458	if ((res = vmalloc(data->l)) == NULL)
1459		return NULL;
1460
1461	/* decryption data */
1462	RC5_32_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
1463		&ks, (unsigned char *)iv->v, RC5_ENCRYPT);
1464
1465	return res;
1466}
1467
1468vchar_t *
1469eay_rc5_decrypt(data, key, iv)
1470	vchar_t *data, *key, *iv;
1471{
1472	vchar_t *res;
1473	RC5_32_KEY ks;
1474
1475	/* in RFC 2451, there is information about the number of round. */
1476	RC5_32_set_key(&ks, key->l, (unsigned char *)key->v, 16);
1477
1478	/* allocate buffer for result */
1479	if ((res = vmalloc(data->l)) == NULL)
1480		return NULL;
1481
1482	/* decryption data */
1483	RC5_32_cbc_encrypt((unsigned char *)data->v, (unsigned char *)res->v, data->l,
1484		&ks, (unsigned char *)iv->v, RC5_DECRYPT);
1485
1486	return res;
1487}
1488
1489int
1490eay_rc5_weakkey(key)
1491	vchar_t *key;
1492{
1493	return 0;       /* No known weak keys when used with 16 rounds. */
1494
1495}
1496
1497int
1498eay_rc5_keylen(len)
1499	int len;
1500{
1501	if (len == 0)
1502		return 128;
1503	if (len < 40 || len > 2040)
1504		return -1;
1505	return len;
1506}
1507#endif
1508
1509/*
1510 * 3DES-CBC
1511 */
1512vchar_t *
1513eay_3des_encrypt(data, key, iv)
1514	vchar_t *data, *key, *iv;
1515{
1516	return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 1);
1517}
1518
1519vchar_t *
1520eay_3des_decrypt(data, key, iv)
1521	vchar_t *data, *key, *iv;
1522{
1523	return evp_crypt(data, key, iv, EVP_des_ede3_cbc(), 0);
1524}
1525
1526int
1527eay_3des_weakkey(key)
1528	vchar_t *key;
1529{
1530#ifdef USE_NEW_DES_API
1531	return (DES_is_weak_key((void *)key->v) ||
1532	    DES_is_weak_key((void *)(key->v + 8)) ||
1533	    DES_is_weak_key((void *)(key->v + 16)));
1534#else
1535	if (key->l < 24)
1536		return 0;
1537
1538	return (des_is_weak_key((void *)key->v) ||
1539	    des_is_weak_key((void *)(key->v + 8)) ||
1540	    des_is_weak_key((void *)(key->v + 16)));
1541#endif
1542}
1543
1544int
1545eay_3des_keylen(len)
1546	int len;
1547{
1548	if (len != 0 && len != 192)
1549		return -1;
1550	return 192;
1551}
1552
1553/*
1554 * CAST-CBC
1555 */
1556vchar_t *
1557eay_cast_encrypt(data, key, iv)
1558	vchar_t *data, *key, *iv;
1559{
1560	return evp_crypt(data, key, iv, EVP_cast5_cbc(), 1);
1561}
1562
1563vchar_t *
1564eay_cast_decrypt(data, key, iv)
1565	vchar_t *data, *key, *iv;
1566{
1567	return evp_crypt(data, key, iv, EVP_cast5_cbc(), 0);
1568}
1569
1570int
1571eay_cast_weakkey(key)
1572	vchar_t *key;
1573{
1574	return 0;	/* No known weak keys. */
1575}
1576
1577int
1578eay_cast_keylen(len)
1579	int len;
1580{
1581	if (len == 0)
1582		return 128;
1583	if (len < 40 || len > 128)
1584		return -1;
1585	return len;
1586}
1587
1588/*
1589 * AES(RIJNDAEL)-CBC
1590 */
1591#ifndef HAVE_OPENSSL_AES_H
1592vchar_t *
1593eay_aes_encrypt(data, key, iv)
1594	vchar_t *data, *key, *iv;
1595{
1596	vchar_t *res;
1597	keyInstance k;
1598	cipherInstance c;
1599
1600	memset(&k, 0, sizeof(k));
1601	if (rijndael_makeKey(&k, DIR_ENCRYPT, key->l << 3, key->v) < 0)
1602		return NULL;
1603
1604	/* allocate buffer for result */
1605	if ((res = vmalloc(data->l)) == NULL)
1606		return NULL;
1607
1608	/* encryption data */
1609	memset(&c, 0, sizeof(c));
1610	if (rijndael_cipherInit(&c, MODE_CBC, iv->v) < 0){
1611		vfree(res);
1612		return NULL;
1613	}
1614	if (rijndael_blockEncrypt(&c, &k, data->v, data->l << 3, res->v) < 0){
1615		vfree(res);
1616		return NULL;
1617	}
1618
1619	return res;
1620}
1621
1622vchar_t *
1623eay_aes_decrypt(data, key, iv)
1624	vchar_t *data, *key, *iv;
1625{
1626	vchar_t *res;
1627	keyInstance k;
1628	cipherInstance c;
1629
1630	memset(&k, 0, sizeof(k));
1631	if (rijndael_makeKey(&k, DIR_DECRYPT, key->l << 3, key->v) < 0)
1632		return NULL;
1633
1634	/* allocate buffer for result */
1635	if ((res = vmalloc(data->l)) == NULL)
1636		return NULL;
1637
1638	/* decryption data */
1639	memset(&c, 0, sizeof(c));
1640	if (rijndael_cipherInit(&c, MODE_CBC, iv->v) < 0){
1641		vfree(res);
1642		return NULL;
1643	}
1644	if (rijndael_blockDecrypt(&c, &k, data->v, data->l << 3, res->v) < 0){
1645		vfree(res);
1646		return NULL;
1647	}
1648
1649	return res;
1650}
1651#else
1652static inline const EVP_CIPHER *
1653aes_evp_by_keylen(int keylen)
1654{
1655	switch(keylen) {
1656		case 16:
1657		case 128:
1658			return EVP_aes_128_cbc();
1659		case 24:
1660		case 192:
1661			return EVP_aes_192_cbc();
1662		case 32:
1663		case 256:
1664			return EVP_aes_256_cbc();
1665		default:
1666			return NULL;
1667	}
1668}
1669
1670vchar_t *
1671eay_aes_encrypt(data, key, iv)
1672       vchar_t *data, *key, *iv;
1673{
1674	return evp_crypt(data, key, iv, aes_evp_by_keylen(key->l), 1);
1675}
1676
1677vchar_t *
1678eay_aes_decrypt(data, key, iv)
1679       vchar_t *data, *key, *iv;
1680{
1681	return evp_crypt(data, key, iv, aes_evp_by_keylen(key->l), 0);
1682}
1683#endif
1684
1685int
1686eay_aes_weakkey(key)
1687	vchar_t *key;
1688{
1689	return 0;
1690}
1691
1692int
1693eay_aes_keylen(len)
1694	int len;
1695{
1696	if (len == 0)
1697		return 128;
1698	if (len != 128 && len != 192 && len != 256)
1699		return -1;
1700	return len;
1701}
1702
1703#if defined(HAVE_OPENSSL_CAMELLIA_H)
1704/*
1705 * CAMELLIA-CBC
1706 */
1707static inline const EVP_CIPHER *
1708camellia_evp_by_keylen(int keylen)
1709{
1710	switch(keylen) {
1711		case 16:
1712		case 128:
1713			return EVP_camellia_128_cbc();
1714		case 24:
1715		case 192:
1716			return EVP_camellia_192_cbc();
1717		case 32:
1718		case 256:
1719			return EVP_camellia_256_cbc();
1720		default:
1721			return NULL;
1722	}
1723}
1724
1725vchar_t *
1726eay_camellia_encrypt(data, key, iv)
1727       vchar_t *data, *key, *iv;
1728{
1729	return evp_crypt(data, key, iv, camellia_evp_by_keylen(key->l), 1);
1730}
1731
1732vchar_t *
1733eay_camellia_decrypt(data, key, iv)
1734       vchar_t *data, *key, *iv;
1735{
1736	return evp_crypt(data, key, iv, camellia_evp_by_keylen(key->l), 0);
1737}
1738
1739int
1740eay_camellia_weakkey(key)
1741	vchar_t *key;
1742{
1743	return 0;
1744}
1745
1746int
1747eay_camellia_keylen(len)
1748	int len;
1749{
1750	if (len == 0)
1751		return 128;
1752	if (len != 128 && len != 192 && len != 256)
1753		return -1;
1754	return len;
1755}
1756
1757#endif
1758
1759/* for ipsec part */
1760int
1761eay_null_hashlen()
1762{
1763	return 0;
1764}
1765
1766int
1767eay_kpdk_hashlen()
1768{
1769	return 0;
1770}
1771
1772int
1773eay_twofish_keylen(len)
1774	int len;
1775{
1776	if (len < 0 || len > 256)
1777		return -1;
1778	return len;
1779}
1780
1781int
1782eay_null_keylen(len)
1783	int len;
1784{
1785	return 0;
1786}
1787
1788/*
1789 * HMAC functions
1790 */
1791static caddr_t
1792eay_hmac_init(key, md)
1793	vchar_t *key;
1794	const EVP_MD *md;
1795{
1796	HMAC_CTX *c = racoon_malloc(sizeof(*c));
1797
1798	HMAC_Init(c, key->v, key->l, md);
1799
1800	return (caddr_t)c;
1801}
1802
1803static vchar_t *eay_hmac_one(key, data, type)
1804	vchar_t *key, *data;
1805	const EVP_MD *type;
1806{
1807	vchar_t *res;
1808
1809	if ((res = vmalloc(EVP_MD_size(type))) == 0)
1810		return NULL;
1811
1812	if (!HMAC(type, (void *) key->v, key->l,
1813		  (void *) data->v, data->l, (void *) res->v, NULL)) {
1814		vfree(res);
1815		return NULL;
1816	}
1817
1818	return res;
1819}
1820
1821static vchar_t *eay_digest_one(data, type)
1822	vchar_t *data;
1823	const EVP_MD *type;
1824{
1825	vchar_t *res;
1826
1827	if ((res = vmalloc(EVP_MD_size(type))) == 0)
1828		return NULL;
1829
1830	if (!EVP_Digest((void *) data->v, data->l,
1831			(void *) res->v, NULL, type, NULL)) {
1832		vfree(res);
1833		return NULL;
1834	}
1835
1836	return res;
1837}
1838
1839#ifdef WITH_SHA2
1840/*
1841 * HMAC SHA2-512
1842 */
1843vchar_t *
1844eay_hmacsha2_512_one(key, data)
1845	vchar_t *key, *data;
1846{
1847	return eay_hmac_one(key, data, EVP_sha2_512());
1848}
1849
1850caddr_t
1851eay_hmacsha2_512_init(key)
1852	vchar_t *key;
1853{
1854	return eay_hmac_init(key, EVP_sha2_512());
1855}
1856
1857void
1858eay_hmacsha2_512_update(c, data)
1859	caddr_t c;
1860	vchar_t *data;
1861{
1862	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
1863}
1864
1865vchar_t *
1866eay_hmacsha2_512_final(c)
1867	caddr_t c;
1868{
1869	vchar_t *res;
1870	unsigned int l;
1871
1872	if ((res = vmalloc(SHA512_DIGEST_LENGTH)) == 0)
1873		return NULL;
1874
1875	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
1876	res->l = l;
1877	HMAC_cleanup((HMAC_CTX *)c);
1878	(void)racoon_free(c);
1879
1880	if (SHA512_DIGEST_LENGTH != res->l) {
1881		plog(LLV_ERROR, LOCATION, NULL,
1882			"hmac sha2_512 length mismatch %zd.\n", res->l);
1883		vfree(res);
1884		return NULL;
1885	}
1886
1887	return(res);
1888}
1889
1890/*
1891 * HMAC SHA2-384
1892 */
1893vchar_t *
1894eay_hmacsha2_384_one(key, data)
1895	vchar_t *key, *data;
1896{
1897	return eay_hmac_one(key, data, EVP_sha2_384());
1898}
1899
1900caddr_t
1901eay_hmacsha2_384_init(key)
1902	vchar_t *key;
1903{
1904	return eay_hmac_init(key, EVP_sha2_384());
1905}
1906
1907void
1908eay_hmacsha2_384_update(c, data)
1909	caddr_t c;
1910	vchar_t *data;
1911{
1912	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
1913}
1914
1915vchar_t *
1916eay_hmacsha2_384_final(c)
1917	caddr_t c;
1918{
1919	vchar_t *res;
1920	unsigned int l;
1921
1922	if ((res = vmalloc(SHA384_DIGEST_LENGTH)) == 0)
1923		return NULL;
1924
1925	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
1926	res->l = l;
1927	HMAC_cleanup((HMAC_CTX *)c);
1928	(void)racoon_free(c);
1929
1930	if (SHA384_DIGEST_LENGTH != res->l) {
1931		plog(LLV_ERROR, LOCATION, NULL,
1932			"hmac sha2_384 length mismatch %zd.\n", res->l);
1933		vfree(res);
1934		return NULL;
1935	}
1936
1937	return(res);
1938}
1939
1940/*
1941 * HMAC SHA2-256
1942 */
1943vchar_t *
1944eay_hmacsha2_256_one(key, data)
1945	vchar_t *key, *data;
1946{
1947	return eay_hmac_one(key, data, EVP_sha2_256());
1948}
1949
1950caddr_t
1951eay_hmacsha2_256_init(key)
1952	vchar_t *key;
1953{
1954	return eay_hmac_init(key, EVP_sha2_256());
1955}
1956
1957void
1958eay_hmacsha2_256_update(c, data)
1959	caddr_t c;
1960	vchar_t *data;
1961{
1962	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
1963}
1964
1965vchar_t *
1966eay_hmacsha2_256_final(c)
1967	caddr_t c;
1968{
1969	vchar_t *res;
1970	unsigned int l;
1971
1972	if ((res = vmalloc(SHA256_DIGEST_LENGTH)) == 0)
1973		return NULL;
1974
1975	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
1976	res->l = l;
1977	HMAC_cleanup((HMAC_CTX *)c);
1978	(void)racoon_free(c);
1979
1980	if (SHA256_DIGEST_LENGTH != res->l) {
1981		plog(LLV_ERROR, LOCATION, NULL,
1982			"hmac sha2_256 length mismatch %zd.\n", res->l);
1983		vfree(res);
1984		return NULL;
1985	}
1986
1987	return(res);
1988}
1989#endif	/* WITH_SHA2 */
1990
1991/*
1992 * HMAC SHA1
1993 */
1994vchar_t *
1995eay_hmacsha1_one(key, data)
1996	vchar_t *key, *data;
1997{
1998	return eay_hmac_one(key, data, EVP_sha1());
1999}
2000
2001caddr_t
2002eay_hmacsha1_init(key)
2003	vchar_t *key;
2004{
2005	return eay_hmac_init(key, EVP_sha1());
2006}
2007
2008void
2009eay_hmacsha1_update(c, data)
2010	caddr_t c;
2011	vchar_t *data;
2012{
2013	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
2014}
2015
2016vchar_t *
2017eay_hmacsha1_final(c)
2018	caddr_t c;
2019{
2020	vchar_t *res;
2021	unsigned int l;
2022
2023	if ((res = vmalloc(SHA_DIGEST_LENGTH)) == 0)
2024		return NULL;
2025
2026	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
2027	res->l = l;
2028	HMAC_cleanup((HMAC_CTX *)c);
2029	(void)racoon_free(c);
2030
2031	if (SHA_DIGEST_LENGTH != res->l) {
2032		plog(LLV_ERROR, LOCATION, NULL,
2033			"hmac sha1 length mismatch %zd.\n", res->l);
2034		vfree(res);
2035		return NULL;
2036	}
2037
2038	return(res);
2039}
2040
2041/*
2042 * HMAC MD5
2043 */
2044vchar_t *
2045eay_hmacmd5_one(key, data)
2046	vchar_t *key, *data;
2047{
2048	return eay_hmac_one(key, data, EVP_md5());
2049}
2050
2051caddr_t
2052eay_hmacmd5_init(key)
2053	vchar_t *key;
2054{
2055	return eay_hmac_init(key, EVP_md5());
2056}
2057
2058void
2059eay_hmacmd5_update(c, data)
2060	caddr_t c;
2061	vchar_t *data;
2062{
2063	HMAC_Update((HMAC_CTX *)c, (unsigned char *) data->v, data->l);
2064}
2065
2066vchar_t *
2067eay_hmacmd5_final(c)
2068	caddr_t c;
2069{
2070	vchar_t *res;
2071	unsigned int l;
2072
2073	if ((res = vmalloc(MD5_DIGEST_LENGTH)) == 0)
2074		return NULL;
2075
2076	HMAC_Final((HMAC_CTX *)c, (unsigned char *) res->v, &l);
2077	res->l = l;
2078	HMAC_cleanup((HMAC_CTX *)c);
2079	(void)racoon_free(c);
2080
2081	if (MD5_DIGEST_LENGTH != res->l) {
2082		plog(LLV_ERROR, LOCATION, NULL,
2083			"hmac md5 length mismatch %zd.\n", res->l);
2084		vfree(res);
2085		return NULL;
2086	}
2087
2088	return(res);
2089}
2090
2091#ifdef WITH_SHA2
2092/*
2093 * SHA2-512 functions
2094 */
2095caddr_t
2096eay_sha2_512_init()
2097{
2098	SHA512_CTX *c = racoon_malloc(sizeof(*c));
2099
2100	SHA512_Init(c);
2101
2102	return((caddr_t)c);
2103}
2104
2105void
2106eay_sha2_512_update(c, data)
2107	caddr_t c;
2108	vchar_t *data;
2109{
2110	SHA512_Update((SHA512_CTX *)c, (unsigned char *) data->v, data->l);
2111
2112	return;
2113}
2114
2115vchar_t *
2116eay_sha2_512_final(c)
2117	caddr_t c;
2118{
2119	vchar_t *res;
2120
2121	if ((res = vmalloc(SHA512_DIGEST_LENGTH)) == 0)
2122		return(0);
2123
2124	SHA512_Final((unsigned char *) res->v, (SHA512_CTX *)c);
2125	(void)racoon_free(c);
2126
2127	return(res);
2128}
2129
2130vchar_t *
2131eay_sha2_512_one(data)
2132	vchar_t *data;
2133{
2134	return eay_digest_one(data, EVP_sha512());
2135}
2136
2137int
2138eay_sha2_512_hashlen()
2139{
2140	return SHA512_DIGEST_LENGTH << 3;
2141}
2142#endif
2143
2144#ifdef WITH_SHA2
2145/*
2146 * SHA2-384 functions
2147 */
2148caddr_t
2149eay_sha2_384_init()
2150{
2151	SHA384_CTX *c = racoon_malloc(sizeof(*c));
2152
2153	SHA384_Init(c);
2154
2155	return((caddr_t)c);
2156}
2157
2158void
2159eay_sha2_384_update(c, data)
2160	caddr_t c;
2161	vchar_t *data;
2162{
2163	SHA384_Update((SHA384_CTX *)c, (unsigned char *) data->v, data->l);
2164
2165	return;
2166}
2167
2168vchar_t *
2169eay_sha2_384_final(c)
2170	caddr_t c;
2171{
2172	vchar_t *res;
2173
2174	if ((res = vmalloc(SHA384_DIGEST_LENGTH)) == 0)
2175		return(0);
2176
2177	SHA384_Final((unsigned char *) res->v, (SHA384_CTX *)c);
2178	(void)racoon_free(c);
2179
2180	return(res);
2181}
2182
2183vchar_t *
2184eay_sha2_384_one(data)
2185	vchar_t *data;
2186{
2187	return eay_digest_one(data, EVP_sha2_384());
2188}
2189
2190int
2191eay_sha2_384_hashlen()
2192{
2193	return SHA384_DIGEST_LENGTH << 3;
2194}
2195#endif
2196
2197#ifdef WITH_SHA2
2198/*
2199 * SHA2-256 functions
2200 */
2201caddr_t
2202eay_sha2_256_init()
2203{
2204	SHA256_CTX *c = racoon_malloc(sizeof(*c));
2205
2206	SHA256_Init(c);
2207
2208	return((caddr_t)c);
2209}
2210
2211void
2212eay_sha2_256_update(c, data)
2213	caddr_t c;
2214	vchar_t *data;
2215{
2216	SHA256_Update((SHA256_CTX *)c, (unsigned char *) data->v, data->l);
2217
2218	return;
2219}
2220
2221vchar_t *
2222eay_sha2_256_final(c)
2223	caddr_t c;
2224{
2225	vchar_t *res;
2226
2227	if ((res = vmalloc(SHA256_DIGEST_LENGTH)) == 0)
2228		return(0);
2229
2230	SHA256_Final((unsigned char *) res->v, (SHA256_CTX *)c);
2231	(void)racoon_free(c);
2232
2233	return(res);
2234}
2235
2236vchar_t *
2237eay_sha2_256_one(data)
2238	vchar_t *data;
2239{
2240	return eay_digest_one(data, EVP_sha2_256());
2241}
2242
2243int
2244eay_sha2_256_hashlen()
2245{
2246	return SHA256_DIGEST_LENGTH << 3;
2247}
2248#endif
2249
2250/*
2251 * SHA functions
2252 */
2253caddr_t
2254eay_sha1_init()
2255{
2256	SHA_CTX *c = racoon_malloc(sizeof(*c));
2257
2258	SHA1_Init(c);
2259
2260	return((caddr_t)c);
2261}
2262
2263void
2264eay_sha1_update(c, data)
2265	caddr_t c;
2266	vchar_t *data;
2267{
2268	SHA1_Update((SHA_CTX *)c, data->v, data->l);
2269
2270	return;
2271}
2272
2273vchar_t *
2274eay_sha1_final(c)
2275	caddr_t c;
2276{
2277	vchar_t *res;
2278
2279	if ((res = vmalloc(SHA_DIGEST_LENGTH)) == 0)
2280		return(0);
2281
2282	SHA1_Final((unsigned char *) res->v, (SHA_CTX *)c);
2283	(void)racoon_free(c);
2284
2285	return(res);
2286}
2287
2288vchar_t *
2289eay_sha1_one(data)
2290	vchar_t *data;
2291{
2292	return eay_digest_one(data, EVP_sha1());
2293}
2294
2295int
2296eay_sha1_hashlen()
2297{
2298	return SHA_DIGEST_LENGTH << 3;
2299}
2300
2301/*
2302 * MD5 functions
2303 */
2304caddr_t
2305eay_md5_init()
2306{
2307	MD5_CTX *c = racoon_malloc(sizeof(*c));
2308
2309	MD5_Init(c);
2310
2311	return((caddr_t)c);
2312}
2313
2314void
2315eay_md5_update(c, data)
2316	caddr_t c;
2317	vchar_t *data;
2318{
2319	MD5_Update((MD5_CTX *)c, data->v, data->l);
2320
2321	return;
2322}
2323
2324vchar_t *
2325eay_md5_final(c)
2326	caddr_t c;
2327{
2328	vchar_t *res;
2329
2330	if ((res = vmalloc(MD5_DIGEST_LENGTH)) == 0)
2331		return(0);
2332
2333	MD5_Final((unsigned char *) res->v, (MD5_CTX *)c);
2334	(void)racoon_free(c);
2335
2336	return(res);
2337}
2338
2339vchar_t *
2340eay_md5_one(data)
2341	vchar_t *data;
2342{
2343	return eay_digest_one(data, EVP_md5());
2344}
2345
2346int
2347eay_md5_hashlen()
2348{
2349	return MD5_DIGEST_LENGTH << 3;
2350}
2351
2352/*
2353 * eay_set_random
2354 *   size: number of bytes.
2355 */
2356vchar_t *
2357eay_set_random(size)
2358	u_int32_t size;
2359{
2360	BIGNUM *r = NULL;
2361	vchar_t *res = 0;
2362
2363	if ((r = BN_new()) == NULL)
2364		goto end;
2365	BN_rand(r, size * 8, 0, 0);
2366	eay_bn2v(&res, r);
2367
2368end:
2369	if (r)
2370		BN_free(r);
2371	return(res);
2372}
2373
2374/* DH */
2375int
2376eay_dh_generate(prime, g, publen, pub, priv)
2377	vchar_t *prime, **pub, **priv;
2378	u_int publen;
2379	u_int32_t g;
2380{
2381	BIGNUM *p = NULL;
2382	DH *dh = NULL;
2383	int error = -1;
2384
2385	/* initialize */
2386	/* pre-process to generate number */
2387	if (eay_v2bn(&p, prime) < 0)
2388		goto end;
2389
2390	if ((dh = DH_new()) == NULL)
2391		goto end;
2392	dh->p = p;
2393	p = NULL;	/* p is now part of dh structure */
2394	dh->g = NULL;
2395	if ((dh->g = BN_new()) == NULL)
2396		goto end;
2397	if (!BN_set_word(dh->g, g))
2398		goto end;
2399
2400	if (publen != 0)
2401		dh->length = publen;
2402
2403	/* generate public and private number */
2404	if (!DH_generate_key(dh))
2405		goto end;
2406
2407	/* copy results to buffers */
2408	if (eay_bn2v(pub, dh->pub_key) < 0)
2409		goto end;
2410	if (eay_bn2v(priv, dh->priv_key) < 0) {
2411		vfree(*pub);
2412		goto end;
2413	}
2414
2415	error = 0;
2416
2417end:
2418	if (dh != NULL)
2419		DH_free(dh);
2420	if (p != 0)
2421		BN_free(p);
2422	return(error);
2423}
2424
2425int
2426eay_dh_compute(prime, g, pub, priv, pub2, key)
2427	vchar_t *prime, *pub, *priv, *pub2, **key;
2428	u_int32_t g;
2429{
2430	BIGNUM *dh_pub = NULL;
2431	DH *dh = NULL;
2432	int l;
2433	unsigned char *v = NULL;
2434	int error = -1;
2435
2436	/* make public number to compute */
2437	if (eay_v2bn(&dh_pub, pub2) < 0)
2438		goto end;
2439
2440	/* make DH structure */
2441	if ((dh = DH_new()) == NULL)
2442		goto end;
2443	if (eay_v2bn(&dh->p, prime) < 0)
2444		goto end;
2445	if (eay_v2bn(&dh->pub_key, pub) < 0)
2446		goto end;
2447	if (eay_v2bn(&dh->priv_key, priv) < 0)
2448		goto end;
2449	dh->length = pub2->l * 8;
2450
2451	dh->g = NULL;
2452	if ((dh->g = BN_new()) == NULL)
2453		goto end;
2454	if (!BN_set_word(dh->g, g))
2455		goto end;
2456
2457	if ((v = racoon_calloc(prime->l, sizeof(u_char))) == NULL)
2458		goto end;
2459	if ((l = DH_compute_key(v, dh_pub, dh)) == -1)
2460		goto end;
2461	memcpy((*key)->v + (prime->l - l), v, l);
2462
2463	error = 0;
2464
2465end:
2466	if (dh_pub != NULL)
2467		BN_free(dh_pub);
2468	if (dh != NULL)
2469		DH_free(dh);
2470	if (v != NULL)
2471		racoon_free(v);
2472	return(error);
2473}
2474
2475/*
2476 * convert vchar_t <-> BIGNUM.
2477 *
2478 * vchar_t: unit is u_char, network endian, most significant byte first.
2479 * BIGNUM: unit is BN_ULONG, each of BN_ULONG is in host endian,
2480 *	least significant BN_ULONG must come first.
2481 *
2482 * hex value of "0x3ffe050104" is represented as follows:
2483 *	vchar_t: 3f fe 05 01 04
2484 *	BIGNUM (BN_ULONG = u_int8_t): 04 01 05 fe 3f
2485 *	BIGNUM (BN_ULONG = u_int16_t): 0x0104 0xfe05 0x003f
2486 *	BIGNUM (BN_ULONG = u_int32_t_t): 0xfe050104 0x0000003f
2487 */
2488int
2489eay_v2bn(bn, var)
2490	BIGNUM **bn;
2491	vchar_t *var;
2492{
2493	if ((*bn = BN_bin2bn((unsigned char *) var->v, var->l, NULL)) == NULL)
2494		return -1;
2495
2496	return 0;
2497}
2498
2499int
2500eay_bn2v(var, bn)
2501	vchar_t **var;
2502	BIGNUM *bn;
2503{
2504	*var = vmalloc(bn->top * BN_BYTES);
2505	if (*var == NULL)
2506		return(-1);
2507
2508	(*var)->l = BN_bn2bin(bn, (unsigned char *) (*var)->v);
2509
2510	return 0;
2511}
2512
2513void
2514eay_init()
2515{
2516	OpenSSL_add_all_algorithms();
2517	ERR_load_crypto_strings();
2518#ifdef HAVE_OPENSSL_ENGINE_H
2519	ENGINE_load_builtin_engines();
2520	ENGINE_register_all_complete();
2521#endif
2522}
2523
2524vchar_t *
2525base64_decode(char *in, long inlen)
2526{
2527	BIO *bio=NULL, *b64=NULL;
2528	vchar_t *res = NULL;
2529	char *outb;
2530	long outlen;
2531
2532	outb = malloc(inlen * 2);
2533	if (outb == NULL)
2534		goto out;
2535	bio = BIO_new_mem_buf(in, inlen);
2536	b64 = BIO_new(BIO_f_base64());
2537	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
2538	bio = BIO_push(b64, bio);
2539
2540	outlen = BIO_read(bio, outb, inlen * 2);
2541	if (outlen <= 0) {
2542		plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror());
2543		goto out;
2544	}
2545
2546	res = vmalloc(outlen);
2547	if (!res)
2548		goto out;
2549
2550	memcpy(res->v, outb, outlen);
2551
2552out:
2553	if (outb)
2554		free(outb);
2555	if (bio)
2556		BIO_free_all(bio);
2557
2558	return res;
2559}
2560
2561vchar_t *
2562base64_encode(char *in, long inlen)
2563{
2564	BIO *bio=NULL, *b64=NULL;
2565	char *ptr;
2566	long plen = -1;
2567	vchar_t *res = NULL;
2568
2569	bio = BIO_new(BIO_s_mem());
2570	b64 = BIO_new(BIO_f_base64());
2571	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
2572	bio = BIO_push(b64, bio);
2573
2574	BIO_write(bio, in, inlen);
2575	BIO_flush(bio);
2576
2577	plen = BIO_get_mem_data(bio, &ptr);
2578	res = vmalloc(plen+1);
2579	if (!res)
2580		goto out;
2581
2582	memcpy (res->v, ptr, plen);
2583	res->v[plen] = '\0';
2584
2585out:
2586	if (bio)
2587		BIO_free_all(bio);
2588
2589	return res;
2590}
2591
2592static RSA *
2593binbuf_pubkey2rsa(vchar_t *binbuf)
2594{
2595	BIGNUM *exp, *mod;
2596	RSA *rsa_pub = NULL;
2597
2598	if (binbuf->v[0] > binbuf->l - 1) {
2599		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: decoded string doesn't make sense.\n");
2600		goto out;
2601	}
2602
2603	exp = BN_bin2bn((unsigned char *) (binbuf->v + 1), binbuf->v[0], NULL);
2604	mod = BN_bin2bn((unsigned char *) (binbuf->v + binbuf->v[0] + 1),
2605			binbuf->l - binbuf->v[0] - 1, NULL);
2606	rsa_pub = RSA_new();
2607
2608	if (!exp || !mod || !rsa_pub) {
2609		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey parsing error: %s\n", eay_strerror());
2610		if (exp)
2611			BN_free(exp);
2612		if (mod)
2613			BN_free(exp);
2614		if (rsa_pub)
2615			RSA_free(rsa_pub);
2616		rsa_pub = NULL;
2617		goto out;
2618	}
2619
2620	rsa_pub->n = mod;
2621	rsa_pub->e = exp;
2622
2623out:
2624	return rsa_pub;
2625}
2626
2627RSA *
2628base64_pubkey2rsa(char *in)
2629{
2630	BIGNUM *exp, *mod;
2631	RSA *rsa_pub = NULL;
2632	vchar_t *binbuf;
2633
2634	if (strncmp(in, "0s", 2) != 0) {
2635		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: doesn't start with '0s'\n");
2636		return NULL;
2637	}
2638
2639	binbuf = base64_decode(in + 2, strlen(in + 2));
2640	if (!binbuf) {
2641		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: Base64 decoding failed.\n");
2642		return NULL;
2643	}
2644
2645	if (binbuf->v[0] > binbuf->l - 1) {
2646		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey format error: decoded string doesn't make sense.\n");
2647		goto out;
2648	}
2649
2650	rsa_pub = binbuf_pubkey2rsa(binbuf);
2651
2652out:
2653	if (binbuf)
2654		vfree(binbuf);
2655
2656	return rsa_pub;
2657}
2658
2659RSA *
2660bignum_pubkey2rsa(BIGNUM *in)
2661{
2662	RSA *rsa_pub = NULL;
2663	vchar_t *binbuf;
2664
2665	binbuf = vmalloc(BN_num_bytes(in));
2666	if (!binbuf) {
2667		plog(LLV_ERROR, LOCATION, NULL, "Plain RSA pubkey conversion: memory allocation failed..\n");
2668		return NULL;
2669	}
2670
2671	BN_bn2bin(in, (unsigned char *) binbuf->v);
2672
2673	rsa_pub = binbuf_pubkey2rsa(binbuf);
2674
2675out:
2676	if (binbuf)
2677		vfree(binbuf);
2678
2679	return rsa_pub;
2680}
2681
2682u_int32_t
2683eay_random()
2684{
2685	u_int32_t result;
2686	vchar_t *vrand;
2687
2688	vrand = eay_set_random(sizeof(result));
2689	memcpy(&result, vrand->v, sizeof(result));
2690	vfree(vrand);
2691
2692	return result;
2693}
2694
2695const char *
2696eay_version()
2697{
2698	return SSLeay_version(SSLEAY_VERSION);
2699}
2700