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

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