This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF9160 Using MQTT with TLS

Hi everyone,

I am looking at using MQTT v3.1.1 with TLS 1.2, to send data to Azure IoT Hub.

I tested the MQTT Simple sample and it worked perfeclty. So I am modifying this project to enable TLS. To do so I followed those threads:

https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/enabling-and-testing-tls-in-mqtt_5f00_simple

https://github.com/joakimtoe/fw-nrfconnect-nrf/commit/36532a8ca60bf7139a988b5cbb4e6cb47948a9fa#diff-607096fd76f1fd14e4c9453aa1dc8fd3

https://devzone.nordicsemi.com/f/nordic-q-a/44921/nrf9160-tls-and-mqtt

https://devzone.nordicsemi.com/f/nordic-q-a/49339/implementing-tls-with-mqtt-in-nrf9160

Right now I am able to create the TLS socket but I am stucked at the next step which is the connection step. 

When defining  tls_config->peer_verify = 2; I got back ERROR: mqtt_connect -45.

And when I define it to 0 or 1 there is no response, as if the nRF9160 is stucked somewhere.

My log is the following for peer_verify=2. It is the same for 0/1, but without the error code.

00> ***** Booting Zephyr OS build v2.0.99-ncs1 *****
00> 
00> The MQTT simple sample started
00> 
00> Deleting certs sec_tag: 2
00> 
00> nrf_inbuilt_key_delete(2, 0) => result=0
00> 
00> Deleting certs sec_tag: 2
00> 
00> nrf_inbuilt_key_delete(2, 1) => result=0
00> 
00> Deleting certs sec_tag: 2
00> 
00> nrf_inbuilt_key_delete(2, 2) => result=0
00> 
00> Deleting certs sec_tag: 2
00> 
00> nrf_inbuilt_key_delete(2, 3) => result=2
00> 
00> Deleting certs sec_tag: 2
00> 
00> nrf_inbuilt_key_delete(2, 4) => result=2
00> 
00> Write ca certs sec_tag: 2
00> 
00> Write private cert sec_tag: 2
00> 
00> Write public cert sec_tag: 2
00> 
00> err_provision = 0
00> 
00> LTE Link Connecting ...
00> 
00> LTE Link Connected!
00> 
00> IPv4 Address found 13.95.15.251
00> 
00> ERROR: mqtt_connect -45

It has to be noted that the certificates I used are working in an application on my computer. They are placed here in certificates.h and are using the right formatting.

In my project folder, my prof.conf file is the following:

#
# Copyright (c) 2019 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
#
# General config
CONFIG_PRINTK=y
CONFIG_CONSOLE=y
CONFIG_LOG=y
CONFIG_SERIAL=y
CONFIG_STDOUT_CONSOLE=y

CONFIG_UART_CONSOLE=n
CONFIG_RTT_CONSOLE=y
CONFIG_HAS_SEGGER_RTT=y
CONFIG_USE_SEGGER_RTT=y

# Random Generator
CONFIG_TEST_RANDOM_GENERATOR=y

# Networking
CONFIG_NETWORKING=y
CONFIG_NET_NATIVE=n
CONFIG_NET_SOCKETS_OFFLOAD=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y

# nRF Cloud
CONFIG_NRF_CLOUD_PROVISION_CERTIFICATES=y
#CONFIG_NRF_CLOUD=y

# Modem info
#CONFIG_MODEM_INFO=y

#TLS
CONFIG_SEC_TAG=2
CONFIG_PEER_VERIFY=2

# LTE link control
#CONFIG_POWER_OPTIMIZATION_ENABLE=n
CONFIG_LTE_LINK_CONTROL=y
CONFIG_LTE_AUTO_INIT_AND_CONNECT=n

# BSD library
CONFIG_BSD_LIBRARY=y

# AT Host
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_AT_HOST_LIBRARY=y

# MQTT
CONFIG_MQTT_LIB=y
#CONFIG_MQTT_SOCKET_LIB=y
CONFIG_MQTT_LIB_TLS=y
#CONFIG_MQTT_MAX_PACKET_LENGTH=2048

# Application
#CONFIG_MQTT_PUB_TOPIC="/my/publish/topic"
#CONFIG_MQTT_SUB_TOPIC="/my/subscribe/topic"
CONFIG_MQTT_CLIENT_ID="mqtt_test"
CONFIG_MQTT_BROKER_HOSTNAME="test-aptus.azure-devices.net"
CONFIG_MQTT_BROKER_PORT=8883

CONFIG_PROVISION_CERTIFICATES=y
CONFIG_CERTIFICATES_FILE="certificates.h"

# Main thread
CONFIG_MAIN_THREAD_PRIORITY=7
CONFIG_MAIN_STACK_SIZE=4096

CONFIG_HEAP_MEM_POOL_SIZE=2048

The Kconfig file there is the following:

#
# Copyright (c) 2018 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
#

menu "MQTT simple sample"

config PROVISION_CERTIFICATES
	bool "Provision of certificate"
	help
		Enable run-time provisioning of certificates from the
		certificates header file selected by using CERTIFICATES_FILE

config CERTIFICATES_FILE
	string "Certificates to use"
	depends on PROVISION_CERTIFICATES
	default "certificates.h"

config SEC_TAG
	int "Security tag to use for the connection"
	default 1

config PEER_VERIFY
    int "Peer verify parameter for mqtt_client"
    default 1
    help
        Set to 0 for VERIFY_NONE, 1 for VERIFY_OPTIONAL, and 2 for VERIFY_REQUIRED.

config MQTT_PUB_TOPIC
	string "MQTT publish topic"
	default "my/publish/topic"

config MQTT_SUB_TOPIC
	string "MQTT subscribe topic"
	default "my/subscribe/topic"

config MQTT_CLIENT_ID
	string "MQTT Client ID"
	default "my-client-id"

config MQTT_BROKER_HOSTNAME
	string "MQTT broker hostname"
	default "mqtt.eclipse.org"

config MQTT_BROKER_PORT
	int "MQTT broker port"
	default 1883

config MQTT_MESSAGE_BUFFER_SIZE
	int "MQTT message buffer size"
	default 128

config MQTT_PAYLOAD_BUFFER_SIZE
	int "MQTT payload buffer size"
	default 128

endmenu

menu "Zephyr Kernel"
source "$ZEPHYR_BASE/Kconfig.zephyr"
endmenu

And the main.c is :

/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
 */

#include <zephyr.h>
#include <stdio.h>
#include <uart.h>
#include <string.h>

#include <net/mqtt.h>
#include <net/socket.h>
#include <lte_lc.h>
#include <certificates.h>


#if defined(CONFIG_BSD_LIBRARY)
#include "nrf_inbuilt_key.h"
#endif

#include CONFIG_CERTIFICATES_FILE

#if defined(CONFIG_LWM2M_CARRIER)
#include <lwm2m_carrier.h>
#endif



//#define CONFIG_NRF_CLOUD_SEC_TAG 1
#define NRF_CLOUD_HOSTNAME CONFIG_MQTT_BROKER_HOSTNAME
//#define NRF_CLOUD_SEC_TAG  CONFIG_NRF_CLOUD_SEC_TAG

static sec_tag_t sec_tag_list[] = {CONFIG_SEC_TAG};

/* Buffers for MQTT client. */
static u8_t rx_buffer[CONFIG_MQTT_MESSAGE_BUFFER_SIZE];
static u8_t tx_buffer[CONFIG_MQTT_MESSAGE_BUFFER_SIZE];
static u8_t payload_buf[CONFIG_MQTT_PAYLOAD_BUFFER_SIZE];

/* The mqtt client struct */
static struct mqtt_client client;

/* MQTT Broker details. */
static struct sockaddr_storage broker;

/* Connected flag */
static bool connected;

/* File descriptor */
static struct pollfd fds;

#if defined(CONFIG_BSD_LIBRARY)

/**@brief Recoverable BSD library error. */
void bsd_recoverable_error_handler(uint32_t err)
{
	printk("bsdlib recoverable error: %u\n", (unsigned int)err);
}

/**@brief Irrecoverable BSD library error. */
void bsd_irrecoverable_error_handler(uint32_t err)
{
	printk("bsdlib irrecoverable error: %u\n", err);

	__ASSERT_NO_MSG(false);
}

#endif /* defined(CONFIG_BSD_LIBRARY) */



/**@brief Function to print strings without null-termination
 */
static void data_print(u8_t *prefix, u8_t *data, size_t len)
{
	char buf[len + 1];
	memcpy(buf, data, len);
	buf[len] = 0;
	printk("%s%s\n", prefix, buf);
}

/**@brief Function to publish data on the configured topic
 */
static int data_publish(struct mqtt_client *c, enum mqtt_qos qos,
	u8_t *data, size_t len)
{
	struct mqtt_publish_param param;

	param.message.topic.qos = qos;
	param.message.topic.topic.utf8 = CONFIG_MQTT_PUB_TOPIC;
	param.message.topic.topic.size = strlen(CONFIG_MQTT_PUB_TOPIC);
	param.message.payload.data = data;
	param.message.payload.len = len;
	param.message_id = sys_rand32_get();
	param.dup_flag = 0;
	param.retain_flag = 0;

	data_print("Publishing: ", data, len);
	printk("to topic: %s len: %u\n",
		CONFIG_MQTT_PUB_TOPIC,
		(unsigned int)strlen(CONFIG_MQTT_PUB_TOPIC));

	return mqtt_publish(c, &param);
}

/**@brief Function to subscribe to the configured topic
 */
static int subscribe(void)
{
	struct mqtt_topic subscribe_topic = {
		.topic = {
			.utf8 = CONFIG_MQTT_SUB_TOPIC,
			.size = strlen(CONFIG_MQTT_SUB_TOPIC)
		},
		.qos = MQTT_QOS_1_AT_LEAST_ONCE
	};

	const struct mqtt_subscription_list subscription_list = {
		.list = &subscribe_topic,
		.list_count = 1,
		.message_id = 1234
	};

	printk("Subscribing to: %s len %u\n", CONFIG_MQTT_SUB_TOPIC,
		(unsigned int)strlen(CONFIG_MQTT_SUB_TOPIC));

	return mqtt_subscribe(&client, &subscription_list);
}

/**@brief Function to read the published payload.
 */
static int publish_get_payload(struct mqtt_client *c, size_t length)
{
	u8_t *buf = payload_buf;
	u8_t *end = buf + length;

	if (length > sizeof(payload_buf)) {
		return -EMSGSIZE;
	}

	while (buf < end) {
		int ret = mqtt_read_publish_payload(c, buf, end - buf);

		if (ret < 0) {
			int err;

			if (ret != -EAGAIN) {
				return ret;
			}

			printk("mqtt_read_publish_payload: EAGAIN\n");

			err = poll(&fds, 1, K_SECONDS(CONFIG_MQTT_KEEPALIVE));
			if (err > 0 && (fds.revents & POLLIN) == POLLIN) {
				continue;
			} else {
				return -EIO;
			}
		}
		if (ret == 0) {
			return -EIO;
		}

		buf += ret;
	}

	return 0;
}

/**@brief MQTT client event handler
 */
