mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-11-09 15:20:58 +00:00
Merge branch '2.0'
* 2.0: Add support for RFC 4419: diffie-hellman-group-exchange-sha{1,256}
This commit is contained in:
commit
489a723d33
@ -201,6 +201,33 @@ class SSH2
|
|||||||
*/
|
*/
|
||||||
var $kex_algorithms = false;
|
var $kex_algorithms = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods
|
||||||
|
*
|
||||||
|
* @see Net_SSH2::_key_exchange()
|
||||||
|
* @var Integer
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $kex_dh_group_size_min = 1536;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preferred Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods
|
||||||
|
*
|
||||||
|
* @see Net_SSH2::_key_exchange()
|
||||||
|
* @var Integer
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $kex_dh_group_size_preferred = 2048;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods
|
||||||
|
*
|
||||||
|
* @see Net_SSH2::_key_exchange()
|
||||||
|
* @var Integer
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $kex_dh_group_size_max = 4096;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server Host Key Algorithms
|
* Server Host Key Algorithms
|
||||||
*
|
*
|
||||||
@ -918,7 +945,13 @@ class SSH2
|
|||||||
array(60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'),
|
array(60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'),
|
||||||
array(60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'),
|
array(60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'),
|
||||||
array(60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST',
|
array(60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST',
|
||||||
61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE')
|
61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'),
|
||||||
|
// RFC 4419 - diffie-hellman-group-exchange-sha{1,256}
|
||||||
|
array(30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD',
|
||||||
|
31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP',
|
||||||
|
32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT',
|
||||||
|
33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY',
|
||||||
|
34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST')
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->host = $host;
|
$this->host = $host;
|
||||||
@ -1099,7 +1132,9 @@ class SSH2
|
|||||||
{
|
{
|
||||||
static $kex_algorithms = array(
|
static $kex_algorithms = array(
|
||||||
'diffie-hellman-group1-sha1', // REQUIRED
|
'diffie-hellman-group1-sha1', // REQUIRED
|
||||||
'diffie-hellman-group14-sha1' // REQUIRED
|
'diffie-hellman-group14-sha1', // REQUIRED
|
||||||
|
'diffie-hellman-group-exchange-sha1', // RFC 4419
|
||||||
|
'diffie-hellman-group-exchange-sha256', // RFC 4419
|
||||||
);
|
);
|
||||||
|
|
||||||
static $server_host_key_algorithms = array(
|
static $server_host_key_algorithms = array(
|
||||||
@ -1379,6 +1414,48 @@ class SSH2
|
|||||||
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strpos($kex_algorithms[$i], '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_algorithms[$i]) {
|
switch ($kex_algorithms[$i]) {
|
||||||
// see http://tools.ietf.org/html/rfc2409#section-6.2 and
|
// see http://tools.ietf.org/html/rfc2409#section-6.2 and
|
||||||
// http://tools.ietf.org/html/rfc2412, appendex E
|
// http://tools.ietf.org/html/rfc2412, appendex E
|
||||||
@ -1400,13 +1477,22 @@ class SSH2
|
|||||||
'3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF';
|
'3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For both diffie-hellman-group1-sha1 and diffie-hellman-group14-sha1
|
// For both diffie-hellman-group1-sha1 and diffie-hellman-group14-sha1
|
||||||
// the generator field element is 2 (decimal) and the hash function is sha1.
|
// the generator field element is 2 (decimal) and the hash function is sha1.
|
||||||
$g = new BigInteger(2);
|
$g = new BigInteger(2);
|
||||||
$prime = new BigInteger($prime, 16);
|
$prime = new BigInteger($prime, 16);
|
||||||
|
$exchange_hash_rfc4419 = '';
|
||||||
|
$clientKexInitMessage = NET_SSH2_MSG_KEXDH_INIT;
|
||||||
|
$serverKexReplyMessage = NET_SSH2_MSG_KEXDH_REPLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($kex_algorithms[$i]) {
|
||||||
|
case 'diffie-hellman-group-exchange-sha256':
|
||||||
|
$kexHash = new Hash('sha256');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
$kexHash = new Hash('sha1');
|
$kexHash = new Hash('sha1');
|
||||||
//$q = $p->bitwise_rightShift(1);
|
}
|
||||||
|
|
||||||
/* To increase the speed of the key exchange, both client and server may
|
/* 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
|
reduce the size of their private exponents. It should be at least
|
||||||
@ -1424,7 +1510,7 @@ class SSH2
|
|||||||
$e = $g->modPow($x, $prime);
|
$e = $g->modPow($x, $prime);
|
||||||
|
|
||||||
$eBytes = $e->toBytes(true);
|
$eBytes = $e->toBytes(true);
|
||||||
$data = pack('CNa*', NET_SSH2_MSG_KEXDH_INIT, strlen($eBytes), $eBytes);
|
$data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
|
||||||
|
|
||||||
if (!$this->_send_binary_packet($data)) {
|
if (!$this->_send_binary_packet($data)) {
|
||||||
user_error('Connection closed by server');
|
user_error('Connection closed by server');
|
||||||
@ -1438,7 +1524,7 @@ class SSH2
|
|||||||
}
|
}
|
||||||
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
extract(unpack('Ctype', $this->_string_shift($response, 1)));
|
||||||
|
|
||||||
if ($type != NET_SSH2_MSG_KEXDH_REPLY) {
|
if ($type != $serverKexReplyMessage) {
|
||||||
user_error('Expected SSH_MSG_KEXDH_REPLY');
|
user_error('Expected SSH_MSG_KEXDH_REPLY');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1462,11 +1548,16 @@ class SSH2
|
|||||||
$key = $f->modPow($x, $prime);
|
$key = $f->modPow($x, $prime);
|
||||||
$keyBytes = $key->toBytes(true);
|
$keyBytes = $key->toBytes(true);
|
||||||
|
|
||||||
$this->exchange_hash = pack('Na*Na*Na*Na*Na*Na*Na*Na*',
|
$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($this->identifier), $this->identifier,
|
||||||
strlen($kexinit_payload_client), $kexinit_payload_client, strlen($kexinit_payload_server),
|
strlen($this->server_identifier), $this->server_identifier,
|
||||||
$kexinit_payload_server, strlen($this->server_public_host_key), $this->server_public_host_key, strlen($eBytes),
|
strlen($kexinit_payload_client), $kexinit_payload_client,
|
||||||
$eBytes, strlen($fBytes), $fBytes, strlen($keyBytes), $keyBytes
|
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);
|
$this->exchange_hash = $kexHash->hash($this->exchange_hash);
|
||||||
|
Loading…
Reference in New Issue
Block a user