getLength() public method

Returns the hash length (in bits)
public getLength ( ) : integer
return integer
Esempio n. 1
0
 /**
  * Key Exchange
  *
  * @param String $kexinit_payload_server
  * @access private
  */
 function _key_exchange($kexinit_payload_server)
 {
     static $kex_algorithms = array('diffie-hellman-group1-sha1', 'diffie-hellman-group14-sha1', 'diffie-hellman-group-exchange-sha1', 'diffie-hellman-group-exchange-sha256');
     static $server_host_key_algorithms = array('ssh-rsa', 'ssh-dss');
     static $encryption_algorithms = false;
     if ($encryption_algorithms === false) {
         $encryption_algorithms = array('arcfour256', 'arcfour128', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'twofish128-ctr', 'twofish192-ctr', 'twofish256-ctr', 'aes128-cbc', 'aes192-cbc', 'aes256-cbc', 'twofish128-cbc', 'twofish192-cbc', 'twofish256-cbc', 'twofish-cbc', 'blowfish-ctr', 'blowfish-cbc', '3des-ctr', '3des-cbc');
         if (extension_loaded('openssl') && !extension_loaded('mcrypt')) {
             // OpenSSL does not support arcfour256 in any capacity and arcfour128 / arcfour support is limited to
             // instances that do not use continuous buffers
             $encryption_algorithms = array_diff($encryption_algorithms, array('arcfour256', 'arcfour128', 'arcfour'));
         }
         if (class_exists('\\phpseclib\\Crypt\\RC4') === false) {
             $encryption_algorithms = array_diff($encryption_algorithms, array('arcfour256', 'arcfour128', 'arcfour'));
         }
         if (class_exists('\\phpseclib\\Crypt\\Rijndael') === false) {
             $encryption_algorithms = array_diff($encryption_algorithms, array('aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-cbc', 'aes192-cbc', 'aes256-cbc'));
         }
         if (class_exists('\\phpseclib\\Crypt\\Twofish') === false) {
             $encryption_algorithms = array_diff($encryption_algorithms, array('twofish128-ctr', 'twofish192-ctr', 'twofish256-ctr', 'twofish128-cbc', 'twofish192-cbc', 'twofish256-cbc', 'twofish-cbc'));
         }
         if (class_exists('\\phpseclib\\Crypt\\Blowfish') === false) {
             $encryption_algorithms = array_diff($encryption_algorithms, array('blowfish-ctr', 'blowfish-cbc'));
         }
         if (class_exists('\\phpseclib\\Crypt\\TripleDES') === false) {
             $encryption_algorithms = array_diff($encryption_algorithms, array('3des-ctr', '3des-cbc'));
         }
         $encryption_algorithms = array_values($encryption_algorithms);
     }
     $mac_algorithms = array('hmac-sha2-256', 'hmac-sha1-96', 'hmac-sha1', 'hmac-md5-96', 'hmac-md5');
     static $compression_algorithms = array('none');
     // some SSH servers have buggy implementations of some of the above algorithms
     switch ($this->server_identifier) {
         case 'SSH-2.0-SSHD':
             $mac_algorithms = array_values(array_diff($mac_algorithms, array('hmac-sha1-96', 'hmac-md5-96')));
     }
     static $str_kex_algorithms, $str_server_host_key_algorithms, $encryption_algorithms_server_to_client, $mac_algorithms_server_to_client, $compression_algorithms_server_to_client, $encryption_algorithms_client_to_server, $mac_algorithms_client_to_server, $compression_algorithms_client_to_server;
     if (empty($str_kex_algorithms)) {
         $str_kex_algorithms = implode(',', $kex_algorithms);
         $str_server_host_key_algorithms = implode(',', $server_host_key_algorithms);
         $encryption_algorithms_server_to_client = $encryption_algorithms_client_to_server = implode(',', $encryption_algorithms);
         $mac_algorithms_server_to_client = $mac_algorithms_client_to_server = implode(',', $mac_algorithms);
         $compression_algorithms_server_to_client = $compression_algorithms_client_to_server = implode(',', $compression_algorithms);
     }
     $client_cookie = Random::string(16);
     $response = $kexinit_payload_server;
     $this->_string_shift($response, 1);
     // skip past the message number (it should be SSH_MSG_KEXINIT)
     $server_cookie = $this->_string_shift($response, 16);
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->kex_algorithms = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->server_host_key_algorithms = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->encryption_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->encryption_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->mac_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->mac_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->compression_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->compression_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->languages_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->languages_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
     extract(unpack('Cfirst_kex_packet_follows', $this->_string_shift($response, 1)));
     $first_kex_packet_follows = $first_kex_packet_follows != 0;
     // the sending of SSH2_MSG_KEXINIT could go in one of two places.  this is the second place.
     $kexinit_payload_client = pack('Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN', NET_SSH2_MSG_KEXINIT, $client_cookie, strlen($str_kex_algorithms), $str_kex_algorithms, strlen($str_server_host_key_algorithms), $str_server_host_key_algorithms, strlen($encryption_algorithms_client_to_server), $encryption_algorithms_client_to_server, strlen($encryption_algorithms_server_to_client), $encryption_algorithms_server_to_client, strlen($mac_algorithms_client_to_server), $mac_algorithms_client_to_server, strlen($mac_algorithms_server_to_client), $mac_algorithms_server_to_client, strlen($compression_algorithms_client_to_server), $compression_algorithms_client_to_server, strlen($compression_algorithms_server_to_client), $compression_algorithms_server_to_client, 0, '', 0, '', 0, 0);
     if (!$this->_send_binary_packet($kexinit_payload_client)) {
         return false;
     }
     // here ends the second place.
     // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
     // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the
     // diffie-hellman key exchange as fast as possible
     $decrypt = $this->_array_intersect_first($encryption_algorithms, $this->encryption_algorithms_server_to_client);
     switch ($decrypt) {
         case '3des-cbc':
         case '3des-ctr':
             $decryptKeyLength = 24;
             // eg. 192 / 8
             break;
         case 'aes256-cbc':
         case 'aes256-ctr':
         case 'twofish-cbc':
         case 'twofish256-cbc':
         case 'twofish256-ctr':
             $decryptKeyLength = 32;
             // eg. 256 / 8
             break;
         case 'aes192-cbc':
         case 'aes192-ctr':
         case 'twofish192-cbc':
         case 'twofish192-ctr':
             $decryptKeyLength = 24;
             // eg. 192 / 8
             break;
         case 'aes128-cbc':
         case 'aes128-ctr':
         case 'twofish128-cbc':
         case 'twofish128-ctr':
         case 'blowfish-cbc':
         case 'blowfish-ctr':
             $decryptKeyLength = 16;
             // eg. 128 / 8
             break;
         case 'arcfour':
         case 'arcfour128':
             $decryptKeyLength = 16;
             // eg. 128 / 8
             break;
         case 'arcfour256':
             $decryptKeyLength = 32;
             // eg. 128 / 8
             break;
         case 'none':
             $decryptKeyLength = 0;
             break;
         default:
             user_error('No compatible server to client encryption algorithms found');
             return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     $encrypt = $this->_array_intersect_first($encryption_algorithms, $this->encryption_algorithms_client_to_server);
     switch ($encrypt) {
         case '3des-cbc':
         case '3des-ctr':
             $encryptKeyLength = 24;
             break;
         case 'aes256-cbc':
         case 'aes256-ctr':
         case 'twofish-cbc':
         case 'twofish256-cbc':
         case 'twofish256-ctr':
             $encryptKeyLength = 32;
             break;
         case 'aes192-cbc':
         case 'aes192-ctr':
         case 'twofish192-cbc':
         case 'twofish192-ctr':
             $encryptKeyLength = 24;
             break;
         case 'aes128-cbc':
         case 'aes128-ctr':
         case 'twofish128-cbc':
         case 'twofish128-ctr':
         case 'blowfish-cbc':
         case 'blowfish-ctr':
             $encryptKeyLength = 16;
             break;
         case 'arcfour':
         case 'arcfour128':
             $encryptKeyLength = 16;
             break;
         case 'arcfour256':
             $encryptKeyLength = 32;
             break;
         case 'none':
             $encryptKeyLength = 0;
             break;
         default:
             user_error('No compatible client to server encryption algorithms found');
             return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     $keyLength = $decryptKeyLength > $encryptKeyLength ? $decryptKeyLength : $encryptKeyLength;
     // through diffie-hellman key exchange a symmetric key is obtained
     $kex_algorithm = $this->_array_intersect_first($kex_algorithms, $this->kex_algorithms);
     if ($kex_algorithm === false) {
         user_error('No compatible key exchange algorithms found');
         return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     if (strpos($kex_algorithm, 'diffie-hellman-group-exchange') === 0) {
         $dh_group_sizes_packed = pack('NNN', $this->kex_dh_group_size_min, $this->kex_dh_group_size_preferred, $this->kex_dh_group_size_max);
         $packet = pack('Ca*', NET_SSH2_MSG_KEXDH_GEX_REQUEST, $dh_group_sizes_packed);
         if (!$this->_send_binary_packet($packet)) {
             return false;
         }
         $response = $this->_get_binary_packet();
         if ($response === false) {
             user_error('Connection closed by server');
             return false;
         }
         extract(unpack('Ctype', $this->_string_shift($response, 1)));
         if ($type != NET_SSH2_MSG_KEXDH_GEX_GROUP) {
             user_error('Expected SSH_MSG_KEX_DH_GEX_GROUP');
             return false;
         }
         extract(unpack('NprimeLength', $this->_string_shift($response, 4)));
         $primeBytes = $this->_string_shift($response, $primeLength);
         $prime = new BigInteger($primeBytes, -256);
         extract(unpack('NgLength', $this->_string_shift($response, 4)));
         $gBytes = $this->_string_shift($response, $gLength);
         $g = new BigInteger($gBytes, -256);
         $exchange_hash_rfc4419 = pack('a*Na*Na*', $dh_group_sizes_packed, $primeLength, $primeBytes, $gLength, $gBytes);
         $clientKexInitMessage = NET_SSH2_MSG_KEXDH_GEX_INIT;
         $serverKexReplyMessage = NET_SSH2_MSG_KEXDH_GEX_REPLY;
     } else {
         switch ($kex_algorithm) {
             // see http://tools.ietf.org/html/rfc2409#section-6.2 and
             // http://tools.ietf.org/html/rfc2412, appendex E
             case 'diffie-hellman-group1-sha1':
                 $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF';
                 break;
                 // see http://tools.ietf.org/html/rfc3526#section-3
             // see http://tools.ietf.org/html/rfc3526#section-3
             case 'diffie-hellman-group14-sha1':
                 $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF';
                 break;
         }
         // For both diffie-hellman-group1-sha1 and diffie-hellman-group14-sha1
         // the generator field element is 2 (decimal) and the hash function is sha1.
         $g = new BigInteger(2);
         $prime = new BigInteger($prime, 16);
         $exchange_hash_rfc4419 = '';
         $clientKexInitMessage = NET_SSH2_MSG_KEXDH_INIT;
         $serverKexReplyMessage = NET_SSH2_MSG_KEXDH_REPLY;
     }
     switch ($kex_algorithm) {
         case 'diffie-hellman-group-exchange-sha256':
             $kexHash = new Hash('sha256');
             break;
         default:
             $kexHash = new Hash('sha1');
     }
     /* To increase the speed of the key exchange, both client and server may
                reduce the size of their private exponents.  It should be at least
                twice as long as the key material that is generated from the shared
                secret.  For more details, see the paper by van Oorschot and Wiener
                [VAN-OORSCHOT].
     
                -- http://tools.ietf.org/html/rfc4419#section-6.2 */
     $one = new BigInteger(1);
     $keyLength = min($keyLength, $kexHash->getLength());
     $max = $one->bitwise_leftShift(16 * $keyLength);
     // 2 * 8 * $keyLength
     $max = $max->subtract($one);
     $x = $one->random($one, $max);
     $e = $g->modPow($x, $prime);
     $eBytes = $e->toBytes(true);
     $data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
     if (!$this->_send_binary_packet($data)) {
         user_error('Connection closed by server');
         return false;
     }
     $response = $this->_get_binary_packet();
     if ($response === false) {
         user_error('Connection closed by server');
         return false;
     }
     extract(unpack('Ctype', $this->_string_shift($response, 1)));
     if ($type != $serverKexReplyMessage) {
         user_error('Expected SSH_MSG_KEXDH_REPLY');
         return false;
     }
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->server_public_host_key = $server_public_host_key = $this->_string_shift($response, $temp['length']);
     $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
     $public_key_format = $this->_string_shift($server_public_host_key, $temp['length']);
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $fBytes = $this->_string_shift($response, $temp['length']);
     $f = new BigInteger($fBytes, -256);
     $temp = unpack('Nlength', $this->_string_shift($response, 4));
     $this->signature = $this->_string_shift($response, $temp['length']);
     $temp = unpack('Nlength', $this->_string_shift($this->signature, 4));
     $this->signature_format = $this->_string_shift($this->signature, $temp['length']);
     $key = $f->modPow($x, $prime);
     $keyBytes = $key->toBytes(true);
     $this->exchange_hash = pack('Na*Na*Na*Na*Na*a*Na*Na*Na*', strlen($this->identifier), $this->identifier, strlen($this->server_identifier), $this->server_identifier, strlen($kexinit_payload_client), $kexinit_payload_client, strlen($kexinit_payload_server), $kexinit_payload_server, strlen($this->server_public_host_key), $this->server_public_host_key, $exchange_hash_rfc4419, strlen($eBytes), $eBytes, strlen($fBytes), $fBytes, strlen($keyBytes), $keyBytes);
     $this->exchange_hash = $kexHash->hash($this->exchange_hash);
     if ($this->session_id === false) {
         $this->session_id = $this->exchange_hash;
     }
     $server_host_key_algorithm = $this->_array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms);
     if ($server_host_key_algorithm === false) {
         user_error('No compatible server host key algorithms found');
         return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     if ($public_key_format != $server_host_key_algorithm || $this->signature_format != $server_host_key_algorithm) {
         user_error('Server Host Key Algorithm Mismatch');
         return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     $packet = pack('C', NET_SSH2_MSG_NEWKEYS);
     if (!$this->_send_binary_packet($packet)) {
         return false;
     }
     $response = $this->_get_binary_packet();
     if ($response === false) {
         user_error('Connection closed by server');
         return false;
     }
     extract(unpack('Ctype', $this->_string_shift($response, 1)));
     if ($type != NET_SSH2_MSG_NEWKEYS) {
         user_error('Expected SSH_MSG_NEWKEYS');
         return false;
     }
     switch ($encrypt) {
         case '3des-cbc':
             $this->encrypt = new TripleDES();
             // $this->encrypt_block_size = 64 / 8 == the default
             break;
         case '3des-ctr':
             $this->encrypt = new TripleDES(Base::MODE_CTR);
             // $this->encrypt_block_size = 64 / 8 == the default
             break;
         case 'aes256-cbc':
         case 'aes192-cbc':
         case 'aes128-cbc':
             $this->encrypt = new Rijndael();
             $this->encrypt_block_size = 16;
             // eg. 128 / 8
             break;
         case 'aes256-ctr':
         case 'aes192-ctr':
         case 'aes128-ctr':
             $this->encrypt = new Rijndael(Base::MODE_CTR);
             $this->encrypt_block_size = 16;
             // eg. 128 / 8
             break;
         case 'blowfish-cbc':
             $this->encrypt = new Blowfish();
             $this->encrypt_block_size = 8;
             break;
         case 'blowfish-ctr':
             $this->encrypt = new Blowfish(Base::MODE_CTR);
             $this->encrypt_block_size = 8;
             break;
         case 'twofish128-cbc':
         case 'twofish192-cbc':
         case 'twofish256-cbc':
         case 'twofish-cbc':
             $this->encrypt = new Twofish();
             $this->encrypt_block_size = 16;
             break;
         case 'twofish128-ctr':
         case 'twofish192-ctr':
         case 'twofish256-ctr':
             $this->encrypt = new Twofish(Base::MODE_CTR);
             $this->encrypt_block_size = 16;
             break;
         case 'arcfour':
         case 'arcfour128':
         case 'arcfour256':
             $this->encrypt = new RC4();
             break;
         case 'none':
             //$this->encrypt = new Null();
     }
     switch ($decrypt) {
         case '3des-cbc':
             $this->decrypt = new TripleDES();
             break;
         case '3des-ctr':
             $this->decrypt = new TripleDES(Base::MODE_CTR);
             break;
         case 'aes256-cbc':
         case 'aes192-cbc':
         case 'aes128-cbc':
             $this->decrypt = new Rijndael();
             $this->decrypt_block_size = 16;
             break;
         case 'aes256-ctr':
         case 'aes192-ctr':
         case 'aes128-ctr':
             $this->decrypt = new Rijndael(Base::MODE_CTR);
             $this->decrypt_block_size = 16;
             break;
         case 'blowfish-cbc':
             $this->decrypt = new Blowfish();
             $this->decrypt_block_size = 8;
             break;
         case 'blowfish-ctr':
             $this->decrypt = new Blowfish(Base::MODE_CTR);
             $this->decrypt_block_size = 8;
             break;
         case 'twofish128-cbc':
         case 'twofish192-cbc':
         case 'twofish256-cbc':
         case 'twofish-cbc':
             $this->decrypt = new Twofish();
             $this->decrypt_block_size = 16;
             break;
         case 'twofish128-ctr':
         case 'twofish192-ctr':
         case 'twofish256-ctr':
             $this->decrypt = new Twofish(Base::MODE_CTR);
             $this->decrypt_block_size = 16;
             break;
         case 'arcfour':
         case 'arcfour128':
         case 'arcfour256':
             $this->decrypt = new RC4();
             break;
         case 'none':
             //$this->decrypt = new Null();
     }
     $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
     if ($this->encrypt) {
         if ($this->crypto_engine) {
             $this->encrypt->setEngine($this->crypto_engine);
         }
         $this->encrypt->enableContinuousBuffer();
         $this->encrypt->disablePadding();
         $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id);
         while ($this->encrypt_block_size > strlen($iv)) {
             $iv .= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
         }
         $this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size));
         $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id);
         while ($encryptKeyLength > strlen($key)) {
             $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
         }
         $this->encrypt->setKey(substr($key, 0, $encryptKeyLength));
     }
     if ($this->decrypt) {
         if ($this->crypto_engine) {
             $this->decrypt->setEngine($this->crypto_engine);
         }
         $this->decrypt->enableContinuousBuffer();
         $this->decrypt->disablePadding();
         $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id);
         while ($this->decrypt_block_size > strlen($iv)) {
             $iv .= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
         }
         $this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size));
         $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id);
         while ($decryptKeyLength > strlen($key)) {
             $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
         }
         $this->decrypt->setKey(substr($key, 0, $decryptKeyLength));
     }
     /* The "arcfour128" algorithm is the RC4 cipher, as described in
                [SCHNEIER], using a 128-bit key.  The first 1536 bytes of keystream
                generated by the cipher MUST be discarded, and the first byte of the
                first encrypted packet MUST be encrypted using the 1537th byte of
                keystream.
     
                -- http://tools.ietf.org/html/rfc4345#section-4 */
     if ($encrypt == 'arcfour128' || $encrypt == 'arcfour256') {
         $this->encrypt->encrypt(str_repeat("", 1536));
     }
     if ($decrypt == 'arcfour128' || $decrypt == 'arcfour256') {
         $this->decrypt->decrypt(str_repeat("", 1536));
     }
     $mac_algorithm = $this->_array_intersect_first($mac_algorithms, $this->mac_algorithms_client_to_server);
     if ($mac_algorithm === false) {
         user_error('No compatible client to server message authentication algorithms found');
         return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     $createKeyLength = 0;
     // ie. $mac_algorithm == 'none'
     switch ($mac_algorithm) {
         case 'hmac-sha2-256':
             $this->hmac_create = new Hash('sha256');
             $createKeyLength = 32;
             break;
         case 'hmac-sha1':
             $this->hmac_create = new Hash('sha1');
             $createKeyLength = 20;
             break;
         case 'hmac-sha1-96':
             $this->hmac_create = new Hash('sha1-96');
             $createKeyLength = 20;
             break;
         case 'hmac-md5':
             $this->hmac_create = new Hash('md5');
             $createKeyLength = 16;
             break;
         case 'hmac-md5-96':
             $this->hmac_create = new Hash('md5-96');
             $createKeyLength = 16;
     }
     $mac_algorithm = $this->_array_intersect_first($mac_algorithms, $this->mac_algorithms_server_to_client);
     if ($mac_algorithm === false) {
         user_error('No compatible server to client message authentication algorithms found');
         return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     $checkKeyLength = 0;
     $this->hmac_size = 0;
     switch ($mac_algorithm) {
         case 'hmac-sha2-256':
             $this->hmac_check = new Hash('sha256');
             $checkKeyLength = 32;
             $this->hmac_size = 32;
             break;
         case 'hmac-sha1':
             $this->hmac_check = new Hash('sha1');
             $checkKeyLength = 20;
             $this->hmac_size = 20;
             break;
         case 'hmac-sha1-96':
             $this->hmac_check = new Hash('sha1-96');
             $checkKeyLength = 20;
             $this->hmac_size = 12;
             break;
         case 'hmac-md5':
             $this->hmac_check = new Hash('md5');
             $checkKeyLength = 16;
             $this->hmac_size = 16;
             break;
         case 'hmac-md5-96':
             $this->hmac_check = new Hash('md5-96');
             $checkKeyLength = 16;
             $this->hmac_size = 12;
     }
     $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id);
     while ($createKeyLength > strlen($key)) {
         $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
     }
     $this->hmac_create->setKey(substr($key, 0, $createKeyLength));
     $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id);
     while ($checkKeyLength > strlen($key)) {
         $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
     }
     $this->hmac_check->setKey(substr($key, 0, $checkKeyLength));
     $compression_algorithm = $this->_array_intersect_first($compression_algorithms, $this->compression_algorithms_server_to_client);
     if ($compression_algorithm === false) {
         user_error('No compatible server to client compression algorithms found');
         return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     $this->decompress = $compression_algorithm == 'zlib';
     $compression_algorithm = $this->_array_intersect_first($compression_algorithms, $this->compression_algorithms_client_to_server);
     if ($compression_algorithm === false) {
         user_error('No compatible client to server compression algorithms found');
         return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
     }
     $this->compress = $compression_algorithm == 'zlib';
     return true;
 }
