AWS IoT Device SDK C: Fleet Provisioning
AWS IoT Fleet Provisioning
Return to main page ↑
aws_iot_provisioning_api.c File Reference

Implements most user-facing functions of the Provisioning library. More...

#include "iot_config.h"
#include <string.h>
#include "iot_error.h"
#include "private/aws_iot_provisioning_internal.h"
#include "platform/iot_threads.h"
#include "iot_atomic.h"
#include "iot_mqtt.h"
#include "aws_iot.h"
#include "iot_logging_setup.h"

Functions

static bool _checkInit (void)
 Check if the library is initialized. More...
 
static AwsIotProvisioningError_t _initializeOperationObject (uint8_t operationIndex)
 Initializes the operation object in _activeOperation array for the passed index reference. More...
 
static void _cleanUpOperationObject (uint8_t operationIndex)
 Cleans up the operation object in _activeOperation array for the passed index reference. More...
 
static void _commonServerResponseHandler (const uint8_t operationIndex, IotMqttCallbackParam_t *const pPublishData, _provisioningServerResponseParser responseParser)
 A utility common for processing server responses of all Provisioning operation APIs. If there is an ongoing operation, the utility processes the incoming PUBLISH message and invokes the provided parser if the server response is received on the "accepted" topic. More...
 
static void _keysAndCertificateResponseReceivedCallback (void *param1, IotMqttCallbackParam_t *const pPublish)
 The common MQTT subscription callback for response topics of the CreateKeysAndCertificate service API.
 
static void _csrResponseReceivedCallback (void *param1, IotMqttCallbackParam_t *const pPublish)
 The common MQTT subscription callback for response topics of the CreateCertificateFromCsr service API.
 
static void _registerThingResponseReceivedCallback (void *param1, IotMqttCallbackParam_t *const pPublish)
 The common MQTT subscription callback for the response topics of the RegisterThing service API.
 
static void _setActiveOperation (uint8_t operationIndex, const _provisioningCallbackInfo_t *pUserCallback)
 Sets an operation object in the _activeOperation array to represent an active operation in progress. More...
 
static AwsIotProvisioningError_t _timedWaitForServerResponse (uint8_t operationIndex, uint32_t timeoutMs)
 Waits for server response within the provided timeout period, and returns the result of the wait operation. More...
 
static bool _isDataForRegisterThingRequestValid (const AwsIotProvisioningRegisterThingRequestInfo_t *pRequestData)
 Checks whether the data that is provided to send along with the provisioning device request is valid. More...
 
AwsIotProvisioningError_t AwsIotProvisioning_Init (uint32_t mqttTimeoutMs)
 One-time initialization function for the Provisioning library. More...
 
AwsIotProvisioningError_t AwsIotProvisioning_CreateKeysAndCertificate (IotMqttConnection_t provisioningConnection, uint32_t flags, uint32_t timeoutMs, const AwsIotProvisioningCreateKeysAndCertificateCallbackInfo_t *keysAndCertificateResponseCallback)
 Requests a new public-private key pair and certificate for the device from AWS IoT Core and invokes the provided user-callback with the response from the server. More...
 
AwsIotProvisioningError_t AwsIotProvisioning_CreateCertificateFromCsr (IotMqttConnection_t connection, IotMqttQos_t operationQos, const char *pCertificateSigningRequest, size_t csrLength, uint32_t timeoutMs, const AwsIotProvisioningCreateCertFromCsrCallbackInfo_t *pResponseCallback)
 Requests the AWS IoT Core service for a certificate by sending a Certificate-Signing Request, and invokes the provided user-defined response handler with the response it receives from the server. More...
 
AwsIotProvisioningError_t AwsIotProvisioning_RegisterThing (IotMqttConnection_t provisioningConnection, const AwsIotProvisioningRegisterThingRequestInfo_t *pRequestData, uint32_t timeoutMs, const AwsIotProvisioningRegisterThingCallbackInfo_t *pResponseCallback)
 Requests the AWS IoT Core service to register the device, and invokes the user-defined callback with the response it receives from the server. More...
 
void AwsIotProvisioning_Cleanup (void)
 One-time deinitialization function for the Provisioning library. More...
 
const char * AwsIotProvisioning_strerror (AwsIotProvisioningError_t status)
 Returns a string that describes an AwsIotProvisioningError_t. More...
 

Variables

const IotSerializerEncodeInterface_t * _pAwsIotProvisioningEncoder = NULL
 Pointer to the encoder utility that will be used for serialization of payload data in the library.
 
const IotSerializerDecodeInterface_t * _pAwsIotProvisioningDecoder = NULL
 Pointer to the decoder utility that will be used for de-serialization of payload data in the library.
 
static _provisioningOperation_t _activeOperation [3]
 An operation object instance for each of the 3 operations: CreateKeysAndCertificate, CreateCertificateFromCsr, RegisterThing.
 
static const uint8_t _createKeysAndCertOperationIndex = 0
 The index reference to the operation object in _activeOperation array for the CreateKeysAndCertificate operation.
 
static const uint8_t _createCertFromCsrOperationIndex = 1
 The index reference to the operation object in _activeOperation array for the CreateCertificateFromCsr operation.
 
static const uint8_t _registerThingOperationIndex = 2
 The index reference to the operation object in _activeOperation array for the RegisterThing operation.
 
uint32_t _AwsIotProvisioningMqttTimeoutMs = AWS_IOT_PROVISIONING_DEFAULT_MQTT_TIMEOUT_MS
 Timeout for MQTT operations that will be used for communicating with the fleet provisioning APIs of the AWS IoT Core server.
 
static bool _initCalled = false
 Tracks whether AwsIotProvisioning_Init has been called. More...
 

Detailed Description

Implements most user-facing functions of the Provisioning library.

Function Documentation

◆ _checkInit()

static bool _checkInit ( void  )
static

Check if the library is initialized.

Returns
true if AwsIotProvisioning_Init was called; false otherwise.

◆ _initializeOperationObject()

static AwsIotProvisioningError_t _initializeOperationObject ( uint8_t  operationIndex)
static

Initializes the operation object in _activeOperation array for the passed index reference.

Parameters
[in]operationIndexThe index reference to the operation object instance to initialize.
Returns
Returns AWS_IOT_PROVISIONING_SUCCESS if initialization is successful; otherwise AWS_IOT_PROVISIONING_INIT_FAILED.

◆ _cleanUpOperationObject()

static void _cleanUpOperationObject ( uint8_t  operationIndex)
static

Cleans up the operation object in _activeOperation array for the passed index reference.

Parameters
[in]operationIndexThe index reference to the operation object instance to clean-up.

◆ _commonServerResponseHandler()

static void _commonServerResponseHandler ( const uint8_t  operationIndex,
IotMqttCallbackParam_t *const  pPublishData,
_provisioningServerResponseParser  responseParser 
)
static

A utility common for processing server responses of all Provisioning operation APIs. If there is an ongoing operation, the utility processes the incoming PUBLISH message and invokes the provided parser if the server response is received on the "accepted" topic.

Parameters
[in]operationIndexThe index reference of the operation to the _activeOperation array.
[in]pPublishDataThe incoming PUBLISH message information from the server.
[in]responseParserThe functor to invoke for parsing a successful server response payload.

◆ _setActiveOperation()

static void _setActiveOperation ( uint8_t  operationIndex,
const _provisioningCallbackInfo_t pUserCallback 
)
static

Sets an operation object in the _activeOperation array to represent an active operation in progress.

Parameters
[in]operationIndexThe index reference to the ongoing operation object in the _activeOperation array.
[in]pUserCallbackThe user-provided callback information that will be copied to the active operation object.

◆ _timedWaitForServerResponse()

static AwsIotProvisioningError_t _timedWaitForServerResponse ( uint8_t  operationIndex,
uint32_t  timeoutMs 
)
static

Waits for server response within the provided timeout period, and returns the result of the wait operation.