void mqtt_evt_handler(struct mqtt_client *const c,
		      const struct mqtt_evt *evt)
{
	int err;

	switch (evt->type) {
	case MQTT_EVT_CONNACK:
		if (evt->result != 0) {
			printk("MQTT connect failed %d\n", evt->result);
			break;
		}

		connected = true;
		printk("[%s:%d] MQTT client connected!\n", __func__, __LINE__);
		subscribe();
		break;

	case MQTT_EVT_DISCONNECT:
		printk("[%s:%d] MQTT client disconnected %d\n", __func__,
		       __LINE__, evt->result);

		connected = false;
		break;

	case MQTT_EVT_PUBLISH: {
		const struct mqtt_publish_param *p = &evt->param.publish;

		printk("[%s:%d] MQTT PUBLISH result=%d len=%d\n", __func__,
		       __LINE__, evt->result, p->message.payload.len);
		err = publish_get_payload(c, p->message.payload.len);
		if (err >= 0) {
			data_print("Received: ", payload_buf,
				p->message.payload.len);
			/* Echo back received data */
			data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE,
				payload_buf, p->message.payload.len);
		} else {
			printk("mqtt_read_publish_payload: Failed! %d\n", err);
			printk("Disconnecting MQTT client...\n");

			err = mqtt_disconnect(c);
			if (err) {
				printk("Could not disconnect: %d\n", err);
			}
		}
	} break;

	case MQTT_EVT_PUBACK:
		if (evt->result != 0) {
			printk("MQTT PUBACK error %d\n", evt->result);
			break;
		}

		printk("[%s:%d] PUBACK packet id: %u\n", __func__, __LINE__,
				evt->param.puback.message_id);
		break;

	case MQTT_EVT_SUBACK:
		if (evt->result != 0) {
			printk("MQTT SUBACK error %d\n", evt->result);
			break;
		}

		printk("[%s:%d] SUBACK packet id: %u\n", __func__, __LINE__,
				evt->param.suback.message_id);
		break;

	default:
		printk("[%s:%d] default: %d\n", __func__, __LINE__,
				evt->type);
		break;
	}
}

/**@brief Resolves the configured hostname and
 * initializes the MQTT broker structure
 */
static void broker_init(void)
{
	int err;
	struct addrinfo *result;
	struct addrinfo *addr;
	struct addrinfo hints = {
		.ai_family = AF_INET,
		.ai_socktype = SOCK_STREAM
	};

	err = getaddrinfo(CONFIG_MQTT_BROKER_HOSTNAME, NULL, &hints, &result);
	if (err) {
		printk("ERROR: getaddrinfo failed %d\n", err);

		return;
	}

	addr = result;
	err = -ENOENT;

	/* Look for address of the broker. */
	while (addr != NULL) {
		/* IPv4 Address. */
		if (addr->ai_addrlen == sizeof(struct sockaddr_in)) {
			struct sockaddr_in *broker4 =
				((struct sockaddr_in *)&broker);
			char ipv4_addr[NET_IPV4_ADDR_LEN];

			broker4->sin_addr.s_addr =
				((struct sockaddr_in *)addr->ai_addr)
				->sin_addr.s_addr;
			broker4->sin_family = AF_INET;
			broker4->sin_port = htons(CONFIG_MQTT_BROKER_PORT);

			inet_ntop(AF_INET, &broker4->sin_addr.s_addr,
				  ipv4_addr, sizeof(ipv4_addr));
			printk("IPv4 Address found %s\n", ipv4_addr);

			break;
		} else {
			printk("ai_addrlen = %u should be %u or %u\n",
				(unsigned int)addr->ai_addrlen,
				(unsigned int)sizeof(struct sockaddr_in),
				(unsigned int)sizeof(struct sockaddr_in6));
		}

		addr = addr->ai_next;
		break;
	}

	/* Free the address. */
	freeaddrinfo(result);
}

/**@brief Initialize the MQTT client structure
 */
