Azure / azure-sdk-for-c

This repository is for active development of the Azure SDK for Embedded C. For consumers of the SDK we recommend visiting our versioned developer docs at https://azure.github.io/azure-sdk-for-c.
MIT License
226 stars 120 forks source link

Error when calling Prov_Device_LL_Register_Device function #2885

Open MrudulaSatya opened 3 months ago

MrudulaSatya commented 3 months ago

Hello,

I am using the TI CC3235SF MCU , TI Simplelink SDK V4.10 and Azure IoT SDK Plugin 4.10. The Azure IoT SDK Version is 1.3.8.

I am trying to provision my device to Azure Cloud (Device provisioning service (DPS) and IoTHub). I am using x509 certificate and key pair fro authentication. (.der files. )

The function "Prov_Device_LL_Register_Device()" is giving me an error code 10 (PROV_DEVICE_RESULT_ERROR). On setting breakpoints, I realized that the code is getting stuck at the following line inside the "Prov_Device_LL_Register_Device" function.

if (handle->prov_transport_protocol->prov_transport_x509_cert(handle->transport_handle, x509_cert, x509_private_key) != 0)

I am using Code Composer Studio CCS V12.7.

What could be the possible reason for this error? What things can I check? Do you think something could be missing in the package.bld file of the Azure SDK? Thank you!

Things I tried to do -

  1. I also tried updating the Azure IoT SDK in side the Plugin to LTS release V1.12.1 and observed the same issue.
  2. Tried to .pem files instead of .der for the device certificate and key pair. - Saw the same issue occur.

