summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Heller <hellerda@us.ibm.com>2018-08-18 22:34:06 -0400
committerDave Heller <hellerda@us.ibm.com>2018-08-18 22:34:06 -0400
commitb02e5fd98135ce8f6271e22a193085a14f66a7af (patch)
treec99624cc6e7d2eeae1e2abe1a6a97d56e7dcf9dd
parent3f6e9a1e2e489555ac45a36aa1c6b5fb53172c50 (diff)
downloadsb-signing-utils-b02e5fd98135ce8f6271e22a193085a14f66a7af.tar.gz
sb-signing-utils-b02e5fd98135ce8f6271e22a193085a14f66a7af.zip
Support multiple KMS in Production mode
This adds support for PKCS11 as an alternate key management system in place of signframework, and adds the configuation property SB_KMS and a new command line option --kms to select between them. If unset the default is "signframework". If set to "pkcs11" two additional configuration properties, specifying the token name and the shared library implementing the token, are recognized. These properties are set by environment, or via the INI under a new section [pkcs11].
-rwxr-xr-xcrtSignedContainer.sh179
1 files changed, 136 insertions, 43 deletions
diff --git a/crtSignedContainer.sh b/crtSignedContainer.sh
index d84100f..d231b5f 100755
--- a/crtSignedContainer.sh
+++ b/crtSignedContainer.sh
@@ -7,6 +7,7 @@
P=${0##*/}
SIGN_MODE=local
+KMS=signframework
HW_KEY_ARGS=""
SW_KEY_ARGS=""
@@ -39,6 +40,8 @@ usage () {
echo " -o, --code-start-offset code start offset for software header in hex"
echo " -f, --flags prefix header flags in hex"
echo " -m, --mode signing mode: local, independent or production"
+ echo " -k, --kms key management system for retrieving keys and signatures"
+ echo " (choices are \"signframework\" or \"pkcs11\")"
echo " -s, --scratchDir scratch directory to use for file caching, etc."
echo " -L, --label name or identifier of the module being built (8 char max)"
echo " --contrHdrOut file write container header only (w/o payload)"
@@ -252,9 +255,19 @@ parseIni () {
findArtifact () {
local f
local found
+ local scope
for f in "$@"
do
+ # If filename starts with ./ search only this component cache.
+ if [ "${f:0:2}" == "./" ]
+ then
+ f="${f:2}"
+ scope=local
+ else
+ scope=global
+ fi
+
# Look for artifact in the local cache
found=$(find "$T" -name "$f" | head -1)
if [ "$found" ]; then
@@ -262,7 +275,9 @@ findArtifact () {
return
fi
- # If not found, look elsewhere in the cache
+ test "$scope" == "local" && continue
+
+ # Look elsewhere in the cache
found=$(find "$TOPDIR" -name "$f" | head -1)
if [ "$found" ]; then
cp -p "$found" "$T/"
@@ -300,6 +315,7 @@ for arg in "$@"; do
"--code-start-offset") set -- "$@" "-o" ;;
"--protectedPayload") set -- "$@" "-l" ;;
"--out") set -- "$@" "-i" ;;
+ "--kms") set -- "$@" "-k" ;;
"--mode") set -- "$@" "-m" ;;
"--scratchDir") set -- "$@" "-s" ;;
"--label") set -- "$@" "-L" ;;
@@ -315,7 +331,7 @@ for arg in "$@"; do
done
# Process command-line arguments
-while getopts -- ?hdvw:a:b:c:p:q:r:f:o:l:i:m:s:L:4:5:6:7:89: opt
+while getopts -- ?hdvw:a:b:c:p:q:r:f:o:l:i:m:k:s:L:4:5:6:7:89: opt
do
case "${opt:?}" in
v) SB_VERBOSE="TRUE";;
@@ -331,6 +347,7 @@ do
o) CS_OFFSET="$OPTARG";;
l) PAYLOAD="$OPTARG";;
i) OUTPUT="$OPTARG";;
+ k) KMS="$(to_lower "$OPTARG")";;
m) SIGN_MODE="$(to_lower "$OPTARG")";;
s) SB_SCRATCH_DIR="$OPTARG";;
L) LABEL="$OPTARG";;
@@ -352,10 +369,11 @@ do
done
# These are the only env vars that override a command line option
+test "$SB_KMS" && KMS="$(to_lower "$SB_KMS")"
test "$SB_SIGN_MODE" && SIGN_MODE="$(to_lower "$SB_SIGN_MODE")"
test "$SB_PROJECT_INI" && PROJECT_INI="$SB_PROJECT_INI"
-# What op-buid calls development mode, we call local mode
+# What op-build calls development mode, we call local mode
test "$SIGN_MODE" == development && SIGN_MODE=local
echo "--> $P: Signing mode: $SIGN_MODE"
@@ -365,7 +383,7 @@ echo "--> $P: Signing mode: $SIGN_MODE"
#
if [ "$(to_upper "$LABEL")" == SBKTRAND ]
then
- # Key transistion container may have its own ini file
+ # Key transition container may have its own ini file
test "$SB_PROJECT_INI_TRANS" && PROJECT_INI=$SB_PROJECT_INI_TRANS
fi
@@ -384,6 +402,8 @@ then
signproject_hw_signing_project_basename=""
signproject_fw_signing_project_basename=""
signproject_getpubkey_project_basename=""
+ pkcs11_module=""
+ pkcs11_token=""
echo "--> $P: Parsing INI file: $PROJECT_INI"
parseIni "$PROJECT_INI"
@@ -405,6 +425,9 @@ then
SF_FW_SIGNING_PROJECT_BASE="$signproject_fw_signing_project_basename"
test "$signproject_getpubkey_project_basename" && \
SF_GETPUBKEY_PROJECT_BASE="$signproject_getpubkey_project_basename"
+
+ test "$pkcs11_module" && SB_PKCS11_MODULE="$pkcs11_module"
+ test "$pkcs11_token" && SB_PKCS11_TOKEN="$pkcs11_token"
fi
#
@@ -542,6 +565,12 @@ then
fi
#
+# Set defaults for PKCS11
+#
+: "${SB_PKCS11_MODULE:=/usr/lib64/pkcs11/libsofthsm2.so}"
+: "${SB_PKCS11_TOKEN:=P9Signing}"
+
+#
# Get the public keys
#
if [ "$SIGN_MODE" == "local" ] || [ "$SIGN_MODE" == "independent" ]
@@ -654,16 +683,33 @@ then
echo "--> $P: Found key for HW key $(to_upper $KEY).${msg}"
else
# No key found, request one.
- KEYFILE="$KEYFILE_BASE.raw"
echo "--> $P: Requesting public key for HW key $(to_upper $KEY)..."
- sf_client $SF_DEBUG_ARGS -project "$SF_GETPUBKEY_PROJECT_BASE" \
- -param "-signproject $SF_PROJECT" \
- -epwd "$SF_EPWD" -comments "Requesting $SF_PROJECT" \
- -url sftp://$SF_USER@$SF_SERVER -pkey "$SF_SSHKEY" \
- -o "$T/$KEYFILE"
- rc=$?
- test $rc -ne 0 && die "Call to sf_client failed with error: $rc"
+ if [ "$KMS" == "signframework" ]
+ then
+ # Output is pubkey in raw format
+ KEYFILE="$KEYFILE_BASE.raw"
+ sf_client $SF_DEBUG_ARGS -project "$SF_GETPUBKEY_PROJECT_BASE" \
+ -param "-signproject $SF_PROJECT" \
+ -epwd "$SF_EPWD" -comments "Requesting $SF_PROJECT" \
+ -url sftp://$SF_USER@$SF_SERVER -pkey "$SF_SSHKEY" \
+ -o "$T/$KEYFILE"
+
+ elif [ "$KMS" == "pkcs11" ]
+ then
+ # Output is pubkey in PEM format
+ KEYFILE="$KEYFILE_BASE.pub"
+ pkcs11-tool --module $SB_PKCS11_MODULE \
+ --token-label $SB_PKCS11_TOKEN \
+ --read-object --type pubkey --label $SF_PROJECT | \
+ openssl ec -inform der -pubout -pubin > "$T/$KEYFILE"
+
+ else
+ die "Unsupported KMS: $KMS"
+ fi
+
+ rc=$?
+ test $rc -ne 0 && die "Call to KMS client failed with error: $rc"
test "$(find "$T" -name $KEYFILE)" || \
die "Unable to retrieve HW key $(to_upper $KEY)."
@@ -693,16 +739,28 @@ then
echo "--> $P: Found key for SW key $(to_upper $KEY).${msg}"
else
# No key found, request one.
- KEYFILE="$KEYFILE_BASE.raw"
echo "--> $P: Requesting public key for SW key $(to_upper $KEY)..."
- sf_client $SF_DEBUG_ARGS -project "$SF_GETPUBKEY_PROJECT_BASE" \
- -param "-signproject $SF_PROJECT" \
- -epwd "$SF_EPWD" -comments "Requesting $SF_PROJECT" \
- -url sftp://$SF_USER@$SF_SERVER -pkey "$SF_SSHKEY" \
- -o "$T/$KEYFILE"
- rc=$?
- test $rc -ne 0 && die "Call to sf_client failed with error: $rc"
+ if [ "$KMS" == "signframework" ]
+ then
+ KEYFILE="$KEYFILE_BASE.raw"
+ sf_client $SF_DEBUG_ARGS -project "$SF_GETPUBKEY_PROJECT_BASE" \
+ -param "-signproject $SF_PROJECT" \
+ -epwd "$SF_EPWD" -comments "Requesting $SF_PROJECT" \
+ -url sftp://$SF_USER@$SF_SERVER -pkey "$SF_SSHKEY" \
+ -o "$T/$KEYFILE"
+
+ elif [ "$KMS" == "pkcs11" ]
+ then
+ KEYFILE="$KEYFILE_BASE.pub"
+ pkcs11-tool --module $SB_PKCS11_MODULE \
+ --token-label $SB_PKCS11_TOKEN \
+ --read-object --type pubkey --label $SF_PROJECT | \
+ openssl ec -inform der -pubout -pubin > "$T/$KEYFILE"
+ fi
+
+ rc=$?
+ test $rc -ne 0 && die "Call to KMS client failed with error: $rc"
test "$(find "$T" -name $KEYFILE)" || \
die "Unable to retrieve SW key $(to_upper $KEY)."
@@ -869,17 +927,29 @@ then
echo "--> $P: Found sig for HW key $(to_upper $KEY).${msg}"
else
# No signature found, request one.
- test "$KEYFILE" == __getkey && break
-
- SIGFILE="$SIGFILE_BASE.raw"
+ test "$KEYFILE" == __getkey && break # (unless instructed not to)
echo "--> $P: Requesting signature for HW key $(to_upper $KEY)..."
- sf_client $SF_DEBUG_ARGS -project $SF_PROJECT -epwd "$SF_EPWD" \
- -comments "Requesting sig for $SF_PROJECT" \
- -url sftp://$SF_USER@$SF_SERVER -pkey "$SF_SSHKEY" \
- -payload "$T/prefix_hdr" -o "$T/$SIGFILE"
- rc=$?
- test $rc -ne 0 && die "Call to sf_client failed with error: $rc"
+ if [ "$KMS" == "signframework" ]
+ then
+ # Output is signature in raw format
+ SIGFILE="$SIGFILE_BASE.raw"
+ sf_client $SF_DEBUG_ARGS -project $SF_PROJECT -epwd "$SF_EPWD" \
+ -comments "Requesting sig for $SF_PROJECT" \
+ -url sftp://$SF_USER@$SF_SERVER -pkey "$SF_SSHKEY" \
+ -payload "$T/prefix_hdr" -o "$T/$SIGFILE"
+
+ elif [ "$KMS" == "pkcs11" ]
+ then
+ # Output is signature in DER format
+ SIGFILE="$SIGFILE_BASE.sig"
+ /bin/openssl dgst -engine pkcs11 -keyform engine \
+ -sign "pkcs11:token=$SB_PKCS11_TOKEN;object=$SF_PROJECT" \
+ -sha512 -out "$T/$SIGFILE" "$T/prefix_hdr"
+ fi
+
+ rc=$?
+ test $rc -ne 0 && die "Call to KMS client failed with error: $rc"
test "$(find "$T" -name $SIGFILE)" || \
die "Unable to retrieve sig for HW key $(to_upper $KEY)."
@@ -892,33 +962,56 @@ then
done
for KEY in p q r; do
- SF_PROJECT=${SF_FW_SIGNING_PROJECT_BASE}_${KEY}
- SIGFILE=project.$SF_PROJECT.SW_sig_$KEY.raw
-
varname=SW_KEY_$(to_upper $KEY); KEYFILE=${!varname}
# Handle the special values, or empty value
test -z "$KEYFILE" && break
test "$KEYFILE" == __skip && break
+ SF_PROJECT=${SF_FW_SIGNING_PROJECT_BASE}_${KEY}
+ SIGFILE_BASE=project.$SF_PROJECT.SW_sig_$KEY
+
# Look for a signature in the local cache dir, if found use it.
- if [ -f "$T/$SIGFILE" ] && \
- [ "$(to_upper "$LABEL")" != SBKT ] && \
- [ "$(to_upper "$LABEL")" != SBKTRAND ]
+ # (but never reuse a sig for SBKT, the payload is always regenerated)
+ if [ "$(to_upper "$LABEL")" == SBKT ] || \
+ [ "$(to_upper "$LABEL")" == SBKTRAND ]
then
+ SIGFILE=""
+ else
+ SIGFILE=$(findArtifact "./$SIGFILE_BASE.sig" "./$SIGFILE_BASE.raw")
+ fi
+
+ if [ "$SIGFILE" ]; then
test "$SB_VERBOSE" && msg=" ($SIGFILE)"
- echo "--> $P: Found signature for SW key $(to_upper $KEY).${msg}"
+ echo "--> $P: Found sig for SW key $(to_upper $KEY).${msg}"
else
# No signature found, request one.
- test "$KEYFILE" == __getkey && continue
+ test "$KEYFILE" == __getkey && break # (unless instructed not to)
echo "--> $P: Requesting signature for SW key $(to_upper $KEY)..."
- sf_client $SF_DEBUG_ARGS -project $SF_PROJECT -epwd "$SF_EPWD" \
- -comments "Requesting sig for $LABEL from $SF_PROJECT" \
- -url sftp://$SF_USER@$SF_SERVER -pkey "$SF_SSHKEY" \
- -payload "$T/software_hdr.md.bin" -o "$T/$SIGFILE"
+
+ if [ "$KMS" == "signframework" ]
+ then
+ # Output is signature in raw format
+ SIGFILE="$SIGFILE_BASE.raw"
+ sf_client $SF_DEBUG_ARGS -project $SF_PROJECT -epwd "$SF_EPWD" \
+ -comments "Requesting sig for $LABEL from $SF_PROJECT" \
+ -url sftp://$SF_USER@$SF_SERVER -pkey "$SF_SSHKEY" \
+ -payload "$T/software_hdr.md.bin" -o "$T/$SIGFILE"
+
+ elif [ "$KMS" == "pkcs11" ]
+ then
+ # Output is signature in DER format
+ SIGFILE="$SIGFILE_BASE.sig"
+ /bin/openssl dgst -engine pkcs11 -keyform engine \
+ -sign "pkcs11:token=$SB_PKCS11_TOKEN;object=$SF_PROJECT" \
+ -sha512 -out "$T/$SIGFILE" "$T/software_hdr"
+ fi
+
rc=$?
+ test $rc -ne 0 && die "Call to KMS client failed with error: $rc"
- test $rc -ne 0 && die "Call to sf_client failed with error: $rc"
+ test "$(find "$T" -name $SIGFILE)" || \
+ die "Unable to retrieve sig for SW key $(to_upper $KEY)."
echo "--> $P: Retrieved signature for SW key $(to_upper $KEY)."
fi
@@ -973,7 +1066,7 @@ fi
if [ "$(to_upper "$LABEL")" == SBKTRAND ]
then
- # Key transistion container may have its own verify value
+ # Key transition container may have its own verify value
test "$SB_VERIFY_TRANS" && SB_VERIFY=$SB_VERIFY_TRANS
fi
OpenPOWER on IntegriCloud