summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorOscar Michael Abrina <abrinao@amazon.com>2020-10-30 15:20:46 -0700
committerGitHub <noreply@github.com>2020-10-30 15:20:46 -0700
commit58adeb2c0f5d029f75f232457b794254726fb3bf (patch)
treec7a1b80d6f0483b17ef51e5f54312c64a1fa0fec /tools
parent4124ac0c5737884c1d8c60ab6c4746891da84c1f (diff)
downloadfreertos-git-58adeb2c0f5d029f75f232457b794254726fb3bf.tar.gz
Tools for configuring AWS credentials in MQTT Mutual Auth Demo (#370)
This adds aws_config_offline, which allows the user to download demo_config.h for the MQTT Mutual Auth Demo using a webpage. This also adds aws_config_quick_start, which provides a means to generate demo_config.h for the Mutual Auth Demo with boto3.
Diffstat (limited to 'tools')
-rw-r--r--tools/aws_config_offline/CertificateConfigurator.html95
-rw-r--r--tools/aws_config_offline/js/aws_iot_demo_config_template.js260
-rw-r--r--tools/aws_config_offline/js/generator.js70
-rw-r--r--tools/aws_config_quick_start/.gitignore5
-rw-r--r--tools/aws_config_quick_start/README.md20
-rw-r--r--tools/aws_config_quick_start/SetupAWS.py235
-rw-r--r--tools/aws_config_quick_start/certs.py88
-rw-r--r--tools/aws_config_quick_start/configure.json4
-rw-r--r--tools/aws_config_quick_start/demo_config.templ258
-rw-r--r--tools/aws_config_quick_start/demo_config_empty.templ251
-rw-r--r--tools/aws_config_quick_start/misc.py99
-rw-r--r--tools/aws_config_quick_start/policy.py27
-rw-r--r--tools/aws_config_quick_start/policy_document.templ25
-rw-r--r--tools/aws_config_quick_start/thing.py44
14 files changed, 1481 insertions, 0 deletions
diff --git a/tools/aws_config_offline/CertificateConfigurator.html b/tools/aws_config_offline/CertificateConfigurator.html
new file mode 100644
index 000000000..25be752e9
--- /dev/null
+++ b/tools/aws_config_offline/CertificateConfigurator.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <title>FreeRTOS.org Developer Demos Configuration Tool</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+ <script src="js/aws_iot_demo_config_template.js"></script>
+ <script src="js/generator.js"></script>
+</head>
+
+<body>
+ <div class="row">
+ <div class="col-lg-2"></div>
+ <div class="col-lg-8">
+ <div class="panel panel-primary">
+ <div class="panel-heading">
+ <h2>AWS Profile Configuration Tool</h2>
+ <h4>FreeRTOS.org Developer Demos</h4>
+ </div>
+ <div class="panel-body">
+ <div class="container-fluid">
+ <div class="row">
+ <div class="col-md-12">
+ <p class="text-primary" style="font-size:18px">
+ Enter Thing name and endpoint. Provide client certificate and private key PEM files
+ downloaded from the AWS IoT Console.
+ </p>
+ <div class="panel panel-default">
+ <div class="panel-body" style="background: #F8F8F8;">
+ <div class="row">
+ <div class="col-md-12">
+ <div class="form-group">
+ <label for="thingName" style="font-size:16px">
+ Thing Name:
+ </label>
+ <input type="text" class="form-control" id="thingName"
+ placeholder="FreeRTOSThing" />
+ </div>
+ <div class="form-group">
+ <label for="AWSEndpoint" style="font-size:16px">
+ AWS IoT Thing Endpoint:
+ </label>
+ <input type="url" class="form-control" id="AWSEndpoint"
+ placeholder="abc123defghijk.iot.us-west-2.amazonaws.com" />
+ </div>
+ <div class="form-group">
+ <label for="pemInputFileCertificate" style="font-size:16px">
+ Certificate PEM file:
+ </label>
+ <input type="file" class="form-control-file"
+ id="pemInputFileCertificate" />
+ </div>
+ <br />
+ <div class="form-group">
+ <label for="pemInputFilePrivateKey" style="font-size:16px">
+ Private Key PEM file:
+ </label>
+ <input type="file" class="form-control-file"
+ id="pemInputFilePrivateKey" />
+ </div>
+ <br />
+ <button type="button" class="btn btn-primary" style="font-size:16px"
+ onclick='generateCertificateConfigurationHeader()'>
+ <span class="glyphicon glyphicon-download"></span>
+ Generate and save demo_config.h
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ <p class="text-primary" style="font-size:14px">
+ <span class="glyphicon glyphicon-warning-sign" style="font-size:16px"></span>
+ Save the generated header file to the
+ <i>FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Mutual_Auth</i> folder
+ of the
+ demo project.
+ </p>
+ </div>
+ </div>
+ </div>
+ <div class="text-center">
+ Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="col-lg-2"></div>
+ </div>
+</body>
+
+</html> \ No newline at end of file
diff --git a/tools/aws_config_offline/js/aws_iot_demo_config_template.js b/tools/aws_config_offline/js/aws_iot_demo_config_template.js
new file mode 100644
index 000000000..782d76e98
--- /dev/null
+++ b/tools/aws_config_offline/js/aws_iot_demo_config_template.js
@@ -0,0 +1,260 @@
+var awsIotProfileTemplate =
+ `/*
+ * FreeRTOS Kernel V10.3.0
+ * 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.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ */
+
+#ifndef DEMO_CONFIG_H
+#define DEMO_CONFIG_H
+
+/* FreeRTOS config include. */
+#include "FreeRTOSConfig.h"
+
+/**************************************************/
+/******* DO NOT CHANGE the following order ********/
+/**************************************************/
+
+/* Include logging header files and define logging macros in the following order:
+ * 1. Include the header file "logging_levels.h".
+ * 2. Define the LIBRARY_LOG_NAME and LIBRARY_LOG_LEVEL macros depending on
+ * the logging configuration for DEMO.
+ * 3. Include the header file "logging_stack.h", if logging is enabled for DEMO.
+ */
+
+#include "logging_levels.h"
+
+/* Logging configuration for the Demo. */
+#ifndef LIBRARY_LOG_NAME
+ #define LIBRARY_LOG_NAME "MQTTDemo"
+#endif
+
+#ifndef LIBRARY_LOG_LEVEL
+ #define LIBRARY_LOG_LEVEL LOG_INFO
+#endif
+#include "logging_stack.h"
+
+/************ End of logging configuration ****************/
+
+/**
+ * @brief The MQTT client identifier used in this example. Each client identifier
+ * must be unique; so edit as required to ensure that no two clients connecting to
+ * the same broker use the same client identifier.
+ *
+ * #define democonfigCLIENT_IDENTIFIER "insert here."
+ */
+#define democonfigCLIENT_IDENTIFIER <IOTThingName>
+
+/**
+ * @brief Endpoint of the MQTT broker to connect to.
+ *
+ * This demo application can be run with any MQTT broker, that supports mutual
+ * authentication.
+ *
+ * For AWS IoT MQTT broker, this is the Thing's REST API Endpoint.
+ *
+ * @note Your AWS IoT Core endpoint can be found in the AWS IoT console under
+ * Settings/Custom Endpoint, or using the describe-endpoint REST API (with
+ * AWS CLI command line tool).
+ *
+ * @note If you would like to setup an MQTT broker for running this demo,
+ * please see \`mqtt_broker_setup.txt\`.
+ *
+ * #define democonfigMQTT_BROKER_ENDPOINT "...insert here..."
+ */
+#define democonfigMQTT_BROKER_ENDPOINT <IOTEndpoint>
+
+/**
+ * @brief The port to use for the demo.
+ *
+ * In general, port 8883 is for secured MQTT connections.
+ *
+ * @note Port 443 requires use of the ALPN TLS extension with the ALPN protocol
+ * name. Using ALPN with this demo would require additional changes, including
+ * setting the \`pAlpnProtos\` member of the \`NetworkCredentials_t\` struct before
+ * forming the TLS connection. When using port 8883, ALPN is not required.
+ *
+ * #define democonfigMQTT_BROKER_PORT ( insert here. )
+ */
+#define democonfigMQTT_BROKER_PORT ( 8883 )
+
+/**
+ * @brief Server's root CA certificate.
+ *
+ * For AWS IoT MQTT broker, this certificate is used to identify the AWS IoT
+ * server and is publicly available. Refer to the AWS documentation available
+ * in the link below.
+ * https://docs.aws.amazon.com/iot/latest/developerguide/server-authentication.html#server-authentication-certs
+ *
+ * @note This certificate should be PEM-encoded.
+ *
+ * Must include the PEM header and footer:
+ * "-----BEGIN CERTIFICATE-----\n"\
+ * "...base64 data...\n"\
+ * "-----END CERTIFICATE-----\n"
+ *
+ * #define democonfigROOT_CA_PEM "...insert here..."
+ */
+#define democonfigROOT_CA_PEM \\
+ "-----BEGIN CERTIFICATE-----\\n" \\
+ "MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\\n" \\
+ "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\\n" \\
+ "b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\\n" \\
+ "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\\n" \\
+ "b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\\n" \\
+ "ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\\n" \\
+ "9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\\n" \\
+ "IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\\n" \\
+ "VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\\n" \\
+ "93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\\n" \\
+ "jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\\n" \\
+ "AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\\n" \\
+ "A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\\n" \\
+ "U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\\n" \\
+ "N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\\n" \\
+ "o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\\n" \\
+ "5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\\n" \\
+ "rqXRfboQnoZsG4q5WTP468SQvvG5\\n" \\
+ "-----END CERTIFICATE-----\\n"
+
+/**
+ * @brief Client certificate.
+ *
+ * For AWS IoT MQTT broker, refer to the AWS documentation below for details
+ * regarding client authentication.
+ * https://docs.aws.amazon.com/iot/latest/developerguide/client-authentication.html
+ *
+ * @note This certificate should be PEM-encoded.
+ *
+ * Must include the PEM header and footer:
+ * "-----BEGIN CERTIFICATE-----\n"\
+ * "...base64 data...\n"\
+ * "-----END CERTIFICATE-----\n"
+ *
+ * #define democonfigCLIENT_CERTIFICATE_PEM "...insert here..."
+ */
+#define democonfigCLIENT_CERTIFICATE_PEM \\
+<ClientCertificatePEM>
+
+/**
+ * @brief PEM-encoded client private key.
+ *
+ * Must include the PEM header and footer:
+ * "-----BEGIN RSA PRIVATE KEY-----\\n"\\
+ * "...base64 data...\\n"\\
+ * "-----END RSA PRIVATE KEY-----\\n"
+ *
+ * #define democonfigCLIENT_PRIVATE_KEY_PEM "...insert here..."
+ */
+#define democonfigCLIENT_PRIVATE_KEY_PEM \\
+<ClientPrivateKeyPEM>
+
+/**
+ * @brief An option to disable Server Name Indication.
+ *
+ * @note When using a local Mosquitto server setup, SNI needs to be disabled
+ * for an MQTT broker that only has an IP address but no hostname. However,
+ * SNI should be enabled whenever possible.
+ */
+#define democonfigDISABLE_SNI ( pdFALSE )
+
+/**
+ * @brief Configuration that indicates if the demo connection is made to the AWS IoT Core MQTT broker.
+ *
+ * If username/password based authentication is used, the demo will use appropriate TLS ALPN and
+ * SNI configurations as required for the Custom Authentication feature of AWS IoT.
+ * For more information, refer to the following documentation:
+ * https://docs.aws.amazon.com/iot/latest/developerguide/custom-auth.html#custom-auth-mqtt
+ *
+ * #define democonfigUSE_AWS_IOT_CORE_BROKER ( 1 )
+ */
+#define democonfigUSE_AWS_IOT_CORE_BROKER ( 1 )
+
+/**
+ * @brief The username value for authenticating client to the MQTT broker when
+ * username/password based client authentication is used.
+ *
+ * For AWS IoT MQTT broker, refer to the AWS IoT documentation below for
+ * details regarding client authentication with a username and password.
+ * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html
+ * An authorizer setup needs to be done, as mentioned in the above link, to use
+ * username/password based client authentication.
+ *
+ * #define democonfigCLIENT_USERNAME "...insert here..."
+ */
+
+/**
+ * @brief The password value for authenticating client to the MQTT broker when
+ * username/password based client authentication is used.
+ *
+ * For AWS IoT MQTT broker, refer to the AWS IoT documentation below for
+ * details regarding client authentication with a username and password.
+ * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html
+ * An authorizer setup needs to be done, as mentioned in the above link, to use
+ * username/password based client authentication.
+ *
+ * #define democonfigCLIENT_PASSWORD "...insert here..."
+ */
+
+/**
+ * @brief The name of the operating system that the application is running on.
+ * The current value is given as an example. Please update for your specific
+ * operating system.
+ */
+#define democonfigOS_NAME "FreeRTOS"
+
+/**
+ * @brief The version of the operating system that the application is running
+ * on. The current value is given as an example. Please update for your specific
+ * operating system version.
+ */
+#define democonfigOS_VERSION tskKERNEL_VERSION_NUMBER
+
+/**
+ * @brief The name of the hardware platform the application is running on. The
+ * current value is given as an example. Please update for your specific
+ * hardware platform.
+ */
+#define democonfigHARDWARE_PLATFORM_NAME "WinSim"
+
+/**
+ * @brief The name of the MQTT library used and its version, following an "@"
+ * symbol.
+ */
+#define democonfigMQTT_LIB "core-mqtt@1.0.0"
+
+/**
+ * @brief Set the stack size of the main demo task.
+ *
+ * In the Windows port, this stack only holds a structure. The actual
+ * stack is created by an operating system thread.
+ */
+#define democonfigDEMO_STACKSIZE configMINIMAL_STACK_SIZE
+
+/**
+ * @brief Size of the network buffer for MQTT packets.
+ */
+#define democonfigNETWORK_BUFFER_SIZE ( 1024U )
+
+#endif /* DEMO_CONFIG_H */
+`; \ No newline at end of file
diff --git a/tools/aws_config_offline/js/generator.js b/tools/aws_config_offline/js/generator.js
new file mode 100644
index 000000000..157a0f7a1
--- /dev/null
+++ b/tools/aws_config_offline/js/generator.js
@@ -0,0 +1,70 @@
+
+// Check for the various File API support.
+if (window.File && window.FileReader && window.FileList && window.Blob) {
+ // Success! All the File APIs are supported.
+} else {
+ alert('Please use a web browser that supports HTML5 file APIs.')
+}
+
+function formatCredentialTextForHeader(credentialText) {
+ // Replace any CR/LF pairs with a newline character.
+ credentialText = credentialText.replace(/\r\n/g, '\n')
+
+ // Add line endings for C-language variable declaration.
+ credentialText = credentialText.replace(/\n/g, '\\n" \\\n "')
+
+ // Remove '\n"' from the last line of the declaration and add a semicolon.
+ credentialText = credentialText.slice(0, -9) + '"\n'
+ return credentialText
+}
+
+function generateCertificateConfigurationHeader() {
+ var pemCertificateText = ''
+ var pemPrivateKeyText = ''
+ var filename = 'demo_config.h'
+ var outputText = ''
+
+ var readerCertificate = new FileReader()
+ var readerPrivateKey = new FileReader()
+
+ // Start certificate read
+ readerCertificate.readAsText(pemInputFileCertificate.files[0])
+
+ // Define a handler to create appropriate client certificate file text.
+ readerCertificate.onload = function (e) {
+ pemCertificateText = e.target.result
+
+ // Add C-language variable declaration plus EOL formatting.
+ pemCertificateText = ' "' + formatCredentialTextForHeader(pemCertificateText)
+
+ // Because this is async, read next file inline.
+ readerPrivateKey.readAsText(pemInputFilePrivateKey.files[0])
+ }
+
+ // Define a handler to create appropriate private key file text.
+ readerPrivateKey.onload = function (e) {
+ pemPrivateKeyText = e.target.result
+
+ // Add C-language variable declaration plus EOL formatting.
+ pemPrivateKeyText = ' "' + formatCredentialTextForHeader(pemPrivateKeyText)
+
+ outputText = awsIotProfileTemplate
+ outputText = outputText.replace('<IOTEndpoint>', '"' + document.getElementById('AWSEndpoint').value + '"')
+ outputText = outputText.replace('<IOTThingName>', '"' + document.getElementById('thingName').value + '"')
+ outputText = outputText.replace('<ClientCertificatePEM>', pemCertificateText)
+ outputText = outputText.replace('<ClientPrivateKeyPEM>', pemPrivateKeyText)
+
+ // Because this is async, handle download generation inline.
+ var downloadBlob = new Blob([outputText], { type: 'text/plain' })
+ if (window.navigator.msSaveOrOpenBlob) {
+ window.navigator.msSaveBlob(downloadBlob, filename)
+ } else {
+ var downloadLink = document.createElement('a')
+ downloadLink.href = window.URL.createObjectURL(downloadBlob)
+ downloadLink.download = filename
+ document.body.appendChild(downloadLink)
+ downloadLink.click()
+ document.body.removeChild(downloadLink)
+ }
+ }
+}
diff --git a/tools/aws_config_quick_start/.gitignore b/tools/aws_config_quick_start/.gitignore
new file mode 100644
index 000000000..08a6cdf73
--- /dev/null
+++ b/tools/aws_config_quick_start/.gitignore
@@ -0,0 +1,5 @@
+__pycache__
+test*
+*_id_file
+*_pem_file
+*.pyc
diff --git a/tools/aws_config_quick_start/README.md b/tools/aws_config_quick_start/README.md
new file mode 100644
index 000000000..2ec371da1
--- /dev/null
+++ b/tools/aws_config_quick_start/README.md
@@ -0,0 +1,20 @@
+## Script to setup the AWS resources through command line
+
+This script automates the process of [Prerequisites](https://docs.aws.amazon.com/freertos/latest/userguide/freertos-prereqs.html) and the configuring the files `demo_config.h` to connect to AWS IoT.
+
+Make sure you have `aws cli` configured on your machine with access_key, secret_key and region.
+
+Open the file `configure.json` and fill in the following details:
+* FreeRTOS_source_dir : The path of the FreeRTOS directory. By default, this is set to the top level of this repo (../..).
+* thing_name : Name of the thing you want to create
+
+**Options to use with the script**
+1. To setup your Thing, and update credentials file, type the command: `python SetupAWS.py setup`
+2. To cleanup the Thing you created with the script, and revert changes in credentials file, type the command: `python SetupAWS.py cleanup`
+3. To only create thing, certificate and policy, type the command: `python SetupAWS.py prereq`
+4. To update the files `demo_config.h` with thing name and the certificate keys, type the command `python SetupAWS.py update_creds`
+5. To delete the thing, certificate and policy created by the script, type the command: `python SetupAWS.py delete_prereq`
+6. To revert the changes in the file `demo_config.h`, type the command: `python SetupAWS.py cleanup_creds`
+7. To list your certificates, type the command: `python SetupAWS.py list_certificates`
+8. To list your policies, type the command: `python SetupAWS.py list_policies`
+9. To list your things, type the command: `python SetupAWS.py list_things`
diff --git a/tools/aws_config_quick_start/SetupAWS.py b/tools/aws_config_quick_start/SetupAWS.py
new file mode 100644
index 000000000..cf6fff548
--- /dev/null
+++ b/tools/aws_config_quick_start/SetupAWS.py
@@ -0,0 +1,235 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import json
+import pprint
+import argparse
+import boto3
+import misc
+import certs
+import thing
+import policy
+
+pp = pprint.PrettyPrinter(indent=4)
+
+
+def check_aws_configuration():
+ mysession = boto3.session.Session()
+ if not mysession._session._config['profiles']:
+ print("AWS not configured. Please run `aws configure`.")
+ sys.exit(1)
+
+
+def prereq():
+ with open('configure.json') as configure_file:
+ json_text = json.load(configure_file)
+
+ # Create a Thing
+ thing_name = json_text['thing_name']
+ thing_obj = thing.Thing(thing_name)
+ if not thing_obj.create():
+
+ # Create a Certificate
+ cert_obj = certs.Certificate()
+ result = cert_obj.create()
+
+ # Store certId
+ cert_id = result['certificateId']
+ cert_id_filename = thing_name + '_cert_id_file.txt'
+ cert_id_file = open(cert_id_filename, 'w')
+ cert_id_file.write(cert_id)
+ cert_id_file_path = os.path.abspath(cert_id_filename)
+ os.chmod(cert_id_file_path, 0o444)
+ cert_id_file.close()
+
+ # Store cert_pem as file
+ cert_pem = result['certificatePem']
+ cert_pem_filename = thing_name + '_cert_pem_file.pem'
+ cert_pem_file = open(cert_pem_filename, 'w')
+ cert_pem_file.write(cert_pem)
+ cert_pem_file_path = os.path.abspath(cert_pem_filename)
+ os.chmod(cert_pem_file_path, 0o444)
+ cert_pem_file.close()
+
+ # Store private key PEM as file
+ private_key_pem = result['keyPair']['PrivateKey']
+ private_key_pem_filename = thing_name + '_private_key_pem_file.pem'
+ private_key_pem_file = open(private_key_pem_filename, 'w')
+ private_key_pem_file.write(private_key_pem)
+ private_key_pem_file_path = os.path.abspath(private_key_pem_filename)
+ os.chmod(private_key_pem_file_path, 0o444)
+ private_key_pem_file.close()
+
+ # Create a Policy
+ policy_document = misc.create_policy_document()
+ policy_name = thing_name + '_amazon_freertos_policy'
+ policy_obj = policy.Policy(policy_name, policy_document)
+ policy_obj.create()
+
+ # Attach certificate to Thing
+ cert_obj.attach_thing(thing_name)
+
+ # Attach policy to certificate
+ cert_obj.attach_policy(policy_name)
+
+
+def update_credential_file():
+ with open('configure.json') as configure_file:
+ json_text = json.load(configure_file)
+
+ source_dir = os.path.expanduser(json_text['FreeRTOS_source_dir'])
+ thing_name = json_text['thing_name']
+
+ # Read cert_pem from file
+ cert_pem_filename = thing_name + '_cert_pem_file.pem'
+ try:
+ cert_pem_file = open(cert_pem_filename, 'r')
+ except IOError:
+ print("{} file not found. Run prerequisite step"
+ .format(cert_pem_filename))
+ sys.exit(1)
+ else:
+ cert_pem = cert_pem_file.read()
+
+ # Read private_key_pem from file
+ private_key_pem_filename = thing_name + '_private_key_pem_file.pem'
+ try:
+ private_key_pem_file = open(private_key_pem_filename, 'r')
+ except IOError:
+ print("{} file not found. Run prerequisite step"
+ .format(private_key_pem_filename))
+ sys.exit(1)
+ else:
+ private_key_pem = private_key_pem_file.read()
+
+ # Modify 'demo_config.h' file
+ misc.write_client_credentials(
+ source_dir,
+ thing_name=thing_name,
+ client_certificate_pem=cert_pem,
+ client_private_key_pem=private_key_pem,
+ cleanup=False)
+
+
+def delete_prereq():
+ with open('configure.json') as configure_file:
+ json_text = json.load(configure_file)
+
+ # Delete Thing
+ thing_name = json_text['thing_name']
+ thing_obj = thing.Thing(thing_name)
+ if thing_obj.exists():
+ thing_obj.delete()
+
+ # Delete certificate
+ cert_id_filename = thing_name + '_cert_id_file.txt'
+ if os.path.exists(cert_id_filename):
+ cert_id_file = open(cert_id_filename, 'r')
+ cert_id = cert_id_file.read()
+ cert_obj = certs.Certificate(cert_id)
+ cert_obj.delete()
+ cert_id_file.close()
+ cert_id_file_path = os.path.abspath(cert_id_filename)
+ os.chmod(cert_id_file_path, 0o666)
+ os.remove(cert_id_filename)
+
+ # Delete cert_pem file and private_key_pem file
+ cert_pem_filename = thing_name + '_cert_pem_file.pem'
+ if os.path.exists(cert_pem_filename):
+ cert_pem_file_path = os.path.abspath(cert_pem_filename)
+ os.chmod(cert_pem_file_path, 0o666)
+ os.remove(cert_pem_filename)
+
+ private_key_pem_filename = thing_name + '_private_key_pem_file.pem'
+ if os.path.exists(private_key_pem_filename):
+ private_key_pem_file_path = os.path.abspath(private_key_pem_filename)
+ os.chmod(private_key_pem_file_path, 0o666)
+ os.remove(private_key_pem_filename)
+
+ # Delete policy
+ policy_name = thing_name + '_amazon_freertos_policy'
+ policy_obj = policy.Policy(policy_name)
+ if policy_obj.exists():
+ policy_obj.delete()
+
+
+def cleanup_creds():
+ with open('configure.json') as file:
+ json_text = json.load(file)
+
+ source_dir = os.path.expanduser(json_text['FreeRTOS_source_dir'])
+
+ # Cleanup 'demo_config.h' file
+ misc.write_client_credentials(source_dir, cleanup=True)
+
+
+def setup():
+ prereq()
+ update_credential_file()
+ print("Setup Completed")
+
+
+def cleanup():
+ delete_prereq()
+ cleanup_creds()
+ print("Cleanup Completed")
+
+
+def list_certificates():
+ client = boto3.client('iot')
+ certs = client.list_certificates()['certificates']
+ pp.pprint(certs)
+
+
+def list_things():
+ client = boto3.client('iot')
+ things = client.list_things()['things']
+ pp.pprint(things)
+
+
+def list_policies():
+ client = boto3.client('iot')
+ policies = client.list_policies()['policies']
+ pp.pprint(policies)
+
+
+if __name__ == "__main__":
+
+ arg_parser = argparse.ArgumentParser()
+ subparsers = arg_parser.add_subparsers(help='Available commands',
+ dest='command')
+ subparsers.add_parser('setup', help='Setup AWS IoT')
+ subparsers.add_parser('cleanup', help='Cleanup AWS IoT')
+ subparsers.add_parser('list_certificates', help='List certificates')
+ subparsers.add_parser('list_things', help='List things')
+ subparsers.add_parser('list_policies', help='List policies')
+ subparsers.add_parser('prereq', help='Setup prerequisites for AWS IoT')
+ subparsers.add_parser('update_creds', help='Update credential files')
+ subparsers.add_parser('delete_prereq', help='Delete prerequisites created')
+ subparsers.add_parser('cleanup_creds', help='Cleanup credential files')
+ args = arg_parser.parse_args()
+ check_aws_configuration()
+
+ if args.command == 'setup':
+ setup()
+ elif args.command == 'cleanup':
+ cleanup()
+ elif args.command == 'list_certificates':
+ list_certificates()
+ elif args.command == 'list_things':
+ list_things()
+ elif args.command == 'list_policies':
+ list_policies()
+ elif args.command == 'prereq':
+ prereq()
+ elif args.command == 'update_creds':
+ update_credential_file()
+ elif args.command == 'delete_prereq':
+ delete_prereq()
+ elif args.command == 'cleanup_creds':
+ cleanup_creds()
+ else:
+ print("Command does not exist")
+
+ sys.exit(0)
diff --git a/tools/aws_config_quick_start/certs.py b/tools/aws_config_quick_start/certs.py
new file mode 100644
index 000000000..1e29f4d93
--- /dev/null
+++ b/tools/aws_config_quick_start/certs.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+
+import boto3
+import json
+
+
+class Certificate():
+
+ def __init__(self, certId=''):
+ self.id = certId
+ self.arn = ''
+ self.client = boto3.client('iot')
+ if (self.id != ''):
+ result = self.client.describe_certificate(certificateId=self.id)
+ self.arn = result['certificateDescription']['certificateArn']
+
+ def create(self):
+ assert not self.exists(), "Cert already exists"
+ cert = self.create_keys_and_certificate()
+ self.id = cert["certificateId"]
+ self.arn = cert["certificateArn"]
+ return cert
+
+ def create_keys_and_certificate(self):
+ result = self.client.create_keys_and_certificate(setAsActive=True)
+ return result
+
+ def delete(self):
+ cert_not_found = True
+ # Detach Policies attached to the cert
+ policies_attached = self.list_policies()
+ for policy in policies_attached:
+ self.detach_policy(policy['policyName'])
+
+ # Detach Things attached to the cert
+ things_attached = self.list_things()
+ for thing in things_attached:
+ self.detach_thing(thing)
+
+ # Update the status of the certificate to INACTIVE
+ try:
+ self.client.update_certificate(certificateId=self.id,
+ newStatus='INACTIVE')
+ cert_not_found = False
+ except self.client.exceptions.ResourceNotFoundException:
+ cert_not_found = True
+ return cert_not_found
+
+ # Delete the certificate
+ try:
+ self.client.delete_certificate(certificateId=self.id)
+ cert_not_found = False
+ except self.client.exceptions.ResourceNotFoundException:
+ cert_not_found = True
+ return cert_not_found
+
+ def exists(self):
+ if self.id == '':
+ return False
+ else:
+ return True
+
+ def get_arn(self):
+ return self.arn
+
+ def list_policies(self):
+ policies = self.client.list_principal_policies(principal=self.arn)
+ policies = policies['policies']
+ return policies
+
+ def attach_policy(self, policy_name):
+ self.client.attach_policy(policyName=policy_name, target=self.arn)
+
+ def detach_policy(self, policy_name):
+ self.client.detach_policy(policyName=policy_name, target=self.arn)
+
+ def list_things(self):
+ things = self.client.list_principal_things(principal=self.arn)
+ things = things['things']
+ return things
+
+ def attach_thing(self, thing_name):
+ self.client.attach_thing_principal(thingName=thing_name,
+ principal=self.arn)
+
+ def detach_thing(self, thing_name):
+ self.client.detach_thing_principal(thingName=thing_name,
+ principal=self.arn)
diff --git a/tools/aws_config_quick_start/configure.json b/tools/aws_config_quick_start/configure.json
new file mode 100644
index 000000000..9db4e7df2
--- /dev/null
+++ b/tools/aws_config_quick_start/configure.json
@@ -0,0 +1,4 @@
+{
+ "FreeRTOS_source_dir": "../..",
+ "thing_name": "$thing_name"
+} \ No newline at end of file
diff --git a/tools/aws_config_quick_start/demo_config.templ b/tools/aws_config_quick_start/demo_config.templ
new file mode 100644
index 000000000..4053a8e98
--- /dev/null
+++ b/tools/aws_config_quick_start/demo_config.templ
@@ -0,0 +1,258 @@
+/*
+ * FreeRTOS Kernel V10.3.0
+ * 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.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ */
+
+#ifndef DEMO_CONFIG_H
+#define DEMO_CONFIG_H
+
+/* FreeRTOS config include. */
+#include "FreeRTOSConfig.h"
+
+/**************************************************/
+/******* DO NOT CHANGE the following order ********/
+/**************************************************/
+
+/* Include logging header files and define logging macros in the following order:
+ * 1. Include the header file "logging_levels.h".
+ * 2. Define the LIBRARY_LOG_NAME and LIBRARY_LOG_LEVEL macros depending on
+ * the logging configuration for DEMO.
+ * 3. Include the header file "logging_stack.h", if logging is enabled for DEMO.
+ */
+
+#include "logging_levels.h"
+
+/* Logging configuration for the Demo. */
+#ifndef LIBRARY_LOG_NAME
+ #define LIBRARY_LOG_NAME "MQTTDemo"
+#endif
+
+#ifndef LIBRARY_LOG_LEVEL
+ #define LIBRARY_LOG_LEVEL LOG_INFO
+#endif
+#include "logging_stack.h"
+
+/************ End of logging configuration ****************/
+
+/**
+ * @brief The MQTT client identifier used in this example. Each client identifier
+ * must be unique; so edit as required to ensure that no two clients connecting to
+ * the same broker use the same client identifier.
+ *
+ * #define democonfigCLIENT_IDENTIFIER "insert here."
+ */
+#define democonfigCLIENT_IDENTIFIER <IOTThingName>
+
+/**
+ * @brief Endpoint of the MQTT broker to connect to.
+ *
+ * This demo application can be run with any MQTT broker, that supports mutual
+ * authentication.
+ *
+ * For AWS IoT MQTT broker, this is the Thing's REST API Endpoint.
+ *
+ * @note Your AWS IoT Core endpoint can be found in the AWS IoT console under
+ * Settings/Custom Endpoint, or using the describe-endpoint REST API (with
+ * AWS CLI command line tool).
+ *
+ * @note If you would like to setup an MQTT broker for running this demo,
+ * please see \`mqtt_broker_setup.txt\`.
+ *
+ * #define democonfigMQTT_BROKER_ENDPOINT "...insert here..."
+ */
+#define democonfigMQTT_BROKER_ENDPOINT <IOTEndpoint>
+
+/**
+ * @brief The port to use for the demo.
+ *
+ * In general, port 8883 is for secured MQTT connections.
+ *
+ * @note Port 443 requires use of the ALPN TLS extension with the ALPN protocol
+ * name. Using ALPN with this demo would require additional changes, including
+ * setting the \`pAlpnProtos\` member of the \`NetworkCredentials_t\` struct before
+ * forming the TLS connection. When using port 8883, ALPN is not required.
+ *
+ * #define democonfigMQTT_BROKER_PORT ( insert here. )
+ */
+#define democonfigMQTT_BROKER_PORT ( 8883 )
+
+/**
+ * @brief Server's root CA certificate.
+ *
+ * For AWS IoT MQTT broker, this certificate is used to identify the AWS IoT
+ * server and is publicly available. Refer to the AWS documentation available
+ * in the link below.
+ * https://docs.aws.amazon.com/iot/latest/developerguide/server-authentication.html#server-authentication-certs
+ *
+ * @note This certificate should be PEM-encoded.
+ *
+ * Must include the PEM header and footer:
+ * "-----BEGIN CERTIFICATE-----\n"\
+ * "...base64 data...\n"\
+ * "-----END CERTIFICATE-----\n"
+ *
+ * #define democonfigROOT_CA_PEM "...insert here..."
+ */
+#define democonfigROOT_CA_PEM \
+ "-----BEGIN CERTIFICATE-----\n" \
+ "MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\n" \
+ "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" \
+ "b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\n" \
+ "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\n" \
+ "b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\n" \
+ "ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\n" \
+ "9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\n" \
+ "IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\n" \
+ "VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\n" \
+ "93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\n" \
+ "jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n" \
+ "AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\n" \
+ "A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\n" \
+ "U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\n" \
+ "N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\n" \
+ "o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\n" \
+ "5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\n" \
+ "rqXRfboQnoZsG4q5WTP468SQvvG5\n" \
+ "-----END CERTIFICATE-----\n"
+
+/**
+ * @brief Client certificate.
+ *
+ * For AWS IoT MQTT broker, refer to the AWS documentation below for details
+ * regarding client authentication.
+ * https://docs.aws.amazon.com/iot/latest/developerguide/client-authentication.html
+ *
+ * @note This certificate should be PEM-encoded.
+ *
+ * Must include the PEM header and footer:
+ * "-----BEGIN CERTIFICATE-----\n"\
+ * "...base64 data...\n"\
+ * "-----END CERTIFICATE-----\n"
+ *
+ * #define democonfigCLIENT_CERTIFICATE_PEM "...insert here..."
+ */
+#define democonfigCLIENT_CERTIFICATE_PEM \
+<ClientCertificatePEM>
+
+/**
+ * @brief PEM-encoded client private key.
+ *
+ * Must include the PEM header and footer:
+ * "-----BEGIN RSA PRIVATE KEY-----\n"\
+ * "...base64 data...\n"\
+ * "-----END RSA PRIVATE KEY-----\n"
+ *
+ * #define democonfigCLIENT_PRIVATE_KEY_PEM "...insert here..."
+ */
+#define democonfigCLIENT_PRIVATE_KEY_PEM \
+<ClientPrivateKeyPEM>
+
+/**
+ * @brief An option to disable Server Name Indication.
+ *
+ * @note When using a local Mosquitto server setup, SNI needs to be disabled
+ * for an MQTT broker that only has an IP address but no hostname. However,
+ * SNI should be enabled whenever possible.
+ */
+#define democonfigDISABLE_SNI ( pdFALSE )
+
+/**
+ * @brief Configuration that indicates if the demo connection is made to the AWS IoT Core MQTT broker.
+ *
+ * If username/password based authentication is used, the demo will use appropriate TLS ALPN and
+ * SNI configurations as required for the Custom Authentication feature of AWS IoT.
+ * For more information, refer to the following documentation:
+ * https://docs.aws.amazon.com/iot/latest/developerguide/custom-auth.html#custom-auth-mqtt
+ *
+ * #define democonfigUSE_AWS_IOT_CORE_BROKER ( 1 )
+ */
+#define democonfigUSE_AWS_IOT_CORE_BROKER ( 1 )
+
+/**
+ * @brief The username value for authenticating client to the MQTT broker when
+ * username/password based client authentication is used.
+ *
+ * For AWS IoT MQTT broker, refer to the AWS IoT documentation below for
+ * details regarding client authentication with a username and password.
+ * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html
+ * An authorizer setup needs to be done, as mentioned in the above link, to use
+ * username/password based client authentication.
+ *
+ * #define democonfigCLIENT_USERNAME "...insert here..."
+ */
+
+/**
+ * @brief The password value for authenticating client to the MQTT broker when
+ * username/password based client authentication is used.
+ *
+ * For AWS IoT MQTT broker, refer to the AWS IoT documentation below for
+ * details regarding client authentication with a username and password.
+ * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html
+ * An authorizer setup needs to be done, as mentioned in the above link, to use
+ * username/password based client authentication.
+ *
+ * #define democonfigCLIENT_PASSWORD "...insert here..."
+ */
+
+/**
+ * @brief The name of the operating system that the application is running on.
+ * The current value is given as an example. Please update for your specific
+ * operating system.
+ */
+#define democonfigOS_NAME "FreeRTOS"
+
+/**
+ * @brief The version of the operating system that the application is running
+ * on. The current value is given as an example. Please update for your specific
+ * operating system version.
+ */
+#define democonfigOS_VERSION tskKERNEL_VERSION_NUMBER
+
+/**
+ * @brief The name of the hardware platform the application is running on. The
+ * current value is given as an example. Please update for your specific
+ * hardware platform.
+ */
+#define democonfigHARDWARE_PLATFORM_NAME "WinSim"
+
+/**
+ * @brief The name of the MQTT library used and its version, following an "@"
+ * symbol.
+ */
+#define democonfigMQTT_LIB "core-mqtt@1.0.0"
+
+/**
+ * @brief Set the stack size of the main demo task.
+ *
+ * In the Windows port, this stack only holds a structure. The actual
+ * stack is created by an operating system thread.
+ */
+#define democonfigDEMO_STACKSIZE configMINIMAL_STACK_SIZE
+
+/**
+ * @brief Size of the network buffer for MQTT packets.
+ */
+#define democonfigNETWORK_BUFFER_SIZE ( 1024U )
+
+#endif /* DEMO_CONFIG_H */ \ No newline at end of file
diff --git a/tools/aws_config_quick_start/demo_config_empty.templ b/tools/aws_config_quick_start/demo_config_empty.templ
new file mode 100644
index 000000000..94fae967e
--- /dev/null
+++ b/tools/aws_config_quick_start/demo_config_empty.templ
@@ -0,0 +1,251 @@
+/*
+ * FreeRTOS Kernel V10.3.0
+ * 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.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ */
+
+#ifndef DEMO_CONFIG_H
+#define DEMO_CONFIG_H
+
+/* FreeRTOS config include. */
+#include "FreeRTOSConfig.h"
+
+/**************************************************/
+/******* DO NOT CHANGE the following order ********/
+/**************************************************/
+
+/* Include logging header files and define logging macros in the following order:
+ * 1. Include the header file "logging_levels.h".
+ * 2. Define the LIBRARY_LOG_NAME and LIBRARY_LOG_LEVEL macros depending on
+ * the logging configuration for DEMO.
+ * 3. Include the header file "logging_stack.h", if logging is enabled for DEMO.
+ */
+
+#include "logging_levels.h"
+
+/* Logging configuration for the Demo. */
+#ifndef LIBRARY_LOG_NAME
+ #define LIBRARY_LOG_NAME "MQTTDemo"
+#endif
+
+#ifndef LIBRARY_LOG_LEVEL
+ #define LIBRARY_LOG_LEVEL LOG_INFO
+#endif
+#include "logging_stack.h"
+
+/************ End of logging configuration ****************/
+
+/**
+ * @brief The MQTT client identifier used in this example. Each client identifier
+ * must be unique; so edit as required to ensure that no two clients connecting to
+ * the same broker use the same client identifier.
+ *
+ * #define democonfigCLIENT_IDENTIFIER "insert here."
+ */
+
+/**
+ * @brief Endpoint of the MQTT broker to connect to.
+ *
+ * This demo application can be run with any MQTT broker, that supports mutual
+ * authentication.
+ *
+ * For AWS IoT MQTT broker, this is the Thing's REST API Endpoint.
+ *
+ * @note Your AWS IoT Core endpoint can be found in the AWS IoT console under
+ * Settings/Custom Endpoint, or using the describe-endpoint REST API (with
+ * AWS CLI command line tool).
+ *
+ * @note If you would like to setup an MQTT broker for running this demo,
+ * please see \`mqtt_broker_setup.txt\`.
+ *
+ * #define democonfigMQTT_BROKER_ENDPOINT "...insert here..."
+ */
+
+/**
+ * @brief The port to use for the demo.
+ *
+ * In general, port 8883 is for secured MQTT connections.
+ *
+ * @note Port 443 requires use of the ALPN TLS extension with the ALPN protocol
+ * name. Using ALPN with this demo would require additional changes, including
+ * setting the \`pAlpnProtos\` member of the \`NetworkCredentials_t\` struct before
+ * forming the TLS connection. When using port 8883, ALPN is not required.
+ *
+ * #define democonfigMQTT_BROKER_PORT ( insert here. )
+ */
+#define democonfigMQTT_BROKER_PORT ( 8883 )
+
+/**
+ * @brief Server's root CA certificate.
+ *
+ * For AWS IoT MQTT broker, this certificate is used to identify the AWS IoT
+ * server and is publicly available. Refer to the AWS documentation available
+ * in the link below.
+ * https://docs.aws.amazon.com/iot/latest/developerguide/server-authentication.html#server-authentication-certs
+ *
+ * @note This certificate should be PEM-encoded.
+ *
+ * Must include the PEM header and footer:
+ * "-----BEGIN CERTIFICATE-----\n"\
+ * "...base64 data...\n"\
+ * "-----END CERTIFICATE-----\n"
+ *
+ * #define democonfigROOT_CA_PEM "...insert here..."
+ */
+#define democonfigROOT_CA_PEM \
+ "-----BEGIN CERTIFICATE-----\\n" \\
+ "MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\\n" \\
+ "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\\n" \\
+ "b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\\n" \\
+ "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\\n" \\
+ "b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\\n" \\
+ "ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\\n" \\
+ "9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\\n" \\
+ "IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\\n" \\
+ "VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\\n" \\
+ "93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\\n" \\
+ "jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\\n" \\
+ "AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\\n" \\
+ "A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\\n" \\
+ "U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\\n" \\
+ "N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\\n" \\
+ "o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\\n" \\
+ "5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\\n" \\
+ "rqXRfboQnoZsG4q5WTP468SQvvG5\\n" \\
+ "-----END CERTIFICATE-----\\n"
+
+/**
+ * @brief Client certificate.
+ *
+ * For AWS IoT MQTT broker, refer to the AWS documentation below for details
+ * regarding client authentication.
+ * https://docs.aws.amazon.com/iot/latest/developerguide/client-authentication.html
+ *
+ * @note This certificate should be PEM-encoded.
+ *
+ * Must include the PEM header and footer:
+ * "-----BEGIN CERTIFICATE-----\n"\
+ * "...base64 data...\n"\
+ * "-----END CERTIFICATE-----\n"
+ *
+ * #define democonfigCLIENT_CERTIFICATE_PEM "...insert here..."
+ */
+
+/**
+ * @brief PEM-encoded client private key.
+ *
+ * Must include the PEM header and footer:
+ * "-----BEGIN RSA PRIVATE KEY-----\\n"\\
+ * "...base64 data...\\n"\\
+ * "-----END RSA PRIVATE KEY-----\\n"
+ *
+ * #define democonfigCLIENT_PRIVATE_KEY_PEM "...insert here..."
+ */
+
+/**
+ * @brief An option to disable Server Name Indication.
+ *
+ * @note When using a local Mosquitto server setup, SNI needs to be disabled
+ * for an MQTT broker that only has an IP address but no hostname. However,
+ * SNI should be enabled whenever possible.
+ */
+#define democonfigDISABLE_SNI ( pdFALSE )
+
+/**
+ * @brief Configuration that indicates if the demo connection is made to the AWS IoT Core MQTT broker.
+ *
+ * If username/password based authentication is used, the demo will use appropriate TLS ALPN and
+ * SNI configurations as required for the Custom Authentication feature of AWS IoT.
+ * For more information, refer to the following documentation:
+ * https://docs.aws.amazon.com/iot/latest/developerguide/custom-auth.html#custom-auth-mqtt
+ *
+ * #define democonfigUSE_AWS_IOT_CORE_BROKER ( 1 )
+ */
+
+/**
+ * @brief The username value for authenticating client to the MQTT broker when
+ * username/password based client authentication is used.
+ *
+ * For AWS IoT MQTT broker, refer to the AWS IoT documentation below for
+ * details regarding client authentication with a username and password.
+ * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html
+ * An authorizer setup needs to be done, as mentioned in the above link, to use
+ * username/password based client authentication.
+ *
+ * #define democonfigCLIENT_USERNAME "...insert here..."
+ */
+
+/**
+ * @brief The password value for authenticating client to the MQTT broker when
+ * username/password based client authentication is used.
+ *
+ * For AWS IoT MQTT broker, refer to the AWS IoT documentation below for
+ * details regarding client authentication with a username and password.
+ * https://docs.aws.amazon.com/iot/latest/developerguide/custom-authentication.html
+ * An authorizer setup needs to be done, as mentioned in the above link, to use
+ * username/password based client authentication.
+ *
+ * #define democonfigCLIENT_PASSWORD "...insert here..."
+ */
+
+/**
+ * @brief The name of the operating system that the application is running on.
+ * The current value is given as an example. Please update for your specific
+ * operating system.
+ */
+#define democonfigOS_NAME "FreeRTOS"
+
+/**
+ * @brief The version of the operating system that the application is running
+ * on. The current value is given as an example. Please update for your specific
+ * operating system version.
+ */
+#define democonfigOS_VERSION tskKERNEL_VERSION_NUMBER
+
+/**
+ * @brief The name of the hardware platform the application is running on. The
+ * current value is given as an example. Please update for your specific
+ * hardware platform.
+ */
+#define democonfigHARDWARE_PLATFORM_NAME "WinSim"
+
+/**
+ * @brief The name of the MQTT library used and its version, following an "@"
+ * symbol.
+ */
+#define democonfigMQTT_LIB "core-mqtt@1.0.0"
+
+/**
+ * @brief Set the stack size of the main demo task.
+ *
+ * In the Windows port, this stack only holds a structure. The actual
+ * stack is created by an operating system thread.
+ */
+#define democonfigDEMO_STACKSIZE configMINIMAL_STACK_SIZE
+
+/**
+ * @brief Size of the network buffer for MQTT packets.
+ */
+#define democonfigNETWORK_BUFFER_SIZE ( 1024U )
+
+#endif /* DEMO_CONFIG_H */ \ No newline at end of file
diff --git a/tools/aws_config_quick_start/misc.py b/tools/aws_config_quick_start/misc.py
new file mode 100644
index 000000000..c610f1b39
--- /dev/null
+++ b/tools/aws_config_quick_start/misc.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+
+import os
+import boto3
+
+
+def describe_endpoint():
+ client = boto3.client('iot')
+ endpoint = client.describe_endpoint(endpointType='iot:Data-ATS')
+ return endpoint['endpointAddress']
+
+
+def get_account_id():
+ client = boto3.client('sts')
+ aws_account_id = client.get_caller_identity()['Account']
+ return aws_account_id.strip('\n')
+
+
+def get_aws_region():
+ my_session = boto3.session.Session()
+ aws_region = my_session.region_name
+ return aws_region.strip('\n')
+
+
+def create_policy_document():
+ this_file_directory = os.getcwd()
+ policy_document = os.path.join(this_file_directory,
+ 'policy_document.templ')
+ region_name = str(get_aws_region())
+ aws_account_id = str(get_account_id())
+ with open(policy_document) as policy_document_file:
+ policy_document_text = policy_document_file.read()
+
+ # Replace Account ID and AWS Region
+ policy_document_text = policy_document_text.replace('<aws-region>',
+ region_name)
+ policy_document_text = policy_document_text.replace('<aws-account-id>',
+ aws_account_id)
+
+ return policy_document_text
+
+
+def format_credential_keys_text(credential_text):
+ credential_text_lines = credential_text.split('\n')
+ formatted_credential_text_lines = []
+
+ for credential_text_line in credential_text_lines:
+ if credential_text_line.strip():
+ formatted_credential_text_line = ' {:68s}'\
+ .format('"' + credential_text_line + '\\n"')
+ formatted_credential_text_lines.append(
+ formatted_credential_text_line)
+
+ formatted_credential_text = ' \\\n'.join(formatted_credential_text_lines)
+ return formatted_credential_text
+
+
+def write_client_credentials(
+ source_dir,
+ thing_name='',
+ client_certificate_pem='',
+ client_private_key_pem='',
+ cleanup=False):
+
+ file_to_modify = os.path.join(source_dir,
+ 'FreeRTOS-Plus',
+ 'Demo',
+ 'coreMQTT_Windows_Simulator',
+ 'MQTT_Mutual_Auth',
+ 'demo_config.h')
+ file_text = ''
+
+ if cleanup:
+ filename = "demo_config_empty.templ"
+ with open(filename, 'r') as template_file:
+ file_text = template_file.read()
+
+ else:
+ endpoint = describe_endpoint()
+ client_certificate_pem =\
+ format_credential_keys_text(client_certificate_pem)
+ client_private_key_pem =\
+ format_credential_keys_text(client_private_key_pem)
+
+ filename = "demo_config.templ"
+ with open(filename, 'r') as template_file:
+ file_text = template_file.read()
+ file_text = file_text.replace("<IOTEndpoint>",
+ "\"" + endpoint + "\"")
+ file_text = file_text.replace("<IOTThingName>",
+ "\"" + thing_name + "\"")
+ file_text = file_text.replace("<ClientCertificatePEM>",
+ client_certificate_pem)
+ file_text = file_text.replace("<ClientPrivateKeyPEM>",
+ client_private_key_pem)
+
+ header_file = open(str(file_to_modify), 'w')
+ header_file.write(file_text)
+ header_file.close()
diff --git a/tools/aws_config_quick_start/policy.py b/tools/aws_config_quick_start/policy.py
new file mode 100644
index 000000000..799efa29c
--- /dev/null
+++ b/tools/aws_config_quick_start/policy.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+
+import boto3
+import json
+
+
+class Policy():
+ def __init__(self, name, policy=''):
+ self.name = name
+ self.policy = policy
+ self.client = boto3.client('iot')
+
+ def create(self):
+ assert not self.exists(), "Policy already exists"
+ self.client.create_policy(policyName=self.name,
+ policyDocument=self.policy)
+
+ def delete(self):
+ assert self.exists(), "Policy does not exist, cannot be deleted"
+ self.client.delete_policy(policyName=self.name)
+
+ def exists(self):
+ policies = self.client.list_policies()['policies']
+ for policy in policies:
+ if self.name == policy['policyName']:
+ return True
+ return False
diff --git a/tools/aws_config_quick_start/policy_document.templ b/tools/aws_config_quick_start/policy_document.templ
new file mode 100644
index 000000000..dd33f15a6
--- /dev/null
+++ b/tools/aws_config_quick_start/policy_document.templ
@@ -0,0 +1,25 @@
+{
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Action": "iot:Connect",
+ "Resource": "arn:aws:iot:<aws-region>:<aws-account-id>:*"
+ },
+ {
+ "Effect": "Allow",
+ "Action": "iot:Publish",
+ "Resource": "arn:aws:iot:<aws-region>:<aws-account-id>:*"
+ },
+ {
+ "Effect": "Allow",
+ "Action": "iot:Subscribe",
+ "Resource": "arn:aws:iot:<aws-region>:<aws-account-id>:*"
+ },
+ {
+ "Effect": "Allow",
+ "Action": "iot:Receive",
+ "Resource": "arn:aws:iot:<aws-region>:<aws-account-id>:*"
+ }
+ ]
+} \ No newline at end of file
diff --git a/tools/aws_config_quick_start/thing.py b/tools/aws_config_quick_start/thing.py
new file mode 100644
index 000000000..07d81d790
--- /dev/null
+++ b/tools/aws_config_quick_start/thing.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+
+import boto3
+import json
+
+
+class Thing():
+ def __init__(self, name):
+ self.client = boto3.client('iot')
+ self.name = name
+ self.arn = ''
+
+ def create(self):
+ assert not self.exists(), "Thing already exists"
+ result = self.client.create_thing(thingName=self.name)
+ self.arn = result['thingArn']
+
+ def delete(self):
+ assert self.exists(), "Thing does not exist"
+ principals = self.list_principals()
+ for principal in principals:
+ self.detach_principal(principal)
+ self.client.delete_thing(thingName=self.name)
+
+ def exists(self):
+ list_of_things = self.client.list_things()['things']
+ for thing in list_of_things:
+ if thing['thingName'] == self.name:
+ return True
+ return False
+
+ def attach_principal(self, arn):
+ assert self.exists(), "Thing does not exist"
+ self.client.attach_thing_principal(thingName=self.name, principal=arn)
+
+ def detach_principal(self, arn):
+ assert self.exists(), "Thing does not exist"
+ self.client.detach_thing_principal(thingName=self.name, principal=arn)
+
+ def list_principals(self):
+ assert self.exists(), "Thing does not exist"
+ principals = self.client.list_thing_principals(thingName=self.name)
+ principals = principals['principals']
+ return principals