123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- From 8228c484a1533ff904b276c342adcb6310abe272 Mon Sep 17 00:00:00 2001
- From: Taahir Ahmed <ahmed.taahir@gmail.com>
- Date: Wed, 30 Mar 2016 11:23:54 -0300
- Subject: [PATCH] crda: support python 3 in utils/key2pub.py
- utils/key2pub.py can now be run under either python 2.7 or python 3.x.
- This required some minor syntactical changes as well as switching from
- M2Crypto to pycryptodomex, since M2Crypto doesn't support python 3.x.
- In addition, some errors in the generated source file keys-ssl.h are
- fixed:
- * The correct OpenSSL header for BN_ULONG is included.
- * The generated constants are given the 'ull' suffix to prevent
- warnings about constants that are too large.
- [Gustavo: don't call /utils/key2pub.py since that doesn't compute]
- Use pycryptodomex insdead of pycrypto
- From [1]:
- "PyCryptodome is a fork of PyCrypto, which is not maintained any more
- (the last release dates back to 2013 [2]). It exposes almost the same
- API, but there are a few incompatibilities [3]."
- [1] https://github.com/OP-TEE/optee_os/commit/90ad2450436fdd9fc0d28a3f92f3fbcfd89a38f0
- [2] https://pypi.org/project/pycrypto/#history
- [3] https://pycryptodome.readthedocs.io/en/latest/src/vs_pycrypto.html
- Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
- [Rebased against crda-4.14]
- Signed-off-by: Peter Seiderer <ps.report@gmx.net>
- [Romain: Use pycryptodomex]
- Signed-off-by: Romain Naour <romain.naour@gmail.com>
- ---
- Makefile | 2 +-
- utils/key2pub.py | 146 ++++++++++++++++++++++++-----------------------
- 2 files changed, 75 insertions(+), 73 deletions(-)
- diff --git a/Makefile b/Makefile
- index a3ead30..8da38d0 100644
- --- a/Makefile
- +++ b/Makefile
- @@ -112,7 +112,7 @@ $(REG_BIN):
- keys-%.c: utils/key2pub.py $(wildcard $(PUBKEY_DIR)/*.pem)
- $(NQ) ' GEN ' $@
- $(NQ) ' Trusted pubkeys:' $(wildcard $(PUBKEY_DIR)/*.pem)
- - $(Q)./utils/key2pub.py --$* $(wildcard $(PUBKEY_DIR)/*.pem) $@
- + $(Q) python utils/key2pub.py --$* $(wildcard $(PUBKEY_DIR)/*.pem) $@
-
- $(LIBREG): regdb.h reglib.h reglib.c
- $(NQ) ' CC ' $@
- diff --git a/utils/key2pub.py b/utils/key2pub.py
- index 9bb04cd..8a0ba2a 100755
- --- a/utils/key2pub.py
- +++ b/utils/key2pub.py
- @@ -1,126 +1,128 @@
- #!/usr/bin/env python
-
- +import io
- import sys
- try:
- - from M2Crypto import RSA
- -except ImportError, e:
- - sys.stderr.write('ERROR: Failed to import the "M2Crypto" module: %s\n' % e.message)
- - sys.stderr.write('Please install the "M2Crypto" Python module.\n')
- - sys.stderr.write('On Debian GNU/Linux the package is called "python-m2crypto".\n')
- - sys.exit(1)
- + from Cryptodome.PublicKey import RSA
- +except ImportError as e:
- + sys.stderr.write('ERROR: Failed to import the "Cryptodome.PublicKey" module: %s\n' % e.message)
- + sys.stderr.write('Please install the "Cryptodome.PublicKey" Python module.\n')
- + sys.stderr.write('On Debian GNU/Linux the package is called "python-cryptodomex".\n')
- + sys.exit(1)
- +
- +def bitwise_collect(value, radix_bits):
- + words = []
- + radix_mask = (1 << radix_bits) - 1
- + while value != 0:
- + words.append(value & radix_mask)
- + value >>= radix_bits
- + return words
-
- def print_ssl_64(output, name, val):
- - while val[0] == '\0':
- - val = val[1:]
- - while len(val) % 8:
- - val = '\0' + val
- - vnew = []
- - while len(val):
- - vnew.append((val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]))
- - val = val[8:]
- - vnew.reverse()
- - output.write('static BN_ULONG %s[%d] = {\n' % (name, len(vnew)))
- + # OpenSSL expects 64-bit words given least-significant-word first.
- + vwords = bitwise_collect(val, 64)
- +
- + output.write(u'static BN_ULONG {}[] = {{\n'.format(name))
- idx = 0
- - for v1, v2, v3, v4, v5, v6, v7, v8 in vnew:
- + for vword in vwords:
- if not idx:
- - output.write('\t')
- - output.write('0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x, ' % (ord(v1), ord(v2), ord(v3), ord(v4), ord(v5), ord(v6), ord(v7), ord(v8)))
- + output.write(u'\t')
- + output.write(u'0x{:016x}ULL, '.format(vword))
- idx += 1
- if idx == 2:
- idx = 0
- - output.write('\n')
- + output.write(u'\n')
- if idx:
- - output.write('\n')
- - output.write('};\n\n')
- + output.write(u'\n')
- + output.write(u'};\n\n')
-
- def print_ssl_32(output, name, val):
- - while val[0] == '\0':
- - val = val[1:]
- - while len(val) % 4:
- - val = '\0' + val
- - vnew = []
- - while len(val):
- - vnew.append((val[0], val[1], val[2], val[3], ))
- - val = val[4:]
- - vnew.reverse()
- - output.write('static BN_ULONG %s[%d] = {\n' % (name, len(vnew)))
- + # OpenSSL expects 32-bit words given least-significant-word first.
- + vwords = bitwise_collect(val, 32)
- +
- + output.write(u'static BN_ULONG {}[] = {{\n'.format(name))
- idx = 0
- - for v1, v2, v3, v4 in vnew:
- + for vword in vwords:
- if not idx:
- - output.write('\t')
- - output.write('0x%.2x%.2x%.2x%.2x, ' % (ord(v1), ord(v2), ord(v3), ord(v4)))
- + output.write(u'\t')
- + output.write(u'0x{:08x}, '.format(vword))
- idx += 1
- if idx == 4:
- idx = 0
- - output.write('\n')
- + output.write(u'\n')
- if idx:
- - output.write('\n')
- - output.write('};\n\n')
- + output.write(u'\n')
- + output.write(u'};\n\n')
-
- def print_ssl(output, name, val):
- +
- + output.write(u'#include <stdint.h>\n')
- + output.write(u'#include <openssl/bn.h>\n')
- +
- import struct
- - output.write('#include <stdint.h>\n')
- if len(struct.pack('@L', 0)) == 8:
- return print_ssl_64(output, name, val)
- else:
- return print_ssl_32(output, name, val)
-
- def print_ssl_keys(output, n):
- - output.write(r'''
- + output.write(u'''
- struct pubkey {
- struct bignum_st e, n;
- };
-
- -#define KEY(data) { \
- - .d = data, \
- - .top = sizeof(data)/sizeof(data[0]), \
- +#define KEY(data) { \\
- + .d = data, \\
- + .top = sizeof(data)/sizeof(data[0]), \\
- }
-
- -#define KEYS(e,n) { KEY(e), KEY(n), }
- +#define KEYS(e,n) { KEY(e), KEY(n), }
-
- static struct pubkey keys[] = {
- ''')
- for n in xrange(n + 1):
- - output.write(' KEYS(e_%d, n_%d),\n' % (n, n))
- - output.write('};\n')
- + output.write(u' KEYS(e_{0}, n_{0}),\n'.format(n))
- + output.write(u'};\n')
- pass
-
- def print_gcrypt(output, name, val):
- - output.write('#include <stdint.h>\n')
- - while val[0] == '\0':
- - val = val[1:]
- - output.write('static const uint8_t %s[%d] = {\n' % (name, len(val)))
- + # gcrypt expects 8-bit words most-significant-word first
- + vwords = bitwise_collect(val, 8)
- + vwords.reverse()
- +
- + output.write(u'#include <stdint.h>\n')
- + output.write(u'static const uint8_t %s[%d] = {\n' % (name, len(vwords)))
- idx = 0
- - for v in val:
- + for vword in vwords:
- if not idx:
- - output.write('\t')
- - output.write('0x%.2x, ' % ord(v))
- + output.write(u'\t')
- + output.write(u'0x{:02x}, '.format(vword))
- idx += 1
- if idx == 8:
- idx = 0
- - output.write('\n')
- + output.write(u'\n')
- if idx:
- - output.write('\n')
- - output.write('};\n\n')
- + output.write(u'\n')
- + output.write(u'};\n\n')
-
- def print_gcrypt_keys(output, n):
- - output.write(r'''
- + output.write(u'''
- struct key_params {
- const uint8_t *e, *n;
- uint32_t len_e, len_n;
- };
-
- -#define KEYS(_e, _n) { \
- - .e = _e, .len_e = sizeof(_e), \
- - .n = _n, .len_n = sizeof(_n), \
- +#define KEYS(_e, _n) { \\
- + .e = _e, .len_e = sizeof(_e), \\
- + .n = _n, .len_n = sizeof(_n), \\
- }
-
- static const struct key_params __attribute__ ((unused)) keys[] = {
- ''')
- - for n in xrange(n + 1):
- - output.write(' KEYS(e_%d, n_%d),\n' % (n, n))
- - output.write('};\n')
- -
- + for n in range(n + 1):
- + output.write(u' KEYS(e_{0}, n_{0}),\n'.format(n))
- + output.write(u'};\n')
- +
-
- modes = {
- '--ssl': (print_ssl, print_ssl_keys),
- @@ -135,21 +137,21 @@ except IndexError:
- mode = None
-
- if not mode in modes:
- - print 'Usage: %s [%s] input-file... output-file' % (sys.argv[0], '|'.join(modes.keys()))
- + print('Usage: {} [{}] input-file... output-file'.format(sys.argv[0], '|'.join(modes.keys())))
- sys.exit(2)
-
- -output = open(outfile, 'w')
- +output = io.open(outfile, 'w')
-
- # load key
- idx = 0
- for f in files:
- - try:
- - key = RSA.load_pub_key(f)
- - except RSA.RSAError:
- - key = RSA.load_key(f)
-
- - modes[mode][0](output, 'e_%d' % idx, key.e[4:])
- - modes[mode][0](output, 'n_%d' % idx, key.n[4:])
- + key_contents = io.open(f, 'rb').read()
- + key = RSA.importKey(key_contents)
- +
- + modes[mode][0](output, 'e_{}'.format(idx), key.e)
- + modes[mode][0](output, 'n_{}'.format(idx), key.n)
- +
- idx += 1
-
- modes[mode][1](output, idx - 1)
- --
- 2.25.3
|