diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..210a9034 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,27 @@ +build: false +shallow_clone: false +platform: + - x86 + - x64 +clone_folder: C:\projects\phpseclib + +install: + - cinst -y OpenSSL.Light + - SET PATH=C:\Program Files\OpenSSL;%PATH% + - sc config wuauserv start= auto + - net start wuauserv + - cinst -y php --version 5.6.30 + - cd c:\tools\php56 + - copy php.ini-production php.ini + - echo date.timezone="UTC" >> php.ini + - echo extension_dir=ext >> php.ini + - echo extension=php_openssl.dll >> php.ini + - echo extension=php_gmp.dll >> php.ini + - cd C:\projects\phpseclib + - SET PATH=C:\tools\php56;%PATH% + - php.exe -r "readfile('http://getcomposer.org/installer');" | php.exe + - php.exe composer.phar install --prefer-source --no-interaction + +test_script: + - cd C:\projects\phpseclib + - vendor\bin\phpunit.bat tests/Windows32Test.php \ No newline at end of file diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 9fd71421..0afa1759 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -929,6 +929,14 @@ class SSH2 */ private $binary_packet_buffer = false; + /** + * Preferred Signature Format + * + * @var string|false + * @access private + */ + var $preferred_signature_format = false; + /** * Default Constructor. * @@ -1323,6 +1331,8 @@ class SSH2 } $server_host_key_algorithms = [ + 'rsa-sha2-256', // RFC 8332 + 'rsa-sha2-512', // RFC 8332 'ssh-rsa', // RECOMMENDED sign Raw RSA Key 'ssh-dss' // REQUIRED sign Raw DSS Key ]; @@ -1794,7 +1804,18 @@ class SSH2 throw new NoSupportedAlgorithmsException('No compatible server host key algorithms found'); } - if ($public_key_format != $server_host_key_algorithm || $this->signature_format != $server_host_key_algorithm) { + switch ($server_host_key_algorithm) { + case 'ssh-dss': + $expected_key_format = 'ssh-dss'; + break; + //case 'rsa-sha2-256': + //case 'rsa-sha2-512': + //case 'ssh-rsa': + default: + $expected_key_format = 'ssh-rsa'; + } + + if ($public_key_format != $expected_key_format || $this->signature_format != $server_host_key_algorithm) { $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); throw new \RuntimeException('Server Host Key Algorithm Mismatch'); } @@ -2621,9 +2642,23 @@ class SSH2 } $packet = $part1 . chr(1) . $part2; - $privatekey->setHash('sha1'); + switch ($this->signature_format) { + case 'rsa-sha2-512': + $hash = 'sha512'; + $type = 'rsa-sha2-512'; + break; + case 'rsa-sha2-256': + $hash = 'sha256'; + $type = 'rsa-sha2-256'; + break; + //case 'ssh-rsa': + default: + $hash = 'sha1'; + $type = 'ssh-rsa'; + } + $privatekey->setHash($hash); $signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet), RSA::PADDING_PKCS1); - $signature = pack('Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($signature), $signature); + $signature = pack('Na*Na*', strlen($type), $type, strlen($signature), $signature); $packet.= pack('Na*', strlen($signature), $signature); if (!$this->send_binary_packet($packet)) { @@ -4525,6 +4560,8 @@ class SSH2 break; case 'ssh-rsa': + case 'rsa-sha2-256': + case 'rsa-sha2-512': if (strlen($server_public_host_key) < 4) { return false; } @@ -4548,7 +4585,18 @@ class SSH2 $rsa = new RSA(); $rsa->load(['e' => $e, 'n' => $n], 'raw'); - $rsa->setHash('sha1'); + switch ($this->signature_format) { + case 'rsa-sha2-512': + $hash = 'sha512'; + break; + case 'rsa-sha2-256': + $hash = 'sha256'; + break; + //case 'ssh-rsa': + default: + $hash = 'sha1'; + } + $rsa->setHash($hash); if (!$rsa->verify($this->exchange_hash, $signature, RSA::PADDING_PKCS1)) { //user_error('Bad server signature'); return $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); @@ -4575,7 +4623,30 @@ class SSH2 $s = $s->modPow($e, $n); $s = $s->toBytes(); - $h = pack('N4H*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, sha1($this->exchange_hash)); + switch ($this->signature_format) { + case 'rsa-sha2-512': + $hash = 'sha512'; + break; + case 'rsa-sha2-256': + $hash = 'sha256'; + break; + //case 'ssh-rsa': + default: + $hash = 'sha1'; + } + $hashObj = new Crypt_Hash($hash); + switch ($this->signature_format) { + case 'rsa-sha2-512': + $h = pack('N5a*', 0x00305130, 0x0D060960, 0x86480165, 0x03040203, 0x05000440, $hashObj->hash($this->exchange_hash)); + break; + case 'rsa-sha2-256': + $h = pack('N5a*', 0x00303130, 0x0D060960, 0x86480165, 0x03040201, 0x05000420, $hashObj->hash($this->exchange_hash)); + break; + //case 'ssh-rsa': + default: + $hash = 'sha1'; + $h = pack('N4a*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, $hashObj->hash($this->exchange_hash)); + } $h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h; if ($s != $h) {