Esempio n. 2
0
 /**
  * Sets the password.
  *
  * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
  *     {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1:
  *         $hash, $salt, $count, $dkLen
  *
  *         Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php
  *
  * @see Crypt/Hash.php
  * @param string $password
  * @param string $method
  * @throws \LengthException if pbkdf1 is being used and the derived key length exceeds the hash length
  * @return bool
  * @access public
  * @internal Could, but not must, extend by the child Crypt_* class
  */
 function setPassword($password, $method = 'pbkdf2')
 {
     $key = '';
     switch ($method) {
         default:
             // 'pbkdf2' or 'pbkdf1'
             $func_args = func_get_args();
             // Hash function
             $hash = isset($func_args[2]) ? $func_args[2] : 'sha1';
             // WPA and WPA2 use the SSID as the salt
             $salt = isset($func_args[3]) ? $func_args[3] : $this->password_default_salt;
             // RFC2898#section-4.2 uses 1,000 iterations by default
             // WPA and WPA2 use 4,096.
             $count = isset($func_args[4]) ? $func_args[4] : 1000;
             // Keylength
             if (isset($func_args[5])) {
                 $dkLen = $func_args[5];
             } else {
                 $key_length = $this->explicit_key_length !== false ? $this->explicit_key_length : $this->key_length;
                 $dkLen = $method == 'pbkdf1' ? 2 * $key_length : $key_length;
             }
             switch (true) {
                 case $method == 'pbkdf1':
                     $hashObj = new Hash();
                     $hashObj->setHash($hash);
                     if ($dkLen > $hashObj->getLength()) {
                         throw new \LengthException('Derived key length cannot be longer than the hash length');
                     }
                     $t = $password . $salt;
                     for ($i = 0; $i < $count; ++$i) {
                         $t = $hashObj->hash($t);
                     }
                     $key = substr($t, 0, $dkLen);
                     $this->setKey(substr($key, 0, $dkLen >> 1));
                     $this->setIV(substr($key, $dkLen >> 1));
                     return true;
                     // Determining if php[>=5.5.0]'s hash_pbkdf2() function avail- and useable
                 // Determining if php[>=5.5.0]'s hash_pbkdf2() function avail- and useable
                 case !function_exists('hash_pbkdf2'):
                 case !function_exists('hash_algos'):
                 case !in_array($hash, hash_algos()):
                     $i = 1;
                     while (strlen($key) < $dkLen) {
                         $hmac = new Hash();
                         $hmac->setHash($hash);
                         $hmac->setKey($password);
                         $f = $u = $hmac->hash($salt . pack('N', $i++));
                         for ($j = 2; $j <= $count; ++$j) {
                             $u = $hmac->hash($u);
                             $f ^= $u;
                         }
                         $key .= $f;
                     }
                     $key = substr($key, 0, $dkLen);
                     break;
                 default:
                     $key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true);
             }
     }
     $this->setKey($key);
     return true;
 }
Esempio n. 3
0
 /**
  * Determines which hashing function should be used for the mask generation function
  *
  * The mask generation function is used by CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_SIGNATURE_PSS and although it's
  * best if Hash and MGFHash are set to the same thing this is not a requirement.
  *
  * @access public
  * @param String $hash        	
  */
 function setMGFHash($hash)
 {
     // Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example.
     switch ($hash) {
         case 'md2':
         case 'md5':
         case 'sha1':
         case 'sha256':
         case 'sha384':
         case 'sha512':
             $this->mgfHash = new Hash($hash);
             break;
         default:
             $this->mgfHash = new Hash('sha1');
     }
     $this->mgfHLen = $this->mgfHash->getLength();
 }
Esempio n. 4
0
 /**
  * @dataProvider lengths
  */
 public function testGetLengthKnown($algorithm, $length)
 {
     $hash = new Hash($algorithm);
     $this->assertSame($hash->getLength(), $length);
 }