1 (edited by windyMk92 2020-12-09 03:39:15)

Topic: Error when using HTTPs and FTPs

Hi everyone,
I'm trying using wolfSSL to secure h.ttp_server and ftp server on STM32F746 board.
I using FreeRTOS and lwip to create 2 threads for h.ttp_server and ftp server. Both h.ttp_server and ftp server share a self-sign certificate. When only one thread have client connect to it (h.ttp_server or ftp client) at a time, it works fine.
When h.ttp_server server serving its client, if a ftp-client try to connect to my ftp server then an error occur, please see my files I attach below.

Please give some clues to help me solve my problems

Thanks in advance.

The error message in filezilla client
Error:    GnuTLS error -110: The TLS connection was non-properly terminated.
Status:    Server did not properly shut down TLS connection
Error:    The data connection could not be established: ECONNABORTED - Connection aborted
Error:    Connection timed out after 20 seconds of inactivity
Error:    Failed to retrieve directory listing

Share

Re: Error when using HTTPs and FTPs

Hi windyMk92,

The attachments are missing. Feel free to email support@wolfssl.com if you cannot post them here.

Is the issue specific to two concurrent threads or just when the STM32F7 is acting as the server? Are you using AES Hardware acceleration? If so have you tried disabling using NO_STM32_CRYPTO?

For multi-threading the common issues are not using mutex protection on the WOLFSSL object between threads. For the WOLFSSL_CTX you should have separate ones. Make sure the server side CTX constructor is using the wolfTLSv1_2_server_method or wolfSSLv23_server_method (to select highest available TLS version and allow downgrade).

We have some excellent TLS examples here: https://github.com/wolfSSL/wolfssl-exam … master/tls

Thanks,
David Garske, wolfSSL

Share

Re: Error when using HTTPs and FTPs

dgarske wrote:

Hi windyMk92,

The attachments are missing. Feel free to email support@wolfssl.com if you cannot post them here.

Is the issue specific to two concurrent threads or just when the STM32F7 is acting as the server? Are you using AES Hardware acceleration? If so have you tried disabling using NO_STM32_CRYPTO?

For multi-threading the common issues are not using mutex protection on the WOLFSSL object between threads. For the WOLFSSL_CTX you should have separate ones. Make sure the server side CTX constructor is using the wolfTLSv1_2_server_method or wolfSSLv23_server_method (to select highest available TLS version and allow downgrade).

We have some excellent TLS examples here: https://github.com/wolfSSL/wolfssl-exam … master/tls

Thanks,
David Garske, wolfSSL

Dear David,

Thank you for your quick response.
Let's me clarify my issue:
+ I'm using 2 concurrent threads H.ttps on port 443 and FTPS on port 990
+ I didn't use AES Hardware acceleration

#define NO_STM32_HASH
#define NO_STM32_CRYPTO
#define WOLFSSL_STM32F7
#define STM32_HAL_V2
#define HAL_CONSOLE_UART huart1

+ I didn't use mutex protection for my threads, so maybe it causes my problem.
+ For the WOLFSSL_CTX, yes it is separated for each thread, and I'm using wolfTLSv1_2_server_method.

void HTTPS_ServerTask(void const * args)
{
        SOCKET_T       sockfd = 0;
        WOLFSSL_METHOD* method = 0;
        WOLFSSL_CTX*    ctx    = 0;
        word16 port= 443;
        /* Let tcp_listen assign port */
        wolfTcp_listen(&sockfd, &port, 1, 0, 0);

        method = wolfTLSv1_2_server_method();

        ctx    = wolfSSL_CTX_new(method);
#ifndef USE_WOLFSSL_IO
    wolfSSL_CTX_SetIORecv(ctx, my_EmbedReceive);
    wolfSSL_CTX_SetIOSend(ctx, my_EmbedSend);
#endif
...
}

void FTPS_ServerTask(void const * args)
{
    SOCKET_T       sockfd = 0;
    WOLFSSL_METHOD* method = 0;
    WOLFSSL_CTX*    ctx    = 0;

    word16 port= 990;
    /* Let tcp_listen assign port */
    wolfTcp_listen(&sockfd, &port, 1, 0, 0);
    method = wolfTLSv1_2_server_method();

    ctx    = wolfSSL_CTX_new(method);

#ifndef USE_WOLFSSL_IO
    wolfSSL_CTX_SetIORecv(ctx, my_EmbedReceive);
    wolfSSL_CTX_SetIOSend(ctx, my_EmbedSend);
#endif
...
}

Both threads use the same functions my_EmbedReceive/my_EmbedSend.

I will try add mutex protection for my threads.
Thank you.
Sincerely.

Share

Re: Error when using HTTPs and FTPs

Hi windyMk92,

