OXIESEC PANEL
- Current Dir:
/
/
usr
/
lib
/
python3
/
dist-packages
/
twisted
/
conch
/
test
Server IP: 139.59.38.164
Upload:
Create Dir:
Name
Size
Modified
Perms
📁
..
-
03/31/2022 06:22:38 AM
rwxr-xr-x
📄
__init__.py
14 bytes
09/08/2017 10:38:36 AM
rw-r--r--
📁
__pycache__
-
03/31/2022 06:22:39 AM
rwxr-xr-x
📄
keydata.py
17.06 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
loopback.py
757 bytes
09/08/2017 10:38:35 AM
rw-r--r--
📄
test_address.py
1.59 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_agent.py
12.78 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_cftp.py
49.7 KB
03/22/2022 11:03:56 AM
rw-r--r--
📄
test_channel.py
11.82 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_checkers.py
30.76 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_ckeygen.py
19.8 KB
03/22/2022 11:03:56 AM
rw-r--r--
📄
test_conch.py
24.55 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_connection.py
27.49 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_default.py
11.31 KB
09/08/2017 10:38:35 AM
rw-r--r--
📄
test_endpoints.py
51.96 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_filetransfer.py
26.65 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_forwarding.py
2.16 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_helper.py
20.01 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_insults.py
32.79 KB
09/08/2017 10:38:35 AM
rw-r--r--
📄
test_keys.py
53.57 KB
09/08/2017 10:38:35 AM
rw-r--r--
📄
test_knownhosts.py
48.26 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_manhole.py
12.52 KB
09/08/2017 10:38:35 AM
rw-r--r--
📄
test_manhole_tap.py
4.14 KB
09/08/2017 10:38:35 AM
rw-r--r--
📄
test_mixin.py
1.03 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_openssh_compat.py
4.52 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_recvline.py
24.81 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_scripts.py
1.84 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_session.py
38.54 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_ssh.py
31.62 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_tap.py
4.83 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_telnet.py
25.9 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_text.py
3.85 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_transport.py
89.71 KB
03/22/2022 11:03:56 AM
rw-r--r--
📄
test_unix.py
2.47 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_userauth.py
31.84 KB
09/08/2017 10:38:36 AM
rw-r--r--
📄
test_window.py
2.07 KB
09/08/2017 10:38:36 AM
rw-r--r--
Editing: test_keys.py
Close
# Copyright (c) Twisted Matrix Laboratories. # See LICENSE for details. """ Tests for L{twisted.conch.ssh.keys}. """ from __future__ import absolute_import, division from twisted.python.reflect import requireModule cryptography = requireModule("cryptography") if cryptography is None: skipCryptography = 'Cannot run without cryptography.' pyasn1 = requireModule("pyasn1") if requireModule("Crypto"): import Crypto.Cipher.DES3 import Crypto.PublicKey.RSA import Crypto.PublicKey.DSA else: # we'll have to skip some tests without PyCrypto Crypto = None skipPyCrypto = 'Cannot run without PyCrypto.' if cryptography and pyasn1: from twisted.conch.ssh import keys, common, sexpy import base64 import os from twisted.conch.test import keydata from twisted.python import randbytes from twisted.trial import unittest from twisted.python.compat import long, _PY3 from incremental import Version from twisted.python.filepath import FilePath class ObjectTypeTests(unittest.TestCase): """ Unit tests for the objectType method. """ if cryptography is None: skip = skipCryptography if Crypto is None: skip = skipPyCrypto if pyasn1 is None: skip = "Cannot run without PyASN1" if _PY3: skip = "objectType is deprecated and is not being ported to Python 3." def getRSAKey(self): """ Return a PyCrypto RSA key to support the tests. @return: The RSA key to support the tests. @rtype: C{Crypto.PublicKey.RSA} """ # Use lazy import as PyCrypto will be deprecated. from Crypto.PublicKey import RSA return RSA.construct(( keydata.RSAData['n'], keydata.RSAData['e'], keydata.RSAData['d'], )) def getDSAKey(self): """ Return a PyCrypto DSA key to support the tests. @return: The DSA key to support the tests. @rtype: C{Crypto.PublicKey.DSA} """ # Use lazy import as PyCrypto will be deprecated. from Crypto.PublicKey import DSA return DSA.construct(( keydata.DSAData['y'], keydata.DSAData['g'], keydata.DSAData['p'], keydata.DSAData['q'], keydata.DSAData['x'], )) def checkDeprecation(self): """ Check that we have a deprecation warning for C{objectType}. """ warnings = self.flushWarnings() self.assertEqual(1, len(warnings)) self.assertIs(DeprecationWarning, warnings[0]['category']) self.assertEqual( 'twisted.conch.ssh.keys.objectType was deprecated in ' 'Twisted 15.5.0', warnings[0]['message']) def test_objectType_rsa(self): """ C{ssh-rsa} is the type of the RSA keys. """ key = self.getRSAKey() self.assertEqual(keys.objectType(key), b'ssh-rsa') self.checkDeprecation() def test_objectType_dsa(self): """ C{ssh-dss} is the type of the DSA keys. """ key = self.getDSAKey() self.assertEqual(keys.objectType(key), b'ssh-dss') self.checkDeprecation() def test_objectKey_none(self): """ A BadKeyError is raised when getting the type of L{None}. """ self.assertRaises(keys.BadKeyError, keys.objectType, None) self.checkDeprecation() def test_deprecation(self): """ It is deprecated. """ key = self.getRSAKey() keys.objectType(key) self.checkDeprecation() class KeyTests(unittest.TestCase): if cryptography is None: skip = skipCryptography if pyasn1 is None: skip = "Cannot run without PyASN1" def setUp(self): self.rsaObj = keys.Key._fromRSAComponents( n=keydata.RSAData['n'], e=keydata.RSAData['e'], d=keydata.RSAData['d'], p=keydata.RSAData['p'], q=keydata.RSAData['q'], u=keydata.RSAData['u'], )._keyObject self.dsaObj = keys.Key._fromDSAComponents( y=keydata.DSAData['y'], p=keydata.DSAData['p'], q=keydata.DSAData['q'], g=keydata.DSAData['g'], x=keydata.DSAData['x'], )._keyObject self.ecObj = keys.Key._fromECComponents( x=keydata.ECDatanistp256['x'], y=keydata.ECDatanistp256['y'], privateValue=keydata.ECDatanistp256['privateValue'], curve=keydata.ECDatanistp256['curve'] )._keyObject self.ecObj384 = keys.Key._fromECComponents( x=keydata.ECDatanistp384['x'], y=keydata.ECDatanistp384['y'], privateValue=keydata.ECDatanistp384['privateValue'], curve=keydata.ECDatanistp384['curve'] )._keyObject self.ecObj521 = keys.Key._fromECComponents( x=keydata.ECDatanistp521['x'], y=keydata.ECDatanistp521['y'], privateValue=keydata.ECDatanistp521['privateValue'], curve=keydata.ECDatanistp521['curve'] )._keyObject self.rsaSignature = (b'\x00\x00\x00\x07ssh-rsa\x00' b'\x00\x00`N\xac\xb4@qK\xa0(\xc3\xf2h \xd3\xdd\xee6Np\x9d_' b'\xb0>\xe3\x0c(L\x9d{\txUd|!\xf6m\x9c\xd3\x93\x842\x7fU' b'\x05\xf4\xf7\xfaD\xda\xce\x81\x8ea\x7f=Y\xed*\xb7\xba\x81' b'\xf2\xad\xda\xeb(\x97\x03S\x08\x81\xc7\xb1\xb7\xe6\xe3' b'\xcd*\xd4\xbd\xc0wt\xf7y\xcd\xf0\xb7\x7f\xfb\x1e>\xf9r' b'\x8c\xba') self.dsaSignature = ( b'\x00\x00\x00\x07ssh-dss\x00\x00\x00(?\xc7\xeb\x86;\xd5TFA\xb4' b'\xdf\x0c\xc4E@4,d\xbc\t\xd9\xae\xdd[\xed-\x82nQ\x8cf\x9b\xe8\xe1' b'jrg\x84p<' ) self.patch(randbytes, 'secureRandom', lambda x: b'\xff' * x) self.keyFile = self.mktemp() with open(self.keyFile, 'wb') as f: f.write(keydata.privateRSA_lsh) def tearDown(self): os.unlink(self.keyFile) def test_size(self): """ The L{keys.Key.size} method returns the size of key object in bits. """ self.assertEqual(keys.Key(self.rsaObj).size(), 768) self.assertEqual(keys.Key(self.dsaObj).size(), 1024) self.assertEqual(keys.Key(self.ecObj).size(), 256) self.assertEqual(keys.Key(self.ecObj384).size(), 384) self.assertEqual(keys.Key(self.ecObj521).size(), 521) def test__guessStringType(self): """ Test that the _guessStringType method guesses string types correctly. """ self.assertEqual(keys.Key._guessStringType(keydata.publicRSA_openssh), 'public_openssh') self.assertEqual(keys.Key._guessStringType(keydata.publicDSA_openssh), 'public_openssh') self.assertEqual(keys.Key._guessStringType(keydata.publicECDSA_openssh), 'public_openssh') self.assertEqual(keys.Key._guessStringType( keydata.privateRSA_openssh), 'private_openssh') self.assertEqual(keys.Key._guessStringType( keydata.privateDSA_openssh), 'private_openssh') self.assertEqual(keys.Key._guessStringType( keydata.privateECDSA_openssh), 'private_openssh') self.assertEqual(keys.Key._guessStringType(keydata.publicRSA_lsh), 'public_lsh') self.assertEqual(keys.Key._guessStringType(keydata.publicDSA_lsh), 'public_lsh') self.assertEqual(keys.Key._guessStringType(keydata.privateRSA_lsh), 'private_lsh') self.assertEqual(keys.Key._guessStringType(keydata.privateDSA_lsh), 'private_lsh') self.assertEqual(keys.Key._guessStringType( keydata.privateRSA_agentv3), 'agentv3') self.assertEqual(keys.Key._guessStringType( keydata.privateDSA_agentv3), 'agentv3') self.assertEqual(keys.Key._guessStringType( b'\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01\x01'), 'blob') self.assertEqual(keys.Key._guessStringType( b'\x00\x00\x00\x07ssh-dss\x00\x00\x00\x01\x01'), 'blob') self.assertEqual(keys.Key._guessStringType(b'not a key'), None) def test_isPublic(self): """ The L{keys.Key.isPublic} method returns True for public keys otherwise False. """ rsaKey = keys.Key.fromString(keydata.privateRSA_openssh) dsaKey = keys.Key.fromString(keydata.privateDSA_openssh) ecdsaKey = keys.Key.fromString(keydata.privateECDSA_openssh) self.assertTrue(rsaKey.public().isPublic()) self.assertFalse(rsaKey.isPublic()) self.assertTrue(dsaKey.public().isPublic()) self.assertFalse(dsaKey.isPublic()) self.assertTrue(ecdsaKey.public().isPublic()) self.assertFalse(ecdsaKey.isPublic()) def _testPublicPrivateFromString(self, public, private, type, data): self._testPublicFromString(public, type, data) self._testPrivateFromString(private, type, data) def _testPublicFromString(self, public, type, data): publicKey = keys.Key.fromString(public) self.assertTrue(publicKey.isPublic()) self.assertEqual(publicKey.type(), type) for k, v in publicKey.data().items(): self.assertEqual(data[k], v) def _testPrivateFromString(self, private, type, data): privateKey = keys.Key.fromString(private) self.assertFalse(privateKey.isPublic()) self.assertEqual(privateKey.type(), type) for k, v in data.items(): self.assertEqual(privateKey.data()[k], v) def test_fromOpenSSH(self): """ Test that keys are correctly generated from OpenSSH strings. """ self._testPublicPrivateFromString(keydata.publicECDSA_openssh, keydata.privateECDSA_openssh, 'EC', keydata.ECDatanistp256) self._testPublicPrivateFromString(keydata.publicRSA_openssh, keydata.privateRSA_openssh, 'RSA', keydata.RSAData) self.assertEqual(keys.Key.fromString( keydata.privateRSA_openssh_encrypted, passphrase=b'encrypted'), keys.Key.fromString(keydata.privateRSA_openssh)) self.assertEqual(keys.Key.fromString( keydata.privateRSA_openssh_alternate), keys.Key.fromString(keydata.privateRSA_openssh)) self._testPublicPrivateFromString(keydata.publicDSA_openssh, keydata.privateDSA_openssh, 'DSA', keydata.DSAData) def test_fromOpenSSHErrors(self): """ Tests for invalid key types. """ badKey = b"""-----BEGIN FOO PRIVATE KEY----- MIGkAgEBBDAtAi7I8j73WCX20qUM5hhHwHuFzYWYYILs2Sh8UZ+awNkARZ/Fu2LU LLl5RtOQpbWgBwYFK4EEACKhZANiAATU17sA9P5FRwSknKcFsjjsk0+E3CeXPYX0 Tk/M0HK3PpWQWgrO8JdRHP9eFE9O/23P8BumwFt7F/AvPlCzVd35VfraFT0o4cCW G0RqpQ+np31aKmeJshkcYALEchnU+tQ= -----END EC PRIVATE KEY-----""" self.assertRaises(keys.BadKeyError, keys.Key._fromString_PRIVATE_OPENSSH, badKey, None) def test_fromOpenSSH_with_whitespace(self): """ If key strings have trailing whitespace, it should be ignored. """ # from bug #3391, since our test key data doesn't have # an issue with appended newlines privateDSAData = b"""-----BEGIN DSA PRIVATE KEY----- MIIBuwIBAAKBgQDylESNuc61jq2yatCzZbenlr9llG+p9LhIpOLUbXhhHcwC6hrh EZIdCKqTO0USLrGoP5uS9UHAUoeN62Z0KXXWTwOWGEQn/syyPzNJtnBorHpNUT9D Qzwl1yUa53NNgEctpo4NoEFOx8PuU6iFLyvgHCjNn2MsuGuzkZm7sI9ZpQIVAJiR 9dPc08KLdpJyRxz8T74b4FQRAoGAGBc4Z5Y6R/HZi7AYM/iNOM8su6hrk8ypkBwR a3Dbhzk97fuV3SF1SDrcQu4zF7c4CtH609N5nfZs2SUjLLGPWln83Ysb8qhh55Em AcHXuROrHS/sDsnqu8FQp86MaudrqMExCOYyVPE7jaBWW+/JWFbKCxmgOCSdViUJ esJpBFsCgYEA7+jtVvSt9yrwsS/YU1QGP5wRAiDYB+T5cK4HytzAqJKRdC5qS4zf C7R0eKcDHHLMYO39aPnCwXjscisnInEhYGNblTDyPyiyNxAOXuC8x7luTmwzMbNJ /ow0IqSj0VF72VJN9uSoPpFd4lLT0zN8v42RWja0M8ohWNf+YNJluPgCFE0PT4Vm SUrCyZXsNh6VXwjs3gKQ -----END DSA PRIVATE KEY-----""" self.assertEqual(keys.Key.fromString(privateDSAData), keys.Key.fromString(privateDSAData + b'\n')) def test_fromNewerOpenSSH(self): """ Newer versions of OpenSSH generate encrypted keys which have a longer IV than the older versions. These newer keys are also loaded. """ key = keys.Key.fromString(keydata.privateRSA_openssh_encrypted_aes, passphrase=b'testxp') self.assertEqual(key.type(), 'RSA') key2 = keys.Key.fromString( keydata.privateRSA_openssh_encrypted_aes + b'\n', passphrase=b'testxp') self.assertEqual(key, key2) def test_fromOpenSSH_windows_line_endings(self): """ Test that keys are correctly generated from OpenSSH strings with Windows line endings. """ privateDSAData = b"""-----BEGIN DSA PRIVATE KEY----- MIIBuwIBAAKBgQDylESNuc61jq2yatCzZbenlr9llG+p9LhIpOLUbXhhHcwC6hrh EZIdCKqTO0USLrGoP5uS9UHAUoeN62Z0KXXWTwOWGEQn/syyPzNJtnBorHpNUT9D Qzwl1yUa53NNgEctpo4NoEFOx8PuU6iFLyvgHCjNn2MsuGuzkZm7sI9ZpQIVAJiR 9dPc08KLdpJyRxz8T74b4FQRAoGAGBc4Z5Y6R/HZi7AYM/iNOM8su6hrk8ypkBwR a3Dbhzk97fuV3SF1SDrcQu4zF7c4CtH609N5nfZs2SUjLLGPWln83Ysb8qhh55Em AcHXuROrHS/sDsnqu8FQp86MaudrqMExCOYyVPE7jaBWW+/JWFbKCxmgOCSdViUJ esJpBFsCgYEA7+jtVvSt9yrwsS/YU1QGP5wRAiDYB+T5cK4HytzAqJKRdC5qS4zf C7R0eKcDHHLMYO39aPnCwXjscisnInEhYGNblTDyPyiyNxAOXuC8x7luTmwzMbNJ /ow0IqSj0VF72VJN9uSoPpFd4lLT0zN8v42RWja0M8ohWNf+YNJluPgCFE0PT4Vm SUrCyZXsNh6VXwjs3gKQ -----END DSA PRIVATE KEY-----""" self.assertEqual( keys.Key.fromString(privateDSAData), keys.Key.fromString(privateDSAData.replace(b'\n', b'\r\n'))) def test_fromLSHPublicUnsupportedType(self): """ C{BadKeyError} exception is raised when public key has an unknown type. """ sexp = sexpy.pack([[b'public-key', [b'bad-key', [b'p', b'2']]]]) self.assertRaises( keys.BadKeyError, keys.Key.fromString, data=b'{' + base64.encodestring(sexp) + b'}', ) def test_fromLSHPrivateUnsupportedType(self): """ C{BadKeyError} exception is raised when private key has an unknown type. """ sexp = sexpy.pack([[b'private-key', [b'bad-key', [b'p', b'2']]]]) self.assertRaises( keys.BadKeyError, keys.Key.fromString, sexp, ) def test_fromLSHRSA(self): """ RSA public and private keys can be generated from a LSH strings. """ self._testPublicPrivateFromString( keydata.publicRSA_lsh, keydata.privateRSA_lsh, 'RSA', keydata.RSAData, ) def test_fromLSHDSA(self): """ DSA public and private key can be generated from LSHs. """ self._testPublicPrivateFromString( keydata.publicDSA_lsh, keydata.privateDSA_lsh, 'DSA', keydata.DSAData, ) def test_fromAgentv3(self): """ Test that keys are correctly generated from Agent v3 strings. """ self._testPrivateFromString(keydata.privateRSA_agentv3, 'RSA', keydata.RSAData) self._testPrivateFromString(keydata.privateDSA_agentv3, 'DSA', keydata.DSAData) self.assertRaises(keys.BadKeyError, keys.Key.fromString, b'\x00\x00\x00\x07ssh-foo'+ b'\x00\x00\x00\x01\x01'*5) def test_fromStringErrors(self): """ keys.Key.fromString should raise BadKeyError when the key is invalid. """ self.assertRaises(keys.BadKeyError, keys.Key.fromString, b'') # no key data with a bad key type self.assertRaises(keys.BadKeyError, keys.Key.fromString, b'', 'bad_type') # trying to decrypt a key which doesn't support encryption self.assertRaises(keys.BadKeyError, keys.Key.fromString, keydata.publicRSA_lsh, passphrase = b'unencrypted') # trying to decrypt a key with the wrong passphrase self.assertRaises(keys.EncryptedKeyError, keys.Key.fromString, keys.Key(self.rsaObj).toString('openssh', b'encrypted')) # key with no key data self.assertRaises(keys.BadKeyError, keys.Key.fromString, b'-----BEGIN RSA KEY-----\nwA==\n') # key with invalid DEK Info self.assertRaises( keys.BadKeyError, keys.Key.fromString, b"""-----BEGIN ENCRYPTED RSA KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: weird type 4Ed/a9OgJWHJsne7yOGWeWMzHYKsxuP9w1v0aYcp+puS75wvhHLiUnNwxz0KDi6n T3YkKLBsoCWS68ApR2J9yeQ6R+EyS+UQDrO9nwqo3DB5BT3Ggt8S1wE7vjNLQD0H g/SJnlqwsECNhh8aAx+Ag0m3ZKOZiRD5mCkcDQsZET7URSmFytDKOjhFn3u6ZFVB sXrfpYc6TJtOQlHd/52JB6aAbjt6afSv955Z7enIi+5yEJ5y7oYQTaE5zrFMP7N5 9LbfJFlKXxEddy/DErRLxEjmC+t4svHesoJKc2jjjyNPiOoGGF3kJXea62vsjdNV gMK5Eged3TBVIk2dv8rtJUvyFeCUtjQ1UJZIebScRR47KrbsIpCmU8I4/uHWm5hW 0mOwvdx1L/mqx/BHqVU9Dw2COhOdLbFxlFI92chkovkmNk4P48ziyVnpm7ME22sE vfCMsyirdqB1mrL4CSM7FXONv+CgfBfeYVkYW8RfJac9U1L/O+JNn7yee414O/rS hRYw4UdWnH6Gg6niklVKWNY0ZwUZC8zgm2iqy8YCYuneS37jC+OEKP+/s6HSKuqk 2bzcl3/TcZXNSM815hnFRpz0anuyAsvwPNRyvxG2/DacJHL1f6luV4B0o6W410yf qXQx01DLo7nuyhJqoH3UGCyyXB+/QUs0mbG2PAEn3f5dVs31JMdbt+PrxURXXjKk 4cexpUcIpqqlfpIRe3RD0sDVbH4OXsGhi2kiTfPZu7mgyFxKopRbn1KwU1qKinfY EU9O4PoTak/tPT+5jFNhaP+HrURoi/pU8EAUNSktl7xAkHYwkN/9Cm7DeBghgf3n 8+tyCGYDsB5utPD0/Xe9yx0Qhc/kMm4xIyQDyA937dk3mUvLC9vulnAP8I+Izim0 fZ182+D1bWwykoD0997mUHG/AUChWR01V1OLwRyPv2wUtiS8VNG76Y2aqKlgqP1P V+IvIEqR4ERvSBVFzXNF8Y6j/sVxo8+aZw+d0L1Ns/R55deErGg3B8i/2EqGd3r+ 0jps9BqFHHWW87n3VyEB3jWCMj8Vi2EJIfa/7pSaViFIQn8LiBLf+zxG5LTOToK5 xkN42fReDcqi3UNfKNGnv4dsplyTR2hyx65lsj4bRKDGLKOuB1y7iB0AGb0LtcAI dcsVlcCeUquDXtqKvRnwfIMg+ZunyjqHBhj3qgRgbXbT6zjaSdNnih569aTg0Vup VykzZ7+n/KVcGLmvX0NesdoI7TKbq4TnEIOynuG5Sf+2GpARO5bjcWKSZeN/Ybgk gccf8Cqf6XWqiwlWd0B7BR3SymeHIaSymC45wmbgdstrbk7Ppa2Tp9AZku8M2Y7c 8mY9b+onK075/ypiwBm4L4GRNTFLnoNQJXx0OSl4FNRWsn6ztbD+jZhu8Seu10Jw SEJVJ+gmTKdRLYORJKyqhDet6g7kAxs4EoJ25WsOnX5nNr00rit+NkMPA7xbJT+7 CfI51GQLw7pUPeO2WNt6yZO/YkzZrqvTj5FEwybkUyBv7L0gkqu9wjfDdUw0fVHE xEm4DxjEoaIp8dW/JOzXQ2EF+WaSOgdYsw3Ac+rnnjnNptCdOEDGP6QBkt+oXj4P -----END RSA PRIVATE KEY-----""", passphrase='encrypted') # key with invalid encryption type self.assertRaises( keys.BadKeyError, keys.Key.fromString, b"""-----BEGIN ENCRYPTED RSA KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: FOO-123-BAR,01234567 4Ed/a9OgJWHJsne7yOGWeWMzHYKsxuP9w1v0aYcp+puS75wvhHLiUnNwxz0KDi6n T3YkKLBsoCWS68ApR2J9yeQ6R+EyS+UQDrO9nwqo3DB5BT3Ggt8S1wE7vjNLQD0H g/SJnlqwsECNhh8aAx+Ag0m3ZKOZiRD5mCkcDQsZET7URSmFytDKOjhFn3u6ZFVB sXrfpYc6TJtOQlHd/52JB6aAbjt6afSv955Z7enIi+5yEJ5y7oYQTaE5zrFMP7N5 9LbfJFlKXxEddy/DErRLxEjmC+t4svHesoJKc2jjjyNPiOoGGF3kJXea62vsjdNV gMK5Eged3TBVIk2dv8rtJUvyFeCUtjQ1UJZIebScRR47KrbsIpCmU8I4/uHWm5hW 0mOwvdx1L/mqx/BHqVU9Dw2COhOdLbFxlFI92chkovkmNk4P48ziyVnpm7ME22sE vfCMsyirdqB1mrL4CSM7FXONv+CgfBfeYVkYW8RfJac9U1L/O+JNn7yee414O/rS hRYw4UdWnH6Gg6niklVKWNY0ZwUZC8zgm2iqy8YCYuneS37jC+OEKP+/s6HSKuqk 2bzcl3/TcZXNSM815hnFRpz0anuyAsvwPNRyvxG2/DacJHL1f6luV4B0o6W410yf qXQx01DLo7nuyhJqoH3UGCyyXB+/QUs0mbG2PAEn3f5dVs31JMdbt+PrxURXXjKk 4cexpUcIpqqlfpIRe3RD0sDVbH4OXsGhi2kiTfPZu7mgyFxKopRbn1KwU1qKinfY EU9O4PoTak/tPT+5jFNhaP+HrURoi/pU8EAUNSktl7xAkHYwkN/9Cm7DeBghgf3n 8+tyCGYDsB5utPD0/Xe9yx0Qhc/kMm4xIyQDyA937dk3mUvLC9vulnAP8I+Izim0 fZ182+D1bWwykoD0997mUHG/AUChWR01V1OLwRyPv2wUtiS8VNG76Y2aqKlgqP1P V+IvIEqR4ERvSBVFzXNF8Y6j/sVxo8+aZw+d0L1Ns/R55deErGg3B8i/2EqGd3r+ 0jps9BqFHHWW87n3VyEB3jWCMj8Vi2EJIfa/7pSaViFIQn8LiBLf+zxG5LTOToK5 xkN42fReDcqi3UNfKNGnv4dsplyTR2hyx65lsj4bRKDGLKOuB1y7iB0AGb0LtcAI dcsVlcCeUquDXtqKvRnwfIMg+ZunyjqHBhj3qgRgbXbT6zjaSdNnih569aTg0Vup VykzZ7+n/KVcGLmvX0NesdoI7TKbq4TnEIOynuG5Sf+2GpARO5bjcWKSZeN/Ybgk gccf8Cqf6XWqiwlWd0B7BR3SymeHIaSymC45wmbgdstrbk7Ppa2Tp9AZku8M2Y7c 8mY9b+onK075/ypiwBm4L4GRNTFLnoNQJXx0OSl4FNRWsn6ztbD+jZhu8Seu10Jw SEJVJ+gmTKdRLYORJKyqhDet6g7kAxs4EoJ25WsOnX5nNr00rit+NkMPA7xbJT+7 CfI51GQLw7pUPeO2WNt6yZO/YkzZrqvTj5FEwybkUyBv7L0gkqu9wjfDdUw0fVHE xEm4DxjEoaIp8dW/JOzXQ2EF+WaSOgdYsw3Ac+rnnjnNptCdOEDGP6QBkt+oXj4P -----END RSA PRIVATE KEY-----""", passphrase='encrypted') # key with bad IV (AES) self.assertRaises( keys.BadKeyError, keys.Key.fromString, b"""-----BEGIN ENCRYPTED RSA KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-128-CBC,01234 4Ed/a9OgJWHJsne7yOGWeWMzHYKsxuP9w1v0aYcp+puS75wvhHLiUnNwxz0KDi6n T3YkKLBsoCWS68ApR2J9yeQ6R+EyS+UQDrO9nwqo3DB5BT3Ggt8S1wE7vjNLQD0H g/SJnlqwsECNhh8aAx+Ag0m3ZKOZiRD5mCkcDQsZET7URSmFytDKOjhFn3u6ZFVB sXrfpYc6TJtOQlHd/52JB6aAbjt6afSv955Z7enIi+5yEJ5y7oYQTaE5zrFMP7N5 9LbfJFlKXxEddy/DErRLxEjmC+t4svHesoJKc2jjjyNPiOoGGF3kJXea62vsjdNV gMK5Eged3TBVIk2dv8rtJUvyFeCUtjQ1UJZIebScRR47KrbsIpCmU8I4/uHWm5hW 0mOwvdx1L/mqx/BHqVU9Dw2COhOdLbFxlFI92chkovkmNk4P48ziyVnpm7ME22sE vfCMsyirdqB1mrL4CSM7FXONv+CgfBfeYVkYW8RfJac9U1L/O+JNn7yee414O/rS hRYw4UdWnH6Gg6niklVKWNY0ZwUZC8zgm2iqy8YCYuneS37jC+OEKP+/s6HSKuqk 2bzcl3/TcZXNSM815hnFRpz0anuyAsvwPNRyvxG2/DacJHL1f6luV4B0o6W410yf qXQx01DLo7nuyhJqoH3UGCyyXB+/QUs0mbG2PAEn3f5dVs31JMdbt+PrxURXXjKk 4cexpUcIpqqlfpIRe3RD0sDVbH4OXsGhi2kiTfPZu7mgyFxKopRbn1KwU1qKinfY EU9O4PoTak/tPT+5jFNhaP+HrURoi/pU8EAUNSktl7xAkHYwkN/9Cm7DeBghgf3n 8+tyCGYDsB5utPD0/Xe9yx0Qhc/kMm4xIyQDyA937dk3mUvLC9vulnAP8I+Izim0 fZ182+D1bWwykoD0997mUHG/AUChWR01V1OLwRyPv2wUtiS8VNG76Y2aqKlgqP1P V+IvIEqR4ERvSBVFzXNF8Y6j/sVxo8+aZw+d0L1Ns/R55deErGg3B8i/2EqGd3r+ 0jps9BqFHHWW87n3VyEB3jWCMj8Vi2EJIfa/7pSaViFIQn8LiBLf+zxG5LTOToK5 xkN42fReDcqi3UNfKNGnv4dsplyTR2hyx65lsj4bRKDGLKOuB1y7iB0AGb0LtcAI dcsVlcCeUquDXtqKvRnwfIMg+ZunyjqHBhj3qgRgbXbT6zjaSdNnih569aTg0Vup VykzZ7+n/KVcGLmvX0NesdoI7TKbq4TnEIOynuG5Sf+2GpARO5bjcWKSZeN/Ybgk gccf8Cqf6XWqiwlWd0B7BR3SymeHIaSymC45wmbgdstrbk7Ppa2Tp9AZku8M2Y7c 8mY9b+onK075/ypiwBm4L4GRNTFLnoNQJXx0OSl4FNRWsn6ztbD+jZhu8Seu10Jw SEJVJ+gmTKdRLYORJKyqhDet6g7kAxs4EoJ25WsOnX5nNr00rit+NkMPA7xbJT+7 CfI51GQLw7pUPeO2WNt6yZO/YkzZrqvTj5FEwybkUyBv7L0gkqu9wjfDdUw0fVHE xEm4DxjEoaIp8dW/JOzXQ2EF+WaSOgdYsw3Ac+rnnjnNptCdOEDGP6QBkt+oXj4P -----END RSA PRIVATE KEY-----""", passphrase='encrypted') # key with bad IV (DES3) self.assertRaises( keys.BadKeyError, keys.Key.fromString, b"""-----BEGIN ENCRYPTED RSA KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,01234 4Ed/a9OgJWHJsne7yOGWeWMzHYKsxuP9w1v0aYcp+puS75wvhHLiUnNwxz0KDi6n T3YkKLBsoCWS68ApR2J9yeQ6R+EyS+UQDrO9nwqo3DB5BT3Ggt8S1wE7vjNLQD0H g/SJnlqwsECNhh8aAx+Ag0m3ZKOZiRD5mCkcDQsZET7URSmFytDKOjhFn3u6ZFVB sXrfpYc6TJtOQlHd/52JB6aAbjt6afSv955Z7enIi+5yEJ5y7oYQTaE5zrFMP7N5 9LbfJFlKXxEddy/DErRLxEjmC+t4svHesoJKc2jjjyNPiOoGGF3kJXea62vsjdNV gMK5Eged3TBVIk2dv8rtJUvyFeCUtjQ1UJZIebScRR47KrbsIpCmU8I4/uHWm5hW 0mOwvdx1L/mqx/BHqVU9Dw2COhOdLbFxlFI92chkovkmNk4P48ziyVnpm7ME22sE vfCMsyirdqB1mrL4CSM7FXONv+CgfBfeYVkYW8RfJac9U1L/O+JNn7yee414O/rS hRYw4UdWnH6Gg6niklVKWNY0ZwUZC8zgm2iqy8YCYuneS37jC+OEKP+/s6HSKuqk 2bzcl3/TcZXNSM815hnFRpz0anuyAsvwPNRyvxG2/DacJHL1f6luV4B0o6W410yf qXQx01DLo7nuyhJqoH3UGCyyXB+/QUs0mbG2PAEn3f5dVs31JMdbt+PrxURXXjKk 4cexpUcIpqqlfpIRe3RD0sDVbH4OXsGhi2kiTfPZu7mgyFxKopRbn1KwU1qKinfY EU9O4PoTak/tPT+5jFNhaP+HrURoi/pU8EAUNSktl7xAkHYwkN/9Cm7DeBghgf3n 8+tyCGYDsB5utPD0/Xe9yx0Qhc/kMm4xIyQDyA937dk3mUvLC9vulnAP8I+Izim0 fZ182+D1bWwykoD0997mUHG/AUChWR01V1OLwRyPv2wUtiS8VNG76Y2aqKlgqP1P V+IvIEqR4ERvSBVFzXNF8Y6j/sVxo8+aZw+d0L1Ns/R55deErGg3B8i/2EqGd3r+ 0jps9BqFHHWW87n3VyEB3jWCMj8Vi2EJIfa/7pSaViFIQn8LiBLf+zxG5LTOToK5 xkN42fReDcqi3UNfKNGnv4dsplyTR2hyx65lsj4bRKDGLKOuB1y7iB0AGb0LtcAI dcsVlcCeUquDXtqKvRnwfIMg+ZunyjqHBhj3qgRgbXbT6zjaSdNnih569aTg0Vup VykzZ7+n/KVcGLmvX0NesdoI7TKbq4TnEIOynuG5Sf+2GpARO5bjcWKSZeN/Ybgk gccf8Cqf6XWqiwlWd0B7BR3SymeHIaSymC45wmbgdstrbk7Ppa2Tp9AZku8M2Y7c 8mY9b+onK075/ypiwBm4L4GRNTFLnoNQJXx0OSl4FNRWsn6ztbD+jZhu8Seu10Jw SEJVJ+gmTKdRLYORJKyqhDet6g7kAxs4EoJ25WsOnX5nNr00rit+NkMPA7xbJT+7 CfI51GQLw7pUPeO2WNt6yZO/YkzZrqvTj5FEwybkUyBv7L0gkqu9wjfDdUw0fVHE xEm4DxjEoaIp8dW/JOzXQ2EF+WaSOgdYsw3Ac+rnnjnNptCdOEDGP6QBkt+oXj4P -----END RSA PRIVATE KEY-----""", passphrase='encrypted') def test_fromFile(self): """ Test that fromFile works correctly. """ self.assertEqual(keys.Key.fromFile(self.keyFile), keys.Key.fromString(keydata.privateRSA_lsh)) self.assertRaises(keys.BadKeyError, keys.Key.fromFile, self.keyFile, 'bad_type') self.assertRaises(keys.BadKeyError, keys.Key.fromFile, self.keyFile, passphrase='unencrypted') def test_init(self): """ Test that the PublicKey object is initialized correctly. """ obj = keys.Key._fromRSAComponents(n=long(5), e=long(3))._keyObject key = keys.Key(obj) self.assertEqual(key._keyObject, obj) def test_equal(self): """ Test that Key objects are compared correctly. """ rsa1 = keys.Key(self.rsaObj) rsa2 = keys.Key(self.rsaObj) rsa3 = keys.Key( keys.Key._fromRSAComponents(n=long(5), e=long(3))._keyObject) dsa = keys.Key(self.dsaObj) self.assertTrue(rsa1 == rsa2) self.assertFalse(rsa1 == rsa3) self.assertFalse(rsa1 == dsa) self.assertFalse(rsa1 == object) self.assertFalse(rsa1 == None) def test_notEqual(self): """ Test that Key objects are not-compared correctly. """ rsa1 = keys.Key(self.rsaObj) rsa2 = keys.Key(self.rsaObj) rsa3 = keys.Key( keys.Key._fromRSAComponents(n=long(5), e=long(3))._keyObject) dsa = keys.Key(self.dsaObj) self.assertFalse(rsa1 != rsa2) self.assertTrue(rsa1 != rsa3) self.assertTrue(rsa1 != dsa) self.assertTrue(rsa1 != object) self.assertTrue(rsa1 != None) def test_dataError(self): """ The L{keys.Key.data} method raises RuntimeError for bad keys. """ badKey = keys.Key(b'') self.assertRaises(RuntimeError, badKey.data) def test_fingerprintdefault(self): """ Test that the fingerprint method returns fingerprint in L{FingerprintFormats.MD5-HEX} format by default. """ self.assertEqual(keys.Key(self.rsaObj).fingerprint(), '3d:13:5f:cb:c9:79:8a:93:06:27:65:bc:3d:0b:8f:af') self.assertEqual(keys.Key(self.dsaObj).fingerprint(), '63:15:b3:0e:e6:4f:50:de:91:48:3d:01:6b:b3:13:c1') def test_fingerprint_md5_hex(self): """ fingerprint method generates key fingerprint in L{FingerprintFormats.MD5-HEX} format if explicitly specified. """ self.assertEqual( keys.Key(self.rsaObj).fingerprint( keys.FingerprintFormats.MD5_HEX), '3d:13:5f:cb:c9:79:8a:93:06:27:65:bc:3d:0b:8f:af') self.assertEqual( keys.Key(self.dsaObj).fingerprint( keys.FingerprintFormats.MD5_HEX), '63:15:b3:0e:e6:4f:50:de:91:48:3d:01:6b:b3:13:c1') def test_fingerprintsha256(self): """ fingerprint method generates key fingerprint in L{FingerprintFormats.SHA256-BASE64} format if explicitly specified. """ self.assertEqual( keys.Key(self.rsaObj).fingerprint( keys.FingerprintFormats.SHA256_BASE64), 'ryaugIFT0B8ItuszldMEU7q14rG/wj9HkRosMeBWkts=') self.assertEqual( keys.Key(self.dsaObj).fingerprint( keys.FingerprintFormats.SHA256_BASE64), 'Wz5o2YbKyxOEcJn1au/UaALSVruUzfz0vaLI1xiIGyY=') def test_fingerprintBadFormat(self): """ A C{BadFingerPrintFormat} error is raised when unsupported formats are requested. """ with self.assertRaises(keys.BadFingerPrintFormat) as em: keys.Key(self.rsaObj).fingerprint('sha256-base') self.assertEqual('Unsupported fingerprint format: sha256-base', em.exception.args[0]) def test_type(self): """ Test that the type method returns the correct type for an object. """ self.assertEqual(keys.Key(self.rsaObj).type(), 'RSA') self.assertEqual(keys.Key(self.rsaObj).sshType(), b'ssh-rsa') self.assertEqual(keys.Key(self.dsaObj).type(), 'DSA') self.assertEqual(keys.Key(self.dsaObj).sshType(), b'ssh-dss') self.assertEqual(keys.Key(self.ecObj).type(), 'EC') self.assertEqual(keys.Key(self.ecObj).sshType(), keydata.ECDatanistp256['curve']) self.assertRaises(RuntimeError, keys.Key(None).type) self.assertRaises(RuntimeError, keys.Key(None).sshType) self.assertRaises(RuntimeError, keys.Key(self).type) self.assertRaises(RuntimeError, keys.Key(self).sshType) def test_fromBlobUnsupportedType(self): """ A C{BadKeyError} error is raised whey the blob has an unsupported key type. """ badBlob = common.NS(b'ssh-bad') self.assertRaises(keys.BadKeyError, keys.Key.fromString, badBlob) def test_fromBlobRSA(self): """ A public RSA key is correctly generated from a public key blob. """ rsaPublicData = { 'n': keydata.RSAData['n'], 'e': keydata.RSAData['e'], } rsaBlob = ( common.NS(b'ssh-rsa') + common.MP(rsaPublicData['e']) + common.MP(rsaPublicData['n']) ) rsaKey = keys.Key.fromString(rsaBlob) self.assertTrue(rsaKey.isPublic()) self.assertEqual(rsaPublicData, rsaKey.data()) def test_fromBlobDSA(self): """ A public DSA key is correctly generated from a public key blob. """ dsaPublicData = { 'p': keydata.DSAData['p'], 'q': keydata.DSAData['q'], 'g': keydata.DSAData['g'], 'y': keydata.DSAData['y'], } dsaBlob = ( common.NS(b'ssh-dss') + common.MP(dsaPublicData['p']) + common.MP(dsaPublicData['q']) + common.MP(dsaPublicData['g']) + common.MP(dsaPublicData['y']) ) dsaKey = keys.Key.fromString(dsaBlob) self.assertTrue(dsaKey.isPublic()) self.assertEqual(dsaPublicData, dsaKey.data()) def test_fromBlobECDSA(self): """ Key.fromString generates ECDSA keys from blobs. """ from cryptography import utils ecPublicData = { 'x': keydata.ECDatanistp256['x'], 'y': keydata.ECDatanistp256['y'], 'curve': keydata.ECDatanistp256['curve'] } ecblob = (common.NS(ecPublicData['curve']) + common.NS(ecPublicData['curve'][-8:]) + common.NS(b'\x04' + utils.int_to_bytes(ecPublicData['x'], 32) + utils.int_to_bytes(ecPublicData['y'], 32)) ) eckey = keys.Key.fromString(ecblob) self.assertTrue(eckey.isPublic()) self.assertEqual(ecPublicData, eckey.data()) def test_fromPrivateBlobUnsupportedType(self): """ C{BadKeyError} is raised when loading a private blob with an unsupported type. """ badBlob = common.NS(b'ssh-bad') self.assertRaises( keys.BadKeyError, keys.Key._fromString_PRIVATE_BLOB, badBlob) def test_fromPrivateBlobRSA(self): """ A private RSA key is correctly generated from a private key blob. """ rsaBlob = ( common.NS(b'ssh-rsa') + common.MP(keydata.RSAData['n']) + common.MP(keydata.RSAData['e']) + common.MP(keydata.RSAData['d']) + common.MP(keydata.RSAData['u']) + common.MP(keydata.RSAData['p']) + common.MP(keydata.RSAData['q']) ) rsaKey = keys.Key._fromString_PRIVATE_BLOB(rsaBlob) self.assertFalse(rsaKey.isPublic()) self.assertEqual(keydata.RSAData, rsaKey.data()) def test_fromPrivateBlobDSA(self): """ A private DSA key is correctly generated from a private key blob. """ dsaBlob = ( common.NS(b'ssh-dss') + common.MP(keydata.DSAData['p']) + common.MP(keydata.DSAData['q']) + common.MP(keydata.DSAData['g']) + common.MP(keydata.DSAData['y']) + common.MP(keydata.DSAData['x']) ) dsaKey = keys.Key._fromString_PRIVATE_BLOB(dsaBlob) self.assertFalse(dsaKey.isPublic()) self.assertEqual(keydata.DSAData, dsaKey.data()) def test_fromPrivateBlobECDSA(self): """ A private EC key is correctly generated from a private key blob. """ ecblob = ( common.NS(keydata.ECDatanistp256['curve']) + common.MP(keydata.ECDatanistp256['x']) + common.MP(keydata.ECDatanistp256['y']) + common.MP(keydata.ECDatanistp256['privateValue']) ) eckey = keys.Key._fromString_PRIVATE_BLOB(ecblob) self.assertFalse(eckey.isPublic()) self.assertEqual(keydata.ECDatanistp256, eckey.data()) def test_blobRSA(self): """ Return the over-the-wire SSH format of the RSA public key. """ self.assertEqual( keys.Key(self.rsaObj).blob(), common.NS(b'ssh-rsa') + common.MP(self.rsaObj.private_numbers().public_numbers.e) + common.MP(self.rsaObj.private_numbers().public_numbers.n) ) def test_blobDSA(self): """ Return the over-the-wire SSH format of the DSA public key. """ publicNumbers = self.dsaObj.private_numbers().public_numbers self.assertEqual( keys.Key(self.dsaObj).blob(), common.NS(b'ssh-dss') + common.MP(publicNumbers.parameter_numbers.p) + common.MP(publicNumbers.parameter_numbers.q) + common.MP(publicNumbers.parameter_numbers.g) + common.MP(publicNumbers.y) ) def test_blobEC(self): """ Return the over-the-wire SSH format of the EC public key. """ from cryptography import utils byteLength = (self.ecObj.curve.key_size + 7) // 8 self.assertEqual( keys.Key(self.ecObj).blob(), common.NS(keydata.ECDatanistp256['curve']) + common.NS(keydata.ECDatanistp256['curve'][-8:]) + common.NS(b'\x04' + utils.int_to_bytes( self.ecObj.private_numbers().public_numbers.x, byteLength) + utils.int_to_bytes( self.ecObj.private_numbers().public_numbers.y, byteLength)) ) def test_blobNoKey(self): """ C{RuntimeError} is raised when the blob is requested for a Key which is not wrapping anything. """ badKey = keys.Key(None) self.assertRaises(RuntimeError, badKey.blob) def test_privateBlobRSA(self): """ L{keys.Key.privateBlob} returns the SSH protocol-level format of an RSA private key. """ from cryptography.hazmat.primitives.asymmetric import rsa numbers = self.rsaObj.private_numbers() u = rsa.rsa_crt_iqmp(numbers.q, numbers.p) self.assertEqual( keys.Key(self.rsaObj).privateBlob(), common.NS(b'ssh-rsa') + common.MP(self.rsaObj.private_numbers().public_numbers.n) + common.MP(self.rsaObj.private_numbers().public_numbers.e) + common.MP(self.rsaObj.private_numbers().d) + common.MP(u) + common.MP(self.rsaObj.private_numbers().p) + common.MP(self.rsaObj.private_numbers().q) ) def test_privateBlobDSA(self): """ L{keys.Key.privateBlob} returns the SSH protocol-level format of a DSA private key. """ publicNumbers = self.dsaObj.private_numbers().public_numbers self.assertEqual( keys.Key(self.dsaObj).privateBlob(), common.NS(b'ssh-dss') + common.MP(publicNumbers.parameter_numbers.p) + common.MP(publicNumbers.parameter_numbers.q) + common.MP(publicNumbers.parameter_numbers.g) + common.MP(publicNumbers.y) + common.MP(self.dsaObj.private_numbers().x) ) def test_privateBlobEC(self): """ L{keys.Key.privateBlob} returns the SSH ptotocol-level format of EC private key. """ self.assertEqual( keys.Key(self.ecObj).privateBlob(), common.NS(keydata.ECDatanistp256['curve']) + common.MP(self.ecObj.private_numbers().public_numbers.x) + common.MP(self.ecObj.private_numbers().public_numbers.y) + common.MP(self.ecObj.private_numbers().private_value) ) def test_privateBlobNoKeyObject(self): """ Raises L{RuntimeError} if the underlying key object does not exists. """ badKey = keys.Key(None) self.assertRaises(RuntimeError, badKey.privateBlob) def test_toOpenSSHRSA(self): """ L{keys.Key.toString} serializes an RSA key in OpenSSH format. """ key = keys.Key.fromString(keydata.privateRSA_agentv3) self.assertEqual(key.toString('openssh'), keydata.privateRSA_openssh) self.assertEqual(key.toString('openssh', b'encrypted'), keydata.privateRSA_openssh_encrypted) self.assertEqual(key.public().toString('openssh'), keydata.publicRSA_openssh[:-8]) # no comment self.assertEqual(key.public().toString('openssh', b'comment'), keydata.publicRSA_openssh) def test_toOpenSSHDSA(self): """ L{keys.Key.toString} serializes a DSA key in OpenSSH format. """ key = keys.Key.fromString(keydata.privateDSA_lsh) self.assertEqual(key.toString('openssh'), keydata.privateDSA_openssh) self.assertEqual(key.public().toString('openssh', b'comment'), keydata.publicDSA_openssh) self.assertEqual(key.public().toString('openssh'), keydata.publicDSA_openssh[:-8]) # no comment def test_toOpenSSHECDSA(self): """ L{keys.Key.toString} serializes a ECDSA key in OpenSSH format. """ key = keys.Key.fromString(keydata.privateECDSA_openssh) self.assertEqual(key.public().toString('openssh', b'comment'), keydata.publicECDSA_openssh) self.assertEqual(key.public().toString('openssh'), keydata.publicECDSA_openssh[:-8]) # no comment def test_toLSHRSA(self): """ L{keys.Key.toString} serializes an RSA key in LSH format. """ key = keys.Key.fromString(keydata.privateRSA_openssh) self.assertEqual(key.toString('lsh'), keydata.privateRSA_lsh) self.assertEqual(key.public().toString('lsh'), keydata.publicRSA_lsh) def test_toLSHDSA(self): """ L{keys.Key.toString} serializes a DSA key in LSH format. """ key = keys.Key.fromString(keydata.privateDSA_openssh) self.assertEqual(key.toString('lsh'), keydata.privateDSA_lsh) self.assertEqual(key.public().toString('lsh'), keydata.publicDSA_lsh) def test_toAgentv3RSA(self): """ L{keys.Key.toString} serializes an RSA key in Agent v3 format. """ key = keys.Key.fromString(keydata.privateRSA_openssh) self.assertEqual(key.toString('agentv3'), keydata.privateRSA_agentv3) def test_toAgentv3DSA(self): """ L{keys.Key.toString} serializes a DSA key in Agent v3 format. """ key = keys.Key.fromString(keydata.privateDSA_openssh) self.assertEqual(key.toString('agentv3'), keydata.privateDSA_agentv3) def test_toStringErrors(self): """ L{keys.Key.toString} raises L{keys.BadKeyError} when passed an invalid format type. """ self.assertRaises(keys.BadKeyError, keys.Key(self.rsaObj).toString, 'bad_type') def test_signAndVerifyRSA(self): """ Signed data can be verified using RSA. """ data = b'some-data' key = keys.Key.fromString(keydata.privateRSA_openssh) signature = key.sign(data) self.assertTrue(key.public().verify(signature, data)) self.assertTrue(key.verify(signature, data)) def test_signAndVerifyDSA(self): """ Signed data can be verified using DSA. """ data = b'some-data' key = keys.Key.fromString(keydata.privateDSA_openssh) signature = key.sign(data) self.assertTrue(key.public().verify(signature, data)) self.assertTrue(key.verify(signature, data)) def test_signAndVerifyEC(self): """ Signed data can be verified using EC. """ data = b'some-data' key = keys.Key.fromString(keydata.privateECDSA_openssh) signature = key.sign(data) key384 = keys.Key.fromString(keydata.privateECDSA_openssh384) signature384 = key384.sign(data) key521 = keys.Key.fromString(keydata.privateECDSA_openssh521) signature521 = key521.sign(data) self.assertTrue(key.public().verify(signature, data)) self.assertTrue(key.verify(signature, data)) self.assertTrue(key384.public().verify(signature384, data)) self.assertTrue(key384.verify(signature384, data)) self.assertTrue(key521.public().verify(signature521, data)) self.assertTrue(key521.verify(signature521, data)) def test_verifyRSA(self): """ A known-good RSA signature verifies successfully. """ key = keys.Key.fromString(keydata.publicRSA_openssh) self.assertTrue(key.verify(self.rsaSignature, b'')) self.assertFalse(key.verify(self.rsaSignature, b'a')) self.assertFalse(key.verify(self.dsaSignature, b'')) def test_verifyDSA(self): """ A known-good DSA signature verifies successfully. """ key = keys.Key.fromString(keydata.publicDSA_openssh) self.assertTrue(key.verify(self.dsaSignature, b'')) self.assertFalse(key.verify(self.dsaSignature, b'a')) self.assertFalse(key.verify(self.rsaSignature, b'')) def test_verifyDSANoPrefix(self): """ Some commercial SSH servers send DSA keys as 2 20-byte numbers; they are still verified as valid keys. """ key = keys.Key.fromString(keydata.publicDSA_openssh) self.assertTrue(key.verify(self.dsaSignature[-40:], b'')) def test_reprPrivateRSA(self): """ The repr of a L{keys.Key} contains all of the RSA components for an RSA private key. """ self.assertEqual(repr(keys.Key(self.rsaObj)), """<RSA Private Key (768 bits) attr d: \t6e:1f:b5:55:97:eb:ed:67:ed:2b:99:6e:ec:c1:ed: \ta8:4d:52:d6:f3:d6:65:06:04:df:e5:54:9f:cc:89: \t00:3c:9b:67:87:ec:65:a0:ab:cd:6f:65:90:8a:97: \t90:4d:c6:21:8f:a8:8d:d8:59:86:43:b5:81:b1:b4: \td7:5f:2c:22:0a:61:c1:25:8a:47:12:b4:9a:f8:7a: \t11:1c:4a:a8:8b:75:c4:91:09:3b:be:04:ca:45:d9: \t57:8a:0d:27:cb:23 attr e: \t23 attr n: \t00:af:32:71:f0:e6:0e:9c:99:b3:7f:8b:5f:04:4b: \tcb:8b:c0:d5:3e:b2:77:fd:cf:64:d8:8f:c0:cf:ae: \t1f:c6:31:df:f6:29:b2:44:96:e2:c6:d4:21:94:7f: \t65:7c:d8:d4:23:1f:b8:2e:6a:c9:1f:94:0d:46:c1: \t69:a2:b7:07:0c:a3:93:c1:34:d8:2e:1e:4a:99:1a: \t6c:96:46:07:46:2b:dc:25:29:1b:87:f0:be:05:1d: \tee:b4:34:b9:e7:99:95 attr p: \t00:cb:4a:4b:d0:40:47:e8:45:52:f7:c7:af:0c:20: \t6d:43:0d:b6:39:94:f9:da:a5:e5:03:06:76:83:24: \teb:88:a1:55:a2:a8:de:12:3b:77:49:92:8a:a9:71: \td2:02:93:ff attr q: \t00:dc:9f:6b:d9:98:21:56:11:8d:e9:5f:03:9d:0a: \td3:93:6e:13:77:41:3c:85:4f:00:70:fd:05:54:ff: \tbc:3d:09:bf:83:f6:97:7f:64:10:91:04:fe:a2:67: \t47:54:42:6b attr u: \t00:b4:73:97:4b:50:10:a3:17:b3:a8:47:f1:3a:14: \t76:52:d1:38:2a:cf:12:14:34:c1:a8:54:4c:29:35: \t80:a0:38:b8:f0:fa:4c:c4:c2:85:ab:db:87:82:ba: \tdc:eb:db:2a>""") def test_reprPublicRSA(self): """ The repr of a L{keys.Key} contains all of the RSA components for an RSA public key. """ self.assertEqual(repr(keys.Key(self.rsaObj).public()), """<RSA Public Key (768 bits) attr e: \t23 attr n: \t00:af:32:71:f0:e6:0e:9c:99:b3:7f:8b:5f:04:4b: \tcb:8b:c0:d5:3e:b2:77:fd:cf:64:d8:8f:c0:cf:ae: \t1f:c6:31:df:f6:29:b2:44:96:e2:c6:d4:21:94:7f: \t65:7c:d8:d4:23:1f:b8:2e:6a:c9:1f:94:0d:46:c1: \t69:a2:b7:07:0c:a3:93:c1:34:d8:2e:1e:4a:99:1a: \t6c:96:46:07:46:2b:dc:25:29:1b:87:f0:be:05:1d: \tee:b4:34:b9:e7:99:95>""") def test_reprPublicECDSA(self): """ The repr of a L{keys.Key} contains all the OpenSSH format for an ECDSA public key. """ self.assertEqual(repr(keys.Key(self.ecObj).public()), """<Elliptic Curve Public Key (256 bits) curve: \tecdsa-sha2-nistp256 x: \t76282513020392096317118503144964731774299773481750550543382904345687059013883 y:""" + "\n\t8154319786460285263226566476944164753434437589431431968106113715931064" + "6683104>\n") def test_reprPrivateECDSA(self): """ The repr of a L{keys.Key} contains all the OpenSSH format for an ECDSA private key. """ self.assertEqual(repr(keys.Key(self.ecObj)), """<Elliptic Curve Private Key (256 bits) curve: \tecdsa-sha2-nistp256 privateValue: \t34638743477210341700964008455655698253555655678826059678074967909361042656500 x: \t76282513020392096317118503144964731774299773481750550543382904345687059013883 y:""" + "\n\t8154319786460285263226566476944164753434437589431431968106113715931064" + "6683104>\n") class KeyKeyObjectTests(unittest.TestCase): """ The L{keys.Key.keyObject} property provides deprecated access to a PyCrypto key instance of the corresponding type. """ if cryptography is None: skip = skipCryptography if Crypto is None: skip = skipPyCrypto def test_deprecation(self): """ Accessing the L{keys.Key.keyObject} property emits a deprecation warning. """ keys.Key.fromString(keydata.publicRSA_openssh).keyObject [warning] = self.flushWarnings([KeyKeyObjectTests.test_deprecation]) self.assertIs(warning['category'], DeprecationWarning) def test_keyObjectGetRSAPublic(self): """ The PyCrypto key instance for an RSA public key has the same components as the internal key. """ key = keys.Key.fromString(keydata.publicRSA_openssh) result = key.keyObject self.assertIsInstance(result, Crypto.PublicKey.RSA._RSAobj) self.assertEqual(keydata.RSAData['e'], result.key.e) self.assertEqual(keydata.RSAData['n'], result.key.n) def test_keyObjectGetRSAPrivate(self): """ The PyCrypto key instance for an RSA private key has the same components as the internal key. """ key = keys.Key.fromString(keydata.privateRSA_openssh) result = key.keyObject self.assertIsInstance(result, Crypto.PublicKey.RSA._RSAobj) self.assertEqual(keydata.RSAData['e'], result.key.e) self.assertEqual(keydata.RSAData['n'], result.key.n) self.assertEqual(keydata.RSAData['d'], result.key.d) self.assertEqual(keydata.RSAData['p'], result.key.p) self.assertEqual(keydata.RSAData['q'], result.key.q) self.assertEqual(keydata.RSAData['u'], result.key.u) def test_keyObjectGetDSAPublic(self): """ The PyCrypto key instance for a DSA public key has the same components as the internal key. """ key = keys.Key.fromString(keydata.publicDSA_openssh) result = key.keyObject self.assertIsInstance(result, Crypto.PublicKey.DSA._DSAobj) self.assertEqual(keydata.DSAData['y'], result.key.y) self.assertEqual(keydata.DSAData['g'], result.key.g) self.assertEqual(keydata.DSAData['p'], result.key.p) self.assertEqual(keydata.DSAData['q'], result.key.q) def test_keyObjectGetDSAPrivate(self): """ The PyCrypto key instance for a DSA private key has the same components as the internal key. """ key = keys.Key.fromString(keydata.privateDSA_openssh) result = key.keyObject self.assertIsInstance(result, Crypto.PublicKey.DSA._DSAobj) self.assertEqual(keydata.DSAData['y'], result.key.y) self.assertEqual(keydata.DSAData['g'], result.key.g) self.assertEqual(keydata.DSAData['p'], result.key.p) self.assertEqual(keydata.DSAData['q'], result.key.q) self.assertEqual(keydata.DSAData['x'], result.key.x) def test_keyObjectSetRSAPublic(self): """ Setting the L{keys.Key.keyObject} property to a PyCrypto public RSA key instance updates the internal key. """ key = keys.Key.fromString(keydata.publicDSA_openssh) newPyCryptoKey = Crypto.PublicKey.RSA.construct(( keydata.RSAData['n'], keydata.RSAData['e'], )) self.assertEqual('DSA', key.type()) key.keyObject = newPyCryptoKey [warning] = self.flushWarnings([ KeyKeyObjectTests.test_keyObjectSetRSAPublic]) self.assertIs(warning['category'], DeprecationWarning) self.assertEqual('RSA', key.type()) self.assertEqual({ 'n': keydata.RSAData['n'], 'e': keydata.RSAData['e'], }, key.data()) def test_keyObjectSetRSAPrivate(self): """ Setting the L{keys.Key.keyObject} property to a PyCrypto private RSA key instance updates the internal key. """ key = keys.Key.fromString(keydata.publicDSA_openssh) newPyCryptoKey = Crypto.PublicKey.RSA.construct(( keydata.RSAData['n'], keydata.RSAData['e'], keydata.RSAData['d'], keydata.RSAData['p'], keydata.RSAData['q'], keydata.RSAData['u'], )) self.assertEqual('DSA', key.type()) key.keyObject = newPyCryptoKey self.assertEqual('RSA', key.type()) self.assertEqual({ 'n': keydata.RSAData['n'], 'e': keydata.RSAData['e'], 'd': keydata.RSAData['d'], 'p': keydata.RSAData['p'], 'q': keydata.RSAData['q'], 'u': keydata.RSAData['u'], }, key.data()) def test_keyObjectSetDSAPublic(self): """ Setting the L{keys.Key.keyObject} property to a PyCrypto public DSA key instance updates the internal key. """ key = keys.Key.fromString(keydata.publicRSA_openssh) newPyCryptoKey = Crypto.PublicKey.DSA.construct(( keydata.DSAData['y'], keydata.DSAData['g'], keydata.DSAData['p'], keydata.DSAData['q'], )) self.assertEqual('RSA', key.type()) key.keyObject = newPyCryptoKey self.assertEqual('DSA', key.type()) self.assertEqual({ 'y': keydata.DSAData['y'], 'g': keydata.DSAData['g'], 'p': keydata.DSAData['p'], 'q': keydata.DSAData['q'], }, key.data()) def test_keyObjectSetDSAPrivate(self): """ Setting the L{keys.Key.keyObject} property to a PyCrypto private DSA key instance updates the internal key. """ key = keys.Key.fromString(keydata.publicRSA_openssh) newPyCryptoKey = Crypto.PublicKey.DSA.construct(( keydata.DSAData['y'], keydata.DSAData['g'], keydata.DSAData['p'], keydata.DSAData['q'], keydata.DSAData['x'], )) self.assertEqual('RSA', key.type()) key.keyObject = newPyCryptoKey self.assertEqual('DSA', key.type()) self.assertEqual({ 'y': keydata.DSAData['y'], 'g': keydata.DSAData['g'], 'p': keydata.DSAData['p'], 'q': keydata.DSAData['q'], 'x': keydata.DSAData['x'], }, key.data()) def test_constructorPyCrypto(self): """ Passing a PyCrypto key object to L{keys.Key} is deprecated. """ pycryptoKey = Crypto.PublicKey.RSA.construct(( keydata.RSAData['n'], keydata.RSAData['e'])) key = self.callDeprecated( (Version('Twisted', 16, 0, 0), 'passing a cryptography key object'), keys.Key, pycryptoKey) self.assertEqual('RSA', key.type()) self.assertEqual({ 'n': keydata.RSAData['n'], 'e': keydata.RSAData['e'], }, key.data()) class PersistentRSAKeyTests(unittest.TestCase): """ Tests for L{keys._getPersistentRSAKey}. """ if cryptography is None: skip = skipCryptography def test_providedArguments(self): """ L{keys._getPersistentRSAKey} will put the key in C{directory}/C{filename}, with the key length of C{keySize}. """ tempDir = FilePath(self.mktemp()) keyFile = tempDir.child("mykey.pem") key = keys._getPersistentRSAKey(keyFile, keySize=512) self.assertEqual(key.size(), 512) self.assertTrue(keyFile.exists()) def test_noRegeneration(self): """ L{keys._getPersistentRSAKey} will not regenerate the key if the key already exists. """ tempDir = FilePath(self.mktemp()) keyFile = tempDir.child("mykey.pem") key = keys._getPersistentRSAKey(keyFile, keySize=512) self.assertEqual(key.size(), 512) self.assertTrue(keyFile.exists()) keyContent = keyFile.getContent() # Set the key size to 1024 bits. Since it exists already, it will find # the 512 bit key, and not generate a 1024 bit key. key = keys._getPersistentRSAKey(keyFile, keySize=1024) self.assertEqual(key.size(), 512) self.assertEqual(keyFile.getContent(), keyContent) def test_keySizeZero(self): """ If the key generated by L{keys.getPersistentRSAKey} is set to None the key size should then become 0. """ tempDir = FilePath(self.mktemp()) keyFile = tempDir.child("mykey.pem") key = keys._getPersistentRSAKey(keyFile, keySize=512) key._keyObject = None self.assertEqual( key.size(), 0)