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