summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2016-06-22 21:14:40 -0700
committerGuy Harris <guy@alum.mit.edu>2016-06-22 21:14:40 -0700
commitb1f305da3ddf635522bdcd6c88918beaea330968 (patch)
tree902044f80b10a4de19692039fc2aa4f7abcc1714
parent6334c9435e782cc73406e03a4328da58630c6639 (diff)
downloadtcpdump-b1f305da3ddf635522bdcd6c88918beaea330968.tar.gz
Handle OpenSSL 1.1.x.
In 1.1.x, EVP_CIPHER_CTX is an opaque structure, so we can't declare it on the stack. Instead, if we don't have EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free() in libcrypto, define our own versions, with the same signatures as the ones in OpenSSL 1.1.x's libcrypto, and have the code use EVP_CIPHER_CTX_new() to allocate the structure and EVP_CIPHER_CTX_free() to free it.
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure21
-rw-r--r--configure.in11
-rw-r--r--print-esp.c63
4 files changed, 80 insertions, 18 deletions
diff --git a/config.h.in b/config.h.in
index 6f6bb11a..27ba4b10 100644
--- a/config.h.in
+++ b/config.h.in
@@ -34,6 +34,9 @@
/* Define to 1 if you have the `ether_ntohost' function. */
#undef HAVE_ETHER_NTOHOST
+/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */
+#undef HAVE_EVP_CIPHER_CTX_NEW
+
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
diff --git a/configure b/configure
index a3a3e01e..aab7239a 100755
--- a/configure
+++ b/configure
@@ -8041,7 +8041,8 @@ _ACEOF
fi
- for ac_header in openssl/evp.h
+ if test "$ac_cv_lib_crypto_DES_cbc_encrypt" = "yes"; then
+ for ac_header in openssl/evp.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "openssl/evp.h" "ac_cv_header_openssl_evp_h" "$ac_includes_default"
if test "x$ac_cv_header_openssl_evp_h" = xyes; then :
@@ -8053,6 +8054,24 @@ fi
done
+ #
+ # OK, do we have EVP_CIPHER_CTX_new?
+ # If so, we use it to allocate an
+ # EVP_CIPHER_CTX, as EVP_CIPHER_CTX may be
+ # opaque; otherwise, we allocate it ourselves.
+ #
+ for ac_func in EVP_CIPHER_CTX_new
+do :
+ ac_fn_c_check_func "$LINENO" "EVP_CIPHER_CTX_new" "ac_cv_func_EVP_CIPHER_CTX_new"
+if test "x$ac_cv_func_EVP_CIPHER_CTX_new" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_EVP_CIPHER_CTX_NEW 1
+_ACEOF
+
+fi
+done
+
+ fi
fi
diff --git a/configure.in b/configure.in
index 8ceb46bb..22ecee6f 100644
--- a/configure.in
+++ b/configure.in
@@ -918,7 +918,16 @@ if test "$want_libcrypto" != "no"; then
AC_CHECK_HEADER(openssl/crypto.h,
[
AC_CHECK_LIB(crypto, DES_cbc_encrypt)
- AC_CHECK_HEADERS(openssl/evp.h)
+ if test "$ac_cv_lib_crypto_DES_cbc_encrypt" = "yes"; then
+ AC_CHECK_HEADERS(openssl/evp.h)
+ #
+ # OK, do we have EVP_CIPHER_CTX_new?
+ # If so, we use it to allocate an
+ # EVP_CIPHER_CTX, as EVP_CIPHER_CTX may be
+ # opaque; otherwise, we allocate it ourselves.
+ #
+ AC_CHECK_FUNCS(EVP_CIPHER_CTX_new)
+ fi
])
fi
diff --git a/print-esp.c b/print-esp.c
index 247796da..8339a567 100644
--- a/print-esp.c
+++ b/print-esp.c
@@ -117,6 +117,32 @@ struct sa_list {
int secretlen;
};
+#ifndef HAVE_EVP_CIPHER_CTX_NEW
+/*
+ * Allocate an EVP_CIPHER_CTX.
+ * Used if we have an older version of OpenSSL that doesn't provide
+ * routines to allocate and free them.
+ */
+static EVP_CIPHER_CTX *
+EVP_CIPHER_CTX_new(void)
+{
+ EVP_CIPHER_CTX *ctx;
+
+ ctx = malloc(sizeof (EVP_CIPHER_CTX));
+ if (ctx == NULL)
+ return (NULL);
+ memset(ctx, 0, sizeof(*ctx));
+ return (ctx);
+}
+
+static void
+EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
+{
+ EVP_CIPHER_CTX_cleanup(ctx);
+ free(ctx);
+}
+#endif
+
/*
* this will adjust ndo_packetp and ndo_snapend to new buffer!
*/
@@ -129,7 +155,7 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
struct sa_list *sa;
const u_char *iv;
int len;
- EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX *ctx;
/* initiator arg is any non-zero value */
if(initiator) initiator=1;
@@ -157,12 +183,14 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
if(end <= buf) return 0;
- memset(&ctx, 0, sizeof(ctx));
- if (EVP_CipherInit(&ctx, sa->evp, sa->secret, NULL, 0) < 0)
+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx == NULL)
+ return 0;
+ if (EVP_CipherInit(ctx, sa->evp, sa->secret, NULL, 0) < 0)
(*ndo->ndo_warning)(ndo, "espkey init failed");
- EVP_CipherInit(&ctx, NULL, NULL, iv, 0);
- EVP_Cipher(&ctx, buf, buf, len);
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CipherInit(ctx, NULL, NULL, iv, 0);
+ EVP_Cipher(ctx, buf, buf, len);
+ EVP_CIPHER_CTX_free(ctx);
ndo->ndo_packetp = buf;
ndo->ndo_snapend = end;
@@ -568,7 +596,7 @@ esp_print(netdissect_options *ndo,
int ivlen = 0;
const u_char *ivoff;
const u_char *p;
- EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX *ctx;
#endif
esp = (const struct newesp *)bp;
@@ -672,15 +700,18 @@ esp_print(netdissect_options *ndo,
ep = ep - sa->authlen;
if (sa->evp) {
- memset(&ctx, 0, sizeof(ctx));
- if (EVP_CipherInit(&ctx, sa->evp, secret, NULL, 0) < 0)
- (*ndo->ndo_warning)(ndo, "espkey init failed");
-
- p = ivoff;
- EVP_CipherInit(&ctx, NULL, NULL, p, 0);
- EVP_Cipher(&ctx, p + ivlen, p + ivlen, ep - (p + ivlen));
- EVP_CIPHER_CTX_cleanup(&ctx);
- advance = ivoff - (const u_char *)esp + ivlen;
+ ctx = EVP_CIPHER_CTX_new();
+ if (ctx != NULL) {
+ if (EVP_CipherInit(ctx, sa->evp, secret, NULL, 0) < 0)
+ (*ndo->ndo_warning)(ndo, "espkey init failed");
+
+ p = ivoff;
+ EVP_CipherInit(ctx, NULL, NULL, p, 0);
+ EVP_Cipher(ctx, p + ivlen, p + ivlen, ep - (p + ivlen));
+ EVP_CIPHER_CTX_free(ctx);
+ advance = ivoff - (const u_char *)esp + ivlen;
+ } else
+ advance = sizeof(struct newesp);
} else
advance = sizeof(struct newesp);