Return to crypto_openssl.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon |
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: }