From c0b514f1aca78a84891c3202e3417a8fe98c6ad5 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Tue, 13 Aug 2019 14:50:45 -0700 Subject: create-user-key-store.sh: Update for OSTree and ease of use The create-user-key-store.sh was changed in a number ways to improve the usability with other layers that will consume the key services provided by meta-secure-core. New features: * A safety check was added that keys can only be written to a fresh empty directory. * The script can be run non-iteractively or interactively for the ease of use. * gpg 1.x support and gpg 2.x support work with the passphrases * A keys.conf is generated to allow a single line to be written into the local.conf with all the keys. An interactive session looks like: ================================== ./create-user-key-store.sh -d /tmp/test KEYS_DIR: /tmp/test Enter RPM/OSTree GPG keyname (use dashes instead of spaces) [default: PKG-SecureCore]: PKG-Sample-Man Enter RPM/OSTree GPG e-mail address [default: SecureCore@foo.com]: sample.man@sample.com Enter RPM/OSTREE GPG comment [default: Signing Key]: Sample Signing Key Using boot loader gpg name: BOOT-Sample-Man Using boot loader gpg email: sample.man@sample.com Using boot loader gpg comment: Sample Signing Key Press control-c now if and use -bn -bm -bc arguments if you want different values other than listed above Enter RPM/OSTREE passphrase: abc1234 Enter IMA passphrase: 1234pass Enter boot loader GPG passphrase: bootup Enter boot loader locked configuration password(e.g. grub pw): root MASTER_KEYS_DIR = "/tmp/test" IMA_KEYS_DIR = "${MASTER_KEYS_DIR}/ima_keys" IMA_EVM_KEY_DIR = "${MASTER_KEYS_DIR}/ima_keys" RPM_KEYS_DIR = "${MASTER_KEYS_DIR}/rpm_keys" BOOT_KEYS_DIR = "${MASTER_KEYS_DIR}/boot_keys" MOK_SB_KEYS_DIR = "${MASTER_KEYS_DIR}/mok_sb_keys" SYSTEM_TRUSTED_KEYS_DIR = "${MASTER_KEYS_DIR}/system_trusted_keys" UEFI_SB_KEYS_DIR = "${MASTER_KEYS_DIR}/uefi_sb_keys" GRUB_PUB_KEY = "${MASTER_KEYS_DIR}/boot_keys/boot_pub_key" GRUB_PW_FILE = "${MASTER_KEYS_DIR}/boot_keys/boot_cfg_pw" OSTREE_GPGDIR = "${MASTER_KEYS_DIR}/rpm_keys" RPM_GPG_NAME = "PKG-Sample-Man" RPM_GPG_PASSPHRASE = "abc1234" RPM_FSK_PASSWORD = "1234pass" BOOT_GPG_NAME = "BOOT-Sample-Man" BOOT_GPG_PASSPHRASE = "bootup" OSTREE_GPGID = "PKG-Sample-Man" OSTREE_GPG_PASSPHRASE = "abc1234" OSTREE_GRUB_PW_FILE = "${GRUB_PW_FILE}" [ Issue: LINUXEXEC-2450 ] Signed-off-by: Jason Wessel --- meta-signing-key/scripts/create-user-key-store.sh | 377 ++++++++++++++++++---- 1 file changed, 306 insertions(+), 71 deletions(-) diff --git a/meta-signing-key/scripts/create-user-key-store.sh b/meta-signing-key/scripts/create-user-key-store.sh index eea52df..7d224fc 100755 --- a/meta-signing-key/scripts/create-user-key-store.sh +++ b/meta-signing-key/scripts/create-user-key-store.sh @@ -7,6 +7,20 @@ ROOT_DIR="`cd "$_D" && pwd`" KEYS_DIR="$ROOT_DIR/user-keys" GPG_KEYNAME= GPG_EMAIL= +GPG_COMMENT= +BOOT_GPG_KEYNAME= +BOOT_GPG_EMAIL= +BOOT_GPG_COMMENT= +EMPTY_PW=0 +GPG_PASS= +GPG_BIN=${GPG_BIN=gpg} +IMA_PASS= +gpg_key_name="PKG-SecureCore" +gpg_email="SecureCore@foo.com" +gpg_comment="Signing Key" +boot_gpg_key_name="BOOT-SecureCore" +boot_gpg_email="SecureCore@foo.com" +boot_gpg_comment="Bootloader Signing Key" function show_help() { @@ -14,6 +28,7 @@ function show_help() $1 - creation tool for user key store (C)Copyright 2017, Jia Zhang +(C)Copyright 2019, Jason Wessel Wind River Systems, Inc. Usage: $1 options... @@ -21,21 +36,37 @@ Options: -d Set the path to save the generated user keys. Default: `pwd`/user-keys - + -c + Set the RPM/OStree gpg's key name + Default: $gpg_comment -n - Set the gpg's key name - Default: SecureCore - - -m - Set the ower's email address of the gpg key - Default: SecureCore@foo.com - - -h|--help - Show this help information. + Set the RPM/OStree gpg's key name + Default: $gpg_key_name + -m + Set the RPM/OStree owner's email address of the gpg key + Default: $gpg_email + -rp + -bgp + -bp + -ip + -h|--help Show this help information. +Overides: + -bc + Force set the gpg key comment for the boot loader + -bn + Force set the gpg key name for the boot loader + -bm + Force set the gpg email address for the boot loader EOF } +print_fatal() { + printf "\033[1;35m" + echo "$@" + printf "\033[0m" + exit 1 +} print_critical() { printf "\033[1;35m" echo "$@" @@ -72,19 +103,42 @@ while [ $# -gt 0 ]; do -d) shift && KEYS_DIR="$1" ;; + -c) + shift && GPG_COMMENT="$1" + ;; + -bc) + shift && BOOT_GPG_COMMENT="$1" + ;; -n) shift && GPG_KEYNAME="$1" ;; + -bn) + shift && BOOT_GPG_KEYNAME="$1" + ;; -m) shift && GPG_EMAIL="$1" ;; + -bm) + shift && BOOT_GPG_EMAIL="$1" + ;; + -rp) + shift && GPG_PASS="$1" + ;; + -bgp) + shift && BOOT_GPG_PASS="$1" + ;; + -bp) + shift && BOOT_PASS="$1" + ;; + -ip) + shift && IMA_PASS="$1" + ;; -h|--help) show_help `basename $0` exit 0 ;; *) - echo "Unsupported option $opt" - exit 1 + print_fatal "Unsupported option $opt" ;; esac shift @@ -97,6 +151,7 @@ MOK_SB_KEYS_DIR="$KEYS_DIR/mok_sb_keys" SYSTEM_KEYS_DIR="$KEYS_DIR/system_trusted_keys" IMA_KEYS_DIR="$KEYS_DIR/ima_keys" RPM_KEYS_DIR="$KEYS_DIR/rpm_keys" +BOOT_KEYS_DIR="$KEYS_DIR/boot_keys" MODSIGN_KEYS_DIR="$KEYS_DIR/modsign_keys" SECONDARY_TRUSTED_KEYS_DIR="$KEYS_DIR/secondary_trusted_keys" @@ -121,22 +176,39 @@ ca_sign() { -sha256 -nodes -days 3650 \ -subj "$subject" \ -keyout "$key_dir/$key_name.key" \ - -out "$key_dir/$key_name.crt" + -out "$key_dir/$key_name.crt" \ + || print_fatal "openssl failure" else if [ -z "$encrypted" ]; then openssl req -new -newkey rsa:2048 \ -sha256 -nodes \ -subj "$subject" \ -keyout "$key_dir/$key_name.key" \ - -out "$key_dir/$key_name.csr" + -out "$key_dir/$key_name.csr" \ + || print_fatal "openssl failure" else # Prompt user to type the password - openssl genrsa -des3 -out "$key_dir/$key_name.key" 2048 + if [ "$IMA_PASS" = "" ] ; then + openssl genrsa -des3 -out "$key_dir/$key_name.key" 2048 \ + || print_fatal "openssl failure" + + openssl req -new -sha256 \ + -subj "$subject" \ + -key "$key_dir/$key_name.key" \ + -out "$key_dir/$key_name.csr" \ + || print_fatal "openssl failure" + else + openssl genrsa -des3 -passout "pass:$IMA_PASS" \ + -out "$key_dir/$key_name.key" 2048 \ + || print_fatal "openssl failure" + + openssl req -new -sha256 -passin "pass:$IMA_PASS" \ + -subj "$subject" \ + -key "$key_dir/$key_name.key" \ + -out "$key_dir/$key_name.csr" \ + || print_fatal "openssl failure" + fi - openssl req -new -sha256 \ - -subj "$subject" \ - -key "$key_dir/$key_name.key" \ - -out "$key_dir/$key_name.csr" fi local ca_cert="$ca_key_dir/$ca_key_name.crt" @@ -153,7 +225,8 @@ ca_sign() { -CAkey "$ca_key_dir/$ca_key_name.key" \ -set_serial 1 -days 3650 \ -extfile "$ROOT_DIR/openssl.cnf" -extensions v3_req \ - -out "$key_dir/$key_name.crt" + -out "$key_dir/$key_name.crt" \ + || print_fatal "openssl failure" rm -f "$key_dir/$key_name.csr" fi @@ -222,69 +295,74 @@ create_ima_user_key() { rm -f "$key_dir/x509_ima.crt" } -create_rpm_user_key() { - local gpg_ver=`gpg --version | head -1 | awk '{ print $3 }' | awk -F. '{ print $1 }'` - local key_dir="$RPM_KEYS_DIR" - - [ ! -d "$key_dir" ] && mkdir -m 0700 -p "$key_dir" - - local gpg_key_name="SecureCore" - local gpg_email="SecureCore@foo.com" - - if [ ! -z $GPG_KEYNAME ]; then - gpg_key_name=$GPG_KEYNAME - fi - - if [ ! -z $GPG_EMAIL ]; then - gpg_email=$GPG_EMAIL - fi +create_boot_pw_key() { + local bootprog=`which grub-mkpasswd-pbkdf2` + if [ "$bootprog" = "" ] ; then + print_fatal "ERROR could not locate \"grub-mkpasswd-pbkdf2\" please install it or set the path to the host native sysroot" + fi + (echo "$BOOT_PASS"; echo "$BOOT_PASS") | $bootprog > $BOOT_KEYS_DIR/boot_cfg_pw.tmp + if [ $? != 0 ] ; then + print_fatal "ERROR failed to run grub-mkpasswd-mpkdf2 to generate password" + fi + cat $BOOT_KEYS_DIR/boot_cfg_pw.tmp |grep grub.pbkdf2 |sed -e 's/.*grub.pbkdf2/grub.pbkdf2/' > $BOOT_KEYS_DIR/boot_cfg_pw + rm -f $BOOT_KEYS_DIR/boot_cfg_pw.tmp - local priv_key="$key_dir/RPM-GPG-PRIVKEY-$gpg_key_name" - local pub_key="$key_dir/RPM-GPG-KEY-$gpg_key_name" +} - if [ "$gpg_ver" == "2" ]; then - gpg --homedir "$key_dir" --quick-generate-key --batch \ - "$gpg_key_name" default default never +create_gpg_user_key() { + local gpg_ver=`$GPG_BIN --version | head -1 | awk '{ print $3 }' | awk -F. '{ print $1 }'` + local key_dir="$1" - gpg --homedir "$key_dir" --export --armor "$gpg_key_name" > "$pub_key" + [ ! -d "$key_dir" ] && mkdir -m 0700 -p "$key_dir" - gpg --homedir "$key_dir" --export-secret-keys --armor "$gpg_key_name" > "$priv_key" + local priv_key="$key_dir/$2-GPG-PRIVKEY-$3" + local pub_key="$key_dir/$2-GPG-KEY-$3" + local name_real="$3" + local USE_PW="Passphrase: $4" + local pw="$4" + local comment="$5" + local email="$6" - cd "$key_dir" - rm -rf openpgp-revocs.d private-keys-v1.d pubring.kbx* \ - trustdb.gpg - cd - - else - cat >"$key_dir/gen_rpm_keyring" <"$key_dir/gen_keyring" < $key_dir/gpg-agent.conf + gpg-connect-agent --homedir "$key_dir" reloadagent /bye + fi + $GPG_BIN --homedir "$key_dir" --batch --yes --gen-key "$key_dir/gen_keyring" + if [ $? != 0 ] ; then + print_fatal "Error with keyring generation" + fi - print_error "Please type passwd to modify the passphrase, and type quit to exit" + $GPG_BIN --homedir "$key_dir" -k - $gpg --edit-key "$gpg_key_name" + $GPG_BIN --homedir "$key_dir" --export --armor "$name_real" > "$pub_key" || print_fatal "gpg export failed" + if [ "$2" = "BOOT" ] ; then + $GPG_BIN --homedir "$key_dir" --export "$name_real" > "$key_dir/boot_pub_key" || print_fatal "gpg export failed" + fi - $gpg --export --armor "$gpg_key_name" > "$pub_key" - $gpg --export-secret-keys --armor "$gpg_key_name" > "$priv_key" + $GPG_BIN --homedir "$key_dir" --export-secret-keys $pinentry --passphrase "$pw" --armor "$3" > "$priv_key" || print_fatal "gpg export failed" - rm -f "$key_dir/gen_rpm_keyring" - rm -f "$priv_key.sec" "$pub_key.pub" - fi + rm -f "$key_dir/gen_keyring" + cd "$key_dir" + rm -rf openpgp-revocs.d private-keys-v1.d pubring.kbx* \ + trustdb.gpg* random_seed pubring.gpg* secring.gpg* gpg-agent.conf + cd - } create_user_keys() { @@ -306,9 +384,166 @@ create_user_keys() { echo "Creating the user key for IMA appraisal" create_ima_user_key - echo "Creating the user key for RPM" - create_rpm_user_key + echo "Creating the gpg key for RPM/OSTree" + create_gpg_user_key "$RPM_KEYS_DIR" RPM "$gpg_key_name" "$GPG_PASS" "$gpg_comment" "$gpg_email" + + echo "Creating the gpg key for boot loader" + create_gpg_user_key "$BOOT_KEYS_DIR" BOOT "$boot_gpg_key_name" "$BOOT_GPG_PASS" "$boot_gpg_comment" "$boot_gpg_email" + + echo "Creating the password salt for boot" + create_boot_pw_key } +if [ -d "$KEYS_DIR" ] ; then + print_fatal "ERROR: $KEYS_DIR already exists, please remove it, to allow for the creation of new keys." +fi + +if [ ! -z "$GPG_KEYNAME" ]; then + gpg_key_name="$GPG_KEYNAME" +else + echo -n "Enter RPM/OSTree GPG keyname (use dashes instead of spaces) [default: $gpg_key_name]: " + read val + if [ ! -z "$val" ] ; then + gpg_key_name=$val + fi +fi + +if [ ! -z "$GPG_EMAIL" ]; then + gpg_email=$GPG_EMAIL +else + echo -n "Enter RPM/OSTree GPG e-mail address [default: $gpg_email]: " + read val + if [ ! -z "$val" ] ; then + gpg_email=$val + fi +fi + +if [ ! -z "$GPG_COMMENT" ]; then + gpg_comment=$GPG_COMMENT +else + echo -n "Enter RPM/OSTREE GPG comment [default: $gpg_comment]: " + read val + if [ ! -z "$val" ] ; then + gpg_comment=$val + fi +fi + +boot_gpg_key_name="BOOT-${gpg_key_name#PKG-}" +boot_gpg_email="$gpg_email" +boot_gpg_comment="$gpg_comment" +if [ ! -z "$BOOT_GPG_KEYNAME" ]; then + boot_gpg_key_name="$BOOT_GPG_KEYNAME" +fi +if [ ! -z "$BOOT_GPG_EMAIL" ]; then + boot_gpg_email=$BOOT_GPG_EMAIL +fi +if [ ! -z "$BOOT_GPG_COMMENT" ]; then + boot_gpg_comment=$BOOT_GPG_COMMENT +fi + +echo " Using boot loader gpg name: $boot_gpg_key_name" +echo " Using boot loader gpg email: $boot_gpg_email" +echo " Using boot loader gpg comment: $boot_gpg_comment" +echo " Press control-c now if and use -bn -bm -bc arguments if you want" +echo " different values other than listed above" + +# Sanity checks on values so far + +if [ "$boot_gpg_key_name" = "$gpg_key_name" ] ; then + echo "===================================" + echo " RPM_GPG_NAME = \"$gpg_key_name\"" + echo " BOOT_GPG_NAME = \"$boot_gpg_key_name\"" + print_fatal "ERROR: The gpg key names must be unique" +fi +if [ "$boot_gpg_key_name" != "${boot_gpg_key_name/$gpg_key_name/}" ] ; then + echo "===================================" + echo " RPM_GPG_NAME = \"$gpg_key_name\"" + echo " BOOT_GPG_NAME = \"$boot_gpg_key_name\"" + print_fatal "ERROR: The RPM/OSTree gpg key name cannot be a subset of the boot loader gpg key name" +fi +if [ "$gpg_key_name" != "${gpg_key_name/$boot_gpg_key_name/}" ] ; then + echo "===================================" + echo " RPM_GPG_NAME = \"$gpg_key_name\"" + echo " BOOT_GPG_NAME = \"$boot_gpg_key_name\"" + print_fatal "ERROR: The boot loader gpg key name cannot be a subset of the RPM/OSTREE gpg key name" +fi + +# Passwor section next +if [ -z $GPG_PASS ]; then + while [ 1 ] ; do + echo -n "Enter RPM/OSTREE passphrase: " + read val + if [ ! -z "$val" ] ; then + GPG_PASS=$val + break + fi + done +fi +if [ -z $IMA_PASS ]; then + while [ 1 ] ; do + echo -n "Enter IMA passphrase: " + read val + if [ ! -z "$val" ] ; then + IMA_PASS=$val + break + fi + done +fi +if [ -z $BOOT_GPG_PASS ]; then + while [ 1 ] ; do + echo -n "Enter boot loader GPG passphrase: " + read val + if [ ! -z "$val" ] ; then + BOOT_GPG_PASS=$val + break + fi + done +fi +if [ -z $BOOT_PASS ]; then + while [ 1 ] ; do + echo -n "Enter boot loader locked configuration password(e.g. grub pw): " + read val + if [ ! -z "$val" ] ; then + BOOT_PASS=$val + break + fi + done +fi + create_user_keys +cat <$KEYS_DIR/keys.conf +MASTER_KEYS_DIR = "$(readlink -f $KEYS_DIR)" + +IMA_KEYS_DIR = "\${MASTER_KEYS_DIR}/ima_keys" +IMA_EVM_KEY_DIR = "\${MASTER_KEYS_DIR}/ima_keys" +RPM_KEYS_DIR = "\${MASTER_KEYS_DIR}/rpm_keys" +BOOT_KEYS_DIR = "\${MASTER_KEYS_DIR}/boot_keys" +MOK_SB_KEYS_DIR = "\${MASTER_KEYS_DIR}/mok_sb_keys" +SYSTEM_TRUSTED_KEYS_DIR = "\${MASTER_KEYS_DIR}/system_trusted_keys" +UEFI_SB_KEYS_DIR = "\${MASTER_KEYS_DIR}/uefi_sb_keys" +GRUB_PUB_KEY = "\${MASTER_KEYS_DIR}/boot_keys/boot_pub_key" +GRUB_PW_FILE = "\${MASTER_KEYS_DIR}/boot_keys/boot_cfg_pw" +OSTREE_GPGDIR = "\${MASTER_KEYS_DIR}/rpm_keys" + +RPM_GPG_NAME = "$gpg_key_name" +RPM_GPG_PASSPHRASE = "$GPG_PASS" +RPM_FSK_PASSWORD = "$IMA_PASS" +BOOT_GPG_NAME = "$boot_gpg_key_name" +BOOT_GPG_PASSPHRASE = "$BOOT_GPG_PASS" +OSTREE_GPGID = "$gpg_key_name" +OSTREE_GPG_PASSPHRASE = "$GPG_PASS" +OSTREE_GRUB_PW_FILE = "\${GRUB_PW_FILE}" +EOF + +cat<