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