Commit Graph

157 Commits

Author SHA1 Message Date
Guy Harris
d44658b2e4 esp: don't use EVP_add_cipher_alias().
It's described in
https://github.com/openssl/openssl/issues/11715#issuecomment-2164442688
as being one of several routines that "are internal macros and not
really suitable for the Brave New Provider World", and the bug in
question complains that they're not documented.

Instead, just map "3des" to "des-ede3-cbc" ourselves.

This should fix #1175.
2024-07-31 22:49:39 -07:00
Guy Harris
749988b236 autotools: use pkg-config and Homebrew when looking for libcrypto.
Grab the stuff from libpcap's configure script that looks for libssl
(and libcrypto) and adapt it to look for libcrypto.

his includes some macros to check using pkg-config (and other macros,
such as macros to save and restore CFLAGS, LIBS, and LDFLAGS; any
resemblance between their names and the cmake_push_check_state() and
cmake_pop_check_state() commands is *entirely* coincidental :-)).

Instead of checking for DES_cbc_encrypt(), which we don't use, to
determine whether the libcrypto we found is usable, check for
EVP_CIPHER_CTX_block_size(), which we *do* use.  (We also check whether
the openssl/evp.h header exists; if it doesn't, we might have found the
libcrypto that Apple bundles with macOS, for which they do *NOT* provide
the header in newer versions of Xcode.)  See also #1174.

This means that we don't need to check whether we have openssl/evp.h at
compile time - now, if we don't, we don't even set HAVE_LIBCRYPTO, so
there's no need to check HAVE_OPENSSL_EVP_H.
2024-07-09 23:04:41 -07:00
Guy Harris
83d7ac7aac esp: report a warning, not an error, for an invalid hex digit in a secret.
We already report a warning if the secret is too long; do so if there's
an invalid hex digit in the secret.

See

https://github.com/the-tcpdump-group/tcpdump/pull/1185#issuecomment-2119211162

While we're at it, put the length of the string, in hex-digit pairs,
into a size_t rather than an unsigned int, just in case (it's unlikely
that it will overflow a 32-bit unsigned integer, but...).
2024-05-19 23:03:32 -07:00
Guy Harris
074d10aa1a esp: mark unreached code as such.
Some compilers might not understand the declaration of the ndo_error
member of an netdissect_options as pointing to a function that never
returns; add a /* NOTREACHED */ comment in case they recognize that as a
hint.
2024-05-19 12:25:59 -07:00
Rose
9b97f85e62 Prefer calloc over malloc
This makes the code cleaner anyway and avoids branching.
2024-04-02 11:19:15 +01:00
Francois-Xavier Le Bail
94a3708f00 Include <config.h> unconditionally
Builds using Autotools or CMake generate config.h, thus remove the
'#ifdef HAVE_CONFIG_H'/'#endif'.

Remove also the 'add_definitions(-DHAVE_CONFIG_H)' in CMakeLists.txt.
2024-03-28 05:34:34 +00:00
Francois-Xavier Le Bail
699711dfb3 Fix a typo
[skip ci]
2022-08-28 21:29:50 +02:00
Francois-Xavier Le Bail
47a7e20a48 ESP: Add a workaround to a "use-of-uninitialized-value"
Found with clang, CFLAGS=-fsanitize=memory.

Fix GitHub issues #848 and #849.

The problem is that for some unknown reason the pt buffer is not
initialized after EVP_DecryptUpdate() call, no error, in:

print-esp.c:260:        if (!EVP_DecryptUpdate(ctx, pt, &len, ct, ctlen)) {
2022-08-12 16:54:37 +02:00
Guy Harris
e84f58700f Fail if nd_push_buffer() or nd_push_snaplen() fails.
Always call ndo->ndo_error with a memory-allocation error if they fail.

Add WARN_UNUSED_RESULT for compilers that support it, and use it for
those routines, so that any future code that doesn't check for failure
gets a warning.
2022-04-01 15:28:33 -07:00
Guy Harris
6a681e6a16 Have routines that set the snapend take a buffer pointer and length as args.
Have nd_push_buffer() take a snapshot length, not a snapshot end, as
its last argument.

Replace nd_push_snapend() and nd_change_snapend() with nd_push_snaplen()
and nd_change_snaplen(), both of which take a pointer into the packet
buffer and snapshot length relative to that pointer as arguments.  Have
those routines check the snapshot length to make sure it's not bigger
than the number of bytes in the packet past the pointer, and silently
ignore the requst if it is.

Using a length rather than a pointer avoids the possibility of the
calculation of the snapshot end overflowing and resulting in a snapshot
end *before* the point in the buffer.

Add a test for this, with a capture file containing an IPv6 packet with
an extremely large "jumbo" packet size.

Revert the "Make sure we don't set the snapend before the beginning of
the packet." changes, as they no longer apply with this change (which
also makes sure we don't set the snapend before the beginning of the
packet).
2022-03-31 02:29:19 -07:00
Francois-Xavier Le Bail
51a470b913 ESP: Add a const qualifier 2022-03-02 17:07:30 +01:00
Francois-Xavier Le Bail
9c9c8a93dd ESP: Put static and int on the same line (style)
[skip ci]
2022-01-19 12:00:22 +01:00
Francois-Xavier Le Bail
bd1adc39f6 Use __func__ from C99 in two function calls 2021-10-31 13:27:20 +01:00
Guy Harris
39f09d68ce Suppress "casting away const" warnings in missing/getopt_long.c.
It's explicitly cheating in some places; just cast away the warnings.

