poniedziałek, 15 lipca 2024

STM32H7 - SSL Serwer

W tym poście chciałbym opisać implementację serwera SSL. Testy wykonałem na płycie z układem STM32H725 oraz układem LAN8720A. 


Plik LWIP 

Poniżej konfiguracja biblioteki LWIP do projektu:

  1. #define LWIP_DEBUG 2
  2. #define NETIF_DEBUG LWIP_DBG_ON
  3. #define DHCP_DEBUG LWIP_DBG_ON
  4. #define UDP_DEBUG  LWIP_DBG_ON
  5. #define MEMP_DEBUG LWIP_DBG_ON
  6. #define MEM_DEBUG LWIP_DBG_ON
  7. #define ICMP_DEBUG LWIP_DBG_ON
  8. /* STM32CubeMX Specific Parameters (not defined in opt.h) ---------------------*/
  9. /* Parameters set in STM32CubeMX LwIP Configuration GUI -*/
  10. /*----- WITH_RTOS enabled (Since FREERTOS is set) -----*/
  11. #define WITH_RTOS 1
  12. /* Temporary workaround to avoid conflict on errno defined in STM32CubeIDE and lwip sys_arch.c errno */
  13. #undef LWIP_PROVIDE_ERRNO
  14. /*----- WITH_MBEDTLS enabled (Since MBEDTLS and FREERTOS are set) -----*/
  15. #define WITH_MBEDTLS 1
  16. /*----- CHECKSUM_BY_HARDWARE enabled -----*/
  17. #define CHECKSUM_BY_HARDWARE 1
  18. /*-----------------------------------------------------------------------------*/
  19.  
  20. /* LwIP Stack Parameters (modified compared to initialization value in opt.h) -*/
  21. /* Parameters set in STM32CubeMX LwIP Configuration GUI -*/
  22. /*----- Default value in ETH configuration GUI in CubeMx: 1524 -----*/
  23. //#define ETH_RX_BUFFER_SIZE 1536
  24. #define ETH_RX_BUFFER_SIZE 2048
  25.  /*----- Value in opt.h for MEM_ALIGNMENT: 1 -----*/
  26.  #define MEM_ALIGNMENT 4
  27.  /*----- Default Value for MEM_SIZE: 1600 ---*/
  28.  #define MEM_SIZE 32232
  29. /*----- Value in opt.h for LWIP_DNS: 0 -----*/
  30. #define LWIP_DNS 1
  31. /*----- Value in opt.h for MEM_ALIGNMENT: 1 -----*/
  32. #define MEM_ALIGNMENT 4
  33. /*----- Default Value for H7 devices: 0x30044000 -----*/
  34. #define LWIP_RAM_HEAP_POINTER 0x30000200
  35. /*----- Value supported for H7 devices: 1 -----*/
  36. #define LWIP_SUPPORT_CUSTOM_PBUF 1
  37. /*----- Value in opt.h for LWIP_ETHERNET: LWIP_ARP || PPPOE_SUPPORT -*/
  38. #define LWIP_ETHERNET 1
  39. /*----- Value in opt.h for LWIP_DNS_SECURE: (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT) -*/
  40. #define LWIP_DNS_SECURE 7
  41.  /*----- Default Value for TCP_MSS: 536 ---*/
  42. #define TCP_MSS 1460
  43. /*----- Default Value for TCP_SND_BUF: 2920 ---*/
  44. #define TCP_SND_BUF 2920//5840
  45. /*----- Value in opt.h for TCP_SND_QUEUELEN: (4*TCP_SND_BUF + (TCP_MSS - 1))/TCP_MSS -----*/
  46. #define TCP_SND_QUEUELEN 16
  47. /*----- Value in opt.h for TCP_SNDLOWAT: LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) -*/
  48. #define TCP_SNDLOWAT 1071
  49. /*----- Value in opt.h for TCP_SNDQUEUELOWAT: LWIP_MAX(TCP_SND_QUEUELEN)/2, 5) -*/
  50. #define TCP_SNDQUEUELOWAT 5
  51. /*----- Value in opt.h for TCP_WND_UPDATE_THRESHOLD: LWIP_MIN(TCP_WND/4, TCP_MSS*4) -----*/
  52. #define TCP_WND_UPDATE_THRESHOLD 536
  53. /*----- Value in opt.h for LWIP_NETIF_LINK_CALLBACK: 0 -----*/
  54. #define LWIP_NETIF_LINK_CALLBACK 1
  55. /*----- Value in opt.h for TCPIP_THREAD_STACKSIZE: 0 -----*/
  56. #define TCPIP_THREAD_STACKSIZE 1024
  57. /*----- Value in opt.h for TCPIP_THREAD_PRIO: 1 -----*/
  58. #define TCPIP_THREAD_PRIO osPriorityNormal
  59. /*----- Value in opt.h for TCPIP_MBOX_SIZE: 0 -----*/
  60. #define TCPIP_MBOX_SIZE 6
  61. /*----- Value in opt.h for SLIPIF_THREAD_STACKSIZE: 0 -----*/
  62. #define SLIPIF_THREAD_STACKSIZE 1024
  63. /*----- Value in opt.h for SLIPIF_THREAD_PRIO: 1 -----*/
  64. #define SLIPIF_THREAD_PRIO 3
  65. /*----- Value in opt.h for DEFAULT_THREAD_STACKSIZE: 0 -----*/
  66. #define DEFAULT_THREAD_STACKSIZE 1024
  67. /*----- Value in opt.h for DEFAULT_THREAD_PRIO: 1 -----*/
  68. #define DEFAULT_THREAD_PRIO 3
  69. /*----- Value in opt.h for DEFAULT_UDP_RECVMBOX_SIZE: 0 -----*/
  70. #define DEFAULT_UDP_RECVMBOX_SIZE 6
  71. /*----- Value in opt.h for DEFAULT_TCP_RECVMBOX_SIZE: 0 -----*/
  72. #define DEFAULT_TCP_RECVMBOX_SIZE 6
  73. /*----- Value in opt.h for DEFAULT_ACCEPTMBOX_SIZE: 0 -----*/
  74. #define DEFAULT_ACCEPTMBOX_SIZE 6
  75. /*----- Value in opt.h for RECV_BUFSIZE_DEFAULT: INT_MAX -----*/
  76. #define RECV_BUFSIZE_DEFAULT 2000000000
  77. /*----- Value in opt.h for LWIP_USE_EXTERNAL_MBEDTLS: 0 -----*/
  78. #define LWIP_USE_EXTERNAL_MBEDTLS 1
  79. /*----- Default Value for LWIP_HTTPD: 0 ---*/
  80. #define LWIP_HTTPD 1
  81. #define HTTPD_USE_CUSTOM_FSDATA 0
  82. #define LWIP_HTTPD_SUPPORT_POST 1
  83. #define LWIP_HTTPD_CGI 1
  84. #define LWIP_HTTPD_SSI 1
  85. /*----- Value in opt.h for LWIP_STATS: 1 -----*/
  86. #define LWIP_STATS 0
  87. /*----- Value in opt.h for CHECKSUM_GEN_IP: 1 -----*/
  88. #define CHECKSUM_GEN_IP 0
  89. /*----- Value in opt.h for CHECKSUM_GEN_UDP: 1 -----*/
  90. #define CHECKSUM_GEN_UDP 0
  91. /*----- Value in opt.h for CHECKSUM_GEN_TCP: 1 -----*/
  92. #define CHECKSUM_GEN_TCP 0
  93. /*----- Value in opt.h for CHECKSUM_GEN_ICMP6: 1 -----*/
  94. #define CHECKSUM_GEN_ICMP6 0
  95. /*----- Value in opt.h for CHECKSUM_CHECK_IP: 1 -----*/
  96. #define CHECKSUM_CHECK_IP 0
  97. /*----- Value in opt.h for CHECKSUM_CHECK_UDP: 1 -----*/
  98. #define CHECKSUM_CHECK_UDP 0
  99. /*----- Value in opt.h for CHECKSUM_CHECK_TCP: 1 -----*/
  100. #define CHECKSUM_CHECK_TCP 0
  101. /*----- Value in opt.h for CHECKSUM_CHECK_ICMP6: 1 -----*/
  102. #define CHECKSUM_CHECK_ICMP6 0
  103. /*-----------------------------------------------------------------------------*/
  104. /* USER CODE BEGIN 1 */
  105. #define LWIP_SOCKET                     1
  106. #define LWIP_DNS                        1
  107. #define SO_REUSE                        1
  108. /* USER CODE END 1 */

