aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package/pkg-download.mk20
-rwxr-xr-xsupport/download/check-hash76
2 files changed, 93 insertions, 3 deletions
diff --git a/package/pkg-download.mk b/package/pkg-download.mk
index d3cd0c144e..7f208d538b 100644
--- a/package/pkg-download.mk
+++ b/package/pkg-download.mk
@@ -58,6 +58,17 @@ domainseparator=$(if $(1),$(1),/)
# github(user,package,version): returns site of GitHub repository
github = https://github.com/$(1)/$(2)/archive/$(3)
+# Helper for checking a tarball's checksum
+# If the hash does not match, remove the incorrect file
+# $(1): the path to the file with the hashes
+# $(2): the full path to the file to check
+define VERIFY_HASH
+ if ! support/download/check-hash $(1) $(2); then \
+ rm -f $(2); \
+ exit 1; \
+ fi
+endef
+
################################################################################
# The DOWNLOAD_* helpers are in charge of getting a working copy
# of the source repository for their corresponding SCM,
@@ -148,7 +159,8 @@ endef
define DOWNLOAD_SCP
test -e $(DL_DIR)/$(2) || \
$(EXTRA_ENV) support/download/scp '$(call stripurischeme,$(call qstrip,$(1)))' \
- $(DL_DIR)/$(2)
+ $(DL_DIR)/$(2) && \
+ $(call VERIFY_HASH,$(PKGDIR)/$($(PKG)_NAME).hash,$(DL_DIR)/$(2))
endef
define SOURCE_CHECK_SCP
@@ -179,7 +191,8 @@ endef
define DOWNLOAD_WGET
test -e $(DL_DIR)/$(2) || \
- $(EXTRA_ENV) support/download/wget '$(call qstrip,$(1))' $(DL_DIR)/$(2)
+ $(EXTRA_ENV) support/download/wget '$(call qstrip,$(1))' $(DL_DIR)/$(2) && \
+ $(call VERIFY_HASH,$(PKGDIR)/$($(PKG)_NAME).hash,$(DL_DIR)/$(2))
endef
define SOURCE_CHECK_WGET
@@ -193,7 +206,8 @@ endef
define DOWNLOAD_LOCALFILES
test -e $(DL_DIR)/$(2) || \
$(EXTRA_ENV) support/download/cp $(call stripurischeme,$(call qstrip,$(1))) \
- $(DL_DIR)
+ $(DL_DIR) && \
+ $(call VERIFY_HASH,$(PKGDIR)/$($(PKG)_NAME).hash,$(DL_DIR)/$(2))
endef
define SOURCE_CHECK_LOCALFILES
diff --git a/support/download/check-hash b/support/download/check-hash
new file mode 100755
index 0000000000..9ea7c415a1
--- /dev/null
+++ b/support/download/check-hash
@@ -0,0 +1,76 @@
+#!/bin/bash
+set -e
+
+# Helper to check a file matches its known hash
+# Call it with:
+# $1: the full path to the file to check
+# $2: the path of the file containing all the the expected hashes
+
+h_file="${1}"
+file="${2}"
+
+# Does the hash-file exist?
+if [ ! -f "${h_file}" ]; then
+ exit 0
+fi
+
+# Check one hash for a file
+# $1: known hash
+# $2: file (full path)
+check_one_hash() {
+ _h="${1}"
+ _known="${2}"
+ _file="${3}"
+
+ # Note: sha3 is not supported, since there is currently no implementation
+ # (the NIST has yet to publish the parameters).
+ case "${_h}" in
+ md5|sha1) ;;
+ sha224|sha256|sha384|sha512) ;;
+ *) # Unknown hash, exit with error
+ printf "ERROR: unknown hash '%s' for '%s'\n" \
+ "${_h}" "${_file##*/}" >&2
+ exit 1
+ ;;
+ esac
+
+ # Do the hashes match?
+ _hash=$( ${_h}sum "${_file}" |cut -d ' ' -f 1 )
+ if [ "${_hash}" = "${_known}" ]; then
+ printf "%s: OK (%s: %s)\n" "${_file##*/}" "${_h}" "${_hash}"
+ return 0
+ fi
+
+ printf "ERROR: %s has wrong %s hash:\n" "${_file##*/}" "${_h}" >&2
+ printf "ERROR: expected: %s\n" "${_known}" >&2
+ printf "ERROR: got : %s\n" "${_hash}" >&2
+ printf "ERROR: Incomplete download, or man-in-the-middle (MITM) attack\n" >&2
+
+ exit 1
+}
+
+# Do we know one or more hashes for that file?
+nb_checks=0
+while read t h f; do
+ case "${t}" in
+ ''|'#'*)
+ # Skip comments and empty lines
+ continue
+ ;;
+ *)
+ if [ "${f}" = "${file##*/}" ]; then
+ check_one_hash "${t}" "${h}" "${file}"
+ : $((nb_checks++))
+ fi
+ ;;
+ esac
+done <"${h_file}"
+
+if [ ${nb_checks} -eq 0 ]; then
+ if [ -n "${BR2_ENFORCE_CHECK_HASH}" ]; then
+ printf "ERROR: No hash found for %s\n" "${file}" >&2
+ exit 1
+ else
+ printf "WARNING: No hash found for %s\n" "${file}" >&2
+ fi
+fi