def test_4_misc(self): msg = Message(self.__d) self.assertEquals(msg.get_int(), 5) self.assertEquals(msg.get_mpint(), 0x1122334455L) self.assertEquals(msg.get_so_far(), self.__d[:13]) self.assertEquals(msg.get_remainder(), self.__d[13:]) msg.rewind() self.assertEquals(msg.get_int(), 5) self.assertEquals(msg.get_so_far(), self.__d[:4]) self.assertEquals(msg.get_remainder(), self.__d[4:])
def test_4_misc(self): msg = Message(self.__d) self.assertEquals(msg.get_int(), 5) self.assertEquals(msg.get_mpint(), 0x1122334455) self.assertEquals(msg.get_so_far(), self.__d[:13]) self.assertEquals(msg.get_remainder(), self.__d[13:]) msg.rewind() self.assertEquals(msg.get_int(), 5) self.assertEquals(msg.get_so_far(), self.__d[:4]) self.assertEquals(msg.get_remainder(), self.__d[4:])
def test_4_misc(self): msg = Message(self.__d) self.assertEqual(msg.get_adaptive_int(), 5) self.assertEqual(msg.get_adaptive_int(), 0x1122334455) self.assertEqual(msg.get_adaptive_int(), 0xf00000000000000000) self.assertEqual(msg.get_so_far(), self.__d[:29]) self.assertEqual(msg.get_remainder(), self.__d[29:]) msg.rewind() self.assertEqual(msg.get_adaptive_int(), 5) self.assertEqual(msg.get_so_far(), self.__d[:4]) self.assertEqual(msg.get_remainder(), self.__d[4:])
def test_misc(self): msg = Message(self.__d) self.assertEqual(msg.get_int(), 5) self.assertEqual(msg.get_boolean(), True) self.assertEqual(msg.get_text(), 'cat') self.assertEqual(msg.get_so_far(), self.__d[:12]) self.assertEqual(msg.get_remainder(), self.__d[12:])
def _from_message(self, msg): """ Internal fuction to parse the contents of a certificate. There are several pieces of information to be parsed specificed by PROTOCOL.certkeys in the OpenSSH source code. string cert_key_type (i.e. "*****@*****.**") string nonce various public key data : Fields and types dependent on key type uint64 serial uint32 type string key_id string principals : Message containing a list of principals uint64 valid_after uint64 valid_before string critical_options : Message containing various critical options string extensions : Mesage containing optional extensions string reserved string signature_key string signature :param .Message msg: An instance of a paramiko.message.Message containing the certificate data. """ cert_key_type = msg.get_text() self.nonce = msg.get_binary() # Use the _key_parsers dictionary to look up the appropriate key # parser to read the key. Then dispatch to that function to do the # actual reading of the key data. key_parser = self._key_parsers.get(cert_key_type) if key_parser is None: err = "Unknown cert key type {}".format(cert_key_type) raise SSHException(err) self.key = key_parser(msg) self.serial = msg.get_int64() self.type = msg.get_int() self.key_id = msg.get_text() principals_msg = Message(msg.get_binary()) while principals_msg.get_remainder(): self.principals.append(principals_msg.get_text()) self.valid_after = msg.get_int64() self.valid_before = msg.get_int64() copts_msg = Message(msg.get_binary()) while copts_msg.get_remainder(): opt = copts_msg.get_text() val_msg = Message(copts_msg.get_binary()) val = val_msg.get_text() self.set_critical_option(opt, val) ext_msg = Message(msg.get_binary()) while ext_msg.get_remainder(): ext = ext_msg.get_text() val = ext_msg.get_binary() self.extensions[ext] = val self.reserved = msg.get_string() self.signature_key = msg.get_binary() self._body_bytes = msg.get_so_far() self.signature = msg.get_binary() self._bytes = msg.get_so_far()
def _read_private_key_new_format(data, password): """ Read the new OpenSSH SSH2 private key format available since OpenSSH version 6.5 Reference: https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key https://coolaj86.com/articles/the-openssh-private-key-format/ """ message = Message(data) OPENSSH_AUTH_MAGIC = b"openssh-key-v1\x00" if message.get_bytes(len(OPENSSH_AUTH_MAGIC)) != OPENSSH_AUTH_MAGIC: raise SSHException("unexpected OpenSSH key header encountered") cipher = message.get_text() kdfname = message.get_text() kdfoptions = message.get_binary() num_keys = message.get_int() if num_keys > 1: raise SSHException( "unsupported: private keyfile has multiple keys") public_data = message.get_binary() privkey_blob = message.get_binary() pub_keytype = Message(public_data).get_text() if kdfname == "none": if kdfoptions or cipher != "none": raise SSHException("Invalid key options for kdf 'none'") private_data = privkey_blob elif kdfname == "bcrypt": if not password: raise PasswordRequiredException( "Private key file is encrypted") if cipher == 'aes256-cbc': mode = modes.CBC elif cipher == 'aes256-ctr': mode = modes.CTR else: raise SSHException( "unknown cipher '%s' used in private key file" % cipher) kdf = Message(kdfoptions) salt = kdf.get_binary() rounds = kdf.get_int() # run bcrypt kdf to derive key and iv/nonce (desired_key_bytes = 32 + 16 bytes) key_iv = bcrypt.kdf(b(password), salt, 48, rounds, ignore_few_rounds=True) key = key_iv[:32] iv = key_iv[32:] # decrypt private key blob decryptor = Cipher(algorithms.AES(key), mode(iv), default_backend()).decryptor() private_data = decryptor.update( privkey_blob) + decryptor.finalize() else: raise SSHException( "unknown cipher or kdf used in private key file") # Unpack private key and verify checkints priv_msg = Message(private_data) checkint1 = priv_msg.get_int() checkint2 = priv_msg.get_int() if checkint1 != checkint2: raise SSHException( 'OpenSSH private key file checkints do not match') keytype = priv_msg.get_text() if pub_keytype != keytype: raise SSHException( "Inconsistent key types for public and private parts") keydata = priv_msg.get_remainder() return keytype, _unpad(keydata)