The following is the code snippet I am using -

        PROV_DEVICE_TRANSPORT_PROVIDER_FUNCTION g_prov_transport;
        HTTP_PROXY_OPTIONS http_proxy;
        CLIENT_SAMPLE_INFO user_ctx; 

        memset(&http_proxy, 0, sizeof(HTTP_PROXY_OPTIONS));
        memset(&user_ctx, 0, sizeof(CLIENT_SAMPLE_INFO));

        g_prov_transport = Prov_Device_HTTP_Protocol;

        user_ctx.registration_complete = 0;
        user_ctx.sleep_time = 10;

        UART_PRINT("Provisioning API Version: foobar\r\n");
        UART_PRINT("Iothub API Version: foobar\r\n");

        PROV_DEVICE_LL_HANDLE handle;
        if ((handle = Prov_Device_LL_Create(global_prov_uri_temp, id_scope_temp, g_prov_transport)) == NULL)
        {
            UART_PRINT("failed calling Prov_Device_LL_Create\r\n");
        }
        else
        {
            UART_PRINT("Prov_Device_LL_Create success!\r\n");

            Prov_Device_LL_SetOption(handle, "logtrace", &g_trace_on);

            PROV_DEVICE_RESULT x = Prov_Device_LL_Register_Device(handle, register_device_callback, &user_ctx, registation_status_callback, &user_ctx);

            if (x != PROV_DEVICE_RESULT_OK)
            {
                UART_PRINT("failed calling Prov_Device_LL_Register_Device %d\r\n", x);
                DPSServiceConnected = 2;
            }
            else
            {
              UART_PRINT("Prov_Device_LL_Register_Device success\r\n");
                .
                .
                .
            }    `

My custom_hsm_tirtos.c file is this:-


// Copyright (c) Microsoft. All rights reserved.

// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include <stdlib.h>

#include <string.h>

#include "hsm_client_data.h"

const int serialNumberLen= 14;

extern char* extract_common_name();

#define     SL_FS_READ                             ((unsigned long)0x8<<(17+10))

//extern SL_FS_READ;

typedef struct CUSTOM_HSM_INFO_TAG

{

    int info;

} CUSTOM_HSM_INFO;

HSM_CLIENT_HANDLE custom_hsm_create()

{

    CUSTOM_HSM_INFO* result;

    result = malloc(sizeof(CUSTOM_HSM_INFO));

    if (result == NULL)

    {

        //TODO: TI should log something here (void)printf("Failure: malloc CUSTOM_HSM_INFO.");

        result = 0;

    }

    else

    {

        memset(result, 0, sizeof(CUSTOM_HSM_INFO));

    }

    return (HSM_CLIENT_HANDLE)result;

}

void custom_hsm_destroy(HSM_CLIENT_HANDLE handle)

{

    if (handle != NULL)

    {

        CUSTOM_HSM_INFO* hsm_impl = (CUSTOM_HSM_INFO*)handle;

        free(hsm_impl);

    }

}

int hsm_client_x509_init()

{

    // Add any code needed to initialize the x509 module

    return 0;

}

void hsm_client_x509_deinit()

{

}

int hsm_client_tpm_init()

{

    // Add any code needed to initialize the TPM module

    return 0;

}

void hsm_client_tpm_deinit()

{

}

// Return the X509 certificate in PEM format

char* custom_hsm_get_certificate(HSM_CLIENT_HANDLE handle)

{

    char* result;

    if (handle == NULL)

    {

        //TODO: TI should log something here (void)printf("Invalid handle value specified");

        result = NULL;

    }

    else

    {

        CUSTOM_HSM_INFO* cust_hsm = (CUSTOM_HSM_INFO*)handle;

        cust_hsm->info += 1;

        //TODO: Ideally TI would load the this from secure storage

        const char* cert = "path to location of .der file";

        if (cert == NULL)

        {

            //TODO: TI should log something here (void)printf("Failure retrieving cert");

            result = NULL;

        }

        else

        {

            size_t length = strlen(cert);

            result = malloc(length + 1);

            if (result == NULL)

            {

                //TODO: TI should log something here (void)printf("Failure allocating certifiicate");

            }

            else

            {

                strcpy(result, cert);

            }

        }

    }

    return result;

}

// Return Private Key of the Certification

char* custom_hsm_get_alias_key(HSM_CLIENT_HANDLE handle)

{

    char* result;

    if (handle == NULL)

    {

        //TODO: TI should log something here (void)printf("Invalid handle value specified");

        result = NULL;

    }

    else

    {

        CUSTOM_HSM_INFO* cust_hsm = (CUSTOM_HSM_INFO*)handle;

        cust_hsm->info += 1;

        //TODO: Ideally TI would load the this from secure storage

        const char* private_key = "path to location of .der file";

        if (private_key == NULL)

        {

            //TODO: TI should log something here (void)printf("Failure retrieving private key");

            result = NULL;

        }

        else

        {

            size_t length = strlen(private_key);

            result = malloc(length + 1);

            if (result == NULL)

            {

                //TODO: TI should log something here (void)printf("Failure allocating private key");

            }

            else

            {

                strcpy(result, private_key);

            }

        }

    }

    return result;

}

// Return allocated common name on the x509 certificate

char* custom_hsm_get_common_name(HSM_CLIENT_HANDLE handle)

{

    char* result;

    if (handle == NULL)

    {

        //TODO: TI should log something here (void)printf("Invalid handle value specified");

        result = NULL;

    }

    else

    {

        CUSTOM_HSM_INFO* cust_hsm = (CUSTOM_HSM_INFO*)handle;

        cust_hsm->info += 1;

        //TODO: Ideally TI would load the this from secure storage

        const char* common_name = extract_common_name(); 

        if (common_name == NULL)

        {

            //TODO: TI should log something here (void)printf("Failure retrieving common name");

            result = NULL;

        }

        else

        {

            size_t length =  serialNumberLen; //strlen(common_name);

            result = malloc(length + 1);

            if (result == NULL)

            {

                //TODO: TI should log something here (void)printf("Failure allocating common name");

            }

            else

            {

                strcpy(result, common_name);

            }

        }

    }

    return result;

}

// TPM Custom Information handling

// Allocates the endorsement key using as key and the length as key_len

int custom_hsm_get_endorsement_key(HSM_CLIENT_HANDLE handle, unsigned char** key, size_t* key_len)

{

    int result;

    if (handle == NULL)

    {

        //TODO: TI should log something here (void)printf("Invalid handle value specified");

        result = __LINE__;

    }

    else

    {

      result = <Number>; //TI doesn't have a TPM

    }

    return result;

}

// Allocates the Storage Root key using as key and the length as key_len

int custom_hsm_get_storage_root_key(HSM_CLIENT_HANDLE handle, unsigned char** key, size_t* key_len)

{

    int result;

    if (handle == NULL || key == NULL || key_len == NULL)

    {

        //TODO: TI should log something here (void)printf("Invalid handle value specified");

        result = __LINE__;

    }

    else

    {

      result = <Number>; //TI doesn't have a TPM

    }

    return result;

}

// Decrypt and Stores the encrypted key

int custom_hsm_activate_id_key(HSM_CLIENT_HANDLE handle, const unsigned char* key, size_t key_len)

{

    int result;

    if (handle == NULL || key == NULL || key_len == 0)

    {

        //TODO: TI should log something here (void)printf("Invalid argument specified handle: %p, key: %p, key_len: %d", handle, key, key_len);

        result = __LINE__;

    }

    else

    {

      result = <Number>; //TI doesn't have a TPM

    }

    return result;

}

// Hashes value specified in data with the key stored in slot 1 and returns the result in signed_value

int custom_hsm_sign_with_identity(HSM_CLIENT_HANDLE handle, const unsigned char* data, size_t data_len, unsigned char** signed_value, size_t* signed_len)

{

    int result;

    if (handle == NULL || data == NULL || data_len == 0 || signed_value == NULL || signed_len == NULL)

    {

        //TODO: TI should log something here (void)printf("Invalid handle value specified handle: %p, data: %p", handle, data);

        result = __LINE__;

    }

    else

    {

        result = <Number>; //TI doesn't have a TPM

    }

    return result;

}

static const HSM_CLIENT_X509_INTERFACE x509_interface =

{

    custom_hsm_create,

    custom_hsm_destroy,

    custom_hsm_get_certificate,

    custom_hsm_get_alias_key,

    custom_hsm_get_common_name

};

static const HSM_CLIENT_TPM_INTERFACE tpm_interface =

{

    custom_hsm_create,

    custom_hsm_destroy,

    custom_hsm_activate_id_key,

    custom_hsm_get_endorsement_key,

    custom_hsm_get_storage_root_key,

    custom_hsm_sign_with_identity

};

const HSM_CLIENT_TPM_INTERFACE* hsm_client_tpm_interface()

{

    return &tpm_interface;

}

const HSM_CLIENT_X509_INTERFACE* hsm_client_x509_interface()

{

    return &x509_interface;

}

```        
MrudulaSatyaY commented 3 months ago

I wanted to share the error logs from the Azure IoT SDK C when this issue occurs -

[18:48:36.104] Iothub API Version: foobar
[18:48:36.109] Prov_Device_LL_Create success!
Error: Time:Thu Aug 22 18:48:36 2024 File:../../pal/src/tlsio_sl.c Func:tlsio_sl_open Line:371 SlNetSock_startSec failed to start session

Error: Time:Thu Aug 22 18:48:36 2024 File:../../sdk/deps/uhttp/src/uhttp.c Func:uhttp_client_open Line:1125 opening xio failed
Error: Time:Thu Aug 22 18:48:36 2024 File:../../sdk/provisioning_client/src/prov_transport_http_client.c Func:create_connection Line:617 failed to open http client
Error: Time:Thu Aug 22 18:48:36 2024 File:../../sdk/provisioning_client/src/prov_transport_http_client.c Func:prov_transport_http_open Line:763 Failure creating http connection
Error: Time:Thu Aug 22 18:48:36 2024 File:../../sdk/provisioning_client/src/prov_device_ll_client.c Func:Prov_Device_LL_Register_Device Line:1081 Failure establishing  connection
[18:48:36.344] failed calling Prov_Device_LL_Register_Device 10
[18:48:36.350] registration failed!`