From 7c5451c742facb9ff48b374df14705fb7ed60cf9 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 13 Dec 2024 21:36:40 -0600 Subject: [PATCH] fips-check.sh fixes + enhancements: * change default WOLFSSL_REPO to the canonical upstream. * refactor tag calculation without bash associative arrays, for backward compat. * add support for fetching FIPS tags/branches into a persistent fips repo if one is found at ../fips. * use --shared in git clones where applicable. * always check out the master FIPS branch, for its tooling, and always make sure it's up to date with $FIPS_REPO. * after each fetch for a previously unknown tag, explicitly associate the tag with the FETCH_HEAD. --- fips-check.sh | 153 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 123 insertions(+), 30 deletions(-) diff --git a/fips-check.sh b/fips-check.sh index 7d0e588998..968e878204 100755 --- a/fips-check.sh +++ b/fips-check.sh @@ -14,13 +14,18 @@ MAKE="${MAKE:-make}" GIT="${GIT:-git -c advice.detachedHead=false}" TEST_DIR="${TEST_DIR:-XXX-fips-test}" +case "$TEST_DIR" in + /*) ;; + *) TEST_DIR="${PWD}/${TEST_DIR}" + ;; +esac FLAVOR="${FLAVOR:-linux}" KEEP="${KEEP:-no}" MAKECHECK=${MAKECHECK:-yes} DOCONFIGURE=${DOCONFIGURE:-yes} DOAUTOGEN=${DOAUTOGEN:-yes} FIPS_REPO="${FIPS_REPO:-git@github.com:wolfssl/fips.git}" -WOLFSSL_REPO="${WOLFSSL_REPO:-origin}" +WOLFSSL_REPO="${WOLFSSL_REPO:-git@github.com:wolfssl/wolfssl.git}" Usage() { cat </dev/null; then - continue - fi - if ! $GIT fetch --depth 1 "$WOLFSSL_REPO" tag "$tag"; then - echo "Can't fetch wolfCrypt tag: $tag" +declare -a WOLFCRYPT_TAGS_NEEDED_UNSORTED WOLFCRYPT_TAGS_NEEDED +if [ ${#WOLFCRYPT_FILES[@]} -gt 0 ]; then + for file_entry in "${WOLFCRYPT_FILES[@]}"; do + WOLFCRYPT_TAGS_NEEDED_UNSORTED+=("${file_entry#*:}") + done + while IFS= read -r tag; do WOLFCRYPT_TAGS_NEEDED+=("$tag"); done < <(IFS=$'\n'; sort -u <<< "${WOLFCRYPT_TAGS_NEEDED_UNSORTED[*]}") + if [ "${#WOLFCRYPT_TAGS_NEEDED[@]}" = "0" ]; then + echo "Error -- missing wolfCrypt tags." 1>&2 exit 1 fi -done +fi -if ! $GIT clone . "$TEST_DIR"; then - echo "fips-check: Couldn't duplicate current working directory." +declare -a FIPS_TAGS_NEEDED_UNSORTED FIPS_TAGS_NEEDED +for file_entry in "${FIPS_FILES[@]}"; do + FIPS_TAGS_NEEDED_UNSORTED+=("${file_entry#*:}") +done +while IFS= read -r tag; do FIPS_TAGS_NEEDED+=("$tag"); done < <(IFS=$'\n'; sort -u <<< "${FIPS_TAGS_NEEDED_UNSORTED[*]}") +if [ "${#FIPS_TAGS_NEEDED[@]}" = "0" ]; then + echo "Error -- missing FIPS tags." 1>&2 exit 1 fi -pushd "$TEST_DIR" 1>/dev/null || exit 2 +if [ ${#WOLFCRYPT_TAGS_NEEDED[@]} -gt 0 ]; then + echo "wolfCrypt tag$( [[ ${#WOLFCRYPT_TAGS_NEEDED[@]} != "1" ]] && echo -n 's'):" -if ! $GIT clone "$FIPS_REPO" fips; then - echo "fips-check: Couldn't check out FIPS repository." + # Only use shallow fetch if the repo already has shallow branches, to avoid + # tainting full repos with shallow objects. + if [ -f .git/shallow ]; then + shallow_args=(--depth 1) + else + shallow_args=() + fi + + for tag in "${WOLFCRYPT_TAGS_NEEDED[@]}"; do + if $GIT describe --long --exact-match "$tag" 2>/dev/null; then + continue + fi + if ! $GIT fetch "${shallow_args[@]}" "$WOLFSSL_REPO" tag "$tag"; then + echo "Can't fetch wolfCrypt tag: $tag" 1>&2 + exit 1 + fi + # Make sure the tag is associated: + $GIT tag "$tag" FETCH_HEAD >/dev/null 2>&1 + done +fi + +if ! $GIT clone --shared . "$TEST_DIR"; then + echo "fips-check: Couldn't clone current working directory." 1>&2 exit 1 fi -pushd fips 1>/dev/null || exit 2 +# If there is a FIPS repo under the parent directory, leverage that: +if [ -d ../fips/.git ]; then + pushd ../fips 1>/dev/null || exit 2 + + # Only use shallow fetch if the repo already has shallow branches, to avoid + # tainting full repos with shallow objects. + if [ -f .git/shallow ]; then + shallow_args=(--depth 1) + else + shallow_args=() + fi -echo "FIPS tag$( [[ ${#FIPS_TAGS_NEEDED[@]} != "1" ]] && echo -n 's'):" -for tag in "${!FIPS_TAGS_NEEDED[@]}"; do - if $GIT describe "$tag" 2>/dev/null; then - continue + echo "FIPS tag$( [[ ${#FIPS_TAGS_NEEDED[@]} != "1" ]] && echo -n 's'):" + for tag in "${FIPS_TAGS_NEEDED[@]}"; do + if [ "$tag" = "master" ]; then + # master is handled specially below. + continue + fi + if $GIT describe --long --exact-match "$tag" 2>/dev/null; then + continue + fi + if ! $GIT fetch "${shallow_args[@]}" "$FIPS_REPO" tag "$tag"; then + echo "Can't fetch FIPS tag: $tag" 1>&2 + exit 1 + fi + # Make sure the tag is associated: + $GIT tag "$tag" FETCH_HEAD >/dev/null 2>&1 + done + + # The current tooling for the FIPS tests is in the master branch and must be + # checked out here. + if ! $GIT clone --shared --branch master . "${TEST_DIR}/fips"; then + echo "fips-check: Couldn't clone current working directory." 1>&2 + exit 1 fi - if ! $GIT fetch --depth 1 "$FIPS_REPO" tag "$tag"; then - echo "Can't fetch FIPS tag: $tag" + + popd 1>/dev/null || exit 2 + + # Make sure master is up-to-date: + pushd "${TEST_DIR}/fips" 1>/dev/null || exit 2 + if ! $GIT pull "$FIPS_REPO" master; then + echo "Can't refresh master FIPS tag" 1>&2 exit 1 fi -done + popd 1>/dev/null || exit 2 +fi -popd 1>/dev/null || exit 2 +pushd "$TEST_DIR" 1>/dev/null || exit 2 + +if [ ! -d fips ]; then + # The current tooling for the FIPS tests is in the master branch and must be + # checked out here. + if ! $GIT clone --depth 1 --branch master "$FIPS_REPO" fips; then + echo "fips-check: Couldn't check out FIPS repository." + exit 1 + fi + + pushd fips 1>/dev/null || exit 2 + echo "FIPS tag$( [[ ${#FIPS_TAGS_NEEDED[@]} != "1" ]] && echo -n 's'):" + for tag in "${FIPS_TAGS_NEEDED[@]}"; do + if [ "$tag" = "master" ]; then + # master was just cloned fresh from $FIPS_REPO above. + continue + fi + if $GIT describe --long --exact-match "$tag" 2>/dev/null; then + continue + fi + # The FIPS repo here is an ephemeral clone, so we can safely use shallow + # fetch unconditionally. + if ! $GIT fetch --depth 1 "$FIPS_REPO" tag "$tag"; then + echo "Can't fetch FIPS tag: $tag" 1>&2 + exit 1 + fi + # Make sure the tag is associated: + $GIT tag "$tag" FETCH_HEAD >/dev/null 2>&1 + done + popd 1>/dev/null || exit 2 +fi checkout_files "${WOLFCRYPT_FILES[@]}" || exit 3 pushd fips 1>/dev/null || exit 2