aboutsummaryrefslogtreecommitdiff
path: root/support/download/check-hash
blob: 067e7a2395d8c400a3442e81dfddfaaf26ab2367 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/env 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: md5 is supported, but undocumented on purpose.
    # 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