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>