From bcd922f0da7703e0e3e966c266043e3957f1dc6d Mon Sep 17 00:00:00 2001 From: anmol372 Date: Wed, 21 Aug 2024 11:56:17 -0700 Subject: [PATCH] update artifact-signing script for release signing --- docker/rpms/my_setup_dev.sh | 3 +- docker/rpms/my_setup_rel.sh | 102 ++++++++++++++++++++++++++++++++++++ docker/rpms/sign-rpm.sh | 73 +++++++++++++++++--------- pipeline-rpm-script | 3 +- 4 files changed, 155 insertions(+), 26 deletions(-) create mode 100755 docker/rpms/my_setup_rel.sh diff --git a/docker/rpms/my_setup_dev.sh b/docker/rpms/my_setup_dev.sh index d042e0f9..42050dd5 100755 --- a/docker/rpms/my_setup_dev.sh +++ b/docker/rpms/my_setup_dev.sh @@ -1,3 +1,4 @@ +# shellcheck disable=all set -a # if dev=1, then we recompile tools before each invocation, even if binaries already exist (not recommended for signing users) @@ -10,7 +11,7 @@ dev=0 ## Use ./signContent-swims for SWIMS signing_helper=./signContent-swims -key_creation_time=0 # If set to 1, a timestamp of current time will be added to the signature in the public key file, otherwise +key_creation_time=1 # If set to 1, a timestamp of current time will be added to the signature in the public key file, otherwise # a static timestamp of "2017-Jan-01" will be used (when set to 0) sig_creation_time=0 # If set to 0, or not set, a timestamp of current time will be added to the signature file (common case). diff --git a/docker/rpms/my_setup_rel.sh b/docker/rpms/my_setup_rel.sh new file mode 100755 index 00000000..db66ae87 --- /dev/null +++ b/docker/rpms/my_setup_rel.sh @@ -0,0 +1,102 @@ +# shellcheck disable=all +set -a + +# if dev=1, then we recompile tools before each invocation, even if binaries already exist (this is for batch-mode development team only) +dev=0 + +# If you are running rpm signing tools from a daemon process, set the Environment Variable RPM_SIGN_DAEMON=1, otherwise leave it unset. +# This will prevent output to a tty, which doesn't exist on a daemon process +#RPM_SIGN_DAEMON=1 + +## Use ./signContent-swims for SWIMS +signing_helper=./signContent-swims + +key_creation_time=1 # If 1, a timestamp of current time will be added to the signature in the public key file, otherwise + # a static timestamp of "2017-Jan-01" will be used (when set to 0) + +sig_creation_time=0 # If set to 0, or not set, a timestamp of current time will be added to the signature file (common case). + # If set to 1, a static timestamp (of 2017-Jan-02) will be added to the signature file. This + # aligns with the 'key_creation_time' timestamp setting above, the key must be equal to or of older age than the + # signature to verify successfully. + # If set to > 0, it is assumed to be seconds since the epoch, 1970-01-01 00:00:00 UTC + # This value can typically be determined using the date unix command for a particular date, e.g. + # $ date --date='2018-01-01' +%s + # 1514782800 + # + # $ date --date='2021-07-11 11:43:40' +%s + # 1626018220 + + +## comment these out to use the production SWIMS server +##swims_certfile=swims_root_ca.pem # if set, alternate cert to validate host, typically don't use +##swims_host='swims-stg.cisco.com' # if set, alternate host to use + +swims_client_log="swims_client.log" + +#For the swims_client command, you have options: +# 1) For newer 64-bit machines (e.g. RHEL7, RHEL8, Ubuntu16, ubuntu18, Ubuntu20, and future), use the code_sign7.x86_64 executable provided in this repo (built on py3 RHEL7) +# 2) For python2 and/or older 64-bit machines (e.g. CentOs6, CEL6, etc), use the code_sign.x86_64 executable provided in this repo +# 3) For 32-bit machines, use the code_sign6_32 executable provided in this repo +# 4) Use your own code_sign executable copy (not recommended), provide the path to it +# 5) A copy of the swims_client.py script (see below) + +#This example uses option 1, always include the keyword 'swims' (except for option 5) +swims_client_cmd=$1' swims' +#swims_client_cmd='/code_sign7.x86_64 swims' +#swims_client_cmd="$PWD"'/code_sign.x86_64 swims' + +## un-comment this to use option 5, a swims_client.py python script (not provided in repo) +##swims_client_cmd='python swims_client.py' # eval-able string + +sig_type=rel # must be either "dev" or "rel" + +#gpgkeydir= # if you want to create the gpgkey (i.e. run-make-cert) into or retrieve the gpgkey from someplace other than + # this scripts directory, set this parameter to the directory path only. Otherwise don't set. Include final + # slash if you do set it, e.g. /tmp/ . The keys must be named rel.gpg or dev.gpg regardless. + + +notes="RPM Test REL for ISC" +user1=$2 # CEC name; only user required for dev signatures +pass1=push # For DUO push request +user2=$3 # CEC name; only used when sig_type=rel, otherwise use tickets or tokens +pass2=push # For DUO push request + +# To use tickets rather than OTP (for SWIMS), specify the ticket_file path +# e.g. ticket_file=/home/swims/RPM/rpm_deb_signing-master/Linux-64/swims-openpgp/myticket +#ticket_file= # if this is specified, uses a ticket rather than OTP (for SWIMS) +#ticket_file=/home/swims/repo-rpm-deb-sign-src/rpm_deb_sign_src/Linux-64/swims-openpgp/mph-2987471-REL-ticket + +# To use session tokens, use the SWIMS_SESSION_TOKEN and SWIMS_TREAT_TICKET_AS_TOKEN Environment Variables. See +# https://docs.cisco.com/share/page/site/nextgen-edcs/document-details?nodeRef=workspace://SpacesStore/44769d41-9bb4-4a4e-b6c1-cbfd1a7184a1 for more details. + +# If using a token, "SWIMS_SESSION_TOKEN" must be set to the raw token string or the path to the file containing the token. +#SWIMS_SESSION_TOKEN= +# If using a token for a legacy build script that cannot easily utilize the "SWIMS_SESSION_TOKEN" variable, +# the "ticket_file" variable must be set to the path to the file containing the token, +# and "SWIMS_TREAT_TICKET_AS_TOKEN" must be set to "True." +#SWIMS_TREAT_TICKET_AS_TOKEN=True + +# User provided encoded JSON string or file path to the file containing the encoded JSON string that includes +# all mandatory and optional build or artifact metadata regarding the build session. (See code_sign tool: "code_sign build-data -h") +#BUILD_METADATA= +#ARTIFACT_METADATA= + +product=dcn-container-vm-plugins # Product name (also key name for Abraxas, which only has one key for product) +product_key=dcn-container-vm-release +#product_pid=testPid # PID for SWIMS; if commented out, no PID will be given. If your PID is not marked as 'Real Pid' in your Product Entry in SWIMs, don't set this. + +#armored_pgp_sig=yes # Uncomment to make run-extsign produce an armored base64 gpg signature file + +#If you are using GRUB2 to verify gpg signatures for files (e.g. the kernel), then the file must be signed with RPM_MAJOR_VERSION = 5. This allows the key id to be placed +#in the unhashed sub-components within the signature, which GRUB2 currently expects. +#RPM_MAJOR_VERSION = 5 + +## Customer-visible identity for "who signed this code?" +# Do not include invalid characters like '\x00', '(', ')', '<' and '>' in fields +identity_name=$2 +identity_email=$2'@cisco.com' +#identity_comment="${product}.${sig_type}" # if commented out / undefined, default will be built per this pattern + +set +a + +# vim: filetype=sh \ No newline at end of file diff --git a/docker/rpms/sign-rpm.sh b/docker/rpms/sign-rpm.sh index 8217ae0a..10056b1c 100755 --- a/docker/rpms/sign-rpm.sh +++ b/docker/rpms/sign-rpm.sh @@ -1,8 +1,7 @@ #!/bin/bash -set -x +#set -x #TODO: add verification -#TODO: add release signing # Ensure the script is called with the correct number of arguments if [ "$#" -ne 4 ]; then @@ -29,8 +28,30 @@ VAULT_SECRET_ID=$KEEPER_SECRET # Signing CECs USER1=$2 USER2=$3 + +# Check if SIGNUSER1 is set +if [ "$USER1" == "empty" ]; then + echo "NO RPMS signed, please provide a valid CEC user for dev signing." + exit 0 +fi + # Release Signing or not RELEASE=$4 + +BUILD_TYPE="DEV" +VARSOURCE="$WORKSPACE/docker/rpms/my_setup_dev.sh" +GPG_FILE="dev.gpg" +# Check if RELEASE is True and validate SIGNUSER1 and SIGNUSER2 +if [ "$RELEASE" == "true" ]; then + if [ "$USER1" == "empty" ] || [ "$USER2" == "empty" ]; then + echo "Two valid CEC users required for release signing." + exit 1 + fi + BUILD_TYPE="RELEASE" + VARSOURCE="$WORKSPACE/docker/rpms/my_setup_rel.sh" + GPG_FILE="rel.gpg" +fi + # Constants from Travis CI environment variables BRANCH_NAME=$GIT_BRANCH PROJECT_NAME=$GIT_URL @@ -43,7 +64,6 @@ CODE_SIGN_EXEC="$RPM_DEB_SIGN/Linux-64/swims-openpgp/code_sign.x86_64" RPM_SIGN_SCRIPTDIR="$RPM_DEB_SIGN/Linux-64/swims-openpgp" RPM_BATCH_SIGN="$RPM_SIGN_SCRIPTDIR/rpm_sign_batchmode.py3" RUN_EXT_SIGN="$RPM_SIGN_SCRIPTDIR/run-extsign" -RPMMACROS="$WORKSPACE/signedRPMS" WORKING_DIR="$WORKSPACE/SIGNRPMS" OUTPUT_TOKEN="$WORKING_DIR/dcn-bld.tkn" @@ -55,19 +75,18 @@ SESSION_TOKEN_OUTPUT="$WORKING_DIR/build-session.tkn" REASON="CLI Test #1" BUILD_INITIATOR=$USER1 -BUILD_TYPE="DEV" ATTESTATION_KEY_NAME="dcn-plugin-build" PRODUCT="dcn-container-vm-plugins" AUTH_TYPE="OTP" -USERNAME=$USER1 -PASSWORD="push" +PASS="push" + # Step 0: Clone the repository if it does not exist and navigate into it -mkdir -p $SIGNHELPER_DIR -rm -rf $RPM_DEB_SIGN -git clone $REPO_URL $RPM_DEB_SIGN +mkdir -p "$SIGNHELPER_DIR" +rm -rf "$RPM_DEB_SIGN" +git clone "$REPO_URL" "$RPM_DEB_SIGN" -mkdir -p $WORKING_DIR +mkdir -p "$WORKING_DIR" # Find RPM files in the RPM directory RPM_FILES=$(find "$RPM_DIR_PATH" -type f -name "*.rpm") @@ -87,13 +106,19 @@ for RPM_FILE in $RPM_FILES; do done # Step 1: Create build authorization token -$CODE_SIGN_EXEC swims build authorization create -product $PRODUCT -buildType $BUILD_TYPE \ - -attestationKeyName $ATTESTATION_KEY_NAME -reason "$REASON" -buildInitiators $BUILD_INITIATOR \ - -authType $AUTH_TYPE -username1 $USERNAME -password1 $PASSWORD -out $OUTPUT_TOKEN -logFile $LOG_FILE +if [ "$RELEASE" == "true" ]; then + "$CODE_SIGN_EXEC" swims build authorization create -product "$PRODUCT" -buildType "$BUILD_TYPE" \ + -attestationKeyName "$ATTESTATION_KEY_NAME" -reason "$REASON" -buildInitiators "$BUILD_INITIATOR" \ + -authType "$AUTH_TYPE" -username1 "$USER1" -password1 "$PASS" -username2 "$USER2" -password2 "$PASS" -approvers "$USER2" -out "$OUTPUT_TOKEN" -logFile "$LOG_FILE" +else + "$CODE_SIGN_EXEC" swims build authorization create -product "$PRODUCT" -buildType "$BUILD_TYPE" \ + -attestationKeyName "$ATTESTATION_KEY_NAME" -reason "$REASON" -buildInitiators "$BUILD_INITIATOR" \ + -authType "$AUTH_TYPE" -username1 "$USER1" -password1 "$PASS" -out "$OUTPUT_TOKEN" -logFile "$LOG_FILE" +fi # Step 2: Encode payload for build session -$CODE_SIGN_EXEC swims build session encodePayload -buildInitiator $BUILD_INITIATOR -branchName $BRANCH_NAME \ - -projectName $PROJECT_NAME -buildAuthToken $OUTPUT_TOKEN -out $PAYLOAD_OUTPUT -logFile $LOG_FILE +"$CODE_SIGN_EXEC" swims build session encodePayload -buildInitiator "$BUILD_INITIATOR" -branchName "$BRANCH_NAME" \ + -projectName "$PROJECT_NAME" -buildAuthToken "$OUTPUT_TOKEN" -out "$PAYLOAD_OUTPUT" -logFile "$LOG_FILE" # Step 3: Set Vault environment variables export VAULT_ADDR=$VAULT_ADDR @@ -102,21 +127,21 @@ export VAULT_ROLE_ID=$VAULT_ROLE_ID export VAULT_SECRET_ID=$VAULT_SECRET_ID # Step 4: Sign the payload with attestation key -$CODE_SIGN_EXEC swims utils vault signWithAttestationKey -attestationKeyName $ATTESTATION_KEY_NAME \ - -input $PAYLOAD_OUTPUT -out $SIGNATURE_OUTPUT -logFile $LOG_FILE +"$CODE_SIGN_EXEC" swims utils vault signWithAttestationKey -attestationKeyName "$ATTESTATION_KEY_NAME" \ + -input "$PAYLOAD_OUTPUT" -out "$SIGNATURE_OUTPUT" -logFile "$LOG_FILE" # Step 5: Create build session token -$CODE_SIGN_EXEC swims build session create -requestPayload $PAYLOAD_OUTPUT -requestSignature $SIGNATURE_OUTPUT \ - -out $SESSION_TOKEN_OUTPUT -logFile $LOG_FILE +"$CODE_SIGN_EXEC" swims build session create -requestPayload "$PAYLOAD_OUTPUT" -requestSignature "$SIGNATURE_OUTPUT" \ + -out "$SESSION_TOKEN_OUTPUT" -logFile "$LOG_FILE" # Print completion message echo "Build session token created successfully and stored in $SESSION_TOKEN_OUTPUT" export SWIMS_SESSION_TOKEN=$SESSION_TOKEN_OUTPUT -source $WORKSPACE/docker/rpms/my_setup_dev.sh $CODE_SIGN_EXEC $USER1 -cd $RPM_SIGN_SCRIPTDIR +cd "$RPM_SIGN_SCRIPTDIR" +source "$VARSOURCE" "$CODE_SIGN_EXEC" "$USER1" "$USER2" ./run-make-cert.exp -gpg --import dev.gpg +gpg --import "$GPG_FILE" #gpg --list-keys # Create the ~/.rpmmacros file with the specified configuration @@ -127,6 +152,6 @@ cat >"$WORKING_DIR/.rpmmacros" <