update windows build to Python 3.7
This commit is contained in:
parent
73105fa71e
commit
ddc59ab92d
5761 changed files with 750298 additions and 213405 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,210 +1,210 @@
|
|||
# -*- 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.assertEqual(ct[0], d['ct1'])
|
||||
self.assertEqual(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.assertEqual(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.assertEqual(sig1, d['sig1'])
|
||||
self.assertEqual(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.assertTrue(res)
|
||||
# Negative test
|
||||
res = key.verify( d['h'], (d['sig1']+1,d['sig2']) )
|
||||
self.assertFalse(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 list(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.assertTrue(elgObj.has_private())
|
||||
self.assertTrue(elgObj.can_sign())
|
||||
self.assertTrue(elgObj.can_encrypt())
|
||||
|
||||
# Sanity check key data
|
||||
self.assertTrue(1<elgObj.g<(elgObj.p-1))
|
||||
self.assertEqual(pow(elgObj.g, elgObj.p-1, elgObj.p), 1)
|
||||
self.assertTrue(1<elgObj.x<(elgObj.p-1))
|
||||
self.assertEqual(pow(elgObj.g, elgObj.x, elgObj.p), elgObj.y)
|
||||
|
||||
def _check_public_key(self, elgObj):
|
||||
|
||||
# Check capabilities
|
||||
self.assertFalse(elgObj.has_private())
|
||||
self.assertTrue(elgObj.can_sign())
|
||||
self.assertTrue(elgObj.can_encrypt())
|
||||
|
||||
# Sanity check key data
|
||||
self.assertTrue(1<elgObj.g<(elgObj.p-1))
|
||||
self.assertEqual(pow(elgObj.g, elgObj.p-1, elgObj.p), 1)
|
||||
|
||||
def _exercise_primitive(self, elgObj):
|
||||
# Test encryption/decryption
|
||||
plaintext = b("Test")
|
||||
ciphertext = elgObj.encrypt(plaintext, 123456789)
|
||||
plaintextP = elgObj.decrypt(ciphertext)
|
||||
self.assertEqual(plaintext, plaintextP)
|
||||
|
||||
# Test signature/verification
|
||||
signature = elgObj.sign(plaintext, 987654321)
|
||||
elgObj.verify(plaintext, signature)
|
||||
|
||||
def _exercise_public_primitive(self, elgObj):
|
||||
plaintext = b("Test")
|
||||
ciphertext = elgObj.encrypt(plaintext, 123456789)
|
||||
|
||||
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')
|
||||
|
||||
# -*- 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.assertEqual(ct[0], d['ct1'])
|
||||
self.assertEqual(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.assertEqual(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.assertEqual(sig1, d['sig1'])
|
||||
self.assertEqual(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.assertTrue(res)
|
||||
# Negative test
|
||||
res = key.verify( d['h'], (d['sig1']+1,d['sig2']) )
|
||||
self.assertFalse(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 list(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.assertTrue(elgObj.has_private())
|
||||
self.assertTrue(elgObj.can_sign())
|
||||
self.assertTrue(elgObj.can_encrypt())
|
||||
|
||||
# Sanity check key data
|
||||
self.assertTrue(1<elgObj.g<(elgObj.p-1))
|
||||
self.assertEqual(pow(elgObj.g, elgObj.p-1, elgObj.p), 1)
|
||||
self.assertTrue(1<elgObj.x<(elgObj.p-1))
|
||||
self.assertEqual(pow(elgObj.g, elgObj.x, elgObj.p), elgObj.y)
|
||||
|
||||
def _check_public_key(self, elgObj):
|
||||
|
||||
# Check capabilities
|
||||
self.assertFalse(elgObj.has_private())
|
||||
self.assertTrue(elgObj.can_sign())
|
||||
self.assertTrue(elgObj.can_encrypt())
|
||||
|
||||
# Sanity check key data
|
||||
self.assertTrue(1<elgObj.g<(elgObj.p-1))
|
||||
self.assertEqual(pow(elgObj.g, elgObj.p-1, elgObj.p), 1)
|
||||
|
||||
def _exercise_primitive(self, elgObj):
|
||||
# Test encryption/decryption
|
||||
plaintext = b("Test")
|
||||
ciphertext = elgObj.encrypt(plaintext, 123456789)
|
||||
plaintextP = elgObj.decrypt(ciphertext)
|
||||
self.assertEqual(plaintext, plaintextP)
|
||||
|
||||
# Test signature/verification
|
||||
signature = elgObj.sign(plaintext, 987654321)
|
||||
elgObj.verify(plaintext, signature)
|
||||
|
||||
def _exercise_public_primitive(self, elgObj):
|
||||
plaintext = b("Test")
|
||||
ciphertext = elgObj.encrypt(plaintext, 123456789)
|
||||
|
||||
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 +1,415 @@
|
|||
# -*- 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 = 0x11 # 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.assertTrue(rsaObj.p==self.p or rsaObj.p==self.q)
|
||||
self.assertTrue(rsaObj.q==self.p or rsaObj.q==self.q)
|
||||
self.assertTrue(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:
|
||||
# -*- 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 = 0x11 # 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.assertTrue(rsaObj.p==self.p or rsaObj.p==self.q)
|
||||
self.assertTrue(rsaObj.q==self.p or rsaObj.q==self.q)
|
||||
self.assertTrue(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 +1,345 @@
|
|||
# -*- 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.
|
||||
# ===================================================================
|
||||
|
||||
|
||||
|
||||
__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 = '''-----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 = '''-----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', '''-----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', '''-----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 = '''-----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 = int('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 = 65537
|
||||
d = int('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 = int('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 = int('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 = int('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.assertTrue(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.assertFalse(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.assertTrue(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.assertTrue(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.assertTrue(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 = list(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:
|
||||
# -*- 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.
|
||||
# ===================================================================
|
||||
|
||||
|
||||
|
||||
__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 = '''-----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 = '''-----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', '''-----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', '''-----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 = '''-----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 = int('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 = 65537
|
||||
d = int('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 = int('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 = int('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 = int('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.assertTrue(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.assertFalse(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.assertTrue(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.assertTrue(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.assertTrue(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 = list(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:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue