From f6a97a5fff1dd2c1c4dde99a1cc787859bb338c6 Mon Sep 17 00:00:00 2001 From: markrtuttle Date: Fri, 10 Apr 2020 16:05:26 -0400 Subject: [PATCH 01/41] Add back to CBMC Makefiles definitions for CI (#863) Co-authored-by: Mark R Tuttle --- cbmc/proofs/Makefile.common | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cbmc/proofs/Makefile.common b/cbmc/proofs/Makefile.common index f28773ed38..c0ee0c2758 100644 --- a/cbmc/proofs/Makefile.common +++ b/cbmc/proofs/Makefile.common @@ -155,7 +155,17 @@ veryclean: clean ################################################################ # Build configuration file to run cbmc under cbmc-batch in CI -CBMC_FLAGS = '$(call encode_options,$(CBMCFLAGS))' +JOBOS ?= ubuntu16 +PROOFMEM ?= 32000 + +define yaml_encode_options + "$(shell echo $(1) | sed 's/ ,/ /g' | sed 's/ /;/g')" +endef + +define encode_options + '=$(shell echo $(1) | sed 's/ ,/ /g' | sed 's/ /;/g')=' +endef + cbmc-batch.yaml: Makefile ../Makefile.common @echo "Building $@" @$(RM) $@ From e69bea62151c1ddfa712ab33c5e719db902ffb38 Mon Sep 17 00:00:00 2001 From: "Felipe R. Monteiro" Date: Tue, 14 Apr 2020 18:48:11 -0400 Subject: [PATCH 02/41] Avoid undefined behavior in IotMqtt_Connect (#864) * Avoid undefined behavior in IotMqtt_Connect Signed-off-by: Felipe R. Monteiro --- libraries/standard/mqtt/src/iot_mqtt_validate.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/standard/mqtt/src/iot_mqtt_validate.c b/libraries/standard/mqtt/src/iot_mqtt_validate.c index cbefb80ab2..79831631d1 100644 --- a/libraries/standard/mqtt/src/iot_mqtt_validate.c +++ b/libraries/standard/mqtt/src/iot_mqtt_validate.c @@ -600,7 +600,8 @@ bool _IotMqtt_ValidateConnect( const IotMqttConnectInfo_t * pConnectInfo ) /* If will info is provided, check that it is valid. */ if( pConnectInfo->pWillInfo != NULL ) { - status = _IotMqtt_ValidateLwtPublish( pConnectInfo->awsIotMqttMode, + status = ( pConnectInfo->pWillInfo->pPayload != NULL ) && + _IotMqtt_ValidateLwtPublish( pConnectInfo->awsIotMqttMode, pConnectInfo->pWillInfo ); } } From 9c078dfcc8c5c9cb64bb8dda7bb11ebe375531cc Mon Sep 17 00:00:00 2001 From: Carl Lundin <53273776+lundinc2@users.noreply.github.com> Date: Tue, 14 Apr 2020 16:41:09 -0700 Subject: [PATCH 03/41] Set mbedTLS version to 2.16.6 (#865) --- .gitmodules | 2 +- third_party/mbedtls/mbedtls | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 5c06a58594..9d89661479 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,4 +4,4 @@ [submodule "third_party/mbedtls/mbedtls"] path = third_party/mbedtls/mbedtls url = https://github.com/ARMmbed/mbedtls.git - branch = mbedtls-2.16.5 + branch = mbedtls-2.16.6 diff --git a/third_party/mbedtls/mbedtls b/third_party/mbedtls/mbedtls index 0fce215851..2a1d9332d5 160000 --- a/third_party/mbedtls/mbedtls +++ b/third_party/mbedtls/mbedtls @@ -1 +1 @@ -Subproject commit 0fce215851cc069c5b5def12fcc18725055fa6cf +Subproject commit 2a1d9332d55d1270084232e42df08fdb08129f1b From ed14e06eca984f18ab7df84a0699a2b77c00b9f2 Mon Sep 17 00:00:00 2001 From: "Felipe R. Monteiro" Date: Wed, 15 Apr 2020 17:24:08 -0400 Subject: [PATCH 04/41] Adds a proof for _IotMqtt_RemoveSubscriptionByTopicFilter function (#867) * Adds a proof harness for _IotMqtt_RemoveSubscriptionByTopicFilter function Signed-off-by: Felipe R. Monteiro --- ..._RemoveSubscriptionByTopicFilter_harness.c | 53 +++++++++++++++++++ .../Makefile | 40 ++++++++++++++ .../cbmc-batch.yaml | 2 + .../cbmc-viewer.json | 8 +++ 4 files changed, 103 insertions(+) create mode 100644 cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/IotMqtt_RemoveSubscriptionByTopicFilter_harness.c create mode 100644 cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/Makefile create mode 100644 cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/cbmc-batch.yaml create mode 100644 cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/cbmc-viewer.json diff --git a/cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/IotMqtt_RemoveSubscriptionByTopicFilter_harness.c b/cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/IotMqtt_RemoveSubscriptionByTopicFilter_harness.c new file mode 100644 index 0000000000..9d21097fb7 --- /dev/null +++ b/cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/IotMqtt_RemoveSubscriptionByTopicFilter_harness.c @@ -0,0 +1,53 @@ +/* + * IoT MQTT V2.1.0 + * Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file IotMqtt_RemoveSubscriptionByTopicFilter_harness.c + * @brief Implements the proof harness for _IotMqtt_RemoveSubscriptionByTopicFilter function. + */ + +#include "iot_config.h" +#include "private/iot_mqtt_internal.h" + +#include + +#include "mqtt_state.h" + +void harness() +{ + /* Assume a valid MQTT connection. */ + IotMqttConnection_t mqttConnection = allocate_IotMqttConnection( NULL ); + __CPROVER_assume( mqttConnection != NULL ); + ensure_IotMqttConnection_has_lists( mqttConnection ); + __CPROVER_assume( valid_IotMqttConnection( mqttConnection ) ); + + /* Assume unconstrained inputs. */ + size_t subscriptionCount; + __CPROVER_assume( subscriptionCount < SUBSCRIPTION_COUNT_MAX ); + IotMqttSubscription_t * pSubscriptionList = allocate_IotMqttSubscriptionArray( NULL, subscriptionCount ); + __CPROVER_assume( valid_IotMqttSubscriptionArray( pSubscriptionList, subscriptionCount ) ); + + /* Operation under verification. */ + _IotMqtt_RemoveSubscriptionByTopicFilter( mqttConnection, + pSubscriptionList, + subscriptionCount ); +} diff --git a/cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/Makefile b/cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/Makefile new file mode 100644 index 0000000000..7c9c7661d0 --- /dev/null +++ b/cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/Makefile @@ -0,0 +1,40 @@ +ENTRY=IotMqtt_RemoveSubscriptionByTopicFilter + +# We abstract all unreachable functions to improve coverage metrics +ABSTRACTIONS += --remove-function-body _packetMatch +ABSTRACTIONS += --remove-function-body _topicFilterMatch + +OBJS += $(ENTRY)_harness.goto +OBJS += $(MQTT)/cbmc/proofs/mqtt_state.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_subscription.goto + +# One more than actual number of subscriptions in a subscription list +SUBSCRIPTION_COUNT_MAX=4 +DEF += -DSUBSCRIPTION_COUNT_MAX=$(SUBSCRIPTION_COUNT_MAX) + +# One more than actual number of operations in an operation list +OPERATION_COUNT_MAX=4 +DEF += -DOPERATION_COUNT_MAX=$(OPERATION_COUNT_MAX) + +# One more than actual length of topics +TOPIC_LENGTH_MAX=10 +DEF += -DTOPIC_LENGTH_MAX=$(TOPIC_LENGTH_MAX) + +# Should be 2*SUBSCRIPTION_COUNT_MAX-1 +SUBSCRIPTION_LIST_MAX=7 +DEF += -DSUBSCRIPTION_LIST_MAX=$(SUBSCRIPTION_LIST_MAX) + +LOOP += allocate_IotMqttSubscriptionArray.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += allocate_IotMqttSubscriptionList.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += IotListDouble_FindFirstMatch.0:$(SUBSCRIPTION_LIST_MAX) +LOOP += IotListDouble_FindFirstMatch\$$link2.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += strncmp.0:$(TOPIC_LENGTH_MAX) +LOOP += valid_IotMqttOperationList.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += valid_IotMqttSubscriptionArray.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += valid_IotMqttSubscriptionList.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += _IotMqtt_RemoveSubscriptionByTopicFilter.0:$(SUBSCRIPTION_COUNT_MAX) + +UNWINDING += --unwind 1 +UNWINDING += --unwindset '$(shell echo $(LOOP) | sed 's/ /,/g')' + +include ../Makefile.common diff --git a/cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/cbmc-batch.yaml new file mode 100644 index 0000000000..7eeb12ad71 --- /dev/null +++ b/cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/cbmc-batch.yaml @@ -0,0 +1,2 @@ +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/cbmc-viewer.json b/cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/cbmc-viewer.json new file mode 100644 index 0000000000..f982298e80 --- /dev/null +++ b/cbmc/proofs/IotMqtt_RemoveSubscriptionByTopicFilter/cbmc-viewer.json @@ -0,0 +1,8 @@ +{ "expected-missing-functions": + [ + "IotMutex_Lock", + "IotMutex_Unlock" + ], + "proof-name": "IotMqtt_RemoveSubscriptionByTopicFilter", + "proof-root": "cbmc/proofs" +} From 897c3083a06de4c796d0221905a70d55b7a46942 Mon Sep 17 00:00:00 2001 From: markrtuttle Date: Wed, 15 Apr 2020 18:18:53 -0400 Subject: [PATCH 05/41] Add CBMC proof for MQTT Disconnect. (#868) * Update CBMC patches for Disconnect proof. * Update CBMC .gitignore for Disconnect proof. * Update CBMC mqtt_state.h model for Disconnect proof. * Add CBMC Disconnect proof. * Respond to comments on pull request. * Clean up CBMC Disconnect proof harness in response to PR comments Co-authored-by: Mark R Tuttle Co-authored-by: Felipe R. Monteiro --- ...et-CBMC-proofs-stub-out-RemoveAllMat.patch | 57 +++++-- ...ch-local-statics-after-nondet-static.patch | 28 ++++ cbmc/proofs/.gitignore | 1 + .../IotMqtt_Disconnect_harness.c | 149 ++++++++++++++++++ cbmc/proofs/IotMqtt_Disconnect/Makefile | 101 ++++++++++++ cbmc/proofs/IotMqtt_Disconnect/README.md | 143 +++++++++++++++++ .../proofs/IotMqtt_Disconnect/cbmc-batch.yaml | 2 + .../IotMqtt_Disconnect/cbmc-viewer.json | 28 ++++ cbmc/proofs/mqtt_state.h | 21 ++- 9 files changed, 514 insertions(+), 16 deletions(-) create mode 100644 cbmc/patches/0001-Patch-local-statics-after-nondet-static.patch create mode 100644 cbmc/proofs/.gitignore create mode 100644 cbmc/proofs/IotMqtt_Disconnect/IotMqtt_Disconnect_harness.c create mode 100644 cbmc/proofs/IotMqtt_Disconnect/Makefile create mode 100644 cbmc/proofs/IotMqtt_Disconnect/README.md create mode 100644 cbmc/proofs/IotMqtt_Disconnect/cbmc-batch.yaml create mode 100644 cbmc/proofs/IotMqtt_Disconnect/cbmc-viewer.json diff --git a/cbmc/patches/0001-Modify-MQTT-to-let-CBMC-proofs-stub-out-RemoveAllMat.patch b/cbmc/patches/0001-Modify-MQTT-to-let-CBMC-proofs-stub-out-RemoveAllMat.patch index 063f46309e..5db2188c7e 100644 --- a/cbmc/patches/0001-Modify-MQTT-to-let-CBMC-proofs-stub-out-RemoveAllMat.patch +++ b/cbmc/patches/0001-Modify-MQTT-to-let-CBMC-proofs-stub-out-RemoveAllMat.patch @@ -1,17 +1,46 @@ -From a1455991c02aa6d7db1d4333e2cdc5add392c105 Mon Sep 17 00:00:00 2001 -From: Mark R Tuttle -Date: Thu, 13 Feb 2020 17:39:51 +0000 -Subject: [PATCH] Modify MQTT to let CBMC proofs stub out RemoveAllMatches - ---- - libraries/standard/common/include/iot_linear_containers.h | 8 ++++++++ - 1 file changed, 8 insertions(+) - diff --git a/libraries/standard/common/include/iot_linear_containers.h b/libraries/standard/common/include/iot_linear_containers.h -index 689ea5e..ffb3469 100644 +index 689ea5e..09061f2 100644 --- a/libraries/standard/common/include/iot_linear_containers.h +++ b/libraries/standard/common/include/iot_linear_containers.h -@@ -719,6 +719,13 @@ static inline IotLink_t * IotListDouble_RemoveFirstMatch( const IotListDouble_t +@@ -489,6 +489,9 @@ static inline void IotListDouble_InsertSorted( IotListDouble_t * const pList, + * @param[in] pLink The element to remove. + */ + /* @[declare_linear_containers_list_double_remove] */ ++#ifdef CBMC_STUB_REMOVE ++void IotListDouble_Remove( IotLink_t * const pLink ); ++#else + static inline void IotListDouble_Remove( IotLink_t * const pLink ) + /* @[declare_linear_containers_list_double_remove] */ + { +@@ -503,6 +506,7 @@ static inline void IotListDouble_Remove( IotLink_t * const pLink ) + pLink->pPrevious = NULL; + pLink->pNext = NULL; + } ++#endif + + /** + * @brief Remove the element at the head of a doubly-linked list. +@@ -564,6 +568,11 @@ static inline IotLink_t * IotListDouble_RemoveTail( const IotListDouble_t * cons + * or its value is `0`. + */ + /* @[declare_linear_containers_list_double_removeall] */ ++#ifdef CBMC_STUB_REMOVEALL ++void IotListDouble_RemoveAll( const IotListDouble_t * const pList, ++ void ( *freeElement )( void * pData ), ++ size_t linkOffset ); ++#else + static inline void IotListDouble_RemoveAll( const IotListDouble_t * const pList, + void ( *freeElement )( void * pData ), + size_t linkOffset ) +@@ -593,6 +602,7 @@ static inline void IotListDouble_RemoveAll( const IotListDouble_t * const pList, + pCurrent = pNext; + } + } ++#endif + + /** + * @brief Search a doubly-linked list for the first matching element. +@@ -719,6 +734,13 @@ static inline IotLink_t * IotListDouble_RemoveFirstMatch( const IotListDouble_t * or its value is `0`. */ /* @[declare_linear_containers_list_double_removeallmatches] */ @@ -25,13 +54,11 @@ index 689ea5e..ffb3469 100644 static inline void IotListDouble_RemoveAllMatches( const IotListDouble_t * const pList, bool ( *isMatch )( const IotLink_t * const pOperationLink, void * pCompare ), void * pMatch, -@@ -754,6 +761,7 @@ static inline void IotListDouble_RemoveAllMatches( const IotListDouble_t * const +@@ -754,6 +776,7 @@ static inline void IotListDouble_RemoveAllMatches( const IotListDouble_t * const } } while( pMatchedElement != NULL ); } +#endif - + /** * @brief Create a new queue. --- -2.7.4 diff --git a/cbmc/patches/0001-Patch-local-statics-after-nondet-static.patch b/cbmc/patches/0001-Patch-local-statics-after-nondet-static.patch new file mode 100644 index 0000000000..33ba59ba57 --- /dev/null +++ b/cbmc/patches/0001-Patch-local-statics-after-nondet-static.patch @@ -0,0 +1,28 @@ +diff --git a/libraries/standard/mqtt/src/iot_mqtt_serialize.c b/libraries/standard/mqtt/src/iot_mqtt_serialize.c +index 016111e..285f03d 100644 +--- a/libraries/standard/mqtt/src/iot_mqtt_serialize.c ++++ b/libraries/standard/mqtt/src/iot_mqtt_serialize.c +@@ -948,6 +948,11 @@ IotMqttError_t _IotMqtt_SerializePingreq( uint8_t ** pPingreqPacket, + 0x00 + }; + ++#ifdef CBMC ++ __CPROVER_assume( pPingreq[0] == MQTT_PACKET_TYPE_PINGREQ ); ++ __CPROVER_assume( pPingreq[1] == 0x00 ); ++#endif ++ + /* Set the output parameters. */ + *pPingreqPacket = ( uint8_t * ) pPingreq; + *pPacketSize = MQTT_PACKET_PINGREQ_SIZE; +@@ -1009,6 +1014,11 @@ IotMqttError_t _IotMqtt_SerializeDisconnect( uint8_t ** pDisconnectPacket, + 0x00 + }; + ++#ifdef CBMC ++ __CPROVER_assume( pDisconnect[0] == MQTT_PACKET_TYPE_DISCONNECT ); ++ __CPROVER_assume( pDisconnect[1] == 0x00 ); ++#endif ++ + /* Set the output parameters. */ + *pDisconnectPacket = ( uint8_t * ) pDisconnect; + *pPacketSize = MQTT_PACKET_DISCONNECT_SIZE; diff --git a/cbmc/proofs/.gitignore b/cbmc/proofs/.gitignore new file mode 100644 index 0000000000..bee8a64b79 --- /dev/null +++ b/cbmc/proofs/.gitignore @@ -0,0 +1 @@ +__pycache__ diff --git a/cbmc/proofs/IotMqtt_Disconnect/IotMqtt_Disconnect_harness.c b/cbmc/proofs/IotMqtt_Disconnect/IotMqtt_Disconnect_harness.c new file mode 100644 index 0000000000..eca69b41cd --- /dev/null +++ b/cbmc/proofs/IotMqtt_Disconnect/IotMqtt_Disconnect_harness.c @@ -0,0 +1,149 @@ +/* + * IoT MQTT V2.1.0 + * Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file IotMqtt_Disconnect_harness.c + * @brief Implements the proof harness for IotMqtt_Disconnect function. + */ + +#include "iot_config.h" +#include "private/iot_mqtt_internal.h" + +#include + +#include "mqtt_state.h" + +/**************************************************************** + * Type definitions used by the IoT List Double remove functions + ****************************************************************/ + +typedef bool ( *MatchFunction_t )( const IotLink_t * const pOperationLink, + void * pCompare ); +typedef void ( *FreeElementFunction_t )( void * pData ); + +/**************************************************************** + * We assume the IoT List Double remove functions are memory safe. + * + * We abstract the list remove functions for performance reasons. Our + * abstraction replaces the original list with an unconstrained list. + * Our abstraction proves that none of the elements on the original + * list are accessed after the remove: We free all elements on the + * original list, so that any later access will be caught as a + * use-after-free error. + ****************************************************************/ + +void IotListDouble_RemoveAllMatches( const IotListDouble_t * const pList, + MatchFunction_t isMatch, + void * pMatch, + FreeElementFunction_t freeElement, + size_t linkOffset ) +{ + free_IotMqttSubscriptionList( pList ); + allocate_IotMqttSubscriptionList( pList, SUBSCRIPTION_COUNT_MAX - 1 ); +} + +/****************************************************************/ + +void IotListDouble_RemoveAll( const IotListDouble_t * const pList, + FreeElementFunction_t freeElement, + size_t linkOffset ) +{ + free_IotMqttSubscriptionList( pList ); + allocate_IotMqttSubscriptionList( pList, SUBSCRIPTION_COUNT_MAX - 1 ); +} + +/**************************************************************** + * We assume the IoT Semaphore operations are memory safe. + * + * We abstract the semaphores because we are doing sequential proof. + * But the semaphore API assures us that TimedWait called after Post will + * never fail. Our abstraction of the semaphores models this behavior. + * + * Our abstraction is safe because the Disconnect method invokes the + * semaphore methods on the semaphore associated with the Disconnect + * packet. The Disconnect method is the only code that accesses this + * semaphore. This justifies this simple semaphore model of checking + * for Post before TimedWait. + *****************************************************************/ + +static unsigned int flagSemaphore; + +/****************************************************************/ + +void IotSemaphore_Post( IotSemaphore_t * pSemaphore ) +{ + assert( pSemaphore != NULL ); + flagSemaphore++; +} + +/****************************************************************/ + +bool IotSemaphore_TimedWait( IotSemaphore_t * pSemaphore, + uint32_t timeoutMs ) +{ + assert( pSemaphore != NULL ); + + if( flagSemaphore > 0 ) + { + flagSemaphore--; + return true; + } + + return false; +} + +/**************************************************************** + * The proof harness + ****************************************************************/ + +void harness() +{ + /* initialize semaphore flag */ + flagSemaphore = 0; + + IotMqttConnection_t mqttConnection = allocate_IotMqttConnection( NULL ); + uint32_t flags; + + /* Proof assumptions. */ + __CPROVER_assume( mqttConnection != NULL ); + ensure_IotMqttConnection_has_lists( mqttConnection ); + __CPROVER_assume( valid_IotMqttConnection( mqttConnection ) ); + __CPROVER_assume( mqttConnection->references > 0 ); + __CPROVER_assume( + IMPLIES( + mqttConnection->pingreq.u.operation.periodic.ping.keepAliveMs != 0, + mqttConnection->references > 1 ) ); + __CPROVER_assume( mqttConnection->pNetworkInterface != NULL ); + __CPROVER_assume( + IS_STUBBED_NETWORKIF_SEND( mqttConnection->pNetworkInterface ) ); + __CPROVER_assume( + IS_STUBBED_NETWORKIF_DESTROY( mqttConnection->pNetworkInterface ) ); + __CPROVER_assume( + MAYBE_STUBBED_NETWORKIF_CLOSE( mqttConnection->pNetworkInterface ) ); + + IotMqtt_Disconnect( mqttConnection, flags ); +} + +/****************************************************************/ diff --git a/cbmc/proofs/IotMqtt_Disconnect/Makefile b/cbmc/proofs/IotMqtt_Disconnect/Makefile new file mode 100644 index 0000000000..c3cb284c36 --- /dev/null +++ b/cbmc/proofs/IotMqtt_Disconnect/Makefile @@ -0,0 +1,101 @@ +ENTRY=IotMqtt_Disconnect + +################################################################ +# Proof assumptions + +# Bound the number of subscriptions in a list (BOUND = MAX-1) +SUBSCRIPTION_COUNT_MAX=2 +DEF += -DSUBSCRIPTION_COUNT_MAX=$(SUBSCRIPTION_COUNT_MAX) + +# Bound the number of operations in a list (BOUND = MAX-1) +OPERATION_COUNT_MAX=2 +DEF += -DOPERATION_COUNT_MAX=$(OPERATION_COUNT_MAX) + +# Bound the length of subscription topics (BOUND = MAX-1) +TOPIC_LENGTH_MAX=8 +DEF += -DTOPIC_LENGTH_MAX=$(TOPIC_LENGTH_MAX) + +# A constant that should be 2*SUBSCRIPTION_COUNT_MAX-1 +SUBSCRIPTION_LIST_MAX=3 +DEF += -DSUBSCRIPTION_LIST_MAX=$(SUBSCRIPTION_LIST_MAX) + +################################################################ +# MQTT configuration constants modified for testing + +# this should be smaller than topic_length_max for coverage +# _validateSubscription coverage at line 385 +AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH=6 +DEF += -DAWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH=$(AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH) + +# this should be smaller than topic_length_max for coverage +# _IotMqtt_SubscriptionPacketSize coverage at line 702 +MQTT_MAX_REMAINING_LENGTH=6 +DEF += -DMQTT_MAX_REMAINING_LENGTH=$(MQTT_MAX_REMAINING_LENGTH) + +################################################################ +# Function omitted from the proof +# See the proof harness for + +ABSTRACTIONS += --remove-function-body IotLog_Generic + +# Functions removed as manually proven to be unreachable +ABSTRACTIONS += --remove-function-body _IotMqtt_PublishSetDup +ABSTRACTIONS += --remove-function-body _IotMqtt_RemoveSubscriptionByPacket +ABSTRACTIONS += --remove-function-body _IotMqtt_ScheduleOperation +ABSTRACTIONS += --remove-function-body _checkRetryLimit +ABSTRACTIONS += --remove-function-body _completePendingSend +ABSTRACTIONS += --remove-function-body _scheduleCallback +ABSTRACTIONS += --remove-function-body _scheduleNextRetry + +# Functions omitted for coverage +ABSTRACTIONS += --remove-function-body IotMqtt_ReceiveCallback +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceReceive +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeConnack +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializePuback +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeSuback +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeUnsuback +ABSTRACTIONS += --remove-function-body _matchEndWildcards +ABSTRACTIONS += --remove-function-body _matchWildcards +ABSTRACTIONS += --remove-function-body _mqttOperation_match +ABSTRACTIONS += --remove-function-body _mqttSubscription_setUnsubscribe +ABSTRACTIONS += --remove-function-body _packetMatch +ABSTRACTIONS += --remove-function-body _topicFilterMatch +ABSTRACTIONS += --remove-function-body _topicMatch + +################################################################ +# Stub out list remove functions. + +DEF += -DCBMC_STUB_REMOVEALL=1 +DEF += -DCBMC_STUB_REMOVEALLMATCHES=1 + +################################################################ + +OBJS += $(ENTRY)_harness.goto +OBJS += $(MQTT)/cbmc/proofs/mqtt_state.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_api.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_helper.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_operation.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_network.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_serialize.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_subscription.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_validate.goto + +# allow mqtt mallocs to fail for coverage +DEF += -include mqtt_state.h +DEF += -DIotMqtt_MallocMessage=malloc_can_fail +DEF += -DIotMqtt_MallocOperation=malloc_can_fail + +################################################################ +# Loop unwinding + +LOOP += valid_IotMqttOperationList.0:$(OPERATION_COUNT_MAX) +LOOP += valid_IotMqttSubscriptionList.0:$(SUBSCRIPTION_COUNT_MAX) + +UNWINDING += --unwind 1 + +UNWINDING += --unwindset '$(shell echo $(LOOP) | sed 's/ /,/g')' + +################################################################ + +include ../Makefile.common + diff --git a/cbmc/proofs/IotMqtt_Disconnect/README.md b/cbmc/proofs/IotMqtt_Disconnect/README.md new file mode 100644 index 0000000000..77d41aa3ea --- /dev/null +++ b/cbmc/proofs/IotMqtt_Disconnect/README.md @@ -0,0 +1,143 @@ +This is a memory safety proof for IotMqtt_Disconnect. + +This proof attains 86% code coverage. The following comments explain +why the uncovered lines of code are unreachable code. + +Unreachable code blocks within functions: + +* `_IotMqtt_CreateOperation` + + * Called from `IotMqtt_Disconnect` + * Called with pCallbackInfo == NULL + +* `_initializeOperation` + + * Called from `_IotMqtt_CreateOperation` <- `IotMqtt_Disconnect` + * waitable: Disconnect calls CreateOperation with waitable flag + +* `_IotMqtt_DestroyOperation` + + * Called from `IotMqtt_Wait` <- `IotMqtt_Disconnect` + * operation linked: Disconnected called CreateOperation that linked the operation + * operation mqttpacket defined: Checked by Disconnect assertion + * Called from `_IotMqtt_Notify` <- `_IotMqtt_ProcessSend` <- `IotMqtt_Disconnect` + * Called from dead code block + * Called from `_IotMqtt_ProcessSend` <- `IotMqtt_Disconnect` + * Called from dead code block + +* `IotMqtt_Wait` + + * Called from `IotMqtt_Disconnect` + * checkInit == true: checked by disconnect + * ValidateOperation == true: operation is nonnull and waitable + * connection->disconnected == false: Disconnect would set status to pending and not call wait. + +* `_destroyMqttConnection` + + * Called from `_IotMqtt_DecrementConnectionReferences` but only + when reference has been decremented to 0. + * The uncovered block is guarded by the conditional keepalive!=0. + * A valid connection has references > 0 and references > 1 + when keepalive!=0 (the ping request operation references + it). + * So a path with keepalive!=0 has references set to >=2, + Disconnect calls CreateOperation (for the Disconnect packet) + that increments references to >=3, and Disconnect calls Wait + that call Destroy Operation (for the Disconnect packet) that + decrements references to >=2. + * There are only remaining decrements: + Disconnect calls DecrementConnectionReferences and + CloseNetworkConnection. + * Both decrements are required to get reference to 0, + but the decrement in CloseNetworkConnection also sets keepalive=0. + * Thus it is impossible to invoke destroyMqttConnection (with + references=0) and execute this block of code (with + keepalive!=0). + +* `_IotMqtt_ProcessSend` + + * Called from `IotMqtt_Disconnect` + * retry limit == 0: checked in disconnect + * operation type == disconnect: In disconnect, processsend called => status == success => type set to disconnect + +* `_IotMqtt_DecrementOperationReferences` + + * Called from `IotMqtt_Wait` <- `IotMqtt_Disconnect` + * Called with canceljob == false + * Called from `_IotMqtt_Notify` <- `_IotMqtt_ProcessSend` <- `IotMqtt_Disconnect` + * Called with canceljob == false + * Called from `_completePendingSend` <- `_IotMqtt_ProcessSend` <- `IotMqtt_Disconnect` + * Called with canceljob == false + * Called from `_waitForOperation` <- `IotMqtt_Wait` <- `IotMqtt_Disconnect` + * Called from dead code + +* `_IotMqtt_ValidateOperation` + + * Called from `IotMqtt_Wait` <- `IotMqtt_Disconnect` + * operation is nonnull and waitable (checked by disconnect) + +* `_IotMqtt_Notify` + + * Called from `_IotMqtt_ProcessSend` <- `IotMqtt_Disconnect` + * operation type set to disconnect by disconnect + * operation created as waitable by disconnect + * status initialized to error and unchanged + +* `IotMqtt_OperationType` + + * Called only with `DISCONNECT` operation type + +* `_waitForOperation` + + * Called from `IotMqtt_Wait` <- `IotMqtt_Disconnect` + * packet type != subscribe + +* `IotMqtt_strerror` + + * Called only with `NETWORK_ERROR` and `SUCCESS` + +Unreachable functions + +* `_IotMqtt_ScheduleOperation` + + * Called from `_scheduleCallback` <- `_IotMqtt_Notify` <- `_IotMqtt_ProcessSend` <- `IotMqtt_Disconnect` + * Called from unreachable function + * Called from `_scheduleNextRetry` <- `_completePendingSend` <- `_IotMqtt_ProcessSend` <- `IotMqtt_Disconnect` + * Called from unreachable function + +* `_checkRetryLimit` + + * Called from `_IotMqtt_ProcessSend` <- `IotMqtt_Disconnect` + * Called from dead code block + +* `_completePendingSend` + + * Called from `_IotMqtt_ProcessSend` <- `IotMqtt_Disconnect` + * Called from dead code block + +* `_scheduleCallback` + + * Called from `_IotMqtt_Notify` <- `_IotMqtt_ProcessSend` <- `IotMqtt_Disconnect` + * Called from dead code block + +* `_scheduleNextRetry` + + * Called from `_completePendingSend` <- `_IotMqtt_ProcessSend` <- `IotMqtt_Disconnect` + * Called from unreachable function + +* `_IotMqtt_PublishSetDup` + + * Called from `_checkRetryLimit` <- `_IotMqtt_ProcessSend` <- `IotMqtt_Disconnect` + * Called from unreachable function + +* `_IotMqtt_RemoveSubscriptionByPacket` + + * Called from `_IotMqtt_Notify` <- `_IotMqtt_ProcessSend` <- `IotMqtt_Disconnect` + * Called from dead code block + * Called from `_waitForOperation` <- `IotMqtt_Wait` <- `IotMqtt_Disconnect` + * Called from dead code block + +Modeling code whose coverage is irrelevant: + +* `IotSemaphore_TimedWait` +* `_IotMqtt_NextPacketIdentifier` diff --git a/cbmc/proofs/IotMqtt_Disconnect/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_Disconnect/cbmc-batch.yaml new file mode 100644 index 0000000000..87089222ce --- /dev/null +++ b/cbmc/proofs/IotMqtt_Disconnect/cbmc-batch.yaml @@ -0,0 +1,2 @@ +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. \ No newline at end of file diff --git a/cbmc/proofs/IotMqtt_Disconnect/cbmc-viewer.json b/cbmc/proofs/IotMqtt_Disconnect/cbmc-viewer.json new file mode 100644 index 0000000000..70942fad73 --- /dev/null +++ b/cbmc/proofs/IotMqtt_Disconnect/cbmc-viewer.json @@ -0,0 +1,28 @@ +{ "expected-missing-functions": + [ + "IotClock_GetTimeMs", + "IotLog_Generic", + "IotMutex_Destroy", + "IotMutex_Lock", + "IotMutex_Unlock", + "IotSemaphore_Create", + "IotSemaphore_Destroy", + "IotSemaphore_Post", + "IotSemaphore_TimedWait", + "IotTaskPool_CreateJob", + "IotTaskPool_GetSystemTaskPool", + "IotTaskPool_ScheduleDeferred", + "IotTaskPool_TryCancel", + "IotTaskPool_strerror", + + "_IotMqtt_PublishSetDup", + "_IotMqtt_RemoveSubscriptionByPacket", + "_IotMqtt_ScheduleOperation", + "_checkRetryLimit", + "_completePendingSend", + "_scheduleCallback", + "_scheduleNextRetry" + ], + "proof-name": "IotMqtt_Disconnect", + "proof-root": "cbmc/proofs" +} diff --git a/cbmc/proofs/mqtt_state.h b/cbmc/proofs/mqtt_state.h index 237b8cb31b..28f8c49945 100644 --- a/cbmc/proofs/mqtt_state.h +++ b/cbmc/proofs/mqtt_state.h @@ -187,7 +187,11 @@ void *allocate_IotNetworkConnection(); * Instead, when a proof requires a stub, we make an explicit * assumption that the needed struct member is pointing to the correct * stub. The macro IS_STUBBED_NETWORKIF_XXX(IF) states that the - * method XXX in the interface IF points to the correct stub. + * method XXX in the interface IF points to the correct stub. A + * parallel set of macros MAYBE_STUBBED_NETWORKIF_XXX states the + * weaker claim that the method XXX may be NULL in the interface (and + * we expect the code to check for a NULL pointer before invoking the + * method). ****************************************************************/ IotNetworkInterface_t *allocate_IotNetworkInterface(); @@ -209,6 +213,21 @@ bool stubbed_IotNetworkInterface( const IotNetworkInterface_t *netif ); #define IS_STUBBED_NETWORKIF_DESTROY(netif) \ (netif->destroy == IotNetworkInterfaceDestroy) +#define MAYBE_STUBBED_NETWORKIF_CREATE(netif) \ + (netif->create == NULL || netif->create == IotNetworkInterfaceCreate) +#define MAYBE_STUBBED_NETWORKIF_CLOSE(netif) \ + (netif->close == NULL || netif->close == IotNetworkInterfaceClose) +#define MAYBE_STUBBED_NETWORKIF_SEND(netif) \ + (netif->send == NULL || netif->send == IotNetworkInterfaceSend) +#define MAYBE_STUBBED_NETWORKIF_RECEIVE(netif) \ + (netif->receive == NULL || netif->receive == IotNetworkInterfaceReceive) +#define MAYBE_STUBBED_NETWORKIF_SETRECEIVECALLBACK(netif) \ + (netif->setReceiveCallback == NULL || netif->setReceiveCallback == IotNetworkInterfaceReceiveCallback) +#define MAYBE_STUBBED_NETWORKIF_SETCLOSECALLBACK(netif) \ + (netif->setCloseCallback == NULL || netif->setCloseCallback == IotNetworkInterfaceCloseCallback) +#define MAYBE_STUBBED_NETWORKIF_DESTROY(netif) \ + (netif->destroy == NULL || netif->destroy == IotNetworkInterfaceDestroy) + IotNetworkError_t IotNetworkInterfaceCreate( void * pConnectionInfo, void * pCredentialInfo, void * pConnection ); From 4c750b6f3f5a103fa35549aac96a4ad7f2c7afce Mon Sep 17 00:00:00 2001 From: "Felipe R. Monteiro" Date: Wed, 15 Apr 2020 18:56:37 -0400 Subject: [PATCH 06/41] Adds a proof harness for the IotMqtt_Connect function (#871) * Adds a proof harness for the IotMqtt_Connect function Signed-off-by: Felipe R. Monteiro --- ...zePingreq-nondet-for-IotMqtt_Connect.patch | 31 ++++ ...ary-code-for-CBMC-Unsubscribe-proofs.patch | 13 -- ...s-from-internal-constant-definitions.patch | 63 ++++++++ ...d-thread-behavior-in-IotMqtt_Connect.patch | 34 +++++ .../IotMqtt_Connect/IotMqtt_Connect_harness.c | 126 ++++++++++++++++ cbmc/proofs/IotMqtt_Connect/Makefile | 128 ++++++++++++++++ cbmc/proofs/IotMqtt_Connect/README.md | 139 ++++++++++++++++++ cbmc/proofs/IotMqtt_Connect/cbmc-batch.yaml | 2 + cbmc/proofs/IotMqtt_Connect/cbmc-viewer.json | 23 +++ cbmc/proofs/mqtt_state.c | 95 +++++++----- 10 files changed, 604 insertions(+), 50 deletions(-) create mode 100644 cbmc/patches/0001-Make-_IotMqtt_SerializePingreq-nondet-for-IotMqtt_Connect.patch create mode 100644 cbmc/patches/0001-Replace-limits-from-internal-constant-definitions.patch create mode 100644 cbmc/patches/0001-Simulates-background-thread-behavior-in-IotMqtt_Connect.patch create mode 100644 cbmc/proofs/IotMqtt_Connect/IotMqtt_Connect_harness.c create mode 100644 cbmc/proofs/IotMqtt_Connect/Makefile create mode 100644 cbmc/proofs/IotMqtt_Connect/README.md create mode 100644 cbmc/proofs/IotMqtt_Connect/cbmc-batch.yaml create mode 100644 cbmc/proofs/IotMqtt_Connect/cbmc-viewer.json diff --git a/cbmc/patches/0001-Make-_IotMqtt_SerializePingreq-nondet-for-IotMqtt_Connect.patch b/cbmc/patches/0001-Make-_IotMqtt_SerializePingreq-nondet-for-IotMqtt_Connect.patch new file mode 100644 index 0000000000..4265745f91 --- /dev/null +++ b/cbmc/patches/0001-Make-_IotMqtt_SerializePingreq-nondet-for-IotMqtt_Connect.patch @@ -0,0 +1,31 @@ +From 67cbcc3041a3354fbafd4526d710b59804dd249e Mon Sep 17 00:00:00 2001 +From: "Felipe R. Monteiro" +Date: Wed, 15 Apr 2020 17:16:26 +0000 +Subject: [PATCH] Make _IotMqtt_SerializePingreq nondet for IotMqtt_Connect + +Signed-off-by: Felipe R. Monteiro +--- + libraries/standard/mqtt/src/iot_mqtt_serialize.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/libraries/standard/mqtt/src/iot_mqtt_serialize.c b/libraries/standard/mqtt/src/iot_mqtt_serialize.c +index 016111e..8a0d589 100644 +--- a/libraries/standard/mqtt/src/iot_mqtt_serialize.c ++++ b/libraries/standard/mqtt/src/iot_mqtt_serialize.c +@@ -955,7 +955,13 @@ IotMqttError_t _IotMqtt_SerializePingreq( uint8_t ** pPingreqPacket, + /* Print out the PINGREQ packet for debugging purposes. */ + IotLog_PrintBuffer( "MQTT PINGREQ packet:", pPingreq, MQTT_PACKET_PINGREQ_SIZE ); + ++#ifdef SERIALIZAPINGREQ_NONDET_RETURN ++ /* Return nondet status to improve coverage. */ ++ IotMqttError_t status; ++ return status; ++#else + return IOT_MQTT_SUCCESS; ++#endif + } + + /*-----------------------------------------------------------*/ +-- +2.17.1 + diff --git a/cbmc/patches/0001-Patch-MQTT-library-code-for-CBMC-Unsubscribe-proofs.patch b/cbmc/patches/0001-Patch-MQTT-library-code-for-CBMC-Unsubscribe-proofs.patch index e652d56664..c307068a13 100644 --- a/cbmc/patches/0001-Patch-MQTT-library-code-for-CBMC-Unsubscribe-proofs.patch +++ b/cbmc/patches/0001-Patch-MQTT-library-code-for-CBMC-Unsubscribe-proofs.patch @@ -68,19 +68,6 @@ index 5afce54..0e4d923 100644 if( pOperation != NULL ) { IotMqtt_FreeOperation( pOperation ); -diff --git a/libraries/standard/mqtt/src/private/iot_mqtt_internal.h b/libraries/standard/mqtt/src/private/iot_mqtt_internal.h -index ccfb802..d1b540c 100644 ---- a/libraries/standard/mqtt/src/private/iot_mqtt_internal.h -+++ b/libraries/standard/mqtt/src/private/iot_mqtt_internal.h -@@ -237,7 +237,9 @@ - * Used to validate parameters if when connecting to an AWS IoT MQTT server. - */ - #define AWS_IOT_MQTT_SERVER_MAX_CLIENTID_LENGTH ( ( uint16_t ) 128 ) /**< @brief Maximum length of client identifier accepted by AWS IoT. */ -+#ifndef AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH - #define AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH ( ( uint16_t ) 256 ) /**< @brief Maximum length of topic names or filters accepted by AWS IoT. */ -+#endif - #define AWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE ( ( size_t ) 8 ) /**< @brief Maximum number of topic filters in a single SUBSCRIBE packet. */ - #define AWS_IOT_MQTT_SERVER_MAX_PUBLISH_PAYLOAD_LENGTH ( ( size_t ) ( 131072 ) ) /**< @brief Maximum publish payload length accepted by AWS IoT. */ -- 2.7.4 diff --git a/cbmc/patches/0001-Replace-limits-from-internal-constant-definitions.patch b/cbmc/patches/0001-Replace-limits-from-internal-constant-definitions.patch new file mode 100644 index 0000000000..05da86db2b --- /dev/null +++ b/cbmc/patches/0001-Replace-limits-from-internal-constant-definitions.patch @@ -0,0 +1,63 @@ +From 1728071c2f234b6a5e9e0aaa5fda44958b1e799a Mon Sep 17 00:00:00 2001 +From: "Felipe R. Monteiro" +Date: Tue, 14 Apr 2020 00:04:57 +0000 +Subject: [PATCH] Replace limits from internal constant definitions + +Signed-off-by: Felipe R. Monteiro +--- + libraries/standard/mqtt/include/iot_mqtt_protocol.h | 4 ++++ + .../standard/mqtt/src/private/iot_mqtt_internal.h | 11 ++++++++++- + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/libraries/standard/mqtt/include/iot_mqtt_protocol.h b/libraries/standard/mqtt/include/iot_mqtt_protocol.h +index 0fedcea..7777ea2 100644 +--- a/libraries/standard/mqtt/include/iot_mqtt_protocol.h ++++ b/libraries/standard/mqtt/include/iot_mqtt_protocol.h +@@ -84,7 +84,9 @@ + * All strings in a CONNECT packet are constrained to 2-byte lengths, giving a + * maximum length smaller than the max "Remaining Length" constant above. + */ ++#ifndef MQTT_PACKET_CONNECT_MAX_SIZE + #define MQTT_PACKET_CONNECT_MAX_SIZE ( 327700UL ) ++#endif + + /** + * @brief The minimum remaining length for a QoS 0 PUBLISH. +diff --git a/libraries/standard/mqtt/src/private/iot_mqtt_internal.h b/libraries/standard/mqtt/src/private/iot_mqtt_internal.h +index ccfb802..4249a70 100644 +--- a/libraries/standard/mqtt/src/private/iot_mqtt_internal.h ++++ b/libraries/standard/mqtt/src/private/iot_mqtt_internal.h +@@ -223,10 +223,13 @@ + #define IOT_MQTT_RETRY_MS_CEILING ( 60000U ) + #endif + /** @endcond */ +- ++#ifndef MQTT_SERVER_MAX_CLIENTID_LENGTH + #define MQTT_SERVER_MAX_CLIENTID_LENGTH ( ( uint16_t ) 23 ) /**< @brief Optional maximum length of client identifier specified by MQTT 3.1.1. */ ++#endif + #define MQTT_SERVER_MAX_PUBLISH_PAYLOAD_LENGTH ( ( size_t ) ( 268435456 ) ) /**< @brief Maximum publish payload length supported by MQTT 3.1.1. */ ++#ifndef MQTT_SERVER_MAX_LWT_PAYLOAD_LENGTH + #define MQTT_SERVER_MAX_LWT_PAYLOAD_LENGTH ( ( size_t ) UINT16_MAX ) /**< @brief Maximum LWT payload length supported by MQTT 3.1.1. */ ++#endif + + /* + * Constants related to limits defined in AWS Service Limits. +@@ -236,9 +239,15 @@ + * + * Used to validate parameters if when connecting to an AWS IoT MQTT server. + */ ++#ifndef AWS_IOT_MQTT_SERVER_MAX_CLIENTID_LENGTH + #define AWS_IOT_MQTT_SERVER_MAX_CLIENTID_LENGTH ( ( uint16_t ) 128 ) /**< @brief Maximum length of client identifier accepted by AWS IoT. */ ++#endif ++#ifndef AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH + #define AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH ( ( uint16_t ) 256 ) /**< @brief Maximum length of topic names or filters accepted by AWS IoT. */ ++#endif ++#ifndef AWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE + #define AWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE ( ( size_t ) 8 ) /**< @brief Maximum number of topic filters in a single SUBSCRIBE packet. */ ++#endif + #define AWS_IOT_MQTT_SERVER_MAX_PUBLISH_PAYLOAD_LENGTH ( ( size_t ) ( 131072 ) ) /**< @brief Maximum publish payload length accepted by AWS IoT. */ + + /* +-- +2.17.1 + diff --git a/cbmc/patches/0001-Simulates-background-thread-behavior-in-IotMqtt_Connect.patch b/cbmc/patches/0001-Simulates-background-thread-behavior-in-IotMqtt_Connect.patch new file mode 100644 index 0000000000..08181853d8 --- /dev/null +++ b/cbmc/patches/0001-Simulates-background-thread-behavior-in-IotMqtt_Connect.patch @@ -0,0 +1,34 @@ +From 0b165aed126cda9132720d7d452fa1490a3c2a14 Mon Sep 17 00:00:00 2001 +From: "Felipe R. Monteiro" +Date: Wed, 15 Apr 2020 17:22:55 +0000 +Subject: [PATCH] Simulates background thread behavior in IotMqtt_Connect + +Signed-off-by: Felipe R. Monteiro +--- + libraries/standard/mqtt/src/iot_mqtt_api.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/libraries/standard/mqtt/src/iot_mqtt_api.c b/libraries/standard/mqtt/src/iot_mqtt_api.c +index 1e55cb5..fa8f634 100644 +--- a/libraries/standard/mqtt/src/iot_mqtt_api.c ++++ b/libraries/standard/mqtt/src/iot_mqtt_api.c +@@ -1005,6 +1005,16 @@ static IotMqttError_t _sendConnectRequest( _mqttOperation_t * pOperation, + /* Wait for the CONNECT operation to complete, i.e. wait for CONNACK. */ + status = IotMqtt_Wait( pOperation, timeoutMs ); + ++#ifdef BACKGROUND_THREAD_SIMULATION ++ /* There is a background thread that's part of the network and changes ++ * the status from IOT_MQTT_STATUS_PENDING to IOT_MQTT_SUCCESS. This ++ * code snippet simulates the thread behavior and improves coverage. */ ++ if(status == IOT_MQTT_STATUS_PENDING && nondet_bool()) ++ { ++ status = IOT_MQTT_SUCCESS; ++ } ++#endif ++ + return status; + } + +-- +2.17.1 + diff --git a/cbmc/proofs/IotMqtt_Connect/IotMqtt_Connect_harness.c b/cbmc/proofs/IotMqtt_Connect/IotMqtt_Connect_harness.c new file mode 100644 index 0000000000..823e7e8d54 --- /dev/null +++ b/cbmc/proofs/IotMqtt_Connect/IotMqtt_Connect_harness.c @@ -0,0 +1,126 @@ +/* + * IoT MQTT V2.1.0 + * Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file IotMqtt_Connect_harness.c + * @brief Implements the proof harness for IotMqtt_Connect function. + */ + +#include "iot_config.h" +#include "private/iot_mqtt_internal.h" +#include "iot_mqtt_protocol.h" + +#include +#include + +#include "mqtt_state.h" + +typedef bool ( * MatchFunction_t )( const IotLink_t * const pOperationLink, + void * pCompare ); + +typedef void ( * FreeElementFunction_t )( void * pData ); + +/** + * We constrain the return values of this function because it + * is checked by assertions in the MQTT code. + */ +IotTaskPoolError_t IotTaskPool_TryCancel( IotTaskPool_t taskPool, + IotTaskPoolJob_t job, + IotTaskPoolJobStatus_t * const pStatus ) +{ + assert( ( taskPool == NULL ) || ( job == NULL ) ); + return IOT_TASKPOOL_BAD_PARAMETER; +} + +/** + * We constrain the return values of these functions because + * they are checked by assertions in the MQTT code. + */ +IotTaskPoolError_t IotTaskPool_CreateJob( IotTaskPoolRoutine_t userCallback, + void * pUserContext, + IotTaskPoolJobStorage_t * const pJobStorage, + IotTaskPoolJob_t * const pJob ) +{ + assert( userCallback != NULL ); + assert( pJobStorage != NULL ); + assert( pJob != NULL ); + + /* _IotMqtt_ScheduleOperation asserts this. */ + return IOT_TASKPOOL_SUCCESS; +} + +/** + * We assume the list remove functions are memory safe. + * + * We abstract the list remove functions for performance reasons. Our + * abstraction replaces the original list with an unconstrained list. + * Our abstraction proves that none of the elements on the original + * list are accessed after the remove: We free all elements on the + * original list, so that any later access will be caught as a + * use-after-free error. + */ +void IotListDouble_RemoveAllMatches( const IotListDouble_t * const pList, + MatchFunction_t isMatch, + void * pMatch, + FreeElementFunction_t freeElement, + size_t linkOffset ) +{ + free_IotMqttSubscriptionList( pList ); + allocate_IotMqttSubscriptionList( pList, SUBSCRIPTION_COUNT_MAX - 1 ); +} + +void _IotMqtt_RemoveSubscriptionByTopicFilter( _mqttConnection_t * pMqttConnection, + const IotMqttSubscription_t * pSubscriptionList, + size_t subscriptionCount ) +{ + free_IotMqttSubscriptionList( &( pMqttConnection->subscriptionList ) ); + allocate_IotMqttSubscriptionList( &( pMqttConnection->subscriptionList ), subscriptionCount ); +} + +void harness() +{ + /* Assume a valid NetworkInfo_t. */ + IotMqttNetworkInfo_t * pNetworkInfo = allocate_IotMqttNetworkInfo( NULL ); + + __CPROVER_assume( IMPLIES( pNetworkInfo != NULL, + pNetworkInfo->pNetworkInterface != NULL && + IS_STUBBED_NETWORKIF_CREATE( pNetworkInfo->pNetworkInterface ) && + IS_STUBBED_NETWORKIF_SEND( pNetworkInfo->pNetworkInterface ) && + IS_STUBBED_NETWORKIF_CLOSE( pNetworkInfo->pNetworkInterface ) && + IS_STUBBED_NETWORKIF_DESTROY( pNetworkInfo->pNetworkInterface ) && + IS_STUBBED_NETWORKIF_SETRECEIVECALLBACK( pNetworkInfo->pNetworkInterface ) && + valid_IotMqttNetworkInfo( pNetworkInfo ) ) ); + + /* Assume a valid ConnectInfo_t. */ + IotMqttConnectInfo_t * pConnectInfo = allocate_IotMqttConnectInfo( NULL ); + __CPROVER_assume( IMPLIES( pConnectInfo != NULL, + valid_IotMqttConnectInfo( pConnectInfo ) ) ); + + /* Assume a unconstrained timeout. */ + uint32_t timeoutMs; + + /* Assume a valid MQTT connection. */ + IotMqttConnection_t pMqttConnection = allocate_IotMqttConnection( NULL ); + + /* Operation under verification. */ + IotMqttError_t status = IotMqtt_Connect( pNetworkInfo, pConnectInfo, timeoutMs, pMqttConnection ); +} diff --git a/cbmc/proofs/IotMqtt_Connect/Makefile b/cbmc/proofs/IotMqtt_Connect/Makefile new file mode 100644 index 0000000000..7ba6208f41 --- /dev/null +++ b/cbmc/proofs/IotMqtt_Connect/Makefile @@ -0,0 +1,128 @@ +ENTRY=IotMqtt_Connect + +# We abstract these functions because manual inspection demonstrates they are unreachable +ABSTRACTIONS += --remove-function-body _checkRetryLimit +ABSTRACTIONS += --remove-function-body _IotMqtt_RemoveSubscriptionByPacket +ABSTRACTIONS += --remove-function-body _scheduleCallback +ABSTRACTIONS += --remove-function-body _scheduleNextRetry + +# We abstract all unreachable functions to improve coverage metrics +ABSTRACTIONS += --remove-function-body _IotMqtt_NextPacketIdentifier +ABSTRACTIONS += --remove-function-body _IotMqtt_PublishSetDup +ABSTRACTIONS += --remove-function-body _IotMqtt_ScheduleOperation +ABSTRACTIONS += --remove-function-body _matchEndWildcards +ABSTRACTIONS += --remove-function-body _matchWildcards +ABSTRACTIONS += --remove-function-body _mqttOperation_match +ABSTRACTIONS += --remove-function-body _mqttSubscription_setUnsubscribe +ABSTRACTIONS += --remove-function-body _packetMatch +ABSTRACTIONS += --remove-function-body _topicFilterMatch +ABSTRACTIONS += --remove-function-body IotMutex_Create +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceCloseCallback +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceReceive +ABSTRACTIONS += --remove-function-body IotTaskPool_ScheduleDeferred +ABSTRACTIONS += --remove-function-body IotSemaphore_TimedWait + +OBJS += $(ENTRY)_harness.goto +OBJS += $(MQTT)/cbmc/proofs/mqtt_state.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_api.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_helper.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_operation.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_serialize.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_subscription.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_validate.goto + +################################################################ +# Proof assumptions + +# This should be smaller than CLIENT_IDENTIFIER_LENGTH_MAX for coverage +AWS_IOT_MQTT_SERVER_MAX_CLIENTID_LENGTH=6 +DEF += -DAWS_IOT_MQTT_SERVER_MAX_CLIENTID_LENGTH=$(AWS_IOT_MQTT_SERVER_MAX_CLIENTID_LENGTH) + +# This should be smaller than SUBSCRIPTION_COUNT_MAX for coverage +AWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE=1 +DEF += -DAWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE=$(AWS_IOT_MQTT_SERVER_MAX_TOPIC_FILTERS_PER_SUBSCRIBE) + +# This should be smaller than TOPIC_LENGTH_MAX for coverage +AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH=2 +DEF += -DAWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH=$(AWS_IOT_MQTT_SERVER_MAX_TOPIC_LENGTH) + +# One more than actual number of clientIdentifierLength +CLIENT_IDENTIFIER_LENGTH_MAX=8 +DEF += -DCLIENT_IDENTIFIER_LENGTH_MAX=$(CLIENT_IDENTIFIER_LENGTH_MAX) + +# This should be smaller than CLIENT_IDENTIFIER_LENGTH_MAX for coverage +MQTT_SERVER_MAX_CLIENTID_LENGTH=6 +DEF += -DMQTT_SERVER_MAX_CLIENTID_LENGTH=$(MQTT_SERVER_MAX_CLIENTID_LENGTH) + +# This should be smaller than PAYLOAD_LENGTH_MAX for coverage +MQTT_SERVER_MAX_LWT_PAYLOAD_LENGTH=2 +DEF += -DMQTT_SERVER_MAX_LWT_PAYLOAD_LENGTH=$(MQTT_SERVER_MAX_LWT_PAYLOAD_LENGTH) + +# One more than actual number of connectPacketSize +MQTT_PACKET_CONNECT_MAX_SIZE=50 +DEF += -DMQTT_PACKET_CONNECT_MAX_SIZE=$(MQTT_PACKET_CONNECT_MAX_SIZE) + +# One more than actual number of passwordLength +PASSWORD_LENGTH_MAX=3 +DEF += -DPASSWORD_LENGTH_MAX=$(PASSWORD_LENGTH_MAX) + +# One more than actual number of payloadLength +PAYLOAD_LENGTH_MAX=4 +DEF += -DPAYLOAD_LENGTH_MAX=$(PAYLOAD_LENGTH_MAX) + +# One more than actual number of subscriptions +SUBSCRIPTION_COUNT_MAX=3 +DEF += -DSUBSCRIPTION_COUNT_MAX=$(SUBSCRIPTION_COUNT_MAX) + +# Should be 2*SUBSCRIPTION_COUNT_MAX-1 +SUBSCRIPTION_LIST_MAX=3 +DEF += -DSUBSCRIPTION_LIST_MAX=$(SUBSCRIPTION_LIST_MAX) + +# One more than actual length of topics +TOPIC_LENGTH_MAX=4 +DEF += -DTOPIC_LENGTH_MAX=$(TOPIC_LENGTH_MAX) + +# One more than actual number of topicNameLength +TOPIC_NAME_LENGTH_MAX=8 +DEF += -DTOPIC_NAME_LENGTH_MAX=$(TOPIC_NAME_LENGTH_MAX) + +# One more than actual number of userNameLength +USER_NAME_LENGTH_MAX=3 +DEF += -DUSER_NAME_LENGTH_MAX=$(USER_NAME_LENGTH_MAX) + +# Enables CBMC stub for RemoveAllMatches function +DEF += -DCBMC_STUB_REMOVEALLMATCHES=1 + +# Enables _IotMqtt_SerializePingreq to return a nondet status +DEF += -DSERIALIZAPINGREQ_NONDET_RETURN=1 + +# Simulates background thread behavior in _sendConnectRequest +DEF += -DBACKGROUND_THREAD_SIMULATION=1 + +# Allow MQTT allocations to fail for coverage +DEF += -include mqtt_state.h +DEF += -DIotMqtt_MallocMessage=malloc_can_fail +DEF += -DIotMqtt_MallocOperation=malloc_can_fail +DEF += -DIotMqtt_MallocSubscription=malloc_can_fail +DEF += -DIotMqtt_MallocConnection=malloc_can_fail + +################################################################ + +LOOP += harness.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += allocate_IotMqttSubscriptionArray.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += valid_IotMqttSubscriptionArray.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += IotListDouble_FindFirstMatch.0:$(SUBSCRIPTION_LIST_MAX) +LOOP += IotListDouble_FindFirstMatch\$$link1.0:$(SUBSCRIPTION_LIST_MAX) +LOOP += IotListDouble_RemoveAllMatches.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += _IotMqtt_AddSubscriptions.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += _IotMqtt_AddSubscriptions.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += _IotMqtt_ValidateSubscriptionList.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += _encodeRemainingLength.0:$(TOPIC_LENGTH_MAX) +LOOP += strncmp.0:$(TOPIC_LENGTH_MAX) +LOOP += _validateSubscription.0:$(TOPIC_LENGTH_MAX) +LOOP += valid_IotMqttSubscriptionList.0:$(SUBSCRIPTION_COUNT_MAX) + +UNWINDING += --unwind 1 +UNWINDING += --unwindset '$(shell echo $(LOOP) | sed 's/ /,/g')' + +include ../Makefile.common diff --git a/cbmc/proofs/IotMqtt_Connect/README.md b/cbmc/proofs/IotMqtt_Connect/README.md new file mode 100644 index 0000000000..a61d40dae2 --- /dev/null +++ b/cbmc/proofs/IotMqtt_Connect/README.md @@ -0,0 +1,139 @@ +# Memory safety proof for IotMqtt_Connect + +This proof harness attains 92% code coverage. The following comments explain +why the uncovered lines of code are unreachable code. + +Some functions contain unreachable blocks of code: + +* `_IotMqtt_SerializeConnectCommon` + + * `_validatePublish` eliminates that possibility of `QoS == IOT_MQTT_QOS_2` + +* `IotListDouble_FindFirstMatch` + + * Always called with a nonnull isMatch parameter + +* `_topicMatch` + + * `_IotMqtt_AddSubscriptions` sets `pParam->exactMatchOnly == true`, + so `_topicFilterMatch` is never called + +* `_encodeUserNameAndMetrics` + + * At this point `pConnectInfo->userNameLength` is smaller + than `(UINT16_MAX - AWS_IOT_METRICS_USERNAME_LENGTH)` + +* `_validatePublish` + + * Always called with a nonnull pPublishInfo parameter + +* `_IotMqtt_DestroyOperation` + + * Notify calls `DestroyOperation` with a linked operation + +* `_IotMqtt_IncrementConnectionReferences` + + * `pMqttConnection->disconnected` is false + +* `_encodeRemainingLength` + + * `remainingLength` is smaller than 128 (higher sizes lead + to way higher verification time) + +* `_IotMqtt_DecrementOperationReferences` + + * `IotTaskPool_TryCancel` always return bad parameter, + because we do not create a TaskPool job. + +* `_initializeOperation` + + * The operation is always waitable + +* `_IotMqtt_CreateOperation` + + * `pMqttConnection->disconnected` is true; therefore, + `_IotMqtt_IncrementConnectionReferences` always return false + +* `_completePendingSend` + + * `pOperation->u.operation.periodic.retry.limit` always 0 + +* `_IotMqtt_ProcessSend` + + * `pOperation->u.operation.periodic.retry.limit` always 0 + * `pOperation->u.operation.type != IOT_MQTT_DISCONNECT` + * Operation is always waitable + * `_completePendingSend` always return `destroyOperation == false` + +* `IotMqtt_Wait` + + * operation is always initialized at this point + * all parameters are valid + * `pMqttConnection->disconnected == false` + +* `_IotMqtt_DecrementConnectionReferences` + + * `pMqttConnection->references` is always different than zero, so the + connection won't be destroyed + * `destroyConnection == false` -> `pMqttConnection->references always != 0` + +* `_waitForOperation` + + * `operation->u.operation.type != IOT_MQTT_SUBSCRIBE` + +* `IotMqtt_strerror` + + * Never returns the following messages: `IOT_MQTT_SUCCESS`, + `IOT_MQTT_INIT_FAILED`, `IOT_MQTT_BAD_RESPONSE`, `IOT_MQTT_SERVER_REFUSED`, + `IOT_MQTT_RETRY_NO_RESPONSE`, and `default` + +* `_validateListSize` + + * Always called with a nonnull list parameter + * List size different than zero + +* `_IotMqtt_ValidateOperation` + + * Always called with a nonnull operation parameter + * Operation is waitable + +* `_IotMqtt_RemainingLengthEncodedSize` + + * If length is too big, proof takes more than an hour to complete, + so we consider small bounds here (i.e. `length < 128U`) + +* `_IotMqtt_Notify` + + * `pOperation->u.operation.type != IOT_MQTT_SUBSCRIBE` + * Operation is waitable + * At this point, `status == IOT_MQTT_SCHEDULING_ERROR` + * `_IotMqtt_DecrementOperationReferences` always returns false and + the operation is not destroyed + +* `IotMqtt_OperationType` + + * Always returns `IOT_MQTT_CONNECT` + + +Some functions are simply unreachable: + +* `_IotMqtt_RemoveSubscriptionByPacket` + + * Unreachable: Only function call in from an unreachable block of + `_IotMqtt_Notify` + +* `_checkRetryLimit` + + * Unreachable: Only function call is in an unreachable block of code + in `ProcessSend` + +* `_scheduleCallback` + + * Unreachable: Only function call in from an unreachable block of + `_IotMqtt_Notify` + +* `_scheduleNextRetry` + + * Unreachable: Only function call is in an unreachable block of code + in `completePendingSend` + diff --git a/cbmc/proofs/IotMqtt_Connect/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_Connect/cbmc-batch.yaml new file mode 100644 index 0000000000..7eeb12ad71 --- /dev/null +++ b/cbmc/proofs/IotMqtt_Connect/cbmc-batch.yaml @@ -0,0 +1,2 @@ +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_Connect/cbmc-viewer.json b/cbmc/proofs/IotMqtt_Connect/cbmc-viewer.json new file mode 100644 index 0000000000..9235704822 --- /dev/null +++ b/cbmc/proofs/IotMqtt_Connect/cbmc-viewer.json @@ -0,0 +1,23 @@ +{ "expected-missing-functions": + [ + "IotClock_GetTimeMs", + "IotLog_Generic", + "IotMutex_Create", + "IotMutex_Destroy", + "IotMutex_Lock", + "IotMutex_Unlock", + "IotSemaphore_Create", + "IotSemaphore_Destroy", + "IotSemaphore_Post", + "IotSemaphore_TimedWait", + "IotTaskPool_GetSystemTaskPool", + "IotTaskPool_ScheduleDeferred", + + "_IotMqtt_RemoveSubscriptionByPacket", + "_checkRetryLimit", + "_scheduleCallback", + "_scheduleNextRetry" + ], + "proof-name": "IotMqtt_Connect", + "proof-root": "cbmc/proofs" +} diff --git a/cbmc/proofs/mqtt_state.c b/cbmc/proofs/mqtt_state.c index 83f655ba28..b105021a3c 100644 --- a/cbmc/proofs/mqtt_state.c +++ b/cbmc/proofs/mqtt_state.c @@ -285,18 +285,51 @@ bool valid_IotMqttNetworkInfo( const IotMqttNetworkInfo_t *pInfo ) * IotMqttConnectInfo ****************************************************************/ +void bound_IotMqttConnectInfo( IotMqttConnectInfo_t *pInfo ) +{ +#ifdef SUBSCRIPTION_COUNT_MAX + __CPROVER_assume( pInfo->previousSubscriptionCount < SUBSCRIPTION_COUNT_MAX ); +#endif + +#ifdef CLIENT_IDENTIFIER_LENGTH_MAX + __CPROVER_assume( pInfo->clientIdentifierLength < CLIENT_IDENTIFIER_LENGTH_MAX && + VALID_CBMC_SIZE( pInfo->clientIdentifierLength ) ); +#else + __CPROVER_assume( pInfo->clientIdentifierLength <= UINT16_MAX ); +#endif + +#ifdef USER_NAME_LENGTH_MAX + __CPROVER_assume( pInfo->userNameLength < USER_NAME_LENGTH_MAX && + VALID_CBMC_SIZE( pInfo->userNameLength ) ); +#else + __CPROVER_assume( pInfo->userNameLength <= UINT16_MAX ); +#endif + +#ifdef PASSWORD_LENGTH_MAX + __CPROVER_assume( pInfo->passwordLength < PASSWORD_LENGTH_MAX && + VALID_CBMC_SIZE( pInfo->passwordLength ) ); +#else + __CPROVER_assume( pInfo->passwordLength <= UINT16_MAX ); +#endif +} + IotMqttConnectInfo_t *allocate_IotMqttConnectInfo( IotMqttConnectInfo_t *pInfo ) { if ( pInfo == NULL ) pInfo = malloc_can_fail( sizeof( *pInfo ) ); if ( pInfo == NULL ) return NULL; + bound_IotMqttConnectInfo( pInfo ); + pInfo->pPreviousSubscriptions = allocate_IotMqttSubscriptionArray( NULL, pInfo->previousSubscriptionCount ); + pInfo->pWillInfo = allocate_IotMqttPublishInfo( NULL ); pInfo->pClientIdentifier = malloc_can_fail( pInfo->clientIdentifierLength ); pInfo->pUserName = malloc_can_fail( pInfo->userNameLength ); pInfo->pPassword = malloc_can_fail( pInfo->passwordLength ); + + return pInfo; } bool valid_IotMqttConnectInfo( const IotMqttConnectInfo_t *pInfo ) @@ -304,22 +337,12 @@ bool valid_IotMqttConnectInfo( const IotMqttConnectInfo_t *pInfo ) return pInfo != NULL && - VALID_STRING( pInfo->pClientIdentifier, pInfo->clientIdentifierLength ) && - VALID_CBMC_SIZE( pInfo->clientIdentifierLength ) && - - VALID_STRING( pInfo->pUserName, pInfo->userNameLength ) && - VALID_CBMC_SIZE( pInfo->userNameLength ) && - - VALID_STRING( pInfo->pPassword, pInfo->passwordLength ) && - VALID_CBMC_SIZE( pInfo->passwordLength ) && - - // MAX is one greater than the maximum length - pInfo->previousSubscriptionCount < SUBSCRIPTION_COUNT_MAX && + valid_IotMqttPublishInfo( pInfo->pWillInfo ) && IFF( pInfo->pPreviousSubscriptions == NULL, - pInfo->previousSubscriptionCount == 0 ) && - valid_IotMqttSubscriptionArray( pInfo->pPreviousSubscriptions, - pInfo->previousSubscriptionCount ); + pInfo->previousSubscriptionCount == 0 ) && + valid_IotMqttSubscriptionArray( pInfo->pPreviousSubscriptions, + pInfo->previousSubscriptionCount ); } /**************************************************************** @@ -545,14 +568,31 @@ void free_IotMqttSubscriptionList( IotListDouble_t *pSub ) * IotMqttPublishInfo ****************************************************************/ +void bound_IotMqttPublishInfo( IotMqttPublishInfo_t *pInfo ) +{ + #ifdef TOPIC_NAME_LENGTH_MAX + __CPROVER_assume( pInfo->topicNameLength < TOPIC_NAME_LENGTH_MAX && + VALID_CBMC_SIZE( pInfo->topicNameLength ) ); + #else + __CPROVER_assume( pInfo->topicNameLength <= UINT16_MAX ); + #endif + + #ifdef PAYLOAD_LENGTH_MAX + __CPROVER_assume( pInfo->payloadLength < PAYLOAD_LENGTH_MAX && + VALID_CBMC_SIZE( pInfo->payloadLength ) ); + #else + __CPROVER_assume( pInfo->payloadLength <= UINT16_MAX ); + #endif +} + IotMqttPublishInfo_t *allocate_IotMqttPublishInfo( IotMqttPublishInfo_t *pInfo ) { if ( pInfo == NULL ) pInfo = malloc_can_fail( sizeof( *pInfo ) ); if ( pInfo == NULL ) return NULL; + bound_IotMqttPublishInfo( pInfo ); + pInfo->pTopicName = malloc_can_fail( pInfo->topicNameLength ); - // assumption here is checked below in valid_ - __CPROVER_assume( VALID_CBMC_SIZE( pInfo->payloadLength ) ); pInfo->pPayload = malloc_can_fail( pInfo->payloadLength ); return pInfo; } @@ -560,28 +600,9 @@ IotMqttPublishInfo_t *allocate_IotMqttPublishInfo( IotMqttPublishInfo_t *pInfo ) bool valid_IotMqttPublishInfo( const IotMqttPublishInfo_t *pInfo ) { return - pInfo && - + pInfo != NULL && VALID_QOS(pInfo->qos) && - - VALID_STRING( pInfo->pTopicName, pInfo->topicNameLength ) && - VALID_CBMC_SIZE( pInfo->topicNameLength ) && - pInfo->pTopicName != NULL && - - VALID_STRING( pInfo->pPayload, pInfo->payloadLength ) && - VALID_CBMC_SIZE( pInfo->payloadLength ) && -#ifdef PAYLOAD_LENGTH_MAX - // Some proofs iterate over it - pInfo->payloadLength < PAYLOAD_LENGTH_MAX && -#endif - - pInfo->retryMs <= IOT_MQTT_RETRY_MS_CEILING && - pInfo->retryMs > 0 && - - // TODO: experiment with removing these assumptions - // topicNameLength is a unint16 - pInfo->topicNameLength <= UINT16_MAX && - pInfo->payloadLength > 0; + pInfo->retryMs <= IOT_MQTT_RETRY_MS_CEILING; } /**************************************************************** From 6cfd10c8f5df9c0f3e9f94fb848cc43d82c04c92 Mon Sep 17 00:00:00 2001 From: "Felipe R. Monteiro" Date: Thu, 16 Apr 2020 17:12:57 -0400 Subject: [PATCH 07/41] Adds a proof harness for _IotMqtt_Notify function (#875) * Adds a proof harness for _IotMqtt_Notify function Signed-off-by: Felipe R. Monteiro --- cbmc/proofs/IotMqtt_Notify/Makefile | 38 ++++++ .../IotMqtt_Notify/_IotMqtt_Notify_harness.c | 121 ++++++++++++++++++ cbmc/proofs/IotMqtt_Notify/cbmc-batch.yaml | 2 + cbmc/proofs/IotMqtt_Notify/cbmc-viewer.json | 14 ++ cbmc/proofs/mqtt_state.c | 19 ++- 5 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 cbmc/proofs/IotMqtt_Notify/Makefile create mode 100644 cbmc/proofs/IotMqtt_Notify/_IotMqtt_Notify_harness.c create mode 100644 cbmc/proofs/IotMqtt_Notify/cbmc-batch.yaml create mode 100644 cbmc/proofs/IotMqtt_Notify/cbmc-viewer.json diff --git a/cbmc/proofs/IotMqtt_Notify/Makefile b/cbmc/proofs/IotMqtt_Notify/Makefile new file mode 100644 index 0000000000..f44f3aa79c --- /dev/null +++ b/cbmc/proofs/IotMqtt_Notify/Makefile @@ -0,0 +1,38 @@ +ENTRY=_IotMqtt_Notify + +# We abstract all unreachable functions to improve coverage metrics +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceClose + +OBJS += $(ENTRY)_harness.goto +OBJS += $(MQTT)/cbmc/proofs/mqtt_state.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_api.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_operation.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_serialize.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_subscription.goto + +# One more than actual number of subscriptions +SUBSCRIPTION_COUNT_MAX=4 +DEF += -DSUBSCRIPTION_COUNT_MAX=$(SUBSCRIPTION_COUNT_MAX) + +# One more than actual number of operations +OPERATION_COUNT_MAX=4 +DEF += -DOPERATION_COUNT_MAX=$(OPERATION_COUNT_MAX) + +# One more than actual length of topics +TOPIC_LENGTH_MAX=258 +DEF += -DTOPIC_LENGTH_MAX=$(TOPIC_LENGTH_MAX) + +# Enables CBMC stub for RemoveAllMatches function +DEF += -DCBMC_STUB_REMOVEALLMATCHES=1 + +LOOP += _matchWildcards.0:$(TOPIC_LENGTH_MAX) +LOOP += _topicFilterMatch.0:$(TOPIC_LENGTH_MAX) +LOOP += IotListDouble_RemoveAllMatches.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += IotListDouble_RemoveAllMatches$$link2.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += valid_IotMqttOperationList.0:$(OPERATION_COUNT_MAX) +LOOP += valid_IotMqttSubscriptionList.0:$(SUBSCRIPTION_COUNT_MAX) + +UNWINDING += --unwind 1 +UNWINDING += --unwindset '$(shell echo $(LOOP) | sed 's/ /,/g')' + +include ../Makefile.common diff --git a/cbmc/proofs/IotMqtt_Notify/_IotMqtt_Notify_harness.c b/cbmc/proofs/IotMqtt_Notify/_IotMqtt_Notify_harness.c new file mode 100644 index 0000000000..dac09e4e3c --- /dev/null +++ b/cbmc/proofs/IotMqtt_Notify/_IotMqtt_Notify_harness.c @@ -0,0 +1,121 @@ +/* + * IoT MQTT V2.1.0 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file IotMqtt_Notify_harness.c + * @brief Implements the proof harness for _IotMqtt_Notify function. + */ + +#include "iot_config.h" +#include "private/iot_mqtt_internal.h" +#include "platform/iot_threads.h" + +#include +#include + +#include "mqtt_state.h" + +typedef bool ( * MatchFunction_t )( const IotLink_t * const pOperationLink, + void * pCompare ); + +typedef void ( *FreeElementFunction_t )( void * pData ); + +/** + * We constrain the return values of these functions because + * they are checked by assertions in the MQTT code. + */ +IotTaskPoolError_t IotTaskPool_CreateJob( IotTaskPoolRoutine_t userCallback, + void * pUserContext, + IotTaskPoolJobStorage_t * const pJobStorage, + IotTaskPoolJob_t * const pJob ) +{ + assert( userCallback != NULL ); + assert( pJobStorage != NULL ); + assert( pJob != NULL ); + + /* _IotMqtt_ScheduleOperation asserts this. */ + return IOT_TASKPOOL_SUCCESS; +} + +IotTaskPoolError_t IotTaskPool_ScheduleDeferred( IotTaskPool_t taskPool, + IotTaskPoolJob_t job, + uint32_t timeMs ) +{ + IotTaskPoolError_t error; + + /* _IotMqtt_ScheduleOperation asserts this. */ + __CPROVER_assume( error != IOT_TASKPOOL_BAD_PARAMETER && + error != IOT_TASKPOOL_ILLEGAL_OPERATION ); + return error; +} + +/** + * We assume the list remove functions are memory safe. + * + * We abstract the list remove functions for performance reasons. Our + * abstraction replaces the original list with an unconstrained list. + * Our abstraction proves that none of the elements on the original + * list are accessed after the remove: we free all elements on the + * original list, so that any later access will be caught as a + * use-after-free error. + */ +void IotListDouble_RemoveAllMatches( const IotListDouble_t * const pList, + MatchFunction_t isMatch, + void * pMatch, + FreeElementFunction_t freeElement, + size_t linkOffset ) +{ + free_IotMqttSubscriptionList( pList ); + allocate_IotMqttSubscriptionList( pList, SUBSCRIPTION_COUNT_MAX - 1 ); +} + +void harness() +{ + /* Assume a valid MQTT connection. */ + IotMqttConnection_t pMqttConnection = allocate_IotMqttConnection( NULL ); + __CPROVER_assume( pMqttConnection != NULL ); + __CPROVER_assume( pMqttConnection->pNetworkInterface != NULL ); + __CPROVER_assume( IS_STUBBED_NETWORKIF_SEND( pMqttConnection->pNetworkInterface ) ); + __CPROVER_assume( IS_STUBBED_NETWORKIF_DESTROY( pMqttConnection->pNetworkInterface ) ); + ensure_IotMqttConnection_has_lists( pMqttConnection ); + __CPROVER_assume( valid_IotMqttConnection( pMqttConnection ) ); + /* If there are no operations waiting on this connection, then there is nothing + * to notify, so assume references is positive. */ + __CPROVER_assume( pMqttConnection->references > 0 ); + + /* Assume unconstrained operation. */ + IotMqttOperation_t pOperation = allocate_IotMqttOperation( NULL, pMqttConnection ); + __CPROVER_assume( valid_IotMqttOperation( pOperation ) ); + /* Inbound packets are either an inbound publish or an inbound response + * (a ping response or an acknowledgement). The purpose of _IotMqtt_Notify + * is to alert any task waiting on an inbound response. _IotMqtt_Notify is + * never invoked on an inbound publish, so assume incomingPublish is false. */ + __CPROVER_assume( pOperation->incomingPublish == false ); + IotListDouble_Create( &( pOperation->link )); + if ( nondet_bool() ) + { + IotListDouble_InsertHead( &( pMqttConnection->pendingProcessing ), &( pOperation->link )); + } + + /* Function under verification. */ + _IotMqtt_Notify( pOperation ); +} diff --git a/cbmc/proofs/IotMqtt_Notify/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_Notify/cbmc-batch.yaml new file mode 100644 index 0000000000..7eeb12ad71 --- /dev/null +++ b/cbmc/proofs/IotMqtt_Notify/cbmc-batch.yaml @@ -0,0 +1,2 @@ +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_Notify/cbmc-viewer.json b/cbmc/proofs/IotMqtt_Notify/cbmc-viewer.json new file mode 100644 index 0000000000..78c178ef93 --- /dev/null +++ b/cbmc/proofs/IotMqtt_Notify/cbmc-viewer.json @@ -0,0 +1,14 @@ +{ "expected-missing-functions": + [ + "IotLog_Generic", + "IotMutex_Destroy", + "IotMutex_Lock", + "IotMutex_Unlock", + "IotSemaphore_Destroy", + "IotSemaphore_Post", + "IotTaskPool_GetSystemTaskPool", + "IotTaskPool_strerror" + ], + "proof-name": "_IotMqtt_Notify", + "proof-root": "cbmc/proofs" +} diff --git a/cbmc/proofs/mqtt_state.c b/cbmc/proofs/mqtt_state.c index b105021a3c..881c757e88 100644 --- a/cbmc/proofs/mqtt_state.c +++ b/cbmc/proofs/mqtt_state.c @@ -110,12 +110,19 @@ bool valid_IotMqttOperation( const IotMqttOperation_t pOp ) bool waitable = ( pOp->u.operation.flags & IOT_MQTT_FLAG_WAITABLE ) == IOT_MQTT_FLAG_WAITABLE; - bool valid_jobReference = - // Async operations are waitable. Loosely speaking, an async operation - // is split into independent send and ack events, and an sync operation - // is not. - IMPLIES( waitable, pOp->u.operation.jobReference == 2 ) && - IMPLIES( !waitable, pOp->u.operation.jobReference == 1 ); + // Async operations are waitable. Loosely speaking, an async operation + // is split into independent send and ack events, and an sync operation + // is not. + bool valid_jobReference; + // Implication is most natural here, but the use of it with __CPROVER_assume + // leads to inconsistent values in jobReferences. + if ( waitable ) { + valid_jobReference = ( pOp->u.operation.jobReference == 2 ); + } + else + { + valid_jobReference = ( pOp->u.operation.jobReference == 1 ); + } bool valid_operation_member = IMPLIES( !pOp->incomingPublish, From 2607cd8d609ef4fc61ff67a42eb1d6c2f7d420f2 Mon Sep 17 00:00:00 2001 From: markrtuttle Date: Thu, 16 Apr 2020 19:50:31 -0400 Subject: [PATCH 08/41] Add CBMC proof for MQTT ReceiveCallback (#877) * Add CBMC patches for ReceiveCallback proof * Add CBMC proof for ReceiveCallback * Update CBMC .gitignore to omit python and ninja build artifacts. * Modify CBMC prepare.py to accept flags to selectively prepare source tree. * Modify CBMC Makefile.common to always rebuild cbmc-batch.yaml. * Modify CBMC mqtt_state to define IotUserCallback predicates. * Add CBMC ninja build capability. * Revise CBMC proof for ReceiveCallback based on code review. Co-authored-by: Mark R Tuttle --- cbmc/.gitignore | 4 + .../Stub-network-function-pointers.patch | 48 +++ .../bound-packet-remaining-length.patch | 17 + .../IotMqtt_ReceiveCallback_CONNACK/Makefile | 32 ++ .../cbmc-batch.yaml | 8 + .../cbmc-viewer.json | 24 ++ .../IotMqtt_ReceiveCallback_OTHER/Makefile | 37 ++ .../cbmc-batch.yaml | 8 + .../cbmc-viewer.json | 24 ++ .../IotMqtt_ReceiveCallback_PUBACK/Makefile | 32 ++ .../cbmc-batch.yaml | 8 + .../cbmc-viewer.json | 24 ++ .../IotMqtt_ReceiveCallback_PUBLISH/Makefile | 41 ++ .../cbmc-batch.yaml | 8 + .../cbmc-viewer.json | 24 ++ .../IotMqtt_ReceiveCallback_SUBACK/Makefile | 33 ++ .../cbmc-batch.yaml | 8 + .../cbmc-viewer.json | 24 ++ .../IotMqtt_ReceiveCallback_UNSUBACK/Makefile | 33 ++ .../cbmc-batch.yaml | 8 + .../cbmc-viewer.json | 24 ++ .../IotMqtt_ReceiveCallback_harness.c | 385 ++++++++++++++++++ cbmc/proofs/IotMqtt_ReceiveCallback/Makefile | 90 ++++ .../IotMqtt_ReceiveCallback/Makefile.ninja | 33 ++ cbmc/proofs/IotMqtt_ReceiveCallback/README.md | 5 + cbmc/proofs/Makefile.common | 3 +- cbmc/proofs/make_cbmc_batch_files.py | 19 +- cbmc/proofs/mqtt_state.h | 5 + cbmc/proofs/ninja.py | 270 ++++++++++++ cbmc/proofs/prepare.py | 83 +++- 30 files changed, 1343 insertions(+), 19 deletions(-) create mode 100644 cbmc/patches/Stub-network-function-pointers.patch create mode 100644 cbmc/patches/bound-packet-remaining-length.patch create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/Makefile create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/cbmc-batch.yaml create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/cbmc-viewer.json create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/Makefile create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/cbmc-batch.yaml create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/cbmc-viewer.json create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/Makefile create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/cbmc-batch.yaml create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/cbmc-viewer.json create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/Makefile create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/cbmc-batch.yaml create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/cbmc-viewer.json create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/Makefile create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/cbmc-batch.yaml create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/cbmc-viewer.json create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/Makefile create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/cbmc-batch.yaml create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/cbmc-viewer.json create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_harness.c create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/Makefile create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/Makefile.ninja create mode 100644 cbmc/proofs/IotMqtt_ReceiveCallback/README.md create mode 100755 cbmc/proofs/ninja.py diff --git a/cbmc/.gitignore b/cbmc/.gitignore index 031b1db6c9..7d4e335f3e 100644 --- a/cbmc/.gitignore +++ b/cbmc/.gitignore @@ -1,2 +1,6 @@ *.csv *.log +__pycache__ +.ninja_deps +.ninja_log +build.ninja diff --git a/cbmc/patches/Stub-network-function-pointers.patch b/cbmc/patches/Stub-network-function-pointers.patch new file mode 100644 index 0000000000..5626512ad8 --- /dev/null +++ b/cbmc/patches/Stub-network-function-pointers.patch @@ -0,0 +1,48 @@ +diff --git a/libraries/standard/mqtt/src/iot_mqtt_network.c b/libraries/standard/mqtt/src/iot_mqtt_network.c +index f39eb98..6b7d13d 100644 +--- a/libraries/standard/mqtt/src/iot_mqtt_network.c ++++ b/libraries/standard/mqtt/src/iot_mqtt_network.c +@@ -281,6 +281,10 @@ static IotMqttError_t _allocateAndReceivePacket( IotNetworkConnection_t pNetwork + + if( status == IOT_MQTT_SUCCESS ) + { ++#ifdef CBMC ++ assert( IS_STUBBED_NETWORKIF_RECEIVE( pMqttConnection->pNetworkInterface ) ); ++ __CPROVER_assume( IS_STUBBED_NETWORKIF_RECEIVE( pMqttConnection->pNetworkInterface ) ); ++#endif + dataBytesRead = pMqttConnection->pNetworkInterface->receive( pNetworkConnection, + pIncomingPacket->pRemainingData, + pIncomingPacket->remainingLength ); +@@ -701,6 +705,10 @@ bool _IotMqtt_GetNextByte( IotNetworkConnection_t pNetworkConnection, + size_t bytesReceived = 0; + + /* Attempt to read 1 byte. */ ++#ifdef CBMC ++ assert( IS_STUBBED_NETWORKIF_RECEIVE( pNetworkInterface ) ); ++ __CPROVER_assume( IS_STUBBED_NETWORKIF_RECEIVE( pNetworkInterface ) ); ++#endif + bytesReceived = pNetworkInterface->receive( pNetworkConnection, + &incomingByte, + 1 ); +@@ -792,6 +800,10 @@ void _IotMqtt_CloseNetworkConnection( IotMqttDisconnectReason_t disconnectReason + /* Close the network connection. */ + if( closeConnection != NULL ) + { ++#ifdef CBMC ++ assert( closeConnection == IotNetworkInterfaceClose ); ++ __CPROVER_assume( closeConnection == IotNetworkInterfaceClose ); ++#endif + closeStatus = closeConnection( pNetworkConnection ); + + if( closeStatus == IOT_NETWORK_SUCCESS ) +@@ -818,6 +830,10 @@ void _IotMqtt_CloseNetworkConnection( IotMqttDisconnectReason_t disconnectReason + callbackParam.mqttConnection = pMqttConnection; + callbackParam.u.disconnectReason = disconnectReason; + ++#ifdef CBMC ++ assert( IS_STUBBED_USER_CALLBACK( disconnectCallback ) ); ++ __CPROVER_assume( IS_STUBBED_USER_CALLBACK( disconnectCallback ) ); ++#endif + disconnectCallback( pDisconnectCallbackContext, + &callbackParam ); + } diff --git a/cbmc/patches/bound-packet-remaining-length.patch b/cbmc/patches/bound-packet-remaining-length.patch new file mode 100644 index 0000000000..3b0c8f63a6 --- /dev/null +++ b/cbmc/patches/bound-packet-remaining-length.patch @@ -0,0 +1,17 @@ +diff --git a/libraries/standard/mqtt/src/iot_mqtt_network.c b/libraries/standard/mqtt/src/iot_mqtt_network.c +index f39eb98..805eca7 100644 +--- a/libraries/standard/mqtt/src/iot_mqtt_network.c ++++ b/libraries/standard/mqtt/src/iot_mqtt_network.c +@@ -256,6 +256,12 @@ static IotMqttError_t _allocateAndReceivePacket( IotNetworkConnection_t pNetwork + IotMqtt_Assert( pMqttConnection != NULL ); + IotMqtt_Assert( pIncomingPacket != NULL ); + ++#ifdef CBMC ++#ifdef REMAINING_LENGTH_BOUND ++ __CPROVER_assume( pIncomingPacket->remainingLength < REMAINING_LENGTH_BOUND ); ++#endif ++#endif ++ + /* Allocate a buffer for the remaining data and read the data. */ + if( pIncomingPacket->remainingLength > 0U ) + { diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/Makefile b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/Makefile new file mode 100644 index 0000000000..c224489240 --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/Makefile @@ -0,0 +1,32 @@ +PACKET=CONNACK + +ENTRY=IotMqtt_ReceiveCallback +MQTT = $(abspath ../../../..) + +################################################################ +# Functions made unreachable by the case split + +#ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeConnack +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializePuback +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeSuback +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeUnsuback + +ABSTRACTIONS += --remove-function-body _deserializePingResp +ABSTRACTIONS += --remove-function-body _deserializePublishPacket + +################################################################ +# Functions the solver can prove are unreachable + +ABSTRACTIONS += --remove-function-body Atomic_CompareAndSwap_u32 +ABSTRACTIONS += --remove-function-body Atomic_CompareAndSwap_u32 +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceDestroy +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceSend +ABSTRACTIONS += --remove-function-body _matchEndWildcards +ABSTRACTIONS += --remove-function-body _matchWildcards +ABSTRACTIONS += --remove-function-body _mqttSubscription_setUnsubscribe +ABSTRACTIONS += --remove-function-body _packetMatch +ABSTRACTIONS += --remove-function-body _topicFilterMatch +ABSTRACTIONS += --remove-function-body _topicMatch + +include ../Makefile +include ../../Makefile.common diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/cbmc-batch.yaml new file mode 100644 index 0000000000..5fffb7e309 --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/cbmc-batch.yaml @@ -0,0 +1,8 @@ +build_memory: 32000 +cbmcflags: "--flush;--object-bits;8;--unwind;1;--unwindset;IotListDouble_FindFirstMatch.0:2,IotListDouble_FindFirstMatch$link1.0:2,IotListDouble_FindFirstMatch$link2.0:2,IotListDouble_FindFirstMatch$link3.0:2,IotListDouble_FindFirstMatch$link4.0:2,IotListDouble_FindFirstMatch$link5.0:2,_IotMqtt_GetRemainingLength.0:5,_decodeSubackStatus.0:15,valid_IotMqttOperationList.0:2,valid_IotMqttSubscriptionList.0:2;--object-bits;8;--bounds-check;--conversion-check;--div-by-zero-check;--float-overflow-check;--flush;--nan-check;--pointer-check;--pointer-overflow-check;--signed-overflow-check;--undefined-shift-check;--unsigned-overflow-check;--unwinding-assertions" +coverage_memory: 32000 +expected: SUCCESSFUL +goto: IotMqtt_ReceiveCallback.goto +jobos: ubuntu16 +property_memory: 32000 +report_memory: 32000 diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/cbmc-viewer.json b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/cbmc-viewer.json new file mode 100644 index 0000000000..eb5742fdbb --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/cbmc-viewer.json @@ -0,0 +1,24 @@ +{ "expected-missing-functions": + [ + "IotLog_Generic", + "IotMqtt_Wait", + "IotMutex_Create", + "IotMutex_Destroy", + "IotMutex_Lock", + "IotMutex_Unlock", + "IotSemaphore_Create", + "IotSemaphore_Destroy", + "IotSemaphore_Post", + "IotSemaphore_TimedWait", + "IotSemaphore_Wait", + "IotTaskPool_CreateJob", + "IotTaskPool_GetSystemTaskPool", + "IotTaskPool_ScheduleDeferred", + "IotTaskPool_strerror", + "IotTaskPool_TryCancel", + "Iot_EnterCritical", + "Iot_ExitCritical" + ], + "proof-name": "IotMqtt_ReceiveCallback_CONNACK", + "proof-root": "cbmc/proofs" +} diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/Makefile b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/Makefile new file mode 100644 index 0000000000..d8f58aaddd --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/Makefile @@ -0,0 +1,37 @@ +# Leave PACKET undefined for the OTHER case. +#PACKET= + +# Note: We should be able to abstract all of the functions below, but +# symbolic execution wants _deserializePublishPacket for the OTHER +# case. The constraint solver is able to prove that the function is +# unreachable in the OTHER case. + +ENTRY=IotMqtt_ReceiveCallback +MQTT = $(abspath ../../../..) + +################################################################ +# Functions made unreachable by the case split + +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeConnack +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializePuback +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeSuback +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeUnsuback + +ABSTRACTIONS += --remove-function-body _deserializeAck +ABSTRACTIONS += --remove-function-body _deserializePublishPacket + +################################################################ +# Functions the solver can prove are unreachable + +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceDestroy +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceSend +ABSTRACTIONS += --remove-function-body _matchEndWildcards +ABSTRACTIONS += --remove-function-body _matchWildcards +ABSTRACTIONS += --remove-function-body _mqttOperation_match +ABSTRACTIONS += --remove-function-body _mqttSubscription_setUnsubscribe +ABSTRACTIONS += --remove-function-body _packetMatch +ABSTRACTIONS += --remove-function-body _topicFilterMatch +ABSTRACTIONS += --remove-function-body _topicMatch + +include ../Makefile +include ../../Makefile.common diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/cbmc-batch.yaml new file mode 100644 index 0000000000..5fffb7e309 --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/cbmc-batch.yaml @@ -0,0 +1,8 @@ +build_memory: 32000 +cbmcflags: "--flush;--object-bits;8;--unwind;1;--unwindset;IotListDouble_FindFirstMatch.0:2,IotListDouble_FindFirstMatch$link1.0:2,IotListDouble_FindFirstMatch$link2.0:2,IotListDouble_FindFirstMatch$link3.0:2,IotListDouble_FindFirstMatch$link4.0:2,IotListDouble_FindFirstMatch$link5.0:2,_IotMqtt_GetRemainingLength.0:5,_decodeSubackStatus.0:15,valid_IotMqttOperationList.0:2,valid_IotMqttSubscriptionList.0:2;--object-bits;8;--bounds-check;--conversion-check;--div-by-zero-check;--float-overflow-check;--flush;--nan-check;--pointer-check;--pointer-overflow-check;--signed-overflow-check;--undefined-shift-check;--unsigned-overflow-check;--unwinding-assertions" +coverage_memory: 32000 +expected: SUCCESSFUL +goto: IotMqtt_ReceiveCallback.goto +jobos: ubuntu16 +property_memory: 32000 +report_memory: 32000 diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/cbmc-viewer.json b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/cbmc-viewer.json new file mode 100644 index 0000000000..865b95be16 --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/cbmc-viewer.json @@ -0,0 +1,24 @@ +{ "expected-missing-functions": + [ + "IotLog_Generic", + "IotMqtt_Wait", + "IotMutex_Create", + "IotMutex_Destroy", + "IotMutex_Lock", + "IotMutex_Unlock", + "IotSemaphore_Create", + "IotSemaphore_Destroy", + "IotSemaphore_Post", + "IotSemaphore_TimedWait", + "IotSemaphore_Wait", + "IotTaskPool_CreateJob", + "IotTaskPool_GetSystemTaskPool", + "IotTaskPool_ScheduleDeferred", + "IotTaskPool_strerror", + "IotTaskPool_TryCancel", + "Iot_EnterCritical", + "Iot_ExitCritical" + ], + "proof-name": "IotMqtt_ReceiveCallback_OTHER", + "proof-root": "cbmc/proofs" +} diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/Makefile b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/Makefile new file mode 100644 index 0000000000..2b633b774e --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/Makefile @@ -0,0 +1,32 @@ +PACKET=PUBACK + +ENTRY=IotMqtt_ReceiveCallback +MQTT = $(abspath ../../../..) + +################################################################ +# Functions made unreachable by the case split + +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeConnack +#ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializePuback +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeSuback +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeUnsuback + +ABSTRACTIONS += --remove-function-body _deserializePingResp +ABSTRACTIONS += --remove-function-body _deserializePublishPacket + +################################################################ +# Functions the solver can prove are unreachable + +ABSTRACTIONS += --remove-function-body Atomic_CompareAndSwap_u32 +ABSTRACTIONS += --remove-function-body Atomic_CompareAndSwap_u32 +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceDestroy +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceSend +ABSTRACTIONS += --remove-function-body _matchEndWildcards +ABSTRACTIONS += --remove-function-body _matchWildcards +ABSTRACTIONS += --remove-function-body _mqttSubscription_setUnsubscribe +ABSTRACTIONS += --remove-function-body _packetMatch +ABSTRACTIONS += --remove-function-body _topicFilterMatch +ABSTRACTIONS += --remove-function-body _topicMatch + +include ../Makefile +include ../../Makefile.common diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/cbmc-batch.yaml new file mode 100644 index 0000000000..5fffb7e309 --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/cbmc-batch.yaml @@ -0,0 +1,8 @@ +build_memory: 32000 +cbmcflags: "--flush;--object-bits;8;--unwind;1;--unwindset;IotListDouble_FindFirstMatch.0:2,IotListDouble_FindFirstMatch$link1.0:2,IotListDouble_FindFirstMatch$link2.0:2,IotListDouble_FindFirstMatch$link3.0:2,IotListDouble_FindFirstMatch$link4.0:2,IotListDouble_FindFirstMatch$link5.0:2,_IotMqtt_GetRemainingLength.0:5,_decodeSubackStatus.0:15,valid_IotMqttOperationList.0:2,valid_IotMqttSubscriptionList.0:2;--object-bits;8;--bounds-check;--conversion-check;--div-by-zero-check;--float-overflow-check;--flush;--nan-check;--pointer-check;--pointer-overflow-check;--signed-overflow-check;--undefined-shift-check;--unsigned-overflow-check;--unwinding-assertions" +coverage_memory: 32000 +expected: SUCCESSFUL +goto: IotMqtt_ReceiveCallback.goto +jobos: ubuntu16 +property_memory: 32000 +report_memory: 32000 diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/cbmc-viewer.json b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/cbmc-viewer.json new file mode 100644 index 0000000000..536174f8ee --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/cbmc-viewer.json @@ -0,0 +1,24 @@ +{ "expected-missing-functions": + [ + "IotLog_Generic", + "IotMqtt_Wait", + "IotMutex_Create", + "IotMutex_Destroy", + "IotMutex_Lock", + "IotMutex_Unlock", + "IotSemaphore_Create", + "IotSemaphore_Destroy", + "IotSemaphore_Post", + "IotSemaphore_TimedWait", + "IotSemaphore_Wait", + "IotTaskPool_CreateJob", + "IotTaskPool_GetSystemTaskPool", + "IotTaskPool_ScheduleDeferred", + "IotTaskPool_strerror", + "IotTaskPool_TryCancel", + "Iot_EnterCritical", + "Iot_ExitCritical" + ], + "proof-name": "IotMqtt_ReceiveCallback_PUBACK", + "proof-root": "cbmc/proofs" +} diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/Makefile b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/Makefile new file mode 100644 index 0000000000..6b21214434 --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/Makefile @@ -0,0 +1,41 @@ +PACKET=PUBLISH + +ENTRY=IotMqtt_ReceiveCallback +MQTT = $(abspath ../../../..) + +################################################################ +# Functions made unreachable by the case split + +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeConnack +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializePuback +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeSuback +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeUnsuback + +ABSTRACTIONS += --remove-function-body _deserializeAck +ABSTRACTIONS += --remove-function-body _deserializePingResp + +################################################################ +# Functions the solver can prove are unreachable + +ABSTRACTIONS += --remove-function-body Atomic_CompareAndSwap_u32 +ABSTRACTIONS += --remove-function-body Atomic_CompareAndSwap_u32 +ABSTRACTIONS += --remove-function-body IotListDouble_FindFirstMatch +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceDestroy +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceSend +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializePingresp +ABSTRACTIONS += --remove-function-body _IotMqtt_FindOperation +ABSTRACTIONS += --remove-function-body _IotMqtt_Notify +ABSTRACTIONS += --remove-function-body _matchEndWildcards +ABSTRACTIONS += --remove-function-body _matchWildcards +ABSTRACTIONS += --remove-function-body _mqttOperation_match +ABSTRACTIONS += --remove-function-body _mqttSubscription_setUnsubscribe +ABSTRACTIONS += --remove-function-body _packetMatch +ABSTRACTIONS += --remove-function-body _topicFilterMatch +ABSTRACTIONS += --remove-function-body _topicMatch +ABSTRACTIONS += --remove-function-body destroy_operation_list +ABSTRACTIONS += --remove-function-body destroy_operation_list_element +ABSTRACTIONS += --remove-function-body destroy_subscription_list +ABSTRACTIONS += --remove-function-body destroy_subscription_list_element + +include ../Makefile +include ../../Makefile.common diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/cbmc-batch.yaml new file mode 100644 index 0000000000..5fffb7e309 --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/cbmc-batch.yaml @@ -0,0 +1,8 @@ +build_memory: 32000 +cbmcflags: "--flush;--object-bits;8;--unwind;1;--unwindset;IotListDouble_FindFirstMatch.0:2,IotListDouble_FindFirstMatch$link1.0:2,IotListDouble_FindFirstMatch$link2.0:2,IotListDouble_FindFirstMatch$link3.0:2,IotListDouble_FindFirstMatch$link4.0:2,IotListDouble_FindFirstMatch$link5.0:2,_IotMqtt_GetRemainingLength.0:5,_decodeSubackStatus.0:15,valid_IotMqttOperationList.0:2,valid_IotMqttSubscriptionList.0:2;--object-bits;8;--bounds-check;--conversion-check;--div-by-zero-check;--float-overflow-check;--flush;--nan-check;--pointer-check;--pointer-overflow-check;--signed-overflow-check;--undefined-shift-check;--unsigned-overflow-check;--unwinding-assertions" +coverage_memory: 32000 +expected: SUCCESSFUL +goto: IotMqtt_ReceiveCallback.goto +jobos: ubuntu16 +property_memory: 32000 +report_memory: 32000 diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/cbmc-viewer.json b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/cbmc-viewer.json new file mode 100644 index 0000000000..93958f7dbc --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/cbmc-viewer.json @@ -0,0 +1,24 @@ +{ "expected-missing-functions": + [ + "IotLog_Generic", + "IotMqtt_Wait", + "IotMutex_Create", + "IotMutex_Destroy", + "IotMutex_Lock", + "IotMutex_Unlock", + "IotSemaphore_Create", + "IotSemaphore_Destroy", + "IotSemaphore_Post", + "IotSemaphore_TimedWait", + "IotSemaphore_Wait", + "IotTaskPool_CreateJob", + "IotTaskPool_GetSystemTaskPool", + "IotTaskPool_ScheduleDeferred", + "IotTaskPool_strerror", + "IotTaskPool_TryCancel", + "Iot_EnterCritical", + "Iot_ExitCritical" + ], + "proof-name": "IotMqtt_ReceiveCallback_PUBLISH", + "proof-root": "cbmc/proofs" +} diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/Makefile b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/Makefile new file mode 100644 index 0000000000..3158b1d56e --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/Makefile @@ -0,0 +1,33 @@ +PACKET=SUBACK + +ENTRY=IotMqtt_ReceiveCallback +MQTT = $(abspath ../../../..) + +################################################################ +# Functions made unreachable by the case split + +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeConnack +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializePuback +#ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeSuback +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeUnsuback + +ABSTRACTIONS += --remove-function-body _deserializePingResp +ABSTRACTIONS += --remove-function-body _deserializePublishPacket + +################################################################ +# Functions the solver can prove are unreachable + +ABSTRACTIONS += --remove-function-body Atomic_CompareAndSwap_u32 +ABSTRACTIONS += --remove-function-body Atomic_CompareAndSwap_u32 +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceDestroy +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceSend +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializePingresp +ABSTRACTIONS += --remove-function-body _matchEndWildcards +ABSTRACTIONS += --remove-function-body _matchWildcards +ABSTRACTIONS += --remove-function-body _mqttSubscription_setUnsubscribe +ABSTRACTIONS += --remove-function-body _packetMatch +ABSTRACTIONS += --remove-function-body _topicFilterMatch +ABSTRACTIONS += --remove-function-body _topicMatch + +include ../Makefile +include ../../Makefile.common diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/cbmc-batch.yaml new file mode 100644 index 0000000000..5fffb7e309 --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/cbmc-batch.yaml @@ -0,0 +1,8 @@ +build_memory: 32000 +cbmcflags: "--flush;--object-bits;8;--unwind;1;--unwindset;IotListDouble_FindFirstMatch.0:2,IotListDouble_FindFirstMatch$link1.0:2,IotListDouble_FindFirstMatch$link2.0:2,IotListDouble_FindFirstMatch$link3.0:2,IotListDouble_FindFirstMatch$link4.0:2,IotListDouble_FindFirstMatch$link5.0:2,_IotMqtt_GetRemainingLength.0:5,_decodeSubackStatus.0:15,valid_IotMqttOperationList.0:2,valid_IotMqttSubscriptionList.0:2;--object-bits;8;--bounds-check;--conversion-check;--div-by-zero-check;--float-overflow-check;--flush;--nan-check;--pointer-check;--pointer-overflow-check;--signed-overflow-check;--undefined-shift-check;--unsigned-overflow-check;--unwinding-assertions" +coverage_memory: 32000 +expected: SUCCESSFUL +goto: IotMqtt_ReceiveCallback.goto +jobos: ubuntu16 +property_memory: 32000 +report_memory: 32000 diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/cbmc-viewer.json b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/cbmc-viewer.json new file mode 100644 index 0000000000..7d0fb87869 --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/cbmc-viewer.json @@ -0,0 +1,24 @@ +{ "expected-missing-functions": + [ + "IotLog_Generic", + "IotMqtt_Wait", + "IotMutex_Create", + "IotMutex_Destroy", + "IotMutex_Lock", + "IotMutex_Unlock", + "IotSemaphore_Create", + "IotSemaphore_Destroy", + "IotSemaphore_Post", + "IotSemaphore_TimedWait", + "IotSemaphore_Wait", + "IotTaskPool_CreateJob", + "IotTaskPool_GetSystemTaskPool", + "IotTaskPool_ScheduleDeferred", + "IotTaskPool_strerror", + "IotTaskPool_TryCancel", + "Iot_EnterCritical", + "Iot_ExitCritical" + ], + "proof-name": "IotMqtt_ReceiveCallback_SUBACK", + "proof-root": "cbmc/proofs" +} diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/Makefile b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/Makefile new file mode 100644 index 0000000000..9204eefbca --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/Makefile @@ -0,0 +1,33 @@ +PACKET=UNSUBACK + +ENTRY=IotMqtt_ReceiveCallback +MQTT = $(abspath ../../../..) + +################################################################ +# Functions made unreachable by the case split + +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeConnack +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializePuback +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeSuback +#ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializeUnsuback + +ABSTRACTIONS += --remove-function-body _deserializePingResp +ABSTRACTIONS += --remove-function-body _deserializePublishPacket + +################################################################ +# Functions the solver can prove are unreachable + +ABSTRACTIONS += --remove-function-body Atomic_CompareAndSwap_u32 +ABSTRACTIONS += --remove-function-body Atomic_CompareAndSwap_u32 +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceDestroy +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceSend +ABSTRACTIONS += --remove-function-body _IotMqtt_DeserializePingresp +ABSTRACTIONS += --remove-function-body _matchEndWildcards +ABSTRACTIONS += --remove-function-body _matchWildcards +ABSTRACTIONS += --remove-function-body _mqttSubscription_setUnsubscribe +ABSTRACTIONS += --remove-function-body _packetMatch +ABSTRACTIONS += --remove-function-body _topicFilterMatch +ABSTRACTIONS += --remove-function-body _topicMatch + +include ../Makefile +include ../../Makefile.common diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/cbmc-batch.yaml new file mode 100644 index 0000000000..5fffb7e309 --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/cbmc-batch.yaml @@ -0,0 +1,8 @@ +build_memory: 32000 +cbmcflags: "--flush;--object-bits;8;--unwind;1;--unwindset;IotListDouble_FindFirstMatch.0:2,IotListDouble_FindFirstMatch$link1.0:2,IotListDouble_FindFirstMatch$link2.0:2,IotListDouble_FindFirstMatch$link3.0:2,IotListDouble_FindFirstMatch$link4.0:2,IotListDouble_FindFirstMatch$link5.0:2,_IotMqtt_GetRemainingLength.0:5,_decodeSubackStatus.0:15,valid_IotMqttOperationList.0:2,valid_IotMqttSubscriptionList.0:2;--object-bits;8;--bounds-check;--conversion-check;--div-by-zero-check;--float-overflow-check;--flush;--nan-check;--pointer-check;--pointer-overflow-check;--signed-overflow-check;--undefined-shift-check;--unsigned-overflow-check;--unwinding-assertions" +coverage_memory: 32000 +expected: SUCCESSFUL +goto: IotMqtt_ReceiveCallback.goto +jobos: ubuntu16 +property_memory: 32000 +report_memory: 32000 diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/cbmc-viewer.json b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/cbmc-viewer.json new file mode 100644 index 0000000000..4a0b72bf5b --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/cbmc-viewer.json @@ -0,0 +1,24 @@ +{ "expected-missing-functions": + [ + "IotLog_Generic", + "IotMqtt_Wait", + "IotMutex_Create", + "IotMutex_Destroy", + "IotMutex_Lock", + "IotMutex_Unlock", + "IotSemaphore_Create", + "IotSemaphore_Destroy", + "IotSemaphore_Post", + "IotSemaphore_TimedWait", + "IotSemaphore_Wait", + "IotTaskPool_CreateJob", + "IotTaskPool_GetSystemTaskPool", + "IotTaskPool_ScheduleDeferred", + "IotTaskPool_strerror", + "IotTaskPool_TryCancel", + "Iot_EnterCritical", + "Iot_ExitCritical" + ], + "proof-name": "IotMqtt_ReceiveCallback_UNSUBACK", + "proof-root": "cbmc/proofs" +} diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_harness.c b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_harness.c new file mode 100644 index 0000000000..06d1712e11 --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_harness.c @@ -0,0 +1,385 @@ +/* + * IoT MQTT V2.1.0 + * Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * @file IotMqtt_ReceiveCallback_harness.c + * @brief Implements the proof harness for IotMqtt_ReceiveCallback function. + */ + +#include "iot_config.h" +#include "private/iot_mqtt_internal.h" + +#include + +#include "mqtt_state.h" + +/**************************************************************** +* Type definitions used by the IoT List Double remove functions +****************************************************************/ + +typedef bool ( *MatchFunction_t )( const IotLink_t * const pOperationLink, + void * pCompare ); +typedef void ( *FreeElementFunction_t )( void * pData ); + +/**************************************************************** +* We assume the IoT List Double remove functions are memory safe. +* +* We abstract the list remove functions for performance reasons. Our +* abstraction replaces the original list with an unconstrained list. +* Our abstraction proves that none of the elements on the original +* list are accessed after the remove: We free all elements on the +* original list, so that any later access will be caught as a +* use-after-free error. +****************************************************************/ + +void IotListDouble_RemoveAllMatches( const IotListDouble_t * const pList, + MatchFunction_t isMatch, + void * pMatch, + FreeElementFunction_t freeElement, + size_t linkOffset ) +{ + free_IotMqttSubscriptionList( pList ); + allocate_IotMqttSubscriptionList( pList, SUBSCRIPTION_COUNT_MAX - 1 ); +} + +/****************************************************************/ + +void IotListDouble_RemoveAll( const IotListDouble_t * const pList, + FreeElementFunction_t freeElement, + size_t linkOffset ) +{ + free_IotMqttSubscriptionList( pList ); + allocate_IotMqttSubscriptionList( pList, SUBSCRIPTION_COUNT_MAX - 1 ); +} + +/**************************************************************** +* We assume the TaskPool functions are memory safe. +* +* We abstract the task pool functions (we assume they have no side +* effects and return an unconstrained value), but there are some +* assertions in the code that the task pool functions return a +* constrained set of values. We model these functions as simply +* returning one of those values. +****************************************************************/ + +IotTaskPoolError_t IotTaskPool_CreateJob( const IotTaskPoolRoutine_t userCallback, + void * const pUserContext, + IotTaskPoolJob_t * const pJob ) +{ + assert( userCallback != NULL ); + assert( pUserContext != NULL ); + assert( pJob != NULL ); + + /* + * *_IotMqtt_ScheduleOperation says creating a new job should + * never fail when parameters are valid. + */ + return IOT_TASKPOOL_SUCCESS; +} + +/****************************************************************/ + +IotTaskPoolError_t IotTaskPool_ScheduleDeferred( IotTaskPool_t * const pTaskPool, + IotTaskPoolJob_t * const pJob, + uint32_t timeMs ) +{ + /* assert(pTaskPool != NULL); */ + /* assert(pJob != NULL); */ + + /* + * *_IotMqtt_ScheduleOperation says a newly created job should + * never be invalid or illegal. + */ + IotTaskPoolError_t error; + + __CPROVER_assume( error != IOT_TASKPOOL_BAD_PARAMETER ); + __CPROVER_assume( error != IOT_TASKPOOL_ILLEGAL_OPERATION ); + return error; +} + +/**************************************************************** +* We abstract the Notify method by assuming it havocs subscription and +* operation lists. +* +* These functions are used to havoc the lists. The lists are written +* and then never again read. We model these updates by simply freeing +* the lists, and trusting CBMC to flag a use-after-free error if an +* element of the list is accessed. +****************************************************************/ + +void * invalid_pointer(); + +IotListDouble_t * destroy_subscription_list_element( IotListDouble_t * pElt ) +{ + if( pElt == NULL ) + { + return NULL; + } + + IotListDouble_t * pNext = pElt->pNext; + free( IotLink_Container( _mqttSubscription_t, pElt, link ) ); + return pNext; +} + +void destroy_subscription_list( IotListDouble_t * pList ) +{ + if( pList == NULL ) + { + return; + } + + /* Assuming lists are of length at most 3 */ + + IotListDouble_t * pElt = pList->pNext; + + if( pElt != pList ) + { + pElt = destroy_subscription_list_element( pElt ); + } + + if( pElt != pList ) + { + pElt = destroy_subscription_list_element( pElt ); + } + + if( pElt != pList ) + { + pElt = destroy_subscription_list_element( pElt ); + } + + pList->pNext = invalid_pointer(); + pList->pPrevious = invalid_pointer(); +} + +IotListDouble_t * destroy_operation_list_element( IotListDouble_t * pElt ) +{ + if( pElt == NULL ) + { + return NULL; + } + + IotListDouble_t * pNext = pElt->pNext; + free( IotLink_Container( struct _mqttOperation, pElt, link ) ); + return pNext; +} + +void destroy_operation_list( IotListDouble_t * pList ) +{ + if( pList == NULL ) + { + return; + } + + /* Assuming lists are of length at most 3 */ + + IotListDouble_t * pElt = pList->pNext; + + if( pElt != pList ) + { + pElt = destroy_operation_list_element( pElt ); + } + + if( pElt != pList ) + { + pElt = destroy_operation_list_element( pElt ); + } + + if( pElt != pList ) + { + pElt = destroy_operation_list_element( pElt ); + } + + pList->pNext = invalid_pointer(); + pList->pPrevious = invalid_pointer(); +} + +/**************************************************************** +* Abstract the Notify method +* +* This abstraction assumes that the write set of Notify is just the +* subscription and operation lists in the connection, and it models +* Notify by simply havocing these lists. +****************************************************************/ + +void _IotMqtt_Notify( _mqttOperation_t * pOperation ) +{ + destroy_subscription_list( &pOperation->pMqttConnection->subscriptionList ); + destroy_operation_list( &pOperation->pMqttConnection->pendingProcessing ); + destroy_operation_list( &pOperation->pMqttConnection->pendingResponse ); +} + +/**************************************************************** +* A predicate asserting that an operation on the pending list with no +* retry has a job reference of 1. This property is asserted by +* _IotMqtt_FindOperation. +* +* Notice that this predicate tests members of a union guaranteed to +* be valid only when the operation's incomingPublish is false. This +* condition not tested by _IotMqtt_FindOperation and thus not tested +* by this predicate. +* +* This predicate is implemented using straight line code to avoid +* loop unwinding. It assumes that the operation list has length at +* most 3. +****************************************************************/ + +bool pending_operation_has_valid_jobreference( IotLink_t * pElt ) +{ + _mqttOperation_t * pOp = IotLink_Container( _mqttOperation_t, pElt, link ); + + return IMPLIES( pOp->u.operation.periodic.retry.limit == 0, + pOp->u.operation.jobReference == 1 ); +} + +bool pending_operations_have_valid_jobreference( IotMqttConnection_t pConn ) +{ + if( pConn == NULL ) + { + return false; + } + + IotLink_t * pHead = &pConn->pendingResponse; + IotLink_t * pElt = pHead->pNext; + bool status = true; + + if( pElt != pHead ) + { + status = status && pending_operation_has_valid_jobreference( pElt ); + pElt = pElt->pNext; + } + + if( pElt != pHead ) + { + status = status && pending_operation_has_valid_jobreference( pElt ); + pElt = pElt->pNext; + } + + if( pElt != pHead ) + { + status = status && pending_operation_has_valid_jobreference( pElt ); + pElt = pElt->pNext; + } + + status = status && pElt == pHead; + + return status; +} + +/**************************************************************** +* This proof works by splitting into cases based on incoming packet +* type. There are six valid incoming packet types: +* +* MQTT_PACKET_TYPE_CONNACK +* MQTT_PACKET_TYPE_PUBLISH +* MQTT_PACKET_TYPE_PUBACK +* MQTT_PACKET_TYPE_SUBACK +* MQTT_PACKET_TYPE_UNSUBACK +* and +* MQTT_PACKET_TYPE_PINGRESP +* +* We split these cases into the first 5 and everything else by +* modifying the function that reads the byte from the network +* connection that includes the packet type. This byte consists of 4 +* bits giving the packet type and 4 bits giving the packet flags like +* quality of service. +****************************************************************/ + +uint8_t _IotMqtt_GetPacketType( IotNetworkConnection_t pNetworkConnection, + const IotNetworkInterface_t * pNetworkInterface ) +{ + uint8_t byte; + + /* Top 4 bits are packet type, the bottom 4 bits are flags */ + uint8_t type = byte & 0xf0U; + + #ifdef CBMC_PACKET + __CPROVER_assume( type == CBMC_PACKET ); + assert( type == MQTT_PACKET_TYPE_CONNACK || + type == MQTT_PACKET_TYPE_PUBLISH || + type == MQTT_PACKET_TYPE_PUBACK || + type == MQTT_PACKET_TYPE_SUBACK || + type == MQTT_PACKET_TYPE_UNSUBACK ); + #else + __CPROVER_assume( type != MQTT_PACKET_TYPE_CONNACK && + type != MQTT_PACKET_TYPE_PUBLISH && + type != MQTT_PACKET_TYPE_PUBACK && + type != MQTT_PACKET_TYPE_SUBACK && + type != MQTT_PACKET_TYPE_UNSUBACK ); + #endif /* ifdef CBMC_PACKET */ + + return byte; +} + +/**************************************************************** +* The proof harness +****************************************************************/ + +void harness() +{ + IotMqttConnection_t ReceiveContext = allocate_IotMqttConnection( NULL ); + + __CPROVER_assume( ReceiveContext ); + ensure_IotMqttConnection_has_lists( ReceiveContext ); + __CPROVER_assume( valid_IotMqttConnection( ReceiveContext ) ); + + __CPROVER_assume( + pending_operations_have_valid_jobreference( ReceiveContext ) ); + + /* There must be some operation waiting for an inbound ack */ + __CPROVER_assume( ReceiveContext->references > 0 ); + + /* Disconnect callback function pointer points to our stub */ + __CPROVER_assume( + MAYBE_STUBBED_USER_CALLBACK( + ReceiveContext->disconnectCallback.function ) ); + + /* Network interface method functions pointers point to our stubs */ + __CPROVER_assume( + IS_STUBBED_NETWORKIF_RECEIVE( + ReceiveContext->pNetworkInterface ) ); + __CPROVER_assume( + MAYBE_STUBBED_NETWORKIF_CREATE( + ReceiveContext->pNetworkInterface ) ); + __CPROVER_assume( + MAYBE_STUBBED_NETWORKIF_CLOSE( + ReceiveContext->pNetworkInterface ) ); + __CPROVER_assume( + MAYBE_STUBBED_NETWORKIF_SEND( + ReceiveContext->pNetworkInterface ) ); + __CPROVER_assume( + MAYBE_STUBBED_NETWORKIF_SETRECEIVECALLBACK( + ReceiveContext->pNetworkInterface ) ); + __CPROVER_assume( + MAYBE_STUBBED_NETWORKIF_SETCLOSECALLBACK( + ReceiveContext->pNetworkInterface ) ); + __CPROVER_assume( + MAYBE_STUBBED_NETWORKIF_DESTROY( + ReceiveContext->pNetworkInterface ) ); + + IotMqtt_ReceiveCallback( ReceiveContext->pNetworkConnection, + ReceiveContext ); +} + +/****************************************************************/ diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/Makefile b/cbmc/proofs/IotMqtt_ReceiveCallback/Makefile new file mode 100644 index 0000000000..5e142d72b5 --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/Makefile @@ -0,0 +1,90 @@ +ENTRY?=IotMqtt_ReceiveCallback + +################################################################ +# Proof works by case splitting by packet type +# +# The value of PACKET should be set on the make command line to one of +# CONNACK +# PUBLISH +# PUBACK +# SUBACK +# UNSUBACK +# or should be left undefined to model any other packet type +# +# The proof is driving by running make in the six subdirectories. + +ifdef PACKET +DEF += -DCBMC_PACKET=MQTT_PACKET_TYPE_$(PACKET) +endif + +################################################################ +# Proof assumptions + +# Bound the number of subscriptions in a list (BOUND = MAX-1) +SUBSCRIPTION_COUNT_MAX=2 +DEF += -DSUBSCRIPTION_COUNT_MAX=$(SUBSCRIPTION_COUNT_MAX) + +# Bound the number of operations in a list (BOUND = MAX-1) +OPERATION_COUNT_MAX=2 +DEF += -DOPERATION_COUNT_MAX=$(OPERATION_COUNT_MAX) + +# Bound the length of subscription topics (BOUND = MAX-1) +TOPIC_LENGTH_MAX=6 +DEF += -DTOPIC_LENGTH_MAX=$(TOPIC_LENGTH_MAX) + +# Bound the remaing length of a packet (BOUND = MAX-1) +REMAINING_LENGTH_BOUND=15 +DEF += -DREMAINING_LENGTH_BOUND=$(REMAINING_LENGTH_BOUND) + +# A constant that should be 2*SUBSCRIPTION_COUNT_MAX-1 +SUBSCRIPTION_LIST_MAX=3 +DEF += -DSUBSCRIPTION_LIST_MAX=$(SUBSCRIPTION_LIST_MAX) + +################################################################ +# Abstract the flush packet method + +ABSTRACTIONS += --remove-function-body _flushPacket + +################################################################ +# Abstract list remove functions + +DEF += -DCBMC_STUB_REMOVEALL=1 +DEF += -DCBMC_STUB_REMOVEALLMATCHES=1 + +################################################################ + +OBJS += $(MQTT)/cbmc/proofs/$(ENTRY)/$(ENTRY)_harness.goto +OBJS += $(MQTT)/cbmc/proofs/mqtt_state.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_api.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_helper.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_network.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_operation.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_serialize.goto +OBJS += $(MQTT)/libraries/standard/mqtt/src/iot_mqtt_subscription.goto + +# allow mqtt mallocs to fail for coverage +DEF += -include mqtt_state.h +DEF += -DIotMqtt_MallocMessage=malloc_can_fail +DEF += -DIotMqtt_MallocOperation=malloc_can_fail + +################################################################ +# Loop unwinding + +LOOP += IotListDouble_FindFirstMatch.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += IotListDouble_FindFirstMatch\$$link1.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += IotListDouble_FindFirstMatch\$$link2.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += IotListDouble_FindFirstMatch\$$link3.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += IotListDouble_FindFirstMatch\$$link4.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += IotListDouble_FindFirstMatch\$$link5.0:$(SUBSCRIPTION_COUNT_MAX) + +LOOP += _IotMqtt_GetRemainingLength.0:5 +LOOP += _decodeSubackStatus.0:$(REMAINING_LENGTH_BOUND) +LOOP += valid_IotMqttOperationList.0:$(OPERATION_COUNT_MAX) +LOOP += valid_IotMqttSubscriptionList.0:$(SUBSCRIPTION_COUNT_MAX) + +UNWINDING += --unwind 1 +UNWINDING += --unwindset '$(shell echo $(LOOP) | sed 's/ /,/g')' + +################################################################ + +sinclude ../Makefile.common diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/Makefile.ninja b/cbmc/proofs/IotMqtt_ReceiveCallback/Makefile.ninja new file mode 100644 index 0000000000..229f4c1952 --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/Makefile.ninja @@ -0,0 +1,33 @@ +# -*- mode: makefile -*- + +# This Makefile runs the ReceiveCallback proofs with as much +# concurrency as possible. It runs each case in isolation, but runs +# the two instances of cbmc in parallel. +# +# The ninja build file does not run the ReceiveCallback proofs +# correctly. +# +# The problem is that each case of the proof requires a different +# version of IotMqtt_ReceiveCallback.goto. One could ask ninja to do +# a "make clean" before doing a "make goto". But the result would be +# that case A would build goto, then case B would build goto, then +# case A would run cbmc and see the IotMqtt_ReceiveCallback.goto has +# changed and rebuild goto. Now the concurrently running cases are +# stompping on each other's goto binaries. + +DIRS = \ + IotMqtt_ReceiveCallback_CONNACK \ + IotMqtt_ReceiveCallback_OTHER \ + IotMqtt_ReceiveCallback_PUBACK \ + IotMqtt_ReceiveCallback_PUBLISH \ + IotMqtt_ReceiveCallback_SUBACK \ + IotMqtt_ReceiveCallback_UNSUBACK + +default: + ninja veryclean + for d in $(DIRS); do \ + echo -n TIME: STARTING $$d ": "; date; \ + make -C $$d veryclean2; \ + ninja $$d; \ + echo -n TIME: ENDING $$d ": "; date; \ + done diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/README.md b/cbmc/proofs/IotMqtt_ReceiveCallback/README.md new file mode 100644 index 0000000000..9092ec953e --- /dev/null +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/README.md @@ -0,0 +1,5 @@ +This is a memory safety proof for IotMqtt_ReceiveCallback. + +The proof is split into six cases based on the type of the incoming +packet. This directory has six subdirectories, one for each case. +The proof is the result of the proofs in the six subdirectories. diff --git a/cbmc/proofs/Makefile.common b/cbmc/proofs/Makefile.common index c0ee0c2758..4664695fc9 100644 --- a/cbmc/proofs/Makefile.common +++ b/cbmc/proofs/Makefile.common @@ -166,7 +166,8 @@ define encode_options '=$(shell echo $(1) | sed 's/ ,/ /g' | sed 's/ /;/g')=' endef -cbmc-batch.yaml: Makefile ../Makefile.common +# Regenerate cbmc-batch.yaml every time (use PHONY, list no dependencies) +cbmc-batch.yaml: @echo "Building $@" @$(RM) $@ @echo 'build_memory: $(PROOFMEM)' > $@ diff --git a/cbmc/proofs/make_cbmc_batch_files.py b/cbmc/proofs/make_cbmc_batch_files.py index 622e000c3a..f739e43acf 100644 --- a/cbmc/proofs/make_cbmc_batch_files.py +++ b/cbmc/proofs/make_cbmc_batch_files.py @@ -25,29 +25,24 @@ import os import platform import subprocess +import logging - -def remove_cbmc_yaml_files(): - for dyr, _, files in os.walk("."): - cbmc_batch_files = [os.path.join(os.path.abspath(dyr), file) - for file in files if file == "cbmc-batch.yaml"] - for file in cbmc_batch_files: - os.remove(file) - +MAKEFILE = "Makefile" +YAML_FILE = "cbmc-batch.yaml" def create_cbmc_yaml_files(): # The YAML files are only used by CI and are not needed on Windows. if platform.system() == "Windows": return for dyr, _, files in os.walk("."): - harness = [file for file in files if file.endswith("_harness.c")] - if harness and "Makefile" in files: - subprocess.run(["make", "cbmc-batch.yaml"], + if YAML_FILE in files and MAKEFILE in files: + logging.info("Building %s in %s", YAML_FILE, dyr) + os.remove(os.path.join(os.path.abspath(dyr), YAML_FILE)) + subprocess.run(["make", YAML_FILE], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=os.path.abspath(dyr), check=True) if __name__ == '__main__': - remove_cbmc_yaml_files() create_cbmc_yaml_files() diff --git a/cbmc/proofs/mqtt_state.h b/cbmc/proofs/mqtt_state.h index 28f8c49945..eaa22a60f5 100644 --- a/cbmc/proofs/mqtt_state.h +++ b/cbmc/proofs/mqtt_state.h @@ -253,3 +253,8 @@ IotNetworkError_t IotNetworkInterfaceDestroy( void * pConnection ); IotMqttCallbackInfo_t *allocate_IotMqttCallbackInfo(IotMqttCallbackInfo_t *pCb); void IotUserCallback( void * pCallbackContext, IotMqttCallbackParam_t * pCallbackParam ); + +#define IS_STUBBED_USER_CALLBACK(cb) (cb == IotUserCallback) +#define MAYBE_STUBBED_USER_CALLBACK(cb) (cb == NULL || cb == IotUserCallback) + +/****************************************************************/ diff --git a/cbmc/proofs/ninja.py b/cbmc/proofs/ninja.py new file mode 100755 index 0000000000..544f749b30 --- /dev/null +++ b/cbmc/proofs/ninja.py @@ -0,0 +1,270 @@ +#!/usr/bin/env python3 + +""" +Write a ninja build file to generate reports for cbmc proofs. + +Given a list of folders containing cbmc proofs, write a ninja build +file the generate reports for these proofs. The list of folders may +be given on the command line, in a json file, or found in the file +system. +""" + +# Add task pool + +import sys +import os +import platform +import argparse +import json + +################################################################ +# The command line parser + +def argument_parser(): + """Return the command line parser.""" + + parser = argparse.ArgumentParser( + description='Generate ninja build file for cbmc proofs.', + epilog=""" + Given a list of folders containing cbmc proofs, write a ninja build + file the generate reports for these proofs. The list of folders may + be given on the command line, in a json file, or found in the file + system. + In the json file, there should be a dict mapping the key "proofs" + to a list of folders containing proofs. + The file system, all folders folders under the current directory + containing a file named 'cbmc-batch.yaml' is considered a + proof folder. + This script assumes that the proof is driven by a Makefile + with targets goto, cbmc, coverage, property, and report. + This script does not work with Windows and Visual Studio. + """ + ) + parser.add_argument('folders', metavar='PROOF', nargs='*', + help='Folder containing a cbmc proof') + parser.add_argument('--proofs', metavar='JSON', + help='Json file listing folders containing cbmc proofs') + return parser + +################################################################ +# The list of folders containing proofs +# +# The list of folders will be taken from +# 1. the list PROOFS defined here or +# 2. the command line +# 3. the json file specified on the command line containing a +# dict mapping the key JSON_KEY to a list of folders +# 4. the folders below the current directory containing +# a file named FS_KEY +# + +PROOFS = [ +] + +JSON_KEY = 'proofs' +FS_KEY = 'cbmc-batch.yaml' + +def find_proofs_in_json_file(filename): + """Read the list of folders containing proofs from a json file.""" + + if not filename: + return [] + try: + with open(filename) as proofs: + return json.load(proofs)[JSON_KEY] + except (FileNotFoundError, KeyError): + raise UserWarning("Can't find key {} in json file {}".format(JSON_KEY, filename)) + except json.decoder.JSONDecodeError: + raise UserWarning("Can't parse json file {}".format(filename)) + +def find_proofs_in_filesystem(): + """Locate the folders containing proofs in the filesystem.""" + + proofs = [] + for root, _, files in os.walk('.'): + if FS_KEY in files: + proofs.append(os.path.normpath(root)) + return proofs + +################################################################ +# The strings used to write sections of the ninja file + +NINJA_RULES = """ +################################################################ +# task pool to force sequential builds of goto binaries + +pool goto_pool + depth = 1 + +################################################################ +# proof target rules + +rule build_json + command = cd ${folder} && make sources.json + pool = goto_pool + +rule build_goto + command = cd ${folder} && make goto + pool = goto_pool + +rule build_cbmc + command = cd ${folder} && make cbmc.xml + +rule build_coverage + command = cd ${folder} && make coverage + +rule build_property + command = cd ${folder} && make property + +rule build_report + command = cd ${folder} && make report2 + +rule clean_folder + command = cd ${folder} && make clean2 + +rule veryclean_folder + command = cd ${folder} && make veryclean2 + +rule open_proof + command = open ${folder}/html/index.html + +""" + +NINJA_BUILDS = """ +################################################################ +# {folder} proof targets + +build {folder}/sources.json: build_json + folder={folder} + +build {folder}/{entry}.goto: build_goto + folder={folder} + +build {folder}/cbmc.xml: build_cbmc {folder}/{entry}.goto + folder={folder} + +build {folder}/coverage.xml: build_coverage {folder}/{entry}.goto + folder={folder} + +build {folder}/property.xml: build_property {folder}/{entry}.goto + folder={folder} + +build {folder}/html/index.html: build_report {folder}/sources.json {folder}/{entry}.goto {folder}/cbmc.xml {folder}/coverage.xml {folder}/property.xml + folder={folder} + +build json_{folder}: phony {folder}/sources.json + +build goto_{folder}: phony {folder}/{entry}.goto + +build cbmc_{folder}: phony {folder}/cbmc.xml + +build property_{folder}: phony {folder}/property.xml + +build coverage_{folder}: phony {folder}/html/index.html + +build report_{folder}: phony {folder}/cbmc.xml + +build clean_{folder}: clean_folder + folder={folder} + +build veryclean_{folder}: veryclean_folder + folder={folder} + +build open_{folder}: open_proof + folder={folder} + +build {folder}: phony {folder}/html/index.html + +default {folder} + +""" + +NINJA_GLOBALS = """ +################################################################ +# global targets + +build json: phony {json_targets} + +build goto: phony {goto_targets} + +build cbmc: phony {cbmc_targets} + +build property: phony {property_targets} + +build coverage: phony {coverage_targets} + +build report: phony {report_targets} + +build clean: phony {clean_targets} + +build veryclean: phony {veryclean_targets} + +build open: phony {open_targets} + +build fast: phony {fast_targets} + +build slow: phony {slow_targets} + +""" + +################################################################ +# The main function + +def get_entry(folder): + """Find the name of the proof in the proof Makefile.""" + + with open('{}/Makefile'.format(folder)) as makefile: + for line in makefile: + if line.strip().lower().startswith('entry'): + return line[line.find('=')+1:].strip() + if line.strip().lower().startswith('h_entry'): + return line[line.find('=')+1:].strip() + raise UserWarning("Can't find ENTRY in {}/Makefile".format(folder)) + +def write_ninja_build_file(): + """Write a ninja build file to generate proof results.""" + + if platform.system().lower() == 'windows': + print("This script does not run on Windows.") + sys.exit() + + args = argument_parser().parse_args() + + proofs = (PROOFS or + args.folders or + find_proofs_in_json_file(args.proofs) or + find_proofs_in_filesystem()) + + with open('build.ninja', 'w') as ninja: + ninja.write(NINJA_RULES) + for proof in proofs: + entry = get_entry(proof) + ninja.write(NINJA_BUILDS.format(folder=proof, entry=entry)) + targets = lambda kind, folders: ' '.join( + ['{}_{}'.format(kind, folder) for folder in folders] + ) + slow = [ + 'IotMqtt_Connect', + 'IotMqtt_Disconnect', + 'IotMqtt_ReceiveCallback', + 'IotMqtt_UnsubscribeSync' + ] + fast = [proof for proof in proofs if proof not in slow] + ninja.write(NINJA_GLOBALS.format( + json_targets=targets('json', proofs), + goto_targets=targets('goto', proofs), + cbmc_targets=targets('cbmc', proofs), + property_targets=targets('property', proofs), + coverage_targets=targets('coverage', proofs), + report_targets=targets('report', proofs), + clean_targets=targets('clean', proofs), + veryclean_targets=targets('veryclean', proofs), + open_targets=targets('open', proofs), + fast_targets=' '.join(fast), + slow_targets=' '.join(slow) + )) + +################################################################ + +if __name__ == "__main__": + write_ninja_build_file() diff --git a/cbmc/proofs/prepare.py b/cbmc/proofs/prepare.py index dd0fd385d4..bdbd6e5b36 100755 --- a/cbmc/proofs/prepare.py +++ b/cbmc/proofs/prepare.py @@ -22,6 +22,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import argparse import logging import os import pathlib @@ -31,6 +32,71 @@ from make_cbmc_batch_files import create_cbmc_yaml_files +################################################################ +# Argument parsing + +def command_line_arguments(): + """Define command line arguments.""" + + parser = argparse.ArgumentParser( + description='Prepare MQTT source tree for CBMC proofs.' + ) + + parser.add_argument( + '--patches', + action='store_true', + default=True, + help='Apply patches to MQTT source tree to run proofs.' + ) + parser.add_argument( + '--no-patches', + action='store_false', + dest='patches', + help='Apply patches to MQTT source tree to run proofs.' + ) + parser.add_argument( + '--yamls', + action='store_true', + default=True, + help='Generate cbmc-batch.yaml files to run proofs in CI.' + ) + parser.add_argument( + '--no-yamls', + action='store_false', + dest='yamls', + help='Generate cbmc-batch.yaml files to run proofs in CI.' + ) + + parser.add_argument( + '--verbose', + action='store_true', + help='Verbose output.' + ) + parser.add_argument( + '--debug', + action='store_true', + help='Debugging output.' + ) + + args = parser.parse_args() + + # Only the first invocation of basicConfig configures the root logger + if args.debug: + logging.basicConfig( + level=logging.DEBUG, + format="{script}: %(levelname)s %(message)s".format( + script=os.path.basename(__file__))) + if args.verbose: + logging.basicConfig( + level=logging.INFO, + format="{script}: %(levelname)s %(message)s".format( + script=os.path.basename(__file__))) + logging.basicConfig(format="{script}: %(levelname)s %(message)s".format( + script=os.path.basename(__file__))) + + return args + +################################################################ def apply_patches(): patch_dir = pathlib.Path(__file__).resolve().parent.parent / "patches" @@ -70,17 +136,22 @@ def apply_patches(): def build(): try: create_cbmc_yaml_files() - except subprocess.CalledProcessError as e: + except subprocess.CalledProcessError as error: logging.error(textwrap.dedent("""\ An error occured during cbmc-batch generation. The error message is: {} - """.format(str(e)))) + """.format(str(error)))) exit(1) ################################################################ +def main(): + args = command_line_arguments() + + if args.yamls: + build() + if args.patches: + apply_patches() + if __name__ == '__main__': - logging.basicConfig(format="{script}: %(levelname)s %(message)s".format( - script=os.path.basename(__file__))) - build() - apply_patches() + main() From fab0df74d6f8849ff74c732bc74b352abbf325eb Mon Sep 17 00:00:00 2001 From: markrtuttle Date: Sat, 18 Apr 2020 00:28:45 -0400 Subject: [PATCH 09/41] Build CBMC binaries out of source for concurrent proof checking (#878) * Add out-of-source builds for CBMC goto binaries * Modify CBMC ninja builds to elminate task pools * Add whitespace to CBMC Makefile.common Co-authored-by: Mark R Tuttle --- cbmc/proofs/Makefile.common | 27 ++++++++++++++++++++++++--- cbmc/proofs/ninja.py | 12 ++---------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/cbmc/proofs/Makefile.common b/cbmc/proofs/Makefile.common index 4664695fc9..d8e016318d 100644 --- a/cbmc/proofs/Makefile.common +++ b/cbmc/proofs/Makefile.common @@ -51,15 +51,35 @@ CFLAGS += $(CFLAGS2) $(INC) $(DEF) -std=gnu99 NONDET += --nondet-static -%.goto : %.c +# Out of source builds +# +# Proof makefiles were originally written using in-source builds, but +# this inhibits building and running proofs concurrently when +# different proofs build sources with different configurations. These +# definitions assume $(OBJS) is the original list of in-source goto +# binaries and defines $(GOTOS) to be the list of out-of-source goto +# binaries written into the local gotos subdirectory. + +SRCS=$(patsubst %.goto,%.c,$(patsubst $(MQTT)/%,%,$(OBJS))) +GOTO_DIR=gotos +GOTOS=$(patsubst %.c,$(GOTO_DIR)/%.goto,$(SRCS)) + +# Build sources in the source tree with full paths +$(GOTO_DIR)/%.goto: $(MQTT)/%.c + mkdir -p $(dir $@) + $(GOTO_CC) -o $@ $(CFLAGS) $< + +# build sources in the local directory with relative paths +$(GOTO_DIR)/%.goto: ./%.c + mkdir -p $(dir $@) $(GOTO_CC) -o $@ $(CFLAGS) $< $(MQTT)/build: (mkdir -p $(MQTT)/build; cd $(MQTT)/build; cmake ..) \ > $(ENTRY)0.txt 2>&1 -$(ENTRY)1.goto: $(MQTT)/build $(OBJS) - $(GOTO_CC) --function harness -o $@ $(OBJS) \ +$(ENTRY)1.goto: $(MQTT)/build $(GOTOS) + $(GOTO_CC) --function harness -o $@ $(GOTOS) \ > $(ENTRY)1.txt 2>&1 $(ENTRY)2.goto: $(ENTRY)1.goto @@ -144,6 +164,7 @@ report: cbmc.txt property.xml coverage.xml clean: $(RM) $(OBJS) $(ENTRY).goto $(RM) $(ENTRY)[0-9].goto $(ENTRY)[0-9].txt + $(RM) -r $(GOTO_DIR) $(RM) cbmc.txt property.xml coverage.xml TAGS TAGS-* $(RM) *~ \#* diff --git a/cbmc/proofs/ninja.py b/cbmc/proofs/ninja.py index 544f749b30..6ad33ccd3a 100755 --- a/cbmc/proofs/ninja.py +++ b/cbmc/proofs/ninja.py @@ -90,22 +90,14 @@ def find_proofs_in_filesystem(): # The strings used to write sections of the ninja file NINJA_RULES = """ -################################################################ -# task pool to force sequential builds of goto binaries - -pool goto_pool - depth = 1 - ################################################################ # proof target rules rule build_json command = cd ${folder} && make sources.json - pool = goto_pool rule build_goto - command = cd ${folder} && make goto - pool = goto_pool + command = cd ${folder} && make sources.json && make goto rule build_cbmc command = cd ${folder} && make cbmc.xml @@ -149,7 +141,7 @@ def find_proofs_in_filesystem(): build {folder}/property.xml: build_property {folder}/{entry}.goto folder={folder} -build {folder}/html/index.html: build_report {folder}/sources.json {folder}/{entry}.goto {folder}/cbmc.xml {folder}/coverage.xml {folder}/property.xml +build {folder}/html/index.html: build_report {folder}/{entry}.goto {folder}/cbmc.xml {folder}/coverage.xml {folder}/property.xml folder={folder} build json_{folder}: phony {folder}/sources.json From 5b246cc2580a867ba47fc81c4cbe311d94f76924 Mon Sep 17 00:00:00 2001 From: "Felipe R. Monteiro" Date: Sat, 18 Apr 2020 02:57:33 -0400 Subject: [PATCH 10/41] All cbmc-batch.yaml are automatically generated during CI (#879) Signed-off-by: Felipe R. Monteiro --- cbmc/.gitignore | 1 + cbmc/proofs/IotMqtt_Cleanup/cbmc-batch.yaml | 6 ++---- cbmc/proofs/IotMqtt_DeserializeConnack/cbmc-batch.yaml | 6 ++---- .../proofs/IotMqtt_DeserializePingresp/cbmc-batch.yaml | 6 ++---- cbmc/proofs/IotMqtt_DeserializePuback/cbmc-batch.yaml | 6 ++---- cbmc/proofs/IotMqtt_DeserializePublish/cbmc-batch.yaml | 6 ++---- cbmc/proofs/IotMqtt_DeserializeSuback/cbmc-batch.yaml | 6 ++---- .../proofs/IotMqtt_DeserializeUnsuback/cbmc-batch.yaml | 6 ++---- cbmc/proofs/IotMqtt_Disconnect/cbmc-batch.yaml | 2 +- cbmc/proofs/IotMqtt_Init/cbmc-batch.yaml | 6 ++---- cbmc/proofs/IotMqtt_IsSubscribed/cbmc-batch.yaml | 6 ++---- cbmc/proofs/IotMqtt_OperationType/cbmc-batch.yaml | 6 ++---- cbmc/proofs/IotMqtt_PublishAsync/cbmc-batch.yaml | 6 ++---- cbmc/proofs/IotMqtt_PublishSync/cbmc-batch.yaml | 6 ++---- .../IotMqtt_ReceiveCallback_CONNACK/cbmc-batch.yaml | 10 ++-------- .../IotMqtt_ReceiveCallback_OTHER/cbmc-batch.yaml | 10 ++-------- .../IotMqtt_ReceiveCallback_PUBACK/cbmc-batch.yaml | 10 ++-------- .../IotMqtt_ReceiveCallback_PUBLISH/cbmc-batch.yaml | 10 ++-------- .../IotMqtt_ReceiveCallback_SUBACK/cbmc-batch.yaml | 10 ++-------- .../IotMqtt_ReceiveCallback_UNSUBACK/cbmc-batch.yaml | 10 ++-------- cbmc/proofs/IotMqtt_SubscribeAsync/cbmc-batch.yaml | 10 ++-------- cbmc/proofs/IotMqtt_UnsubscribeAsync/cbmc-batch.yaml | 2 +- cbmc/proofs/IotMqtt_UnsubscribeSync/cbmc-batch.yaml | 2 +- cbmc/proofs/IotMqtt_Wait/cbmc-batch.yaml | 6 ++---- cbmc/proofs/IotMqtt_strerror/cbmc-batch.yaml | 6 ++---- 25 files changed, 46 insertions(+), 115 deletions(-) diff --git a/cbmc/.gitignore b/cbmc/.gitignore index 7d4e335f3e..28560c9fd8 100644 --- a/cbmc/.gitignore +++ b/cbmc/.gitignore @@ -4,3 +4,4 @@ __pycache__ .ninja_deps .ninja_log build.ninja +*.yaml diff --git a/cbmc/proofs/IotMqtt_Cleanup/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_Cleanup/cbmc-batch.yaml index a4d18f6094..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_Cleanup/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_Cleanup/cbmc-batch.yaml @@ -1,4 +1,2 @@ -jobos: ubuntu16 -cbmcflags: '=--unwind;1;--bounds-check;--pointer-check;--unwinding-assertions;--nondet-static=' -goto: IotMqtt_Cleanup.goto -expected: SUCCESSFUL +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_DeserializeConnack/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_DeserializeConnack/cbmc-batch.yaml index dc42695b88..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_DeserializeConnack/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_DeserializeConnack/cbmc-batch.yaml @@ -1,4 +1,2 @@ -cbmcflags: "--object-bits;8;--bounds-check;--pointer-check;--unwinding-assertions;--nondet-static;--div-by-zero-check;--float-overflow-check;--nan-check;--pointer-overflow-check;--undefined-shift-check;--signed-overflow-check;--unsigned-overflow-check;--flush" -expected: SUCCESSFUL -goto: _IotMqtt_DeserializeConnack.goto -jobos: ubuntu16 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_DeserializePingresp/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_DeserializePingresp/cbmc-batch.yaml index 032b39a1c5..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_DeserializePingresp/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_DeserializePingresp/cbmc-batch.yaml @@ -1,4 +1,2 @@ -cbmcflags: "--object-bits;8;--bounds-check;--pointer-check;--unwinding-assertions;--nondet-static;--div-by-zero-check;--float-overflow-check;--nan-check;--pointer-overflow-check;--undefined-shift-check;--signed-overflow-check;--unsigned-overflow-check;--flush" -expected: SUCCESSFUL -goto: _IotMqtt_DeserializePingresp.goto -jobos: ubuntu16 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_DeserializePuback/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_DeserializePuback/cbmc-batch.yaml index 87c3065c33..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_DeserializePuback/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_DeserializePuback/cbmc-batch.yaml @@ -1,4 +1,2 @@ -cbmcflags: "--object-bits;8;--bounds-check;--pointer-check;--unwinding-assertions;--nondet-static;--div-by-zero-check;--float-overflow-check;--nan-check;--pointer-overflow-check;--undefined-shift-check;--signed-overflow-check;--unsigned-overflow-check;--flush" -expected: SUCCESSFUL -goto: _IotMqtt_DeserializePuback.goto -jobos: ubuntu16 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_DeserializePublish/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_DeserializePublish/cbmc-batch.yaml index 81b52871a8..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_DeserializePublish/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_DeserializePublish/cbmc-batch.yaml @@ -1,4 +1,2 @@ -cbmcflags: "--object-bits;8;--bounds-check;--pointer-check;--unwinding-assertions;--nondet-static;--div-by-zero-check;--float-overflow-check;--nan-check;--pointer-overflow-check;--undefined-shift-check;--signed-overflow-check;--unsigned-overflow-check;--flush" -expected: SUCCESSFUL -goto: _IotMqtt_DeserializePublish.goto -jobos: ubuntu16 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_DeserializeSuback/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_DeserializeSuback/cbmc-batch.yaml index fefaa22dba..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_DeserializeSuback/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_DeserializeSuback/cbmc-batch.yaml @@ -1,4 +1,2 @@ -cbmcflags: "--object-bits;8;--unwind;1;--unwindset;valid_IotMqttSubscriptionList.0:2,valid_IotMqttOperationList.0:2,_decodeSubackStatus.0:15;--bounds-check;--pointer-check;--unwinding-assertions;--nondet-static;--div-by-zero-check;--float-overflow-check;--nan-check;--pointer-overflow-check;--undefined-shift-check;--signed-overflow-check;--unsigned-overflow-check;--flush" -expected: SUCCESSFUL -goto: _IotMqtt_DeserializeSuback.goto -jobos: ubuntu16 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_DeserializeUnsuback/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_DeserializeUnsuback/cbmc-batch.yaml index 10adae41b1..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_DeserializeUnsuback/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_DeserializeUnsuback/cbmc-batch.yaml @@ -1,4 +1,2 @@ -cbmcflags: "--object-bits;8;--bounds-check;--pointer-check;--unwinding-assertions;--nondet-static;--div-by-zero-check;--float-overflow-check;--nan-check;--pointer-overflow-check;--undefined-shift-check;--signed-overflow-check;--unsigned-overflow-check;--flush" -expected: SUCCESSFUL -goto: _IotMqtt_DeserializeUnsuback.goto -jobos: ubuntu16 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_Disconnect/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_Disconnect/cbmc-batch.yaml index 87089222ce..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_Disconnect/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_Disconnect/cbmc-batch.yaml @@ -1,2 +1,2 @@ # This file marks this directory as containing a CBMC proof. -# The contents of this file will be generated by continuous integration. \ No newline at end of file +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_Init/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_Init/cbmc-batch.yaml index 0233491a13..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_Init/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_Init/cbmc-batch.yaml @@ -1,4 +1,2 @@ -cbmcflags: "--object-bits;8;--unwind;1;--bounds-check;--pointer-check;--unwinding-assertions;--nondet-static;--div-by-zero-check;--float-overflow-check;--nan-check;--pointer-overflow-check;--undefined-shift-check;--signed-overflow-check;--unsigned-overflow-check" -expected: SUCCESSFUL -goto: IotMqtt_Init.goto -jobos: ubuntu16 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_IsSubscribed/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_IsSubscribed/cbmc-batch.yaml index a6b1ba20e3..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_IsSubscribed/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_IsSubscribed/cbmc-batch.yaml @@ -1,4 +1,2 @@ -jobos: ubuntu16 -cbmcflags: "--object-bits;8;--unwind;1;--unwindset;allocate_IotMqttSubscriptionArray.0:4,valid_IotMqttSubscriptionArray.0:4,allocate_IotMqttSubscriptionList.0:4,valid_IotMqttSubscriptionList.0:4,valid_IotMqttOperationList.0:4,IotListDouble_FindFirstMatch$link1.0:4,strncmp.0:6;--bounds-check;--pointer-check;--unwinding-assertions;--nondet-static;--div-by-zero-check;--float-overflow-check;--nan-check;--pointer-overflow-check;--undefined-shift-check;--signed-overflow-check;--unsigned-overflow-check" -goto: IotMqtt_IsSubscribed.goto -expected: SUCCESSFUL +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_OperationType/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_OperationType/cbmc-batch.yaml index 61f0662cfb..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_OperationType/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_OperationType/cbmc-batch.yaml @@ -1,4 +1,2 @@ -cbmcflags: "--object-bits;8;--bounds-check;--pointer-check;--unwinding-assertions;--nondet-static;--div-by-zero-check;--float-overflow-check;--nan-check;--pointer-overflow-check;--undefined-shift-check;--signed-overflow-check;--unsigned-overflow-check" -expected: SUCCESSFUL -goto: IotMqtt_OperationType.goto -jobos: ubuntu16 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_PublishAsync/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_PublishAsync/cbmc-batch.yaml index 0b28bbe6b7..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_PublishAsync/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_PublishAsync/cbmc-batch.yaml @@ -1,4 +1,2 @@ -cbmcflags: "--object-bits;8;--unwind;1;--unwindset;IotListDouble_RemoveAllMatches.0:4,valid_IotMqttSubscriptionList.0:4,valid_IotMqttOperationList.0:4,_encodeRemainingLength.0:4;--bounds-check;--pointer-check;--unwinding-assertions;--nondet-static;--div-by-zero-check;--float-overflow-check;--nan-check;--pointer-overflow-check;--undefined-shift-check;--signed-overflow-check;--unsigned-overflow-check;--flush" -expected: SUCCESSFUL -goto: IotMqtt_PublishAsync.goto -jobos: ubuntu16 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_PublishSync/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_PublishSync/cbmc-batch.yaml index 8fe378dfcd..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_PublishSync/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_PublishSync/cbmc-batch.yaml @@ -1,4 +1,2 @@ -cbmcflags: "--object-bits;8;--unwind;1;--unwindset;_encodeRemainingLength.0:6,_IotMqtt_InvokeSubscriptionCallback.0:4,_matchWildcards.0:6,_topicFilterMatch.0:6,IotListDouble_RemoveAllMatches.0:4,IotListDouble_RemoveAllMatches.0:4,valid_IotMqttOperationList.0:4,valid_IotMqttSubscriptionList.0:4;--bounds-check;--conversion-check;--div-by-zero-check;--float-overflow-check;--flush;--nan-check;--nondet-static;--pointer-check;--pointer-overflow-check;--signed-overflow-check;--undefined-shift-check;--unsigned-overflow-check;--unwinding-assertions" -expected: SUCCESSFUL -goto: IotMqtt_PublishSync.goto -jobos: ubuntu16 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/cbmc-batch.yaml index 5fffb7e309..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_CONNACK/cbmc-batch.yaml @@ -1,8 +1,2 @@ -build_memory: 32000 -cbmcflags: "--flush;--object-bits;8;--unwind;1;--unwindset;IotListDouble_FindFirstMatch.0:2,IotListDouble_FindFirstMatch$link1.0:2,IotListDouble_FindFirstMatch$link2.0:2,IotListDouble_FindFirstMatch$link3.0:2,IotListDouble_FindFirstMatch$link4.0:2,IotListDouble_FindFirstMatch$link5.0:2,_IotMqtt_GetRemainingLength.0:5,_decodeSubackStatus.0:15,valid_IotMqttOperationList.0:2,valid_IotMqttSubscriptionList.0:2;--object-bits;8;--bounds-check;--conversion-check;--div-by-zero-check;--float-overflow-check;--flush;--nan-check;--pointer-check;--pointer-overflow-check;--signed-overflow-check;--undefined-shift-check;--unsigned-overflow-check;--unwinding-assertions" -coverage_memory: 32000 -expected: SUCCESSFUL -goto: IotMqtt_ReceiveCallback.goto -jobos: ubuntu16 -property_memory: 32000 -report_memory: 32000 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/cbmc-batch.yaml index 5fffb7e309..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_OTHER/cbmc-batch.yaml @@ -1,8 +1,2 @@ -build_memory: 32000 -cbmcflags: "--flush;--object-bits;8;--unwind;1;--unwindset;IotListDouble_FindFirstMatch.0:2,IotListDouble_FindFirstMatch$link1.0:2,IotListDouble_FindFirstMatch$link2.0:2,IotListDouble_FindFirstMatch$link3.0:2,IotListDouble_FindFirstMatch$link4.0:2,IotListDouble_FindFirstMatch$link5.0:2,_IotMqtt_GetRemainingLength.0:5,_decodeSubackStatus.0:15,valid_IotMqttOperationList.0:2,valid_IotMqttSubscriptionList.0:2;--object-bits;8;--bounds-check;--conversion-check;--div-by-zero-check;--float-overflow-check;--flush;--nan-check;--pointer-check;--pointer-overflow-check;--signed-overflow-check;--undefined-shift-check;--unsigned-overflow-check;--unwinding-assertions" -coverage_memory: 32000 -expected: SUCCESSFUL -goto: IotMqtt_ReceiveCallback.goto -jobos: ubuntu16 -property_memory: 32000 -report_memory: 32000 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/cbmc-batch.yaml index 5fffb7e309..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBACK/cbmc-batch.yaml @@ -1,8 +1,2 @@ -build_memory: 32000 -cbmcflags: "--flush;--object-bits;8;--unwind;1;--unwindset;IotListDouble_FindFirstMatch.0:2,IotListDouble_FindFirstMatch$link1.0:2,IotListDouble_FindFirstMatch$link2.0:2,IotListDouble_FindFirstMatch$link3.0:2,IotListDouble_FindFirstMatch$link4.0:2,IotListDouble_FindFirstMatch$link5.0:2,_IotMqtt_GetRemainingLength.0:5,_decodeSubackStatus.0:15,valid_IotMqttOperationList.0:2,valid_IotMqttSubscriptionList.0:2;--object-bits;8;--bounds-check;--conversion-check;--div-by-zero-check;--float-overflow-check;--flush;--nan-check;--pointer-check;--pointer-overflow-check;--signed-overflow-check;--undefined-shift-check;--unsigned-overflow-check;--unwinding-assertions" -coverage_memory: 32000 -expected: SUCCESSFUL -goto: IotMqtt_ReceiveCallback.goto -jobos: ubuntu16 -property_memory: 32000 -report_memory: 32000 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/cbmc-batch.yaml index 5fffb7e309..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_PUBLISH/cbmc-batch.yaml @@ -1,8 +1,2 @@ -build_memory: 32000 -cbmcflags: "--flush;--object-bits;8;--unwind;1;--unwindset;IotListDouble_FindFirstMatch.0:2,IotListDouble_FindFirstMatch$link1.0:2,IotListDouble_FindFirstMatch$link2.0:2,IotListDouble_FindFirstMatch$link3.0:2,IotListDouble_FindFirstMatch$link4.0:2,IotListDouble_FindFirstMatch$link5.0:2,_IotMqtt_GetRemainingLength.0:5,_decodeSubackStatus.0:15,valid_IotMqttOperationList.0:2,valid_IotMqttSubscriptionList.0:2;--object-bits;8;--bounds-check;--conversion-check;--div-by-zero-check;--float-overflow-check;--flush;--nan-check;--pointer-check;--pointer-overflow-check;--signed-overflow-check;--undefined-shift-check;--unsigned-overflow-check;--unwinding-assertions" -coverage_memory: 32000 -expected: SUCCESSFUL -goto: IotMqtt_ReceiveCallback.goto -jobos: ubuntu16 -property_memory: 32000 -report_memory: 32000 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/cbmc-batch.yaml index 5fffb7e309..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_SUBACK/cbmc-batch.yaml @@ -1,8 +1,2 @@ -build_memory: 32000 -cbmcflags: "--flush;--object-bits;8;--unwind;1;--unwindset;IotListDouble_FindFirstMatch.0:2,IotListDouble_FindFirstMatch$link1.0:2,IotListDouble_FindFirstMatch$link2.0:2,IotListDouble_FindFirstMatch$link3.0:2,IotListDouble_FindFirstMatch$link4.0:2,IotListDouble_FindFirstMatch$link5.0:2,_IotMqtt_GetRemainingLength.0:5,_decodeSubackStatus.0:15,valid_IotMqttOperationList.0:2,valid_IotMqttSubscriptionList.0:2;--object-bits;8;--bounds-check;--conversion-check;--div-by-zero-check;--float-overflow-check;--flush;--nan-check;--pointer-check;--pointer-overflow-check;--signed-overflow-check;--undefined-shift-check;--unsigned-overflow-check;--unwinding-assertions" -coverage_memory: 32000 -expected: SUCCESSFUL -goto: IotMqtt_ReceiveCallback.goto -jobos: ubuntu16 -property_memory: 32000 -report_memory: 32000 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/cbmc-batch.yaml index 5fffb7e309..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/IotMqtt_ReceiveCallback_UNSUBACK/cbmc-batch.yaml @@ -1,8 +1,2 @@ -build_memory: 32000 -cbmcflags: "--flush;--object-bits;8;--unwind;1;--unwindset;IotListDouble_FindFirstMatch.0:2,IotListDouble_FindFirstMatch$link1.0:2,IotListDouble_FindFirstMatch$link2.0:2,IotListDouble_FindFirstMatch$link3.0:2,IotListDouble_FindFirstMatch$link4.0:2,IotListDouble_FindFirstMatch$link5.0:2,_IotMqtt_GetRemainingLength.0:5,_decodeSubackStatus.0:15,valid_IotMqttOperationList.0:2,valid_IotMqttSubscriptionList.0:2;--object-bits;8;--bounds-check;--conversion-check;--div-by-zero-check;--float-overflow-check;--flush;--nan-check;--pointer-check;--pointer-overflow-check;--signed-overflow-check;--undefined-shift-check;--unsigned-overflow-check;--unwinding-assertions" -coverage_memory: 32000 -expected: SUCCESSFUL -goto: IotMqtt_ReceiveCallback.goto -jobos: ubuntu16 -property_memory: 32000 -report_memory: 32000 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_SubscribeAsync/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_SubscribeAsync/cbmc-batch.yaml index 16b101ea1f..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_SubscribeAsync/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_SubscribeAsync/cbmc-batch.yaml @@ -1,8 +1,2 @@ -build_memory: 32000 -cbmcflags: "--object-bits;8;--unwind;1;--unwindset;_IotMqtt_AddSubscriptions.0:3,_IotMqtt_SerializeSubscribeCommon.0:3,_IotMqtt_SubscriptionPacketSize.0:3,_IotMqtt_ValidateSubscriptionList.0:3,_validateSubscription.0:6,allocate_IotMqttSubscriptionArray.0:2,allocate_IotMqttSubscriptionList.0:2,IotListDouble_FindFirstMatch.0:3,IotListDouble_FindFirstMatch$link1.0:2,IotListDouble_RemoveAllMatches.0:3,IotListDouble_RemoveAllMatches$link1.0:3,strncmp.0:6,valid_IotMqttOperationList.0:2,valid_IotMqttSubscriptionArray.0:2,valid_IotMqttSubscriptionList.0:2;--object-bits;8;--bounds-check;--conversion-check;--div-by-zero-check;--float-overflow-check;--flush;--nan-check;--nondet-static;--pointer-check;--pointer-overflow-check;--signed-overflow-check;--undefined-shift-check;--unsigned-overflow-check;--unwinding-assertions" -coverage_memory: 32000 -expected: SUCCESSFUL -goto: IotMqtt_SubscribeAsync.goto -jobos: ubuntu16 -property_memory: 32000 -report_memory: 32000 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_UnsubscribeAsync/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_UnsubscribeAsync/cbmc-batch.yaml index 87089222ce..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_UnsubscribeAsync/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_UnsubscribeAsync/cbmc-batch.yaml @@ -1,2 +1,2 @@ # This file marks this directory as containing a CBMC proof. -# The contents of this file will be generated by continuous integration. \ No newline at end of file +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_UnsubscribeSync/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_UnsubscribeSync/cbmc-batch.yaml index 87089222ce..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_UnsubscribeSync/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_UnsubscribeSync/cbmc-batch.yaml @@ -1,2 +1,2 @@ # This file marks this directory as containing a CBMC proof. -# The contents of this file will be generated by continuous integration. \ No newline at end of file +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_Wait/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_Wait/cbmc-batch.yaml index 4c2535b0ae..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_Wait/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_Wait/cbmc-batch.yaml @@ -1,4 +1,2 @@ -cbmcflags: "--object-bits;8;--unwind;1;--unwindset;valid_IotMqttSubscriptionList.0:4,valid_IotMqttOperationList.0:4,IotListDouble_RemoveAllMatches.0:4;--bounds-check;--pointer-check;--unwinding-assertions;--nondet-static;--div-by-zero-check;--float-overflow-check;--nan-check;--pointer-overflow-check;--undefined-shift-check;--signed-overflow-check;--unsigned-overflow-check" -expected: SUCCESSFUL -goto: IotMqtt_Wait.goto -jobos: ubuntu16 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. diff --git a/cbmc/proofs/IotMqtt_strerror/cbmc-batch.yaml b/cbmc/proofs/IotMqtt_strerror/cbmc-batch.yaml index 3b3467c140..7eeb12ad71 100644 --- a/cbmc/proofs/IotMqtt_strerror/cbmc-batch.yaml +++ b/cbmc/proofs/IotMqtt_strerror/cbmc-batch.yaml @@ -1,4 +1,2 @@ -cbmcflags: "--object-bits;8;--bounds-check;--pointer-check;--unwinding-assertions;--nondet-static;--div-by-zero-check;--float-overflow-check;--nan-check;--pointer-overflow-check;--undefined-shift-check;--signed-overflow-check;--unsigned-overflow-check" -expected: SUCCESSFUL -goto: IotMqtt_strerror.goto -jobos: ubuntu16 +# This file marks this directory as containing a CBMC proof. +# The contents of this file will be generated by continuous integration. From 5943fbcda9621906955253cafb734ed12ec33264 Mon Sep 17 00:00:00 2001 From: Gaurav Aggarwal Date: Sun, 26 Apr 2020 17:17:39 -0700 Subject: [PATCH 11/41] Log error when re-scheduling of the metrics job fails This was reported as the dead assignment using the clang static analysis tools as mentioned here: https://github.com/aws/aws-iot-device-sdk-embedded-C/issues/883 Signed-off-by: Gaurav Aggarwal --- libraries/aws/defender/src/aws_iot_defender_api.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/aws/defender/src/aws_iot_defender_api.c b/libraries/aws/defender/src/aws_iot_defender_api.c index 07cb6fe4f3..61612d711d 100644 --- a/libraries/aws/defender/src/aws_iot_defender_api.c +++ b/libraries/aws/defender/src/aws_iot_defender_api.c @@ -504,6 +504,11 @@ static void _metricsPublishRoutine( IotTaskPool_t pTaskPool, { /* Re-schedule metrics job with period as deferred interval. */ taskPoolError = IotTaskPool_ScheduleDeferred( IOT_SYSTEM_TASKPOOL, _metricsPublishJob, _periodMilliSecond ); + + if( taskPoolError != IOT_TASKPOOL_SUCCESS ) + { + IotLogError( "Failed to re-schedule the metrics job. Error: %s.", IotTaskPool_strerror( taskPoolError ) ); + } } /* Give Done semaphore so AwsIotDefender_Stop() can proceed */ From 3358a94f62edca1d02635918a0e6503dbc81960c Mon Sep 17 00:00:00 2001 From: "Felipe R. Monteiro" Date: Tue, 28 Apr 2020 15:40:37 -0400 Subject: [PATCH 12/41] Update harness for IotMqtt_PublishAsync function (#887) Signed-off-by: Felipe R. Monteiro --- .../IotMqtt_PublishAsync_harness.c | 155 ++++++++++++------ cbmc/proofs/IotMqtt_PublishAsync/Makefile | 23 ++- cbmc/proofs/IotMqtt_PublishAsync/README.md | 71 ++++++++ .../IotMqtt_PublishAsync/cbmc-viewer.json | 9 +- 4 files changed, 199 insertions(+), 59 deletions(-) create mode 100644 cbmc/proofs/IotMqtt_PublishAsync/README.md diff --git a/cbmc/proofs/IotMqtt_PublishAsync/IotMqtt_PublishAsync_harness.c b/cbmc/proofs/IotMqtt_PublishAsync/IotMqtt_PublishAsync_harness.c index 00c6189551..3f7f8424b0 100644 --- a/cbmc/proofs/IotMqtt_PublishAsync/IotMqtt_PublishAsync_harness.c +++ b/cbmc/proofs/IotMqtt_PublishAsync/IotMqtt_PublishAsync_harness.c @@ -1,3 +1,30 @@ +/* + * IoT MQTT V2.1.0 + * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file IotMqtt_PublishAsync_harness.c + * @brief Implements the proof harness for IotMqtt_PublishAsync function. + */ + #include "iot_config.h" #include "private/iot_mqtt_internal.h" @@ -6,83 +33,115 @@ #include "mqtt_state.h" +typedef bool ( * MatchFunction_t )( const IotLink_t * const pOperationLink, + void * pCompare ); + +typedef void ( * FreeElementFunction_t )( void * pData ); + /** - * We abstract all functions related to concurrency and assume they are correct. - * Thus, we add these stub to increase coverage. + * We constrain the return values of these functions because + * they are checked by assertions in the MQTT code. */ IotTaskPoolError_t IotTaskPool_CreateJob( IotTaskPoolRoutine_t userCallback, void * pUserContext, IotTaskPoolJobStorage_t * const pJobStorage, IotTaskPoolJob_t * const pJob ) { - if (userCallback == NULL || pJobStorage == NULL || pJob == NULL) - { - return IOT_TASKPOOL_BAD_PARAMETER; - } - /* _IotMqtt_ScheduleOperation asserts this */ - return IOT_TASKPOOL_SUCCESS; + assert( userCallback != NULL ); + assert( pJobStorage != NULL ); + assert( pJob != NULL ); + + /* _IotMqtt_ScheduleOperation asserts this. */ + return IOT_TASKPOOL_SUCCESS; } IotTaskPoolError_t IotTaskPool_ScheduleDeferred( IotTaskPool_t taskPool, IotTaskPoolJob_t job, uint32_t timeMs ) { - IotTaskPoolError_t error; + IotTaskPoolError_t error; - /* _IotMqtt_ScheduleOperation asserts this */ - __CPROVER_assume(error != IOT_TASKPOOL_BAD_PARAMETER && - error != IOT_TASKPOOL_ILLEGAL_OPERATION); - return error; + /* _IotMqtt_ScheduleOperation asserts this */ + __CPROVER_assume( error != IOT_TASKPOOL_BAD_PARAMETER && + error != IOT_TASKPOOL_ILLEGAL_OPERATION ); + return error; } /** * _IotMqtt_NextPacketIdentifier calls Atomic_Add_u32, which receives * a volatile variable as input. Thus, CBMC will always consider that * Atomic_Add_u32 will operate over nondetermistic values and raises - * a unsigned integer overflow failure. However, developers have reported + * an unsigned integer overflow failure. However, developers have reported * that the use of this overflow is part of the function implementation. * In order to mirror _IotMqtt_NextPacketIdentifier behaviour and avoid * spurious alarms, we stub out this function to always * return a nondetermistic odd value. */ -uint16_t _IotMqtt_NextPacketIdentifier( void ) { - uint16_t id; +uint16_t _IotMqtt_NextPacketIdentifier( void ) +{ + uint16_t id; - /* Packet identifiers will follow the sequence 1,3,5...65535,1,3,5... */ - __CPROVER_assume(id & 0x0001 == 1); + /* Packet identifiers will follow the sequence 1,3,5...65535,1,3,5... */ + __CPROVER_assume( id & 0x0001 == 1 ); - return id; + return id; +} + +/** + * We assume the list remove functions are memory safe. + * + * We abstract the list remove functions for performance reasons. Our + * abstraction replaces the original list with an unconstrained list. + * Our abstraction proves that none of the elements on the original + * list are accessed after the remove: We free all elements on the + * original list, so that any later access will be caught as a + * use-after-free error. + */ +void IotListDouble_RemoveAllMatches( const IotListDouble_t * const pList, + MatchFunction_t isMatch, + void * pMatch, + FreeElementFunction_t freeElement, + size_t linkOffset ) +{ + free_IotMqttSubscriptionList( pList ); + allocate_IotMqttSubscriptionList( pList, SUBSCRIPTION_COUNT_MAX - 1 ); } void harness() { - /* assume a valid MQTT connection */ - IotMqttConnection_t mqttConnection = allocate_IotMqttConnection(NULL); - __CPROVER_assume(mqttConnection != NULL); - __CPROVER_assume(mqttConnection->pNetworkInterface != NULL); - __CPROVER_assume( IS_STUBBED_NETWORKIF_SEND( mqttConnection->pNetworkInterface ) ); - ensure_IotMqttConnection_has_lists(mqttConnection); - __CPROVER_assume(valid_IotMqttConnection(mqttConnection)); - - /* assume a valid publish info */ - IotMqttPublishInfo_t *pPublishInfo = allocate_IotMqttPublishInfo(NULL); - if (pPublishInfo != NULL) __CPROVER_assume(valid_IotMqttPublishInfo(pPublishInfo)); - - /* assume unconstrained inputs */ - uint32_t flags; - IotMqttCallbackInfo_t *callbackInfo = malloc_can_fail(sizeof (*callbackInfo) ); - - /* output */ - IotMqttOperation_t *publishOperation = malloc_can_fail(sizeof (*publishOperation) ); - - - /* function under verification */ - IotMqttError_t status = IotMqtt_PublishAsync( mqttConnection, /* always assume a valid connection */ - pPublishInfo, - flags, - callbackInfo, - publishOperation ); - /* assert post-conditions */ - assert(IMPLIES(status == IOT_MQTT_STATUS_PENDING, pPublishInfo->qos == IOT_MQTT_QOS_1)); - assert(IMPLIES(status == IOT_MQTT_SUCCESS, pPublishInfo->qos == IOT_MQTT_QOS_0 || pPublishInfo->qos == IOT_MQTT_QOS_1)); + /* Assume a valid MQTT connection. */ + IotMqttConnection_t mqttConnection = allocate_IotMqttConnection( NULL ); + + __CPROVER_assume( mqttConnection != NULL ); + __CPROVER_assume( mqttConnection->pNetworkInterface != NULL ); + __CPROVER_assume( IS_STUBBED_NETWORKIF_SEND( mqttConnection->pNetworkInterface ) ); + __CPROVER_assume( IS_STUBBED_NETWORKIF_DESTROY( mqttConnection->pNetworkInterface ) ); + ensure_IotMqttConnection_has_lists( mqttConnection ); + __CPROVER_assume( valid_IotMqttConnection( mqttConnection ) ); + + + /* Assume a valid publish info. */ + IotMqttPublishInfo_t * pPublishInfo = allocate_IotMqttPublishInfo( NULL ); + __CPROVER_assume( IMPLIES( pPublishInfo != NULL, valid_IotMqttPublishInfo( pPublishInfo ) ) ); + + /* Assume unconstrained inputs. */ + uint32_t flags; + IotMqttCallbackInfo_t * callbackInfo = malloc_can_fail( sizeof( *callbackInfo ) ); + + /* Output. */ + IotMqttOperation_t * publishOperation = malloc_can_fail( sizeof( *publishOperation ) ); + + + /* Function under verification. */ + IotMqttError_t status = IotMqtt_PublishAsync( mqttConnection, + pPublishInfo, + flags, + callbackInfo, + publishOperation ); + /* Post-conditions. */ + assert( IMPLIES( status == IOT_MQTT_STATUS_PENDING, + pPublishInfo->qos == IOT_MQTT_QOS_1 ) ); + assert( IMPLIES( status == IOT_MQTT_SUCCESS, + pPublishInfo->qos == IOT_MQTT_QOS_0 || + pPublishInfo->qos == IOT_MQTT_QOS_1 ) ); } diff --git a/cbmc/proofs/IotMqtt_PublishAsync/Makefile b/cbmc/proofs/IotMqtt_PublishAsync/Makefile index b84411fc7c..bf691dbfa5 100644 --- a/cbmc/proofs/IotMqtt_PublishAsync/Makefile +++ b/cbmc/proofs/IotMqtt_PublishAsync/Makefile @@ -3,8 +3,10 @@ ENTRY=IotMqtt_PublishAsync # We abstract all the log and concurrency related functions in this proof # and assume their implementation is correct ABSTRACTIONS += --remove-function-body IotLog_Generic -ABSTRACTIONS += --remove-function-body _IotMqtt_ProcessSend -ABSTRACTIONS += --remove-function-body _destroyMqttConnection + +# We also abstract unreachable functions to improve coverage metrics +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceClose +ABSTRACTIONS += --remove-function-body IotNetworkInterfaceReceive OBJS += $(ENTRY)_harness.goto OBJS += $(MQTT)/cbmc/proofs/mqtt_state.goto @@ -22,10 +24,23 @@ DEF += -DSUBSCRIPTION_COUNT_MAX=$(SUBSCRIPTION_COUNT_MAX) OPERATION_COUNT_MAX=4 DEF += -DOPERATION_COUNT_MAX=$(OPERATION_COUNT_MAX) +# Enables CBMC stub for RemoveAllMatches function +DEF += -DCBMC_STUB_REMOVEALLMATCHES=1 + +# Allow MQTT allocations to fail for coverage +DEF += -include mqtt_state.h +DEF += -DIotMqtt_MallocMessage=malloc_can_fail +DEF += -DIotMqtt_MallocOperation=malloc_can_fail + +# The bound for _encodeRemainingLength is based on the maximum +# possible value for remainingLength, in this case, 2 * UINT16_MAX + 4 +# (see _IotMqtt_PublishPacketSize). Thus, the bound is the number of +# times the function must divide the maximum remainingLength +# value by 128 until hits zero. +LOOP += _encodeRemainingLength.0:3 LOOP += IotListDouble_RemoveAllMatches.0:$(SUBSCRIPTION_COUNT_MAX) -LOOP += valid_IotMqttSubscriptionList.0:$(SUBSCRIPTION_COUNT_MAX) LOOP += valid_IotMqttOperationList.0:$(OPERATION_COUNT_MAX) -LOOP += _encodeRemainingLength.0:$(SUBSCRIPTION_COUNT_MAX) +LOOP += valid_IotMqttSubscriptionList.0:$(SUBSCRIPTION_COUNT_MAX) UNWINDING += --unwind 1 UNWINDING += --unwindset '$(shell echo $(LOOP) | sed 's/ /,/g')' diff --git a/cbmc/proofs/IotMqtt_PublishAsync/README.md b/cbmc/proofs/IotMqtt_PublishAsync/README.md new file mode 100644 index 0000000000..8a5af1f803 --- /dev/null +++ b/cbmc/proofs/IotMqtt_PublishAsync/README.md @@ -0,0 +1,71 @@ +# Memory safety proof for IotMqtt_PublishAsync + +This proof harness attains 94% code coverage. The following comments explain +why the uncovered lines of code are unreachable code. + +Some functions contain unreachable blocks of code: + +* `_IotMqtt_SerializeConnectCommon` + + * `_validatePublish` eliminates that possibility of `QoS == IOT_MQTT_QOS_2` + +* `_scheduleNextRetry` + + * `pOperation->u.operation.periodic.retry.count < + pOperation->u.operation.periodic.retry.limit` + +* `_IotMqtt_DestroyOperation` + + * Notify calls `DestroyOperation` with a linked operation + +* `_IotMqtt_RemainingLengthEncodedSize` + + * This function never reaches `length > 2097152U` + +* `_IotMqtt_ProcessSend` + + * `pOperation->u.operation.periodic.retry.limit` always 0 + * `pOperation->u.operation.type != IOT_MQTT_DISCONNECT` + * `_completePendingSend` always return `destroyOperation == false` + +* `_IotMqtt_PublishPacketSize` + + * This function never reaches `pPublishInfo->payloadLength > payloadLimit` + +* `_IotMqtt_SerializePublish` + + * `_IotMqtt_PublishPacketSize` never returns false, because + `pPublishInfo->payloadLength` is always smaller than `payloadLimit` + +* `_IotMqtt_PublishSetDup` + + * `pPacketIdentifierHigh != NULL` + +* `_validatePublishPayload` + + * This function never reaches `payloadLength > maximumPayloadLength` + +* `_checkRetryLimit` + + * `pOperation->u.operation.periodic.retry.count < + pOperation->u.operation.periodic.retry.limit` + * `pOperation->u.operation.periodic.retry.count != 1U` + +* `_IotMqtt_DecrementOperationReferences` + + * `cancelJob == false` + +* `_IotMqtt_Notify` + + * `pOperation->u.operation.type != IOT_MQTT_SUBSCRIBE` + +* `IotMqtt_OperationType` + + * Always returns `IOT_MQTT_PUBLISH_TO_SERVER` + +Some functions are simply unreachable: + +* `_IotMqtt_RemoveSubscriptionByPacket` + + * Unreachable: Only function call in from an unreachable block of + `_IotMqtt_Notify` diff --git a/cbmc/proofs/IotMqtt_PublishAsync/cbmc-viewer.json b/cbmc/proofs/IotMqtt_PublishAsync/cbmc-viewer.json index 8a9dedf46c..34aeb6f02a 100644 --- a/cbmc/proofs/IotMqtt_PublishAsync/cbmc-viewer.json +++ b/cbmc/proofs/IotMqtt_PublishAsync/cbmc-viewer.json @@ -1,21 +1,16 @@ { "expected-missing-functions": [ + "IotClock_GetTimeMs", "IotLog_Generic", - "IotMqtt_Wait", - "IotMutex_Create", "IotMutex_Destroy", "IotMutex_Lock", "IotMutex_Unlock", "IotSemaphore_Create", "IotSemaphore_Destroy", "IotSemaphore_Post", - "IotSemaphore_TimedWait", - "IotSemaphore_Wait", - "IotTaskPool_CreateJob", "IotTaskPool_GetSystemTaskPool", - "IotTaskPool_ScheduleDeferred", "IotTaskPool_strerror", - "IotTaskPool_TryCancel" + "_IotMqtt_RemoveSubscriptionByPacket" ], "proof-name": "IotMqtt_PublishAsync", "proof-root": "cbmc/proofs" From 6fad6b7b17bbda68a1d78caf443f2495e0fbcf61 Mon Sep 17 00:00:00 2001 From: "Felipe R. Monteiro" Date: Tue, 28 Apr 2020 16:32:55 -0400 Subject: [PATCH 13/41] Adds CBMC prefix to all proof-related macros (#886) Signed-off-by: Felipe R. Monteiro --- .../0001-Bound-packet-remaining-length.patch | 28 +++++++++++++++++++ ...zePingreq-nondet-for-IotMqtt_Connect.patch | 2 +- ...d-thread-behavior-in-IotMqtt_Connect.patch | 2 +- .../bound-packet-remaining-length.patch | 17 ----------- cbmc/proofs/IotMqtt_Connect/Makefile | 4 +-- cbmc/proofs/IotMqtt_ReceiveCallback/Makefile | 6 ++-- 6 files changed, 35 insertions(+), 24 deletions(-) create mode 100644 cbmc/patches/0001-Bound-packet-remaining-length.patch delete mode 100644 cbmc/patches/bound-packet-remaining-length.patch diff --git a/cbmc/patches/0001-Bound-packet-remaining-length.patch b/cbmc/patches/0001-Bound-packet-remaining-length.patch new file mode 100644 index 0000000000..406952dcc7 --- /dev/null +++ b/cbmc/patches/0001-Bound-packet-remaining-length.patch @@ -0,0 +1,28 @@ +From c785aa73d869777a8a0ee4f8ff488397a70e0e29 Mon Sep 17 00:00:00 2001 +From: "Felipe R. Monteiro" +Date: Mon, 20 Apr 2020 20:08:05 +0000 +Subject: [PATCH] Bound packet remaining length + +Signed-off-by: Felipe R. Monteiro +--- + libraries/standard/mqtt/src/iot_mqtt_network.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/libraries/standard/mqtt/src/iot_mqtt_network.c b/libraries/standard/mqtt/src/iot_mqtt_network.c +index f39eb98..31c083e 100644 +--- a/libraries/standard/mqtt/src/iot_mqtt_network.c ++++ b/libraries/standard/mqtt/src/iot_mqtt_network.c +@@ -256,6 +256,10 @@ static IotMqttError_t _allocateAndReceivePacket( IotNetworkConnection_t pNetwork + IotMqtt_Assert( pMqttConnection != NULL ); + IotMqtt_Assert( pIncomingPacket != NULL ); + ++#ifdef CBMC_REMAINING_LENGTH_BOUND ++ __CPROVER_assume( pIncomingPacket->remainingLength < CBMC_REMAINING_LENGTH_BOUND ); ++#endif ++ + /* Allocate a buffer for the remaining data and read the data. */ + if( pIncomingPacket->remainingLength > 0U ) + { +-- +2.17.1 + diff --git a/cbmc/patches/0001-Make-_IotMqtt_SerializePingreq-nondet-for-IotMqtt_Connect.patch b/cbmc/patches/0001-Make-_IotMqtt_SerializePingreq-nondet-for-IotMqtt_Connect.patch index 4265745f91..db0a3cebc1 100644 --- a/cbmc/patches/0001-Make-_IotMqtt_SerializePingreq-nondet-for-IotMqtt_Connect.patch +++ b/cbmc/patches/0001-Make-_IotMqtt_SerializePingreq-nondet-for-IotMqtt_Connect.patch @@ -16,7 +16,7 @@ index 016111e..8a0d589 100644 /* Print out the PINGREQ packet for debugging purposes. */ IotLog_PrintBuffer( "MQTT PINGREQ packet:", pPingreq, MQTT_PACKET_PINGREQ_SIZE ); -+#ifdef SERIALIZAPINGREQ_NONDET_RETURN ++#ifdef CBMC_SERIALIZAPINGREQ_NONDET_RETURN + /* Return nondet status to improve coverage. */ + IotMqttError_t status; + return status; diff --git a/cbmc/patches/0001-Simulates-background-thread-behavior-in-IotMqtt_Connect.patch b/cbmc/patches/0001-Simulates-background-thread-behavior-in-IotMqtt_Connect.patch index 08181853d8..545d4a4d1e 100644 --- a/cbmc/patches/0001-Simulates-background-thread-behavior-in-IotMqtt_Connect.patch +++ b/cbmc/patches/0001-Simulates-background-thread-behavior-in-IotMqtt_Connect.patch @@ -16,7 +16,7 @@ index 1e55cb5..fa8f634 100644 /* Wait for the CONNECT operation to complete, i.e. wait for CONNACK. */ status = IotMqtt_Wait( pOperation, timeoutMs ); -+#ifdef BACKGROUND_THREAD_SIMULATION ++#ifdef CBMC_BACKGROUND_THREAD_SIMULATION + /* There is a background thread that's part of the network and changes + * the status from IOT_MQTT_STATUS_PENDING to IOT_MQTT_SUCCESS. This + * code snippet simulates the thread behavior and improves coverage. */ diff --git a/cbmc/patches/bound-packet-remaining-length.patch b/cbmc/patches/bound-packet-remaining-length.patch deleted file mode 100644 index 3b0c8f63a6..0000000000 --- a/cbmc/patches/bound-packet-remaining-length.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/libraries/standard/mqtt/src/iot_mqtt_network.c b/libraries/standard/mqtt/src/iot_mqtt_network.c -index f39eb98..805eca7 100644 ---- a/libraries/standard/mqtt/src/iot_mqtt_network.c -+++ b/libraries/standard/mqtt/src/iot_mqtt_network.c -@@ -256,6 +256,12 @@ static IotMqttError_t _allocateAndReceivePacket( IotNetworkConnection_t pNetwork - IotMqtt_Assert( pMqttConnection != NULL ); - IotMqtt_Assert( pIncomingPacket != NULL ); - -+#ifdef CBMC -+#ifdef REMAINING_LENGTH_BOUND -+ __CPROVER_assume( pIncomingPacket->remainingLength < REMAINING_LENGTH_BOUND ); -+#endif -+#endif -+ - /* Allocate a buffer for the remaining data and read the data. */ - if( pIncomingPacket->remainingLength > 0U ) - { diff --git a/cbmc/proofs/IotMqtt_Connect/Makefile b/cbmc/proofs/IotMqtt_Connect/Makefile index 7ba6208f41..f07fc96c4e 100644 --- a/cbmc/proofs/IotMqtt_Connect/Makefile +++ b/cbmc/proofs/IotMqtt_Connect/Makefile @@ -94,10 +94,10 @@ DEF += -DUSER_NAME_LENGTH_MAX=$(USER_NAME_LENGTH_MAX) DEF += -DCBMC_STUB_REMOVEALLMATCHES=1 # Enables _IotMqtt_SerializePingreq to return a nondet status -DEF += -DSERIALIZAPINGREQ_NONDET_RETURN=1 +DEF += -DCBMC_SERIALIZAPINGREQ_NONDET_RETURN=1 # Simulates background thread behavior in _sendConnectRequest -DEF += -DBACKGROUND_THREAD_SIMULATION=1 +DEF += -DCBMC_BACKGROUND_THREAD_SIMULATION=1 # Allow MQTT allocations to fail for coverage DEF += -include mqtt_state.h diff --git a/cbmc/proofs/IotMqtt_ReceiveCallback/Makefile b/cbmc/proofs/IotMqtt_ReceiveCallback/Makefile index 5e142d72b5..787c00cac5 100644 --- a/cbmc/proofs/IotMqtt_ReceiveCallback/Makefile +++ b/cbmc/proofs/IotMqtt_ReceiveCallback/Makefile @@ -33,8 +33,8 @@ TOPIC_LENGTH_MAX=6 DEF += -DTOPIC_LENGTH_MAX=$(TOPIC_LENGTH_MAX) # Bound the remaing length of a packet (BOUND = MAX-1) -REMAINING_LENGTH_BOUND=15 -DEF += -DREMAINING_LENGTH_BOUND=$(REMAINING_LENGTH_BOUND) +CBMC_REMAINING_LENGTH_BOUND=15 +DEF += -DCBMC_REMAINING_LENGTH_BOUND=$(CBMC_REMAINING_LENGTH_BOUND) # A constant that should be 2*SUBSCRIPTION_COUNT_MAX-1 SUBSCRIPTION_LIST_MAX=3 @@ -78,7 +78,7 @@ LOOP += IotListDouble_FindFirstMatch\$$link4.0:$(SUBSCRIPTION_COUNT_MAX) LOOP += IotListDouble_FindFirstMatch\$$link5.0:$(SUBSCRIPTION_COUNT_MAX) LOOP += _IotMqtt_GetRemainingLength.0:5 -LOOP += _decodeSubackStatus.0:$(REMAINING_LENGTH_BOUND) +LOOP += _decodeSubackStatus.0:$(CBMC_REMAINING_LENGTH_BOUND) LOOP += valid_IotMqttOperationList.0:$(OPERATION_COUNT_MAX) LOOP += valid_IotMqttSubscriptionList.0:$(SUBSCRIPTION_COUNT_MAX) From d6ef35fcfc8a14ef45c2a17ee533d1a505d6312d Mon Sep 17 00:00:00 2001 From: Daniel Schwartz-Narbonne Date: Wed, 29 Apr 2020 15:45:30 -0400 Subject: [PATCH 14/41] use __CPROVER_havoc_object instead of __CPROVER_array_copy (#904) --- cbmc/proofs/mqtt_state.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cbmc/proofs/mqtt_state.c b/cbmc/proofs/mqtt_state.c index 881c757e88..b70fd1a44b 100644 --- a/cbmc/proofs/mqtt_state.c +++ b/cbmc/proofs/mqtt_state.c @@ -730,10 +730,7 @@ size_t IotNetworkInterfaceReceive( void * pConnection, __CPROVER_assert( pBuffer, "IotNetworkInterfaceReceive pBuffer is not NULL" ); - // Fill the memory object pointed to by pBuffer with unconstrained - // data. What follows a CBMC idiom to do that. - uint8_t byte; - __CPROVER_array_copy( pBuffer, &byte ); + __CPROVER_havoc_object( pBuffer ); // Choose the number of bytes in pBuffer considered received. size_t size; From 148d3fabcdc783885207b98da7a879aa7fedd30d Mon Sep 17 00:00:00 2001 From: Archit Aggarwal Date: Thu, 30 Apr 2020 11:03:56 -0700 Subject: [PATCH 15/41] Fleet provisioning/release to v4 beta (#906) Release client library for the Fleet Provisioning feature of AWS IoT Core service --- .travis.yml | 27 +- CMakeLists.txt | 3 + README.md | 50 +- demos/CMakeLists.txt | 13 +- demos/iot_config.h | 70 +- demos/lexicon.txt | 8 + .../aws_iot_demo_provisioning_with_csr.c | 597 ++++++ ...iot_demo_provisioning_with_keys_and_cert.c | 592 ++++++ doc/config/layout_main.xml | 1 + doc/config/main | 3 +- doc/config/provisioning | 32 + doc/guide/developer/automated_tests.txt | 4 +- doc/lib/jobs.txt | 6 +- doc/lib/provisioning.txt | 416 +++++ ...ioning_createkeysandcertificate_design.png | Bin 0 -> 281485 bytes .../images/provisioning_demo_with_csr.png | Bin 0 -> 107518 bytes .../provisioning_demo_with_keys_and_cert.png | Bin 0 -> 107538 bytes ...provisioning_operation_detailed_design.png | Bin 0 -> 237239 bytes ...rovisioning_operation_highlevel_design.png | Bin 0 -> 197059 bytes doc/plantuml/provisioning_demo_with_csr.pu | 41 + .../provisioning_demo_with_keys_and_cert.pu | 41 + .../provisioning_operation_detailed_design.pu | 103 + ...provisioning_operation_highlevel_design.pu | 97 + libraries/aws/provisioning/CMakeLists.txt | 82 + .../include/aws_iot_provisioning.h | 319 ++++ .../types/aws_iot_provisioning_types.h | 557 ++++++ .../src/aws_iot_provisioning_api.c | 1110 +++++++++++ .../src/aws_iot_provisioning_parser.c | 825 ++++++++ .../src/aws_iot_provisioning_serializer.c | 627 +++++++ .../private/aws_iot_provisioning_internal.h | 653 +++++++ .../test/aws_iot_tests_provisioning.c | 57 + .../aws_iot_tests_provisioning_system.c | 747 ++++++++ .../unit/aws_iot_tests_provisioning_api.c | 1660 +++++++++++++++++ .../unit/aws_iot_tests_provisioning_parser.c | 896 +++++++++ .../aws_iot_tests_provisioning_serializer.c | 414 ++++ .../serializer/include/iot_serializer.h | 24 +- libraries/standard/serializer/lexicon.txt | 3 + .../cbor/iot_serializer_tinycbor_decoder.c | 136 +- .../test/unit/iot_tests_serializer_cbor.c | 147 ++ scripts/ci_test_provisioning.sh | 202 ++ scripts/setup/ci_setup_linux.sh | 7 + tests/iot_config.h | 88 +- 42 files changed, 10583 insertions(+), 75 deletions(-) create mode 100644 demos/src/Provisioning/aws_iot_demo_provisioning_with_csr.c create mode 100644 demos/src/Provisioning/aws_iot_demo_provisioning_with_keys_and_cert.c create mode 100644 doc/config/provisioning create mode 100644 doc/lib/provisioning.txt create mode 100644 doc/plantuml/images/provisioning_createkeysandcertificate_design.png create mode 100644 doc/plantuml/images/provisioning_demo_with_csr.png create mode 100644 doc/plantuml/images/provisioning_demo_with_keys_and_cert.png create mode 100644 doc/plantuml/images/provisioning_operation_detailed_design.png create mode 100644 doc/plantuml/images/provisioning_operation_highlevel_design.png create mode 100644 doc/plantuml/provisioning_demo_with_csr.pu create mode 100644 doc/plantuml/provisioning_demo_with_keys_and_cert.pu create mode 100644 doc/plantuml/provisioning_operation_detailed_design.pu create mode 100644 doc/plantuml/provisioning_operation_highlevel_design.pu create mode 100644 libraries/aws/provisioning/CMakeLists.txt create mode 100644 libraries/aws/provisioning/include/aws_iot_provisioning.h create mode 100644 libraries/aws/provisioning/include/types/aws_iot_provisioning_types.h create mode 100644 libraries/aws/provisioning/src/aws_iot_provisioning_api.c create mode 100644 libraries/aws/provisioning/src/aws_iot_provisioning_parser.c create mode 100644 libraries/aws/provisioning/src/aws_iot_provisioning_serializer.c create mode 100644 libraries/aws/provisioning/src/private/aws_iot_provisioning_internal.h create mode 100644 libraries/aws/provisioning/test/aws_iot_tests_provisioning.c create mode 100644 libraries/aws/provisioning/test/system/aws_iot_tests_provisioning_system.c create mode 100644 libraries/aws/provisioning/test/unit/aws_iot_tests_provisioning_api.c create mode 100644 libraries/aws/provisioning/test/unit/aws_iot_tests_provisioning_parser.c create mode 100644 libraries/aws/provisioning/test/unit/aws_iot_tests_provisioning_serializer.c create mode 100755 scripts/ci_test_provisioning.sh diff --git a/.travis.yml b/.travis.yml index 9dcd5764d0..67618abae5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -# Only run on the v4 beta branch for now. +# Only run on the v4_beta branch for now. branches: only: - v4_beta @@ -38,6 +38,7 @@ jobs: - env: RUN_TEST=mqtt NETWORK_STACK=openssl - env: RUN_TEST=shadow - env: RUN_TEST=jobs + - env: RUN_TEST=provisioning AWS_PROVISIONING_REGION=us-east-1 - if: type = push compiler: gcc env: RUN_TEST=coverage @@ -57,10 +58,28 @@ script: # Get AWS credentials when not a pull request build. - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then mkdir credentials; fi - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then wget https://www.amazontrust.com/repository/AmazonRootCA1.pem -O credentials/AmazonRootCA1.pem; fi - - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then echo -e $AWS_IOT_CLIENT_CERT > credentials/clientCert.pem; fi - - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then echo -e $AWS_IOT_PRIVATE_KEY > credentials/privateKey.pem; fi + - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then + if [ "$RUN_TEST" == "provisioning" ]; then + echo -e $AWS_IOT_GAMMA_CLIENT_CERT > credentials/clientCert.pem; + else + echo -e $AWS_IOT_CLIENT_CERT > credentials/clientCert.pem; + fi + fi + - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then + if [ "$RUN_TEST" == "provisioning" ]; then + echo -e $AWS_IOT_GAMMA_PRIVATE_KEY > credentials/privateKey.pem; + else + echo -e $AWS_IOT_PRIVATE_KEY > credentials/privateKey.pem; + fi + fi # Set credential defines passed to CMake when not a pull request build. - - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then export AWS_IOT_CREDENTIAL_DEFINES="-DIOT_TEST_SERVER=\"\\\"$AWS_IOT_ENDPOINT\\\"\" -DIOT_TEST_PORT=443 -DIOT_TEST_ROOT_CA=\"\\\"../credentials/AmazonRootCA1.pem\\\"\" -DIOT_TEST_CLIENT_CERT=\"\\\"../credentials/clientCert.pem\\\"\" -DIOT_TEST_PRIVATE_KEY=\"\\\"../credentials/privateKey.pem\\\"\""; fi + - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then + if [ "$RUN_TEST" == "provisioning" ]; then + export AWS_IOT_CREDENTIAL_DEFINES="-DIOT_TEST_SERVER=\"\\\"$AWS_IOT_GAMMA_ENDPOINT\\\"\" -DIOT_TEST_PORT=443 -DIOT_TEST_ROOT_CA=\"\\\"../credentials/AmazonRootCA1.pem\\\"\" -DIOT_TEST_CLIENT_CERT=\"\\\"../credentials/clientCert.pem\\\"\" -DIOT_TEST_PRIVATE_KEY=\"\\\"../credentials/privateKey.pem\\\"\""; + else + export AWS_IOT_CREDENTIAL_DEFINES="-DIOT_TEST_SERVER=\"\\\"$AWS_IOT_ENDPOINT\\\"\" -DIOT_TEST_PORT=443 -DIOT_TEST_ROOT_CA=\"\\\"../credentials/AmazonRootCA1.pem\\\"\" -DIOT_TEST_CLIENT_CERT=\"\\\"../credentials/clientCert.pem\\\"\" -DIOT_TEST_PRIVATE_KEY=\"\\\"../credentials/privateKey.pem\\\"\""; + fi + fi # Create build directory. - mkdir build - cd build diff --git a/CMakeLists.txt b/CMakeLists.txt index 630d7d891f..81d3265832 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,6 +101,9 @@ add_subdirectory( libraries/aws/jobs ) # AWS IoT Device Defender library. add_subdirectory( libraries/aws/defender ) +# Provisioning library. +add_subdirectory( libraries/aws/provisioning ) + # TinyCBOR library (third-party). add_subdirectory( third_party/tinycbor ) diff --git a/README.md b/README.md index 7342c9abad..368bf947b2 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,11 @@ This library is a new design that inherits from both the AWS IoT Device SDK Embe - Configurable memory allocation (static-only or dynamic). Memory allocation functions may also be set by the user. - Network stack based on OpenSSL when building for Linux. - MQTT persistent session support. -- Device Defender library. +- Device Defender client library for the [AWS IoT Device Defender](https://docs.aws.amazon.com/iot/latest/developerguide/device-defender.html) service. +- Provisioning client library for the [Fleet Provisioning feature +of AWS IoT Core](https://docs.aws.amazon.com/iot/latest/developerguide/provision-wo-cert.html). -Compared to the AWS IoT Device SDK Embedded C v3.0.1, the following features were removed: -- Auto-reconnect for MQTT connections. -- Shadow JSON document generator. - -## Building and Running Demos +## Building and Running the Fleet Provisioning library Demo **Main documentation page:** [Building the SDK](https://docs.aws.amazon.com/freertos/latest/lib-ref/c-sdk/main/building.html) @@ -37,39 +35,51 @@ This SDK builds with [CMake](https://cmake.org/), a cross-platform build tool. T - Linux system with POSIX thread and timer APIs. (CI tests on Ubuntu 16.04).
On Linux systems, the OpenSSL network implementation may be used instead of the default network implementation based on mbed TLS. This requires the installation of OpenSSL development libraries and header files, version 1.0.2g or later. The OpenSSL development libraries are usually called something like `libssl-dev` or `openssl-devel` when installed through a package manager. +### AWS IoT Account Setup +It is required to setup an AWS account and access the AWS IoT Console for running tests and demos. Follow the links to: +- [Setup an AWS account](https://docs.aws.amazon.com/iot/latest/developerguide/iot-console-signin.html). +- [Sign-in to the AWS IoT Console](https://docs.aws.amazon.com/iot/latest/developerguide/iot-console-signin.html) after setting up the AWS account. + +If using the Provisioning library, a fleet provisioning template, a provisioning claim, IoT policies and IAM policies need to be setup for the AWS account. Complete the steps to setup your device and AWS IoT account outlined [here](https://docs.aws.amazon.com/iot/latest/developerguide/provision-wo-cert.html#use-claim). + +If using the Shadow, Jobs or Defender libraries, a device needs to be registered on the AWS IoT account. Complete the following steps from the [Getting Started with AWS IoT](https://docs.aws.amazon.com/iot/latest/developerguide/iot-gs.html) guide. The guide mentions the AWS IoT Button, but you do not need one to use this SDK. + 1. [Register a Device in the Registry](https://docs.aws.amazon.com/iot/latest/developerguide/register-device.html) + 2. [Create and Activate a Device Certificate](https://docs.aws.amazon.com/iot/latest/developerguide/create-device-certificate.html) + 3. [Create an AWS IoT Policy](https://docs.aws.amazon.com/iot/latest/developerguide/create-iot-policy.html) + 4. [Attach an AWS IoT Policy to a Device Certificate](https://docs.aws.amazon.com/iot/latest/developerguide/attach-policy-to-certificate.html) + ### Build Steps 1. Clone the source code and submodules. This SDK uses third-party libraries as submodules in the `third_party` directory. - If the source code is downloaded via `git clone`, nothing further needs to be done. The CMake build system can automatically clone submodules in this case. - For any other download, the submodules must be downloaded and placed in their respective `third_party` directory. - [mbed TLS](https://github.com/ARMmbed/mbedtls/tree/mbedtls-2.17) → `third_party/mbedtls/mbedtls` - [tinyCBOR](https://github.com/intel/tinycbor) → `third_party/tinycbor/tinycbor` -2. Complete the first 6 steps in the guide [Getting Started with AWS IoT](https://docs.aws.amazon.com/iot/latest/developerguide/iot-gs.html). The guide mentions the AWS IoT Button, but you do not need one to use this SDK. - 1. [Sign in to the AWS IoT Console](https://docs.aws.amazon.com/iot/latest/developerguide/iot-console-signin.html) - 2. [Register a Device in the Registry](https://docs.aws.amazon.com/iot/latest/developerguide/register-device.html) - 3. [Create and Activate a Device Certificate](https://docs.aws.amazon.com/iot/latest/developerguide/create-device-certificate.html) - 4. [Create an AWS IoT Policy](https://docs.aws.amazon.com/iot/latest/developerguide/create-iot-policy.html) - 5. [Attach an AWS IoT Policy to a Device Certificate](https://docs.aws.amazon.com/iot/latest/developerguide/attach-policy-to-certificate.html) - 6. [Attach a Certificate to a Thing](https://docs.aws.amazon.com/iot/latest/developerguide/attach-cert-thing.html) +2. *Required ONLY for Provisioning library:* (Skip if not using Provisioning library) Set the following `#define`s in [iot_config.h](demos/iot_config.h). The demo requires configuration of 2 parameter name-value pairs to send to the AWS IoT Core service. Update the fleet provisioning template on the AWS IoT Console to support an extra parameter, besides the Certificate ID and Serial Number parameters (that are present in the default template created from AWS IoT Console). Refer to the [Parameters section](https://docs.aws.amazon.com/iot/latest/developerguide/provision-template.html#parameters-section) of [Fleet Provisioning Template](https://docs.aws.amazon.com/iot/latest/developerguide/provision-template.html#fleet-provision-template) for more information. + - Set `AWS_IOT_DEMO_PROVISIONING_TEMPLATE_NAME` with the name of the fleet provisioning template created in step 1. of [Provisioning by claim](https://docs.aws.amazon.com/iot/latest/developerguide/provision-wo-cert.html#use-claim). + - Set `AWS_IOT_DEMO_PROVISIONING_PARAMETER_NAME_SERIAL_NUMBER_VALUE` with the value of the device's serial number (or an equivalent unique device identifier) that will be used to create a Thing resource by the fleet provisioning template. + - Set `AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME` with the name of an additional parameter that the device needs to send to the fleet provisioning template. The demo requires exactly 2 different parameter name-value pairs (including serial number) to be configured. + - Set `AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE` with the value of the additional parameter. + - When testing the Certificate-Signing Request (CSR) based Provisioning demo, set the `AWS_IOT_DEMO_PROVISIONING_CSR_PEM` macro with the Certificate-Signing Request string. 3. *Optional:* Set the following `#define` in [iot_config.h](demos/iot_config.h). You may skip this step and instead pass these configuration settings as command line options when running the demos. - - Set `IOT_DEMO_IDENTIFIER` to the Thing Name you set in [step 1.2](https://docs.aws.amazon.com/iot/latest/developerguide/register-device.html). The corresponding command line option for this constant is `-i`. + - Set `IOT_DEMO_IDENTIFIER` to a MQTT client identifier that you want to use for the MQTT connection to AWS IoT Core. The corresponding command line option for this constant is `-i`. - Set `IOT_DEMO_SERVER` to your custom endpoint. This is found on the *Settings* page of the AWS IoT Console and has a format of `ABCDEFG1234567.iot.us-east-2.amazonaws.com`. The corresponding command line option for this constant is `-h`. - - Set `IOT_DEMO_ROOT_CA` to the path of the root CA certificate downloaded in [step 1.3](https://docs.aws.amazon.com/iot/latest/developerguide/create-device-certificate.html). The corresponding command line option for this constant is `-r`. - - Set `IOT_DEMO_CLIENT_CERT` to the path of the client certificate downloaded in [step 1.3](https://docs.aws.amazon.com/iot/latest/developerguide/create-device-certificate.html). The corresponding command line option for this constant is `-c`. - - Set `IOT_DEMO_PRIVATE_KEY` to the path of the private downloaded in [step 1.3](https://docs.aws.amazon.com/iot/latest/developerguide/create-device-certificate.html). The corresponding command line option for this constant is `-k`. + - Set `IOT_DEMO_ROOT_CA` to the path of the root CA certificate downloaded when setting up device certificate (or Provisioning Claim for Fleet Provisioning) in [AWS IoT Account Setup](https://github.com/aws/aws-iot-device-sdk-embedded-C/tree/v4_beta#aws-iot-account-setup). The corresponding command line option for this constant is `-r`. + - Set `IOT_DEMO_CLIENT_CERT` to the path of the client certificate downloaded when setting up device certificate (or Provisioning Claim for Fleet Provisioning) in [AWS IoT Account Setup](https://github.com/aws/aws-iot-device-sdk-embedded-C/tree/v4_beta#aws-iot-account-setup). The corresponding command line option for this constant is `-c`. + - Set `IOT_DEMO_PRIVATE_KEY` to the path of the private downloaded when setting up device certificate (or Provisioning Claim for Fleet Provisioning) in [AWS IoT Account Setup](https://github.com/aws/aws-iot-device-sdk-embedded-C/tree/v4_beta#aws-iot-account-setup). The corresponding command line option for this constant is `-k`. - Set `IOT_DEMO_USER_NAME` to the username string, if any, required to authenticate to your MQTT broker. The corresponding command line option for this constant is `-m`. - Set `IOT_DEMO_PASSWORD` to the password string, if any, required to authenticate to your MQTT broker. The corresponding command line option for this constant is `-w`. -4. Make a build directory in the SDK's root directory and `cd` into it. +5. Make a build directory in the SDK's root directory and `cd` into it. ```sh mkdir build cd build ``` -5. Run CMake from the build directory. +6. Run CMake from the build directory. ```sh cmake .. ``` CMake will generate a project based on the detected operating system. On Linux, the default project is a Makefile. To build the SDK with this Makefile, run `make`. The resulting binaries (the demo executables) and libraries will be placed in the `build/output` directory. - You may also use CMake GUI. Specify the SDK's root directory as the source directory and the build directory created in step 4 as the build directory in CMake GUI. + You may also use CMake GUI. Specify the SDK's root directory as the source directory and the build directory created in step 5 as the build directory in CMake GUI. See the documentation page [Building the SDK](https://docs.aws.amazon.com/freertos/latest/lib-ref/c-sdk/main/building.html) for a list of options that can be used to configure the build system. diff --git a/demos/CMakeLists.txt b/demos/CMakeLists.txt index cd8aa43a60..b969de2cf9 100644 --- a/demos/CMakeLists.txt +++ b/demos/CMakeLists.txt @@ -30,17 +30,24 @@ set( DEMO_MAIN_FUNCTIONS RunMqttDemo RunShadowDemo RunDefenderDemo - RunJobsDemo ) + RunJobsDemo + RunProvisioningWithKeysAndCertDemo + RunProvisioningWithCsrDemo ) set( DEMO_SOURCES src/iot_demo_mqtt.c src/aws_iot_demo_shadow.c src/aws_iot_demo_defender.c - src/aws_iot_demo_jobs.c ) + src/aws_iot_demo_jobs.c + src/Provisioning/aws_iot_demo_provisioning_with_keys_and_cert.c + src/Provisioning/aws_iot_demo_provisioning_with_csr.c ) + set( DEMO_LIBRARY_DEPENDENCY iotmqtt "awsiotshadow\\\;awsiotcommon" awsiotdefender - "awsiotjobs\\\;awsiotcommon" ) + "awsiotjobs\\\;awsiotcommon" + "awsiotprovisioning\\\;awsiotcommon" + "awsiotprovisioning\\\;awsiotcommon" ) # Get the list length to iterate over it. Since CMake indexes from 0, subtract # 1 for the iteration range. diff --git a/demos/iot_config.h b/demos/iot_config.h index 750b7ab9f9..fea5613894 100644 --- a/demos/iot_config.h +++ b/demos/iot_config.h @@ -55,30 +55,66 @@ /* Shadow demo configuration. The demo publishes periodic Shadow updates and responds * to changing Shadows. */ -#define AWS_IOT_DEMO_SHADOW_UPDATE_COUNT ( 20 ) /* Number of updates to publish. */ -#define AWS_IOT_DEMO_SHADOW_UPDATE_PERIOD_MS ( 3000 ) /* Period of Shadow updates. */ +#define AWS_IOT_DEMO_SHADOW_UPDATE_COUNT ( 20 ) /* Number of updates to publish. */ +#define AWS_IOT_DEMO_SHADOW_UPDATE_PERIOD_MS ( 3000 ) /* Period of Shadow updates. */ + +/** + * The Certificate-Signing Request string to use for CSR-based Provisioning demo app. + */ +#define AWS_IOT_DEMO_PROVISIONING_CSR_PEM "" + +/** + * The name for the fleet provisioning template that will be used for provisioning + * for registering thing in the Provisioning demo applications. + */ +#define AWS_IOT_DEMO_PROVISIONING_TEMPLATE_NAME "" + +/** + * List of parameters that will be used for provisioning in the demo application. + * There are 2 requirements for passing parameters to the Provisioning demo: + * 1. One parameter is a "SerialNumber". The AWS IoT console generates a provisioning template + * that by default uses a "SerialNumber" device parameter for creating a Thing resource. Also, the + * setup instructions in the API reference documentation of Fleet Provisioning + * (https://docs.aws.amazon.com/freertos/latest/lib-ref/c-sdk/provisioning/provisioning_tests.html + * #provisioning_system_tests_setup) + * provide an AWS CLI command example for creating a provisioning template, in which the template + * JSON string contains the "SerialNumber" parameter. + * 2. A second parameter which is configurable for both the name and value. The example provisioning + * JSON string in the demo setup instructions contains "DeviceLocation" as the default parameter name. + * If a different parameter name is used, make SURE to update the provisioning template on the AWS IoT Console! + */ +#define AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME "SerialNumber" +#define AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME_LENGTH sizeof( AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME ) - 1 +#define AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE "" +#define AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE_LENGTH sizeof( AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE ) - 1 +#define AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME "" +#define AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME_LENGTH sizeof( AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME ) - 1 +#define AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE "" +#define AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE_LENGTH sizeof( AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE ) - 1 /* Enable asserts in the libraries. */ -#define IOT_CONTAINERS_ENABLE_ASSERTS ( 1 ) -#define IOT_MQTT_ENABLE_ASSERTS ( 1 ) -#define IOT_TASKPOOL_ENABLE_ASSERTS ( 1 ) -#define AWS_IOT_SHADOW_ENABLE_ASSERTS ( 1 ) -#define AWS_IOT_DEFENDER_ENABLE_ASSERTS ( 1 ) -#define AWS_IOT_JOBS_ENABLE_ASSERTS ( 1 ) +#define IOT_CONTAINERS_ENABLE_ASSERTS ( 1 ) +#define IOT_MQTT_ENABLE_ASSERTS ( 1 ) +#define IOT_TASKPOOL_ENABLE_ASSERTS ( 1 ) +#define AWS_IOT_SHADOW_ENABLE_ASSERTS ( 1 ) +#define AWS_IOT_DEFENDER_ENABLE_ASSERTS ( 1 ) +#define AWS_IOT_JOBS_ENABLE_ASSERTS ( 1 ) +#define AWS_IOT_PROVISIONING_ENABLE_ASSERTS ( 1 ) /* Library logging configuration. IOT_LOG_LEVEL_GLOBAL provides a global log * level for all libraries; the library-specific settings override the global * setting. If both the library-specific and global settings are undefined, * no logs will be printed. */ -#define IOT_LOG_LEVEL_GLOBAL IOT_LOG_INFO -#define IOT_LOG_LEVEL_DEMO IOT_LOG_INFO -#define IOT_LOG_LEVEL_PLATFORM IOT_LOG_NONE -#define IOT_LOG_LEVEL_NETWORK IOT_LOG_INFO -#define IOT_LOG_LEVEL_TASKPOOL IOT_LOG_NONE -#define IOT_LOG_LEVEL_MQTT IOT_LOG_INFO -#define AWS_IOT_LOG_LEVEL_SHADOW IOT_LOG_INFO -#define AWS_IOT_LOG_LEVEL_DEFENDER IOT_LOG_INFO -#define AWS_IOT_LOG_LEVEL_JOBS IOT_LOG_INFO +#define IOT_LOG_LEVEL_GLOBAL IOT_LOG_INFO +#define IOT_LOG_LEVEL_DEMO IOT_LOG_INFO +#define IOT_LOG_LEVEL_PLATFORM IOT_LOG_NONE +#define IOT_LOG_LEVEL_NETWORK IOT_LOG_INFO +#define IOT_LOG_LEVEL_TASKPOOL IOT_LOG_NONE +#define IOT_LOG_LEVEL_MQTT IOT_LOG_INFO +#define AWS_IOT_LOG_LEVEL_SHADOW IOT_LOG_INFO +#define AWS_IOT_LOG_LEVEL_DEFENDER IOT_LOG_INFO +#define AWS_IOT_LOG_LEVEL_JOBS IOT_LOG_INFO +#define AWS_IOT_LOG_LEVEL_PROVISIONING IOT_LOG_INFO /* Default assert and memory allocation functions. */ #include diff --git a/demos/lexicon.txt b/demos/lexicon.txt index 39fe6a9356..c467d41143 100644 --- a/demos/lexicon.txt +++ b/demos/lexicon.txt @@ -1,11 +1,13 @@ alpn api +apis ascii aws awsiotmqttmode bool ca cert +certificateidlength cli com config @@ -27,9 +29,11 @@ mbed mqtt openssl org +pcertificateidbuffer pclientcertpath phostname pidentifier +pownershiptokenbuffer poweron ppassword pprivatekeypath @@ -42,7 +46,11 @@ snprintf startnext tcp tls +tokenlength uint username www xhtml +certIdLength +pCertIdBuffer +freertos diff --git a/demos/src/Provisioning/aws_iot_demo_provisioning_with_csr.c b/demos/src/Provisioning/aws_iot_demo_provisioning_with_csr.c new file mode 100644 index 0000000000..9b0a5f2911 --- /dev/null +++ b/demos/src/Provisioning/aws_iot_demo_provisioning_with_csr.c @@ -0,0 +1,597 @@ +/* + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file aws_iot_demo_provisioning_with_csr.c + * @brief Demonstrates usage of the Provisioning library for the use-case + * involving creation of certificate with a Certificate-Signing Request + * to AWS IoT. + */ + +/* The config header is always included first. */ +#include "iot_config.h" + +/* Standard includes. */ +#include +#include +#include +#include + +/* Set up logging for this demo. */ +#include "iot_demo_logging.h" + +/* Platform layer includes. */ +#include "platform/iot_clock.h" +#include "platform/iot_threads.h" + +/* MQTT include. */ +#include "iot_mqtt.h" + +/* Provisioning include. */ +#include "aws_iot_provisioning.h" + +/** + * @cond DOXYGEN_IGNORE + * Doxygen should ignore this section. + * + * Provide default values for undefined configuration settings. + */ +#ifndef AWS_IOT_DEMO_PROVISIONING_TIMEOUT_PERIOD_MS + #define AWS_IOT_DEMO_PROVISIONING_TIMEOUT_PERIOD_MS ( 5000 ) +#endif + +#ifndef AWS_IOT_DEMO_PROVISIONING_CSR_PEM + #error "The AWS_IOT_DEMO_PROVISIONING_CSR_PEM should be defined for the demo." +#endif +/** @endcond */ + +/** + * @brief The keep-alive interval used for this demo. + * + * An MQTT ping request will be sent periodically at this interval. + */ +#define KEEP_ALIVE_SECONDS ( 60 ) + +/** + * @brief The timeout for Provisioning and MQTT operations in this demo. + */ +#define TIMEOUT_MS ( 5000 ) + +/** + * @brief The template name to use for provisioning the demo application. + */ +static const char pTemplateName[] = AWS_IOT_DEMO_PROVISIONING_TEMPLATE_NAME; + +/** + * @brief Stores the received certificate ID and certificate ownership token from the server. + */ +typedef struct _demoCertFromCsrCallbackContext +{ + char * pCertificateIdBuffer; /**< @brief Buffer containing the certificate ID returned by the server. */ + size_t certificateIdLength; /**< @brief Length of the certificate ID* buffer. */ + char * pOwnershipTokenBuffer; /**< @brief Buffer containing the certificate ownership token returned + * by the server. */ + size_t tokenLength; /**< @brief Length of the ownership token. */ +} _demoCertFromCsrCallbackContext_t; + +/*-----------------------------------------------------------*/ + +/* Declaration of demo function. */ +int RunProvisioningWithCsrDemo( bool awsIotMqttMode, + const char * pIdentifier, + void * pNetworkServerInfo, + void * pNetworkCredentialInfo, + const IotNetworkInterface_t * pNetworkInterface ); + +/*-----------------------------------------------------------*/ + +/** + * @brief Prints the rejected reponse information received from the server. + */ +static void _printRejectedResponse( const AwsIotProvisioningRejectedResponse_t * pResponseInfo ) +{ + IotLogError( "ErrorCode={%.*s}\n ErrorMessage={%.*s}\n", + pResponseInfo->errorCodeLength, pResponseInfo->pErrorCode, + pResponseInfo->errorMessageLength, pResponseInfo->pErrorMessage ); +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Callback for displaying the information in the server response. If the response is successful (i.e. contains + * credentials), the Certificate ID and ownership token data will be copied into buffers for use later in the demo. + * + * @param[in] contextParam The context of the callback containing buffers to copy the credentials to. + * @param[in] pResponseInfo The device credentials information obtained from the server that will be copied into the + * shared buffers of the demo. + */ +static void _demoCertFromCsrCallback( void * contextParam, + const AwsIotProvisioningCreateCertFromCsrResponse_t * pResponseInfo ) +{ + _demoCertFromCsrCallbackContext_t * certIdTokenContext = + ( _demoCertFromCsrCallbackContext_t * ) contextParam; + + IotLogInfo( "Server response callback invoked: Received server response: " + "StatusCode={%d}", pResponseInfo->statusCode ); + + if( pResponseInfo->statusCode == AWS_IOT_PROVISIONING_SERVER_STATUS_ACCEPTED ) + { + /* Allocate buffer space for storing the certificate ID obtained from the server. */ + certIdTokenContext->pCertificateIdBuffer = + Iot_DefaultMalloc( pResponseInfo->u.acceptedResponse.certIdLength + 1 ); + + /* Copy the certificate ID into the buffer. */ + if( certIdTokenContext->pCertificateIdBuffer != NULL ) + { + /* Copy the size of the Certificate ID string. */ + certIdTokenContext->certificateIdLength = pResponseInfo->u.acceptedResponse.certIdLength; + + memcpy( certIdTokenContext->pCertificateIdBuffer, + pResponseInfo->u.acceptedResponse.pCertId, + pResponseInfo->u.acceptedResponse.certIdLength ); + /* Add a NULL terminator to the buffer (to treat the buffer as a string!) */ + *( certIdTokenContext->pCertificateIdBuffer + pResponseInfo->u.acceptedResponse.certIdLength ) = '\0'; + } + + /* Allocate buffer space for storing the ownership token string obtained from the server. */ + certIdTokenContext->pOwnershipTokenBuffer = + Iot_DefaultMalloc( pResponseInfo->u.acceptedResponse.ownershipTokenLength + 1 ); + + /* Copy the ownership token into the buffer. */ + if( certIdTokenContext->pOwnershipTokenBuffer != NULL ) + { + /* Copy the size of the ownership token string. */ + certIdTokenContext->tokenLength = pResponseInfo->u.acceptedResponse.ownershipTokenLength; + + memcpy( certIdTokenContext->pOwnershipTokenBuffer, + pResponseInfo->u.acceptedResponse.pCertOwnershipToken, + pResponseInfo->u.acceptedResponse.ownershipTokenLength ); + /* Add a NULL terminator to the buffer (to treat the buffer as a string!) */ + *( certIdTokenContext->pOwnershipTokenBuffer + pResponseInfo->u.acceptedResponse.ownershipTokenLength ) = '\0'; + } + + /* Print the received credentials information.*/ + IotLogInfo( "Server has accepted Certificate-Signing Request: " + "\nCertificate PEM={%.*s}\nCertificate ID={%.*s}\nOwnership Token={%.*s}\n", + pResponseInfo->u.acceptedResponse.deviceCertLength, + pResponseInfo->u.acceptedResponse.pDeviceCert, + pResponseInfo->u.acceptedResponse.certIdLength, + pResponseInfo->u.acceptedResponse.pCertId, + pResponseInfo->u.acceptedResponse.ownershipTokenLength, + pResponseInfo->u.acceptedResponse.pCertOwnershipToken ); + } + else + { + IotLogWarn( "Oops, certificate creation from CSR has been rejected. " + "Please verify that the IoT Policy attached to the demo credentials " + "allows the \"iot:CreateCertificateFromCsr\" action." ); + _printRejectedResponse( &pResponseInfo->u.rejectedResponse ); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Callback for displaying provisioning information sent by the server, if the provisioning request is + * successful. + * + * @param[in] contextParam Unused parameter for the demo. + * @param[in] pResponseInfo The information in the response received from the server. + */ +static void _demoRegisterThingCallback( void * contextParam, + const AwsIotProvisioningRegisterThingResponse_t * pResponseInfo ) +{ + ( void ) contextParam; + + IotLogInfo( "Received StatusCode={%d}", pResponseInfo->statusCode ); + + if( pResponseInfo->statusCode == AWS_IOT_PROVISIONING_SERVER_STATUS_ACCEPTED ) + { + if( pResponseInfo->u.acceptedResponse.pThingName != NULL ) + { + IotLogInfo( "ThingName = %.*s", + pResponseInfo->u.acceptedResponse.thingNameLength, + pResponseInfo->u.acceptedResponse.pThingName ); + } + + if( pResponseInfo->u.acceptedResponse.numOfConfigurationEntries > 0 ) + { + const AwsIotProvisioningResponseDeviceConfigurationEntry_t * pConfigurationList = + pResponseInfo->u.acceptedResponse.pDeviceConfigList; + + for( size_t configIndex = 0; + configIndex < pResponseInfo->u.acceptedResponse.numOfConfigurationEntries; configIndex++ ) + { + IotLogInfo( "Device Configuration no. %d\nConfigName = %.*s, ConfigData = %.*s ", + configIndex, + pConfigurationList[ configIndex ].keyLength, + pConfigurationList[ configIndex ].pKey, + pConfigurationList[ configIndex ].valueLength, + pConfigurationList[ configIndex ].pValue ); + } + } + } + else + { + IotLogInfo( "Oops, server rejected request for provisioning the demo app. " + "Please verify that the IoT Policy attached to the demo credentials " + "allows the \"iot:RegisterThing\" action." ); + _printRejectedResponse( &pResponseInfo->u.rejectedResponse ); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Initialize the the MQTT library and the Provisioning library. + * + * @return `EXIT_SUCCESS` if all libraries were successfully initialized; + * `EXIT_FAILURE` otherwise. + */ +static int _initializeDemo( void ) +{ + int status = EXIT_SUCCESS; + IotMqttError_t mqttInitStatus = IOT_MQTT_SUCCESS; + AwsIotProvisioningError_t provisioningInitStatus = AWS_IOT_PROVISIONING_SUCCESS; + + /* Flags to track cleanup on error. */ + bool mqttInitialized = false; + + /* Initialize the MQTT library. */ + mqttInitStatus = IotMqtt_Init(); + + if( mqttInitStatus == IOT_MQTT_SUCCESS ) + { + mqttInitialized = true; + } + else + { + status = EXIT_FAILURE; + } + + /* Initialize the Provisioning library. */ + if( status == EXIT_SUCCESS ) + { + /* Use the default MQTT timeout. */ + provisioningInitStatus = AwsIotProvisioning_Init( 0 ); + + if( provisioningInitStatus != AWS_IOT_PROVISIONING_SUCCESS ) + { + status = EXIT_FAILURE; + } + } + + /* Clean up on error. */ + if( status == EXIT_FAILURE ) + { + if( mqttInitialized == true ) + { + IotMqtt_Cleanup(); + } + } + + return status; +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Clean up the the MQTT library and the Provisioning library. + */ +static void _cleanupDemo( void ) +{ + AwsIotProvisioning_Cleanup(); + IotMqtt_Cleanup(); +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Establish a new connection to the MQTT server for the Provisioning demo. + * + * @param[in] pIdentifier NULL-terminated MQTT client identifier. The Provisioning + * demo will use the Thing Name as the client identifier. + * @param[in] pNetworkServerInfo Passed to the MQTT connect function when + * establishing the MQTT connection. + * @param[in] pNetworkCredentialInfo Passed to the MQTT connect function when + * establishing the MQTT connection. + * @param[in] pNetworkInterface The network interface to use for this demo. + * @param[out] pMqttConnection Set to the handle to the new MQTT connection. + * + * @return `EXIT_SUCCESS` if the connection is successfully established; `EXIT_FAILURE` + * otherwise. + */ +static int _establishMqttConnection( const char * pIdentifier, + void * pNetworkServerInfo, + void * pNetworkCredentialInfo, + const IotNetworkInterface_t * pNetworkInterface, + IotMqttConnection_t * pMqttConnection ) +{ + int status = EXIT_SUCCESS; + IotMqttError_t connectStatus = IOT_MQTT_STATUS_PENDING; + IotMqttNetworkInfo_t networkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER; + IotMqttConnectInfo_t connectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER; + + /* Set the members of the network info not set by the initializer. This + * struct provided information on the transport layer to the MQTT connection. */ + networkInfo.createNetworkConnection = true; + networkInfo.u.setup.pNetworkServerInfo = pNetworkServerInfo; + networkInfo.u.setup.pNetworkCredentialInfo = pNetworkCredentialInfo; + networkInfo.pNetworkInterface = pNetworkInterface; + + /* Set the members of the connection info not set by the initializer. */ + connectInfo.awsIotMqttMode = true; + connectInfo.cleanSession = true; + connectInfo.keepAliveSeconds = KEEP_ALIVE_SECONDS; + + /* AWS IoT recommends the use of the Thing Name as the MQTT client ID. */ + connectInfo.pClientIdentifier = pIdentifier; + connectInfo.clientIdentifierLength = ( uint16_t ) strlen( pIdentifier ); + + /* Establish the MQTT connection. */ + connectStatus = IotMqtt_Connect( &networkInfo, + &connectInfo, + TIMEOUT_MS, + pMqttConnection ); + + if( connectStatus != IOT_MQTT_SUCCESS ) + { + IotLogError( "MQTT CONNECT returned error %s.", + IotMqtt_strerror( connectStatus ) ); + + status = EXIT_FAILURE; + } + + return status; +} + +/*-----------------------------------------------------------*/ + +/** + * @brief The function that runs the Provisioning demo, for the AWS IoT generated + * certificate from device generated CSR use-case, called by the demo runner. + * + * @param[in] awsIotMqttMode Ignored for the Provisioning demo. + * @param[in] pIdentifier NULL-terminated Provisioning Thing Name. + * @param[in] pNetworkServerInfo Passed to the MQTT connect function when + * establishing the MQTT connection for testing the Fleet Provisioning feature of AWS Iot Core service. + * @param[in] pNetworkCredentialInfo Passed to the MQTT connect function when + * establishing the MQTT connection for testing the Fleet Provisioning feature of AWS Iot Core service. + * @param[in] pNetworkInterface The network interface to use for this demo. + * + * @return `EXIT_SUCCESS` if the demo completes successfully; `EXIT_FAILURE` otherwise. + */ +int RunProvisioningWithCsrDemo( bool awsIotMqttMode, + const char * pIdentifier, + void * pNetworkServerInfo, + void * pNetworkCredentialInfo, + const IotNetworkInterface_t * pNetworkInterface ) +{ + /* Return value of this function and the exit status of this program. */ + int status = 0; + + /* Handle of the MQTT connection used in this demo. */ + IotMqttConnection_t mqttConnection = IOT_MQTT_CONNECTION_INITIALIZER; + + /* Callbacks for the library APIs. */ + AwsIotProvisioningCreateCertFromCsrCallbackInfo_t certFromCsrCallback = + AWS_IOT_PROVISIONING_CREATE_CERTIFICATE_FROM_CSR_CALLBACK_INFO_INITIALIZER; + AwsIotProvisioningRegisterThingCallbackInfo_t registerThingResponseCallback = + AWS_IOT_PROVISIONING_REGISTER_THING_CALLBACK_INFO_INITIALIZER; + + /* Represents memory that will be allocated to store the Certificate ID that will be provided by the credential + * requesting API through the callback. */ + _demoCertFromCsrCallbackContext_t newCertificateDataContext; + + newCertificateDataContext.pCertificateIdBuffer = NULL; + newCertificateDataContext.certificateIdLength = 0; + newCertificateDataContext.pOwnershipTokenBuffer = NULL; + newCertificateDataContext.tokenLength = 0; + + /* Request data for provisioning the demo application. */ + AwsIotProvisioningRegisterThingRequestInfo_t requestInfo; + + /* Flags for tracking which cleanup functions must be called. */ + bool librariesInitialized = false, connectionEstablished = false; + + /* The first parameter of this demo function is not used. Provisioning feature is specific + * to AWS IoT, so this value is hardcoded to true whenever needed. */ + ( void ) awsIotMqttMode; + + /* This will be used for tracking the return code from the Provisioning APIs. */ + AwsIotProvisioningError_t requestStatus = AWS_IOT_PROVISIONING_SUCCESS; + + /* The list of parameters that will be used as "context" for provisioning the demo application. + * This demo will pass exactly 2 different parameter entries for requesting provisioning. */ + AwsIotProvisioningRequestParameterEntry_t provisioningParameters[ 2 ] = { { 0 } }; + + /* Determine if a provisioning template name has been specified. */ + if( ( ( void * ) pTemplateName == NULL ) || ( strlen( pTemplateName ) == 0 ) ) + { + IotLogError( "A valid provisioning template name must be provided." ); + status = EXIT_FAILURE; + } + + /* Generate the list of parameters to send for provisioning */ + if( status != EXIT_FAILURE ) + { + if( ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME == NULL ) || + ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME_LENGTH == 0 ) || + ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE == NULL ) || + ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE_LENGTH == 0 ) || + ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME == NULL ) || + ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME_LENGTH == 0 ) || + ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE == NULL ) || + ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE_LENGTH == 0 ) ) + { + IotLogError( "The provisioning demo requires 2 pairs of name and value data for parameters to be configured." ); + status = EXIT_FAILURE; + } + else + { + provisioningParameters[ 0 ].pParameterKey = AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME; + provisioningParameters[ 0 ].parameterKeyLength = AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME_LENGTH; + provisioningParameters[ 0 ].pParameterValue = AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE; + provisioningParameters[ 0 ].parameterValueLength = AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE_LENGTH; + provisioningParameters[ 1 ].pParameterKey = AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME; + provisioningParameters[ 1 ].parameterKeyLength = AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME_LENGTH; + provisioningParameters[ 1 ].pParameterValue = AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE; + provisioningParameters[ 1 ].parameterValueLength = AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE_LENGTH; + } + } + + if( status != EXIT_FAILURE ) + { + /* Determine the length of the client ID Name. */ + if( pIdentifier != NULL ) + { + if( strlen( pIdentifier ) == 0 ) + { + IotLogError( "The length of the MQTT client identifier must be nonzero." ); + + status = EXIT_FAILURE; + } + } + else if( pIdentifier == NULL ) + { + IotLogError( "A client identifier must be provided for the Provisioning demo." ); + + status = EXIT_FAILURE; + } + } + + /* Initialize the libraries required for this demo. */ + if( status == EXIT_SUCCESS ) + { + status = _initializeDemo(); + } + + if( status == EXIT_SUCCESS ) + { + /* Mark the libraries as initialized. */ + librariesInitialized = true; + + /* Establish a new MQTT connection. */ + status = _establishMqttConnection( pIdentifier, + pNetworkServerInfo, + pNetworkCredentialInfo, + pNetworkInterface, + &mqttConnection ); + } + + if( status == EXIT_SUCCESS ) + { + /* Mark the MQTT connection as established. */ + connectionEstablished = true; + + /* Set the certificate ID pointer as context parameter to the credentials response processing callback. */ + certFromCsrCallback.userParam = &newCertificateDataContext; + + /* Set the callback function for handling device credentials that the server will send. */ + certFromCsrCallback.function = _demoCertFromCsrCallback; + + /* Call the API to get new device credentials for this demo, and check that the certificate ID data is populated. */ + requestStatus = AwsIotProvisioning_CreateCertificateFromCsr( mqttConnection, + IOT_MQTT_QOS_1, + AWS_IOT_DEMO_PROVISIONING_CSR_PEM, + strlen( AWS_IOT_DEMO_PROVISIONING_CSR_PEM ), + AWS_IOT_DEMO_PROVISIONING_TIMEOUT_PERIOD_MS, + &certFromCsrCallback ); + + if( requestStatus != AWS_IOT_PROVISIONING_SUCCESS ) + { + status = EXIT_FAILURE; + IotLogError( "Request to get new credentials failed, error %s ", + AwsIotProvisioning_strerror( requestStatus ) ); + } + else if( ( newCertificateDataContext.pCertificateIdBuffer == NULL ) || + ( newCertificateDataContext.pOwnershipTokenBuffer == NULL ) ) + { + IotLogInfo( "Don't have either the Certificate ID OR the Certificate Ownership Token (or both) to proceed with provisioning. So exiting...!" ); + } + else + { + IotLogInfo( "Succeeded in receiving new device credentials!" ); + } + } + + if( status == EXIT_SUCCESS ) + { + /* Set the parameters for requesting provisioning. */ + requestInfo.pDeviceCertificateId = newCertificateDataContext.pCertificateIdBuffer; + requestInfo.deviceCertificateIdLength = newCertificateDataContext.certificateIdLength; + requestInfo.pCertificateOwnershipToken = newCertificateDataContext.pOwnershipTokenBuffer; + requestInfo.ownershipTokenLength = newCertificateDataContext.tokenLength; + requestInfo.pTemplateName = AWS_IOT_DEMO_PROVISIONING_TEMPLATE_NAME; + requestInfo.templateNameLength = sizeof( AWS_IOT_DEMO_PROVISIONING_TEMPLATE_NAME ) - 1; + requestInfo.pParametersStart = provisioningParameters; + requestInfo.numOfParameters = sizeof( provisioningParameters ) / sizeof( AwsIotProvisioningRequestParameterEntry_t ); + + /* Set the callback function for handling device credentials that the server will send. */ + registerThingResponseCallback.function = _demoRegisterThingCallback; + + /* Call the API to provision the demo application with the certificate ID that we received, and the template + * name associated with the demo endpoint account. */ + requestStatus = AwsIotProvisioning_RegisterThing( mqttConnection, + &requestInfo, + AWS_IOT_DEMO_PROVISIONING_TIMEOUT_PERIOD_MS, + ®isterThingResponseCallback ); + + if( requestStatus != AWS_IOT_PROVISIONING_SUCCESS ) + { + status = EXIT_FAILURE; + IotLogError( "Failed to provision demo application, error %s", + AwsIotProvisioning_strerror( requestStatus ) ); + } + else + { + IotLogInfo( "Succeeded in provisioning our demo application!" ); + } + } + + /* Disconnect the MQTT connection if it was established. */ + if( connectionEstablished == true ) + { + IotMqtt_Disconnect( mqttConnection, 0 ); + } + + /* Clean up libraries if they were initialized. */ + if( librariesInitialized == true ) + { + _cleanupDemo(); + } + + /* Release the Certificate ID buffer, if memory was allocated for it. */ + if( newCertificateDataContext.pCertificateIdBuffer != NULL ) + { + Iot_DefaultFree( newCertificateDataContext.pCertificateIdBuffer ); + } + + /* Release the ownership token buffer, if memory was allocated for it. */ + if( newCertificateDataContext.pOwnershipTokenBuffer != NULL ) + { + Iot_DefaultFree( newCertificateDataContext.pOwnershipTokenBuffer ); + } + + return status; +} + +/*-----------------------------------------------------------*/ diff --git a/demos/src/Provisioning/aws_iot_demo_provisioning_with_keys_and_cert.c b/demos/src/Provisioning/aws_iot_demo_provisioning_with_keys_and_cert.c new file mode 100644 index 0000000000..206c1a2617 --- /dev/null +++ b/demos/src/Provisioning/aws_iot_demo_provisioning_with_keys_and_cert.c @@ -0,0 +1,592 @@ +/* + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * @file aws_iot_demo_provisioning_with_keys_and_cert.c + * @brief Demonstrates usage of the Provisioning library for the use-case involving + * generation of keys and certificate by AWS IoT. + * + * This program demonstrates the using Provisioning documents to toggle a state called + * "powerOn" in a remote device. + */ + +/* The config header is always included first. */ +#include "iot_config.h" + +/* Standard includes. */ +#include +#include +#include +#include + +/* Set up logging for this demo. */ +#include "iot_demo_logging.h" + +/* Platform layer includes. */ +#include "platform/iot_clock.h" +#include "platform/iot_threads.h" + +/* MQTT include. */ +#include "iot_mqtt.h" + +/* Provisioning include. */ +#include "aws_iot_provisioning.h" + +/** + * @cond DOXYGEN_IGNORE + * Doxygen should ignore this section. + * + * Provide default values for undefined configuration settings. + */ +#ifndef AWS_IOT_DEMO_PROVISIONING_TIMEOUT_PERIOD_MS + #define AWS_IOT_DEMO_PROVISIONING_TIMEOUT_PERIOD_MS ( 5000 ) +#endif +/** @endcond */ + +/** + * @brief The keep-alive interval used for this demo. + * + * An MQTT ping request will be sent periodically at this interval. + */ +#define KEEP_ALIVE_SECONDS ( 60 ) + +/** + * @brief The timeout for Provisioning and MQTT operations in this demo. + */ +#define TIMEOUT_MS ( 5000 ) + +/** + * @brief The template name to use for provisioning the demo application. + */ +static const char pTemplateName[] = AWS_IOT_DEMO_PROVISIONING_TEMPLATE_NAME; + +/** + * @brief Stores the received certificate ID and certificate ownership token from the server. + */ +typedef struct _demoKeysAndCertificateCallbackContext +{ + char * pCertificateIdBuffer; /**< @brief Buffer containing the certificate ID returned by the server. */ + size_t certificateIdLength; /**< @brief Length of the certificate ID* buffer. */ + char * pOwnershipTokenBuffer; /**< @brief Buffer containing the certificate ownership token returned + * by the server. */ + size_t tokenLength; /**< @brief Length of the ownership token. */ +} _demoKeysAndCertificateCallbackContext_t; + +/*-----------------------------------------------------------*/ + +/* Declaration of demo function. */ +int RunProvisioningWithKeysAndCertDemo( bool awsIotMqttMode, + const char * pIdentifier, + void * pNetworkServerInfo, + void * pNetworkCredentialInfo, + const IotNetworkInterface_t * pNetworkInterface ); + +/*-----------------------------------------------------------*/ + +/** + * @brief Prints the rejected reponse information received from the server. + */ +static void _printRejectedResponse( const AwsIotProvisioningRejectedResponse_t * pResponseInfo ) +{ + IotLogError( "ErrorCode={%.*s}\n ErrorMessage={%.*s}\n", + pResponseInfo->errorCodeLength, pResponseInfo->pErrorCode, + pResponseInfo->errorMessageLength, pResponseInfo->pErrorMessage ); +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Callback for displaying the information in the server response. If the response is successful (i.e. contains + * credentials), the Certificate ID and ownership token data will be copied into buffers for use later in the demo. + * + * @param[in] contextParam The context of the callback containing buffers to copy the credentials to. + * @param[in] pResponseInfo The device credentials information obtained from the server that will be copied into the + * shared buffers of the demo. + */ +static void _demoKeysAndCertificateCallback( void * contextParam, + const AwsIotProvisioningCreateKeysAndCertificateResponse_t * pResponseInfo ) +{ + _demoKeysAndCertificateCallbackContext_t * certificateIdTokenContext = + ( _demoKeysAndCertificateCallbackContext_t * ) contextParam; + + IotLogInfo( "Received StatusCode={%d}", pResponseInfo->statusCode ); + + if( pResponseInfo->statusCode == AWS_IOT_PROVISIONING_SERVER_STATUS_ACCEPTED ) + { + /* Allocate buffer space for storing the certificate ID obtained from the server. */ + certificateIdTokenContext->pCertificateIdBuffer = + Iot_DefaultMalloc( pResponseInfo->u.acceptedResponse.certificateIdLength + 1 ); + + /* Copy the certificate ID into the buffer. */ + if( certificateIdTokenContext->pCertificateIdBuffer != NULL ) + { + /* Copy the size of the Certificate ID string. */ + certificateIdTokenContext->certificateIdLength = pResponseInfo->u.acceptedResponse.certificateIdLength; + + memcpy( certificateIdTokenContext->pCertificateIdBuffer, + pResponseInfo->u.acceptedResponse.pCertificateId, + pResponseInfo->u.acceptedResponse.certificateIdLength ); + /* Add a NULL terminator to the buffer (to treat the buffer as a string!) */ + *( certificateIdTokenContext->pCertificateIdBuffer + pResponseInfo->u.acceptedResponse.certificateIdLength ) = '\0'; + } + + /* Allocate buffer space for storing the ownership token string obtained from the server. */ + certificateIdTokenContext->pOwnershipTokenBuffer = + Iot_DefaultMalloc( pResponseInfo->u.acceptedResponse.ownershipTokenLength + 1 ); + + /* Copy the ownership token into the buffer. */ + if( certificateIdTokenContext->pOwnershipTokenBuffer != NULL ) + { + /* Copy the size of the ownership token string. */ + certificateIdTokenContext->tokenLength = pResponseInfo->u.acceptedResponse.ownershipTokenLength; + + memcpy( certificateIdTokenContext->pOwnershipTokenBuffer, + pResponseInfo->u.acceptedResponse.pCertificateOwnershipToken, + pResponseInfo->u.acceptedResponse.ownershipTokenLength ); + /* Add a NULL terminator to the buffer (to treat the buffer as a string!) */ + *( certificateIdTokenContext->pOwnershipTokenBuffer + pResponseInfo->u.acceptedResponse.ownershipTokenLength ) = '\0'; + } + + /* Print the received credentials information. This is ONLY for the demonstration purpose, STORE THE + * PRIVATE KEY SECURELY! */ + IotLogInfo( "\n Certificate PEM = %.*s\n Certificate ID = %.*s\n Ownership Token = %.*s\n DREADED PRIVATE KEY = %.*s\n", + pResponseInfo->u.acceptedResponse.deviceCertificateLength, + pResponseInfo->u.acceptedResponse.pDeviceCertificate, + pResponseInfo->u.acceptedResponse.certificateIdLength, + pResponseInfo->u.acceptedResponse.pCertificateId, + pResponseInfo->u.acceptedResponse.ownershipTokenLength, + pResponseInfo->u.acceptedResponse.pCertificateOwnershipToken, + pResponseInfo->u.acceptedResponse.privateKeyLength, + pResponseInfo->u.acceptedResponse.pPrivateKey ); + } + else + { + IotLogInfo( "Oops, server rejected request for creating new credentials. " + "Please verify that the IoT Policy attached to the demo credentials " + "allows the \"iot:CreateKeysAndCertificate\" action." ); + _printRejectedResponse( &pResponseInfo->u.rejectedResponse ); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Callback for displaying provisioning information sent by the server, if the provisioning request is + * successful. + * + * @param[in] contextParam Unused parameter for the demo. + * @param[in] pResponseInfo The information in the response received from the server. + */ +static void _demoRegisterThingCallback( void * contextParam, + const AwsIotProvisioningRegisterThingResponse_t * pResponseInfo ) +{ + ( void ) contextParam; + + IotLogInfo( "Received StatusCode={%d}", pResponseInfo->statusCode ); + + if( pResponseInfo->statusCode == AWS_IOT_PROVISIONING_SERVER_STATUS_ACCEPTED ) + { + if( pResponseInfo->u.acceptedResponse.pThingName != NULL ) + { + IotLogInfo( "ThingName = %.*s", + pResponseInfo->u.acceptedResponse.thingNameLength, + pResponseInfo->u.acceptedResponse.pThingName ); + } + + if( pResponseInfo->u.acceptedResponse.numOfConfigurationEntries > 0 ) + { + const AwsIotProvisioningResponseDeviceConfigurationEntry_t * pConfigurationList = + pResponseInfo->u.acceptedResponse.pDeviceConfigList; + + for( size_t configIndex = 0; + configIndex < pResponseInfo->u.acceptedResponse.numOfConfigurationEntries; configIndex++ ) + { + IotLogInfo( "Device Configuration no. %d\nConfigName = %.*s, ConfigData = %.*s ", + configIndex, + pConfigurationList[ configIndex ].keyLength, + pConfigurationList[ configIndex ].pKey, + pConfigurationList[ configIndex ].valueLength, + pConfigurationList[ configIndex ].pValue ); + } + } + } + else + { + IotLogInfo( "Oops, server rejected request for provisioning the demo app. " + "Please verify that the IoT Policy attached to the demo credentials " + "allows the \"iot:RegisterThing\" action." ); + _printRejectedResponse( &pResponseInfo->u.rejectedResponse ); + } +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Initialize the the MQTT library and the Provisioning library. + * + * @return `EXIT_SUCCESS` if all libraries were successfully initialized; + * `EXIT_FAILURE` otherwise. + */ +static int _initializeDemo( void ) +{ + int status = EXIT_SUCCESS; + IotMqttError_t mqttInitStatus = IOT_MQTT_SUCCESS; + AwsIotProvisioningError_t provisioningInitStatus = AWS_IOT_PROVISIONING_SUCCESS; + + /* Flags to track cleanup on error. */ + bool mqttInitialized = false; + + /* Initialize the MQTT library. */ + mqttInitStatus = IotMqtt_Init(); + + if( mqttInitStatus == IOT_MQTT_SUCCESS ) + { + mqttInitialized = true; + } + else + { + status = EXIT_FAILURE; + } + + /* Initialize the Provisioning library. */ + if( status == EXIT_SUCCESS ) + { + /* Use the default MQTT timeout. */ + provisioningInitStatus = AwsIotProvisioning_Init( 0 ); + + if( provisioningInitStatus != AWS_IOT_PROVISIONING_SUCCESS ) + { + status = EXIT_FAILURE; + } + } + + /* Clean up on error. */ + if( status == EXIT_FAILURE ) + { + if( mqttInitialized == true ) + { + IotMqtt_Cleanup(); + } + } + + return status; +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Clean up the the MQTT library and the Provisioning library. + */ +static void _cleanupDemo( void ) +{ + AwsIotProvisioning_Cleanup(); + IotMqtt_Cleanup(); +} + +/*-----------------------------------------------------------*/ + +/** + * @brief Establish a new connection to the MQTT server for the Provisioning demo. + * + * @param[in] pIdentifier NULL-terminated MQTT client identifier. The Provisioning + * demo will use the Thing Name as the client identifier. + * @param[in] pNetworkServerInfo Passed to the MQTT connect function when + * establishing the MQTT connection. + * @param[in] pNetworkCredentialInfo Passed to the MQTT connect function when + * establishing the MQTT connection. + * @param[in] pNetworkInterface The network interface to use for this demo. + * @param[out] pMqttConnection Set to the handle to the new MQTT connection. + * + * @return `EXIT_SUCCESS` if the connection is successfully established; `EXIT_FAILURE` + * otherwise. + */ +static int _establishMqttConnection( const char * pIdentifier, + void * pNetworkServerInfo, + void * pNetworkCredentialInfo, + const IotNetworkInterface_t * pNetworkInterface, + IotMqttConnection_t * pMqttConnection ) +{ + int status = EXIT_SUCCESS; + IotMqttError_t connectStatus = IOT_MQTT_STATUS_PENDING; + IotMqttNetworkInfo_t networkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER; + IotMqttConnectInfo_t connectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER; + + /* Set the members of the network info not set by the initializer. This + * struct provided information on the transport layer to the MQTT connection. */ + networkInfo.createNetworkConnection = true; + networkInfo.u.setup.pNetworkServerInfo = pNetworkServerInfo; + networkInfo.u.setup.pNetworkCredentialInfo = pNetworkCredentialInfo; + networkInfo.pNetworkInterface = pNetworkInterface; + + /* Set the members of the connection info not set by the initializer. */ + connectInfo.awsIotMqttMode = true; + connectInfo.cleanSession = true; + connectInfo.keepAliveSeconds = KEEP_ALIVE_SECONDS; + + /* AWS IoT recommends the use of the Thing Name as the MQTT client ID. */ + connectInfo.pClientIdentifier = pIdentifier; + connectInfo.clientIdentifierLength = ( uint16_t ) strlen( pIdentifier ); + + /* Establish the MQTT connection. */ + connectStatus = IotMqtt_Connect( &networkInfo, + &connectInfo, + TIMEOUT_MS, + pMqttConnection ); + + if( connectStatus != IOT_MQTT_SUCCESS ) + { + IotLogError( "MQTT CONNECT returned error %s.", + IotMqtt_strerror( connectStatus ) ); + + status = EXIT_FAILURE; + } + + return status; +} + +/*-----------------------------------------------------------*/ + +/** + * @brief The function that runs the Provisioning demo for the AWS IoT generated + * keys and certificate use-case, called by the demo runner. + * + * @param[in] awsIotMqttMode Ignored for the Provisioning demo. + * @param[in] pIdentifier NULL-terminated Provisioning Thing Name. + * @param[in] pNetworkServerInfo Passed to the MQTT connect function when + * establishing the MQTT connection for testing the Fleet Provisioning feature of AWS Iot Core service. + * @param[in] pNetworkCredentialInfo Passed to the MQTT connect function when + * establishing the MQTT connection for testing the Fleet Provisioning feature of AWS Iot Core service. + * @param[in] pNetworkInterface The network interface to use for this demo. + * + * @return `EXIT_SUCCESS` if the demo completes successfully; `EXIT_FAILURE` otherwise. + */ +int RunProvisioningWithKeysAndCertDemo( bool awsIotMqttMode, + const char * pIdentifier, + void * pNetworkServerInfo, + void * pNetworkCredentialInfo, + const IotNetworkInterface_t * pNetworkInterface ) +{ + /* Return value of this function and the exit status of this program. */ + int status = 0; + + /* Handle of the MQTT connection used in this demo. */ + IotMqttConnection_t mqttConnection = IOT_MQTT_CONNECTION_INITIALIZER; + + /* Callbacks for the library APIs. */ + AwsIotProvisioningCreateKeysAndCertificateCallbackInfo_t keysAndCertificateCallback = AWS_IOT_PROVISIONING_CREATE_KEYS_AND_CERTIFICATE_CALLBACK_INFO_INITIALIZER; + AwsIotProvisioningRegisterThingCallbackInfo_t registerThingResponseCallback = AWS_IOT_PROVISIONING_REGISTER_THING_CALLBACK_INFO_INITIALIZER; + + /* Represents memory that will be allocated to store the Certificate ID that will be provided by the credential + * requesting API through the callback. */ + _demoKeysAndCertificateCallbackContext_t newCertificateDataContext; + + newCertificateDataContext.pCertificateIdBuffer = NULL; + newCertificateDataContext.certificateIdLength = 0; + newCertificateDataContext.pOwnershipTokenBuffer = NULL; + newCertificateDataContext.tokenLength = 0; + + /* Request data for provisioning the demo application. */ + AwsIotProvisioningRegisterThingRequestInfo_t requestInfo; + + /* Flags for tracking which cleanup functions must be called. */ + bool librariesInitialized = false, connectionEstablished = false; + + /* The first parameter of this demo function is not used. Provisioning feature is specific + * to AWS IoT, so this value is hardcoded to true whenever needed. */ + ( void ) awsIotMqttMode; + + /* This will be used for tracking the return code from the Provisioning APIs. */ + AwsIotProvisioningError_t requestStatus = AWS_IOT_PROVISIONING_SUCCESS; + + /* The list of parameters that will be used as "context" for provisioning the demo application. + * This demo will pass exactly 2 different parameter entries for requesting provisioning. */ + AwsIotProvisioningRequestParameterEntry_t provisioningParameters[ 2 ] = { { 0 } }; + + /* Determine if a provisioning template name has been specified. */ + if( ( ( void * ) pTemplateName == NULL ) || ( strlen( pTemplateName ) == 0 ) ) + { + IotLogError( "A valid provisioning template name must be provided." ); + status = EXIT_FAILURE; + } + + /* Generate the list of parameters to send for provisioning */ + if( status != EXIT_FAILURE ) + { + if( ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME == NULL ) || + ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME_LENGTH == 0 ) || + ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE == NULL ) || + ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE_LENGTH == 0 ) || + ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME == NULL ) || + ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME_LENGTH == 0 ) || + ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE == NULL ) || + ( AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE_LENGTH == 0 ) ) + { + IotLogError( "The provisioning demo requires 2 pairs of name and value data for parameters to be configured." ); + status = EXIT_FAILURE; + } + else + { + provisioningParameters[ 0 ].pParameterKey = AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME; + provisioningParameters[ 0 ].parameterKeyLength = AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME_LENGTH; + provisioningParameters[ 0 ].pParameterValue = AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE; + provisioningParameters[ 0 ].parameterValueLength = AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE_LENGTH; + provisioningParameters[ 1 ].pParameterKey = AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME; + provisioningParameters[ 1 ].parameterKeyLength = AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME_LENGTH; + provisioningParameters[ 1 ].pParameterValue = AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE; + provisioningParameters[ 1 ].parameterValueLength = AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE_LENGTH; + } + } + + if( status != EXIT_FAILURE ) + { + /* Determine the length of the client ID Name. */ + if( pIdentifier != NULL ) + { + if( strlen( pIdentifier ) == 0 ) + { + IotLogError( "The length of the MQTT client identifier must be nonzero." ); + + status = EXIT_FAILURE; + } + } + else if( pIdentifier == NULL ) + { + IotLogError( "A client identifier must be provided for the Provisioning demo." ); + + status = EXIT_FAILURE; + } + } + + /* Initialize the libraries required for this demo. */ + if( status == EXIT_SUCCESS ) + { + status = _initializeDemo(); + } + + if( status == EXIT_SUCCESS ) + { + /* Mark the libraries as initialized. */ + librariesInitialized = true; + + /* Establish a new MQTT connection. */ + status = _establishMqttConnection( pIdentifier, + pNetworkServerInfo, + pNetworkCredentialInfo, + pNetworkInterface, + &mqttConnection ); + } + + if( status == EXIT_SUCCESS ) + { + /* Mark the MQTT connection as established. */ + connectionEstablished = true; + + /* Set the certificate ID pointer as context parameter to the credentials response processing callback. */ + keysAndCertificateCallback.userParam = &newCertificateDataContext; + + /* Set the callback function for handling device credentials that the server will send. */ + keysAndCertificateCallback.function = _demoKeysAndCertificateCallback; + + /* Call the API to get new device credentials for this demo, and check that the certificate ID data is populated. */ + requestStatus = AwsIotProvisioning_CreateKeysAndCertificate( mqttConnection, + 0, + AWS_IOT_DEMO_PROVISIONING_TIMEOUT_PERIOD_MS, + &keysAndCertificateCallback ); + + if( requestStatus != AWS_IOT_PROVISIONING_SUCCESS ) + { + status = EXIT_FAILURE; + IotLogError( "Request to get new credentials failed, error %s ", + AwsIotProvisioning_strerror( requestStatus ) ); + } + else if( ( newCertificateDataContext.pCertificateIdBuffer == NULL ) || + ( newCertificateDataContext.pOwnershipTokenBuffer == NULL ) ) + { + IotLogInfo( "Don't have either the Certificate ID OR the Certificate Ownership Token (or both) to proceed with provisioning. So exiting...!" ); + } + else + { + IotLogInfo( "Succeeded in receiving new device credentials!" ); + } + } + + if( status == EXIT_SUCCESS ) + { + /* Set the parameters for requesting provisioning. */ + requestInfo.pDeviceCertificateId = newCertificateDataContext.pCertificateIdBuffer; + requestInfo.deviceCertificateIdLength = newCertificateDataContext.certificateIdLength; + requestInfo.pCertificateOwnershipToken = newCertificateDataContext.pOwnershipTokenBuffer; + requestInfo.ownershipTokenLength = newCertificateDataContext.tokenLength; + requestInfo.pTemplateName = AWS_IOT_DEMO_PROVISIONING_TEMPLATE_NAME; + requestInfo.templateNameLength = sizeof( AWS_IOT_DEMO_PROVISIONING_TEMPLATE_NAME ) - 1; + requestInfo.pParametersStart = provisioningParameters; + requestInfo.numOfParameters = sizeof( provisioningParameters ) / sizeof( AwsIotProvisioningRequestParameterEntry_t ); + + /* Set the callback function for handling device credentials that the server will send. */ + registerThingResponseCallback.function = _demoRegisterThingCallback; + + /* Call the API to provision the demo application with the certificate ID that we received, and the template + * name associated with the demo endpoint account. */ + requestStatus = AwsIotProvisioning_RegisterThing( mqttConnection, + &requestInfo, + AWS_IOT_DEMO_PROVISIONING_TIMEOUT_PERIOD_MS, + ®isterThingResponseCallback ); + + if( requestStatus != AWS_IOT_PROVISIONING_SUCCESS ) + { + status = EXIT_FAILURE; + IotLogError( "Failed to provision demo application, error %s", + AwsIotProvisioning_strerror( requestStatus ) ); + } + else + { + IotLogInfo( "Succeeded in provisioning our demo application!" ); + } + } + + /* Disconnect the MQTT connection if it was established. */ + if( connectionEstablished == true ) + { + IotMqtt_Disconnect( mqttConnection, 0 ); + } + + /* Clean up libraries if they were initialized. */ + if( librariesInitialized == true ) + { + _cleanupDemo(); + } + + /* Release the Certificate ID buffer, if memory was allocated for it. */ + if( newCertificateDataContext.pCertificateIdBuffer != NULL ) + { + Iot_DefaultFree( newCertificateDataContext.pCertificateIdBuffer ); + } + + /* Release the ownership token buffer, if memory was allocated for it. */ + if( newCertificateDataContext.pOwnershipTokenBuffer != NULL ) + { + Iot_DefaultFree( newCertificateDataContext.pOwnershipTokenBuffer ); + } + + return status; +} + +/*-----------------------------------------------------------*/ diff --git a/doc/config/layout_main.xml b/doc/config/layout_main.xml index e2014d4de6..f28d650242 100644 --- a/doc/config/layout_main.xml +++ b/doc/config/layout_main.xml @@ -11,6 +11,7 @@ + diff --git a/doc/config/main b/doc/config/main index 32b1919719..783d7557c7 100644 --- a/doc/config/main +++ b/doc/config/main @@ -31,7 +31,8 @@ TAGFILES = doc/tag/logging.tag=../logging \ doc/tag/platform.tag=../platform \ doc/tag/mqtt.tag=../mqtt \ doc/tag/shadow.tag=../shadow \ - doc/tag/jobs.tag=../jobs + doc/tag/jobs.tag=../jobs \ + doc/tag/provisioning.tag=../provisioning # Use the Main page layout file LAYOUT_FILE = doc/config/layout_main.xml diff --git a/doc/config/provisioning b/doc/config/provisioning new file mode 100644 index 0000000000..a9adbbdf9b --- /dev/null +++ b/doc/config/provisioning @@ -0,0 +1,32 @@ +# Include common configuration options. +@INCLUDE_PATH = doc/config +@INCLUDE = common + +# Basic project information. +PROJECT_NAME = "Fleet Provisioning" +PROJECT_BRIEF = "AWS IoT Fleet Provisioning" + +# Library documentation output directory. +HTML_OUTPUT = provisioning + +# Generate Doxygen tag file for this library. +GENERATE_TAGFILE = doc/tag/provisioning.tag + +# Directories containing library source code. +INPUT = doc/lib/ \ + libraries/aws/provisioning/include \ + libraries/aws/provisioning/include/types \ + libraries/aws/provisioning/src \ + libraries/aws/provisioning/src/private \ + libraries/aws/provisioning/test \ + demos/src + +# Library file names. +FILE_PATTERNS = *provisioning*.h *provisioning*.c *provisioning*.txt + +# External tag files required by this library. +TAGFILES = doc/tag/main.tag=../main \ + doc/tag/mqtt.tag=../mqtt \ + doc/tag/logging.tag=../logging \ + doc/tag/static_memory.tag=../static_memory \ + doc/tag/platform.tag=../platform diff --git a/doc/guide/developer/automated_tests.txt b/doc/guide/developer/automated_tests.txt index 4ede09d1be..d84f98daf9 100644 --- a/doc/guide/developer/automated_tests.txt +++ b/doc/guide/developer/automated_tests.txt @@ -150,8 +150,8 @@ AWS recommends using the most restrictive policy possible. The following policy This policy only allows the CI to interact with topics that contain a matching client identifier (which is prefixed with the Travis CI variable `IOT_IDENTIFIER_PREFIX`). A few special topics used by the MQTT tests are also present. The policy will need to be updated if any new topics are used by the tests in the future. -@section guide_developer_automated_tests_jobs Additional Travis CI setup for Jobs system tests -@brief Additional CI settings for running the [Jobs system tests](@ref jobs_tests). +@section guide_developer_automated_tests_jobs_and_provisioning Additional Travis CI setup for Jobs and Provisioning system tests +@brief Additional CI settings for running the [Jobs system tests](@ref jobs_tests) and [Provisioning system tests](@ref provisioning_tests). The Jobs system tests use AWS CLI to create and delete Jobs. Therefore, additional setup is needed in Travis CI. diff --git a/doc/lib/jobs.txt b/doc/lib/jobs.txt index 7b18b06f51..d91f5949c0 100644 --- a/doc/lib/jobs.txt +++ b/doc/lib/jobs.txt @@ -49,7 +49,7 @@ In addition to the components above, the Jobs library also depends on C standard @page jobs_design Design @brief Architecture behind the Jobs library. -The Jobs library uses MQTT subscriptions and publishes to communicate with the AWS IoT Jobs Service. Jobs operations such as Get Pending, Start Next, Describe, and Update use MQTT subscriptions to two MQTT topics in order to receive their accepted/rejected status, and publish to the appropriate topic for the operation. The Jobs Notify Next callback uses an MQTT subscription to receive data from the AWS IoT Jobs Service when the information for the next job in the queue changes. The Notify Pending callbacks does the same for the case when any job changes. These callbacks are run in MQTT's taskpool context. +The Jobs library uses MQTT subscriptions and publishes to communicate with the AWS IoT Jobs Service. Jobs operations such as Get Pending, Start Next, Describe, and Update use MQTT subscriptions to two MQTT topics in order to receive their accepted/rejected status, and publish to the appropriate topic for the operation. The Jobs Notify Next callback uses an MQTT subscription to receive data from the AWS IoT Jobs Service when the information for the next job in the queue changes. The Notify Pending callbacks does the same for the case when any job changes. These callbacks are run in the system taskpool context. @section jobs_synchronous_design Synchronous Design @image html jobs_sync_detail.png width=100% @@ -71,7 +71,7 @@ The Jobs demo establishes an MQTT connection and registers a [Jobs NotifyNext ca Because the Jobs MQTT API does not support creating Jobs, you must create Jobs for the demo separately. We recommend using AWS CLI to create Jobs. -1. Create a user for AWS CLI. See steps 1 and 2 of @ref guide_developer_automated_tests_jobs for more information. +1. Create a user for AWS CLI. See steps 1 and 2 of @ref guide_developer_automated_tests_jobs_and_provisioning for more information. 2. Build and run the demo as described [here](@ref building). 3. When the following message appears, you may begin creating Jobs for the demo. @code{sh} @@ -143,7 +143,7 @@ The current Jobs tests use the [Unity test framework](http://www.throwtheswitch. The Jobs system tests require Jobs to be created with an AWS account. AWS does not provide the functionality to create Jobs using the Device API; therefore, Jobs will have to be created using another method. -See @ref guide_developer_automated_tests_jobs for additional setup for running the Jobs tests on Travis CI. +See @ref guide_developer_automated_tests_jobs_and_provisioning for additional setup for running the Jobs tests on Travis CI. 1. Register a Thing for the tests. This needs to be done only once.
Follow [this guide](https://docs.aws.amazon.com/iot/latest/developerguide/register-device.html) to register a new Thing. diff --git a/doc/lib/provisioning.txt b/doc/lib/provisioning.txt new file mode 100644 index 0000000000..59ea279f27 --- /dev/null +++ b/doc/lib/provisioning.txt @@ -0,0 +1,416 @@ +/** +@mainpage +@anchor Fleet Provisioning +@brief Library for the fleet provisioning feature of AWS IoT. + +> When you use AWS IoT fleet provisioning, AWS IoT can generate and securely deliver device certificates and private keys to your devices when they connect to AWS IoT for the first time. + +Description of the fleet provisioning feature from [AWS IoT documentation](https://docs.aws.amazon.com/iot/latest/developerguide/provision-wo-cert.html)
+ +This library provides an API based on the [Fleet Provisioning APIs available over MQTT](https://docs.aws.amazon.com/iot/latest/developerguide/provision-wo-cert.html#fleet-provision-api). Features of this library include: +- Synchronous API functions. +- User-defined callbacks for handling responses. + +@dependencies{provisioning,Provisioning library} +@dot "Provisioning direct dependencies" +digraph provisioning_dependencies +{ + node[shape=box, fontname=Helvetica, fontsize=10, style=filled]; + edge[fontname=Helvetica, fontsize=10]; + subgraph + { + provisioning[label="Provisioning", fillcolor="#cc00ccff"]; + mqtt[label="MQTT", fillcolor="#cc00ccff", URL="@ref mqtt"]; + } + subgraph + { + node[fillcolor="#aed8a9ff"]; + rank = same; + static_memory[label="Static memory", URL="@ref static_memory"]; + logging[label="Logging", URL="@ref logging"]; + } + provisioning -> mqtt; + provisioning -> logging [label=" if logging enabled", style="dashed"]; + provisioning -> static_memory [label=" if static memory only", style="dashed"]; +} +@enddot + +Currently, the Provisioning library has the following dependencies: +- The MQTT library used to communicate with the AWS IoT Core service. See [this page](@ref mqtt) for more information on the MQTT library (and [its dependencies](@ref mqtt_dependencies)) +- The static memory library will be used if the library is built with `IOT_STATIC_MEMORY_ONLY` flag set to `1` +- The logging library may be used if @ref AWS_IOT_LOG_LEVEL_PROVISIONING is not #IOT_LOG_NONE. + +In addition to the components above, the Provisioning library also depends on C standard libraries. + +@section provisioning_memory Memory requirements +@brief Memory requirements of the Provisioning library. + +@subsection provisioning_memory_code Code size +@brief Code size of the Provisioning library. + +The following measurements were taken with arm-none-eabi-gcc v9.2.1 (November 2019) with the [Provisioning library from April 2020](https://github.com/aws/aws-iot-device-sdk-embedded-C/commit/26acc9320e35d29086e2b519f46040daab776f70). These values are rough estimates not tuned for any specific ARM processor. + +(Also, refer to the [MQTT memory requirements](@ref mqtt_memory), which is a dependency of the Provisioning library.) + +Minimal Size Build
+No logging, asserts, or diagnostic information. Compiled using the ARM Thumb instruction set (`-mthumb`) and optimized for size (`-Os`). Values are in bytes. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
objecttextdatabss
aws_iot_provisioning_api1744472
aws_iot_provisioning_parser154200
aws_iot_provisioning_serializer127800
total4564472
+ +Debug Build
+All logging, asserts, and diagnostic information enabled. Debugging symbols available. Compiled using the ARM Thumb instruction set (`-mthumb`). Values are in bytes. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
objecttextdatabss
aws_iot_provisioning_api7644469
aws_iot_provisioning_parser789900
aws_iot_provisioning_serializer570100
total21244469
+ +*/ + +/** +@page provisioning_design Design +@brief Provisioning library architecture. + +The Provisioning library uses MQTT publish/subscribe to interact with the AWS IoT Core service for the Fleet Provisioning feature. Each library operation ("CreateKeysAndCertificate", "CreateCertificateFromCsr", "RegisterThing") uses two MQTT subscriptions, one for the "accepted" topic and one for the "rejected" topic, to obtain the responses from AWS IoT Core, and publishes to the MQTT request topic of the operation. Each operation also requires a user-callback for handling the server response. The callbacks will run in the system taskpool context. + +@section HighLevelOperation_Design High Level Design of a Provisioning Operation +@brief The following shows a high-level workflow of each library operation. The library uses the MQTT stack for communicating with AWS IoT and the serializer stack for serializing and de-serializing request and responses, respectively, from the server. +@image html provisioning_operation_highlevel_design.png width=100% + +@section DetailedOperation_Design Detailed Workflow Diagram of a Provisioning Operation +@brief The following shows the detailed workflow of each Provisioning operation. The Provisioning library architecture consists of 3 layers: API, serializer and parser, all of which are used for each Provisioning operation. The library uses an internal global state memory, separate for each operation type, that is shared between the Provisioning API and MQTT subscription callback layers. The global state represents the state of the operation and provides a synchronization mechanism between the Provisioning API and MQTT subscription callback layers. +@image html provisioning_operation_detailed_design.png width=100% + +*/ + +/** +@page provisioning_demo Demo +@brief The demos demonstrate the usage of the Provisioning library for 2 different Provisioning workflows: +
    +
  • Provisioning when both keys and certificate are requested from AWS IoT.
  • +
  • Provisioning when device provides a Certificate-Signing Request to AWS IoT for certificate creation.
  • +
+These demos represent simple examples of using the Provisioning library for provisioning devices with the AWS IoT Fleet Provisioning feature. + +Both the demos establish an MQTT connection and make two API calls to the Fleet Provisioning feature of the AWS IoT Core service for illustrating their specific Provisioning workflow. + +@section Demo_KeysAndCert Provisioning Demo with AWS IoT created Keys and certificate +@image html provisioning_demo_with_keys_and_cert.png "Provisioning Demo Workflow when keys are generated by AWS IoT" width=80% + +@section Demo_Csr Provisioning Demo with Certificate-Signing Request +@image html provisioning_demo_with_csr.png "Provisioning Demo Workflow with Certificate-Signing Request" width=80% + +@section provisioning_demo_setup Demo Setup +@brief How to set up a fleet provisioning template for the Provisioning demo. + +The demo assumes a fleet provisioning template which takes parameters (including one for "SerialNumber") from the device has been created in the account that will be used for connecting to AWS IoT Core. +To create a template, you can use the AWS IoT Console or AWS CLI. (For more information on fleet provisioning templates, refer [here](https://docs.aws.amazon.com/iot/latest/developerguide/provision-template.html). ) + +1. Create an IAM user for AWS CLI. See steps 1 @ref guide_developer_automated_tests_jobs_and_provisioning for more information. +2. Create an IAM role and attach a policy to the role. The role is required to create the provisioning template. (The provisioning template assumes the role for its runtime behavior.) See steps 2 and 3 in @ref provisioning_system_tests_setup for more information +3. Create a provisioning template for the demo. See step 4 in @ref provisioning_system_tests_setup for more information. +4. Build and run the demo as described [here](@ref building). + +See @subpage provisioning_demo_config for configuration settings that change the behavior of the demo. + +*/ + +/** +@configpage{provisioning_demo,Provisioning demo,Demo,demos} + +@section AWS_IOT_DEMO_PROVISIONING_CSR_PEM +@brief The provisioning demo uses this Certificate-Signing Request data to demonstrate the CSR based provisioning use-case of fleet provisioning. + +@configpossible The Certificate-Signing Request string in PEM format
+@configdefault `""` (empty string) + +@section AWS_IOT_DEMO_PROVISIONING_TEMPLATE_NAME +@brief The provisioning demo uses this template to demonstrate the fleet provisioning feature. + +@configpossible Any string
+@configdefault `""` (empty string) + +@section AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME +@brief The name of the serial number parameter sent in the provisioning request. + +The fleet provisioning template, `AWS_IOT_DEMO_PROVISIONING_TEMPLATE_NAME`, should be configured to accept the parameter. (The default template generated by AWS IoT Console uses "SerialNumber" to generate Thing resource name on provisioning device.) +It is recommended to use serial number (or an equivalent unique device identifier) to provide as parameter to the AWS IoT Core service for provisioning of the device. + +@configpossible Any string that can be accepted by the template.
+@configdefault `"SerialNumber"` + +@section AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME_LENGTH +@brief The length of the parameter associated with `AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME`. + +@configdefault `sizeof( AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME ) - 1`
+@configrecommended Don't change the default value unless there is a need to use a different length. + +@section AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE +@brief The value of the parameter associated with `AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE`. + +@configpossible Any string value
+@configdefault `""` (empty string) + +@section AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE_LENGTH +@brief The length of the parameter associated with `AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_NAME`. + +@configdefault `sizeof( AWS_IOT_DEMO_PROVISIONING_PARAMETER_SERIAL_NUMBER_VALUE_LENGTH ) - 1`
+@configrecommended Don't change the default value unless there is a need to use a different length. + +@section AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME +@brief The name of the additional parameter sent in the provisioning request. + +An additional parameter can be sent to the AWS IoT Core service to utilize for _evaluating_ and sending back device configuration in the response. In that case, make sure that the fleet provisioning template is configured to accept the parameter. + +@configpossible Any string that can be accepted by the template.
+@configdefault `""` + +@section AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME_LENGTH +@brief The length of the parameter associated with `AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME_LENGTH_NAME`. + +@configdefault `sizeof( AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME_LENGTH ) - 1`
+@configrecommended Don't change the default value unless there is a need to use a different length. + +@section AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE +@brief The value of the parameter associated with `AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME`. + +@configpossible Any string value
+@configdefault `""` (empty string) + +@section AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE_LENGTH +@brief The length of the parameter associated with `AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_NAME_LENGTH_VALUE`. + +@configdefault `sizeof( AWS_IOT_DEMO_PROVISIONING_PARAMETER_2_VALUE_LENGTH ) - 1`
+@configrecommended Don't change the default value unless there is a need to use a different length. + +*/ + +/** +@page provisioning_tests Tests +@brief Tests written for the Provisioning library. + +The Provisioning tests reside in the `provisioning/test` directory. They are divided into the following subdirectories: +- `system`: Provisioning system tests. These tests require a network connection and AWS IoT credentials. They also need an AWS account and a registered Provisioning Template in the account; see @ref provisioning_system_tests_setup for instructions to configure an AWS account to run these tests. The command line option `-n` may be passed to the test executable to disable these tests. +- `unit`: Provisioning unit tests. These tests do not require a network connection or credentials. These tests use the [MQTT mocks.](@ref mqtt_tests) + +See @subpage provisioning_tests_config for configuration settings that change the behavior of the Provisioning system tests. The Provisioning unit tests require no special configuration. + +The current Provisioning tests use the [Unity test framework](http://www.throwtheswitch.org/unity/). See @ref building_tests for a guide on running the tests. + +@section provisioning_system_tests_setup Setting up Provisioning system tests +@brief How to set up the Provisioning system tests. + +@pre The steps below assume basic familiarity with AWS and AWS CLI. + +The Provisioning system tests require a Provisioning Template to be created with an AWS account. AWS does not provide the functionality to create a fleet provisioning template using the Device API; therefore, a fleet provisioning template will have to be created using another method. + +See @ref guide_developer_automated_tests_jobs_and_provisioning for additional setup for running the Provisioning tests on Travis CI. + +1. Create an IAM user for the tests. This needs to be done only once.
+Follow [this guide](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html) to create an IAM user for the Provisioning tests. + - Only programmatic access is required. + - Save the access key and secret access key for this user. + - The following policy grants the necessary permissions for this user. Replace `` and `` with your AWS region and account number, respectively; replace `` with the name of the Provisioning Template that will be created in the next step (step 2).
+@code +{ + "Version": "2012-10-17", + "Statement": { + "Effect": "Allow", + "Action": [ + "iot:CreateProvisioningTemplate", + "iot:UpdateProvisioningTemplate", + "iot:DescribeProvisioningTemplate", + "iot:DeleteProvisioningTemplate", + "iot:ListProvisioningTemplates" + ], + "Resource": [ + "arn:aws:iot:::provisioningtemplate/*", + "arn:aws:iot:::service-role/*" + ] + } +} +@endcode + +2. Create an IAM role that will be needed by a fleet provisioning template. Replace `RoleName` with a name of the role you want to create. +@code{sh} +aws iam create-role \ + --role-name \ + --assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Action":"sts:AssumeRole","Effect":"Allow","Principal":{"Service":"iot.amazonaws.com"}}]}' +@endcode + +3. Attach a policy to the role created in step2. Replace `RoleName` with the name of the role you created in Step 2. +@code{sh} +aws iam attach-role-policy \ + --role-name \ + --policy-arn arn:aws:iam::aws:policy/service-role/AWSIoTThingsRegistration +@endcode + +4. Create the template resource which will be used for provisioning the demo application. This needs to be done only once.
+To create a template, the following AWS CLI command may be used. Replace `TemplateName` with the name of the fleet provisioning template you want to create. Replace `RoleName` with the name of the role you created in Step 2. Replace `TemplateJSON` with the template body as a JSON string (containing escape characters). Replace `account` with your AWS account number. +@code{sh} +aws iot create-provisioning-template \ + --template-name \ + --provisioning-role-arn arn:aws:iam:::service-role/ \ + --template-body "" \ + --enabled +@endcode +For more information on fleet provisioning template, refer to [this guide](https://docs.aws.amazon.com/iot/latest/developerguide/provision-template.html#fleet-provision-template) +Following is an example template JSON string (that uses "SerialNumber" for Thing resource name and accepts an additional "DeviceLocation" parameter) which can be viewed on AWS IoT Console after the AWS CLI command using it is executed
+``` +{\"Parameters\":{\"DeviceLocation\":{\"Type\":\"String\"},\"AWS::IoT::Certificate::Id\":{\"Type\":\"String\"},\"SerialNumber\":{\"Type\":\"String\"}},\"Mappings\":{\"LocationTable\":{\"Seattle\":{\"LocationUrl\":\"https://example.aws\"}}},\"Resources\":{\"thing\":{\"Type\":\"AWS::IoT::Thing\",\"Properties\":{\"ThingName\":{\"Fn::Join\":[\"\",[\"ThingPrefix_\",{\"Ref\":\"SerialNumber\"}]]},\"AttributePayload\":{\"version\":\"v1\",\"serialNumber\":\"serialNumber\"}},\"OverrideSettings\":{\"AttributePayload\":\"MERGE\",\"ThingTypeName\":\"REPLACE\",\"ThingGroups\":\"DO_NOTHING\"}},\"certificate\":{\"Type\":\"AWS::IoT::Certificate\",\"Properties\":{\"CertificateId\":{\"Ref\":\"AWS::IoT::Certificate::Id\"},\"Status\":\"Active\"},\"OverrideSettings\":{\"Status\":\"REPLACE\"}},\"policy\":{\"Type\":\"AWS::IoT::Policy\",\"Properties\":{\"PolicyDocument\":{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"iot:Connect\",\"iot:Subscribe\",\"iot:Publish\",\"iot:Receive\"],\"Resource\":\"*\"}]}}}},\"DeviceConfiguration\":{\"FallbackUrl\":\"https://www.example.com/test-site\",\"LocationUrl\":{\"Fn::FindInMap\":[\"LocationTable\",{\"Ref\":\"DeviceLocation\"},\"LocationUrl\"]}}} +``` +You can query the created template using the following CLI command. Replace the `TemplateName` with the fleet provisioning template you created. +@code{sh} +aws iot describe-provisioning-template --template-name +@endcode + +5. Set the name of provisioning template, created in step 4, in the config file for the `AWS_IOT_TEST_PROVISIONING_TEMPLATE_NAME` macro. Build the tests for the `aws_iot_tests_provisioning` target.
+ +6. When the Provisioning tests are complete, the provisioning template it used is no longer needed. Provisioning templates can be deleted with the following command, where `TemplateName` is the name of the template that is to be deleted. Replace the `` with the name of the provisioning template created in Step 4. +@code{sh} +aws iot delete-provisioning-template --template-name +@endcode +*/ + +/** +@configpage{provisioning_tests,Provisioning system tests,Test,tests} + +@section AWS_IOT_TEST_PROVISIONING_TEMPLATE_NAME +@brief The Template name to use in the Provisioning system tests. + +Provisioning Templates are used to facilitate provisioning of devices with AWS IoT Core. No default value is provided for Template Names, so this constant must be defined. In addition to the Template Name, AWS IoT credentials ([root CA certificate](@ref IOT_TEST_ROOT_CA), [client certificate](@ref IOT_TEST_CLIENT_CERT), and [client certificate private key](@ref IOT_TEST_PRIVATE_KEY)) must be provided to run the system tests. The [AWS IoT policy](https://docs.aws.amazon.com/iot/latest/developerguide/iot-policies.html) must also be properly configured. + +@configpossible A string representing an AWS IoT Fleet Provisioning Template Name. + +@section AWS_IOT_TEST_PROVISIONING_TEMPLATE_PARAMETERS +@brief The list of parameters to pass as device context in the Provisioning system tests. + +Template parameters are used to provide context of the device requesting provisioning. + +@configpossible A C-style list initialization of parameters.
+@configrecommended A "SerialNumber" parameter is required by the default Provisioning Template, that is created by the AWS IoT Console, to create a Thing resource. It should also include other parameter name-value pairs that are needed by the Provisioning Template.
+@configdefault A "SerialNumber" parameter name without the value. The parameter value should to be specified. +@code{c} + { \ + { \ + .pParameterKey = "SerialNumber", \ + .parameterKeyLength = sizeof( "SerialNumber" ) - 1, \ + .pParameterValue = "", \ + .parameterValueLength = 0 \ + } \ + } +@endcode + +*/ + +/** +@configpage{provisioning,Provisioning library} + +@section AWS_IOT_PROVISIONING_ENABLE_ASSERTS +@brief Set this to `1` to perform sanity checks when using the Provisioning library. + +Asserts are useful for debugging, but should be disabled in production code. If this is set to `1`, @ref AwsIotProvisioning_Assert can be defined to set the assertion function; otherwise, the @ref Iot_DefaultAssert will be used. + +@configpossible `0` (asserts disabled) or `1` (asserts enabled)
+@configrecommended `1` when debugging; `0` in production code.
+@configdefault `0` + +@section AWS_IOT_PROVISIONING_DEFAULT_MQTT_TIMEOUT_MS +@brief Set the default timeout (in milliseconds) for [MQTT library](@ref mqtt_functions) called by the Provisioning library. + +If the `mqttTimeout` argument of @ref provisioning_function_init is `0`, the Provisioning library uses this setting for MQTT timeouts. This timeout is passed to functions such as @ref mqtt_function_subscribesync, and @ref mqtt_function_publishsync to limit amount of time an MQTT function may block. + +@configpossible Any positive integer.
+@configrecommended This setting must be at least the network round-trip time, as an MQTT packet must be sent to the AWS IoT server and a response must be received. The recommended minimum value is `500`.
+@configdefault `5000` + +@section AWS_IOT_LOG_LEVEL_PROVISIONING +@brief Set the log level of the Provisioning library. + +Log messages from the Provisioning library at or below this setting will be printed. + +@configpossible One of the @ref logging_constants_levels.
+@configdefault @ref IOT_LOG_LEVEL_GLOBAL; if that is undefined, then #IOT_LOG_NONE. + +@section AwsIotProvisioning_Assert +@brief Assertion function used when @ref AWS_IOT_PROVISIONING_ENABLE_ASSERTS is `1`. + +@configpossible Any function with the same signature as the standard library's [assert](http://pubs.opengroup.org/onlinepubs/9699919799/functions/assert.html) function.
+@configdefault @ref Iot_DefaultAssert if @ref AWS_IOT_PROVISIONING_ENABLE_ASSERTS is `1`; otherwise, nothing. If @ref Iot_DefaultAssert is not defined when asserts are enabled, the Provisioning library will fail to build. + +@section provisioning_config_memory Memory allocation +@brief The following functions may be re-implemented for the Provisioning library. +- #AwsIotProvisioning_MallocPayload
+ @copybrief AwsIotProvisioning_MallocPayload +- #AwsIotProvisioning_FreePayload
+ @copybrief AwsIotProvisioning_FreePayload +- #AwsIotProvisioning_MallocString
+ @copybrief AwsIotProvisioning_MallocString +- #AwsIotProvisioning_FreeString
+ @copybrief AwsIotProvisioning_FreeString +- #AwsIotProvisioning_MallocDeviceConfigurationList
+ @copybrief AwsIotProvisioning_MallocDeviceConfigurationList +- #AwsIotProvisioning_FreeDeviceConfigurationList
+ @copybrief AwsIotProvisioning_FreeDeviceConfigurationList + +If a custom implementation is not set for a Provisioning memory allocation function, @ref Iot_DefaultMalloc will be used. If @ref Iot_DefaultMalloc are not set, the Provisioning library will fail to build. +*/ diff --git a/doc/plantuml/images/provisioning_createkeysandcertificate_design.png b/doc/plantuml/images/provisioning_createkeysandcertificate_design.png new file mode 100644 index 0000000000000000000000000000000000000000..6babb72607bf6998162202566f159b9cdd98fc21 GIT binary patch literal 281485 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

J zY_+~-r>Q|-9#B6y)oa>St%K&7s*??#8#!rc=v762uA-LbIIkPo%95T^%D~*h!Udek z)Y)yg&-(RU1<~@3&Hb`xs7SQgv&{OH=i6!vtT8kWS`BilR6|PzR0!46`eQAr4gF|7 z`jBv9#8U2D3(uTo_T6uvTZL#!*AfVaMyu&Vk-&?UK1s)b^C7t*Jj3+BFZ1x4yh&>2 z)pYKO*>BHtWGAX%hiGuouxh6EXqf@Kc6_sUs!gNJIM*FsP8~Q#F@*B|Bg}B~Bk(+= znQJH7m6brmlHO_@l#f^Jt!wM*nquU;g%yL18d=QHdxbqB44g=5k(HuuoqU*5PcXh{dV#zgk zy0KoS?mEJc&RJXH2~B5Ed?|X%y|O$m�A%W;M|IJR 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 z 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 QOFtqfr6>u%srUGQ02+zTVgLXD literal 0 HcmV?d00001 diff --git a/doc/plantuml/images/provisioning_demo_with_keys_and_cert.png b/doc/plantuml/images/provisioning_demo_with_keys_and_cert.png new file mode 100644 index 0000000000000000000000000000000000000000..4f3ece452931ff903e13429dd1d99b8099307440 GIT binary patch literal 107538 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 literal 0 HcmV?d00001 diff --git a/doc/plantuml/images/provisioning_operation_detailed_design.png b/doc/plantuml/images/provisioning_operation_detailed_design.png new file mode 100644 index 0000000000000000000000000000000000000000..e1b97075fc881d695fb74e9574b03952615334f1 GIT binary patch literal 237239 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