DTLS with certificate handshake debugging

Hello.

I'm trying to connect to a CoAP server (Thingsboard) with a certificate based DTLS socket. In Wireshark I see that the handshake failes, but not why. I post the relevant code here:

int modem_configure(void)
{
    int err;
    nrf_sec_tag_t sec_tag = SEC_TAG;

    LOG_INF("Initializing modem library");
    err = nrf_modem_lib_init();
    if (err)
    {
        LOG_ERR("Failed to initialize the modem library, error: %d", err);
        return err;
    }

    err = modem_key_mgmt_clear(sec_tag);
    if (err)
    {
        LOG_ERR("Failed to clear credentials on sectag, err %d\n", err);
    }

    err = modem_key_mgmt_write(sec_tag, MODEM_KEY_MGMT_CRED_TYPE_CA_CHAIN, myiot_onesolutions_io_cert, sizeof(myiot_onesolutions_io_cert));
    if (err)
    {
        LOG_ERR("Failed to provision certificate, err %d\n", err);
    }

    /* Disable PSM (Power Saving Mode) */
    err = lte_lc_psm_req(false);
    if (err)
    {
        LOG_ERR("Failed to disable PSM, error: %d", err);
    }

    /* Disable eDRX (Extended Discontinuous Reception) */
    err = lte_lc_edrx_req(false);
    if (err)
    {
        LOG_ERR("Failed to disable eDRX, error: %d", err);
    }

    LOG_INF("Connecting to LTE network");
    err = lte_lc_connect_async(lte_handler);
    if (err)
    {
        LOG_ERR("Error in lte_lc_connect_async, error: %d", err);
        return err;
    }

    if (k_sem_take(&lte_connected, K_SECONDS(60)) == 0)
    {
        k_event_set(&lte_connected_event, 0x001);
        LOG_INF("Connected to LTE network");
    }
    else
    {
        LOG_ERR("No connection to LTE network!");
    }

    return 0;
}

static int client_init(void)
{
    int err;
    enum
    {
        NONE = 0,
        OPTIONAL = 1,
        REQUIRED = 2,
    };
    int verify = NONE;

    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_DTLS_1_2);
    if (sock < 0)
    {
        LOG_ERR("Failed to create CoAP socket: %d.\n", errno);
        return -errno;
    }

    err = setsockopt(sock, SOL_TLS, TLS_PEER_VERIFY, &verify, sizeof(verify));
    if (err)
    {
        LOG_ERR("Failed to setup peer verification, errno %d\n", errno);
        return -errno;
    }

    err = setsockopt(sock, SOL_TLS, TLS_HOSTNAME, CONFIG_COAP_SERVER_HOSTNAME, strlen(CONFIG_COAP_SERVER_HOSTNAME));
    if (err)
    {
        LOG_ERR("Failed to setup TLS hostname (%s), errno %d\n", CONFIG_COAP_SERVER_HOSTNAME, errno);
        return -errno;
    }

    uint8_t cyph_id[2] = {MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 >> 8, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 & 0xFF};
    err = setsockopt(sock, SOL_TLS, TLS_CIPHERSUITE_LIST, cyph_id, sizeof(cyph_id));
    if (err)
    {
        LOG_ERR("Failed to setup cypher suit, errno %d\n", errno);
        return -errno;
    }

    sec_tag_t sec_tag_list[] = {SEC_TAG};
    err = setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_list, sizeof(sec_tag_t) * ARRAY_SIZE(sec_tag_list));
    if (err)
    {
        LOG_ERR("Failed to setup socket security tag, errno %d\n", errno);
        return -errno;
    }

    err = connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_in));
    if (err < 0)
    {
        LOG_ERR("Connect failed : %d\n", errno);
        return -errno;
    }

    LOG_INF("Successfully connected to server");

    return 0;
}

proj.conf

# Configure Sowftware Version
CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION="1.0.16"

# Logging
CONFIG_LOG=y
CONFIG_LOG_BUFFER_SIZE=4096
CONFIG_LOG_MAX_LEVEL=4

CONFIG_EVENTS=y

# Newlib
CONFIG_NEWLIB_LIBC=y

CONFIG_GPIO=y
CONFIG_SPI=y
CONFIG_SPI_NOR=y
CONFIG_SPI_NOR_SFDP_DEVICETREE=y
CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
# QSPI drivers are enabled by defualt for some chips.
# Disable it explicitly to be sure QSPI is disabled.
CONFIG_NORDIC_QSPI_NOR=n

