test_import_DSA.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. # -*- coding: utf-8 -*-
  2. #
  3. # SelfTest/PublicKey/test_import_DSA.py: Self-test for importing DSA keys
  4. #
  5. # ===================================================================
  6. # The contents of this file are dedicated to the public domain. To
  7. # the extent that dedication to the public domain is not available,
  8. # everyone is granted a worldwide, perpetual, royalty-free,
  9. # non-exclusive license to exercise all rights associated with the
  10. # contents of this file for any purpose whatsoever.
  11. # No rights are reserved.
  12. #
  13. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  14. # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  15. # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  17. # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  18. # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. # SOFTWARE.
  21. # ===================================================================
  22. import unittest
  23. import re
  24. from tls.Crypto.PublicKey import DSA
  25. from tls.Crypto.SelfTest.st_common import *
  26. from tls.Crypto.Util.py3compat import *
  27. from binascii import unhexlify
  28. class ImportKeyTests(unittest.TestCase):
  29. y = 92137165128186062214622779787483327510946462589285775188003362705875131352591574106484271700740858696583623951844732128165434284507709057439633739849986759064015013893156866539696757799934634945787496920169462601722830899660681779448742875054459716726855443681559131362852474817534616736104831095601710736729
  30. p = 162452170958135306109773853318304545923250830605675936228618290525164105310663722368377131295055868997377338797580997938253236213714988311430600065853662861806894003694743806769284131194035848116051021923956699231855223389086646903420682639786976554552864568460372266462812137447840653688476258666833303658691
  31. q = 988791743931120302950649732173330531512663554851
  32. g = 85583152299197514738065570254868711517748965097380456700369348466136657764813442044039878840094809620913085570225318356734366886985903212775602770761953571967834823306046501307810937486758039063386311593890777319935391363872375452381836756832784184928202587843258855704771836753434368484556809100537243908232
  33. x = 540873410045082450874416847965843801027716145253
  34. def setUp(self):
  35. # It is easier to write test vectors in text form,
  36. # and convert them to byte strigs dynamically here
  37. for mname, mvalue in ImportKeyTests.__dict__.items():
  38. if mname[:4] in ('der_', 'pem_', 'ssh_'):
  39. if mname[:4] == 'der_':
  40. mvalue = unhexlify(tobytes(mvalue))
  41. mvalue = tobytes(mvalue)
  42. setattr(self, mname, mvalue)
  43. # 1. SubjectPublicKeyInfo
  44. der_public=\
  45. '308201b73082012b06072a8648ce3804013082011e02818100e756ee1717f4b6'+\
  46. '794c7c214724a19763742c45572b4b3f8ff3b44f3be9f44ce039a2757695ec91'+\
  47. '5697da74ef914fcd1b05660e2419c761d639f45d2d79b802dbd23e7ab8b81b47'+\
  48. '9a380e1f30932584ba2a0b955032342ebc83cb5ca906e7b0d7cd6fe656cecb4c'+\
  49. '8b5a77123a8c6750a481e3b06057aff6aa6eba620b832d60c3021500ad32f48c'+\
  50. 'd3ae0c45a198a61fa4b5e20320763b2302818079dfdc3d614fe635fceb7eaeae'+\
  51. '3718dc2efefb45282993ac6749dc83c223d8c1887296316b3b0b54466cf444f3'+\
  52. '4b82e3554d0b90a778faaf1306f025dae6a3e36c7f93dd5bac4052b92370040a'+\
  53. 'ca70b8d5820599711900efbc961812c355dd9beffe0981da85c5548074b41c56'+\
  54. 'ae43fd300d89262e4efd89943f99a651b03888038185000281810083352a69a1'+\
  55. '32f34843d2a0eb995bff4e2f083a73f0049d2c91ea2f0ce43d144abda48199e4'+\
  56. 'b003c570a8af83303d45105f606c5c48d925a40ed9c2630c2fa4cdbf838539de'+\
  57. 'b9a29f919085f2046369f627ca84b2cb1e2c7940564b670f963ab1164d4e2ca2'+\
  58. 'bf6ffd39f12f548928bf4d2d1b5e6980b4f1be4c92a91986fba559'
  59. def testImportKey1(self):
  60. key_obj = DSA.importKey(self.der_public)
  61. self.failIf(key_obj.has_private())
  62. self.assertEqual(self.y, key_obj.y)
  63. self.assertEqual(self.p, key_obj.p)
  64. self.assertEqual(self.q, key_obj.q)
  65. self.assertEqual(self.g, key_obj.g)
  66. def testExportKey1(self):
  67. tup = (self.y, self.g, self.p, self.q)
  68. key = DSA.construct(tup)
  69. encoded = key.export_key('DER')
  70. self.assertEqual(self.der_public, encoded)
  71. # 2.
  72. pem_public="""\
  73. -----BEGIN PUBLIC KEY-----
  74. MIIBtzCCASsGByqGSM44BAEwggEeAoGBAOdW7hcX9LZ5THwhRyShl2N0LEVXK0s/
  75. j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4uBtH
  76. mjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47BgV6/2
  77. qm66YguDLWDDAhUArTL0jNOuDEWhmKYfpLXiAyB2OyMCgYB539w9YU/mNfzrfq6u
  78. NxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG8CXa
  79. 5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0tBxW
  80. rkP9MA2JJi5O/YmUP5mmUbA4iAOBhQACgYEAgzUqaaEy80hD0qDrmVv/Ti8IOnPw
  81. BJ0skeovDOQ9FEq9pIGZ5LADxXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTne
  82. uaKfkZCF8gRjafYnyoSyyx4seUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmA
  83. tPG+TJKpGYb7pVk=
  84. -----END PUBLIC KEY-----"""
  85. def testImportKey2(self):
  86. for pem in (self.pem_public, tostr(self.pem_public)):
  87. key_obj = DSA.importKey(pem)
  88. self.failIf(key_obj.has_private())
  89. self.assertEqual(self.y, key_obj.y)
  90. self.assertEqual(self.p, key_obj.p)
  91. self.assertEqual(self.q, key_obj.q)
  92. self.assertEqual(self.g, key_obj.g)
  93. def testExportKey2(self):
  94. tup = (self.y, self.g, self.p, self.q)
  95. key = DSA.construct(tup)
  96. encoded = key.export_key('PEM')
  97. self.assertEqual(self.pem_public, encoded)
  98. # 3. OpenSSL/OpenSSH format
  99. der_private=\
  100. '308201bb02010002818100e756ee1717f4b6794c7c214724a19763742c45572b'+\
  101. '4b3f8ff3b44f3be9f44ce039a2757695ec915697da74ef914fcd1b05660e2419'+\
  102. 'c761d639f45d2d79b802dbd23e7ab8b81b479a380e1f30932584ba2a0b955032'+\
  103. '342ebc83cb5ca906e7b0d7cd6fe656cecb4c8b5a77123a8c6750a481e3b06057'+\
  104. 'aff6aa6eba620b832d60c3021500ad32f48cd3ae0c45a198a61fa4b5e2032076'+\
  105. '3b2302818079dfdc3d614fe635fceb7eaeae3718dc2efefb45282993ac6749dc'+\
  106. '83c223d8c1887296316b3b0b54466cf444f34b82e3554d0b90a778faaf1306f0'+\
  107. '25dae6a3e36c7f93dd5bac4052b92370040aca70b8d5820599711900efbc9618'+\
  108. '12c355dd9beffe0981da85c5548074b41c56ae43fd300d89262e4efd89943f99'+\
  109. 'a651b038880281810083352a69a132f34843d2a0eb995bff4e2f083a73f0049d'+\
  110. '2c91ea2f0ce43d144abda48199e4b003c570a8af83303d45105f606c5c48d925'+\
  111. 'a40ed9c2630c2fa4cdbf838539deb9a29f919085f2046369f627ca84b2cb1e2c'+\
  112. '7940564b670f963ab1164d4e2ca2bf6ffd39f12f548928bf4d2d1b5e6980b4f1'+\
  113. 'be4c92a91986fba55902145ebd9a3f0b82069d98420986b314215025756065'
  114. def testImportKey3(self):
  115. key_obj = DSA.importKey(self.der_private)
  116. self.failUnless(key_obj.has_private())
  117. self.assertEqual(self.y, key_obj.y)
  118. self.assertEqual(self.p, key_obj.p)
  119. self.assertEqual(self.q, key_obj.q)
  120. self.assertEqual(self.g, key_obj.g)
  121. self.assertEqual(self.x, key_obj.x)
  122. def testExportKey3(self):
  123. tup = (self.y, self.g, self.p, self.q, self.x)
  124. key = DSA.construct(tup)
  125. encoded = key.export_key('DER', pkcs8=False)
  126. self.assertEqual(self.der_private, encoded)
  127. # 4.
  128. pem_private="""\
  129. -----BEGIN DSA PRIVATE KEY-----
  130. MIIBuwIBAAKBgQDnVu4XF/S2eUx8IUckoZdjdCxFVytLP4/ztE876fRM4DmidXaV
  131. 7JFWl9p075FPzRsFZg4kGcdh1jn0XS15uALb0j56uLgbR5o4Dh8wkyWEuioLlVAy
  132. NC68g8tcqQbnsNfNb+ZWzstMi1p3EjqMZ1CkgeOwYFev9qpuumILgy1gwwIVAK0y
  133. 9IzTrgxFoZimH6S14gMgdjsjAoGAed/cPWFP5jX8636urjcY3C7++0UoKZOsZ0nc
  134. g8Ij2MGIcpYxazsLVEZs9ETzS4LjVU0LkKd4+q8TBvAl2uaj42x/k91brEBSuSNw
  135. BArKcLjVggWZcRkA77yWGBLDVd2b7/4JgdqFxVSAdLQcVq5D/TANiSYuTv2JlD+Z
  136. plGwOIgCgYEAgzUqaaEy80hD0qDrmVv/Ti8IOnPwBJ0skeovDOQ9FEq9pIGZ5LAD
  137. xXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTneuaKfkZCF8gRjafYnyoSyyx4s
  138. eUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmAtPG+TJKpGYb7pVkCFF69mj8L
  139. ggadmEIJhrMUIVAldWBl
  140. -----END DSA PRIVATE KEY-----"""
  141. def testImportKey4(self):
  142. for pem in (self.pem_private, tostr(self.pem_private)):
  143. key_obj = DSA.importKey(pem)
  144. self.failUnless(key_obj.has_private())
  145. self.assertEqual(self.y, key_obj.y)
  146. self.assertEqual(self.p, key_obj.p)
  147. self.assertEqual(self.q, key_obj.q)
  148. self.assertEqual(self.g, key_obj.g)
  149. self.assertEqual(self.x, key_obj.x)
  150. def testExportKey4(self):
  151. tup = (self.y, self.g, self.p, self.q, self.x)
  152. key = DSA.construct(tup)
  153. encoded = key.export_key('PEM', pkcs8=False)
  154. self.assertEqual(self.pem_private, encoded)
  155. # 5. PKCS8 (unencrypted)
  156. der_pkcs8=\
  157. '3082014a0201003082012b06072a8648ce3804013082011e02818100e756ee17'+\
  158. '17f4b6794c7c214724a19763742c45572b4b3f8ff3b44f3be9f44ce039a27576'+\
  159. '95ec915697da74ef914fcd1b05660e2419c761d639f45d2d79b802dbd23e7ab8'+\
  160. 'b81b479a380e1f30932584ba2a0b955032342ebc83cb5ca906e7b0d7cd6fe656'+\
  161. 'cecb4c8b5a77123a8c6750a481e3b06057aff6aa6eba620b832d60c3021500ad'+\
  162. '32f48cd3ae0c45a198a61fa4b5e20320763b2302818079dfdc3d614fe635fceb'+\
  163. '7eaeae3718dc2efefb45282993ac6749dc83c223d8c1887296316b3b0b54466c'+\
  164. 'f444f34b82e3554d0b90a778faaf1306f025dae6a3e36c7f93dd5bac4052b923'+\
  165. '70040aca70b8d5820599711900efbc961812c355dd9beffe0981da85c5548074'+\
  166. 'b41c56ae43fd300d89262e4efd89943f99a651b03888041602145ebd9a3f0b82'+\
  167. '069d98420986b314215025756065'
  168. def testImportKey5(self):
  169. key_obj = DSA.importKey(self.der_pkcs8)
  170. self.failUnless(key_obj.has_private())
  171. self.assertEqual(self.y, key_obj.y)
  172. self.assertEqual(self.p, key_obj.p)
  173. self.assertEqual(self.q, key_obj.q)
  174. self.assertEqual(self.g, key_obj.g)
  175. self.assertEqual(self.x, key_obj.x)
  176. def testExportKey5(self):
  177. tup = (self.y, self.g, self.p, self.q, self.x)
  178. key = DSA.construct(tup)
  179. encoded = key.export_key('DER')
  180. self.assertEqual(self.der_pkcs8, encoded)
  181. encoded = key.export_key('DER', pkcs8=True)
  182. self.assertEqual(self.der_pkcs8, encoded)
  183. # 6.
  184. pem_pkcs8="""\
  185. -----BEGIN PRIVATE KEY-----
  186. MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBAOdW7hcX9LZ5THwhRyShl2N0LEVX
  187. K0s/j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4
  188. uBtHmjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47Bg
  189. V6/2qm66YguDLWDDAhUArTL0jNOuDEWhmKYfpLXiAyB2OyMCgYB539w9YU/mNfzr
  190. fq6uNxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG
  191. 8CXa5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0
  192. tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAQWAhRevZo/C4IGnZhCCYazFCFQJXVgZQ==
  193. -----END PRIVATE KEY-----"""
  194. def testImportKey6(self):
  195. for pem in (self.pem_pkcs8, tostr(self.pem_pkcs8)):
  196. key_obj = DSA.importKey(pem)
  197. self.failUnless(key_obj.has_private())
  198. self.assertEqual(self.y, key_obj.y)
  199. self.assertEqual(self.p, key_obj.p)
  200. self.assertEqual(self.q, key_obj.q)
  201. self.assertEqual(self.g, key_obj.g)
  202. self.assertEqual(self.x, key_obj.x)
  203. def testExportKey6(self):
  204. tup = (self.y, self.g, self.p, self.q, self.x)
  205. key = DSA.construct(tup)
  206. encoded = key.export_key('PEM')
  207. self.assertEqual(self.pem_pkcs8, encoded)
  208. encoded = key.export_key('PEM', pkcs8=True)
  209. self.assertEqual(self.pem_pkcs8, encoded)
  210. # 7. OpenSSH/RFC4253
  211. ssh_pub="""ssh-dss AAAAB3NzaC1kc3MAAACBAOdW7hcX9LZ5THwhRyShl2N0LEVXK0s/j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4uBtHmjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47BgV6/2qm66YguDLWDDAAAAFQCtMvSM064MRaGYph+kteIDIHY7IwAAAIB539w9YU/mNfzrfq6uNxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG8CXa5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAAAAIEAgzUqaaEy80hD0qDrmVv/Ti8IOnPwBJ0skeovDOQ9FEq9pIGZ5LADxXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTneuaKfkZCF8gRjafYnyoSyyx4seUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmAtPG+TJKpGYb7pVk="""
  212. def testImportKey7(self):
  213. for ssh in (self.ssh_pub, tostr(self.ssh_pub)):
  214. key_obj = DSA.importKey(ssh)
  215. self.failIf(key_obj.has_private())
  216. self.assertEqual(self.y, key_obj.y)
  217. self.assertEqual(self.p, key_obj.p)
  218. self.assertEqual(self.q, key_obj.q)
  219. self.assertEqual(self.g, key_obj.g)
  220. def testExportKey7(self):
  221. tup = (self.y, self.g, self.p, self.q)
  222. key = DSA.construct(tup)
  223. encoded = key.export_key('OpenSSH')
  224. self.assertEqual(self.ssh_pub, encoded)
  225. # 8. Encrypted OpenSSL/OpenSSH
  226. pem_private_encrypted="""\
  227. -----BEGIN DSA PRIVATE KEY-----
  228. Proc-Type: 4,ENCRYPTED
  229. DEK-Info: AES-128-CBC,70B6908939D65E9F2EB999E8729788CE
  230. 4V6GHRDpCrdZ8MBjbyp5AlGUrjvr2Pn2e2zVxy5RBt4FBj9/pa0ae0nnyUPMLSUU
  231. kKyOR0topRYTVRLElm4qVrb5uNZ3hRwfbklr+pSrB7O9eHz9V5sfOQxyODS07JxK
  232. k1OdOs70/ouMXLF9EWfAZOmWUccZKHNblUwg1p1UrZIz5jXw4dUE/zqhvXh6d+iC
  233. ADsICaBCjCrRQJKDp50h3+ndQjkYBKVH+pj8TiQ79U7lAvdp3+iMghQN6YXs9mdI
  234. gFpWw/f97oWM4GHZFqHJ+VSMNFjBiFhAvYV587d7Lk4dhD8sCfbxj42PnfRgUItc
  235. nnPqHxmhMQozBWzYM4mQuo3XbF2WlsNFbOzFVyGhw1Bx1s91qvXBVWJh2ozrW0s6
  236. HYDV7ZkcTml/4kjA/d+mve6LZ8kuuR1qCiZx6rkffhh1gDN/1Xz3HVvIy/dQ+h9s
  237. 5zp7PwUoWbhqp3WCOr156P6gR8qo7OlT6wMh33FSXK/mxikHK136fV2shwTKQVII
  238. rJBvXpj8nACUmi7scKuTWGeUoXa+dwTZVVe+b+L2U1ZM7+h/neTJiXn7u99PFUwu
  239. xVJtxaV37m3aXxtCsPnbBg==
  240. -----END DSA PRIVATE KEY-----"""
  241. def testImportKey8(self):
  242. for pem in (self.pem_private_encrypted, tostr(self.pem_private_encrypted)):
  243. key_obj = DSA.importKey(pem, "PWDTEST")
  244. self.failUnless(key_obj.has_private())
  245. self.assertEqual(self.y, key_obj.y)
  246. self.assertEqual(self.p, key_obj.p)
  247. self.assertEqual(self.q, key_obj.q)
  248. self.assertEqual(self.g, key_obj.g)
  249. self.assertEqual(self.x, key_obj.x)
  250. def testExportKey8(self):
  251. tup = (self.y, self.g, self.p, self.q, self.x)
  252. key = DSA.construct(tup)
  253. encoded = key.export_key('PEM', pkcs8=False, passphrase="PWDTEST")
  254. key = DSA.importKey(encoded, "PWDTEST")
  255. self.assertEqual(self.y, key.y)
  256. self.assertEqual(self.p, key.p)
  257. self.assertEqual(self.q, key.q)
  258. self.assertEqual(self.g, key.g)
  259. self.assertEqual(self.x, key.x)
  260. # 9. Encrypted PKCS8
  261. # pbeWithMD5AndDES-CBC
  262. pem_pkcs8_encrypted="""\
  263. -----BEGIN ENCRYPTED PRIVATE KEY-----
  264. MIIBcTAbBgkqhkiG9w0BBQMwDgQI0GC3BJ/jSw8CAggABIIBUHc1cXZpExIE9tC7
  265. 7ryiW+5ihtF2Ekurq3e408GYSAu5smJjN2bvQXmzRFBz8W38K8eMf1sbWroZ4+zn
  266. kZSbb9nSm5kAa8lR2+oF2k+WRswMR/PTC3f/D9STO2X0QxdrzKgIHEcSGSHp5jTx
  267. aVvbkCDHo9vhBTl6S3ogZ48As/MEro76+9igUwJ1jNhIQZPJ7e20QH5qDpQFFJN4
  268. CKl2ENSEuwGiqBszItFy4dqH0g63ZGZV/xt9wSO9Rd7SK/EbA/dklOxBa5Y/VItM
  269. gnIhs9XDMoGYyn6F023EicNJm6g/bVQk81BTTma4tm+12TKGdYm+QkeZvCOMZylr
  270. Wv67cKwO3cAXt5C3QXMDgYR64XvuaT5h7C0igMp2afSXJlnbHEbFxQVJlv83T4FM
  271. eZ4k+NQDbEL8GiHmFxzDWQAuPPZKJWEEEV2p/To+WOh+kSDHQw==
  272. -----END ENCRYPTED PRIVATE KEY-----"""
  273. def testImportKey9(self):
  274. for pem in (self.pem_pkcs8_encrypted, tostr(self.pem_pkcs8_encrypted)):
  275. key_obj = DSA.importKey(pem, "PWDTEST")
  276. self.failUnless(key_obj.has_private())
  277. self.assertEqual(self.y, key_obj.y)
  278. self.assertEqual(self.p, key_obj.p)
  279. self.assertEqual(self.q, key_obj.q)
  280. self.assertEqual(self.g, key_obj.g)
  281. self.assertEqual(self.x, key_obj.x)
  282. # 10. Encrypted PKCS8
  283. # pkcs5PBES2 /
  284. # pkcs5PBKDF2 (rounds=1000, salt=D725BF1B6B8239F4) /
  285. # des-EDE3-CBC (iv=27A1C66C42AFEECE)
  286. #
  287. der_pkcs8_encrypted=\
  288. '30820196304006092a864886f70d01050d3033301b06092a864886f70d01050c'+\
  289. '300e0408d725bf1b6b8239f4020203e8301406082a864886f70d0307040827a1'+\
  290. 'c66c42afeece048201505cacfde7bf8edabb3e0d387950dc872662ea7e9b1ed4'+\
  291. '400d2e7e6186284b64668d8d0328c33a9d9397e6f03df7cb68268b0a06b4e22f'+\
  292. '7d132821449ecf998a8b696dbc6dd2b19e66d7eb2edfeb4153c1771d49702395'+\
  293. '4f36072868b5fcccf93413a5ac4b2eb47d4b3f681c6bd67ae363ed776f45ae47'+\
  294. '174a00098a7c930a50f820b227ddf50f9742d8e950d02586ff2dac0e3c372248'+\
  295. 'e5f9b6a7a02f4004f20c87913e0f7b52bccc209b95d478256a890b31d4c9adec'+\
  296. '21a4d157a179a93a3dad06f94f3ce486b46dfa7fc15fd852dd7680bbb2f17478'+\
  297. '7e71bd8dbaf81eca7518d76c1d26256e95424864ba45ca5d47d7c5a421be02fa'+\
  298. 'b94ab01e18593f66cf9094eb5c94b9ecf3aa08b854a195cf87612fbe5e96c426'+\
  299. '2b0d573e52dc71ba3f5e468c601e816c49b7d32c698b22175e89aaef0c443770'+\
  300. '5ef2f88a116d99d8e2869a4fd09a771b84b49e4ccb79aadcb1c9'
  301. def testImportKey10(self):
  302. key_obj = DSA.importKey(self.der_pkcs8_encrypted, "PWDTEST")
  303. self.failUnless(key_obj.has_private())
  304. self.assertEqual(self.y, key_obj.y)
  305. self.assertEqual(self.p, key_obj.p)
  306. self.assertEqual(self.q, key_obj.q)
  307. self.assertEqual(self.g, key_obj.g)
  308. self.assertEqual(self.x, key_obj.x)
  309. def testExportKey10(self):
  310. tup = (self.y, self.g, self.p, self.q, self.x)
  311. key = DSA.construct(tup)
  312. randfunc = BytesIO(unhexlify(b("27A1C66C42AFEECE") + b("D725BF1B6B8239F4"))).read
  313. encoded = key.export_key('DER', pkcs8=True, passphrase="PWDTEST", randfunc=randfunc)
  314. self.assertEqual(self.der_pkcs8_encrypted, encoded)
  315. # ----
  316. def testImportError1(self):
  317. self.assertRaises(ValueError, DSA.importKey, self.der_pkcs8_encrypted, "wrongpwd")
  318. def testExportError2(self):
  319. tup = (self.y, self.g, self.p, self.q, self.x)
  320. key = DSA.construct(tup)
  321. self.assertRaises(ValueError, key.export_key, 'DER', pkcs8=False, passphrase="PWDTEST")
  322. def test_import_key(self):
  323. """Verify importKey is an alias to import_key"""
  324. key_obj = DSA.import_key(self.der_public)
  325. self.failIf(key_obj.has_private())
  326. self.assertEqual(self.y, key_obj.y)
  327. self.assertEqual(self.p, key_obj.p)
  328. self.assertEqual(self.q, key_obj.q)
  329. self.assertEqual(self.g, key_obj.g)
  330. def test_exportKey(self):
  331. tup = (self.y, self.g, self.p, self.q, self.x)
  332. key = DSA.construct(tup)
  333. self.assertEquals(key.exportKey(), key.export_key())
  334. def test_import_empty(self):
  335. self.assertRaises(ValueError, DSA.import_key, b'')
  336. class ImportKeyFromX509Cert(unittest.TestCase):
  337. def test_x509v1(self):
  338. # Sample V1 certificate with a 1024 bit DSA key
  339. x509_v1_cert = """
  340. -----BEGIN CERTIFICATE-----
  341. MIIDUjCCArsCAQIwDQYJKoZIhvcNAQEFBQAwfjENMAsGA1UEChMEQWNtZTELMAkG
  342. A1UECxMCUkQxHDAaBgkqhkiG9w0BCQEWDXNwYW1AYWNtZS5vcmcxEzARBgNVBAcT
  343. Ck1ldHJvcG9saXMxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYDVQQGEwJVUzENMAsG
  344. A1UEAxMEdGVzdDAeFw0xNDA3MTEyMDM4NDNaFw0xNzA0MDYyMDM4NDNaME0xCzAJ
  345. BgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazENMAsGA1UEChMEQWNtZTELMAkG
  346. A1UECxMCUkQxDzANBgNVBAMTBnBvbGFuZDCCAbYwggErBgcqhkjOOAQBMIIBHgKB
  347. gQDOrN4Ox4+t3T6wKeHfhzArhcrNEFMQ4Ss+4PIKyimDy9Bn64WPkL1B/9dvYIga
  348. 23GLu6tVJmXo6EdJnVOHEMhr99EeOwuDWWeP7Awq7RSlKEejokr4BEzMTW/tExSD
  349. cO6/GI7xzh0eTH+VTTPDfyrJMYCkh0rJAfCP+5xrmPNetwIVALtXYOV1yoRrzJ2Q
  350. M5uEjidH6GiZAoGAfUqA1SAm5g5U68SILMVX9l5rq0OpB0waBMpJQ31/R/yXNDqo
  351. c3gGWZTOJFU4IzwNpGhrGNADUByz/lc1SAOAdEJIr0JVrhbGewQjB4pWqoLGbBKz
  352. RoavTNDc/zD7SYa12evWDHADwvlXoeQg+lWop1zS8OqaDC7aLGKpWN3/m8kDgYQA
  353. AoGAKoirPAfcp1rbbl4y2FFAIktfW8f4+T7d2iKSg73aiVfujhNOt1Zz1lfC0NI2
  354. eonLWO3tAM4XGKf1TLjb5UXngGn40okPsaA81YE6ZIKm20ywjlOY3QkAEdMaLVY3
  355. 9PJvM8RGB9m7pLKxyHfGMfF40MVN4222zKeGp7xhM0CNiCUwDQYJKoZIhvcNAQEF
  356. BQADgYEAfbNZfpYa2KlALEM1FZnwvQDvJHntHz8LdeJ4WM7CXDlKi67wY2HKM30w
  357. s2xej75imkVOFd1kF2d0A8sjfriXLVIt1Hwq9ANZomhu4Edx0xpH8tqdh/bDtnM2
  358. TmduZNY9OWkb07h0CtWD6Zt8fhRllVsSSrlWd/2or7FXNC5weFQ=
  359. -----END CERTIFICATE-----
  360. """.strip()
  361. # DSA public key as dumped by openssl
  362. y_str = """
  363. 2a:88:ab:3c:07:dc:a7:5a:db:6e:5e:32:d8:51:40:
  364. 22:4b:5f:5b:c7:f8:f9:3e:dd:da:22:92:83:bd:da:
  365. 89:57:ee:8e:13:4e:b7:56:73:d6:57:c2:d0:d2:36:
  366. 7a:89:cb:58:ed:ed:00:ce:17:18:a7:f5:4c:b8:db:
  367. e5:45:e7:80:69:f8:d2:89:0f:b1:a0:3c:d5:81:3a:
  368. 64:82:a6:db:4c:b0:8e:53:98:dd:09:00:11:d3:1a:
  369. 2d:56:37:f4:f2:6f:33:c4:46:07:d9:bb:a4:b2:b1:
  370. c8:77:c6:31:f1:78:d0:c5:4d:e3:6d:b6:cc:a7:86:
  371. a7:bc:61:33:40:8d:88:25
  372. """
  373. p_str = """
  374. 00:ce:ac:de:0e:c7:8f:ad:dd:3e:b0:29:e1:df:87:
  375. 30:2b:85:ca:cd:10:53:10:e1:2b:3e:e0:f2:0a:ca:
  376. 29:83:cb:d0:67:eb:85:8f:90:bd:41:ff:d7:6f:60:
  377. 88:1a:db:71:8b:bb:ab:55:26:65:e8:e8:47:49:9d:
  378. 53:87:10:c8:6b:f7:d1:1e:3b:0b:83:59:67:8f:ec:
  379. 0c:2a:ed:14:a5:28:47:a3:a2:4a:f8:04:4c:cc:4d:
  380. 6f:ed:13:14:83:70:ee:bf:18:8e:f1:ce:1d:1e:4c:
  381. 7f:95:4d:33:c3:7f:2a:c9:31:80:a4:87:4a:c9:01:
  382. f0:8f:fb:9c:6b:98:f3:5e:b7
  383. """
  384. q_str = """
  385. 00:bb:57:60:e5:75:ca:84:6b:cc:9d:90:33:9b:84:
  386. 8e:27:47:e8:68:99
  387. """
  388. g_str = """
  389. 7d:4a:80:d5:20:26:e6:0e:54:eb:c4:88:2c:c5:57:
  390. f6:5e:6b:ab:43:a9:07:4c:1a:04:ca:49:43:7d:7f:
  391. 47:fc:97:34:3a:a8:73:78:06:59:94:ce:24:55:38:
  392. 23:3c:0d:a4:68:6b:18:d0:03:50:1c:b3:fe:57:35:
  393. 48:03:80:74:42:48:af:42:55:ae:16:c6:7b:04:23:
  394. 07:8a:56:aa:82:c6:6c:12:b3:46:86:af:4c:d0:dc:
  395. ff:30:fb:49:86:b5:d9:eb:d6:0c:70:03:c2:f9:57:
  396. a1:e4:20:fa:55:a8:a7:5c:d2:f0:ea:9a:0c:2e:da:
  397. 2c:62:a9:58:dd:ff:9b:c9
  398. """
  399. key = DSA.importKey(x509_v1_cert)
  400. for comp_name in ('y', 'p', 'q', 'g'):
  401. comp_str = locals()[comp_name + "_str"]
  402. comp = int(re.sub("[^0-9a-f]", "", comp_str), 16)
  403. self.assertEqual(getattr(key, comp_name), comp)
  404. self.failIf(key.has_private())
  405. def test_x509v3(self):
  406. # Sample V3 certificate with a 1024 bit DSA key
  407. x509_v3_cert = """
  408. -----BEGIN CERTIFICATE-----
  409. MIIFhjCCA26gAwIBAgIBAzANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJVUzEL
  410. MAkGA1UECAwCTUQxEjAQBgNVBAcMCUJhbHRpbW9yZTEQMA4GA1UEAwwHVGVzdCBD
  411. QTEfMB0GCSqGSIb3DQEJARYQdGVzdEBleGFtcGxlLmNvbTAeFw0xNDA3MTMyMDUz
  412. MjBaFw0xNzA0MDgyMDUzMjBaMEAxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNRDES
  413. MBAGA1UEBwwJQmFsdGltb3JlMRAwDgYDVQQDDAdhdXN0cmlhMIIBtjCCASsGByqG
  414. SM44BAEwggEeAoGBALfd8gyEpVPA0ZI69Kp3nyJcu5N0ZZ3K1K9hleQLNqKEcZOh
  415. 7a/C2J1TPdmHTLJ0rAwBZ1nWxnARSgRphziGDFspKCYQwYcSMz8KoFgvXbXpuchy
  416. oFACiQ2LqZnc5MakuLQtLcQciSYGYj3zmZdYMoa904F1aDWr+DxQI6DVC3/bAhUA
  417. hqXMCJ6fQK3G2O9S3/CC/yVZXCsCgYBRXROl3R2khX7l10LQjDEgo3B1IzjXU/jP
  418. McMBl6XO+nBJXxr/scbq8Ajiv7LTnGpSjgryHtvfj887kfvo8QbSS3kp3vq5uSqI
  419. ui7E7r3jguWaLj616AG1HWOctXJUjqsiabZwsp2h09gHTzmHEXBOmiARu8xFxKAH
  420. xsuo7onAbwOBhAACgYBylWjWSnKHE8mHx1A5m/0GQx6xnhWIe3+MJAnEhRGxA2J4
  421. SCsfWU0OwglIQToh1z5uUU9oDi9cYgNPBevOFRnDhc2yaJY6VAYnI+D+6J5IU6Yd
  422. 0iaG/iSc4sV4bFr0axcPpse3SN0XaQxiKeSFBfFnoMqL+dd9Gb3QPZSllBcVD6OB
  423. 1TCB0jAdBgNVHQ4EFgQUx5wN0Puotv388M9Tp/fsPbZpzAUwHwYDVR0jBBgwFoAU
  424. a0hkif3RMaraiWtsOOZZlLu9wJwwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwSgYD
  425. VR0RBEMwQYILZXhhbXBsZS5jb22CD3d3dy5leGFtcGxlLmNvbYIQbWFpbC5leGFt
  426. cGxlLmNvbYIPZnRwLmV4YW1wbGUuY29tMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM
  427. IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAgEAyWf1TiJI
  428. aNEIA9o/PG8/JiGASTS2/HBVTJbkq03k6NkJVk/GxC1DPziTUJ+CdWlHWcAi1EOW
  429. Ach3QxNDRrVfCOfCMDgElIO1094/reJgdFYG00LRi8QkRJuxANV7YS4tLudhyHJC
  430. kR2lhdMNmEuzWK+s2y+5cLrdm7qdvdENQCcV67uvGPx4sc+EaE7x13SczKjWBtbo
  431. QCs6JTOW+EkPRl4Zo27K4OIZ43/J+GxvwU9QUVH3wPVdbbLNw+QeTFBYMTEcxyc4
  432. kv50HPBFaithziXBFyvdIs19FjkFzu0Uz/e0zb1+vMzQlJMD94HVOrMnIj5Sb2cL
  433. KKdYXS4uhxFJmdV091Xur5JkYYwEzuaGav7J3zOzYutrIGTgDluLCvA+VQkRcTsy
  434. jZ065SkY/v+38QHp+cmm8WRluupJTs8wYzVp6Fu0iFaaK7ztFmaZmHpiPIfDFjva
  435. aCIgzzT5NweJd/b71A2SyzHXJ14zBXsr1PMylMp2TpHIidhuuNuQL6I0HaollB4M
  436. Z3FsVBMhVDw4Z76qnFPr8mZE2tar33hSlJI/3pS/bBiukuBk8U7VB0X8OqaUnP3C
  437. 7b2Z4G8GtqDVcKGMzkvMjT4n9rKd/Le+qHSsQOGO9W/0LB7UDAZSwUsfAPnoBgdS
  438. 5t9tIomLCOstByXi+gGZue1TcdCa3Ph4kO0=
  439. -----END CERTIFICATE-----
  440. """.strip()
  441. # DSA public key as dumped by openssl
  442. y_str = """
  443. 72:95:68:d6:4a:72:87:13:c9:87:c7:50:39:9b:fd:
  444. 06:43:1e:b1:9e:15:88:7b:7f:8c:24:09:c4:85:11:
  445. b1:03:62:78:48:2b:1f:59:4d:0e:c2:09:48:41:3a:
  446. 21:d7:3e:6e:51:4f:68:0e:2f:5c:62:03:4f:05:eb:
  447. ce:15:19:c3:85:cd:b2:68:96:3a:54:06:27:23:e0:
  448. fe:e8:9e:48:53:a6:1d:d2:26:86:fe:24:9c:e2:c5:
  449. 78:6c:5a:f4:6b:17:0f:a6:c7:b7:48:dd:17:69:0c:
  450. 62:29:e4:85:05:f1:67:a0:ca:8b:f9:d7:7d:19:bd:
  451. d0:3d:94:a5:94:17:15:0f
  452. """
  453. p_str = """
  454. 00:b7:dd:f2:0c:84:a5:53:c0:d1:92:3a:f4:aa:77:
  455. 9f:22:5c:bb:93:74:65:9d:ca:d4:af:61:95:e4:0b:
  456. 36:a2:84:71:93:a1:ed:af:c2:d8:9d:53:3d:d9:87:
  457. 4c:b2:74:ac:0c:01:67:59:d6:c6:70:11:4a:04:69:
  458. 87:38:86:0c:5b:29:28:26:10:c1:87:12:33:3f:0a:
  459. a0:58:2f:5d:b5:e9:b9:c8:72:a0:50:02:89:0d:8b:
  460. a9:99:dc:e4:c6:a4:b8:b4:2d:2d:c4:1c:89:26:06:
  461. 62:3d:f3:99:97:58:32:86:bd:d3:81:75:68:35:ab:
  462. f8:3c:50:23:a0:d5:0b:7f:db
  463. """
  464. q_str = """
  465. 00:86:a5:cc:08:9e:9f:40:ad:c6:d8:ef:52:df:f0:
  466. 82:ff:25:59:5c:2b
  467. """
  468. g_str = """
  469. 51:5d:13:a5:dd:1d:a4:85:7e:e5:d7:42:d0:8c:31:
  470. 20:a3:70:75:23:38:d7:53:f8:cf:31:c3:01:97:a5:
  471. ce:fa:70:49:5f:1a:ff:b1:c6:ea:f0:08:e2:bf:b2:
  472. d3:9c:6a:52:8e:0a:f2:1e:db:df:8f:cf:3b:91:fb:
  473. e8:f1:06:d2:4b:79:29:de:fa:b9:b9:2a:88:ba:2e:
  474. c4:ee:bd:e3:82:e5:9a:2e:3e:b5:e8:01:b5:1d:63:
  475. 9c:b5:72:54:8e:ab:22:69:b6:70:b2:9d:a1:d3:d8:
  476. 07:4f:39:87:11:70:4e:9a:20:11:bb:cc:45:c4:a0:
  477. 07:c6:cb:a8:ee:89:c0:6f
  478. """
  479. key = DSA.importKey(x509_v3_cert)
  480. for comp_name in ('y', 'p', 'q', 'g'):
  481. comp_str = locals()[comp_name + "_str"]
  482. comp = int(re.sub("[^0-9a-f]", "", comp_str), 16)
  483. self.assertEqual(getattr(key, comp_name), comp)
  484. self.failIf(key.has_private())
  485. if __name__ == '__main__':
  486. unittest.main()
  487. def get_tests(config={}):
  488. tests = []
  489. tests += list_test_cases(ImportKeyTests)
  490. tests += list_test_cases(ImportKeyFromX509Cert)
  491. return tests
  492. if __name__ == '__main__':
  493. suite = lambda: unittest.TestSuite(get_tests())
  494. unittest.main(defaultTest='suite')