I need to store the thing's AWS certificates and key in the SPIFFS in order to survive OTA updates. The certificates are then read from the SPIFFS and connection to AWS IoT needs to be initialized using them. However, mbedtls_ssl_handshake fails with the below error:
Code: Select all
E (2884467) aws_iot: failed! mbedtls_ssl_handshake returned -0x2700
E (2884467) aws_iot: Unable to verify the server's certificate.
E (2884477) AWS_CONTROL: Error(-4) connecting to a1k8en70rrdegy-ats.iot.us-east-1.amazonaws.com:8883
Code: Select all
char aws_root_ca_pem_start[2048] = "0";
char certificate_pem_crt_start[2048] = "0";
char private_pem_key_start[2048] = "0";
int init_spiffs(void)
{
esp_vfs_spiffs_conf_t conf = {
.base_path = "/spiffs",
.partition_label = NULL,
.max_files = 5,
.format_if_mount_failed = false};
esp_err_t ret = esp_vfs_spiffs_register(&conf);
if (ret != ESP_OK)
{
if (ret == ESP_FAIL)
{
ESP_LOGE(TAG, "Failed to mount or format filesystem");
}
else if (ret == ESP_ERR_NOT_FOUND)
{
ESP_LOGE(TAG, "Failed to find SPIFFS partition");
}
else
{
ESP_LOGE(TAG, "Failed to initialize SPIFFS (%d)", ret);
}
return -1;
}
vTaskDelay(1000 / portTICK_RATE_MS);
return 0;
}
void read_file_to_string(char *fname, char buf[2048])
{
printf(" file: \"%s\"\n", fname);
int res;
FILE *fd = fopen(fname, "rb");
if (fd == NULL)
{
ESP_LOGE(TAG, "Error !!!");
printf(" Error opening file (%d) %s\n", errno, strerror(errno));
free(buf);
printf("\n");
return;
}
res = 999;
res = fread(buf, 1, 2047, fd);
if (res <= 0)
{
ESP_LOGE(TAG, "Error !!!");
printf(" Error reading from file\n");
}
else
{
ESP_LOGI(TAG," %d bytes read \n", res);
buf[res] = '\0';
// printf("%s\n]\n", buf);
}
// free(buf);
res = fclose(fd);
if (res)
{
ESP_LOGE(TAG, "Error !!!");
printf(" Error closing file\n");
}
printf("\n");
}
void aws_iot_task(void *param)
{
IoT_Error_t rc = FAILURE;
AWS_IoT_Client client;
IoT_Client_Init_Params mqttInitParams = iotClientInitParamsDefault;
IoT_Client_Connect_Params connectParams = iotClientConnectParamsDefault;
IoT_Publish_Message_Params paramsQOS0;
ESP_LOGI(TAG, "AWS IoT SDK Version %d.%d.%d-%s", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG);
mqttInitParams.enableAutoReconnect = false; // We enable this later below
mqttInitParams.pHostURL = HostAddress;
mqttInitParams.port = port;
mqttInitParams.pRootCALocation = (const char *)aws_root_ca_pem_start;
mqttInitParams.pDeviceCertLocation = (const char *)certificate_pem_crt_start;
mqttInitParams.pDevicePrivateKeyLocation = (const char *)private_pem_key_start;
mqttInitParams.mqttCommandTimeout_ms = 20000;
mqttInitParams.tlsHandshakeTimeout_ms = 5000;
mqttInitParams.isSSLHostnameVerify = true;
mqttInitParams.disconnectHandler = disconnect_callback_handler;
mqttInitParams.disconnectHandlerData = NULL;
rc = aws_iot_mqtt_init(&client, &mqttInitParams);
if(SUCCESS != rc) {
ESP_LOGE(TAG, "aws_iot_mqtt_init returned error : %d ", rc);
abort();
}
/* Wait for WiFI to show as connected */
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
connectParams.keepAliveIntervalInSec = 10;
connectParams.isCleanSession = true;
connectParams.MQTTVersion = MQTT_3_1_1;
/* Client ID is set in the menuconfig of the example */
connectParams.pClientID = device_id;
connectParams.clientIDLen = (uint16_t) strlen(device_id);
connectParams.isWillMsgPresent = false;
ESP_LOGI(TAG, "Connecting to AWS...");
do {
ESP_LOGW(TAG, "Reattempting ************************************** Connecting to AWS...");
rc = aws_iot_mqtt_connect(&client, &connectParams);
if(SUCCESS != rc) {
ESP_LOGE(TAG, "Error(%d) connecting to %s:%d", rc, mqttInitParams.pHostURL, mqttInitParams.port);
vTaskDelay(1000 / portTICK_RATE_MS);
}
} while(SUCCESS != rc);
rc = aws_iot_mqtt_autoreconnect_set_status(&client, true);
if(SUCCESS != rc) {
ESP_LOGE(TAG, "Unable to set Auto Reconnect to true - %d", rc);
abort();
}
char sub_topic[] = "esp32/device";
ESP_LOGW(TAG, "Subscribing to %s", sub_topic);
rc = aws_iot_mqtt_subscribe(&client, SUBTOPIC, SUBTOPIC_LEN, QOS0, iot_subscribe_callback_handler, NULL);
if(SUCCESS != rc) {
ESP_LOGE(TAG, "Error subscribing : %d ", rc);
abort();
}
int spiffs_ok = init_spiffs();
if (spiffs_ok == 0)
{
// read aws certificates into memory
read_file_to_string("/spiffs/certificate.pem.crt", certificate_pem_crt_start);
ESP_LOGI(TAG, "PEM CERT: \n %s", certificate_pem_crt_start);
read_file_to_string("/spiffs/private.pem.key", private_pem_key_start);
ESP_LOGI(TAG, "PEM KEY: \n %s", private_pem_key_start);
read_file_to_string("/spiffs/aws-root-ca.pem", aws_root_ca_pem_start);
ESP_LOGI(TAG, "ROOT CERT: \n %s", aws_root_ca_pem_start);
xTaskCreate(&aws_iot_task, "aws_iot_task", LARGER_STACK, NULL, LOW_PRIORITY, aws_iot_task_handle);
}
When I use the same certificates with the https://github.com/espressif/esp-aws-io ... be_publish, it works fine. But the example, embeds the certificates onto the binary, and that destroys my OTA use-case.
Thanks for reading. Any help is appreciated!
Regards,
Karan