static void client_init(struct mqtt_client *client)
{
	mqtt_client_init(client);

	broker_init();

	/* MQTT client configuration */
	client->broker = &broker;
	client->evt_cb = mqtt_evt_handler;
	client->client_id.utf8 = (u8_t *)CONFIG_MQTT_CLIENT_ID;
	client->client_id.size = strlen(CONFIG_MQTT_CLIENT_ID);
        printk("clientId %s \n", CONFIG_MQTT_CLIENT_ID);
	client->password = NULL;
	client->user_name = NULL;
	client->protocol_version = MQTT_VERSION_3_1_1;

	/* MQTT buffers configuration */
	client->rx_buf = rx_buffer;
	client->rx_buf_size = sizeof(rx_buffer);
	client->tx_buf = tx_buffer;
	client->tx_buf_size = sizeof(tx_buffer);

	/* MQTT transport configuration */
        #if defined(CONFIG_MQTT_LIB_TLS)
          struct mqtt_sec_config *tls_config = &client->transport.tls.config;
    
          client->transport.type = MQTT_TRANSPORT_SECURE;
    
          tls_config->peer_verify = 2;
          tls_config->cipher_count = 0;
          tls_config->cipher_list = NULL;
          tls_config->sec_tag_count = ARRAY_SIZE(sec_tag_list);
          tls_config->sec_tag_list = sec_tag_list;
          tls_config->hostname = CONFIG_MQTT_BROKER_HOSTNAME;
          #else /* MQTT transport configuration */
          client->transport.type = MQTT_TRANSPORT_NON_SECURE;
          #endif /* defined(CONFIG_MQTT_LIB_TLS) */
}

/**@brief Initialize the file descriptor structure used by poll.
 */
static int fds_init(struct mqtt_client *c)
{
	if (c->transport.type == MQTT_TRANSPORT_NON_SECURE) {
		fds.fd = c->transport.tcp.sock;
	} else {
#if defined(CONFIG_MQTT_LIB_TLS)
		fds.fd = c->transport.tls.sock;
#else
		return -ENOTSUP;
#endif
	}

	fds.events = POLLIN;

	return 0;
}

/**@brief Configures modem to provide LTE link. Blocks until link is
 * successfully established.
 */
static void modem_configure(void)
{
#if defined(CONFIG_LTE_LINK_CONTROL)
	if (IS_ENABLED(CONFIG_LTE_AUTO_INIT_AND_CONNECT)) {
		/* Do nothing, modem is already turned on
		 * and connected.
		 */
	} else {
#if defined(CONFIG_LWM2M_CARRIER)
		/* Wait for the LWM2M_CARRIER to configure the modem and
		 * start the connection.
		 */
		printk("Waitng for carrier registration...\n");
		k_sem_take(&carrier_registered, K_FOREVER);
		printk("Registered!\n");
#else /* defined(CONFIG_LWM2M_CARRIER) */
		int err;
		printk("LTE Link Connecting ...\n");
		err = lte_lc_init_and_connect();
		__ASSERT(err == 0, "LTE link could not be established.");
		printk("LTE Link Connected!\n");
#endif /* defined(CONFIG_LWM2M_CARRIER) */
	}
#endif /* defined(CONFIG_LTE_LINK_CONTROL) */
}

/* Provisions root CA certificate using nrf_inbuilt_key API */
static int provision_certificate(void)
{
#if defined(CONFIG_PROVISION_CERTIFICATES)
#if defined(CONFIG_BSD_LIBRARY)
	{
		int err;

		/* Delete certificates */
		nrf_sec_tag_t sec_tag = (nrf_sec_tag_t) sec_tag_list[0];

		for (nrf_key_mgnt_cred_type_t type = 0; type < 5; type++) {
			printk("Deleting certs sec_tag: %d\n", sec_tag);
			err = nrf_inbuilt_key_delete(sec_tag, type);
			printk("nrf_inbuilt_key_delete(%u, %d) => result=%d\n",
				sec_tag, type, err);
		}

#if defined(CA_CERTIFICATE)
		/* Provision CA Certificate. */
		printk("Write ca certs sec_tag: %d\n", sec_tag);
		err = nrf_inbuilt_key_write(sec_tag,
			NRF_KEY_MGMT_CRED_TYPE_CA_CHAIN,
			CA_CERTIFICATE,
			strlen(CA_CERTIFICATE));
		if (err) {
			printk("CA_CERTIFICATE err: %d\n", err);
			return err;
		}
#endif
#if defined (CLIENT_PRIVATE_KEY)
		/* Provision Private Certificate. */
		printk("Write private cert sec_tag: %d\n", sec_tag);
		err = nrf_inbuilt_key_write(
			sec_tag,
			NRF_KEY_MGMT_CRED_TYPE_PRIVATE_CERT,
			CLIENT_PRIVATE_KEY,
			strlen(CLIENT_PRIVATE_KEY));
		if (err) {
			printk("CLIENT_PRIVATE_KEY err: %d\n", err);
			return err;
		}
#endif
#if defined(CLIENT_PUBLIC_CERTIFICATE)
		/* Provision Public Certificate. */
		printk("Write public cert sec_tag: %d\n", sec_tag);
		err = nrf_inbuilt_key_write(
			sec_tag,
			NRF_KEY_MGMT_CRED_TYPE_PUBLIC_CERT,
			CLIENT_PUBLIC_CERTIFICATE,
			strlen(CLIENT_PUBLIC_CERTIFICATE));
		if (err) {
			printk("CLIENT_PUBLIC_CERTIFICATE err: %d\n",err);
			return err;
		}
	}
#endif
#else
	{
		int err;
		err = tls_credential_add(CONFIG_SEC_TAG,
			TLS_CREDENTIAL_CA_CERTIFICATE,
			NRF_CLOUD_CA_CERTIFICATE,
			sizeof(NRF_CLOUD_CA_CERTIFICATE));
		if (err < 0) {
			printk("Failed to register ca certificate: %d\n",err);
			return err;
		}
		err = tls_credential_add(CONFIG_SEC_TAG,
			TLS_CREDENTIAL_PRIVATE_KEY,
			NRF_CLOUD_CLIENT_PRIVATE_KEY,
			sizeof(NRF_CLOUD_CLIENT_PRIVATE_KEY));
		if (err < 0) {
			printk("Failed to register private key: %d\n",err);
			return err;
		}
		err = tls_credential_add(CONFIG_SEC_TAG,
			TLS_CREDENTIAL_SERVER_CERTIFICATE,
			NRF_CLOUD_CLIENT_PUBLIC_CERTIFICATE,
			sizeof(NRF_CLOUD_CLIENT_PUBLIC_CERTIFICATE));
		if (err < 0) {
			printk("Failed to register public certificate: %d\n",err);
			return err;
		}

	}
#endif /* defined(CONFIG_BSD_LIBRARY) */
#endif /* defined(CONFIG_PROVISION_CERTIFICATES) */

	return 0;
}

void main(void)
{
	int err;

	printk("The MQTT simple sample started\n");

        int err_provision = provision_certificate();
        if (err_provision != 0) {
          printk("ERROR: nct_provision failure %d\n", err_provision);
          return;
        }
        printk("err_provision = %d\n", err_provision);

	modem_configure();

	client_init(&client);

	err = mqtt_connect(&client);
	if (err != 0) {
		printk("ERROR: mqtt_connect %d\n", err);
		return;
	}
        printk("\n CONNECTED\n");

	err = fds_init(&client);
	if (err != 0) {
		printk("ERROR: fds_init %d\n", err);
		return;
	}
        printk("FDS init done \n");
	while (1) {
		err = poll(&fds, 1, K_SECONDS(CONFIG_MQTT_KEEPALIVE));
		if (err < 0) {
			printk("ERROR: poll %d\n", errno);
			break;
		}

		err = mqtt_live(&client);
		if (err != 0) {
			printk("ERROR: mqtt_live %d\n", err);
			break;
		}

		if ((fds.revents & POLLIN) == POLLIN) {
			err = mqtt_input(&client);
			if (err != 0) {
				printk("ERROR: mqtt_input %d\n", err);
				break;
			}
		}

		if ((fds.revents & POLLERR) == POLLERR) {
			printk("POLLERR\n");
			break;
		}

		if ((fds.revents & POLLNVAL) == POLLNVAL) {
			printk("POLLNVAL\n");
			break;
		}
	}

	printk("Disconnecting MQTT client...\n");

	err = mqtt_disconnect(&client);
	if (err) {
		printk("Could not disconnect MQTT client. Error: %d\n", err);
	}
}

Looking at errno.h, I understand the error -45 as "Operation not supported on socket".

