About

 

This is the third part of a ThingBerry related blog post series.

 

 

ThingBerry is ThingWorx installed on a RaspBerry Pi, which can be used for portable demonstrations without the need of utilizing e.g. customer networks. Instead the ThingBerry provides its own custom WIFI hotspot and allows Things to connect and send / receive demo data on a small scale.

 

In this particual blog post we'll discuss on how to setup the ThingBerry for encrypted communication and trust via certificates. We will create a custom Root and Intermediate Certificate Authority as well as a server specific certificate.

 

More information on the theory of Trust & Encryption can be found here: Trust & Encryption - Theory

 

As the ThingBerry is a highly unsupported environment for ThingWorx, please see this blog post for all related warnings.

 

Preparing the environment

 

To get started and keep all the working materials safe and secure within the scope of the pi user account, let's start creating a workspace directory and then install the openssl package

 

cd ~
mkdir certs
chmod 700 certs
cd certs

 

sudo apt-get install openssl

 

Troubleshooting Tips

 

Keytool

 

To look at a specific certificate use the keytool and specify the .crt file to look at

 

keytool -printcert -file rootca.crt

 

This will show information on the certificate's configuration, such as signing authority or validity.

 

Timestamps

 

It's important, that the Chain of Trust follows a timely fashion.

The Root CA has the longest expiration date. Within its validity the Intermediate CA must be valid. The server specific certificate must be valid in the timeframe of the Intermediate CA validity.

 

As the validity is calculated based on seconds of the current (signing) action, I'm using valid days of

 

  • Root CA 999 days
  • Intermediate CA 888 days
  • Server specific certificate 777 days

 

Any other times, that make sense can be used, as long as the time constraints are followed.

Otherwise the certificate will not be recognized as valid and will therefore not be trusted.

 

Creating a Chain of Trust

 

For this example we'll create a Root and Intermediate Certificate Authority (CA) as well as the server specific certificate. In a first step we can create all of the required keys.

 

openssl genrsa -des3 -out rootca.key 4096
openssl genrsa -out intermediateca.key 4096
openssl genrsa -out server.key 4096

 

The -des3 option for the rootca will store a password and encrypt it within the key for more secure access.

This tightens up security, so that the key for the rootca is not easily corrupted or exposed.

 

Root Certificate Authority

 

Having the keys, we now create the Root CA itself

 

openssl req -new -x509 -sha256 -days 999 -key rootca.key -reqexts v3_req -extensions v3_ca -out rootca.crt

 

Enter the information, starting with the password for the Root CA key.

Use a easy to identify name for the Common Name (CN), e.g. "My Root CA"

 

Intermediate Certificate Authority

 

As the Intermediate CA needs to be signed / approved by the Root CA, we need a Certficiate Signing Request (CSR)

 

openssl req -new -key intermediateca.key -reqexts v3_req -extensions v3_ca -out intermediateca.csr

 

The v3_ca extension will mark this certificate as CA itself.

This means that we can use the intermediate CA to sign other certificates as well.

 

The CSR will be signed with the Root CA's key and certificate.

For this the CSR must be sent to the whoever own the Root CA.

In our case, we're the owner ourselves and have everything in the same directory, so no need to send it off to Let's Encrypt, Google or VeriSign.

 

For signing the Intermediate CA as an actual CA, the Root CA must have a specific configuration to allow the v3_ca extension. This needs to be created via

 

nano v3_ca.ext

 

Into this new file, copy & paste the following:

 

basicConstraints        = CA:TRUE
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always,issuer:always
keyUsage                = cRLSign, dataEncipherment, digitalSignature, keyCertSign, keyEncipherment, nonRepudiation

 

Save and exit.

 

Finally, the Root CA is signing the Intermediate CA, using the v3_ca extension via:

 

openssl x509 -req -in intermediateca.csr -CA rootca.crt -CAkey rootca.key -CAcreateserial -CAserial intermediateca.srl -extfile v3_ca.ext -days 888 -sha256 -out intermediateca.crt

 

Certificate Authority Chain

 

Having now two CAs, they need to be chained together.

This is required for later to create the keystore used in Tomcat.

 

Creating the Chain is probably the easiest part of this blog:

 

cat intermediateca.crt rootca.crt > cachain.crt

 

Server Specific Certificate

 

The server specific certificate has to be signed and obtained by the Intermediate CA; for this a CSR is required.

 

openssl req -new -key server.key -out server.csr

 

The request is then signed with the Intermediate CA's key and certificate.

For commerical certificates this signing process will be done by publicly trusted CAs, like Let's Encrypt, VeriSign or Google.

In our case, we're the Intermediate CA ourselves and can sign the CSR.

 

openssl x509 -req -in server.csr -CA intermediateca.crt -CAkey intermediateca.key -CAcreateserial -CAserial server.srl -days 777 -sha256 -out server.crt

 

Creating Keystores

 

For the keystore as used in Tomcat we need the CA Chain as well as the server specific certificate and the corresponding key.

To generate a keystore that can be used in Tomcat, we first need to create a PKCS12 type keystore with openssl

 

openssl pkcs12 -export -certfile cachain.crt -in server.crt -inkey server.key -out server.p12

 

This PKCS12 keystore can now be transformed into a JKS keystore, by importing the PKCS12 information into a new JKS keystore

 

keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 -destkeystore keystore.jks -deststoretype JKS

 

Important: the passwords for the PKCS12 keystore and the JKS keystore must match!

Tomcat requires those passwords to be same - in case they are different, the configuration will not work and ThingWorx cannot be accessed through a secure connection.

 

Configuring ThingWorx

 

For ThingWorx, only the keystore is required.

It can be copied over e.g. to certificates area in the storage directory.

 

sudo cp keystore.jks /thingworx/storage/certificates
sudo chmod 640 /thingworx/storage/certificates/keystore.jks
sudo chown tomcat:tomcat /thingworx/storage/certificates/keystore.jks

 

To enable it, Tomcat's server.xml needs to be updated.

 

sudo nano $CATALINA_HOME/conf/server.xml

 

Find the connector for port 80 and add a new connector after the port 80 connector:

 

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" connectionTimeout="20000"  redirectPort="8443"
           SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLSv1.2" enableLookups="false"
           keystoreFile="/thingworx/storage/certificates/keystore.jks" keystorePass="<keystorePass>" />

 

Don't forget to update the password.

 

Stop Tomcat

 

sudo service tomcat stop

 

Ensure Tomcat is actually down with

 

ps -ef | grep tomcat

 

If it's still running, just sudo kill it and start Tomcat again to activate the new configuration

 

sudo service tomcat start

 

And now?

 

Congratulations!

ThingWorx is now running on your ThingBerry using a secure channel.

 

Access it via https://<thingberry>/Thingworx

As HTTPS is automatically using port 443, you will automatically connect to the port configured in the server.xml

 

Classic HTTP connections on port 80 can still be used.

 

For more information about setting up ThingWorx with (self-signed) certificates also see https://support.ptc.com/appserver/cs/view/solution.jsp?n=CS193947 - there's also a note on forwarding all HTTP traffic to HTTPS.

 

See also https://support.ptc.com/appserver/cs/view/solution.jsp?n=CS246292 for more information about using specific SSL protocols or cipher suites.