# Enable flash operations
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_FLASH_PAGE_LAYOUT=y

# Enable file system
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL=y
# LittleFS with ~30MB
CONFIG_PM_PARTITION_SIZE_LITTLEFS=0x1C00000

# Modem library
CONFIG_NRF_MODEM_LIB=y
CONFIG_MODEM_KEY_MGMT=y

# LTE link control
CONFIG_LTE_LINK_CONTROL=y
CONFIG_LTE_NETWORK_MODE_LTE_M_NBIOT=y
CONFIG_LTE_LC_EDRX_MODULE=y
CONFIG_LTE_LC_PSM_MODULE=y
CONFIG_LTE_EDRX_REQ=n
CONFIG_LTE_PSM_REQ=n

# Network
CONFIG_NETWORKING=y
CONFIG_NET_NATIVE=n
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_OFFLOAD=y
CONFIG_POSIX_API=y

# CoAP
CONFIG_COAP=y
CONFIG_COAP_CLIENT=y
CONFIG_COAP_CLIENT_BLOCK_SIZE=1024
CONFIG_COAP_CLIENT_MAX_REQUESTS=100
CONFIG_COAP_CLIENT_STACK_SIZE=2048
CONFIG_COAP_CLIENT_THREAD_PRIORITY=-2
CONFIG_COAP_SERVER_HOSTNAME="myiot.one-solutions.io"
CONFIG_COAP_SERVER_PORT=5684

CONFIG_IMG_MANAGER=y
CONFIG_STREAM_FLASH=y
CONFIG_DFU_TARGET=y
CONFIG_DFU_TARGET_MCUBOOT=y

# Memory
CONFIG_HEAP_MEM_POOL_SIZE=4096
CONFIG_MAIN_STACK_SIZE=4096

################ SHA-256 ###########################
# Using hardware crypto accelerator
CONFIG_PSA_CRYPTO_DRIVER_CC3XX=y
CONFIG_TFM_PROFILE_TYPE_NOT_SET=y

# Enable nordic security backend and PSA APIs
CONFIG_NRF_SECURITY=y
CONFIG_MBEDTLS_PSA_CRYPTO_C=y

CONFIG_PSA_WANT_ALG_SHA_256=y
####################################################

################ DTLS ##############################
CONFIG_MBEDTLS_DEBUG=n
CONFIG_MBEDTLS_DEBUG_C=y
CONFIG_MBEDTLS_TLS_LIBRARY=y
# --- Zeit (für Zertifikate wichtig) ---
CONFIG_DATE_TIME=y
CONFIG_DATE_TIME_AUTO_UPDATE=y
CONFIG_MODEM_KEY_MGMT_LOG_LEVEL_DBG=y
CONFIG_NET_SOCKETS_LOG_LEVEL_DBG=y
#CONFIG_NRF_MODEM_LIB_TRACE=y      # erzeugt .etrace für TLS/Handshake-Analyse
#CONFIG_MBEDTLS_PK_C=n

CONFIG_MBEDTLS_RSA_C=y
CONFIG_MBEDTLS_X509_USE_C=y
CONFIG_MBEDTLS_X509_CRT_PARSE_C=y

# --- Modem Trace (TLS-Handshake/Alerts sichtbar machen) ---
#CONFIG_UART_ASYNC_API=y
#CONFIG_NRF_MODEM_LIB_TRACE_BACKEND_RTT=y

CONFIG_MBEDTLS_DEBUG_LEVEL=4
####################################################

CONFIG_NANOPB=y

# --- Ressourcen (Handshake braucht RAM) ---
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_HEAP_MEM_POOL_SIZE=32768
CONFIG_LOG_BUFFER_SIZE=4096

How can I activate debug messages, so that I can find out more details why handshaking fails?
Is there any obvious mistake I made?

Thanks in advance.
BR
Christian

  • There is a modem trace, which contains some more information than the IP capture, but the additional information is AFAIK only readable by Nordic.

    In the past there was some documentation about the limits in TLS and DTLS and in some topics, there was a difference between TLS and DTLS. Currently I didn't find that again in the new documentation pages.

    In general. using RSA for embedded is frequently a decision, which comes with pain. ECDSA certificates are smaller and work usually with less pain.

  • It's working now. There where two problems I've got:

    1. Misconfigured server with an expired certificate.
    2. If I specify a ciphersuit list (with setsockopt()) it's not working. If I do not set such a list (all available ciphers are presented to the server) it is working.

    Thanks for your help.

    BR
    Christian

Related