python3 update
This commit is contained in:
@@ -1,44 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/__init__.py: Self-test for public key crypto
|
||||
#
|
||||
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
"""Self-test for public-key crypto"""
|
||||
|
||||
__revision__ = "$Id$"
|
||||
|
||||
import os
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
from Crypto.SelfTest.PublicKey import test_DSA; tests += test_DSA.get_tests(config=config)
|
||||
from Crypto.SelfTest.PublicKey import test_RSA; tests += test_RSA.get_tests(config=config)
|
||||
from Crypto.SelfTest.PublicKey import test_importKey; tests += test_importKey.get_tests(config=config)
|
||||
from Crypto.SelfTest.PublicKey import test_ElGamal; tests += test_ElGamal.get_tests(config=config)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
import unittest
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
# vim:set ts=4 sw=4 sts=4 expandtab:
|
@@ -1,244 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_DSA.py: Self-test for the DSA primitive
|
||||
#
|
||||
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
"""Self-test suite for Crypto.PublicKey.DSA"""
|
||||
|
||||
__revision__ = "$Id$"
|
||||
|
||||
import sys
|
||||
import os
|
||||
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
|
||||
from Crypto.Util.py21compat import *
|
||||
from Crypto.Util.py3compat import *
|
||||
|
||||
import unittest
|
||||
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
|
||||
|
||||
def _sws(s):
|
||||
"""Remove whitespace from a text or byte string"""
|
||||
if isinstance(s,str):
|
||||
return "".join(s.split())
|
||||
else:
|
||||
return b("").join(s.split())
|
||||
|
||||
class DSATest(unittest.TestCase):
|
||||
# Test vector from "Appendix 5. Example of the DSA" of
|
||||
# "Digital Signature Standard (DSS)",
|
||||
# U.S. Department of Commerce/National Institute of Standards and Technology
|
||||
# FIPS 186-2 (+Change Notice), 2000 January 27.
|
||||
# http://csrc.nist.gov/publications/fips/fips186-2/fips186-2-change1.pdf
|
||||
|
||||
y = _sws("""19131871 d75b1612 a819f29d 78d1b0d7 346f7aa7 7bb62a85
|
||||
9bfd6c56 75da9d21 2d3a36ef 1672ef66 0b8c7c25 5cc0ec74
|
||||
858fba33 f44c0669 9630a76b 030ee333""")
|
||||
|
||||
g = _sws("""626d0278 39ea0a13 413163a5 5b4cb500 299d5522 956cefcb
|
||||
3bff10f3 99ce2c2e 71cb9de5 fa24babf 58e5b795 21925c9c
|
||||
c42e9f6f 464b088c c572af53 e6d78802""")
|
||||
|
||||
p = _sws("""8df2a494 492276aa 3d25759b b06869cb eac0d83a fb8d0cf7
|
||||
cbb8324f 0d7882e5 d0762fc5 b7210eaf c2e9adac 32ab7aac
|
||||
49693dfb f83724c2 ec0736ee 31c80291""")
|
||||
|
||||
q = _sws("""c773218c 737ec8ee 993b4f2d ed30f48e dace915f""")
|
||||
|
||||
x = _sws("""2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614""")
|
||||
|
||||
k = _sws("""358dad57 1462710f 50e254cf 1a376b2b deaadfbf""")
|
||||
k_inverse = _sws("""0d516729 8202e49b 4116ac10 4fc3f415 ae52f917""")
|
||||
m = b2a_hex(b("abc"))
|
||||
m_hash = _sws("""a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d""")
|
||||
r = _sws("""8bac1ab6 6410435c b7181f95 b16ab97c 92b341c0""")
|
||||
s = _sws("""41e2345f 1f56df24 58f426d1 55b4ba2d b6dcd8c8""")
|
||||
|
||||
def setUp(self):
|
||||
global DSA, Random, bytes_to_long, size
|
||||
from Crypto.PublicKey import DSA
|
||||
from Crypto import Random
|
||||
from Crypto.Util.number import bytes_to_long, inverse, size
|
||||
|
||||
self.dsa = DSA
|
||||
|
||||
def test_generate_1arg(self):
|
||||
"""DSA (default implementation) generated key (1 argument)"""
|
||||
dsaObj = self.dsa.generate(1024)
|
||||
self._check_private_key(dsaObj)
|
||||
pub = dsaObj.publickey()
|
||||
self._check_public_key(pub)
|
||||
|
||||
def test_generate_2arg(self):
|
||||
"""DSA (default implementation) generated key (2 arguments)"""
|
||||
dsaObj = self.dsa.generate(1024, Random.new().read)
|
||||
self._check_private_key(dsaObj)
|
||||
pub = dsaObj.publickey()
|
||||
self._check_public_key(pub)
|
||||
|
||||
def test_construct_4tuple(self):
|
||||
"""DSA (default implementation) constructed key (4-tuple)"""
|
||||
(y, g, p, q) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q)]
|
||||
dsaObj = self.dsa.construct((y, g, p, q))
|
||||
self._test_verification(dsaObj)
|
||||
|
||||
def test_construct_5tuple(self):
|
||||
"""DSA (default implementation) constructed key (5-tuple)"""
|
||||
(y, g, p, q, x) = [bytes_to_long(a2b_hex(param)) for param in (self.y, self.g, self.p, self.q, self.x)]
|
||||
dsaObj = self.dsa.construct((y, g, p, q, x))
|
||||
self._test_signing(dsaObj)
|
||||
self._test_verification(dsaObj)
|
||||
|
||||
def _check_private_key(self, dsaObj):
|
||||
# Check capabilities
|
||||
self.assertEqual(1, dsaObj.has_private())
|
||||
self.assertEqual(1, dsaObj.can_sign())
|
||||
self.assertEqual(0, dsaObj.can_encrypt())
|
||||
self.assertEqual(0, dsaObj.can_blind())
|
||||
|
||||
# Check dsaObj.[ygpqx] -> dsaObj.key.[ygpqx] mapping
|
||||
self.assertEqual(dsaObj.y, dsaObj.key.y)
|
||||
self.assertEqual(dsaObj.g, dsaObj.key.g)
|
||||
self.assertEqual(dsaObj.p, dsaObj.key.p)
|
||||
self.assertEqual(dsaObj.q, dsaObj.key.q)
|
||||
self.assertEqual(dsaObj.x, dsaObj.key.x)
|
||||
|
||||
# Sanity check key data
|
||||
self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q
|
||||
self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits
|
||||
self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1
|
||||
self.assertEqual(dsaObj.y, pow(dsaObj.g, dsaObj.x, dsaObj.p)) # y == g**x mod p
|
||||
self.assertEqual(1, 0 < dsaObj.x < dsaObj.q) # 0 < x < q
|
||||
|
||||
def _check_public_key(self, dsaObj):
|
||||
k = a2b_hex(self.k)
|
||||
m_hash = a2b_hex(self.m_hash)
|
||||
|
||||
# Check capabilities
|
||||
self.assertEqual(0, dsaObj.has_private())
|
||||
self.assertEqual(1, dsaObj.can_sign())
|
||||
self.assertEqual(0, dsaObj.can_encrypt())
|
||||
self.assertEqual(0, dsaObj.can_blind())
|
||||
|
||||
# Check dsaObj.[ygpq] -> dsaObj.key.[ygpq] mapping
|
||||
self.assertEqual(dsaObj.y, dsaObj.key.y)
|
||||
self.assertEqual(dsaObj.g, dsaObj.key.g)
|
||||
self.assertEqual(dsaObj.p, dsaObj.key.p)
|
||||
self.assertEqual(dsaObj.q, dsaObj.key.q)
|
||||
|
||||
# Check that private parameters are all missing
|
||||
self.assertEqual(0, hasattr(dsaObj, 'x'))
|
||||
self.assertEqual(0, hasattr(dsaObj.key, 'x'))
|
||||
|
||||
# Sanity check key data
|
||||
self.assertEqual(1, dsaObj.p > dsaObj.q) # p > q
|
||||
self.assertEqual(160, size(dsaObj.q)) # size(q) == 160 bits
|
||||
self.assertEqual(0, (dsaObj.p - 1) % dsaObj.q) # q is a divisor of p-1
|
||||
|
||||
# Public-only key objects should raise an error when .sign() is called
|
||||
self.assertRaises(TypeError, dsaObj.sign, m_hash, k)
|
||||
|
||||
# Check __eq__ and __ne__
|
||||
self.assertEqual(dsaObj.publickey() == dsaObj.publickey(),True) # assert_
|
||||
self.assertEqual(dsaObj.publickey() != dsaObj.publickey(),False) # failIf
|
||||
|
||||
def _test_signing(self, dsaObj):
|
||||
k = a2b_hex(self.k)
|
||||
m_hash = a2b_hex(self.m_hash)
|
||||
r = bytes_to_long(a2b_hex(self.r))
|
||||
s = bytes_to_long(a2b_hex(self.s))
|
||||
(r_out, s_out) = dsaObj.sign(m_hash, k)
|
||||
self.assertEqual((r, s), (r_out, s_out))
|
||||
|
||||
def _test_verification(self, dsaObj):
|
||||
m_hash = a2b_hex(self.m_hash)
|
||||
r = bytes_to_long(a2b_hex(self.r))
|
||||
s = bytes_to_long(a2b_hex(self.s))
|
||||
self.assertEqual(1, dsaObj.verify(m_hash, (r, s)))
|
||||
self.assertEqual(0, dsaObj.verify(m_hash + b("\0"), (r, s)))
|
||||
|
||||
class DSAFastMathTest(DSATest):
|
||||
def setUp(self):
|
||||
DSATest.setUp(self)
|
||||
self.dsa = DSA.DSAImplementation(use_fast_math=True)
|
||||
|
||||
def test_generate_1arg(self):
|
||||
"""DSA (_fastmath implementation) generated key (1 argument)"""
|
||||
DSATest.test_generate_1arg(self)
|
||||
|
||||
def test_generate_2arg(self):
|
||||
"""DSA (_fastmath implementation) generated key (2 arguments)"""
|
||||
DSATest.test_generate_2arg(self)
|
||||
|
||||
def test_construct_4tuple(self):
|
||||
"""DSA (_fastmath implementation) constructed key (4-tuple)"""
|
||||
DSATest.test_construct_4tuple(self)
|
||||
|
||||
def test_construct_5tuple(self):
|
||||
"""DSA (_fastmath implementation) constructed key (5-tuple)"""
|
||||
DSATest.test_construct_5tuple(self)
|
||||
|
||||
class DSASlowMathTest(DSATest):
|
||||
def setUp(self):
|
||||
DSATest.setUp(self)
|
||||
self.dsa = DSA.DSAImplementation(use_fast_math=False)
|
||||
|
||||
def test_generate_1arg(self):
|
||||
"""DSA (_slowmath implementation) generated key (1 argument)"""
|
||||
DSATest.test_generate_1arg(self)
|
||||
|
||||
def test_generate_2arg(self):
|
||||
"""DSA (_slowmath implementation) generated key (2 arguments)"""
|
||||
DSATest.test_generate_2arg(self)
|
||||
|
||||
def test_construct_4tuple(self):
|
||||
"""DSA (_slowmath implementation) constructed key (4-tuple)"""
|
||||
DSATest.test_construct_4tuple(self)
|
||||
|
||||
def test_construct_5tuple(self):
|
||||
"""DSA (_slowmath implementation) constructed key (5-tuple)"""
|
||||
DSATest.test_construct_5tuple(self)
|
||||
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(DSATest)
|
||||
try:
|
||||
from Crypto.PublicKey import _fastmath
|
||||
tests += list_test_cases(DSAFastMathTest)
|
||||
except ImportError:
|
||||
from distutils.sysconfig import get_config_var
|
||||
import inspect
|
||||
_fm_path = os.path.normpath(os.path.dirname(os.path.abspath(
|
||||
inspect.getfile(inspect.currentframe())))
|
||||
+"/../../PublicKey/_fastmath"+get_config_var("SO"))
|
||||
if os.path.exists(_fm_path):
|
||||
raise ImportError("While the _fastmath module exists, importing "+
|
||||
"it failed. This may point to the gmp or mpir shared library "+
|
||||
"not being in the path. _fastmath was found at "+_fm_path)
|
||||
tests += list_test_cases(DSASlowMathTest)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
# vim:set ts=4 sw=4 sts=4 expandtab:
|
@@ -1,210 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_ElGamal.py: Self-test for the ElGamal primitive
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
"""Self-test suite for Crypto.PublicKey.ElGamal"""
|
||||
|
||||
__revision__ = "$Id$"
|
||||
|
||||
import unittest
|
||||
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
|
||||
from Crypto import Random
|
||||
from Crypto.PublicKey import ElGamal
|
||||
from Crypto.Util.number import *
|
||||
from Crypto.Util.py3compat import *
|
||||
|
||||
class ElGamalTest(unittest.TestCase):
|
||||
|
||||
#
|
||||
# Test vectors
|
||||
#
|
||||
# There seem to be no real ElGamal test vectors available in the
|
||||
# public domain. The following test vectors have been generated
|
||||
# with libgcrypt 1.5.0.
|
||||
#
|
||||
# Encryption
|
||||
tve=[
|
||||
{
|
||||
# 256 bits
|
||||
'p' :'BA4CAEAAED8CBE952AFD2126C63EB3B345D65C2A0A73D2A3AD4138B6D09BD933',
|
||||
'g' :'05',
|
||||
'y' :'60D063600ECED7C7C55146020E7A31C4476E9793BEAED420FEC9E77604CAE4EF',
|
||||
'x' :'1D391BA2EE3C37FE1BA175A69B2C73A11238AD77675932',
|
||||
'k' :'F5893C5BAB4131264066F57AB3D8AD89E391A0B68A68A1',
|
||||
'pt' :'48656C6C6F207468657265',
|
||||
'ct1':'32BFD5F487966CEA9E9356715788C491EC515E4ED48B58F0F00971E93AAA5EC7',
|
||||
'ct2':'7BE8FBFF317C93E82FCEF9BD515284BA506603FEA25D01C0CB874A31F315EE68'
|
||||
},
|
||||
|
||||
{
|
||||
# 512 bits
|
||||
'p' :'F1B18AE9F7B4E08FDA9A04832F4E919D89462FD31BF12F92791A93519F75076D6CE3942689CDFF2F344CAFF0F82D01864F69F3AECF566C774CBACF728B81A227',
|
||||
'g' :'07',
|
||||
'y' :'688628C676E4F05D630E1BE39D0066178CA7AA83836B645DE5ADD359B4825A12B02EF4252E4E6FA9BEC1DB0BE90F6D7C8629CABB6E531F472B2664868156E20C',
|
||||
'x' :'14E60B1BDFD33436C0DA8A22FDC14A2CCDBBED0627CE68',
|
||||
'k' :'38DBF14E1F319BDA9BAB33EEEADCAF6B2EA5250577ACE7',
|
||||
'pt' :'48656C6C6F207468657265',
|
||||
'ct1':'290F8530C2CC312EC46178724F196F308AD4C523CEABB001FACB0506BFED676083FE0F27AC688B5C749AB3CB8A80CD6F7094DBA421FB19442F5A413E06A9772B',
|
||||
'ct2':'1D69AAAD1DC50493FB1B8E8721D621D683F3BF1321BE21BC4A43E11B40C9D4D9C80DE3AAC2AB60D31782B16B61112E68220889D53C4C3136EE6F6CE61F8A23A0'
|
||||
}
|
||||
]
|
||||
|
||||
# Signature
|
||||
tvs=[
|
||||
{
|
||||
# 256 bits
|
||||
'p' :'D2F3C41EA66530838A704A48FFAC9334F4701ECE3A97CEE4C69DD01AE7129DD7',
|
||||
'g' :'05',
|
||||
'y' :'C3F9417DC0DAFEA6A05C1D2333B7A95E63B3F4F28CC962254B3256984D1012E7',
|
||||
'x' :'165E4A39BE44D5A2D8B1332D416BC559616F536BC735BB',
|
||||
'k' :'C7F0C794A7EAD726E25A47FF8928013680E73C51DD3D7D99BFDA8F492585928F',
|
||||
'h' :'48656C6C6F207468657265',
|
||||
'sig1':'35CA98133779E2073EF31165AFCDEB764DD54E96ADE851715495F9C635E1E7C2',
|
||||
'sig2':'0135B88B1151279FE5D8078D4FC685EE81177EE9802AB123A73925FC1CB059A7',
|
||||
},
|
||||
{
|
||||
# 512 bits
|
||||
'p' :'E24CF3A4B8A6AF749DCA6D714282FE4AABEEE44A53BB6ED15FBE32B5D3C3EF9CC4124A2ECA331F3C1C1B667ACA3766825217E7B5F9856648D95F05330C6A19CF',
|
||||
'g' :'0B',
|
||||
'y' :'2AD3A1049CA5D4ED207B2431C79A8719BB4073D4A94E450EA6CEE8A760EB07ADB67C0D52C275EE85D7B52789061EE45F2F37D9B2AE522A51C28329766BFE68AC',
|
||||
'x' :'16CBB4F46D9ECCF24FF9F7E63CAA3BD8936341555062AB',
|
||||
'k' :'8A3D89A4E429FD2476D7D717251FB79BF900FFE77444E6BB8299DC3F84D0DD57ABAB50732AE158EA52F5B9E7D8813E81FD9F79470AE22F8F1CF9AEC820A78C69',
|
||||
'h' :'48656C6C6F207468657265',
|
||||
'sig1':'BE001AABAFFF976EC9016198FBFEA14CBEF96B000CCC0063D3324016F9E91FE80D8F9325812ED24DDB2B4D4CF4430B169880B3CE88313B53255BD4EC0378586F',
|
||||
'sig2':'5E266F3F837BA204E3BBB6DBECC0611429D96F8C7CE8F4EFDF9D4CB681C2A954468A357BF4242CEC7418B51DFC081BCD21299EF5B5A0DDEF3A139A1817503DDE',
|
||||
}
|
||||
]
|
||||
|
||||
def test_generate_128(self):
|
||||
self._test_random_key(128)
|
||||
|
||||
def test_generate_512(self):
|
||||
self._test_random_key(512)
|
||||
|
||||
def test_encryption(self):
|
||||
for tv in self.tve:
|
||||
for as_longs in (0,1):
|
||||
d = self.convert_tv(tv, as_longs)
|
||||
key = ElGamal.construct(d['key'])
|
||||
ct = key.encrypt(d['pt'], d['k'])
|
||||
self.assertEquals(ct[0], d['ct1'])
|
||||
self.assertEquals(ct[1], d['ct2'])
|
||||
|
||||
def test_decryption(self):
|
||||
for tv in self.tve:
|
||||
for as_longs in (0,1):
|
||||
d = self.convert_tv(tv, as_longs)
|
||||
key = ElGamal.construct(d['key'])
|
||||
pt = key.decrypt((d['ct1'], d['ct2']))
|
||||
self.assertEquals(pt, d['pt'])
|
||||
|
||||
def test_signing(self):
|
||||
for tv in self.tvs:
|
||||
for as_longs in (0,1):
|
||||
d = self.convert_tv(tv, as_longs)
|
||||
key = ElGamal.construct(d['key'])
|
||||
sig1, sig2 = key.sign(d['h'], d['k'])
|
||||
self.assertEquals(sig1, d['sig1'])
|
||||
self.assertEquals(sig2, d['sig2'])
|
||||
|
||||
def test_verification(self):
|
||||
for tv in self.tvs:
|
||||
for as_longs in (0,1):
|
||||
d = self.convert_tv(tv, as_longs)
|
||||
key = ElGamal.construct(d['key'])
|
||||
# Positive test
|
||||
res = key.verify( d['h'], (d['sig1'],d['sig2']) )
|
||||
self.failUnless(res)
|
||||
# Negative test
|
||||
res = key.verify( d['h'], (d['sig1']+1,d['sig2']) )
|
||||
self.failIf(res)
|
||||
|
||||
def convert_tv(self, tv, as_longs=0):
|
||||
"""Convert a test vector from textual form (hexadecimal ascii
|
||||
to either integers or byte strings."""
|
||||
key_comps = 'p','g','y','x'
|
||||
tv2 = {}
|
||||
for c in tv.keys():
|
||||
tv2[c] = a2b_hex(tv[c])
|
||||
if as_longs or c in key_comps or c in ('sig1','sig2'):
|
||||
tv2[c] = bytes_to_long(tv2[c])
|
||||
tv2['key']=[]
|
||||
for c in key_comps:
|
||||
tv2['key'] += [tv2[c]]
|
||||
del tv2[c]
|
||||
return tv2
|
||||
|
||||
def _test_random_key(self, bits):
|
||||
elgObj = ElGamal.generate(bits, Random.new().read)
|
||||
self._check_private_key(elgObj)
|
||||
self._exercise_primitive(elgObj)
|
||||
pub = elgObj.publickey()
|
||||
self._check_public_key(pub)
|
||||
self._exercise_public_primitive(elgObj)
|
||||
|
||||
def _check_private_key(self, elgObj):
|
||||
|
||||
# Check capabilities
|
||||
self.failUnless(elgObj.has_private())
|
||||
self.failUnless(elgObj.can_sign())
|
||||
self.failUnless(elgObj.can_encrypt())
|
||||
|
||||
# Sanity check key data
|
||||
self.failUnless(1<elgObj.g<(elgObj.p-1))
|
||||
self.assertEquals(pow(elgObj.g, elgObj.p-1, elgObj.p), 1)
|
||||
self.failUnless(1<elgObj.x<(elgObj.p-1))
|
||||
self.assertEquals(pow(elgObj.g, elgObj.x, elgObj.p), elgObj.y)
|
||||
|
||||
def _check_public_key(self, elgObj):
|
||||
|
||||
# Check capabilities
|
||||
self.failIf(elgObj.has_private())
|
||||
self.failUnless(elgObj.can_sign())
|
||||
self.failUnless(elgObj.can_encrypt())
|
||||
|
||||
# Sanity check key data
|
||||
self.failUnless(1<elgObj.g<(elgObj.p-1))
|
||||
self.assertEquals(pow(elgObj.g, elgObj.p-1, elgObj.p), 1)
|
||||
|
||||
def _exercise_primitive(self, elgObj):
|
||||
# Test encryption/decryption
|
||||
plaintext = b("Test")
|
||||
ciphertext = elgObj.encrypt(plaintext, 123456789L)
|
||||
plaintextP = elgObj.decrypt(ciphertext)
|
||||
self.assertEquals(plaintext, plaintextP)
|
||||
|
||||
# Test signature/verification
|
||||
signature = elgObj.sign(plaintext, 987654321L)
|
||||
elgObj.verify(plaintext, signature)
|
||||
|
||||
def _exercise_public_primitive(self, elgObj):
|
||||
plaintext = b("Test")
|
||||
ciphertext = elgObj.encrypt(plaintext, 123456789L)
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(ElGamalTest)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
@@ -1,415 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_RSA.py: Self-test for the RSA primitive
|
||||
#
|
||||
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
"""Self-test suite for Crypto.PublicKey.RSA"""
|
||||
|
||||
__revision__ = "$Id$"
|
||||
|
||||
import sys
|
||||
import os
|
||||
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
|
||||
from Crypto.Util.py21compat import *
|
||||
from Crypto.Util.py3compat import *
|
||||
|
||||
import unittest
|
||||
from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex
|
||||
|
||||
class RSATest(unittest.TestCase):
|
||||
# Test vectors from "RSA-OAEP and RSA-PSS test vectors (.zip file)"
|
||||
# ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
|
||||
# See RSADSI's PKCS#1 page at
|
||||
# http://www.rsa.com/rsalabs/node.asp?id=2125
|
||||
|
||||
# from oaep-int.txt
|
||||
|
||||
# TODO: PyCrypto treats the message as starting *after* the leading "00"
|
||||
# TODO: That behaviour should probably be changed in the future.
|
||||
plaintext = """
|
||||
eb 7a 19 ac e9 e3 00 63 50 e3 29 50 4b 45 e2
|
||||
ca 82 31 0b 26 dc d8 7d 5c 68 f1 ee a8 f5 52 67
|
||||
c3 1b 2e 8b b4 25 1f 84 d7 e0 b2 c0 46 26 f5 af
|
||||
f9 3e dc fb 25 c9 c2 b3 ff 8a e1 0e 83 9a 2d db
|
||||
4c dc fe 4f f4 77 28 b4 a1 b7 c1 36 2b aa d2 9a
|
||||
b4 8d 28 69 d5 02 41 21 43 58 11 59 1b e3 92 f9
|
||||
82 fb 3e 87 d0 95 ae b4 04 48 db 97 2f 3a c1 4f
|
||||
7b c2 75 19 52 81 ce 32 d2 f1 b7 6d 4d 35 3e 2d
|
||||
"""
|
||||
|
||||
ciphertext = """
|
||||
12 53 e0 4d c0 a5 39 7b b4 4a 7a b8 7e 9b f2 a0
|
||||
39 a3 3d 1e 99 6f c8 2a 94 cc d3 00 74 c9 5d f7
|
||||
63 72 20 17 06 9e 52 68 da 5d 1c 0b 4f 87 2c f6
|
||||
53 c1 1d f8 23 14 a6 79 68 df ea e2 8d ef 04 bb
|
||||
6d 84 b1 c3 1d 65 4a 19 70 e5 78 3b d6 eb 96 a0
|
||||
24 c2 ca 2f 4a 90 fe 9f 2e f5 c9 c1 40 e5 bb 48
|
||||
da 95 36 ad 87 00 c8 4f c9 13 0a de a7 4e 55 8d
|
||||
51 a7 4d df 85 d8 b5 0d e9 68 38 d6 06 3e 09 55
|
||||
"""
|
||||
|
||||
modulus = """
|
||||
bb f8 2f 09 06 82 ce 9c 23 38 ac 2b 9d a8 71 f7
|
||||
36 8d 07 ee d4 10 43 a4 40 d6 b6 f0 74 54 f5 1f
|
||||
b8 df ba af 03 5c 02 ab 61 ea 48 ce eb 6f cd 48
|
||||
76 ed 52 0d 60 e1 ec 46 19 71 9d 8a 5b 8b 80 7f
|
||||
af b8 e0 a3 df c7 37 72 3e e6 b4 b7 d9 3a 25 84
|
||||
ee 6a 64 9d 06 09 53 74 88 34 b2 45 45 98 39 4e
|
||||
e0 aa b1 2d 7b 61 a5 1f 52 7a 9a 41 f6 c1 68 7f
|
||||
e2 53 72 98 ca 2a 8f 59 46 f8 e5 fd 09 1d bd cb
|
||||
"""
|
||||
|
||||
e = 0x11L # public exponent
|
||||
|
||||
prime_factor = """
|
||||
c9 7f b1 f0 27 f4 53 f6 34 12 33 ea aa d1 d9 35
|
||||
3f 6c 42 d0 88 66 b1 d0 5a 0f 20 35 02 8b 9d 86
|
||||
98 40 b4 16 66 b4 2e 92 ea 0d a3 b4 32 04 b5 cf
|
||||
ce 33 52 52 4d 04 16 a5 a4 41 e7 00 af 46 15 03
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
global RSA, Random, bytes_to_long
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto import Random
|
||||
from Crypto.Util.number import bytes_to_long, inverse
|
||||
self.n = bytes_to_long(a2b_hex(self.modulus))
|
||||
self.p = bytes_to_long(a2b_hex(self.prime_factor))
|
||||
|
||||
# Compute q, d, and u from n, e, and p
|
||||
self.q = divmod(self.n, self.p)[0]
|
||||
self.d = inverse(self.e, (self.p-1)*(self.q-1))
|
||||
self.u = inverse(self.p, self.q) # u = e**-1 (mod q)
|
||||
|
||||
self.rsa = RSA
|
||||
|
||||
def test_generate_1arg(self):
|
||||
"""RSA (default implementation) generated key (1 argument)"""
|
||||
rsaObj = self.rsa.generate(1024)
|
||||
self._check_private_key(rsaObj)
|
||||
self._exercise_primitive(rsaObj)
|
||||
pub = rsaObj.publickey()
|
||||
self._check_public_key(pub)
|
||||
self._exercise_public_primitive(rsaObj)
|
||||
|
||||
def test_generate_2arg(self):
|
||||
"""RSA (default implementation) generated key (2 arguments)"""
|
||||
rsaObj = self.rsa.generate(1024, Random.new().read)
|
||||
self._check_private_key(rsaObj)
|
||||
self._exercise_primitive(rsaObj)
|
||||
pub = rsaObj.publickey()
|
||||
self._check_public_key(pub)
|
||||
self._exercise_public_primitive(rsaObj)
|
||||
|
||||
def test_generate_3args(self):
|
||||
rsaObj = self.rsa.generate(1024, Random.new().read,e=65537)
|
||||
self._check_private_key(rsaObj)
|
||||
self._exercise_primitive(rsaObj)
|
||||
pub = rsaObj.publickey()
|
||||
self._check_public_key(pub)
|
||||
self._exercise_public_primitive(rsaObj)
|
||||
self.assertEqual(65537,rsaObj.e)
|
||||
|
||||
def test_construct_2tuple(self):
|
||||
"""RSA (default implementation) constructed key (2-tuple)"""
|
||||
pub = self.rsa.construct((self.n, self.e))
|
||||
self._check_public_key(pub)
|
||||
self._check_encryption(pub)
|
||||
self._check_verification(pub)
|
||||
|
||||
def test_construct_3tuple(self):
|
||||
"""RSA (default implementation) constructed key (3-tuple)"""
|
||||
rsaObj = self.rsa.construct((self.n, self.e, self.d))
|
||||
self._check_encryption(rsaObj)
|
||||
self._check_decryption(rsaObj)
|
||||
self._check_signing(rsaObj)
|
||||
self._check_verification(rsaObj)
|
||||
|
||||
def test_construct_4tuple(self):
|
||||
"""RSA (default implementation) constructed key (4-tuple)"""
|
||||
rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p))
|
||||
self._check_encryption(rsaObj)
|
||||
self._check_decryption(rsaObj)
|
||||
self._check_signing(rsaObj)
|
||||
self._check_verification(rsaObj)
|
||||
|
||||
def test_construct_5tuple(self):
|
||||
"""RSA (default implementation) constructed key (5-tuple)"""
|
||||
rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q))
|
||||
self._check_private_key(rsaObj)
|
||||
self._check_encryption(rsaObj)
|
||||
self._check_decryption(rsaObj)
|
||||
self._check_signing(rsaObj)
|
||||
self._check_verification(rsaObj)
|
||||
|
||||
def test_construct_6tuple(self):
|
||||
"""RSA (default implementation) constructed key (6-tuple)"""
|
||||
rsaObj = self.rsa.construct((self.n, self.e, self.d, self.p, self.q, self.u))
|
||||
self._check_private_key(rsaObj)
|
||||
self._check_encryption(rsaObj)
|
||||
self._check_decryption(rsaObj)
|
||||
self._check_signing(rsaObj)
|
||||
self._check_verification(rsaObj)
|
||||
|
||||
def test_factoring(self):
|
||||
rsaObj = self.rsa.construct([self.n, self.e, self.d])
|
||||
self.failUnless(rsaObj.p==self.p or rsaObj.p==self.q)
|
||||
self.failUnless(rsaObj.q==self.p or rsaObj.q==self.q)
|
||||
self.failUnless(rsaObj.q*rsaObj.p == self.n)
|
||||
|
||||
self.assertRaises(ValueError, self.rsa.construct, [self.n, self.e, self.n-1])
|
||||
|
||||
def _check_private_key(self, rsaObj):
|
||||
# Check capabilities
|
||||
self.assertEqual(1, rsaObj.has_private())
|
||||
self.assertEqual(1, rsaObj.can_sign())
|
||||
self.assertEqual(1, rsaObj.can_encrypt())
|
||||
self.assertEqual(1, rsaObj.can_blind())
|
||||
|
||||
# Check rsaObj.[nedpqu] -> rsaObj.key.[nedpqu] mapping
|
||||
self.assertEqual(rsaObj.n, rsaObj.key.n)
|
||||
self.assertEqual(rsaObj.e, rsaObj.key.e)
|
||||
self.assertEqual(rsaObj.d, rsaObj.key.d)
|
||||
self.assertEqual(rsaObj.p, rsaObj.key.p)
|
||||
self.assertEqual(rsaObj.q, rsaObj.key.q)
|
||||
self.assertEqual(rsaObj.u, rsaObj.key.u)
|
||||
|
||||
# Sanity check key data
|
||||
self.assertEqual(rsaObj.n, rsaObj.p * rsaObj.q) # n = pq
|
||||
self.assertEqual(1, rsaObj.d * rsaObj.e % ((rsaObj.p-1) * (rsaObj.q-1))) # ed = 1 (mod (p-1)(q-1))
|
||||
self.assertEqual(1, rsaObj.p * rsaObj.u % rsaObj.q) # pu = 1 (mod q)
|
||||
self.assertEqual(1, rsaObj.p > 1) # p > 1
|
||||
self.assertEqual(1, rsaObj.q > 1) # q > 1
|
||||
self.assertEqual(1, rsaObj.e > 1) # e > 1
|
||||
self.assertEqual(1, rsaObj.d > 1) # d > 1
|
||||
|
||||
def _check_public_key(self, rsaObj):
|
||||
ciphertext = a2b_hex(self.ciphertext)
|
||||
|
||||
# Check capabilities
|
||||
self.assertEqual(0, rsaObj.has_private())
|
||||
self.assertEqual(1, rsaObj.can_sign())
|
||||
self.assertEqual(1, rsaObj.can_encrypt())
|
||||
self.assertEqual(1, rsaObj.can_blind())
|
||||
|
||||
# Check rsaObj.[ne] -> rsaObj.key.[ne] mapping
|
||||
self.assertEqual(rsaObj.n, rsaObj.key.n)
|
||||
self.assertEqual(rsaObj.e, rsaObj.key.e)
|
||||
|
||||
# Check that private parameters are all missing
|
||||
self.assertEqual(0, hasattr(rsaObj, 'd'))
|
||||
self.assertEqual(0, hasattr(rsaObj, 'p'))
|
||||
self.assertEqual(0, hasattr(rsaObj, 'q'))
|
||||
self.assertEqual(0, hasattr(rsaObj, 'u'))
|
||||
self.assertEqual(0, hasattr(rsaObj.key, 'd'))
|
||||
self.assertEqual(0, hasattr(rsaObj.key, 'p'))
|
||||
self.assertEqual(0, hasattr(rsaObj.key, 'q'))
|
||||
self.assertEqual(0, hasattr(rsaObj.key, 'u'))
|
||||
|
||||
# Sanity check key data
|
||||
self.assertEqual(1, rsaObj.e > 1) # e > 1
|
||||
|
||||
# Public keys should not be able to sign or decrypt
|
||||
self.assertRaises(TypeError, rsaObj.sign, ciphertext, b(""))
|
||||
self.assertRaises(TypeError, rsaObj.decrypt, ciphertext)
|
||||
|
||||
# Check __eq__ and __ne__
|
||||
self.assertEqual(rsaObj.publickey() == rsaObj.publickey(),True) # assert_
|
||||
self.assertEqual(rsaObj.publickey() != rsaObj.publickey(),False) # failIf
|
||||
|
||||
def _exercise_primitive(self, rsaObj):
|
||||
# Since we're using a randomly-generated key, we can't check the test
|
||||
# vector, but we can make sure encryption and decryption are inverse
|
||||
# operations.
|
||||
ciphertext = a2b_hex(self.ciphertext)
|
||||
|
||||
# Test decryption
|
||||
plaintext = rsaObj.decrypt((ciphertext,))
|
||||
|
||||
# Test encryption (2 arguments)
|
||||
(new_ciphertext2,) = rsaObj.encrypt(plaintext, b(""))
|
||||
self.assertEqual(b2a_hex(ciphertext), b2a_hex(new_ciphertext2))
|
||||
|
||||
# Test blinded decryption
|
||||
blinding_factor = Random.new().read(len(ciphertext)-1)
|
||||
blinded_ctext = rsaObj.blind(ciphertext, blinding_factor)
|
||||
blinded_ptext = rsaObj.decrypt((blinded_ctext,))
|
||||
unblinded_plaintext = rsaObj.unblind(blinded_ptext, blinding_factor)
|
||||
self.assertEqual(b2a_hex(plaintext), b2a_hex(unblinded_plaintext))
|
||||
|
||||
# Test signing (2 arguments)
|
||||
signature2 = rsaObj.sign(ciphertext, b(""))
|
||||
self.assertEqual((bytes_to_long(plaintext),), signature2)
|
||||
|
||||
# Test verification
|
||||
self.assertEqual(1, rsaObj.verify(ciphertext, (bytes_to_long(plaintext),)))
|
||||
|
||||
def _exercise_public_primitive(self, rsaObj):
|
||||
plaintext = a2b_hex(self.plaintext)
|
||||
|
||||
# Test encryption (2 arguments)
|
||||
(new_ciphertext2,) = rsaObj.encrypt(plaintext, b(""))
|
||||
|
||||
# Exercise verification
|
||||
rsaObj.verify(new_ciphertext2, (bytes_to_long(plaintext),))
|
||||
|
||||
def _check_encryption(self, rsaObj):
|
||||
plaintext = a2b_hex(self.plaintext)
|
||||
ciphertext = a2b_hex(self.ciphertext)
|
||||
|
||||
# Test encryption (2 arguments)
|
||||
(new_ciphertext2,) = rsaObj.encrypt(plaintext, b(""))
|
||||
self.assertEqual(b2a_hex(ciphertext), b2a_hex(new_ciphertext2))
|
||||
|
||||
def _check_decryption(self, rsaObj):
|
||||
plaintext = a2b_hex(self.plaintext)
|
||||
ciphertext = a2b_hex(self.ciphertext)
|
||||
|
||||
# Test plain decryption
|
||||
new_plaintext = rsaObj.decrypt((ciphertext,))
|
||||
self.assertEqual(b2a_hex(plaintext), b2a_hex(new_plaintext))
|
||||
|
||||
# Test blinded decryption
|
||||
blinding_factor = Random.new().read(len(ciphertext)-1)
|
||||
blinded_ctext = rsaObj.blind(ciphertext, blinding_factor)
|
||||
blinded_ptext = rsaObj.decrypt((blinded_ctext,))
|
||||
unblinded_plaintext = rsaObj.unblind(blinded_ptext, blinding_factor)
|
||||
self.assertEqual(b2a_hex(plaintext), b2a_hex(unblinded_plaintext))
|
||||
|
||||
def _check_verification(self, rsaObj):
|
||||
signature = bytes_to_long(a2b_hex(self.plaintext))
|
||||
message = a2b_hex(self.ciphertext)
|
||||
|
||||
# Test verification
|
||||
t = (signature,) # rsaObj.verify expects a tuple
|
||||
self.assertEqual(1, rsaObj.verify(message, t))
|
||||
|
||||
# Test verification with overlong tuple (this is a
|
||||
# backward-compatibility hack to support some harmless misuse of the
|
||||
# API)
|
||||
t2 = (signature, '')
|
||||
self.assertEqual(1, rsaObj.verify(message, t2)) # extra garbage at end of tuple
|
||||
|
||||
def _check_signing(self, rsaObj):
|
||||
signature = bytes_to_long(a2b_hex(self.plaintext))
|
||||
message = a2b_hex(self.ciphertext)
|
||||
|
||||
# Test signing (2 argument)
|
||||
self.assertEqual((signature,), rsaObj.sign(message, b("")))
|
||||
|
||||
class RSAFastMathTest(RSATest):
|
||||
def setUp(self):
|
||||
RSATest.setUp(self)
|
||||
self.rsa = RSA.RSAImplementation(use_fast_math=True)
|
||||
|
||||
def test_generate_1arg(self):
|
||||
"""RSA (_fastmath implementation) generated key (1 argument)"""
|
||||
RSATest.test_generate_1arg(self)
|
||||
|
||||
def test_generate_2arg(self):
|
||||
"""RSA (_fastmath implementation) generated key (2 arguments)"""
|
||||
RSATest.test_generate_2arg(self)
|
||||
|
||||
def test_construct_2tuple(self):
|
||||
"""RSA (_fastmath implementation) constructed key (2-tuple)"""
|
||||
RSATest.test_construct_2tuple(self)
|
||||
|
||||
def test_construct_3tuple(self):
|
||||
"""RSA (_fastmath implementation) constructed key (3-tuple)"""
|
||||
RSATest.test_construct_3tuple(self)
|
||||
|
||||
def test_construct_4tuple(self):
|
||||
"""RSA (_fastmath implementation) constructed key (4-tuple)"""
|
||||
RSATest.test_construct_4tuple(self)
|
||||
|
||||
def test_construct_5tuple(self):
|
||||
"""RSA (_fastmath implementation) constructed key (5-tuple)"""
|
||||
RSATest.test_construct_5tuple(self)
|
||||
|
||||
def test_construct_6tuple(self):
|
||||
"""RSA (_fastmath implementation) constructed key (6-tuple)"""
|
||||
RSATest.test_construct_6tuple(self)
|
||||
|
||||
def test_factoring(self):
|
||||
RSATest.test_factoring(self)
|
||||
|
||||
class RSASlowMathTest(RSATest):
|
||||
def setUp(self):
|
||||
RSATest.setUp(self)
|
||||
self.rsa = RSA.RSAImplementation(use_fast_math=False)
|
||||
|
||||
def test_generate_1arg(self):
|
||||
"""RSA (_slowmath implementation) generated key (1 argument)"""
|
||||
RSATest.test_generate_1arg(self)
|
||||
|
||||
def test_generate_2arg(self):
|
||||
"""RSA (_slowmath implementation) generated key (2 arguments)"""
|
||||
RSATest.test_generate_2arg(self)
|
||||
|
||||
def test_construct_2tuple(self):
|
||||
"""RSA (_slowmath implementation) constructed key (2-tuple)"""
|
||||
RSATest.test_construct_2tuple(self)
|
||||
|
||||
def test_construct_3tuple(self):
|
||||
"""RSA (_slowmath implementation) constructed key (3-tuple)"""
|
||||
RSATest.test_construct_3tuple(self)
|
||||
|
||||
def test_construct_4tuple(self):
|
||||
"""RSA (_slowmath implementation) constructed key (4-tuple)"""
|
||||
RSATest.test_construct_4tuple(self)
|
||||
|
||||
def test_construct_5tuple(self):
|
||||
"""RSA (_slowmath implementation) constructed key (5-tuple)"""
|
||||
RSATest.test_construct_5tuple(self)
|
||||
|
||||
def test_construct_6tuple(self):
|
||||
"""RSA (_slowmath implementation) constructed key (6-tuple)"""
|
||||
RSATest.test_construct_6tuple(self)
|
||||
|
||||
def test_factoring(self):
|
||||
RSATest.test_factoring(self)
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
tests += list_test_cases(RSATest)
|
||||
try:
|
||||
from Crypto.PublicKey import _fastmath
|
||||
tests += list_test_cases(RSAFastMathTest)
|
||||
except ImportError:
|
||||
from distutils.sysconfig import get_config_var
|
||||
import inspect
|
||||
_fm_path = os.path.normpath(os.path.dirname(os.path.abspath(
|
||||
inspect.getfile(inspect.currentframe())))
|
||||
+"/../../PublicKey/_fastmath"+get_config_var("SO"))
|
||||
if os.path.exists(_fm_path):
|
||||
raise ImportError("While the _fastmath module exists, importing "+
|
||||
"it failed. This may point to the gmp or mpir shared library "+
|
||||
"not being in the path. _fastmath was found at "+_fm_path)
|
||||
if config.get('slow_tests',1):
|
||||
tests += list_test_cases(RSASlowMathTest)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
# vim:set ts=4 sw=4 sts=4 expandtab:
|
@@ -1,345 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_importKey.py: Self-test for importing RSA keys
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
from __future__ import nested_scopes
|
||||
|
||||
__revision__ = "$Id$"
|
||||
|
||||
import unittest
|
||||
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.SelfTest.st_common import *
|
||||
from Crypto.Util.py3compat import *
|
||||
from Crypto.Util.number import inverse
|
||||
from Crypto.Util import asn1
|
||||
|
||||
def der2pem(der, text='PUBLIC'):
|
||||
import binascii
|
||||
chunks = [ binascii.b2a_base64(der[i:i+48]) for i in range(0, len(der), 48) ]
|
||||
pem = b('-----BEGIN %s KEY-----\n' % text)
|
||||
pem += b('').join(chunks)
|
||||
pem += b('-----END %s KEY-----' % text)
|
||||
return pem
|
||||
|
||||
class ImportKeyTests(unittest.TestCase):
|
||||
# 512-bit RSA key generated with openssl
|
||||
rsaKeyPEM = u'''-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+TLr7UkvEtFrRhDDKMtuII
|
||||
q19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQJACUSDEp8RTe32ftq8IwG8
|
||||
Wojl5mAd1wFiIOrZ/Uv8b963WJOJiuQcVN29vxU5+My9GPZ7RA3hrDBEAoHUDPrI
|
||||
OQIhAPIPLz4dphiD9imAkivY31Rc5AfHJiQRA7XixTcjEkojAiEAyh/pJHks/Mlr
|
||||
+rdPNEpotBjfV4M4BkgGAA/ipcmaAjcCIQCHvhwwKVBLzzTscT2HeUdEeBMoiXXK
|
||||
JACAr3sJQJGxIQIgarRp+m1WSKV1MciwMaTOnbU7wxFs9DP1pva76lYBzgUCIQC9
|
||||
n0CnZCJ6IZYqSt0H5N7+Q+2Ro64nuwV/OSQfM6sBwQ==
|
||||
-----END RSA PRIVATE KEY-----'''
|
||||
|
||||
# As above, but this is actually an unencrypted PKCS#8 key
|
||||
rsaKeyPEM8 = u'''-----BEGIN PRIVATE KEY-----
|
||||
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvx4nkAqgiyNRGlwS
|
||||
ga5tkzEsPv6RP5MuvtSS8S0WtGEMMoy24girX0WsvilQgzKY8xIsGfeEkt7fQPDj
|
||||
wZAzhQIDAQABAkAJRIMSnxFN7fZ+2rwjAbxaiOXmYB3XAWIg6tn9S/xv3rdYk4mK
|
||||
5BxU3b2/FTn4zL0Y9ntEDeGsMEQCgdQM+sg5AiEA8g8vPh2mGIP2KYCSK9jfVFzk
|
||||
B8cmJBEDteLFNyMSSiMCIQDKH+kkeSz8yWv6t080Smi0GN9XgzgGSAYAD+KlyZoC
|
||||
NwIhAIe+HDApUEvPNOxxPYd5R0R4EyiJdcokAICvewlAkbEhAiBqtGn6bVZIpXUx
|
||||
yLAxpM6dtTvDEWz0M/Wm9rvqVgHOBQIhAL2fQKdkInohlipK3Qfk3v5D7ZGjrie7
|
||||
BX85JB8zqwHB
|
||||
-----END PRIVATE KEY-----'''
|
||||
|
||||
# The same RSA private key as in rsaKeyPEM, but now encrypted
|
||||
rsaKeyEncryptedPEM=(
|
||||
|
||||
# With DES and passphrase 'test'
|
||||
('test', u'''-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-CBC,AF8F9A40BD2FA2FC
|
||||
|
||||
Ckl9ex1kaVEWhYC2QBmfaF+YPiR4NFkRXA7nj3dcnuFEzBnY5XULupqQpQI3qbfA
|
||||
u8GYS7+b3toWWiHZivHbAAUBPDIZG9hKDyB9Sq2VMARGsX1yW1zhNvZLIiVJzUHs
|
||||
C6NxQ1IJWOXzTew/xM2I26kPwHIvadq+/VaT8gLQdjdH0jOiVNaevjWnLgrn1mLP
|
||||
BCNRMdcexozWtAFNNqSzfW58MJL2OdMi21ED184EFytIc1BlB+FZiGZduwKGuaKy
|
||||
9bMbdb/1PSvsSzPsqW7KSSrTw6MgJAFJg6lzIYvR5F4poTVBxwBX3+EyEmShiaNY
|
||||
IRX3TgQI0IjrVuLmvlZKbGWP18FXj7I7k9tSsNOOzllTTdq3ny5vgM3A+ynfAaxp
|
||||
dysKznQ6P+IoqML1WxAID4aGRMWka+uArOJ148Rbj9s=
|
||||
-----END RSA PRIVATE KEY-----''',
|
||||
"\xAF\x8F\x9A\x40\xBD\x2F\xA2\xFC"),
|
||||
|
||||
# With Triple-DES and passphrase 'rocking'
|
||||
('rocking', u'''-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,C05D6C07F7FC02F6
|
||||
|
||||
w4lwQrXaVoTTJ0GgwY566htTA2/t1YlimhxkxYt9AEeCcidS5M0Wq9ClPiPz9O7F
|
||||
m6K5QpM1rxo1RUE/ZyI85gglRNPdNwkeTOqit+kum7nN73AToX17+irVmOA4Z9E+
|
||||
4O07t91GxGMcjUSIFk0ucwEU4jgxRvYscbvOMvNbuZszGdVNzBTVddnShKCsy9i7
|
||||
nJbPlXeEKYi/OkRgO4PtfqqWQu5GIEFVUf9ev1QV7AvC+kyWTR1wWYnHX265jU5c
|
||||
sopxQQtP8XEHIJEdd5/p1oieRcWTCNyY8EkslxDSsrf0OtZp6mZH9N+KU47cgQtt
|
||||
9qGORmlWnsIoFFKcDohbtOaWBTKhkj5h6OkLjFjfU/sBeV1c+7wDT3dAy5tawXjG
|
||||
YSxC7qDQIT/RECvV3+oQKEcmpEujn45wAnkTi12BH30=
|
||||
-----END RSA PRIVATE KEY-----''',
|
||||
"\xC0\x5D\x6C\x07\xF7\xFC\x02\xF6"),
|
||||
)
|
||||
|
||||
rsaPublicKeyPEM = u'''-----BEGIN PUBLIC KEY-----
|
||||
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+T
|
||||
Lr7UkvEtFrRhDDKMtuIIq19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQ==
|
||||
-----END PUBLIC KEY-----'''
|
||||
|
||||
# Obtained using 'ssh-keygen -i -m PKCS8 -f rsaPublicKeyPEM'
|
||||
rsaPublicKeyOpenSSH = '''ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQC/HieQCqCLI1EaXBKBrm2TMSw+/pE/ky6+1JLxLRa0YQwyjLbiCKtfRay+KVCDMpjzEiwZ94SS3t9A8OPBkDOF comment\n'''
|
||||
|
||||
# The private key, in PKCS#1 format encoded with DER
|
||||
rsaKeyDER = a2b_hex(
|
||||
'''3082013b020100024100bf1e27900aa08b23511a5c1281ae6d93312c3efe
|
||||
913f932ebed492f12d16b4610c328cb6e208ab5f45acbe2950833298f312
|
||||
2c19f78492dedf40f0e3c190338502030100010240094483129f114dedf6
|
||||
7edabc2301bc5a88e5e6601dd7016220ead9fd4bfc6fdeb75893898ae41c
|
||||
54ddbdbf1539f8ccbd18f67b440de1ac30440281d40cfac839022100f20f
|
||||
2f3e1da61883f62980922bd8df545ce407c726241103b5e2c53723124a23
|
||||
022100ca1fe924792cfcc96bfab74f344a68b418df578338064806000fe2
|
||||
a5c99a023702210087be1c3029504bcf34ec713d877947447813288975ca
|
||||
240080af7b094091b12102206ab469fa6d5648a57531c8b031a4ce9db53b
|
||||
c3116cf433f5a6f6bbea5601ce05022100bd9f40a764227a21962a4add07
|
||||
e4defe43ed91a3ae27bb057f39241f33ab01c1
|
||||
'''.replace(" ",""))
|
||||
|
||||
# The private key, in unencrypted PKCS#8 format encoded with DER
|
||||
rsaKeyDER8 = a2b_hex(
|
||||
'''30820155020100300d06092a864886f70d01010105000482013f3082013
|
||||
b020100024100bf1e27900aa08b23511a5c1281ae6d93312c3efe913f932
|
||||
ebed492f12d16b4610c328cb6e208ab5f45acbe2950833298f3122c19f78
|
||||
492dedf40f0e3c190338502030100010240094483129f114dedf67edabc2
|
||||
301bc5a88e5e6601dd7016220ead9fd4bfc6fdeb75893898ae41c54ddbdb
|
||||
f1539f8ccbd18f67b440de1ac30440281d40cfac839022100f20f2f3e1da
|
||||
61883f62980922bd8df545ce407c726241103b5e2c53723124a23022100c
|
||||
a1fe924792cfcc96bfab74f344a68b418df578338064806000fe2a5c99a0
|
||||
23702210087be1c3029504bcf34ec713d877947447813288975ca240080a
|
||||
f7b094091b12102206ab469fa6d5648a57531c8b031a4ce9db53bc3116cf
|
||||
433f5a6f6bbea5601ce05022100bd9f40a764227a21962a4add07e4defe4
|
||||
3ed91a3ae27bb057f39241f33ab01c1
|
||||
'''.replace(" ",""))
|
||||
|
||||
rsaPublicKeyDER = a2b_hex(
|
||||
'''305c300d06092a864886f70d0101010500034b003048024100bf1e27900a
|
||||
a08b23511a5c1281ae6d93312c3efe913f932ebed492f12d16b4610c328c
|
||||
b6e208ab5f45acbe2950833298f3122c19f78492dedf40f0e3c190338502
|
||||
03010001
|
||||
'''.replace(" ",""))
|
||||
|
||||
n = long('BF 1E 27 90 0A A0 8B 23 51 1A 5C 12 81 AE 6D 93 31 2C 3E FE 91 3F 93 2E BE D4 92 F1 2D 16 B4 61 0C 32 8C B6 E2 08 AB 5F 45 AC BE 29 50 83 32 98 F3 12 2C 19 F7 84 92 DE DF 40 F0 E3 C1 90 33 85'.replace(" ",""),16)
|
||||
e = 65537L
|
||||
d = long('09 44 83 12 9F 11 4D ED F6 7E DA BC 23 01 BC 5A 88 E5 E6 60 1D D7 01 62 20 EA D9 FD 4B FC 6F DE B7 58 93 89 8A E4 1C 54 DD BD BF 15 39 F8 CC BD 18 F6 7B 44 0D E1 AC 30 44 02 81 D4 0C FA C8 39'.replace(" ",""),16)
|
||||
p = long('00 F2 0F 2F 3E 1D A6 18 83 F6 29 80 92 2B D8 DF 54 5C E4 07 C7 26 24 11 03 B5 E2 C5 37 23 12 4A 23'.replace(" ",""),16)
|
||||
q = long('00 CA 1F E9 24 79 2C FC C9 6B FA B7 4F 34 4A 68 B4 18 DF 57 83 38 06 48 06 00 0F E2 A5 C9 9A 02 37'.replace(" ",""),16)
|
||||
|
||||
# This is q^{-1} mod p). fastmath and slowmath use pInv (p^{-1}
|
||||
# mod q) instead!
|
||||
qInv = long('00 BD 9F 40 A7 64 22 7A 21 96 2A 4A DD 07 E4 DE FE 43 ED 91 A3 AE 27 BB 05 7F 39 24 1F 33 AB 01 C1'.replace(" ",""),16)
|
||||
pInv = inverse(p,q)
|
||||
|
||||
def testImportKey1(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE"""
|
||||
key = self.rsa.importKey(self.rsaKeyDER)
|
||||
self.failUnless(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey2(self):
|
||||
"""Verify import of SubjectPublicKeyInfo DER SEQUENCE"""
|
||||
key = self.rsa.importKey(self.rsaPublicKeyDER)
|
||||
self.failIf(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey3unicode(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as unicode"""
|
||||
key = RSA.importKey(self.rsaKeyPEM)
|
||||
self.assertEqual(key.has_private(),True) # assert_
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey3bytes(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as byte string"""
|
||||
key = RSA.importKey(b(self.rsaKeyPEM))
|
||||
self.assertEqual(key.has_private(),True) # assert_
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey4unicode(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as unicode"""
|
||||
key = RSA.importKey(self.rsaPublicKeyPEM)
|
||||
self.assertEqual(key.has_private(),False) # failIf
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey4bytes(self):
|
||||
"""Verify import of SubjectPublicKeyInfo DER SEQUENCE, encoded with PEM as byte string"""
|
||||
key = RSA.importKey(b(self.rsaPublicKeyPEM))
|
||||
self.assertEqual(key.has_private(),False) # failIf
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey5(self):
|
||||
"""Verifies that the imported key is still a valid RSA pair"""
|
||||
key = RSA.importKey(self.rsaKeyPEM)
|
||||
idem = key.encrypt(key.decrypt(b("Test")),0)
|
||||
self.assertEqual(idem[0],b("Test"))
|
||||
|
||||
def testImportKey6(self):
|
||||
"""Verifies that the imported key is still a valid RSA pair"""
|
||||
key = RSA.importKey(self.rsaKeyDER)
|
||||
idem = key.encrypt(key.decrypt(b("Test")),0)
|
||||
self.assertEqual(idem[0],b("Test"))
|
||||
|
||||
def testImportKey7(self):
|
||||
"""Verify import of OpenSSH public key"""
|
||||
key = self.rsa.importKey(self.rsaPublicKeyOpenSSH)
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey8(self):
|
||||
"""Verify import of encrypted PrivateKeyInfo DER SEQUENCE"""
|
||||
for t in self.rsaKeyEncryptedPEM:
|
||||
key = self.rsa.importKey(t[1], t[0])
|
||||
self.failUnless(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey9(self):
|
||||
"""Verify import of unencrypted PrivateKeyInfo DER SEQUENCE"""
|
||||
key = self.rsa.importKey(self.rsaKeyDER8)
|
||||
self.failUnless(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey10(self):
|
||||
"""Verify import of unencrypted PrivateKeyInfo DER SEQUENCE, encoded with PEM"""
|
||||
key = self.rsa.importKey(self.rsaKeyPEM8)
|
||||
self.failUnless(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey11(self):
|
||||
"""Verify import of RSAPublicKey DER SEQUENCE"""
|
||||
der = asn1.DerSequence([17, 3]).encode()
|
||||
key = self.rsa.importKey(der)
|
||||
self.assertEqual(key.n, 17)
|
||||
self.assertEqual(key.e, 3)
|
||||
|
||||
def testImportKey12(self):
|
||||
"""Verify import of RSAPublicKey DER SEQUENCE, encoded with PEM"""
|
||||
der = asn1.DerSequence([17, 3]).encode()
|
||||
pem = der2pem(der)
|
||||
key = self.rsa.importKey(pem)
|
||||
self.assertEqual(key.n, 17)
|
||||
self.assertEqual(key.e, 3)
|
||||
|
||||
###
|
||||
def testExportKey1(self):
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
derKey = key.exportKey("DER")
|
||||
self.assertEqual(derKey, self.rsaKeyDER)
|
||||
|
||||
def testExportKey2(self):
|
||||
key = self.rsa.construct([self.n, self.e])
|
||||
derKey = key.exportKey("DER")
|
||||
self.assertEqual(derKey, self.rsaPublicKeyDER)
|
||||
|
||||
def testExportKey3(self):
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
pemKey = key.exportKey("PEM")
|
||||
self.assertEqual(pemKey, b(self.rsaKeyPEM))
|
||||
|
||||
def testExportKey4(self):
|
||||
key = self.rsa.construct([self.n, self.e])
|
||||
pemKey = key.exportKey("PEM")
|
||||
self.assertEqual(pemKey, b(self.rsaPublicKeyPEM))
|
||||
|
||||
def testExportKey5(self):
|
||||
key = self.rsa.construct([self.n, self.e])
|
||||
openssh_1 = key.exportKey("OpenSSH").split()
|
||||
openssh_2 = self.rsaPublicKeyOpenSSH.split()
|
||||
self.assertEqual(openssh_1[0], openssh_2[0])
|
||||
self.assertEqual(openssh_1[1], openssh_2[1])
|
||||
|
||||
def testExportKey4(self):
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
# Tuple with index #1 is encrypted with 3DES
|
||||
t = map(b,self.rsaKeyEncryptedPEM[1])
|
||||
# Force the salt being used when exporting
|
||||
key._randfunc = lambda N: (t[2]*divmod(N+len(t[2]),len(t[2]))[0])[:N]
|
||||
pemKey = key.exportKey("PEM", t[0])
|
||||
self.assertEqual(pemKey, t[1])
|
||||
|
||||
def testExportKey5(self):
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
derKey = key.exportKey("DER", pkcs=8)
|
||||
self.assertEqual(derKey, self.rsaKeyDER8)
|
||||
|
||||
def testExportKey6(self):
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
pemKey = key.exportKey("PEM", pkcs=8)
|
||||
self.assertEqual(pemKey, b(self.rsaKeyPEM8))
|
||||
|
||||
class ImportKeyTestsSlow(ImportKeyTests):
|
||||
def setUp(self):
|
||||
self.rsa = RSA.RSAImplementation(use_fast_math=0)
|
||||
|
||||
class ImportKeyTestsFast(ImportKeyTests):
|
||||
def setUp(self):
|
||||
self.rsa = RSA.RSAImplementation(use_fast_math=1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
try:
|
||||
from Crypto.PublicKey import _fastmath
|
||||
tests += list_test_cases(ImportKeyTestsFast)
|
||||
except ImportError:
|
||||
pass
|
||||
tests += list_test_cases(ImportKeyTestsSlow)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
# vim:set ts=4 sw=4 sts=4 expandtab:
|
@@ -1,389 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_import_DSA.py: Self-test for importing DSA keys
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
import unittest
|
||||
|
||||
from Crypto.PublicKey import DSA, KeyFormatError
|
||||
from Crypto.SelfTest.st_common import *
|
||||
from Crypto.Util.py3compat import *
|
||||
|
||||
from binascii import unhexlify
|
||||
|
||||
class ImportKeyTests(unittest.TestCase):
|
||||
|
||||
y = 92137165128186062214622779787483327510946462589285775188003362705875131352591574106484271700740858696583623951844732128165434284507709057439633739849986759064015013893156866539696757799934634945787496920169462601722830899660681779448742875054459716726855443681559131362852474817534616736104831095601710736729L
|
||||
p = 162452170958135306109773853318304545923250830605675936228618290525164105310663722368377131295055868997377338797580997938253236213714988311430600065853662861806894003694743806769284131194035848116051021923956699231855223389086646903420682639786976554552864568460372266462812137447840653688476258666833303658691L
|
||||
q = 988791743931120302950649732173330531512663554851L
|
||||
g = 85583152299197514738065570254868711517748965097380456700369348466136657764813442044039878840094809620913085570225318356734366886985903212775602770761953571967834823306046501307810937486758039063386311593890777319935391363872375452381836756832784184928202587843258855704771836753434368484556809100537243908232L
|
||||
x = 540873410045082450874416847965843801027716145253L
|
||||
|
||||
def setUp(self):
|
||||
|
||||
# It is easier to write test vectors in text form,
|
||||
# and convert them to byte strigs dynamically here
|
||||
for mname, mvalue in ImportKeyTests.__dict__.items():
|
||||
if mname[:4] in ('der_', 'pem_', 'ssh_'):
|
||||
if mname[:4] == 'der_':
|
||||
mvalue = unhexlify(tobytes(mvalue))
|
||||
mvalue = tobytes(mvalue)
|
||||
setattr(self, mname, mvalue)
|
||||
|
||||
# 1. SubjectPublicKeyInfo
|
||||
der_public=\
|
||||
'308201b73082012b06072a8648ce3804013082011e02818100e756ee1717f4b6'+\
|
||||
'794c7c214724a19763742c45572b4b3f8ff3b44f3be9f44ce039a2757695ec91'+\
|
||||
'5697da74ef914fcd1b05660e2419c761d639f45d2d79b802dbd23e7ab8b81b47'+\
|
||||
'9a380e1f30932584ba2a0b955032342ebc83cb5ca906e7b0d7cd6fe656cecb4c'+\
|
||||
'8b5a77123a8c6750a481e3b06057aff6aa6eba620b832d60c3021500ad32f48c'+\
|
||||
'd3ae0c45a198a61fa4b5e20320763b2302818079dfdc3d614fe635fceb7eaeae'+\
|
||||
'3718dc2efefb45282993ac6749dc83c223d8c1887296316b3b0b54466cf444f3'+\
|
||||
'4b82e3554d0b90a778faaf1306f025dae6a3e36c7f93dd5bac4052b92370040a'+\
|
||||
'ca70b8d5820599711900efbc961812c355dd9beffe0981da85c5548074b41c56'+\
|
||||
'ae43fd300d89262e4efd89943f99a651b03888038185000281810083352a69a1'+\
|
||||
'32f34843d2a0eb995bff4e2f083a73f0049d2c91ea2f0ce43d144abda48199e4'+\
|
||||
'b003c570a8af83303d45105f606c5c48d925a40ed9c2630c2fa4cdbf838539de'+\
|
||||
'b9a29f919085f2046369f627ca84b2cb1e2c7940564b670f963ab1164d4e2ca2'+\
|
||||
'bf6ffd39f12f548928bf4d2d1b5e6980b4f1be4c92a91986fba559'
|
||||
|
||||
def testImportKey1(self):
|
||||
key_obj = self.dsa.importKey(self.der_public)
|
||||
self.failIf(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.key.y)
|
||||
self.assertEqual(self.p, key_obj.key.p)
|
||||
self.assertEqual(self.q, key_obj.key.q)
|
||||
self.assertEqual(self.g, key_obj.key.g)
|
||||
|
||||
def testExportKey1(self):
|
||||
tup = (self.y, self.g, self.p, self.q)
|
||||
key = self.dsa.construct(tup)
|
||||
encoded = key.exportKey('DER')
|
||||
self.assertEqual(self.der_public, encoded)
|
||||
|
||||
# 2.
|
||||
pem_public="""\
|
||||
-----BEGIN DSA PUBLIC KEY-----
|
||||
MIIBtzCCASsGByqGSM44BAEwggEeAoGBAOdW7hcX9LZ5THwhRyShl2N0LEVXK0s/
|
||||
j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4uBtH
|
||||
mjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47BgV6/2
|
||||
qm66YguDLWDDAhUArTL0jNOuDEWhmKYfpLXiAyB2OyMCgYB539w9YU/mNfzrfq6u
|
||||
NxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG8CXa
|
||||
5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0tBxW
|
||||
rkP9MA2JJi5O/YmUP5mmUbA4iAOBhQACgYEAgzUqaaEy80hD0qDrmVv/Ti8IOnPw
|
||||
BJ0skeovDOQ9FEq9pIGZ5LADxXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTne
|
||||
uaKfkZCF8gRjafYnyoSyyx4seUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmA
|
||||
tPG+TJKpGYb7pVk=
|
||||
-----END DSA PUBLIC KEY-----"""
|
||||
|
||||
def testImportKey2(self):
|
||||
for pem in (self.pem_public, tostr(self.pem_public)):
|
||||
key_obj = self.dsa.importKey(pem)
|
||||
self.failIf(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.key.y)
|
||||
self.assertEqual(self.p, key_obj.key.p)
|
||||
self.assertEqual(self.q, key_obj.key.q)
|
||||
self.assertEqual(self.g, key_obj.key.g)
|
||||
|
||||
def testExportKey2(self):
|
||||
tup = (self.y, self.g, self.p, self.q)
|
||||
key = self.dsa.construct(tup)
|
||||
encoded = key.exportKey('PEM')
|
||||
self.assertEqual(self.pem_public, encoded)
|
||||
|
||||
# 3. OpenSSL/OpenSSH format
|
||||
der_private=\
|
||||
'308201bb02010002818100e756ee1717f4b6794c7c214724a19763742c45572b'+\
|
||||
'4b3f8ff3b44f3be9f44ce039a2757695ec915697da74ef914fcd1b05660e2419'+\
|
||||
'c761d639f45d2d79b802dbd23e7ab8b81b479a380e1f30932584ba2a0b955032'+\
|
||||
'342ebc83cb5ca906e7b0d7cd6fe656cecb4c8b5a77123a8c6750a481e3b06057'+\
|
||||
'aff6aa6eba620b832d60c3021500ad32f48cd3ae0c45a198a61fa4b5e2032076'+\
|
||||
'3b2302818079dfdc3d614fe635fceb7eaeae3718dc2efefb45282993ac6749dc'+\
|
||||
'83c223d8c1887296316b3b0b54466cf444f34b82e3554d0b90a778faaf1306f0'+\
|
||||
'25dae6a3e36c7f93dd5bac4052b92370040aca70b8d5820599711900efbc9618'+\
|
||||
'12c355dd9beffe0981da85c5548074b41c56ae43fd300d89262e4efd89943f99'+\
|
||||
'a651b038880281810083352a69a132f34843d2a0eb995bff4e2f083a73f0049d'+\
|
||||
'2c91ea2f0ce43d144abda48199e4b003c570a8af83303d45105f606c5c48d925'+\
|
||||
'a40ed9c2630c2fa4cdbf838539deb9a29f919085f2046369f627ca84b2cb1e2c'+\
|
||||
'7940564b670f963ab1164d4e2ca2bf6ffd39f12f548928bf4d2d1b5e6980b4f1'+\
|
||||
'be4c92a91986fba55902145ebd9a3f0b82069d98420986b314215025756065'
|
||||
|
||||
def testImportKey3(self):
|
||||
key_obj = self.dsa.importKey(self.der_private)
|
||||
self.failUnless(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.key.y)
|
||||
self.assertEqual(self.p, key_obj.key.p)
|
||||
self.assertEqual(self.q, key_obj.key.q)
|
||||
self.assertEqual(self.g, key_obj.key.g)
|
||||
self.assertEqual(self.x, key_obj.key.x)
|
||||
|
||||
def testExportKey3(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = self.dsa.construct(tup)
|
||||
encoded = key.exportKey('DER', pkcs8=False)
|
||||
self.assertEqual(self.der_private, encoded)
|
||||
|
||||
# 4.
|
||||
pem_private="""\
|
||||
-----BEGIN DSA PRIVATE KEY-----
|
||||
MIIBuwIBAAKBgQDnVu4XF/S2eUx8IUckoZdjdCxFVytLP4/ztE876fRM4DmidXaV
|
||||
7JFWl9p075FPzRsFZg4kGcdh1jn0XS15uALb0j56uLgbR5o4Dh8wkyWEuioLlVAy
|
||||
NC68g8tcqQbnsNfNb+ZWzstMi1p3EjqMZ1CkgeOwYFev9qpuumILgy1gwwIVAK0y
|
||||
9IzTrgxFoZimH6S14gMgdjsjAoGAed/cPWFP5jX8636urjcY3C7++0UoKZOsZ0nc
|
||||
g8Ij2MGIcpYxazsLVEZs9ETzS4LjVU0LkKd4+q8TBvAl2uaj42x/k91brEBSuSNw
|
||||
BArKcLjVggWZcRkA77yWGBLDVd2b7/4JgdqFxVSAdLQcVq5D/TANiSYuTv2JlD+Z
|
||||
plGwOIgCgYEAgzUqaaEy80hD0qDrmVv/Ti8IOnPwBJ0skeovDOQ9FEq9pIGZ5LAD
|
||||
xXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTneuaKfkZCF8gRjafYnyoSyyx4s
|
||||
eUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmAtPG+TJKpGYb7pVkCFF69mj8L
|
||||
ggadmEIJhrMUIVAldWBl
|
||||
-----END DSA PRIVATE KEY-----"""
|
||||
|
||||
def testImportKey4(self):
|
||||
for pem in (self.pem_private, tostr(self.pem_private)):
|
||||
key_obj = self.dsa.importKey(pem)
|
||||
self.failUnless(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.key.y)
|
||||
self.assertEqual(self.p, key_obj.key.p)
|
||||
self.assertEqual(self.q, key_obj.key.q)
|
||||
self.assertEqual(self.g, key_obj.key.g)
|
||||
self.assertEqual(self.x, key_obj.key.x)
|
||||
|
||||
def testExportKey4(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = self.dsa.construct(tup)
|
||||
encoded = key.exportKey('PEM', pkcs8=False)
|
||||
self.assertEqual(self.pem_private, encoded)
|
||||
|
||||
# 5. PKCS8 (unencrypted)
|
||||
der_pkcs8=\
|
||||
'3082014a0201003082012b06072a8648ce3804013082011e02818100e756ee17'+\
|
||||
'17f4b6794c7c214724a19763742c45572b4b3f8ff3b44f3be9f44ce039a27576'+\
|
||||
'95ec915697da74ef914fcd1b05660e2419c761d639f45d2d79b802dbd23e7ab8'+\
|
||||
'b81b479a380e1f30932584ba2a0b955032342ebc83cb5ca906e7b0d7cd6fe656'+\
|
||||
'cecb4c8b5a77123a8c6750a481e3b06057aff6aa6eba620b832d60c3021500ad'+\
|
||||
'32f48cd3ae0c45a198a61fa4b5e20320763b2302818079dfdc3d614fe635fceb'+\
|
||||
'7eaeae3718dc2efefb45282993ac6749dc83c223d8c1887296316b3b0b54466c'+\
|
||||
'f444f34b82e3554d0b90a778faaf1306f025dae6a3e36c7f93dd5bac4052b923'+\
|
||||
'70040aca70b8d5820599711900efbc961812c355dd9beffe0981da85c5548074'+\
|
||||
'b41c56ae43fd300d89262e4efd89943f99a651b03888041602145ebd9a3f0b82'+\
|
||||
'069d98420986b314215025756065'
|
||||
|
||||
def testImportKey5(self):
|
||||
key_obj = self.dsa.importKey(self.der_pkcs8)
|
||||
self.failUnless(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.key.y)
|
||||
self.assertEqual(self.p, key_obj.key.p)
|
||||
self.assertEqual(self.q, key_obj.key.q)
|
||||
self.assertEqual(self.g, key_obj.key.g)
|
||||
self.assertEqual(self.x, key_obj.key.x)
|
||||
|
||||
def testExportKey5(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = self.dsa.construct(tup)
|
||||
encoded = key.exportKey('DER')
|
||||
self.assertEqual(self.der_pkcs8, encoded)
|
||||
encoded = key.exportKey('DER', pkcs8=True)
|
||||
self.assertEqual(self.der_pkcs8, encoded)
|
||||
|
||||
# 6.
|
||||
pem_pkcs8="""\
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBAOdW7hcX9LZ5THwhRyShl2N0LEVX
|
||||
K0s/j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4
|
||||
uBtHmjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47Bg
|
||||
V6/2qm66YguDLWDDAhUArTL0jNOuDEWhmKYfpLXiAyB2OyMCgYB539w9YU/mNfzr
|
||||
fq6uNxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG
|
||||
8CXa5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0
|
||||
tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAQWAhRevZo/C4IGnZhCCYazFCFQJXVgZQ==
|
||||
-----END PRIVATE KEY-----"""
|
||||
|
||||
def testImportKey6(self):
|
||||
for pem in (self.pem_pkcs8, tostr(self.pem_pkcs8)):
|
||||
key_obj = self.dsa.importKey(pem)
|
||||
self.failUnless(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.key.y)
|
||||
self.assertEqual(self.p, key_obj.key.p)
|
||||
self.assertEqual(self.q, key_obj.key.q)
|
||||
self.assertEqual(self.g, key_obj.key.g)
|
||||
self.assertEqual(self.x, key_obj.key.x)
|
||||
|
||||
def testExportKey6(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = self.dsa.construct(tup)
|
||||
encoded = key.exportKey('PEM')
|
||||
self.assertEqual(self.pem_pkcs8, encoded)
|
||||
encoded = key.exportKey('PEM', pkcs8=True)
|
||||
self.assertEqual(self.pem_pkcs8, encoded)
|
||||
|
||||
# 7. OpenSSH/RFC4253
|
||||
ssh_pub="""ssh-dss AAAAB3NzaC1kc3MAAACBAOdW7hcX9LZ5THwhRyShl2N0LEVXK0s/j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4uBtHmjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47BgV6/2qm66YguDLWDDAAAAFQCtMvSM064MRaGYph+kteIDIHY7IwAAAIB539w9YU/mNfzrfq6uNxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG8CXa5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAAAAIEAgzUqaaEy80hD0qDrmVv/Ti8IOnPwBJ0skeovDOQ9FEq9pIGZ5LADxXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTneuaKfkZCF8gRjafYnyoSyyx4seUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmAtPG+TJKpGYb7pVk="""
|
||||
|
||||
def testImportKey7(self):
|
||||
for ssh in (self.ssh_pub, tostr(self.ssh_pub)):
|
||||
key_obj = self.dsa.importKey(ssh)
|
||||
self.failIf(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.key.y)
|
||||
self.assertEqual(self.p, key_obj.key.p)
|
||||
self.assertEqual(self.q, key_obj.key.q)
|
||||
self.assertEqual(self.g, key_obj.key.g)
|
||||
|
||||
def testExportKey7(self):
|
||||
tup = (self.y, self.g, self.p, self.q)
|
||||
key = self.dsa.construct(tup)
|
||||
encoded = key.exportKey('OpenSSH')
|
||||
self.assertEqual(self.ssh_pub, encoded)
|
||||
|
||||
# 8. Encrypted OpenSSL/OpenSSH
|
||||
pem_private_encrypted="""\
|
||||
-----BEGIN DSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,70B6908939D65E9F2EB999E8729788CE
|
||||
|
||||
4V6GHRDpCrdZ8MBjbyp5AlGUrjvr2Pn2e2zVxy5RBt4FBj9/pa0ae0nnyUPMLSUU
|
||||
kKyOR0topRYTVRLElm4qVrb5uNZ3hRwfbklr+pSrB7O9eHz9V5sfOQxyODS07JxK
|
||||
k1OdOs70/ouMXLF9EWfAZOmWUccZKHNblUwg1p1UrZIz5jXw4dUE/zqhvXh6d+iC
|
||||
ADsICaBCjCrRQJKDp50h3+ndQjkYBKVH+pj8TiQ79U7lAvdp3+iMghQN6YXs9mdI
|
||||
gFpWw/f97oWM4GHZFqHJ+VSMNFjBiFhAvYV587d7Lk4dhD8sCfbxj42PnfRgUItc
|
||||
nnPqHxmhMQozBWzYM4mQuo3XbF2WlsNFbOzFVyGhw1Bx1s91qvXBVWJh2ozrW0s6
|
||||
HYDV7ZkcTml/4kjA/d+mve6LZ8kuuR1qCiZx6rkffhh1gDN/1Xz3HVvIy/dQ+h9s
|
||||
5zp7PwUoWbhqp3WCOr156P6gR8qo7OlT6wMh33FSXK/mxikHK136fV2shwTKQVII
|
||||
rJBvXpj8nACUmi7scKuTWGeUoXa+dwTZVVe+b+L2U1ZM7+h/neTJiXn7u99PFUwu
|
||||
xVJtxaV37m3aXxtCsPnbBg==
|
||||
-----END DSA PRIVATE KEY-----"""
|
||||
|
||||
def testImportKey8(self):
|
||||
for pem in (self.pem_private_encrypted, tostr(self.pem_private_encrypted)):
|
||||
key_obj = self.dsa.importKey(pem, "PWDTEST")
|
||||
self.failUnless(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.key.y)
|
||||
self.assertEqual(self.p, key_obj.key.p)
|
||||
self.assertEqual(self.q, key_obj.key.q)
|
||||
self.assertEqual(self.g, key_obj.key.g)
|
||||
self.assertEqual(self.x, key_obj.key.x)
|
||||
|
||||
def testExportKey8(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = self.dsa.construct(tup)
|
||||
encoded = key.exportKey('PEM', pkcs8=False, passphrase="PWDTEST")
|
||||
key = self.dsa.importKey(encoded, "PWDTEST")
|
||||
self.assertEqual(self.y, key.key.y)
|
||||
self.assertEqual(self.p, key.key.p)
|
||||
self.assertEqual(self.q, key.key.q)
|
||||
self.assertEqual(self.g, key.key.g)
|
||||
self.assertEqual(self.x, key.key.x)
|
||||
|
||||
# 9. Encrypted PKCS8
|
||||
# pbeWithMD5AndDES-CBC
|
||||
pem_pkcs8_encrypted="""\
|
||||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBcTAbBgkqhkiG9w0BBQMwDgQI0GC3BJ/jSw8CAggABIIBUHc1cXZpExIE9tC7
|
||||
7ryiW+5ihtF2Ekurq3e408GYSAu5smJjN2bvQXmzRFBz8W38K8eMf1sbWroZ4+zn
|
||||
kZSbb9nSm5kAa8lR2+oF2k+WRswMR/PTC3f/D9STO2X0QxdrzKgIHEcSGSHp5jTx
|
||||
aVvbkCDHo9vhBTl6S3ogZ48As/MEro76+9igUwJ1jNhIQZPJ7e20QH5qDpQFFJN4
|
||||
CKl2ENSEuwGiqBszItFy4dqH0g63ZGZV/xt9wSO9Rd7SK/EbA/dklOxBa5Y/VItM
|
||||
gnIhs9XDMoGYyn6F023EicNJm6g/bVQk81BTTma4tm+12TKGdYm+QkeZvCOMZylr
|
||||
Wv67cKwO3cAXt5C3QXMDgYR64XvuaT5h7C0igMp2afSXJlnbHEbFxQVJlv83T4FM
|
||||
eZ4k+NQDbEL8GiHmFxzDWQAuPPZKJWEEEV2p/To+WOh+kSDHQw==
|
||||
-----END ENCRYPTED PRIVATE KEY-----"""
|
||||
|
||||
def testImportKey9(self):
|
||||
for pem in (self.pem_pkcs8_encrypted, tostr(self.pem_pkcs8_encrypted)):
|
||||
key_obj = self.dsa.importKey(pem, "PWDTEST")
|
||||
self.failUnless(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.key.y)
|
||||
self.assertEqual(self.p, key_obj.key.p)
|
||||
self.assertEqual(self.q, key_obj.key.q)
|
||||
self.assertEqual(self.g, key_obj.key.g)
|
||||
self.assertEqual(self.x, key_obj.key.x)
|
||||
|
||||
# 10. Encrypted PKCS8
|
||||
# pkcs5PBES2 /
|
||||
# pkcs5PBKDF2 (rounds=1000, salt=D725BF1B6B8239F4) /
|
||||
# des-EDE3-CBC (iv=27A1C66C42AFEECE)
|
||||
#
|
||||
der_pkcs8_encrypted=\
|
||||
'30820196304006092a864886f70d01050d3033301b06092a864886f70d01050c'+\
|
||||
'300e0408d725bf1b6b8239f4020203e8301406082a864886f70d0307040827a1'+\
|
||||
'c66c42afeece048201505cacfde7bf8edabb3e0d387950dc872662ea7e9b1ed4'+\
|
||||
'400d2e7e6186284b64668d8d0328c33a9d9397e6f03df7cb68268b0a06b4e22f'+\
|
||||
'7d132821449ecf998a8b696dbc6dd2b19e66d7eb2edfeb4153c1771d49702395'+\
|
||||
'4f36072868b5fcccf93413a5ac4b2eb47d4b3f681c6bd67ae363ed776f45ae47'+\
|
||||
'174a00098a7c930a50f820b227ddf50f9742d8e950d02586ff2dac0e3c372248'+\
|
||||
'e5f9b6a7a02f4004f20c87913e0f7b52bccc209b95d478256a890b31d4c9adec'+\
|
||||
'21a4d157a179a93a3dad06f94f3ce486b46dfa7fc15fd852dd7680bbb2f17478'+\
|
||||
'7e71bd8dbaf81eca7518d76c1d26256e95424864ba45ca5d47d7c5a421be02fa'+\
|
||||
'b94ab01e18593f66cf9094eb5c94b9ecf3aa08b854a195cf87612fbe5e96c426'+\
|
||||
'2b0d573e52dc71ba3f5e468c601e816c49b7d32c698b22175e89aaef0c443770'+\
|
||||
'5ef2f88a116d99d8e2869a4fd09a771b84b49e4ccb79aadcb1c9'
|
||||
|
||||
def testImportKey10(self):
|
||||
key_obj = self.dsa.importKey(self.der_pkcs8_encrypted, "PWDTEST")
|
||||
self.failUnless(key_obj.has_private())
|
||||
self.assertEqual(self.y, key_obj.key.y)
|
||||
self.assertEqual(self.p, key_obj.key.p)
|
||||
self.assertEqual(self.q, key_obj.key.q)
|
||||
self.assertEqual(self.g, key_obj.key.g)
|
||||
self.assertEqual(self.x, key_obj.key.x)
|
||||
|
||||
def testExportKey10(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = self.dsa.construct(tup)
|
||||
randfunc = BytesIO(unhexlify(b("27A1C66C42AFEECE") + b("D725BF1B6B8239F4"))).read
|
||||
key._randfunc = randfunc
|
||||
encoded = key.exportKey('DER', pkcs8=True, passphrase="PWDTEST")
|
||||
self.assertEqual(self.der_pkcs8_encrypted, encoded)
|
||||
|
||||
# ----
|
||||
|
||||
def testImportError1(self):
|
||||
self.assertRaises(KeyFormatError, self.dsa.importKey, self.der_pkcs8_encrypted, "wrongpwd")
|
||||
|
||||
def testExportError2(self):
|
||||
tup = (self.y, self.g, self.p, self.q, self.x)
|
||||
key = self.dsa.construct(tup)
|
||||
self.assertRaises(ValueError, key.exportKey, 'DER', pkcs8=False, passphrase="PWDTEST")
|
||||
|
||||
class ImportKeyTestsSlow(ImportKeyTests):
|
||||
def setUp(self):
|
||||
ImportKeyTests.setUp(self)
|
||||
self.dsa = DSA.DSAImplementation(use_fast_math=0)
|
||||
|
||||
class ImportKeyTestsFast(ImportKeyTests):
|
||||
def setUp(self):
|
||||
ImportKeyTests.setUp(self)
|
||||
self.dsa = DSA.DSAImplementation(use_fast_math=1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
try:
|
||||
from Crypto.PublicKey import _fastmath
|
||||
tests += list_test_cases(ImportKeyTestsFast)
|
||||
except ImportError:
|
||||
pass
|
||||
tests += list_test_cases(ImportKeyTestsSlow)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
@@ -1,404 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SelfTest/PublicKey/test_importKey.py: Self-test for importing RSA keys
|
||||
#
|
||||
# ===================================================================
|
||||
# The contents of this file are dedicated to the public domain. To
|
||||
# the extent that dedication to the public domain is not available,
|
||||
# everyone is granted a worldwide, perpetual, royalty-free,
|
||||
# non-exclusive license to exercise all rights associated with the
|
||||
# contents of this file for any purpose whatsoever.
|
||||
# No rights are reserved.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# ===================================================================
|
||||
|
||||
from __future__ import nested_scopes
|
||||
|
||||
__revision__ = "$Id$"
|
||||
|
||||
import unittest
|
||||
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.SelfTest.st_common import *
|
||||
from Crypto.Util.py3compat import *
|
||||
from Crypto.Util.number import inverse
|
||||
from Crypto.Util import asn1
|
||||
|
||||
def der2pem(der, text='PUBLIC'):
|
||||
import binascii
|
||||
chunks = [ binascii.b2a_base64(der[i:i+48]) for i in range(0, len(der), 48) ]
|
||||
pem = b('-----BEGIN %s KEY-----\n' % text)
|
||||
pem += b('').join(chunks)
|
||||
pem += b('-----END %s KEY-----' % text)
|
||||
return pem
|
||||
|
||||
class ImportKeyTests(unittest.TestCase):
|
||||
# 512-bit RSA key generated with openssl
|
||||
rsaKeyPEM = u'''-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIBOwIBAAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+TLr7UkvEtFrRhDDKMtuII
|
||||
q19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQJACUSDEp8RTe32ftq8IwG8
|
||||
Wojl5mAd1wFiIOrZ/Uv8b963WJOJiuQcVN29vxU5+My9GPZ7RA3hrDBEAoHUDPrI
|
||||
OQIhAPIPLz4dphiD9imAkivY31Rc5AfHJiQRA7XixTcjEkojAiEAyh/pJHks/Mlr
|
||||
+rdPNEpotBjfV4M4BkgGAA/ipcmaAjcCIQCHvhwwKVBLzzTscT2HeUdEeBMoiXXK
|
||||
JACAr3sJQJGxIQIgarRp+m1WSKV1MciwMaTOnbU7wxFs9DP1pva76lYBzgUCIQC9
|
||||
n0CnZCJ6IZYqSt0H5N7+Q+2Ro64nuwV/OSQfM6sBwQ==
|
||||
-----END RSA PRIVATE KEY-----'''
|
||||
|
||||
# As above, but this is actually an unencrypted PKCS#8 key
|
||||
rsaKeyPEM8 = u'''-----BEGIN PRIVATE KEY-----
|
||||
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvx4nkAqgiyNRGlwS
|
||||
ga5tkzEsPv6RP5MuvtSS8S0WtGEMMoy24girX0WsvilQgzKY8xIsGfeEkt7fQPDj
|
||||
wZAzhQIDAQABAkAJRIMSnxFN7fZ+2rwjAbxaiOXmYB3XAWIg6tn9S/xv3rdYk4mK
|
||||
5BxU3b2/FTn4zL0Y9ntEDeGsMEQCgdQM+sg5AiEA8g8vPh2mGIP2KYCSK9jfVFzk
|
||||
B8cmJBEDteLFNyMSSiMCIQDKH+kkeSz8yWv6t080Smi0GN9XgzgGSAYAD+KlyZoC
|
||||
NwIhAIe+HDApUEvPNOxxPYd5R0R4EyiJdcokAICvewlAkbEhAiBqtGn6bVZIpXUx
|
||||
yLAxpM6dtTvDEWz0M/Wm9rvqVgHOBQIhAL2fQKdkInohlipK3Qfk3v5D7ZGjrie7
|
||||
BX85JB8zqwHB
|
||||
-----END PRIVATE KEY-----'''
|
||||
|
||||
# The same RSA private key as in rsaKeyPEM, but now encrypted
|
||||
rsaKeyEncryptedPEM=(
|
||||
|
||||
# PEM encryption
|
||||
# With DES and passphrase 'test'
|
||||
('test', u'''-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-CBC,AF8F9A40BD2FA2FC
|
||||
|
||||
Ckl9ex1kaVEWhYC2QBmfaF+YPiR4NFkRXA7nj3dcnuFEzBnY5XULupqQpQI3qbfA
|
||||
u8GYS7+b3toWWiHZivHbAAUBPDIZG9hKDyB9Sq2VMARGsX1yW1zhNvZLIiVJzUHs
|
||||
C6NxQ1IJWOXzTew/xM2I26kPwHIvadq+/VaT8gLQdjdH0jOiVNaevjWnLgrn1mLP
|
||||
BCNRMdcexozWtAFNNqSzfW58MJL2OdMi21ED184EFytIc1BlB+FZiGZduwKGuaKy
|
||||
9bMbdb/1PSvsSzPsqW7KSSrTw6MgJAFJg6lzIYvR5F4poTVBxwBX3+EyEmShiaNY
|
||||
IRX3TgQI0IjrVuLmvlZKbGWP18FXj7I7k9tSsNOOzllTTdq3ny5vgM3A+ynfAaxp
|
||||
dysKznQ6P+IoqML1WxAID4aGRMWka+uArOJ148Rbj9s=
|
||||
-----END RSA PRIVATE KEY-----'''),
|
||||
|
||||
# PKCS8 encryption
|
||||
('winter', u'''-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIBpjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIeZIsbW3O+JcCAggA
|
||||
MBQGCCqGSIb3DQMHBAgSM2p0D8FilgSCAWBhFyP2tiGKVpGj3mO8qIBzinU60ApR
|
||||
3unvP+N6j7LVgnV2lFGaXbJ6a1PbQXe+2D6DUyBLo8EMXrKKVLqOMGkFMHc0UaV6
|
||||
R6MmrsRDrbOqdpTuVRW+NVd5J9kQQh4xnfU/QrcPPt7vpJvSf4GzG0n666Ki50OV
|
||||
M/feuVlIiyGXY6UWdVDpcOV72cq02eNUs/1JWdh2uEBvA9fCL0c07RnMrdT+CbJQ
|
||||
NjJ7f8ULtp7xvR9O3Al/yJ4Wv3i4VxF1f3MCXzhlUD4I0ONlr0kJWgeQ80q/cWhw
|
||||
ntvgJwnCn2XR1h6LA8Wp+0ghDTsL2NhJpWd78zClGhyU4r3hqu1XDjoXa7YCXCix
|
||||
jCV15+ViDJzlNCwg+W6lRg18sSLkCT7alviIE0U5tHc6UPbbHwT5QqAxAABaP+nZ
|
||||
CGqJGyiwBzrKebjgSm/KRd4C91XqcsysyH2kKPfT51MLAoD4xelOURBP
|
||||
-----END ENCRYPTED PRIVATE KEY-----'''
|
||||
),
|
||||
)
|
||||
|
||||
rsaPublicKeyPEM = u'''-----BEGIN RSA PUBLIC KEY-----
|
||||
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+T
|
||||
Lr7UkvEtFrRhDDKMtuIIq19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQ==
|
||||
-----END RSA PUBLIC KEY-----'''
|
||||
|
||||
# Obtained using 'ssh-keygen -i -m PKCS8 -f rsaPublicKeyPEM'
|
||||
rsaPublicKeyOpenSSH = b('''ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQC/HieQCqCLI1EaXBKBrm2TMSw+/pE/ky6+1JLxLRa0YQwyjLbiCKtfRay+KVCDMpjzEiwZ94SS3t9A8OPBkDOF comment\n''')
|
||||
|
||||
# The private key, in PKCS#1 format encoded with DER
|
||||
rsaKeyDER = a2b_hex(
|
||||
'''3082013b020100024100bf1e27900aa08b23511a5c1281ae6d93312c3efe
|
||||
913f932ebed492f12d16b4610c328cb6e208ab5f45acbe2950833298f312
|
||||
2c19f78492dedf40f0e3c190338502030100010240094483129f114dedf6
|
||||
7edabc2301bc5a88e5e6601dd7016220ead9fd4bfc6fdeb75893898ae41c
|
||||
54ddbdbf1539f8ccbd18f67b440de1ac30440281d40cfac839022100f20f
|
||||
2f3e1da61883f62980922bd8df545ce407c726241103b5e2c53723124a23
|
||||
022100ca1fe924792cfcc96bfab74f344a68b418df578338064806000fe2
|
||||
a5c99a023702210087be1c3029504bcf34ec713d877947447813288975ca
|
||||
240080af7b094091b12102206ab469fa6d5648a57531c8b031a4ce9db53b
|
||||
c3116cf433f5a6f6bbea5601ce05022100bd9f40a764227a21962a4add07
|
||||
e4defe43ed91a3ae27bb057f39241f33ab01c1
|
||||
'''.replace(" ",""))
|
||||
|
||||
# The private key, in unencrypted PKCS#8 format encoded with DER
|
||||
rsaKeyDER8 = a2b_hex(
|
||||
'''30820155020100300d06092a864886f70d01010105000482013f3082013
|
||||
b020100024100bf1e27900aa08b23511a5c1281ae6d93312c3efe913f932
|
||||
ebed492f12d16b4610c328cb6e208ab5f45acbe2950833298f3122c19f78
|
||||
492dedf40f0e3c190338502030100010240094483129f114dedf67edabc2
|
||||
301bc5a88e5e6601dd7016220ead9fd4bfc6fdeb75893898ae41c54ddbdb
|
||||
f1539f8ccbd18f67b440de1ac30440281d40cfac839022100f20f2f3e1da
|
||||
61883f62980922bd8df545ce407c726241103b5e2c53723124a23022100c
|
||||
a1fe924792cfcc96bfab74f344a68b418df578338064806000fe2a5c99a0
|
||||
23702210087be1c3029504bcf34ec713d877947447813288975ca240080a
|
||||
f7b094091b12102206ab469fa6d5648a57531c8b031a4ce9db53bc3116cf
|
||||
433f5a6f6bbea5601ce05022100bd9f40a764227a21962a4add07e4defe4
|
||||
3ed91a3ae27bb057f39241f33ab01c1
|
||||
'''.replace(" ",""))
|
||||
|
||||
rsaPublicKeyDER = a2b_hex(
|
||||
'''305c300d06092a864886f70d0101010500034b003048024100bf1e27900a
|
||||
a08b23511a5c1281ae6d93312c3efe913f932ebed492f12d16b4610c328c
|
||||
b6e208ab5f45acbe2950833298f3122c19f78492dedf40f0e3c190338502
|
||||
03010001
|
||||
'''.replace(" ",""))
|
||||
|
||||
n = long('BF 1E 27 90 0A A0 8B 23 51 1A 5C 12 81 AE 6D 93 31 2C 3E FE 91 3F 93 2E BE D4 92 F1 2D 16 B4 61 0C 32 8C B6 E2 08 AB 5F 45 AC BE 29 50 83 32 98 F3 12 2C 19 F7 84 92 DE DF 40 F0 E3 C1 90 33 85'.replace(" ",""),16)
|
||||
e = 65537L
|
||||
d = long('09 44 83 12 9F 11 4D ED F6 7E DA BC 23 01 BC 5A 88 E5 E6 60 1D D7 01 62 20 EA D9 FD 4B FC 6F DE B7 58 93 89 8A E4 1C 54 DD BD BF 15 39 F8 CC BD 18 F6 7B 44 0D E1 AC 30 44 02 81 D4 0C FA C8 39'.replace(" ",""),16)
|
||||
p = long('00 F2 0F 2F 3E 1D A6 18 83 F6 29 80 92 2B D8 DF 54 5C E4 07 C7 26 24 11 03 B5 E2 C5 37 23 12 4A 23'.replace(" ",""),16)
|
||||
q = long('00 CA 1F E9 24 79 2C FC C9 6B FA B7 4F 34 4A 68 B4 18 DF 57 83 38 06 48 06 00 0F E2 A5 C9 9A 02 37'.replace(" ",""),16)
|
||||
|
||||
# This is q^{-1} mod p). fastmath and slowmath use pInv (p^{-1}
|
||||
# mod q) instead!
|
||||
qInv = long('00 BD 9F 40 A7 64 22 7A 21 96 2A 4A DD 07 E4 DE FE 43 ED 91 A3 AE 27 BB 05 7F 39 24 1F 33 AB 01 C1'.replace(" ",""),16)
|
||||
pInv = inverse(p,q)
|
||||
|
||||
def testImportKey1(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE"""
|
||||
key = self.rsa.importKey(self.rsaKeyDER)
|
||||
self.failUnless(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey2(self):
|
||||
"""Verify import of SubjectPublicKeyInfo DER SEQUENCE"""
|
||||
key = self.rsa.importKey(self.rsaPublicKeyDER)
|
||||
self.failIf(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey3unicode(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as unicode"""
|
||||
key = RSA.importKey(self.rsaKeyPEM)
|
||||
self.assertEqual(key.has_private(),True) # assert_
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey3bytes(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as byte string"""
|
||||
key = RSA.importKey(b(self.rsaKeyPEM))
|
||||
self.assertEqual(key.has_private(),True) # assert_
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey4unicode(self):
|
||||
"""Verify import of RSAPrivateKey DER SEQUENCE, encoded with PEM as unicode"""
|
||||
key = RSA.importKey(self.rsaPublicKeyPEM)
|
||||
self.assertEqual(key.has_private(),False) # failIf
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey4bytes(self):
|
||||
"""Verify import of SubjectPublicKeyInfo DER SEQUENCE, encoded with PEM as byte string"""
|
||||
key = RSA.importKey(b(self.rsaPublicKeyPEM))
|
||||
self.assertEqual(key.has_private(),False) # failIf
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey5(self):
|
||||
"""Verifies that the imported key is still a valid RSA pair"""
|
||||
key = RSA.importKey(self.rsaKeyPEM)
|
||||
idem = key.encrypt(key.decrypt(b("Test")),0)
|
||||
self.assertEqual(idem[0],b("Test"))
|
||||
|
||||
def testImportKey6(self):
|
||||
"""Verifies that the imported key is still a valid RSA pair"""
|
||||
key = RSA.importKey(self.rsaKeyDER)
|
||||
idem = key.encrypt(key.decrypt(b("Test")),0)
|
||||
self.assertEqual(idem[0],b("Test"))
|
||||
|
||||
def testImportKey7(self):
|
||||
"""Verify import of OpenSSH public key"""
|
||||
key = self.rsa.importKey(self.rsaPublicKeyOpenSSH)
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
|
||||
def testImportKey8(self):
|
||||
"""Verify import of encrypted PrivateKeyInfo DER SEQUENCE"""
|
||||
for t in self.rsaKeyEncryptedPEM:
|
||||
key = self.rsa.importKey(t[1], t[0])
|
||||
self.failUnless(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey9(self):
|
||||
"""Verify import of unencrypted PrivateKeyInfo DER SEQUENCE"""
|
||||
key = self.rsa.importKey(self.rsaKeyDER8)
|
||||
self.failUnless(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey10(self):
|
||||
"""Verify import of unencrypted PrivateKeyInfo DER SEQUENCE, encoded with PEM"""
|
||||
key = self.rsa.importKey(self.rsaKeyPEM8)
|
||||
self.failUnless(key.has_private())
|
||||
self.assertEqual(key.n, self.n)
|
||||
self.assertEqual(key.e, self.e)
|
||||
self.assertEqual(key.d, self.d)
|
||||
self.assertEqual(key.p, self.p)
|
||||
self.assertEqual(key.q, self.q)
|
||||
|
||||
def testImportKey11(self):
|
||||
"""Verify import of RSAPublicKey DER SEQUENCE"""
|
||||
der = asn1.DerSequence([17, 3]).encode()
|
||||
key = self.rsa.importKey(der)
|
||||
self.assertEqual(key.n, 17)
|
||||
self.assertEqual(key.e, 3)
|
||||
|
||||
def testImportKey12(self):
|
||||
"""Verify import of RSAPublicKey DER SEQUENCE, encoded with PEM"""
|
||||
der = asn1.DerSequence([17, 3]).encode()
|
||||
pem = der2pem(der)
|
||||
key = self.rsa.importKey(pem)
|
||||
self.assertEqual(key.n, 17)
|
||||
self.assertEqual(key.e, 3)
|
||||
|
||||
###
|
||||
def testExportKey1(self):
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
derKey = key.exportKey("DER")
|
||||
self.assertEqual(derKey, self.rsaKeyDER)
|
||||
|
||||
def testExportKey2(self):
|
||||
key = self.rsa.construct([self.n, self.e])
|
||||
derKey = key.exportKey("DER")
|
||||
self.assertEqual(derKey, self.rsaPublicKeyDER)
|
||||
|
||||
def testExportKey3(self):
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
pemKey = key.exportKey("PEM")
|
||||
self.assertEqual(pemKey, b(self.rsaKeyPEM))
|
||||
|
||||
def testExportKey4(self):
|
||||
key = self.rsa.construct([self.n, self.e])
|
||||
pemKey = key.exportKey("PEM")
|
||||
self.assertEqual(pemKey, b(self.rsaPublicKeyPEM))
|
||||
|
||||
def testExportKey5(self):
|
||||
key = self.rsa.construct([self.n, self.e])
|
||||
openssh_1 = key.exportKey("OpenSSH").split()
|
||||
openssh_2 = self.rsaPublicKeyOpenSSH.split()
|
||||
self.assertEqual(openssh_1[0], openssh_2[0])
|
||||
self.assertEqual(openssh_1[1], openssh_2[1])
|
||||
|
||||
def testExportKey7(self):
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
derKey = key.exportKey("DER", pkcs=8)
|
||||
self.assertEqual(derKey, self.rsaKeyDER8)
|
||||
|
||||
def testExportKey8(self):
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
pemKey = key.exportKey("PEM", pkcs=8)
|
||||
self.assertEqual(pemKey, b(self.rsaKeyPEM8))
|
||||
|
||||
def testExportKey9(self):
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
self.assertRaises(ValueError, key.exportKey, "invalid-format")
|
||||
|
||||
def testExportKey10(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# PEM envelope, PKCS#1, old PEM encryption
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.exportKey('PEM', 'test')
|
||||
self.failUnless(tostr(outkey).find('4,ENCRYPTED')!=-1)
|
||||
self.failUnless(tostr(outkey).find('BEGIN RSA PRIVATE KEY')!=-1)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey11(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# PEM envelope, PKCS#1, old PEM encryption
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.exportKey('PEM', 'test', pkcs=1)
|
||||
self.failUnless(tostr(outkey).find('4,ENCRYPTED')!=-1)
|
||||
self.failUnless(tostr(outkey).find('BEGIN RSA PRIVATE KEY')!=-1)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey12(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# PEM envelope, PKCS#8, old PEM encryption
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.exportKey('PEM', 'test', pkcs=8)
|
||||
self.failUnless(tostr(outkey).find('4,ENCRYPTED')!=-1)
|
||||
self.failUnless(tostr(outkey).find('BEGIN PRIVATE KEY')!=-1)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey13(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# PEM envelope, PKCS#8, PKCS#8 encryption
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.exportKey('PEM', 'test', pkcs=8,
|
||||
protection='PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC')
|
||||
self.failUnless(tostr(outkey).find('4,ENCRYPTED')==-1)
|
||||
self.failUnless(tostr(outkey).find('BEGIN ENCRYPTED PRIVATE KEY')!=-1)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey14(self):
|
||||
# Export and re-import the encrypted key. It must match.
|
||||
# DER envelope, PKCS#8, PKCS#8 encryption
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
outkey = key.exportKey('DER', 'test', pkcs=8)
|
||||
inkey = RSA.importKey(outkey, 'test')
|
||||
self.assertEqual(key.n, inkey.n)
|
||||
self.assertEqual(key.e, inkey.e)
|
||||
self.assertEqual(key.d, inkey.d)
|
||||
|
||||
def testExportKey15(self):
|
||||
# Verify that that error an condition is detected when trying to
|
||||
# use a password with DER encoding and PKCS#1.
|
||||
key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv])
|
||||
self.assertRaises(ValueError, key.exportKey, 'DER', 'test', 1)
|
||||
|
||||
class ImportKeyTestsSlow(ImportKeyTests):
|
||||
def setUp(self):
|
||||
self.rsa = RSA.RSAImplementation(use_fast_math=0)
|
||||
|
||||
class ImportKeyTestsFast(ImportKeyTests):
|
||||
def setUp(self):
|
||||
self.rsa = RSA.RSAImplementation(use_fast_math=1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
def get_tests(config={}):
|
||||
tests = []
|
||||
try:
|
||||
from Crypto.PublicKey import _fastmath
|
||||
tests += list_test_cases(ImportKeyTestsFast)
|
||||
except ImportError:
|
||||
pass
|
||||
tests += list_test_cases(ImportKeyTestsSlow)
|
||||
return tests
|
||||
|
||||
if __name__ == '__main__':
|
||||
suite = lambda: unittest.TestSuite(get_tests())
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
# vim:set ts=4 sw=4 sts=4 expandtab:
|
Reference in New Issue
Block a user