blob: cf1c9b2f8d72f596f4885a7796c2c8160b2fa28a [file] [log] [blame]
#!/bin/bash
#
#
# Copyright 2019 NXP
# SPDX-License-Identifier: Apache-2.0
#
#
# NOTE: This script is based upon 'provisionA71CH_WatsonIoT.sh' included in the project
# hosted on https://github.com/ibm-watson-iot/iot-nxpimxa71ch-c
#
#
#########################################################################################################
##
# Set global variables to default values
gExecMsg=""
gRetValue=0
# Tools
A71CH_CONFIG_TOOL="./a71chConfig_i2c_imx"
SSS_CONFIG_TOOL="ssscli"
# Customization variables
# For Watson IoT Platform Device and Gateway types
#
devType="NXP-A71CH-D"
gwType="NXP-A71CH-G"
#
# For root CA
#
ROOT_CA_CN="NXP Semiconductors DEMO rootCA v E"
CA_EXISTS="FALSE"
CA_ENC_TYPE="ECC" # Options are RSA or ECC
CA_ECC_CURVE="prime256v1" # Only used if CA_ENC_TYPE is ECC
# CA_ECC_CURVE="secp384r1" # Only used if CA_ENC_TYPE is ECC
#
# For intermediate CA - Intermediate CA will be signed by root CA
#
CREATE_INTERMEDIATE_CA="TRUE"
INTERMEDIATE_CA_CN="NXP Semiconductors DEMO intermediateCA v E"
INTERMEDIATE_CA_EXISTS="FALSE"
INTERMEDIATE_CA_ENC_TYPE="ECC" # Supported type for intermedite CA is ECC
INTERMEDIATE_CA_ECC_CURVE="prime256v1" # Only used if INTERMEDIATE_CA_ENC_TYPE is ECC
#
# Certificate validity
#
CA_CERT_VALIDITY=7300 # 20 years
CLIENT_CERT_VALIDITY=7300 # 20 years
# Root CA Files
if [ "${CA_ENC_TYPE}" == "RSA" ]; then
rootcaKey="CACertificate_RSA.key"
rootcaCert="CACertificate_RSA.crt"
ca_srl="CACertificate_RSA.srl"
else
rootcaKey="CACertificate_ECC.key"
rootcaCert="CACertificate_ECC.crt"
ca_srl="CACertificate_ECC.srl"
fi
# Intermediate CA files - RSA is not supported yet
intercaKey="interCACertificate_ECC.key"
intercaCsr="interCACertificate_ECC.csr"
intercaCert="interCACertificate_ECC.crt"
inter_srl="interCACertificate_ECC.srl"
# Chain of CA root and intermediate certificate
chaincaCert="CACertificateChain.crt"
# UTILITY FUNCTIONS
# -----------------
# xCmd will stop script execution when the program executed does return gRetValue (0 by default) to the shell
xCmd () {
local command="$*"
echo ">> ${gExecMsg}"
echo ">> ${command}"
${command}
local nRetProc="$?"
if [ ${nRetProc} -ne ${gRetValue} ]
then
echo "\"${command}\" failed to run successfully, returned ${nRetProc}"
echo "** Script execution failed **"
exit 2
fi
echo ""
# Set global variables to default values
gExecMsg=""
gRetValue=0
}
prog_usage() {
echo "Usage:"
echo " $0 [-u <UID-value>] [ip:port]"
}
# Check command line arguments
if [ "$#" -gt 3 ]; then
echo "Too many arguments"
prog_usage
exit 1
else
# default values
ip_addr_port_server=""
SE_UID=""
if [ "$1" == "-u" ]; then
if [ "$#" -lt 2 ]; then
prog_usage
exit 1
else
SE_UID="$2"
if [ "${#SE_UID}" -ne 20 ]; then
echo " The UID (provided as argument) must be exactly 20 characters long"
echo "The current argument is ${#SE_UID} characters long"
echo "Exiting..."
exit 4
fi
if [ -n "$3" ]; then
ip_addr_port_server="$3"
fi
fi
elif [ "$#" -eq 1 ]; then
ip_addr_port_server="$1"
elif [ "$#" -eq 0 ]; then
# No arguments is fine
echo "Will fetch UID from attached sample"
else
# Wrong command line options
prog_usage
exit 1
fi
fi
echo "SE_UID=${SE_UID}"
echo "ip_addr_port_server=${ip_addr_port_server}"
# Provide UID as argument, or
# attach the SE and have the script retrieve the UID from the IC
if [ -z ${SE_UID} ]; then
echo " Get UID from attached SE"
# ${A71CH_CONFIG_TOOL} info device | grep -e "[0-9][0-9]:[0-9][0-9]:[0-9][0-9]"
# SE_UID="$(${A71CH_CONFIG_TOOL} info device | grep -e "\([0-9][0-9]:\)\{17,\}" \
# | awk 'BEGIN {FS=":"}; {printf $3$4$9$10$11$12$13$14$15$16}')"
xCmd "ssscli disconnect"
xCmd "ssscli connect se05x t1oi2c none"
xCmd "ssscli se05x certuid"
SE_UID="$(ssscli se05x certuid 2>&1 | grep -e 'Cert UID' | grep -o -e '\([0-9a-zA-Z]\)\{20,\}')"
echo "SE_UID: ${SE_UID}"
fi
# Sanity check on UID
if [ "${#SE_UID}" -ne 20 ]; then
echo " Could not retrieve UID from SE."
echo "Exiting..."
exit 5
fi
###########################################
# Create root CA key and certificate.
###########################################
if [ "${CA_EXISTS}" != "TRUE" ]; then
if [ "${CA_ENC_TYPE}" == "RSA" ]; then
# RSA Root Certificates
if [ ! -e ${rootcaKey} ]; then
# Create both the CA keypair and CA certificate
# The root CA is RSA 4096
echo "## Create RSA Root CA Key: (${rootcaKey})"
xCmd "openssl genrsa -out ${rootcaKey} 4096"
echo "## Create RSA Root CA Certificate: (${rootcaCert})"
openssl req -x509 -new -nodes -key ${rootcaKey} -sha256 -days ${CA_CERT_VALIDITY} -out ${rootcaCert} -subj "/CN=${ROOT_CA_CN}"
fi
if [ ! -e ${rootcaCert} ]; then
echo "## Create ECC Root CA Certificate: (${rootcaCert}); Root CA keypair was already present"
openssl req -x509 -new -nodes -key ${rootcaKey} -sha256 -days ${CA_CERT_VALIDITY} -out ${rootcaCert} -subj "/CN=${ROOT_CA_CN}"
fi
else
# ECC Root Certificates
if [ ! -e ${rootcaKey} ]; then
# Create both the CA keypair and CA certificate
# The root CA is ECC using curve defined in CA_ECC_CURVE variable
echo "## Create ECC Root CA Key: (${rootcaKey}) Curve: (${CA_ECC_CURVE})"
xCmd "openssl ecparam -genkey -name ${CA_ECC_CURVE} -out ${rootcaKey}"
echo "## Create ECC Root CA Certificate: (${rootcaCert})"
openssl req -x509 -new -nodes -key ${rootcaKey} -sha256 -days ${CA_CERT_VALIDITY} -out ${rootcaCert} -subj "/CN=${ROOT_CA_CN}"
fi
if [ ! -e ${rootcaCert} ]; then
echo "## Create ECC Root CA Certificate: (${rootcaCert}); Root CA keypair was already present"
openssl req -x509 -new -nodes -key ${rootcaKey} -sha256 -days ${CA_CERT_VALIDITY} -out ${rootcaCert} -subj "/CN=${ROOT_CA_CN}"
fi
fi
else
# Check whether RootCA key and certificate are present.
if [ ! -e ${rootcaKey} ]; then
if [ "${CA_ENC_TYPE}" == "RSA" ]; then
echo "## No RSA Root CA Key available (${rootcaKey})"
else
echo "## No ECC Root CA Key available (${rootcaKey})"
fi
exit 8
fi
if [ ! -e ${rootcaCert} ]; then
if [ "${CA_ENC_TYPE}" == "RSA" ]; then
echo "## No RSA Root CA Certificate available (${rootcaCert})"
else
echo "## No ECC Root CA Certificate available (${rootcaCert})"
fi
exit 9
fi
fi
##############################################
# Create intermediate CA key and certificate.
##############################################
# echo "Check whether a .srl file of Root CA is present"
if [ -e ${ca_srl} ]; then
echo "## ${ca_srl} already exists, use it"
x509_serial="-CAserial ${ca_srl}"
else
echo "## no ${ca_srl} found, create it"
x509_serial="-CAcreateserial"
fi
SIGN_BY_INTERMEDIATE_CA="FALSE"
echo "## CREATE_INTERMEDIATE_CA = ${CREATE_INTERMEDIATE_CA}"
if [ "${CREATE_INTERMEDIATE_CA}" == "TRUE" ]
then
echo "## Create Intermediate CA"
if [ "${INTERMEDIATE_CA_EXISTS}" != "TRUE" ]
then
# Define the v3 extension that will be included in the intermediate certificate
echo "## Create v3 extension file for Intermediate CA Certificate"
echo "[ v3_req ]" > v3_ext.cnf
echo "basicConstraints = CA:TRUE, pathlen:0" >> v3_ext.cnf
echo "keyUsage = critical, digitalSignature, keyCertSign" >> v3_ext.cnf
if [ "${INTERMEDIATE_CA_ENC_TYPE}" == "RSA" ]
then
echo "## RSA Encryption type is not supported yet."
exit 10
else
# ECC Intemediate Certificates
if [ ! -e ${intercaKey} ]
then
# Create both the CA keypair and CA certificate
# The intermediate CA is ECC using curve defined in INTERMEDIATE_CA_ECC_CURVE variable
echo "## Create ECC intermediate CA Key: (${intercaKey}) Curve: (${INTERMEDIATE_CA_ECC_CURVE})"
xCmd "openssl ecparam -genkey -name ${INTERMEDIATE_CA_ECC_CURVE} -out ${intercaKey}"
echo "## Create ECC Intermediate CA CSR: (${intercaCsr})"
openssl req -new -key ${intercaKey} -out ${intercaCsr} -subj "/CN=${INTERMEDIATE_CA_CN}"
echo "## Sign Intermediate CA CSR with (${rootcaCert})"
openssl x509 -req -days ${CA_CERT_VALIDITY} -in ${intercaCsr} ${x509_serial} -CA ${rootcaCert} \
-CAkey ${rootcaKey} -extfile ./v3_ext.cnf -extensions v3_req -out ${intercaCert}
fi
if [ ! -e ${intercaCert} ]; then
echo "## Create ECC Intermediate CA CSR: (${intercaCsr})"
openssl req -new -key ${intercaKey} -out ${intercaCsr} -subj "/CN=${INTERMEDIATE_CA_CN}"
echo "## Sign Intermediate CA CSR with (${rootcaCert})"
openssl x509 -req -days ${CA_CERT_VALIDITY} -in ${intercaCsr} ${x509_serial} -CA ${rootcaCert} \
-CAkey ${rootcaKey} -extfile ./v3_ext.cnf -extensions v3_req -out ${intercaCert}
fi
fi
else
# Check whether Intermediate CA key and certificate are present.
if [ ! -e ${intercaKey} ]; then
if [ "${INTERMEDIATE_CA_ENC_TYPE}" == "RSA" ]; then
echo "## RSA Encryption type is not supported yet."
else
echo "## No ECC Intermediate CA Key available (${intercaKey})"
fi
exit 11
fi
if [ ! -e ${intercaCert} ]; then
if [ "${INTERMEDIATE_CA_ENC_TYPE}" == "RSA" ]; then
echo "## RSA Encryption type is not supported yet."
else
echo "## No ECC Intermediate CA Certificate available (${intercaCert})"
fi
exit 12
fi
fi
SIGN_BY_INTERMEDIATE_CA="TRUE"
fi
############################################
# Create key and device/gateway certificates
############################################
if [ "${SIGN_BY_INTERMEDIATE_CA}" == "TRUE" ]; then
# Create Chain of CA Certificates for WIoTP CA Certificate upload step
cat ${intercaCert} ${rootcaCert} > ${chaincaCert}
fi
# Create serial number of gateway and device certificates
# for device 1${SE_UID}
# for gateway 2${SE_UID}
deviceSerial="0x01${SE_UID}"
gatewaySerial="0x02${SE_UID}"
# Unique ID Key, reference key and CSR files
uidKey="${SE_UID}.key"
uidRefKey="${SE_UID}_ref.pem"
uidCsr="${SE_UID}.csr"
# Device certificate
deviceCert="${SE_UID}_device_ec_pem.crt"
deviceCertAscii="${SE_UID}_device_ec_crt_ascii_dump.txt"
# Gateway certificate
gatewayCert="${SE_UID}_gateway_ec_pem.crt"
gatewayCertAscii="${SE_UID}_gateway_ec_crt_ascii_dump.txt"
echo "## Preparing device certificate ${deviceCert}"
CN_val="${SE_UID}"
GENERIC_val="URI:NXP:${SE_UID}"
SAN_D_val="email:d:${devType}:${SE_UID}, ${GENERIC_val}"
SAN_G_val="email:g:${gwType}:${SE_UID}, ${GENERIC_val}"
echo "## CN=${CN_val}"
echo "## SAN_D_VAL=${SAN_D_val}"
echo "## SAN_G_VAL=${SAN_G_val}"
# Create a device key pair & CSR
xCmd "openssl ecparam -genkey -name prime256v1 -out ${uidKey}"
openssl req -new -key ${uidKey} -out ${uidCsr} -subj "/CN=${CN_val}"
# Define the v3 extension that will be included in the device certificate
echo "[ v3_req ]" > v3_ext.cnf
echo "" >> v3_ext.cnf
echo "# Extensions to add to a certificate request" >> v3_ext.cnf
echo "" >> v3_ext.cnf
echo "basicConstraints = CA:FALSE" >> v3_ext.cnf
echo "# keyUsage = nonRepudiation, digitalSignature, keyEncipherment" >> v3_ext.cnf
echo "keyUsage = digitalSignature" >> v3_ext.cnf
echo "subjectAltName = ${SAN_D_val}" >> v3_ext.cnf
if [ "${SIGN_BY_INTERMEDIATE_CA}" == "TRUE" ]; then
# Create a Cert signed by Intermediate CA
xCmd "openssl x509 -req -days ${CLIENT_CERT_VALIDITY} -in ${uidCsr} -set_serial ${deviceSerial} -CA ${intercaCert} -CAkey ${intercaKey} \
-extfile ./v3_ext.cnf -extensions v3_req -out ${deviceCert}"
else
# Create a Cert signed by Root CA
xCmd "openssl x509 -req -days ${CLIENT_CERT_VALIDITY} -in ${uidCsr} -set_serial ${deviceSerial} -CA ${rootcaCert} -CAkey ${rootcaKey} \
-extfile ./v3_ext.cnf -extensions v3_req -out ${deviceCert}"
fi
openssl x509 -in ${deviceCert} -text -noout > ${deviceCertAscii}
echo "## Device certificate ${deviceCert} created successfully"
# Define the v3 extension that will be included in the gateway certificate
echo "[ v3_req ]" > v3_ext.cnf
echo "" >> v3_ext.cnf
echo "# Extensions to add to a certificate request" >> v3_ext.cnf
echo "" >> v3_ext.cnf
echo "basicConstraints = CA:FALSE" >> v3_ext.cnf
echo "# keyUsage = nonRepudiation, digitalSignature, keyEncipherment" >> v3_ext.cnf
echo "keyUsage = digitalSignature" >> v3_ext.cnf
echo "subjectAltName = ${SAN_G_val}" >> v3_ext.cnf
if [ "${SIGN_BY_INTERMEDIATE_CA}" == "TRUE" ]; then
# Create a Cert signed by Intermediate CA
xCmd "openssl x509 -req -days ${CLIENT_CERT_VALIDITY} -in ${uidCsr} -set_serial ${gatewaySerial} -CA ${intercaCert} -CAkey ${intercaKey} \
-extfile ./v3_ext.cnf -extensions v3_req -out ${gatewayCert}"
else
# Create a Cert signed by Root CA
xCmd "openssl x509 -req -days ${CLIENT_CERT_VALIDITY} -in ${uidCsr} -set_serial ${gatewaySerial} -CA ${rootcaCert} -CAkey ${rootcaKey} \
-extfile ./v3_ext.cnf -extensions v3_req -out ${gatewayCert}"
fi
openssl x509 -in ${gatewayCert} -text -noout > ${gatewayCertAscii}
echo "## Gateway certificate ${gatewayCert} created successfully"
###########################################
# Create config tool script and execute it.
###########################################
configScript="${SE_UID}_se050ConfigScript.sh"
echo "## Create config tool script ${configScript}"
echo "# ################################################" > ${configScript}
echo "# Name: ${configScript}" >> ${configScript}
echo "# Revision 0.9" >> ${configScript}
echo "# Purpose: Provision SE050 matching UID ("${SE_UID}") for Watson IoT" >> ${configScript}
echo "# Pre-condition: " >> ${configScript}
echo "# Post-condition: keypair and certificate injected" >> ${configScript}
echo "# ################################################" >> ${configScript}
echo "ssscli disconnect" >> ${configScript}
echo "ssscli connect se05x t1oi2c none" >> ${configScript}
echo "ssscli se05x reset # Bring secure element in its original state" >> ${configScript}
echo "# key_id=\"0x7DC1B000\"" >> ${configScript}
echo "ssscli set ecc pair 0x7DC1B000 ${uidKey} --format PEM" >> ${configScript}
echo "ssscli refpem ecc pair 0x7DC1B000 ${uidRefKey} # Creates the reference key on the file system" >> ${configScript}
# echo "# dev_cert_id=\"0x7DC1B010\"" >> ${configScript}
# echo "ssscli set cert 0x7DC1B010 ${deviceCert}" >> ${configScript}
# echo "# gw_cert_id=\"0x7DC1B011\"" >> ${configScript}
# echo "ssscli set cert 0x7DC1B011 ${gatewayCert}" >> ${configScript}
# ssscli set cert [OPTIONS] KEYID KEY
# xCmd "${A71CH_CONFIG_TOOL} script -f ${configScript}"
# echo "## Successfully configured A71CH sample ${SE_UID}"
exit 0