Add a Clang version testing macro to compiler-tests.h.

Move the diagnostic control #defines from netdissect-stdinc.h to
diag-control.h, libpcap-style, so that they can be used by code that
doesn't use (or need) netdissect-stdinc.h.  This also means that we can
limit the inclusion of diag-control.h, and the definition of those

Do them more libpcap-style, with separate DIAG_OFF/DIAG_ON pairs for
particular issues, rather than having DIAG_OFF() and DIAG_ON() macros
that take -W option names as arguments; that way, if we need to define
them for compilers that don't have the GCC/Clang syntax for those
pragmas, e.g. MSVC, we can do so.
2021-07-24 01:51:02 -07:00
Francois-Xavier Le Bail
c4c8ea9a2c ESP: Remove padding, padding length and next header from the buffer
Moreover:
Fix indentation.
2021-02-10 20:55:02 +01:00
Denis Ovsienko
3059f35812 Use __func__ from C99 in error messages. [skip ci]
This automatically fixes a few error messages that would tell an
incorrect function name.
2020-10-08 14:34:25 +01:00
Francois-Xavier Le Bail
6dcc487b7a ESP: Include conditionally "strtoaddr.h" and "ascii_strcasecmp.h" 2020-03-31 17:51:20 +02:00
Francois-Xavier Le Bail
6a66f11096 IPv4/IPv6 demux: Rename a printer
Rename ip_print_demux() to ip_demux_print(), with _print suffix like
in most similar cases.

Moreover:
Rename a test.
2020-03-08 14:07:37 +01:00
Francois-Xavier Le Bail
8c88f9f54a ESP: Rename two printers
Rename esp_print_decodesecret() to esp_decodesecret_print() and
esp_print_decrypt_buffer_by_ikev2() to esp_decrypt_buffer_by_ikev2_print()
with _print suffix like in most similar cases.
2020-03-08 13:41:07 +01:00
Guy Harris
77328e886b Fix #ifdef to test for something we set at configuration time. 2020-01-20 11:19:39 -08:00
Guy Harris
fba80a0b83 Put the crypto stuff into a common routine.
That makes it easier to 1) change it and 2) use different crypto
libraries for it.
2020-01-05 19:25:00 -08:00
Guy Harris
bd22f1fd9a Clean up ESP and ISAKMP decryption.
At least as I read RFC 5996 section 3.14 and RFC 4303 section 2.4, if
the cipher has a block size of which the ciphertext's size must be a
multiple, the payload must be padded to make that happen, so the
ciphertext length must be a multiple of the block size.  Instead of
allocating a buffer, copying the ciphertext to it, and padding it to the
block size, fail if its size isn't a multiple of the block size.

(Note also that the old padding code added a block's worth of padding to
the end of a ciphertext block that *was* a multiple of the cipher block
size; this might have caused problems.)

Don't use the undocumented EVP_Cipher(); the lack of documentation means
a lack of information about whatever requirements it might impose.  Use
EVP_DecryptUpdate() instead.

Before calling it, use EVP_CIPHER_CTX_set_padding() to say "don't do
your own padding, this block is a multiple of the cipher block size".

Instead of using EVP_CipherInit() or EVP_CipherInit_ex(), use
EVP_DecryptInit() or EVP_DecryptInit_ex().  as we're always doing
decryption and never doing encryption - the extra parameter to
EVP_CipherInit() and EVP_CipherInit_ex() is always 0.

This may address GitHub issue #814.

It may also make it a bit easier to have the code use Common Crypto on
macOS (rather than requiring that OpenSSL be installed - macOS ships
with an OpenSSL shared library for binary compatibility with older
releases, but doesn't ship with the headers, because Apple wants you
using their crypto code) and use Cryptography API: Next Generation on
Windows (Vista/Server 2008 and later) (rather than requiring a Windows
build of OpenSSL).