Konfiguracja serwera:

Inicjalizacja zmiennych:

  1. static void MBEDTLS_Init(void){
  2.     #ifdef MBEDTLS_MEMORY_BUFFER_ALLOC_C
  3.     mbedtls_memory_buffer_alloc_init(memory_buf, sizeof(memory_buf));
  4.     #endif
  5.     mbedtls_net_init( &listen_fd );
  6.     mbedtls_net_init( &client_fd );
  7.     mbedtls_ssl_init( &ssl );
  8.     mbedtls_ssl_config_init( &conf );
  9.     #if defined(MBEDTLS_SSL_CACHE_C)
  10.     mbedtls_ssl_cache_init( &cache );
  11.     #endif
  12.     mbedtls_x509_crt_init( &srvcert );
  13.     mbedtls_pk_init( &pkey );
  14.     mbedtls_entropy_init( &entropy );
  15.     mbedtls_ctr_drbg_init( &ctr_drbg );
  16. }

Ustawienie certyfikatów:

  1. static uint8_t MBEDTLS_ParseCerificateKey(void) {
  2.     int opStatus = 0;
  3.  
  4.     opStatus = mbedtls_pk_parse_key(&pkey, (const unsigned char*)mbedtls_certificate_key_ssl_server,        mbedtls_server_certificate_key_len, (const unsigned char*)mbedtls_certificate_key_pass_ssl_server, mbedtls_server_certificate_key_pass_len);
  5.  
  6.     if(opStatus < 0) {
  7.         mbedtls_printf("ERROR - mbedtls_pk_parse_key returned -0x%x\r\n \r\n ", (unsigned int) -opStatus);
  8.         return 1;
  9.     }
  10.  
  11.     opStatus = mbedtls_x509_crt_parse(&srvcert, (const unsigned char*)mbedtls_server_certificate, mbedtls_server_certificate_len  + 1);
  12.  
  13.     if(opStatus < 0) {
  14.         mbedtls_printf("ERROR - mbedtls_x509_crt_parse returned -0x%x\r\n \r\n ", (unsigned int) -opStatus);
  15.         return 1;
  16.     }
  17.  
  18.     opStatus = mbedtls_ssl_conf_own_cert(&conf, &srvcert, &pkey);
  19.     if(opStatus < 0) {
  20.           mbedtls_printf("ERROR - mbedtls_ssl_conf_own_cert returned -0x%x\r\n \r\n ", (unsigned int) -opStatus);
  21.           return 1;
  22.     }
  23.     return 0;
  24. }

