Welcome to the IoT Fuse 2018 workshop on PKI Integration.
The purpose of this class is to discuss and practice using tools helpful in securing devices at the transport layer. Modern IoT Platforms, such as Murano, can utilize the device's Client Certificate (public key) to authenticate and identify the connecting device.
This allows the IoT platform to utilize the asymmetric encryption methods in TLS for provisioning and identification at the connection-level.
Though it is still common, and sometimes necessary, to add a symmetric provisioning layer on top of the TLS connection (e.g. connect, retrieve auth token in a secure/trusted environment like a manufacturing facility, use token for all subsequent connections), it is often desirable and becoming more common to allow the connecting device to present its Client Cert as its identity.
For the purposes of this workshop, there are a few things that we will either not cover or cover only briefly in order to keep the scope of the workshop manageable for the alloted two-hour slot.
- Registration Authorities (RA) - The concept of an RA will not be covered in this workshop. It is assumed that the CA and the RA is the same entity, which is fairly common. If, in your IoT solution/implemementation an RA is needed or desired, a CISSP certified admnistrator should be consulted to make sure it is done correctly.
- Best practice or advice on how to secure the CA private key. This is up to your organization to keep these secrets safe.
- Certificate Authority - What they are and how to function as one.
- Certificate Signing Requests (CSR) - How to create them for your devices and getting them signed.
- Public and Private Keys - These are what make communication security possible in any setting (e.g. IPoAC).
- Securely Provisioning Devices - The workshop uses
openssl
commands, but the same concepts apply to the rapid market adoption of crypto coprocessors as well (e.g. ECC508). - Client Certificates - This is what you get back from signing a CSR. It is loaded onto the device and is used in the Diffie-Hellman exchage to secure TCP connections. Mature IoT Platforms uses this Client Cert to identify connecting clients via the
CN
field of the cert. The term "Client Cert" is synonomous to the Public Key. - Exosite's Murano IoT Platform - Participants will create a new account, as well as create and configure a Product for TLS Client Cert provisioning.
Each step in the sequence diagram, referenced below, is numbered and the remainder of the workshop will refer to these steps by number (e.g. [1]
, [2]
, etc.). This document is organized in basic sections:
- Set Up Environment
- Establish The Root
- Establish An Intermediary
- Provision Devices
- Update The Intermediary
These sections contain commands that are grouped together by category, not sequence, so look in the subsection title for the step of the sequence of interest.
Before getting started, take a few moments to set up your laptop with a working environment that will help keep files organized and configure the Murano Product you will use as the IoT Platform for this workshop.
IMPORTANT: Throughout this workshop, all commands are written so the entire command-block can and should be copied and pasted into a bash
terminal.
In a new tab in your browser, navigate to Exosite's Murano IoT Platform and perform the following:
- If you have not done so already, create an account and login.
- If you have not done so already, create a new Product (click SOLUTIONS > + NEW SOLUTION > Add A Product), give it a unique name with only lower-case alpha-numeric characters.
- Create a new Device Resource (click on your new Product, Resources, + NEW RESOURCE) called
data_in
with all options set to the defaults. - Copy the App Link (click the little green hyperlink icon in the upper-left-hand corner of the Product view).
openssl version
At the end of most of the code-blocks in this workshop is a tree
command that shows how the pki-workshop
directory is organized. It is a convenience and not required, but helpful. If you don't have the tree
command and/or can't install it, just skip running all of the tree
commands.
Linux:
sudo apt-get install tree --upgrade
OSX:
brew install tree
Copy and paste the code block below to create a directory for the root
, intermediary
and device
credentials that will be created throughout the workshop.
NOTE: If you're not using your own Murano Product and wish to use the instructor's, use the following for the Product App Link when prompted, below: https://u2bp3samq5t340000.m2.exosite.io/
read -p "Paste the Product App Link: " MURANO_HOST && export MURANO_HOST && \
mkdir -p ~/iotfuse2018/pki-workshop/{root,intermediary,devices} && \
cd ~/iotfuse2018/pki-workshop && \
tree
The sequence diagram located here (right-click and open in new tab) illustrates the players involved in Client Certificate based device provisioning.
This section marks the beginning of the workshop.
Below are the commands needed to function as a CA. This does not make the user compliant with the Mozilla Root Store Policy, which goes far beyond the scope of this workshop.
That commands, below, create the root key-pair, defining the CA.
cd ~/iotfuse2018/pki-workshop
openssl req -x509 \
-nodes \
-days 3650 \
-newkey rsa:2048 \
-keyout root/root-key.pem \
-out root/root.pem \
-subj "/C=US/ST=MN/L=Mpls/O=Exosite/CN=IoTFuse2018Root"
tree
In your Murano Product SETTINGS, perform the following:
-
Select "Enable Client CA Certificate"
-
Paste the entire contents of the
root/root.pem
file. -
Click "SAVE" in the upper-right-hand corner of the SETTINGS view.
EXAMPLE:
$ cd ~/iotfuse2018/pki-workshop $ cat root/root.pem -----BEGIN CERTIFICATE----- MIIDITCCAgkCCQD3i1Z46zr+IzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJV UzELMAkGA1UECAwCTU4xDTALBgNVBAcMBE1wbHMxEDAOBgNVBAoMB0V4b3NpdGUx FjAUBgNVBAMMDUlvVEZ1c2UyMDE4Q2EwHhcNMTgwNTAyMDM0MjIxWhcNMjgwNDI5 MDM0MjIxWjBSMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTU4xDTALBgNVBAcMBE1w bHMxEDAOBgNVBAoMB0V4b3NpdGUxFTATBgNVBAMMDHdpbGxjaGFybHRvbjCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN3FHHIpHDjwj3ySHl0w7LJDPuIf jmn1YykghEVHtVqcAKueBe/bbRTMsayZT1sN839w7EN4yZ1da6D8AjXnxaj8WMX7 gyN2gw2BvT6oBsz9oK0D0OtJyLjQc31d7IB9TOgkV6qoqTuQoG2mJTGGtqmR2aOD pEDwVWe1is/x3bqjyMuyfBFEWVIW5XBV8R1SDfaN+oeVGd0qPNr6E1oMxZRmTdc5 /taIK9qZJwJ5QaTdsO5BDFOtywCblgLyU7iTbKQvE2xOcCDm+nOh8xrUvkjWZkx6 HFsqLSMnv9fzXKnWgQ4lOZ6dtx+octYSySCOyhtPDAIhgBUZbC/iJ0iIiA0CAwEA ATANBgkqhkiG9w0BAQsFAAOCAQEAKpWU1cyb9zR8Fb1Ww4X4Rir0R/i06L8b0++8 E23q41aOQPoLztu/tk+fR8yUSFrlLyARsyYanSvOJHoszCm5iEU9g01GQEXBB34T WfLoIXiNa8G/4YbdiyhKzrVM0G5wKZtzjyplKMH7elwCb25e1e8/u6FEQu/i29F2 UUDmADw/z01IRFBM0WzvieOjA1oIiSTuSIBLLXJXBLWCPyVT9+1xMNUiKcCv2BL4 Lv3fIeck9suJVy9+HP/eskIrmmU7QF/3eI/lQNNt8g4+fpb//zM4kkbEb+RGt0zS T/0Tolf07YryMkcZ2EjRvcl2HDpVVLyVHKjSL1YfY3mUWxenbw== -----END CERTIFICATE-----
This is how one, acting as the CA, signs incoming Certificate Signing Requests (CSR) for intermediary CAs.
cd ~/iotfuse2018/pki-workshop
openssl x509 -req \
-days 3650 \
-in intermediary/intermediary.csr \
-CA root/root.pem \
-CAkey root/root-key.pem \
-CAcreateserial \
-out intermediary/intermediary.pem
tree
This section outlines how to create an intermediary CA. It is common to create an intermediary for many reasons (e.g. CA cert expires, gets compromised, security policy, etc.).
The commands, below, create a new private key and a CSR that is later signed by the root cert.
cd ~/iotfuse2018/pki-workshop
openssl req -new \
-newkey rsa:2048 \
-nodes \
-out intermediary/intermediary.csr \
-keyout intermediary/intermediary-key.pem \
-subj "/C=US/ST=MN/L=Mpls/O=Exosite/CN=IoTFuse2018Intermediary"
tree
In the browser tab containing the Murano Product, navigate to SETTINGS and set the following options:
- PROTOCOL: Select "HTTPS Device API" (leave Enable Developer Mode unchecked).
- PROVISIONING: Select "Allow devices to register their own identity".
- PROVISIONING: Select "TLS Client Certificate".
- Click "SAVE" in the upper-right-hand corner of the SETTINGS view.
The commands, below, can be used to sign device CSRs.
cd ~/iotfuse2018/pki-workshop
read -p "device id: " CN && export CN && \
openssl x509 -req -days 3650 \
-in devices/device-${CN}.csr \
-CA intermediary/intermediary.pem \
-CAkey intermediary/intermediary-key.pem \
-CAcreateserial \
-out devices/device-${CN}.pem && \
tree
During the workshop, the instructor will be running a flask server that participants can POST their CSRs to and get a cert signed by the instructor's Platform Cert. This will allow connections to the instructor's Murano Product.
cd ~/iotfuse2018/pki-workshop/devices
curl <ip-address>:5000/csr -F csr=@<name-of-csr>.csr > <name-of-cert>.pem
Running the commands, above, will save a client cert that was signed by the instructor's root CA Certificate.
When prompted by the commands, below, provide a unique name for your "device". The result is a CSR and private key.
cd ~/iotfuse2018/pki-workshop
read -p "device id: " CN && export CN && \
openssl req -out devices/device-${CN}.csr -new \
-newkey rsa:2048 \
-nodes \
-keyout devices/device-${CN}-key.pem \
-subj "/C=US/ST=MN/L=Mpls/O=Exosite/CN=${CN}" && \
tree
The next step for provisioning this "device" is to have the CSR signed by a CA. Once this is done, the "device" will be able to connect and have its Client Certificate verified against the root CA cert.
The commands, below, use curl
to POST/GET arbitrary data to/from the Murano Product.
cd ~/iotfuse2018/pki-workshop
read -p "device id: " CN && export CN && \
curl -k -X POST \
"${MURANO_HOST}onep:v1/stack/alias" \
-H "User-Agent: IoTFuse-PKI-Workshop-V1." \
-H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" \
--cert devices/device-${CN}.pem \
--key devices/device-${CN}-key.pem \
--cacert intermediary/intermediary.pem \
-d "data_in=i have become aware: ${RANDOM}" && \
tree
In your Murano Product tab, navigate the the DEVICES tab and verify that the device has been successfully provisioned and that there is data in the data_in
resource.
The commands below, create a self-signed client cert and attempt to use it to connect to the Murano Product, which should fail since the client cert wasn't signed by the intermediary CA cert.
cd ~/iotfuse2018/pki-workshop
read -p "device id: " CN && export CN && \
openssl req -x509 \
-nodes \
-days 3650 \
-subj "/C=US/ST=MN/L=Mpls/O=Exosite/CN=${CN}" \
-newkey rsa:2048 \
-keyout devices/self-device-${CN}-key.pem \
-out devices/self-device-${CN}.pem && \
tree && \
curl -k -X POST \
"${MURANO_HOST}onep:v1/stack/alias" \
-H "User-Agent: IoTFuse-PKI-Workshop-V1." \
-H "Content-Type: application/x-www-form-urlencoded; charset=utf-8" \
--cert devices/self-device-${CN}.pem \
--key devices/self-device-${CN}-key.pem \
--cacert intermediary/intermediary.pem \
-d "data_in=i have become aware: ${RANDOM}"
Expect:
curl: (35) error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate
For any reason, at any time, the Intermediary CA can be changed. For a good read on why intermediary certs are used: link.
To update the Intermediary Cert, execute steps [3]
, [4]
and [5]
.
Once the intermediary is updated, execute steps [6-8]
to provision new devices, then execute steps [13-15,30-33]
once again to verify the fleet of devices can still operate.
THIS CONCLUDES THE WORKSHOP
Products like the ECC508 from Microchip depend on IoT Platforms that support ecdha
algorithms and PKI infrastructures.
The idea behind these pieces of silicon is that they are added to PCBs of embedded systems and industrial gateways so the core processor's ALU doesn't have to do all of the hard math of TLS negotiations (i.e. diffie-hellman). These cryptocoprocessors are optimized so that they are almost always faster at computation than the host ALU, so it is advantageous to use them.
In addition to being fast, they are incredibly secure. The private key on these units cannot be read from the device. The process of creating CSRs and getting the signed Client Cert onto the chip is a bit more involved, but the overall concepts covered in this workshop remain valid when using hardware cryptocoprocessors.
During this workshop we covered:
- How to create a self-signed (root) CA.
- Configure an IoT Platform with the root CA for device authentication and identity.
- Create an intermediary CA and provision devices via the intermediary.
- Update/change the intermediary CA and provision new devices with the updated CA.
- Verify all authorized devices can connect and POST/GET data.
PKI environments can get more complex than this, but the basics with regards to overall concepts and using common tools were covered.