Merge pull request #821 from csssuf/signing-server

Add signing server support to signing scripts
This commit is contained in:
James Forcier 2018-07-13 16:05:55 -07:00 committed by GitHub
commit 3ff2eacd3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 184 additions and 24 deletions

86
core_dev_sign_update Executable file
View File

@ -0,0 +1,86 @@
#!/usr/bin/env bash
SCRIPT_ROOT=$(dirname $(readlink -f "$0"))
. "${SCRIPT_ROOT}/common.sh" || exit 1
assert_inside_chroot
DEFINE_string data_dir "" "Directory containing downloaded release artifacts"
DEFINE_string board "" "Board to sign artifacts for"
DEFINE_string version "" "Version to sign artifacts for"
DEFINE_integer n_signatures "2" "Number of signatures this release will be signed with"
DEFINE_string output_dir "" "Output directory"
DEFINE_string gpg_key "" "Value for '--default-key' argument to gpg --sign"
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
set -e
data_dir="${FLAGS_data_dir}/${FLAGS_board}/${FLAGS_version}"
output_dir="${FLAGS_output_dir}/${FLAGS_board}/${FLAGS_version}"
mkdir -p "$output_dir"
cleanup() {
# core_sign_update expects to unpack this too, so we'll clean it up.
rm -f "${data_dir}/coreos_production_update.bin"
rm -f "${data_dir}/update"
rm -f "${data_dir}/update.hash"
}
trap cleanup INT TERM EXIT
# delta_generator expects a list of colon-separated sizes for signature hash algorithms in order to
# build the update payload protobuf properly. Since we already assume sha256 elsewhere in
# core_sign_update, do it here as well.
signature_sizes=""
for i in $(seq 1 $FLAGS_n_signatures); do
signature_sizes="${signature_sizes}:256"
done
signature_sizes="${signature_sizes:1:${#signature_sizes}}"
echo "=== Verifying update payload... ==="
gpg2 --verify "${data_dir}/coreos_production_update.bin.bz2.sig"
gpg2 --verify "${data_dir}/coreos_production_image.vmlinuz.sig"
gpg2 --verify "${data_dir}/coreos_production_update.zip.sig"
echo "=== Decompressing update payload... ==="
bunzip2 --keep "${data_dir}/coreos_production_update.bin.bz2"
echo "=== Creating signable update payload... ==="
delta_generator \
-new_image "${data_dir}/coreos_production_update.bin" \
-new_kernel "${data_dir}/coreos_production_image.vmlinuz" \
-out_file "${data_dir}/update"
delta_generator \
--signature_size ${signature_sizes} \
--in_file "${data_dir}/update" \
--out_hash_file "${data_dir}/update.hash"
echo "=== Signing update payload... ==="
if [[ -z "${FLAGS_gpg_key}" ]]; then
gpg2 \
--output "${output_dir}/update.sig.$(whoami)" \
--armor --detach-sign "${data_dir}/update.hash"
else
gpg2 \
--local-user "$FLAGS_gpg_key" \
--output "${output_dir}/update.sig.$(whoami)" \
--armor --detach-sign "${data_dir}/update.hash"
fi
echo "=== Update payload signed successfully. ==="
echo "=== Verifying torcx manifest... ==="
gpg2 --verify "${data_dir}/torcx_manifest.json.sig"
echo "=== Signing torcx manifest... ==="
if [[ -z "${FLAGS_gpg_key}" ]]; then
gpg2 \
--output "${output_dir}/torcx_manifest.json.sig.$(whoami)" \
--detach-sign --armor "${data_dir}/torcx_manifest.json"
else
gpg2 \
--local-user "$FLAGS_gpg_key" \
--output "${output_dir}/torcx_manifest.json.sig.$(whoami)" \
--detach-sign --armor "${data_dir}/torcx_manifest.json"
fi
echo "=== Torcx manifest signed successfully. ==="

View File

@ -18,9 +18,13 @@ export GCLIENT_ROOT=$(readlink -f "${SCRIPT_ROOT}/../../")
DEFINE_string image "" "The filesystem image of /usr"
DEFINE_string kernel "" "The kernel image"
DEFINE_string output "" "Output file"
DEFINE_string private_keys "" "Path or pkcs11 URI to private keys."
DEFINE_string private_keys "" "Path, pkcs11 URI, or fero:<keyname> for private keys."
DEFINE_string public_keys "" "Path to public keys in .pem format."
DEFINE_string keys_separator ":" "Separator for the above keys"
DEFINE_string user_signatures "" \
"Colon-separated paths to user signatures to provide to signing server"
DEFINE_string signing_server_address "" "Hostname of the signing server"
DEFINE_integer signing_server_port "50051" "Port of the signing server"
# Parse command line
FLAGS "$@" || exit 1
@ -41,6 +45,7 @@ cleanup() {
trap cleanup INT TERM EXIT
echo "=== Creating signable update payload... ==="
delta_generator \
-new_image "$FLAGS_image" \
-new_kernel "$FLAGS_kernel" \
@ -63,6 +68,16 @@ for key in "${private_keys[@]}"; do
done
signature_sizes="${signature_sizes:1:${#signature_sizes}}"
# We don't need to maintain backwards compatibility with old `sign.sh` scripts here, so we only
# allow colon-separated values for user signature files.
IFS=":" read -a user_signatures <<< "$FLAGS_user_signatures"
user_signatures_arg=""
for user_signature in "${user_signatures[@]}"; do
user_signatures_arg="${user_signatures_arg} --signature ${user_signature}"
done
user_signatures_arg="${user_signatures_arg:1:${#user_signatures_arg}}"
delta_generator \
--signature_size ${signature_sizes} \
--in_file update \
@ -116,12 +131,21 @@ cat padding-pkcs11 update.hash > update.pkcs11-padhash
echo "AAH/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ADAxMA0GCWCGSAFlAwQCAQUABCA=" | base64 -d > padding
cat padding update.hash > update.padhash
echo "=== Signing update payload... ==="
i=1
signature_sizes=""
for key in "${private_keys[@]}"; do
if [[ "${key}" == pkcs11* ]]; then
openssl rsautl -engine pkcs11 -pkcs -sign -inkey ${key} -keyform engine -in update.pkcs11-padhash -out update.sig.${i}
elif [[ "${key}" == fero* ]]; then
fero-client \
--address $FLAGS_signing_server_address \
--port $FLAGS_signing_server_port \
sign --pkcs1 \
--file update.hash \
--output update.sig.${i} \
--secret-key ${key:5:${#key}} \
${user_signatures_arg}
else
openssl rsautl -raw -sign -inkey ${key} -in update.padhash -out update.sig.${i}
fi
@ -148,6 +172,7 @@ for key in "${public_keys[@]}"; do
done
mv update.signed ${FLAGS_output}
echo "=== Update payload signed successfully. ==="
trap - INT TERM EXIT
cleanup noexit

View File

@ -1,22 +0,0 @@
#!/usr/bin/env bash
set -ex
DATA_DIR="$(readlink -f "$1")"
KEYS_DIR="$(readlink -f "$(dirname "$0")")"
gpg2 --verify "${DATA_DIR}/coreos_production_update.bin.bz2.sig"
gpg2 --verify "${DATA_DIR}/coreos_production_image.vmlinuz.sig"
gpg2 --verify "${DATA_DIR}/coreos_production_update.zip.sig"
bunzip2 --keep "${DATA_DIR}/coreos_production_update.bin.bz2"
unzip "${DATA_DIR}/coreos_production_update.zip" -d "${DATA_DIR}"
export PATH="${DATA_DIR}:${PATH}"
cd "${DATA_DIR}"
./core_sign_update \
--image "${DATA_DIR}/coreos_production_update.bin" \
--kernel "${DATA_DIR}/coreos_production_image.vmlinuz" \
--output "${DATA_DIR}/coreos_production_update.gz" \
--private_keys "${KEYS_DIR}/devel.key.pem+pkcs11:object=CoreOS_Update_Signing_Key;type=private" \
--public_keys "${KEYS_DIR}/devel.pub.pem+${KEYS_DIR}/prod-2.pub.pem" \
--keys_separator "+"

9
signing/prod-2.pub.pem Normal file
View File

@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7pO21yN+b6yx9P+wHzS2
clxGs18eWxfoleETLbFVmcXu783rgBP0bFjYfqrNZNaI1Ip6bxEYkPacg0xFg7ri
lNdO/cxJV5Ltj40wFlpmzJOAH8hx5SF8KWg2NV1I6TS8pp+CQqcvvOKu6AIcWfeY
11V7eJ8rWcDsnqpTg8T1VRxytsg2UjTMfQwzcGLTb8cQ8AV39ED5WC5NdS9Bld4h
XqS9Dx6Pe3JOQLZze6XIIwWuB2jxGpM1GWfRNm5nxvne3l7ggC970482a7STGK10
fD8//k8myVxleMAeQoMRXoRq9p3C84H4Bw8v2dX13kFFCgfEQj6SOZ5huXZKLPpB
LwIDAQAB
-----END PUBLIC KEY-----

62
signing/sign.sh Executable file
View File

@ -0,0 +1,62 @@
#!/usr/bin/env bash
set -ex
if [[ $# -lt 2 ]]; then
echo "Usage: $0 DATA_DIR SIGS_DIR [SERVER_ADDR [SERVER_PORT]]"
exit 1
fi
DATA_DIR="$(readlink -f "$1")"
KEYS_DIR="$(readlink -f "$(dirname "$0")")"
SIGS_DIR="$(readlink -f "$2")"
SERVER_ADDR="${3:-10.7.16.138}"
SERVER_PORT="${4:-50051}"
echo "=== Verifying update payload... ==="
gpg2 --verify "${DATA_DIR}/coreos_production_update.bin.bz2.sig"
gpg2 --verify "${DATA_DIR}/coreos_production_image.vmlinuz.sig"
gpg2 --verify "${DATA_DIR}/coreos_production_update.zip.sig"
echo "=== Decompressing update payload... ==="
bunzip2 --keep "${DATA_DIR}/coreos_production_update.bin.bz2"
unzip "${DATA_DIR}/coreos_production_update.zip" -d "${DATA_DIR}"
payload_signature_files=""
for i in ${SIGS_DIR}/update.sig.*; do
payload_signature_files=${payload_signature_files}:${i}
done
payload_signature_files="${payload_signature_files:1:${#payload_signature_files}}"
pushd "${DATA_DIR}"
./core_sign_update \
--image "${DATA_DIR}/coreos_production_update.bin" \
--kernel "${DATA_DIR}/coreos_production_image.vmlinuz" \
--output "${DATA_DIR}/coreos_production_update.gz" \
--private_keys "${KEYS_DIR}/devel.key.pem+fero:coreos-update-prod" \
--public_keys "${KEYS_DIR}/devel.pub.pem+${KEYS_DIR}/prod-2.pub.pem" \
--keys_separator "+" \
--signing_server_address "$SERVER_ADDR" \
--signing_server_port "$SERVER_PORT" \
--user_signatures "${payload_signature_files}"
popd
echo "=== Signing torcx manifest... ==="
torcx_signature_arg=""
for torcx_signature in ${SIGS_DIR}/torcx_manifest.json.sig.*; do
torcx_signature_arg="${torcx_signature_arg} --signature ${torcx_signature}"
done
torcx_signature_arg="${torcx_signature_arg:1:${#torcx_signature_arg}}"
fero-client \
--address $SERVER_ADDR \
--port $SERVER_PORT \
sign \
--file "${DATA_DIR}/torcx_manifest.json" \
--output "${DATA_DIR}/torcx_manifest.json.sig-fero" \
--secret-key coreos-torcx \
${torcx_signature_arg}
gpg2 --enarmor \
--output "${DATA_DIR}/torcx_manifest.json.asc" \
"${DATA_DIR}/torcx_manifest.json.sig-fero"
echo "=== Torcx manifest signed successfully. ==="
rm -f "${DATA_DIR}/torcx_manifest.json.sig-fero"