Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Works perfectly with ArduinoMqttClient on Arduino Due, same code gives inconsistent SSL errors on Teensy 4.1 #33

Closed
MaffooClock opened this issue Mar 5, 2021 · 3 comments
Labels
question Further information is requested

Comments

@MaffooClock
Copy link

I have a program that is an MQTT client for AWS IoT service, which means it uses mTLS and certificate authentication. The same codebase has been tested on:

  1. Seeeduino XIAO (SAMD21)
  2. Arduino Due (SAM3X8E)

I had repeated and continual success connecting to AWS IoT MQTT using AWS-issued certificates, as well as a private TLS-only Mosquitto server using self-signed certificates (so yes, I'm familiar with using SSLClientParameters::fromPEM() and sslClient.setMutualAuthParams(), as well as creating a certificates.h file from root certificates).

I've been trying to use the same code on a new Teensy 4.1 (ARM Cortex M7), but I seem to have trouble with SSLClient. The errors I get are different almost every time (each one of these was from a single connection attempt from a fresh boot):

  1. (SSLClient)(SSL_ERROR)(m_update_engine): Error writing to m_client
    (SSLClient)(SSL_ERROR)(m_update_engine): 0
    (SSLClient)(SSL_ERROR)(connected): Not connected because write error is set
    (SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_WRITE_FAIL
    (SSLClient)(SSL_WARN)(m_run_until): Terminating with write error:
    (SSLClient)(SSL_WARN)(m_run_until): 4
    (SSLClient)(SSL_ERROR)(m_start_ssl): Failed to initlalize the SSL layer
    (SSLClient)(SSL_ERROR)(m_print_br_error): Unknown error code: 0

  2. (SSLClient)(SSL_WARN)(m_run_until): Terminating because the ssl engine closed
    (SSLClient)(SSL_ERROR)(m_start_ssl): Failed to initlalize the SSL layer
    (SSLClient)(SSL_ERROR)(m_print_br_error): Unsupported or invalid algorithm (ECDHE curve, signature algorithm, hash function).

  3. (SSLClient)(SSL_WARN)(m_run_until): Terminating because the ssl engine closed
    (SSLClient)(SSL_ERROR)(m_start_ssl): Failed to initlalize the SSL layer
    (SSLClient)(SSL_ERROR)(m_print_br_error): Issuer/Subject DN mismatch in the chain.

  4. (SSLClient)(SSL_ERROR)(m_run_until): SSL internals timed out! This could be an internal error, bad data sent from the server, or data being discarded due to a buffer overflow. If you are using Ethernet, did you modify the library properly (see README)?
    (SSLClient)(SSL_ERROR)(connected): Not connected because write error is set
    (SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_BR_WRITE_ERROR
    (SSLClient)(SSL_ERROR)(m_start_ssl): Failed to initlalize the SSL layer
    (SSLClient)(SSL_ERROR)(m_print_br_error): Unknown error code: 0

There have been others, but these were the four that I captured when I made the decision to file a bug.

Troubleshooting:
One of the troubleshooting steps was to completely remove SSLClient and test MQTT connections to a test server without encryption, which worked, so it's not the network hardware nor anything else I'm doing in code.

I have scoured the SSLClient source to see if there were any flags that were different between the Due and Teensy platforms that might be throwing things off during compile, but I didn't notice anything interesting.

Context:

  • Teensy 4.1 (600MHz ARM Cortex M7, 1024K RAM)
  • Teensyduino v1.53 (based on Arduino Core 1.8.13)
  • Relevant Libraries:
    • TinyGSM v0.10.9
    • ArduinoMqttClient v0.1.5 (have also tested with PubSubClient v2.8)
  • SSLClient Version 1.6.10

Additional context
The same codebase has been used on other devices not listed above, but those were not using this library. I only mention this to further assert that everything else in my MQTT client program works fine.

Network access is provided by cellular modem. The Arduino Due used a SIM7000A, and the Teensy 4.1 is using a u-blox SARA-R410M.

I ran the TinyGSM HttpsClient demo, which successfully downloaded the TinyGSM text logo over HTTPS. Of course, this has nothing to do with SSLClient, I'm only making the point that encrypted communication is possible on this setup.

I haven't included any code snippets in this initial report because I'm not sure it's relevant yet. My main goal here is to see if any other Teensy 4.x users might be having the same experience, or to see if anyone smarter than me might know of things to check or tweak.

@MaffooClock MaffooClock added the question Further information is requested label Mar 5, 2021
@MaffooClock
Copy link
Author

Interesting... when I swapped out the SARA-R410 modem with the SIM7000 (on the same Teensy 4.1), connection to AWS IoT MQTT works fine.

So, Teensy 4.x + SARA-R410 + SSLClient is a NOOP? This makes no sense, because the same modem works fine on the other boards I tested. Weird.

@prototypicalpro
Copy link
Member

Thanks for the detailed writeup! Yeah there's at least a few platform-dependent bugs rattling around that I've been pretty stumped on (see #9), and so far every bug has been with SSLClient and not BearSSL (the underlying library SSLClient wraps). I think ultimately the logic for a Message -> MQTT -> TLS -> TCP -> 4G pipeline is so complicated that the bugs that occur are easier to work around than they are to find, which is unfortunate. Glad you got it working!

@AB-informatica-service
Copy link

AB-informatica-service commented Jun 27, 2023

Hi @MaffooClock
I reopen this topic because I have the same configuration as yours, i.e. SIM7000E but I have problems maintaining a stable SSL connection.

Let me explain, I use ESP32-S3 and I want to create an MQTT connection with SSL always active.
At the moment it connects and works fine but after 2/3 days I lose the SSL connection and it goes into an infinite loop and on the serial monitor I get:
(SSLClient)(SSL_ERROR)(connected): Not connected because write error is set
(SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_CONNECT_FAIL
(SSLClient)(SSL_ERROR)(connected): Not connected because write error is set
(SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_CONNECT_FAIL
(SSLClient)(SSL_ERROR)(connect): Failed to connect using m_client. Are you connected to the internet?
[93660039][E][AbiotMQTT.cpp:96] loop(): Impossibile connettersi al broker MQTT
(SSLClient)(SSL_ERROR)(connected): Not connected because write error is set
(SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_CONNECT_FAIL
[93660529][I][AbiotMQTT.cpp:88] loop(): Connessione con broker MQTT disconnesso
(SSLClient)(SSL_ERROR)(connected): Not connected because write error is set
(SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_CONNECT_FAIL
(SSLClient)(SSL_ERROR)(connected): Not connected because write error is set
(SSLClient)(SSL_ERROR)(m_print_ssl_error): SSL_CLIENT_CONNECT_FAIL

Code:
`#include <TinyGsmClient.h>
SerialAT = new SoftwareSerial(9, 8);
gsmModem = new TinyGsm(*SerialAT);
this->rawClient = new TinyGsmClient(*gsmModem);

this->sslClient = new SSLClient(*this->rawClient, TAs, (size_t)TAs_NUM, 17, 2, SSLClient::DebugLevel::SSL_INFO);
this->sslClient->setMutualAuthParams(mTLS);

in Setup():
this->mqtt = new PubSubClient(AWS_IOT_ENDPOINT, 8883, AbiotMQTT::subscribeHandler, this->client);

In loop():
void AbiotMQTT::loop()
{
if (!mqtt->connected())
{
if (lostConnection > 5)
{
lostConnection = 0;
log_i("5 tentativi di riconnessione con MQTT fatti, ora vado nel setup di MQTT.");
this->setup();
}
else
{
lostConnection++;
}

    log_i("Connessione con broker MQTT disconnesso");
    delay(1000);
    // Reconnect every 10 seconds
    uint32_t t = millis();
    if (t - lastReconnectAttempt > 1000L)
    {
        while (!mqtt->connect(CONSORTIUM_ID))
        {
            log_e("Impossibile connettersi al broker MQTT");
            lastReconnectAttempt = 0;
            return;
        }

        log_e("Iscrizione al topic %s", TOPIC_SUB);
        while (!mqtt->subscribe(TOPIC_SUB))
        {
            log_i("Iscrizione al Topic fallita");
            // delay(500);
        }
        delay(100);

        log_i("Connesso al broker: %s ", String(mqtt->connected()).c_str());
    }
}

if (pilaMQTT.size() != 0)
{
    String messaggio = pilaMQTT.front();
    Serial.print("trovato messaggio da inviare con MQTT:");
    Serial.println(messaggio);
    sendMessage(messaggio);
    deleteMessageFromPilaMQTT();
}
this->mqtt->loop();

}`

Am I doing something wrong?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants