Skip to content

Keys and certificates

Many different keys and certificates are used by all of Fobnail's components. Most of them are automatically generated, but some must be provided by user.

List of keys and certificates used

Refer to architecture doc for description of actors and phases listed below. List items have the following format:

  • Name of key or certificate
    • Phase during which it is obtained, received or used
    • Other details, if any

Note that this list includes possible usages that may not be implemented yet.

Platform Owner

Knows in advance

  • Platform Owner key (signing and encryption)
    • Fobnail and remote platform provisioning
    • used for TLS and for signing certificates
  • Platform Owner certificate
    • Fobnail and remote platform provisioning
    • has to be able to provide whole CA chain
    • both Fobnail Token and Platform must trust root CA in this chain
  • root CA certificate for EK certificate chain
    • remote platform provisioning

Receives

  • Fobnail Identity key
    • Fobnail provisioning
  • Fobnail Encryption key
    • Fobnail provisioning
  • EK certificate
    • remote platform provisioning
  • AIK
    • remote platform provisioning

Produces

  • Fobnail Identity certificate
    • Fobnail provisioning
  • Fobnail Encryption certificate
    • Fobnail provisioning
  • AIK certificate
    • remote platform provisioning
    • simple signature instead of certificate may be sufficient

Fobnail Token

Knows in advance

  • root CA certificate for EK certificate chain
    • local platform provisioning
  • root CA for Platform Owner certificate chain
    • Fobnail provisioning

Receives

  • Platform Owner certificate chain
    • Fobnail provisioning
    • saved in flash, used in local platform provisioning and attestation
  • Fobnail Identity certificate
    • Fobnail provisioning
    • signed by Platform Owner
  • Fobnail Encryption certificate
    • Fobnail provisioning
    • signed by Platform Owner
  • EK certificate
    • local platform provisioning
  • AIK
    • local platform provisioning
    • remote platform provisioning - signed by Platform Owner
    • stored in flash and used during attestation

Produces

  • Fobnail Identity key (signing and encryption)
    • Fobnail provisioning
    • key and certificate signed by Platform Owner is stored for later use
  • Fobnail Encryption key (encryption)
    • Fobnail provisioning

Platform

Knows in advance

  • root CA for Platform Owner certificate chain
    • remote platform provisioning
    • local platform provisioning and attestation - Fobnail Identity key is signed by Platform Owner, so Platform needs a way of verifying trust chain
  • Endorsement Key (encryption)
    • remote and local platform provisioning
    • for this project may be considered immutable persistent key unique to TPM
  • EK certificate
    • EK is unique so is its certificate
    • usually saved in TPM NVRAM
    • signed by TPM manufacturer CA

Receives

  • Platform Owner certificate chain
    • remote platform provisioning - directly from Platform Owner
    • local platform provisioning and attestation - from Fobnail Token
    • used for identification, TLS and verifying Fobnail Identity certificate
  • Fobnail Identity certificate
    • local platform provisioning and attestation
    • used for identification and TLS

Produces

  • Attester Identity Key (signing)
    • local and remote platform provisioning
    • created by TPM
    • trusted based on Make/ActivateCredential and pairing with EK instead of certificate

Platform Owner certificate chain

Platform Owner trust chain uses X.509 certificates, usually in PEM format. It aims to be compatible with standard Public Key Infrastructure, as described in RFCs 5280 or 3647, among others. At least basic understanding of PKI is strongly suggested, but if you just want to quickly test Fobnail, you may just do steps in TL;DR section.

Platform Owner certificate is used during Fobnail provisioning. Its root CA certificate must be preinstalled on Fobnail Token. Due to limited hardware capabilities of Fobnail Token, following restrictions apply.

Validity checks

