-
Notifications
You must be signed in to change notification settings - Fork 383
X509_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 .
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 :-
- 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
anddevice
to create 3 separate common names for the 3 certificates.
- The common name is used as a common portion for common names for all the certs. This common name is appended to the words
-
Required password for ca certificate
- Used to create the private key of the root certificate.
-
Required password for intermediate certificate
- Used to create the private key of the intermediate certificate.
-
Required password for device or leaf certificate
- Used to create the private key of the leaf/device certificate.
-
Optional number of leaf devices applicable
- Used to create equal number of device certificates.
- If not provided the default device count will be
1
.
-
Optional number of days for expiry
- Used to create duration for certificates
- if not provided
root
will have10 years
,intermediate
will have1 year
and anyleaf
will have1 month
.
python create_x509_chain_crypto.py "leviosa" --ca-password "hogwarts" --intermediate-password "hogwartsi" --device-password "hogwartsd"
python create_x509_chain_crypto.py "nox" --ca-password "hogwarts" --intermediate-password "hogwartsi" --device-password "hogwartsd" --device-count "3"
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.
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
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
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
-
- 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
isaccio
then the common name of the leaf/device certificate needs to beaccio
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 isexpecto
and my module_id ispatronum
then the common name of the leaf/device certificate should beexpecto/patronum
- 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 bedeviceaccio
. There should not be any need to use any other registration id.
- 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.
-
Option 1.
- 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.