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