But which operation is not supported ?

How can I fix this ? And why is it hanging out when I use peer-verify=0 or 1 ?

Thank you in advance

  • Hi,

     

    Q1: How large are your certificates?

    They are casted from const to non-const, meaning that they'll be stacked. Increasing the main stack size might be beneficial (double the heap as well, testing purposes):

    CONFIG_MAIN_STACK_SIZE=8192
    CONFIG_HEAP_MEM_POOL_SIZE=4096

     

    Q2: Do you chain your CA root? Ie: having one root auth. certificate and a second one? The .peer_verify value of 2 indicates that you shall verify the hostname, while 1 states optional, and 0 is do not verify.

    If your broker requires key-pair + CA, you need to provide a CA to the host you're connecting to + a root CA (ie: a chained CA certificate)

    In C format, it'll look like this: https://devzone.nordicsemi.com/f/nordic-q-a/55393/nrf9160-adding-intermediate-certificates-to-the-tls-engine/225697#225697

     

    Q3: When you're setting .peer_verify=1, does it hang forever? Does it print anything? Have you checked if the firmware is stuck somewhere?

     

    Q4: Have you checked if TLS section is working, by for instance connecting to mosquitto? You can connect to mosquitto, https://test.mosquitto.org/, on port 8883 without any certificates to see if your TLS setup itself is working. In this case, you can set peer_verify=1, and tls_config->sec_tag_count = 0 , tls_config->sec_tag_list = NULL

     

    Kind regards,

    Håkon

  • Hi Håkon,

    Q1 : I have change the main stack size and memory pool size as you showed. And the issue is stil there

    Q2: I have the Root CA, the Client CA and the Client Key in a header file certificates.h. It looks like this :

    #define CLIENT_PRIVATE_KEY \
    "-----BEGIN RSA PRIVATE KEY-----\n" \
    "MIIEowIBAAKCAQEAmHoUn2xBQf9+9QQYyxZZtsmJYw/N5z1cO4yt6S2bpIeynfU8\n" \
    ...
    "dP7W0GsXt3aYNSdfTjcp7cw62gEvJ64BI+FKxzpbocnetWCeyUaB\n" \
    "-----END RSA PRIVATE KEY-----\n"
    
    
    
    #define CLIENT_PUBLIC_CERTIFICATE \
    "-----BEGIN CERTIFICATE-----\n" \
    "MIICvDCCAaSgAwIBAgIEAQhZ6DANBgkqhkiG9w0BAQsFADAQMQ4wDAYDVQQDDAVU\n" \
    ...
    "o5ym/Cy1VLs28we6Uk3FgbSQy8aBHV8JplbapPaLYQ8=\n" \
    "-----END CERTIFICATE-----\n"
    
    
    
    #define CA_CERTIFICATE \
    "-----BEGIN CERTIFICATE-----\n" \
    "MIICtjCCAZ6gAwIBAgIJAIjqRXrEC+UGMA0GCSqGSIb3DQEBCwUAMBAxDjAMBgNV\n" \
    ...
    "xCYJngfVEThKYGTCyCC09GsG6uWcRDfnrwo=\n" \
    "-----END CERTIFICATE-----\n"
    

    I now answer first Q4 as I did it before Q3 and it showed me interesting things 

    Q4: Yes I can connect to mosquitto and wait for the event with the modification you showed. The first time I got the mqtt event handler being triggered with :

     

    [mqtt_evt_handler:169] MQTT client connected!
    [mqtt_evt_handler:219] SUBACK packet id: 1234

    But not the other times. I changed the clien Id and restarted the the DK but nothing appears. So I added a printk call after the poll function and I got :

     The MQTT simple sample started
    
    err_provision = 0
    
    LTE Link Connecting ...
    
    LTE Link Connected!
     
    IPv4 Address found 5.196.95.208
     
    After Poll

    I print "After Poll" just after the poll function

    Q3 : Now I am back with my DNS, and the certificates. I am testing with peer-verify =1and I am looking at were it is hanging out.

    I have left the "After Poll" printk call, and I have added a "CONNECTED" printk call after the mqtt_connect function and a "FDS init done" after the fds_init function like here :

    err = mqtt_connect(&client);
    	if (err != 0) {
    		printk("ERROR: mqtt_connect %d\n", err);
    		return;
    	}
            printk("\n CONNECTED\n");
    
    	err = fds_init(&client);
    	if (err != 0) {
    		printk("ERROR: fds_init %d\n", err);
    		return;
    	}
            printk("FDS init done \n");
    	while (1) {
    		err = poll(&fds, 1, K_SECONDS(CONFIG_MQTT_KEEPALIVE));
    		if (err < 0) {
    			printk("ERROR: poll %d\n", errno);
    			break;
    		}
                    printk("After Poll");

    And I got this : 

    ***** Booting Zephyr OS build v2.0.99-ncs1 *****
    The MQTT simple sample started
    Deleting certs sec_tag: 2
    nrf_inbuilt_key_delete(2, 0) => result=0
    Deleting certs sec_tag: 2
    nrf_inbuilt_key_delete(2, 1) => result=0
    Deleting certs sec_tag: 2
    nrf_inbuilt_key_delete(2, 2) => result=0
    Deleting certs sec_tag: 2
    nrf_inbuilt_key_delete(2, 3) => result=2
    Deleting certs sec_tag: 2
    nrf_inbuilt_key_delete(2, 4) => result=2
    Write ca certs sec_tag: 2
    Write private cert sec_tag: 2
    Write public cert sec_tag: 2
    err_provision = 0
    LTE Link Connecting ...
    LTE Link Connected!
    IPv4 Address found 13.95.15.251
    clientId mqtt_test 
    
     CONNECTED
    FDS init done 
    After poll
    

    So it seems the connection is successfull but that I got no response from server like with the test on mosquitto

  • Hi,

     

    The mqtt_simple sample will just connect, and subscribe to a given topic. Not much more will happen there, unless you publish to the specific topic that the nrf is subscribed to.

    Poll will stand there for CONFIG_MQTT_KEEPALIVE seconds before sending a keep-alive, so it might not do much unless you wait 60 seconds (default value), where then should print "after poll" again.

    I did this exact setup with mqtt_simple (.peer_verify = 1 for testing purposes), connecting to mqtt.eclipse.org port 8883, and I'm not seeing the same failure as you.

    Note that I am not testing with test.mosquitto.org. It seems to be down? I get a timed out request back when I try to connect to port 8883, which I also get if I use mosquitto_sub on my PC.

     

    Have you removed the prints in the mqtt_evt_handler() ? You do not seem to get any mqtt-related prints from that one.

    PS: I see that you're using ncs v1.1.0. We have released v1.2.0, but this sample should work on both.

     

    Kind regards,

    Håkon

  • Hi Håkon,

    I also got the time out if I try with test.mosquito.org. Yes it seems to be down

    I did not remove the printk calls from the mqtt_evt_handler. I also tried with mqtt.eclipse.org and I have the same thing : the mqtt_event handler is never called

  • I tested with both v1.1.0 and v1.2.0, and get this behavior:

    ***** Booting Zephyr OS build v2.0.99-ncs1 *****
    The MQTT simple sample started
    LTE Link Connecting ...
    +CEREG: 2,"76C1","014ACE00",7,0,0,"11100000","11100000"
    +CEREG: 1,"76C1","014ACE00",7,,,"11100000","00001111"
    LTE Link Connected!
    IPv4 Address found 137.135.83.217
    [mqtt_evt_handler:190] MQTT client connected!
    Subscribing to: my/subscribe/topic len 18
    After Poll
    [mqtt_evt_handler:240] SUBACK packet id: 1234
    After Poll

    Here's my source for reference: mqtt_simple.zip

    Please note that the .peer_verify shall be '2' in an actual product, as we are currently not performing hostname verification.

     

    Could you test this and see if you still do not get connected and suback callback?

     

    Kind regards,

    Håkon

Related