Secure Provisioning of IoT device using Azure IoT Hub device SDK


Editor’s note: The following post was written by Visual Studio and Development Technologies MVP Alon Fliess as part of our Technical Tuesday series, with support from MVP Award Blog Technical Editor James Chambers.

Introduction

Security is a serious subject, especially when it comes to IoT systems and devices. There’s many critical systems that if malicious hackers were to take control, they’d be able to cause great damage – from retrieving private information, taking money and even sometimes one’s life.

In the past, hackers were gifted teenagers that had the time and patience to find vulnerabilities in computer systems and hacked them for fun. However nowadays, countries and security agencies all over the world invest billions of dollars and put their best minds towards attacking vital systems.

Here’s a story that demonstrates just how important security is:

Not long ago, I had a customer – an amazing medical startup- who developed a life saving solution. The project had three different devices; two had embedded systems running code written in C and C++. The third part was a desktop application that served doctors and the technician. The smaller device is implanted inside the human body, just above the heart, and has no inner power source. When the time came for the patient to need treatment, an external device, similar to a tablet, is put over the patient’s chest. The tablet provides the power, using inductive power supply circuit to wake up the implanted device. The same inductive based power supply also provides the communication channel, which is used to download the treatment plan, update device settings, and get device status. When the doctor needs to get a status, or changes the treatment plan, they use the PC to communicate with the pad, using BLE (Bluetooth Low Energy).

The implanted device is an 8-bit, low energy system on a chip controller, which is not capable of encryption. This means that if you know how to hack the communication protocol, you can kill a patient by transmitting the wrong treatment plan. I had recommended that there should be at least a way that both parties – the implanted device and the pad – should trust each other. Of course, without encryption capabilities, one can record the communication and understand the protocol and learn the device’s identity.

In the last article, I wrote about building a modern IoT application using Azure IoT Hub and Azure IoT Device SDK for C. For demonstration purposes, I used a small and cheap device, based on the ESP8266 chip.  In the article, I talked about device registration possibilities that enable easy and secure device onboarding.

However, in the sample code, I put the Azure IoT Hub Device connection string, as a clear text in the open, under the Configuration.h file. In this article, I will show you how you can set the ESP8266 to create an access point that lets you connect to it, and surf into a configuration page, where you can set the Azure IoT Device connection strings and other device settings.

This approach provides a way of deploying devices in the field without the need to compile a new version with the IoT Hub connection string, and without the need to have credentials embedded in the code.

I will also write about other security measures one needs to take in order to create a secure IoT system, and introduce the Microsoft holistic approach to IoT system security – all the way from device and field gateway screen-shot-2017-03-12-at-6-11-28-pmto the cloud. At the end of the article, I will talk about the challenges that one will encounter after onboarding a new device into the system, including device management and what the Azure IoT Hub provides you as a foundation to use. In my next article, I will get deeper into device management.

Back to the device. As I did in my last article, I use an ESP8266 based device. The code that I show in the example can run on the NodeMCU, which I used in the last article, or on other ESP8266 devices such as the WEMOS D1 mini pro, which I use in this article. These devices can handle a secure channel with the cloud, and they are very easy to program, using either the LUA programming language or the open tools of the Arduino development environment. I especially prefer the Visual Micro, a Visual Studio add-on made available in the latest versions of Visual Studio (2017).

figure-1b

Figure 1: Above images are the WEMOS D1 with Relay and my own Leds and Button shields

Besides having a secure way to configure a new device, I also decided to enhance my previous Gate Control application and to provide a setup web page; these were my requirements:

1. Start the device in Access Point mode with a well-known SSID (Wi-Fi network) and password (new requirement)

2. Support two operation modes: (old requirement, however moved from compile time to runtime)

  • Web Services/Embedded web site mode – directly call the device to activate the relay
  • Azure IoT mode – control the device via Azure IoT Hub commands

3. Enable two different reset options: (used to be only single reset option)

  • When pressing the button long enough (the default duration is above five seconds) the device will soft reset
  • When pressing the button for a (very) long period (the default duration is more than twenty seconds) the device will perform a factory reset, reboot and enter Access Point mode

