From ec00631aa2273a6a7c8b1c3c8bf2a20113c9694f Mon Sep 17 00:00:00 2001 From: Volodymyr Khoroz Date: Thu, 4 Apr 2024 16:27:50 +0300 Subject: [PATCH] Update Factory PKI docs according to recent changes Signed-off-by: Volodymyr Khoroz --- .../security/device-gateway.rst | 211 +++++++++-- .../device-gateway-pki/device-gateway-pki.rst | 331 ++++++++++++------ 2 files changed, 410 insertions(+), 132 deletions(-) diff --git a/source/reference-manual/security/device-gateway.rst b/source/reference-manual/security/device-gateway.rst index 28f25386..29997ccb 100644 --- a/source/reference-manual/security/device-gateway.rst +++ b/source/reference-manual/security/device-gateway.rst @@ -3,10 +3,27 @@ Managing Factory PKI ==================== -LmP devices connect to OTA services via a :ref:`device gateway ` configured with mutual TLS. -Each Factory uses a default device gateway with certificates owned by Foundries.io™. -We allow—and **encourage**\—you to set up your own PKI infrastructure. -This is so that you are in control of the security of the device gateway. +LmP devices connect to OTA services via a :ref:`Device Gateway ` configured with mutual TLS. +A set of Digital Certificates used to establish trust between Factory devices and Device Gateway is a Factory Public Key Infrastructure (PKI). + +When a new Factory is created, it is configured to use the default shared PKI with Certificates owned by Foundries.io™. +This provides a faster engagement with the FoundriesFactory®, allowing streamlined product development. + +FoundriesFactory supports setting up your own Factory PKI via either :ref:`Fioctl® ` commands or the API integration. +We recommend setting up your own Factory PKI **before** going to production. +Benefits of owning your Factory PKI are two-fold: + +- Controlling which devices can connect to your Factory Device Gateway to fetch configuration and software updates. +- Controlling which servers can deliver configuration and software updates to your Factory devices. + +.. warning:: + The Factory :ref:`Root of Trust ` **can only be set once**; subsequent attempts will fail. + Other Factory PKI certificates can be updated at any time; having that you own your Factory Root of Trust. + + `Contact customer support ` if you need your Factory PKI being reset. + Once a reset was performed, all connected devices will lose their connection. + These devices will not be able to connect to the Device Gateway until they are re-provisioned with a new Root of Trust. + On practice that usually means that these devices need to be re-flashed (after the Factory PKI reset). Terminology ----------- @@ -16,51 +33,105 @@ Terminology Root of Trust: ``factory_ca.key / factory_ca.pem`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The PKI root of trust for your Factory. -You own the private key (NIST P-256 by default). -The corresponding x509 certificate is shared with Foundries.io to define your root of trust. +An X.509 certificate used as a Root Certificate Authority (RCA) for your Factory. +You own the private key (NIST P-256 by default), and share the corresponding certificate with Foundries.io. + +All intermediate Certificate Authorities (CAs) and TLS certificates configured in your Factory must be signed by its Root of Trust. +The Root of Trust is preloaded to factory devices, so that they can use it to verify the FoundriesFactory web APIs TLS certificates. + +.. warning:: + Never lose the private key of your Factory Root of Trust. + By design, Foundries.io only stores a copy of the CA certificate bearing its public key. + We are not able to recover your private key in case of its loss. + + We recommend storing your Factory Root of Trust in a cloud-based HSM solution of your choice. + For example, we verified that the `AWS Cloud HSM `_ supports `importing EC private keys`_. + That way you get an increased safety of your highly important secret through their redundancy and backup policies. -All intermediate CA and mutual TLS certificates configured in your Factory must be signed by this keypair. -In particular, the certificates mentioned below. + Additionally, we recommend printing the private key of your Root of Trust on paper and storing it in multiple fire and waterproof safes. + +.. _importing EC private keys: https://docs.aws.amazon.com/cloudhsm/latest/userguide/key_mgmt_util-importPrivateKey.html .. _tls-crt: Server TLS Certificate: ``tls-crt`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This certificate along with its private key is used by Device Gateway during mTLS handshake/session setup. -Specifically, they are used for Device Gateway identity verification by a device/client and a TLS session's symmetric key setup. -The private key is owned by Foundries.io and the certificate is signed by the root of trust. +An X.509 certificate used by :ref:`Device Gateway ` during a mutual TLS handshake and session setup. +Foundries.io owns the private key (NIST P-256 by default), and you sign the certificate by the Factory Root of Trust. + +When your Factory devices connect to the Device Gateway, they verify the server identity by validating its TLS Certificate. +They use the preloaded Factory Root of Trust to perform that validation. +Once the mutual trust is established, Device Gateway uses its TLS Certificate to setup a session symmetric key. +That temporary symmetric key is used to encrypt all session traffic between the Device Gateway and the device. + +Device Client Certificate +~~~~~~~~~~~~~~~~~~~~~~~~~ + +An X.509 certificate was issued to your Factory device during the registration process. +The device owns the private key (NIST P-256 by default) and the certificate. + +This certificate must be signed by either a :ref:`Local Device CA ` or an :ref:`Online Device CA ` (see below). +For example, when using the `lmp-device-register`_ to register your device, it generates the Device Client Certificate Signing Request (CSR). +That CSR is then signed by an appropriate Device CA at the registration server (either your own or Foundries.io), and stored on the device. + +When connecting to the :ref:`Device Gateway `, a device must present its Client Certificate during a TLS handshake. +The device identity is verified at the Device Gateway, and the device is either allowed or denied to connect based on its certificate validity. +Once the mutual trust is established, device uses its Client Certificate to setup a session symmetric key. + +.. _lmp-device-register: https://github.com/foundriesio/lmp-device-register/ .. _online-ca: -Certificate: ``online-ca`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ +Online Device CA: ``online-ca`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In order for ``lmp-device-register`` to work, Foundries.io needs the ability to sign client certificates for devices. -If enabled, the root of trust will sign an ``online-ca`` certificate that Foundries.io can use to sign client authentication certificates. +An X.509 certificate used as a CA issuing certificates to devices registered via the FoundriesFactory API. +Foundries.io owns the private key (NIST P-256 by default), and you sign the certificate by the Factory Root of Trust. + +When using the "shared" Factory PKI, this is the only CA used to issue Client Certificates to your Factory devices. +Once you take ownership of your Factory PKI, you may opt out of using the Online Device CA. .. _local-ca: -Certificate: ``local-ca`` -~~~~~~~~~~~~~~~~~~~~~~~~~ +Local Device CA: ``local-ca`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Optional pair(s) of a private key and intermediate CA certificate, signed by the root CA. -Can be used by something like your manufacturing process to sign client certificates for devices—without needing access to Foundries.io. +An X.509 certificate used as a CA issuing certificates to devices registered via your offline registration process. +You own the private key (NIST P-256 by default), and share the corresponding certificate with Foundries.io. +It must be signed by the Root of Trust, so that Foundries.io may verify if a user is entitled to upload a Device CA. -It is also known and referred to as ``offline CA``, since you own its private key and keep it "offline". +At creation, your Factory only has an Online Device CA and no Local Device CAs. +Your factory may be configured to have one or more Local Device CAs only after you took ownership of your Factory PKI. +You may use the Local Device CA with our :ref:`ref-factory-registration-ref` to register your devices offline. .. figure:: /_static/ca_certs.png :align: center :scale: 90 % :alt: PKI hierarchy +.. _est-tls-crt: + +EST Server TLS Certificate: ``est-tls-crt`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An X.509 certificate used by FoundriesFactory hosted :ref:`ref-cert-rotation` during a mutual TLS handshake and session setup. +Foundries.io owns the private key (NIST P-256 by default), and you sign the certificate by the Factory Root of Trust. + +The FoundriesFactory process for rotating device certificates is based on the industry standard `RFC 7030`_ Enrollment over Secure Transport (EST). +Your Factory may be configured to use a FoundriesFactory hosted EST service, your own EST service, or no EST service. + +.. _RFC 7030: https://datatracker.ietf.org/doc/html/rfc7030 + .. _ref-rm-pki: +Managing Your Factory PKI +------------------------- + Setting Up Your PKI -------------------- +~~~~~~~~~~~~~~~~~~~ -:ref:`ref-fioctl` includes a sub-command to set up your PKI: +:ref:`ref-fioctl` includes a command to set up your PKI: .. warning:: The following command can only be used once. @@ -72,7 +143,7 @@ Setting Up Your PKI A few important things to note about this command: * Use a PKCS#11 compatible HSM. - This will ensure the safety of your Factory's root of trust private key. + This will ensure the safety of your Factory's Root of Trust private key. * The "PKI Directory" is important, and should be securely backed up. @@ -86,7 +157,97 @@ After running the above command, you can validate the outcome and view the confi fioctl keys ca show --pretty +Rotating Server TLS Certificate +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sometimes, you might need to rotate the TLS certificate used by the Device Gateway to serve your Factory devices. +For example, the corresponding TLS certificate might be close to its expiration date, or it might be compromised. +Foundries.io is not able to perform that task for you, as it requires access to your Factory Root of Trust. + +:ref:`ref-fioctl` includes a command to rotate your Server TLS Certificate: + +.. code-block:: + + fioctl keys ca rotate-tls /absolute/path/to/certs/ + +Adding Device CA +~~~~~~~~~~~~~~~~ + +Sometimes, you might need to add more than one Device CA to your Factory. +Some use cases when this is needed include (but are not limited to) the following situations: + + * You have only initially set up an Online Device CA for your Factory, + and want to also configure a Local Device CA (or vice versa). + + * You opened a new manufacturing site, + and want a dedicated Local Device CA to issue Client Certificates to devices manufactured at this site. + + * One of your Device CAs was compromised, + and you need to replace it by a new Device CA (either Online or Local). + +:ref:`ref-fioctl` includes a command to add one more Device CA to your Factory: + +.. code-block:: + + fioctl keys ca add-device-ca /absolute/path/to/certs/ [--online-ca | --local-ca] + +Revoking Device CA +~~~~~~~~~~~~~~~~~~ + +You may need to revoke or disable a Device CA for your Factory. +Some use cases when this is needed include the following situations: + + * One of your Device CAs was compromised, + and you need to deny an ability to register new devices with client certificates issued by this CA. + You may also want to completely deny access to the Device Gateway for already registered devices with such certificates. + + * You are closing a manufacturing site, + and want to make sure that a Device CA issued for that manufacturing site can no longer be used to issue new client certificates. + +:ref:`ref-fioctl` provides two separate commands: to disable and revoke an existing Device CA. + +There is an important difference between disabling and revoking a Device CA: + +- When you disable the Device CA, + new devices with client certificates issued by that CA cannot be registered. +- When you revoke the Device CA, in addition to the above, + already registered devices with client certificates issued by that CA cannot connect to your Factory. + +Use the below command when you need to disable a Device CA: + +.. code-block:: + + fioctl keys ca disable-device-ca /absolute/path/to/certs/ [--ca-file | --ca-serial ] + +Use the following command when you need to revoke a Device CA: + +.. code-block:: + + fioctl keys ca revoke-device-ca /absolute/path/to/certs/ [--ca-file | --ca-serial ] + +After the Device CA is revoked, devices can no longer update their apps or config. +Therefore, the revocation process needs to be planned properly. +We recommend the following workflow: + +1. Disable the Device CA. + This action needs to be taken as soon as you notice that your Device CA was compromised. + This makes sure that an attacker is not able to register new devices with client certificates issued by that CA. + +2. Inspect your fleet of already registered devices, and delete those devices which you think are not legitimate. + After this point, you can be sure that an attacker can no longer steal your new Intellectual Property (provided by OTA updates). + FoundriesFactory advices you to also prepare a separate plan how to deal with already compromised devices. + +3. Rotate client certificates on your devices which have a client certificate issued by a Device CA you are revoking. + You may use Foundries.io hosted ref:`ref-cert-rotation` service, or use your own certificate rotation workflow. + Make sure that new device client certificates are issued by one of Device CAs enabled at your Factory. + +4. Revoke the Device CA. + At this point a reference to a given Device CA is completely removed from our servers, hence becomes untrusted. + +Related Topics +-------------- + The Factory PKI is interwoven with the device manufacturing process and device registration. You can find out more details on this topic in this guide :ref:`ref-factory-registration-ref`. -More details on Factory PKI can be found in this :ref:`guide `. +More details on Factory PKI internals can be found in this :ref:`guide `. diff --git a/source/user-guide/device-gateway-pki/device-gateway-pki.rst b/source/user-guide/device-gateway-pki/device-gateway-pki.rst index ececadc6..4f048ae8 100644 --- a/source/user-guide/device-gateway-pki/device-gateway-pki.rst +++ b/source/user-guide/device-gateway-pki/device-gateway-pki.rst @@ -3,158 +3,275 @@ Details Of Device Gateway PKI Settings ====================================== +The PKI for Device Gateway and Factory Devices is vital for the secure communication between them. +It is important to understand exactly what the Factory PKI related commands do. +The :ref:`Factory PKI ` reference manual describes core concepts of your Factory PKI. +It also provides examples to configure your Factory PKI using the :ref:`Fioctl® ` commands. + +This user guide focuses more on the Factory PKI internals. +That should allow you to integrate with the Factory PKI API directly if you need to. + +Fioctl uses the `Golang native cryptographic libraries `_ to implement all PKI related commands. +However, the same cryptographic functions can be implemented using `OpenSSL `_, as demonstrated in this guide. + .. warning:: - The factory root of trust **can only be set once** — - `contact customer support ` if you need to have the value reset. - This means the command ``fioctl keys ca create`` works only for the first run. - Subsequent attempts will fail. - Additionally,if you do have a reset performed, it will result in connected devices losing connection. - However, the Device CA bundle (``ca-crt``) can be updated many times; - you may add or remove local/offline CA certs for the bundle with ``fioctl keys ca update``. + The Factory :ref:`Root of Trust ` **can only be set once**; subsequent attempts will fail. + Other Factory PKI certificates can be updated at any time; having that you own your Factory Root of Trust. -This guide covers Public Key Infrastructure (PKI) Settings. -In particular, the low-level details of what happens behind the scenes when running the ``fioctl keys ca`` commands. -It also provides instructions to create, sign, and use an *offline* (aka *local*) device certificate. + `Contact customer support ` if you need your Factory PKI being reset. + Once a reset was performed, all connected devices will lose their connection. + These devices will not be able to connect to the Device Gateway until they are re-provisioned with a new Root of Trust. + On practice that usually means that these devices need to be re-flashed (after the Factory PKI reset). -The :ref:`Factory PKI ` reference manual describes core concepts of Device Gateway PKI and how it can be configured by using the ``fioctl keys ca``. -.. seealso:: - Documentation on using :ref:`Fioctl® ` +Taking Ownership of Factory PKI Using the API +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Under the Hood -~~~~~~~~~~~~~~ +Before setting up your Factory PKI, your Devices and Device Gateway talk to each other by utilizing a so-called "shared PKI". +This is the default PKI that FoundriesFactory® sets up as part of provisioning a new Factory. -The PKI for Device Gateway and Factory Devices is vital for the secure communication between them. -It is important to understand exactly what the given command does. +You can always check your Factory PKI settings using the ``fioctl keys ca show``. +In case of a shared PKI that command would tell you that your Factory PKI is not configured yet. + +In order to take ownership of your Factory PKI, run a ``fioctl keys ca create`` command. +This command communicates with the FoundriesFactory API to create and update Factory specific PKI keys and certificates. + +First, a command calls the API to initialize a Factory PKI, which performs the following actions: + +- Verify if the Factory PKI was already initialized, and fail if a user attempts to initialize an already initialized PKI. +- Generates a server-side crypto-key for the ref:`tls-crt` and returns a Certificate Signing Request (CSR) for it. +- Optionally generates a server-side crypto-key for the ref:`online-ca` and returns a CSR for it. +- Optionally generates a server-side crypto-key for the ref:`est-tls-crt` and returns a CSR for it. + +Once the ``fioctl keys ca create`` command receives a response, it performs the following actions: + + - Generates the Factory Root CA on either your local file system or an HSM device. + - Optionally generates a Local Device CA on your local file system, and signs it using the Factory Root CA. + - Signs all CSRs received from the above API call. + - Finally, that command uploads all generated certificates to the API; private keys are not uploaded. + +You can replay what the ``fioctl keys ca create`` command does using the following steps. + +1. Call the API to Generate CSRs +'''''''''''''''''''''''''''''''' -Before a user sets up the PKI, their Devices and Device Gateway talk to each other by utilizing a so-called "shared PKI". -This is the default PKI that the FoundriesFactory™ service sets up as part of new Factory provisioning. -The ``fioctl`` command communicates with the end point ``https://api.foundries.io/ota/factories/$FACTORY/certs/`` to create and update Factory specific PKI keys and certificates. -As long as the Factory uses the "shared PKI", the endpoint returns an empty response, as no Factory PKI is set:: +You may use `Curl `_ to play with the Factory PKI APIs. +The following command calls the API to generate CSRs for the server TLS certificate and the Online Device CA:: + + curl "https://api.foundries.io/ota/factories/${FACTORY}/certs/" \ + -s -X POST -H "Content-Type: application/json" -H "OSF-Token: $TOKEN" \ + -d '{"first-time-init": true, "tls-csr": true, "ca-csr": true, "est-tls-csr": false}' + +The above API returns the following output in case of success:: - curl -s -H "OSF-TOKEN: $TOKEN" https://api.foundries.io/ota/factories/${FACTORY}/certs/ | jq { - "tls-crt": null, - "ca-crt": null, - "root-crt": null + "ca-csr": "(Optionally) A CSR for online Device CA of your Factory in PEM format." + "tls-csr": "A CSR for device APIs server TLS certificate of your Factory in PEM format". + "est-tls-csr": "(Optionally) A CSR for (Foundries.io hosted) EST server TLS certificate of your Factory in PEM format". } -* ``root-crt`` is the PKI root CA certificate, also referred as :ref:`Root of Trust ` -* ``ca-crt`` is a certificate bundle containing one :ref:`online CA ` certificate and optionally one or more :ref:`local CA ` certificates, aka "offline-ca". -* ``tls-crt`` is a Device Gateway certificate, also referred as :ref:`a server TLS certificate ` +You need to store all received CSRs on your local file system to be able to use OpenSSL to generate corresponding certificates. +For example, store a `tls-csr` into a `tls.csr` file (as used in examples below) and so on. + +2. Generate a Private Key and Certificate for Factory Root CA +''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +You may use OpenSSL to generate your Factory Root CA. + +First, you need to create the following certificate configuration file on your file system:: + + factory_ca.cnf: + [req] + prompt = no + distinguished_name = dn + x509_extensions = ext + + [dn] + CN = Factory-CA + OU = + + [ext] + basicConstraints=CA:TRUE + keyUsage = keyCertSign, cRLSign + extendedKeyUsage = critical, clientAuth, serverAuth + +.. important:: + It is important that the Organization Unit (OU) of your Factory Root CA Subject field is set to your Factory name. + That information is used by the API to validate that you upload a Root CA for a correct Factory. + +Next, use the following OpenSSL command to generate the private key for your Factory Root CA:: + + openssl ecparam -genkey -name prime256v1 | openssl ec -out factory_ca.key + +The above command stores the private key in a ``factory_ca.key`` file on your local file system. +If you want to store in on an HSM device, look at the `Fioctl Bash based PKI implementation`_ for an example. + +.. _Fioctl Bash based PKI implementation: https://github.com/foundriesio/fioctl/blob/main/x509/bash.go + +Once you have a configuration and private key files, use the following OpenSSL command to generate the Factory Root CA:: + + openssl req -new -x509 -days 7300 -sha256 -config factory_ca.cnf -key factory_ca.key -out factory_ca.pem + +The above command stores your Factory Root CA certificate in a ``factory_ca.pem`` file on your local file system. +In this example, the Factory Root CA is self-signed by its own private key. +Alternatively, you may sign it by a higher level CA at your disposal. + +3. Optionally Generate Your Local Device CA +''''''''''''''''''''''''''''''''''''''''''' + +Although Foundries.io™ securely stores your Factory Online Device CA; its private key is not owned by you. +We recommended generating one or more Local Device CA for your Factory before going to production. +Those Local Device CAs should be used to issue client TLS certificates for your production devices. +In a fully sealed setup you would disable or revoke the Online Device CA for your Factory. + +Similarly to the Factory Root CA, you may use OpenSSL to generate your Local Device CA. + +First, you need to create the following certificate configuration files on your file system:: + + local_ca.cnf + [req] + prompt = no + distinguished_name = dn + + [dn] + CN = fio- + OU = + + ca.ext: + keyUsage=critical, keyCertSign + basicConstraints=critical, CA:TRUE, pathlen:0 + +.. important:: + It is important that the Organization Unit of your Factory Device CA Subject field is set to your Factory name. + That information is used by the API to validate that you upload a Root CA for a correct Factory. + + Additionally, the Common Name (CN) of your Factory Local Device CA Subject field needs to equal "fio-" plus your user ID. + A user ID can be determined from the ``fioctl users`` command output or your Factory Users page. + A user specified in this field becomes an owner of all devices auto-registered using client certificates issued by this CA. + +Next, use the following OpenSSL command to generate the private key for your Factory Root CA:: + + openssl ecparam -genkey -name prime256v1 | openssl ec -out local_ca.key + +Then, generate a CSR for your Local Device CA using the following OpenSSL command:: + + openssl req -new -config local_ca.cnf -key local_ca.key -out local_ca.csr + +Finally, use OpenSSL to generate your Factory Local Device CA, and sign it by your Factory Root CA:: + + openssl x509 -req -days 3650 -sha256 -CAcreateserial -in local_ca.csr \ + -extfile ca.ext -CAkey factory_ca.key -CA factory_ca.pem -out local_ca.pem + +These commands will store your Factory Local Device CA private key and certificate in ``local_ca.key`` and ``local_ca.pem`` files. + +4. Sign CSRs Received from the API +'''''''''''''''''''''''''''''''''' + +You may use OpenSSL to sign API provided CSRs for your Factory, similarly to how the Factory Local Device CA is signed. +First, you need to create the following certificate configuration files on your file system:: -The first step that the ``fioctl`` command does is send a post request to the PKI endpoint. -In the following example, a response is redirected to a json file so its content can be used later.:: + server.ext + keyUsage=critical, digitalSignature + extendedKeyUsage=critical, serverAuth - curl -s -X POST -H "Content-Type: application/json" -H "OSF-TOKEN: $TOKEN" "https://api.foundries.io/ota/factories/${FACTORY}/certs/" | jq . > factory_certs.json + ca.ext: + keyUsage=critical, keyCertSign + basicConstraints=critical, CA:TRUE, pathlen:0 -The endpoint handler does the following: +Next, use OpenSSL to determine the DNS names from the server TLS CSR, and append it to the server configuration file:: -1. Generates a private key and corresponding Certificate Signing Request (CSR) for Device Gateway (tls-crt); -2. Generates a private key and corresponding CSR for Online Device CA (online-ca); -3. Returns a json formatted response to a caller, the response includes: + echo "subjectAltName=$(openssl req -text -noout -verify -in tls.csr | grep DNS:)" >> server.ext - a. ``tls-csr`` - CSR for Device Gateway certificate - b. ``ca-csr`` - CSR for Online Device CA certificate - c. ``create_ca`` - a script that can be used for root CA creation, i.e. a private key and corresponding self-signed certificate - d. ``create_device_ca`` - a script that can be used for "local-ca"/"offline-ca" creation, i.e. a private key, corresponding certificate signed by the root CA - e. ``sign_tls_csr`` - a script that signs received ``tls-csr`` by the root CA - f. ``sign_ca_csr`` - a script that signs received ``ca-csr`` ("online-ca") by the root CA. +Finally, use OpenSSL to generate the server TLS certificate, and sign it by your Factory Root CA:: -A user can extract any of the aforementioned fields by utilizing the ``jq`` utility: :: + openssl x509 -req -days 3650 -sha256 -CAcreateserial -in tls.csr \ + -extfile server.ext -CAkey factory_ca.key -CA factory_ca.pem -out tls.pem - cat factory_certs.json | jq -r .create_ca +Similarly, you may generate and sign a server TLS certificate for Foundries.io hosted EST server if you need it. -Once the ``fioctl`` command receives a response, it makes use of the above scripts included in a response. -Specifically, it: +If you also want to have a Factory Online Device CA, generate and sign using the following OpenSSL command:: -1. Invokes the ``create_ca`` script to generate Root CA key (``factory_ca.key``) and Root CA certificate (``factory_ca.pem``); -2. Signs the ``tls-csr`` by invoking the ``sign_tls_csr`` script, the resultant certificate is stored in ``tls-crt``; -3. Signs the ``ca-csr`` by invoking the ``sign_ca_csr`` script, the resultant certificate is stored in ``online-crt``; -4. Creates a local/offline Device CA by using ``create_device_ca``, the resultant private key and certificate are stored in ``local-ca.key`` and ``local-ca.pem`` correspondingly; + openssl x509 -req -days 3650 -sha256 -CAcreateserial -in online_ca.csr \ + -extfile ca.ext -CAkey factory_ca.key -CA factory_ca.pem -out online_ca.pem -Then the ``fioctl`` command uploads the generated artifacts to the backend by issuing a ``PATCH`` request to the endpoint. -The following files are uploaded: +5. Upload Generated Certificates to the API +''''''''''''''''''''''''''''''''''''''''''' -1. ``tls-crt`` - the result of ``tls-csr`` signing; -2. ``online-crt`` and ``local-ca.pem`` bundled together into the ``ca-crt`` field of the PATCH request; -3. ``factory_ca.pem`` - root CA certificate created by running ``create_ca`` transferred via ``root-crt`` fields of the PATCH request. +Once you have generated all the necessary certificates, you may upload them to the Factory PKI API. -Device Key and Certificate -~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once the PKI is setup, your Factory Device Gateway is ready to communicate via mTLS with Factory devices. -The devices must have a private key and a x509 certificate to setup mTLS session with Device Gateway. -It also needs the Root CA certificate to verify Device Gateway certificate during mTLS handshake. +You might have generated more than one Device CA (for example both Local and Online Device CAs, or several Local Device CAs). +In this case, you need to contatenate them into a single file before the upload, e.g. using this command:: -As explained above, the ``fioctl`` command generates two types of Device CA, online and local/offline CAs. -Both of these CAs can be used to sign Device CSR. + cat online_ca.pem local_ca.pem >> device_ca_list.pem -Online Device Certificate -************************* -In the case of online CA, a private key is owned by the backend. Hence, only the backend can sign a Device CSR with the online CA. -The utility called ``lmp-device-register`` can be used for this purpose, and is the default device registration mechanism. -The tool generates a device private key, creates a corresponding device CSR, and makes a request to the backend to sign it with the online CA. -As a response, the backend returns a signed device certificate as well as a default configuration for the device (aka ``sota.toml``). -More details on ``lmp-device-register`` usage can be found in the :ref:`getting started guide `. +Your Factory PKI certificates may be uploaded to the API using this Curl command:: -Local/Offline Device Certificate -******************************** + ROOT_CA_CRT=$(cat factory_ca.pem | awk -v ORS='\\n' '1') \ + DEVICE_CA_CRT=$(cat device_ca_list.pem | awk -v ORS='\\n' '1') \ + TLS_CRT=$(cat tls.pem | awk -v ORS='\\n' '1') \ + curl "https://api.foundries.io/ota/factories/${FACTORY}/certs/" \ + -s -X PATCH -H "Content-Type: application/json" -H "OSF-Token: $TOKEN" \ + -d '{"root-crt": "'"${ROOT_CA_CRT}"'", "tls-crt": "'"${TLS_CRT}"'", "ca-crt": "'"${DEVICE_CA_CRT}"'"}' -We advise using the Factory registration `reference implementation`_ as a mechanism for offline device key and certificate generation as well as device registration. -The following is a guide on the manual creation of Local/Offline Device keys and certificates. -This can be useful for understanding low-level details of the overall process. +After this command your Factory PKI is ready to use. -Create a directory for offline device key and certificate:: +Registering Factory Devices Using the API +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - mkdir -p devices/offline-device +Devices are usually registered with your Factory by running the +`lmp-device-register® `_ tool. +See the :ref:`getting started guide ` for more details on using the tool. -Generate a private key:: +This same task may be accomplished by generating the device client certificate using OpenSSL, and uploading it to the API. +The device may be registered via the FoundriesFactory API or the your own registration service +(e.g. a `factory-registration-ref® `_). - openssl ecparam -genkey -name prime256v1 -out devices/offline-device/pkey.pem +Below steps perform device registration using OpenSSL the same way as the ``lmp-device-register`` +and ``factory-registration-reg`` tools would do. -Set offline Device certificate config:: +First, you need to create the following certificate configuration files on your file system:: - cat > devices/offline-device/device-cert.conf < + OU = -Make sure to replace ```` and ``${FACTORY}`` with your values. + client.ext: + keyUsage=critical, digitalSignature + basicConstraints=critical, clientAuth -Set offline Device certificate extensions:: +Next, use the following OpenSSL command to generate the private key for your device client certificate:: - cat > devices/offline-device/device-cert.ext <"}' -:: +You may run the following commands to verify that your device can connect to your Factory Device Gateway:: - curl --cacert factory_ca.pem --cert devices/offline-device/client.pem --key devices/offline-device/pkey.pem https://.ota-lite.foundries.io:8443/repo/1.root.json | jq + # Run this command first to see the device gateway host name (which looks like .ota-lite.foundries.io): + openssl x509 -noout -in tls.pem -ext subjectAltName -It is worth noticing that the device is registered at the backend on the first request to Device Gateway in this case. + # Then, substitute the in the below command with your findings. + curl --cacert factory_ca.pem --cert client.pem --key client.key https://.ota-lite.foundries.io:8443/repo/1.root.json | jq -.. _reference implementation: - https://github.com/foundriesio/factory-registration-ref +If you did not register your device with the API, it will be auto-registered on the first call to the Device Gateway.