check-hash 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #!/usr/bin/env bash
  2. set -e
  3. # Helper to check a file matches its known hash
  4. # Call it with:
  5. # $1: the path of the file containing all the the expected hashes
  6. # $2: the full path to the temporary file that was downloaded, and
  7. # that is to be checked
  8. # $3: the final basename of the file, to which it will be ultimately
  9. # saved as, to be able to match it to the corresponding hashes
  10. # in the .hash file
  11. while getopts :q OPT; do
  12. case "${OPT}" in
  13. q) exec >/dev/null;;
  14. \?) exit 1;;
  15. esac
  16. done
  17. shift $((OPTIND-1))
  18. h_file="${1}"
  19. file="${2}"
  20. base="${3}"
  21. # Does the hash-file exist?
  22. if [ -z "${h_file}" -o ! -f "${h_file}" ]; then
  23. exit 0
  24. fi
  25. # Check one hash for a file
  26. # $1: known hash
  27. # $2: file (full path)
  28. check_one_hash() {
  29. _h="${1}"
  30. _known="${2}"
  31. _file="${3}"
  32. # Note: md5 is supported, but undocumented on purpose.
  33. # Note: sha3 is not supported, since there is currently no implementation
  34. # (the NIST has yet to publish the parameters).
  35. # Note: 'none' means there is explicitly no hash for that file.
  36. case "${_h}" in
  37. none)
  38. return 0
  39. ;;
  40. md5|sha1) ;;
  41. sha224|sha256|sha384|sha512) ;;
  42. *) # Unknown hash, exit with error
  43. printf "ERROR: unknown hash '%s' for '%s'\n" \
  44. "${_h}" "${base}" >&2
  45. exit 1
  46. ;;
  47. esac
  48. # Do the hashes match?
  49. _hash=$( ${_h}sum "${_file}" |cut -d ' ' -f 1 )
  50. if [ "${_hash}" = "${_known}" ]; then
  51. printf "%s: OK (%s: %s)\n" "${base}" "${_h}" "${_hash}"
  52. return 0
  53. fi
  54. printf "ERROR: %s has wrong %s hash:\n" "${base}" "${_h}" >&2
  55. printf "ERROR: expected: %s\n" "${_known}" >&2
  56. printf "ERROR: got : %s\n" "${_hash}" >&2
  57. printf "ERROR: Incomplete download, or man-in-the-middle (MITM) attack\n" >&2
  58. exit 1
  59. }
  60. # Do we know one or more hashes for that file?
  61. nb_checks=0
  62. while read t h f; do
  63. case "${t}" in
  64. ''|'#'*)
  65. # Skip comments and empty lines
  66. continue
  67. ;;
  68. *)
  69. if [ "${f}" = "${base}" ]; then
  70. check_one_hash "${t}" "${h}" "${file}"
  71. : $((nb_checks++))
  72. fi
  73. ;;
  74. esac
  75. done <"${h_file}"
  76. if [ ${nb_checks} -eq 0 ]; then
  77. if [ -n "${BR2_ENFORCE_CHECK_HASH}" ]; then
  78. printf "ERROR: No hash found for %s\n" "${base}" >&2
  79. exit 1
  80. else
  81. printf "WARNING: No hash found for %s\n" "${base}" >&2
  82. fi
  83. fi