Parameters
[in]operationIndexThe index reference to the ongoing operation object in the _activeOperation array.
[in]timeoutMsThe time period (in milliseconds) to wait for server response.
Returns
Returns AWS_IOT_PROVISIONING_SUCCESS if a server response is received within the timeoutMs period; otherwise returns AWS_IOT_PROVISIONING_TIMEOUT

◆ _isDataForRegisterThingRequestValid()

static bool _isDataForRegisterThingRequestValid ( const AwsIotProvisioningRegisterThingRequestInfo_t pRequestData)
static

Checks whether the data that is provided to send along with the provisioning device request is valid.

Parameters
pRequestDataThe data for the RegisterThing service API request whose validity will be checked.
Returns
Returns true if data is valid; false otherwise.

◆ AwsIotProvisioning_Init()

AwsIotProvisioningError_t AwsIotProvisioning_Init ( uint32_t  mqttTimeout)

One-time initialization function for the Provisioning library.

This function performs internal setup of the Provisioning library. It must be called once before calling any other Fleet Provisioning function.

Parameters
[in]mqttTimeoutThe amount of time (in milliseconds) that the Provisioning library will wait for MQTT operations. Optional; set this to 0 to use AWS_IOT_PROVISIONING_DEFAULT_MQTT_TIMEOUT_MS.
Returns
One of the following:
Warning
No thread-safety guarantees are provided for this function.
See also
AwsIotProvisioning_Cleanup

◆ AwsIotProvisioning_CreateKeysAndCertificate()

AwsIotProvisioningError_t AwsIotProvisioning_CreateKeysAndCertificate ( IotMqttConnection_t  connection,
uint32_t  flags,
uint32_t  timeoutMs,
const AwsIotProvisioningCreateKeysAndCertificateCallbackInfo_t pResponseCallback 
)

Requests a new public-private key pair and certificate for the device from AWS IoT Core and invokes the provided user-callback with the response from the server.

Note
It is advised to use a shared MQTT connection to AWS IoT Core across all API functions.
Warning
This function is NOT thread-safe. Concurrent calls to the library API functions can result in undefined behavior. Device provisioning with this library REQUIRES calling the API functions of this library sequentially.
Do not overwrite the existing Provisioning claim credentials with the new credentials provided by the server, at least until the device has been provisioned with a new certificate using the AwsIotProvisioning_RegisterThing function. It is also recommended to always retain the Provisioning claim credentials, if your product use-case supports re-provisioning of the device.
Note
We provide a security recommendation for protecting the identity, received from the server through this API function, for your IoT device. For the threat of an unauthorized reuse of the private key, that is received in the server response, in order to clone the device, an effective way to mitigate that is to audit, in the cloud, the use of each device private key. For example, if a device private key is reused, your cloud app (through Fleet Provisioning Hooks) could log an audit event for operator follow-up, and/or initiate a workflow for revoking the previous certificate(s) issued to that key.
Parameters
[in]connectionThe MQTT connection handle to the user AWS IoT account, which will be used for communicating with the server for creating new device credentials.
[in]flagsThe flags for configuring the behavior of the API. See the options available in the aws_iot_provisioning_types.h file.
[in]timeoutMsThe timeout (in milliseconds) for a response from the server. If there is a timeout, this function returns AWS_IOT_PROVISIONING_TIMEOUT.
[in]pResponseCallbackThe user-defined callback that will be invoked with the response from the server, whether new credentials for the device in case of success, OR error response in case of server rejection of the credentials generation request. The callback should be defined appropriately for storing the credentials provided by the server on the device.
Returns
This function will return AWS_IOT_PROVISIONING_SUCCESS upon success; otherwise, AWS_IOT_PROVISIONING_NOT_INITIALIZED, if the API is called without initializing the Provisioning library (i.e. with a prior call to AwsIotProvisioning_Init function.) AWS_IOT_PROVISIONING_BAD_PARAMETER, if one or more input parameters are invalid. AWS_IOT_PROVISIONING_NO_MEMORY, if there is insufficient memory for allocation in internal operations. AWS_IOT_PROVISIONING_MQTT_ERROR, for errors from the MQTT stack. AWS_IOT_PROVISIONING_TIMEOUT, if there is a timeout in waiting for the server response for the request to generate new credentials for the device. AWS_IOT_PROVISIONING_SERVER_REFUSED, if the server rejects the request for generating device credentials. AWS_IOT_PROVISIONING_BAD_RESPONSE, if the response from the server cannot be successfully parsed or comprehended. AWS_IOT_PROVISIONING_INTERNAL_FAILURE, if any there are operation failures internal to the library.

