diff --git a/CHANGELOG b/CHANGELOG index e64ef485..11edb14b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,6 @@ Changes to version 1.3.0 ------------------------ -- HAL: unified platform abstraction layer (to simply use together with lib60870) +- HAL: unified platform abstraction layer (to simplify using the library together with lib60870) - IEC 61850 server: fixed bug when calling write access handler (wrong pointer for ClientConnection object) - updated IEC 61850-9-2 LE example to be more realistic - added server side example for the substitution service diff --git a/CMakeLists.txt b/CMakeLists.txt index 5afc22fb..c4d457a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,7 +72,6 @@ include_directories( ${CMAKE_CURRENT_LIST_DIR}/src/mms/inc_private ${CMAKE_CURRENT_LIST_DIR}/src/mms/iso_mms/asn1c ${CMAKE_CURRENT_LIST_DIR}/src/logging - ${CMAKE_CURRENT_LIST_DIR}/src/tls ) set(API_HEADERS @@ -80,12 +79,13 @@ set(API_HEADERS hal/inc/hal_thread.h hal/inc/hal_filesystem.h hal/inc/hal_ethernet.h + hal/inc/tls_config.h hal/inc/platform_endian.h + hal/inc/lib_memory.h src/common/inc/libiec61850_common_api.h src/common/inc/libiec61850_platform_includes.h src/common/inc/linked_list.h src/common/inc/byte_buffer.h - src/common/inc/lib_memory.h src/common/inc/string_utilities.h src/iec61850/inc/iec61850_client.h src/iec61850/inc/iec61850_common.h @@ -112,7 +112,6 @@ set(API_HEADERS src/sampled_values/sv_subscriber.h src/sampled_values/sv_publisher.h src/logging/logging_api.h - src/tls/tls_api.h ${CMAKE_CURRENT_BINARY_DIR}/config/stack_config.h ) @@ -145,7 +144,6 @@ configure_file( ${CMAKE_CURRENT_BINARY_DIR}/config/stack_config.h ) -#include("${CMAKE_CURRENT_LIST_DIR}/hal/CMakeLists.txt") include_directories( ${CMAKE_CURRENT_LIST_DIR}/hal/inc ) diff --git a/Makefile b/Makefile index 58562b28..1c6ce571 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,7 @@ LIB_SOURCE_DIRS += hal/ethernet/win32 LIB_SOURCE_DIRS += hal/filesystem/win32 LIB_SOURCE_DIRS += hal/time/win32 LIB_SOURCE_DIRS += hal/serial/win32 +LIB_SOURCE_DIRS += hal/memory else ifeq ($(HAL_IMPL), POSIX) LIB_SOURCE_DIRS += hal/socket/linux LIB_SOURCE_DIRS += hal/thread/linux @@ -44,12 +45,14 @@ LIB_SOURCE_DIRS += hal/ethernet/linux LIB_SOURCE_DIRS += hal/filesystem/linux LIB_SOURCE_DIRS += hal/time/unix LIB_SOURCE_DIRS += hal/serial/linux +LIB_SOURCE_DIRS += hal/memory else ifeq ($(HAL_IMPL), BSD) LIB_SOURCE_DIRS += hal/socket/bsd LIB_SOURCE_DIRS += hal/thread/bsd LIB_SOURCE_DIRS += hal/ethernet/bsd LIB_SOURCE_DIRS += hal/filesystem/linux LIB_SOURCE_DIRS += hal/time/unix +LIB_SOURCE_DIRS += hal/memory endif LIB_INCLUDE_DIRS += config LIB_INCLUDE_DIRS += hal/inc @@ -69,9 +72,9 @@ endif ifdef WITH_MBEDTLS LIB_SOURCE_DIRS += third_party/mbedtls/mbedtls-2.6.0/library -LIB_SOURCE_DIRS += src/tls/mbedtls +LIB_SOURCE_DIRS += hal/tls/mbedtls LIB_INCLUDE_DIRS += third_party/mbedtls/mbedtls-2.6.0/include -LIB_INCLUDE_DIRS += src/tls/mbedtls +LIB_INCLUDE_DIRS += hal/tls/mbedtls CFLAGS += -D'MBEDTLS_CONFIG_FILE="mbedtls_config.h"' CFLAGS += -D'CONFIG_MMS_SUPPORT_TLS=1' endif @@ -84,7 +87,8 @@ endif LIB_API_HEADER_FILES = hal/inc/hal_time.h LIB_API_HEADER_FILES += hal/inc/hal_thread.h -LIB_API_HEADER_FILES += hal/inc/hal_filesystem.h +LIB_API_HEADER_FILES += hal/inc/hal_filesystem.h +LIB_API_HEADER_FILES += hal/inc/tls_config.h LIB_API_HEADER_FILES += src/common/inc/libiec61850_common_api.h LIB_API_HEADER_FILES += src/common/inc/linked_list.h LIB_API_HEADER_FILES += src/common/inc/byte_buffer.h @@ -114,7 +118,6 @@ LIB_API_HEADER_FILES += src/goose/goose_publisher.h LIB_API_HEADER_FILES += src/sampled_values/sv_subscriber.h LIB_API_HEADER_FILES += src/sampled_values/sv_publisher.h LIB_API_HEADER_FILES += src/logging/logging_api.h -LIB_API_HEADER_FILES += src/tls/tls_api.h get_sources_from_directory = $(wildcard $1/*.c) get_sources = $(foreach dir, $1, $(call get_sources_from_directory,$(dir))) diff --git a/hal/CMakeLists.txt b/hal/CMakeLists.txt index 2a3e6790..a225a92b 100644 --- a/hal/CMakeLists.txt +++ b/hal/CMakeLists.txt @@ -97,6 +97,29 @@ ENDIF(WIN32) #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" ) #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC" ) +if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.6.0) +message("Found mbedtls -> can compile with TLS support") +set(WITH_MBEDTLS 1) +endif(EXISTS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.6.0) + +if(WITH_MBEDTLS) +include_directories( + ${CMAKE_CURRENT_LIST_DIR}/tls/mbedtls + ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.6.0/include +) + +file(GLOB tls_SRCS ${CMAKE_CURRENT_LIST_DIR}/../third_party/mbedtls/mbedtls-2.6.0/library/*.c) + +add_definitions(-DMBEDTLS_CONFIG_FILE="mbedtls_config.h") + +set (libhal_SRCS ${libhal_SRCS} + ${CMAKE_CURRENT_LIST_DIR}/tls/mbedtls/tls_mbedtls.c +) + +list (APPEND libhal_SRCS ${tls_SRCS}) + +endif(WITH_MBEDTLS) + add_library (hal STATIC ${libhal_SRCS}) add_library (hal-shared STATIC ${libhal_SRCS}) diff --git a/src/tls/tls_api.h b/hal/inc/tls_config.h similarity index 84% rename from src/tls/tls_api.h rename to hal/inc/tls_config.h index e2392369..ec70fe9b 100644 --- a/src/tls/tls_api.h +++ b/hal/inc/tls_config.h @@ -1,27 +1,40 @@ /* - * tls_api.h + * tls_config.h * - * TLS API for TCP/IP protocol stacks + * TLS Configuration API for protocol stacks using TCP/IP * - * Copyright 2017 MZ Automation GmbH + * Copyright 2017-2018 MZ Automation GmbH * - * Abstraction layer for different TLS implementations - * - * Implementation connects the TLS API layer with the socket API layer - * and performs all TLS tasks like handshake, encryption/decryption. + * Abstraction layer for configuration of different TLS implementations * */ -#ifndef SRC_TLS_TLS_API_H_ -#define SRC_TLS_TLS_API_H_ - -#include -#include +#ifndef SRC_TLS_CONFIG_H_ +#define SRC_TLS_CONFIG_H_ #ifdef __cplusplus extern "C" { #endif +#include +#include + +/** + * \file tls_config.h + * \brief TLS API functions + */ + +/*! \addtogroup hal Platform (Hardware/OS) abstraction layer + * + * @{ + */ + +/** + * @defgroup TLS_CONFIG_API TLS configuration + * + * @{ + */ + typedef struct sTLSConfiguration* TLSConfiguration; /** @@ -107,8 +120,12 @@ TLSConfiguration_setRenegotiationTime(TLSConfiguration self, int timeInMs); void TLSConfiguration_destroy(TLSConfiguration self); +/** @} */ + +/** @} */ + #ifdef __cplusplus } #endif -#endif /* SRC_TLS_TLS_API_H_ */ +#endif /* SRC_TLS_CONFIG_H_ */ diff --git a/src/tls/tls_socket.h b/hal/inc/tls_socket.h similarity index 50% rename from src/tls/tls_socket.h rename to hal/inc/tls_socket.h index 009a9906..553cb82b 100644 --- a/src/tls/tls_socket.h +++ b/hal/inc/tls_socket.h @@ -1,30 +1,64 @@ /* * tls_socket.h * - * TLS API for TCP/IP protocol stacks + * TLS socket API for protocol libraries using TCP/IP * - * Copyright 2017 MZ Automation GmbH + * Copyright 2017-2018 Michael Zillgith, MZ Automation GmbH * * Abstraction layer for different TLS implementations * - * Implementation connects the TLS API layer with the socket API layer - * and performs all TLS tasks like handshake, encryption/decryption. + * The implementation has to connect the TLS API layer with the socket API layer + * and perform all TLS tasks like handshake, encryption/decryption. * */ -#ifndef SRC_TLS_TLS_SOCKET_H_ -#define SRC_TLS_TLS_SOCKET_H_ - -#include "tls_api.h" - -#include "hal_socket.h" +#ifndef SRC_TLS_SOCKET_API_H_ +#define SRC_TLS_SOCKET_API_H_ #ifdef __cplusplus extern "C" { #endif +/** + * \file tls_socket.h + * \brief Abstraction layer for different TLS implementations. + * + * The implementation has to connect the TLS API layer with the socket API layer + * and perform all TLS tasks like handshake, encryption/decryption. + */ + +/*! \addtogroup hal Platform (Hardware/OS) abstraction layer + * + * @{ + */ + +/** + * @defgroup HAL_TLS_SOCKET Abstraction layer for different TLS implementations. + * + * The implementation has to connect the TLS API layer with the socket API layer + * and perform all TLS tasks like handshake, encryption/decryption. + * + * @{ + */ + +#include +#include "tls_config.h" +#include "hal_socket.h" + typedef struct sTLSSocket* TLSSocket; +/** + * \brief This function create a new TLSSocket instance using the given Socket instance + * + * NOTE: This function also has to perform the TLS handshake + * + * \param socket the socket instance to use for the TLS connection + * \param configuration the TLS configuration object to use + * \param storeClientCert if true, the client certificate will be stored + * for later access by \ref TLSSocket_getPeerCertificate + * + * \return new TLS connection instance + */ TLSSocket TLSSocket_create(Socket socket, TLSConfiguration configuration, bool storeClientCert); @@ -50,10 +84,6 @@ TLSSocket_getPeerCertificate(TLSSocket self, int* certSize); * The function shall return immediately if no data is available. In this case * the function returns 0. If an error happens the function shall return -1. * - * Implementation of this function is MANDATORY - * - * NOTE: The behaviour of this function changed with version 0.8! - * * \param self the client, connection or server socket instance * \param buf the buffer where the read bytes are copied to * \param size the maximum number of bytes to read (size of the provided buffer) @@ -76,13 +106,17 @@ int TLSSocket_write(TLSSocket self, uint8_t* buf, int size); /** - * \brief Close the TLS socket and release all resources + * \brief Closes the TLS connection and released all resources */ void TLSSocket_close(TLSSocket self); +/*! @} */ + +/*! @} */ + #ifdef __cplusplus } #endif -#endif /* SRC_TLS_TLS_SOCKET_H_ */ +#endif /* SRC_TLS_SOCKET_API_H_ */ diff --git a/src/tls/mbedtls/mbedtls_config.h b/hal/tls/mbedtls/mbedtls_config.h similarity index 100% rename from src/tls/mbedtls/mbedtls_config.h rename to hal/tls/mbedtls/mbedtls_config.h diff --git a/src/tls/mbedtls/tls_mbedtls.c b/hal/tls/mbedtls/tls_mbedtls.c similarity index 87% rename from src/tls/mbedtls/tls_mbedtls.c rename to hal/tls/mbedtls/tls_mbedtls.c index f0dc1da2..2319d647 100644 --- a/src/tls/mbedtls/tls_mbedtls.c +++ b/hal/tls/mbedtls/tls_mbedtls.c @@ -11,13 +11,11 @@ #include -#include "tls_api.h" #include "tls_socket.h" #include "hal_thread.h" #include "lib_memory.h" #include "linked_list.h" -//#include "mbedtls/config.h" #include "mbedtls/platform.h" #include "mbedtls/entropy.h" #include "mbedtls/ctr_drbg.h" @@ -28,10 +26,10 @@ #include "mbedtls/error.h" #include "mbedtls/debug.h" -#define CONFIG_DEBUG_TLS 0 - #if (CONFIG_DEBUG_TLS == 1) -#define DEBUG_PRINT(appId, fmt, ...) fprintf(stderr, "%s: " fmt, appId, ## __VA_ARGS__) +#define DEBUG_PRINT(appId, fmt, ...) fprintf(stderr, "%s: " fmt, \ + appId, \ + __VA_ARGS__) #else #define DEBUG_PRINT(fmt, ...) {do {} while(0);} #endif @@ -212,7 +210,7 @@ TLSConfiguration_setOwnCertificate(TLSConfiguration self, uint8_t* certificate, int ret = mbedtls_x509_crt_parse(&(self->ownCertificate), certificate, certLen); if (ret != 0) - printf("mbedtls_x509_crt_parse returned %d\n", ret); + DEBUG_PRINT("mbedtls_x509_crt_parse returned %d\n", ret); return (ret == 0); } @@ -344,7 +342,6 @@ readFunction(void* ctx, unsigned char* buf, size_t len) int ret = Socket_read((Socket) ctx, buf, len); if ((ret == 0) && (len > 0)) { - Thread_sleep(1); return MBEDTLS_ERR_SSL_WANT_READ; } @@ -422,47 +419,30 @@ TLSSocket_performHandshake(TLSSocket self) int TLSSocket_read(TLSSocket self, uint8_t* buf, int size) { - int ret; - int len = size; - - do - { - ret = mbedtls_ssl_read( &(self->ssl), buf, len ); + int ret = mbedtls_ssl_read(&(self->ssl), buf, size); - if( ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE ) - continue; + if ((ret == MBEDTLS_ERR_SSL_WANT_READ) || (ret == MBEDTLS_ERR_SSL_WANT_WRITE)) + return 0; - if( ret <= 0 ) - { - switch( ret ) - { - case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: - DEBUG_PRINT("TLS", " connection was closed gracefully\n" ); - len = -1; - break; + if (ret < 0) { - case MBEDTLS_ERR_NET_CONN_RESET: - len = -1; - DEBUG_PRINT("TLS", " connection was reset by peer\n" ); - break; - - default: - DEBUG_PRINT("TLS", " mbedtls_ssl_read returned -0x%x\n", -ret ); - len = -1; //TODO is this the correct return value? - break; - } - - break; - } + switch (ret) + { + case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: + DEBUG_PRINT("TLS", " connection was closed gracefully\n"); + return -1; - len = ret; + case MBEDTLS_ERR_NET_CONN_RESET: + DEBUG_PRINT("TLS", " connection was reset by peer\n"); + return -1; - if( ret > 0 ) - break; - } - while( 1 ); + default: + DEBUG_PRINT("TLS", " mbedtls_ssl_read returned -0x%x\n", -ret); + return -1; + } + } - return len; + return ret; } int @@ -471,18 +451,17 @@ TLSSocket_write(TLSSocket self, uint8_t* buf, int size) int ret; int len = size; - - while( ( ret = mbedtls_ssl_write( &(self->ssl), buf, len ) ) <= 0 ) + while ((ret = mbedtls_ssl_write(&(self->ssl), buf, len)) <= 0) { - if( ret == MBEDTLS_ERR_NET_CONN_RESET ) + if (ret == MBEDTLS_ERR_NET_CONN_RESET) { - DEBUG_PRINT("TLS", "peer closed the connection\n" ); + DEBUG_PRINT("TLS", "peer closed the connection\n"); return -1; } - if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + if ((ret != MBEDTLS_ERR_SSL_WANT_READ) && (ret != MBEDTLS_ERR_SSL_WANT_WRITE)) { - DEBUG_PRINT("TLS", "mbedtls_ssl_write returned %d\n", ret ); + DEBUG_PRINT("TLS", "mbedtls_ssl_write returned %d\n", ret); return -1; } } @@ -499,12 +478,11 @@ TLSSocket_close(TLSSocket self) //TODO add timeout? - while( ( ret = mbedtls_ssl_close_notify( &(self->ssl) ) ) < 0 ) + while ((ret = mbedtls_ssl_close_notify(&(self->ssl))) < 0) { - if( ret != MBEDTLS_ERR_SSL_WANT_READ && - ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + if ((ret != MBEDTLS_ERR_SSL_WANT_READ) && (ret != MBEDTLS_ERR_SSL_WANT_WRITE)) { - DEBUG_PRINT("TLS", "mbedtls_ssl_close_notify returned %d\n", ret ); + DEBUG_PRINT("TLS", "mbedtls_ssl_close_notify returned %d\n", ret); break; } } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b362e4b0..e9f4f903 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -79,15 +79,6 @@ set (lib_common_SRCS ./logging/log_storage.c ) -if(WITH_MBEDTLS) -set (lib_common_SRCS ${lib_common_SRCS} -./tls/mbedtls/tls_mbedtls.c -) - -list (APPEND lib_common_SRCS ${tls_SRCS}) - -endif(WITH_MBEDTLS) - set (lib_asn1c_SRCS ./mms/iso_mms/asn1c/DataAccessError.c ./mms/iso_mms/asn1c/DeleteNamedVariableListRequest.c diff --git a/src/mms/inc/iso_connection_parameters.h b/src/mms/inc/iso_connection_parameters.h index 8d9a054a..81d340b2 100644 --- a/src/mms/inc/iso_connection_parameters.h +++ b/src/mms/inc/iso_connection_parameters.h @@ -28,7 +28,7 @@ extern "C" { #endif -#include "tls_api.h" +#include "tls_config.h" /** * \addtogroup mms_client_api_group diff --git a/src/mms/inc/mms_client_connection.h b/src/mms/inc/mms_client_connection.h index aa33938c..d5bd40ed 100644 --- a/src/mms/inc/mms_client_connection.h +++ b/src/mms/inc/mms_client_connection.h @@ -40,8 +40,7 @@ extern "C" { #include "mms_value.h" #include "iso_connection_parameters.h" #include "linked_list.h" - -#include "tls_api.h" +#include "tls_config.h" /** * Contains MMS layer specific parameters diff --git a/src/mms/inc_private/iso_server_private.h b/src/mms/inc_private/iso_server_private.h index 4ae78808..e700c9ec 100644 --- a/src/mms/inc_private/iso_server_private.h +++ b/src/mms/inc_private/iso_server_private.h @@ -24,8 +24,8 @@ #ifndef ISO_SERVER_PRIVATE_H_ #define ISO_SERVER_PRIVATE_H_ +#include "tls_config.h" #include "hal_socket.h" -#include "tls_api.h" IsoConnection IsoConnection_create(Socket socket, IsoServer isoServer); diff --git a/src/mms/iso_client/iso_client_connection.c b/src/mms/iso_client/iso_client_connection.c index 8563270c..3b2e8060 100644 --- a/src/mms/iso_client/iso_client_connection.c +++ b/src/mms/iso_client/iso_client_connection.c @@ -33,8 +33,9 @@ #include "iso_session.h" #include "iso_presentation.h" #include "iso_client_connection.h" + +#include "tls_config.h" #include "acse.h" -#include "tls_api.h" #ifndef DEBUG_ISO_CLIENT diff --git a/src/mms/iso_mms/client/mms_client_connection.c b/src/mms/iso_mms/client/mms_client_connection.c index 93fb0d18..49f8f0df 100644 --- a/src/mms/iso_mms/client/mms_client_connection.c +++ b/src/mms/iso_mms/client/mms_client_connection.c @@ -28,14 +28,13 @@ #include "mms_client_internal.h" #include "stack_config.h" -#include "tls_api.h" - #include #include "byte_buffer.h" #include "ber_decode.h" #include +#include "tls_config.h" #define CONFIG_MMS_CONNECTION_DEFAULT_TIMEOUT 5000 #define CONFIG_MMS_CONNECTION_DEFAULT_CONNECT_TIMEOUT 10000