|
| 1 | +#!/usr/bin/env python |
| 2 | +# -*- coding: utf-8 -*- |
| 3 | +# |
| 4 | +import sys |
| 5 | +import argparse |
| 6 | +import subprocess |
| 7 | +import hashlib |
| 8 | + |
| 9 | +def parse_args(): |
| 10 | + parser = argparse.ArgumentParser(description='Binary signing tool') |
| 11 | + parser.add_argument('-m', '--mode', help='Mode (header, sign)') |
| 12 | + parser.add_argument('-b', '--bin', help='Unsigned binary') |
| 13 | + parser.add_argument('-o', '--out', help='Output file'); |
| 14 | + parser.add_argument('-p', '--publickey', help='Public key file'); |
| 15 | + parser.add_argument('-s', '--privatekey', help='Private(secret) key file'); |
| 16 | + return parser.parse_args() |
| 17 | + |
| 18 | + |
| 19 | +def main(): |
| 20 | + args = parse_args() |
| 21 | + if args.mode == "header": |
| 22 | + val = "" |
| 23 | + try: |
| 24 | + with open(args.publickey, "rb") as f: |
| 25 | + pub = f.read() |
| 26 | + val += "#include <pgmspace.h>\n" |
| 27 | + val += "#define ARDUINO_SIGNING 1\n" |
| 28 | + val += "static const char signing_pubkey[] PROGMEM = {\n" |
| 29 | + for i in pub: |
| 30 | + val += "0x%02x, \n" % ord(i) |
| 31 | + val = val[:-3] |
| 32 | + val +="\n};\n" |
| 33 | + print "Enabling binary signing\n" |
| 34 | + except: |
| 35 | + print "Not enabling binary signing\n" |
| 36 | + val += "#define ARDUINO_SIGNING 0\n" |
| 37 | + with open(args.out, "w") as f: |
| 38 | + f.write(val) |
| 39 | + return 0 |
| 40 | + elif args.mode == "sign": |
| 41 | + val = "" |
| 42 | + try: |
| 43 | + with open(args.bin, "rb") as b: |
| 44 | + bin = b.read() |
| 45 | + sha256 = hashlib.sha256(bin) |
| 46 | + print "Binary SHA256 = " + sha256.hexdigest() |
| 47 | + signcmd = [ 'openssl', 'rsautl', '-sign', '-inkey', args.privatekey ] |
| 48 | + proc = subprocess.Popen(signcmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) |
| 49 | + signout = proc.communicate(input=sha256.digest())[0] |
| 50 | + with open(args.out, "wb") as out: |
| 51 | + out.write(bin) |
| 52 | + out.write(signout) |
| 53 | + out.write(b'\x00\x01\x00\x00') |
| 54 | + print "Signed binary: " + args.out |
| 55 | + except: |
| 56 | + print "Not signing the generated binary\n" |
| 57 | + return 0 |
| 58 | + else: |
| 59 | + print "ERROR: Mode not specified as header or sign\n" |
| 60 | + |
| 61 | +if __name__ == '__main__': |
| 62 | + sys.exit(main()) |
| 63 | + |
0 commit comments