-
Notifications
You must be signed in to change notification settings - Fork 2
/
hmac
executable file
·85 lines (76 loc) · 2.32 KB
/
hmac
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
78
79
80
81
82
83
84
85
#!/bin/bash
# Implement HMAC functionality on top of the OpenSSL digest functions.
# licensed under the terms of the GNU GPL v2
# Copyright 2007 Victor Lowther <[email protected]>
set -o pipefail
die() {
echo $*
exit 1
}
check_deps() {
local res=0
while [ $# -ne 0 ]; do
which "${1}" >& /dev/null || { res=1; echo "${1} not found."; }
shift
done
(( res == 0 )) || die "aborting."
}
# write a byte (passed as hex) to stdout
write_byte() {
# $1 = byte to write
printf "\\x$(printf "%x" ${1})"
}
# make an hmac pad out of a key.
# this is not the most secure way of doing it, but it is
# the most expedient.
make_hmac_pad() {
# using key in file $1 and byte in $2, create the appropriate hmac pad
# Pad keys out to $3 bytes
# if key is longer than $3, use hash $4 to hash the key first.
local x y a size remainder oifs
[[ -f ${1} ]] || die "${1} does not exist when making hmac pads."
(( remainder = ${3} ))
# in case someone else was messing with IFS.
for x in $(od -v -t u1 < "${1}"|cut -b 9-);
do
write_byte $((${x} ^ ${2}))
(( remainder -= 1 ))
done
for ((y=0; remainder - y ;y++)); do
write_byte $((0 ^ ${2}))
done
}
# utility functions for making hmac pads
hmac_ipad() {
make_hmac_pad "${1}" 0x36 ${2} "${3}"
}
hmac_opad() {
make_hmac_pad "${1}" 0x5c ${2} "${3}"
}
# hmac something
do_hmac() {
# $1 = algo to use. Must be one that openssl knows about
# $2 = keyfile to use
# $3 = file to hash. uses stdin if none is given.
# accepts input on stdin, leaves it on stdout.
# Output is binary, if you want something else pipe it accordingly.
local blocklen keysize x
case "${1}" in
sha) blocklen=64 ;;
sha1) blocklen=64 ;;
md5) blocklen=64 ;;
md4) blocklen=64 ;;
sha256) blocklen=64 ;;
sha512) blocklen=128 ;;
*) die "Unknown hash ${1} passed to hmac!" ;;
esac
keysize="$(wc -c "${2}")"
(( ${keysize%%[!0-9 ]*} > blocklen )) && \
die "Prehashing large-size keys not implemented yet. Sorry."
cat <(hmac_ipad ${2} ${blocklen} "${1}") "${3:--}" | openssl dgst "-${1}" -binary | \
cat <(hmac_opad ${2} ${blocklen} "${1}") - | openssl dgst "-${1}" -binary
}
[[ ${1} ]] || die "Must pass the name of the hash function to use to ${0}".
[[ -f ${2} ]] || die "Must pass file containing the secret to $0"
check_deps od openssl
do_hmac "${@}"