diff --git a/.gitignore b/.gitignore index af08cfa..3eabd07 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ */.dep doc/chopstx.info .vs/ +test/*.json diff --git a/src/inject_key.py b/src/inject_key.py index 80a0c61..368e0af 100755 --- a/src/inject_key.py +++ b/src/inject_key.py @@ -10,8 +10,10 @@ # > openssl ecparam -name prime256v1 -genkey -noout -outform der > key.der # # Inject generated key into u2f.bin and set auth counter to 100: -# > python3 inject_key.py --key key.der --ctr 100 +# > python3 inject_key_bin.py --key key.der --ctr 100 --bin build/u2f.bin # +# key will not be modified if --key parameter is not present +# counter will not be modified if --ctr parameter is not present from __future__ import print_function from asn1crypto.keys import ECPrivateKey @@ -20,49 +22,60 @@ import sys import struct import os -import tempfile -import subprocess parser = argparse.ArgumentParser() -parser.add_argument("--elf", default="build/u2f.elf", - help=".elf file to inject keys into") +parser.add_argument("--bin", default="build/u2f.bin", + help='.bin file to inject keys into. Or "stdin"') parser.add_argument("--key", help="EC private key in DER format") -parser.add_argument("--ctr", default=1, type=int, help="value of auth counter") +parser.add_argument("--ctr", default=0, type=lambda x: int(x,0), help="Value of auth counter") +parser.add_argument("--offset", default=0, type=lambda x: int(x,0), help="Offset within file to patch") args = parser.parse_args() -# load and parse private key -if args.key: - with open(args.key, "rb") as f: - der = f.read() +fname, fext = os.path.splitext(args.bin) +assert fext == ".bin" + +fsize = os.path.getsize(args.bin) + +print("Target binary file %s, size 0x%X" % (args.bin, fsize)) + +if args.offset: + offset = args.offset else: - stdin = sys.stdin.buffer if hasattr(sys.stdin, "buffer") else sys.stdin - der = stdin.read() -key = ECPrivateKey.load(der) + offset = fsize - 0x800 -# convert key into raw bytes and calculate it's sha256 -key_bytes = bytearray.fromhex(format(key["private_key"].native, '064x')) -key_hash = hashlib.sha256(key_bytes).digest() +# load and parse private key +if not args.key: + print("Key not modified") +else: + key_offset = offset + print("Injecting key from %s at 0x%0X" % (args.key, key_offset)) + if args.key == "stdin": + stdin = sys.stdin.buffer if hasattr(sys.stdin, "buffer") else sys.stdin + der = stdin.read() + else: + with open(args.key, "rb") as f: + der = f.read() + key = ECPrivateKey.load(der) -# fill authentication counter -ctr_bytes = struct.pack(" regchallenge.json +cat regchallenge.json +echo "Touch key to confirm registration" +u2f-host -a register -o 'https://demo.yubico.com' < regchallenge.json > regdata.json +#cat regdata.json +curl https://demo.yubico.com/wsapi/u2f/bind -d "username=$user&password=$pass&data=$(cat regdata.json)" +curl "https://demo.yubico.com/wsapi/u2f/sign?username=$user&password=$pass" > challenge.json +cat challenge.json +echo "Touch key to confirm authentication" +u2f-host -a authenticate -o 'https://demo.yubico.com' < challenge.json > signature.json +#cat signature.json +curl https://demo.yubico.com/wsapi/u2f/verify -d "username=$user&password=$pass&data=$(cat signature.json)" > response.json +cat response.json +echo "" + +if [ "$1" != "-k" ] +then + rm *.json +fi +