blob: 4f5e56b79f98b00f3ffc36232a800a39d9795c05 [file] [log] [blame]
David Brown23f91ad2017-05-16 11:38:17 -06001#! /usr/bin/env python3
2
3import argparse
4from imgtool import keys
5from imgtool import image
6from imgtool import version
7import sys
8
9def gen_rsa2048(args):
10 keys.RSA2048.generate().export_private(args.keyfile)
11def gen_ecdsa_p256(args):
12 keys.ecdsa256p1.generate().export_private(args.keyfile)
13def gen_ecdsa_p224(args):
14 print("TODO: p-224 not yet implemented")
15
16keygens = {
17 'rsa-2048': gen_rsa2048,
18 'ecdsa-p256': gen_ecdsa_p256,
19 'ecdsa-p224': gen_ecdsa_p224, }
20
21def do_keygen(args):
22 if args.type not in keygens:
23 msg = "Unexpected key type: {}".format(args.type)
24 raise argparse.ArgumentTypeError(msg)
25 keygens[args.type](args)
26
27def do_getpub(args):
28 key = keys.load(args.key)
29 key.emit_c()
30
31def do_sign(args):
32 align = args.align
33 # print('sign:', args)
34 img = image.Image.load(args.infile, version=args.version,
35 header_size=args.header_size,
36 pad=args.pad)
37 key = keys.load(args.key)
38 img.sign(key)
39
40 if args.pad:
41 img.pad_to(args.pad, args.align)
42
43 img.save(args.outfile)
44
45subcmds = {
46 'keygen': do_keygen,
47 'getpub': do_getpub,
48 'sign': do_sign, }
49
50def alignment_value(text):
51 value = int(text)
52 if value not in [1, 2, 4, 8]:
53 msg = "{} must be one of 1, 2, 4 or 8".format(value)
54 raise argparse.ArgumentTypeError(msg)
55 return value
56
57def intparse(text):
58 """Parse a command line argument as an integer.
59
60 Accepts 0x and other prefixes to allow other bases to be used."""
61 return int(text, 0)
62
63def args():
64 parser = argparse.ArgumentParser()
65 subs = parser.add_subparsers(help='subcommand help', dest='subcmd')
66
67 keygenp = subs.add_parser('keygen', help='Generate pub/private keypair')
68 keygenp.add_argument('-k', '--key', metavar='filename', required=True)
69 keygenp.add_argument('-t', '--type', metavar='type',
70 choices=['rsa-2048', 'ecdsa-p224', 'ecdsa-p256'],
71 required=True)
72
73 getpub = subs.add_parser('getpub', help='Get public key from keypair')
74 getpub.add_argument('-k', '--key', metavar='filename', required=True)
75
76 sign = subs.add_parser('sign', help='Sign an image with a private key')
77 sign.add_argument('-k', '--key', metavar='filename', required=True)
78 sign.add_argument("--align", type=alignment_value, required=True)
79 sign.add_argument("-v", "--version", type=version.decode_version, required=True)
80 sign.add_argument("-H", "--header-size", type=intparse, required=True)
81 sign.add_argument("--pad", type=intparse,
82 help='Pad image to this many bytes, adding trailer magic')
83 sign.add_argument("infile")
84 sign.add_argument("outfile")
85
86 args = parser.parse_args()
87 if args.subcmd is None:
88 print('Must specify a subcommand', file=sys.stderr)
89 sys.exit(1)
90
91 subcmds[args.subcmd](args)
92
93if __name__ == '__main__':
94 args()