From d8969a7bb28adb5495e0c601e41b3b1988574afa Mon Sep 17 00:00:00 2001 From: root Date: Mon, 15 Oct 2012 00:27:37 +0100 Subject: [PATCH] initial commit --- door_init.sh | 82 +++++++++++++++++++++++++++++++++++++++++++ door_lock.sh | 32 +++++++++++++++++ door_verify.sh | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+) create mode 100755 door_init.sh create mode 100755 door_lock.sh create mode 100755 door_verify.sh diff --git a/door_init.sh b/door_init.sh new file mode 100755 index 0000000..b929a51 --- /dev/null +++ b/door_init.sh @@ -0,0 +1,82 @@ +#! /bin/sh + +NAME=$1 +SLOT=$2 +if [ ! -n "$SLOT" ]; then + echo "no slot defined -> using slot 1" + SLOT=1 +fi +KEYFILE=/etc/door_keys +DATE=$(date +%s) + +rand20() { +openssl rand -hex 20 +} + +hmac() { +echo -n "$1" | openssl dgst -sha1 -mac HMAC -macopt "hexkey:$2" | cut -d= -f2 | grep -oe [0-9a-fA-F]\* +} + +challenge() { +ykchalresp -$1 $2 2>/dev/null +} + +configure() { +ykpersonalize -$1 -ochal-resp -ochal-hmac -ohmac-lt64 -y -a $2 >> /dev/null 2>&1 +} + +aes_encrypt() { +echo "$1" | openssl enc -aes256 -e -k "$2" | xxd -ps -c 256 +} + +aes_decrypt() { +echo "$1" | xxd -ps -r | openssl enc -aes256 -d -k "$2" >> /dev/null 2>&1 +DECRYPT_OK=$? +DECRYPTED_TEXT="$(echo "$1" | xxd -ps -r | openssl enc -aes256 -d -k "$2" 2>&1)" +if [ $DECRYPT_OK -ne 0 ]; then + DECRYPTED_TEXT="DEADBEEF" +fi +echo $DECRYPTED_TEXT +} + +if [ ! -f $KEYFILE ]; then + echo "creating key file under $KEYFILE" + touch $KEYFILE + chown root:root $KEYFILE + chmod 600 $KEYFILE + echo "# ID_RESP:SLOT:SECRET_KEY_ENC:NEXT_CHAL:DATE:NAME" >> $KEYFILE +fi + +#generate global challenge to identify all keys +ID_CHAL=$(cat $KEYFILE | grep -e "^ID_CHAL=" | tail -n1 | cut -d= -f2) +if [ ! -n "$ID_CHAL" ]; then + ID_CHAL=$(rand20) + echo "ID_CHAL=$ID_CHAL" >> $KEYFILE +fi + +#see if the key is already registered +ID_RESP=$(challenge $SLOT $ID_CHAL || (configure $SLOT $(rand20) && challenge $SLOT $ID_CHAL)) +KEYFILE_ENTRY=$(grep -e "^$ID_RESP" $KEYFILE | tail -n1) +if [ -n "$KEYFILE_ENTRY" ]; then + echo "key already registered" + echo "rewriting secret key" + + #delete old key + sed -i -e "/^${ID_RESP}:.*$/d" $KEYFILE +fi + +echo "registering new key" + +#configure secret key +SECRET_KEY=$(rand20) +configure $SLOT $SECRET_KEY + +#precalculate next response +NEXT_CHAL=$(rand20) +NEXT_RESP=$(hmac $NEXT_CHAL $SECRET_KEY) +ID_RESP=$(hmac $ID_CHAL $SECRET_KEY) + +#encrypt secret key +SECRET_KEY_ENC=$(aes_encrypt $SECRET_KEY $NEXT_RESP) + +echo "$ID_RESP:$SLOT:$SECRET_KEY_ENC:$NEXT_CHAL:$DATE:$NAME" >> $KEYFILE diff --git a/door_lock.sh b/door_lock.sh new file mode 100755 index 0000000..4884e5b --- /dev/null +++ b/door_lock.sh @@ -0,0 +1,32 @@ +#! /bin/sh + +GPIO_OPEN=23 +GPIO_CLOSE=24 +GPIO_CLIP=22 +SLEEP=2 + +for i in $GPIO_OPEN $GPIO_CLOSE $GPIO_CLIP; do + echo "$i" > /sys/class/gpio/export + echo "out" > /sys/class/gpio/gpio${i}/direction +done + +case $1 in + open) + echo "1" > /sys/class/gpio/gpio${GPIO_OPEN}/value + sleep $SLEEP + echo "0" > /sys/class/gpio/gpio${GPIO_OPEN}/value + ;; + close) + echo "1" > /sys/class/gpio/gpio${GPIO_CLOSE}/value + sleep $SLEEP + echo "0" > /sys/class/gpio/gpio${GPIO_CLOSE}/value + ;; + clip) + echo "1" > /sys/class/gpio/gpio${GPIO_CLIP}/value + sleep $SLEEP + echo "0" > /sys/class/gpio/gpio${GPIO_CLIP}/value + ;; + *) + echo "valid commands are \"open\", \"close\" and \"clip\"" + ;; +esac diff --git a/door_verify.sh b/door_verify.sh new file mode 100755 index 0000000..2832cc2 --- /dev/null +++ b/door_verify.sh @@ -0,0 +1,95 @@ +#! /bin/sh + +KEYFILE=/etc/door_keys +LOGFILE=/var/log/door.log +DATE=$(date +%s) + +rand20() { +openssl rand -hex 20 +} + +hmac() { +echo -n "$1" | openssl dgst -sha1 -mac HMAC -macopt "hexkey:$2" | cut -d= -f2 | grep -oe [0-9a-fA-F]\* +} + +aes_encrypt() { +echo "$1" | openssl enc -aes256 -e -k "$2" | xxd -ps -c 256 +} + +aes_decrypt() { +echo "$1" | xxd -ps -r | openssl enc -aes256 -d -k "$2" >> /dev/null 2>&1 +DECRYPT_OK=$? +DECRYPTED_TEXT="$(echo "$1" | xxd -ps -r | openssl enc -aes256 -d -k "$2" 2>&1)" +if [ $DECRYPT_OK -ne 0 ]; then + DECRYPTED_TEXT="DEADBEEF" +fi +echo $DECRYPTED_TEXT +} + +challenge() { +ykchalresp -$1 $2 2>/dev/null +} + +if [ ! -f $KEYFILE ]; then + echo "no keyfile found" >&2 + exit 1 +fi + +if [ ! -f $LOGFILE ]; then + echo "generating new logfile" >&2 + echo "# DATE:ID:SIGNED_DATE:STATUS" > $LOGFILE + chmod 600 $LOGFILE +fi + +ID_CHAL=$(cat $KEYFILE | grep -e "^ID_CHAL=" | tail -n1 | cut -d= -f2) +if [ ! -n "$ID_CHAL" ]; then + echo "no global challenge defined (can't identify keys)" >&2 + exit 1 +fi + + +ID_RESP_1=$(challenge 1 $ID_CHAL) +ID_RESP_2=$(challenge 2 $ID_CHAL) +KEYFILE_ENTRY_1=$(grep -e "^$ID_RESP_1" $KEYFILE | tail -n1) +KEYFILE_ENTRY_2=$(grep -e "^$ID_RESP_2" $KEYFILE | tail -n1) +if [ -n "$KEYFILE_ENTRY_1" ]; then + KEYFILE_ENTRY=$KEYFILE_ENTRY_1 + SLOT=1 +elif [ -n "$KEYFILE_ENTRY_2" ]; then + KEYFILE_ENTRY=$KEYFILE_ENTRY_2 + SLOT=2 +else + echo "key couldn't be identified" >&2 + echo "$DATE:::ERROR_UNKNOWN_ID" >> $LOGFILE + exit 1 +fi + +ID=$(echo $KEYFILE_ENTRY | cut -d: -f1) +SLOT=$(echo $KEYFILE_ENTRY | cut -d: -f2) +SECRET_KEY_ENC=$(echo $KEYFILE_ENTRY | cut -d: -f3) +CHALLENGE=$(echo $KEYFILE_ENTRY | cut -d: -f4) + +#challenge key +RESPONSE=$(challenge $SLOT $CHALLENGE) +SECRET_KEY="$(aes_decrypt $SECRET_KEY_ENC $RESPONSE)" +if test "$(hmac $CHALLENGE $SECRET_KEY)" = "$RESPONSE"; then + echo "$DATE:$ID:$(hmac $DATE $SECRET_KEY):OK" >> $LOGFILE + echo "OK" + + #precalculate next response + NEXT_CHALLENGE=$(rand20) + NEXT_RESP=$(hmac $NEXT_CHALLENGE $SECRET_KEY) + + #encrypt secret key + SECRET_KEY_ENC=$(aes_encrypt $SECRET_KEY $NEXT_RESP) + SECRET_KEY="" + + export ID=$ID SLOT=$SLOT SECRET_KEY_ENC=$SECRET_KEY_ENC NEXT_CHALLENGE=$NEXT_CHALLENGE + sed -i -e "s/^${ID}:[^:]*:[^:]*:[^:]*:/$ID:$SLOT:$SECRET_KEY_ENC:$NEXT_CHALLENGE:/" $KEYFILE + export ID="" SLOT="" SECRET_KEY_ENC="" NEXT_CHALLENGE="" CREATION_DATE="" KEY_NAME="" + exit 0 +else + echo "$DATE:$ID::ERROR_FAILED_ON_CHALLENGE" >> $LOGFILE + echo "not identified" + exit 1 +fi