Feedback

Your feedback is important to keep improving our website and offer you a more reliable experience.

Securely Accessing IoT Devices based on JavaScript*

BY Tonny Tzeng ON Dec 15, 2017

Synopsis

The vision for the Internet of Things is an exciting world where simple objects interconnect to exchange data and collaborate to provide advanced services. To make objects secure and seamlessly connected, Open Connectivity Foundation (OCF) develops and ratifies specifications for device interoperability regardless of the manufacturer and the implementation. The open source project IoTivity delivers a reference implementation of the OCF specifications, providing a foundation for developers to create interoperable devices. The  open source project iotivity-node provides the Node.js binding to IoTivity for fast prototyping of OCF devices using JavaScript. Together, these projects allow you to use JavaScript to access the IoTivity security implementation to help protect resources from unauthorized accesses. This article will walk you through an exercise to show you how to use IoTivity security framework to quickly and securely prototype an OCF device.

Overview

Hackers used the Internet to break into a bank’s terminal server and issued commands to an ATM to withdraw money remotely. Although they were in different countries, both the terminal and ATM were considered to be on the same private network. However, because these devices were not actually in a physically isolated network, software security threats to them put the overall system at risk. In the emerging IoT space, more and more devices join to the network, and technologies are scaling up from smart home and smart building to factory automation and all the way to smart city applications. Even on a simple home network, unless the IoT devices are completely physically isolated from the outside world, they may be hijacked by unauthorized people due to unsecured IoT software solutions running on the devices.

OCF defined its specifications after reviewing IoT security requirements. The goal of the OCF security architecture is to protect the resources hosted on the server, providing access only to clients, subject to a set of access control and authorization mechanisms. In addition, end-to-end device interactions can be protected using a session protection protocol such as DTLS (Datagram Transport Layer Security) and the data encryption methods as shown in Figure 1.

Note: The abbreviation OIC in Figure 1 below is a reference to Open Interconnect Consortium, a previous name for OCF. The name was changed in early 2016 but still persists in some specifications.



Figure 1 OCF Security Architecture

In the OCF security architecture, the top-most application resources are protected through the implementation of access control, authentication and confidentiality protection. The resource access control relies on a set of predefined access policies in the form of Access Control Entries (ACE), which define permissions required to access a specific resource along with an optional validity period for the granted permission. In the following sections, we take a Node.js-based IoTivity virtual server as an example and explain the steps to grant its accesses only to the authorized client.

Prerequisites

To learn the security features in the IoTivity implementation, we combined the software components of an OCF Server, an OCF Client, and an Onboarding Tool in a container, so that the security exploration can be done in a sandbox environment. The container technology is an operating system level virtualization, which allows running isolated apps on supported platforms regardless of the environment. A container is a lightweight, stand-alone, executable package that includes everything needed to run the image, including the code, runtime, system tools, system libraries, and settings. Docker*, a popular software technology providing containers, is available on Windows*, Linux*, and Mac*. Please reference the Docker installation guide to setup Docker on your development platform. The Linux commands shown in the code block below are provided for your reference.

Note: In addition to the disk space required for Docker, make sure you have at least 20 GB available for the docker daemon to store the built image containing IoTivity programs, Android* SDK, etc.

Clone the container Dockerfile and example scripts from the GitHub repository and build the container image with the following commands.

$ git clone https://github.com/ttzeng/iotivity-inabox.git
    <git output omitted>
$ cd iotivity-inabox
$ sudo docker build -t iotivity-inabox .

The build will take a while as it pulls the ingredients from the Internet and builds the software inside a container. Once the build is complete, run the container image with the following command to mount the folders containing the example scripts.

$ sudo docker run -it -v `pwd`:/opt/mnt \
              -p 5901:5901 --privileged iotivity-inabox

 

We will be using the example scripts in a container to exercise the IoTivity security. The above command instructs the host to connect to network port 5901, as the image will start a VNC server for user interactions. The --privileged argument is required by the Android* x86 emulator.

Set the password for the created VNC session when you initialize the container. You will need to enter that password whenever you connect to the container using any VNC remote desktop client software.

You will require a password to access your desktops.
Password:
Verify:

In the next step, you will  launch VNC client software to connect to the container. Some operating systems have VNC client software included with the package, but you can use any VNC client that is compatible with your operating system.

