diff --git a/.travis.yml b/.travis.yml index 339ec5a1..8ef7cae6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ php: - 7.2 - 7.3 - 7.4 + - 8.0 - nightly before_install: true @@ -20,7 +21,7 @@ matrix: install: - wget http://ftp.gnu.org/gnu/parallel/parallel-20170822.tar.bz2 - tar -xvjf parallel* - - cd parallel* + - cd parallel-20170822 - ./configure - make - sudo make install diff --git a/build/code-sniffer-ruleset-tests.xml b/build/code-sniffer-ruleset-tests.xml index 7169012e..8767eee9 100644 --- a/build/code-sniffer-ruleset-tests.xml +++ b/build/code-sniffer-ruleset-tests.xml @@ -11,6 +11,7 @@ using underscore. --> + diff --git a/composer.json b/composer.json index 3212508a..c1b517a9 100644 --- a/composer.json +++ b/composer.json @@ -51,13 +51,13 @@ } ], "require": { - "paragonie/constant_time_encoding": "^1", + "paragonie/constant_time_encoding": "^1|^2", "paragonie/random_compat": "^1.4|^2.0", "php": ">=5.6.1" }, "require-dev": { "phing/phing": "~2.7", - "phpunit/phpunit": "^4.8.35|^5.7|^6.0", + "phpunit/phpunit": "^5.7|^6.0|^9.4", "squizlabs/php_codesniffer": "~2.0" }, "suggest": { diff --git a/phpseclib/File/ANSI.php b/phpseclib/File/ANSI.php index e124f855..f0dc1961 100644 --- a/phpseclib/File/ANSI.php +++ b/phpseclib/File/ANSI.php @@ -315,19 +315,20 @@ class ANSI $mods = explode(';', $match[1]); foreach ($mods as $mod) { switch ($mod) { - case 0: // Turn off character attributes + case '': + case '0': // Turn off character attributes $attr_cell = clone $this->base_attr_cell; break; - case 1: // Turn bold mode on + case '1': // Turn bold mode on $attr_cell->bold = true; break; - case 4: // Turn underline mode on + case '4': // Turn underline mode on $attr_cell->underline = true; break; - case 5: // Turn blinking mode on + case '5': // Turn blinking mode on $attr_cell->blink = true; break; - case 7: // Turn reverse video on + case '7': // Turn reverse video on $attr_cell->reverse = !$attr_cell->reverse; $temp = $attr_cell->background; $attr_cell->background = $attr_cell->foreground; @@ -340,23 +341,23 @@ class ANSI $back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' }; switch ($mod) { // @codingStandardsIgnoreStart - case 30: $front = 'black'; break; - case 31: $front = 'red'; break; - case 32: $front = 'green'; break; - case 33: $front = 'yellow'; break; - case 34: $front = 'blue'; break; - case 35: $front = 'magenta'; break; - case 36: $front = 'cyan'; break; - case 37: $front = 'white'; break; + case '30': $front = 'black'; break; + case '31': $front = 'red'; break; + case '32': $front = 'green'; break; + case '33': $front = 'yellow'; break; + case '34': $front = 'blue'; break; + case '35': $front = 'magenta'; break; + case '36': $front = 'cyan'; break; + case '37': $front = 'white'; break; - case 40: $back = 'black'; break; - case 41: $back = 'red'; break; - case 42: $back = 'green'; break; - case 43: $back = 'yellow'; break; - case 44: $back = 'blue'; break; - case 45: $back = 'magenta'; break; - case 46: $back = 'cyan'; break; - case 47: $back = 'white'; break; + case '40': $back = 'black'; break; + case '41': $back = 'red'; break; + case '42': $back = 'green'; break; + case '43': $back = 'yellow'; break; + case '44': $back = 'blue'; break; + case '45': $back = 'magenta'; break; + case '46': $back = 'cyan'; break; + case '47': $back = 'white'; break; // @codingStandardsIgnoreEnd default: diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 21b0cda9..bc934099 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -715,6 +715,14 @@ class SSH2 */ protected $curTimeout; + /** + * Keep Alive Interval + * + * @see self::setKeepAlive() + * @access private + */ + var $keepAlive; + /** * Real-time log file pointer * @@ -2537,6 +2545,19 @@ class SSH2 $this->timeout = $this->curTimeout = $timeout; } + /** + * Set Keep Alive + * + * Sends an SSH2_MSG_IGNORE message every x seconds, if x is a positive non-zero number. + * + * @param mixed $timeout + * @access public + */ + function setKeepAlive($interval) + { + $this->keepAlive = $interval; + } + /** * Get the output from stdError * @@ -3167,6 +3188,57 @@ class SSH2 */ private function get_binary_packet($skip_channel_filter = false) { + if ($skip_channel_filter) { + $read = [$this->fsock]; + $write = $except = null; + + if ($this->curTimeout <= 0) { + if ($this->keepAlive <= 0) { + stream_select($read, $write, $except, null); + } else { + if (!stream_select($read, $write, $except, $this->keepAlive)) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + return $this->get_binary_packet(true); + } + } + } else { + if ($this->curTimeout < 0) { + $this->is_timeout = true; + return true; + } + + $read = [$this->fsock]; + $write = $except = null; + + $start = microtime(true); + + if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) { + if (!stream_select($read, $write, $except, $this->keepAlive)) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + $elapsed = microtime(true) - $start; + $this->curTimeout-= $elapsed; + return $this->get_binary_packet(true); + } + $elapsed = microtime(true) - $start; + $this->curTimeout-= $elapsed; + } + + $sec = floor($this->curTimeout); + $usec = 1000000 * ($this->curTimeout - $sec); + + // on windows this returns a "Warning: Invalid CRT parameters detected" error + if (!stream_select($read, $write, $except, $sec, $usec)) { + $this->is_timeout = true; + if ($client_channel == self::CHANNEL_EXEC && !$this->request_pty) { + $this->close_channel($client_channel); + } + return true; + } + $elapsed = microtime(true) - $start; + $this->curTimeout-= $elapsed; + } + } + if (!is_resource($this->fsock) || feof($this->fsock)) { $this->bitmap = 0; throw new ConnectionClosedException('Connection closed prematurely'); @@ -3423,9 +3495,19 @@ class SSH2 // only called when we've already logged in if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) { switch (ord($payload[0])) { + case NET_SSH2_MSG_CHANNEL_REQUEST: + if (strlen($payload) == 31) { + extract(unpack('cpacket_type/Nchannel/Nlength', $payload)); + if (substr($payload, 9, $length) == 'keepalive@openssh.com' && isset($this->server_channels[$channel])) { + if (ord(substr($payload, 9 + $length))) { // want reply + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_SUCCESS, $this->server_channels[$channel])); + } + $payload = $this->get_binary_packet($skip_channel_filter); + } + } + break; case NET_SSH2_MSG_CHANNEL_DATA: case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA: - case NET_SSH2_MSG_CHANNEL_REQUEST: case NET_SSH2_MSG_CHANNEL_CLOSE: case NET_SSH2_MSG_CHANNEL_EOF: if (!$skip_channel_filter && !empty($this->server_channels)) { @@ -3609,34 +3691,6 @@ class SSH2 $response = $this->binary_packet_buffer; $this->binary_packet_buffer = false; } else { - $read = [$this->fsock]; - $write = $except = null; - - if (!$this->curTimeout) { - stream_select($read, $write, $except, null); - } else { - if ($this->curTimeout < 0) { - $this->is_timeout = true; - return true; - } - - $read = [$this->fsock]; - $write = $except = null; - - $start = microtime(true); - $sec = floor($this->curTimeout); - $usec = 1000000 * ($this->curTimeout - $sec); - if (!stream_select($read, $write, $except, $sec, $usec)) { - $this->is_timeout = true; - if ($client_channel == self::CHANNEL_EXEC && !$this->request_pty) { - $this->close_channel($client_channel); - } - return true; - } - $elapsed = microtime(true) - $start; - $this->curTimeout-= $elapsed; - } - $response = $this->get_binary_packet(true); if ($response === false) { $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); diff --git a/tests/Functional/Net/SFTPLargeFileTest.php b/tests/Functional/Net/SFTPLargeFileTest.php index 718426b0..68c40149 100644 --- a/tests/Functional/Net/SFTPLargeFileTest.php +++ b/tests/Functional/Net/SFTPLargeFileTest.php @@ -16,6 +16,7 @@ class Functional_Net_SFTPLargeFileTest extends Functional_Net_SFTPTestCase if (!extension_loaded('mcrypt') && !extension_loaded('openssl')) { self::markTestSkipped('This test depends on mcrypt or openssl for performance.'); } + self::ensureConstant('CRYPT_HASH_MODE', 3); parent::setUpBeforeClass(); } diff --git a/tests/Functional/Net/SFTPStreamTest.php b/tests/Functional/Net/SFTPStreamTest.php index e24e85f5..5388269a 100644 --- a/tests/Functional/Net/SFTPStreamTest.php +++ b/tests/Functional/Net/SFTPStreamTest.php @@ -22,7 +22,7 @@ class Functional_Net_SFTPStreamTest extends Functional_Net_SFTPTestCase 'sftp' => ['session' => $this->sftp], ]); $fp = fopen($this->buildUrl('fooo.txt'), 'wb', false, $context); - $this->assertInternalType('resource', $fp); + $this->assertIsResource($fp); fclose($fp); $this->assertSame(0, $this->sftp->filesize('fooo.txt')); } diff --git a/tests/Functional/Net/SFTPUserStoryTest.php b/tests/Functional/Net/SFTPUserStoryTest.php index 56c76fe5..619e9a96 100644 --- a/tests/Functional/Net/SFTPUserStoryTest.php +++ b/tests/Functional/Net/SFTPUserStoryTest.php @@ -29,8 +29,7 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase { $sftp = new SFTP($this->getEnv('SSH_HOSTNAME')); - $this->assertInternalType( - 'object', + $this->assertIsObject( $sftp, 'Could not construct NET_SFTP object.' ); @@ -136,6 +135,16 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase return $sftp; } + static function demoCallback($length) + { + $r = substr(self::$buffer, 0, $length); + self::$buffer = substr(self::$buffer, $length); + if (strlen($r)) { + return $r; + } + return null; + } + /** * @depends testStatOnDir */ @@ -161,16 +170,6 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase return $sftp; } - static function callback($length) - { - $r = substr(self::$buffer, 0, $length); - self::$buffer = substr(self::$buffer, $length); - if (strlen($r)) { - return $r; - } - return null; - } - /** * @depends testStatOnDir */ @@ -178,7 +177,7 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase { self::$buffer = self::$exampleData; $this->assertTrue( - $sftp->put('file1.txt', [__CLASS__, 'callback'], $sftp::SOURCE_CALLBACK), + $sftp->put('file1.txt', [__CLASS__, 'demoCallback'], $sftp::SOURCE_CALLBACK), 'Failed asserting that example data could be successfully put().' ); @@ -440,8 +439,7 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase */ public function testReadlink($sftp) { - $this->assertInternalType( - 'string', + $this->assertIsString( $sftp->readlink('symlink'), 'Failed asserting that a symlink\'s target could be read' ); @@ -456,14 +454,12 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase public function testStatOnCWD($sftp) { $stat = $sftp->stat('.'); - $this->assertInternalType( - 'array', + $this->assertIsArray( $stat, 'Failed asserting that stat on . returns an array' ); $lstat = $sftp->lstat('.'); - $this->assertInternalType( - 'array', + $this->assertIsArray( $lstat, 'Failed asserting that lstat on . returns an array' ); @@ -605,8 +601,7 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase 'Failed asserting that scratch directory could ' . 'be created.' ); - $this->assertInternalType( - 'array', + $this->assertIsArray( $sftp->stat(self::$scratchDir), 'Failed asserting that stat on an existent empty directory returns an array' ); diff --git a/tests/Functional/Net/SSH2Test.php b/tests/Functional/Net/SSH2Test.php index f51c1cb7..1a9747c4 100644 --- a/tests/Functional/Net/SSH2Test.php +++ b/tests/Functional/Net/SSH2Test.php @@ -14,8 +14,7 @@ class Functional_Net_SSH2Test extends PhpseclibFunctionalTestCase { $ssh = new SSH2($this->getEnv('SSH_HOSTNAME')); - $this->assertInternalType( - 'object', + $this->assertIsObject( $ssh, 'Could not construct NET_SSH2 object.' ); @@ -125,7 +124,7 @@ class Functional_Net_SSH2Test extends PhpseclibFunctionalTestCase { $ssh = new SSH2($this->getEnv('SSH_HOSTNAME')); - $this->assertInternalType('string', $ssh->getServerPublicHostKey()); + $this->assertIsString($ssh->getServerPublicHostKey()); } public function testOpenSocketConnect() diff --git a/tests/PhpseclibTestCase.php b/tests/PhpseclibTestCase.php index 1996af6c..3eaff1c7 100644 --- a/tests/PhpseclibTestCase.php +++ b/tests/PhpseclibTestCase.php @@ -117,4 +117,70 @@ abstract class PhpseclibTestCase extends PHPUnit\Framework\TestCase $method->setAccessible(true); return $method->invokeArgs($obj, $params); } + + // assertIsArray was not introduced until PHPUnit 8 + public static function assertIsArray($actual, $message = '') + { + if (method_exists('\PHPUnit\Framework\TestCase', 'assertIsArray')) { + parent::assertIsArray($actual, $message); + return; + } + + parent::assertInternalType('array', $actual, $message); + } + + // assertIsString was not introduced until PHPUnit 8 + public static function assertIsString($actual, $message = '') + { + if (method_exists('\PHPUnit\Framework\TestCase', 'assertIsString')) { + parent::assertIsString($actual, $message); + return; + } + + parent::assertInternalType('string', $actual, $message); + } + + // assertIsResource was not introduced until PHPUnit 8 + public static function assertIsResource($actual, $message = '') + { + if (method_exists('\PHPUnit\Framework\TestCase', 'assertIsResource')) { + parent::assertIsResource($actual, $message); + return; + } + + parent::assertInternalType('resource', $actual, $message); + } + + // assertIsObject was not introduced until PHPUnit 8 + public static function assertIsObject($actual, $message = '') + { + if (method_exists('\PHPUnit\Framework\TestCase', 'assertIsObject')) { + parent::assertIsObject($actual, $message); + return; + } + + parent::assertInternalType('object', $actual, $message); + } + + // assertContains is deprecated for strings in PHPUnit 8 + public static function assertStringContainsString($needle, $haystack, $message = '') + { + if (method_exists('\PHPUnit\Framework\TestCase', 'assertStringContainsString')) { + parent::assertStringContainsString($needle, $haystack, $message); + return; + } + + parent::assertContains($needle, $haystack, $message); + } + + // assertNotContains is deprecated for strings in PHPUnit 8 + public static function assertStringNotContainsString($needle, $haystack, $message = '') + { + if (method_exists('\PHPUnit\Framework\TestCase', 'assertStringContainsString')) { + parent::assertStringNotContainsString($needle, $haystack, $message); + return; + } + + parent::assertNotContains($needle, $haystack, $message); + } } diff --git a/tests/Unit/Crypt/AES/InternalTest.php b/tests/Unit/Crypt/AES/PurePHPTest.php similarity index 81% rename from tests/Unit/Crypt/AES/InternalTest.php rename to tests/Unit/Crypt/AES/PurePHPTest.php index 9e0e8cb3..43495088 100644 --- a/tests/Unit/Crypt/AES/InternalTest.php +++ b/tests/Unit/Crypt/AES/PurePHPTest.php @@ -7,7 +7,7 @@ use phpseclib3\Crypt\Common\BlockCipher; -class Unit_Crypt_AES_InternalTest extends Unit_Crypt_AES_TestCase +class Unit_Crypt_AES_PurePHPTest extends Unit_Crypt_AES_TestCase { protected function setUp() { diff --git a/tests/Unit/Crypt/AES/TestCase.php b/tests/Unit/Crypt/AES/TestCase.php index f884ae4c..3fbca424 100644 --- a/tests/Unit/Crypt/AES/TestCase.php +++ b/tests/Unit/Crypt/AES/TestCase.php @@ -8,6 +8,8 @@ use phpseclib3\Crypt\AES; use phpseclib3\Crypt\Common\BlockCipher; use phpseclib3\Crypt\Rijndael; +use phpseclib3\Exception\InconsistentSetupException; +use phpseclib3\Exception\InsufficientSetupException; abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase { @@ -105,10 +107,11 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase /** * @group github451 - * @expectedException \LengthException */ public function testKeyPaddingAES() { + $this->expectException('LengthException'); + // same as the above - just with a different ciphertext $aes = new AES('cbc'); @@ -347,11 +350,10 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $this->assertSame($aes->getKeyLength(), 192); } - /** - * @expectedException \phpseclib3\Exception\InconsistentSetupException - */ public function testSetKeyLengthWithLargerKey() { + $this->expectException(InconsistentSetupException::class); + $aes = new AES('cbc'); $aes->setKeyLength(128); $aes->setKey(str_repeat('a', 24)); @@ -362,11 +364,10 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $this->assertSame($aes->getKeyLength(), 128); } - /** - * @expectedException \phpseclib3\Exception\InconsistentSetupException - */ public function testSetKeyLengthWithSmallerKey() { + $this->expectException(InconsistentSetupException::class); + $aes = new AES('cbc'); $aes->setKeyLength(256); $aes->setKey(str_repeat('a', 16)); @@ -408,11 +409,10 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase $this->assertEquals($plaintext, $actual); } - /** - * @expectedException \phpseclib3\Exception\InsufficientSetupException - */ public function testNoKey() { + $this->expectException(InsufficientSetupException::class); + $aes = new AES('cbc'); $aes->setPreferredEngine($this->engine); $aes->setIV(str_repeat('x', 16)); diff --git a/tests/Unit/Crypt/DHTest.php b/tests/Unit/Crypt/DHTest.php index 0750ce5e..e6e15ba3 100644 --- a/tests/Unit/Crypt/DHTest.php +++ b/tests/Unit/Crypt/DHTest.php @@ -30,7 +30,7 @@ Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL public function testParametersWithInteger() { $a = DH::createParameters(512); - $this->assertInternalType('string', "$a"); + $this->assertIsString("$a"); } public function testParametersWithBigIntegers() @@ -55,8 +55,8 @@ Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL { $param = DH::createParameters('diffie-hellman-group1-sha1'); $key = DH::createKey($param); - $this->assertInternalType('string', "$key"); - $this->assertInternalType('string', (string) $key->getPublicKey()); + $this->assertIsString("$key"); + $this->assertIsString((string) $key->getPublicKey()); } public function testLoadPrivate() @@ -119,7 +119,7 @@ i2REGZNPWmF3SRPrtq/4urrDRU0F2eQks7qnTkrauPK1/UvE1gwbqWrWgBko+6L+ Q3ADAIcv9LEmTBnSAOsCs1K9ExAmSv/T2/4+9dW28UYb+p/uV477d1wf+nCWS6VU /gTm -----END PUBLIC KEY-----'); - $this->assertInternalType('string', DH::computeSecret($ourPriv, $theirPub)); + $this->assertIsString(DH::computeSecret($ourPriv, $theirPub)); } public function testComputeSecret() @@ -130,7 +130,7 @@ Q3ADAIcv9LEmTBnSAOsCs1K9ExAmSv/T2/4+9dW28UYb+p/uV477d1wf+nCWS6VU foreach ($curves as $curve) { $ourPriv = EC::createKey($curve); $theirPub = EC::createKey($curve)->getPublicKey(); - $this->assertInternalType('string', DH::computeSecret($ourPriv, $theirPub)); + $this->assertIsString(DH::computeSecret($ourPriv, $theirPub)); } } diff --git a/tests/Unit/Crypt/DSA/CreateKeyTest.php b/tests/Unit/Crypt/DSA/CreateKeyTest.php index 70dd1a61..103be760 100644 --- a/tests/Unit/Crypt/DSA/CreateKeyTest.php +++ b/tests/Unit/Crypt/DSA/CreateKeyTest.php @@ -53,4 +53,3 @@ class Unit_Crypt_DSA_CreateKeyTest extends PhpseclibTestCase $this->assertInstanceOf(PublicKey::class, $privatekey->getPublicKey()); } } - diff --git a/tests/Unit/Crypt/DSA/LoadKeyTest.php b/tests/Unit/Crypt/DSA/LoadDSAKeyTest.php similarity index 92% rename from tests/Unit/Crypt/DSA/LoadKeyTest.php rename to tests/Unit/Crypt/DSA/LoadDSAKeyTest.php index 48b7f2af..d981136e 100644 --- a/tests/Unit/Crypt/DSA/LoadKeyTest.php +++ b/tests/Unit/Crypt/DSA/LoadDSAKeyTest.php @@ -13,14 +13,14 @@ use phpseclib3\Crypt\DSA\Formats\Keys\PKCS1; use phpseclib3\Crypt\DSA\Formats\Keys\PKCS8; use phpseclib3\Crypt\DSA\Formats\Keys\PuTTY; use phpseclib3\Math\BigInteger; +use phpseclib3\Exception\NoKeyLoadedException; -class Unit_Crypt_DSA_LoadKeyTest extends PhpseclibTestCase +class Unit_Crypt_DSA_LoadDSAKeyTest extends PhpseclibTestCase { - /** - * @expectedException \phpseclib3\Exception\NoKeyLoadedException - */ public function testBadKey() { + $this->expectException(NoKeyLoadedException::class); + $key = 'zzzzzzzzzzzzzz'; PublicKeyLoader::load($key); } @@ -57,9 +57,9 @@ Private-MAC: 62b92ddd8b341b9414d640c24ba6ae929a78e039 $dsa = PublicKeyLoader::load($key); $this->assertInstanceOf(PrivateKey::class, $dsa); - $this->assertInternalType('string', "$dsa"); - $this->assertInternalType('string', $dsa->getPublicKey()->toString('PuTTY')); - $this->assertInternalType('string', $dsa->getParameters()->toString('PuTTY')); + $this->assertIsString("$dsa"); + $this->assertIsString($dsa->getPublicKey()->toString('PuTTY')); + $this->assertIsString($dsa->getParameters()->toString('PuTTY')); $dsa = $dsa->withPassword('password'); $this->assertGreaterThan(0, strlen("$dsa")); @@ -91,9 +91,9 @@ Eb2s9fDOpnMhj+WqwcQgs18= $dsa = PublicKeyLoader::load($key); $this->assertInstanceOf(PrivateKey::class, $dsa); - $this->assertInternalType('string', "$dsa"); - $this->assertInternalType('string', $dsa->getPublicKey()->toString('PKCS1')); - $this->assertInternalType('string', (string) $dsa->getParameters()); + $this->assertIsString("$dsa"); + $this->assertIsString($dsa->getPublicKey()->toString('PKCS1')); + $this->assertIsString((string) $dsa->getParameters()); } public function testParameters() @@ -133,7 +133,7 @@ ZpmyOpXM/0opRMIRdmqVW4ardBFNokmlqngwcbaptfRnk9W2cQtx0lmKy6X/vnis $dsa = PublicKeyLoader::load($key); $this->assertInstanceOf(PublicKey::class, $dsa); - $this->assertInternalType('string', "$dsa"); + $this->assertIsString("$dsa"); } public function testPKCS8Private() @@ -151,16 +151,15 @@ Syea3pSvWdBpVhWzOX4A7qbxs+bhWAQWAhQiF7sFfCtZ7oOgCb2aJ9ySC9sTug== $dsa = PublicKeyLoader::load($key); $this->assertInstanceOf(PrivateKey::class, $dsa); - $this->assertInternalType('string', "$dsa"); + $this->assertIsString("$dsa"); $this->assertInstanceOf(PublicKey::class, $dsa->getPublicKey()); $this->assertInstanceOf(Parameters::class, $dsa->getParameters()); } - /** - * @expectedException \phpseclib3\Exception\NoKeyLoadedException - */ public function testPuTTYBadMAC() { + $this->expectException(NoKeyLoadedException::class); + $key = 'PuTTY-User-Key-File-2: ssh-dss Encryption: none Comment: dsa-key-20161223 @@ -208,7 +207,7 @@ ZpmyOpXM/0opRMIRdmqVW4ardBFNokmlqngwcbaptfRnk9W2cQtx0lmKy6X/vnis $dsa = PublicKeyLoader::load($key); $xml = $dsa->toString('XML'); - $this->assertContains('DSAKeyValue', $xml); + $this->assertStringContainsString('DSAKeyValue', $xml); $dsa = PublicKeyLoader::load($xml); $pkcs8 = $dsa->toString('PKCS8'); diff --git a/tests/Unit/Crypt/EC/KeyTest.php b/tests/Unit/Crypt/EC/KeyTest.php index 60b958f1..7d72102c 100644 --- a/tests/Unit/Crypt/EC/KeyTest.php +++ b/tests/Unit/Crypt/EC/KeyTest.php @@ -14,7 +14,7 @@ use phpseclib3\Crypt\EC\Formats\Keys\XML; use phpseclib3\Crypt\PublicKeyLoader; use phpseclib3\Crypt\EC\PrivateKey; -class Unit_Crypt_EC_LoadKeyTest extends PhpseclibTestCase +class Unit_Crypt_EC_KeyTest extends PhpseclibTestCase { public function testBinaryPKCS1PrivateParameters() { @@ -27,7 +27,7 @@ Stf/0U65RhWgBwYFK4EEACKhZANiAASVZJGIs6m/TZhbFoTwBtpvU1JcyixD2YI3 5YnoIx/6Q1oqJg1vrrmUoXaeEpaO6JH8RgItTl9lYMdmOk5309WJka6tI1QAAK3+ Jq9z4moG4whp3JsuiBQG9wnaHVrQPA4= -----END EC PRIVATE KEY-----'); - $this->assertSame('secp384r1', $key->getCurve()); + $this->assertSameNL('secp384r1', $key->getCurve()); } // openssl ecparam -name secp256k1 -genkey -noout -out secp256k1.pem @@ -38,9 +38,9 @@ MHQCAQEEIEzUawcXqUsQhaEQ51JLeOIY0ddzlO2nNgwDk32ETqwkoAcGBSuBBAAK oUQDQgAEFuVcVb9iCUhg2cknHPE+BouHGhQ39ORjMaMI3T4RfRxr6dj5HAXdEqVZ 1W94KMe30ndmTndcJ8BPeT1Dd15FdQ== -----END EC PRIVATE KEY-----'); - $this->assertSame('secp256k1', $key->getCurve()); + $this->assertSameNL('secp256k1', $key->getCurve()); //PKCS1::useNamedCurve(); - $this->assertSame($expected, $key->toString('PKCS1')); + $this->assertSameNL($expected, $key->toString('PKCS1')); } // openssl ecparam -name secp256k1 -genkey -noout -out secp256k1.pem -param_enc explicit @@ -54,7 +54,7 @@ o8RlXaT7/A4RCKj9F7RIpoVUGZxH0I/7ENS4AiEA/////////////////////rqu 3OavSKA7v9JejNA2QUECAQGhRANCAASCTRhjXqmdbqphSdxNkfTNAOmDW5cZ5fnZ ys0Tk4pUv/XdiMZtVCGTNsotGeFbT5X64JkP/BFi3PVqjwy2VhOc -----END EC PRIVATE KEY-----'); - $this->assertSame('secp256k1', $key->getCurve()); + $this->assertSameNL('secp256k1', $key->getCurve()); // this key and the above key have a few small differences. // in both keys the coefficient's are 0 and 7. in the above @@ -75,7 +75,7 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAABwRBBHm+Zn753LusVaBilc6HCwcCm/zbLc4o E5w= -----END EC PRIVATE KEY-----'; PKCS1::useSpecifiedCurve(); - $this->assertSame($expected, $key->toString('PKCS1')); + $this->assertSameNL($expected, $key->toString('PKCS1')); } // openssl ecparam -name secp256k1 -genkey -noout -out secp256k1.pem @@ -87,8 +87,8 @@ MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgAYCXwnhqMT6fCIKIkQ0w cac7QqHrn4TCQMF9a+im74WhRANCAATwCjyGuP8xQbvVjznqazL36oeAnD32I+X2 +wscW3OmyTDpk41HaWYPh+j+BoufsSkCwf8dBRGEQbCieZbbZogy -----END PRIVATE KEY-----'); - $this->assertSame('secp256k1', $key->getCurve()); - $this->assertSame($expected, $key->toString('PKCS8')); + $this->assertSameNL('secp256k1', $key->getCurve()); + $this->assertSameNL($expected, $key->toString('PKCS8')); } // openssl ecparam -name secp256k1 -genkey -noout -out secp256k1.pem -param_enc explicit @@ -104,7 +104,7 @@ IKFfw3vfd5pqA5SZOTFtpr7hdJoKP/rmTPMCggkAOA35oUQDQgAEnX66+UCzUW3T /fkLGIIfZjJm5bIMwAV85LpDom2hI441JRx+/W4WqtGuW+B/LABS6ZHp+qzepThC HsjS3Q9Pew== -----END PRIVATE KEY-----'); - $this->assertSame('secp256k1', $key->getCurve()); + $this->assertSameNL('secp256k1', $key->getCurve()); // see testPKCS1PrivateKeySpecifiedCurve for an explanation // of how this key and the above key differ @@ -119,7 +119,7 @@ AASdfrr5QLNRbdP9+QsYgh9mMmblsgzABXzkukOibaEjjjUlHH79bhaq0a5b4H8s AFLpken6rN6lOEIeyNLdD097 -----END PRIVATE KEY-----'; PKCS8::useSpecifiedCurve(); - $this->assertSame($expected, $key->toString('PKCS8')); + $this->assertSameNL($expected, $key->toString('PKCS8')); } // openssl ecparam -name sect113r1 -genkey -noout -out sect113r1.pem @@ -129,10 +129,10 @@ AFLpken6rN6lOEIeyNLdD097 MEECAQEEDwBZdP4eSzKk/uQa6jdtfKAHBgUrgQQABKEiAyAABAHqCoNb++mK5qvE c4rCzQEuI19czqvXpEPcAWSXew== -----END EC PRIVATE KEY-----'); - $this->assertSame('sect113r1', $key->getCurve()); + $this->assertSameNL('sect113r1', $key->getCurve()); PKCS1::useNamedCurve(); - $this->assertSame($expected, $key->toString('PKCS1')); + $this->assertSameNL($expected, $key->toString('PKCS1')); } // openssl ecparam -name sect113r1 -genkey -noout -out sect113r1.pem -param_enc explicit @@ -145,7 +145,7 @@ AxUAEOcjqxTWluZ2h1YVF1b+v4/LSakEHwQAnXNhbzX0qxQH1zViwQ8ApSgwJ3lY 7oTRMV7TGIYCDwEAAAAAAAAA2czsijnlbwIBAqEiAyAABAFC7c50y7uw+iuHeMCt WwCpKNBUcVeiHme609Dv/g== -----END EC PRIVATE KEY-----'); - $this->assertSame('sect113r1', $key->getCurve()); + $this->assertSameNL('sect113r1', $key->getCurve()); // this key and the above key have a few small differences. // the above key has the (optional) seed for the verifiably @@ -159,7 +159,7 @@ BACdc2FvNfSrFAfXNWLBDwClKDAneVjuhNExXtMYhgIPAQAAAAAAAADZzOyKOeVv oSIDIAAEAULtznTLu7D6K4d4wK1bAKko0FRxV6IeZ7rT0O/+ -----END EC PRIVATE KEY-----'; PKCS1::useSpecifiedCurve(); - $this->assertSame($expected, $key->toString('PKCS1')); + $this->assertSameNL($expected, $key->toString('PKCS1')); } // openssl ecparam -name sect113r1 -genkey -noout -out sect113r1.pem @@ -171,10 +171,10 @@ oSIDIAAEAULtznTLu7D6K4d4wK1bAKko0FRxV6IeZ7rT0O/+ MFECAQAwEAYHKoZIzj0CAQYFK4EEAAQEOjA4AgEBBA8A5OuqAY8HYoFOaz9mE6mh IgMgAAQASF3rOTPXvH0QdRBvsrMBdLMf27yd8AWABrZTxvI= -----END PRIVATE KEY-----'); - $this->assertSame('sect113r1', $key->getCurve()); + $this->assertSameNL('sect113r1', $key->getCurve()); PKCS8::useNamedCurve(); - $this->assertSame($expected, $key->toString('PKCS8')); + $this->assertSameNL($expected, $key->toString('PKCS8')); } // openssl ecparam -name sect113r1 -genkey -noout -out sect113r1.pem -param_enc explicit @@ -188,7 +188,7 @@ AgMCAgEJMDcEDjCIJQym58f+ZJzoWCD3BA7ovuTT4iYHRBiL4OnHIwMVABDnI6sU Ag8BAAAAAAAAANnM7Io55W8CAQIEOjA4AgEBBA8AXtfDMRsRTx8snPbWHquhIgMg AAQA9xdWGJ6vV23+vkdq0C8BLJVg5E3amMyf/5keGa4= -----END PRIVATE KEY-----'); - $this->assertSame('sect113r1', $key->getCurve()); + $this->assertSameNL('sect113r1', $key->getCurve()); // see testBinaryPKCS1PrivateKeySpecifiedCurve() for an // explanation of the differences between the above key @@ -201,7 +201,7 @@ BA8AXtfDMRsRTx8snPbWHquhIgMgAAQA9xdWGJ6vV23+vkdq0C8BLJVg5E3amMyf /5keGa4= -----END PRIVATE KEY-----'; PKCS8::useSpecifiedCurve(); - $this->assertSame($expected, $key->toString('PKCS8')); + $this->assertSameNL($expected, $key->toString('PKCS8')); } // openssl ecparam -name sect131r1 -genkey -noout -out sect131r1.pem -param_enc explicit @@ -215,7 +215,7 @@ AhfAVhCIS2O5xscpFnj500EDFQBNaW5naHVhUXWYW9OtutohtDqX4gQjBACBuvkf 35gzxA+cGBNDY4OZB4xufqOMAB9zyBNLG0754VACEQQAAAAAAAAAAjEjlTqUZLVN AgECoSYDJAAEBEIolGjo5lnsYqNagqYPOaEGOglkllDO2aWPtB6n+x/WXw== -----END EC PRIVATE KEY-----'); - $this->assertSame('sect131r1', $key->getCurve()); + $this->assertSameNL('sect131r1', $key->getCurve()); // see testBinaryPKCS1PrivateKeySpecifiedCurve() for an // explanation of the differences between the above key @@ -228,7 +228,7 @@ SxtO+eFQAhEEAAAAAAAAAAIxI5U6lGS1TaEmAyQABARCKJRo6OZZ7GKjWoKmDzmh BjoJZJZQztmlj7Qep/sf1l8= -----END EC PRIVATE KEY-----'; PKCS1::useSpecifiedCurve(); - $this->assertSame($expected, $key->toString('PKCS1')); + $this->assertSameNL($expected, $key->toString('PKCS1')); } // from https://tools.ietf.org/html/draft-ietf-curdle-pkix-07#section-10.1 @@ -237,7 +237,7 @@ BjoJZJZQztmlj7Qep/sf1l8= $key = PublicKeyLoader::load('-----BEGIN PUBLIC KEY----- MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuE= -----END PUBLIC KEY-----'); - $this->assertSame('Ed25519', $key->getCurve()); + $this->assertSameNL('Ed25519', $key->getCurve()); // in the above key AlgorithmIdentifier has a single "child". in the // following key it has two. The second one is ("optional") NULL. @@ -246,7 +246,7 @@ MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuE= $expected = '-----BEGIN PUBLIC KEY----- MCwwBwYDK2VwBQADIQAZv0QJaYTN/oVBusFn3DuWyFCGqjC2tssMXDitcDFm4Q== -----END PUBLIC KEY-----'; - $this->assertSame($expected, $key->toString('PKCS8')); + $this->assertSameNL($expected, $key->toString('PKCS8')); } // from https://tools.ietf.org/html/draft-ietf-curdle-pkix-07#section-10.3 @@ -256,8 +256,8 @@ MCwwBwYDK2VwBQADIQAZv0QJaYTN/oVBusFn3DuWyFCGqjC2tssMXDitcDFm4Q== $key = PublicKeyLoader::load('-----BEGIN PRIVATE KEY----- MC4CAQAwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC -----END PRIVATE KEY-----'); - $this->assertSame('Ed25519', $key->getCurve()); - $this->assertSame('Ed25519', $key->getPublicKey()->getCurve()); + $this->assertSameNL('Ed25519', $key->getCurve()); + $this->assertSameNL('Ed25519', $key->getPublicKey()->getCurve()); // with public key $key = PublicKeyLoader::load('-----BEGIN PRIVATE KEY----- @@ -265,8 +265,8 @@ MHICAQEwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC oB8wHQYKKoZIhvcNAQkJFDEPDA1DdXJkbGUgQ2hhaXJzgSEAGb9ECWmEzf6FQbrB Z9w7lshQhqowtrbLDFw4rXAxZuE= -----END PRIVATE KEY-----'); - $this->assertSame('Ed25519', $key->getCurve()); - $this->assertSame('Ed25519', $key->getPublicKey()->getCurve()); + $this->assertSameNL('Ed25519', $key->getCurve()); + $this->assertSameNL('Ed25519', $key->getPublicKey()->getCurve()); // the above key not only omits NULL - it also includes a // unstructuredName attribute with a value of "Curdle Chairs" @@ -275,12 +275,12 @@ Z9w7lshQhqowtrbLDFw4rXAxZuE= MFMCAQEwBwYDK2VwBQAEIgQg1O5y2/kTWErVttjx92n4rTr+fCjL8dT74Jeoj0R1 WEKBIQAZv0QJaYTN/oVBusFn3DuWyFCGqjC2tssMXDitcDFm4Q== -----END PRIVATE KEY-----'; - $this->assertSame($expected, $key->toString('PKCS8')); + $this->assertSameNL($expected, $key->toString('PKCS8')); $expected = EC::createKey('Ed25519')->toString('PKCS8'); $key = PublicKeyLoader::load($expected); - $this->assertSame('Ed25519', $key->getCurve()); - $this->assertSame('Ed25519', $key->getPublicKey()->getCurve()); + $this->assertSameNL('Ed25519', $key->getCurve()); + $this->assertSameNL('Ed25519', $key->getPublicKey()->getCurve()); } public function testPuTTYnistp256() @@ -296,16 +296,16 @@ Private-Lines: 1 AAAAIQDwaPlajbXY1SxhuwsUqN1CEZ5g4adsbmJsKm+ZbUVm4g== Private-MAC: b85ca0eb7c612df5d18af85128821bd53faaa3ef '); - $this->assertSame('secp256r1', $key->getCurve()); + $this->assertSameNL('secp256r1', $key->getCurve()); PuTTY::setComment('ecdsa-key-20181105'); - $this->assertSame($expected, $key->toString('PuTTY')); + $this->assertSameNL($expected, $key->toString('PuTTY')); $key = PublicKeyLoader::load($expected = 'ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJEXCsWA8s18m25MJlVE1urbXPYFi4q8oMbb2H0kE2f5WPxizsKXRmb1J68paXQizryL9fC4FTqICJ1+UnaPfk0= ecdsa-key-20181105'); - $this->assertSame('secp256r1', $key->getCurve()); + $this->assertSameNL('secp256r1', $key->getCurve()); OpenSSH::setComment('ecdsa-key-20181105'); - $this->assertSame($expected, $key->toString('OpenSSH')); + $this->assertSameNL($expected, $key->toString('OpenSSH')); } public function testPuTTYnistp384() @@ -322,16 +322,16 @@ AAAAMQCEMkGMDg6N7bUqdvLXe0YmY4qBSi8hmAuMvU38RDoVFVmV+R4RYmMueyrX be9Oyus= Private-MAC: 97a990a3d5f6b8f268d4be9c4ab9ebfd8fa79849 '); - $this->assertSame('secp384r1', $key->getCurve()); + $this->assertSameNL('secp384r1', $key->getCurve()); PuTTY::setComment('ecdsa-key-20181105'); - $this->assertSame($expected, $key->toString('PuTTY')); + $this->assertSameNL($expected, $key->toString('PuTTY')); $key = PublicKeyLoader::load($expected = 'ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBOI53wHG3CdcAJZq5PXWZAEAxxsNVFQlQgOX9toWEOgqQF5LbK2nWLKRvaHMzocUXaTYZDccSS0ATZFPT3j1Er1LU9cu4PHpyS07v262jdzkxIvKCPcAeISuV80MC7rHog== ecdsa-key-20181105'); - $this->assertSame('secp384r1', $key->getCurve()); + $this->assertSameNL('secp384r1', $key->getCurve()); OpenSSH::setComment('ecdsa-key-20181105'); - $this->assertSame($expected, $key->toString('OpenSSH')); + $this->assertSameNL($expected, $key->toString('OpenSSH')); } @@ -350,16 +350,16 @@ AAAAQgHJl8/dIArolFymdzhagXCfd2l8UF3CQXWGVGDQ0R04nnntlyztYiVdRXXK r84NnzS7dJcAsR9YaUOZ69NRKNiUAQ== Private-MAC: 6d49ce289b85549a43d74422dd8bb3ba8798c72c '); - $this->assertSame('secp521r1', $key->getCurve()); + $this->assertSameNL('secp521r1', $key->getCurve()); PuTTY::setComment('ecdsa-key-20181105'); - $this->assertSame($expected, $key->toString('PuTTY')); + $this->assertSameNL($expected, $key->toString('PuTTY')); $key = PublicKeyLoader::load($expected = 'ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAF1Eg0MjaJwooFj6HCNh4RWbvmQRY+sdczJyBdT3EaTc/6IUcCfW7w7rAeRp2CDdE9RlAVD8IuLqW7DJH06Xeov8wBO5G6jUqXu0rlHsOSiC6VcCxBJuWVNB1IorHnS7PX0f6HdLlIEme73P77drqpn5YY0XLtP6hFrF7H5XfCxpNyaJA== ecdsa-key-20181105'); - $this->assertSame('secp521r1', $key->getCurve()); + $this->assertSameNL('secp521r1', $key->getCurve()); OpenSSH::setComment('ecdsa-key-20181105'); - $this->assertSame($expected, $key->toString('OpenSSH')); + $this->assertSameNL($expected, $key->toString('OpenSSH')); } public function testPuTTYed25519() @@ -374,16 +374,16 @@ Private-Lines: 1 AAAAIAHu1uI7dxFzo/SleEI2CekXKmgqlXwOgvfaRWxiX4Jd Private-MAC: 8a06821a1c8b8b40fc40f876e543c4ea3fb81bb9 '); - $this->assertSame('Ed25519', $key->getCurve()); + $this->assertSameNL('Ed25519', $key->getCurve()); PuTTY::setComment('ed25519-key-20181105'); - $this->assertSame($expected, $key->toString('PuTTY')); + $this->assertSameNL($expected, $key->toString('PuTTY')); $key = PublicKeyLoader::load($expected = 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC6I6RyYAqtBcWXws9EDqGbhFtc5rKG4NMn/G7temQtu ed25519-key-20181105'); - $this->assertSame('Ed25519', $key->getCurve()); + $this->assertSameNL('Ed25519', $key->getCurve()); OpenSSH::setComment('ed25519-key-20181105'); - $this->assertSame($expected, $key->toString('OpenSSH')); + $this->assertSameNL($expected, $key->toString('OpenSSH')); } public function testlibsodium() @@ -395,12 +395,12 @@ Private-MAC: 8a06821a1c8b8b40fc40f876e543c4ea3fb81bb9 $kp = sodium_crypto_sign_keypair(); $key = EC::loadFormat('libsodium', $expected = sodium_crypto_sign_secretkey($kp)); - $this->assertSame('Ed25519', $key->getCurve()); - $this->assertSame($expected, $key->toString('libsodium')); + $this->assertSameNL('Ed25519', $key->getCurve()); + $this->assertSameNL($expected, $key->toString('libsodium')); $key = EC::loadFormat('libsodium', $expected = sodium_crypto_sign_publickey($kp)); - $this->assertSame('Ed25519', $key->getCurve()); - $this->assertSame($expected, $key->toString('libsodium')); + $this->assertSameNL('Ed25519', $key->getCurve()); + $this->assertSameNL($expected, $key->toString('libsodium')); } // ssh-keygen -t ed25519 @@ -413,7 +413,7 @@ eQAAAAtzc2gtZWQyNTUxOQAAACCpm7dS1/WDTW+uuhp2+aFLPKaJle6+oJqDGLXhlQAX4A AAAEDltCTSbrr42IS4hhkS6ly0W2XItRQwxjLT+03bIyA+V6mbt1LX9YNNb666Gnb5oUs8 pomV7r6gmoMYteGVABfgAAAAD3ZhZ3JhbnRAdmFncmFudAECAwQFBg== -----END OPENSSH PRIVATE KEY-----'); - $this->assertSame('Ed25519', $key->getCurve()); + $this->assertSameNL('Ed25519', $key->getCurve()); // testing this key is a little difficult because of this format's // two back to back checkint fields. both fields correspond to the @@ -423,7 +423,7 @@ pomV7r6gmoMYteGVABfgAAAAD3ZhZ3JhbnRAdmFncmFudAECAwQFBg== // none-the-less, because of the randomized component we can't easily // see if the key string is equal to another known string $key2 = PublicKeyLoader::load($key->toString('OpenSSH')); - $this->assertSame('Ed25519', $key2->getCurve()); + $this->assertSameNL('Ed25519', $key2->getCurve()); } // from https://www.w3.org/TR/xmldsig-core/#sec-RFC4050Compat @@ -438,7 +438,7 @@ pomV7r6gmoMYteGVABfgAAAAD3ZhZ3JhbnRAdmFncmFudAECAwQFBg== '); - $this->assertSame('secp256r1', $key->getCurve()); + $this->assertSameNL('secp256r1', $key->getCurve()); XML::enableRFC4050Syntax(); @@ -452,14 +452,14 @@ pomV7r6gmoMYteGVABfgAAAAD3ZhZ3JhbnRAdmFncmFudAECAwQFBg== $dom->loadXML($key->toString('XML')); $actual = $dom->C14N(); - $this->assertSame($expected, $actual); + $this->assertSameNL($expected, $actual); } - public static function assertSame($expected, $actual, $message = '') + public function assertSameNL($expected, $actual, $message = '') { $expected = str_replace("\r\n", "\n", $expected); $actual = str_replace("\r\n", "\n", $actual); - return parent::assertSame($expected, $actual, $message); + $this->assertSame($expected, $actual, $message); } public function testOpenSSHPrivateEC() diff --git a/tests/Unit/Crypt/HashTest.php b/tests/Unit/Crypt/HashTest.php index 9c8a1e3d..80e57f40 100644 --- a/tests/Unit/Crypt/HashTest.php +++ b/tests/Unit/Crypt/HashTest.php @@ -6,6 +6,7 @@ */ use phpseclib3\Crypt\Hash; +use phpseclib3\Exception\UnsupportedAlgorithmException; class Unit_Crypt_HashTest extends PhpseclibTestCase { @@ -373,19 +374,17 @@ class Unit_Crypt_HashTest extends PhpseclibTestCase $this->assertSame($hash->getHash(), 'sha256'); } - /** - * @expectedException \phpseclib3\Exception\UnsupportedAlgorithmException - */ public function testConstructorArgumentInvalid() { + $this->expectException(UnsupportedAlgorithmException::class); + new Hash('abcdefghijklmnopqrst'); } - /** - * @expectedException \phpseclib3\Exception\UnsupportedAlgorithmException - */ public function testSetHashInvalid() { + $this->expectException(UnsupportedAlgorithmException::class); + $hash = new Hash('md5'); $hash->setHash('abcdefghijklmnopqrst-96'); } diff --git a/tests/Unit/Crypt/RSA/CreateKeyTest.php b/tests/Unit/Crypt/RSA/CreateKeyTest.php index 6506d862..7c56312f 100644 --- a/tests/Unit/Crypt/RSA/CreateKeyTest.php +++ b/tests/Unit/Crypt/RSA/CreateKeyTest.php @@ -34,7 +34,7 @@ class Unit_Crypt_RSA_CreateKeyTest extends PhpseclibTestCase { list($publickey, $privatekey) = $args; $ciphertext = $publickey->encrypt('zzz'); - $this->assertInternalType('string', $ciphertext); + $this->assertIsString($ciphertext); $plaintext = $privatekey->decrypt($ciphertext); $this->assertSame($plaintext, 'zzz'); } diff --git a/tests/Unit/Crypt/RSA/LoadKeyTest.php b/tests/Unit/Crypt/RSA/LoadKeyTest.php index f2fe3e0c..9105e484 100644 --- a/tests/Unit/Crypt/RSA/LoadKeyTest.php +++ b/tests/Unit/Crypt/RSA/LoadKeyTest.php @@ -15,6 +15,8 @@ use phpseclib3\Crypt\RSA\Formats\Keys\PuTTY; use phpseclib3\Crypt\RSA\Formats\Keys\OpenSSH; use phpseclib3\Crypt\RSA\Formats\Keys\PSS; use phpseclib3\Math\BigInteger; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Exception\NoKeyLoadedException; class Unit_Crypt_RSA_LoadKeyTest extends PhpseclibTestCase { @@ -24,11 +26,10 @@ class Unit_Crypt_RSA_LoadKeyTest extends PhpseclibTestCase OpenSSH::setComment('phpseclib-generated-key'); } - /** - * @expectedException \phpseclib3\Exception\NoKeyLoadedException - */ public function testBadKey() { + $this->expectException(NoKeyLoadedException::class); + $key = 'zzzzzzzzzzzzzz'; PublicKeyLoader::load($key); } @@ -52,7 +53,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ $rsa = PublicKeyLoader::load($key); $this->assertInstanceOf(PrivateKey::class, $rsa); - $this->assertInternalType('string', "$rsa"); + $this->assertIsString("$rsa"); } public function testPKCS1SpacesKey() @@ -75,7 +76,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ $rsa = PublicKeyLoader::load($key); $this->assertInstanceOf(PrivateKey::class, $rsa); - $this->assertInternalType('string', "$rsa"); + $this->assertIsString("$rsa"); } public function testPKCS1NoHeaderKey() @@ -95,7 +96,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ $rsa = PublicKeyLoader::load($key); $this->assertInstanceOf(PrivateKey::class, $rsa); - $this->assertInternalType('string', "$rsa"); + $this->assertIsString("$rsa"); } public function testPKCS1NoWhitespaceNoHeaderKey() @@ -115,7 +116,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ $rsa = PublicKeyLoader::load($key); $this->assertInstanceOf(PrivateKey::class, $rsa); - $this->assertInternalType('string', "$rsa"); + $this->assertIsString("$rsa"); } public function testRawPKCS1Key() @@ -136,7 +137,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ $rsa = PublicKeyLoader::load($key); $this->assertInstanceOf(PrivateKey::class, $rsa); - $this->assertInternalType('string', "$rsa"); + $this->assertIsString("$rsa"); } public function testLoadPKCS8PrivateKey() @@ -174,7 +175,7 @@ xryZaRDVmtMuf/OZBQ== $rsa = PublicKeyLoader::load($key, 'password'); $this->assertInstanceOf(PrivateKey::class, $rsa); - $this->assertInternalType('string', "$rsa"); + $this->assertIsString("$rsa"); } public function testSavePKCS8PrivateKey() @@ -247,7 +248,7 @@ Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB $rsa = PublicKeyLoader::load($key)->asPrivateKey(); $this->assertInstanceOf(PrivateKey::class, $rsa); - $this->assertInternalType('string', $rsa->sign('zzz')); + $this->assertIsString($rsa->sign('zzz')); } public function testSSHPubKey() @@ -1016,11 +1017,10 @@ YYFw8pfGesIFoEuVth4HKyF8k1y4mRUnYHP1XNMNMJl1JcEArC2asV8sHf6zSPVffozZ $this->assertInstanceOf(PublicKey::class, $key); } - /** - * @expectedException \phpseclib3\Exception\UnsupportedFormatException - */ public function testSavePasswordXML() { + $this->expectException(UnsupportedFormatException::class); + $key = '-----BEGIN RSA PRIVATE KEY----- MIIBOgIBAAJBAKj34GkxFhD90vcNLYLInFEX6Ppy1tPf9Cnzj4p4WGeKLs1Pt8Qu KUpRKfFLfRYC9AIKjbJTWit+CqvjWYzvQwECAwEAAQJAIJLixBy2qpFoS4DSmoEm @@ -1043,6 +1043,6 @@ n9dyFZYXxil/cgFG/PDMnuXy1Wcl8hb8iwQag4Y7ohiLXVTJa/0BAgMBAAE= -----END RSA PRIVATE KEY-----'; $key = PublicKeyLoader::load($key); $result = $key->toString('PKCS1'); - $this->assertInternalType('string', $result); + $this->assertIsString($result); } } diff --git a/tests/Unit/Crypt/RSA/ModeTest.php b/tests/Unit/Crypt/RSA/ModeTest.php index bc4e12e4..c1202a51 100644 --- a/tests/Unit/Crypt/RSA/ModeTest.php +++ b/tests/Unit/Crypt/RSA/ModeTest.php @@ -67,11 +67,10 @@ p0GbMJDyR4e9T04ZZwIDAQAB $this->assertTrue($rsa->verify('zzzz', $sig)); } - /** - * @expectedException \LengthException - */ public function testSmallModulo() { + $this->expectException('LengthException'); + $plaintext = 'x'; $key = PKCS8::savePublicKey( diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index 810111e0..d9f80e8f 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -78,7 +78,7 @@ class Unit_File_ASN1Test extends PhpseclibTestCase $decoded = ASN1::decodeBER(base64_decode($str)); $result = ASN1::asn1map($decoded[0], $AS_REP); - $this->assertInternalType('array', $result); + $this->assertIsArray($result); } /** @@ -229,7 +229,7 @@ class Unit_File_ASN1Test extends PhpseclibTestCase $decoded = ASN1::decodeBER(base64_decode($str)); $result = ASN1::asn1map($decoded[0], $AS_REP); - $this->assertInternalType('array', $result); + $this->assertIsArray($result); } /** @@ -271,7 +271,7 @@ class Unit_File_ASN1Test extends PhpseclibTestCase public function testContextSpecificNonConstructed() { $decoded = ASN1::decodeBER(base64_decode('MBaAFJtUo7c00HsI5EPZ4bkICfkOY2Pv')); - $this->assertInternalType('string', $decoded[0]['content'][0]['content']); + $this->assertIsString($decoded[0]['content'][0]['content']); } /** @@ -280,7 +280,7 @@ class Unit_File_ASN1Test extends PhpseclibTestCase public function testEmptyContextTag() { $decoded = ASN1::decodeBER("\xa0\x00"); - $this->assertInternalType('array', $decoded); + $this->assertIsArray($decoded); $this->assertCount(0, $decoded[0]['content']); } @@ -390,6 +390,6 @@ class Unit_File_ASN1Test extends PhpseclibTestCase $a = ASN1::decodeBER($a); $a = ASN1::asn1map($a[0], $map); - $this->assertInternalType('array', $a); + $this->assertIsArray($a); } } diff --git a/tests/Unit/File/X509/CSRTest.php b/tests/Unit/File/X509/CSRTest.php index 4e5e666f..f2732471 100644 --- a/tests/Unit/File/X509/CSRTest.php +++ b/tests/Unit/File/X509/CSRTest.php @@ -28,7 +28,7 @@ v5RwaQHmQEzHofTzF7I+ $spkac = $x509->loadCSR($test); - $this->assertInternalType('array', $spkac); + $this->assertIsArray($spkac); } public function testCSRWithAttributes() @@ -68,7 +68,7 @@ draiRBZruwMPwPIP $csr = $x509->loadCSR($test); - $this->assertInternalType('array', $csr); + $this->assertIsArray($csr); } public function testCSRDER() @@ -93,7 +93,7 @@ draiRBZruwMPwPIP $csr = $x509->loadCSR($csr); - $this->assertInternalType('array', $csr); + $this->assertIsArray($csr); } // on PHP 7.1, with older versions of phpseclib, this would produce a "A non-numeric value encountered" warning diff --git a/tests/Unit/File/X509/SPKACTest.php b/tests/Unit/File/X509/SPKACTest.php index d71d2813..fd1caeee 100644 --- a/tests/Unit/File/X509/SPKACTest.php +++ b/tests/Unit/File/X509/SPKACTest.php @@ -28,11 +28,11 @@ class Unit_File_X509_SPKACTest extends PhpseclibTestCase $spkac = $x509->loadSPKAC($test); - $this->assertInternalType('array', $spkac); + $this->assertIsArray($spkac); $spkac = $x509->loadSPKAC('SPKAC=' . $test); - $this->assertInternalType('array', $spkac); + $this->assertIsArray($spkac); $this->assertTrue( $x509->validateSignature(), @@ -41,7 +41,7 @@ class Unit_File_X509_SPKACTest extends PhpseclibTestCase $pubKey = $x509->getPublicKey(); - $this->assertInternalType('string', "$pubKey"); + $this->assertIsString("$pubKey"); } public function testSaveSPKAC() @@ -55,17 +55,17 @@ class Unit_File_X509_SPKACTest extends PhpseclibTestCase $x509->setChallenge('...'); $spkac = $x509->signSPKAC(); - $this->assertInternalType('array', $spkac); + $this->assertIsArray($spkac); - $this->assertInternalType('string', $x509->saveSPKAC($spkac)); + $this->assertIsString($x509->saveSPKAC($spkac)); $x509 = new X509(); $x509->setPrivateKey($privatekey); $spkac = $x509->signSPKAC(); - $this->assertInternalType('array', $spkac); + $this->assertIsArray($spkac); - $this->assertInternalType('string', $x509->saveSPKAC($spkac)); + $this->assertIsString($x509->saveSPKAC($spkac)); } public function testBadSignatureSPKAC() diff --git a/tests/Unit/File/X509/X509Test.php b/tests/Unit/File/X509/X509Test.php index 3aaefd36..76b85c35 100644 --- a/tests/Unit/File/X509/X509Test.php +++ b/tests/Unit/File/X509/X509Test.php @@ -59,7 +59,7 @@ k6m17mi63YW/+iPCGOWZ2qXmY5HPEyyF2L4L4IDryFJ+8xLyw3pH9/yp5aHZDtp6 $cert = $x509->loadX509($test); - $this->assertInternalType('array', $cert['tbsCertificate']['extensions'][3]['extnValue']); + $this->assertIsArray($cert['tbsCertificate']['extensions'][3]['extnValue']); } public function testLoadUnsupportedExtension() @@ -865,7 +865,7 @@ uhPlgkgknwIgdDqqKIAF60ouiynsbU53ERS0TwpjeFiYGA48SwYW3Nk= $result = $x509->sign($issuer, $subject); $result = $x509->saveX509($result); - $this->assertInternalType('string', $result); + $this->assertIsString($result); $r = $x509->loadX509($result); $this->assertSame('id-dsa-with-sha256', $r['tbsCertificate']['signature']['algorithm']); @@ -896,7 +896,7 @@ wkwhE/JaQAEHq2PHnEmvwyBiJcHSdLXkcLzYlg19Ho0BPqVKdulx8GAk $result = $x509->sign($issuer, $subject); $result = $x509->saveX509($result); - $this->assertInternalType('string', $result); + $this->assertIsString($result); $r = $x509->loadX509($result); $this->assertSame('ecdsa-with-SHA256', $r['tbsCertificate']['signature']['algorithm']); @@ -935,7 +935,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ $result = $x509->sign($issuer, $subject); $result = $x509->saveX509($result); - $this->assertInternalType('string', $result); + $this->assertIsString($result); $r = $x509->loadX509($result); $this->assertSame('id-RSASSA-PSS', $r['tbsCertificate']['signature']['algorithm']); @@ -979,7 +979,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ $result = $x509->sign($issuer, $subject); $result = $x509->saveX509($result); - $this->assertInternalType('string', $result); + $this->assertIsString($result); $r = $x509->loadX509($result); $this->assertSame('sha256WithRSAEncryption', $r['tbsCertificate']['signature']['algorithm']); diff --git a/tests/Unit/Math/BigInteger/PHP64OpenSSLTest.php b/tests/Unit/Math/BigInteger/PHP64OpenSSLTest.php index c4a28bcf..a49eecab 100644 --- a/tests/Unit/Math/BigInteger/PHP64OpenSSLTest.php +++ b/tests/Unit/Math/BigInteger/PHP64OpenSSLTest.php @@ -7,11 +7,13 @@ use \phpseclib3\Math\BigInteger\Engines\PHP64; -class Unit_Math_BigInteger_PHP64OpenSSLTest extends Unit_Math_BigInteger_PHP64Test +class Unit_Math_BigInteger_PHP64OpenSSLTest extends Unit_Math_BigInteger_TestCase { public static function setUpBeforeClass() { - parent::setUpBeforeClass(); + if (!PHP64::isValidEngine()) { + self::markTestSkipped('64-bit integers are not available.'); + } try { PHP64::setModExpEngine('OpenSSL'); @@ -19,4 +21,22 @@ class Unit_Math_BigInteger_PHP64OpenSSLTest extends Unit_Math_BigInteger_PHP64Te self::markTestSkipped('openssl_public_encrypt() function is not available.'); } } + + public function getInstance($x = 0, $base = 10) + { + return new PHP64($x, $base); + } + + public function testInternalRepresentation() + { + $x = new PHP64('FFFFFFFFFFFFFFFFC90FDA', 16); + $y = new PHP64("$x"); + + $this->assertSame(self::getVar($x, 'value'), self::getVar($y, 'value')); + } + + public static function getStaticClass() + { + return 'phpseclib3\Math\BigInteger\Engines\PHP64'; + } } diff --git a/tests/Unit/Math/BigInteger/TestCase.php b/tests/Unit/Math/BigInteger/TestCase.php index a64fb9ad..75066a54 100644 --- a/tests/Unit/Math/BigInteger/TestCase.php +++ b/tests/Unit/Math/BigInteger/TestCase.php @@ -384,7 +384,7 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase { $num = $this->getInstance(50); $str = print_r($num, true); - $this->assertContains('[value] => 0x32', $str); + $this->assertStringContainsString('[value] => 0x32', $str); } public function testPrecision() diff --git a/tests/Unit/Net/SFTPStreamTest.php b/tests/Unit/Net/SFTPStreamUnitTest.php similarity index 92% rename from tests/Unit/Net/SFTPStreamTest.php rename to tests/Unit/Net/SFTPStreamUnitTest.php index 90647bd7..2aa7ab21 100644 --- a/tests/Unit/Net/SFTPStreamTest.php +++ b/tests/Unit/Net/SFTPStreamUnitTest.php @@ -7,7 +7,7 @@ use phpseclib3\Net\SFTP\Stream; -class Unit_Net_SFTPStreamTest extends PhpseclibTestCase +class Unit_Net_SFTPStreamUnitTest extends PhpseclibTestCase { public function testRegisterWithoutArgument() { diff --git a/tests/Unit/Net/SSH2Test.php b/tests/Unit/Net/SSH2UnitTest.php similarity index 75% rename from tests/Unit/Net/SSH2Test.php rename to tests/Unit/Net/SSH2UnitTest.php index 8703709a..824f52a3 100644 --- a/tests/Unit/Net/SSH2Test.php +++ b/tests/Unit/Net/SSH2UnitTest.php @@ -6,7 +6,7 @@ * @license http://www.opensource.org/licenses/mit-license.html MIT License */ -class Unit_Net_SSH2Test extends PhpseclibTestCase +class Unit_Net_SSH2UnitTest extends PhpseclibTestCase { public function formatLogDataProvider() { @@ -41,30 +41,30 @@ class Unit_Net_SSH2Test extends PhpseclibTestCase $identifier = self::callFunc($this->createSSHMock(), 'generate_identifier'); $this->assertStringStartsWith('SSH-2.0-phpseclib_3.0', $identifier); - if (function_exists('\\Sodium\\library_version_major')) { - $this->assertContains('libsodium', $identifier); + if (function_exists('sodium_crypto_sign_keypair')) { + $this->assertStringContainsString('libsodium', $identifier); } if (extension_loaded('openssl')) { - $this->assertContains('openssl', $identifier); - $this->assertNotContains('mcrypt', $identifier); + $this->assertStringContainsString('openssl', $identifier); + $this->assertStringNotContainsString('mcrypt', $identifier); } elseif (extension_loaded('mcrypt')) { - $this->assertNotContains('openssl', $identifier); - $this->assertContains('mcrypt', $identifier); + $this->assertStringNotContainsString('openssl', $identifier); + $this->assertStringContainsString('mcrypt', $identifier); } else { - $this->assertNotContains('openssl', $identifier); - $this->assertNotContains('mcrypt', $identifier); + $this->assertStringNotContainsString('openssl', $identifier); + $this->assertStringNotContainsString('mcrypt', $identifier); } if (extension_loaded('gmp')) { - $this->assertContains('gmp', $identifier); - $this->assertNotContains('bcmath', $identifier); + $this->assertStringContainsString('gmp', $identifier); + $this->assertStringNotContainsString('bcmath', $identifier); } elseif (extension_loaded('bcmath')) { - $this->assertNotContains('gmp', $identifier); - $this->assertContains('bcmath', $identifier); + $this->assertStringNotContainsString('gmp', $identifier); + $this->assertStringContainsString('bcmath', $identifier); } else { - $this->assertNotContains('gmp', $identifier); - $this->assertNotContains('bcmath', $identifier); + $this->assertStringNotContainsString('gmp', $identifier); + $this->assertStringNotContainsString('bcmath', $identifier); } } diff --git a/travis/run-phpunit.sh b/travis/run-phpunit.sh index ce393a77..95a419b1 100755 --- a/travis/run-phpunit.sh +++ b/travis/run-phpunit.sh @@ -20,6 +20,24 @@ then PHPUNIT_ARGS="$PHPUNIT_ARGS -d zend.enable_gc=0" fi +if [ `php -r "echo (int) version_compare(PHP_VERSION, '7.3', '>=');"` = "1" ] +then + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/n setUpBeforeClass()/n setUpBeforeClass(): void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/n setUp()/n setUp(): void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/n tearDown()/n tearDown(): void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertIsArray([^)]*)\)/\1: void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertIsString([^)]*)\)/\1: void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertIsResource([^)]*)\)/\1: void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertIsObject([^)]*)\)/\1: void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertStringContainsString([^)]*)\)/\1: void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertStringNotContainsString([^)]*)\)/\1: void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Unit_Crypt_\(AES\|DSA\|EC\|RSA\)_/class /g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Unit_File_\(X509\)_/class /g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Unit_Math_\(BigInteger\)_/class /g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Unit_\(Crypt\|File\|Math\|Net\)_/class /g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Functional_Net_/class /g' +fi + if [ "$TRAVIS_PHP_VERSION" = 'hhvm' -o `php -r "echo (int) version_compare(PHP_VERSION, '7.0', '>=');"` = "1" ] then find tests -type f -name "*Test.php" | \