Annotation of embedaddon/ipsec-tools/src/racoon/crypto_openssl.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>