# 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 number
#3 test name

  local result=0

  if test "$1" -eq 0
    then
      printf "%s\n" "Test succeeded"
    else
      printf "%s\n" "Test failed"
      printf "%03d. %-90s\t%s\n" "$2" "$3" "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 > "changed_$1.$2"

  ../../osslsigncode verify \
      -CAfile "${script_path}/../certs/CACert.pem" \
      -CRLfile "${script_path}/../certs/CACertCRL.pem" \
      -in "changed_$1.$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) -gt 1
    then
      printf "Failed: verify error or non-unique message digests found\n" 2>> "verify.log" 1>&2
      result=1
    else
      rm -f "changed_$1.$2"
    fi

  return "$result"
}

search_pattern() {
# $1 test number
# $2 filename extension
# $3 pattern searched in a binary file or verify.log

  local result=0

  if ! grep -q "$3" "verify.log"
    then
      hex_pattern=$(echo -n "$3" | xxd -p)
      if ! xxd -p -c 1000 "test_$1.$2" | grep "$hex_pattern" 2>> /dev/null 1>&2
        then
          result=1
          printf "Failed: $3 not found\n"
        fi
    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 pattern searched in the verify.log file
# $8 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"
        then
          search_pattern "$2" "$3" "$7"
          result=$?
        fi

      if test "$result" -eq 0 -a "$8" == "MODIFY"
        then
          modify_blob "$2" "$3" "$7"
          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" "signed_$2.$3" "signed1_$2.$3" "signed2_$2.$3"
        elif test "$4" = "fail" -a "$result" -eq 1
          then
            rm -f "test_$2.$3" "signed_$2.$3" "signed1_$2.$3" "signed2_$2.$3"
            rm -f "changed_$2.$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"
}