From 5be2f7aeb4a762744e4bea16b287235b0fa0222f Mon Sep 17 00:00:00 2001 From: "Akhilesh Kr. Yadav" Date: Sat, 8 Feb 2025 18:09:44 +0530 Subject: [PATCH] feat: adds 3-level certificate chain generation script Signed-off-by: Akhilesh Kr. Yadav Signed-off-by: Akhilesh Kr. Yadav --- Makefile | 6 ++ misc/endEntity.der | Bin 0 -> 385 bytes misc/endEntity.key | 5 ++ misc/intermediateCA.der | Bin 0 -> 371 bytes misc/rootCA.der | Bin 0 -> 385 bytes scripts/gen-certs.sh | 161 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 172 insertions(+) create mode 100644 misc/endEntity.der create mode 100644 misc/endEntity.key create mode 100644 misc/intermediateCA.der create mode 100644 misc/rootCA.der create mode 100644 scripts/gen-certs.sh diff --git a/Makefile b/Makefile index 28ec37d..140ecc1 100644 --- a/Makefile +++ b/Makefile @@ -49,6 +49,11 @@ presubmit: .PHONY: licenses licenses: ; @./scripts/licenses.sh +.PHONY: certs +certs: + @echo "Generating certificate chain..." + @$(SHELL) scripts/gen-certs.sh create + .PHONY: help help: @echo "Available targets:" @@ -58,3 +63,4 @@ help: @echo " * presubmit: check you are ready to push your local branch to remote" @echo " * help: print this menu" @echo " * licenses: check licenses of dependent packages" + @echo " * certs: generate the certificate chain" diff --git a/misc/endEntity.der b/misc/endEntity.der new file mode 100644 index 0000000000000000000000000000000000000000..5a4d8a7d123a711963e72d22f76beb8602ebf688 GIT binary patch literal 385 zcmXqLVyrc2VpLkd%*4pVBx162jwb7;X`YIG>rst&=8AKWgv$2D1Vq%0^$;`;k?8LxwJ3;ZR*q#q77C62B zR?^#{dnre!dD*r#mx6Xze|7%<{d`~I!IB4HrbAmVuH zWZkQNomVS)vR}PY-&9>x_WLJtFfe;E7`QPhGMqN+?p_pj=HSc6Ukh5A?yrAkuOSe2 zWv#Ah__^!tIlG?#mHa#OXzNvNSze|LuLIW$)ck*D9a{NH`u>$$k;+MBKlr2o;*gC$ literal 0 HcmV?d00001 diff --git a/misc/endEntity.key b/misc/endEntity.key new file mode 100644 index 0000000..bc3b906 --- /dev/null +++ b/misc/endEntity.key @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEICoAlM1RuYHR4AdyqUgP6o4rx9XlNa3aj8fBqrTboTSvoAoGCCqGSM49 +AwEHoUQDQgAE22AhzRa88KigQuv2dI2ILdJsLIOmtqzSUrt79UP/98+OYeFclOED +NjdahFsdZcZ9tyUEUF3I23Prl1RMszEh/Q== +-----END EC PRIVATE KEY----- diff --git a/misc/intermediateCA.der b/misc/intermediateCA.der new file mode 100644 index 0000000000000000000000000000000000000000..f84f448c05b9fc622ba97501d227671780400e53 GIT binary patch literal 371 zcmXqLV$3&aViZ}x%*4pVBqAg9-`vfOgHtirT~k~rdam2#m?s8YY#dr`9_MUXn3)Vj z4228?*qB3En0YuIlXFuQJoA$E4CKUljZ6)U3=Is;jV(-!qr`cQ4GfG7ETLQjF+&jp zA&4$+urBw^s@(iygGd8mHg>StOpH)Vm>Jobofuf=>hZ5Al9zh_?eB-r@=J1pnyn4F z_h_2)zdHGnVMW*Vmk#ffqXiipr@nru``6s1CH|VzIyW=J{B<+5yw*}>t6NiyjsbV{pywars|@y-#-oHLDI@B5(Z)oB5a>$GfT;`MQ0q4 z?|Qt>-=jfuYcI0LnLQZ{+?W&@rf2S{UYL2e((1|EQv2=({%eaSnng_(!bF*!F?!80#e&p=L`*T~es$k4#h+}OgzI7*z?7|1oSfO2u@iZl>r zV+Whe#0a&5nUS5@iGk(m$<5_C+VM*~S26~lp7W~t>^99SC(JojwZwnr?EF<_JcqgS zaf|Z3O;YwuIcs@sR$u5T&y5qi+w2&j|R=Hy$13iX=N4(1F;6|3iv?^gc%wCv#=U411aQiVD?}zaAi`+`*~b# z<(z}}v%HRZ&&iheOAU>Vez&3T@XCc}S)^6 literal 0 HcmV?d00001 diff --git a/scripts/gen-certs.sh b/scripts/gen-certs.sh new file mode 100644 index 0000000..2f05bdf --- /dev/null +++ b/scripts/gen-certs.sh @@ -0,0 +1,161 @@ +#!/bin/bash +# SPDX-License-Identifier: Apache-2.0 +set -e + +ROOT_CERT_NAME=rootCA +INTERMEDIATE_CERT_NAME=intermediateCA +END_ENTITY_CERT_NAME=endEntity + +THIS_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +MISC_DIR="$THIS_DIR/../misc" + +mkdir -p "$MISC_DIR" + +function create_root_cert() { + if [[ -f "${MISC_DIR}/${ROOT_CERT_NAME}.der" ]]; then + echo "Root certificate already exists. Skipping creation." + return + fi + openssl ecparam -name prime256v1 -genkey -noout -out ${MISC_DIR}/${ROOT_CERT_NAME}.key + openssl req -x509 -new -nodes -key ${MISC_DIR}/${ROOT_CERT_NAME}.key -sha256 -days 3650 \ + -subj "/CN=Acme Inc." -out ${MISC_DIR}/${ROOT_CERT_NAME}.crt + openssl x509 -in ${MISC_DIR}/${ROOT_CERT_NAME}.crt -outform der -out ${MISC_DIR}/${ROOT_CERT_NAME}.der + rm -f ${MISC_DIR}/${ROOT_CERT_NAME}.crt # Remove the PEM certificate + echo "Created ${MISC_DIR}/${ROOT_CERT_NAME}.der and ${MISC_DIR}/${ROOT_CERT_NAME}.key" +} + +function create_intermediate_cert() { + if [[ -f "${MISC_DIR}/${INTERMEDIATE_CERT_NAME}.der" ]]; then + echo "Intermediate certificate already exists. Skipping creation." + return + fi + openssl ecparam -name prime256v1 -genkey -noout -out ${MISC_DIR}/${INTERMEDIATE_CERT_NAME}.key + openssl req -new -key ${MISC_DIR}/${INTERMEDIATE_CERT_NAME}.key -out ${MISC_DIR}/${INTERMEDIATE_CERT_NAME}.csr -subj "/CN=Acme Gizmos" + openssl x509 -req -in ${MISC_DIR}/${INTERMEDIATE_CERT_NAME}.csr -CA ${MISC_DIR}/${ROOT_CERT_NAME}.der -CAkey ${MISC_DIR}/${ROOT_CERT_NAME}.key -CAcreateserial -out ${MISC_DIR}/${INTERMEDIATE_CERT_NAME}.crt -days 1825 -sha256 + openssl x509 -in ${MISC_DIR}/${INTERMEDIATE_CERT_NAME}.crt -outform der -out ${MISC_DIR}/${INTERMEDIATE_CERT_NAME}.der + rm -f ${MISC_DIR}/${INTERMEDIATE_CERT_NAME}.crt # Remove the PEM certificate + echo "Created ${MISC_DIR}/${INTERMEDIATE_CERT_NAME}.der and ${MISC_DIR}/${INTERMEDIATE_CERT_NAME}.key" +} + +function create_end_entity_cert() { + if ([[ -f "${MISC_DIR}/${END_ENTITY_CERT_NAME}.der" ]] && [[ -f "${MISC_DIR}/${END_ENTITY_CERT_NAME}.key" ]]); then + echo "End-entity certificate and key already exist. Skipping creation." + return + fi + openssl ecparam -name prime256v1 -genkey -noout -out ${MISC_DIR}/${END_ENTITY_CERT_NAME}.key + openssl req -new -key ${MISC_DIR}/${END_ENTITY_CERT_NAME}.key -out ${MISC_DIR}/${END_ENTITY_CERT_NAME}.csr -subj "/CN=Acme Gizmo CoRIM signer" + openssl x509 -req -in ${MISC_DIR}/${END_ENTITY_CERT_NAME}.csr -CA ${MISC_DIR}/${INTERMEDIATE_CERT_NAME}.der -CAkey ${MISC_DIR}/${INTERMEDIATE_CERT_NAME}.key -CAcreateserial -out ${MISC_DIR}/${END_ENTITY_CERT_NAME}.crt -days 825 -sha256 -CAform der + openssl x509 -in ${MISC_DIR}/${END_ENTITY_CERT_NAME}.crt -outform der -out ${MISC_DIR}/${END_ENTITY_CERT_NAME}.der + rm -f ${MISC_DIR}/${END_ENTITY_CERT_NAME}.crt # Remove the PEM certificate + echo "Created ${MISC_DIR}/${END_ENTITY_CERT_NAME}.der and ${MISC_DIR}/${END_ENTITY_CERT_NAME}.key" +} + +function clean_intermediate() { + pushd "$MISC_DIR" > /dev/null || exit 1 + echo "rm -f -- *.csr *.srl" + rm -f -- *.csr *.srl + popd > /dev/null || exit 1 +} + +function clean_cert() { + pushd "$MISC_DIR" > /dev/null || exit 1 + local cert="$1" + echo "rm -f \"${cert}.der\" \"${cert}.key\"" + rm -f "${cert}.der" "${cert}.key" + popd > /dev/null || exit 1 +} + +function clean_all() { + clean_intermediate + clean_cert "$ROOT_CERT_NAME" + clean_cert "$INTERMEDIATE_CERT_NAME" + clean_cert "$END_ENTITY_CERT_NAME" +} + +function help() { + set +e + read -r -d '' usage <<-EOF + Usage: gen-certs [-h] [-C] [COMMAND] + + This script is used to (re-)generate certificates used for a veraison + deployment. The certificates are signed by a CA certificate called + ${ROOT_CERT_NAME}.crt. If this does not exist, a self-signed one will + be generated. + + Commands: + + create + Create the root, intermediate, and end-entity certificates. + + clean + Clean output artifacts for the certificates. + + clean_all + Clean both intermediate and output artifacts for everything (including + the root CA cert). + + help + Print this message and exit (same as -h option). + + Options: + + -h Print this message and exit. + -C Do not clean up intermediate artifacts (e.g., CSRs). + +EOF + + echo "$usage" +} + +function _check_openssl() { + if [[ "$(which openssl 2>/dev/null)" == "" ]]; then + echo -e "ERROR: openssl executable must be installed to use this command." + exit 1 + fi +} + +function _check_root_cert() { + if [[ ! -f "${MISC_DIR}/${ROOT_CERT_NAME}.der" ]]; then + create_root_cert + fi +} + +_should_clean_intermediate=true + +OPTIND=1 + +while getopts "hC" opt; do + case "$opt" in + h) help; exit 0;; + C) _should_clean_intermediate=false;; + *) break;; + esac +done + +shift $((OPTIND-1)) +[ "${1:-}" = "--" ] && shift + +command=$1 +case $command in + help) + help + exit 0 + ;; + clean) + clean_intermediate + ;; + clean_all) + clean_all + ;; + create) + create_root_cert + create_intermediate_cert + create_end_entity_cert + if [[ $_should_clean_intermediate == true ]]; then + clean_intermediate + fi + ;; + *) + echo -e "ERROR: unexpected command: \"$command\" (use -h for help)" + ;; +esac \ No newline at end of file