Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop support for non-gcrypt builds. #1469

Merged
merged 1 commit into from
Mar 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ A clear and concise description of what happening.
* OS version: [e.g. 18.04]
* Architecture: [e.g. arm64]
* nDPI version or commit hash: [e.g. 4.0-stable or 937357e4bc55610f116f66d15a8e0fc1e260c02c].
* nDPI compilation flags used: if you are building from source [e.g. --with-pcre --disable-gcrypt].
* nDPI compilation flags used: if you are building from source [e.g. --with-pcre --with-local-libgcrypt].
* Attach the `config.log` file generated after `./configure` ran (if you are building from source).

## How to reproduce the reported bug
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
sudo apt-get update
sudo apt-get install autoconf automake libtool pkg-config gettext libjson-c-dev flex bison libpcap-dev
sudo apt-get install rrdtool librrd-dev
sudo apt-get install libgcrypt20-dev libpcre3-dev libmaxminddb-dev lcov
sudo apt-get install libpcre3-dev libmaxminddb-dev lcov
- name: Configure
run: env CC=gcc CFLAGS='-Werror' ./autogen.sh --enable-debug-messages --enable-code-coverage --with-pcre --with-maxminddb
- name: Build
Expand Down Expand Up @@ -51,7 +51,7 @@ jobs:
matrix:
os: ["ubuntu-latest", "ubuntu-18.04", "macOS-latest", "macos-11"]
arch: ["x86_64"]
gcrypt: ["--disable-gcrypt", ""]
gcrypt: ["--with-local-libgcrypt", ""]
compiler: ["default-cc"]
pcre: [""]
maxminddb: [""]
Expand Down Expand Up @@ -151,7 +151,7 @@ jobs:
sudo apt-get install doxygen python3-sphinx python3-sphinx-rtd-theme python3-breathe python3-pip
sudo apt-get install rrdtool librrd-dev
- name: Install Ubuntu Prerequisites (libgcrypt)
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.arch, 'x86_64') && !startsWith(matrix.gcrypt, '--disable-gcrypt')
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.arch, 'x86_64') && startsWith(matrix.gcrypt, '--with-local-libgcrypt')
run: |
sudo apt-get install libgcrypt20-dev
- name: Install Ubuntu Prerequisites (libpcre)
Expand All @@ -177,7 +177,7 @@ jobs:
brew install coreutils
brew install rrdtool
- name: Install MacOS Prerequisites (libgcrypt)
if: startsWith(matrix.os, 'macOS') && startsWith(matrix.arch, 'x86_64') && !startsWith(matrix.gcrypt, '--disable-gcrypt')
if: startsWith(matrix.os, 'macOS') && startsWith(matrix.arch, 'x86_64') && startsWith(matrix.gcrypt, '--with-local-libgcrypt')
run: |
brew install libgcrypt
- name: Install MacOS Prerequisites (libpcre)
Expand Down Expand Up @@ -241,7 +241,7 @@ jobs:
- name: Configure nDPI [Mingw-w64] (runs only on ubuntu jobs)
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.arch, 'x86_64')
run: |
make distclean && ./autogen.sh --host=x86_64-w64-mingw32 ${{ matrix.gcrypt }} ${{ matrix.pcre }} ${{ matrix.maxminddb }}
make distclean && ./autogen.sh --host=x86_64-w64-mingw32 ${{ matrix.pcre }} ${{ matrix.maxminddb }}
- name: Build nDPI [Mingw-w64] (runs only on ubuntu jobs)
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.arch, 'x86_64')
run: |
Expand Down
29 changes: 11 additions & 18 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ AS_IF([test "${with_only_libndpi+set}" = set],[
AC_ARG_WITH(sanitizer, AS_HELP_STRING([--with-sanitizer], [Build with support for address, undefined and leak sanitizer]))
AC_ARG_ENABLE(fuzztargets, AS_HELP_STRING([--enable-fuzztargets], [Enable fuzz targets]),[enable_fuzztargets=$enableval],[enable_fuzztargets=no])
AC_ARG_ENABLE(code-coverage, AS_HELP_STRING([--enable-code-coverage], [Generate Code Coverage report]))
AC_ARG_WITH(libgcrypt, AS_HELP_STRING([--with-libgcrypt], [Build with libgcrypt (if present) instead of the enclosed gcrypt light]))
AC_ARG_WITH(local-libgcrypt, AS_HELP_STRING([--with-local-libgcrypt], [Build with libgcrypt (if present) instead of the enclosed gcrypt light]))

AS_IF([test "x$enable_fuzztargets" = "xyes"], [BUILD_FUZZTARGETS=1], [BUILD_FUZZTARGETS=0])
AM_CONDITIONAL([BUILD_FUZZTARGETS], [test "x$enable_fuzztargets" = "xyes"])
Expand Down Expand Up @@ -238,27 +238,20 @@ AM_CONDITIONAL([HAS_FUZZLDFLAGS], [test "x$has_sanitizefuzzer" = "xyes"])

AC_CHECK_LIB(pthread, pthread_setaffinity_np, AC_DEFINE_UNQUOTED(HAVE_PTHREAD_SETAFFINITY_NP, 1, [libc has pthread_setaffinity_np]))

AS_IF([test "${with_libgcrypt+set}" = set],[
dnl> GCRYPT
GCRYPT_ENABLED=1
AC_ARG_ENABLE([gcrypt],
[AS_HELP_STRING([--disable-gcrypt], [Avoid compiling with libgcrypt/libgpg-error, even if they are present. QUIC sub-classification may be missing])],
[GCRYPT_ENABLED=0],
[AC_CHECK_LIB(gcrypt, gcry_cipher_checktag)])
AS_IF([test ${GCRYPT_ENABLED} -eq 1], [
dnl> libgcrypt (external)
USE_HOST_LIBGCRYPT=0
AS_IF([test "${with_local_libgcrypt+set}" = set],[
USE_HOST_LIBGCRYPT=1
AC_CHECK_LIB(gcrypt, gcry_cipher_checktag)
if test "x$ac_cv_lib_gcrypt_gcry_cipher_checktag" = xyes; then :
ADDITIONAL_LIBS="${ADDITIONAL_LIBS} -lgcrypt"
else
$as_unset ac_cv_lib_gcrypt_gcry_cipher_checktag
AC_CHECK_LIB(gpg-error, gpg_strerror_r)
AC_CHECK_LIB(gcrypt, gcry_cipher_checktag)
if test "x$ac_cv_lib_gcrypt_gcry_cipher_checktag" = xyes -a "x$ac_cv_lib_gpg_error_gpg_strerror_r" = xyes; then :
ADDITIONAL_LIBS="${ADDITIONAL_LIBS} -lgcrypt -lgpg-error"
else
GCRYPT_ENABLED=0
fi
AC_CHECK_LIB(gpg-error, gpg_strerror_r, [], AC_MSG_ERROR([libgpg-error required (because of --with-local-libgcrypt) but not found or too old.]))
AC_CHECK_LIB(gcrypt, gcry_cipher_checktag, [], AC_MSG_ERROR([libgcrypt required (because of --with-local-libgcrypt) but not found or too old.]))
ADDITIONAL_LIBS="${ADDITIONAL_LIBS} -lgcrypt -lgpg-error"
fi
])
AC_DEFINE_UNQUOTED(USE_HOST_LIBGCRYPT, 1, [Use locally installed libgcrypt instead of builtin gcrypt-light])
])

dnl> PCRE
Expand Down Expand Up @@ -314,6 +307,6 @@ AC_SUBST(BUILD_MINGW_X64)
AC_SUBST(BUILD_FUZZTARGETS)
AC_SUBST(JSONC_CFLAGS)
AC_SUBST(JSONC_LIBS)
AC_SUBST(GCRYPT_ENABLED)
AC_SUBST(USE_HOST_LIBGCRYPT)
AC_SUBST(PCRE_ENABLED)
AC_OUTPUT
9 changes: 5 additions & 4 deletions packages/openwrt/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/uclibc++.mk
include $(INCLUDE_DIR)/package.mk

ifeq ($(CONFIG_LIBNDPI_GCRYPT),)
CONFIGURE_ARGS += --disable-gcrypt
ifneq ($(CONFIG_LIBNDPI_GCRYPT),)
CONFIGURE_ARGS += --with-local-libgcrypt
endif

define Package/libndpi
Expand All @@ -47,11 +47,12 @@ endef

define Package/libndpi/config
config LIBNDPI_GCRYPT
bool "GCrypt support"
bool "Use external libgcrypt"
depends on PACKAGE_libndpi
default n
help
This option enables QUIC client hello decryption.
This option enables QUIC client hello decryption through
an external libgcrypt instead of a lightweight builtin version.
Disabled by default.
endef

Expand Down
9 changes: 5 additions & 4 deletions packages/openwrt/Makefile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/uclibc++.mk
include $(INCLUDE_DIR)/package.mk

ifeq ($(CONFIG_LIBNDPI_GCRYPT),)
CONFIGURE_ARGS += --disable-gcrypt
ifneq ($(CONFIG_LIBNDPI_GCRYPT),)
CONFIGURE_ARGS += --with-local-libgcrypt
endif

define Package/libndpi
Expand All @@ -46,11 +46,12 @@ endef

define Package/libndpi/config
config LIBNDPI_GCRYPT
bool "GCrypt support"
bool "Use external libgcrypt"
depends on PACKAGE_libndpi
default n
help
This option enables QUIC client hello decryption.
This option enables QUIC client hello decryption through
an external libgcrypt instead of a lightweight builtin version.
Disabled by default.
endef

Expand Down
6 changes: 6 additions & 0 deletions src/lib/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ NDPI_LIB_STATIC = libndpi.a
NDPI_LIB_SHARED_BASE = libndpi.so
NDPI_LIB_SHARED = $(NDPI_LIB_SHARED_BASE).@NDPI_VERSION_SHORT@
NDPI_LIBS = $(NDPI_LIB_STATIC) $(NDPI_LIB_SHARED)
USE_HOST_LIBGCRYPT = @USE_HOST_LIBGCRYPT@

ifneq ($(USE_HOST_LIBGCRYPT),0)
TMP_OBJS := $(OBJECTS)
OBJECTS = $(filter-out third_party/src/gcrypt_light.o,$(TMP_OBJS))
endif

ifneq ($(OS),Windows_NT)
OS := $(shell uname)
Expand Down
8 changes: 1 addition & 7 deletions src/lib/ndpi_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,10 @@
#include "ahocorasick.h"
#include "libcache.h"

#ifdef HAVE_LIBGCRYPT
#ifdef USE_HOST_LIBGCRYPT
#include <gcrypt.h>
#else
#include <gcrypt_light.h>
#define HAVE_LIBGCRYPT 1
#endif

#include <time.h>
Expand Down Expand Up @@ -2420,7 +2419,6 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs
if(prefs & ndpi_enable_ja3_plus)
ndpi_str->enable_ja3_plus = 1;

#ifdef HAVE_LIBGCRYPT
if(!(prefs & ndpi_dont_init_libgcrypt)) {
if(!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
const char *gcrypt_ver = gcry_check_version(NULL);
Expand All @@ -2436,7 +2434,6 @@ struct ndpi_detection_module_struct *ndpi_init_detection_module(ndpi_init_prefs
} else {
NDPI_LOG_DBG(ndpi_str, "Libgcrypt initialization skipped\n");
}
#endif

if((ndpi_str->protocols_ptree = ndpi_patricia_new(32 /* IPv4 */)) != NULL) {
ndpi_init_ptree_ipv4(ndpi_str, ndpi_str->protocols_ptree, host_protocol_list);
Expand Down Expand Up @@ -7554,10 +7551,7 @@ u_int16_t ndpi_get_api_version() {
}

const char *ndpi_get_gcrypt_version(void) {
#ifdef HAVE_LIBGCRYPT
return gcry_check_version(NULL);
#endif
return NULL;
}

ndpi_proto_defaults_t *ndpi_get_proto_defaults(struct ndpi_detection_module_struct *ndpi_str) {
Expand Down
43 changes: 14 additions & 29 deletions src/lib/protocols/quic.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_QUIC
#include "ndpi_api.h"

#ifdef HAVE_LIBGCRYPT
#ifdef USE_HOST_LIBGCRYPT
#include <gcrypt.h>
#else
#define HAVE_LIBGCRYPT 1
#include <gcrypt_light.h>
#endif

Expand Down Expand Up @@ -124,13 +123,13 @@ static uint8_t get_u8_quic_ver(uint32_t version)

return 0;
}
#ifdef HAVE_LIBGCRYPT

static int is_quic_ver_less_than(uint32_t version, uint8_t max_version)
{
uint8_t u8_ver = get_u8_quic_ver(version);
return u8_ver && u8_ver <= max_version;
}
#endif

static int is_quic_ver_greater_than(uint32_t version, uint8_t min_version)
{
return get_u8_quic_ver(version) >= min_version;
Expand Down Expand Up @@ -191,15 +190,13 @@ int is_version_with_ietf_long_header(uint32_t version)
((version & 0xFFFFFF00) == 0x51303500) /* Q05X */ ||
((version & 0xFFFFFF00) == 0x54303500) /* T05X */;
}
#ifdef HAVE_LIBGCRYPT
int is_version_with_v1_labels(uint32_t version)
{
if(((version & 0xFFFFFF00) == 0x51303500) /* Q05X */ ||
((version & 0xFFFFFF00) == 0x54303500)) /* T05X */
return 1;
return is_quic_ver_less_than(version, 33);
}
#endif

int quic_len(const uint8_t *buf, uint64_t *value)
{
Expand Down Expand Up @@ -246,12 +243,10 @@ static uint16_t gquic_get_u16(const uint8_t *buf, uint32_t version)
}


#if defined(HAVE_LIBGCRYPT)

#ifdef DEBUG_CRYPT
char *__gcry_err(gpg_error_t err, char *buf, size_t buflen)
{
#if defined(HAVE_LIBGPG_ERROR) || defined(LIBGCRYPT_INTERNAL)
#if defined(HAVE_LIBGPG_ERROR) || !defined(USE_HOST_LIBGCRYPT)
gpg_strerror_r(err, buf, buflen);
/* I am not sure if the string will be always null-terminated...
Better safe than sorry */
Expand Down Expand Up @@ -555,7 +550,7 @@ static int quic_hp_cipher_init(quic_hp_cipher *hp_cipher, int hash_algo,
{
uint8_t hp_key[256/8]; /* Maximum key size is for AES256 cipher. */
uint32_t hash_len = gcry_md_get_algo_dlen(hash_algo);
char *label = is_version_with_v1_labels(version) ? "quic hp" : "quicv2 hp";
char const * const label = is_version_with_v1_labels(version) ? "quic hp" : "quicv2 hp";

if(!quic_hkdf_expand_label(hash_algo, secret, hash_len, label, hp_key, key_length)) {
return 0;
Expand All @@ -569,8 +564,8 @@ static int quic_pp_cipher_init(quic_pp_cipher *pp_cipher, int hash_algo,
{
uint8_t write_key[256/8]; /* Maximum key size is for AES256 cipher. */
uint32_t hash_len = gcry_md_get_algo_dlen(hash_algo);
char *key_label = is_version_with_v1_labels(version) ? "quic key" : "quicv2 key";
char *iv_label = is_version_with_v1_labels(version) ? "quic iv" : "quicv2 iv";
char const * const key_label = is_version_with_v1_labels(version) ? "quic key" : "quicv2 key";
char const * const iv_label = is_version_with_v1_labels(version) ? "quic iv" : "quicv2 iv";

if(key_length > sizeof(write_key)) {
return 0;
Expand Down Expand Up @@ -955,7 +950,6 @@ static int quic_derive_initial_secrets(uint32_t version,


static uint8_t *decrypt_initial_packet(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
const uint8_t *dest_conn_id, uint8_t dest_conn_id_len,
uint8_t source_conn_id_len, uint32_t version,
uint32_t *clear_payload_len)
Expand Down Expand Up @@ -1036,8 +1030,6 @@ static uint8_t *decrypt_initial_packet(struct ndpi_detection_module_struct *ndpi
return NULL;
}

#endif /* HAVE_LIBGCRYPT */


static int __reassemble(struct ndpi_flow_struct *flow, const u_int8_t *frag,
uint64_t frag_len, uint64_t frag_offset,
Expand All @@ -1053,7 +1045,7 @@ static int __reassemble(struct ndpi_flow_struct *flow, const u_int8_t *frag,
*/

if(!flow->l4.udp.quic_reasm_buf) {
flow->l4.udp.quic_reasm_buf = ndpi_malloc(max_quic_reasm_buffer_len);
flow->l4.udp.quic_reasm_buf = (uint8_t *)ndpi_malloc(max_quic_reasm_buffer_len);
if(!flow->l4.udp.quic_reasm_buf)
return -1; /* Memory error */
flow->l4.udp.quic_reasm_buf_len = 0;
Expand Down Expand Up @@ -1090,7 +1082,7 @@ static int is_ch_reassembler_pending(struct ndpi_flow_struct *flow)
flow->l4.udp.quic_reasm_buf_len);
}
static const uint8_t *get_reassembled_crypto_data(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
struct ndpi_flow_struct *flow,
const u_int8_t *frag,
uint64_t frag_offset, uint64_t frag_len,
uint64_t *crypto_data_len)
Expand Down Expand Up @@ -1265,15 +1257,12 @@ static const uint8_t *get_crypto_data(struct ndpi_detection_module_struct *ndpi_
}

static uint8_t *get_clear_payload(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
uint32_t version, uint32_t *clear_payload_len)
{
struct ndpi_packet_struct *packet = &ndpi_struct->packet;
u_int8_t *clear_payload;
u_int8_t dest_conn_id_len;
#ifdef HAVE_LIBGCRYPT
u_int8_t source_conn_id_len;
#endif

if(is_gquic_ver_less_than(version, 43)) {
clear_payload = (uint8_t *)&packet->payload[26];
Expand All @@ -1300,16 +1289,13 @@ static uint8_t *get_clear_payload(struct ndpi_detection_module_struct *ndpi_stru
version, dest_conn_id_len);
return NULL;
}
#ifdef HAVE_LIBGCRYPT

source_conn_id_len = packet->payload[6 + dest_conn_id_len];
const u_int8_t *dest_conn_id = &packet->payload[6];
clear_payload = decrypt_initial_packet(ndpi_struct, flow,
clear_payload = decrypt_initial_packet(ndpi_struct,
dest_conn_id, dest_conn_id_len,
source_conn_id_len, version,
clear_payload_len);
#else
clear_payload = NULL;
#endif
}

return clear_payload;
Expand Down Expand Up @@ -1435,7 +1421,6 @@ static void process_chlo(struct ndpi_detection_module_struct *ndpi_struct,


static int may_be_initial_pkt(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
uint32_t *version)
{
struct ndpi_packet_struct *packet = &ndpi_struct->packet;
Expand Down Expand Up @@ -1529,7 +1514,7 @@ static int may_be_initial_pkt(struct ndpi_detection_module_struct *ndpi_struct,
/* ***************************************************************** */

static int eval_extra_processing(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow, u_int32_t version)
struct ndpi_flow_struct *flow, u_int32_t version)
{
/* For the time being we need extra processing in two cases only:
1) to detect Snapchat calls, i.e. RTP/RTCP multiplxed with QUIC.
Expand Down Expand Up @@ -1631,7 +1616,7 @@ static void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct,
* anyone complains...
*/

is_quic = may_be_initial_pkt(ndpi_struct, flow, &version);
is_quic = may_be_initial_pkt(ndpi_struct, &version);
if(!is_quic) {
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
return;
Expand Down Expand Up @@ -1659,7 +1644,7 @@ static void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct,
/*
* 4) Extract the Payload from Initial Packets
*/
clear_payload = get_clear_payload(ndpi_struct, flow, version, &clear_payload_len);
clear_payload = get_clear_payload(ndpi_struct, version, &clear_payload_len);
if(!clear_payload) {
NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
return;
Expand Down
Loading