You might also want to use these API's to set your own IO callback context pointer. This will allow you to specify a different socket/IO context for each thread.

wolfSSL_SetIOReadCtx
wolfSSL_SetIOWriteCtx

Thanks,
David Garske, wolfSSL

Share

Re: Error when using HTTPs and FTPs

dgarske wrote:

Hi windyMk92,

You might also want to use these API's to set your own IO callback context pointer. This will allow you to specify a different socket/IO context for each thread.

wolfSSL_SetIOReadCtx
wolfSSL_SetIOWriteCtx

Thanks,
David Garske, wolfSSL

Hi David,
I was using wolfSSL_set_fd instead of those API. I tried to use mutex base on this example
https://github.com/wolfSSL/wolfssl-exam … threaded.c but still face the error.

Thank you.

Share

Re: Error when using HTTPs and FTPs

Hi windyMk92,

Can you share what your IO read/write callback functions look like (my_EmbedReceive)? Also can you send your logs to review?

You might try using the WOLFSSL_ALT_CERT_CHAINS build option. I've noticed some FTP servers include an additional certificate not in the chain.

Thanks,
David Garske, wolfSSL

Share

Re: Error when using HTTPs and FTPs

dgarske wrote:

Hi windyMk92,

Can you share what your IO read/write callback functions look like (my_EmbedReceive)? Also can you send your logs to review?

You might try using the WOLFSSL_ALT_CERT_CHAINS build option. I've noticed some FTP servers include an additional certificate not in the chain.

Thanks,
David Garske, wolfSSL

Hi David,

Here is my callback function, it is base on wolf callback function

int ftpIORecv(WOLFSSL *ssl, char *buf, int sz, void *ctx)
{
    LOCK_FTP_MUTEX
    int sd = *(int*)ctx;
    int recvd = 0;
    recvd = lwip_recv(sd, buf, sz, ssl->rflags);
    UNLOCK_FTP_MUTEX
    if (recvd < 0) {
        int err = errno;
        WOLFSSL_MSG("Embed Receive error");

        if (err == EWOULDBLOCK || err == EAGAIN) {
            WOLFSSL_MSG("\tWould block");
            return WOLFSSL_CBIO_ERR_WANT_READ;
        }
        else if (err == ECONNRESET) {
            WOLFSSL_MSG("\tConnection reset");
            return WOLFSSL_CBIO_ERR_CONN_RST;
        }
        else if (err == EINTR) {
            WOLFSSL_MSG("\tSocket interrupted");
            return WOLFSSL_CBIO_ERR_ISR;
        }
        else if (err == ECONNABORTED) {
            WOLFSSL_MSG("\tConnection aborted");
            return WOLFSSL_CBIO_ERR_CONN_CLOSE;
        }
        else {
            WOLFSSL_MSG("\tGeneral error");
            return WOLFSSL_CBIO_ERR_GENERAL;
        }
    }
    else if (recvd == 0) {
        WOLFSSL_MSG("Embed receive connection closed");
        return WOLFSSL_CBIO_ERR_CONN_CLOSE;
    }

    return recvd;
}

/* The send embedded callback
 *  return : nb bytes sent, or error
 */
int ftpIOSend(WOLFSSL* ssl, char *buf, int sz, void *ctx)
{
    LOCK_HTTP_MUTEX
    int sd = *(int*)ctx;
    int sent = -1;

#ifdef WOLFSSL_MAX_SEND_SZ
    if (sz > WOLFSSL_MAX_SEND_SZ)
        sz = WOLFSSL_MAX_SEND_SZ;
#endif
    sent = lwip_send(sd, buf, sz, ssl->wflags);
    printf("ftpIOSend %d %d\n", sd, sz);
    UNLOCK_HTTP_MUTEX
    if (sent < 0) {
        int err = errno;
        WOLFSSL_MSG("Embed Send error");

        if (err == EWOULDBLOCK || err == EAGAIN) {
            WOLFSSL_MSG("\tWould Block");
            return WOLFSSL_CBIO_ERR_WANT_WRITE;
        }
        else if (err == ECONNRESET) {
            WOLFSSL_MSG("\tConnection reset");
            return WOLFSSL_CBIO_ERR_CONN_RST;
        }
        else if (err == EINTR) {
            WOLFSSL_MSG("\tSocket interrupted");
            return WOLFSSL_CBIO_ERR_ISR;
        }
        else if (err == EPIPE) {
            WOLFSSL_MSG("\tSocket EPIPE");
            return WOLFSSL_CBIO_ERR_CONN_CLOSE;
        }
        else {
            WOLFSSL_MSG("\tGeneral error");
            return WOLFSSL_CBIO_ERR_GENERAL;
        }
    }
    return sent;
}

Btw, I somehow solved my problem by increase Ram for each thread.
Thank you very much for your reply.

Share