Smart Tecnnic
Smart Tecnnic

Reputation: 21

Implementing MQTT using ESP-IDF and GoogleCloudPlataform (pub / sub)

PROBLEM SOLVED

I am trying to communicate my esp32 with google iot (pub / sub) using the native language of ESP-IDF. I'm using this framework https://github.com/espressif/esp-google-iot. I can connect to wifi, I put all the necessary informations: project_id, location_id, registry_id, device_id, private_key.pem.

The private_key.pem is on the directory: ...\examples\smart_outlet\main\certs, however I have two private keys, the first starts with ----begin----have 2 line ----end---- and the other is similar to this format d4:5z:sq:2A:sg:0s:u8:99:az.

When the program tries to create JWT, it displays this error APP: iotc_create_iotcore_jwt returned with error: 71. I researched and found error 71 in the iotc_error.h library: @cond Numeric code: 71 * / IOTC_JWT_FORMATTION_ERROR.

file iotc_jwt.c:

iotc_state_t iotc_create_iotcore_jwt(
    const char* project_id, uint32_t expiration_period_sec,
    const iotc_crypto_key_data_t* private_key_data, char* dst_jwt_buf,
    size_t dst_jwt_buf_len, size_t* bytes_written) {
  if (NULL == project_id || NULL == private_key_data || NULL == dst_jwt_buf ||
      NULL == bytes_written) {
    return IOTC_INVALID_PARAMETER;
  }and the program returns IOTC_INVALID_PARAMETER as an error.

now in the main program I include iotc_jwt.c, and call the certificate as shown below

extern const uint8_t ec_pv_key_start [] asm ("_ binary_private_key_pem_start");
extern const uint8_t ec_pv_key_end [] asm ("_ binary_private_key_pem_end");

Now I start task of defining the mqtt parameters

static void mqtt_task (void * pvParameters)
{
/ * Format the key type descriptors so that the customer understands
     what type of key is being represented. In this case, PEM encoded
     byte array of an ES256 key. * /
    iotc_crypto_key_data_t iotc_connect_private_key_data;
    
    iotc_connect_private_key_data.crypto_key_signature_algorithm = IOTC_CRYPTO_KEY_SIGNATURE_ALGORITHM_ES256;
    iotc_connect_private_key_data.crypto_key_union_type = IOTC_CRYPTO_KEY_UNION_TYPE_PEM;
    iotc_connect_private_key_data.crypto_key_union.key_pem.key = (char *) ec_pv_key_start;

finally creation of the JWT

/ * Generate the client authentication JWT, which will serve as the MQTT
     * password. * /
    char jwt [IOTC_JWT_SIZE] = {0};
                                         
    printf ("creating JWT");
    size_t bytes_written = 0;
    iotc_state_t state = iotc_create_iotcore_jwt (CONFIG_GIOT_PROJECT_ID,
                            / * jwt_expiration_period_sec = * / 3600, & iotc_connect_private_key_data, jwt,
                             IOTC_JWT_SIZE, & bytes_written);
    if (IOTC_STATE_OK! = state) {
       ESP_LOGI (TAG, "iotc_create_iotcore_jwt returned with error:% ul", state);
        vTaskDelete (NULL);
    }

My question is: is the program code incorrect somewhere? or am I putting the wrong certificate and is it affecting the creation of the JWT? if so, what would be the correct model of the certificate?

I think the problem is in the call from the certificate to the main program, because I have already tested both examples of certificates and it didn't work, after that

If someone made this communication, can help me? I believe that other people are having the same problem.

I already made this communication on arduino and it worked, I managed to publish it in the IOT core, persisted this data in a function and stored it in firebase database realtime. but I need to do it on IDF-ESPRESSIF.

PROBLEM SOLVED HERE

The problem was in the certificate, I was generating a public and a private key, but I was just receiving the public key, so I used the following commands in the cloud shell terminal to solve my problem

first I generated the private key again:

openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem

then the public key:

openssl ec -in ec_private.pem -pubout -out ec_public.pem

they were created now you need to receive them, that was my problem I just called the public key with the following command: cat ec_public.pem

but the key I needed was private so I used this command cat ec_private.pem and received the key I copied it and pasted it into the directory

...\esp-google-iot\examples\smart_outlet\main\certs\private_key.pem

I did this and my problem was solved.

Reference from https://cloud.google.com/iot/docs/how-tos/credentials/keys

Thank you!

att, Augusto

Upvotes: 2

Views: 806

Answers (1)

Noe Romero
Noe Romero

Reputation: 400

The problem was in the certificate, I was generating a public and a private key, but I was just receiving the public key, so I used the following commands in the cloud shell terminal to solve my problem

first I generated the private key again:

openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem

then the public key:

openssl ec -in ec_private.pem -pubout -out ec_public.pem

they were created now you need to receive them, that was my problem I just called the public key with the following command: cat ec_public.pem

but the key I needed was private so I used this command cat ec_private.pem and received the key I copied it and pasted it into the directory

...\esp-google-iot\examples\smart_outlet\main\certs\private_key.pem

I did this and my problem was solved.

Reference from https://cloud.google.com/iot/docs/how-tos/credentials/keys

Upvotes: 1

Related Questions