check-hash 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. h_file="${1}"
  12. file="${2}"
  13. base="${3}"
  14. # Does the hash-file exist?
  15. if [ ! -f "${h_file}" ]; then
  16. exit 0
  17. fi
  18. # Check one hash for a file
  19. # $1: known hash
  20. # $2: file (full path)
  21. check_one_hash() {
  22. _h="${1}"
  23. _known="${2}"
  24. _file="${3}"
  25. # Note: md5 is supported, but undocumented on purpose.
  26. # Note: sha3 is not supported, since there is currently no implementation
  27. # (the NIST has yet to publish the parameters).
  28. case "${_h}" in
  29. md5|sha1) ;;
  30. sha224|sha256|sha384|sha512) ;;
  31. *) # Unknown hash, exit with error
  32. printf "ERROR: unknown hash '%s' for '%s'\n" \
  33. "${_h}" "${base}" >&2
  34. exit 1
  35. ;;
  36. esac
  37. # Do the hashes match?
  38. _hash=$( ${_h}sum "${_file}" |cut -d ' ' -f 1 )
  39. if [ "${_hash}" = "${_known}" ]; then
  40. printf "%s: OK (%s: %s)\n" "${base}" "${_h}" "${_hash}"
  41. return 0
  42. fi
  43. printf "ERROR: %s has wrong %s hash:\n" "${base}" "${_h}" >&2
  44. printf "ERROR: expected: %s\n" "${_known}" >&2
  45. printf "ERROR: got : %s\n" "${_hash}" >&2
  46. printf "ERROR: Incomplete download, or man-in-the-middle (MITM) attack\n" >&2
  47. exit 1
  48. }
  49. # Do we know one or more hashes for that file?
  50. nb_checks=0
  51. while read t h f; do
  52. case "${t}" in
  53. ''|'#'*)
  54. # Skip comments and empty lines
  55. continue
  56. ;;
  57. *)
  58. if [ "${f}" = "${base}" ]; then
  59. check_one_hash "${t}" "${h}" "${file}"
  60. : $((nb_checks++))
  61. fi
  62. ;;
  63. esac
  64. done <"${h_file}"
  65. if [ ${nb_checks} -eq 0 ]; then
  66. if [ -n "${BR2_ENFORCE_CHECK_HASH}" ]; then
  67. printf "ERROR: No hash found for %s\n" "${base}" >&2
  68. exit 1
  69. else
  70. printf "WARNING: No hash found for %s\n" "${base}" >&2
  71. fi
  72. fi