As explained in OpenSSL: Apache Setup, Generating CSR, Zymkey can participate in the handshake of a mutual authentication (i.e. client side certificate) TLS session. Security is enhanced since the private keys that are used for signing the TLS handshake are contained in the Zymkey and are never exposed to the host.
stunnel is a package which allows a socket based application to transparently send and receive data across an encrypted tunnel. This way, an application writer can write an app which securely sends and receives data between another endpoint (e.g. a server or another Raspberry Pi) without having to know too much about cryptography.
In this example, I’ll show you how to configure
stunnel for use with a Raspberry Pi host to make an encrypted chat session using
If you have not done so already, install your Zymkey onto your Raspberry Pi per the Getting Started guide.
After installing your Zymkey, install the
sudo apt-get install stunnel
Note: if you’re running Ubuntu 16.04, you may need to build stunnel yourself because (as of this writing) the version in the apt repo is too old to accept the
requireCert parameter in the server configuration file. More on this later in step 8.
We are going to assume that your server environment runs Linux. There are several ways to do this:
- A PC running native Linux
- A PC running Windows with Linux running as guest on Virtualbox
- Another Raspberry Pi
We won’t go into how to install Linux on a PC natively or in a virtual machine. Just make sure that
stunnel is installed on the server machine as well.
Here, we will set up our own CA rather than send the Certificate Signing Request (CSR) that we’ll be generating from the Host Raspberry Pi to a known CA like Symantec or GoDaddy. For simplicity, we will assume that the server that you configured in Step 3 is also your CA.
On the server, create a directory for the CA and change directory:
mkdir -p ~/stunnel_demo/myCA
Next, generate the CA ECDSA key pair:
openssl ecparam -name prime256v1 -genkey -noout -out ca.key
Now generate the CA certificate:
openssl req -x509 -new -SHA256 -nodes -key ca.key -days 3650 -out ca.crt -subj "/C=US/ST=California/L=Santa Barbara/O=Zymkey/CN=zymkey-verify.zymbit.com.dev"
On the server, create a directory for the server certificate:
mkdir -p ~/stunnel_demo/myServer
Next, generate the server ECDSA key pair:
openssl ecparam -name prime256v1 -genkey -noout -out myServer.key
Generate a server CSR:
openssl req -new -sha256 -key myServer.key -out myServer.csr -subj "/C=US/ST=California/L=Santa Barbara/O=Zymkey/CN=zymkey-server.zymbit.com.dev"
Generate the server certificate:
openssl x509 -req -in myServer.csr -CA ~/stunnel_demo/myCA/ca.crt -CAkey ~/stunnel_demo/myCA/ca.key -CAcreateserial -days 3650 -out myServer.crt
On the Host Raspberry Pi, create the CSR using a public key on the Zymkey. We’ll be using one of Zymkey’s public keys via the Zymkey OpenSSL engine. Because OpenSSL expects a private key, we’ll be “faking out” the private key file with an empty file called
mkdir -p ~/stunnel_demo/myClient
openssl req -key bogus.key -new -out myClientCert.csr -engine zymkey_ssl -keyform e -subj "/C=US/ST=California/L=Santa Barbara/O=Zymkey/CN=zymkey-client.zymbit.com.dev"
As you can see in the last command, we’re telling OpenSSL to use a hardware engine called
zymkey_ssl and that the key format is an engine with
Next, we’ll copy
myClientCert.csr to the server with
scp myClientCert.csr <server username>@<server hostname>:/home/<server username>/stunnel_demo/myCA
Be sure to substitute
<server username> and
<server hostname> with your username on the server as well as the server’s hostname or ip address.
On the server/CA machine, cd to the myCA directory and tell OpenSSL to generate a certificate from the client CSR:
openssl x509 -req -in myClientCert.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out myClientCert.crt
Now copy the client certificate back to the client:
scp myClientCert.crt pi@raspberrypi:/home/pi/stunnel_demo/myClient
On the server/CA machine, create a file in the ~/stunnel_demo/myServer directory called nc_stunnel_server.conf:
debug = 7 output = /tmp/stunnel.log client = no cert = myServer.crt key = myServer.key [netcat_server] accept = 4444 connect = 7777 requireCert = yes CAfile = ../myCA/myClientCert.crt
stunnel is started on the server machine, it will look for connections from
stunnel on the client side at port 4444 and will connect to port 7777 from the application, in this case
netcat. We’ve also configured the server side
stunnel to require the client to provide a certificate.
As mentioned previously, if you get an error when trying to start
stunnel on the server related to
requireCert=yes, you can do one of two things:
- Remove the
- Build stunnel on the server yourself from version 5.24 or later.
Next, create a file called nc_stunnel_client.conf on the Raspberry Pi client:
debug = 7 output = /tmp/stunnel.log client = yes engine = zymkey_ssl engineDefault = EC [netcat_client] cert = myClientCert.crt engineId = zymkey_ssl connect = <server ip addr>:4444 accept = 5555
Here, we’ve configured
stunnel on the client side to use a hardware engine plugin called
zymkey_ssl that will be used for
EC or Elliptical Curve cryptography. Be sure to change to the ip address of your server.
sudo stunnel nc_stunnel_server.conf
nc -lv 7777
sudo stunnel nc_stunnel_client.conf
nc localhost 5555
You should now be able to type characters on the server and see it show up client window after the Enter key is pressed and vice-versa.