From 430b73776034e62dcdd3541bec6ee0dd47e67d22 Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Wed, 28 Aug 2019 10:03:17 +0100 Subject: [PATCH] Fix libcoap building with various MbedTLS compile time options components/coap/port/coap_mbedtls.c: Add in additional compile time check wrappers for different MbedTLS configurations. components/coap/CMakeLists.txt: components/coap/component.mk: components/coap/port/coap_notls.c: components/coap/port/include/coap_config_posix.h: Add in the ability to compile and run if MbedTLS does not have any TLS mode enabled. examples/protocols/coap_client/main/coap_client_example_main.c: Inform user that MbedTLS Client Mode is required for DTLS if not enabled, and coaps:// has been requested. [Lower libcoap library will still error and report this condition] examples/protocols/coap_server/main/coap_server_example_main.c: Inform user that MbedTLS Server Mode is required for DTLS if not enabled. [Lower libcoap library will still error and report this condition] Closes https://github.com/espressif/esp-idf/issues/3961 Closes https://github.com/espressif/esp-idf/issues/3971 Closes https://github.com/espressif/esp-idf/pull/3977 --- components/coap/CMakeLists.txt | 1 + components/coap/component.mk | 2 +- components/coap/port/coap_mbedtls.c | 49 ++++- components/coap/port/coap_notls.c | 190 ++++++++++++++++++ .../coap/port/include/coap_config_posix.h | 16 +- .../main/coap_client_example_main.c | 13 +- .../main/coap_server_example_main.c | 8 + 7 files changed, 266 insertions(+), 13 deletions(-) create mode 100644 components/coap/port/coap_notls.c diff --git a/components/coap/CMakeLists.txt b/components/coap/CMakeLists.txt index 3b2da20ce8..50c55e7723 100644 --- a/components/coap/CMakeLists.txt +++ b/components/coap/CMakeLists.txt @@ -19,6 +19,7 @@ set(srcs "libcoap/src/subscribe.c" "libcoap/src/uri.c" "libcoap/src/coap_io.c" + "port/coap_notls.c" "port/coap_mbedtls.c") idf_component_register(SRCS "${srcs}" diff --git a/components/coap/component.mk b/components/coap/component.mk index 46f7039870..448a94f6cb 100644 --- a/components/coap/component.mk +++ b/components/coap/component.mk @@ -4,7 +4,7 @@ COMPONENT_ADD_INCLUDEDIRS := port/include port/include/coap libcoap/include libcoap/include/coap2 -COMPONENT_OBJS = libcoap/src/address.o libcoap/src/async.o libcoap/src/block.o libcoap/src/coap_event.o libcoap/src/coap_hashkey.o libcoap/src/coap_session.o libcoap/src/coap_time.o port/coap_debug.o libcoap/src/encode.o libcoap/src/mem.o libcoap/src/net.o libcoap/src/option.o libcoap/src/pdu.o libcoap/src/resource.o libcoap/src/str.o libcoap/src/subscribe.o libcoap/src/uri.o port/coap_mbedtls.o libcoap/src/coap_io.o +COMPONENT_OBJS = libcoap/src/address.o libcoap/src/async.o libcoap/src/block.o libcoap/src/coap_event.o libcoap/src/coap_hashkey.o libcoap/src/coap_session.o libcoap/src/coap_time.o port/coap_debug.o libcoap/src/encode.o libcoap/src/mem.o libcoap/src/net.o libcoap/src/option.o libcoap/src/pdu.o libcoap/src/resource.o libcoap/src/str.o libcoap/src/subscribe.o libcoap/src/uri.o port/coap_mbedtls.o libcoap/src/coap_io.o port/coap_notls.o COMPONENT_SRCDIRS := libcoap/src libcoap port diff --git a/components/coap/port/coap_mbedtls.c b/components/coap/port/coap_mbedtls.c index 9f8c1fab98..4d616e9098 100644 --- a/components/coap/port/coap_mbedtls.c +++ b/components/coap/port/coap_mbedtls.c @@ -188,7 +188,7 @@ coap_dgram_write(void *ctx, const unsigned char *send_buffer, return result; } -#if !defined(ESPIDF_VERSION) || defined(CONFIG_MBEDTLS_SSL_PROTO_DTLS) +#if !defined(ESPIDF_VERSION) || (defined(CONFIG_MBEDTLS_SSL_PROTO_DTLS) && defined(CONFIG_MBEDTLS_TLS_SERVER)) static char* get_ip_addr(const struct coap_address_t *addr) { @@ -222,9 +222,9 @@ get_ip_addr(const struct coap_address_t *addr) } return str; } -#endif /* !ESPIDF_VERSION || CONFIG_MBEDTLS_SSL_PROTO_DTLS */ +#endif /* !ESPIDF_VERSION || (CONFIG_MBEDTLS_SSL_PROTO_DTLS && CONFIG_MBEDTLS_TLS_SERVER) */ -#if !defined(ESPIDF_VERSION) || (defined(CONFIG_MBEDTLS_SSL_PROTO_DTLS) && defined(CONFIG_MBEDTLS_PSK_MODES)) +#if !defined(ESPIDF_VERSION) || (defined(CONFIG_MBEDTLS_SSL_PROTO_DTLS) && defined(CONFIG_MBEDTLS_PSK_MODES) && defined(CONFIG_MBEDTLS_TLS_SERVER)) /* * Server side PSK callback */ @@ -277,7 +277,7 @@ static int psk_server_callback(void *p_info, mbedtls_ssl_context *ssl, mbedtls_ssl_set_hs_psk(ssl, buf, psk_len); return 0; } -#endif /* !ESPIDF_VERSION || CONFIG_MBEDTLS_SSL_PROTO_DTLS */ +#endif /* !ESPIDF_VERSION || (CONFIG_MBEDTLS_SSL_PROTO_DTLS && CONFIG_MBEDTLS_PSK_MODES && CONFIG_MBEDTLS_TLS_SERVER) */ static char* get_san_or_cn_from_cert(mbedtls_x509_crt *crt) @@ -691,6 +691,7 @@ setup_pki_credentials(mbedtls_x509_crt *cacert, return 0; } +#if !defined(ESPIDF_VERSION) || defined(CONFIG_MBEDTLS_TLS_SERVER) /* * PKI SNI callback. */ @@ -763,6 +764,7 @@ end: } return ret; } +#endif /* !ESPIDF_VERSION || CONFIG_MBEDTLS_TLS_SERVER */ #ifdef PSK2_PR /* @@ -836,6 +838,8 @@ end: } #endif /* PSK2_PR */ +#if !defined(ESPIDF_VERSION) || defined(CONFIG_MBEDTLS_TLS_SERVER) + static int setup_server_ssl_session(coap_session_t *c_session, coap_mbedtls_env_t *m_env) { @@ -897,11 +901,12 @@ static int setup_server_ssl_session(coap_session_t *c_session, mbedtls_ssl_conf_dtls_cookies(&m_env->conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, &m_env->cookie_ctx ); - mbedtls_ssl_set_mtu(&m_env->ssl, c_session->mtu); + mbedtls_ssl_set_mtu(&m_env->ssl, c_session->mtu); #endif /* !ESPIDF_VERSION || CONFIG_MBEDTLS_SSL_PROTO_DTLS */ fail: return ret; } +#endif /* !defined(ESPIDF_VERSION) || CONFIG_MBEDTLS_TLS_SERVER) */ #define MAX_CIPHERS 100 static int psk_ciphers[MAX_CIPHERS]; @@ -1043,6 +1048,7 @@ static int setup_client_ssl_session(coap_session_t *c_session, coap_log(LOG_ERR, "PKI setup failed\n"); return ret; } +#if !defined(ESPIDF_VERSION) || defined(CONFIG_MBEDTLS_TLS_SERVER) if (c_session->proto == COAP_PROTO_TLS) { const char *alpn_list[2]; @@ -1053,6 +1059,7 @@ static int setup_client_ssl_session(coap_session_t *c_session, coap_log(LOG_ERR, "ALPN setup failed %d)\n", ret); } } +#endif /* !ESPIDF_VERSION || CONFIG_MBEDTLS_TLS_SERVER */ if (m_context->setup_data.client_sni) { mbedtls_ssl_set_hostname(&m_env->ssl, m_context->setup_data.client_sni); } @@ -1189,10 +1196,12 @@ static coap_mbedtls_env_t *coap_dtls_new_mbedtls_env(coap_session_t *c_session, if (setup_client_ssl_session(c_session, m_env) != 0) { goto fail; } +#if !defined(ESPIDF_VERSION) || defined(CONFIG_MBEDTLS_TLS_SERVER) } else if (role == COAP_DTLS_ROLE_SERVER) { if (setup_server_ssl_session(c_session, m_env) != 0) { goto fail; } +#endif /* !ESPIDF_VERSION || CONFIG_MBEDTLS_TLS_SERVER */ } else { goto fail; } @@ -1251,6 +1260,12 @@ int coap_dtls_context_set_psk(struct coap_context_t *c_context, { coap_mbedtls_context_t *m_context = ((coap_mbedtls_context_t *)c_context->dtls_context); +#if defined(ESPIDF_VERSION) && !defined(CONFIG_MBEDTLS_TLS_SERVER) + coap_log(LOG_EMERG, "coap_dtls_context_set_psk:" + " libcoap not compiled for Server Mode for MbedTLS" + " - update MbedTLS to include Server Mode\n"); + return 0; +#endif /* ESPIDF_VERSION && !CONFIG_MBEDTLS_TLS_SERVER */ m_context->psk_pki_enabled |= IS_PSK; return 1; } @@ -1266,6 +1281,12 @@ coap_dtls_context_set_spsk(coap_context_t *c_context, coap_mbedtls_context_t *m_context = ((coap_mbedtls_context_t *)c_context->dtls_context); +#if defined(ESPIDF_VERSION) && !defined(CONFIG_MBEDTLS_TLS_SERVER) + coap_log(LOG_EMERG, "coap_dtls_context_set_spsk:" + " libcoap not compiled for Server Mode for MbedTLS" + " - update MbedTLS to include Server Mode\n"); + return 0; +#endif /* ESPIDF_VERSION && !CONFIG_MBEDTLS_TLS_SERVER */ if (!m_context || !setup_data) return 0; @@ -1315,6 +1336,7 @@ int coap_dtls_context_set_pki_root_cas(struct coap_context_t *c_context, { coap_mbedtls_context_t *m_context = ((coap_mbedtls_context_t *)c_context->dtls_context); + if (!m_context) { coap_log(LOG_WARNING, "coap_context_set_pki_root_cas: (D)TLS environment " @@ -1383,6 +1405,13 @@ void coap_dtls_free_context(void *dtls_context) void *coap_dtls_new_client_session(coap_session_t *c_session) { +#if defined(ESPIDF_VERSION) && !defined(CONFIG_MBEDTLS_TLS_CLIENT) + (void)c_session; + coap_log(LOG_EMERG, "coap_dtls_new_client_session:" + " libcoap not compiled for Client Mode for MbedTLS" + " - update MbedTLS to include Client Mode\n"); + return NULL; +#else /* !ESPIDF_VERSION || CONFIG_MBEDTLS_TLS_CLIENT */ coap_mbedtls_env_t *m_env = coap_dtls_new_mbedtls_env(c_session, COAP_DTLS_ROLE_CLIENT); int ret; @@ -1395,6 +1424,7 @@ void *coap_dtls_new_client_session(coap_session_t *c_session) } } return m_env; +#endif /* !ESPIDF_VERSION || CONFIG_MBEDTLS_TLS_CLIENT */ } void *coap_dtls_new_server_session(coap_session_t *c_session) @@ -1628,12 +1658,15 @@ int coap_dtls_hello(coap_session_t *c_session, const uint8_t *data, size_t data_len) { -#if defined(ESPIDF_VERSION) && !defined(CONFIG_MBEDTLS_SSL_PROTO_DTLS) +#if defined(ESPIDF_VERSION) && (!defined(CONFIG_MBEDTLS_SSL_PROTO_DTLS) || !defined(CONFIG_MBEDTLS_TLS_SERVER)) (void)c_session; (void)data; (void)data_len; + coap_log(LOG_EMERG, "coap_dtls_hello:" + " libcoap not compiled for DTLS or Server Mode for MbedTLS" + " - update MbedTLS to include DTLS and Server Mode\n"); return -1; -#else /* !ESPIDF_VERSION) || CONFIG_MBEDTLS_SSL_PROTO_DTLS */ +#else /* !ESPIDF_VERSION) || (CONFIG_MBEDTLS_SSL_PROTO_DTLS && CONFIG_MBEDTLS_TLS_SERVER) */ coap_mbedtls_env_t *m_env = (coap_mbedtls_env_t *)c_session->tls; coap_ssl_t *ssl_data = m_env ? &m_env->coap_ssl_data : NULL; int ret; @@ -1697,7 +1730,7 @@ int coap_dtls_hello(coap_session_t *c_session, return 1; } return 0; -#endif /* !ESPIDF_VERSION || CONFIG_MBEDTLS_SSL_PROTO_DTLS */ +#endif /* !ESPIDF_VERSION) || (CONFIG_MBEDTLS_SSL_PROTO_DTLS && CONFIG_MBEDTLS_TLS_SERVER) */ } unsigned int coap_dtls_get_overhead(coap_session_t *c_session UNUSED) diff --git a/components/coap/port/coap_notls.c b/components/coap/port/coap_notls.c new file mode 100644 index 0000000000..aa2c27c688 --- /dev/null +++ b/components/coap/port/coap_notls.c @@ -0,0 +1,190 @@ +/* +* coap_notls.c -- Stub Datagram Transport Layer Support for libcoap +* +* Copyright (C) 2016 Olaf Bergmann +* +* This file is part of the CoAP library libcoap. Please see README for terms +* of use. +*/ + +#include "coap_config.h" + +#if !defined(HAVE_LIBTINYDTLS) && !defined(HAVE_OPENSSL) && !defined(HAVE_LIBGNUTLS) && !defined(HAVE_MBEDTLS) + +#include "net.h" + +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else /* __GNUC__ */ +#define UNUSED +#endif /* __GNUC__ */ + +int +coap_dtls_is_supported(void) { + return 0; +} + +int +coap_tls_is_supported(void) { + return 0; +} + +coap_tls_version_t * +coap_get_tls_library_version(void) { + static coap_tls_version_t version; + version.version = 0; + version.type = COAP_TLS_LIBRARY_NOTLS; + return &version; +} + +int +coap_dtls_context_set_pki(coap_context_t *ctx UNUSED, + coap_dtls_pki_t* setup_data UNUSED, + coap_dtls_role_t role UNUSED +) { + return 0; +} + +int +coap_dtls_context_set_pki_root_cas(struct coap_context_t *ctx UNUSED, + const char *ca_file UNUSED, + const char *ca_path UNUSED +) { + return 0; +} + +int +coap_dtls_context_set_psk(coap_context_t *ctx UNUSED, + const char *hint UNUSED, + coap_dtls_role_t role UNUSED +) { + return 0; +} + +int +coap_dtls_context_check_keys_enabled(coap_context_t *ctx UNUSED) +{ + return 0; +} + +static int dtls_log_level = 0; + +void coap_dtls_startup(void) { +} + +void +coap_dtls_set_log_level(int level) { + dtls_log_level = level; +} + +int +coap_dtls_get_log_level(void) { + return dtls_log_level; +} + +void * +coap_dtls_new_context(struct coap_context_t *coap_context UNUSED) { + return NULL; +} + +void +coap_dtls_free_context(void *handle UNUSED) { +} + +void *coap_dtls_new_server_session(coap_session_t *session UNUSED) { + return NULL; +} + +void *coap_dtls_new_client_session(coap_session_t *session UNUSED) { + return NULL; +} + +void coap_dtls_free_session(coap_session_t *coap_session UNUSED) { +} + +void coap_dtls_session_update_mtu(coap_session_t *session UNUSED) { +} + +int +coap_dtls_send(coap_session_t *session UNUSED, + const uint8_t *data UNUSED, + size_t data_len UNUSED +) { + return -1; +} + +int coap_dtls_is_context_timeout(void) { + return 1; +} + +coap_tick_t coap_dtls_get_context_timeout(void *dtls_context UNUSED) { + return 0; +} + +coap_tick_t +coap_dtls_get_timeout(coap_session_t *session UNUSED, coap_tick_t now UNUSED) { + return 0; +} + +void coap_dtls_handle_timeout(coap_session_t *session UNUSED) { +} + +int +coap_dtls_receive(coap_session_t *session UNUSED, + const uint8_t *data UNUSED, + size_t data_len UNUSED +) { + return -1; +} + +int +coap_dtls_hello(coap_session_t *session UNUSED, + const uint8_t *data UNUSED, + size_t data_len UNUSED +) { + return 0; +} + +unsigned int coap_dtls_get_overhead(coap_session_t *session UNUSED) { + return 0; +} + +void *coap_tls_new_client_session(coap_session_t *session UNUSED, int *connected UNUSED) { + return NULL; +} + +void *coap_tls_new_server_session(coap_session_t *session UNUSED, int *connected UNUSED) { + return NULL; +} + +void coap_tls_free_session(coap_session_t *coap_session UNUSED) { +} + +ssize_t coap_tls_write(coap_session_t *session UNUSED, + const uint8_t *data UNUSED, + size_t data_len UNUSED +) { + return -1; +} + +ssize_t coap_tls_read(coap_session_t *session UNUSED, + uint8_t *data UNUSED, + size_t data_len UNUSED +) { + return -1; +} + +#undef UNUSED + +#else /* !HAVE_LIBTINYDTLS && !HAVE_OPENSSL && !HAVE_LIBGNUTLS */ + +#ifdef __clang__ +/* Make compilers happy that do not like empty modules. As this function is + * never used, we ignore -Wunused-function at the end of compiling this file + */ +#pragma GCC diagnostic ignored "-Wunused-function" +#endif +static inline void dummy(void) { +} + +#endif /* !HAVE_LIBTINYDTLS && !HAVE_OPENSSL && !HAVE_LIBGNUTLS */ diff --git a/components/coap/port/include/coap_config_posix.h b/components/coap/port/include/coap_config_posix.h index dc1166090d..3f6b7c605f 100644 --- a/components/coap/port/include/coap_config_posix.h +++ b/components/coap/port/include/coap_config_posix.h @@ -29,13 +29,27 @@ #define HAVE_TIME_H #define HAVE_NETDB_H #define HAVE_NETINET_IN_H +#define HAVE_STRUCT_CMSGHDR -#define IPV6_PKTINFO IPV6_V6ONLY +#define ipi_spec_dst ipi_addr +struct in6_pktinfo { + struct in6_addr ipi6_addr; /* src/dst IPv6 address */ + unsigned int ipi6_ifindex; /* send/recv interface index */ +}; +#define IN6_IS_ADDR_V4MAPPED(a) \ + ((((__const uint32_t *) (a))[0] == 0) \ + && (((__const uint32_t *) (a))[1] == 0) \ + && (((__const uint32_t *) (a))[2] == htonl (0xffff))) + +/* As not defined, just need to define is as something innocuous */ +#define IPV6_PKTINFO IPV6_CHECKSUM #define PACKAGE_NAME "libcoap-posix" #define PACKAGE_VERSION "?" +#ifdef CONFIG_MBEDTLS_TLS_ENABLED #define HAVE_MBEDTLS +#endif /* CONFIG_MBEDTLS_TLS_ENABLED */ #define COAP_CONSTRAINED_STACK 1 #define ESPIDF_VERSION diff --git a/examples/protocols/coap_client/main/coap_client_example_main.c b/examples/protocols/coap_client/main/coap_client_example_main.c index c7223bc0e6..de7ec60be9 100644 --- a/examples/protocols/coap_client/main/coap_client_example_main.c +++ b/examples/protocols/coap_client/main/coap_client_example_main.c @@ -219,9 +219,12 @@ static void coap_example_client(void *p) break; } - if ((uri.scheme == COAP_URI_SCHEME_COAPS && !coap_dtls_is_supported()) || - (uri.scheme == COAP_URI_SCHEME_COAPS_TCP && !coap_tls_is_supported())) { - ESP_LOGE(TAG, "CoAP server uri scheme is not supported"); + if (uri.scheme == COAP_URI_SCHEME_COAPS && !coap_dtls_is_supported()) { + ESP_LOGE(TAG, "MbedTLS (D)TLS Client Mode not configured"); + break; + } + if (uri.scheme == COAP_URI_SCHEME_COAPS_TCP && !coap_tls_is_supported()) { + ESP_LOGE(TAG, "CoAP server uri coaps+tcp:// scheme is not supported"); break; } @@ -308,6 +311,10 @@ static void coap_example_client(void *p) * but the code is left in for completeness. */ if (uri.scheme == COAP_URI_SCHEME_COAPS || uri.scheme == COAP_URI_SCHEME_COAPS_TCP) { +#ifndef CONFIG_MBEDTLS_TLS_CLIENT + ESP_LOGE(TAG, "MbedTLS (D)TLS Client Mode not configured"); + goto clean_up; +#endif /* CONFIG_MBEDTLS_TLS_CLIENT */ #ifdef CONFIG_COAP_MBEDTLS_PSK session = coap_new_client_session_psk(ctx, NULL, &dst_addr, uri.scheme == COAP_URI_SCHEME_COAPS ? COAP_PROTO_DTLS : COAP_PROTO_TLS, diff --git a/examples/protocols/coap_server/main/coap_server_example_main.c b/examples/protocols/coap_server/main/coap_server_example_main.c index 29bf691223..562c85a833 100644 --- a/examples/protocols/coap_server/main/coap_server_example_main.c +++ b/examples/protocols/coap_server/main/coap_server_example_main.c @@ -252,12 +252,20 @@ static void coap_example_server(void *p) } #if defined(CONFIG_COAP_MBEDTLS_PSK) || defined(CONFIG_COAP_MBEDTLS_PKI) if (coap_dtls_is_supported()) { +#ifndef CONFIG_MBEDTLS_TLS_SERVER + /* This is not critical as unencrypted support is still available */ + ESP_LOGI(TAG, "MbedTLS (D)TLS Server Mode not configured"); +#else /* CONFIG_MBEDTLS_TLS_SERVER */ serv_addr.addr.sin.sin_port = htons(COAPS_DEFAULT_PORT); ep = coap_new_endpoint(ctx, &serv_addr, COAP_PROTO_DTLS); if (!ep) { ESP_LOGE(TAG, "dtls: coap_new_endpoint() failed"); goto clean_up; } +#endif /* CONFIG_MBEDTLS_TLS_SERVER */ + } else { + /* This is not critical as unencrypted support is still available */ + ESP_LOGI(TAG, "MbedTLS (D)TLS Server Mode not configured"); } #endif /* CONFIG_COAP_MBEDTLS_PSK CONFIG_COAP_MBEDTLS_PKI */ resource = coap_resource_init(coap_make_str_const("Espressif"), 0);