diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 62dda0ad..6a41dbb8 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -14,7 +14,7 @@ jobs: matrix: cc: [gcc, clang, g++, clang++] target: [test, mip_test] - ssl: ["", BUILTIN, MBEDTLS, OPENSSL] #, WOLFSSL] + ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL] select: ["-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=0", "-DMG_ENABLE_POLL=1 -DMG_ENABLE_EPOLL=0", "-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=1"] exclude: - ssl: MBEDTLS @@ -43,7 +43,7 @@ jobs: strategy: fail-fast: false matrix: - ssl: [""] + ssl: ["", BUILTIN] name: S390 SSL=${{ matrix.ssl }} steps: - uses: actions/checkout@v4 @@ -65,7 +65,7 @@ jobs: strategy: fail-fast: false matrix: - ssl: ["", BUILTIN, MBEDTLS, OPENSSL] #, WOLFSSL] + ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL] name: unamalgamated-mg_prefix SSL=${{ matrix.ssl }} steps: - uses: actions/checkout@v4 @@ -77,7 +77,7 @@ jobs: strategy: fail-fast: false matrix: - ssl: ["", BUILTIN, MBEDTLS, OPENSSL] #, WOLFSSL] + ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL] name: Valgrind SSL=${{ matrix.ssl }} steps: - uses: actions/checkout@v4 @@ -89,7 +89,7 @@ jobs: strategy: fail-fast: false matrix: - ssl: ["", BUILTIN, MBEDTLS, OPENSSL] #, WOLFSSL] + ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL] select: [-DMG_ENABLE_POLL=0, -DMG_ENABLE_POLL=1] exclude: - ssl: MBEDTLS @@ -106,7 +106,7 @@ jobs: steps: - uses: actions/checkout@v4 with: { fetch-depth: 2 } - - run: brew install jq mbedtls openssl wolfssl + - run: brew install mbedtls wolfssl # jq openssl already pre-installed - run: make -C test test ASAN_OPTIONS= MBEDTLS=$(echo $(brew --cellar)/mbedtls*/*) OPENSSL=$(echo $(brew --cellar)/openssl*/*) WOLFSSL=$(echo $(brew --cellar)/wolfssl*/*) windows: runs-on: ubuntu-latest @@ -158,7 +158,7 @@ jobs: name: examples ${{ matrix.ssl }} steps: - uses: actions/checkout@v4 - - run: sudo apt -y install libmbedtls-dev libwolfssl-dev libpcap-dev + - run: sudo apt -y install libpcap-dev - run: make -C test examples CFLAGS_EXTRA="${{ matrix.ssl }}" - run: make -C test clean_examples examples_win: @@ -243,7 +243,7 @@ jobs: name: tutorials ${{ matrix.ssl }} steps: - uses: actions/checkout@v4 - - run: sudo apt -y install libmbedtls-dev libwolfssl-dev libpcap-dev + - run: sudo apt -y install libpcap-dev - run: make -C test tutorials CFLAGS_EXTRA="${{ matrix.ssl }}" - run: make -C test clean_tutorials tutorials_win: diff --git a/mongoose.c b/mongoose.c index f67ce7e9..3fc0e14a 100644 --- a/mongoose.c +++ b/mongoose.c @@ -4659,7 +4659,7 @@ static bool mg_atone(struct mg_str str, struct mg_addr *addr) { static bool mg_aton4(struct mg_str str, struct mg_addr *addr) { uint8_t data[4] = {0, 0, 0, 0}; - size_t i, num_dots = 0; // TODO(): refactor to mg_span() + mg_str_num() + size_t i, num_dots = 0; for (i = 0; i < str.len; i++) { if (str.buf[i] >= '0' && str.buf[i] <= '9') { int octet = data[num_dots] * 10 + (str.buf[i] - '0'); @@ -4705,7 +4705,7 @@ static bool mg_aton6(struct mg_str str, struct mg_addr *addr) { if ((str.buf[i] >= '0' && str.buf[i] <= '9') || (str.buf[i] >= 'a' && str.buf[i] <= 'f') || (str.buf[i] >= 'A' && str.buf[i] <= 'F')) { - unsigned long val; // TODO(): This loops, refactor + unsigned long val; // TODO(): This loops on chars, refactor if (i > j + 3) return false; // MG_DEBUG(("%lu %lu [%.*s]", i, j, (int) (i - j + 1), &str.buf[j])); mg_str_to_num(mg_str_n(&str.buf[j], i - j + 1), 16, &val, sizeof(val)); @@ -10904,8 +10904,9 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { if (c->is_listening) goto fail; MG_DEBUG(("%lu Setting TLS", c->id)); MG_PROF_ADD(c, "mbedtls_init_start"); -#if defined(MBEDTLS_PSA_CRYPTO_C) - psa_crypto_init(); +#if defined(MBEDTLS_VERSION_NUMBER) && MBEDTLS_VERSION_NUMBER >= 0x03000000 && \ + defined(MBEDTLS_PSA_CRYPTO_C) + psa_crypto_init(); // https://github.com/Mbed-TLS/mbedtls/issues/9072#issuecomment-2084845711 #endif mbedtls_ssl_init(&tls->ssl); mbedtls_ssl_config_init(&tls->conf); @@ -11034,7 +11035,8 @@ void mg_tls_ctx_free(struct mg_mgr *mgr) { -#if MG_TLS == MG_TLS_OPENSSL +#if MG_TLS == MG_TLS_OPENSSL || MG_TLS == MG_TLS_WOLFSSL + static int tls_err_cb(const char *s, size_t len, void *c) { int n = (int) len - 1; MG_ERROR(("%lu %.*s", ((struct mg_connection *) c)->id, n, s)); @@ -11094,13 +11096,12 @@ static X509 *load_cert(struct mg_str s) { return cert; } - static long mg_bio_ctrl(BIO *b, int cmd, long larg, void *pargs) { long ret = 0; if (cmd == BIO_CTRL_PUSH) ret = 1; if (cmd == BIO_CTRL_POP) ret = 1; if (cmd == BIO_CTRL_FLUSH) ret = 1; -#ifndef OPENSSL_IS_WOLFSSL +#if MG_TLS == MG_TLS_OPENSSL if (cmd == BIO_C_SET_NBIO) ret = 1; #endif // MG_DEBUG(("%d -> %ld", cmd, ret)); @@ -11163,6 +11164,13 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { SSL_set_options(tls->ssl, SSL_OP_CIPHER_SERVER_PREFERENCE); #endif +#if MG_TLS == MG_TLS_WOLFSSL && !defined(OPENSSL_COMPATIBLE_DEFAULTS) + if (opts->ca.len == 0 || mg_strcmp(opts->ca, mg_str("*")) == 0) { + // Older versions require that either the CA is loaded or SSL_VERIFY_NONE + // explicitly set + SSL_set_verify(tls->ssl, SSL_VERIFY_NONE, NULL); + } +#endif if (opts->ca.buf != NULL && opts->ca.buf[0] != '\0') { SSL_set_verify(tls->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); @@ -11194,21 +11202,25 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { } SSL_set_mode(tls->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); -#if OPENSSL_VERSION_NUMBER > 0x10002000L && !defined(OPENSSL_IS_WOLFSSL) +#if MG_TLS == MG_TLS_OPENSSL && OPENSSL_VERSION_NUMBER > 0x10002000L (void) SSL_set_ecdh_auto(tls->ssl, 1); #endif #if OPENSSL_VERSION_NUMBER >= 0x10100000L if (opts->name.len > 0) { char *s = mg_mprintf("%.*s", (int) opts->name.len, opts->name.buf); +#if MG_TLS != MG_TLS_WOLFSSL || LIBWOLFSSL_VERSION_HEX >= 0x05005002 SSL_set1_host(tls->ssl, s); +#else + X509_VERIFY_PARAM_set1_host(SSL_get0_param(tls->ssl), s, 0); +#endif SSL_set_tlsext_host_name(tls->ssl, s); free(s); } #endif -#ifndef OPENSSL_IS_WOLFSSL - tls->bm = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, "bio_mg"); -#else +#if MG_TLS == MG_TLS_WOLFSSL tls->bm = BIO_meth_new(0, "bio_mg"); +#else + tls->bm = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, "bio_mg"); #endif BIO_meth_set_write(tls->bm, mg_bio_write); BIO_meth_set_read(tls->bm, mg_bio_read); diff --git a/mongoose.h b/mongoose.h index 9c78f683..d2d06ef1 100644 --- a/mongoose.h +++ b/mongoose.h @@ -2147,6 +2147,7 @@ void mg_http_serve_ssi(struct mg_connection *c, const char *root, #define MG_TLS_NONE 0 // No TLS support #define MG_TLS_MBED 1 // mbedTLS #define MG_TLS_OPENSSL 2 // OpenSSL +#define MG_TLS_WOLFSSL 5 // WolfSSL (based on OpenSSL) #define MG_TLS_BUILTIN 3 // Built-in #define MG_TLS_CUSTOM 4 // Custom implementation @@ -2214,7 +2215,7 @@ struct mg_tls { #endif -#if MG_TLS == MG_TLS_OPENSSL +#if MG_TLS == MG_TLS_OPENSSL || MG_TLS == MG_TLS_WOLFSSL #include #include @@ -2917,6 +2918,49 @@ struct mg_tcpip_driver_tm4c_data { #endif +#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_W5500) && MG_ENABLE_DRIVER_W5500 + +#undef MG_ENABLE_TCPIP_DRIVER_INIT +#define MG_ENABLE_TCPIP_DRIVER_INIT 0 + +#endif + + +#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC7) && MG_ENABLE_DRIVER_XMC7 + +struct mg_tcpip_driver_xmc7_data { + int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5 + uint8_t phy_addr; +}; + +#ifndef MG_TCPIP_PHY_ADDR +#define MG_TCPIP_PHY_ADDR 0 +#endif + +#ifndef MG_DRIVER_MDC_CR +#define MG_DRIVER_MDC_CR 3 +#endif + +#define MG_TCPIP_DRIVER_INIT(mgr) \ + do { \ + static struct mg_tcpip_driver_xmc7_data driver_data_; \ + static struct mg_tcpip_if mif_; \ + driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \ + driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \ + mif_.ip = MG_TCPIP_IP; \ + mif_.mask = MG_TCPIP_MASK; \ + mif_.gw = MG_TCPIP_GW; \ + mif_.driver = &mg_tcpip_driver_xmc7; \ + mif_.driver_data = &driver_data_; \ + MG_SET_MAC_ADDRESS(mif_.mac); \ + mg_tcpip_init(mgr, &mif_); \ + MG_INFO(("Driver: xmc7, MAC: %M", mg_print_mac, mif_.mac)); \ + } while (0) + +#endif + + + #if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC) && MG_ENABLE_DRIVER_XMC struct mg_tcpip_driver_xmc_data { @@ -2963,41 +3007,6 @@ struct mg_tcpip_driver_xmc_data { #endif - -#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_XMC7) && MG_ENABLE_DRIVER_XMC7 - -struct mg_tcpip_driver_xmc7_data { - int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5 - uint8_t phy_addr; -}; - -#ifndef MG_TCPIP_PHY_ADDR -#define MG_TCPIP_PHY_ADDR 0 -#endif - -#ifndef MG_DRIVER_MDC_CR -#define MG_DRIVER_MDC_CR 3 -#endif - -#define MG_TCPIP_DRIVER_INIT(mgr) \ - do { \ - static struct mg_tcpip_driver_xmc7_data driver_data_; \ - static struct mg_tcpip_if mif_; \ - driver_data_.mdc_cr = MG_DRIVER_MDC_CR; \ - driver_data_.phy_addr = MG_TCPIP_PHY_ADDR; \ - mif_.ip = MG_TCPIP_IP; \ - mif_.mask = MG_TCPIP_MASK; \ - mif_.gw = MG_TCPIP_GW; \ - mif_.driver = &mg_tcpip_driver_xmc7; \ - mif_.driver_data = &driver_data_; \ - MG_SET_MAC_ADDRESS(mif_.mac); \ - mg_tcpip_init(mgr, &mif_); \ - MG_INFO(("Driver: xmc7, MAC: %M", mg_print_mac, mif_.mac)); \ - } while (0) - -#endif - - #ifdef __cplusplus } #endif diff --git a/src/tls.h b/src/tls.h index dbcb1124..95376c1a 100644 --- a/src/tls.h +++ b/src/tls.h @@ -3,6 +3,7 @@ #define MG_TLS_NONE 0 // No TLS support #define MG_TLS_MBED 1 // mbedTLS #define MG_TLS_OPENSSL 2 // OpenSSL +#define MG_TLS_WOLFSSL 5 // WolfSSL (based on OpenSSL) #define MG_TLS_BUILTIN 3 // Built-in #define MG_TLS_CUSTOM 4 // Custom implementation diff --git a/src/tls_openssl.c b/src/tls_openssl.c index 2840da62..9d73aa9f 100644 --- a/src/tls_openssl.c +++ b/src/tls_openssl.c @@ -1,7 +1,8 @@ #include "printf.h" #include "tls.h" -#if MG_TLS == MG_TLS_OPENSSL +#if MG_TLS == MG_TLS_OPENSSL || MG_TLS == MG_TLS_WOLFSSL + static int tls_err_cb(const char *s, size_t len, void *c) { int n = (int) len - 1; MG_ERROR(("%lu %.*s", ((struct mg_connection *) c)->id, n, s)); @@ -61,13 +62,12 @@ static X509 *load_cert(struct mg_str s) { return cert; } - static long mg_bio_ctrl(BIO *b, int cmd, long larg, void *pargs) { long ret = 0; if (cmd == BIO_CTRL_PUSH) ret = 1; if (cmd == BIO_CTRL_POP) ret = 1; if (cmd == BIO_CTRL_FLUSH) ret = 1; -#ifndef OPENSSL_IS_WOLFSSL +#if MG_TLS == MG_TLS_OPENSSL if (cmd == BIO_C_SET_NBIO) ret = 1; #endif // MG_DEBUG(("%d -> %ld", cmd, ret)); @@ -130,6 +130,13 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { SSL_set_options(tls->ssl, SSL_OP_CIPHER_SERVER_PREFERENCE); #endif +#if MG_TLS == MG_TLS_WOLFSSL && !defined(OPENSSL_COMPATIBLE_DEFAULTS) + if (opts->ca.len == 0 || mg_strcmp(opts->ca, mg_str("*")) == 0) { + // Older versions require that either the CA is loaded or SSL_VERIFY_NONE + // explicitly set + SSL_set_verify(tls->ssl, SSL_VERIFY_NONE, NULL); + } +#endif if (opts->ca.buf != NULL && opts->ca.buf[0] != '\0') { SSL_set_verify(tls->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); @@ -161,21 +168,25 @@ void mg_tls_init(struct mg_connection *c, const struct mg_tls_opts *opts) { } SSL_set_mode(tls->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); -#if OPENSSL_VERSION_NUMBER > 0x10002000L && !defined(OPENSSL_IS_WOLFSSL) +#if MG_TLS == MG_TLS_OPENSSL && OPENSSL_VERSION_NUMBER > 0x10002000L (void) SSL_set_ecdh_auto(tls->ssl, 1); #endif #if OPENSSL_VERSION_NUMBER >= 0x10100000L if (opts->name.len > 0) { char *s = mg_mprintf("%.*s", (int) opts->name.len, opts->name.buf); +#if MG_TLS != MG_TLS_WOLFSSL || LIBWOLFSSL_VERSION_HEX >= 0x05005002 SSL_set1_host(tls->ssl, s); +#else + X509_VERIFY_PARAM_set1_host(SSL_get0_param(tls->ssl), s, 0); +#endif SSL_set_tlsext_host_name(tls->ssl, s); free(s); } #endif -#ifndef OPENSSL_IS_WOLFSSL - tls->bm = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, "bio_mg"); -#else +#if MG_TLS == MG_TLS_WOLFSSL tls->bm = BIO_meth_new(0, "bio_mg"); +#else + tls->bm = BIO_meth_new(BIO_get_new_index() | BIO_TYPE_SOURCE_SINK, "bio_mg"); #endif BIO_meth_set_write(tls->bm, mg_bio_write); BIO_meth_set_read(tls->bm, mg_bio_read); diff --git a/src/tls_openssl.h b/src/tls_openssl.h index d203dc5d..44b57dc6 100644 --- a/src/tls_openssl.h +++ b/src/tls_openssl.h @@ -1,6 +1,6 @@ #pragma once -#if MG_TLS == MG_TLS_OPENSSL +#if MG_TLS == MG_TLS_OPENSSL || MG_TLS == MG_TLS_WOLFSSL #include #include diff --git a/test/Makefile b/test/Makefile index 6dbd0754..fca1c48f 100644 --- a/test/Makefile +++ b/test/Makefile @@ -41,22 +41,39 @@ else C_WARN ?= -Wno-deprecated endif -ifeq "$(SSL)" "MBEDTLS" -MBEDTLS ?= /usr/local -CFLAGS += -DMG_TLS=MG_TLS_MBED -I$(MBEDTLS)/include -I/usr/include -LDFLAGS += -L$(MBEDTLS)/lib -lmbedtls -lmbedcrypto -lmbedx509 -endif - ifeq "$(SSL)" "OPENSSL" -OPENSSL ?= /usr/local +ifeq "$(OPENSSL)" "" +CFLAGS += -DMG_TLS=MG_TLS_OPENSSL $(shell pkg-config openssl --cflags) +LDFLAGS += $(shell pkg-config openssl --libs) +else CFLAGS += -DMG_TLS=MG_TLS_OPENSSL -I$(OPENSSL)/include LDFLAGS += -L$(OPENSSL)/lib -lssl -lcrypto endif +endif + +ifeq "$(SSL)" "MBEDTLS" +ifeq "$(MBEDTLS)" "" +# Ubuntu 22.04 does not provide 'pc' files for MbedTLS (others may) +#CFLAGS += -DMG_TLS=MG_TLS_MBED $(shell pkg-config mbedtls --cflags) $(shell pkg-config mbedcrypto --cflags) $(shell pkg-config mbedx509 --cflags) +#LDFLAGS += $(shell pkg-config mbedtls --libs) $(shell pkg-config mbedcrypto --libs) $(shell pkg-config mbedx509 --libs) +CFLAGS += -DMG_TLS=MG_TLS_MBED -I/usr/include +LDFLAGS += -lmbedtls -lmbedcrypto -lmbedx509 +else +CFLAGS += -DMG_TLS=MG_TLS_MBED -I$(MBEDTLS)/include -I/usr/include +LDFLAGS += -L$(MBEDTLS)/lib -lmbedtls -lmbedcrypto -lmbedx509 +endif +endif ifeq "$(SSL)" "WOLFSSL" -WOLFSSL ?= /usr/local -CFLAGS += -DMG_TLS=MG_TLS_OPENSSL -I$(WOLFSSL)/include -I$(WOLFSSL)/include/wolfssl -DEXTERNAL_OPTS_OPENVPN +# WolfSSL requires overriding the include path when used in OpenSSL compatibility mode (we do) +#ifeq "$(WOLFSSL)" "" +#CFLAGS += -DMG_TLS=MG_TLS_WOLFSSL -DEXTERNAL_OPTS_OPENVPN $(shell pkg-config openssl --cflags) +#LDFLAGS += $(shell pkg-config wolfssl --libs) +#else +WOLFSSL ?= $(shell pkg-config wolfssl --variable=prefix) +CFLAGS += -DMG_TLS=MG_TLS_WOLFSSL -DEXTERNAL_OPTS_OPENVPN -I$(WOLFSSL)/include -I$(WOLFSSL)/include/wolfssl LDFLAGS += -L$(WOLFSSL)/lib -lwolfssl +#endif endif ifeq "$(SSL)" "BUILTIN"