Note: The screenshots included in this tutorial were captured using the open source Remmina Remote Desktop Client installed on Ubuntu* systems by default.

Run the Android emulator with the start-emulator.sh script from the VNC session connecting to the container.

# /opt/mnt/scripts/start-emulator.sh



Figure 2 Launch Android emulator inside a container

If you are launching the emulator for the first time, enter the command below to install the companion app to the emulator.

# adb install ~/companion-debug.apk

 

The companion app acts as the OCF native client. It is also an onboarding tool for retrieving the resource state of the virtual server and provisioning the devices.

Start the Server

Use the following commands to start hosting an OCF binary switch virtual resource on the server.

# cd /opt/mnt/simpleserver
# node binarySwitch.js

The Device ID field shown in Figure 3 is a unique identifier of the OCF stack instance. Note the value is just an example and will be changed after we reset the SVR (Security Virtual Resource) database in the persistent storage later.



Figure 3 Install the Companion app and start hosting a virtual OCF Server

In the OCF access control model, a resource instance must have an associated access control policy; otherwise the resource is inaccessible. Since we haven’t yet set up the proper Access Control Entries (ACE) in Server’s SVR database for accessing the resource, expect to see an  UNAUTHORIZED_REQ error message while accessing the LED resource from the companion app, as shown in Figure 4 below.



Figure 4 Access the virtual Server from the Companion app

Access to the Server

Secure Resource Manager (SRM) plays a key role in the OCF security architecture, as it authenticates incoming requests received via the secure port and manages security resources such as SVR, Access Control Lists (ACL), credentials, and device owner transfer state.

On receiving requests for a hosted resource, if the request arrives over the secured port, only authorized requestors, called subjects, are successfully matched to ACL entries. Access is denied if there is no ACE matched.

If the request arrives over the unsecured port, the only ACL policies allowed are either those ACEs that use an anonymous connection type or a subject wildcard that matches any anonymous requests.

In the OCF security framework, the access policies may be stored by a local ACL or an Access Manager Service (AMS). This tutorial uses the local ACL mechanism for simplicity.

The SVR in IoTivity software implementation optionally takes a configuration file in CBOR (Concise Binary Object Representation) format during the initialization, and a json2cbor utility is designed to generate the binary configuration file from a human readable JSON (JavaScript Object Notation) file. In addition, a wrapper script init-svr-db.sh is provided to simplify the SVR database creation process.

Press CTRL-C to stop running the Server script, and issue the following commands to set up the default SVR database and re-launch the Server.

# /opt/mnt/scripts/init-svr-db.sh binarySwitch.js
# node binarySwitch.js

The current Server script does not specify the use of secure endpoints for communications, so the companion app sends the access request to the Server over an unsecured channel. On receiving the request, the Server treats the request as anonymous, and no device UUID or role ID are associated with that request. The Server then consults the ACL and looks for an ACE matching any configured access policy.



Figure 5 Allowing anonymous access to the Server

Access Authentication

In OCF terminology, the device acting as the Server holds and controls resources, providing the device acting as a Client accessing to those resources, subject to a set of security mechanisms. So, let’s open a new window and introduce the Client to our experiment with the following commands to set up its SVR database and launch the Client script.

# cd /opt/mnt/simpleclient
# /opt/mnt/scripts/init-svr-db.sh index.html
# npm start



Figure 6 Access the Server from a new OCF Client

Though the Client can change the resource state of the Server, it doesn’t seem right that a new Client can access the existing Server without receiving an acknowledgement!

Use Secured Endpoint

Let’s review the default SVR database named oic_svr_db.json which we configured for the Server. The acl section contains a list of ACE access policies that govern the subjects and operations allowed on the resources. Though access control mechanisms can be subject-based, role-based, or connection-based, we only apply the connection-base access control mechanism in this tutorial for simplicity. The first four ACE policies instruct the SRM to allow the resource discovery and the ownership transfer requests through either secured port or unsecured port, but the fifth ACE policy grants read/write accesses to any requests from unsecured anonymous connections.

