0001-crda-support-python-3-in-utils-key2pub.py.patch 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. From 797f2836c48f9ba2446629ae4b6867ca1a5ea512 Mon Sep 17 00:00:00 2001
  2. From: Taahir Ahmed <ahmed.taahir@gmail.com>
  3. Date: Wed, 30 Mar 2016 11:23:54 -0300
  4. Subject: [PATCH 1/2] crda: support python 3 in utils/key2pub.py
  5. utils/key2pub.py can now be run under either python 2.7 or python 3.x.
  6. This required some minor syntactical changes as well as switching from
  7. M2Crypto to pycrypto, since M2Crypto doesn't support python 3.x.
  8. In addition, some errors in the generated source file keys-ssl.h are
  9. fixed:
  10. * The correct OpenSSL header for BN_ULONG is included.
  11. * The generated constants are given the 'ull' suffix to prevent
  12. warnings about constants that are too large.
  13. [Gustavo: don't call /utils/key2pub.py since that doesn't compute]
  14. Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
  15. ---
  16. Status: submitted upstream by author but not (yet) accepted
  17. URL: http://www.spinics.net/lists/linux-wireless/msg138936.html
  18. Makefile | 2 +-
  19. utils/key2pub.py | 146 ++++++++++++++++++++++++++++---------------------------
  20. 2 files changed, 75 insertions(+), 73 deletions(-)
  21. diff --git a/Makefile b/Makefile
  22. index 1f25509..523a96e 100644
  23. --- a/Makefile
  24. +++ b/Makefile
  25. @@ -112,7 +112,7 @@ $(REG_BIN):
  26. keys-%.c: utils/key2pub.py $(wildcard $(PUBKEY_DIR)/*.pem)
  27. $(NQ) ' GEN ' $@
  28. $(NQ) ' Trusted pubkeys:' $(wildcard $(PUBKEY_DIR)/*.pem)
  29. - $(Q)./utils/key2pub.py --$* $(wildcard $(PUBKEY_DIR)/*.pem) $@
  30. + $(Q) python utils/key2pub.py --$* $(wildcard $(PUBKEY_DIR)/*.pem) $@
  31. $(LIBREG): regdb.h reglib.h reglib.c
  32. $(NQ) ' CC ' $@
  33. diff --git a/utils/key2pub.py b/utils/key2pub.py
  34. index 3e84cd2..c76cbbb 100755
  35. --- a/utils/key2pub.py
  36. +++ b/utils/key2pub.py
  37. @@ -1,126 +1,128 @@
  38. #!/usr/bin/env python
  39. +import io
  40. import sys
  41. try:
  42. - from M2Crypto import RSA
  43. -except ImportError, e:
  44. - sys.stderr.write('ERROR: Failed to import the "M2Crypto" module: %s\n' % e.message)
  45. - sys.stderr.write('Please install the "M2Crypto" Python module.\n')
  46. - sys.stderr.write('On Debian GNU/Linux the package is called "python-m2crypto".\n')
  47. - sys.exit(1)
  48. + from Crypto.PublicKey import RSA
  49. +except ImportError as e:
  50. + sys.stderr.write('ERROR: Failed to import the "Crypto.PublicKey" module: %s\n' % e.message)
  51. + sys.stderr.write('Please install the "Crypto.PublicKey" Python module.\n')
  52. + sys.stderr.write('On Debian GNU/Linux the package is called "python-crypto".\n')
  53. + sys.exit(1)
  54. +
  55. +def bitwise_collect(value, radix_bits):
  56. + words = []
  57. + radix_mask = (1 << radix_bits) - 1
  58. + while value != 0:
  59. + words.append(value & radix_mask)
  60. + value >>= radix_bits
  61. + return words
  62. def print_ssl_64(output, name, val):
  63. - while val[0] == '\0':
  64. - val = val[1:]
  65. - while len(val) % 8:
  66. - val = '\0' + val
  67. - vnew = []
  68. - while len(val):
  69. - vnew.append((val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]))
  70. - val = val[8:]
  71. - vnew.reverse()
  72. - output.write('static BN_ULONG %s[%d] = {\n' % (name, len(vnew)))
  73. + # OpenSSL expects 64-bit words given least-significant-word first.
  74. + vwords = bitwise_collect(val, 64)
  75. +
  76. + output.write(u'static BN_ULONG {}[] = {{\n'.format(name))
  77. idx = 0
  78. - for v1, v2, v3, v4, v5, v6, v7, v8 in vnew:
  79. + for vword in vwords:
  80. if not idx:
  81. - output.write('\t')
  82. - 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)))
  83. + output.write(u'\t')
  84. + output.write(u'0x{:016x}ULL, '.format(vword))
  85. idx += 1
  86. if idx == 2:
  87. idx = 0
  88. - output.write('\n')
  89. + output.write(u'\n')
  90. if idx:
  91. - output.write('\n')
  92. - output.write('};\n\n')
  93. + output.write(u'\n')
  94. + output.write(u'};\n\n')
  95. def print_ssl_32(output, name, val):
  96. - while val[0] == '\0':
  97. - val = val[1:]
  98. - while len(val) % 4:
  99. - val = '\0' + val
  100. - vnew = []
  101. - while len(val):
  102. - vnew.append((val[0], val[1], val[2], val[3], ))
  103. - val = val[4:]
  104. - vnew.reverse()
  105. - output.write('static BN_ULONG %s[%d] = {\n' % (name, len(vnew)))
  106. + # OpenSSL expects 32-bit words given least-significant-word first.
  107. + vwords = bitwise_collect(val, 32)
  108. +
  109. + output.write(u'static BN_ULONG {}[] = {{\n'.format(name))
  110. idx = 0
  111. - for v1, v2, v3, v4 in vnew:
  112. + for vword in vwords:
  113. if not idx:
  114. - output.write('\t')
  115. - output.write('0x%.2x%.2x%.2x%.2x, ' % (ord(v1), ord(v2), ord(v3), ord(v4)))
  116. + output.write(u'\t')
  117. + output.write(u'0x{:08x}, '.format(vword))
  118. idx += 1
  119. if idx == 4:
  120. idx = 0
  121. - output.write('\n')
  122. + output.write(u'\n')
  123. if idx:
  124. - output.write('\n')
  125. - output.write('};\n\n')
  126. + output.write(u'\n')
  127. + output.write(u'};\n\n')
  128. def print_ssl(output, name, val):
  129. +
  130. + output.write(u'#include <stdint.h>\n')
  131. + output.write(u'#include <openssl/bn.h>\n')
  132. +
  133. import struct
  134. - output.write('#include <stdint.h>\n')
  135. if len(struct.pack('@L', 0)) == 8:
  136. return print_ssl_64(output, name, val)
  137. else:
  138. return print_ssl_32(output, name, val)
  139. def print_ssl_keys(output, n):
  140. - output.write(r'''
  141. + output.write(u'''
  142. struct pubkey {
  143. struct bignum_st e, n;
  144. };
  145. -#define KEY(data) { \
  146. - .d = data, \
  147. - .top = sizeof(data)/sizeof(data[0]), \
  148. +#define KEY(data) { \\
  149. + .d = data, \\
  150. + .top = sizeof(data)/sizeof(data[0]), \\
  151. }
  152. -#define KEYS(e,n) { KEY(e), KEY(n), }
  153. +#define KEYS(e,n) { KEY(e), KEY(n), }
  154. static struct pubkey keys[] = {
  155. ''')
  156. for n in xrange(n + 1):
  157. - output.write(' KEYS(e_%d, n_%d),\n' % (n, n))
  158. - output.write('};\n')
  159. + output.write(u' KEYS(e_{0}, n_{0}),\n'.format(n))
  160. + output.write(u'};\n')
  161. pass
  162. def print_gcrypt(output, name, val):
  163. - output.write('#include <stdint.h>\n')
  164. - while val[0] == '\0':
  165. - val = val[1:]
  166. - output.write('static const uint8_t %s[%d] = {\n' % (name, len(val)))
  167. + # gcrypt expects 8-bit words most-significant-word first
  168. + vwords = bitwise_collect(val, 8)
  169. + vwords.reverse()
  170. +
  171. + output.write(u'#include <stdint.h>\n')
  172. + output.write(u'static const uint8_t %s[%d] = {\n' % (name, len(vwords)))
  173. idx = 0
  174. - for v in val:
  175. + for vword in vwords:
  176. if not idx:
  177. - output.write('\t')
  178. - output.write('0x%.2x, ' % ord(v))
  179. + output.write(u'\t')
  180. + output.write(u'0x{:02x}, '.format(vword))
  181. idx += 1
  182. if idx == 8:
  183. idx = 0
  184. - output.write('\n')
  185. + output.write(u'\n')
  186. if idx:
  187. - output.write('\n')
  188. - output.write('};\n\n')
  189. + output.write(u'\n')
  190. + output.write(u'};\n\n')
  191. def print_gcrypt_keys(output, n):
  192. - output.write(r'''
  193. + output.write(u'''
  194. struct key_params {
  195. const uint8_t *e, *n;
  196. uint32_t len_e, len_n;
  197. };
  198. -#define KEYS(_e, _n) { \
  199. - .e = _e, .len_e = sizeof(_e), \
  200. - .n = _n, .len_n = sizeof(_n), \
  201. +#define KEYS(_e, _n) { \\
  202. + .e = _e, .len_e = sizeof(_e), \\
  203. + .n = _n, .len_n = sizeof(_n), \\
  204. }
  205. static const struct key_params keys[] = {
  206. ''')
  207. - for n in xrange(n + 1):
  208. - output.write(' KEYS(e_%d, n_%d),\n' % (n, n))
  209. - output.write('};\n')
  210. -
  211. + for n in range(n + 1):
  212. + output.write(u' KEYS(e_{0}, n_{0}),\n'.format(n))
  213. + output.write(u'};\n')
  214. +
  215. modes = {
  216. '--ssl': (print_ssl, print_ssl_keys),
  217. @@ -135,21 +137,21 @@ except IndexError:
  218. mode = None
  219. if not mode in modes:
  220. - print 'Usage: %s [%s] input-file... output-file' % (sys.argv[0], '|'.join(modes.keys()))
  221. + print('Usage: {} [{}] input-file... output-file'.format(sys.argv[0], '|'.join(modes.keys())))
  222. sys.exit(2)
  223. -output = open(outfile, 'w')
  224. +output = io.open(outfile, 'w')
  225. # load key
  226. idx = 0
  227. for f in files:
  228. - try:
  229. - key = RSA.load_pub_key(f)
  230. - except RSA.RSAError:
  231. - key = RSA.load_key(f)
  232. - modes[mode][0](output, 'e_%d' % idx, key.e[4:])
  233. - modes[mode][0](output, 'n_%d' % idx, key.n[4:])
  234. + key_contents = io.open(f, 'rb').read()
  235. + key = RSA.importKey(key_contents)
  236. +
  237. + modes[mode][0](output, 'e_{}'.format(idx), key.e)
  238. + modes[mode][0](output, 'n_{}'.format(idx), key.n)
  239. +
  240. idx += 1
  241. modes[mode][1](output, idx - 1)
  242. --
  243. 2.7.3