From 158634888a466f3f12fa45dcdb95a94f793e9389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Tue, 11 Dec 2018 12:52:26 +0000 Subject: [PATCH] Work on configuration block implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add support for nanoframework/nf-debugger#173. - Improve Monitor_UpdateConfiguration command to handle configuration blocks larger then the WP buffer size. - Add new configuration block to store X509 CA Root certificate bundles. - Tested for STM32. - **WIP for ESP32** Signed-off-by: José Simões --- CMake/Modules/FindNF_Networking.cmake | 1 - CMake/Modules/FindSystem.Net.cmake | 1 + azure-pipelines.yml | 2 +- src/CLR/Debugger/Debugger.cpp | 28 ++++- .../Include/WireProtocol_MonitorCommands.h | 1 + .../System.Net/sys_net_native.cpp | 9 +- .../System.Net/sys_net_native.h | 9 +- ...System_Net_Security_CertificateManager.cpp | 51 +++++++++ ...t_native_System_Net_Security_SslNative.cpp | 47 -------- .../Include/nanoHAL_ConfigurationManager.h | 21 +++- src/HAL/Include/nanoHAL_Network.h | 17 +++ src/HAL/nanoHAL_ConfigurationManager.c | 47 ++++++++ src/HAL/nanoHAL_ConfigurationManager_stubs.c | 8 ++ .../mbedTLS/ssl_add_cert_auth_internal.cpp | 18 --- .../mbedTLS/ssl_clear_cert_auth_internal.cpp | 39 ------- .../ssl/mbedTLS/ssl_generic_init_internal.cpp | 55 +++++++-- src/PAL/COM/sockets/ssl/openssl/openssl.h | 1 - .../openssl/ssl_add_cert_auth_internal.cpp | 77 +++++-------- .../openssl/ssl_clear_cert_auth_internal.cpp | 38 ------- .../COM/sockets/ssl/openssl/ssl_functions.h | 1 - .../ssl/openssl/ssl_generic_init_internal.cpp | 19 +++- .../ssl/openssl/ssl_uninitialize_internal.cpp | 4 - src/PAL/COM/sockets/ssl/ssl.cpp | 5 - src/PAL/COM/sockets/ssl/ssl_functions.h | 1 - src/PAL/COM/sockets/ssl/ssl_stubs.cpp | 6 - src/PAL/Include/nanoPAL_Sockets.h | 1 - targets-community | 2 +- .../common/targetHAL_ConfigurationManager.cpp | 74 ++++++++++-- .../nanoBooter/WireProtocol_MonitorCommands.c | 3 +- .../targetHAL_ConfigurationManager.cpp | 106 +++++++++++++++++- 30 files changed, 444 insertions(+), 248 deletions(-) create mode 100644 src/DeviceInterfaces/System.Net/sys_net_native_System_Net_Security_CertificateManager.cpp delete mode 100644 src/PAL/COM/sockets/ssl/mbedTLS/ssl_clear_cert_auth_internal.cpp delete mode 100644 src/PAL/COM/sockets/ssl/openssl/ssl_clear_cert_auth_internal.cpp diff --git a/CMake/Modules/FindNF_Networking.cmake b/CMake/Modules/FindNF_Networking.cmake index 8d1016083e..865a14127a 100644 --- a/CMake/Modules/FindNF_Networking.cmake +++ b/CMake/Modules/FindNF_Networking.cmake @@ -34,7 +34,6 @@ set(NF_Networking_Security_SRCS ssl.cpp ssl_accept_internal.cpp ssl_add_cert_auth_internal.cpp - ssl_clear_cert_auth_internal.cpp ssl_closesocket_internal.cpp ssl_connect_internal.cpp ssl_exit_context_internal.cpp diff --git a/CMake/Modules/FindSystem.Net.cmake b/CMake/Modules/FindSystem.Net.cmake index 2e3055cadb..b8bf39f2e2 100644 --- a/CMake/Modules/FindSystem.Net.cmake +++ b/CMake/Modules/FindSystem.Net.cmake @@ -23,6 +23,7 @@ set(System.Net_SRCS # System.Net.Security sys_net_native_System_Net_Security_SslNative.cpp + sys_net_native_System_Net_Security_CertificateManager.cpp ) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 9e4a4f6f0c..b06b9dfe92 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -23,7 +23,7 @@ pr: branches: include: - master - - develop + - develop/* - release/* autoCancel: true diff --git a/src/CLR/Debugger/Debugger.cpp b/src/CLR/Debugger/Debugger.cpp index ff89351d7e..c1b9cabf2a 100644 --- a/src/CLR/Debugger/Debugger.cpp +++ b/src/CLR/Debugger/Debugger.cpp @@ -853,9 +853,11 @@ bool CLR_DBG_Debugger::Monitor_QueryConfiguration( WP_Message* message) Monitor_QueryConfiguration_Command *cmd = (Monitor_QueryConfiguration_Command*)message->m_payload; int size = 0; + int sizeOfBlock = 0; HAL_Configuration_NetworkInterface* configNetworkInterface; HAL_Configuration_Wireless80211* configWireless80211NetworkInterface; + HAL_Configuration_X509CaRootBundle* x509Certificate; switch((DeviceConfigurationOption)cmd->Configuration) { @@ -886,7 +888,28 @@ bool CLR_DBG_Debugger::Monitor_QueryConfiguration( WP_Message* message) platform_free(configWireless80211NetworkInterface); } break; - + + case DeviceConfigurationOption_X509CaRootBundle: + + if(g_TargetConfiguration.CertificateStore->Count > 0) + { + // because X509 certificate has a variable length need to compute the block size in two steps + sizeOfBlock = offsetof(HAL_Configuration_X509CaRootBundle, Certificate); + sizeOfBlock += g_TargetConfiguration.CertificateStore->Certificates[cmd->BlockIndex]->CertificateSize; + } + + x509Certificate = (HAL_Configuration_X509CaRootBundle*)platform_malloc(sizeOfBlock); + + if(ConfigurationManager_GetConfigurationBlock(x509Certificate, (DeviceConfigurationOption)cmd->Configuration, cmd->BlockIndex) == true) + { + size = sizeOfBlock; + success = true; + + WP_ReplyToCommand( message, success, false, (uint8_t*)x509Certificate, size ); + platform_free(x509Certificate); + } + break; + case DeviceConfigurationOption_WirelessNetworkAP: // TODO missing implementation for now break; @@ -925,8 +948,9 @@ bool CLR_DBG_Debugger::Monitor_UpdateConfiguration(WP_Message* message) { case DeviceConfigurationOption_Network: case DeviceConfigurationOption_Wireless80211Network: + case DeviceConfigurationOption_X509CaRootBundle: case DeviceConfigurationOption_All: - if(ConfigurationManager_StoreConfigurationBlock(cmd->Data, (DeviceConfigurationOption)cmd->Configuration, cmd->BlockIndex, cmd->Length) == true) + if(ConfigurationManager_StoreConfigurationBlock(cmd->Data, (DeviceConfigurationOption)cmd->Configuration, cmd->BlockIndex, cmd->Length, cmd->Offset) == true) { cmdReply.ErrorCode = 0; success = true; diff --git a/src/CLR/Include/WireProtocol_MonitorCommands.h b/src/CLR/Include/WireProtocol_MonitorCommands.h index 30a386da35..f2cea51ca2 100644 --- a/src/CLR/Include/WireProtocol_MonitorCommands.h +++ b/src/CLR/Include/WireProtocol_MonitorCommands.h @@ -161,6 +161,7 @@ typedef struct Monitor_UpdateConfiguration_Command uint32_t Configuration; uint32_t BlockIndex; uint32_t Length; + uint32_t Offset; uint8_t Data[1]; }Monitor_UpdateConfiguration_Command; diff --git a/src/DeviceInterfaces/System.Net/sys_net_native.cpp b/src/DeviceInterfaces/System.Net/sys_net_native.cpp index 9bf420f772..303273e670 100644 --- a/src/DeviceInterfaces/System.Net/sys_net_native.cpp +++ b/src/DeviceInterfaces/System.Net/sys_net_native.cpp @@ -102,9 +102,11 @@ static const CLR_RT_MethodHandler method_lookup[] = Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::GetNetworkInterfaceCount___STATIC__I4, Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::GetNetworkInterface___STATIC__SystemNetNetworkInformationNetworkInterface__U4, Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::IPAddressFromString___STATIC__U4__STRING, + NULL, + NULL, + Library_sys_net_native_System_Net_Security_CertificateManager::AddCaCertificateBundle___STATIC__BOOLEAN__SZARRAY_U1, Library_sys_net_native_System_Net_Security_SslNative::SecureServerInit___STATIC__I4__I4__I4__SystemSecurityCryptographyX509CertificatesX509Certificate__SystemSecurityCryptographyX509CertificatesX509Certificate, Library_sys_net_native_System_Net_Security_SslNative::SecureClientInit___STATIC__I4__I4__I4__SystemSecurityCryptographyX509CertificatesX509Certificate__SystemSecurityCryptographyX509CertificatesX509Certificate, - Library_sys_net_native_System_Net_Security_SslNative::UpdateCertificates___STATIC__VOID__I4__SystemSecurityCryptographyX509CertificatesX509Certificate__SZARRAY_SystemSecurityCryptographyX509CertificatesX509Certificate, Library_sys_net_native_System_Net_Security_SslNative::SecureAccept___STATIC__VOID__I4__OBJECT, Library_sys_net_native_System_Net_Security_SslNative::SecureConnect___STATIC__VOID__I4__STRING__OBJECT, Library_sys_net_native_System_Net_Security_SslNative::SecureRead___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4, @@ -156,7 +158,6 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, - NULL, Library_sys_net_native_System_Net_Sockets_NativeSocket::socket___STATIC__I4__I4__I4__I4, Library_sys_net_native_System_Net_Sockets_NativeSocket::bind___STATIC__VOID__OBJECT__SZARRAY_U1, Library_sys_net_native_System_Net_Sockets_NativeSocket::connect___STATIC__VOID__OBJECT__SZARRAY_U1__BOOLEAN, @@ -234,7 +235,7 @@ static const CLR_RT_MethodHandler method_lookup[] = const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_System_Net = { "System.Net", - 0xFD8EBD9C, + 0x001C1FB9, method_lookup, - { 1, 0, 2, 2 } + { 1, 0, 3, 0 } }; diff --git a/src/DeviceInterfaces/System.Net/sys_net_native.h b/src/DeviceInterfaces/System.Net/sys_net_native.h index 8c277e124a..a5bc8516d0 100644 --- a/src/DeviceInterfaces/System.Net/sys_net_native.h +++ b/src/DeviceInterfaces/System.Net/sys_net_native.h @@ -123,11 +123,18 @@ struct Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface }; +struct Library_sys_net_native_System_Net_Security_CertificateManager +{ + NANOCLR_NATIVE_DECLARE(AddCaCertificateBundle___STATIC__BOOLEAN__SZARRAY_U1); + + //--// + +}; + struct Library_sys_net_native_System_Net_Security_SslNative { NANOCLR_NATIVE_DECLARE(SecureServerInit___STATIC__I4__I4__I4__SystemSecurityCryptographyX509CertificatesX509Certificate__SystemSecurityCryptographyX509CertificatesX509Certificate); NANOCLR_NATIVE_DECLARE(SecureClientInit___STATIC__I4__I4__I4__SystemSecurityCryptographyX509CertificatesX509Certificate__SystemSecurityCryptographyX509CertificatesX509Certificate); - NANOCLR_NATIVE_DECLARE(UpdateCertificates___STATIC__VOID__I4__SystemSecurityCryptographyX509CertificatesX509Certificate__SZARRAY_SystemSecurityCryptographyX509CertificatesX509Certificate); NANOCLR_NATIVE_DECLARE(SecureAccept___STATIC__VOID__I4__OBJECT); NANOCLR_NATIVE_DECLARE(SecureConnect___STATIC__VOID__I4__STRING__OBJECT); NANOCLR_NATIVE_DECLARE(SecureRead___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4); diff --git a/src/DeviceInterfaces/System.Net/sys_net_native_System_Net_Security_CertificateManager.cpp b/src/DeviceInterfaces/System.Net/sys_net_native_System_Net_Security_CertificateManager.cpp new file mode 100644 index 0000000000..4946f4df4f --- /dev/null +++ b/src/DeviceInterfaces/System.Net/sys_net_native_System_Net_Security_CertificateManager.cpp @@ -0,0 +1,51 @@ +// +// Copyright (c) 2018 The nanoFramework project contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include "sys_net_native.h" + +HRESULT Library_sys_net_native_System_Net_Security_CertificateManager::AddCaCertificateBundle___STATIC__BOOLEAN__SZARRAY_U1( CLR_RT_StackFrame& stack ) +{ + NATIVE_PROFILE_CLR_NETWORK(); + NANOCLR_HEADER(); + + CLR_RT_HeapBlock_Array* arrayCA = stack.Arg0().DereferenceArray(); + + CLR_UINT8* certificateBinary; + uint32_t certificateSize; + + // we only have one CA root bundle, so this is fixed to 0 + uint32_t configIndex = 0; + + // check for empty array + FAULT_ON_NULL(arrayCA); + + certificateSize = (int)arrayCA->m_numOfElements; + + // get a pointer to the the binary data for the certificate + certificateBinary = arrayCA->GetFirstElement(); + + if(g_TargetConfiguration.CertificateStore->Count == 0) + { + // not found, add the certificate bundle + if(ConfigurationManager_StoreConfigurationBlock(certificateBinary, DeviceConfigurationOption_X509CaRootBundle, configIndex, certificateSize, 0) != TRUE) + { + NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + } + } + else + { + // update the configuration block + if(ConfigurationManager_UpdateConfigurationBlock(certificateBinary, DeviceConfigurationOption_X509CaRootBundle, configIndex) != TRUE) + { + NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + } + } + + // reach here, we should be OK + stack.SetResult_Boolean(TRUE); + + NANOCLR_NOCLEANUP(); +} diff --git a/src/DeviceInterfaces/System.Net/sys_net_native_System_Net_Security_SslNative.cpp b/src/DeviceInterfaces/System.Net/sys_net_native_System_Net_Security_SslNative.cpp index 87eb7952b2..5937d3a239 100644 --- a/src/DeviceInterfaces/System.Net/sys_net_native_System_Net_Security_SslNative.cpp +++ b/src/DeviceInterfaces/System.Net/sys_net_native_System_Net_Security_SslNative.cpp @@ -108,53 +108,6 @@ HRESULT Library_sys_net_native_System_Net_Security_SslNative::SecureClientInit__ return InitHelper( stack, false ); } -HRESULT Library_sys_net_native_System_Net_Security_SslNative::UpdateCertificates___STATIC__VOID__I4__SystemSecurityCryptographyX509CertificatesX509Certificate__SZARRAY_SystemSecurityCryptographyX509CertificatesX509Certificate( CLR_RT_StackFrame& stack ) -{ - NATIVE_PROFILE_CLR_NETWORK(); - NANOCLR_HEADER(); - - CLR_INT32 sslContext = stack.Arg0().NumericByRef().s4; - CLR_RT_HeapBlock* hbCert = stack.Arg1().Dereference(); - CLR_RT_HeapBlock_Array* arrCA = stack.Arg2().DereferenceArray(); - CLR_RT_HeapBlock_Array* arrCert; - CLR_UINT8* sslCert; - int i; - CLR_RT_HeapBlock* hbPwd; - const char * szPwd; - - FAULT_ON_NULL(hbCert); - FAULT_ON_NULL(arrCA); - - arrCert = hbCert[ Library_sys_net_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD___certificate ].DereferenceArray(); FAULT_ON_NULL(arrCert); - - sslCert = arrCert->GetFirstElement(); - - hbPwd = hbCert[ Library_sys_net_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD___password ].Dereference(); FAULT_ON_NULL(hbPwd); - - szPwd = hbPwd->StringText(); - - SSL_ClearCertificateAuthority( sslContext ); - - if(!SSL_AddCertificateAuthority( sslContext, (const char*)sslCert, arrCert->m_numOfElements, szPwd )) NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); - - for(i=0; i<(int)arrCA->m_numOfElements; i++) - { - hbCert = (CLR_RT_HeapBlock*)arrCA->GetElement( i ); FAULT_ON_NULL(arrCert); - - arrCert = hbCert[ Library_sys_net_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD___certificate ].DereferenceArray(); - - sslCert = arrCert->GetFirstElement(); - - hbPwd = hbCert[ Library_sys_net_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD___password ].Dereference(); - - szPwd = hbPwd->StringText(); - - if(!SSL_AddCertificateAuthority( sslContext, (const char*)sslCert, arrCert->m_numOfElements, szPwd )) NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); - } - - NANOCLR_NOCLEANUP(); -} - // // Server - socket connected now accept connection by doing the server SSL handshake // diff --git a/src/HAL/Include/nanoHAL_ConfigurationManager.h b/src/HAL/Include/nanoHAL_ConfigurationManager.h index 6dfd06fe36..371ebd532b 100644 --- a/src/HAL/Include/nanoHAL_ConfigurationManager.h +++ b/src/HAL/Include/nanoHAL_ConfigurationManager.h @@ -29,6 +29,9 @@ typedef enum DeviceConfigurationOption // Wireless Network as AP configuration block DeviceConfigurationOption_WirelessNetworkAP = 3, + // X509 CA Root Certificates bundle block + DeviceConfigurationOption_X509CaRootBundle = 4, + // All configuration blocks DeviceConfigurationOption_All = 255, @@ -58,12 +61,25 @@ typedef struct HAL_CONFIGURATION_NETWORK_WIRELESS80211 } HAL_CONFIGURATION_NETWORK_WIRELESS80211; +// certificate store struct +// declared with a flexible array member to allow N config blocks totally independent of compilation +typedef struct HAL_CONFIGURATION_X509_CERTIFICATE +{ + // count of the configs elements + uint8_t Count; + + // pointer to the certificates + HAL_Configuration_X509CaRootBundle* Certificates[]; + +} HAL_CONFIGURATION_X509_CERTIFICATE; + // target configuration storage struct // the memory allocation for these will have to be done as required according to the number and type of blocks found in memory typedef struct HAL_TARGET_CONFIGURATION { HAL_CONFIGURATION_NETWORK* NetworkInterfaceConfigs; HAL_CONFIGURATION_NETWORK_WIRELESS80211* Wireless80211Configs; + HAL_CONFIGURATION_X509_CERTIFICATE* CertificateStore; } HAL_TARGET_CONFIGURATION; @@ -81,7 +97,7 @@ bool ConfigurationManager_GetConfigurationBlock(void* configurationBlock, Device // StoreConfigurationBlock() is defined in targetHAL_ConfigurationManager.cpp at target level because the target // needs to be free to implement the storage of the configuration block as they see fit -bool ConfigurationManager_StoreConfigurationBlock(void* configurationBlock, DeviceConfigurationOption configuration, uint32_t configurationIndex, uint32_t blockSize); +bool ConfigurationManager_StoreConfigurationBlock(void* configurationBlock, DeviceConfigurationOption configuration, uint32_t configurationIndex, uint32_t blockSize, uint32_t offset); // UpdateConfigurationBlock() is defined in targetHAL_ConfigurationManager.cpp at target level because the target // needs to be free to implement the storage of the configuration block as they see fit @@ -103,6 +119,9 @@ void* ConfigurationManager_FindNetworkConfigurationBlocks(uint32_t startAddress, // function that sweeps a memory region searching for wireless network configuration blocks void* ConfigurationManager_FindNetworkWireless80211ConfigurationBlocks(uint32_t startAddress, uint32_t endAddress); +// function that sweeps a memory region searching for X509 certificates configuration blocks +void* ConfigurationManager_FindX509CertificateConfigurationBlocks(uint32_t startAddress, uint32_t endAddress); + // gets the HAL_Configuration_Wireless80211 configuration block that has the specified Id, if that exists // defined as weak needs to be free to implement the storage of the configuration block as they see fit HAL_Configuration_Wireless80211* ConfigurationManager_GetWirelessConfigurationFromId(uint32_t configurationId); diff --git a/src/HAL/Include/nanoHAL_Network.h b/src/HAL/Include/nanoHAL_Network.h index 96c3b32f1a..91662d701c 100644 --- a/src/HAL/Include/nanoHAL_Network.h +++ b/src/HAL/Include/nanoHAL_Network.h @@ -39,6 +39,9 @@ static const unsigned char c_MARKER_CONFIGURATION_WIRELESS80211_V1[] = "WN1"; // Wireless AP configuration block start marker static const unsigned char c_MARKER_CONFIGURATION_WIRELESS_AP_V1[] = "AP1"; +// X509 certificate configuration block start marker +static const unsigned char c_MARKER_CONFIGURATION_X509CAROOTBUNDLE_V1[] = "XB1"; + //////////////////////////////////////////////////////////////////////////////////////////////////// // !!! KEEP IN SYNC WITH System.Net.NetworkInformation.NetworkInterfaceType (in managed code) !!! // //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -206,6 +209,20 @@ typedef struct __nfpack HAL_Configuration_Wireless80211 { } HAL_Configuration_Wireless80211; +typedef struct __nfpack HAL_Configuration_X509CaRootBundle { + + // this is the marker placeholder for this configuration block + uint8_t Marker[4]; + + // Size of the X509 CA Root certificate bundle + uint32_t CertificateSize; + + // X509 CA Root certificate bundle + uint8_t Certificate[1]; + +} HAL_Configuration_X509CaRootBundle; + + void nanoHAL_Network_Initialize(); void sys_signal_sock_event(); diff --git a/src/HAL/nanoHAL_ConfigurationManager.c b/src/HAL/nanoHAL_ConfigurationManager.c index 82a13d9250..0bf00d9997 100644 --- a/src/HAL/nanoHAL_ConfigurationManager.c +++ b/src/HAL/nanoHAL_ConfigurationManager.c @@ -5,6 +5,7 @@ #include #include +#include uint32_t FindNextBlock(uint32_t startAddress, uint32_t endAddress, const unsigned char* marker) { @@ -105,6 +106,52 @@ __nfweak void* ConfigurationManager_FindNetworkWireless80211ConfigurationBlocks( return networkWirelessConfigs; } +__nfweak void* ConfigurationManager_FindX509CertificateConfigurationBlocks(uint32_t startAddress, uint32_t endAddress) +{ + uint32_t nextBlock = startAddress; + uint32_t allocationSize = 0; + + // first pass: find out how many blocks of this type we have + // because these blocks have an unknow size, need to call this without a fixed size + uint32_t blockCount = GetBlockCount(startAddress, endAddress, 1, c_MARKER_CONFIGURATION_X509CAROOTBUNDLE_V1); + + // start computing allocation size, first part is the struct initial fields + allocationSize = offsetof(HAL_CONFIGURATION_X509_CERTIFICATE, Certificates); + + // second pass: find out the size of each X509 certificate (because they can have different sizes and we need this to allocate memory for the struct) + if(blockCount > 0) + { + for(uint32_t i = 0; i < blockCount; i++) + { + nextBlock = FindNextBlock(nextBlock, endAddress, c_MARKER_CONFIGURATION_X509CAROOTBUNDLE_V1); + + // header + allocationSize += offsetof(HAL_Configuration_X509CaRootBundle, Certificate); + + // certificate + allocationSize += ((HAL_Configuration_X509CaRootBundle*)nextBlock)->CertificateSize; + } + } + + // allocate config struct + HAL_CONFIGURATION_X509_CERTIFICATE *certificateStore = (HAL_CONFIGURATION_X509_CERTIFICATE *)platform_malloc(allocationSize); + + // set collection count + certificateStore->Count = blockCount; + + if(blockCount > 0) + { + // second pass: get address of each config block + for(uint32_t i = 0; i < blockCount; i++) + { + nextBlock = FindNextBlock(nextBlock, endAddress, c_MARKER_CONFIGURATION_X509CAROOTBUNDLE_V1); + certificateStore->Certificates[i] = (HAL_Configuration_X509CaRootBundle*)nextBlock; + } + } + + return certificateStore; +} + __nfweak HAL_Configuration_Wireless80211* ConfigurationManager_GetWirelessConfigurationFromId(uint32_t configurationId) { for(int i = 0; i < g_TargetConfiguration.Wireless80211Configs->Count; i++) diff --git a/src/HAL/nanoHAL_ConfigurationManager_stubs.c b/src/HAL/nanoHAL_ConfigurationManager_stubs.c index 3abe2af839..1377a64c68 100644 --- a/src/HAL/nanoHAL_ConfigurationManager_stubs.c +++ b/src/HAL/nanoHAL_ConfigurationManager_stubs.c @@ -26,6 +26,14 @@ __nfweak void* ConfigurationManager_FindNetworkWireless80211ConfigurationBlocks( return NULL; } +__nfweak void* ConfigurationManager_FindX509CertificateConfigurationBlocks(uint32_t startAddress, uint32_t endAddress) +{ + (void)startAddress; + (void)endAddress; + + return NULL; +} + __nfweak HAL_Configuration_Wireless80211* ConfigurationManager_GetWirelessConfigurationFromId(uint32_t configurationId) { (void)configurationId; diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_add_cert_auth_internal.cpp b/src/PAL/COM/sockets/ssl/mbedTLS/ssl_add_cert_auth_internal.cpp index a8b8cadcb1..4933df1384 100644 --- a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_add_cert_auth_internal.cpp +++ b/src/PAL/COM/sockets/ssl/mbedTLS/ssl_add_cert_auth_internal.cpp @@ -6,22 +6,6 @@ #include #include "mbedtls.h" -// TODO FIXME - no Certificate store - -#ifdef NO_CERT_STORE - -bool ssl_add_cert_auth_internal( int sslContextHandle, const char* certificate, int certLength, const char* certPassword ) -{ - (void)sslContextHandle; - (void)certificate; - (void)certLength; - (void)certPassword; - - return false; -} - -#else - bool ssl_add_cert_auth_internal( int sslContextHandle, const char* certificate, int certLength, const char* certPassword ) { (void)certPassword; @@ -57,5 +41,3 @@ bool ssl_add_cert_auth_internal( int sslContextHandle, const char* certificate, return false; } - -#endif diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_clear_cert_auth_internal.cpp b/src/PAL/COM/sockets/ssl/mbedTLS/ssl_clear_cert_auth_internal.cpp deleted file mode 100644 index 5f5d316dd4..0000000000 --- a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_clear_cert_auth_internal.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// See LICENSE file in the project root for full license information. -// - -#include -#include "mbedtls.h" - -// TODO FIXME - no Certificate store - -void ssl_clear_cert_auth_internal(int sslContextHandle ) -{ - #ifndef NO_CERT_STORE - - mbedTLS_NFContext* context; - - // Check sslContextHandle range - if((sslContextHandle >= (int)ARRAYSIZE(g_SSL_Driver.m_sslContextArray)) || (sslContextHandle < 0)) - { - return; - } - - // Retrieve SSL struct from g_SSL_Driver - // sd should already have been created - // Now do the SSL negotiation - context = (mbedTLS_NFContext*)g_SSL_Driver.m_sslContextArray[sslContextHandle].SslContext; - if (context == NULL) - { - return; - } - - // // Set a NULL cert store, SSL_CTX_set_cert_store will free the existing cert store - // SSL_CTX_set_cert_store( SSL_get_SSL_CTX(ssl), NULL ); - #else - - (void)sslContextHandle; - - #endif -} diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_generic_init_internal.cpp b/src/PAL/COM/sockets/ssl/mbedTLS/ssl_generic_init_internal.cpp index 6550873002..6d72d112b8 100644 --- a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_generic_init_internal.cpp +++ b/src/PAL/COM/sockets/ssl/mbedTLS/ssl_generic_init_internal.cpp @@ -19,6 +19,9 @@ bool ssl_generic_init_internal( int sslMode, int sslVerify, const char* certific int authMode = MBEDTLS_SSL_VERIFY_NONE; int endpoint = 0; + // we only have one CA root bundle, so this is fixed to 0 + uint32_t configIndex = 0; + /////////////////////// mbedTLS_NFContext* context; @@ -51,9 +54,6 @@ bool ssl_generic_init_internal( int sslMode, int sslVerify, const char* certific if(isServer) { endpoint = MBEDTLS_SSL_IS_SERVER; - - // TODO NOT IMPLEMENTED - // // TODO: we should be setting up the CA list } else { @@ -161,23 +161,56 @@ bool ssl_generic_init_internal( int sslMode, int sslVerify, const char* certific mbedtls_ssl_conf_rng( context->conf, mbedtls_ctr_drbg_random, context->ctr_drbg ); - // parse certificate if passed - if(certificate != NULL && certLength > 0) + // CA root certs from store, if available + if(g_TargetConfiguration.CertificateStore->Count > 0) { ///////////////////////////////////////////////////////////////////////////////////////////////// // developer notes: // + // don't care about failure in processing the CA cert bundle // + // the outcome is that the CA certs won't be loaded into the trusted CA chain // // this call parses certificates in both string and binary formats // // when the formart is a string it has to include the terminator otherwise the parse will fail // ///////////////////////////////////////////////////////////////////////////////////////////////// - if(mbedtls_x509_crt_parse( context->x509_crt, (const unsigned char*)certificate, certLength ) != 0) - { - // x509_crt_parse_failed - goto error; - } + mbedtls_x509_crt_parse( + context->x509_crt, + (const unsigned char*)g_TargetConfiguration.CertificateStore->Certificates[configIndex]->Certificate, + g_TargetConfiguration.CertificateStore->Certificates[configIndex]->CertificateSize ); - mbedtls_ssl_conf_ca_chain( context->conf, context->x509_crt, NULL ); } + // parse "own" certificate if passed + if(certificate != NULL && certLength > 0) + { + // TODO + // this isn't required for client authentication + + // mbedtls_x509_crt_init( &clicert ); + + // ///////////////////////////////////////////////////////////////////////////////////////////////// + // // developer notes: // + // // this call parses certificates in both string and binary formats // + // // when the formart is a string it has to include the terminator otherwise the parse will fail // + // ///////////////////////////////////////////////////////////////////////////////////////////////// + // if(mbedtls_x509_crt_parse( &clicert, (const unsigned char*)certificate, certLength ) != 0) + // { + // // x509_crt_parse_failed + // goto error; + // } + + // if( mbedtls_pk_parse_key( &pkey, (const unsigned char *) mbedtls_test_cli_key, mbedtls_test_cli_key_len, NULL, 0 ) != 0) + // { + // // failed parsing the + // } + + // if( mbedtls_ssl_conf_own_cert( &conf, &clicert, &pkey ) != 0 ) + // { + // // configuring own certificate failed + // goto error; + // } + } + + mbedtls_ssl_conf_ca_chain( context->conf, context->x509_crt, NULL ); + // set certificate verification // the current options provided by mbed TLS are only verify or don't verify if((SslVerification)sslVerify == SslVerification_CertificateRequired) diff --git a/src/PAL/COM/sockets/ssl/openssl/openssl.h b/src/PAL/COM/sockets/ssl/openssl/openssl.h index af3d0ef162..7fd339097a 100644 --- a/src/PAL/COM/sockets/ssl/openssl/openssl.h +++ b/src/PAL/COM/sockets/ssl/openssl/openssl.h @@ -22,6 +22,5 @@ X509* ssl_parse_certificate(void* pCert, size_t certLen, const char* pwd, EVP_PK // Define disable functions that are not available - openssl wrapper #define NO_LIBRARY_INIT -#define NO_CERT_STORE #define NO_CHECK_PRIVATE_KEY #endif diff --git a/src/PAL/COM/sockets/ssl/openssl/ssl_add_cert_auth_internal.cpp b/src/PAL/COM/sockets/ssl/openssl/ssl_add_cert_auth_internal.cpp index c3bcb9fc1c..1aef66b10f 100644 --- a/src/PAL/COM/sockets/ssl/openssl/ssl_add_cert_auth_internal.cpp +++ b/src/PAL/COM/sockets/ssl/openssl/ssl_add_cert_auth_internal.cpp @@ -15,30 +15,14 @@ // #include // #include -// TODO FIXME - no Certificate store -#ifdef NO_CERT_STORE - -bool ssl_add_cert_auth_internal( int sslContextHandle, const char* certificate, - int certLength, const char* certPassword ) -{ - (void)sslContextHandle; - (void)certificate; - (void)certLength; - (void)certPassword; - - return false; -} - -#else - -extern CK_RV Cryptoki_GetSlotIDFromSession(CK_SESSION_HANDLE session, CK_SLOT_ID_PTR pSlotID, CryptokiSession** ppSession); +//extern CK_RV Cryptoki_GetSlotIDFromSession(CK_SESSION_HANDLE session, CK_SLOT_ID_PTR pSlotID, CryptokiSession** ppSession); bool ssl_add_cert_auth_internal( int sslContextHandle, const char* certificate, int certLength, const char* certPassword ) { SSL *ssl = NULL; int ret = FALSE; - X509 *x=NULL; + X509 *tempCertificate=NULL; if((sslContextHandle >= ARRAYSIZE(g_SSL_Driver.m_sslContextArray)) || (sslContextHandle < 0)) { @@ -51,54 +35,49 @@ bool ssl_add_cert_auth_internal( int sslContextHandle, const char* certificate, goto error; } - if(certLength == sizeof(INT32)) - { - CryptokiSession* pSession; - CK_SLOT_ID slotID; - OBJECT_DATA* pObj; - CERT_DATA* pCert; - CK_SESSION_HANDLE sessCtx; + // if(certLength == sizeof(INT32)) + // { + // CryptokiSession* pSession; + // CK_SLOT_ID slotID; + // OBJECT_DATA* pObj; + // CERT_DATA* pCert; + // CK_SESSION_HANDLE sessCtx; - if(certPassword == NULL) return FALSE; + // if(certPassword == NULL) return FALSE; - sessCtx = *(INT32*)certPassword; + // sessCtx = *(INT32*)certPassword; - if(CKR_OK != Cryptoki_GetSlotIDFromSession(sessCtx, &slotID, &pSession)) return FALSE; + // if(CKR_OK != Cryptoki_GetSlotIDFromSession(sessCtx, &slotID, &pSession)) return FALSE; - pObj = PKCS11_Objects_OpenSSL::GetObjectFromHandle(&pSession->Context, *(INT32*)certificate); + // pObj = PKCS11_Objects_OpenSSL::GetObjectFromHandle(&pSession->Context, *(INT32*)certificate); - if(pObj == NULL || pObj->Type != CertificateType) return FALSE; + // if(pObj == NULL || pObj->Type != CertificateType) return FALSE; - pCert = (CERT_DATA*)pObj->Data; + // pCert = (CERT_DATA*)pObj->Data; - x = pCert->cert; - } - else + // certificate = pCert->cert; + // } + // else { - x = ssl_parse_certificate((void*)certificate, certLength, certPassword, NULL); + tempCertificate = ssl_parse_certificate((void*)certificate, certLength, certPassword, NULL); } - if(x != NULL) + if(tempCertificate != NULL) { - X509_NAME* pName = X509_get_subject_name(x); + SSL_CTX* pCtx = SSL_get_SSL_CTX(ssl); - if(pName) + if(pCtx == NULL) { - SSL_CTX* pCtx = SSL_get_SSL_CTX(ssl); + X509_free(tempCertificate); + + return FALSE; + } - if(pCtx == NULL) - { - if(certLength != sizeof(INT32)) X509_free(x); - - return FALSE; - } + ret = X509_STORE_add_cert(SSL_CTX_get_cert_store(pCtx), tempCertificate); - ret = X509_STORE_add_cert(SSL_CTX_get_cert_store(pCtx), x); - } + X509_free(tempCertificate); } error: return ret; } -#endif - diff --git a/src/PAL/COM/sockets/ssl/openssl/ssl_clear_cert_auth_internal.cpp b/src/PAL/COM/sockets/ssl/openssl/ssl_clear_cert_auth_internal.cpp deleted file mode 100644 index d36f1d41a9..0000000000 --- a/src/PAL/COM/sockets/ssl/openssl/ssl_clear_cert_auth_internal.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (c) 2017 The nanoFramework project contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -#include -#include -#include - -// #include -// #include -// #include - -void ssl_clear_cert_auth_internal( int sslContextHandle ) -{ -#ifndef NO_CERT_STORE - SSL *ssl = NULL; - - if((sslContextHandle >= (int)ARRAYSIZE(g_SSL_Driver.m_sslContextArray)) || (sslContextHandle < 0)) - { - return; - } - - ssl = (SSL*)g_SSL_Driver.m_sslContextArray[sslContextHandle].SslContext; - if (ssl == NULL) - { - return; - } - - // Set a NULL cert store, SSL_CTX_set_cert_store will free the existing cert store - SSL_CTX_set_cert_store( SSL_get_SSL_CTX(ssl), NULL ); -#else - (void)sslContextHandle; -#endif -} - - diff --git a/src/PAL/COM/sockets/ssl/openssl/ssl_functions.h b/src/PAL/COM/sockets/ssl/openssl/ssl_functions.h index 564b0a927e..a0f9387887 100644 --- a/src/PAL/COM/sockets/ssl/openssl/ssl_functions.h +++ b/src/PAL/COM/sockets/ssl/openssl/ssl_functions.h @@ -36,7 +36,6 @@ BOOL ssl_exit_context_internal(int sslContextHandle ); BOOL ssl_generic_init_internal( int sslMode, int sslVerify, const char* certificate, int certLength, const char* pwd, int& sslContextHandle, BOOL isServer ); BOOL ssl_initialize_internal(); BOOL ssl_uninitialize_internal(); -void ssl_clear_cert_auth_internal(int sslContextHandle ); BOOL ssl_add_cert_auth_internal( int sslContextHandle, const char* certificate, int certLength, const char* certPassword ); #endif diff --git a/src/PAL/COM/sockets/ssl/openssl/ssl_generic_init_internal.cpp b/src/PAL/COM/sockets/ssl/openssl/ssl_generic_init_internal.cpp index 8531a2c843..6b26109634 100644 --- a/src/PAL/COM/sockets/ssl/openssl/ssl_generic_init_internal.cpp +++ b/src/PAL/COM/sockets/ssl/openssl/ssl_generic_init_internal.cpp @@ -53,6 +53,9 @@ bool ssl_generic_init_internal( int sslMode, int sslVerify, const char* certific int sslCtxIndex = -1; + // we only have one CA root bundle, so this is fixed to 0 + uint32_t configIndex = 0; + for(uint32_t i=0; iCount > 0) + { + cert_x509 = ssl_parse_certificate( + (void*)g_TargetConfiguration.CertificateStore->Certificates[configIndex]->Certificate, + g_TargetConfiguration.CertificateStore->Certificates[configIndex]->CertificateSize, NULL, NULL); + + if(cert_x509 != NULL) + { + X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert_x509); + } + } + + if(certLength != sizeof(INT32) || cert_x509 != NULL) { if(cert_x509 != NULL) X509_free(cert_x509); } - // NANOCLR_SSL_VERIFY_XXX >> 1 == SSL_VERIFY_xxx ssl->verify_mode = (sslVerify >> 1); diff --git a/src/PAL/COM/sockets/ssl/openssl/ssl_uninitialize_internal.cpp b/src/PAL/COM/sockets/ssl/openssl/ssl_uninitialize_internal.cpp index 3a33242276..553452acce 100644 --- a/src/PAL/COM/sockets/ssl/openssl/ssl_uninitialize_internal.cpp +++ b/src/PAL/COM/sockets/ssl/openssl/ssl_uninitialize_internal.cpp @@ -14,8 +14,6 @@ // #include // #include -extern volatile int ssl_x509_store_ctx_idx; - bool ssl_uninitialize_internal() { bool result = TRUE; @@ -34,8 +32,6 @@ bool ssl_uninitialize_internal() // CRYPTO_cleanup_all_ex_data(); // EVP_cleanup(); - ssl_x509_store_ctx_idx = -1; - return result; } diff --git a/src/PAL/COM/sockets/ssl/ssl.cpp b/src/PAL/COM/sockets/ssl/ssl.cpp index ffdc8e8c51..1d515d2325 100644 --- a/src/PAL/COM/sockets/ssl/ssl.cpp +++ b/src/PAL/COM/sockets/ssl/ssl.cpp @@ -72,11 +72,6 @@ bool SSL_AddCertificateAuthority( int sslContextHandle, const char* certificate, return ssl_add_cert_auth_internal(sslContextHandle, certificate, certLength, certPassword); } -void SSL_ClearCertificateAuthority( int sslContextHandle ) -{ - ssl_clear_cert_auth_internal(sslContextHandle); -} - bool SSL_ExitContext( int sslContextHandle ) { return ssl_exit_context_internal(sslContextHandle); diff --git a/src/PAL/COM/sockets/ssl/ssl_functions.h b/src/PAL/COM/sockets/ssl/ssl_functions.h index 803a7d2108..08af7057f0 100644 --- a/src/PAL/COM/sockets/ssl/ssl_functions.h +++ b/src/PAL/COM/sockets/ssl/ssl_functions.h @@ -60,7 +60,6 @@ bool ssl_exit_context_internal(int sslContextHandle ); bool ssl_generic_init_internal( int sslMode, int sslVerify, const char* certificate, int certLength, const char* pwd, int& sslContextHandle, bool isServer ); bool ssl_initialize_internal(); bool ssl_uninitialize_internal(); -void ssl_clear_cert_auth_internal(int sslContextHandle ); bool ssl_add_cert_auth_internal( int sslContextHandle, const char* certificate, int certLength, const char* certPassword ); #endif diff --git a/src/PAL/COM/sockets/ssl/ssl_stubs.cpp b/src/PAL/COM/sockets/ssl/ssl_stubs.cpp index 7170723353..b72efca104 100644 --- a/src/PAL/COM/sockets/ssl/ssl_stubs.cpp +++ b/src/PAL/COM/sockets/ssl/ssl_stubs.cpp @@ -50,12 +50,6 @@ __nfweak bool SSL_AddCertificateAuthority( int sslContextHandle, const char* cer return TRUE; } -__nfweak void SSL_ClearCertificateAuthority( int sslContextHandle ) -{ - (void)sslContextHandle; - NATIVE_PROFILE_PAL_COM(); -} - __nfweak bool SSL_ExitContext( int sslContextHandle ) { (void)sslContextHandle; diff --git a/src/PAL/Include/nanoPAL_Sockets.h b/src/PAL/Include/nanoPAL_Sockets.h index ba72d29362..8a7d1bdadc 100644 --- a/src/PAL/Include/nanoPAL_Sockets.h +++ b/src/PAL/Include/nanoPAL_Sockets.h @@ -607,7 +607,6 @@ bool SSL_Uninitialize(); bool SSL_ServerInit ( int sslMode, int sslVerify, const char* certificate, int certLength, const char* certPassword, int& sslContextHandle ); bool SSL_ClientInit ( int sslMode, int sslVerify, const char* certificate, int certLength, const char* certPassword, int& sslContextHandle ); bool SSL_AddCertificateAuthority( int sslContextHandle, const char* certificate, int certLength, const char* certPassword ); -void SSL_ClearCertificateAuthority( int sslContextHandle ); bool SSL_ExitContext( int sslContextHandle ); int SSL_Accept ( int socket, int sslContextHandle ); int SSL_Connect ( int socket, const char* szTargetHost, int sslContextHandle ); diff --git a/targets-community b/targets-community index 79ff67d68a..eaaeff7dd4 160000 --- a/targets-community +++ b/targets-community @@ -1 +1 @@ -Subproject commit 79ff67d68acc03d96b6fdd19b07948804492a4c6 +Subproject commit eaaeff7dd4bfe44bf7c43fa9d2cafc5d62d2882f diff --git a/targets/CMSIS-OS/ChibiOS/common/targetHAL_ConfigurationManager.cpp b/targets/CMSIS-OS/ChibiOS/common/targetHAL_ConfigurationManager.cpp index 5b79aee387..115bcabb0c 100644 --- a/targets/CMSIS-OS/ChibiOS/common/targetHAL_ConfigurationManager.cpp +++ b/targets/CMSIS-OS/ChibiOS/common/targetHAL_ConfigurationManager.cpp @@ -29,22 +29,29 @@ __nfweak void ConfigurationManager_EnumerateConfigurationBlocks() // find wireless 80211 network configuration blocks HAL_CONFIGURATION_NETWORK_WIRELESS80211* networkWirelessConfigs = (HAL_CONFIGURATION_NETWORK_WIRELESS80211*)ConfigurationManager_FindNetworkWireless80211ConfigurationBlocks((uint32_t)&__nanoConfig_start__, (uint32_t)&__nanoConfig_end__); + // find X509 certificate blocks + HAL_CONFIGURATION_X509_CERTIFICATE* certificateStore = (HAL_CONFIGURATION_X509_CERTIFICATE*)ConfigurationManager_FindX509CertificateConfigurationBlocks((uint32_t)&__nanoConfig_start__, (uint32_t)&__nanoConfig_end__); + // alloc memory for g_TargetConfiguration // because this is a struct of structs that use flexible members the memory has to be allocated from the heap // the malloc size for each struct is computed separately uint32_t sizeOfNetworkInterfaceConfigs = offsetof(HAL_CONFIGURATION_NETWORK, Configs) + networkConfigs->Count * sizeof(networkConfigs->Configs[0]); uint32_t sizeOfWireless80211Configs = offsetof(HAL_CONFIGURATION_NETWORK_WIRELESS80211, Configs) + networkWirelessConfigs->Count * sizeof(networkWirelessConfigs->Configs[0]); + uint32_t sizeOfX509CertificateStore = offsetof(HAL_CONFIGURATION_X509_CERTIFICATE, Certificates) + certificateStore->Count * sizeof(certificateStore->Certificates[0]); g_TargetConfiguration.NetworkInterfaceConfigs = (HAL_CONFIGURATION_NETWORK*)platform_malloc(sizeOfNetworkInterfaceConfigs); g_TargetConfiguration.Wireless80211Configs = (HAL_CONFIGURATION_NETWORK_WIRELESS80211*)platform_malloc(sizeOfWireless80211Configs); + g_TargetConfiguration.CertificateStore = (HAL_CONFIGURATION_X509_CERTIFICATE*)platform_malloc(sizeOfX509CertificateStore); // copy structs to g_TargetConfiguration memcpy((HAL_CONFIGURATION_NETWORK*)g_TargetConfiguration.NetworkInterfaceConfigs, networkConfigs, sizeOfNetworkInterfaceConfigs); memcpy((HAL_CONFIGURATION_NETWORK_WIRELESS80211*)g_TargetConfiguration.Wireless80211Configs, networkWirelessConfigs, sizeOfWireless80211Configs); + memcpy((HAL_CONFIGURATION_X509_CERTIFICATE*)g_TargetConfiguration.CertificateStore, certificateStore, sizeOfX509CertificateStore); - // // now free the memory of the original structs + // now free the memory of the original structs platform_free(networkConfigs); platform_free(networkWirelessConfigs); + platform_free(certificateStore); } else { @@ -100,6 +107,22 @@ __nfweak bool ConfigurationManager_GetConfigurationBlock(void* configurationBloc // get block address blockAddress = (uint8_t*)g_TargetConfiguration.Wireless80211Configs->Configs[configurationIndex]; } + else if(configuration == DeviceConfigurationOption_X509CaRootBundle) + { + if(g_TargetConfiguration.CertificateStore->Count == 0 || + (configurationIndex + 1) > g_TargetConfiguration.CertificateStore->Count) + { + return FALSE; + } + + // get block address + blockAddress = (uint8_t*)g_TargetConfiguration.CertificateStore->Certificates[configurationIndex]; + + // set block size + // because X509 certificate has a variable length need to compute the block size in two steps + sizeOfBlock = offsetof(HAL_Configuration_X509CaRootBundle, Certificate); + sizeOfBlock += ((HAL_Configuration_X509CaRootBundle*)blockAddress)->CertificateSize; + } // copy the config block content to the pointer in the argument memcpy(configurationBlock, blockAddress, sizeOfBlock); @@ -111,7 +134,7 @@ __nfweak bool ConfigurationManager_GetConfigurationBlock(void* configurationBloc // NOTE: because inserting or removing a configuration block it's very 'RAM expensive' we choose not to support those operations // the host debugger will have to be used to manage these operations on the device configuration collection // it's implemented with 'weak' attribute so it can be replaced at target level if a different persistance mechanism is used -__nfweak bool ConfigurationManager_StoreConfigurationBlock(void* configurationBlock, DeviceConfigurationOption configuration, uint32_t configurationIndex, uint32_t blockSize) +__nfweak bool ConfigurationManager_StoreConfigurationBlock(void* configurationBlock, DeviceConfigurationOption configuration, uint32_t configurationIndex, uint32_t blockSize, uint32_t offset) { ByteAddress storageAddress = 0; bool requiresEnumeration = FALSE; @@ -127,8 +150,8 @@ __nfweak bool ConfigurationManager_StoreConfigurationBlock(void* configurationBl return FALSE; } - // set storage address from block address - storageAddress = (ByteAddress)g_TargetConfiguration.NetworkInterfaceConfigs->Configs[configurationIndex]; + // set storage address from block address, plus the requested offset + storageAddress = (ByteAddress)g_TargetConfiguration.NetworkInterfaceConfigs->Configs[configurationIndex] + offset; // set block size, in case it's not already set blockSize = sizeof(HAL_Configuration_NetworkInterface); @@ -148,8 +171,8 @@ __nfweak bool ConfigurationManager_StoreConfigurationBlock(void* configurationBl return FALSE; } - // set storage address from block address - storageAddress = (ByteAddress)g_TargetConfiguration.Wireless80211Configs->Configs[configurationIndex]; + // set storage address from block address, plus the requested offset + storageAddress = (ByteAddress)g_TargetConfiguration.Wireless80211Configs->Configs[configurationIndex] + offset; // set block size, in case it's not already set blockSize = sizeof(HAL_Configuration_Wireless80211); @@ -157,12 +180,33 @@ __nfweak bool ConfigurationManager_StoreConfigurationBlock(void* configurationBl // make sure the config block marker is set memcpy(configurationBlock, c_MARKER_CONFIGURATION_WIRELESS80211_V1, sizeof(c_MARKER_CONFIGURATION_WIRELESS80211_V1)); } + else if(configuration == DeviceConfigurationOption_X509CaRootBundle) + { + if( g_TargetConfiguration.CertificateStore->Count == 0 || + (configurationIndex + 1) > g_TargetConfiguration.CertificateStore->Count) + { + // there is no room for this block, or there are no blocks stored at all + // failing the operation + return FALSE; + } + + // set storage address from block address, plus the requested offset + storageAddress = (ByteAddress)g_TargetConfiguration.CertificateStore->Certificates[configurationIndex] + offset; + + // set block size, in case it's not already set + // because X509 certificate has a variable length need to compute the block size in two steps + blockSize = offsetof(HAL_Configuration_X509CaRootBundle, Certificate); + blockSize += ((HAL_Configuration_X509CaRootBundle*)configurationBlock)->CertificateSize; + + // make sure the config block marker is set + memcpy(configurationBlock, c_MARKER_CONFIGURATION_X509CAROOTBUNDLE_V1, sizeof(c_MARKER_CONFIGURATION_X509CAROOTBUNDLE_V1)); + } else if(configuration == DeviceConfigurationOption_All) { // particular situation where we are receiving the full configuration block - // set storage address as the start of the flash configuration sector - storageAddress = (ByteAddress)&__nanoConfig_start__; + // set storage address as the start of the flash configuration sector, plus the requested offset + storageAddress = (ByteAddress)&__nanoConfig_start__ + offset; // always enumerate the blocks again after storing it requiresEnumeration = TRUE; @@ -182,6 +226,7 @@ __nfweak bool ConfigurationManager_StoreConfigurationBlock(void* configurationBl // free the current allocation(s) platform_free(g_TargetConfiguration.NetworkInterfaceConfigs); platform_free(g_TargetConfiguration.Wireless80211Configs); + platform_free(g_TargetConfiguration.CertificateStore); // perform enumeration of configuration blocks ConfigurationManager_EnumerateConfigurationBlocks(); @@ -240,6 +285,19 @@ __nfweak bool ConfigurationManager_UpdateConfigurationBlock(void* configurationB // make sure the config block marker is set memcpy(configurationBlock, c_MARKER_CONFIGURATION_WIRELESS80211_V1, sizeof(c_MARKER_CONFIGURATION_WIRELESS80211_V1)); } + else if(configuration == DeviceConfigurationOption_X509CaRootBundle) + { + // storage address from block address + storageAddress = (ByteAddress)g_TargetConfiguration.CertificateStore->Certificates[configurationIndex]; + + // set block size, in case it's not already set + // because X509 certificate has a variable length need to compute the block size in two steps + blockSize = offsetof(HAL_Configuration_X509CaRootBundle, Certificate); + blockSize += ((HAL_Configuration_X509CaRootBundle*)configurationBlock)->CertificateSize; + + // make sure the config block marker is set + memcpy(configurationBlock, c_MARKER_CONFIGURATION_X509CAROOTBUNDLE_V1, sizeof(c_MARKER_CONFIGURATION_X509CAROOTBUNDLE_V1)); + } else { // this not a valid configuration option to update, quit diff --git a/targets/CMSIS-OS/ChibiOS/nanoBooter/WireProtocol_MonitorCommands.c b/targets/CMSIS-OS/ChibiOS/nanoBooter/WireProtocol_MonitorCommands.c index a959bcea75..ec6a5eea0c 100644 --- a/targets/CMSIS-OS/ChibiOS/nanoBooter/WireProtocol_MonitorCommands.c +++ b/targets/CMSIS-OS/ChibiOS/nanoBooter/WireProtocol_MonitorCommands.c @@ -256,8 +256,9 @@ int Monitor_UpdateConfiguration(WP_Message* message) { case DeviceConfigurationOption_Network: case DeviceConfigurationOption_Wireless80211Network: + case DeviceConfigurationOption_X509CaRootBundle: case DeviceConfigurationOption_All: - if(ConfigurationManager_StoreConfigurationBlock(cmd->Data, (DeviceConfigurationOption)cmd->Configuration, cmd->BlockIndex, cmd->Length) == true) + if(ConfigurationManager_StoreConfigurationBlock(cmd->Data, (DeviceConfigurationOption)cmd->Configuration, cmd->BlockIndex, cmd->Length, cmd->Offset) == true) { cmdReply.ErrorCode = 0; success = true; diff --git a/targets/FreeRTOS/ESP32_DevKitC/nanoCLR/targetHAL_ConfigurationManager.cpp b/targets/FreeRTOS/ESP32_DevKitC/nanoCLR/targetHAL_ConfigurationManager.cpp index 037595be6d..fd84f2ca65 100644 --- a/targets/FreeRTOS/ESP32_DevKitC/nanoCLR/targetHAL_ConfigurationManager.cpp +++ b/targets/FreeRTOS/ESP32_DevKitC/nanoCLR/targetHAL_ConfigurationManager.cpp @@ -76,7 +76,11 @@ void ConfigurationManager_allocate_wireless( uint32_t configCount ) g_TargetConfiguration.Wireless80211Configs->Count = configCount; } - +// Allocate HAL_CONFIGURATION_X509_CERTIFICATE block +// TODO FIXME +// void ConfigurationManager_allocate_certificates( uint32_t certificateCount ) +// { +// } // Enumerates the configuration blocks from the configuration flash sector // it's implemented with 'weak' attribute so it can be replaced at target level if a different persistance mechanism is used @@ -86,9 +90,13 @@ void ConfigurationManager_EnumerateConfigurationBlocks() // Still need to do wireless AP int networkCount = 3; // Esp32 has 3 network interfaces, Ethernet, Wireless Station & Wireless APn int wirelessCount = 2; + int certificateCount = 1; ConfigurationManager_allocate_network( networkCount ); ConfigurationManager_allocate_wireless( wirelessCount ); + // TODO FIXME + //ConfigurationManager_allocate_certificates( certificateCount ); + (void)certificateCount; for( int configIndex = 0; configIndex < networkCount; configIndex++) { @@ -101,6 +109,13 @@ void ConfigurationManager_EnumerateConfigurationBlocks() g_TargetConfiguration.Wireless80211Configs->Configs[configIndex] = (HAL_Configuration_Wireless80211*)platform_malloc(sizeof(HAL_Configuration_Wireless80211)); ConfigurationManager_GetConfigurationBlock( g_TargetConfiguration.Wireless80211Configs->Configs[configIndex], DeviceConfigurationOption_Wireless80211Network, configIndex); } + + // TODO FIXME + // for( int certificateIndex = 0; certificateIndex < certificateCount; configIndex++) + // { + // g_TargetConfiguration.CertificateStore->Certificate[certificateIndex] = (HAL_Configuration_X509CaRootBundle*)platform_malloc(sizeof(HAL_Configuration_X509CaRootBundle)); + // ConfigurationManager_GetConfigurationBlock( g_TargetConfiguration.CertificateStore->Certificates[certificateIndex], DeviceConfigurationOption_X509CaRootBundle, certificateIndex); + // } } // Default initialisation of wireless config blocks for ESP32 targets @@ -220,6 +235,24 @@ bool ConfigurationManager_GetConfigurationBlock(void* configurationBlock, Device blobSize = sizeof(HAL_Configuration_Wireless80211); configName[0] = 'W'; } + else if(configuration == DeviceConfigurationOption_X509CaRootBundle) + { + if(g_TargetConfiguration.CertificateStore->Count == 0 || + (configurationIndex + 1) > g_TargetConfiguration.CertificateStore->Count) + { +#ifdef DEBUG_CONFIG + ets_printf("GetConfig XC exit false\n"); +#endif + return FALSE; + } + + // set blob size + // TODO FIXME + blobSize = offsetof(HAL_Configuration_X509CaRootBundle, Certificate); + blobSize += ((HAL_Configuration_X509CaRootBundle*)configurationBlock)->CertificateSize; + + configName[0] = 'X'; + } // Anything to get if (blobSize != 0 ) @@ -246,6 +279,11 @@ bool ConfigurationManager_GetConfigurationBlock(void* configurationBlock, Device InitialiseNetworkDefaultConfig((HAL_Configuration_NetworkInterface *)configurationBlock,configurationIndex); storeConfig = true; } + else if ( configuration == DeviceConfigurationOption_X509CaRootBundle ) + { + // OK to skip checking return value + storeConfig = false; + } else { // If not found just return initialized block @@ -261,7 +299,8 @@ bool ConfigurationManager_GetConfigurationBlock(void* configurationBlock, Device nvs_close(out_handle); if ( storeConfig ) { - ConfigurationManager_StoreConfigurationBlock(configurationBlock, configuration, configurationIndex, blobSize); + // TODO FIXME, offset parameter is 0 + ConfigurationManager_StoreConfigurationBlock(configurationBlock, configuration, configurationIndex, blobSize, 0); } } } @@ -300,13 +339,17 @@ bool StoreConfigBlock(char ConfigType, uint32_t configurationIndex, void * pConf } // Stores the network configuration block to the EPS32 storage -bool ConfigurationManager_StoreConfigurationBlock(void* configurationBlock, DeviceConfigurationOption configuration, uint32_t configurationIndex, uint32_t blockSize) +bool ConfigurationManager_StoreConfigurationBlock(void* configurationBlock, DeviceConfigurationOption configuration, uint32_t configurationIndex, uint32_t blockSize, uint32_t offset) { bool result = false; bool requiresEnumeration = false; size_t blobSize = 0; + //size_t chunkSize = 0; char ConfigType; + // TODO FIXME + (void)offset; + #ifdef DEBUG_CONFIG ets_printf("StoreConfig %d, %d", (int)configuration, configurationIndex); #endif @@ -323,16 +366,26 @@ bool ConfigurationManager_StoreConfigurationBlock(void* configurationBlock, Devi blobSize = sizeof(HAL_Configuration_Wireless80211); ConfigType = 'W'; } + else if(configuration == DeviceConfigurationOption_X509CaRootBundle) + { + // set blob size + // because X509 certificate has a variable length need to compute the block size in two steps + blobSize = offsetof(HAL_Configuration_X509CaRootBundle, Certificate); + blobSize += ((HAL_Configuration_X509CaRootBundle*)configurationBlock)->CertificateSize; + + ConfigType = 'C'; + } else if(configuration == DeviceConfigurationOption_All) { // All configuration blocks in one block // Separate and update #ifdef DEBUG_CONFIG - ets_printf( "Block size %d\n",blockSize); + ets_printf( "Block size %d\n", blockSize); ets_printf( "sizeof HAL_Configuration_NetworkInterface %d\n", sizeof(HAL_Configuration_NetworkInterface)); ets_printf( "sizeof HAL_Configuration_Wireless80211 %d\n", sizeof(HAL_Configuration_Wireless80211)); + ets_printf( "sizeof of X509Certificate varies\n"); #endif configurationIndex = 0; @@ -367,6 +420,26 @@ bool ConfigurationManager_StoreConfigurationBlock(void* configurationBlock, Devi PrintBlock( (char *)pWirelessConfig, sizeof(HAL_Configuration_Wireless80211) ); #endif } + // X509 certificate block ? + else if (*pConfig == 'C') + { + // TODO +// HAL_Configuration_X509CaRootBundle * pX509Certificate = (HAL_Configuration_X509CaRootBundle*)pConfig; + +// // set block size, in case it's not already set +// // because X509 certificate has a variable length need to compute the block size in two steps +// chunkSize = offsetof(HAL_Configuration_X509CaRootBundle, Certificate); +// chunkSize += pX509Certificate->CertificateSize; + +// pConfig += chunkSize; + +// result = StoreConfigBlock( 'C', pX509Certificate->Id, (void*)pX509Certificate, chunkSize ); + +// #ifdef DEBUG_CONFIG +// ets_printf("X509 certificate block ret:%d\n", result); +// PrintBlock( (char *)pX509Certificate, chunkSize ); +// #endif + } else break; } @@ -396,5 +469,28 @@ bool ConfigurationManager_StoreConfigurationBlock(void* configurationBlock, Devi // Updates a configuration block in the configuration flash sector bool ConfigurationManager_UpdateConfigurationBlock(void* configurationBlock, DeviceConfigurationOption configuration, uint32_t configurationIndex) { - return ConfigurationManager_StoreConfigurationBlock(configurationBlock, configuration, configurationIndex, 0); + // figure out the block size first + uint32_t blockSize = 0; + + switch(configuration) + { + case DeviceConfigurationOption_Network: + blockSize = sizeof(HAL_Configuration_NetworkInterface); + break; + + case DeviceConfigurationOption_Wireless80211Network: + blockSize = sizeof(HAL_Configuration_Wireless80211); + break; + + case DeviceConfigurationOption_X509CaRootBundle: + blockSize = offsetof(HAL_Configuration_X509CaRootBundle, Certificate); + blockSize += ((HAL_Configuration_X509CaRootBundle*)configurationBlock)->CertificateSize; + break; + + default: + // shouldn't ever reach here + return FALSE; + } + + return ConfigurationManager_StoreConfigurationBlock(configurationBlock, configuration, configurationIndex, blockSize, 0); }