Reputation: 913
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:
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.
Upvotes: 1
Views: 4172
Reputation: 913
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:
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;
}
Upvotes: 1
Reputation: 4762
Firstly, please avoid posting screenshots with compiler output. Instead, please copy the output text and paste it into your post (with relevant formatting).
You appear to be using an older version of the WiFiClientSecure library which has a different interface - setCACert()
expects two arguments, the key and its length. Why don't you try that?
net.setCACert((const uint8_t*)AWS_CERT_CA, sizeof(AWS_CERT_CA) - 1);
The - 1
strips the terminating null, as the function appears to take binary blob and those don't usually come with terminators. If authentication doesn't work, try removing that subtraction.
Upvotes: 4