# this file is a library sourced from recipes/*

result_path=$(pwd)
cd $(dirname "$0")/../
script_path=$(pwd)
cd "${result_path}"

test_result() {
#1 last exit status
#2 test name

  local result=0

  if test "$1" -eq 0
    then
      printf "%s\n" "Test succeeded"
    else
      printf "%s\n" "Test failed"
      printf "%-80s\t%s\n" "$2" "failed" 1>&3
      result=1
    fi
  return "$result"
}

modify_blob() {
# $1 test number
# $2 filename extension
# $3 text searched in a binary file

  local result=0

  initial_blob=$(echo -n "$3" | xxd -p)
  modified_blob=$(echo -n "FAKE" | xxd -p)
  zero_blob="00000000"
  xxd -p -c 1000 "test_$1.$2" | \
      sed "s/$initial_blob$zero_blob/$initial_blob$modified_blob/" | \
      xxd -p -r > "test_$1_changed.$2"
  ../../osslsigncode verify \
      -CAfile "${script_path}/../certs/CACert.pem" \
      -CRLfile "${script_path}/../certs/CACertCRL.pem" \
      -in "test_$1_changed.$2" 2>> "verify.log" 1>&2
  result=$?
  if test "$result" -ne 0 \
      -o $(grep -e "Calculated DigitalSignature" -e "Calculated message digest" "verify.log" | uniq | wc -l) -ne 1
    then
      printf "Failed: verify error or non-unique message digests found\n" 2>> "verify.log" 1>&2
      result=1
    else
      rm -f "test_$1_changed.$2"
    fi

  return "$result"
}

search_pattern() {
# $1 test number
# $2 filename extension
# $3 ASCII or HEX "$7 pattern" format
# $4 pattern searched in a binary file or verify.log
# $5 modify requirement

  local result=0

  if test "$3" = "ASCII"
    then
      hex_pattern=$(echo -n "$4" | xxd -p)
    else
      hex_pattern=$4
    fi
  if ! grep -q "$4" "verify.log" && \
      ! xxd -p -c 1000 "test_$1.$2" | grep "$hex_pattern" 2>> /dev/null 1>&2
    then
      result=1
      printf "Failed: $4 not found\n"
    elif test "$5" = "MODIFY"
      then
        modify_blob "$1" "$2" "$4"
        result=$?
      fi

  return "$result"
}

verify_signature() {
# $1 sign exit code
# $2 test number
# $3 filename extension
# $4 expected result
# $5 fake time
# $6 sha256sum requirement
# $7 ASCII or HEX "$7 pattern" format
# $8 pattern searched in a binary file or verify.log
# $9 modify requirement

  local result=0
  printf "" > "verify.log"
  if test "$1" -eq 0
    then
      cp "test_$2.$3" "test_tmp.tmp"
      TZ=GMT faketime -f "$5" /bin/bash -c '
          printf "Verify time: " >> "verify.log" && date >> "verify.log" && printf "\n" >> "verify.log"
          script_path=$(pwd)
          ../../osslsigncode verify \
              -CAfile "${script_path}/../certs/CACert.pem" \
              -CRLfile "${script_path}/../certs/CACertCRL.pem" \
              -in "test_tmp.tmp" 2>> "verify.log" 1>&2'
      result=$?
      rm -f "test_tmp.tmp"
      if test "$result" -eq 0 -a "$7" != "UNUSED_PATTERN" -a "$8" != "UNUSED_PATTERN"
        then
          search_pattern "$2" "$3" "$7" "$8" "$9"
          result=$?
        fi
      if test "$6" = "sha256sum"
        then
          sha256sum "test_$2.$3" 2>> "sha256sum_$3.log" 1>&2
        fi
      if test "$4" = "success" -a "$result" -eq 0
        then
          rm -f "test_$2.$3" "test_$2_signed.$3" "test_$2_modifed.$3" "test_$2_changed.$3"
          rm -f "test_$2_a.$3" "test_$2_b.$3"
          result=0
        elif test "$4" = "fail" -a "$result" -eq 1
          then
            rm -f "test_$2.$3" "test_$2_signed.$3" "test_$2_modifed.$3" "test_$2_changed.$3"
            cat "verify.log" >> "results.log"
            result=0
        else
          cat "verify.log" >> "results.log"
          result=1
        fi
    else
      result=1
    fi
  return "$result"
}

verify_leaf_hash() {
# $1 sign exit code
# $2 test number
# $3 filename extension
# $4 fake time

  local result=0
  printf "" > "verify.log"
  if test "$1" -eq 0
    then
      cp "test_$2.$3" "test_tmp.tmp"
      TZ=GMT faketime -f "$4" /bin/bash -c '
          printf "Verify time: " >> "verify.log" && date >> "verify.log" && printf "\n" >> "verify.log"
          script_path=$(pwd)
          ../../osslsigncode verify \
              -CAfile "${script_path}/../certs/CACert.pem" \
              -CRLfile "${script_path}/../certs/CACertCRL.pem" \
              -require-leaf-hash SHA256:$(sha256sum "${script_path}/../certs/cert.der" | cut -d" " -f1) \
              -in "test_tmp.tmp" 2>> "verify.log" 1>&2'
      result=$?
      rm -f "test_tmp.tmp"
      if test "$result" -eq 0
        then
          rm -f "test_$2.$3"
        else
          cat "verify.log" >> "results.log"
        fi
    else
      result=1
    fi
  return "$result"
}