Certyfikaty musza byc zdefiniowane w następujący sposób:

  1. const char mbedtls_server_certificate[] =
  2.         "-----BEGIN CERTIFICATE-----\r\n"
  3.             "CERTYFIKAT\r\n"
  4.             "CERTYFIKAT\r\n"
  5.         "-----END CERTIFICATE-----\r\n";
  6.  
  7. const char mbedtls_certificate_key_pass_ssl_server[] = "sH$kd@t@104";
  8.  
  9. const char mbedtls_certificate_key_ssl_server[] =
  10.             "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n"
  11.             "CERTYFIKAT KLUCZ\r\n"
  12.             "CERTYFIKAT KLUCZ\r\n"
  13.             "-----END ENCRYPTED PRIVATE KEY-----\r\n";
  14.  
  15. const size_t mbedtls_server_certificate_len = strlen(mbedtls_server_certificate);
  16. const size_t mbedtls_server_certificate_key_len = sizeof(mbedtls_certificate_key_ssl_server);
  17. const size_t mbedtls_server_certificate_key_pass_len = strlen(mbedtls_certificate_key_pass_ssl_server);

Należy pamiętać aby w certyfikatach oraz kluczach nie znajdowałuy się spacje. Każda linia musi być zakończona znakiem \r\n. 

Ustawienie soketu TCP:

  1. static uint8_t SetupTCPSocket(void) {
  2.     int ret;
  3.     mbedtls_printf( "  . Bind on https://localhost:%s/ ...", SERVER_PORT );
  4.     fflush(stdout);
  5.  
  6.     if((ret = mbedtls_net_bind(&listen_fd, NULL, SERVER_PORT , MBEDTLS_NET_PROTO_TCP )) != 0)
  7.     {
  8.         mbedtls_printf( " failed\n  ! mbedtls_net_bind returned %d -0x%x\n\n", ret, (unsigned int) -ret);
  9.         return 1;
  10.     }
  11.     return 0;
  12. }

