From 6337e812c52ea63746435236949c651f56927cc0 Mon Sep 17 00:00:00 2001 From: Xavrax Date: Wed, 17 Apr 2024 19:07:19 +0200 Subject: [PATCH] working with MbedLTS init --- CMakeLists.txt | 65 +++++++++++----- README.md | 5 +- freertos/pubnub_config.h | 7 ++ freertos/pubnub_internal.h | 12 +++ mbedtls/pbpal_connect_mbedtls.c | 129 ++++++++++++++++++++++++++++++++ mbedtls/pbpal_mbedtls.c | 65 +++++++++++++++- mbedtls/pubnub_pal.h | 16 ++++ 7 files changed, 280 insertions(+), 19 deletions(-) create mode 100644 mbedtls/pbpal_connect_mbedtls.c create mode 100644 mbedtls/pubnub_pal.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 02ac94f4..7762e2ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ endfunction() message(STATUS "Options (Enabled *):") log_option(OPENSSL "Use OpenSSL" OFF) -log_option(MBEDTLS "Use mbedTLS" OFF) +num_option(MBEDTLS "Use mbedTLS" ON) log_option(EXAMPLES "Build all examples" OFF) log_option(SHARED_LIB "Library type. [SHARED=ON STATIC=OFF]" OFF) log_option(WITH_CPP "Build the CPP headers" OFF) @@ -103,7 +103,8 @@ set(FLAGS "\ -D PUBNUB_USE_GRANT_TOKEN_API=${USE_GRANT_TOKEN_API} \ -D PUBNUB_USE_REVOKE_TOKEN_API=${USE_REVOKE_TOKEN_API} \ -D PUBNUB_USE_FETCH_HISTORY=${USE_FETCH_HISTORY} \ - -D PUBNUB_RAND_INIT_VECTOR=${USE_LEGACY_CRYPTO_RANDOM_IV}") + -D PUBNUB_RAND_INIT_VECTOR=${USE_LEGACY_CRYPTO_RANDOM_IV} \ + -D PUBNUB_MBEDTLS=${MBEDTLS}") set(LDLIBS) set(OS_SOURCEFILES) @@ -379,17 +380,17 @@ if(${USE_REVOKE_TOKEN_API}) ${CMAKE_CURRENT_LIST_DIR}/core/pubnub_revoke_token_api.c) endif() -set(OPENSSL_LINK_LIBRARIES) +set(SSL_LINK_LIBRARIES) if(${OPENSSL}) message(STATUS "Using OpenSSL") if("${OPENSSL_ROOT_DIR}" STREQUAL "") find_package(OpenSSL REQUIRED) - set(OPENSSL_LINK_LIBRARIES OpenSSL::SSL OpenSSL::Crypto) + set(SSL_LINK_LIBRARIES OpenSSL::SSL OpenSSL::Crypto) else() find_package(OpenSSL PATHS ${OPENSSL_ROOT_DIR}) if(OpenSSl_FOUND) - set(OPENSSL_LINK_LIBRARIES OpenSSL::SSL OpenSSL::Crypto) + set(SSL_LINK_LIBRARIES OpenSSL::SSL OpenSSL::Crypto) else() message(STATUS "Searching for custom OpenSSL library") if(WIN32 OR WIN64 OR MSVC) @@ -404,7 +405,7 @@ if(${OPENSSL}) message(STATUS "-> ${OpenSSL}") message(STATUS "-> ${Crypto}") - set(OPENSSL_LINK_LIBRARIES ${OpenSSL} ${Crypto}) + set(SSL_LINK_LIBRARIES ${OpenSSL} ${Crypto}) include_directories(${OPENSSL_ROOT_DIR}/${CUSTOM_OPENSSL_INCLUDE_DIR}) message(STATUS "Used headers:") @@ -444,6 +445,16 @@ if(${OPENSSL}) elseif(WIN32 OR WIN64 OR MSVC) set(FEATURE_SOURCEFILES ${FEATURE_SOURCEFILES} ${CMAKE_CURRENT_LIST_DIR}/openssl/pbpal_add_system_certs_windows.c) endif() +elseif(${MBEDTLS}) + message(STATUS "Using mbedTLS") + + if(NOT ESP_PLATFORM) + # TODO: Add mbedTLS support for generic builds + endif() + + set(SSL_LINK_LIBRARIES + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/pbpal_mbedtls.c + ${CMAKE_CURRENT_LIST_DIR}/mbedtls/pbpal_connect_mbedtls.c) else() set(LIB_SOURCEFILES ${CMAKE_CURRENT_LIST_DIR}/lib/sockets/pbpal_sockets.c @@ -491,6 +502,8 @@ if(NOT ESP_PLATFORM) ${CMAKE_CURRENT_LIST_DIR}/openssl/ ${CMAKE_CURRENT_LIST_DIR}/lib/base64) target_include_directories(pubnub PUBLIC ${OPENSSL_INCLUDE_DIR}) + elseif(${MBEDTLS}) + target_include_directories(pubnub PUBLIC ${CMAKE_CURRENT_LIST_DIR}/mbedtls) else() if(UNIX) target_include_directories(pubnub PUBLIC ${CMAKE_CURRENT_LIST_DIR}/posix) @@ -503,22 +516,40 @@ if(NOT ESP_PLATFORM) endif() endif() - target_link_libraries(pubnub ${LDLIBS} ${OPENSSL_LINK_LIBRARIES}) + target_link_libraries(pubnub ${LDLIBS} ${SSL_LINK_LIBRARIES}) else() message(STATUS "Building ESP32 IDF component") set(EXTRA_CFLAGS ${EXTRA_CFLAGS} ${FLAGS}) - idf_component_register(SRCS ${SOURCEFILES} - INCLUDE_DIRS - ${CMAKE_CURRENT_LIST_DIR} - ${CMAKE_CURRENT_LIST_DIR}/core - ${CMAKE_CURRENT_LIST_DIR}/lib - ${CMAKE_CURRENT_LIST_DIR}/freertos - $ENV{IDF_PATH}/components/freertos/FreeRTOS-Kernel/include/freertos - REQUIRES - freertos - lwip) + if (${MBEDTLS}) + idf_component_register(SRCS ${SOURCEFILES} + INCLUDE_DIRS + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/core + ${CMAKE_CURRENT_LIST_DIR}/lib + ${CMAKE_CURRENT_LIST_DIR}/freertos + ${CMAKE_CURRENT_LIST_DIR}/mbedtls + $ENV{IDF_PATH}/components/freertos/FreeRTOS-Kernel/include/freertos + $ENV{IDF_PATH}/components/mbedtls/mbedtls/include + REQUIRES + freertos + lwip + mbedtls) + else() + idf_component_register(SRCS ${SOURCEFILES} + INCLUDE_DIRS + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/core + ${CMAKE_CURRENT_LIST_DIR}/lib + ${CMAKE_CURRENT_LIST_DIR}/freertos + $ENV{IDF_PATH}/components/freertos/FreeRTOS-Kernel/include/freertos + REQUIRES + freertos + lwip) + endif() + + endif() # TODO: Check if CPP is supported on ESP32 diff --git a/README.md b/README.md index f631d39e..99d45d5a 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,8 @@ For more info check those links: - [posix](posix/README.md), - [windows](windows/README.md), -- [openssl](openssl/), +- [openssl](openssl/README.md), +- [freertos](freertos/README.md), depending on what fits you best. @@ -67,6 +68,8 @@ The directories of the library repository are: - `openssl`: Modules and Makefile(s) for OpenSSL (on POSIX and Windows) +- `mbedtls`: Modules for MBedTLS + - `cpp`: Modules, Makefile(s) and examples for the C++ wrapper - `qt`: Modules, Qt projects and examples for Qt diff --git a/freertos/pubnub_config.h b/freertos/pubnub_config.h index 5fa924e5..c08d4448 100644 --- a/freertos/pubnub_config.h +++ b/freertos/pubnub_config.h @@ -104,5 +104,12 @@ #define PUBNUB_ONLY_PUBSUB_API 0 #endif +#ifndef PUBNUB_USE_SSL +/** If true (!=0), will enable SSL/TLS support. If false (==0), will + disable SSL/TLS support. If not defined, will enable SSL/TLS + support. */ +#define PUBNUB_USE_SSL 1 +#endif + #endif /* !defined INC_PUBNUB_CONFIG */ diff --git a/freertos/pubnub_internal.h b/freertos/pubnub_internal.h index 0b723597..0cac9f1b 100644 --- a/freertos/pubnub_internal.h +++ b/freertos/pubnub_internal.h @@ -79,11 +79,23 @@ typedef int pb_socket_t; #define socket_disable_SIGPIPE(socket) +#ifndef PUBNUB_MBEDTLS +/** Flag to indicate that we are using MBEDTLS library support */ +#define PUBNUB_MBEDTLS 1 +#endif +// TODO: move pubnub_pal to other header to avoid multiple definitions +// of the same struct +// Maybe modularization of the Pubnub library is needed sooner than +// later in this SDK +#if !PUBNUB_MBEDTLS /** The Pubnub FreeRTOS context */ struct pubnub_pal { pb_socket_t socket; }; +#else +#include "mbedtls/pubnub_pal.h" +#endif /** The sockets interface of FreeRTOS+TCP, doesn't provide a non-blocking blocking I/O. Another implementation may be diff --git a/mbedtls/pbpal_connect_mbedtls.c b/mbedtls/pbpal_connect_mbedtls.c new file mode 100644 index 00000000..187d8dd2 --- /dev/null +++ b/mbedtls/pbpal_connect_mbedtls.c @@ -0,0 +1,129 @@ +#include "pubnub_internal.h" + +#if PUBNUB_USE_SSL + +#include "pbpal.h" +#include "pubnub_pal.h" +#include "pubnub_api_types.h" +#include "pubnub_internal_common.h" +#include "pubnub_log.h" + +#ifdef ESP_PLATFORM +#include "esp_crt_bundle.h" +#endif + +#include "mbedtls/ssl.h" + +/* Starfields Inc (Class 2) Root certificate. + It was used to sign the server certificate of https://pubsub.pubnub.com. + (at the time of writing this, 2015-06-04). + */ +static char pubnub_cert_Starfield[] = + "-----BEGIN CERTIFICATE-----\n" + "MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl\n" + "MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp\n" + "U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw\n" + "NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE\n" + "ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp\n" + "ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3\n" + "DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf\n" + "8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN\n" + "+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0\n" + "X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa\n" + "K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA\n" + "1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G\n" + "A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR\n" + "zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0\n" + "YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD\n" + "bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w\n" + "DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3\n" + "L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D\n" + "eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl\n" + "xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp\n" + "VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY\n" + "WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=\n" + "-----END CERTIFICATE-----\n"; + + +/* GlobalSign Root class 2 Certificate, used at the time of this + writing (2016-11-26): + + 2 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA + i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA + + */ +static char pubnub_cert_GlobalSign[] = + "-----BEGIN CERTIFICATE-----\n" + "MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG\n" + "A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\n" + "b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw\n" + "MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i\n" + "YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT\n" + "aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ\n" + "jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp\n" + "xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp\n" + "1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG\n" + "snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ\n" + "U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8\n" + "9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E\n" + "BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B\n" + "AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz\n" + "yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE\n" + "38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP\n" + "AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad\n" + "DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME\n" + "HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n" + "-----END CERTIFICATE-----\n"; + + + +// TODO: https://github.com/espressif/esp-idf/blob/v5.2.1/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c +// reference for mbedtls usage +enum pbpal_tls_result pbpal_start_tls(pubnub_t* pb) +{ + struct pubnub_pal* pal = &pb->pal; + + mbedtls_ssl_init(pal->ssl); + mbedtls_ssl_config_init(pal->ssl_config); + +#ifndef ESP_PLATFORM + // TODO: not implemented yet +#else + if(esp_crt_bundle_attach(pal->ssl_config) != 0) { + PUBNUB_LOG_ERROR("Failed to attach CRT bundle\n"); + return pbtlsFailed; + } +#endif + +#ifdef PUBNUB_ORIGIN_SETTABLE + if (mbedtls_ssl_set_hostname(pal->ssl, pb->origin) != 0) { +#else + if (mbedtls_ssl_set_hostname(pal->ssl, PUBNUB_ORIGIN) != 0) { +#endif + PUBNUB_LOG_ERROR("Failed to set hostname\n"); + return pbtlsFailed; + } + + if (mbedtls_ssl_config_defaults( + pal->ssl_config, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT + ) != 0) { + PUBNUB_LOG_ERROR("Failed to set SSL config defaults\n"); + return pbtlsFailed; + } + + mbedtls_ssl_conf_authmode(pal->ssl_config, MBEDTLS_SSL_VERIFY_REQUIRED); + mbedtls_ssl_conf_ca_chain(pal->ssl_config, pal->ca_certificates, NULL); + + if (mbedtls_ssl_setup(pal->ssl, pal->ssl_config) != 0) { + PUBNUB_LOG_ERROR("Failed to setup SSL\n"); + return pbtlsFailed; + } + + return pbtlsStarted; +} + + +#endif /* PUBNUB_USE_SSL */ diff --git a/mbedtls/pbpal_mbedtls.c b/mbedtls/pbpal_mbedtls.c index 96e7633d..19a61f8f 100644 --- a/mbedtls/pbpal_mbedtls.c +++ b/mbedtls/pbpal_mbedtls.c @@ -1,10 +1,34 @@ +#include "pubnub_internal.h" +#include "pubnub_log.h" + +#if PUBNUB_USE_SSL + #include "pubnub_api_types.h" +#include "pubnub_internal.h" +#include "pubnub_internal_common.h" +#include "pubnub_pal.h" +#include "pubnub_assert.h" #include #include #include +#ifdef ESP_PLATFORM +#include "esp_crt_bundle.h" +#endif + + +static void pbntf_setup(void); +static void options_setup(pubnub_t* pb); +static void buffer_setup(pubnub_t* pb); + + void pbpal_init(pubnub_t* pb) { + memset(&pb->pal, 0, sizeof pb->pal); + + pbntf_setup(); + options_setup(pb); + buffer_setup(pb); } @@ -63,7 +87,7 @@ enum pubnub_res pbpal_read_status(pubnub_t* pb) bool pbpal_closed(pubnub_t* pb) { - return (pb->pal.ssl == NULL) && (pb->pal.socket == SOCKET_INVALID); + return (pb->pal.ssl == NULL); } @@ -82,3 +106,42 @@ int pbpal_close(pubnub_t* pb) void pbpal_free(pubnub_t* pb) { } + +static void pbntf_setup(void) +{ + static bool init_done = false; + + if (init_done) { + return; + } + + pbntf_init(); + init_done = true; +} + + +static void options_setup(pubnub_t* pb) +{ + pb->options.useSSL = true; + pb->options.fallbackSSL = true; + pb->options.use_system_certificate_store = false; + pb->options.reuse_SSL_session = false; + pb->flags.trySSL = false; + pb->ssl_CAfile = NULL; + pb->ssl_CApath = NULL; + pb->ssl_userPEMcert = NULL; + pb->sock_state = STATE_NONE; +#if PUBNUB_USE_MULTIPLE_ADDRESSES + pbpal_multiple_addresses_reset_counters(&pb->spare_addresses); +#endif + +} + + +static void buffer_setup(pubnub_t* pb) +{ + pb->ptr = (uint8_t*)pb->core.http_buf; + pb->left = sizeof pb->core.http_buf / sizeof pb->core.http_buf[0]; +} + +#endif /* defined PUBNUB_USE_SSL */ diff --git a/mbedtls/pubnub_pal.h b/mbedtls/pubnub_pal.h new file mode 100644 index 00000000..0c1b8104 --- /dev/null +++ b/mbedtls/pubnub_pal.h @@ -0,0 +1,16 @@ +#ifndef PUBNUB_PAL_H +#define PUBNUB_PAL_H + +#include +#include + + +/** The Pubnub FreeRTOS context */ +struct pubnub_pal { + mbedtls_ssl_context* ssl; + mbedtls_ssl_config* ssl_config; + mbedtls_x509_crt* ca_certificates; + mbedtls_net_context* net; +}; + +#endif /* PUBNUB_PAL_H */