(Hopefully this will all work with LibreSSL.)
2020-01-05 18:37:52 -08:00
Guy Harris
011ae55410 Fix check of authentication algorithm.
If you split a string by overwriting the separator character with a NUL,
and you want to compare the first part with various values, use a
pointer to the beginning of the string, not to the NUL you just dropped
in.

This is a bug found while testing some cleanups for GitHub issue #814;
it's necessary for the cleanups to work.
2020-01-05 17:49:42 -08:00
Guy Harris
9a6a650241 Don't use <ctype.h> macros.
Some of them are locale-dependent, and all of them run the risk of
failing if you hand them a char with the 8th bit set.

Move our replacements to a new netdissect-ctype.h file, and, for the
ones that check for particular character types, add _ASCII to the name,
to indicate that only ASCII characters pass the check.  Do the same for
the ones that map between cases, to indicate that they only map ASCII
letters.

For isspace(), explicitly check for the characters we care about, to
make it clearer what we're doing.
2019-09-01 16:11:32 -07:00
Francois-Xavier Le Bail
0c9cfdcb0d Use nd_ipv6 rather than struct in6_addr 2019-06-10 15:32:20 +02:00
Francois-Xavier Le Bail
6fc5b4200b Use nd_ipv4 rather than struct in_addr 2019-06-10 14:14:46 +02:00
Guy Harris
b7b72b7c63 Treat the length field in an Ethernet header as such.
If we have an Ethernet packet where the last 2 octets of the header are
a length rather than an Ethernet type, and it's less than the remaining
length of the packet, shorten the length and captured length, update the
snapshot end.

Turn the buffer stack into a "packet information" stack, so that, if we
*do* update the snapshot end, we push the old end onto the stack, and
pop it off as soon as we're done dissecting the Ethernet packet, in case
there's more data in the packet after the Ethernet packet.

Use the stack when we use the IPv4 and IPv6 length fields as well.
2019-04-22 23:49:02 -07:00
Francois-Xavier Le Bail
89c54d9bda Remove a trailing space 2019-04-02 14:24:17 +02:00
Guy Harris
6da51b3ec9 Introduce a buffer stack, and use it for ESP decryption.
If a dissector has to process its input - decryption, decompression,
etc. - rather than dissect the raw input, it should push the processed
input onto the buffer stack.  As soon as the dissection is done, the
stack should be popped, to free the buffer into which the processing was
done, and restore the "pointer to packet data" and "pointer to end of
packet data" members of the netdissect_options structure, so the code
can go back to dissecting the original data.

The stack will get everything popped off it when dissection is done.

Use this mechanism in the ESP decryption code rather than scribbling on
top of the input packet data.
2019-03-30 19:26:06 -07:00
Guy Harris
3d9ae63197 Remove "ptr" from the names of pointers into the packet.
The IV pointer is just called iv in esp_print_decrypt_buffer_by_ikev2();
do the same in esp_print().  Rename ctptr to match.
2019-03-30 19:10:27 -07:00
Guy Harris
ada17ed496 Clean up code a bit.
"ivoff" is a pointer to the IV, not the offset of the IV; call it ivptr.

Have a variable that points to the beginning of the ciphertext, and use
that.

Fix the check that makes sure the authentication data/integrity check
value length isn't too big - it needs to make sure that it doesn't go
before the beginning of the ciphertext, i.e. doesn't overlap with the
IV.

Don't bother with a variable pointing to the secret, just pass
sa->secret.

Fix the check that makes sure the padding length isn't too big - make
sure it, plus 2 for the padding length and next header bytes, isn't
bigger than the ciphertext length.

Update a test to reflect the stricter length checks.
2019-03-30 18:08:02 -07:00
Guy Harris
fefd7f527f Clean up the check to make sure we can get the next header field.
Just check whether the pointer to it is within the available packet data
- and, if it's not, report truncation.

While we're at it:

Make the initialization vector length unsigned; it's either zero or a
positive number.

Rename a variable used for the ciphertext len to ctlen.
2019-03-29 16:16:46 -07:00
Guy Harris
a0ac048cf8 Check the return values of set_cipher_parameters() and EVP_Cipher(). 2019-03-29 12:40:20 -07:00
Guy Harris
b0acedad18 Don't hand un-decrypted data to the IP demuxer.
If we can't decrypt the payload, we can't dissect it, so don't try -
just give up immediately.

While we're at it:

