For context, check the intro post.
Summary: How to use Signed Certificates in an IoT supply chain. Without giving away your private keys to your subcontractor.
At the end of this post, you completed 60% of the end-to-end process.
You will generate an Intermediate Certificate for your supplier. They can then use that to sign Things on your behalf.
No private keys will be shared. The subcontractor can generate their own private key and generate a certificate request based on that.
We as Root CA can then generate a valid certificate based on the request, without the need to get the subcontractor's key.
Subcontractor Generates Request for a Certificate
Prepare the intermediate certification infra.
mkdir louisiana cd louisiana mkdir certs crl csr newcerts private chmod 700 private touch index.txt echo 1000 > serial echo 1000 > crlnumber
In the louisiana folder; create a file called openssl.cnf, Adapt where appropriate.
# OpenSSL intermediate CA configuration file. # Copy to `/root/ca/louisiana/openssl.cnf`. [ ca ] # `man ca` default_ca = CA_default [ CA_default ] # Directory and file locations. dir = /home/avnet/.openssl_certification_authority_USM/ca/louisiana certs = $dir/certs crl_dir = $dir/crl 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/louisiana.key.pem certificate = $dir/certs/louisiana.cert.pem # For certificate revocation lists. crlnumber = $dir/crlnumber crl = $dir/crl/louisiana.crl.pem crl_extensions = crl_ext default_crl_days = 30 # 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_loose [ 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 [ 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 [ 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 [ 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 = BE stateOrProvinceName_default = Brussels Capital District localityName_default = Schaarbeek 0.organizationName_default = United States Manufacturing organizationalUnitName_default = emailAddress_default = openssl_certification_authority.usm@gmail.com [ 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 [ 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 [ 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 [ 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 [ validation_cert ] # Extensions for IoTConnect and Azure CA validation certificates (`man x509v3_config`). basicConstraints = CA:FALSE nsCertType = client nsComment = "OpenSSL Generated Client Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth [ crl_ext ] # Extension for CRLs (`man x509v3_config`). authorityKeyIdentifier=keyid:always [ ocsp ] # Extension for OCSP signing certificates (`man ocsp`). basicConstraints = CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, digitalSignature extendedKeyUsage = critical, OCSPSigning
cd ..
You are doing the next two steps, but in reality they are done by the 3rd party on their systems:
Supplier Generates Private Key
openssl genrsa -aes256 \ -out louisiana/private/louisiana.key.pem 4096 chmod 400 louisiana/private/louisiana.key.pem
Never ask the supplier for the .key.pem file nor the password. You don't need it, and they should not share it with anyone.
Supplier Generates a Request for the Intermediate Certificate
Use these parameters (1st exact the same as Root, 2nd should identify the intermediate):
Org name: United States Manufacturing
CN: Louisiana Branch Intermediate CA
openssl req -config louisiana/openssl.cnf -new -sha256 \ -key louisiana/private/louisiana.key.pem \ -out louisiana/csr/louisiana.csr.pem
This request has to be handed over by the subcontractor to the Root CA (you).
Root CA Generates Intermediate Certificate for Supplier
You, the Root CA, will now generate an intermediate certificate for the subcontractor.
It will be based on the request they generated in the step above.
The certificate is powerful. They can create new certificates on our behalf, based on it. Even other intermediate certificates.
That makes sense. They may want to also delegate the final certificate generation to an employee.
It makes sense for the subcontractor to generate an intermediate CA certificate to each employee. Only the employee knows their private key and password.
It keeps the cycle traceable and safe. No one needs to share the secrets.
In this exercise, we will not add an additional intermediate CA. The supplier will use their intermediate certificate directly to generate final (leaf) certificates for the things they produce.
Generate the Intermediate CA Certificate
The password asked is that of yourself, the Root CA.
openssl ca -config openssl.cnf -extensions v3_intermediate_ca \ -days 3650 -notext -md sha256 \ -in louisiana/csr/louisiana.csr.pem \ -out louisiana/certs/louisiana.cert.pem chmod 444 louisiana/certs/louisiana.cert.pem
Validate the Certificate
cat index.txt openssl x509 -noout -text \ -in louisiana/certs/louisiana.cert.pem openssl verify -CAfile certs/ca.cert.pem \ louisiana/certs/louisiana.cert.pem
Create the Intermediate Certificate Chain
To be able to use the Root CA Certificate as validation, the downstream certificates should contain the Root CA.
Every step will add their certificate to the chain, including the thing.
If you don't do that, you'd have to register intermediate certificates in the server's trusted root database.
You don't want that. You want to validate against your Root CA only.
I step away from the article I based the steps on. Azure requires the order Leaf -> ... -> Intermediate CA -> ... -> Root CA.
cat \ louisiana/certs/louisiana.cert.pem \ certs/ca.cert.pem \ > louisiana/certs/ca-chain.cert.pem chmod 444 louisiana/certs/ca-chain.cert.pem
You as Root CA give that signed certificate to the subcontractor together and the chain and your Root certificate.
- louisiana.cert.pem
- ca-chain.cert.pem
- ca.cert.pem
They can now start programming devices and generate their certificates for you.
What Have You Achieved: 60%
Previous post:
You generated and installed a root certificate on IoTConnect Cloud.
You built a major part of the infrastructure that you will later use to generate the intermediate certificates.
This post:
Subcontractor generated a private key and a certificate request. They gave you the request file.
You generated the intermediate CA certificate and signed it with your Root CA private key.
You gave the certificate, your own root certificate, and the chain up to that point, to the supplier.
Next article: The supplier generates certificates while programming your Things.