◆ AwsIotProvisioning_CreateCertificateFromCsr()

AwsIotProvisioningError_t AwsIotProvisioning_CreateCertificateFromCsr ( IotMqttConnection_t  connection,
IotMqttQos_t  operationQos,
const char *  pCertificateSigningRequest,
size_t  csrLength,
uint32_t  timeoutMs,
const AwsIotProvisioningCreateCertFromCsrCallbackInfo_t pResponseCallback 
)

Requests the AWS IoT Core service for a certificate by sending a Certificate-Signing Request, and invokes the provided user-defined response handler with the response it receives from the server.

Note
It is advised to use a shared MQTT connection to AWS IoT Core across all API functions.
Warning
This function is NOT thread-safe. Concurrent calls to the library API functions can result in undefined behavior. Device provisioning with this library REQUIRES calling the API functions of this library sequentially.
Note
Depending on the threat model of your IoT device, there are considerations for protecting its identity. One threat is theft of the private key that the application uses to sign the pCertificateSigningRequest input to this function. An effective way to mitigate that threat is to store all device private keys in a secure element. Another threat is the unauthorized reuse of the device private key, and/or of the contents of pCertificateSigningRequest, in order to clone the device. An effective way to mitigate that threat is to audit, in the cloud, the use of each device private key. For example, if a device private key is reused, your cloud app (through Fleet Provisioning Hooks) could log an audit event for operator follow-up, and/or initiate a workflow for revoking the previous certificate(s) issued to that key.
Warning
Do not overwrite the existing Provisioning claim credentials with the new credentials provided by the server, at least until the device has been provisioned with a new certificate using the AwsIotProvisioning_RegisterThing function. It is also recommended to always retain the Provisioning claim credentials, if your product use-case supports re-provisioning of the device.
Parameters
[in]connectionThe MQTT connection handle that will be used to communicate with AWS IoT Core for the Certificate-Signing Request.
[in]operationQosThe Quality of Service (QoS) level for the MQTT publish/subscribe communication with the server.
[in]pCertificateSigningRequestThe PEM encoded string for the Certificate-Signing Request.
[in]csrLengthThe length of the Certificate-Signing Request string.
[in]timeoutMsThe timeout (in milliseconds) for a response from the server. If there is a timeout, this function returns AWS_IOT_PROVISIONING_TIMEOUT.
[in]pResponseCallbackThe user-defined callback that will be invoked with the server's response to the CSR request. The server can respond either with the new certificate information (in case of request acceptance) OR with error (in case of request rejection).
Note
The callback is expected to store/retain the new certificate information from the server response, which will be required for registering the device with AwsIotProvisioning_RegisterThing function.
Returns
This function will return AWS_IOT_PROVISIONING_SUCCESS upon success; otherwise, AWS_IOT_PROVISIONING_NOT_INITIALIZED, if the API is called without initializing the Provisioning library (i.e. with a prior call to AwsIotProvisioning_Init function.) AWS_IOT_PROVISIONING_BAD_PARAMETER, if one or more input parameters are invalid. AWS_IOT_PROVISIONING_NO_MEMORY, if there is insufficient memory for allocation in internal operations. AWS_IOT_PROVISIONING_MQTT_ERROR, for errors from the MQTT stack. AWS_IOT_PROVISIONING_TIMEOUT, if there is a timeout in waiting for the server response for the request to generate new credentials for the device. AWS_IOT_PROVISIONING_SERVER_REFUSED, if the server rejects the request for generating device credentials. AWS_IOT_PROVISIONING_BAD_RESPONSE, if the response from the server cannot be successfully parsed or comprehended. AWS_IOT_PROVISIONING_INTERNAL_FAILURE, if any there are operation failures internal to the library.

