rt.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #!/usr/bin/env python
  2. import sys
  3. import os
  4. import hashlib
  5. def md5_for_file(path, block_size=256*128):
  6. '''
  7. Block size directly depends on the block size of your filesystem
  8. to avoid performances issues
  9. Here I have blocks of 4096 octets (Default NTFS)
  10. '''
  11. md5 = hashlib.md5()
  12. with open(path,'rb') as f:
  13. for chunk in iter(lambda: f.read(block_size), b''):
  14. md5.update(chunk)
  15. f.close()
  16. return md5.hexdigest()
  17. def read_until_eq(f, s):
  18. while True:
  19. l = f.readline()
  20. if l.strip() == s:
  21. break
  22. return l
  23. def read_until_start(f, s):
  24. while True:
  25. l = f.readline()
  26. if l.startswith(s):
  27. break
  28. return l
  29. def read_hex(f):
  30. t = []
  31. while True:
  32. l = f.readline()
  33. if l.strip() == '':
  34. break
  35. t.extend(l.strip().split(' '))
  36. return t
  37. class NamedData(object):
  38. def __init__(self, name, data):
  39. self.name = name
  40. self.data = data
  41. def __str__(self):
  42. return " /* {0} */\n {1},\n {{ {2} }}\n".format(self.name, len(self.data), ', '.join('0x' + x for x in self.data))
  43. def read_part(f, s):
  44. name = read_until_start(f, s).strip().lstrip('# ').rstrip(':')
  45. data = read_hex(f)
  46. e = NamedData(name, data)
  47. return e
  48. class RsaKey(object):
  49. def __init__(self, n, e, d, q, p, dP, dQ, qInv):
  50. self.n = n
  51. self.e = e
  52. self.d = d
  53. self.q = q
  54. self.p = p
  55. self.dP = dP
  56. self.dQ = dQ
  57. self.qInv = qInv
  58. def __str__(self):
  59. return "{{\n{0},\n{1},\n{2},\n{3},\n{4},\n{5},\n{6},\n{7}\n}}\n".format(self.n, self.e, self.d, self.q, self.p, self.dP, self.dQ, self.qInv)
  60. def read_key(f):
  61. n = read_part(f, '# RSA modulus n')
  62. e = read_part(f, '# RSA public exponent e')
  63. d = read_part(f, '# RSA private exponent d')
  64. q = read_part(f, '# Prime p')
  65. p = read_part(f, '# Prime q')
  66. dP = read_part(f, '# p\'s CRT exponent dP')
  67. dQ = read_part(f, '# q\'s CRT exponent dQ')
  68. qInv = read_part(f, '# CRT coefficient qInv')
  69. k = RsaKey(n, e, d, q, p, dP, dQ, qInv)
  70. return k
  71. class Data(object):
  72. def __init__(self, name, obj1, obj2, obj3):
  73. self.name = name
  74. self.obj1 = obj1
  75. self.obj2 = obj2
  76. self.obj3 = obj3
  77. def __str__(self):
  78. return "{{\n \"{0}\",\n{1},\n{2},\n{3}\n}}\n,".format(self.name, self.obj1, self.obj2, self.obj3)
  79. def read_data(f):
  80. name = read_until_start(f, ftype.o).strip().lstrip('# ')
  81. obj1 = read_part(f, ftype.o1)
  82. obj2 = read_part(f, ftype.o2)
  83. obj3 = read_part(f, ftype.o3)
  84. s = Data(name, obj1, obj2, obj3)
  85. return s
  86. class Example(object):
  87. def __init__(self, name, key, data):
  88. self.name = name
  89. self.key = key
  90. self.data = data
  91. def __str__(self):
  92. res = "{{\n \"{0}\",\n{1},\n{{".format(self.name, str(self.key))
  93. for i in self.data:
  94. res += str(i) + '\n'
  95. res += '}\n},'
  96. return res
  97. def read_example(f):
  98. name = read_until_start(f, '# Example').strip().lstrip('# ')
  99. key = read_key(f)
  100. l = read_until_start(f, '#')
  101. d = []
  102. while l.strip().startswith('# --------------------------------'):
  103. data = read_data(f)
  104. d.append(data)
  105. l = read_until_start(f, '#')
  106. e = Example(name, key, d)
  107. f.seek(-len(l), os.SEEK_CUR)
  108. return e
  109. class PkcsType(object):
  110. def __init__(self, name):
  111. if name == 'pss':
  112. self.o = '# RSASSA-PSS Signature Example'
  113. self.o1 = '# Message to be signed'
  114. self.o2 = '# Salt'
  115. self.o3 = '# Signature'
  116. elif name == 'oaep':
  117. self.o = '# RSAES-OAEP Encryption Example'
  118. self.o1 = '# Message to be encrypted'
  119. self.o2 = '# Seed'
  120. self.o3 = '# Encryption'
  121. else:
  122. raise ValueError('Type unknown: ' + name)
  123. self.name = name
  124. ftype = PkcsType(sys.argv[2])
  125. print('/* Generated from file: %s\n * with md5 hash: %s\n */\n' % (sys.argv[1], md5_for_file(sys.argv[1])))
  126. print('''
  127. typedef struct rsaKey {
  128. int n_l;
  129. unsigned char n[256];
  130. int e_l;
  131. unsigned char e[256];
  132. int d_l;
  133. unsigned char d[256];
  134. int p_l;
  135. unsigned char p[256];
  136. int q_l;
  137. unsigned char q[256];
  138. int dP_l;
  139. unsigned char dP[256];
  140. int dQ_l;
  141. unsigned char dQ[256];
  142. int qInv_l;
  143. unsigned char qInv[256];
  144. } rsaKey_t;
  145. typedef struct rsaData {
  146. const char* name;
  147. int o1_l;
  148. unsigned char o1[256];
  149. int o2_l;
  150. unsigned char o2[256];
  151. int o3_l;
  152. unsigned char o3[256];
  153. } rsaData_t;
  154. typedef struct testcase {
  155. const char* name;
  156. rsaKey_t rsa;
  157. rsaData_t data[6];
  158. } testcase_t;
  159. testcase_t testcases_%s[] =
  160. {''' % sys.argv[2])
  161. with open(sys.argv[1], 'rb') as f:
  162. ex = []
  163. while read_until_eq(f, '# ============================================='):
  164. if f.tell() == os.path.getsize(sys.argv[1]):
  165. break
  166. ex.append(read_example(f))
  167. for i in ex:
  168. print(i)
  169. f.close()
  170. print('};\n')