Search code examples
c++amazon-web-servicesiotesp32aws-iot-core

WiFiClientSecure setCaCert does not accept my parameters


I am currently trying to connect my ESP32 to AWS IoT. Therefore, I have to use certificates to encrypt the connection. In theory I know how this will work, but I´m not a C++ pro and I get an error. Of course I tried to google, but I always find the same solution which does not work for me. To be concrete, I try ti declare a cacert in a header file like so:

const char AWS_CERT_CA[] = "-----BEGIN CERTIFICATE-----\n" \
"MIIDQTChkiG9w0CAimfz5m/jAo5gAwIBBgkqBAkPmljZbyjQsAgITBmy4vB4iANF\n" \
"ADA5MGQW1hem5sGQW1hemDVVUzEMQxBBDVhMQsYDVQQQGEwJQDExBBbWF6\n" \
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" \
"-----END CERTIFICATE-----\n";

In the main file I try to use it like so:

WiFiClientSecure net = WiFiClientSecure();
void connectToAWS()
{
    // Configure WiFiClientSecure to use the AWS certificates we generated
    net.setCACert(AWS_CERT_CA);
    net.setCertificate(AWS_CERT_CRT);
    net.setPrivateKey(AWS_CERT_PRIVATE);
...

When I try to compile, it gives me the following error:

enter image description here

Obviously, the parameter types are not correct, but why does it work for others (e.g. here and here)? An int as a parameter for the function does not make sense to me. Hope you can help me.


Solution

  • So it took me quite w while to figure out how I can solve this. The main problem was that I am using an old version of BearSSL, but I was not able to update it. To circumvent this problem, I create files out of my cryptographic information and use these files for creating the secured connection to AWS iot. Furthermore, I do not use MQTT to transfer my metrics, but the REST endpoint. I am sure this is not an optimal solution, but it works so far. Here´s how I´ve done it. Things to understand first:

    • net is an instance of WiFiClientSecure: BearSSL::WiFiClientSecure net = BearSSL::WiFiClientSecure();

    My cryptographic information (key, CACert, cert) looks like this:

    const char AWS_CA_CERT[]="-----BEGIN CERTIFICATE-----\n" \
    ...
    "rqXRfboQnoZsG4q5WTP468SQvvG5\n" \
    "-----END CERTIFICATE-----";
    

    After establishing the Wifi connection, I do the following to establish the secure connection:

    bool establishSecureConnection()
    {
      if (!SPIFFS.begin())
      {
        Serial.println("An Error has occurred while mounting SPIFFS");
        return false;
      }
    
      File tempCA = SPIFFS.open("/ca.crt", "w");
      File tempCert = SPIFFS.open("/cert.crt", "w");
      File tempKey = SPIFFS.open("/cert.priv", "w");
    
      if (!tempCA || !tempCert || !tempKey)
      {
        Serial.println("There was an error opening the file for writing");
        return false;
      }
    
      if (tempCA.print(AWS_CA_CERT))
      {
        Serial.println("Ca File was written");
      }
      else
      {
        Serial.println("Ca File write failed");
      }
      tempCA.close();
    
      if (tempCert.print(AWS_CERT))
      {
        Serial.println("cert File was written");
      }
      else
      {
        Serial.println("cert File write failed");
      }
      tempCert.close();
    
      if (tempKey.print(AWS_PRIVATE_KEY))
      {
        Serial.println("key File was written");
      }
      else
      {
        Serial.println("key File write failed");
      }
      tempKey.close();
    
      File ca = SPIFFS.open("/ca.crt", "r");
      if (!ca)
      {
        Serial.println("Failed to open ca file for reading");
        return false;
      }
    
      File cert = SPIFFS.open("/cert.crt", "r");
      if (!cert)
      {
        Serial.println("Failed to open cert file for reading");
        return false;
      }
    
      File pk = SPIFFS.open("/cert.priv", "r");
      if (!pk)
      {
        Serial.println("Failed to open pk file for reading");
        return false;
      }
      if (net.loadCACert(ca))
      {
        Serial.println("Successfully loaded ca");
      }
      else
      {
        Serial.println("Could not load ca");
        return false;
      }
      if (net.loadCertificate(cert))
      {
        Serial.println("Successfully loaded cert");
      }
      else
      {
        Serial.println("Could not load cert");
        return false;
      }
      if (net.loadPrivateKey(pk))
      {
        Serial.println("Successfully loaded pk");
      }
      else
      {
        Serial.println("Could not load pk");
        return false;
      }
    
      net.setTimeout(20000);
      if (!net.connect(AWS_IOT_ENDPOINT, 8443))
      {
        Serial.println("connection failed");
        char err_buf[1024];
        Serial.println(net.getLastSSLError(err_buf, 1024));
        Serial.printf("ssl_error: %s\n", err_buf);
        return false;
      }
      else
      {
        Serial.println("Connected to AWS!");
      }
      return true;
    }