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

nRF9160 issue in receiving MQTT publish messages larger than 2048 bytes over TLS

Hi,

My Setup details:

nRF9160 DK Board: 0.8.3
nRF Connect SDK tag: 1.3.0
OS: Windows 10 Pro
LTE Network: NB-IoT
Modem Firmware: mfw_nrf9160_1.2.0
Cloud Platform: AWS IoT Core
CONFIG_AWS_IOT_MQTT_PAYLOAD_BUFFER_LEN: 5120

Use case:

As part of device provisioning process we need to receive a MQTT message from AWS which contains certificate details, this message can't be split as we don't have control over it. Size of such messages are around 3KB.

Issue:

Whenever the incoming PUBLISH message size from AWS is more than 2048 bytes, MQTT connection is dropped. After some debugging the function "mqtt_read_and_parse_fixed_header" in MQTT library (mqtt_rx.c source code) returns -ENOTCONN.

In the release notes of modem firmware, a limitation is mentioned about TLS feature: "2kB secure socket buffer size."
However after experimenting with incoming message sizes I noticed publish messages up to 2235 bytes are received successfully. Few bytes over it and the connection drops. In general with TCP protocol large packets can be received with small buffers with appropriate MTU/Window size. Is this issue linked to the above TLS limitation or something else?

Reproducing the issue is simple, use any cloud example to connect to AWS over TLS, subscribe to any topic and from AWS send 2KB+ sized messages.

Thanks,
Ravikiran

  • Thank you Øyvind, Markus for your suggestions. We will explore all our options.

    Regards,
    Ravikiran

  • Just commenting on this because I ran into the same issue. The lambda which intercepts the CreateKeysAndCertificate response ("$aws/certificates/create/json/accepted") must then republish the certificate and key separately to two new topics.

    There is some trickery going on in the AWS IoT backend because the policy document states that a device can subscribe to any subtopic of "$aws/certificates/create/*" but you will find that subscribing to a subtopic other than /accepted and /rejected causes the client to be disconnected from the broker. Also, the lambda cannot publish to a reserved topic denoted by the '$' prefix

    The solution is to create two new topics, eg: "fleetprovision/certificate" and "fleetprovision/key" which the lambda can publish to. The final step is updating the fleet certificate policy document so that the device can also subscribe and receive messages from these topics using its fleet provisioning certificate.

  • Well unfortunately I have hit a dead end as the AWS IoT broker only sends the CreateKeysAndCertificate response to the client on same same connection as the originating request, meaning it can't be intercepted by the rules engine nor any other clients.

    A potential hack is to use an EC2 instance as a middle-man which can both submit a certificate request and receive a response, then encode that into a smaller payload and pass it onto the nrf9160 but this likely has security implications.

  • Hei Dominic,

    for this specific message it is a good security measure on AWS that it is only sent to the requesting client. 

    However you can implement this using a lambda (or EC2 instance) which sends the new certificate to the device: the device would e.g. send a blank MQTT message to /<deviceId>/newcert/request and a lambda listening to this message creates a new certificate and sends it via/<deviceId>/newcert/created and the device can retrieve it there (again split up in multiple messages because of the size).

    This would be as secure resp. insecure as using the AWS IoT MQTT topics directly (it is still sent over the wire).

  • Thanks Markus, this is exactly how I ended up implementing it

Related