diff --git a/Zotlabs/Lib/Keyutils.php b/Zotlabs/Lib/Keyutils.php index 616ecfcf6..33f910236 100644 --- a/Zotlabs/Lib/Keyutils.php +++ b/Zotlabs/Lib/Keyutils.php @@ -2,8 +2,8 @@ namespace Zotlabs\Lib; -use phpseclib\Crypt\RSA; -use phpseclib\Math\BigInteger; +use phpseclib3\Crypt\PublicKeyLoader; +use phpseclib3\Math\BigInteger; /** * Keyutils @@ -16,41 +16,42 @@ class Keyutils { * @param string $e exponent * @return string */ - public static function meToPem($m, $e) { - - $rsa = new RSA(); - $rsa->loadKey([ + public static function meToPem(string $m, string $e): string + { + $parsedKey = PublicKeyLoader::load([ 'e' => new BigInteger($e, 256), 'n' => new BigInteger($m, 256) ]); - return $rsa->getPublicKey(); - + if (method_exists($parsedKey, 'getPublicKey')) { + $parsedKey = $parsedKey->getPublicKey(); + } + return $parsedKey->toString('PKCS8'); } /** * @param string key * @return string */ - public static function rsaToPem($key) { - - $rsa = new RSA(); - $rsa->setPublicKey($key); - - return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS8); - + public static function rsaToPem(string $key): string + { + $parsedKey = PublicKeyLoader::load($key); + if (method_exists($parsedKey, 'getPublicKey')) { + $parsedKey = $parsedKey->getPublicKey(); + } + return $parsedKey->toString('PKCS8'); } /** * @param string key * @return string */ - public static function pemToRsa($key) { - - $rsa = new RSA(); - $rsa->setPublicKey($key); - - return $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1); - + public static function pemToRsa(string $key): string + { + $parsedKey = PublicKeyLoader::load($key); + if (method_exists($parsedKey, 'getPublicKey')) { + $parsedKey = $parsedKey->getPublicKey(); + } + return $parsedKey->toString('PKCS1'); } /** @@ -58,23 +59,28 @@ class Keyutils { * @param string $m reference modulo * @param string $e reference exponent */ - public static function pemToMe($key, &$m, &$e) { + public static function pemToMe(string $key): array + { + $parsedKey = PublicKeyLoader::load($key); + if (method_exists($parsedKey, 'getPublicKey')) { + $parsedKey = $parsedKey->getPublicKey(); + } + $raw = $parsedKey->toString('Raw'); - $rsa = new RSA(); - $rsa->loadKey($key); - $rsa->setPublicKey(); - - $m = $rsa->modulus->toBytes(); - $e = $rsa->exponent->toBytes(); + $m = $raw['n']; + $e = $raw['e']; + return [$m->toBytes(), $e->toBytes()]; } /** * @param string $pubkey * @return string */ - public static function salmonKey($pubkey) { - self::pemToMe($pubkey, $m, $e); + public static function salmonKey(string $pubkey): string + { + [$m, $e] = self::pemToMe($pubkey); + /** @noinspection PhpRedundantOptionalArgumentInspection */ return 'RSA' . '.' . base64url_encode($m, true) . '.' . base64url_encode($e, true); } @@ -82,11 +88,13 @@ class Keyutils { * @param string $key * @return string */ - public static function convertSalmonKey($key) { - if (strstr($key, ',')) + public static function convertSalmonKey(string $key): string + { + if (str_contains($key, ',')) { $rawkey = substr($key, strpos($key, ',') + 1); - else + } else { $rawkey = substr($key, 5); + } $key_info = explode('.', $rawkey); @@ -96,4 +104,4 @@ class Keyutils { return self::meToPem($m, $e); } -} \ No newline at end of file +} diff --git a/composer.lock b/composer.lock index a0e1beefb..d96066d56 100644 --- a/composer.lock +++ b/composer.lock @@ -1081,16 +1081,16 @@ }, { "name": "macgirvin/http-message-signer", - "version": "v0.2.0", + "version": "v0.2.1", "source": { "type": "git", "url": "https://github.com/macgirvin/HTTP-Message-Signer.git", - "reference": "055198699858f8a99acf75b62190d70ac0c8cb00" + "reference": "55ea393671c58bb6b93445b5f3ee8ba41154f0c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/macgirvin/HTTP-Message-Signer/zipball/055198699858f8a99acf75b62190d70ac0c8cb00", - "reference": "055198699858f8a99acf75b62190d70ac0c8cb00", + "url": "https://api.github.com/repos/macgirvin/HTTP-Message-Signer/zipball/55ea393671c58bb6b93445b5f3ee8ba41154f0c9", + "reference": "55ea393671c58bb6b93445b5f3ee8ba41154f0c9", "shasum": "" }, "require": { @@ -1098,6 +1098,8 @@ "ext-openssl": "*", "guzzlehttp/psr7": "^2.0", "php": "^8.1", + "phpseclib/phpseclib": "~3.0", + "phpseclib/phpseclib2_compat": "^1.0", "psr/http-message": "^2.0" }, "require-dev": { @@ -1116,9 +1118,9 @@ "description": "RFC 9421 HTTP Message Signer and Verifier for PSR-7 requests", "support": { "issues": "https://github.com/macgirvin/HTTP-Message-Signer/issues", - "source": "https://github.com/macgirvin/HTTP-Message-Signer/tree/v0.2.0" + "source": "https://github.com/macgirvin/HTTP-Message-Signer/tree/v0.2.1" }, - "time": "2025-07-01T02:57:39+00:00" + "time": "2025-07-05T00:38:21+00:00" }, { "name": "michelf/php-markdown", @@ -1560,6 +1562,54 @@ ], "time": "2025-06-26T16:29:55+00:00" }, + { + "name": "phpseclib/phpseclib2_compat", + "version": "1.0.6", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib2_compat.git", + "reference": "90976f25d6c2ff936878624b9cfaa322db11dde7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib2_compat/zipball/90976f25d6c2ff936878624b9cfaa322db11dde7", + "reference": "90976f25d6c2ff936878624b9cfaa322db11dde7", + "shasum": "" + }, + "require": { + "phpseclib/phpseclib": "^3.0" + }, + "provide": { + "phpseclib/phpseclib": "2.0.47" + }, + "require-dev": { + "phpunit/phpunit": "^5.7|^6.0|^9.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpseclib\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + } + ], + "description": "phpseclib 2.0 polyfill built with phpseclib 3.0", + "homepage": "https://github.com/phpseclib/phpseclib2_compat", + "support": { + "issues": "https://github.com/phpseclib/phpseclib2_compat/issues", + "source": "https://github.com/phpseclib/phpseclib2_compat" + }, + "time": "2024-02-26T14:37:15+00:00" + }, { "name": "psr/clock", "version": "1.0.0", diff --git a/tests/unit/Lib/KeyutilsTest.php b/tests/unit/Lib/KeyutilsTest.php index d1b0b5ab8..6f5cad10d 100644 --- a/tests/unit/Lib/KeyutilsTest.php +++ b/tests/unit/Lib/KeyutilsTest.php @@ -23,8 +23,9 @@ namespace Zotlabs\Tests\Unit\Lib; -use phpseclib\Crypt\RSA; -use phpseclib\Math\BigInteger; +use phpseclib3\Crypt\PublicKeyLoader; +use phpseclib3\Math\BigInteger; + use Zotlabs\Tests\Unit\UnitTestCase; use Zotlabs\Lib\Keyutils; @@ -38,56 +39,58 @@ class KeyutilsTest extends UnitTestCase { protected function getPubPKCS1() { $key = '-----BEGIN RSA PUBLIC KEY----- -MIIBCgKCAQEArXcEXQSkk25bwDxq5Ym85/OwernfOz0hgve46Jm1KXCF0+yeje8J -BDbQTsMgkF+G8eP1er3oz3E0qlIFpYrza5o6kaaLETSroTyZR5QW5S21r/QJHE+4 -F08bw1zp9hrlvoOCE/g/W0mr3asO/x7LrQRKOETlZ/U6HGexTdYLyKlXJtB+VKjI -XKAHxfVLRW2AvnFj+deowS1OhTN8ECpz88xG9wnh5agoq7Uol0WZNNm0p4oR6+cd -zTPx/mBwcOoSqHLlO7ZACbx/VyD5G7mQKWfGP4b96D8FcUO74531my+aKIpLF4Io -1JN4R4a4P8tZ8BkCnMvpuq9TF1s6vEthYQIDAQAB +MIIBCgKCAQEAsSBBV5khOWvMAOIV2AhxQukBgWc1pfYqUM/9OIFfL+KaRDOFAT0y +jMbtTCbHEjxZbasS3CNnHtAgJ+4BWjtFnZl7zY4pXb2RDe4IWNnK8BjqsWDVuPks +sc+yRBTepR/50FG/xB4HfI4GRc/8EDmynyAdLDD/r6oPxmz1gMICqSGDX8yXYG4o +DliNT3bWDH+uf1+6pWsN6IFQYmUoRLly1xsfc8AV4H1GmSFrbAvQpHA95GOlxnPY +IwVth1m8O+D9SH2+0e8ourdXH3/9ccJnh6FVvFvkyeC1e2vY+J+uC0uwu+6IvHFV +pSnS8lTmwG/BBh2dA5eqV3s+REdLdS/tsQIDAQAB -----END RSA PUBLIC KEY-----'; return str_replace(["\r", "\n"], "\r\n", $key); } protected function getPubPKCS8() { $key = '-----BEGIN PUBLIC KEY----- -MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUKfOIkFX/Zcv6bmaTIYO6OO2g -XQOne+iPfXo6YDdrtvvQNZwW5P/fptrgBzmUBkpuc/sEEKpMV2bGhBLsWSlPBYHe -2ewwLwyzbnuHvGhc1PzwMNQ7R60ubVDQT6sBVigYGZIDBgUPjAXeqmg5qgWWh04H -8Zf/YxyoGEovWDMxGQIDAQAB +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsSBBV5khOWvMAOIV2Ahx +QukBgWc1pfYqUM/9OIFfL+KaRDOFAT0yjMbtTCbHEjxZbasS3CNnHtAgJ+4BWjtF +nZl7zY4pXb2RDe4IWNnK8BjqsWDVuPkssc+yRBTepR/50FG/xB4HfI4GRc/8EDmy +nyAdLDD/r6oPxmz1gMICqSGDX8yXYG4oDliNT3bWDH+uf1+6pWsN6IFQYmUoRLly +1xsfc8AV4H1GmSFrbAvQpHA95GOlxnPYIwVth1m8O+D9SH2+0e8ourdXH3/9ccJn +h6FVvFvkyeC1e2vY+J+uC0uwu+6IvHFVpSnS8lTmwG/BBh2dA5eqV3s+REdLdS/t +sQIDAQAB -----END PUBLIC KEY-----'; return str_replace(["\r", "\n"], "\r\n", $key); } public function testMeToPem() { - Keyutils::pemToMe($this->getPubPKCS8(), $m, $e); + [$m, $e] = Keyutils::pemToMe($this->getPubPKCS8()); $gen_key = Keyutils::meToPem($m, $e); self::assertEquals($this->getPubPKCS8(), $gen_key); } public function testRsaToPem() { - $rsa = new RSA(); - $rsa->setPublicKey($this->getPubPKCS8()); - $key = $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1); - $gen_key = Keyutils::rsaToPem($key); + $gen_key = Keyutils::rsaToPem($this->getPubPKCS1()); self::assertEquals($gen_key, $this->getPubPKCS8()); } public function testPemToRsa() { - $rsa = new RSA(); - $rsa->setPublicKey($this->getPubPKCS1()); - $key = $rsa->getPublicKey(RSA::PUBLIC_FORMAT_PKCS8); - $gen_key = Keyutils::pemToRsa($key); + $gen_key = Keyutils::pemToRsa($this->getPubPKCS8()); self::assertEquals($gen_key, $this->getPubPKCS1()); } public function testPemToMe() { - Keyutils::pemToMe($this->getPubPKCS8(), $m, $e); - $gen_key = new RSA(); - $gen_key->loadKey([ + [$m, $e] = Keyutils::pemToMe($this->getPubPKCS8()); + + $parsedKey = PublicKeyLoader::load([ 'e' => new BigInteger($e, 256), 'n' => new BigInteger($m, 256) ]); - self::assertEquals($gen_key->getPublicKey(), $this->getPubPKCS8()); + + if (method_exists($parsedKey, 'getPublicKey')) { + $parsedKey = $parsedKey->getPublicKey(); + } + + self::assertEquals($parsedKey->toString('PKCS8'), $this->getPubPKCS8()); } } diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 1ad0f2e7a..ec901b895 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -2689,6 +2689,28 @@ return array( 'phpseclib3\\System\\SSH\\Agent' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php', 'phpseclib3\\System\\SSH\\Agent\\Identity' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php', 'phpseclib3\\System\\SSH\\Common\\Traits\\ReadBytes' => $vendorDir . '/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php', + 'phpseclib\\Crypt\\AES' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Crypt/AES.php', + 'phpseclib\\Crypt\\Base' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Crypt/Base.php', + 'phpseclib\\Crypt\\Blowfish' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Crypt/Blowfish.php', + 'phpseclib\\Crypt\\DES' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Crypt/DES.php', + 'phpseclib\\Crypt\\Hash' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Crypt/Hash.php', + 'phpseclib\\Crypt\\RC2' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Crypt/RC2.php', + 'phpseclib\\Crypt\\RC4' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Crypt/RC4.php', + 'phpseclib\\Crypt\\RSA' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Crypt/RSA.php', + 'phpseclib\\Crypt\\Random' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Crypt/Random.php', + 'phpseclib\\Crypt\\Rijndael' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Crypt/Rijndael.php', + 'phpseclib\\Crypt\\TripleDES' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Crypt/TripleDES.php', + 'phpseclib\\Crypt\\Twofish' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Crypt/Twofish.php', + 'phpseclib\\File\\ANSI' => $vendorDir . '/phpseclib/phpseclib2_compat/src/File/ANSI.php', + 'phpseclib\\File\\ASN1' => $vendorDir . '/phpseclib/phpseclib2_compat/src/File/ASN1.php', + 'phpseclib\\File\\ASN1\\Element' => $vendorDir . '/phpseclib/phpseclib2_compat/src/File/ASN1/Element.php', + 'phpseclib\\File\\X509' => $vendorDir . '/phpseclib/phpseclib2_compat/src/File/X509.php', + 'phpseclib\\Math\\BigInteger' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Math/BigInteger.php', + 'phpseclib\\Net\\SFTP' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Net/SFTP.php', + 'phpseclib\\Net\\SFTP\\Stream' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Net/SFTP/Stream.php', + 'phpseclib\\Net\\SSH2' => $vendorDir . '/phpseclib/phpseclib2_compat/src/Net/SSH2.php', + 'phpseclib\\System\\SSH\\Agent' => $vendorDir . '/phpseclib/phpseclib2_compat/src/System/SSH/Agent.php', + 'phpseclib\\System\\SSH\\Agent\\Identity' => $vendorDir . '/phpseclib/phpseclib2_compat/src/System/SSH/Agent/Identity.php', 'voku\\helper\\ASCII' => $vendorDir . '/voku/portable-ascii/src/voku/helper/ASCII.php', 'voku\\helper\\StopWords' => $vendorDir . '/voku/stop-words/src/voku/helper/StopWords.php', 'voku\\helper\\StopWordsLanguageNotExists' => $vendorDir . '/voku/stop-words/src/voku/helper/StopWordsLanguageNotExists.php', diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index 4fa3c3acf..47b457816 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -8,6 +8,7 @@ $baseDir = dirname($vendorDir); return array( '383eaff206634a77a1be54e64e6459c7' => $vendorDir . '/sabre/uri/lib/functions.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', + 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php', '2b9d0f43f9552984cfa82fee95491826' => $vendorDir . '/sabre/event/lib/coroutine.php', 'd81bab31d3feb45bfe2f283ea3c8fdf7' => $vendorDir . '/sabre/event/lib/Loop/functions.php', 'a1cce3d26cc15c00fcd0b3354bd72c88' => $vendorDir . '/sabre/event/lib/Promise/functions.php', @@ -18,7 +19,6 @@ return array( 'ebdb698ed4152ae445614b69b5e4bb6a' => $vendorDir . '/sabre/http/lib/functions.php', '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', '2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php', - 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php', 'c15d4a1253e33e055d05e547c61dcb71' => $vendorDir . '/smarty/smarty/src/functions.php', ); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index 6443df8bd..3a0f148bf 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -7,6 +7,7 @@ $baseDir = dirname($vendorDir); return array( 'voku\\' => array($vendorDir . '/voku/stop-words/src/voku', $vendorDir . '/voku/portable-ascii/src/voku'), + 'phpseclib\\' => array($vendorDir . '/phpseclib/phpseclib2_compat/src'), 'phpseclib3\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'), 'chillerlan\\Settings\\' => array($vendorDir . '/chillerlan/php-settings-container/src'), 'chillerlan\\QRCode\\' => array($vendorDir . '/chillerlan/php-qrcode/src'), diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 714b776f8..7ae0881e4 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -9,6 +9,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d public static $files = array ( '383eaff206634a77a1be54e64e6459c7' => __DIR__ . '/..' . '/sabre/uri/lib/functions.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', + 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', '2b9d0f43f9552984cfa82fee95491826' => __DIR__ . '/..' . '/sabre/event/lib/coroutine.php', 'd81bab31d3feb45bfe2f283ea3c8fdf7' => __DIR__ . '/..' . '/sabre/event/lib/Loop/functions.php', 'a1cce3d26cc15c00fcd0b3354bd72c88' => __DIR__ . '/..' . '/sabre/event/lib/Promise/functions.php', @@ -19,7 +20,6 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'ebdb698ed4152ae445614b69b5e4bb6a' => __DIR__ . '/..' . '/sabre/http/lib/functions.php', '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', '2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php', - 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php', 'c15d4a1253e33e055d05e547c61dcb71' => __DIR__ . '/..' . '/smarty/smarty/src/functions.php', ); @@ -31,6 +31,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d ), 'p' => array ( + 'phpseclib\\' => 10, 'phpseclib3\\' => 11, ), 'c' => @@ -117,6 +118,10 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 0 => __DIR__ . '/..' . '/voku/stop-words/src/voku', 1 => __DIR__ . '/..' . '/voku/portable-ascii/src/voku', ), + 'phpseclib\\' => + array ( + 0 => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src', + ), 'phpseclib3\\' => array ( 0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib', @@ -2995,6 +3000,28 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'phpseclib3\\System\\SSH\\Agent' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php', 'phpseclib3\\System\\SSH\\Agent\\Identity' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php', 'phpseclib3\\System\\SSH\\Common\\Traits\\ReadBytes' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php', + 'phpseclib\\Crypt\\AES' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Crypt/AES.php', + 'phpseclib\\Crypt\\Base' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Crypt/Base.php', + 'phpseclib\\Crypt\\Blowfish' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Crypt/Blowfish.php', + 'phpseclib\\Crypt\\DES' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Crypt/DES.php', + 'phpseclib\\Crypt\\Hash' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Crypt/Hash.php', + 'phpseclib\\Crypt\\RC2' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Crypt/RC2.php', + 'phpseclib\\Crypt\\RC4' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Crypt/RC4.php', + 'phpseclib\\Crypt\\RSA' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Crypt/RSA.php', + 'phpseclib\\Crypt\\Random' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Crypt/Random.php', + 'phpseclib\\Crypt\\Rijndael' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Crypt/Rijndael.php', + 'phpseclib\\Crypt\\TripleDES' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Crypt/TripleDES.php', + 'phpseclib\\Crypt\\Twofish' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Crypt/Twofish.php', + 'phpseclib\\File\\ANSI' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/File/ANSI.php', + 'phpseclib\\File\\ASN1' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/File/ASN1.php', + 'phpseclib\\File\\ASN1\\Element' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/File/ASN1/Element.php', + 'phpseclib\\File\\X509' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/File/X509.php', + 'phpseclib\\Math\\BigInteger' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Math/BigInteger.php', + 'phpseclib\\Net\\SFTP' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Net/SFTP.php', + 'phpseclib\\Net\\SFTP\\Stream' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Net/SFTP/Stream.php', + 'phpseclib\\Net\\SSH2' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/Net/SSH2.php', + 'phpseclib\\System\\SSH\\Agent' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/System/SSH/Agent.php', + 'phpseclib\\System\\SSH\\Agent\\Identity' => __DIR__ . '/..' . '/phpseclib/phpseclib2_compat/src/System/SSH/Agent/Identity.php', 'voku\\helper\\ASCII' => __DIR__ . '/..' . '/voku/portable-ascii/src/voku/helper/ASCII.php', 'voku\\helper\\StopWords' => __DIR__ . '/..' . '/voku/stop-words/src/voku/helper/StopWords.php', 'voku\\helper\\StopWordsLanguageNotExists' => __DIR__ . '/..' . '/voku/stop-words/src/voku/helper/StopWordsLanguageNotExists.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index a0257a81f..caae8bc82 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1112,17 +1112,17 @@ }, { "name": "macgirvin/http-message-signer", - "version": "v0.2.0", - "version_normalized": "0.2.0.0", + "version": "v0.2.1", + "version_normalized": "0.2.1.0", "source": { "type": "git", "url": "https://github.com/macgirvin/HTTP-Message-Signer.git", - "reference": "055198699858f8a99acf75b62190d70ac0c8cb00" + "reference": "55ea393671c58bb6b93445b5f3ee8ba41154f0c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/macgirvin/HTTP-Message-Signer/zipball/055198699858f8a99acf75b62190d70ac0c8cb00", - "reference": "055198699858f8a99acf75b62190d70ac0c8cb00", + "url": "https://api.github.com/repos/macgirvin/HTTP-Message-Signer/zipball/55ea393671c58bb6b93445b5f3ee8ba41154f0c9", + "reference": "55ea393671c58bb6b93445b5f3ee8ba41154f0c9", "shasum": "" }, "require": { @@ -1130,12 +1130,14 @@ "ext-openssl": "*", "guzzlehttp/psr7": "^2.0", "php": "^8.1", + "phpseclib/phpseclib": "~3.0", + "phpseclib/phpseclib2_compat": "^1.0", "psr/http-message": "^2.0" }, "require-dev": { "phpunit/phpunit": "^10.0" }, - "time": "2025-07-01T02:57:39+00:00", + "time": "2025-07-05T00:38:21+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1150,7 +1152,7 @@ "description": "RFC 9421 HTTP Message Signer and Verifier for PSR-7 requests", "support": { "issues": "https://github.com/macgirvin/HTTP-Message-Signer/issues", - "source": "https://github.com/macgirvin/HTTP-Message-Signer/tree/v0.2.0" + "source": "https://github.com/macgirvin/HTTP-Message-Signer/tree/v0.2.1" }, "install-path": "../macgirvin/http-message-signer" }, @@ -1615,6 +1617,57 @@ ], "install-path": "../phpseclib/phpseclib" }, + { + "name": "phpseclib/phpseclib2_compat", + "version": "1.0.6", + "version_normalized": "1.0.6.0", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib2_compat.git", + "reference": "90976f25d6c2ff936878624b9cfaa322db11dde7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib2_compat/zipball/90976f25d6c2ff936878624b9cfaa322db11dde7", + "reference": "90976f25d6c2ff936878624b9cfaa322db11dde7", + "shasum": "" + }, + "require": { + "phpseclib/phpseclib": "^3.0" + }, + "provide": { + "phpseclib/phpseclib": "2.0.47" + }, + "require-dev": { + "phpunit/phpunit": "^5.7|^6.0|^9.4" + }, + "time": "2024-02-26T14:37:15+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpseclib\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + } + ], + "description": "phpseclib 2.0 polyfill built with phpseclib 3.0", + "homepage": "https://github.com/phpseclib/phpseclib2_compat", + "support": { + "issues": "https://github.com/phpseclib/phpseclib2_compat/issues", + "source": "https://github.com/phpseclib/phpseclib2_compat" + }, + "install-path": "../phpseclib/phpseclib2_compat" + }, { "name": "psr/clock", "version": "1.0.0", diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 5a0a4cddf..115299154 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'zotlabs/hubzilla', 'pretty_version' => 'dev-10.4RC', 'version' => 'dev-10.4RC', - 'reference' => 'fcb0ef9633fd32bbb28adccc3e60749e6c5a7348', + 'reference' => '1162615c52d562b96220be3d12c27d410feb74a6', 'type' => 'application', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -146,9 +146,9 @@ 'dev_requirement' => false, ), 'macgirvin/http-message-signer' => array( - 'pretty_version' => 'v0.2.0', - 'version' => '0.2.0.0', - 'reference' => '055198699858f8a99acf75b62190d70ac0c8cb00', + 'pretty_version' => 'v0.2.1', + 'version' => '0.2.1.0', + 'reference' => '55ea393671c58bb6b93445b5f3ee8ba41154f0c9', 'type' => 'library', 'install_path' => __DIR__ . '/../macgirvin/http-message-signer', 'aliases' => array(), @@ -216,6 +216,18 @@ 'install_path' => __DIR__ . '/../phpseclib/phpseclib', 'aliases' => array(), 'dev_requirement' => false, + 'provided' => array( + 0 => '2.0.47', + ), + ), + 'phpseclib/phpseclib2_compat' => array( + 'pretty_version' => '1.0.6', + 'version' => '1.0.6.0', + 'reference' => '90976f25d6c2ff936878624b9cfaa322db11dde7', + 'type' => 'library', + 'install_path' => __DIR__ . '/../phpseclib/phpseclib2_compat', + 'aliases' => array(), + 'dev_requirement' => false, ), 'psr/clock' => array( 'pretty_version' => '1.0.0', @@ -487,7 +499,7 @@ 'zotlabs/hubzilla' => array( 'pretty_version' => 'dev-10.4RC', 'version' => 'dev-10.4RC', - 'reference' => 'fcb0ef9633fd32bbb28adccc3e60749e6c5a7348', + 'reference' => '1162615c52d562b96220be3d12c27d410feb74a6', 'type' => 'application', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), diff --git a/vendor/macgirvin/http-message-signer/composer.json b/vendor/macgirvin/http-message-signer/composer.json index 8c02de2c6..dfb735938 100644 --- a/vendor/macgirvin/http-message-signer/composer.json +++ b/vendor/macgirvin/http-message-signer/composer.json @@ -7,7 +7,9 @@ "psr/http-message": "^2.0", "guzzlehttp/psr7": "^2.0", "bakame/http-structured-fields": "^2.0", - "ext-openssl": "*" + "ext-openssl": "*", + "phpseclib/phpseclib": "~3.0", + "phpseclib/phpseclib2_compat": "^1.0" }, "require-dev": { "phpunit/phpunit": "^10.0" diff --git a/vendor/macgirvin/http-message-signer/src/HttpMessageSigner.php b/vendor/macgirvin/http-message-signer/src/HttpMessageSigner.php index 69b47c65a..ae1b5cd18 100644 --- a/vendor/macgirvin/http-message-signer/src/HttpMessageSigner.php +++ b/vendor/macgirvin/http-message-signer/src/HttpMessageSigner.php @@ -2,6 +2,7 @@ namespace HttpSignature; +use Bakame\Http\StructuredFields\Dictionary; use Bakame\Http\StructuredFields\InnerList; use Bakame\Http\StructuredFields\Item; use Bakame\Http\StructuredFields\OuterList; @@ -9,7 +10,7 @@ use Bakame\Http\StructuredFields\Parameters; use Psr\Http\Message\MessageInterface; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use Bakame\Http\StructuredFields\Dictionary; +use phpseclib\Crypt\RSA; class HttpMessageSigner { @@ -45,6 +46,13 @@ class HttpMessageSigner /* PSR-7 interface to signing function */ + /** + * @param string $coveredFields + * @param MessageInterface $interface + * @param RequestInterface|null $originalRequest + * @return MessageInterface + * @throws UnProcessableSignatureException + */ public function signRequest(string $coveredFields, MessageInterface $interface, RequestInterface $originalRequest = null): MessageInterface { @@ -66,6 +74,13 @@ class HttpMessageSigner } /* PSR-7 verify interface and also check body digest if included */ + /** + * @param MessageInterface $interface + * @param RequestInterface|null $originalRequest + * @return bool + * + * @throws UnProcessableSignatureException + */ public function verifyRequest(MessageInterface $interface, RequestInterface $originalRequest = null): bool { @@ -486,7 +501,9 @@ class HttpMessageSigner private function createSignature(string $data): string { return match ($this->algorithm) { + 'rsa-v1_5-sha256' => $this->rsaSign($data), 'rsa-sha256' => $this->rsaSign($data), + 'rsa-pss-sha512' => $this->pssSign($data), 'ed25519' => $this->ed25519Sign($data), 'hmac-sha256' => base64_encode(hash_hmac('sha256', $data, $this->privateKey, true)), default => throw new UnProcessableSignatureException("Unsupported algorithm: $this->algorithm") @@ -496,8 +513,11 @@ class HttpMessageSigner private function verifySignature(string $data, string $signature, string $alg): bool { return match ($alg) { - 'rsa-sha256' => openssl_verify($data, $signature, $this->publicKey, - OPENSSL_ALGO_SHA256) === 1, + 'rsa-v1_5-sha256' => openssl_verify($data, $signature, $this->publicKey, + OPENSSL_ALGO_SHA256) === 1, + 'rsa-sha256' => openssl_verify($data, $signature, $this->publicKey, + OPENSSL_ALGO_SHA256) === 1, + 'rsa-pss-sha512' => $this->pssVerify($data, $signature), 'ed25519' => openssl_verify($data, $signature, $this->publicKey, "Ed25519") === 1, 'hmac-sha256' => hash_equals( base64_encode(hash_hmac('sha256', $data, $this->privateKey, true)), @@ -517,6 +537,23 @@ class HttpMessageSigner return base64_encode($signature); } + private function pssSign(string $data): string + { + $rsa = new RSA(); + if ($rsa->loadKey($this->privateKey) !== true) { + throw new UnprocessableSignatureException("PSS loadkey failure"); + }; + $rsa->setHash('sha512'); + $rsa->setMGFHash('sha512'); + $rsa->setSignatureMode(RSA::SIGNATURE_PSS); + try { + $signatureBytes = $rsa->sign($data); + } catch (\Exception $exception) { + throw new UnprocessableSignatureException($exception->getMessage()); + } + return base64_encode($signatureBytes); + } + private function ed25519Sign(string $data): string { if (!openssl_sign($data, $signature, $this->privateKey, "Ed25519")) { @@ -525,6 +562,23 @@ class HttpMessageSigner return base64_encode($signature); } + private function pssVerify(string $data, $signature): bool + { + $rsa = new RSA(); + if ($rsa->loadKey($this->publicKey) !== true) { + throw new UnprocessableSignatureException("PSS loadkey failure"); + }; + $rsa->setHash('sha512'); + $rsa->setMGFHash('sha512'); + $rsa->setSignatureMode(RSA::SIGNATURE_PSS); + try { + $verified = $rsa->verify($data, $signature); + } catch (\Exception $exception) { + $verified = false; + } + return $verified; + } + /* parse a structed dict */ private function parseStructuredDict(string $headerValue) diff --git a/vendor/phpseclib/phpseclib2_compat/.github/workflows/ci.yml b/vendor/phpseclib/phpseclib2_compat/.github/workflows/ci.yml new file mode 100644 index 000000000..4d19f96c9 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/.github/workflows/ci.yml @@ -0,0 +1,61 @@ +name: CI +on: [push, pull_request] + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + tests: + name: Tests + timeout-minutes: 10 + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + - name: Clone phpseclib v2 and update tests + run: | + git clone -b 2.0 --single-branch https://github.com/phpseclib/phpseclib.git temp + mv temp/tests tests + rm tests/Functional/Net/SCPSSH2UserStoryTest.php + rm tests/Unit/Net/SSH1Test.php + rm tests/Unit/Net/SSH2UnitTest.php + rm tests/Unit/Math/BigInteger/InternalTest.php + php .github/workflows/update.php + - name: Composer Install + run: composer install --no-interaction --no-cache + - name: Make Tests Compatiable With PHPUnit 9+ + if: matrix.php-version != '5.6' && matrix.php-version != '7.0' && matrix.php-version != '7.1' && matrix.php-version != '7.2' + run: php tests/make_compatible_with_phpunit9.php + - name: Setup Secure Shell Functional Tests + if: matrix.os == 'ubuntu-latest' + run: | + PHPSECLIB_SSH_USERNAME='phpseclib' + PHPSECLIB_SSH_PASSWORD='EePoov8po1aethu2kied1ne0' + + sudo useradd --create-home --base-dir /home "$PHPSECLIB_SSH_USERNAME" + echo "$PHPSECLIB_SSH_USERNAME:$PHPSECLIB_SSH_PASSWORD" | sudo chpasswd + ssh-keygen -t rsa -b 1024 -f "$HOME/.ssh/id_rsa" -q -N "" + eval `ssh-agent -s` + ssh-add "$HOME/.ssh/id_rsa" + sudo mkdir -p "/home/$PHPSECLIB_SSH_USERNAME/.ssh/" + sudo cp "$HOME/.ssh/id_rsa.pub" "/home/$PHPSECLIB_SSH_USERNAME/.ssh/authorized_keys" + sudo ssh-keyscan -t rsa localhost > "/tmp/known_hosts" + sudo cp "/tmp/known_hosts" "/home/$PHPSECLIB_SSH_USERNAME/.ssh/known_hosts" + sudo chown "$PHPSECLIB_SSH_USERNAME:$PHPSECLIB_SSH_USERNAME" "/home/$PHPSECLIB_SSH_USERNAME/.ssh/" -R + + echo "PHPSECLIB_SSH_HOSTNAME=localhost" >> $GITHUB_ENV + echo "PHPSECLIB_SSH_USERNAME=$PHPSECLIB_SSH_USERNAME" >> $GITHUB_ENV + echo "PHPSECLIB_SSH_PASSWORD=$PHPSECLIB_SSH_PASSWORD" >> $GITHUB_ENV + echo "PHPSECLIB_SSH_HOME=/home/phpseclib" >> $GITHUB_ENV + echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" >> $GITHUB_ENV + - name: PHPUnit + run: vendor/bin/phpunit + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + php-version: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] diff --git a/vendor/phpseclib/phpseclib2_compat/.github/workflows/update.php b/vendor/phpseclib/phpseclib2_compat/.github/workflows/update.php new file mode 100644 index 000000000..61cd00641 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/.github/workflows/update.php @@ -0,0 +1,12 @@ +loadKey('ecdsa private key'); + +$ssh = new SSH2('website.com'); +$ssh->login('username', $rsa); +``` +That'll work with phpseclib2_compat, even with an ECDSA private key, whereas in phpseclib 2.0 it would not work. + +SSH1 and SCP are not supported but those were likely never frequently used anyway. + +## Using the old cipher suite + +phpseclib 3.0 uses a different cipher suite (an expanded one) than 2.0. If this causes you issues you can use the 2.0 ciphersuite by doing this prior to calling `$ssh->login()`: + +```php +$methods = [ + 'crypt' => array_intersect([ + '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' + ], $ssh->getSupportedEncryptionAlgorithms()), + 'mac' => [ + 'hmac-sha2-256', + 'hmac-sha1-96', + 'hmac-sha1', + 'hmac-md5-96', + 'hmac-md5' + ], + 'comp' => ['none'] +]; + +$ssh->setPreferredAlgorithms([ + 'kex' => [ + 'curve25519-sha256@libssh.org', + 'diffie-hellman-group-exchange-sha256', + 'diffie-hellman-group-exchange-sha1', + 'diffie-hellman-group14-sha1', + 'diffie-hellman-group14-sha256' + ], + 'hostkey' => [ + 'rsa-sha2-256', + 'rsa-sha2-512', + 'ssh-rsa', + 'ssh-dss' + ], + 'client_to_server' => $methods, + 'server_to_client' => $methods +]); +``` + +## Installation + +With [Composer](https://getcomposer.org/): + +``` +composer require phpseclib/phpseclib2_compat:~1.0 +``` diff --git a/vendor/phpseclib/phpseclib2_compat/composer.json b/vendor/phpseclib/phpseclib2_compat/composer.json new file mode 100644 index 000000000..f32ef85e8 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/composer.json @@ -0,0 +1,30 @@ +{ + "name": "phpseclib/phpseclib2_compat", + "description": "phpseclib 2.0 polyfill built with phpseclib 3.0", + "type": "library", + "homepage": "https://github.com/phpseclib/phpseclib2_compat", + "license": "MIT", + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + } + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib2_compat/issues", + "source": "https://github.com/phpseclib/phpseclib2_compat" + }, + "provide": { + "phpseclib/phpseclib": "2.0.47" + }, + "require": { + "phpseclib/phpseclib": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7|^6.0|^9.4" + }, + "autoload": { + "psr-4": {"phpseclib\\": "src/"} + } +} diff --git a/vendor/phpseclib/phpseclib2_compat/src/Crypt/AES.php b/vendor/phpseclib/phpseclib2_compat/src/Crypt/AES.php new file mode 100644 index 000000000..0e4da3543 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Crypt/AES.php @@ -0,0 +1,93 @@ + + * setKey('abcdefghijklmnop'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $aes->decrypt($aes->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package AES + * @author Jim Wigginton + * @copyright 2008 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Crypt; + +/** + * Pure-PHP implementation of AES. + * + * @package AES + * @author Jim Wigginton + * @access public + */ +class AES extends Rijndael +{ + /** + * Dummy function + * + * Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything. + * + * @see \phpseclib\Crypt\Rijndael::setBlockLength() + * @access public + * @param int $length + */ + function setBlockLength($length) + { + return; + } + + /** + * Turns key lengths, be they valid or invalid, to valid key lengths + * + * @param int $length + * @access private + * @return int + */ + protected function calculateNewKeyLength($length) + { + switch (true) { + case $length <= 128: + return 128; + case $length <= 192: + return 192; + default: + return 256; + } + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Crypt/Base.php b/vendor/phpseclib/phpseclib2_compat/src/Crypt/Base.php new file mode 100644 index 000000000..fad69c023 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Crypt/Base.php @@ -0,0 +1,585 @@ + + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Crypt; + +use phpseclib3\Exception\BadDecryptionException; +use phpseclib3\Exception\InconsistentSetupException; + +/** + * Base Class for all \phpseclib\Crypt\* cipher classes + * + * @package Base + * @author Jim Wigginton + * @author Hans-Juergen Petrich + */ +abstract class Base +{ + /**#@+ + * @access public + * @see \phpseclib\Crypt\Base::encrypt() + * @see \phpseclib\Crypt\Base::decrypt() + */ + /** + * Encrypt / decrypt using the Counter mode. + * + * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29 + */ + const MODE_CTR = -1; + /** + * Encrypt / decrypt using the Electronic Code Book mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29 + */ + const MODE_ECB = 1; + /** + * Encrypt / decrypt using the Code Book Chaining mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29 + */ + const MODE_CBC = 2; + /** + * Encrypt / decrypt using the Cipher Feedback mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29 + */ + const MODE_CFB = 3; + /** + * Encrypt / decrypt using the Cipher Feedback mode (8bit) + */ + const MODE_CFB8 = 38; + /** + * Encrypt / decrypt using the Output Feedback mode (8bit) + */ + const MODE_OFB8 = 7; + /** + * Encrypt / decrypt using the Output Feedback mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29 + */ + const MODE_OFB = 4; + /** + * Encrypt / decrypt using streaming mode. + */ + const MODE_STREAM = 5; + /** + * Encrypt / decrypt using Galois/Counter mode. + * + * @link https://en.wikipedia.org/wiki/Galois/Counter_Mode + */ + const MODE_GCM = 6; + /**#@-*/ + + /**#@+ + * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + /** + * Base value for the internal implementation $engine switch + */ + const ENGINE_INTERNAL = 1; + /** + * Base value for the eval() implementation $engine switch + */ + const ENGINE_EVAL = 4; + /** + * Base value for the mcrypt implementation $engine switch + */ + const ENGINE_MCRYPT = 2; + /** + * Base value for the openssl implementation $engine switch + */ + const ENGINE_OPENSSL = 3; + /** + * Base value for the libsodium implementation $engine switch + */ + const ENGINE_LIBSODIUM = 5; + /** + * Base value for the openssl / gcm implementation $engine switch + */ + const ENGINE_OPENSSL_GCM = 6; + /**#@-*/ + + /** + * Engine Map + * + * @access private + * @see \phpseclib3\Crypt\Common\SymmetricKey::getEngine() + */ + const ENGINE_MAP = [ + self::ENGINE_INTERNAL => 'PHP', + self::ENGINE_EVAL => 'Eval', + self::ENGINE_MCRYPT => 'mcrypt', + self::ENGINE_OPENSSL => 'OpenSSL', + self::ENGINE_LIBSODIUM => 'libsodium', + self::ENGINE_OPENSSL_GCM => 'OpenSSL (GCM)' + ]; + + /** + * The Cipher + * + * @var \phpseclib3\Crypt\Common\SymmetricKey + * @access private + */ + protected $cipher; + + /** + * The Key + * + * @see self::setKey() + * @var string + * @access private + */ + protected $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + + /** + * Password Parameters + * + * @see self::setPassword() + * @var array + * @access private + */ + protected $password = []; + + /** + * The Key Length (in bytes) + * + * @see self::setKeyLength() + * @var int + * @access private + */ + protected $key_length = 128; + + /** + * Does internal cipher state need to be (re)initialized? + * + * @see self::setKey() + * @var bool + * @access private + */ + private $changed = true; + + /** + * Has the IV been set? + * + * @var bool + * @access private + */ + protected $ivSet = false; + + /** + * Has the key length been explictly set? + * + * @var bool + * @access private + */ + protected $explicit_key_length = false; + + /** + * Default Constructor. + * + * Determines whether or not the mcrypt extension should be used. + * + * $mode could be: + * + * - self::MODE_ECB + * + * - self::MODE_CBC + * + * - self::MODE_CTR + * + * - self::MODE_CFB + * + * - self::MODE_OFB + * + * If not explicitly set, self::MODE_CBC will be used. + * + * @param int $mode + * @access public + */ + public function __construct($mode = self::MODE_CBC) + { + $map = [ + self::MODE_CTR => 'ctr', + self::MODE_ECB => 'ecb', + self::MODE_CBC => 'cbc', + self::MODE_CFB => 'cfb', + self::MODE_CFB8 => 'cfb8', + self::MODE_OFB => 'ofb', + self::MODE_OFB8 => 'ofb8', + self::MODE_GCM => 'gcm', + self::MODE_STREAM => 'stream' + ]; + if (!isset($map[$mode])) { + $mode = self::MODE_CBC; + } + $class = new \ReflectionClass(static::class); + $class = "phpseclib3\\Crypt\\" . $class->getShortName(); + $this->cipher = new $class($map[$mode]); + $this->key_length = $this->cipher->getKeyLength(); + } + + /** + * Sets the initialization vector. (optional) + * + * SetIV is not required when self::MODE_ECB (or ie for AES: \phpseclib\Crypt\AES::MODE_ECB) is being used. If not explicitly set, it'll be assumed + * to be all zero's. + * + * @access public + * @param string $iv + * @internal Can be overwritten by a sub class, but does not have to be + */ + public function setIV($iv) + { + $this->ivSet = true; + + if (!$this->cipher->usesIV()) { + return; + } + + $length = $this->cipher->getBlockLengthInBytes(); + $iv = str_pad(substr($iv, 0, $length), $length, "\0"); + + try { + $this->cipher->setIV($iv); + } catch (\Exception $e) {} + } + + /** + * Sets the key length. + * + * Keys with explicitly set lengths need to be treated accordingly + * + * @access public + * @param int $length + */ + public function setKeyLength($length) + { + // algorithms that have a fixed key length should override this with a method that does nothing + $this->changed = true; + $this->key_length = static::calculateNewKeyLength($length); + $this->explicit_key_length = true; + } + + /** + * Returns the current key length in bits + * + * @access public + * @return int + */ + public function getKeyLength() + { + return $this->key_length; + } + + /** + * Returns the current block length in bits + * + * @access public + * @return int + */ + public function getBlockLength() + { + return $this->cipher->getBlockLength(); + } + + /** + * Sets the key. + * + * The min/max length(s) of the key depends on the cipher which is used. + * If the key not fits the length(s) of the cipher it will paded with null bytes + * up to the closest valid key length. If the key is more than max length, + * we trim the excess bits. + * + * If the key is not explicitly set, it'll be assumed to be all null bytes. + * + * @access public + * @param string $key + * @internal Could, but not must, extend by the child Crypt_* class + */ + public function setKey($key) + { + $this->key = $key; + $this->password = []; + if (!$this->explicit_key_length) { + $this->key_length = static::calculateNewKeyLength(strlen($key) << 3); + } + $this->changed = true; + } + + /** + * 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 + * @return bool + * @access public + * @internal Could, but not must, extend by the child Crypt_* class + */ + public function setPassword($password, $method = 'pbkdf2') + { + $this->password = func_get_args(); + $this->cipher->setKeyLength($this->key_length); + $this->cipher->setPassword(...func_get_args()); + } + + /** + * Encrypts a message. + * + * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher + * implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's + * necessary are discussed in the following + * URL: + * + * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html} + * + * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does. + * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that + * length. + * + * @see self::decrypt() + * @access public + * @param string $plaintext + * @return string $ciphertext + * @internal Could, but not must, extend by the child Crypt_* class + */ + public function encrypt($plaintext) + { + if ($this->changed) { + $this->setup(); + } + + try { + return $this->cipher->encrypt($plaintext); + } catch (\LengthException $e) { + user_error($e->getMessage()); + $this->cipher->enablePadding(); + return $this->cipher->encrypt($plaintext); + } + } + + /** + * Decrypts a message. + * + * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until + * it is. + * + * @see self::encrypt() + * @access public + * @param string $ciphertext + * @return string $plaintext + * @internal Could, but not must, extend by the child Crypt_* class + */ + public function decrypt($ciphertext) + { + if ($this->changed) { + $this->setup(); + } + + try { + return $this->cipher->decrypt($ciphertext); + } catch (\LengthException $e) { + $len = strlen($ciphertext); + $block_size = $this->cipher->getBlockLengthInBytes(); + $ciphertext = str_pad($ciphertext, $len + ($block_size - $len % $block_size) % $block_size, chr(0)); + try { + return $this->cipher->decrypt($ciphertext); + } catch (BadDecryptionException $e) { + return false; + } + } catch (\Exception $e) { + return false; + } + } + + /** + * Setup IV and key + */ + protected function setup() + { + // we set this just in case it was already set to anything via setPassword() + $temp = $this->explicit_key_length; + $this->setKeyLength($this->key_length); + $this->explicit_key_length = $temp; + if ($this->explicit_key_length) { + $this->cipher->setKeyLength($this->key_length); + } + if (empty($this->password)) { + $key_length = $this->key_length >> 3; + $key = str_pad(substr($this->key, 0, $key_length), $key_length, "\0"); + $this->cipher->setKey($key); + } else { + $this->cipher->setPassword(...$this->password); + } + if (!$this->ivSet) { + $this->setIV(''); + } + $this->changed = false; + } + + /** + * Pad "packets". + * + * Block ciphers working by encrypting between their specified [$this->]block_size at a time + * If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to + * pad the input so that it is of the proper length. + * + * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH, + * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping + * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is + * transmitted separately) + * + * @see self::disablePadding() + * @access public + */ + public function enablePadding() + { + $this->cipher->enablePadding(); + } + + /** + * Do not pad packets. + * + * @see self::enablePadding() + * @access public + */ + public function disablePadding() + { + $this->cipher->disablePadding(); + } + + /** + * Treat consecutive "packets" as if they are a continuous buffer. + * + * Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets + * will yield different outputs: + * + * + * echo $rijndael->encrypt(substr($plaintext, 0, 16)); + * echo $rijndael->encrypt(substr($plaintext, 16, 16)); + * + * + * echo $rijndael->encrypt($plaintext); + * + * + * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates + * another, as demonstrated with the following: + * + * + * $rijndael->encrypt(substr($plaintext, 0, 16)); + * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); + * + * + * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); + * + * + * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different + * outputs. The reason is due to the fact that the initialization vector's change after every encryption / + * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. + * + * Put another way, when the continuous buffer is enabled, the state of the \phpseclib\Crypt\*() object changes after each + * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that + * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), + * however, they are also less intuitive and more likely to cause you problems. + * + * @see self::disableContinuousBuffer() + * @access public + * @internal Could, but not must, extend by the child Crypt_* class + */ + public function enableContinuousBuffer() + { + try { + $this->cipher->enableContinuousBuffer(); + } catch (\BadMethodCallException $e) { + user_error($e->getMessage()); + } + } + + /** + * Treat consecutive packets as if they are a discontinuous buffer. + * + * The default behavior. + * + * @see self::enableContinuousBuffer() + * @access public + * @internal Could, but not must, extend by the child Crypt_* class + */ + public function disableContinuousBuffer() + { + $this->cipher->disableContinuousBuffer(); + } + + /** + * Test for engine validity + * + * @see self::__construct() + * @param int $engine + * @access public + * @return bool + */ + public function isValidEngine($engine) + { + $map = self::ENGINE_MAP; + return $this->cipher->isValidEngine($map[$engine]); + } + + /** + * Sets the preferred crypt engine + * + * Currently, $engine could be: + * + * - \phpseclib\Crypt\Base::ENGINE_OPENSSL [very fast] + * + * - \phpseclib\Crypt\Base::ENGINE_MCRYPT [fast] + * + * - \phpseclib\Crypt\Base::ENGINE_INTERNAL [slow] + * + * If the preferred crypt engine is not available the fastest available one will be used + * + * @see self::__construct() + * @param int $engine + * @access public + */ + public function setPreferredEngine($engine) + { + $map = self::ENGINE_MAP; + $this->cipher->setPreferredEngine($map[$engine]); + } + + /** + * Returns the engine currently being utilized + * + * @see self::_setEngine() + * @access public + */ + public function getEngine() + { + static $reverseMap; + if (!isset($reverseMap)) { + $reverseMap = array_flip(self::ENGINE_MAP); + } + return $reverseMap[$this->cipher->getEngine()]; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Crypt/Blowfish.php b/vendor/phpseclib/phpseclib2_compat/src/Crypt/Blowfish.php new file mode 100644 index 000000000..f2cb68ee8 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Crypt/Blowfish.php @@ -0,0 +1,66 @@ + + * setKey('12345678901234567890123456789012'); + * + * $plaintext = str_repeat('a', 1024); + * + * echo $blowfish->decrypt($blowfish->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package Blowfish + * @author Jim Wigginton + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Crypt; + +/** + * Pure-PHP implementation of Blowfish. + * + * @package Blowfish + * @author Jim Wigginton + * @access public + */ +class Blowfish extends Base +{ + /** + * Turns key lengths, be they valid or invalid, to valid key lengths + * + * @param int $length + * @access private + * @return int + */ + protected function calculateNewKeyLength($length) + { + switch (true) { + case $length < 32: + return 32; + case $length > 448: + return 448; + } + return $length; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Crypt/DES.php b/vendor/phpseclib/phpseclib2_compat/src/Crypt/DES.php new file mode 100644 index 000000000..512c59a27 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Crypt/DES.php @@ -0,0 +1,65 @@ + + * setKey('abcdefgh'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $des->decrypt($des->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package DES + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Crypt; + +/** + * Pure-PHP implementation of DES. + * + * @package DES + * @author Jim Wigginton + * @access public + */ +class DES extends Base +{ + /** + * Turns key lengths, be they valid or invalid, to valid key lengths + * + * @param int $length + * @access private + * @return int + */ + protected function calculateNewKeyLength($length) + { + return 64; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Crypt/Hash.php b/vendor/phpseclib/phpseclib2_compat/src/Crypt/Hash.php new file mode 100644 index 000000000..de7942705 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Crypt/Hash.php @@ -0,0 +1,145 @@ + + * setKey('abcdefg'); + * + * echo base64_encode($hash->hash('abcdefg')); + * ?> + * + * + * @category Crypt + * @package Hash + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Crypt; + +/** + * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions. + * + * @package Hash + * @author Jim Wigginton + * @access public + */ +class Hash +{ + /**#@+ + * @access private + * @see \phpseclib\Crypt\Hash::__construct() + */ + /** + * Toggles the internal implementation + */ + const MODE_INTERNAL = 1; + /**#@-*/ + + /** + * Hash Object + * + * @see self::setHash() + * @var null|\phpseclib3\Crypt\Hash + * @access private + */ + private $hash; + + /** + * Default Constructor. + * + * @param string $hash + * @return \phpseclib\Crypt\Hash + * @access public + */ + public function __construct($hash = 'sha1') + { + $this->setHash($hash); + } + + /** + * Sets the key for HMACs + * + * Keys can be of any length. + * + * @access public + * @param string $key + */ + public function setKey($key = false) + { + $this->hash->setKey($key); + } + + /** + * Gets the hash function. + * + * As set by the constructor or by the setHash() method. + * + * @access public + * @return string + */ + public function getHash() + { + return $this->hash->getHash(); + } + + /** + * Sets the hash function. + * + * @access public + * @param string $hash + */ + public function setHash($hash) + { + $this->hash = new \phpseclib3\Crypt\Hash; + try { + $this->hash->setHash($hash); + } catch (\phpseclib3\Exception\UnsupportedAlgorithmException $e) { + $this->hash->setHash('sha1'); + } + } + + /** + * Compute the HMAC. + * + * @access public + * @param string $text + * @return string + */ + public function hash($text) + { + return $this->hash->hash($text); + } + + /** + * Returns the hash length (in bytes) + * + * @access public + * @return int + */ + public function getLength() + { + return $this->hash->getLengthInBytes(); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Crypt/RC2.php b/vendor/phpseclib/phpseclib2_compat/src/Crypt/RC2.php new file mode 100644 index 000000000..b23f73bca --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Crypt/RC2.php @@ -0,0 +1,132 @@ + + * setKey('abcdefgh'); + * + * $plaintext = str_repeat('a', 1024); + * + * echo $rc2->decrypt($rc2->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package RC2 + * @author Patrick Monnerat + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Crypt; + +/** + * Pure-PHP implementation of RC2. + * + * @package RC2 + * @author Jim Wigginton + * @access public + */ +class RC2 extends Base +{ + /** + * Default Constructor. + * + * Determines whether or not the mcrypt extension should be used. + * + * $mode could be: + * + * - self::MODE_ECB + * + * - self::MODE_CBC + * + * - self::MODE_CTR + * + * - self::MODE_CFB + * + * - self::MODE_OFB + * + * If not explicitly set, self::MODE_CBC will be used. + * + * @param int $mode + * @access public + */ + public function __construct($mode = self::MODE_CBC) + { + parent::__construct($mode); + $this->key_length = 8; + } + + /** + * Turns key lengths, be they valid or invalid, to valid key lengths + * + * @param int $length + * @access private + * @return int + */ + protected function calculateNewKeyLength($length) + { + switch (true) { + case $length < 8: + return 8; + case $length > 1024: + return 1024; + } + + return $length; + } + + /** + * Setup IV and key + */ + protected function setup() + { + if ($this->explicit_key_length) { + $this->cipher->setKeyLength($this->key_length); + } + $this->cipher->setKey($this->key); + if (!$this->ivSet) { + $this->setIV(''); + } + $this->changed = false; + } + + /** + * Sets the key. + * + * Keys can be of any length. RC2, itself, uses 8 to 1024 bit keys (eg. + * strlen($key) <= 128), however, we only use the first 128 bytes if $key + * has more then 128 bytes in it, and set $key to a single null byte if + * it is empty. + * + * If the key is not explicitly set, it'll be assumed to be a single + * null byte. + * + * @see \phpseclib\Crypt\Base::setKey() + * @access public + * @param string $key + * @param int $t1 optional Effective key length in bits. + */ + function setKey($key, $t1 = 0) + { + parent::setKey($key); + if ($t1) { + $this->setKeyLength($t1); + } + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Crypt/RC4.php b/vendor/phpseclib/phpseclib2_compat/src/Crypt/RC4.php new file mode 100644 index 000000000..78781f553 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Crypt/RC4.php @@ -0,0 +1,74 @@ + + * setKey('abcdefgh'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $rc4->decrypt($rc4->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package RC4 + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Crypt; + +/** + * Pure-PHP implementation of RC4. + * + * @package RC4 + * @author Jim Wigginton + * @access public + */ +class RC4 extends Base +{ + /** + * Turns key lengths, be they valid or invalid, to valid key lengths + * + * @param int $length + * @access private + * @return int + */ + protected function calculateNewKeyLength($length) + { + switch (true) { + case $length < 8: + return 8; + case $length > 2048: + return 2048; + } + + return $length; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Crypt/RSA.php b/vendor/phpseclib/phpseclib2_compat/src/Crypt/RSA.php new file mode 100644 index 000000000..7a45a0bb5 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Crypt/RSA.php @@ -0,0 +1,948 @@ + + * createKey()); + * + * $plaintext = 'terrafrost'; + * + * $rsa->loadKey($privatekey); + * $ciphertext = $rsa->encrypt($plaintext); + * + * $rsa->loadKey($publickey); + * echo $rsa->decrypt($ciphertext); + * ?> + * + * + * Here's an example of how to create signatures and verify signatures with this library: + * + * createKey()); + * + * $plaintext = 'terrafrost'; + * + * $rsa->loadKey($privatekey); + * $signature = $rsa->sign($plaintext); + * + * $rsa->loadKey($publickey); + * echo $rsa->verify($plaintext, $signature) ? 'verified' : 'unverified'; + * ?> + * + * + * @category Crypt + * @package RSA + * @author Jim Wigginton + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Crypt; + +use phpseclib3\Crypt\RSA as RSA2; +use phpseclib3\Crypt\PublicKeyLoader; +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\Common\PublicKey; +use phpseclib3\Crypt\Common\PrivateKey; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Exception\NoKeyLoadedException; +use phpseclib3\Crypt\Common\Formats\Keys\PuTTY; +use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH; +use phpseclib3\Math\BigInteger; +use phpseclib\Math\BigInteger as BigInteger2; + +/** + * Pure-PHP PKCS#1 compliant implementation of RSA. + * + * @package RSA + * @author Jim Wigginton + * @access public + */ +class RSA +{ + /**#@+ + * @access public + * @see self::encrypt() + * @see self::decrypt() + */ + /** + * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding} + * (OAEP) for encryption / decryption. + * + * Uses sha1 by default. + * + * @see self::setHash() + * @see self::setMGFHash() + */ + const ENCRYPTION_OAEP = 1; + /** + * Use PKCS#1 padding. + * + * Although self::ENCRYPTION_OAEP offers more security, including PKCS#1 padding is necessary for purposes of backwards + * compatibility with protocols (like SSH-1) written before OAEP's introduction. + */ + const ENCRYPTION_PKCS1 = 2; + /** + * Do not use any padding + * + * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy + * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc. + */ + const ENCRYPTION_NONE = 3; + /**#@-*/ + + /**#@+ + * @access public + * @see self::sign() + * @see self::verify() + * @see self::setHash() + */ + /** + * Use the Probabilistic Signature Scheme for signing + * + * Uses sha1 by default. + * + * @see self::setSaltLength() + * @see self::setMGFHash() + */ + const SIGNATURE_PSS = 1; + /** + * Use the PKCS#1 scheme by default. + * + * Although self::SIGNATURE_PSS offers more security, including PKCS#1 signing is necessary for purposes of backwards + * compatibility with protocols (like SSH-2) written before PSS's introduction. + */ + const SIGNATURE_PKCS1 = 2; + /**#@-*/ + + /**#@+ + * @access public + * @see \phpseclib\Crypt\RSA::createKey() + * @see \phpseclib\Crypt\RSA::setPrivateKeyFormat() + */ + /** + * PKCS#1 formatted private key + * + * Used by OpenSSH + */ + const PRIVATE_FORMAT_PKCS1 = 0; + /** + * PuTTY formatted private key + */ + const PRIVATE_FORMAT_PUTTY = 1; + /** + * XML formatted private key + */ + const PRIVATE_FORMAT_XML = 2; + /** + * PKCS#8 formatted private key + */ + const PRIVATE_FORMAT_PKCS8 = 8; + /** + * OpenSSH formatted private key + */ + const PRIVATE_FORMAT_OPENSSH = 9; + /**#@-*/ + + /**#@+ + * @access public + * @see \phpseclib\Crypt\RSA::createKey() + * @see \phpseclib\Crypt\RSA::setPublicKeyFormat() + */ + /** + * Raw public key + * + * An array containing two \phpseclib\Math\BigInteger objects. + * + * The exponent can be indexed with any of the following: + * + * 0, e, exponent, publicExponent + * + * The modulus can be indexed with any of the following: + * + * 1, n, modulo, modulus + */ + const PUBLIC_FORMAT_RAW = 3; + /** + * PKCS#1 formatted public key (raw) + * + * Used by File/X509.php + * + * Has the following header: + * + * -----BEGIN RSA PUBLIC KEY----- + * + * Analogous to ssh-keygen's pem format (as specified by -m) + */ + const PUBLIC_FORMAT_PKCS1 = 4; + const PUBLIC_FORMAT_PKCS1_RAW = 4; + /** + * XML formatted public key + */ + const PUBLIC_FORMAT_XML = 5; + /** + * OpenSSH formatted public key + * + * Place in $HOME/.ssh/authorized_keys + */ + const PUBLIC_FORMAT_OPENSSH = 6; + /** + * PKCS#1 formatted public key (encapsulated) + * + * Used by PHP's openssl_public_encrypt() and openssl's rsautl (when -pubin is set) + * + * Has the following header: + * + * -----BEGIN PUBLIC KEY----- + * + * Analogous to ssh-keygen's pkcs8 format (as specified by -m). Although PKCS8 + * is specific to private keys it's basically creating a DER-encoded wrapper + * for keys. This just extends that same concept to public keys (much like ssh-keygen) + */ + const PUBLIC_FORMAT_PKCS8 = 7; + /**#@-*/ + + /** + * The Original Key + * + * @see self::getComment() + * @var string + * @access private + */ + private $origKey = null; + + /** + * The Key + * + * @var \phpseclib3\Crypt\Common\AsymmetricKey + * @access private + */ + private $key = null; + + /** + * Password + * + * @var string + * @access private + */ + private $password = false; + + /** + * Private Key Format + * + * @var int + * @access private + */ + private $privateKeyFormat = self::PRIVATE_FORMAT_PKCS1; + + /** + * Public Key Format + * + * @var int + * @access public + */ + private $publicKeyFormat = self::PUBLIC_FORMAT_PKCS1; + + /** + * Public key comment field. + * + * @var string + * @access private + */ + private $comment = 'phpseclib-generated-key'; + + /** + * Encryption mode + * + * @var int + * @access private + */ + private $encryptionMode = self::ENCRYPTION_OAEP; + + /** + * Signature mode + * + * @var int + * @access private + */ + private $signatureMode = self::SIGNATURE_PSS; + + /** + * Hash name + * + * @var string + * @access private + */ + private $hash = 'sha1'; + + /** + * Hash function for the Mask Generation Function + * + * @var string + * @access private + */ + private $mgfHash = 'sha1'; + + /** + * Length of salt + * + * @var int + * @access private + */ + private $sLen; + + /** + * The constructor + * + * @return \phpseclib\Crypt\RSA + * @access public + */ + public function __construct() + { + // don't do anything + } + + /** + * Create public / private key pair + * + * Returns an array with the following three elements: + * - 'privatekey': The private key. + * - 'publickey': The public key. + * - 'partialkey': A partially computed key (if the execution time exceeded $timeout). + * Will need to be passed back to \phpseclib\Crypt\RSA::createKey() as the third parameter for further processing. + * + * @access public + * @param int $bits + */ + public function createKey($bits = 1024) + { + $privatekey = RSA2::createKey($bits); + + return [ + 'privatekey' => $privatekey, + 'publickey' => $privatekey->getPublicKey(), + 'partialkey' => false + ]; + } + + /** + * Returns the key size + * + * More specifically, this returns the size of the modulo in bits. + * + * @access public + * @return int + */ + public function getSize() + { + // for EC and RSA keys this'll return an integer + // for DSA keys this'll return an array (L + N) + return isset($this->key) ? $this->key->getLength() : 0; + } + + /** + * Sets the password + * + * Private keys can be encrypted with a password. To unset the password, pass in the empty string or false. + * Or rather, pass in $password such that empty($password) && !is_string($password) is true. + * + * @see self::createKey() + * @see self::loadKey() + * @access public + * @param string $password + */ + public function setPassword($password = false) + { + $this->password = $password; + } + + /** + * Loads a public or private key + * + * Returns true on success and false on failure (ie. an incorrect password was provided or the key was malformed) + * + * @access public + * @param string|RSA|array $key + * @param bool|int $type optional + * @return bool + */ + public function loadKey($key) + { + if ($key instanceof AsymmetricKey) { + $this->key = $key; + } else if ($key instanceof RSA) { + $this->key = $key->key; + } else { + try { + if (is_array($key)) { + foreach ($key as &$value) { + if ($value instanceof BigInteger2) { + $value = new BigInteger($value->toBytes(true), -256); + } + } + } + $this->key = PublicKeyLoader::load($key, $this->password); + } catch (NoKeyLoadedException $e) { + $this->key = $this->origKey = null; + return false; + } + $this->origKey = $key; + } + + // with phpseclib 2.0 loading a key does not reset any of the following + // so we'll need to preserve the old settings whenever a new key is loaded + // with this shim + $this->setEncryptionMode($this->encryptionMode); + //$this->setSignatureMode($this->signatureMode); + $this->setHash($this->hash); + $this->setMGFHash($this->mgfHash); + $this->setSaltLength($this->sLen); + + return true; + } + + /** + * __toString() magic method + * + * @access public + * @return string + */ + public function __toString() + { + PuTTY::setComment($this->comment); + OpenSSH::setComment($this->comment); + + if ($this->key instanceof PublicKey) { + return $this->key->toString(self::const2str($this->publicKeyFormat)); + } + + if ($this->key instanceof PrivateKey) { + try { + return $this->key->toString(self::const2str($this->privateKeyFormat)); + } catch (UnsupportedFormatException $e) { + if ($this->password) { + return $this->key->withPassword()->toString(self::const2str($this->privateKeyFormat)); + } + } + } + + return ''; + } + + /** + * Defines the public key + * + * Some private key formats define the public exponent and some don't. Those that don't define it are problematic when + * used in certain contexts. For example, in SSH-2, RSA authentication works by sending the public key along with a + * message signed by the private key to the server. The SSH-2 server looks the public key up in an index of public keys + * and if it's present then proceeds to verify the signature. Problem is, if your private key doesn't include the public + * exponent this won't work unless you manually add the public exponent. phpseclib tries to guess if the key being used + * is the public key but in the event that it guesses incorrectly you might still want to explicitly set the key as being + * public. + * + * Do note that when a new key is loaded the index will be cleared. + * + * Returns true on success, false on failure + * + * @see self::getPublicKey() + * @access public + * @param string $key optional + * @param int $type optional + * @return bool + */ + public function setPublicKey() + { + return false; + } + + /** + * Defines the private key + * + * If phpseclib guessed a private key was a public key and loaded it as such it might be desirable to force + * phpseclib to treat the key as a private key. This function will do that. + * + * Do note that when a new key is loaded the index will be cleared. + * + * Returns true on success, false on failure + * + * @see self::getPublicKey() + * @access public + * @param string $key optional + * @param int $type optional + * @return bool + */ + public function setPrivateKey($key = false) + { + if ($key === false && $this->key instanceof RSA2) { + $this->key = $this->key->asPrivateKey(); + } + + try { + $key = PublicKeyLoader::load($key); + } catch (NoKeyLoadedException $e) { + return false; + } + if ($key instanceof RSA2) { + $this->key = $key instanceof PublicKey ? $key->asPrivateKey() : $key; + return true; + } + + return false; + } + + /** + * Returns the public key + * + * The public key is only returned under two circumstances - if the private key had the public key embedded within it + * or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this + * function won't return it since this library, for the most part, doesn't distinguish between public and private keys. + * + * @see self::getPublicKey() + * @access public + * @param string $key + * @param int $type optional + */ + public function getPublicKey($type = self::PUBLIC_FORMAT_PKCS8) + { + PuTTY::setComment($this->comment); + OpenSSH::setComment($this->comment); + + if ($this->key instanceof PrivateKey) { + return $this->key->getPublicKey()->toString(self::const2str($type)); + } + + if ($this->key instanceof PublicKey) { + return $this->key->toString(self::const2str($type)); + } + + return false; + } + + /** + * Returns the public key's fingerprint + * + * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is + * no public key currently loaded, false is returned. + * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716) + * + * @access public + * @param string $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned + * for invalid values. + * @return mixed + */ + public function getPublicKeyFingerprint($algorithm = 'md5') + { + if ($this->key instanceof PublicKey) { + return $this->key->getFingerprint($algorithm); + } + + return false; + } + + /** + * Returns the private key + * + * The private key is only returned if the currently loaded key contains the constituent prime numbers. + * + * @see self::getPublicKey() + * @access public + * @param string $key + * @param int $type optional + * @return mixed + */ + public function getPrivateKey($type = self::PUBLIC_FORMAT_PKCS1) + { + PuTTY::setComment($this->comment); + OpenSSH::setComment($this->comment); + + if ($this->key instanceof PrivateKey) { + try { + return $this->key->toString(self::const2str($this->privateKeyFormat)); + } catch (UnsupportedFormatException $e) { + if ($this->password) { + return $this->key->withPassword()->toString(self::const2str($this->privateKeyFormat)); + } + } + + } + + return false; + } + + /** + * __clone() magic method + * + * @access public + * @return Crypt_RSA + */ + public function __clone() + { + $key = new RSA(); + $key->loadKey($this); + return $key; + } + + /** + * Convert phpseclib 2.0 style constants to phpseclib 3.0 style strings + * + * @param int $const + * @access private + * @return string + */ + private static function const2str($const) + { + switch ($const) { + case self::PRIVATE_FORMAT_PKCS1: + case self::PUBLIC_FORMAT_PKCS1: + return 'PKCS1'; + case self::PRIVATE_FORMAT_PUTTY: + return 'PuTTY'; + case self::PRIVATE_FORMAT_XML: + case self::PUBLIC_FORMAT_XML: + return 'XML'; + case self::PRIVATE_FORMAT_PKCS8: + case self::PUBLIC_FORMAT_PKCS8: + return 'PKCS8'; + case self::PRIVATE_FORMAT_OPENSSH: + case self::PUBLIC_FORMAT_OPENSSH: + return 'OpenSSH'; + } + } + + /** + * Determines the private key format + * + * @see self::createKey() + * @access public + * @param int $format + */ + public function setPrivateKeyFormat($format) + { + $this->privateKeyFormat = $format; + } + + /** + * Determines the public key format + * + * @see self::createKey() + * @access public + * @param int $format + */ + public function setPublicKeyFormat($format) + { + $this->publicKeyFormat = $format; + } + + /** + * Determines which hashing function should be used + * + * Used with signature production / verification and (if the encryption mode is self::ENCRYPTION_OAEP) encryption and + * decryption. If $hash isn't supported, sha1 is used. + * + * @access public + * @param string $hash + */ + public function setHash($hash) + { + $this->hash = $hash; + if ($this->key instanceof AsymmetricKey) { + try { + $this->key = $this->key->withHash($hash); + } catch (UnsupportedAlgorithmException $e) { + $this->key = $this->key->withHash('sha1'); + } + } + } + + /** + * Determines which hashing function should be used for the mask generation function + * + * The mask generation function is used by self::ENCRYPTION_OAEP and self::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 + */ + public function setMGFHash($hash) + { + $this->mgfHash = $hash; + if ($this->key instanceof RSA2) { + try { + $this->key = $this->key->withMGFHash($hash); + } catch (UnsupportedAlgorithmException $e) { + $this->key = $this->key->withMGFHash('sha1'); + } + } + } + + /** + * Determines the salt length + * + * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}: + * + * Typical salt lengths in octets are hLen (the length of the output + * of the hash function Hash) and 0. + * + * @access public + * @param int $format + */ + public function setSaltLength($sLen) + { + $this->sLen = $sLen; + if ($this->key instanceof RSA2) { + $this->key = $this->key->withSaltLength($sLen); + } + } + + /** + * Set Encryption Mode + * + * Valid values include self::ENCRYPTION_OAEP and self::ENCRYPTION_PKCS1. + * + * @access public + * @param int $mode + */ + public function setEncryptionMode($mode) + { + $this->encryptionMode = $mode; + if ($this->key instanceof RSA2) { + $this->key = $this->key->withPadding( + self::enc2pad($this->encryptionMode) | + self::sig2pad($this->signatureMode) + ); + } + } + + /** + * Set Signature Mode + * + * Valid values include self::SIGNATURE_PSS and self::SIGNATURE_PKCS1 + * + * @access public + * @param int $mode + */ + public function setSignatureMode($mode) + { + $this->signatureMode = $mode; + if ($this->key instanceof RSA2) { + $this->key = $this->key->withPadding( + self::enc2pad($this->encryptionMode) | + self::sig2pad($this->signatureMode) + ); + } + } + + /** + * Convert phpseclib 2.0 style constants to phpseclib 3.0 style constants + * + * @param int $mode + * @access private + * @return int + */ + private function enc2pad($mode) + { + switch ($mode) { + case self::ENCRYPTION_PKCS1: + return RSA2::ENCRYPTION_PKCS1; + case self::ENCRYPTION_NONE: + return RSA2::ENCRYPTION_NONE; + //case self::ENCRYPTION_OAEP: + default: + return RSA2::ENCRYPTION_OAEP; + } + } + + /** + * Convert phpseclib 2.0 style constants to phpseclib 3.0 style constants + * + * @param int $mode + * @access private + * @return int + */ + private function sig2pad($mode) + { + switch ($mode) { + case self::SIGNATURE_PKCS1: + return RSA2::SIGNATURE_PKCS1; + //case self::SIGNATURE_PSS: + default: + return RSA2::SIGNATURE_PSS; + } + } + + /** + * Set public key comment. + * + * @access public + * @param string $comment + */ + public function setComment($comment) + { + $this->comment = $comment; + } + + /** + * Get public key comment. + * + * @access public + * @return string + */ + public function getComment() + { + // we'd need to make the load method in the parent PuTTY and OpenSSH classes public instead of protected + // for this to work + try { + $key = PuTTY::load($this->origKey); + return $key['comment']; + } catch (\Exception $e) {} + + try { + $key = OpenSSH::load($this->origKey); + return $key['comment']; + } catch (\Exception $e) {} + + return ''; + } + + /** + * Encryption + * + * Both self::ENCRYPTION_OAEP and self::ENCRYPTION_PKCS1 both place limits on how long $plaintext can be. + * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will + * be concatenated together. + * + * @see self::decrypt() + * @access public + * @param string $plaintext + * @return string + */ + public function encrypt($plaintext) + { + if (!$this->key instanceof RSA2) { + return false; + } + $key = $this->key; + if ($key instanceof PrivateKey) { + $key = $key->toString('Raw'); + $temp = new static(); + $temp->loadKey(['e' => $key['d'], 'n' => $key['n']]); + $key = $temp->key; + } + if ($key instanceof PublicKey) { + switch ($this->encryptionMode) { + case self::ENCRYPTION_PKCS1: + $len = ($key->getLength() - 88) >> 3; + break; + case self::ENCRYPTION_NONE: + $len = $key->getLength() >> 3; + break; + //case self::ENCRYPTION_OAEP: + default: + $len = ($key->getLength() - 2 * $key->getHash()->getLength() - 16) >> 3; + } + $plaintext = str_split($plaintext, $len); + $ciphertext = ''; + foreach ($plaintext as $m) { + $ciphertext.= $key->encrypt($m); + } + return $ciphertext; + } + + return false; + } + + /** + * Decryption + * + * @see self::encrypt() + * @access public + * @param string $plaintext + * @return string + */ + public function decrypt($ciphertext) + { + if (!$this->key instanceof RSA2) { + return false; + } + $key = $this->key; + if ($key instanceof PublicKey) { + $key = $key->asPrivateKey(); + } + if ($key instanceof PrivateKey) { + $len = $key->getLength() >> 3; + $ciphertext = str_split($ciphertext, $len); + $ciphertext[count($ciphertext) - 1] = str_pad($ciphertext[count($ciphertext) - 1], $len, chr(0), STR_PAD_LEFT); + + $plaintext = ''; + foreach ($ciphertext as $c) { + try { + $plaintext.= $key->decrypt($c); + } catch (\Exception $e) { + return false; + } + } + return $plaintext; + } + + return false; + } + + /** + * Create a signature + * + * @see self::verify() + * @access public + * @param string $message + * @return string + */ + public function sign($message) + { + if ($this->key instanceof PrivateKey) { + return $this->key->sign($message); + } + + return false; + } + + /** + * Verifies a signature + * + * @see self::sign() + * @access public + * @param string $message + * @param string $signature + * @return bool + */ + public function verify($message, $signature) + { + if ($this->key instanceof PublicKey) { + return $this->key->verify($message, $signature); + } + + return false; + } + + /** + * Returns a public key object + * + * @access public + * @return AsymmetricKey|false + */ + public function getKeyObject() + { + return $this->key; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Crypt/Random.php b/vendor/phpseclib/phpseclib2_compat/src/Crypt/Random.php new file mode 100644 index 000000000..49a281b3d --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Crypt/Random.php @@ -0,0 +1,36 @@ + + * + * + * + * @category Crypt + * @package Random + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Crypt; + +/** + * Pure-PHP Random Number Generator + * + * @package Random + * @author Jim Wigginton + * @access public + */ +class Random extends \phpseclib3\Crypt\Random +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Crypt/Rijndael.php b/vendor/phpseclib/phpseclib2_compat/src/Crypt/Rijndael.php new file mode 100644 index 000000000..f3b9a7df8 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Crypt/Rijndael.php @@ -0,0 +1,137 @@ + + * setKey('abcdefghijklmnop'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $rijndael->decrypt($rijndael->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package Rijndael + * @author Jim Wigginton + * @copyright 2008 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Crypt; + +/** + * Pure-PHP implementation of Rijndael. + * + * @package Rijndael + * @author Jim Wigginton + * @access public + */ +class Rijndael extends Base +{ + /** + * Sets the block length + * + * Valid block lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to + * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount. + * + * @access public + * @param int $length + */ + public function setBlockLength($length) + { + $length >>= 5; + if ($length > 8) { + $length = 8; + } elseif ($length < 4) { + $length = 4; + } + $this->cipher->setBlockLength($length); + } + + /** + * Turns key lengths, be they valid or invalid, to valid key lengths + * + * @param int $length + * @access private + * @return int + */ + protected function calculateNewKeyLength($length) + { + switch (true) { + case $length <= 128: + return 128; + case $length <= 160: + return 160; + case $length <= 192: + return 192; + case $length <= 224: + return 224; + default: + return 256; + } + } + + /** + * 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 + * @return bool + * @access public + * @internal Could, but not must, extend by the child Crypt_* class + */ + public function setPassword($password, $method = 'pbkdf2') + { + $this->cipher->setKeyLength($this->key_length); + $args = func_get_args(); + if (in_array($method, ['pbkdf1', 'pbkdf2']) && !isset($args[3])) { + $args[1] = $method; + $args[2] = isset($args[2]) ? $args[2] : 'sha1'; + $args[3] = 'phpseclib'; + } + $this->password = $args; + $this->cipher->setPassword(...$args); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Crypt/TripleDES.php b/vendor/phpseclib/phpseclib2_compat/src/Crypt/TripleDES.php new file mode 100644 index 000000000..d66dc74d6 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Crypt/TripleDES.php @@ -0,0 +1,116 @@ + + * setKey('abcdefghijklmnopqrstuvwx'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $des->decrypt($des->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package TripleDES + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Crypt; + +/** + * Pure-PHP implementation of Triple DES. + * + * @package TripleDES + * @author Jim Wigginton + * @access public + */ +class TripleDES extends Base +{ + /** + * Encrypt / decrypt using inner chaining + * + * Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (self::MODE_CBC3). + */ + const MODE_3CBC = -2; + + /** + * Encrypt / decrypt using outer chaining + * + * Outer chaining is used by SSH-2 and when the mode is set to \phpseclib\Crypt\Base::MODE_CBC. + */ + const MODE_CBC3 = Base::MODE_CBC; + + /** + * Default Constructor. + * + * Determines whether or not the mcrypt extension should be used. + * + * $mode could be: + * + * - \phpseclib\Crypt\Base::MODE_ECB + * + * - \phpseclib\Crypt\Base::MODE_CBC + * + * - \phpseclib\Crypt\Base::MODE_CTR + * + * - \phpseclib\Crypt\Base::MODE_CFB + * + * - \phpseclib\Crypt\Base::MODE_OFB + * + * - \phpseclib\Crypt\TripleDES::MODE_3CBC + * + * If not explicitly set, \phpseclib\Crypt\Base::MODE_CBC will be used. + * + * @see \phpseclib\Crypt\DES::__construct() + * @see \phpseclib\Crypt\Base::__construct() + * @param int $mode + * @access public + */ + public function __construct($mode = self::MODE_CBC) + { + if ($mode == self::MODE_3CBC) { + $this->cipher = new \phpseclib3\Crypt\TripleDES('3cbc'); + $this->key_length = $this->cipher->getKeyLength(); + return; + } + parent::__construct($mode); + } + + /** + * Turns key lengths, be they valid or invalid, to valid key lengths + * + * @param int $length + * @access private + * @return int + */ + protected function calculateNewKeyLength($length) + { + switch (true) { + case $length <= 64: + return 64; + case $length <= 128: + return 128; + default: + return 192; + } + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Crypt/Twofish.php b/vendor/phpseclib/phpseclib2_compat/src/Crypt/Twofish.php new file mode 100644 index 000000000..f57c54c9d --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Crypt/Twofish.php @@ -0,0 +1,67 @@ + + * setKey('12345678901234567890123456789012'); + * + * $plaintext = str_repeat('a', 1024); + * + * echo $twofish->decrypt($twofish->encrypt($plaintext)); + * ?> + * + * + * @category Crypt + * @package Twofish + * @author Jim Wigginton + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Crypt; + +/** + * Pure-PHP implementation of Twofish. + * + * @package Twofish + * @author Jim Wigginton + * @access public + */ +class Twofish extends Base +{ + /** + * Turns key lengths, be they valid or invalid, to valid key lengths + * + * @param int $length + * @access private + * @return int + */ + protected function calculateNewKeyLength($length) + { + switch (true) { + case $length <= 128: + return 128; + case $length <= 192: + return 192; + default: + return 256; + } + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/File/ANSI.php b/vendor/phpseclib/phpseclib2_compat/src/File/ANSI.php new file mode 100644 index 000000000..73bbb8a24 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/File/ANSI.php @@ -0,0 +1,32 @@ + + * @copyright 2012 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\File; + +/** + * Pure-PHP ANSI Decoder + * + * @package ANSI + * @author Jim Wigginton + * @access public + */ +class ANSI extends \phpseclib3\File\ANSI +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/File/ASN1.php b/vendor/phpseclib/phpseclib2_compat/src/File/ASN1.php new file mode 100644 index 000000000..ceecf7c0e --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/File/ASN1.php @@ -0,0 +1,95 @@ + + * @copyright 2012 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\File; + +/** + * Pure-PHP ASN.1 Parser + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +class ASN1 extends \phpseclib3\File\ASN1 +{ + /** + * Parse BER-encoding + * + * Serves a similar purpose to openssl's asn1parse + * + * @param string $encoded + * @return array + * @access public + */ + public static function decodeBER($encoded) + { + $decoded = parent::decodeBER($encoded); + if ($decoded === null) { + return [false]; + } + return $decoded; + } + + /** + * BER-decode the OID + * + * Called by _decode_ber() + * + * @access private + * @param string $content + * @return string + */ + public function _decodeOID($content) + { + return $this->decodeOID($content); + } + + /** + * DER-encode the length + * + * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See + * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. + * + * @access private + * @param int $length + * @return string + */ + public function _encodeLength($length) + { + return $this->encodeLength($length); + } + + /** + * DER-encode the OID + * + * Called by _encode_der() + * + * @access private + * @param string $content + * @return string + */ + public function _encodeOID($source) + { + return $this->encodeOID($source); + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/File/ASN1/Element.php b/vendor/phpseclib/phpseclib2_compat/src/File/ASN1/Element.php new file mode 100644 index 000000000..fe1871eb3 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/File/ASN1/Element.php @@ -0,0 +1,28 @@ + + * @copyright 2012 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\File\ASN1; + +/** + * ASN.1 Element + * + * Bypass normal encoding rules in phpseclib\File\ASN1::encodeDER() + * + * @package ASN1 + * @author Jim Wigginton + * @access public + */ +class Element extends \phpseclib3\File\ASN1\Element +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/File/X509.php b/vendor/phpseclib/phpseclib2_compat/src/File/X509.php new file mode 100644 index 000000000..e285ab0b9 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/File/X509.php @@ -0,0 +1,407 @@ + + * @copyright 2012 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\File; + +use phpseclib\Crypt\RSA; +use phpseclib3\File\ASN1\Element as NewElement; +use phpseclib\File\ASN1\Element as OldElement; + +/** + * Pure-PHP X.509 Parser + * + * @package X509 + * @method bool|mixed[] loadX509(string $cert, int $mode = X509::FORMAT_AUTO_DETECT) + * @method string|false saveX509(mixed[] $cert, int $format = X509::FORMAT_PEM) + * @method bool loadCA(string $cert) + * @method bool validateURL(string $url) + * @method bool validateDate(\DateTimeInterface|string $date = null) + * @method ?bool validateSignature(bool $caonly = true) + * @method static void setRecurLimit(int $count) + * @method static void disableURLFetch() + * @method static void enableURLFetch() + * @method static string decodeIP(string $ip) + * @method static array{bool|string, bool|string} decodeNameConstraintIP(string $ip) + * @method static string encodeIP(string|array{string, string} $ip) + * @method bool setDNProp(string $propName, mixed $propValue, string $type = 'utf8String') + * @method void removeDNProp(string $propName) + * @method mixed[] getDNProp(string $propName, mixed[] $dn, bool $withType = false) + * @method bool setDN(mixed $dn, bool $merge = false, string $type = 'utf8String') + * @method mixed getDN(int $format = X509::DN_ARRAY, mixed[] $dn = null) + * @method mixed getIssuerDN(int $format = X509::DN_ARRAY) + * @method mixed getSubjectDN(int $format = X509::DN_ARRAY) + * @method mixed getIssuerDNProp(string $propName, bool $withType = false) + * @method mixed getSubjectDNProp(string $propName, bool $withType = false) + * @method mixed[] getChain() + * @method bool|mixed[] getCurrentCert() + * @method void setChallenge(string $challenge) + * @method PublicKey|false getPublicKey() + * @method bool|mixed[] loadCSR(string $csr, int $mode = X509::FORMAT_AUTO_DETECT) + * @method string|false saveCSR(array $csr, int $format = X509::FORMAT_PEM) + * @method bool|mixed[] loadSPKAC(string $spkac) + * @method string|false saveSPKAC(array $spkac, int $format = X509::FORMAT_PEM) + * @method bool|mixed[] loadCRL(string $crl, int $mode = X509::FORMAT_AUTO_DETECT) + * @method string|false saveCRL(array $crl, int $format = X509::FORMAT_PEM) + * @method bool|mixed[] sign(X509 $issuer, X509 $subject) + * @method bool|mixed[] signCSR() + * @method bool|mixed[] signSPKAC() + * @method bool|mixed[] signCRL(X509 $issuer, X509 $crl) + * @method void setStartDate(\DateTimeInterface|string $date) + * @method void setEndDate(\DateTimeInterface|string $date) + * @method void setSerialNumber(string $serial, int $base = -256) + * @method void makeCA() + * @method bool removeExtension(string $id) + * @method mixed getExtension(string $id, mixed[] $cert = null, string $path = null) + * @method mixed[] getExtension(mixed[] $cert = null, string $path = null) + * @method bool setExtension(mixed[] $cert = null, mixed $value, string $path = null) + * @method bool removeAttribute(string $id, int $disposition = X509::ATTR_ALL) + * @method mixed getAttribute(string $id, int $disposition = X509::ATTR_ALL, array $csr = null) + * @method mixed[] getAttributes(mixed[] $csr = null) + * @method void setKeyIdentifier(string $value) + * @method mixed computeKeyIdentifier(mixed $key = null, int $method = 1) + * @method void setDomain(string ...$domains) + * @method void setIPAddress(mixed ...$ipAddresses) + * @method bool revoke(string $serial, string $date = null) + * @method bool unrevoke(string $serial) + * @method mixed getRevoked(string $serial) + * @method mixed[] listRevoked(mixed[] $crl = null) + * @method bool removeRevokedCertificateExtension(string $serial, string $id) + * @method mixed getRevokedCertificateExtension(string $serial, string $id, mixed[] $crl = null) + * @method bool|mixed[] getRevokedCertificateExtensions(string $serial, mixed[] $crl = null) + * @method bool setRevokedCertificateExtension(string $serial, string $id, $value, bool $critical = false, bool $replace = true) + * @method static void registerExtension(string $id, mixed[] $mapping) + * @method static ?mixed[] getRegisteredExtension(string $id) + * @method static void setExtensionValue(string $id, $value, bool $critical = false, bool $replace = false) + * @author Jim Wigginton + * @access public + */ +class X509 +{ + /** + * Flag to only accept signatures signed by certificate authorities + * + * Not really used anymore but retained all the same to suppress E_NOTICEs from old installs + * + * @access public + */ + const VALIDATE_SIGNATURE_BY_CA = 1; + + /**#@+ + * @access public + * @see \phpseclib3\File\X509::getDN() + */ + /** + * Return internal array representation + */ + const DN_ARRAY = 0; + /** + * Return string + */ + const DN_STRING = 1; + /** + * Return ASN.1 name string + */ + const DN_ASN1 = 2; + /** + * Return OpenSSL compatible array + */ + const DN_OPENSSL = 3; + /** + * Return canonical ASN.1 RDNs string + */ + const DN_CANON = 4; + /** + * Return name hash for file indexing + */ + const DN_HASH = 5; + /**#@-*/ + + /**#@+ + * @access public + * @see \phpseclib3\File\X509::saveX509() + * @see \phpseclib3\File\X509::saveCSR() + * @see \phpseclib3\File\X509::saveCRL() + */ + /** + * Save as PEM + * + * ie. a base64-encoded PEM with a header and a footer + */ + const FORMAT_PEM = 0; + /** + * Save as DER + */ + const FORMAT_DER = 1; + /** + * Save as a SPKAC + * + * Only works on CSRs. Not currently supported. + */ + const FORMAT_SPKAC = 2; + /** + * Auto-detect the format + * + * Used only by the load*() functions + */ + const FORMAT_AUTO_DETECT = 3; + /**#@-*/ + + /** + * Attribute value disposition. + * If disposition is >= 0, this is the index of the target value. + */ + const ATTR_ALL = -1; // All attribute values (array). + const ATTR_APPEND = -2; // Add a value. + const ATTR_REPLACE = -3; // Clear first, then add a value. + + /** + * The X509 object + * + * @var \phpseclib3\File\X509 + * @access private + */ + private $x509; + + /** + * Default Constructor. + * + * @return \phpseclib\File\X509 + * @access public + */ + public function __construct() + { + // we don't extend phpseclib3\File\X509 because the setPublicKey() and setPrivateKey() methods + // have different method signatures + $this->x509 = new \phpseclib3\File\X509(); + } + + /** + * __call() magic method + * + * @access public + */ + public function __call($name, $args) + { + foreach ($args as &$arg) { + if ($arg instanceof \phpseclib\File\X509) { + $arg = $arg->x509; + } + } + + switch ($name) { + case 'loadX509': + case 'saveX509': + case 'sign': + $part1 = 'tbsCertificate'; + $part2 = 'extensions'; + break; + case 'loadCRL': + case 'saveCRL': + case 'signCRL': + $part1 = 'tbsCertList'; + $part2 = 'crlExtensions'; + break; + case 'loadCSR': + case 'saveCSR': + case 'signCSR': + $part1 = 'certificationRequestInfo'; + $part2 = 'attributes'; + } + + if (isset($args[0])) { + switch ($name) { + case 'saveX509': + case 'saveCRL': + case 'saveCSR': + if (isset($args[0][$part1][$part2])) { + $arr = &$args[0][$part1][$part2]; + if ($part2 == 'attributes') { + foreach ($arr as &$attr) { + if (isset($attr['type']) && $attr['type'] == 'pkcs-9-at-extensionRequest') { + $arr = $attr['value'][0]; + break; + } + } + } + foreach ($arr as &$extension) { + if ($extension instanceof NewElement || !is_array($extension)) { + continue; + } + if (is_string($extension['extnValue'])) { + $extension['extnValue'] = base64_decode($extension['extnValue']); + } + } + } + + if (isset($args[0]['signature'])) { + $args[0]['signature'] = base64_decode($args[0]['signature']); + } + } + } + + $result = $this->x509->$name(...$args); + if ($result instanceof \phpseclib3\File\X509) { + $temp = new static; + $temp->x509 = $result; + return $temp; + } + + if (!is_array($result)) { + return $result; + } + + $result = self::replaceNewElements($result); + + if (!isset($part1)) { + return $result; + } + + if (isset($result[$part1][$part2])) { + $arr = &$result[$part1][$part2]; + if ($part2 == 'attributes') { + foreach ($arr as &$attr) { + if (isset($attr['type']) && $attr['type'] == 'pkcs-9-at-extensionRequest') { + $arr = $attr['value'][0]; + break; + } + } + } + foreach ($arr as &$extension) { + if ($extension instanceof NewElement || !is_array($extension)) { + continue; + } + if (is_string($extension['extnValue'])) { + $extension['extnValue'] = base64_encode($extension['extnValue']); + } + } + } + + if (isset($result['signature'])) { + $result['signature'] = base64_encode($result['signature']); + } + + return $result; + } + + /** + * __callStatic() magic method + * + * @access public + */ + public static function __callStatic($name, $args) + { + return \phpseclib3\File\X509::$name(...$args); + } + + /** + * Set public key + * + * Key needs to be a \phpseclib\Crypt\RSA object + * + * @param object $key + * @access public + * @return bool + */ + public function setPublicKey($key) + { + if (!$key instanceof RSA) { + return; + } + $key = $key->getKeyObject(); + if ($key instanceof \phpseclib3\Crypt\Common\PublicKey) { + if ($key instanceof \phpseclib3\Crypt\RSA) { + $key = $key->withPadding(\phpseclib3\Crypt\RSA::SIGNATURE_PKCS1); + } + $this->x509->setPublicKey($key); + } + } + + /** + * Set private key + * + * Key needs to be a \phpseclib\Crypt\RSA object + * + * @param object $key + * @access public + */ + public function setPrivateKey($key) + { + if (!$key instanceof RSA) { + return; + } + $key = $key->getKeyObject(); + if ($key instanceof \phpseclib3\Crypt\Common\PrivateKey) { + if ($key instanceof \phpseclib3\Crypt\RSA) { + $key = $key->withPadding(\phpseclib3\Crypt\RSA::SIGNATURE_PKCS1); + } + $this->x509->setPrivateKey($key); + } + } + + /** + * Returns the OID corresponding to a name + * + * What's returned in the associative array returned by loadX509() (or load*()) is either a name or an OID if + * no OID to name mapping is available. The problem with this is that what may be an unmapped OID in one version + * of phpseclib may not be unmapped in the next version, so apps that are looking at this OID may not be able + * to work from version to version. + * + * This method will return the OID if a name is passed to it and if no mapping is avialable it'll assume that + * what's being passed to it already is an OID and return that instead. A few examples. + * + * getOID('2.16.840.1.101.3.4.2.1') == '2.16.840.1.101.3.4.2.1' + * getOID('id-sha256') == '2.16.840.1.101.3.4.2.1' + * getOID('zzz') == 'zzz' + * + * @access public + * @return string + */ + public function getOID($name) + { + return \phpseclib3\File\ASN1::getOID($name); + } + + /** + * Replaces \phpseclib3\File\ASN1\Element with \phpseclib\File\ASN1\Element + * + * @return array + */ + private static function replaceNewElements($el) + { + switch (true) { + case $el instanceof NewElement: + return new OldElement($el->element); + case !is_array($el): + return $el; + } + + foreach ($el as &$val) { + $val = self::replaceNewElements($val); + } + + return $el; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Math/BigInteger.php b/vendor/phpseclib/phpseclib2_compat/src/Math/BigInteger.php new file mode 100644 index 000000000..905d8fe65 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Math/BigInteger.php @@ -0,0 +1,308 @@ +> and << cannot be used, nor can the modulo operator %, + * which only supports integers. Although this fact will slow this library down, the fact that such a high + * base is being used should more than compensate. + * + * Numbers are stored in {@link http://en.wikipedia.org/wiki/Endianness little endian} format. ie. + * (new \phpseclib\Math\BigInteger(pow(2, 26)))->value = array(0, 1) + * + * Useful resources are as follows: + * + * - {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf Handbook of Applied Cryptography (HAC)} + * - {@link http://math.libtomcrypt.com/files/tommath.pdf Multi-Precision Math (MPM)} + * - Java's BigInteger classes. See /j2se/src/share/classes/java/math in jdk-1_5_0-src-jrl.zip + * + * Here's an example of how to use this library: + * + * add($b); + * + * echo $c->toString(); // outputs 5 + * ?> + * + * + * @category Math + * @package BigInteger + * @author Jim Wigginton + * @copyright 2006 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib\Math; + +use phpseclib3\Math\BigInteger as BigInteger2; + +/** + * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256 + * numbers. + * + * @package BigInteger + * @method string toString() + * @method string toBytes() + * @method string toHex() + * @method string toBits() + * @method BigInteger add(BigInteger $y) + * @method BigInteger subtract(BigInteger $y) + * @method BigInteger multiply(BigInteger $x) + * @method array{BigInteger, BigInteger} divide(BigInteger $x) + * @method BigInteger modInverse(BigInteger $n) + * @method {'gcd': BigInteger, 'x': BigInteger, 'y': BigInteger} extendedGCD(BigInteger $n) + * @method BigInteger gcd(BigInteger $n) + * @method BigInteger abs() + * @method void setPrecision(int $bits) + * @method int|bool getPrecision() + * @method BigInteger powMod(BigInteger $e, BigInteger $n) + * @method BigInteger modPow(BigInteger $e, BigInteger $n) + * @method int compare(BigInteger $y) + * @method bool equals(BigInteger $x) + * @method BigInteger bitwise_not() + * @method BigInteger bitwise_and(BigInteger $x) + * @method BigInteger bitwise_or(BigInteger $x) + * @method BigInteger bitwise_rightShift($shift) + * @method BigInteger bitwise_leftShift($shift) + * @method BigInteger bitwise_leftRotate($shift) + * @method BigInteger bitwise_rightRotate($shift) + * @method {'min': BigInteger, 'max': BigInteger} minMaxBits($bits) + * @method int getLength() + * @method int getLengthInBytes() + * @method bool isPrime(int|bool $t = false) + * @method BigInteger root(int $n = 2) + * @method BigInteger pow(BigInteger $n) + * @method static BigInteger min(BigInteger ...$nums) + * @method static BigInteger max(BigInteger ...$nums) + * @method bool between(BigInteger $min, BigInteger $max) + * @method bool isOdd() + * @method bool testBit(int $x) + * @method bool isNegative() + * @method BigInteger negate() + * @method callable createRecurringModuloFunction() + * @method BigInteger[] bitwise_split(int $split) + * @author Jim Wigginton + * @access public + */ +class BigInteger +{ + /**#@+ + * Array constants + * + * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and + * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them. + * + * @access private + */ + /** + * $result[self::VALUE] contains the value. + */ + const VALUE = 0; + /** + * $result[self::SIGN] contains the sign. + */ + const SIGN = 1; + /**#@-*/ + + /**#@+ + * @access private + * @see BigInteger::_montgomery() + * @see BigInteger::_barrett() + */ + /** + * Cache constants + * + * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. + */ + const VARIABLE = 0; + /** + * $cache[self::DATA] contains the cached data. + */ + const DATA = 1; + /**#@-*/ + + /**#@+ + * Mode constants. + * + * @access private + * @see BigInteger::__construct() + */ + /** + * To use the pure-PHP implementation + */ + const MODE_INTERNAL = 1; + /** + * To use the BCMath library + * + * (if enabled; otherwise, the internal implementation will be used) + */ + const MODE_BCMATH = 2; + /** + * To use the GMP library + * + * (if present; otherwise, either the BCMath or the internal implementation will be used) + */ + const MODE_GMP = 3; + /**#@-*/ + + /** + * The BigInteger object + * + * @var \phpseclib3\Math\BigInteger + * @access private + */ + private $bigint; + + /** + * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers. + * + * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using + * two's compliment. The sole exception to this is -10, which is treated the same as 10 is. + * + * Here's an example: + * + * toString(); // outputs 50 + * ?> + * + * + * @param $x base-10 number or base-$base number if $base set. + * @param int $base + * @return \phpseclib\Math\BigInteger + * @access public + */ + public function __construct($x = 0, $base = 10) + { + $this->bigint = new BigInteger2($x, $base); + } + + /** + * __call() magic method + * + * @access public + */ + public function __call($name, $args) + { + foreach ($args as &$arg) { + if ($arg instanceof BigInteger) { + $arg = $arg->bigint; + } + } + $result = $this->bigint->$name(...$args); + if (!$result instanceof BigInteger2) { + return $result; + } + + $temp = new static; + $temp->bigint = $result; + + return $temp; + } + + /** + * __toString() magic method + * + * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call + * toString(). + * + * @access public + * @internal Implemented per a suggestion by Techie-Michael - thanks! + */ + public function __toString() + { + return $this->bigint->__toString(); + } + + /** + * __debugInfo() magic method + * + * Will be called, automatically, when print_r() or var_dump() are called + * + * @access public + */ + public function __debugInfo() + { + return $this->bigint->__debugInfo(); + } + + /** + * Generate a random number + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * $min->random($max) + * $max->random($min) + * + * @param \phpseclib\Math\BigInteger $arg1 + * @param \phpseclib\Math\BigInteger $arg2 + * @return \phpseclib\Math\BigInteger + * @access public + * @internal The API for creating random numbers used to be $a->random($min, $max), where $a was a BigInteger object. + * That method is still supported for BC purposes. + */ + public function random($arg1, $arg2 = false) + { + $temp = new static; + $temp->bigint = BigInteger2::randomRange( + $arg1->bigint, + $arg2 instanceof BigInteger ? $arg2->bigint : $this->bigint + ); + return $temp; + } + + /** + * Generate a random prime number. + * + * If there's not a prime within the given range, false will be returned. + * If more than $timeout seconds have elapsed, give up and return false. + * + * @param \phpseclib\Math\BigInteger $arg1 + * @param \phpseclib\Math\BigInteger $arg2 + * @return Math_BigInteger|false + * @access public + * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=15 HAC 4.44}. + */ + public function randomPrime($arg1, $arg2 = false) + { + $temp = new static; + $temp->bigint = BigInteger2::randomRange( + $arg1->bigint, + $arg2 instanceof BigInteger ? $arg2->bigint : $this->bigint + ); + return $temp; + } + + /** + * Logical Exclusive-Or + * + * See https://github.com/phpseclib/phpseclib/issues/1245 for more context + * + * @param \phpseclib\Math\BigInteger $x + * @access public + * @return \phpseclib\Math\BigInteger + */ + public function bitwise_xor($x) + { + $temp = new static; + $temp->bigint = $this->bigint->abs()->bitwise_xor($x->bigint->abs()); + return $temp; + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Net/SFTP.php b/vendor/phpseclib/phpseclib2_compat/src/Net/SFTP.php new file mode 100644 index 000000000..fab1f7219 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Net/SFTP.php @@ -0,0 +1,276 @@ + + * login('username', 'password')) { + * exit('Login Failed'); + * } + * + * echo $sftp->pwd() . "\r\n"; + * $sftp->put('filename.ext', 'hello, world!'); + * print_r($sftp->nlist()); + * ?> + * + * + * @category Net + * @package SFTP + * @author Jim Wigginton + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Net; + +use phpseclib\Crypt\RSA; + +/** + * Pure-PHP implementation of SFTP. + * + * @package SFTP + * @method void disableStatCache() + * @method void enableStatCache() + * @method void clearStatCache() + * @method void enablePathCanonicalization() + * @method void disablePathCanonicalization() + * @method void enableArbitraryLengthPackets() + * @method void disableArbitraryLengthPackets() + * @method string|false pwd() + * @method string|false realpath(string $path) + * @method bool chdir(string $dir) + * @method string[]|false nlist(string $dir = '.', bool $recursive = false) + * @method mixed[]|false rawlist(string $dir = '.', bool $recursive = false) + * @method void setListOrder(mixed ...$args) + * @method mixed[]|false stat(string $filename) + * @method mixed[]|false lstat(string $filename) + * @method bool truncate(string $filename, int $new_size) + * @method bool touch(string $filename, int $time = null, int $atime = null) + * @method bool chown(string $filename, int|string $uid, bool $recursive = false) + * @method bool chgrp(string $filename, int|string $gid, bool $recursive = false) + * @method bool chmod(int $mode, string $filename, bool $recursive = false) + * @method mixed readlink(string $link) + * @method bool symlink(string $target, string $link) + * @method bool mkdir(string $dir, int $mode = -1, bool $recursive = false) + * @method bool rmdir(string $dir) + * @method bool put(string $remote_file, string $data, int $mode = SFTP::SOURCE_STRING, int $start = -1, int $local_start = -1, ?callable $progressCallback = null) + * @method string|bool get(string $remote_file, string $local_file = false, int $offset = 0, int $length = -1, ?callable $progressCallback = null) + * @method bool delete(string $path, bool $recursive = true) + * @method bool file_exists(string $path) + * @method bool is_dir(string $path) + * @method bool is_file(string $path) + * @method bool is_link(string $path) + * @method bool is_readable(string $path) + * @method bool is_writable(string $path) + * @method bool is_writeable(string $path) + * @method int|float|false fileatime(string $path) + * @method int|float|false filemtime(string $path) + * @method int|false fileperms(string $path) + * @method int|false fileowner(string $path) + * @method int|false filegroup(string $path) + * @method int|float|false filesize(string $path) + * @method string|false filetype(string $path) + * @method bool rename(string $oldname, string $newname) + * @method string[]|string getSFTPLog() + * @method string[] getSFTPErrors() + * @method string getLastSFTPError() + * @method mixed[]|false getSupportedVersions() + * @method int|false getNegotiatedVersion() + * @method void setPreferredVersion(int $version) + * @method void enableDatePreservation() + * @method void disableDatePreservation() + * @author Jim Wigginton + * @access public + */ +class SFTP +{ + /**#@+ + * @access public + * @see \phpseclib\Net\SFTP::put() + */ + /** + * Reads data from a local file. + */ + const SOURCE_LOCAL_FILE = 1; + /** + * Reads data from a string. + */ + // this value isn't really used anymore but i'm keeping it reserved for historical reasons + const SOURCE_STRING = 2; + /** + * Reads data from callback: + * function callback($length) returns string to proceed, null for EOF + */ + const SOURCE_CALLBACK = 16; + /** + * Resumes an upload + */ + const RESUME = 4; + /** + * Append a local file to an already existing remote file + */ + const RESUME_START = 8; + /**#@-*/ + + /** + * The SFTP object + * + * @var \phpseclib3\File\SFTP + * @access private + */ + private $sftp = null; + + /** + * Default Constructor. + * + * Connects to an SFTP server + * + * @param string $host + * @param int $port + * @param int $timeout + * @return \phpseclib\Net\SFTP + * @access public + */ + function __construct($host, $port = 22, $timeout = 10) + { + $this->sftp = new \phpseclib3\Net\SFTP($host, $port, $timeout); + } + + /** + * Login + * + * The $password parameter can be a plaintext password, a \phpseclib3\Crypt\RSA object or an array + * + * @param string $username + * @param $args[] param mixed $password + * @return bool + * @see self::_login() + * @access public + */ + public function login($username, ...$args) + { + foreach ($args as &$arg) { + if ($arg instanceof RSA) { + $arg = $arg->getKeyObject(); + if (!$arg instanceof \phpseclib3\Crypt\Common\PrivateKey) { + return false; + } + } + } + + try { + return $this->sftp->login($username, ...$args); + } catch (\Exception $e) { + user_error($e->getMessage()); + return false; + } + } + + /** + * Parse Attributes + * + * See '7. File Attributes' of draft-ietf-secsh-filexfer-13 for more info. + * + * @param string $response + * @return array + * @access private + */ + protected function parseAttributes(&$response) + { + $r = $this->sftp->parseAttributes($response); + if (isset($r['mode'])) { + $r['permissions'] = $r['mode']; + } + return $r; + } + + /** + * Defines how nlist() and rawlist() will be sorted - if at all. + * + * If sorting is enabled directories and files will be sorted independently with + * directories appearing before files in the resultant array that is returned. + * + * Any parameter returned by stat is a valid sort parameter for this function. + * Filename comparisons are case insensitive. + * + * Examples: + * + * $sftp->setListOrder('filename', SORT_ASC); + * $sftp->setListOrder('size', SORT_DESC, 'filename', SORT_ASC); + * $sftp->setListOrder(true); + * Separates directories from files but doesn't do any sorting beyond that + * $sftp->setListOrder(); + * Don't do any sort of sorting + * + * @param $args[] + * @access public + */ + public function setListOrder(...$args) + { + $sortOptions = []; + if (empty($args)) { + return; + } + $len = count($args) & 0x7FFFFFFE; + for ($i = 0; $i < $len; $i+=2) { + if ($args[$i] == 'permissions') { + $args[$i] = 'mode'; + } + $sortOptions[$args[$i]] = $args[$i + 1]; + } + $this->sftp->setListOrder(...$args); + } + + /** + * Returns the file size, in bytes, or false, on failure + * + * Files larger than 4GB will show up as being exactly 4GB. + * + * @param string $filename + * @return mixed + * @access public + */ + public function size($filename) + { + return $this->sftp->filesize($filename); + } + + /** + * Returns a public key object + * + * @access public + * @return SFTP|false + */ + public function getSFTPObject() + { + return $this->sftp; + } + + /** + * __call() magic method + * + * @access public + */ + public function __call($name, $args) + { + try { + return $this->sftp->$name(...$args); + } catch (\Exception $e) { + user_error($e->getMessage()); + } + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Net/SFTP/Stream.php b/vendor/phpseclib/phpseclib2_compat/src/Net/SFTP/Stream.php new file mode 100644 index 000000000..c456990a7 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Net/SFTP/Stream.php @@ -0,0 +1,75 @@ + + * @copyright 2013 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib\Net\SFTP; + +use phpseclib\Crypt\RSA; +use phpseclib\Net\SFTP; + +/** + * SFTP Stream Wrapper + * + * @package SFTP + * @author Jim Wigginton + * @access public + */ +class Stream extends \phpseclib3\Net\SFTP\Stream +{ + /** + * Path Parser + * + * Extract a path from a URI and actually connect to an SSH server if appropriate + * + * If "notification" is set as a context parameter the message code for successful login is + * NET_SSH2_MSG_USERAUTH_SUCCESS. For a failed login it's NET_SSH2_MSG_USERAUTH_FAILURE. + * + * @param string $path + * @return string + * @access private + */ + protected function parse_path($path) + { + $scheme = parse_url($path, PHP_URL_SCHEME); + if (isset($this->context)) { + $options = stream_context_get_options($this->context); + } + if (isset($options[$scheme]['privkey']) && $options[$scheme]['privkey'] instanceof RSA) { + stream_context_set_option($this->context, $scheme, 'privKey', $options[$scheme]['privkey']->getKeyObject()); + } + if (isset($options[$scheme]['session']) && $options[$scheme]['session'] instanceof SFTP) { + stream_context_set_option($this->context, $scheme, 'session', $options[$scheme]['session']->getSFTPObject()); + } + if (isset($options[$scheme]['sftp']) && $options[$scheme]['sftp'] instanceof SFTP) { + stream_context_set_option($this->context, $scheme, 'sftp', $options[$scheme]['sftp']->getSFTPObject()); + } + return parent::parse_path($path); + } + + /** + * __call() magic method + * + * @access public + */ + public function __call($name, array $args) + { + try { + return parent::__call($name, $args); + } catch (\Exception $e) { + user_error($e->getMessage()); + } + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/Net/SSH2.php b/vendor/phpseclib/phpseclib2_compat/src/Net/SSH2.php new file mode 100644 index 000000000..a78e7e87d --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/Net/SSH2.php @@ -0,0 +1,233 @@ + + * login('username', 'password')) { + * exit('Login Failed'); + * } + * + * echo $ssh->exec('pwd'); + * echo $ssh->exec('ls -la'); + * ?> + * + * + * + * setPassword('whatever'); + * $key->loadKey(file_get_contents('privatekey')); + * + * $ssh = new \phpseclib\Net\SSH2('www.domain.tld'); + * if (!$ssh->login('username', $key)) { + * exit('Login Failed'); + * } + * + * echo $ssh->read('username@username:~$'); + * $ssh->write("ls -la\n"); + * echo $ssh->read('username@username:~$'); + * ?> + * + * + * @category Net + * @package SSH2 + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + + +namespace phpseclib\Net; + +use phpseclib\Crypt\RSA; + +/** + * Pure-PHP implementation of SSHv2. + * + * @package SSHv2 + * @method static void setCryptoEngine(string $engine) + * @method void sendIdentificationStringFirst() + * @method void sendIdentificationStringLast() + * @method void sendKEXINITFirst() + * @method void sendKEXINITLast() + * @method int|float getTimeout() + * @method void setTimeout(int|float $timeout) + * @method void setKeepAlive(int|float $interval) + * @method string getStdError() + * @method string|bool exec(string $command, callable ?$callback = null) + * @method bool requestAgentForwarding() + * @method string|bool|null read(string $expect = '', int $mode = SSH2::READ_SIMPLE) + * @method void write(string $cmd) + * @method bool startSubsystem(string $subsystem) + * @method bool stopSubsystem() + * @method void reset() + * @method bool isTimeout() + * @method void disconnect() + * @method bool isConnected() + * @method bool isAuthenticated() + * @method bool ping() + * @method void enableQuietMode() + * @method void disableQuietMode() + * @method bool isQuietModeEnabled() + * @method void enablePTY() + * @method void disablePTY() + * @method bool isPTYEnabled() + * @method array|false|string getLog() + * @method string[] getErrors() + * @method ?string getLastError() + * @method string|false getServerIdentification() + * @method mixed[] getServerAlgorithms() + * @method static string[] getSupportedKEXAlgorithms() + * @method static string[] getSupportedHostKeyAlgorithms() + * @method static string[] getSupportedEncryptionAlgorithms() + * @method static string[] getSupportedMACAlgorithms() + * @method static string[] getSupportedCompressionAlgorithms() + * @method mixed[] getAlgorithmsNegotiated() + * @method void setTerminal(string $term) + * @method void setPreferredAlgorithms(mixed[] $methods) + * @method string getBannerMessage() + * @method string|false getServerPublicHostKey() + * @method false|int getExitStatus() + * @method int getWindowColumns() + * @method int getWindowRows() + * @method setWindowColumns(int $value) + * @method setWindowRows(int $value) + * @method setWindowSize(int $columns = 80, int $rows = 24) + * @method string getResourceId() + * @method static bool|SSH2 getConnectionByResourceId(string $id) + * @method static array getConnections() + * @method ?mixed[] getAuthMethodsToContinue() + * @method void enableSmartMFA() + * @method void disableSmartMFA() + * @author Jim Wigginton + * @access public + */ +class SSH2 +{ + /**#@+ + * @access public + * @see \phpseclib\Net\SSH2::getLog() + */ + /** + * Returns the message numbers + */ + const LOG_SIMPLE = 1; + /** + * Returns the message content + */ + const LOG_COMPLEX = 2; + /** + * Outputs the content real-time + */ + const LOG_REALTIME = 3; + /** + * Dumps the content real-time to a file + */ + const LOG_REALTIME_FILE = 4; + /** + * Make sure that the log never gets larger than this + */ + const LOG_MAX_SIZE = 1048576; // 1024 * 1024 + /**#@-*/ + + /**#@+ + * @access public + * @see \phpseclib\Net\SSH2::read() + */ + /** + * Returns when a string matching $expect exactly is found + */ + const READ_SIMPLE = 1; + /** + * Returns when a string matching the regular expression $expect is found + */ + const READ_REGEX = 2; + /** + * Returns whenever a data packet is received. + * + * Some data packets may only contain a single character so it may be necessary + * to call read() multiple times when using this option + */ + const READ_NEXT = 3; + /**#@-*/ + + /** + * The SSH2 object + * + * @var \phpseclib3\File\SSH2 + * @access private + */ + private $ssh; + + /** + * Default Constructor. + * + * $host can either be a string, representing the host, or a stream resource. + * + * @param mixed $host + * @param int $port + * @param int $timeout + * @see self::login() + * @return \phpseclib\Net\SSH2 + * @access public + */ + function __construct($host, $port = 22, $timeout = 10) + { + $this->ssh = new \phpseclib3\Net\SSH2($host, $port, $timeout); + } + + /** + * Login + * + * The $password parameter can be a plaintext password, a \phpseclib3\Crypt\RSA object or an array + * + * @param string $username + * @param $args[] param mixed $password + * @return bool + * @see self::_login() + * @access public + */ + public function login($username, ...$args) + { + foreach ($args as &$arg) { + if ($arg instanceof RSA) { + $arg = $arg->getKeyObject(); + if (!$arg) { + return false; + } + } + } + + try { + return $this->ssh->login($username, ...$args); + } catch (\Exception $e) { + user_error($e->getMessage()); + return false; + } + } + + /** + * __call() magic method + * + * @access public + */ + public function __call($name, $args) + { + try { + return $this->ssh->$name(...$args); + } catch (\Exception $e) { + user_error($e->getMessage()); + } + } +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/System/SSH/Agent.php b/vendor/phpseclib/phpseclib2_compat/src/System/SSH/Agent.php new file mode 100644 index 000000000..365353f67 --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/System/SSH/Agent.php @@ -0,0 +1,47 @@ + + * login('username', $agent)) { + * exit('Login Failed'); + * } + * + * echo $ssh->exec('pwd'); + * echo $ssh->exec('ls -la'); + * ?> + * + * + * @category System + * @package SSH\Agent + * @author Jim Wigginton + * @copyright 2014 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + * @internal See http://api.libssh.org/rfc/PROTOCOL.agent + */ + +namespace phpseclib\System\SSH; + +/** + * Pure-PHP ssh-agent client identity factory + * + * requestIdentities() method pumps out \phpseclib3\System\SSH\Agent\Identity objects + * + * @package SSH\Agent + * @author Jim Wigginton + * @access public + */ +class Agent extends \phpseclib3\System\SSH\Agent +{ +} \ No newline at end of file diff --git a/vendor/phpseclib/phpseclib2_compat/src/System/SSH/Agent/Identity.php b/vendor/phpseclib/phpseclib2_compat/src/System/SSH/Agent/Identity.php new file mode 100644 index 000000000..c85f8330f --- /dev/null +++ b/vendor/phpseclib/phpseclib2_compat/src/System/SSH/Agent/Identity.php @@ -0,0 +1,34 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + * @internal See http://api.libssh.org/rfc/PROTOCOL.agent + */ + +namespace phpseclib\System\SSH\Agent; + +/** + * Pure-PHP ssh-agent client identity object + * + * Instantiation should only be performed by \phpseclib3\System\SSH\Agent class. + * This could be thought of as implementing an interface that phpseclib3\Crypt\RSA + * implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something. + * The methods in this interface would be getPublicKey and sign since those are the + * methods phpseclib looks for to perform public key authentication. + * + * @package SSH\Agent + * @author Jim Wigginton + * @access internal + */ +class Identity extends \phpseclib3\System\SSH\Agent\Identity +{ +} \ No newline at end of file