"acl": {
        "aclist2": [
            {
                "aceid": 1,
                "subject": { "conntype": "anon-clear" },
                "resources": [
                    { "href": "/oic/res" },
                    { "href": "/oic/d" },
                    { "href": "/oic/p" }
                ],
                "permission": 2
            },
            {
                "aceid": 2,
                "subject": { "conntype": "auth-crypt" },
                "resources": [
                    { "href": "/oic/res" },
                    { "href": "/oic/d" },
                    { "href": "/oic/p" }
                ],
                "permission": 2
            },
            {
                "aceid": 3,
                "subject": { "conntype": "anon-clear" },
                "resources": [
                    { "href": "/oic/sec/doxm" }
                ],
                "permission": 6
            },
            {
                "aceid": 4,
                "subject": { "conntype": "auth-crypt" },
                "resources": [
                    { "href": "/oic/sec/doxm" }
                ],
                "permission": 6
            },
            {
                "aceid": 5,
                "subject": { "conntype": "anon-clear" },
                "resources": [
                    { "href": "/a/switch" }
                ],
                "permission": 6
            }
        ]

Figure 7 The Server accepts anonymous connections by default

To properly manage the accesses on the Server, instead of configuring the ACE to allow anonymous connections in the default SVR database, we need to modify the configuration to allow only encrypted connections as the first step. Launch the pre-included geany editor to modify the subject field of the corresponding ACE from anon-clear to auth-crypt and reset the SVR database.

# cd /opt/mnt/simpleserver
# geany oic_svr_db.json

 



Figure 8 The ACE property to be revised to accept requests through a secured channel

Save the file and proceed.

Now reset the SVR database, using the command:

# /opt/mnt/scripts/init-svr-db.sh binarySwitch.js

To enforce the use of a mutually authenticated secure channel for exchanging messages, the Server must set the secure property of the hosting resource during the resource registration. The oic.sec.cred resource in the SVR database on each device should also hold the credentials used for mutual authentication and certificate validation. The credential of the Client will be exchanged and installed on the Server while pairing the two devices by the companion app.

Launch the geany editor to change the secure property of the resource server from false to true, as shown in Figure 9 below.

# geany binarySwitch.js



Figure 9 Properties used by the Server during the resource registration

Save the file. Then restart the server with this command:

# node binarySwitch.js

Onboarding Unowned Devices

Before a device can interact with other devices in an OCF environment, it must be onboarded appropriately. The onboarding process starts by configuring the ownership of the device, in which only the legitimate user who purchases the device can establish its ownership using the Onboarding Tool (OBT). Once ownership is established, the OBT becomes the mechanism for provisioning the device. At the end of the onboarding process, the device is ready for normal operations.

To establish ownership with a device using the companion app, select the Provisioning action in the control panel to discover both owned and unowned devices within an OCF environment.



Figure 10 Use the Companion app to discover unowned OCF devices

Once an unowned / new device is discovered, press the associated button to assert the companion app as the owner and manager of the device. The companion app uses one of the Owner Transfer methods (OxM) supported by the device to securely establish trust in the device, authorize the companion app to manage the device, and prepare the device for provisioning. An owner credential is provisioned to the device, which allows the device and the companion app to mutually authenticate during subsequent interactions.



Figure 11 Use the Companion app to establish ownership with the unowned Server

Pairing Client to Server

After both the Client and Server devices are onboarded, and the credential of the companion app has been installed to the oic.sec.cred resource of both the Client and Server devices, the companion app is now trusted by both the Client and the Server. However, in order to have the Client and the Server interact over a mutually authenticated secure channel, they need to have each other’s credentials.

Identify the Client and Server devices by the Device ID with the companion app. Click the checkboxes of the desired devices and press the button in the menu bar to pair the selected devices. The companion app will install the peer credential to each device to achieve mutual trusted status between the Client and the Server.



Figure 12 Pairing the Client and the Server



Figure 13 The managed Client accesses to the Server through a secured channel

Summary

After completing the onboarding process and pairing the Client and the Server, the resource hosted on the Server can be retrieved and updated by the Client. Other Clients joining the network need to go through the same authentication process before they can access the Server.

Through these technologies, including mutual authentication, per resource access control, data transport layer protection mechanism, and more, OCF ensures the robustness of the resource confidentiality protection and message integrity among IoT devices. Reference the OCF Security Specification for more detailed information.