diff options
author | Guy Harris <guy@alum.mit.edu> | 2017-09-01 04:00:38 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2017-09-01 04:00:38 -0700 |
commit | 6f0750ee0c5e19c6c2586d4d3ffa897853b8341b (patch) | |
tree | 4b3b582b96473ff8b49a0787ecb5a7c236330bdf /print-esp.c | |
parent | 0d2cdb5dad1a983d0e1884497e439efb39c9609d (diff) | |
download | tcpdump-6f0750ee0c5e19c6c2586d4d3ffa897853b8341b.tar.gz |
Make the ESP decryption not crash with OpenSSL 1.1.
While we're at it, free the cipher context if we fail to allocate the
output buffer for decryption.
Diffstat (limited to 'print-esp.c')
-rw-r--r-- | print-esp.c | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/print-esp.c b/print-esp.c index f2b4ab3c..d12b97da 100644 --- a/print-esp.c +++ b/print-esp.c @@ -145,6 +145,39 @@ EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) } #endif +#ifdef HAVE_EVP_CIPHERINIT_EX +/* + * Initialize the cipher by calling EVP_CipherInit_ex(), because + * calling EVP_CipherInit() will reset the cipher context, clearing + * the cipher, so calling it twice, with the second call having a + * null cipher, will clear the already-set cipher. EVP_CipherInit_ex(), + * however, won't reset the cipher context, so you can use it to specify + * the IV oin a second call after a first call to EVP_CipherInit_ex() + * to set the cipher and the key. + * + * XXX - is there some reason why we need to make two calls? + */ +static int +set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, + const unsigned char *iv, int enc) +{ + return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc); +} +#else +/* + * Initialize the cipher by calling EVP_CipherInit(), because we don't + * have EVP_CipherInit_ex(); we rely on it not trashing the context. + */ +static int +set_cipher_parameters(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, + const unsigned char *iv, int enc) +{ + return EVP_CipherInit(ctx, cipher, key, iv, enc); +} +#endif + /* * this will adjust ndo_packetp and ndo_snapend to new buffer! */ @@ -190,9 +223,9 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo, ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) return 0; - if (EVP_CipherInit(ctx, sa->evp, sa->secret, NULL, 0) < 0) + if (set_cipher_parameters(ctx, sa->evp, sa->secret, NULL, 0) < 0) (*ndo->ndo_warning)(ndo, "espkey init failed"); - EVP_CipherInit(ctx, NULL, NULL, iv, 0); + set_cipher_parameters(ctx, NULL, NULL, iv, 0); /* * Allocate a buffer for the decrypted data. * The output buffer must be separate from the input buffer, and @@ -203,6 +236,7 @@ int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo, output_buffer = (u_char *)malloc(output_buffer_size); if (output_buffer == NULL) { (*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer"); + EVP_CIPHER_CTX_free(ctx); return 0; } EVP_Cipher(ctx, output_buffer, buf, len); @@ -735,11 +769,11 @@ esp_print(netdissect_options *ndo, if (sa->evp) { ctx = EVP_CIPHER_CTX_new(); if (ctx != NULL) { - if (EVP_CipherInit(ctx, sa->evp, secret, NULL, 0) < 0) + if (set_cipher_parameters(ctx, sa->evp, secret, NULL, 0) < 0) (*ndo->ndo_warning)(ndo, "espkey init failed"); p = ivoff; - EVP_CipherInit(ctx, NULL, NULL, p, 0); + set_cipher_parameters(ctx, NULL, NULL, p, 0); len = ep - (p + ivlen); /* @@ -753,6 +787,7 @@ esp_print(netdissect_options *ndo, output_buffer = (u_char *)malloc(output_buffer_size); if (output_buffer == NULL) { (*ndo->ndo_warning)(ndo, "can't allocate memory for decryption buffer"); + EVP_CIPHER_CTX_free(ctx); return -1; } |