hcoop-backup: Put temp output in hcoop-backup, not hcoop-backup-testing.
[clinton/scripts.git] / s3-hmac
1 #!/bin/bash
2 # Implement HMAC functionality on top of the OpenSSL digest functions.
3 # licensed under the terms of the GNU GPL v2
4 # Copyright 2007 Victor Lowther <victor.lowther@gmail.com>
5
6 die() {
7 echo $*
8 exit 1
9 }
10
11 check_deps() {
12 local res=0
13 while [ $# -ne 0 ]; do
14 which "${1}" >& /dev/null || { res=1; echo "${1} not found."; }
15 shift
16 done
17 (( res == 0 )) || die "aborting."
18 }
19
20 # write a byte (passed as hex) to stdout
21 write_byte() {
22 # $1 = byte to write
23 printf "\\x$(printf "%x" ${1})"
24 }
25
26 # make an hmac pad out of a key.
27 # this is not the most secure way of doing it, but it is
28 # the most expedient.
29 make_hmac_pad() {
30 # using key in file $1 and byte in $2, create the appropriate hmac pad
31 # Pad keys out to $3 bytes
32 # if key is longer than $3, use hash $4 to hash the key first.
33 local x y a size remainder oifs
34 [[ -f ${1} ]] || die "${1} does not exist when making hmac pads."
35 (( remainder = ${3} ))
36 # in case someone else was messing with IFS.
37 for x in $(od -v -t u1 < "${1}"|cut -b 9-);
38 do
39 write_byte $((${x} ^ ${2}))
40 (( remainder -= 1 ))
41 done
42 for ((y=0; remainder - y ;y++)); do
43 write_byte $((0 ^ ${2}))
44 done
45 }
46
47 # utility functions for making hmac pads
48 hmac_ipad() {
49 make_hmac_pad "${1}" 0x36 ${2} "${3}"
50 }
51
52 hmac_opad() {
53 make_hmac_pad "${1}" 0x5c ${2} "${3}"
54 }
55
56 # hmac something
57 do_hmac() {
58 # $1 = algo to use. Must be one that openssl knows about
59 # $2 = keyfile to use
60 # $3 = file to hash. uses stdin if none is given.
61 # accepts input on stdin, leaves it on stdout.
62 # Output is binary, if you want something else pipe it accordingly.
63 local blocklen keysize x
64 case "${1}" in
65 sha) blocklen=64 ;;
66 sha1) blocklen=64 ;;
67 md5) blocklen=64 ;;
68 md4) blocklen=64 ;;
69 sha256) blocklen=64 ;;
70 sha512) blocklen=128 ;;
71 *) die "Unknown hash ${1} passed to hmac!" ;;
72 esac
73 keysize="$(wc -c "${2}")"
74 (( ${keysize%%[!0-9 ]*} > blocklen )) && \
75 die "Prehashing large-size keys not implemented yet. Sorry."
76 cat <(hmac_ipad ${2} ${blocklen} "${1}") "${3:--}" | openssl dgst "-${1}" -binary | \
77 cat <(hmac_opad ${2} ${blocklen} "${1}") - | openssl dgst "-${1}" -binary
78 }
79
80 [[ ${1} ]] || die "Must pass the name of the hash function to use to ${0}".
81
82 [[ -f ${2} ]] || die "Must pass file containing the secret to $0"
83 check_deps od openssl
84 do_hmac "${@}"