Informational checks

  • Maximum certificate chain length

    Maximal supported certificate chain consists of 3 CA certificates: root CA (flashed to Fobnail's memory), intermediate CA and final CA that is used to issue certificates for keys generated by Fobnail. Intermediate CA is optional, root and issuing CA aren't. During Fobnail provisioning, Platform Owner generates one additional certificate for Token, but this final certificate doesn't allow for use as a CA.

    This limit comes from hardware limitations (in terms of available memory) aggravated by chosen library (Trussed) and its limitations.

  • File format

    Certificates are concatenated to a single PEM file. Order of concatenation matters, certificates must be written starting with root CA certificate and moving through intermediate towards leaf certificate. All of them must be present, despite the fact that root CA is already known by Fobnail.

  • Certificate extensions

    Trust chain will be traversed based on X509v3 Authority Key Identifier extension which is compared against X509v3 Subject Key Identifier, so both of them must be included in every certificate (former should be skipped for root CA). X509v3 Basic Constraints is required for CA certificates. X509v3 Key Usage must specify that all certificates in Platform Owner chain are able to sign certificates.

Temporal checks

  • Validity period

Reference Fobnail Token (nRF52840 dongle) has no timekeeping capabilities. Because of that, validity period cannot be tested without adding another party that Fobnail Token trusts, or by using another dongle for Fobnail Token.

  • Certificate revocation

Fobnail Token doesn't have trusted network connection, so it can't access recent (i.e. one that happened after last firmware update) certificate revocation list at run time. Revocations can only be applied during flashing/update, which should be done by Platform Owner. During that process, attempt to use revoked certificates should result in failed provisioning.

Creating Platform Owner certificate chain with OpenSSL

This section describes how to create a certificate chain that conforms to restrictions mentioned earlier. This is just a minimal example showing all required configuration options and commands used in the process, fields listed here may be extended or modified, but should not be removed. Normally CAs do much more than what is presented here, some guidelines can be found in RFC 3647.

Note that root CA doesn't have to be under Platform Owner's control, but it must issue a certificate that is (either directly or through intermediate issuer). In such cases the issuer may use other form of certificate request or additional mechanisms of proving the identity of the requester than those used by OpenSSL.

Root CA

Root CA certificate is self-signed. This means that signed public and signing private keys belong to the same pair, and no exchange of data between separate entities happens. -x509 parameter tells that this is the case and a self-signed certificate is to be made, instead of CSR (Certificate Signing Request).

  • First create configuration file root_ca.cfg, for example:

    [ req ]
    distinguished_name     = req_distinguished_name
    prompt                 = no
    x509_extensions        = v3_ext
    
    [ req_distinguished_name ]
    C                      = PL
    O                      = Fobnail
    ST                     = State
    CN                     = Platform Owner root CA certificate
    
    [v3_ext]
    basicConstraints       = critical, CA:TRUE, pathlen:3
    keyUsage               = critical, keyCertSign, cRLSign
    subjectKeyIdentifier   = hash
    authorityKeyIdentifier = keyid:always
    

    Feel free to adjust configuration to your needs.

  • Run command:

    openssl req -newkey rsa:2048 -nodes -keyout root_ca_priv.pem -x509 -days 365 \
    -out root.crt -config root_ca.cfg
    
    • root_ca_priv.pem - newly created private root CA key. Keep it safe.
    • root.crt - root CA certificate. This will be hardcoded and marked as trusted by Fobnail Token.

Intermediate/PO issuing CA

Note: "PO issuing CA" in this part of the document should be understood as the CA that issues certificate requested by Fobnail Token. In general, each certificate has its own issuer. If that meaning of the word is required, "higher-level CA", "intermediate CA" or "root CA" is used.

These certificates aren't self-signed. Creation of such certificates consists of two steps: first one is generating a CSR (Certificate Signing Request) and is done by key creator, second one is creating the certificate itself - this is done by the parent CA. This separation is done to keep private keys secret at all times.

Steps for both intermediate and issuing CA certificates are mostly the same, the main difference is that CSR for intermediate is sent to root CA, and PO issuing CA's CSR is sent to intermediate CA. This chain can be longer in general, but Fobnail limits maximum length, as mentioned above. Intermediate CA is optional, PO issuing CA certificate can be signed by root CA directly.

Before issuing a certificate, issuer must check if subject is authorized to ask for it. It can't just blindly provide a new certificate to anyone that asks for it, because by creating a signed certificate CA tells others that it trusts its subject. Trust decision can be based on fields of CSR, challenge password, secure and non-public way of conveying CSR to issuer, or other means. Sometimes the decision is made by another entity called Registration Authority (RA) on behalf of CA.

In this case because subject of each signed certificate is itself a CA and can create certificates for other entities. Certificate revocation for Fobnail can't be done by means other than firmware updates, so issuing a certificate to untrustworthy subject impacts not only the security of devices provisioned by issuer, but also every device with the same root CA.

Generating intermediate CA key and CSR

This is similar to creating root CA with two small but important differences:

  • -x509 flag is not used in the command line
  • x509_extensions are not present (those are added by the issuer)

Command executed by intermediate CA:

openssl req -newkey rsa:2048 -nodes -keyout intermediate_priv_key.pem
-out intermediate.csr -config intermediate.cfg
  • intermediate_priv_key.pem (out) - newly created private intermediate CA key. Keep it safe.
  • intermediate.csr (out) - intermediate CA certificate signing request. This file is signed with private intermediate CA key by above command and must be passed to root CA.
  • intermediate.cfg (in) - configuration file, e.g.:
[ req ]
distinguished_name     = req_distinguished_name
prompt                 = no

[ req_distinguished_name ]
C                      = PL
O                      = Fobnail
ST                     = State
CN                     = Intermediate CA certificate

Generating intermediate CA certificate

openssl ca can also be used for this purpose, but openssl x509 is easier to use for single chain. On the other hand, openssl ca better suits the needs of CA after configuration and may do more checks in semi-automatic process than openssl x509.

Command executed by root CA:

openssl x509 -req -in intermediate.csr -CA root.crt -CAkey root_ca_priv.pem \
    -CAcreateserial -days 365 -extfile intermediate.ext -out intermediate.crt
  • intermediate.csr (in) - sent by intermediate CA.
  • root.crt and root_ca_priv.pem (in) - those were created by root CA earlier.
  • intermediate.crt (out) - intermediate CA certificate signed with root CA key root_ca_priv.pem.
  • intermediate.ext (in) - file describing certificate extensions, e.g.:
basicConstraints       = critical, CA:TRUE, pathlen:2
keyUsage               = critical, keyCertSign, cRLSign
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid:always

Generating PO issuer CA key and CSR

Command executed by PO issuer CA:

openssl req -newkey rsa:2048 -nodes -keyout root_ca_priv.pem -out issuer.csr \
-config issuer.cfg
  • root_ca_priv.pem (out) - newly created private PO issuing CA key. Keep it safe.
  • issuer.csr (out) - PO issuing CA certificate signing request. This file is signed with private PO issuing CA key by above command and must be passed to intermediate CA.
  • issuer.cfg (in) - configuration file, e.g.:
[ req ]
distinguished_name     = req_distinguished_name
prompt                 = no

[ req_distinguished_name ]
C                      = PL
O                      = Fobnail
ST                     = State
CN                     = Platform Owner issuer CA certificate

Generating PO issuer CA certificate

Command executed by intermediate CA:

openssl x509 -req -in issuer.csr -CA $AUTHORITY_CERT -CAkey $AUTHORITY_PRIV \
        -CAcreateserial -days 365 -extfile $SUBJECT_EXT -out $SUBJECT_CERT
  • issuer.csr (in) - sent by PO issuer CA.
  • intermediate_priv_key.pem (in) - created by intermediate CA earlier.
  • intermediate.crt (in) - issued by root CA in response to request from intermediate CA.
  • issuer.crt (out) - PO issuer CA certificate signed with intermediate_priv_key.pem.
  • issuer.ext (in) - file describing certificate extensions, e.g.:
basicConstraints       = critical, CA:TRUE, pathlen:1
keyUsage               = critical, keyCertSign, cRLSign
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid:always

Putting the chain together

PEM files contain certificates (among other objects that are not relevant here) encoded as text. They can be concatenated e.g. with cat to form a chain. As mentioned above, the order of certificates matters: leaf (i.e. PO issuing certificate) must come first, root CA - last. Assuming *.crt files are PEM certificates of various CAs, full chain is produced by:

cat root.crt intermediate.crt issuer.crt > cert_chain.pem

TL;DR version

While it is strongly suggested to understand and follow steps described above, these steps can be used to produce a chain that will be accepted by Fobnail. It can be used to quickly build and test Fobnail project, but such approach defies the idea of Fobnail provisioning and Platform Owner in general. It should not be used on Tokens for production environments.

  1. Create root CA key and certificate:

    openssl req -newkey rsa:2048 -nodes -keyout root_ca_priv.pem -x509
                -days 30 -out root_ca.crt -config <(cat << EOF
    
    [ req ]
    distinguished_name     = req_distinguished_name
    prompt                 = no
    x509_extensions        = v3_ext
    
    [ req_distinguished_name ]
    C                      = PL
    O                      = Fobnail
    ST                     = State
    CN                     = Platform Owner root CA certificate
    
    [v3_ext]
    basicConstraints       = critical, CA:TRUE, pathlen:2
    keyUsage               = critical, keyCertSign, cRLSign
    subjectKeyIdentifier   = hash
    authorityKeyIdentifier = keyid:always
    
    EOF
    )
    
  2. Create PO issuing CA private key and CSR:

    openssl req -newkey rsa:2048 -nodes -keyout po_priv_key.pem \
            -out issuer_ca.csr -config <(cat << EOF
    
    [ req ]
    distinguished_name     = req_distinguished_name
    prompt                 = no
    
    [ req_distinguished_name ]
    C                      = PL
    O                      = Fobnail
    ST                     = State
    CN                     = Platform Owner issuer CA certificate
    
    EOF
    )
    
  3. Create PO issuing CA certificate:

    openssl x509 -req -in issuer_ca.csr -CA root_ca.crt -CAcreateserial \
            -CAkey root_ca_priv.pem -days 30 -out issuer_ca.crt \
            -extfile <(cat << EOF
    
    basicConstraints       = critical, CA:TRUE, pathlen:1
    keyUsage               = critical, keyCertSign, cRLSign
    subjectKeyIdentifier   = hash
    authorityKeyIdentifier = keyid:always
    
    EOF
    )
    
  4. Create chain from both certificates:

    cat root_ca.crt issuer_ca.crt > cert_chain.pem