HTTPS Web server

 Hello,

 

Is it possible with Synergy ?

Looking into the thread 'Converting from HTTP to HTTPS' it must be possible.

But I'm unable to find the final project.

Especially support for multiple sockets (2) would be very welcome, this will give options for things like sse. In the current http server implementation the active socket is closed after the reply and cannot be kept open.

 

Jef

Parents
  • Yes, setting up an HTTPS Web server is possible with Synergy. The HTTPS server code is included in SSP 1.6.0, however there is no XML to allow you to configure it in the Threads tab of the configurator.
    In an up coming release of the SSP there will be XML to allow the HTTPS server to added in the threads tab, and configured like other NetX components.
  • @Jeremy, Till then what is the solution? How to include HTTPS manually or by other means?
  • #include "thread_communication.h"
    #include "tx_api.h"
    #include "fx_api.h"
    #include "nx_api.h"
    #include "nx_crypto.h"
    #include "nx_secure_tls_api.h"
    #include "nx_secure_x509.h"
    #include "nx_web_http_server.h"
    #include "certificate/https_server_cert.h"
    #include "certificate/https_server_private_key.h"
    #include <time.h>
    #include "hal_data.h"
    #include <stdio.h>
    
    /* Set up debug output. */
    #define SEMI_HOSTING
    
    /* Enable the driver for debug output */
    #ifdef SEMI_HOSTING
    #ifdef __GNUC__                 /* GCC Compiler */
    extern void initialise_monitor_handles(void);
    #endif
    #endif
    
    #define USE_HTTPS
    
    /* nx_secure_tls_session_packet_buffer_set() associates a packet re-assembly buffer to a TLS session.
    In order to decrypt and parse incoming TLS records, the data in each record
    must be assembled from the underlying TCP packets. TLS records can be
    up to 16KB in size (though typically are much smaller) so may not fit into a
    single TCP packet.
    If you know the incoming message size will be smaller than the TLS
    record limit of 16KB, the buffer size can be made smaller, but in order to
    handle unknown incoming data the buffer should be made as large as
    possible. If an incoming record is larger than the supplied buffer, the TLS
    session will end with an error.*/
    #define SIZE_OF_TLS_PACKET_BUF      (16 * 1024)
    
    #if (NX_CRYPTO_MAX_RSA_MODULUS_SIZE == 1024)
    
    #ifdef NX_SECURE_ENABLE_PSK_CIPHERSUITES
    #define SIZE_OF_META_BUFFER         (3200)  /* calculated with nx_secure_tls_metadata_size_calculate() for nx_crypto_tls_ciphers_synergys7, RSA Modulus 1024 */
    #else
    #define SIZE_OF_META_BUFFER         (2896)  /* calculated with nx_secure_tls_metadata_size_calculate() for nx_crypto_tls_ciphers_synergys7, RSA Modulus 1024 */
    #endif
    
    #elif (NX_CRYPTO_MAX_RSA_MODULUS_SIZE == 2048)
    
    #ifdef NX_SECURE_ENABLE_PSK_CIPHERSUITES
    #define SIZE_OF_META_BUFFER         (3200)  /* calculated with nx_secure_tls_metadata_size_calculate() for nx_crypto_tls_ciphers_synergys7, RSA Modulus 2048 */
    #else
    #define SIZE_OF_META_BUFFER         (2896)  /* calculated with nx_secure_tls_metadata_size_calculate() for nx_crypto_tls_ciphers_synergys7, RSA Modulus 2048 */
    #endif
    
    #elif (NX_CRYPTO_MAX_RSA_MODULUS_SIZE == 3072)
    
    #ifdef NX_SECURE_ENABLE_PSK_CIPHERSUITES
    #define SIZE_OF_META_BUFFER         (3200)  /* calculated with nx_secure_tls_metadata_size_calculate() for nx_crypto_tls_ciphers_synergys7, RSA Modulus 3072 */
    #else
    #define SIZE_OF_META_BUFFER         (2896)  /* calculated with nx_secure_tls_metadata_size_calculate() for nx_crypto_tls_ciphers_synergys7, RSA Modulus 3072 */
    #endif
    
    #elif (NX_CRYPTO_MAX_RSA_MODULUS_SIZE == 4096)
    #ifdef NX_SECURE_ENABLE_PSK_CIPHERSUITES
    #define SIZE_OF_META_BUFFER         (12496) /* calculated with nx_secure_tls_metadata_size_calculate() for nx_crypto_tls_ciphers_synergys7, RSA Modulus 4096 */
    
    #else
    #define SIZE_OF_META_BUFFER         (12192) /* calculated with nx_secure_tls_metadata_size_calculate() for nx_crypto_tls_ciphers_synergys7, RSA Modulus 4096 */
    #endif
    #endif
    
    #define ETH_INTERFACE       0
    
    extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers_synergys7;
    
    bsp_leds_t          g_leds;
    NX_WEB_HTTP_SERVER  g_https_server;
    uint8_t             g_https_server_memory[4096];
    UCHAR               g_tls_packet_buffer[SIZE_OF_TLS_PACKET_BUF * NX_WEB_HTTP_SERVER_SESSION_MAX];
    CHAR                g_tls_session_meta_data[SIZE_OF_META_BUFFER * NX_WEB_HTTP_SERVER_SESSION_MAX];
    NX_SECURE_X509_CERT g_server_cert;
    
    void print_packet_pool_info(NX_PACKET_POOL * pool);
    
    
    UINT authentication_check(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type,
    CHAR *resource, CHAR **name, CHAR **password, CHAR **realm);
    
    /* Define the application's authentication check. This is called by
    the HTTP server whenever a new request is received. */
    UINT authentication_check(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type,
    CHAR *resource, CHAR **name, CHAR **password, CHAR **realm)
    {
    
        SSP_PARAMETER_NOT_USED(server_ptr);
        SSP_PARAMETER_NOT_USED(request_type);
        SSP_PARAMETER_NOT_USED(resource);
    
        /* Just use a simple name, password, and realm for all
        requests and resources. */
        *name = "";
        *password = "";
        *realm = "";
    
        /* Request basic authentication. */
        return(NX_WEB_HTTP_BASIC_AUTHENTICATE);
    }
    
    
    /* Thread entry function */
    void thread_communication_entry(void)
    {
        uint32_t    i               = 0;
        ULONG       actual_status = 0;
        UINT        status;
    #ifdef USE_HTTPS
        ULONG crypto_metadata_size;
    #endif
    
    
        /* Initialize the debug output utility. */
    #ifdef SEMI_HOSTING
    #ifdef __GNUC__
        initialise_monitor_handles();
    #endif
    #endif
    
    #ifdef SEMI_HOSTING
        if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk)
        {
            printf("testing printf\r\n");
        }
    #endif
    
        /* Setup the LEDS */
        R_BSP_LedsGet(&g_leds);
    
        if (0 < g_leds.led_count)
        {
            for (i = 0; i< g_leds.led_count; i++)
            {
                g_ioport.p_api->pinWrite(g_leds.p_leds[i], IOPORT_LEVEL_LOW);
            }
        }
    
        while ((NX_IP_LINK_ENABLED & actual_status) != NX_IP_LINK_ENABLED)
        {
            status = nx_ip_interface_status_check(&g_ip0,
                    ETH_INTERFACE,
                    NX_IP_LINK_ENABLED,
                    &actual_status,
                    2 * NX_IP_PERIODIC_RATE); // jlc using NX_IP_PERIODIC_RATE
        }
    
    
    
    
        /* Create the NetX Web HTTP Server. */
        status = nx_web_http_server_create(&g_https_server, "My HTTPS Server", &g_ip0,
    #ifdef USE_HTTPS
                                                NX_WEB_HTTPS_SERVER_PORT,
    #else
                                                NX_WEB_HTTP_SERVER_PORT,
    #endif
                                                g_fx_media0_ptr,
                                                g_https_server_memory, sizeof(g_https_server_memory),
                                                &g_packet_pool0, NX_NULL, NX_NULL);
        if (NX_SUCCESS != status)
        {
            while(1);
        }
    
    #ifdef USE_HTTPS
        /* The TLS server needs an identity certificate which is imported as a binary DER-
        encoded X.509 certificate and it’s associated private key (e.g. DER-encoded PKCS#1
        RSA private key). */
        //const uint8_t g_server_cert_der
        //const uint8_t g_server_cert_key_der
        status = nx_secure_x509_certificate_initialize(&g_server_cert, (UCHAR *)https_server_cert,
                                                        sizeof(https_server_cert), NX_NULL, 0,
                                                        https_server_private_key, sizeof(https_server_private_key),
                                                        NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER);
        if (NX_SUCCESS != status)
        {
            while(1);
        }
    
        status = nx_secure_tls_metadata_size_calculate(&nx_crypto_tls_ciphers_synergys7,
        &crypto_metadata_size);
        if (NX_SUCCESS != status)
        {
            while(1);
        }
    
        if (sizeof(g_tls_session_meta_data) < crypto_metadata_size)
        {
            printf("Crypto buffer too small, required size = %u \r\n", (unsigned int)crypto_metadata_size);
            while(1);
        }
    
    
        /* Setup TLS session data for the TCP server. This enables TLS and HTTPS for the
        server. */
        status = nx_web_http_server_secure_configure(&g_https_server, &nx_crypto_tls_ciphers_synergys7,
                                                         g_tls_session_meta_data, sizeof(g_tls_session_meta_data),
                                                         g_tls_packet_buffer, sizeof(g_tls_packet_buffer),
                                                         &g_server_cert, NX_NULL, 0, NX_NULL, 0, NX_NULL, 0);
        if (NX_SUCCESS != status)
        {
            while(1);
        }
    
    #endif
        /* Start the HTTP Server. */
        status = nx_web_http_server_start(&g_https_server);
    
         while (1)
        {
            tx_thread_sleep (1 * TX_TIMER_TICKS_PER_SECOND);
            print_packet_pool_info(&g_packet_pool0);
        }
    
    }
    
    void print_packet_pool_info(NX_PACKET_POOL * pool)
    {
        ULONG total_packets;
        ULONG free_packets;
        ULONG empty_pool_requests;
        ULONG empty_pool_suspensions;
        ULONG invalid_packet_releases;
        UINT status;
    
        status = nx_packet_pool_info_get(pool,
        &total_packets,
        &free_packets,
        &empty_pool_requests,
        &empty_pool_suspensions,
        &invalid_packet_releases);
        if (NX_SUCCESS == status)
        {
            printf("Pool info TP %d, FP %d, EPR %d, EPS %d IPR %d\r\n", (int)total_packets, (int)free_packets, (int)empty_pool_requests,
                   (int)empty_pool_suspensions, (int)invalid_packet_releases);
        }
        else
        {
            printf("Pool info get error 0x%x\r\n", status);
        }
    
    #ifdef SEMI_HOSTING
            if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk)
            {
    
              printf("Connection failures %d connection successes %d invalid headers %d\n",
                     (int)g_https_server.nx_web_http_server_connection_failures,
                     (int)g_https_server.nx_web_http_server_connection_successes,
                     (int)g_https_server.nx_web_http_server_invalid_http_headers);
              printf("get requests %d , put requests %d , post requests %d\n",
                    (int)g_https_server.nx_web_http_server_get_requests,
                    (int)g_https_server.nx_web_http_server_put_requests,
                    (int)g_https_server.nx_web_http_server_post_requests);
            }
    #endif
    
    }
    
    
    

    Hi Jef

    You add the HTTPS server from the components tab. Then you have to create the HTTPS server and do the 'set up' that the configurator would normally do.  Jeremy developed an HTTPS server program last year, for SSP 1.5.x, and he is probably the best person to send you his project as a template you can work off of.  I included the thread entry function from one of his projects for you to see how you create and start up the HTTPS server instance.  I do not include the certificate and key files as they are quite bulky, and you probably have your own certificates anyway (?).  Note the file is a txt file. For some reason the upload utility balks when I try to upload a .c or .zip file. 

    Let me know if you want me to send you the entire HTTPS project I last worked on (1.5.x) or wait to see what Jeremy can send you.  

    Regards,

    Janet

  • here is my HTTPS server project quickly ported to SSP 1.6.0. It use test certificates (there are a couple of batch file to generate the required certificates using OpenSSL in the certificate_generation folder. The create_root_cert_and_key.bat generates the rootCA certificate and private key if they don't already exist. create_certificate_for_domain.bat then uses the rootCA certificate to create another certificate and private key for the HTTPS server to use (to run the batch file create_certificate_for_domain.bat IP <https server IP address> :- file create_certificate_for_domain.bat IP 192.168.0.100)

    You will need to copy the certificate rootCA.cer to the browser or PC as it is using test certificates. I have only tested this with firefox under SSP 1.6.0 and you need to install rootCA.cer into the certificates in Firefox as it has it's own certificate store.

    Using Firefox you will need to limit the max version of TLS that is used:-

     

    This problem should be solved in the version of the SSP that has the XML to configure the HTTPS server.

    S5D9_PK_HTTPS_Server_SSP_1_6_0.zip

  • Hi

    Janet & Jeremy thanks for your replies.
    Will take a look next week and let you known if we manage to get it working

    Thanks,
    J
  • Hi,

    Thanks for the replies.
    As my colleague said we will come back when we tried it

    Thanks.
  • Hello,

    as of the new SSP version there is https support.


    thanks again for al your help !
  • is there a proper guide for creating the certificate create_root_cert_and_key.bat rootCA.pem file not created.

    post that for this create_certificate_for_domain.bat IP 192.168.0.100 This below files are not created :-

    <https server name>.crt   (the https server certificate)
    <https server name>.csr   (the signing request for the certificate)
    device.key                  (the server private key)

  • Any chance there is an update to this project for ssp 2.2 or 2.4 and TLS 1.3?  

Reply Children
No Data