Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/crypto/dist/ipsec-tools/src/racoon/crypto_openssl.c,v rcsdiff: /ftp/cvs/cvsroot/src/crypto/dist/ipsec-tools/src/racoon/crypto_openssl.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.15.4.1 retrieving revision 1.23 diff -u -p -r1.15.4.1 -r1.23 --- src/crypto/dist/ipsec-tools/src/racoon/crypto_openssl.c 2009/02/08 18:42:15 1.15.4.1 +++ src/crypto/dist/ipsec-tools/src/racoon/crypto_openssl.c 2012/12/24 08:46:27 1.23 @@ -1,4 +1,4 @@ -/* $NetBSD: crypto_openssl.c,v 1.15.4.1 2009/02/08 18:42:15 snj Exp $ */ +/* $NetBSD: crypto_openssl.c,v 1.23 2012/12/24 08:46:27 tteras Exp $ */ /* Id: crypto_openssl.c,v 1.47 2006/05/06 20:42:09 manubsd Exp */ @@ -44,8 +44,8 @@ /* get openssl/ssleay version number */ #include -#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090602fL) -#error OpenSSL version 0.9.6 or later required. +#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090813fL) +#error OpenSSL version 0.9.8s or later required. #endif #include @@ -91,12 +91,7 @@ #endif #include "plog.h" -/* 0.9.7 stuff? */ -#if OPENSSL_VERSION_NUMBER < 0x0090700fL -typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; -#else #define USE_NEW_DES_API -#endif #define OpenSSL_BUG() do { plog(LLV_ERROR, LOCATION, NULL, "OpenSSL function failed\n"); } while(0) @@ -107,6 +102,7 @@ typedef STACK_OF(GENERAL_NAME) GENERAL_N #include "crypto_openssl.h" #include "debug.h" #include "gcmalloc.h" +#include "isakmp.h" /* * I hate to cast every parameter to des_xx into void *, but it is @@ -130,9 +126,9 @@ eay_str2asn1dn(str, len) int len; { X509_NAME *name; - char *buf; + char *buf, *dst; char *field, *value; - int i, j; + int i; vchar_t *ret = NULL; caddr_t p; @@ -148,15 +144,38 @@ eay_str2asn1dn(str, len) name = X509_NAME_new(); - field = &buf[0]; + dst = field = &buf[0]; value = NULL; for (i = 0; i < len; i++) { + if (buf[i] == '\\') { + /* Escape characters specified in RFC 2253 */ + if (i < len - 1 && + strchr("\\,=+<>#;", buf[i+1]) != NULL) { + *dst++ = buf[++i]; + continue; + } else if (i < len - 2) { + /* RFC 2253 hexpair character escape */ + long u; + char esc_str[3]; + char *endptr; + + esc_str[0] = buf[++i]; + esc_str[1] = buf[++i]; + esc_str[2] = '\0'; + u = strtol(esc_str, &endptr, 16); + if (*endptr != '\0' || u < 0 || u > 255) + goto err; + *dst++ = u; + continue; + } else + goto err; + } if (!value && buf[i] == '=') { - buf[i] = '\0'; - value = &buf[i + 1]; + *dst = '\0'; + dst = value = &buf[i + 1]; continue; } else if (buf[i] == ',' || buf[i] == '/') { - buf[i] = '\0'; + *dst = '\0'; plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n", field, value); @@ -173,16 +192,16 @@ eay_str2asn1dn(str, len) "%s\n", eay_strerror()); goto err; } - for (j = i + 1; j < len; j++) { - if (buf[j] != ' ') - break; - } - field = &buf[j]; + + while (i + 1 < len && buf[i + 1] == ' ') i++; + dst = field = &buf[i + 1]; value = NULL; continue; + } else { + *dst++ = buf[i]; } } - buf[len] = '\0'; + *dst = '\0'; plog(LLV_DEBUG, LOCATION, NULL, "DN: %s=%s\n", field, value); @@ -481,12 +500,10 @@ eay_check_x509cert(cert, CApath, CAfile, if (csc == NULL) goto end; X509_STORE_CTX_init(csc, cert_ctx, x509, NULL); -#if OPENSSL_VERSION_NUMBER >= 0x00907000L X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK); X509_STORE_CTX_set_flags (csc, X509_V_FLAG_CRL_CHECK_ALL); -#endif error = X509_verify_cert(csc); - X509_STORE_CTX_cleanup(csc); + X509_STORE_CTX_free(csc); /* * if x509_verify_cert() is successful then the value of error is @@ -590,7 +607,7 @@ cb_check_cert_remote(ok, ctx) } /* - * get a subjectAltName from X509 certificate. + * get a subjectName from X509 certificate. */ vchar_t * eay_get_x509asn1subjectname(cert) @@ -601,8 +618,6 @@ eay_get_x509asn1subjectname(cert) vchar_t *name = NULL; int len; - bp = (unsigned char *) cert->v; - x509 = mem2x509(cert); if (x509 == NULL) goto error; @@ -736,6 +751,46 @@ end: return error; } +/* + * get a issuerName from X509 certificate. + */ +vchar_t * +eay_get_x509asn1issuername(cert) + vchar_t *cert; +{ + X509 *x509 = NULL; + u_char *bp; + vchar_t *name = NULL; + int len; + + x509 = mem2x509(cert); + if (x509 == NULL) + goto error; + + /* get the length of the name */ + len = i2d_X509_NAME(x509->cert_info->issuer, NULL); + name = vmalloc(len); + if (name == NULL) + goto error; + + /* get the name */ + bp = (unsigned char *) name->v; + len = i2d_X509_NAME(x509->cert_info->issuer, &bp); + + X509_free(x509); + + return name; + +error: + plog(LLV_ERROR, LOCATION, NULL, "%s\n", eay_strerror()); + + if (name != NULL) + vfree(name); + if (x509 != NULL) + X509_free(x509); + + return NULL; +} /* * decode a X509 certificate and make a readable text terminated '\n'. @@ -802,9 +857,9 @@ mem2x509(cert) { u_char *bp; - bp = (unsigned char *) cert->v; + bp = (unsigned char *) cert->v + 1; - x509 = d2i_X509(NULL, (void *)&bp, cert->l); + x509 = d2i_X509(NULL, (void *)&bp, cert->l - 1); } #else { @@ -814,7 +869,7 @@ mem2x509(cert) bio = BIO_new(BIO_s_mem()); if (bio == NULL) return NULL; - len = BIO_write(bio, cert->v, cert->l); + len = BIO_write(bio, cert->v + 1, cert->l - 1); if (len == -1) return NULL; x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); @@ -855,12 +910,13 @@ eay_get_x509cert(path) return NULL; len = i2d_X509(x509, NULL); - cert = vmalloc(len); + cert = vmalloc(len + 1); if (cert == NULL) { X509_free(x509); return NULL; } - bp = (unsigned char *) cert->v; + cert->v[0] = ISAKMP_CERT_X509SIGN; + bp = (unsigned char *) &cert->v[1]; error = i2d_X509(x509, &bp); X509_free(x509); @@ -886,27 +942,24 @@ eay_check_x509sign(source, sig, cert) vchar_t *cert; { X509 *x509; - u_char *bp; EVP_PKEY *evp; int res; - bp = (unsigned char *) cert->v; - - x509 = d2i_X509(NULL, (void *)&bp, cert->l); - if (x509 == NULL) { - plog(LLV_ERROR, LOCATION, NULL, "d2i_X509(): %s\n", eay_strerror()); + x509 = mem2x509(cert); + if (x509 == NULL) return -1; - } evp = X509_get_pubkey(x509); if (! evp) { plog(LLV_ERROR, LOCATION, NULL, "X509_get_pubkey(): %s\n", eay_strerror()); + X509_free(x509); return -1; } res = eay_rsa_verify(source, sig, evp->pkey.rsa); EVP_PKEY_free(evp); + X509_free(x509); return res; } @@ -1640,6 +1693,39 @@ eay_aes_keylen(len) return len; } +int +eay_aesgcm_keylen(len) + int len; +{ + /* RFC 4106: + * The size of the KEYMAT for the AES-GCM-ESP MUST be four octets longer + * than is needed for the associated AES key. The keying material is + * used as follows: + * + * AES-GCM-ESP with a 128 bit key + * The KEYMAT requested for each AES-GCM key is 20 octets. The first + * 16 octets are the 128-bit AES key, and the remaining four octets + * are used as the salt value in the nonce. + * + * AES-GCM-ESP with a 192 bit key + * The KEYMAT requested for each AES-GCM key is 28 octets. The first + * 24 octets are the 192-bit AES key, and the remaining four octets + * are used as the salt value in the nonce. + * + * AES-GCM-ESP with a 256 bit key + * The KEYMAT requested for each AES GCM key is 36 octets. The first + * 32 octets are the 256-bit AES key, and the remaining four octets + * are used as the salt value in the nonce. + */ + if (len == 0) + len = 128; + + if (len != 128 && len != 192 && len != 256) + return -1; + + return len + 32; +} + #if defined(HAVE_OPENSSL_CAMELLIA_H) /* * CAMELLIA-CBC @@ -1740,6 +1826,42 @@ eay_hmac_init(key, md) return (caddr_t)c; } +static vchar_t *eay_hmac_one(key, data, type) + vchar_t *key, *data; + const EVP_MD *type; +{ + vchar_t *res; + + if ((res = vmalloc(EVP_MD_size(type))) == 0) + return NULL; + + if (!HMAC(type, (void *) key->v, key->l, + (void *) data->v, data->l, (void *) res->v, NULL)) { + vfree(res); + return NULL; + } + + return res; +} + +static vchar_t *eay_digest_one(data, type) + vchar_t *data; + const EVP_MD *type; +{ + vchar_t *res; + + if ((res = vmalloc(EVP_MD_size(type))) == 0) + return NULL; + + if (!EVP_Digest((void *) data->v, data->l, + (void *) res->v, NULL, type, NULL)) { + vfree(res); + return NULL; + } + + return res; +} + #ifdef WITH_SHA2 /* * HMAC SHA2-512 @@ -1748,14 +1870,7 @@ vchar_t * eay_hmacsha2_512_one(key, data) vchar_t *key, *data; { - vchar_t *res; - caddr_t ctx; - - ctx = eay_hmacsha2_512_init(key); - eay_hmacsha2_512_update(ctx, data); - res = eay_hmacsha2_512_final(ctx); - - return(res); + return eay_hmac_one(key, data, EVP_sha2_512()); } caddr_t @@ -1805,14 +1920,7 @@ vchar_t * eay_hmacsha2_384_one(key, data) vchar_t *key, *data; { - vchar_t *res; - caddr_t ctx; - - ctx = eay_hmacsha2_384_init(key); - eay_hmacsha2_384_update(ctx, data); - res = eay_hmacsha2_384_final(ctx); - - return(res); + return eay_hmac_one(key, data, EVP_sha2_384()); } caddr_t @@ -1862,14 +1970,7 @@ vchar_t * eay_hmacsha2_256_one(key, data) vchar_t *key, *data; { - vchar_t *res; - caddr_t ctx; - - ctx = eay_hmacsha2_256_init(key); - eay_hmacsha2_256_update(ctx, data); - res = eay_hmacsha2_256_final(ctx); - - return(res); + return eay_hmac_one(key, data, EVP_sha2_256()); } caddr_t @@ -1920,14 +2021,7 @@ vchar_t * eay_hmacsha1_one(key, data) vchar_t *key, *data; { - vchar_t *res; - caddr_t ctx; - - ctx = eay_hmacsha1_init(key); - eay_hmacsha1_update(ctx, data); - res = eay_hmacsha1_final(ctx); - - return(res); + return eay_hmac_one(key, data, EVP_sha1()); } caddr_t @@ -1977,14 +2071,7 @@ vchar_t * eay_hmacmd5_one(key, data) vchar_t *key, *data; { - vchar_t *res; - caddr_t ctx; - - ctx = eay_hmacmd5_init(key); - eay_hmacmd5_update(ctx, data); - res = eay_hmacmd5_final(ctx); - - return(res); + return eay_hmac_one(key, data, EVP_md5()); } caddr_t @@ -2070,14 +2157,7 @@ vchar_t * eay_sha2_512_one(data) vchar_t *data; { - caddr_t ctx; - vchar_t *res; - - ctx = eay_sha2_512_init(); - eay_sha2_512_update(ctx, data); - res = eay_sha2_512_final(ctx); - - return(res); + return eay_digest_one(data, EVP_sha512()); } int @@ -2130,14 +2210,7 @@ vchar_t * eay_sha2_384_one(data) vchar_t *data; { - caddr_t ctx; - vchar_t *res; - - ctx = eay_sha2_384_init(); - eay_sha2_384_update(ctx, data); - res = eay_sha2_384_final(ctx); - - return(res); + return eay_digest_one(data, EVP_sha2_384()); } int @@ -2190,14 +2263,7 @@ vchar_t * eay_sha2_256_one(data) vchar_t *data; { - caddr_t ctx; - vchar_t *res; - - ctx = eay_sha2_256_init(); - eay_sha2_256_update(ctx, data); - res = eay_sha2_256_final(ctx); - - return(res); + return eay_digest_one(data, EVP_sha2_256()); } int @@ -2249,14 +2315,7 @@ vchar_t * eay_sha1_one(data) vchar_t *data; { - caddr_t ctx; - vchar_t *res; - - ctx = eay_sha1_init(); - eay_sha1_update(ctx, data); - res = eay_sha1_final(ctx); - - return(res); + return eay_digest_one(data, EVP_sha1()); } int @@ -2307,14 +2366,7 @@ vchar_t * eay_md5_one(data) vchar_t *data; { - caddr_t ctx; - vchar_t *res; - - ctx = eay_md5_init(); - eay_md5_update(ctx, data); - res = eay_md5_final(ctx); - - return(res); + return eay_digest_one(data, EVP_md5()); } int @@ -2475,7 +2527,7 @@ eay_bn2v(var, bn) vchar_t **var; BIGNUM *bn; { - *var = vmalloc(bn->top * BN_BYTES); + *var = vmalloc(BN_num_bytes(bn)); if (*var == NULL) return(-1);