Skip to content

Commit b9344f6

Browse files
Earle F. Philhower, IIIEarle F. Philhower, III
Earle F. Philhower, III
authored and
Earle F. Philhower, III
committed
Add python automatic signing if keys present
1 parent 5fb8cd5 commit b9344f6

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

platform.txt

+5-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ version=2.5.0-dev
1010

1111
runtime.tools.xtensa-lx106-elf-gcc.path={runtime.platform.path}/tools/xtensa-lx106-elf
1212
runtime.tools.esptool.path={runtime.platform.path}/tools/esptool
13+
runtime.tools.signing={runtime.platform.path}/tools/signing.py
1314

1415
compiler.warning_flags=-w
1516
compiler.warning_flags.none=-w
@@ -74,6 +75,8 @@ compiler.elf2hex.extra_flags=
7475
## needs bash, git, and echo
7576
recipe.hooks.core.prebuild.1.pattern=bash -c "mkdir -p {build.path}/core && echo \#define ARDUINO_ESP8266_GIT_VER 0x`git --git-dir {runtime.platform.path}/.git rev-parse --short=8 HEAD 2>/dev/null || echo ffffffff` >{build.path}/core/core_version.h"
7677
recipe.hooks.core.prebuild.2.pattern=bash -c "mkdir -p {build.path}/core && echo \#define ARDUINO_ESP8266_GIT_DESC `cd "{runtime.platform.path}"; git describe --tags 2>/dev/null || echo unix-{version}` >>{build.path}/core/core_version.h"
78+
recipe.hooks.core.prebuild.2.pattern="{runtime.tools.signing}" --mode header --publickey "{build.source.path}/public.key" --out "{build.path}/core/Updater_Signing.h"
79+
7780
## windows-compatible version without git
7881
recipe.hooks.core.prebuild.1.pattern.windows=cmd.exe /c mkdir {build.path}\core & (echo #define ARDUINO_ESP8266_GIT_VER 0x00000000 & echo #define ARDUINO_ESP8266_GIT_DESC win-{version} ) > {build.path}\core\core_version.h
7982
recipe.hooks.core.prebuild.2.pattern.windows=
@@ -102,7 +105,8 @@ recipe.objcopy.eep.pattern=
102105
## Create hex
103106
#recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"
104107

105-
recipe.objcopy.hex.pattern="{runtime.tools.esptool.path}/{compiler.esptool.cmd}" -eo "{runtime.platform.path}/bootloaders/eboot/eboot.elf" -bo "{build.path}/{build.project_name}.bin" -bm {build.flash_mode} -bf {build.flash_freq} -bz {build.flash_size} -bs .text -bp 4096 -ec -eo "{build.path}/{build.project_name}.elf" -bs .irom0.text -bs .text -bs .data -bs .rodata -bc -ec
108+
recipe.objcopy.hex.1.pattern="{runtime.tools.esptool.path}/{compiler.esptool.cmd}" -eo "{runtime.platform.path}/bootloaders/eboot/eboot.elf" -bo "{build.path}/{build.project_name}.bin" -bm {build.flash_mode} -bf {build.flash_freq} -bz {build.flash_size} -bs .text -bp 4096 -ec -eo "{build.path}/{build.project_name}.elf" -bs .irom0.text -bs .text -bs .data -bs .rodata -bc -ec
109+
recipe.objcopy.hex.2.pattern="{runtime.tools.signing}" --mode sign --privatekey "{build.source.path}/private.key" --bin "{build.path}/{build.project_name}.bin" --out "{build.path}/{build.project_name}.bin.signed"
106110

107111
## Save hex
108112
recipe.output.tmp_file={build.project_name}.bin

tools/signing.py

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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

Comments
 (0)