title: How to debug TLS communication between an ESP8266 and MQTT broker (selfsigned credentials)?
body: <p>I am trying to get an Wemos D1 mini (ESP8266) communicate with a MQTT broker using TLS (garagedoor opener), but failing. I get it to work when testing using MQTT.fx, tho....</p>
  
  <p>I am a first offender, but I have used my google-fu to capacity. Still don't get it.
  I have looked at <a href="https://nofurtherquestions.wordpress.com/2016/03/14/making-an-esp8266-web-accessible/" rel="nofollow noreferrer">https://nofurtherquestions.wordpress.com/2016/03/14/making-an-esp8266-web-accessible/</a> quite a bit. Also <a href="https://myles.eftos.id.au/blog/2016/09/14/so-the-esp8266-does-support-tlsv1-2/#.WptU5-jOXDc" rel="nofollow noreferrer">https://myles.eftos.id.au/blog/2016/09/14/so-the-esp8266-does-support-tlsv1-2/#.WptU5-jOXDc</a> saw some traffic.</p>
  
  <p>There are a few somewhat similar questions like <a href="https://stackoverflow.com/questions/46736158/ssl-certificate-verification-on-esp8266-wemos-d1-mini-with-mqtt-broker">this</a>, <a href="https://stackoverflow.com/questions/37030019/mqtt-between-esp8266-and-arduino-with-pubsubclient">this</a> and <a href="https://stackoverflow.com/questions/23436185/why-is-this-mqtt-client-example-failing">this</a>, but since they don't deal with TLS it isn't that much help to me. </p>
  
  <p>Also, I am an amateur coder/DIYer so code structure and knowledge might be lacking....anyway....</p>
  
  <p>I have combined the client certificate and key files (produced by using openssl) into certificate.h:</p>
  
  <pre><code>$ xxd -i client.crt client_bin.crt
  $ xxd -i client.key client_bin.key
  $ cat client.* &gt; certificate.h
  </code></pre>
  
  <p>My sketch:</p>
  
  <pre><code>// ------------- Includes ---------------
  #include &lt;certificate.h&gt;
  #include &lt;PubSubClient.h&gt;
  #include &lt;ESP8266WiFi.h&gt;
  // ------------- Wifi -------------------
  const char* ssid = "SSID";
  const char* password = "password";
  // ------------- MQTT -------------------
  const char* mqttServer = "mqtt.ranheim3r.com";
  const int mqttPort = 8883;
  const char* mqttTopic = "garagedoor";
  const char* mqttUser = "test";
  const char* mqttPassword = "1234";
  // =====================================
  
  // Set up secure comms
  WiFiClientSecure espClient;
  PubSubClient client(espClient);
  
  void setup() {
    // Set up serial for debug
    Serial.begin(115200);
  
    // Connect to Wifi
    Serial.print("connecting to ");
    Serial.println(ssid);
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
  
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  
    espClient.setCertificate(client_crt, client_crt_len);
    espClient.setPrivateKey(client_key, client_key_len);
  
    client.setServer(mqttServer, mqttPort);
    client.setCallback(callback);
  
    // Init future I/O
  }
  
  void reconnect() {
    // Loop until we're reconnected
    while (!client.connected()) {
      Serial.print("Attempting MQTT connection...");
      // Attempt to connect
      if (client.connect("ESPclient", mqttUser, mqttPassword)) {
        Serial.println("connected to Mqtt broker");
        client.subscribe(mqttTopic);
      } else {
        Serial.print("failed, rc=");
        Serial.print(client.state());
        Serial.println(" try again in 5 seconds");
        // Wait 5 seconds before retrying
        delay(5000);
      }
    }
  }
  
  void loop() {
    // Connect/Reconnect to mqtt broker &amp; subscribe
    if (!client.connected()) {
      reconnect();
    }
    client.loop();
    // Act on messages
  } 
  
  void callback(char* topic, byte* payload, unsigned int length) {
    Serial.print("Message arrived [");
    Serial.print(topic);
    Serial.print("] ");
    for (int i = 0; i &lt; length; i++) {
      Serial.print((char)payload[i]);
    }
    Serial.println();
  
    // Activate the door (Test using BUILTIN_LED) if an 1 was received as first character
    if ((char)payload[0] == '1') {
      digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
      // but actually the LED is on; this is because
      // it is acive low on the ESP-01)
      delay(1000);
      digitalWrite (BUILTIN_LED, HIGH);
    } else {
      // Then nothing...
    }
  }
  </code></pre>
  
  <p>This yields the follwoing result from mosquitto:</p>
  
  <pre><code>1520115630: mosquitto version 1.4.10 (build date Mon, 29 May 2017 13:43:29 +0100) starting
  1520115630: Config loaded from /etc/mosquitto/conf.d/mosquitto.conf.
  1520115630: Opening ipv4 listen socket on port 8883.
  1520115630: Opening ipv6 listen socket on port 8883.
  1520115632: New connection from 192.168.1.170 on port 8883.
  1520115632: OpenSSL Error: error:1417C0C7:SSL routines:tls_process_client_certificate:peer did not return a certificate
  1520115632: Socket error on client &lt;unknown&gt;, disconnecting.
  1520115637: New connection from 192.168.1.170 on port 8883.
  1520115637: OpenSSL Error: error:1417C0C7:SSL routines:tls_process_client_certificate:peer did not return a certificate
  1520115637: Socket error on client &lt;unknown&gt;, disconnecting.
  </code></pre>
  
  <p>....and serial output, mirroring that:</p>
  
  <pre><code>WiFi connected
  IP address: 
  192.168.1.170
  Attempting MQTT connection...failed, rc=-2 try again in 5 seconds
  Attempting MQTT connection...failed, rc=-2 try again in 5 seconds
  </code></pre>
  
  <p>My MQTT.fx config:</p>
  
  <pre><code>{
    "connectionProfiles" : [ {
      "recentSubscriptionTopics" : [ ],
      "recentPublishTopics" : [ ],
      "preDefinedMessages" : [ ],
      "brokerAddress" : "mqtt.ranheim3r.com",
      "brokerPort" : "8883",
      "lastPublishTopic" : null,
      "lastSubscriptionTopic" : null,
      "profileName" : "local mosquitto",
      "profileType" : "MQTT_BROKER",
      "scriptsPath" : "",
      "connectionOptions" : {
        "clientId" : "paho60251542020336",
        "connectionTimeout" : 30,
        "keepAliveInterval" : 60,
        "mqttVersionUseDefault" : true,
        "mqttVersion" : "3.1.1",
        "cleanSession" : true,
        "automaticReconnect" : true,
        "maxInflight" : 10,
        "userName" : "test",
        "password" : "1234",
        "lwtQos" : 0,
        "lwtRetained" : false,
        "lastWillDestination" : "",
        "testament" : "",
        "useProxy" : false,
        "useHttpsProxy" : false,
        "httpsProxyHost" : "",
        "httpsProxyPort" : "",
        "httpProxyHost" : "",
        "httpProxyPort" : "",
        "httpProxyUser" : "",
        "httpProxyPassword" : "",
        "httpProxyHeaderUserAgent" : "defaultClient",
        "enableSSLTLS" : true,
        "sslTlsProtocol" : "TLSv1.1",
        "certificateFilesPemFormat" : true,
        "selfCreatedCaFile" : "C:\\ca.crt",
        "caFile" : "C:\\ca.crt",
        "clientCertificateFile" : "C:\\client2.crt",
        "clientKeyFile" : "C:\\client2.key",
        "clientKeyPassword" : "",
        "useSelfCreatedCA" : false,
        "useServerSignedCertificate" : false,
        "useTrustedKeystoreFile" : false,
        "useCertificateFiles" : true,
        "useKeystoreFiles" : false,
        "clientKeystoreFilesPemFormat" : false,
        "trustedKeystoreOnlyFile" : "",
        "trustedKeystoreOnlyPassword" : "",
        "trustedKeystoreFile" : "C:\\jssecacerts",
        "trustedKeystoreAlias" : "192.168.1.68",
        "trustedKeystorePassword" : "",
        "clientKeystoreFile" : "",
        "clientKeystorePassword" : "",
        "clientKeyPairAlias" : "",
        "clientKeyPairPassword" : ""
      },
      "notificatonsEnabled" : false,
      "showLastestMessagesOnly" : false,
      "lastSelectedPayloadDecoderId" : "plain_text_decoder",
      "googleCloudIotOptions" : {
        "projectId" : "ENTER-YOUR-IOT-PROJECT-ID",
        "registryId" : "ENTER-YOUR-REGISTRY-ID",
        "deviceId" : "ENTER-YOUR-DEVICE-ID",
        "cloudRegion" : "us-central1",
        "privateKeyFile" : "rsa_private_pkcs8",
        "algorithm" : "RS256",
        "mqttBridgeHostname" : "mqtt.googleapis.com",
        "mqttBridgePort" : 443
      }
    } ]
  }
  </code></pre>
  
  <p>At this point, I am at a loss where to look, to be honest.</p>
  
  <ol>
  <li><p>I assume it suffices to put forward client certificate and key (signed by the same CA that signed server cert/key) without the use of the ca.crt?</p></li>
  <li><p>Is there a way to signal the use of, say, TLS1.1...and if so, is it needed? (I have tried changing it at the broker, but that didn't help)</p></li>
  <li><p>If the MQTT.fx client is able to connect using the same credentials, am I (in the ESP8266 case) putting the information forward at the wrong time, or could it be the wrong information?</p></li>
  <li><p>How would you go about debugging this?</p></li>
  </ol>
  
  <p>Thanks for your time,</p>
  
  <p>Greger</p>