source: rtems-libbsd/ipsec-tools/src/racoon/crypto_openssl.c @ ff36f5e

55-freebsd-126-freebsd-12
Last change on this file since ff36f5e was ff36f5e, checked in by Christian Mauderer <christian.mauderer@…>, on 05/30/18 at 12:27:35

Import ipsec-tools 0.8.2.

Import unchanged ipsec-tools sources in the release version 0.8.2. The
homepage of ipsec-tools is http://ipsec-tools.sourceforge.net/. The
sources can be obtained from there.

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