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