HTTPS Intermediate Certificates

Overview

This application note describes how to use TLS intermediate certificates with the Gecko OS embedded HTTPS server. This functionality requires Gecko OS v3.1+.

One evaluation board functions as a HTTPS server while another evaluation board functions as a HTTPS client.

Additionally, a web browser (e.g. Chrome, Safari, Internet Explorer, etc) is used to connect to the HTTPS server.

Procedure

The procedure follows these steps:

Prerequisite Reading

See the Secure TLS Client application note for an introduction to TLS certificates.

See the Secure HTTP Server application note for how to create a basic HTTPS server using Gecko OS.

Introduction

A TLS intermediate certificate is a cert that goes in between the Certificate Authority Cert and Server Cert/Client Cert. e.g.

The above relationships apply if the client and the server use the same certificate chain. See Different Client and Server Certificate Chains below for the procedure when this is not the case.

A TLS intermediate certificate makes the system more secure:

So if the Device is hacked, the hacker is not able to generate rogue certificates because they do not have the intermediate cert key.

In this App Note, only the Intermediate Cert has permissions to generate certificates (and of course the CA). The Server Cert and Client Cert do NOT have permissions to generate certificates.

The certs are used as follows:

Self-Signed Certificate Authority (CA)

This is the root certificate. All other certs can be traced back to this cert. For demo purposes, create a 'Self-Signed' CA cert. In practice a 3rd party is typically used, such as:

Notes :

Intermediate Certificate

This is the cert used to generate Device certificates - client and server. The CA cert 'signs' the Intermediate Cert. The Intermediate Cert also has signing permissions (i.e. it has permissions to generate more certificates)

Notes :

Server Certificate

This is the cert used by the Gecko OS HTTPS server. The Intermediate Cert 'signs' the Server Cert. The Server Cert does NOT have signing permissions (i.e. it is not allowed to generate more certificates).

Notes :

The Gecko OS Device running the HTTPS server requires two files:

Client Certificate

This is the cert used by the Gecko OS HTTPS client. The Intermediate Cert 'signs' the Client Cert. The Client Cert does NOT have signing permissions (i.e. it is not allowed to generate more certificates).

Notes :

The Gecko OS Device running the HTTPS client requires three files:

Note : If the HTTPS server does NOT have client verification enabled (e.g http.server.verify_peer = 0) then certs 2 & 3 are not needed.

Certificate Generation

This section describes how to generate the certificates described above.

Note : For demo purposes create the certs in home directory. In practice the certs should be create in a secure environment. Ideally the certs should be generated on a computer with NO internet access.

OpenSSL

For the following steps in which certificates are generated, it is assumed you have OpenSSL installed on your computer and OpenSSL is in the PATH environment variable i.e. you can execute OpenSSL directly from a command line.

OpenSSL may be downloaded here: https://wiki.openssl.org/index.php/Binaries or on Ubuntu, run the command:

$ sudo apt-get install openssl 

The manual for OpenSSL may be found here: https://www.openssl.org/docs/

Generating a Self-Signed CA Certificate

The first certificate to generate is a self-signed Certificate Authority (CA) certificate. This is the root certificate from which all other certificates are derived.

Prepare the Directory

Choose a directory, e.g. ~/https_example/ca to store all keys and certificates.

$ mkdir -p ~/https_example/ca

Create the directory structure. The index.txt and serial files act as a flat file database to keep track of signed certificates.

$ cd ~/https_example/ca
$ mkdir certs newcerts private
$ touch index.txt
$ echo 1000 > serial

Prepare the OpenSSL Configuration File

Create a configuration file for OpenSSL to use. Copy the root CA configuration file to ~/https_example/ca/openssl.cnf .

The [ ca ] section is mandatory. The following configuration tells OpenSSL to use the options from the [ CA_default ] section:

[ ca ]
# `man ca`
default_ca = CA_default

The [ CA_default ] section contains a range of defaults. Make sure you declare the directory you chose earlier, e.g. ~/https_example/ca .

