]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Handle OpenSSL 1.1.x.
authorGuy Harris <[email protected]>
Thu, 23 Jun 2016 04:14:40 +0000 (21:14 -0700)
committerGuy Harris <[email protected]>
Thu, 23 Jun 2016 04:14:40 +0000 (21:14 -0700)
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.

config.h.in
configure
configure.in
print-esp.c

index 6f6bb11aa9ea8858f798e29e922cdcefea9b09be..27ba4b10d7a0fe6ae10279e7630040320b27d270 100644 (file)
@@ -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
 
index a3a3e01e78634b83876a33473215b58a1cd33d8c..aab7239a1671d52bd8a74687f69e9c62de39967a 100755 (executable)
--- 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
 
index 8ceb46bbad9eb1ef1c6dbcb1b7edd7755a79f85a..22ecee6fccb789886626849ca4098675e4b6e27a 100644 (file)
@@ -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
 
index 247796da8426ed64b243f280607bcd957b5d121e..8339a5678a43bcf2c595618416d7b0c4d8dbf1ce 100644 (file)
@@ -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);