Inicjalizacja generatora liczb losowych. Pozwala to na zapewnienie entropii czyli generowania naprawdę losowych liczb dla RNG. Dzięki temu można uzyskać prawdziwie losowe wartości dla każdej sesji SSL. 

  1. static uint8_t SeedRNG(void) {
  2.     int ret;
  3.     mbedtls_printf( "  . Seeding the random number generator..." );
  4.  
  5.     if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen( (char *)pers))) != 0)
  6.     {
  7.         mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
  8.         return 1;
  9.     }
  10.  
  11.     mbedtls_printf( " ok\n" );
  12.     return 0;
  13. }

Konfiguracja połączenia SSL:

  1. static uint8_t SetupConfig(void) {
  2.     int ret;
  3.  
  4.     mbedtls_printf( "  . Setting up the SSL data...." );
  5.  
  6.     if((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
  7.         return 1;
  8.     }
  9.  
  10.     mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
  11.  
  12.     #if defined(MBEDTLS_SSL_CACHE_C)
  13.     mbedtls_ssl_conf_session_cache(&conf, &cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set);
  14.     #endif
  15.  
  16.     mbedtls_ssl_conf_ca_chain(&conf, srvcert.next, NULL);
  17.     if((ret = mbedtls_ssl_conf_own_cert(&conf, &srvcert, &pkey)) != 0) {
  18.         return 2;
  19.     }
  20.  
  21.     if((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
  22.         return 3;
  23.     }
  24.  
  25.     mbedtls_printf( " ok\n" );
  26.  
  27.     return 0;
  28. }

Kolejnym krokiem jest oczekiwanie na połączenie klienta:

  1. static uint8_t WaitForClientConnection(void) {
  2.     int ret;
  3.  
  4.     if((ret = WaitForConnection()) != 0) {
  5.         mbedtls_printf(" failed\n  ! mbedtls_net_accept returned %d\n\n", ret);
  6.         return 1;
  7.     }
  8.     mbedtls_printf("Client Conn ok\n");
  9.     fflush(stdout);
  10.     return 0;
  11. }

Następnie wykonujemy procedurę Handshake:

  1. static uint8_t PerformHandshake(void) {
  2.     int ret;
  3.  
  4.     if((ret = Handshake()) != 0)
  5.     {
  6.         mbedtls_printf(" failed\n  ! mbedtls_ssl_handshake returned %d\n\n", ret);
  7.         return 1;
  8.     }
  9.     mbedtls_printf("Handshake ok\n");
  10.     fflush(stdout);
  11.     return 0;
  12. }

Następnie odczytujemy rządanie od klienta do serwera:

  1.   mbedtls_printf("  < Read from client:");
  2.   do
  3.   {
  4.     len = sizeof(buf) - 1;
  5.     memset(buf, 0, sizeof(buf));
  6.     ret = mbedtls_ssl_read(&ssl, buf, len);
  7.  
  8.     if(ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE)
  9.     {
  10.       continue;
  11.     }
  12.     if(ret <= 0)
  13.     {
  14.       switch(ret)
  15.       {
  16.         case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY:
  17.           mbedtls_printf(" connection was closed gracefully\n");
  18.           HAL_Delay(100);
  19.           break;
  20.         case MBEDTLS_ERR_NET_CONN_RESET:
  21.           mbedtls_printf(" connection was reset by peer\n");
  22.           HAL_Delay(100);
  23.           break;
  24.         default:
  25.           mbedtls_printf(" mbedtls_ssl_read returned -0x%x\n", -ret);
  26.           HAL_Delay(100);
  27.           break;
  28.       }
  29.       HAL_Delay(100);
  30.       break;
  31.     }
  32.  
  33.     len = ret;
  34.     mbedtls_printf(" %d bytes read\n\n%s", len, (char *) buf);
  35.  
  36.     if(ret > 0)
  37.     {
  38.       break;
  39.     }
  40.   } while(1);

Po odczytaniu odpowiedzi od klienta należy sprawdzić kody odpowiedzi. Po odebraniu danych można przejść do przesłania odpowiedzi.

Z serwera odsyłamy odpowiedź:

  1.   mbedtls_printf( "  > Write to client:" );
  2.   for(uint32_t i=0; i<sizeof(WebSide_LoginPage_buff); i++) {
  3.       buf[i] = WebSide_LoginPage_buff[i];
  4.   }
  5.  
  6.   len = sizeof(WebSide_LoginPage_buff);
  7.   while((ret = mbedtls_ssl_write(&ssl, buf, len)) <= 0)
  8.   {
  9.     if(ret == MBEDTLS_ERR_NET_CONN_RESET)
  10.     {
  11.       mbedtls_printf(" failed\n  ! peer closed the connection\n\n");
  12.       goto reset;
  13.     }
  14.  
  15.     if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
  16.     {
  17.       mbedtls_printf( " failed\n  ! mbedtls_ssl_write returned %d\n\n", ret );
  18.       goto exit;
  19.     }
  20.   }
  21.  
  22.   len = ret;
  23.   mbedtls_printf(" %d bytes written\n\n%s\n", len, (char *) buf);
  24.  
  25.   while((ret = mbedtls_ssl_close_notify(&ssl)) < 0)
  26.   {
  27.     if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
  28.     {
  29.       mbedtls_printf( " failed\n  ! mbedtls_ssl_close_notify returned %d\n\n", ret );
  30.       goto reset;
  31.     }
  32.   }

Z urządzenia przesyłam standardowy kod odpowiedzi:

  1. const unsigned char WebSide_Response_buff[] =
  2.       "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"
  3.       "<h2>mbed TLS Test Server</h2>\r\n"
  4.       "<p>Successful connection using: %s</p>\r\n"

Testowałęm też przesyłanie następującej strony:

  1. const unsigned char WebSide_LoginPage_buff[] =
  2.       "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"
  3.       "<!DOCTYPE html>\r\n"
  4.       "<html lang=\"pl\">\r\n"
  5.             "<head>\r\n"
  6.                 "<meta charset=\"UTF-8\">\r\n"
  7.                 "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\r\n"
  8.                 "<title>TestWeb</title>\r\n"
  9.                 "<style>\r\n"
  10.                 "body {\r\n"
  11.                     "background-color: #9f9da7;\r\n"
  12.                     "font-size: 1.6rem;\r\n"
  13.                     "font-family: \"Open Sans\", sans-serif;\r\n"
  14.                     "color: #2b3e51;\r\n"
  15.                     "margin: 0;\r\n"
  16.                     "padding: 0;\r\n"
  17.                     "display: flex;\r\n"
  18.                     "align-items: center;\r\n"
  19.                     "justify-content: center;\r\n"
  20.                     "height: 100vh;\r\n"
  21.                 "}\r\n"
  22.                 "#login-form-wrap {\r\n"
  23.                     "background-color: #fff;\r\n"
  24.                     "width: 35%;\r\n"
  25.                     "text-align: center;\r\n"
  26.                     "padding: 20px;\r\n"
  27.                     "border-radius: 4px;\r\n"
  28.                     "box-shadow: 0px 30px 50px 0px rgba(0, 0, 0, 0.2);\r\n"
  29.                 "}\r\n"
  30.                 "h2 {\r\n"
  31.                     "font-weight: 300;\r\n"
  32.                     "text-align: center;\r\n"
  33.                 "}\r\n"
  34.                 "form {\r\n"
  35.                     "padding: 0 20px;\r\n"
  36.                 "}\r\n"
  37.                 "input {\r\n"
  38.                     "display: block;\r\n"
  39.                     "box-sizing: border-box;\r\n"
  40.                     "width: 100%;\r\n"
  41.                     "outline: none;\r\n"
  42.                     "height: 60px;\r\n"
  43.                     "line-height: 60px;\r\n"
  44.                     "border-radius: 4px;\r\n"
  45.                     "margin-bottom: 15px;\r\n"
  46.                     "border: 1px solid #c2c0ca;\r\n"
  47.                     "font-style: normal;\r\n"
  48.                     "font-size: 16px;\r\n"
  49.                     "padding: 0 10px;\r\n"
  50.                     "color: #8a8b8e;\r\n"
  51.                 "}\r\n"
  52.                 "input:focus {\r\n"
  53.                     "border-color: #3ca9e2;\r\n"
  54.                 "}\r\n"
  55.                 "input:invalid:focus {\r\n"
  56.                     "color: #cc1e2b;\r\n"
  57.                     "border-color: #cc1e2b;\r\n"
  58.                 "}\r\n"
  59.                 "input[type=\"submit\"] {\r\n"
  60.                     "border: none;\r\n"
  61.                     "display: block;\r\n"
  62.                     "background-color: #3ca9e2;\r\n"
  63.                     "color: #fff;\r\n"
  64.                     "font-weight: bold;\r\n"
  65.                     "text-transform: uppercase;\r\n"
  66.                     "cursor: pointer;\r\n"
  67.                     "transition: background-color 0.2s ease;\r\n"
  68.                     "font-size: 18px;\r\n"
  69.                 "}\r\n"
  70.                 "input[type=\"submit\"]:hover {\r\n"
  71.                     "background-color: #329dd5;\r\n"
  72.                 "}\r\n"
  73.                 "#create-account-wrap {\r\n"
  74.                     "background-color: #eeedf1;\r\n"
  75.                     "color: #8a8b8e;\r\n"
  76.                     "font-size: 14px;\r\n"
  77.                     "padding: 10px 0;\r\n"
  78.                     "border-radius: 0 0 4px 4px;\r\n"
  79.                 "}\r\n"
  80.             "</style>\r\n"
  81.             "</head>\r\n"
  82.             "<body>\r\n"
  83.             "<div id=\"login-form-wrap\">\r\n"
  84.                 "<h2>Logowanie</h2>\r\n"
  85.                 "<form id=\"login-form\" action=\"cgilogin.html\" method=\"post\">\r\n"
  86.                     "<input type=\"text\" id=\"pname\" name=\"pname\" placeholder=\"Użytkownik\" required>\r\n"
  87.                     "<input type=\"password\" id=\"ppass\" name=\"ppass\" placeholder=\"Hasło\" required>\r\n"
  88.                     "<input type=\"submit\" id=\"login\" value=\"Logowanie\">\r\n"
  89.                 "</form>\r\n"
  90.                 "<div id=\"create-account-wrap\"></div>\r\n"
  91.             "</div>\r\n"
  92.             "</body>\r\n"
  93.             "</html>";

Obsługę serwera konczymy przez zwolnienie zasobów obsługujących działanie serwera. Czyli zamknięcie otwartych połączeń, zwolnienie certyfikatów, kluczy, konfiguracji itp:

  1. exit:
  2.     mbedtls_net_free( &client_fd );
  3.     mbedtls_net_free( &listen_fd );
  4.  
  5.     mbedtls_x509_crt_free( &srvcert );
  6.     mbedtls_pk_free( &pkey );
  7.     mbedtls_ssl_free( &ssl );
  8.     mbedtls_ssl_config_free( &conf );
  9.     #if defined(MBEDTLS_SSL_CACHE_C)
  10.     mbedtls_ssl_cache_free( &cache );
  11.     #endif
  12.     mbedtls_ctr_drbg_free( &ctr_drbg );
  13.     mbedtls_entropy_free( &entropy );

Dodatkowo bibliotekę LWIP uruchamiam w innym procesie:

  1. void StartDefaultTask(void const * argument)
  2. {
  3.   /* USER CODE BEGIN 5 */
  4.   MX_LWIP_Init();
  5.  
  6.   for(;;)
  7.   {
  8.       if((CheckIfCableIsConnected() == 0)
  9.       && (flagSSLTask == 0) && (netifIsUpFlag == 1))
  10.       {
  11.           flagSSLTask = 1;
  12.       }
  13.  
  14.       if(flagSSLTask == 1)
  15.       {
  16.           flagSSLTask = 2;
  17.           xSemaphoreGive(sslTaskSemaphore);
  18.       }
  19.  
  20.       osDelay(250);
  21.   }
  22.   /* USER CODE END 5 */
  23. }

Na samym początku procesu SSL_Server oczekuje na odblokowanie semafora, który zapewni, że biblioteka LWIP i interfejs sieciowy są poprawnie zainicjalizowane.

  1.   while(xSemaphoreTake(sslTaskSemaphore, portMAX_DELAY) == 0) {
  2.     osDelay(3000);
  3.   }