If EVP_CIPHER_CTX_new() fails, it means a memory allocation failed;
treat that as such.

Use some of the arguments we're passed rather than re-fetching them from
the IP header.

Add some comments.

Call nd_print_trunc() for failed length sanity checks, and note that
they can fail due to the decryption being done with the wrong key.

Update one test's output; it is, I think, being decrypted with the wrong
key.
2019-03-29 10:52:58 -07:00
Guy Harris
7fbec6b880 Add a length check. 2019-03-28 14:30:33 -07:00
Guy Harris
48644533f2 Have esp_print() handle printing its payload.
That cleans things up a bit, including removing some duplicate code.

Clean up some other things, and add a length check, while we're at it.
2019-03-28 11:45:43 -07:00
Francois-Xavier Le Bail
ee68aa3646 Use the new GET_ macros instead of the EXTRACT_ ones
The exceptions are currently:
Some EXTRACT_ in print-juniper.c, not used on packet buffer pointer.
An EXTRACT_BE_U_3 in addrtoname.c, not always used on packet buffer
pointer.
2019-03-26 21:06:24 +01:00
agnosticdev
50301a252f return-checks: Added a return check for malloc and for strsep 2018-10-08 21:18:52 -05:00
Francois-Xavier Le Bail
e88bf592be ESP: Fix some unreachable code warnings
Found with -Wunreachable-code-return clang compiler option.

The errors were:

./print-esp.c:317:10: warning: 'return' will never be executed
      [-Wunreachable-code-return]
                return 0;
                       ^
./print-esp.c:552:4: warning: 'return' will never be executed
      [-Wunreachable-code-return]
                        return;
                        ^~~~~~
2018-07-17 22:10:57 +02:00
Francois-Xavier Le Bail
dcce77e91d ESP: Fix some unreachable code warnings
Found with -Wunreachable-code clang compiler option.

The errors were:
./print-esp.c:263:3: warning: code will never be executed
                                                 [-Wunreachable-code]
                free(input_buffer);
                ^~~~
./print-esp.c:246:3: warning: code will never be executed
                                                 [-Wunreachable-code]
                EVP_CIPHER_CTX_free(ctx);
                ^~~~~~~~~~~~~~~~~~~
./print-esp.c:843:5: warning: code will never be executed
                                                 [-Wunreachable-code]
                                free(input_buffer);
                                ^~~~
./print-esp.c:826:5: warning: code will never be executed
                                                 [-Wunreachable-code]
                                EVP_CIPHER_CTX_free(ctx);
                                ^~~~~~~~~~~~~~~~~~~
2018-07-08 20:08:07 +02:00
Guy Harris
4ba56b8c2e Encrypted data buffer sizes must also be a multiple of the cipher block size.
This should address the issue in GitHub pull request #680.
2018-05-24 11:45:19 -07:00
Francois-Xavier Le Bail
00ecef01d7 Add more nd_print_trunc() calls
Update the output of some tests accordingly.
2018-05-06 11:26:45 +02:00
Francois-Xavier Le Bail
56e6581c34 Remove useless comments 2018-03-19 15:16:32 +01:00
Francois-Xavier Le Bail
546558eabd Add the ndo_protocol field in the netdissect_options structure
Update this field in printer entry functions.
It will be used for some printings.
2018-03-16 19:44:47 +01:00
Francois-Xavier Le Bail
fa196ecfbe Add a comment on a memory allocation we cannot free 2018-03-12 15:44:10 +01:00
Francois-Xavier Le Bail
5ae22f41a8 Add a status exit code to the function ndo_error()
The status are defined in an enum in status-exit-codes.h.

Moreover:
Use ndo_error() instead of ndo_warning() for malloc() errors in print-esp.c.
2018-02-25 20:58:27 +01:00
Guy Harris
3db38df8ed Use nd_ipv6 rather than struct in6_addr in packet-layout structures.
Also, use it, and nd_ipv4, in sizeof() operations.
2018-01-30 17:29:33 -08:00
Guy Harris
fb2479d733 Always include <config.h> rather than "config.h".
This can prevent bizarre failures if, for example, you've done a
configuration in the top-level source directory, leaving behind one
config.h file, and then do an out-of-tree build in another directory,
with different configuration options.  This way, we always pick up the
same config.h, in the build directory.
2018-01-21 12:27:28 -08:00
Francois-Xavier Le Bail
513f782ae1 Use quoted include netdissect-stdinc.h instead of angle-bracketed one 2018-01-21 10:28:15 +01:00
Guy Harris
64677b0d78 Clean up signed vs. unsigned. 2018-01-11 11:52:30 -08:00