◆ AwsIotProvisioning_RegisterThing()

AwsIotProvisioningError_t AwsIotProvisioning_RegisterThing ( IotMqttConnection_t  connection,
const AwsIotProvisioningRegisterThingRequestInfo_t pProvisioningDataInfo,
uint32_t  timeoutMs,
const AwsIotProvisioningRegisterThingCallbackInfo_t pResponseCallback 
)

Requests the AWS IoT Core service to register the device, and invokes the user-defined callback with the response it receives from the server.

For registering the device, the service is expected to provide the new certificate, and optionally set up the Thing, Attributes and other cloud settings based on the fleet provisioning template and device context information that are passed to the API.

Note
It is advised to use a shared MQTT connection to AWS IoT Core across all API functions.

Also, the AWS IoT account being connected to for registering the device SHOULD have a fleet provisioning template created, whose template name should be passed to this API for requesting device registration.

Warning
This function is NOT thread-safe. Concurrent calls to the library API functions can result in undefined behavior. Device provisioning with this library REQUIRES calling the API functions of this library sequentially.
Note
In case of success response, the server may send device-specific configuration data, which will be provided as a list of key-value pairs in the callback.
Parameters
[in]connectionThe MQTT connection handle to the user AWS IoT account that will be used for registering the device.
[in]pProvisioningDataInfoThe data (including the certificate) that needs to be sent to the server for registering the device.
[in]timeoutMsThe timeout (in milliseconds) for a response from the server. If there is a timeout, this function returns AWS_IOT_PROVISIONING_TIMEOUT.
[in]pResponseCallbackThe user-defined functor that will be called with the response received from the server, whether post-provisioning data in case of success OR error message in case of server rejection of registration request.
Returns
This function will return AWS_IOT_PROVISIONING_SUCCESS upon success; otherwise, AWS_IOT_PROVISIONING_NOT_INITIALIZED, if the API is called without initializing the Provisioning library (i.e. with a prior call to AwsIotProvisioning_Init function.) AWS_IOT_PROVISIONING_BAD_PARAMETER, if one or more input parameters are invalid. AWS_IOT_PROVISIONING_NO_MEMORY, if there is insufficient memory for allocation in internal operations. AWS_IOT_PROVISIONING_MQTT_ERROR, for errors from the MQTT stack. AWS_IOT_PROVISIONING_TIMEOUT, if there is a timeout in waiting for the server response for the request to register the device. AWS_IOT_PROVISIONING_SERVER_REFUSED, if the server rejects the request for register the device. AWS_IOT_PROVISIONING_BAD_RESPONSE, if the response from the server cannot be successfully parsed or comprehended. AWS_IOT_PROVISIONING_INTERNAL_FAILURE, if any there are operation failures internal to the library.

◆ AwsIotProvisioning_Cleanup()

void AwsIotProvisioning_Cleanup ( void  )

One-time deinitialization function for the Provisioning library.

This function frees resources taken in AwsIotProvisioning_Init. It should be called to clean up the Provisioning library. After this function returns, AwsIotProvisioning_Init must be called again before calling any other Provisioning function.

Warning
No thread-safety guarantees are provided for this function.
See also
AwsIotProvisioning_Init

◆ AwsIotProvisioning_strerror()

const char* AwsIotProvisioning_strerror ( AwsIotProvisioningError_t  status)

Returns a string that describes an AwsIotProvisioningError_t.

Like POSIX's strerror, this function returns a string describing a return code. In this case, the return code is a Provisioning library error code, status.

The string returned by this function MUST be treated as read-only: any attempt to modify its contents may result in a crash. Therefore, this function is limited to usage in logging.

Parameters
[in]statusThe status to describe.
Returns
A read-only string that describes status.
Warning
The string returned by this function must never be modified.

Variable Documentation

◆ _initCalled

bool _initCalled = false
static

Tracks whether AwsIotProvisioning_Init has been called.

API functions will fail if AwsIotProvisioning_Init was not called.