diff --git a/lib/Makefile b/lib/Makefile new file mode 100644 index 0000000..83f624e --- /dev/null +++ b/lib/Makefile @@ -0,0 +1,55 @@ +# Tell make to use C++ compiler rule for .c files +COMPILE.c = $(COMPILE.cc) + +CPPFLAGS += -g -Wall -O2 + +.PHONY: clean all test help + +help: + @echo "This Makefile supports the following targets:" + @echo " * signer build signer executable" + @echo " * test check signer operation" + @echo " * all creates executable and runs test" + @echo " * clean removes executable and object files" + @echo " * keys.txt generate a new key pair" + @echo " * keys.sh create shell script to set generated keys when running MCP" + @echo " * keys.c generate C code for adding new public key into Tilda firmware" + +all: signer test + +main.o uECC.o: uECC.h + +signer: main.o uECC.o + $(LINK.cc) -o $@ $^ + +clean: + rm -f signer main.o uECC.o + +test: + ./test.sh + +keys.txt: + ./signer create > $@ + +keys.sh: keys.txt + ( \ + echo "# To generate radio messages signed with your key pair you must"; \ + echo "# set these environment variables before running the MCP"; \ + echo -n "export EMF_PRIVATE_KEY="; \ + echo `grep -A 1 "PRIVATE:" $^ | tail -n 1`; \ + echo -n "export EMF_PUBLIC_KEY="; \ + echo `grep -A 1 "PUBLIC:" $^ | tail -n 1` \ + ) | tee $@ + +keys.c: keys.txt + ( \ + echo "# To make your badge trust messages signed by your"; \ + echo "# new key pair you must replace the public key in"; \ + echo "# EMF2014Config.h with:"; \ + echo ""; \ + echo "const uint8_t EMF_PUBLIC_KEY[40] = {"; \ + grep -A 1 "PUBLIC:" $^ | tail -n 1 | xxd -r -p | xxd -i -c 10; \ + echo "};"; \ + echo ""; \ + echo "# Then rebuild the firmware and download to your badge."; \ + ) | tee $@ diff --git a/lib/main.c b/lib/main.c index d4d7bdf..cc39d40 100644 --- a/lib/main.c +++ b/lib/main.c @@ -2,6 +2,7 @@ #include "uECC.h" #include #include +#include int char2int(uint8_t input) { @@ -11,13 +12,13 @@ int char2int(uint8_t input) return input - 'A' + 10; if(input >= 'a' && input <= 'f') return input - 'a' + 10; - throw "Invalid input string"; + throw std::runtime_error("Invalid input string"); } int main(int argc, char *argv[]) { if (argc < 2) { - std::cerr << "Define mode: sign | verify | create"; + std::cerr << "Define mode: sign | verify | create\n"; return 1; } @@ -49,7 +50,12 @@ int main(int argc, char *argv[]) if (mode.compare("sign") == 0) { - std::string privateKeyAsHex(getenv("EMF_PRIVATE_KEY")); + char *private_key = getenv("EMF_PRIVATE_KEY"); + if (!private_key) { + std::cerr << "Must set EMF_PRIVATE_KEY environment variable for signing\n"; + return 1; + } + std::string privateKeyAsHex(private_key); for (int i=0; i $KEYS + +# Load the new keys in the environment variables expected by signer +export EMF_PRIVATE_KEY=`grep -A 1 "PRIVATE:" $KEYS | tail -n 1` +export EMF_PUBLIC_KEY=`grep -A 1 "PUBLIC:" $KEYS | tail -n 1` + +# Generate hash, must be 20 bytes long ASCII hex +HASH="20140913cafefeedBADC00123456789012345600" + +# Sign hash +SIGNED=`echo $HASH | ./signer sign` + +# Check output contains the hash at beginning +echo $SIGNED | egrep -qi "^$HASH" + +# Test valid data, expect 'OK' response +echo $SIGNED | ./signer verify | grep -q "OK" + +# Test corrupted signature, expect 'Invalid' response +CORRUPT=`echo $SIGNED | sed -e 's/0/f/'` +echo $CORRUPT | ./signer verify | grep -q "Invalid" + +rm $KEYS +echo "PASS"