4. Provide device status indication using two Leds – green and red (enhanced feature)

  • The green Led tells that the device is connected to the router, it also blinks the device IP address (you can count the blinks to get the IP address)
  • The red Led indicates an error
  • When the device is in Access Point mode the two Leds blink together
  • When you press the button long enough, the two Leds blink together fast to indicate a reset state, and very fast to indicate a factory reset state

5. Have a setup web page in a well-known address (http://192.168.4.1/appkey/setup), In the setup page, you can set: (new requirement)

  • The local Wi-Fi network SSID and credentials
  • The operation mode (Web Server or Azure IoT Hub)
  • The Azure IoT Hub connection string and device Id
  • The various device timing for the relay and the button

figure2-the-new-embedded-setup-page

Figure 2: The new embedded setup page

In my last implementation, I already had the two operation modes: the Web Server and the Azure IoT Hub. However you had to use a #define to compile the code and target the device to act in either of the modes. This time I wanted to have both of them available, and to decide about the device operation mode in the field using the device settings. When the device runs its initial boot, it starts in Access Point mode. In this mode, I use the embedded web server to serve the setup page.

After the user sets and chooses the operation mode, the device reboots and initiates a single operation mode: as a Web Server or as an Azure IoT Hub connected device. At the beginning I thought this would be a small change to the code, but it turns out I had to put in a lot of effort to enable this ability.

The main problem is that the chosen device has very small amount of RAM, and using the two modes with the web setting page causes ‘out of memory’ situations, which are very nasty to examine and difficult to debug. What I did to overcome this issue was replace all C++ std::string occurrences with Arduino’s String class – which is already present in the code anyway. I also removed the use of the Azure IoT Hub C SDK Serialization model; hence, I had to parse the message buffer by myself. And finally, I moved many of the predefined strings to the micro controller flash memory. It appears that the main cause for memory consumption is the use of TLS for secure communication.

Since I want to have a secure communication (Azure IoT Hub requires it), I had to change other areas in the code. Choosing a more capable device would make my life easier; however I really wanted to use this cheap and amazing device. If you encountered an unhanded exception using ESP8266 based device, do know that there is a tool named “exception decoder” that provides a meaningful call stack.

The result is a full IoT device that can start and create its own Access Point, and serve a rich HTML setup page, including JavaScript and CSS files. The device can be securely connected to the Azure IoT Hub and send and receive messages from the cloud. Everything comes from this tiny and cheap device!

The IoT device sample code:

You can find the sample code here. There are few managers that implement IProcessor abstract class, and all of them participate in the Arduino main loop:

  1. WiFiManager – handles the Wi-Fi Access Point mode as well as the connection to the network
  2. WebServer – handles the Web page for activating the device as well as provides the new setup page
  3. AzureIoTHubManager – handles the Azure IoT Hub communications
  4. Logger – handles the indication Leds
  5. RelayManager – handles the relay that activates the command (open a gate, turn on the light, etc.)
  6. PushButtonManager – handle the button for local operations as well as for resetting the device

ConfigurationManager – the only manager that is not part of the Arduino processor loop. It handles the device settings, including the Wi-Fi SSID and password, as well as the Azure IoT Hub connection string. It keeps the information in the device eeprom so it can use the information even if the device is not connected to a power supply.

figure3-the-managers

Figure 3: The Managers

The glue that starts everything and ties all managers is the LedLightWebController.ino file. It starts up all managers and provides the managers their component dependencies, using constructor injection or via call to a Register() method. Using IoC (Inversion of Control) idiom isolates each manager from the rest and provides a good design approach.

The Wi-Fi Manager (Access Point and regular mode):

The Wi-Fi manager wraps the ESP8266 Wi-Fi capabilities. According to current configuration it starts either in an Access Point mode using a preconfigured SSID (currently: AlonIoT) and password (currently:12345678), from the Configuration.h file, or tries to connect to a local Wi-Fi network with the provided SSID name and password from the setup page.

Once Wi-Fi is in a connected state, it informs the other managers that they can start communicating with clients, or take other actions. For example, the LedLogger sets the Leds state according to this connection information message.

  1. Green and Red LEDs blink together indicates Access Point mode
  2. Green and Red LEDs stay on indicates Access Point mode with at least one connected client
  3. Green color to show that the Wi-Fi is connected to the local Wi-Fi network
  4. When the device establishes a connection to local Wi-Fi network, the Green led blinks the device assigned IP address
  5. Red LED indicates an error state

The Web Server (Web Server mode)

The web server has two purposes: to serve as a web gateway in order to activate the device and to provide a web-setting page. When we use the device as an Azure IoT device, we need only the latter. Go to the setup page to start the device in Access Point mode, or in a Web Server mode and surf to http://192.168.4.1/appkey/setup.

To present the setup page I had to have an HTML page template loaded into the ESP8266 memory, and parse and replace the text for the form fields. This is something that it is very easy to achieve using common web server frameworks such as ASP.NET MVC and others. However, for such a small device as the ESP8266, it is a challenge.

I took an HTML form that I built using one of the free HTML form builders, and stripped out anything which is not required. I also minified the HTML, and to get it into the code, I just assigned it to a simple C++ (const char PROGMEM []) variable (see WebSettings.h). The PROGMEM keyword tells the compiler to put the data in the flash memory instead of the RAM. This is vital and without it, you will encounter out of memory exceptions. For each form input field, I replaced the value with a tag (<%=tag%>) mimicking the ASP.NET tag style. I wrote my own function that replaces <%= %> tags with configuration values coming from the configuration manager.

For those of you that want to see some code, look at the function WebServer::PopulateHTMLSetupFromTemplate() in the WebServer.cpp file. The map put the tag values with the configuration values coming from the Configuration Manager.

One of the consequences of parsing and replacing tags is that the HTML is limited in size, since there is a need to create another copy of the text with the replaced settings values in runtime, and the amount of RAM is very small. To overcome some of the memory problems I had, I used PROGMEM for static HTML, JavaScript and CSS files. Another approach that I could work is to use the internal ESP8266 file system support. This requires preloading of your HTML and CSS files into the flash memory of the device.

The Configuration Manager:

The configuration manager holds the system settings in the device eeprom. For simplicity, I just copy the configuration structure (eepromInformationBlock) as-is, to the eeprom memory. And whenever the system restarts, it loads it back. When the Configuration Manager starts, it looks for a magic string at the beginning of the eeprom memory. If it finds it, it loads the rest of the data structure; otherwise, it initiates the configuration data to a factory mode setting. When you press the button for a very long time, you actually ask the Configuration Manager to zero this magic text in the eeprom, telling it to start the device in a factory reset mode.

 struct
{
	unsigned char _magicNumber[6];
	char SSIDName[32];
	char AccessPointPassword[64];
	char AzureIoTHubConnectionString[256];
	char IoTHubDeviceId[64];
	unsigned int milliSecondsButonLongTimePeriod;
	unsigned int milliSecondsButonVeryLongTimePeriod;
	unsigned int milliSecondsPulseActivationTimePeriod;
	bool bUseAzureIoTHub;
	bool bPulseRelay;
} _eepromInformationBlock;

The AzureIoTHub Manager: (Azure IoT Mode)

This is the secure way to communicate with the cloud and vice versa. When the device starts in Azure IoT Mode, there is no other way to communicate with the device, but to use the Azure IoT secure messaging system. The device does not open a web interface; it is just listening to Azure IoT Hub commands. When a command arrives, it checks the command validity and publishes it, so the right manager can handle the event. I use the secure https channel to handle Azure IoT Hub communication, but I could use two other protocols, the simple MQTT and the strong and complex AMQP, both in a secure manner.

I encourage you to download the code, buy a cheap ESP8266 based device and try the system. You can also contribute to the code as well as to the documentation. The current implementation, writes log information, to the serial port; this is very helpful for debugging and testing purposes, however, in a real system, for security sake, remove all those debug printings, or even disable the serial communication.

To understand how to send commands to the device, look at my last articles. Since I stripped out the serialization code, you just need to send a command with its simple form: On, Off or Activate, that it! Use the Device Explorer to set the Azure IoT Hub connection string and play with commands:

figure-4-copy-the-connection-string-using-the-device-explorer-tool

Figure 4: Copy the connection string using the Device Explorer tool

Figure 5: Setting the Azure IoT Hub connection string

Figure 5: Setting the Azure IoT Hub connection string

Figure 6: Sending messages (commands) to the device

Figure 6: Sending messages (commands) to the device

Figure 7: The device receives the messages from the IoT Hub

Figure 7: The device receives the messages from the IoT Hub

As you can see, in order to connect the device to the IoT hub, I use the Device Explorer to add the device and get the device connection string. In the last article, I showed you how one can use the registration APIs to do it automatically. If you want to deploy many devices, you may want to do it automatically. Create your own service or Azure Function and point the setup page to take the device name and connection string from this service. To make the device registration secure, you will need to ask the user to provide the URL and password of the registration service.

public class DeviceController : ApiController
    {
        // GET api/deviceid/MyDevice
        public async Task Get(string deviceId)
        {
            var deviceManager = new DeviceManager();
            var result = await deviceManager.UpdateOrCreateDevice(deviceId);
            return result;
        }
    }
 
 public class DeviceManager
    {
        private readonly string _iotHubConnectionString = ConfigurationManager.AppSettings["iotHubConnectionString"];
 
        public async Task UpdateOrCreateDevice(string newDeviceId)
        {
            var registryManager = RegistryManager.CreateFromConnectionString(_iotHubConnectionString);
            await registryManager.OpenAsync();
            var device = await registryManager.GetDeviceAsync(newDeviceId) ??
                         await registryManager.AddDeviceAsync(new Device(newDeviceId));
 
            return device.Authentication.SymmetricKey.PrimaryKey;
        }
    }

IoT System Security

Protecting an information system is a very hard task to achieve; you never know if your system is fully protected. No matter how much effort you put into securing the system, there still might be a hole that the hacker can enter. You only know that your system is not protected once someone hacks into it – until then, you can only hope that it is protected.

About four years ago, I found a security vulnerability in the .NET framework. According to Symantec™, the implication of this bug leads to:

Microsoft Silverlight and Microsoft .NET Framework are prone to a remote code-execution vulnerability. Successful exploits will allow an attacker to execute arbitrary code within the context of the application. Failed exploit attempts will likely result in a denial-of-service condition.

Of course, this bug was fixed a long time ago, but imagine how much effort Microsoft put in securing .NET and still, something like this happened. Developers and QA engineers test their code to find out that the system answers all functional requirements. They often do not test the implications of using the system in the “wrong” way. When you design a system and you write user stories for the system users, do you also write a story for the hacker user? Since anything can be the weak point that the hacker searches, you must take an holistic approach to secure the system.

How do you start with securing your IoT system? You need to create a threat model. The idea behind this is to think the way a hacker thinks, and to look at each layer of your system to find the weak security points. After having a good threat model, you need to think of measures to take in order to protect the system. Sometimes you will need to change a feature or even the system behavior – like use different protocols, or implement other services such as firewalls for the sake of better security. I will not get into the details of how you create the threat model, but I encourage you to read this IoT security article as well as the STRIDE article from 2007. STRIDE stands for Spoofing, Tampering, Repudiation, Information disclosure, Denial of Service and Elevation of privilege.  

The Web Controlled Switch IoT Solution Security Analysis

The web controlled switch IoT system has the following layers (security zone):

  1. The device itself
  2. The Wi-Fi router that connects the device to the internet and to the cloud
  3. The Azure IoT Hub
  4. The Azure Function that provides the API to call and activate the device
  5. The user application that calls the Azure Function to activate the switch

Each one of these layers needs to be addressed in our security threat model. Each one of these layers or zones is separated by a trust boundary. Hackers might try to hack any of these zones, intercept the communication between zones, or present their component to other components in your IoT system as if it was the original component.

screen-shot-2017-03-12-at-6-42-43-pm

Figure 9: Security Boundaries

The ESP8266 based IoT device is a simple device, however it supports secure communication. When the device is in Access Point mode, the technician may connect to it, through the internal access point. The technician must know the device SSID password to be able to connect. Even if hackers succeed to connect the device by hacking into the access point, they still will need to know the embedded application key, which is stored in the configuration.h file. So a brute force attack would take forever if you have a long and strong application key. When the technician sets the Azure IoT Hub connection string in the device setup page, the device is rebooted and no longer presents the web server interface, i.e. port 80 is closed! There is no way to communicate with the device, other than sending commands using the IoT Hub. It’s only if hackers have physical access to the device, that they can reset the device to factory mode – but then the eeprom information, regarding the Azure IoT Hub connection string, is not presented and needs to be set again. To be on the safe side, do not allow resetting the device after the initial setup. Just throw the device out and get a new one instead.

What about the communication between the device and the local Wi-Fi router? Is this communication secure? The answer is yes. All Azure IoT hub communication protocols are secure by default. In our case, the communication protocol is based on HTTPS. This is why the code goes to an NTP server in order to get the current UTC time. It is required for the TLS algorithm to encrypt the information. Read mode about Azure IoT Hub security here.

The other security zones in our application have their own security measures. This is no different from any other cloud based solution and client application security requirements, and has nothing to do with device security.

Azure IoT Hub Device Management

Provisioning a device in a secure manner is just the first step to managing IoT devices. Azure IoT Hub provides new capabilities for managing large number of devices – including the monitoring of device health, and configuration like updating device firmware from the cloud, with no need to be physically connected to the device. The device management API provides a way to store device properties, and to query device information by using a cloud based device twin object that represents the device. Device management is a subject for another article.

Summary

This article continues on from my previous articles; the first article introduced IoT concepts, Azure services and the devices, and the second article showed new capabilities of the Azure IoT solution, as well as the Azure IoT Device SDK. This article shows how it’s possible to have the same device, deployed in a different location with a different device id, and not change the device code, by having a soft access point and a configuration setup web page. With this capability, you have an IoT device that can be configured to use any public network, with no need to ask the network administrator to create a NAT and firewall rules. We also talked about IoT system security and showed the security measures in our Web/Cloud controlled switch example.

Acknowledgment

I would like to thank Hande Kayadeniz Torkan and Victoria Stunt for inviting me to write another article. Many thanks to Dror Gluska, Dror Helper & Aaron Etchin for testing the code and providing good feedback.


pic_14_alon_fliess

Alon Fliess is the Chief Architect and founder of CodeValue. CodeValue is a leading software company, consisting of locally and internationally acclaimed technology experts. CodeValue delivers a full-spectrum of software services – it builds and designs software tools, foundations and products. Our flagship product is OzCodean Amazing debugging add-on for Visual Studio. CodeValue is a Microsoft Partner in two domains – Software Development and Cloud Platform.

With more than 25 years of experience Alon has worked on many major software development projects, designs and architectures for global leading, and cutting edge companies.

Alon has been a Microsoft Regional Director since 2010 and a Visual Studio and Development Technologies MVP since 2005. Alon serves as a focal point between Microsoft product teams and their customers, helping product teams to better understand their customers’ needs, as well as assisting customers in leveraging Microsoft’s technologies. In 2013 Alon was awarded the MVP of the year.

Alon has expertise in many technologies, be it Microsoft Azure Development, Windows internals, C++ Windows programming (Win32/UWP), .NET with C#, and Internet of Things – this includes hardware & software development and cross-platform development (Windows & Linux).

Alon is known within the international community of software developers and considered to be a trusted advisor for all software development related issues.

Alon is a co-author and technical reviewer of several books. He’s a frequent “Developer course” instructor and often speaks at conferences. Alon is a co-leader of Azure Israel –the  Israeli Azure developer community –  together with Eran Stiller, an Azure MVP.

Most of all, Alon loves working at night, He enjoys sitting in front of the computer, learning and testing new technologies, writing code, designing and printing 3D items with his DIY upgraded 3D printer.

Alon’s Open Source Projects:

https://github.com/alonf

https://www.codeplex.com/site/users/view/alon

Comments (0)

Skip to main content