def test_init_dsa(self): """ Check generation of a DSA key. """ key = Key() key.generate(key_type=crypto.TYPE_DSA, key_size=1024) self.assertEqual('DSA', key.type()) self.assertEqual(1024, key.size)
def test_key_init_unknown_type(self): """ An error is raised when generating a key with unknow type. """ with self.assertRaises(UtilsError) as context: key = Key(None) key.generate(key_type=0) self.assertEqual(u'1003', context.exception.event_id)
def test_key_store_comment(self): """ When serializing a SSH public key to a file, a random comment can be added. """ key = Key.fromString(data=RSA_PUBLIC_KEY_OPENSSH) public_file = StringIO() comment = mk.string() public_key_serialization = u'%s %s' % ( RSA_PUBLIC_KEY_OPENSSH, comment) key.store(public_file=public_file, comment=comment) result_key = Key.fromString(public_file.getvalue()) self.assertEqual(key.data, result_key.data) self.assertEqual( public_file.getvalue().decode('utf-8'), public_key_serialization)
def test_key_store_dsa(self): """ Check file serialization for a DSA key. """ key = Key.fromString(data=DSA_PRIVATE_KEY) public_file = StringIO() private_file = StringIO() key.store(private_file=private_file, public_file=public_file) self.assertEqual(DSA_PRIVATE_KEY, private_file.getvalue()) self.assertEqual(DSA_PUBLIC_KEY_OPENSSH, public_file.getvalue())
def test_generate_ssh_key_pair(self): """ Private key is generated in the specified path, and the public key is generated on a path based on private key path. """ private_path, self.private_segments = mk.fs.makePathInTemp() public_path = u"%s.pub" % (private_path) self.public_segments = self.private_segments[:] self.public_segments[-1] = u"%s.pub" % (self.public_segments[-1]) comment = u"%s %s" % (mk.string(), mk.string()) # The current code doesn't allow creating smaller keys, so at 1024 # bit, this test is very slow. options = self.Bunch(key_size=1024, key_type="rsa", key_file=private_path, key_comment=comment) private_path = LocalFilesystem.getEncodedPath(private_path) public_path = LocalFilesystem.getEncodedPath(public_path) self.assertFalse(mk.fs.exists(self.private_segments)) self.assertFalse(mk.fs.exists(self.public_segments)) generate_ssh_key(options) self.assertTrue(mk.fs.exists(self.private_segments)) self.assertTrue(mk.fs.exists(self.public_segments)) # Check content of private key. private_key = Key.fromFile(filename=private_path) self.assertEqual(1024, private_key.size) self.assertIsFalse(private_key.isPublic()) self.assertEqual("RSA", private_key.type()) # Check content of public key. public_key = Key.fromFile(filename=public_path) self.assertEqual(1024, public_key.size) self.assertIsTrue(public_key.isPublic()) self.assertEqual("RSA", public_key.type()) # Check that public key is the pair of private key. private_data = private_key.data() public_data = public_key.data() self.assertEqual(private_data["e"], public_data["e"]) self.assertEqual(private_data["n"], public_data["n"])
def generate_ssh_key(options, key=None, open_method=None): """ Generate a SSH RSA or DSA key. Return a pair of (exit_code, operation_message). For success, exit_code is 0. `key` and `open_method` are helpers for dependency injection during tests. """ if key is None: from chevah.utils.crypto import Key key = Key() if open_method is None: open_method = open exit_code = 0 message = '' try: key_size = options.key_size if options.key_type.lower() == u'rsa': key_type = crypto.TYPE_RSA elif options.key_type.lower() == u'dsa': key_type = crypto.TYPE_DSA else: key_type = options.key_type if not hasattr(options, 'key_file') or options.key_file is None: options.key_file = 'id_%s' % (options.key_type.lower()) private_file = options.key_file public_file = u'%s%s' % ( options.key_file, DEFAULT_PUBLIC_KEY_EXTENSION) key.generate(key_type=key_type, key_size=key_size) private_file_path = LocalFilesystem.getEncodedPath(private_file) public_file_path = LocalFilesystem.getEncodedPath(public_file) with open_method(private_file_path, 'wb') as file_handler: key.store(private_file=file_handler) key_comment = None if hasattr(options, 'key_comment') and options.key_comment: key_comment = options.key_comment message_comment = u'having comment "%s"' % key_comment else: message_comment = u'without a comment' with open_method(public_file_path, 'wb') as file_handler: key.store(public_file=file_handler, comment=key_comment) message = ( u'SSH key of type "%s" and length "%d" generated as ' u'public key file "%s" and private key file "%s" %s.') % ( options.key_type, key_size, public_file, private_file, message_comment, ) exit_code = 0 except UtilsError, error: exit_code = 1 message = unicode(error)