Skip to content

X509_Chain

olivakar edited this page Sep 22, 2020 · 6 revisions

Create X-509 certificate chain

Currently we have a way to create the entire X-509 chain using a python script kept in the scripts folder. These certificates can be used in the X-509 samples we have in our samples directory.

For this script to work need to do pip install cryptography in the local python environment.

This script will create a basic X-509 chain consisting of root chain which is a CA, an intermediate certificate that is related to the root and also a CA and and a leaf/device certificate that is related to the intermediate and is a non CA .

Usage for producing certificate chain

The script expects an environment variable named OPENSSL_CONF to be already defined in the current system. Other than these, there are some arguments that need to be passed while calling the script in order to create the full fledged chain :-

  1. common portion of mandatory common name
    • The common name is used as a common portion for common names for all the certs. This common name is appended to the words root, inter and device to create 3 separate common names for the 3 certificates.
  2. Required password for ca certificate
    • Used to create the private key of the root certificate.
  3. Required password for intermediate certificate
    • Used to create the private key of the intermediate certificate.
  4. Required password for device or leaf certificate
    • Used to create the private key of the leaf/device certificate.
  5. Optional number of leaf devices applicable
    • Used to create equal number of device certificates.
    • If not provided the default device count will be 1.
  6. Optional number of days for expiry
    • Used to create duration for certificates
    • if not provided root will have 10 years, intermediate will have 1 year and any leaf will have 1 month.

Example usages

Default usage for a chain with 1 leaf certificate
python create_x509_chain_crypto.py "leviosa" --ca-password "hogwarts" --intermediate-password "hogwartsi" --device-password "hogwartsd"
Usage for a chain with 3 leaf certificates
python create_x509_chain_crypto.py "nox" --ca-password "hogwarts" --intermediate-password "hogwartsi" --device-password "hogwartsd" --device-count "3"

Usage for producing verification cert

Depending on what sample we are trying to run the root/ca certificate may need to be uploaded to the certificate section of the respective Hub. And after uploading this certificate a nonce or verification code needs to be generated. This nonce needs to be further used to generate a verification certificate. This verification certificate needs to be uploaded to prove that we actually possess the certificate. More detailed steps can be found here.

Example usage for root verification

The default verification is done for root. The argument named root-verify need not be entered as by default this is True.

python create_x509_chain_crypto.py "leviosa" --mode verification --issuer-password "hogwarts" --nonce 3189FC796AB321C17F0A74011E72C64E9FD98FECE90AE0E5

Example usage for intermediate verification

For any other type of verification there is another argument named root-verify which should be False.

python create_x509_chain_crypto.py "leviosa" --mode verification --issuer-password "hogwartsi" --nonce 1CA27CF9052136A642764D0EA87A943DE67F8203AD1D4B2D --root-verify False

Pointers for samples

To make the samples or real code work there are certain conventions that need to be kept in mind. These rules are not super intuitive by nature and hence they have been mentioned here. The simple rule to keep in mind is :-

  • The common name of a certificate can not have any spaces within them. The reason begin the common name is equal to the device_id and neither of these can have spaces or blanks.
  • When using the creation script to generate a verification certificate then the common name is equal to the nonce.
  • For all samples involving X509 in this repository, the environment variables
    • X509_CERT_FILE refers to the device/leaf cert (may OR may not be appended by other certs in chain based on scenario)
    • X509_KEY_FILE refers to device/leaf key
    • PASS_PHRASE refers to the password for device/leaf cert

IoTHub Telemetry Operations

  • For all IoT Hub operations the root/ca certificate must be uploaded to the IoT Hub and a proof of possession must be done in order to proceed further.
  • For telemetry from device , the device id needs to exactly equal to the common name of the device/leaf certificate. For example if my device_id is accio then the common name of the leaf/device certificate needs to be accio as well.
  • For telemetry from module, the common name of the device certificate needs to be exactly equal to <device_id>/<module_id>. For example if my device_id is expecto and my module_id is patronum then the common name of the leaf/device certificate should be expecto/patronum

Provisioning Operations

Individual Enrollment

  • Any individual enrollment works without any proof of possession being done. So for this purpose there is no need to actually upload any certificate or generate nonce
  • For provisioning purposes, the common name of the device certificate needs to be exactly equal to the registration id of the individual enrollment. For example if I have a leaf/device certificate with the common name of deviceaccio then on creation of the individual enrollment the registration id will also be deviceaccio. There should not be any need to use any other registration id.

Group Enrollment

  • For any group enrollment to work the root/ca or intermediate/ca certificate must be uploaded to DPS and a proof of possession must be done to proceed further.
  • The name of the group enrollment record does not matter and has no relation to the common name of the certificate.
  • A group enrollment can be created by utilizing
    • Option 1. ca certificate : In this option you are selecting a ca certificate from a drop down list of available certificates those have been already uploaded to DPS. The certificate of choice needs to be previously verified and uploaded and still available.
    • Option 2. intermediate certificate : In this case the intermediate certificate is separately uploaded to create the group enrollment. Please remember for this is only a step for creation of group enrollment but for this option to work the root/ca had already been uploaded and verified in DPS.
  • In any of the above 2 cases , the registration_id of an individual device should be equal to the common name of the corresponding device/leaf certificate.
    • If the root certificate has gone through proof of possession, then the device sample needs to send the chain of the device certificate appended by the intermediate certificate . This is true even when the group enrollment was created with the intermediate certificate
    • If the intermediate certificate has gone through proof of possession, then the device sample needs to send only the device certificate.
  • For checking whether certificates are valid as well as checking what common names they have created with the certlogic-decoder may be used.