Websocket Secure not working

We want to enable 2 way communiaction between Our Nrf9160 devices and server using Websocket secure. We used this as the starting point. We removed anything related to IPv6 and changed te destination to our secure websocket server. However we cannot connect to the server. We receive - errno 116 (connection timeout). We can connect to a non-secure websocket. We are on Nrf Connect SDK 2.4.2. 

Steps we take:

1. Get certificate pem using openssl command

openssl s_client -connect echo.websocket.org -showcerts

2.  Turn off the modem using 
lte_lc_deinit()
3. Store it on modem at tag TLS_SEC_TAG_SOCKET (8080)
// socket ceritifcate
    mismatch = modem_key_mgmt_cmp(TLS_SEC_TAG_SOCKET, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN, socket_cert, strlen(socket_cert));
    if(!mismatch) {
        printk("socket cert good\n");
    } else {
        err = modem_key_mgmt_write(TLS_SEC_TAG_SOCKET, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN, socket_cert, sizeof(socket_cert) - 1);
        if(err) {
            printk("cannot provision socket cert, err: %d\n", err);
            (void)close(sock);
            return RESULT_ERROR;
        } else {
            printk("socket cert provisioned %d bytes\n", sizeof(socket_cert) - 1);
        }
    }
4. After turning the modem on, we try to connect using the following code:
int m_socket_setup(sa_family_t family, const char *server, int port, int *sock, struct sockaddr *addr,  socklen_t addr_len) {
    int ret = 0;
    memset(addr, 0, addr_len);
    net_sin(addr)->sin_family = AF_INET;
    net_sin(addr)->sin_port = htons(port);
    inet_pton(family, server, & net_sin(addr)->sin_addr);
    sec_tag_t sec_tag_list[] = { TLS_SEC_TAG_SOCKET };
    *sock = socket(family, SOCK_STREAM, IPPROTO_TLS_1_2);
    if(*sock >= 0) {
        enum { NONE = 0, OPTIONAL = 1, REQUIRED = 2};
        int verify = NONE; // <-- try to not care about forcing secure connection, did not work still
        ret = setsockopt(*sock, SOL_TLS, TLS_PEER_VERIFY, & verify, sizeof(verify));
        if (ret < 0) {
            printk("websocket error: failed to set socket option (%d)\n", -errno);
            goto fail;
        }
        ret = setsockopt(*sock, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_list, sizeof(sec_tag_list));
        if (ret < 0) {
            printk("websocket error: failed to set secure option (%d)\n", -errno);
            goto fail;
        }
        ret = setsockopt(*sock, SOL_TLS, TLS_HOSTNAME, server, strlen(server) + 1);
        if(ret < 0) {
            printk("websocket error: fail to set TLS_HOSTNAME option (%d)\n", -errno);
            goto fail;
        }
    }
    if(*sock < 0) {
        printk("websocket error: %d, failed to create socket\n", errno);
    }
    return ret;
fail:
    if(*sock >= 0) {
        close(*sock);
        *sock = -1;
    }
    return ret;
}
We run code here which includes running m_socket_setup():
    char url[256];
    snprintf(url, sizeof(url), "wss://%s.execute-api.ca-central-1.amazonaws.com", md->base_websocket);
    printk("websocket start %s port %d\n", url, md->base_sockport);
    m_socket_setup(AF_INET, url, md->base_sockport, & sock4, (struct sockaddr *)&addr4, sizeof(addr4));
    if (ret < 0 || sock4 < 0) {
        close(sock4);
            return RESULT_ERROR;
      }
    printk("websocket setup completed %d %d\n", sock4, sizeof(addr4)); // 1 8
    ret = connect(sock4, (struct sockaddr *)&addr4, sizeof(addr4)); // <--- 116 timeout
    printk("websocket connect %d %d\n", ret, sock4); // -1 1
    if(ret < 0) {
        printk("websocket cannot connect to remote %d\n", errno); // 116
        close(sock4);
        return RESULT_ERROR;
    } 
5. We think error might be inside m_socket_setup() that makes connect() show the errno 116 (timeout).


We would highly appreciate if you could point us in the right direction, or provide an example project that can connect to secure websocket that is not local.

Thank you, 

Sid
  • Hi,

     

    The website uses Lets Encrypt, which again requires ISRG X1 Root certificate:

    This is downloadable from here:

    https://letsencrypt.org/certificates/

     

    Based on the snippets of code, specifically these lines:

            enum { NONE = 0, OPTIONAL = 1, REQUIRED = 2};
            int verify = NONE; // <-- try to not care about forcing secure connection, did not work still
            ret = setsockopt(*sock, SOL_TLS, TLS_PEER_VERIFY, & verify, sizeof(verify));

    It indicates that you have tried to setup the connection without domain verification, so the certificate itself shall not be the reason for the problematic connection.

     

    Which modem firmware are you using?

     

    Kind regards,

    Håkon

  • We tried both certificates and still got the same error. We are on modem version 1.3.5. We also just ran on modem version 1.3.7. Same error on both modem versions. 

  • Hi,

     

    I used https_client sample, added the ISRG x1 root certificate, and connected to echo.websocket.org:

    *** Booting nRF Connect SDK v2.9.0-7787b2649840 ***
    *** Using Zephyr OS v3.7.99-1f8f3dc29142 ***
    HTTPS client sample started
    Bringing network interface up
    Provisioning certificate
    Certificate mismatch
    Provisioning certificate to the modem
    Connecting to the network
    +CEREG: 2,"816C","03182602",7
    +CSCON: 1
    +CGEV: ME PDN ACT 0
    %MDMEV: SEARCH STATUS 2
    +CEREG: 1,"816C","03182602",7,,,"00100001","00000110"
    Network connectivity established and IP address assigned
    Looking up echo.websocket.org
    +CGEV: IPV6 0
    Resolved 66.241.124.119 (AF_INET)
    Connecting to echo.websocket.org:443
    Sent 68 bytes
    Received 204 bytes
    
    >        HTTP/1.1 200 OK
    
    Finished, closing socket.
    +CGEV: ME PDN DEACT 0
    +CEREG: 0
    +CGEV: ME DETACH
    +CSCON: 0
    Network connectivity lost
    Disconnected from the network

     

    I use mfw v1.3.7.

    If there is a significant delay when trying to run connect(), it might be beneficial to adjust "CONFIG_NET_SOCKETS_CONNECT_TIMEOUT" to a higher value.

     

    Kind regards,

    Håkon

Related