Client certs removed from connection when setInsecure called, causing SSL connect failure. · Issue #7455 · esp8266/Arduino (original) (raw)

Basic Infos

Platform

Settings in IDE

Problem Description

I am attempting to publish a "hello world" MQTT message over WiFi to an Amazon Web Services (AWS) IoT endpoint, which requires SSL encryption. I have been issued a CA cert, device cert and device public & private keys, plus my account-specific AWS endpoint to publish against.

I have configured my sketch to use these credentials (but not currently using PROGMEM to store them), and I populate the WifiClientSecure with my device certificate and private key. For now I am ignoring server certificate verification using WifiClientSecure::setInsecure.

my troubleshooting has included:

The TLS handshake fails around BSSL:_wait_for_handshake: failed; please see debug output.

Further troubleshooting advice greatly appreciated.

MCVE Sketch

#include <Arduino.h> #include <ESP8266WiFi.h> #include <PubSubClient.h>

namespace Secrets { const char wifiSsid[] = "myssid"; const char wifiPassword[] = "mypass"; const char awsIotEndpoint[] = "redacted.iot.eu-west-1.amazonaws.com";

const char awsCentralAuthorityCertificate[] = R"EOF( -----BEGIN CERTIFICATE----- redacted -----END CERTIFICATE----- )EOF"; const char awsDeviceCertificate[] = R"EOF( -----BEGIN CERTIFICATE----- redacted -----END CERTIFICATE----- )EOF"; const char awsDevicePrivateKey[] = R"EOF( -----BEGIN RSA PRIVATE KEY----- redacted -----END RSA PRIVATE KEY----- )EOF"; } // namespace Secrets

void wifiConnect() { WiFi.mode(WIFI_STA);

WiFi.begin(Secrets::wifiSsid, Secrets::wifiPassword);

if (WiFi.waitForConnectResult() != WL_CONNECTED) { Serial.printf("WiFi connection failed (status=[%s])"); } else { Serial.println("WiFi connected. IP address: "); Serial.println(WiFi.localIP()); } }

PubSubClient mqttClient; WiFiClientSecure wifiClient;

void mqttSetup() { wifiClient.setClientRSACert(new X509List(Secrets::awsDeviceCertificate), new PrivateKey(Secrets::awsDevicePrivateKey)); wifiClient.setInsecure(); // TODO: verify server identity using CA cert

mqttClient.setServer(Secrets::awsIotEndpoint, 8883); mqttClient.setClient(wifiClient); }

void mqttReconnect() { while (!mqttClient.connected()) { Serial.printf("Connecting to MQTT broker... (MQTT client state: %d)\n", mqttClient.state()); if (!mqttClient.connect("test-client-id")) { char errorMessage[128]; wifiClient.getLastSSLError(errorMessage, 128); Serial.printf( "Connecting to MQTT broker failed. (MQTT client state: %d, SSL " "error: %s)\n", mqttClient.state(), errorMessage); }; delay(2500); } Serial.println("MQTT client connected to broker."); }

void setup() { Serial.begin(115200); Serial.println("Booting");

wifiConnect(); mqttSetup(); }

void loop() { delay(5000); mqttReconnect();

if (mqttClient.publish("testTopic", "hello world")) { Serial.println("MQTT message published successfully!"); } else { Serial.println("MQTT message publish failed."); }

Serial.println("Finished loop"); }

Debug Messages

[Info] Opened the serial port - /dev/ttyUSB0
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 2
cnt 

connected with MyWifiSSID, channel 11
dhcp client start...
wifi evt: 0
ip:192.168.86.249,mask:255.255.255.0,gw:192.168.86.1
wifi evt: 3
WiFi connected. IP address: 
192.168.86.249
Connecting to MQTT broker... (MQTT client state: -1)
[hostByName] request IP for: redacted.iot.eu-west-1.amazonaws.com
[hostByName] Host: redacted.iot.eu-west-1.amazonaws.com IP: 52.31.xxx.xx
:ref 1
BSSL:_connectSSL: start connection
:wr 251 0
:wrc 251 251 0
:ack 251
:rn 1414
:rd 5, 1414, 0
:rdi 1414, 5
:rd 1409, 1414, 5
:rdi 1409, 1409
:c0 1409, 1414
BSSL:CERT: aa bb cc etc. REDACTED
BSSL:CERT: aa bb cc etc. REDACTED
BSSL:CERT: aa bb cc etc. REDACTED
BSSL:CERT: aa bb cc etc. REDACTED
BSSL:CERT: aa bb cc etc. REDACTED
:rn 1414
:rch 1414, 1414
:rch 2828, 1108
:rd 3936, 3936, 0
:rdi 1414, 1414
:c 1414, 1414, 3936
:rdi 1414, 1414
:c 1414, 1414, 2522
:rdi 1108, 1108
:c0 1108, 1108
BSSL:CERT: aa bb cc etc. REDACTED
:wr 82 0
:wrc 82 82 0
:wr 6 0
:wrc 6 6 0
:wr 45 0
:wrc 45 45 0
:ack 82
:rn 7
:rcl pb=0x3fff88cc sz=7
:rd 5, 7, 0
:rdi 7, 5
:rd 2, 7, 5
:rdi 2, 2
:c0 2, 7
BSSL:_wait_for_handshake: failed
BSSL:Couldn't connect. Error = 'Unknown error code.'
Connecting to MQTT broker failed. (MQTT client state: -2, SSL error: Unknown error code.)
:ack 51
Connecting to MQTT broker... (MQTT client state: -2)
<repeats>

From a terminal, I can connect successfully using the same certificates:
(the certificates redacted in the sketch above are a copy-paste of the files referenced below)

openssl s_client -connect redacted.iot.eu-west-1.amazonaws.com:8443 -CAfile AmazonRootCA1.pem -cert redacted-certificate.pem.crt -key redacted-private.pem.key

And receive successful output:

CONNECTED(00000005)
depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
verify return:1
depth=1 C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
verify return:1
depth=0 CN = *.iot.eu-west-1.amazonaws.com
verify return:1
---
Certificate chain
 0 s:CN = *.iot.eu-west-1.amazonaws.com
   i:C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
 1 s:C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
   i:C = US, O = Amazon, CN = Amazon Root CA 1
 2 s:C = US, O = Amazon, CN = Amazon Root CA 1
   i:C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Services Root Certificate Authority - G2
 3 s:C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Services Root Certificate Authority - G2
   i:C = US, O = "Starfield Technologies, Inc.", OU = Starfield Class 2 Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
redacted
-----END CERTIFICATE-----
subject=CN = *.iot.eu-west-1.amazonaws.com

issuer=C = US, O = Amazon, OU = Server CA 1B, CN = Amazon

---
No client certificate CA names sent
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256:DSA+SHA256:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:ECDSA+SHA1:RSA+SHA1:DSA+SHA1
Shared Requested Signature Algorithms: ECDSA+SHA512:RSA+SHA512:ECDSA+SHA384:RSA+SHA384:ECDSA+SHA256:RSA+SHA256:DSA+SHA256:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:ECDSA+SHA1:RSA+SHA1:DSA+SHA1
Peer signing digest: SHA256
Peer signature type: RSA
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 5400 bytes and written 1620 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: redacted
    Session-ID-ctx: 
    Master-Key: redacted
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1594729814
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: yes
---