diff --git a/docker/rpms/build_opflexrpm.sh b/docker/rpms/build_opflexrpm.sh index d64f2554..a6a29810 100755 --- a/docker/rpms/build_opflexrpm.sh +++ b/docker/rpms/build_opflexrpm.sh @@ -25,9 +25,9 @@ if [ -z "$5" ]; then BUILDVER="private" fi -podman build --no-cache --build-arg baseimage="$BASEIMAGE" --build-arg branch="$BRANCH" \ +docker build --no-cache --build-arg baseimage="$BASEIMAGE" --build-arg branch="$BRANCH" \ --build-arg buildversion="$BUILDVER" -t "$DOCKER_USER"/opflexrpm-build:"$DOCKER_TAG" \ -f ./Dockerfile-opflexrpm-build . -cid=$(podman create "$DOCKER_USER"/opflexrpm-build:"$DOCKER_TAG") -podman cp "$cid:/root/opflexrpms-$BUILDVER.tar.gz" ./opflexrpms-"$BUILDVER".tar.gz -podman rm "$cid" +cid=$(docker create "$DOCKER_USER"/opflexrpm-build:"$DOCKER_TAG") +docker cp "$cid:/root/opflexrpms-$BUILDVER.tar.gz" ./opflexrpms-"$BUILDVER".tar.gz +docker rm "$cid" diff --git a/docker/rpms/my_setup_dev.sh b/docker/rpms/my_setup_dev.sh new file mode 100755 index 00000000..42050dd5 --- /dev/null +++ b/docker/rpms/my_setup_dev.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 (not recommended for signing users) +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 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). + # 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= # if set, alternate cert to validate host, typically don't use +#swims_host='swims-stg-aln.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="$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=dev # 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. + +user1=$2 # CEC name; only user required for dev signatures +pass1=push # For DUO push request + +notes="RPM Test for ISC" + +#Generic userid can be used for DEV signing +#generic_user= # generic user id +#generic_pw= # generic user password + +# 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, use 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-DEV-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=/tmp/build-session.tkn +# 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-keys-dev # Key name for SWIMS (defaults to product name if not given) +#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/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 new file mode 100755 index 00000000..10056b1c --- /dev/null +++ b/docker/rpms/sign-rpm.sh @@ -0,0 +1,157 @@ +#!/bin/bash + +#set -x +#TODO: add verification + +# Ensure the script is called with the correct number of arguments +if [ "$#" -ne 4 ]; then + #echo "Usage: " + exit 1 +fi + +# Define the RPM directories +RPM_DIR_PATH=$(find "$1" -type d -name "*opflexrpms*" | grep "${BUILD_NUMBER}") +#RPM_DIR_PATH=$(find "$1" -type d -name "*opflexrpms*" | grep "19") +if [ -z "$RPM_DIR_PATH" ]; then + echo "No RPM directory found for build number ${BUILD_NUMBER}" + exit 1 +fi +#NOARCH_DIR="$RPM_DIR/RPMS/noarch" +#SRPMS_DIR="$RPM_DIR/SRPMS" + +# Setup Vault +VAULT_ADDR="https://keeper.cisco.com" +VAULT_NAMESPACE="swims-prod/GROUP_2" +VAULT_ROLE_ID=$KEEPER_ROLE_ID +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 + +# Variables +REPO_URL="https://wwwin-github.cisco.com/STO-Image-Signing/rpm_deb_signing.git" +SIGNHELPER_DIR="$WORKSPACE/rpmbuild" +RPM_DEB_SIGN="$WORKSPACE/rpmbuild/rpm_deb_signing" +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" + +WORKING_DIR="$WORKSPACE/SIGNRPMS" +OUTPUT_TOKEN="$WORKING_DIR/dcn-bld.tkn" +LOG_FILE="$WORKING_DIR/swims-session-token.log" + +PAYLOAD_OUTPUT="$WORKING_DIR/requestPayload.out3" +SIGNATURE_OUTPUT="$WORKING_DIR/requestPayload.sig3" +SESSION_TOKEN_OUTPUT="$WORKING_DIR/build-session.tkn" + +REASON="CLI Test #1" +BUILD_INITIATOR=$USER1 +ATTESTATION_KEY_NAME="dcn-plugin-build" +PRODUCT="dcn-container-vm-plugins" +AUTH_TYPE="OTP" +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 "$WORKING_DIR" + +# Find RPM files in the RPM directory +RPM_FILES=$(find "$RPM_DIR_PATH" -type f -name "*.rpm") + +if [ -z "$RPM_FILES" ]; then + echo "No RPM files found to sign in $RPM_DIR_PATH" + exit 1 +fi + +# Define the CSV file path +CSV_FILE="$SIGNHELPER_DIR/rpm_files.csv" +# Ensure csv is empty +> "$CSV_FILE" +# Append RPM file paths to the CSV file +for RPM_FILE in $RPM_FILES; do + echo "$RPM_FILE" >> "$CSV_FILE" +done + +# Step 1: Create build authorization token +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" + +# Step 3: Set Vault environment variables +export VAULT_ADDR=$VAULT_ADDR +export VAULT_NAMESPACE=$VAULT_NAMESPACE +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" + +# 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" + +# Print completion message +echo "Build session token created successfully and stored in $SESSION_TOKEN_OUTPUT" + +export SWIMS_SESSION_TOKEN=$SESSION_TOKEN_OUTPUT +cd "$RPM_SIGN_SCRIPTDIR" +source "$VARSOURCE" "$CODE_SIGN_EXEC" "$USER1" "$USER2" +./run-make-cert.exp +gpg --import "$GPG_FILE" +#gpg --list-keys + +# Create the ~/.rpmmacros file with the specified configuration +cat >"$WORKING_DIR/.rpmmacros" <