[ CA_default ]
# Directory and file locations.
dir               = ~/https_example/ca
certs             = $dir/certs
new_certs_dir     = $dir/newcerts
database          = $dir/index.txt
serial            = $dir/serial
RANDFILE          = $dir/private/.rand

# The root key and root certificate.
private_key       = $dir/private/ca.key
certificate       = $dir/certs/ca.crt

# SHA-1 is deprecated, so use SHA-2 instead.
default_md        = sha256

name_opt          = ca_default
cert_opt          = ca_default
default_days      = 375
preserve          = no
policy            = policy_strict

Apply policy_strict for all root CA signatures, as the root CA is only being used to create intermediate CAs.

[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

Apply policy_loose for all intermediate CA signatures, as the intermediate CA is signing server and client certificates that may come from a variety of third-parties.

[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

Options from the [ req ] section are applied when creating certificates or certificate signing requests.

[ req ]
# Options for the `req` tool (`man req`).
default_bits        = 2048
distinguished_name  = req_distinguished_name
string_mask         = utf8only

# SHA-1 is deprecated, so use SHA-2 instead.
default_md          = sha256

# Extension to add when the -x509 option is used.
x509_extensions     = v3_ca

The [ req_distinguished_name ] section declares the information normally required in a certificate signing request. You can optionally specify some defaults.

[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name
localityName                    = Locality Name
0.organizationName              = Organization Name
organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name
emailAddress                    = Email Address

# Optionally, specify some defaults.
countryName_default             = GB
stateOrProvinceName_default     = England
localityName_default            =
0.organizationName_default      = Alice Ltd
#organizationalUnitName_default =
#emailAddress_default           =

The next few sections are extensions that can be applied when signing certificates. For example, passing the -extensions v3_ca command-line argument applies the options set in [ v3_ca ] .

Apply the v3_ca extension when creating the root certificate.

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

Apply the v3_ca_intermediate extension when creating the intermediate certificate. pathlen:0 ensures that there can be no further certificate authorities below the intermediate CA.

[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

Apply the usr_cert extension when signing client certificates, such as those used for remote user authentication.

[ usr_cert ]
# Extensions for client certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection

Apply the server_cert extension when signing server certificates, such as those used for web servers.

[ server_cert ]
# Extensions for server certificates (`man x509v3_config`).
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

Create the Root CA Certificate Key

Create the root CA key ( ca.key ). This is the most sensitive file in your secure TLS system. Anyone in possession of the root key can issue trusted certificates. This key should be kept in a secure location. Encrypt the root key with AES 256-bit encryption and a strong password.

Note : Use 4096 bits for all root and intermediate certificate authority keys. You’ll still be able to sign server and client certificates of a shorter length.

$ cd ~/https_example/ca
$ openssl ecparam -out private/ca.key -name prime256v1 -genkey

   Enter pass phrase for ca.key.pem: secretpassword
   Verifying - Enter pass phrase for ca.key.pem: secretpassword

After executing this command OpenSSL prompts for a password to secure the CA key, enter a password (and a confirmation password). This is the same password used for the rest of the process.

Create the Root CA Certificate

Next, create the self-signed CA cert using the ca.key . Give the root certificate a long expiry date, such as twenty years. Once the root certificate expires, all certificates signed by the CA become invalid.

$ cd ~/https_example/ca
$ openssl req -config openssl.cnf \
      -key private/ca.key \
      -new -x509 -days 7300 -sha256 -extensions v3_ca \
      -out certs/ca.crt

OpenSSL prompts for various values. Press Enter to accept a default value. At the Common Name prompt, you can enter any name, for example: 'My Root CA'. Here is an example of what to expect (note the Common Name value):

$  openssl req -config openssl.cnf -key private/ca.key -new -x509 -days 7300 -sha256 -extensions v3_ca -out certs/ca.crt
   Enter pass phrase for ca.key: secretpassword
   You are about to be asked to enter information that will be incorporated
   into your certificate request.
   What you are about to enter is what is called a Distinguished Name or a DN.
   There are quite a few fields but you can leave some blank
   For some fields there will be a default value,
   If you enter '.', the field will be left blank.

   ----
   Country Name (2 letter code) [AU]:
   State or Province Name (full name) [Some-State]:
   Locality Name (eg, city) []:
   Organization Name (eg, company) [Internet Widgits Pty Ltd]:
   Organizational Unit Name (eg, section) []:
   Common Name (e.g. server FQDN or YOUR name) []: My Root CA      <-- Common Name
   Email Address []:

Verify the Root Certificate

$ openssl x509 -noout -text -in certs/ca.crt

The output shows:

The Issuer and Subject are identical as the certificate is self-signed. Note that all root certificates are self-signed.

Signature Algorithm: sha256WithRSAEncryption
    Issuer: C=GB, ST=England,
            O=Alice Ltd, OU=Alice Ltd Certificate Authority,
            CN=My Root CA
    Validity
        Not Before: Apr 11 12:22:58 2015 GMT
        Not After : Apr  6 12:22:58 2035 GMT
    Subject: C=GB, ST=England,
             O=Alice Ltd, OU=Alice Ltd Certificate Authority,
             CN=Alice Ltd Root CA
    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
            Public-Key: (4096 bit)

The output also shows the X509v3 extensions. The v3_ca extension is configured, so the options from [ v3_ca ] should be reflected in the output.

X509v3 extensions:
    X509v3 Subject Key Identifier:
        38:58:29:2F:6B:57:79:4F:39:FD:32:35:60:74:92:60:6E:E8:2A:31
    X509v3 Authority Key Identifier:
        keyid:38:58:29:2F:6B:57:79:4F:39:FD:32:35:60:74:92:60:6E:E8:2A:31

    X509v3 Basic Constraints: critical
        CA:TRUE
    X509v3 Key Usage: critical
        Digital Signature, Certificate Sign, CRL Sign

Generating an Intermediate Certificate

Next generate the Intermediate Certificate. An intermediate certificate authority (CA) is an entity that can sign certificates on behalf of the root CA. The root CA signs the intermediate certificate, forming a chain of trust.

This is the certificate which is used to generate all other certificate the go on the Gecko OS devices.

Prepare the directory

The root CA files are kept in ~/https_example/ca . Choose a different directory ( ~/https_example/ca/intermediate ) to store the intermediate CA files.

$ mkdir ~/https_example/ca/intermediate

Create the same directory structure used for the root CA files. It’s convenient to also create a csr directory to hold certificate signing requests.

$ cd ~/https_example/ca/intermediate
$ mkdir certs csr newcerts private
$ touch index.txt
$ echo 1000 > serial

Copy the intermediate CA configuration file to ~/https_example/ca/intermediate/openssl.cnf . Five options have been changed compared to the root CA configuration file:

[ CA_default ]
dir             = ~/https_example/ca/intermediate
private_key     = $dir/private/intermediate.key
certificate     = $dir/certs/intermediate.crt
policy          = policy_loose

Create the Intermediate Key

Create the intermediate key ( intermediate.key ). Encrypt the intermediate key with AES 256-bit encryption and a strong password.

$ cd ~/https_example/ca
$ openssl ecparam -out intermediate/private/intermediate.key -name prime256v1 -genkey

Enter pass phrase for intermediate.key.pem: secretpassword
Verifying - Enter pass phrase for intermediate.key.pem: secretpassword

Create the Intermediate Certificate

Use the intermediate key to create a certificate signing request (CSR). The details should generally match the root CA. The Common Name, however, must be different.

Note : Make sure you specify the intermediate CA configuration file ( intermediate/openssl.cnf ).

$ cd ~/https_example/ca
$ openssl req -config intermediate/openssl.cnf -new -sha256 \
      -key intermediate/private/intermediate.key \
      -out intermediate/csr/intermediate.csr

  Enter pass phrase for intermediate.key.pem: secretpassword
  You are about to be asked to enter information that will be incorporated
  into your certificate request.
  -----
  Country Name (2 letter code) [XX]:GB
  State or Province Name []:England
  Locality Name []:
  Organization Name []:Alice Ltd
  Organizational Unit Name []:Alice Ltd Certificate Authority
  Common Name []:My Intermediate CA
  Email Address []:

To create an intermediate certificate, use the root CA with the v3_intermediate_ca extension to sign the intermediate CSR. The intermediate certificate should be valid for a shorter period than the root certificate. Ten years would be reasonable.

Note : This time, specify the root CA configuration file ( ~/https_example/ca/openssl.cnf ).

$ cd ~/https_example/ca
$ openssl ca -config openssl.cnf -extensions v3_intermediate_ca \
      -days 3650 -notext -md sha256 \
      -in intermediate/csr/intermediate.csr \
      -out intermediate/certs/intermediate.crt

Enter pass phrase for ca.key: secretpassword
Sign the certificate? [y/n]: y

1 out of 1 certificate requests certified, commit? [y/n] y
Write out database with 1 new entries
Data Base Updated

The index.txt file is where the OpenSSL ca tool stores the certificate database. Do not delete or edit this file by hand. It should now contain a line that refers to the intermediate certificate.

V 250408122707Z 1000 unknown ... /CN=My Intermediate CA

Verify the Intermediate Certificate

As for the root certificate, check that the details of the intermediate certificate are correct.

$ openssl x509 -noout -text -in intermediate/certs/intermediate.crt

Verify the intermediate certificate against the root certificate. An OK indicates that the chain of trust is intact.

$ openssl verify -CAfile certs/ca.crt intermediate/certs/intermediate.crt

  intermediate/certs/intermediate.crt: OK

Create the Certificate Chain File

When an application (eg, a web browser) tries to verify a certificate signed by the intermediate CA, it must also verify the intermediate certificate against the root certificate. To complete the chain of trust, create a CA certificate chain to present to the application.

To create the CA certificate chain, concatenate the intermediate and root certificates together.

This file is used later to verify certificates signed by the intermediate CA.

$ cat intermediate/certs/intermediate.crt certs/ca.crt > intermediate/certs/ca-chain.crt

Generating a Server Certificate

The intermediate CA certificate is generated. Now generate a TLS server certificate. This TLS cert is used by the Gecko OS HTTPS server.

To generate the server certificate, the host name of our server is required. The host name is the URL entered into a web browser (e.g https://mydevice.com ). Gecko OS has several options for host names.

Is Gecko OS connecting to a network or is it creating the network? i.e will the Gecko OS 'wlan' or 'softap' interface be used?

If the 'WLAN' interface is used, there are two host name options:

If the 'SoftAP' interface is used, there are three host name options:

The following examples uses the SoftAP interface and mDNS. The host name is: mydevice.com .

When generating the server certificate, it is CRITICAL the host name is used since the web browser verifies the name. If the server certificate is generated with the host name: mydevice.com , the only valid URL is: https://mydevice.com . If any other domain is used the web browser displays a warning indicating the certificate is not valid.

Note : At every point where mydevice.com appears in the procedure below, you should substitute the host name you have chosen for the device.

Note : The steps below are from your perspective as the certificate authority. A third-party, however, can instead create their own private key and certificate signing request (CSR) without revealing their private key to you. They give you their CSR, and you give back a signed certificate. In that scenario, skip the genrsa and req commands.

Create a Server Key

Our root and intermediate pairs are 4096 bits. Server and client certificates normally expire after one year, so 1024 bits can be safely used.

Note : Although 4096 bits is slightly more secure than 1024 bits, it slows down TLS handshakes and significantly increases processor load during handshakes.

For this reason, most websites use 1024-bit pairs.

$ cd ~/https_example/ca
$ openssl ecparam -out intermediate/private/mydevice.com.key -name prime256v1 -genkey

Create a Server Certificate

Use the private key to create a server certificate signing request (CSR). The CSR details don’t need to match the intermediate CA. For server certificates, the Common Name MUST be a fully qualified domain name of the Device HTTP server (e.g. mydeivce.local).

$ cd ~/https_example/ca
$ openssl req -config intermediate/openssl.cnf \
      -key intermediate/private/mydevice.com.key \
      -new -sha256 -out intermediate/csr/mydevice.com.csr

  You are about to be asked to enter information that will be incorporated
  into your certificate request.
  -----
  Country Name (2 letter code) [XX]:US
  State or Province Name []:California
  Locality Name []:Mountain View
  Organization Name []:Alice Ltd
  Organizational Unit Name []:Alice Ltd Web Services
  Common Name []:mydevice.com
  Email Address []:

To create a certificate, use the intermediate CA to sign the CSR. The certificate is going to be used on a server, so use the server_cert extension. Certificates are usually given a validity of one year.

$ cd ~/https_example/ca
$ openssl ca -config intermediate/openssl.cnf \
      -extensions server_cert -days 375 -notext -md sha256 \
      -in intermediate/csr/mydevice.com.csr \
      -out intermediate/certs/mydevice.com.crt

The intermediate/index.txt file should contain a line referring to this new certificate.

V 160420124233Z 1000 unknown ... /CN=mydevice.com

Verify the Server Certificate

$ openssl x509 -noout -text -in intermediate/certs/mydevice.com.crt

The Issuer is the intermediate CA. The Subject refers to the certificate itself.

Signature Algorithm: sha256WithRSAEncryption
    Issuer: C=GB, ST=England,
            O=Alice Ltd, OU=Alice Ltd Certificate Authority,
            CN=My Intermediate CA
    Validity
        Not Before: Apr 11 12:42:33 2015 GMT
        Not After : Apr 20 12:42:33 2016 GMT
    Subject: C=US, ST=California, L=Mountain View,
             O=Alice Ltd, OU=Alice Ltd Web Services,
             CN=mydevice.com
    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
            Public-Key: (1024 bit)

The output shows the X509v3 extensions as well as server_cert extension.

X509v3 extensions:
    X509v3 Basic Constraints:
        CA:FALSE
    Netscape Cert Type:
        SSL Server
    Netscape Comment:
        OpenSSL Generated Server Certificate
    X509v3 Subject Key Identifier:
        B1:B8:88:48:64:B7:45:52:21:CC:35:37:9E:24:50:EE:AD:58:02:B5
    X509v3 Authority Key Identifier:
        keyid:69:E8:EC:54:7F:25:23:60:E5:B6:E7:72:61:F1:D4:B9:21:D4:45:E9
        DirName:/C=GB/ST=England/O=Alice Ltd/OU=My Certificate Authority/CN=My Root CA
        serial:10:00

    X509v3 Key Usage: critical
        Digital Signature, Key Encipherment
    X509v3 Extended Key Usage:
        TLS Web Server Authentication

Use the CA certificate chain file created earlier ( ca-chain.crt ) to verify that the new certificate has a valid chain of trust.

$ openssl verify -CAfile intermediate/certs/ca-chain.crt intermediate/certs/mydevice.com.crt

  intermediate/certs/mydevice.com.crt: OK

Create the Server Certificate Chain File

When an application (eg, a web browser or another Device) tries to verify a certificate signed by the intermediate CA, it must also verify the intermediate certificate against the root certificate. To complete the chain of trust, create a CA certificate chain to present to the application/Device.

To create the CA certificate chain, concatenate the server, intermediate, and root certificates together. This is the file to load onto the Gecko OS device.

$ cat intermediate/certs/mydevice.com.crt intermediate/certs/intermediate.crt certs/ca.crt > intermediate/certs/mydevice.com-chain.crt

Generating Client Certificates

If you don't want to use client authentication, you can skip to the next section.

The Server Certificate is used for the client to verify the server (e.g. to ensure there is no man-in-the-middle). Reciprocally, the Server can verify the client using Client Certificates.

For the Server Certificate, mydevice.com was the certificate's Common Name.

For a client certificate, the user's email address is used. Note that the common name may be any string, such as the device UUID.

Create a Client Key

$ cd ~/https_example/ca
$ openssl ecparam -out intermediate/private/name@email.com.key -name prime256v1 -genkey

Create a Client Certificate

Use the private key to create a client certificate signing request (CSR). The CSR details don’t need to match the intermediate CA or Server Certificate. For client certificates, the Common Name should be something that identifies the user or Device, like an email or UUID.

$ cd ~/https_example/ca
$ openssl req -config intermediate/openssl.cnf \
      -key intermediate/private/name@email.com.key \
      -new -sha256 -out intermediate/csr/name@email.com.csr

  You are about to be asked to enter information that will be incorporated
  into your certificate request.
  -----
  Country Name (2 letter code) [XX]:US
  State or Province Name []:California
  Locality Name []:Mountain View
  Organization Name []:Alice Ltd
  Organizational Unit Name []:Alice Ltd Web Services
  Common Name []:name@email.com
  Email Address []:

To create a certificate, use the intermediate CA to sign the CSR. The certificate is going to be used on a client, so use the usr_cert extension. Certificates are usually given a validity of one year.

$ cd ~/https_example/ca
$ openssl ca -config intermediate/openssl.cnf \
      -extensions usr_cert -days 375 -notext -md sha256 \
      -in intermediate/csr/name@email.com.csr \
      -out intermediate/certs/name@email.com.crt

The intermediate/index.txt file should contain a line referring to this new certificate.

V 160420124233Z 1000 unknown ... /CN=name@email.com

Verify the Client Certificate

$ openssl x509 -noout -text -in intermediate/certs/name@email.com.crt

The Issuer is the intermediate CA. The Subject refers to the certificate itself.

Use the CA certificate chain file created earlier ( ca-chain.crt ) to verify that the new certificate has a valid chain of trust.

$ openssl verify -CAfile intermediate/certs/ca-chain.crt intermediate/certs/name@email.com.crt

  intermediate/certs/mydevice.com.crt: OK

Create a .p12 for Client Certificate

A .p12 file allows for installing the client certificate into a web browser.

If the client certificate is used only on another Gecko OS device, skip this step.

$ openssl pkcs12 -export -clcerts -in intermediate/certs/name@email.com.crt  \
           -inkey intermediate/private/name@email.com.key \
           -out intermediate/certs/name@email.com.p12

Simply press enter when prompted for an 'Export Password' (twice). This makes the .p12 file non-password protected.

Running the HTTPS Server

Once the certificates are generated, the next step is to configure and run a secure HTTP server.

A Gecko OS enabled Device is used.

Load the Server Cert/Key onto the Device

First load the following files on the Device:

~/http_example/ca/intermediate/certs/mydevice.com-chain.crt
~/http_example/ca/intermediate/private/mydevice.com.key

To load the cert/key onto the client Device, see File System, Writing Files

Configure Device as HTTPS server

Now configure the server device for:

Issue the following commands to the server Device:

Command Description
set softap.auto_start 1 set softap.dns_server.url mydevice.com set softap.ssid mydevice set http.server.interface softap set http.server.enabled 1 set http.server.port 443 set http.server.tls_enabled 1 set http.server.tls_cert mydevice.com-chain.crt set http.server.tls_key mydevice.com.key set http.server.max_clients 1 save reboot - - - - <- Enable the HTTP server <- Standard secure HTTP port <- Enable secure (TLS) HTTP server <- Set the server certificate chain <- Set the server certificate key <- (optional) A TLS connection may use a lot of memory. This variable ensures only one connection is opened

That's it! When the Device reboots, it starts a SoftAP network with the name: mydevice . On the SoftAP interface the HTTPS server automatically starts.

Connect to the HTTPS Server via Web Browser

Connect you computer to the Device's SoftAP network. The network Wi-Fi name is: mydevice

Once connected, open a web browser and enter the URL: https://mydevice.com

At this point, your web browser is likely to display a security warning message. That's good!

Recall that the mydevice.com.crt server certificate was signed by the self-signed CA certificate? Your browser doesn't know about the self-signed CA certificate (yet), as a result, it is unable to authenticate the mydevice.com.crt certificate.

To fix this, find and double-click on the ~/http_example/ca/certs/ca.crt file . This should display a dialog providing information about the certificate. There should also be a button that says something like 'Install Certificate'. Click the 'Install Certificate' button and follow the dialogs to install the certificate. Make sure the cert is installed in the 'Trusted Root Certification Authorities' Certificate Store.

Once installed, you may need to restart your browser for the new ca.crt cert to be recognized as a valid certificate authority. Once recognized, the browser should not display a security warning when browsing to the device at the URL: https://mydevice.com

If everything is working, you are now viewing secure encrypted HTTP pages served from the Gecko OS device.

Enable Client Authentication

Currently, only the client is authenticating the server. Any client can connect to the server.

For added security, enable client authentication using the client certificates generated earlier.

To enable client authentication, issue the following commands to the HTTP server Device:

Command Description
set http.server.tls_verify_peer 1 save network_restart -i softap <- Enable client (i.e. peer) authentication <- Save the new settings <- Restart the network to for the setting to take effect

Open your web browser and enter the URL: https://mydevice.com

The browser displays nothing. This is because the browser is not configured to supply a valid TLS certificate.

Fix this by installing the .p12 certificate generated previously.

To install the certificate, double-click the file

~/http_example/intermediate/certs.name@email.com.p12

on your computer file system.

This should bring up a dialog. Follow the dialog to install the cert into your system (the client certificate does not need to go into the Trusted Cert Authority). Again, you may need to restart your browser for the changes to take effect.

After the .p12 certificate is installed, open your web browser and enter the URL: https://mydevice.com

This time you are prompted for certificate information. Select the newly installed name@email.com certificate.

You should once again see the Gecko OS webapp. This time bi-directional client AND server authentication is used. Your browser authenticates the Gecko OS HTTPS server and the Gecko OS HTTPS server authenticates your browser.

Running the HTTPS Client

Now that the Gecko OS HTTPS server is running, let's configure another Gecko OS-enabled Device to securely download a webpage.

Load the Client Cert/Key and CA Cert onto the Client Device

First load the following files on the client Device:

~/http_example/ca/intermediate/certs/name@email.com.crt
~/http_example/ca/intermediate/private/name@email.com.key
~/http_example/ca/certs/ca.crt

To load the cert/key onto the client Device, see File System, Writing Files

Configure Device as HTTPS client

Now configure the device to:

Issue the following commands to the client Device:


set wlan.ssid                mydevice
set network.tls.ca_cert      ca.crt
set network.tls.client_cert  name@email.com.crt
set network.tls.client_key   name@email.com.key
save
reboot

Now that the client Device is configured to connect to the server's network with client certificates, read a file as a test.

Retrieve the webapp/index.html file from the server via HTTP GET:

> http_get https://mydevice.com/webapp/index.html
[Opening: https://mydevice.com/webapp/index.html]
Request GET /webapp/index.html
Connecting (https): mydevice.com:443
Starting TLS
[Opened: 0]
Status: 200

Once the HTTP stream is open, read the webpage data with the read command:

read 0 1024

That's it! The client device has securely connected to the server device and retrieved a file via HTTP get.

This process used bi-directional TLS certificate authentication.

Both the server and client certificates were signed with an intermediate certificate.

Running a TLS Server and Client

The process works for a HTTP server/client also works raw TLS client/server connection.

First factory reset each of the server and client devices to a known state. See Update and Recovery, Factory Reset .

To do this by command, issue get wlan.mac to obtain the device MAC address, then issue the factory_reset command with the returned MAC address as its argument:

factory_reset <MAC address>

Now issue the following commands to the server device:

set bus.mode                     stream
set softap.auto_start            1
set softap.dns_server.url        mydevice.com
set softap.ssid                  mydevice
set tcp.server.auto_interface    softap
set tcp.server.auto_start        1
set tcp.server.port              2000
set tcp.server.max_clients       1
set tcp.server.tls_enabled       1
set tcp.server.tls_cert          mydevice.com-chain.crt
set tcp.server.tls_key           mydevice.com.key
set tcp.server.tls_verify_peer   1
save
reboot

When the server device reboots, the SoftAP and TLS server automatically start. Additionally, the device is in stream mode so anything entered on the UART is sent to the remote connection (if available). Anything from the remote connection is immediately sent to the UART.

Issue the following commands to the client device:

set bus.mode                     stream
set wlan.ssid                    mydevice
set wlan.auto_join.enabled       1
set tcp.client.auto_start        1
set tcp.client.remote_host       mydevice.com
set tcp.client.remote_port       2000
set tcp.client.tls_enabled       1
set network.tls.ca_cert          ca.crt
set network.tls.client_cert      name@email.com.crt
set network.tls.client_key       name@email.com.key
save
reboot

When the client device reboots, it automatically connects to the TLS server. Additionally, the device is in stream mode so anything entered on the UART is sent to the remote connection (if available). Anything from the remote connection is immediately sent to the UART.

Different Client and Server Certificate Chains

In typical setups, there are separate certificate chains for the server and client.

The http.server.tls_peer_cert and tcp.server.tls_peer_cert variables allow for specifying a client certificate chain different to the server certificate chain. The following demonstrates how this works.

Creating a Separate Client Certificate Chain

To modify the above procedure for this case, repeat the steps in Certificate Generation above to create a different set of self-certified certificates and keys for the client.

Use the same self-certified root certificate for the client chain as was used for the server chain. Do not repeat the steps Generating a Self-Signed CA Certificate and Create the Root CA Certificate .

Create different client files in the Generating an Intermediate Certificate step, as follows:

Create a separate intermediate_client directory:

$ mkdir ~/https_example/ca/intermediate_client

Copy the intermediate CA configuration file to ~/https_example/ca/intermediate_client/openssl.cnf .

Follow the remaining steps to generate an intermediate certificate, substituting the directory intermediate_client for the directory intermediate .

Skip the Generating a Server Certificate step.

Follow the Generating Client Certificates step, substituting the directory intermediate_client for the directory intermediate .

Create the Client Certificate Chain File

The HTTPS server must verify the intermediate certificate against the root certificate. To complete the chain of trust, create a CA certificate chain to present to the HTTP Server.

To create the CA certificate chain, concatenate the server, intermediate, and root certificates together. This is the file to load onto the HTTPS Server Gecko OS device.

$ cat intermediate_client/certs/name@email.com.crt intermediate_client/certs/intermediate.crt certs/ca.crt > intermediate_client/certs/name@email.com-chain.crt

Configuring the Server and Client with the Client Certificate Chain

The client certificates are now created, following a different certification chain to the server certificates.

In the Running the HTTPS Server, Enable Client Authentication step, the steps are changed as follows:

In addition to the server certificates, load onto the server device the file:

~/http_example/ca/intermediate_client/certs/name@email.com-chain.crt

The commands are changed as follows:

Command Description
set http.server.tls_verify_peer 1 set http.server.tls_peer_cert name@email.com-chain.crt save network_restart -i softap <- Enable client (i.e. peer) authentication <- Specify the client certification chain <- Save the new settings <- Restart the network to for the setting to take effect

In the Running the HTTPS Client step, load the following files on to the client device:

~/http_example/ca/intermediate_client/certs/name@email.com.crt
~/http_example/ca/intermediate_client/private/name@email.com.key
~/http_example/ca/certs/ca.crt

Follow the Configure Device as HTTPS Client as above with no change.

Further Reading

The following website provides information on cert generation:

https://jamielinux.com/docs/openssl-certificate-authority/index.html

Supporting Gecko OS Versions

Change Log

Modified Changes
2019-01-01 Created
2019-11-14 Added http.server.tls_peer_cert and tcp.server.tls_peer_cert demonstration.