From d077c7b29695ce26a45c4f4c0c56690726388d5c Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 17 Jul 2020 07:53:05 -0500 Subject: [PATCH 01/69] X509: really looong base64 encoded strings broke extractBER() --- phpseclib/File/X509.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 9295c6994..ff4a31a25 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -5144,7 +5144,9 @@ function _extractBER($str) * subject=/O=organization/OU=org unit/CN=common name * issuer=/O=organization/CN=common name */ - $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1); + $temp = strlen($str) <= ini_get('pcre.backtrack_limit') ? + preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1) : + $str; // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff $temp = preg_replace('#-+[^-]+-+#', '', $temp); // remove new lines From 05a564c1368a8251002a0c47f5abe024de240641 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Thu, 30 Jul 2020 15:42:02 +0200 Subject: [PATCH 02/69] Return false by default --- phpseclib/Crypt/RSA.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 2fea3a921..db037fe42 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -1624,6 +1624,8 @@ function. As is, the definitive authority on this encoding scheme isn't the IET return $components; } + + return false; } /** From ea653e1b012a71d6a194452421bb9cdef2cab827 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 30 Jul 2020 09:12:23 -0500 Subject: [PATCH 03/69] SFTP: add enableDatePreservation() / disableDatePreservation() --- phpseclib/Net/SFTP.php | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index 9baca9910..da4c02940 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -300,6 +300,16 @@ class Net_SFTP extends Net_SSH2 */ var $requestBuffer = array(); + /** + * Preserve timestamps on file downloads / uploads + * + * @see self::get() + * @see self::put() + * @var bool + * @access private + */ + var $preserveTime = false; + /** * Default Constructor. * @@ -2136,6 +2146,11 @@ function put($remote_file, $data, $mode = NET_SFTP_STRING, $start = -1, $local_s } if ($mode & NET_SFTP_LOCAL_FILE) { + if ($this->preserveTime) { + $stat = fstat($fp); + $this->touch($remote_file, $stat['mtime'], $stat['atime']); + } + fclose($fp); } @@ -2353,6 +2368,11 @@ function get($remote_file, $local_file = false, $offset = 0, $length = -1, $prog if ($fclose_check) { fclose($fp); + + if ($this->preserveTime) { + $stat = $this->stat($remote_file); + touch($local_file, $stat['mtime'], $stat['atime']); + } } if (!$this->_close_handle($handle)) { @@ -3237,4 +3257,24 @@ function _disconnect($reason) $this->pwd = false; parent::_disconnect($reason); } + + /** + * Enable Date Preservation + * + * @access public + */ + function enableDatePreservation() + { + $this->preserveTime = true; + } + + /** + * Disable Date Preservation + * + * @access public + */ + function disableDatePreservation() + { + $this->preserveTime = false; + } } From c7d7b36018e13d034a74f2416ce1dcd247bda3ec Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 31 Jul 2020 02:49:21 -0500 Subject: [PATCH 04/69] SSH2: don't try to login as none auth method for CoreFTP server --- phpseclib/Net/SSH2.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 31af44534..aa503a1bb 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -2135,11 +2135,13 @@ function login($username) // try logging with 'none' as an authentication method first since that's what // PuTTY does - if ($this->_login($username)) { - return true; - } - if (count($args) == 1) { - return false; + if (substr($this->server_identifier, 0, 13) != 'SSH-2.0-CoreFTP') { + if ($this->_login($username)) { + return true; + } + if (count($args) == 1) { + return false; + } } return call_user_func_array(array(&$this, '_login'), $args); } From 40b4f1d557d2d466987bf6fc573ea205ecaa35d9 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 31 Jul 2020 08:05:31 -0500 Subject: [PATCH 05/69] SSH2: when building algo list look at if crypto engine is set --- phpseclib/Net/SSH2.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index aa503a1bb..465549abf 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -4610,11 +4610,15 @@ function getSupportedEncryptionAlgorithms() //'none' // OPTIONAL no encryption; NOT RECOMMENDED ); - $engines = array( - CRYPT_ENGINE_OPENSSL, - CRYPT_ENGINE_MCRYPT, - CRYPT_ENGINE_INTERNAL - ); + if ($this->crypto_engine) { + $engines = array($this->crypto_engine); + } else { + $engines = array( + CRYPT_ENGINE_OPENSSL, + CRYPT_ENGINE_MCRYPT, + CRYPT_ENGINE_INTERNAL + ); + } $ciphers = array(); foreach ($engines as $engine) { From 239bc636182ec735668067391fa9ab6070a50489 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 9 Aug 2020 11:00:12 -0500 Subject: [PATCH 06/69] SSH2: uploads on low speed networks could get in infinite loop --- phpseclib/Net/SFTP.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index da4c02940..c6c2ea332 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -3041,6 +3041,10 @@ function _parseLongname($longname) */ function _send_sftp_packet($type, $data, $request_id = 1) { + // in SSH2.php the timeout is cumulative per function call. eg. exec() will + // timeout after 10s. but for SFTP.php it's cumulative per packet + $this->curTimeout = $this->timeout; + $packet = $this->use_request_id ? pack('NCNa*', strlen($data) + 5, $type, $request_id, $data) : pack('NCa*', strlen($data) + 1, $type, $data); From ded9b3043fc717ff01be44afe1053a497d243eac Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 17 Aug 2020 07:28:17 -0500 Subject: [PATCH 07/69] SSH2: suppress 'broken pipe' errors --- phpseclib/Net/SSH2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 465549abf..2194d8f5d 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -3981,7 +3981,7 @@ function _send_binary_packet($data, $logged = null) $packet.= $hmac; $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 - $result = strlen($packet) == fputs($this->fsock, $packet); + $result = strlen($packet) == @fputs($this->fsock, $packet); $stop = strtok(microtime(), ' ') + strtok(''); if (defined('NET_SSH2_LOGGING')) { From ceab38e0b85287b68fcc1a1d46403dae3a28e0af Mon Sep 17 00:00:00 2001 From: William Desportes Date: Fri, 21 Aug 2020 18:04:02 +0200 Subject: [PATCH 08/69] Move Doctum config files to phpseclib/api-docs Fixes: #1365 Closes: #416 Closes: #1506 --- README.md | 2 +- build/build.xml | 7 ------- build/sami.conf.php | 32 -------------------------------- composer.json | 1 - 4 files changed, 1 insertion(+), 41 deletions(-) delete mode 100644 build/sami.conf.php diff --git a/README.md b/README.md index 0001e8a39..402ca5eb8 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509 ## Documentation * [Documentation / Manual](http://phpseclib.sourceforge.net/) -* [API Documentation](https://api.phpseclib.org/1.0/) (generated by Sami) +* [API Documentation](https://api.phpseclib.org/1.0/) (generated by Doctum) ## Branches diff --git a/build/build.xml b/build/build.xml index 92d3923f4..5bdd8a80d 100644 --- a/build/build.xml +++ b/build/build.xml @@ -22,11 +22,4 @@ tests/" dir=".." checkreturn="true" passthru="true" /> - - - - - - diff --git a/build/sami.conf.php b/build/sami.conf.php deleted file mode 100644 index 9fe0286c4..000000000 --- a/build/sami.conf.php +++ /dev/null @@ -1,32 +0,0 @@ -classes[$name]); - } -} - -$iterator = Symfony\Component\Finder\Finder::create() - ->files() - ->name('*.php') - ->in(__DIR__ . '/../phpseclib/') -; - -$versions = Sami\Version\GitVersionCollection::create(__DIR__ . '/../') - ->add('1.0') - ->add('2.0') - ->add('master') -; - -return new Sami\Sami($iterator, array( - 'theme' => 'enhanced', - 'versions' => $versions, - 'title' => 'phpseclib API Documentation', - 'build_dir' => __DIR__.'/api/output/%version%', - 'cache_dir' => __DIR__.'/api/cache/%version%', - 'default_opened_level' => 2, - 'store' => new MyArrayStore, -)); diff --git a/composer.json b/composer.json index d5d07bbfd..6729e8f90 100644 --- a/composer.json +++ b/composer.json @@ -56,7 +56,6 @@ "require-dev": { "phing/phing": "~2.7", "phpunit/phpunit": "^4.8.35|^5.7|^6.0", - "sami/sami": "~2.0", "squizlabs/php_codesniffer": "~2.0" }, "suggest": { From 3fe698e9ae5955ddefc2a59eb3e2065a2909f6fb Mon Sep 17 00:00:00 2001 From: William Desportes Date: Fri, 21 Aug 2020 18:43:05 +0200 Subject: [PATCH 09/69] Remove api from build target --- build/build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build.xml b/build/build.xml index 5bdd8a80d..26ab24b8a 100644 --- a/build/build.xml +++ b/build/build.xml @@ -4,7 +4,7 @@ default="all" > - + From f4e017f383074b6bbf99b256a229b0bc74480a6a Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 30 Aug 2020 08:21:50 -0500 Subject: [PATCH 10/69] SFTP: "fix" rare resource not closed error --- phpseclib/Net/SFTP.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index c6c2ea332..612f9b212 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -2151,7 +2151,9 @@ function put($remote_file, $data, $mode = NET_SFTP_STRING, $start = -1, $local_s $this->touch($remote_file, $stat['mtime'], $stat['atime']); } - fclose($fp); + if (isset($fp) && is_resource($fp)) { + fclose($fp); + } } return $this->_close_handle($handle); From 497856a8d997f640b4a516062f84228a772a48a8 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 7 Sep 2020 23:24:43 -0500 Subject: [PATCH 11/69] add 2.0.29 release --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f38529e79..671f50d64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 2.0.29 - 2020-09-07 + +- SFTP: add enableDatePreservation() / disableDatePreservation() (#1496) +- SFTP: uploads on low speed networks could get in infinite loop (#1507) +- SSH2: when building algo list look at if crypto engine is set (#1500) +- X509: really looong base64 encoded strings broke extractBER() (#1486) + ## 2.0.28 - 2020-07-08 - SFTP: realpath('') produced an error (#1474) From 2ae683479a463b88780d051efe063ca3a48b7a5c Mon Sep 17 00:00:00 2001 From: William Desportes Date: Fri, 21 Aug 2020 18:18:18 +0200 Subject: [PATCH 12/69] Fix phpdoc errors --- phpseclib/Crypt/Base.php | 2 +- phpseclib/Crypt/Hash.php | 3 +-- phpseclib/Crypt/RSA.php | 28 ++++++++++++++++------------ phpseclib/File/ANSI.php | 3 +-- phpseclib/File/ASN1.php | 7 ++++--- phpseclib/File/X509.php | 24 ++++++++++++------------ phpseclib/Math/BigInteger.php | 20 ++++++++++---------- phpseclib/Net/SFTP.php | 8 ++++++-- phpseclib/Net/SFTP/Stream.php | 5 ++--- phpseclib/Net/SSH1.php | 5 +++-- phpseclib/Net/SSH2.php | 16 ++++++---------- 11 files changed, 62 insertions(+), 59 deletions(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index e51d1a073..cad9c3829 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -2584,7 +2584,7 @@ function &_getLambdaFunctions() * * @see self::_setupInlineCrypt() * @access private - * @param $bytes + * @param string $bytes * @return string */ function _hashInlineCryptFunction($bytes) diff --git a/phpseclib/Crypt/Hash.php b/phpseclib/Crypt/Hash.php index a998b5b24..d0cb2a15b 100644 --- a/phpseclib/Crypt/Hash.php +++ b/phpseclib/Crypt/Hash.php @@ -191,7 +191,7 @@ function __construct($hash = 'sha1') * PHP4 compatible Default Constructor. * * @see self::__construct() - * @param int $mode + * @param string $hash * @access public */ function Crypt_Hash($hash = 'sha1') @@ -879,7 +879,6 @@ function _not($int) * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the * possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster. * - * @param int $... * @return int * @see self::_sha256() * @access private diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index db037fe42..28309e5b3 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -589,7 +589,7 @@ function Crypt_RSA() * @access public * @param int $bits * @param int $timeout - * @param Math_BigInteger $p + * @param array $partial */ function createKey($bits = 1024, $timeout = false, $partial = array()) { @@ -768,7 +768,12 @@ function createKey($bits = 1024, $timeout = false, $partial = array()) * * @access private * @see self::setPrivateKeyFormat() - * @param string $RSAPrivateKey + * @param Math_BigInteger $n + * @param Math_BigInteger $e + * @param Math_BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients * @return string */ function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients) @@ -1061,8 +1066,9 @@ function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients) * * @access private * @see self::setPublicKeyFormat() - * @param string $RSAPrivateKey - * @return string + * @param Math_BigInteger $n + * @param Math_BigInteger $e + * @return string|array */ function _convertPublicKey($n, $e) { @@ -1964,7 +1970,6 @@ function setPrivateKey($key = false, $type = false) * * @see self::getPublicKey() * @access public - * @param string $key * @param int $type optional */ function getPublicKey($type = CRYPT_RSA_PUBLIC_FORMAT_PKCS8) @@ -2022,7 +2027,6 @@ function getPublicKeyFingerprint($algorithm = 'md5') * * @see self::getPublicKey() * @access public - * @param string $key * @param int $type optional * @return mixed */ @@ -2047,8 +2051,7 @@ function getPrivateKey($type = CRYPT_RSA_PUBLIC_FORMAT_PKCS1) * * @see self::getPrivateKey() * @access private - * @param string $key - * @param int $type optional + * @param int $mode optional */ function _getPrivatePublicKey($mode = CRYPT_RSA_PUBLIC_FORMAT_PKCS8) { @@ -2265,7 +2268,7 @@ function setMGFHash($hash) * of the hash function Hash) and 0. * * @access public - * @param int $format + * @param int $sLen */ function setSaltLength($sLen) { @@ -2298,7 +2301,7 @@ function _i2osp($x, $xLen) * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}. * * @access private - * @param string $x + * @param int|string|resource $x * @return Math_BigInteger */ function _os2ip($x) @@ -2525,7 +2528,7 @@ function _rsavp1($s) * * @access private * @param string $mgfSeed - * @param int $mgfLen + * @param int $maskLen * @return string */ function _mgf1($mgfSeed, $maskLen) @@ -3034,6 +3037,7 @@ function _rsassa_pkcs1_v1_5_sign($m) * * @access private * @param string $m + * @param string $s * @return string */ function _rsassa_pkcs1_v1_5_verify($m, $s) @@ -3174,7 +3178,7 @@ function encrypt($plaintext) * * @see self::encrypt() * @access public - * @param string $plaintext + * @param string $ciphertext * @return string */ function decrypt($ciphertext) diff --git a/phpseclib/File/ANSI.php b/phpseclib/File/ANSI.php index ac030df7f..51693be8f 100644 --- a/phpseclib/File/ANSI.php +++ b/phpseclib/File/ANSI.php @@ -230,8 +230,7 @@ function setDimensions($x, $y) /** * Set the number of lines that should be logged past the terminal height * - * @param int $x - * @param int $y + * @param int $history * @access public */ function setHistory($history) diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 98fe4b83a..00c913b83 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -140,7 +140,7 @@ function __construct($encoded) * PHP4 compatible Default Constructor. * * @see self::__construct() - * @param int $mode + * @param string $encoded * @access public */ function File_ASN1_Element($encoded) @@ -887,7 +887,7 @@ function asn1map($decoded, $mapping, $special = array()) * * @param string $source * @param string $mapping - * @param int $idx + * @param array $special * @return string * @access public */ @@ -903,6 +903,7 @@ function encodeDER($source, $mapping, $special = array()) * @param string $source * @param string $mapping * @param int $idx + * @param array $special * @return string * @access private */ @@ -1262,7 +1263,7 @@ function _decodeOID($content) * Called by _encode_der() * * @access private - * @param string $content + * @param string $source * @return string */ function _encodeOID($source) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index ff4a31a25..57aaf29b4 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -1638,7 +1638,7 @@ function saveX509($cert, $format = FILE_X509_FORMAT_PEM) * Map extension values from octet string to extension-specific internal * format. * - * @param array ref $root + * @param array $root (by reference) * @param string $path * @param object $asn1 * @access private @@ -1691,7 +1691,7 @@ function _mapInExtensions(&$root, $path, $asn1) * Map extension values from extension-specific internal format to * octet string. * - * @param array ref $root + * @param array $root (by reference) * @param string $path * @param object $asn1 * @access private @@ -1757,7 +1757,7 @@ function _mapOutExtensions(&$root, $path, $asn1) * Map attribute values from ANY type to attribute-specific internal * format. * - * @param array ref $root + * @param array $root (by reference) * @param string $path * @param object $asn1 * @access private @@ -1798,7 +1798,7 @@ function _mapInAttributes(&$root, $path, $asn1) * Map attribute values from attribute-specific internal format to * ANY type. * - * @param array ref $root + * @param array $root (by reference) * @param string $path * @param object $asn1 * @access private @@ -1841,7 +1841,7 @@ function _mapOutAttributes(&$root, $path, $asn1) * Map DN values from ANY type to DN-specific internal * format. * - * @param array ref $root + * @param array $root (by reference) * @param string $path * @param object $asn1 * @access private @@ -1871,7 +1871,7 @@ function _mapInDNs(&$root, $path, $asn1) * Map DN values from DN-specific internal format to * ANY type. * - * @param array ref $root + * @param array $root (by reference) * @param string $path * @param object $asn1 * @access private @@ -3243,7 +3243,8 @@ function getPublicKey() /** * Load a Certificate Signing Request * - * @param string $csr + * @param string|array $csr + * @param int $mode * @access public * @return mixed */ @@ -3383,7 +3384,7 @@ function saveCSR($csr, $format = FILE_X509_FORMAT_PEM) * * https://developer.mozilla.org/en-US/docs/HTML/Element/keygen * - * @param string $csr + * @param string|array $spkac * @access public * @return mixed */ @@ -3457,7 +3458,7 @@ function loadSPKAC($spkac) /** * Save a SPKAC CSR request * - * @param array $csr + * @param string|array $spkac * @param int $format optional * @access public * @return string @@ -3501,6 +3502,7 @@ function saveSPKAC($spkac, $format = FILE_X509_FORMAT_PEM) * Load a Certificate Revocation List * * @param string $crl + * @param int $mode * @access public * @return mixed */ @@ -4114,7 +4116,6 @@ function signCRL($issuer, $crl, $signatureAlgorithm = 'sha1WithRSAEncryption') * X.509 certificate signing helper function. * * @param object $key - * @param File_X509 $subject * @param string $signatureAlgorithm * @access public * @return mixed @@ -4192,7 +4193,7 @@ function setEndDate($date) * Set Serial Number * * @param string $serial - * @param $base optional + * @param int $base optional * @access public */ function setSerialNumber($serial, $base = -256) @@ -4866,7 +4867,6 @@ function setDomain() * Set the IP Addresses's which the cert is to be valid for * * @access public - * @param string $ipAddress optional */ function setIPAddress() { diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php index 35df7adac..f48b5ec67 100644 --- a/phpseclib/Math/BigInteger.php +++ b/phpseclib/Math/BigInteger.php @@ -237,7 +237,7 @@ class Math_BigInteger * ?> * * - * @param $x base-10 number or base-$base number if $base set. + * @param int|string|resource $x base-10 number or base-$base number if $base set. * @param int $base * @return Math_BigInteger * @access public @@ -2021,7 +2021,7 @@ function _squareReduce($x, $n, $mode) * * @see self::_slidingWindow() * @access private - * @param Math_BigInteger + * @param Math_BigInteger $n * @return Math_BigInteger */ function _mod2($n) @@ -3136,7 +3136,7 @@ function setRandomGenerator($generator) * * Byte length is equal to $length. Uses crypt_random if it's loaded and mt_rand if it's not. * - * @param int $length + * @param int $size * @return Math_BigInteger * @access private */ @@ -3603,7 +3603,7 @@ function _rshift($shift) * * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision * - * @param Math_BigInteger + * @param Math_BigInteger $result * @return Math_BigInteger * @see self::_trim() * @access private @@ -3680,8 +3680,8 @@ function _trim($value) /** * Array Repeat * - * @param $input Array - * @param $multiplier mixed + * @param array $input + * @param mixed $multiplier * @return array * @access private */ @@ -3695,8 +3695,8 @@ function _array_repeat($input, $multiplier) * * Shifts binary strings $shift bits, essentially multiplying by 2**$shift. * - * @param $x String - * @param $shift Integer + * @param string $x (by reference) + * @param int $shift * @return string * @access private */ @@ -3724,8 +3724,8 @@ function _base256_lshift(&$x, $shift) * * Shifts binary strings $shift bits, essentially dividing by 2**$shift and returning the remainder. * - * @param $x String - * @param $shift Integer + * @param string $x (by referenc) + * @param int $shift * @return string * @access private */ diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index 612f9b212..525f98ac9 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -471,7 +471,6 @@ function Net_SFTP($host, $port = 22, $timeout = 10) * Login * * @param string $username - * @param string $password * @return bool * @access public */ @@ -1286,7 +1285,7 @@ function _remove_from_stat_cache($path) * * Mainly used by file_exists * - * @param string $dir + * @param string $path * @return mixed * @access private */ @@ -1841,6 +1840,8 @@ function symlink($target, $link) * Creates a directory. * * @param string $dir + * @param int $mode + * @param bool $recursive * @return bool * @access public */ @@ -1873,6 +1874,7 @@ function mkdir($dir, $mode = -1, $recursive = false) * Helper function for directory creation * * @param string $dir + * @param int $mode * @return bool * @access private */ @@ -2796,6 +2798,7 @@ function _get_lstat_cache_prop($path, $prop) * * @param string $path * @param string $prop + * @param mixed $type * @return mixed * @access private */ @@ -3036,6 +3039,7 @@ function _parseLongname($longname) * * @param int $type * @param string $data + * @param int $request_id * @see self::_get_sftp_packet() * @see Net_SSH2::_send_channel_packet() * @return bool diff --git a/phpseclib/Net/SFTP/Stream.php b/phpseclib/Net/SFTP/Stream.php index 4ec80996d..842ebab54 100644 --- a/phpseclib/Net/SFTP/Stream.php +++ b/phpseclib/Net/SFTP/Stream.php @@ -644,7 +644,6 @@ function _mkdir($path, $mode, $options) * $options. What does 8 correspond to? * * @param string $path - * @param int $mode * @param int $options * @return bool * @access public @@ -786,8 +785,8 @@ function _stream_close() * If NET_SFTP_STREAM_LOGGING is defined all calls will be output on the screen and then (regardless of whether or not * NET_SFTP_STREAM_LOGGING is enabled) the parameters will be passed through to the appropriate method. * - * @param string - * @param array + * @param string $name + * @param array $arguments * @return mixed * @access public */ diff --git a/phpseclib/Net/SSH1.php b/phpseclib/Net/SSH1.php index bdb57dbdb..76401a003 100644 --- a/phpseclib/Net/SSH1.php +++ b/phpseclib/Net/SSH1.php @@ -857,6 +857,7 @@ function setTimeout($timeout) * @see self::interactiveRead() * @see self::interactiveWrite() * @param string $cmd + * @param bool $block * @return mixed * @access public */ @@ -1434,7 +1435,6 @@ function _rsa_crypt($m, $key) * named constants from it, using the value as the name of the constant and the index as the value of the constant. * If any of the constants that would be defined already exists, none of the constants will be defined. * - * @param array $array * @access private */ function _define_array() @@ -1633,7 +1633,8 @@ function getServerIdentification() * * Makes sure that only the last 1MB worth of packets will be logged * - * @param string $data + * @param int $protocol_flags + * @param string $message * @access private */ function _append_log($protocol_flags, $message) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 2194d8f5d..d3cbc1f4a 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -2122,8 +2122,6 @@ function _bad_algorithm_candidate($algorithm) * The $password parameter can be a plaintext password, a Crypt_RSA object or an array * * @param string $username - * @param mixed $password - * @param mixed $... * @return bool * @see self::_login() * @access public @@ -2150,8 +2148,6 @@ function login($username) * Login Helper * * @param string $username - * @param mixed $password - * @param mixed $... * @return bool * @see self::_login_helper() * @access private @@ -2416,7 +2412,6 @@ function _keyboard_interactive_login($username, $password) /** * Handle the keyboard-interactive requests / responses. * - * @param string $responses... * @return bool * @access private */ @@ -2561,7 +2556,7 @@ function _ssh_agent_login($username, $agent) * Login with an RSA private key * * @param string $username - * @param Crypt_RSA $password + * @param Crypt_RSA $privatekey * @return bool * @access private * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} @@ -3670,8 +3665,9 @@ function isPTYEnabled() * * Returns the data as a string if it's available and false if not. * - * @param $client_channel - * @return mixed + * @param int $client_channel + * @param bool $skip_extended + * @return mixed|bool * @access private */ function _get_channel_packet($client_channel, $skip_extended = false) @@ -4001,7 +3997,8 @@ function _send_binary_packet($data, $logged = null) * * Makes sure that only the last 1MB worth of packets will be logged * - * @param string $data + * @param string $message_number + * @param string $message * @access private */ function _append_log($message_number, $message) @@ -4206,7 +4203,6 @@ function _string_shift(&$string, $index = 1) * named constants from it, using the value as the name of the constant and the index as the value of the constant. * If any of the constants that would be defined already exists, none of the constants will be defined. * - * @param array $array * @access private */ function _define_array() From 96c4c3bc5810e8bed980504e4fefcb49ef437a77 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 28 Sep 2020 06:17:49 -0500 Subject: [PATCH 13/69] SSH2: add setKeepAlive() method --- phpseclib/Net/SSH2.php | 45 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index d3cbc1f4a..17125801a 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -692,6 +692,14 @@ class Net_SSH2 */ var $curTimeout; + /** + * Keep Alive Interval + * + * @see self::setKeepAlive() + * @access private + */ + var $keepAlive; + /** * Real-time log file pointer * @@ -2691,6 +2699,19 @@ function setTimeout($timeout) $this->timeout = $this->curTimeout = $timeout; } + /** + * Set Keep Alive + * + * Sends an SSH2_MSG_IGNORE message every x seconds, if x is a positive non-zero number. + * + * @param mixed $timeout + * @access public + */ + function setKeepAlive($interval) + { + $this->keepAlive = $interval; + } + /** * Get the output from stdError * @@ -3684,8 +3705,15 @@ function _get_channel_packet($client_channel, $skip_extended = false) $read = array($this->fsock); $write = $except = null; - if (!$this->curTimeout) { - @stream_select($read, $write, $except, null); + if ($this->curTimeout <= 0) { + if ($this->keepAlive <= 0) { + @stream_select($read, $write, $except, null); + } else { + if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + continue; + } + } } else { if ($this->curTimeout < 0) { $this->is_timeout = true; @@ -3696,8 +3724,21 @@ function _get_channel_packet($client_channel, $skip_extended = false) $write = $except = null; $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 + + if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) { + if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + $elapsed = strtok(microtime(), ' ') + strtok('') - $start; + $this->curTimeout-= $elapsed; + continue; + } + $elapsed = strtok(microtime(), ' ') + strtok('') - $start; + $this->curTimeout-= $elapsed; + } + $sec = floor($this->curTimeout); $usec = 1000000 * ($this->curTimeout - $sec); + // on windows this returns a "Warning: Invalid CRT parameters detected" error if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) { $this->is_timeout = true; From 00c9edc05889ae41263f026033bcb542d39ff896 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 29 Oct 2020 21:30:01 -0500 Subject: [PATCH 14/69] X509: don't attempt to parse multi-cert PEMs --- phpseclib/File/X509.php | 4 +- tests/Unit/File/X509/X509Test.php | 115 ++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 2 deletions(-) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 57aaf29b4..6dd598bd0 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -5147,10 +5147,10 @@ function _extractBER($str) $temp = strlen($str) <= ini_get('pcre.backtrack_limit') ? preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1) : $str; - // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff - $temp = preg_replace('#-+[^-]+-+#', '', $temp); // remove new lines $temp = str_replace(array("\r", "\n", ' '), '', $temp); + // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff + $temp = preg_replace('#^-+[^-]+-+|-+[^-]+-+$#', '', $temp); $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; return $temp != false ? $temp : $str; } diff --git a/tests/Unit/File/X509/X509Test.php b/tests/Unit/File/X509/X509Test.php index e4ccdd590..93434cbe3 100644 --- a/tests/Unit/File/X509/X509Test.php +++ b/tests/Unit/File/X509/X509Test.php @@ -747,4 +747,119 @@ public function testRandomString() $this->assertFalse($r); } + + /** + * @group github1542 + */ + public function testMultiCertPEM() + { + $a = '-----BEGIN CERTIFICATE----- +MIILODCCCSCgAwIBAgIQDh0LGipJ++wxFLj8X5MXKDANBgkqhkiG9w0BAQsFADCB +kDELMAkGA1UEBhMCVVMxDTALBgNVBAgTBFV0YWgxDTALBgNVBAcTBExlaGkxFzAV +BgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29t +MS8wLQYDVQQDEyZEaWdpQ2VydCBWZXJpZmllZCBNYXJrIEludGVybWVkaWF0ZSBD +QTAeFw0yMDA3MzAwMDAwMDBaFw0yMTAxMjUxMjAwMDBaMIIBDjEdMBsGA1UEDxMU +UHJpdmF0ZSBPcmdhbml6YXRpb24xEzARBgsrBgEEAYI3PAIBAxMCVVMxGTAXBgsr +BgEEAYI3PAIBAhMIRGVsYXdhcmUxEDAOBgNVBAUTBzM2MzMwMTkxGTAXBgNVBAkT +EDEwMDAgVyBNYXVkZSBBdmUxDjAMBgNVBBETBTk0MDg1MQswCQYDVQQGEwJVUzET +MBEGA1UECBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJU3Vubnl2YWxlMR0wGwYDVQQK +ExRMaW5rZWRJbiBDb3Jwb3JhdGlvbjESMBAGCisGAQQBg55fAQMTAlVTMRcwFQYK +KwYBBAGDnl8BBBMHNTY3NTczOTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAOCl7WccAcvSaf5+pNsV82VjFuwdzEwjDYESZmIuurz95e+JtJZst/M3Hw90 +YxKSDV4LdaVFAogXy2F+Npit1KhbBEb8vbBkm4LJ3iM8teE/10JugLyxrcVi3LSj +iKHs+rqxcTJsVYoR+CuPLuAbu4xKi+xQ4tVafrFd0Y21n6OL8nB2SRISHF58kRXq +UDW/NippF1AhcdCc5L5EmXFPCpyWfv+UXgTj9i+/I9AWUC3diHckb5NXd/wS7Jmq +5FE0uixRGTixI5a9uZr0jasTtfhlVtvqFyDmzARB/q9IU0eXm3dtcCJISIXGum6o +yCFUk8pyYsGd/M5Fyw7zbmEqsucCAwEAAaOCBgswggYHMB8GA1UdIwQYMBaAFOsN +zmX0UnV7TbPUsz0w41AYq+NuMB0GA1UdDgQWBBSkuL0+t0wu/+y2xkUY/FOSsiuV +ODAXBgNVHREEEDAOggxsaW5rZWRpbi5jb20wEwYDVR0lBAwwCgYIKwYBBQUHAx8w +gZkGA1UdHwSBkTCBjjBFoEOgQYY/aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp +Z2lDZXJ0VmVyaWZpZWRNYXJrSW50ZXJtZWRpYXRlQ0EuY3JsMEWgQ6BBhj9odHRw +Oi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRWZXJpZmllZE1hcmtJbnRlcm1l +ZGlhdGVDQS5jcmwwUAYDVR0gBEkwRzA3BglghkgBhv1sCgEwKjAoBggrBgEFBQcC +ARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAMBgorBgEEAYOeXwEBMF4G +CCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2VydHMuZGlnaWNl +cnQuY29tL0RpZ2lDZXJ0VmVyaWZpZWRNYXJrSW50ZXJtZWRpYXRlQ0EuY3J0MAwG +A1UdEwEB/wQCMAAwggOsBggrBgEFBQcBDASCA54wggOaooIDlqCCA5IwggOOMIID +ijCCA4YWDWltYWdlL3N2Zyt4bWwwIzAhMAkGBSsOAwIaBQAEFGckN8uhuoNkcXXh +wRAm7wkz4JRLMIIDThaCA0pkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LEg0c0lB +QUFBQUFBQUNsMVR5MjdiTUJDODl5c0k5VXlhKytLanNITElJVWlCRnVqSjkxUlJR +cUdLSGNTQ25PYnJ1NVRVQkMwTVNKN2w3SEozZHJRL3o0OW03bC9PdytuWU51Q3dN +YTlQNC9IY05tV2Fuci9zZHBmTHhWM0luVjRlZCtpOTN5bS9NWmZoZmlwdEUySm9U +T21IeHpKdFlCNzZ5L1hwdFcyODhVWWpab24rdkR2M1AxNU9EOFBZdDgwMEhIL2I1 +M056dForR2FleXZ2ZzNIWC8zOTErTit0K0w5ODkxVWpITEh0dm5zWTB6WFd1Ryti +YjVMQkJkek5vR2NSTHdGenk1NzdpeWk4eHlzUXdETDNnR2dnZWlZWTBYczJWQjJu +T0ZRODFQb0hBcVltaFBGUUhLRXVSTDBIdk5CbHhBTGgrQlNsazZwb0R3VXJnUU1i +R3QxcVVBazJwVjlBRS9PQitxc0k1S2xwUlN0cG5GSWxSSlo3RWVDZHZQVzdQNmQ5 +T2JtWmgwVFdGd01ZakJrNXlHVnBFc0pNbU1BUjVHS1hmRmhPMzU3cWwwbnNFRGVl +Y29kQmcyVFZVblFjSFJBYkJBMHRDTGRpTDQ4OHRrdVVkZzRkbzF1SExzRlY0cjlD +Q3BsMXRJeDZKemVnMFZ4T2RGeUFTODhMMm03WU1sNnl1QkN5bVpycnNUb2N1YVpS +S094YUZhUXV5UTZGNXJ0cGI3UnUxd1N0SXdPcVV2NkZORjRWdFVqR1dGdEp2NUZn +S3p5d3d4TWprUnVXZFFBZEdEZEJqSjIzdXJGVEdvT0liU3FHRUZhNjc0RGJUQkg0 +eTBuOVFBWjBqWHE2WVpDckhZNmlGYlI3cXYwa04rVi8zK0RIdXB2WFdLQXJNcWdF +YThWTXBXbytXRkdVcURPVWkxVXh3M3BJR20yUzZ4VXgyU0FlVUc2V2xGVDUvVnN0 +S3FkVitlcWtwNHFTTHFnQlJTcmpnRzFTTlRCb0pETE10ZWpHTWEwT0hyNVg3Q3VZ +cXlPaC9WMFhwNjNJWUxTMTl4YUtlZGx0UHFsWDMzNkEwYlJhNW9nQkFBQTCBigYK +KwYBBAHWeQIEAgR8BHoAeAB2AFVZU64wlgCAbNLrUgimyZ6TGCisEFa0QhxVNhVM +X3WsAAABc6DTF3wAAAQDAEcwRQIgRsnN1miYsyCMT234C14MaMgSAgKHXmc7RrBM +a/1ovTMCIQCOc/THDvltzhZrtnoRSbjc2EYp57A0VVHvduQPa7FKBDANBgkqhkiG +9w0BAQsFAAOCAgEA8UQt5jcUeOaDkhvbLq380Oq1Jy8Vr1BO1GPisn20KRCz/NvE +56f8hhmZlZ1xXfOM+JCaGQnwVwcRBQtLQ/+6bmeT8/WM3hf9A5rP0g0ZxvaAlQtu +e6UjvgnNx02QOKNPrmxN0rW8s24kUi0OAf1ump3SY5Ab+S+ywRG7Ah+3qch+FwA8 +CYau9TgV5kvfYDRULBM84EeFhsPcwT+YJ5u7RvkGQobqNao21Ti5tupiks/9NzI8 +splBS77Z6bPdFGvZ7pJdXiiDB2+SZdyv8iqDFM6mKRbOcuwAHcTY2zVhcS46H7SO +8OU7L/2y0XQB1rMtQDarCKwdAcsAb2e+N8mYQ0glQX4k41Sf4saMXsU1EjnOCUas +YxvVgJRD+fe4JWf8EO59fElzkrQsT3guBIzV5Kg1dYaCHngCYQIakjKQM0eKxZ3d +vn4648A0vXynhJUThOSxN4jbvVA5uYYHqHDMjJtkBPDA7HtLSIxRNattshOAoeC5 +LMszAsL9th/WoXkAa2lTs2kashOHEpx+ncGactrL8tu7dvU01Yk6yP1QAjFEo1Nt +8umUG7jQQIuquB2ry4qzFuQvKpbNQZ//9RsSmq1nni+DEKd/S63N7T8M0FpioLVm +Z2OXFTCG5ORjPUOyMGjxzjEPZWmTOG+gqNOc0HKXbuBAsGZbK4dind+YdZE= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIHLzCCBRegAwIBAgIQDZXVhKBTvJ0ZjW6meNxHhTANBgkqhkiG9w0BAQsFADCB +iDELMAkGA1UEBhMCVVMxDTALBgNVBAgTBFV0YWgxDTALBgNVBAcTBExlaGkxFzAV +BgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29t +MScwJQYDVQQDEx5EaWdpQ2VydCBWZXJpZmllZCBNYXJrIFJvb3QgQ0EwHhcNMTkw +OTIzMTIyNTQyWhcNMzQwOTIzMTIyNTQyWjCBkDELMAkGA1UEBhMCVVMxDTALBgNV +BAgTBFV0YWgxDTALBgNVBAcTBExlaGkxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu +MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBW +ZXJpZmllZCBNYXJrIEludGVybWVkaWF0ZSBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAPfhMd+2RBjNZpqq0GVUF0kKK72fQxhJbnxgYv7GFpmi69sX +dgeqH9RE07ShTDtkLks9G/GuiXsLEmjSCBDDTwfB3hpbdrZsNQFWOIRHXmU8ykuP +bCd/HVRZGULeWvbt93deEB1el5MpxP9Fs3LKjw7xytbuM/nkGJ4D2R1IHC953FoU +4BYsp+8VB1+7Gh8eKVh+HpmBeEfIB+cuq4FpZKxi+F5J7UjW5yO4SuDcTF4AMY0J +DPuKIy+Og6laNOtDS30P1CUu1N6BwLMYTbeqyYHJ7B3kLWsDceGMqIcxo8zrk1rT +sJctcXHXhB4k2PnVxt8qkQjg2Lo++kU0dFSUyrzvg3WrGypv9vphWMI+vmCjmu2K +0BZLZ4nKshoTX495R6pGbsecGaaGgACB/1NcGI7PVp7spY2ytLvHHZ+Hh446BGFy +AdM8lZCMXEhNftP8RRRVr8mwHHzyIa86r4yk0SkOlXUkNrGdTqqyMSDJ3W7DWGO/ +vCObzXiM0aq77ebD/0fE5LsZhEJYx7txF9NA1DoICgHp8zqF35i3UOp4+5IyJ8A9 +MjqYcX+LayH06B45bMgTHLmJKcsRYvXAtu+nIvIL0fk4+Ea7kJ7MNx5/udS89b2f +vSFC4hmA3OBDiJqGmldwqJL/HP7RI8O54yj10vpiH4obDo8QgfhKSVoX5HwDAgMB +AAGjggGJMIIBhTAdBgNVHQ4EFgQU6w3OZfRSdXtNs9SzPTDjUBir424wHwYDVR0j +BBgwFoAU7G8ipLME4sFjh+Z3Y+pGaU7u/OswDgYDVR0PAQH/BAQDAgGGMBMGA1Ud +JQQMMAoGCCsGAQUFBwMfMBIGA1UdEwEB/wQIMAYBAf8CAQAwfAYIKwYBBQUHAQEE +cDBuMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYB +BQUHMAKGOmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFZlcmlm +aWVkTWFya1Jvb3RDQS5jcnQwSAYDVR0fBEEwPzA9oDugOYY3aHR0cDovL2NybDMu +ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VmVyaWZpZWRNYXJrUm9vdENBLmNybDBCBgNV +HSAEOzA5MDcGCWCGSAGG/WwKATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5k +aWdpY2VydC5jb20vQ1BTMA0GCSqGSIb3DQEBCwUAA4ICAQA6v371ixHAA9WyGlFr ++RvmmqkZZg9pf6+j5sKImeTFAHfYz3TJa2wmDRpZxSRYy9VUFOMPVDEavsJ2i5Ua +jEpkJ/7VHbX60joKBxQHKCbMpbwGen6pTXRaeE6CET2zCMbyiIqT2E6OiBZL8cWT +sgLbdhVKspoOi+c3JwTR4khR24J9IQVxK90Nq3zeciYgBvM3G+ZJtZgkA58CRdex +xVO6O57bwe4ti4rlRgWOGgAFpFrJSD1jqhhHD3MWg17NI4k0ciBPoDHHBAI8hiqg +jPM+y6aEGww7BFSfkp5tl/Aq9uGXCwxNLOc3UlUd8Cc0qH1KfkvjrumVMmJhsk9I +88YefbCuGPZ5Q8V2LIz7LrNDh0VRq/HSENXn1sBGlAFahgUTk/cWJ8nKA+8mHMlE +NGmx205Rtbf9lVL1CbH3QFwlvGEfqoMXw6G9JW2hFQVTKpBKuzjQw43CEw12lstP +oa96ixNAXXVGJsdKpYCqTIWJ0x1DssvG2shvzdHxawvYQ3C+/jaEoQ6bxSIdanI2 +NMtBdy9Q0TjDc7uf/eaUYKkP4wskNc1Os23oHllFHVm++8wdDltNulc7B1TXIQ+2 +oD5EoULMFSVUHX8gtyd463GgOQtBDwf3aZ4Xe6eDrhdfI/4IW098kVcg+qFO841L +qzFkAKWjJj4KjfrbZX4C0Spfxw== +-----END CERTIFICATE-----'; + + $x509 = new File_X509(); + $r = $x509->loadX509($a); + + $this->assertFalse($r); + } } From a72e0e7456cec3310c1a39e23f5cd362634c39ff Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 29 Oct 2020 21:35:59 -0500 Subject: [PATCH 15/69] Tests/X509: update unit test for 2.0 branch --- tests/Unit/File/X509/X509Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/File/X509/X509Test.php b/tests/Unit/File/X509/X509Test.php index 61f025470..67b996a52 100644 --- a/tests/Unit/File/X509/X509Test.php +++ b/tests/Unit/File/X509/X509Test.php @@ -921,7 +921,7 @@ public function testMultiCertPEM() qzFkAKWjJj4KjfrbZX4C0Spfxw== -----END CERTIFICATE-----'; - $x509 = new File_X509(); + $x509 = new X509(); $r = $x509->loadX509($a); $this->assertFalse($r); From b2ae60f0a91adac5eedd190cbfe4bd6b3df327e5 Mon Sep 17 00:00:00 2001 From: "Thomas A. Hirsch" Date: Wed, 21 Oct 2020 18:06:52 +0100 Subject: [PATCH 16/69] $progressCallback should be called after a specific amount of data has been received and not, if its just requested, as the requested packets might be more as the available and received data. --- phpseclib/Net/SFTP.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index 525f98ac9..a94215b8a 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -2309,9 +2309,6 @@ function get($remote_file, $local_file = false, $offset = 0, $length = -1, $prog } $packet = null; $read+= $packet_size; - if (is_callable($progressCallback)) { - call_user_func($progressCallback, $read); - } $i++; } @@ -2341,6 +2338,9 @@ function get($remote_file, $local_file = false, $offset = 0, $length = -1, $prog } else { fputs($fp, $temp); } + if (is_callable($progressCallback)) { + call_user_func($progressCallback, $offset); + } $temp = null; break; case NET_SFTP_STATUS: From d9196e4a83b38ff5238d4489f5cc069dbf0c5b4f Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 2 Nov 2020 19:54:11 -0600 Subject: [PATCH 17/69] X509: fix unit test for multi-cert pems --- tests/Unit/File/X509/X509Test.php | 191 ++++++++++++++---------------- 1 file changed, 92 insertions(+), 99 deletions(-) diff --git a/tests/Unit/File/X509/X509Test.php b/tests/Unit/File/X509/X509Test.php index 93434cbe3..8b86a6376 100644 --- a/tests/Unit/File/X509/X509Test.php +++ b/tests/Unit/File/X509/X509Test.php @@ -754,107 +754,100 @@ public function testRandomString() public function testMultiCertPEM() { $a = '-----BEGIN CERTIFICATE----- -MIILODCCCSCgAwIBAgIQDh0LGipJ++wxFLj8X5MXKDANBgkqhkiG9w0BAQsFADCB -kDELMAkGA1UEBhMCVVMxDTALBgNVBAgTBFV0YWgxDTALBgNVBAcTBExlaGkxFzAV -BgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29t -MS8wLQYDVQQDEyZEaWdpQ2VydCBWZXJpZmllZCBNYXJrIEludGVybWVkaWF0ZSBD -QTAeFw0yMDA3MzAwMDAwMDBaFw0yMTAxMjUxMjAwMDBaMIIBDjEdMBsGA1UEDxMU -UHJpdmF0ZSBPcmdhbml6YXRpb24xEzARBgsrBgEEAYI3PAIBAxMCVVMxGTAXBgsr -BgEEAYI3PAIBAhMIRGVsYXdhcmUxEDAOBgNVBAUTBzM2MzMwMTkxGTAXBgNVBAkT -EDEwMDAgVyBNYXVkZSBBdmUxDjAMBgNVBBETBTk0MDg1MQswCQYDVQQGEwJVUzET -MBEGA1UECBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJU3Vubnl2YWxlMR0wGwYDVQQK -ExRMaW5rZWRJbiBDb3Jwb3JhdGlvbjESMBAGCisGAQQBg55fAQMTAlVTMRcwFQYK -KwYBBAGDnl8BBBMHNTY3NTczOTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAOCl7WccAcvSaf5+pNsV82VjFuwdzEwjDYESZmIuurz95e+JtJZst/M3Hw90 -YxKSDV4LdaVFAogXy2F+Npit1KhbBEb8vbBkm4LJ3iM8teE/10JugLyxrcVi3LSj -iKHs+rqxcTJsVYoR+CuPLuAbu4xKi+xQ4tVafrFd0Y21n6OL8nB2SRISHF58kRXq -UDW/NippF1AhcdCc5L5EmXFPCpyWfv+UXgTj9i+/I9AWUC3diHckb5NXd/wS7Jmq -5FE0uixRGTixI5a9uZr0jasTtfhlVtvqFyDmzARB/q9IU0eXm3dtcCJISIXGum6o -yCFUk8pyYsGd/M5Fyw7zbmEqsucCAwEAAaOCBgswggYHMB8GA1UdIwQYMBaAFOsN -zmX0UnV7TbPUsz0w41AYq+NuMB0GA1UdDgQWBBSkuL0+t0wu/+y2xkUY/FOSsiuV -ODAXBgNVHREEEDAOggxsaW5rZWRpbi5jb20wEwYDVR0lBAwwCgYIKwYBBQUHAx8w -gZkGA1UdHwSBkTCBjjBFoEOgQYY/aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp -Z2lDZXJ0VmVyaWZpZWRNYXJrSW50ZXJtZWRpYXRlQ0EuY3JsMEWgQ6BBhj9odHRw -Oi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRWZXJpZmllZE1hcmtJbnRlcm1l -ZGlhdGVDQS5jcmwwUAYDVR0gBEkwRzA3BglghkgBhv1sCgEwKjAoBggrBgEFBQcC -ARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAMBgorBgEEAYOeXwEBMF4G -CCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2VydHMuZGlnaWNl -cnQuY29tL0RpZ2lDZXJ0VmVyaWZpZWRNYXJrSW50ZXJtZWRpYXRlQ0EuY3J0MAwG -A1UdEwEB/wQCMAAwggOsBggrBgEFBQcBDASCA54wggOaooIDlqCCA5IwggOOMIID -ijCCA4YWDWltYWdlL3N2Zyt4bWwwIzAhMAkGBSsOAwIaBQAEFGckN8uhuoNkcXXh -wRAm7wkz4JRLMIIDThaCA0pkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LEg0c0lB -QUFBQUFBQUNsMVR5MjdiTUJDODl5c0k5VXlhKytLanNITElJVWlCRnVqSjkxUlJR -cUdLSGNTQ25PYnJ1NVRVQkMwTVNKN2w3SEozZHJRL3o0OW03bC9PdytuWU51Q3dN -YTlQNC9IY05tV2Fuci9zZHBmTHhWM0luVjRlZCtpOTN5bS9NWmZoZmlwdEUySm9U -T21IeHpKdFlCNzZ5L1hwdFcyODhVWWpab24rdkR2M1AxNU9EOFBZdDgwMEhIL2I1 -M056dForR2FleXZ2ZzNIWC8zOTErTit0K0w5ODkxVWpITEh0dm5zWTB6WFd1Ryti -YjVMQkJkek5vR2NSTHdGenk1NzdpeWk4eHlzUXdETDNnR2dnZWlZWTBYczJWQjJu -T0ZRODFQb0hBcVltaFBGUUhLRXVSTDBIdk5CbHhBTGgrQlNsazZwb0R3VXJnUU1i -R3QxcVVBazJwVjlBRS9PQitxc0k1S2xwUlN0cG5GSWxSSlo3RWVDZHZQVzdQNmQ5 -T2JtWmgwVFdGd01ZakJrNXlHVnBFc0pNbU1BUjVHS1hmRmhPMzU3cWwwbnNFRGVl -Y29kQmcyVFZVblFjSFJBYkJBMHRDTGRpTDQ4OHRrdVVkZzRkbzF1SExzRlY0cjlD -Q3BsMXRJeDZKemVnMFZ4T2RGeUFTODhMMm03WU1sNnl1QkN5bVpycnNUb2N1YVpS -S094YUZhUXV5UTZGNXJ0cGI3UnUxd1N0SXdPcVV2NkZORjRWdFVqR1dGdEp2NUZn -S3p5d3d4TWprUnVXZFFBZEdEZEJqSjIzdXJGVEdvT0liU3FHRUZhNjc0RGJUQkg0 -eTBuOVFBWjBqWHE2WVpDckhZNmlGYlI3cXYwa04rVi8zK0RIdXB2WFdLQXJNcWdF -YThWTXBXbytXRkdVcURPVWkxVXh3M3BJR20yUzZ4VXgyU0FlVUc2V2xGVDUvVnN0 -S3FkVitlcWtwNHFTTHFnQlJTcmpnRzFTTlRCb0pETE10ZWpHTWEwT0hyNVg3Q3VZ -cXlPaC9WMFhwNjNJWUxTMTl4YUtlZGx0UHFsWDMzNkEwYlJhNW9nQkFBQTCBigYK -KwYBBAHWeQIEAgR8BHoAeAB2AFVZU64wlgCAbNLrUgimyZ6TGCisEFa0QhxVNhVM -X3WsAAABc6DTF3wAAAQDAEcwRQIgRsnN1miYsyCMT234C14MaMgSAgKHXmc7RrBM -a/1ovTMCIQCOc/THDvltzhZrtnoRSbjc2EYp57A0VVHvduQPa7FKBDANBgkqhkiG -9w0BAQsFAAOCAgEA8UQt5jcUeOaDkhvbLq380Oq1Jy8Vr1BO1GPisn20KRCz/NvE -56f8hhmZlZ1xXfOM+JCaGQnwVwcRBQtLQ/+6bmeT8/WM3hf9A5rP0g0ZxvaAlQtu -e6UjvgnNx02QOKNPrmxN0rW8s24kUi0OAf1ump3SY5Ab+S+ywRG7Ah+3qch+FwA8 -CYau9TgV5kvfYDRULBM84EeFhsPcwT+YJ5u7RvkGQobqNao21Ti5tupiks/9NzI8 -splBS77Z6bPdFGvZ7pJdXiiDB2+SZdyv8iqDFM6mKRbOcuwAHcTY2zVhcS46H7SO -8OU7L/2y0XQB1rMtQDarCKwdAcsAb2e+N8mYQ0glQX4k41Sf4saMXsU1EjnOCUas -YxvVgJRD+fe4JWf8EO59fElzkrQsT3guBIzV5Kg1dYaCHngCYQIakjKQM0eKxZ3d -vn4648A0vXynhJUThOSxN4jbvVA5uYYHqHDMjJtkBPDA7HtLSIxRNattshOAoeC5 -LMszAsL9th/WoXkAa2lTs2kashOHEpx+ncGactrL8tu7dvU01Yk6yP1QAjFEo1Nt -8umUG7jQQIuquB2ry4qzFuQvKpbNQZ//9RsSmq1nni+DEKd/S63N7T8M0FpioLVm -Z2OXFTCG5ORjPUOyMGjxzjEPZWmTOG+gqNOc0HKXbuBAsGZbK4dind+YdZE= +MIIL/DCCCuSgAwIBAgIQNC96aabFWNAAAAAAXBAmjjANBgkqhkiG9w0BAQsFADCB +uTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsT +H1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAy +MDE4IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEtMCsG +A1UEAxMkRW50cnVzdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBWTUMxMB4XDTIw +MDUxNDE4NDgwNloXDTIwMTEwOTE5MTgwNFowggE+MQ4wDAYDVQQREwU5NTEyNTEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCFNhbiBK +b3NlMRowGAYDVQQJExEyMDY1IEhhbWlsdG9uIEF2ZTETMBEGCysGAQQBgjc8AgED +EwJVUzEZMBcGCysGAQQBgjc8AgECEwhEZWxhd2FyZTESMBAGA1UEChMJZUJheSBJ +bmMuMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4GA1UEBRMHMjg3 +MTM1MjEXMBUGCisGAQQBg55fAQQTBzQ0MDg0MjMxEjAQBgorBgEEAYOeXwEDEwJV +UzElMCMGCisGAQQBg55fAQITFWh0dHBzOi8vd3d3LnVzcHRvLmdvdjESMBAGA1UE +AxMJZUJheSBJbmMuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmaPd +qOlOyWc8n6MKXI8eIrKgketOTdxuoW1RzfmXB924j2WBzRqNFqcISCYN3a0VpMe3 +AqG9A+YyCWCJWmXdTZkAz3LeJCPTqbzf2nigXYfJX1KFhK96eVVcbirIhRtS4O5G +qYw8v4rokp8YFg/W+c+80i/egNYr4VZCC5zawaYBwtgMkUomSXqz3Yv7JkfZsv5q +pSLD5aO2wSIPjCiPpYzxDO2b/kX1goV6Oyvd4PTmvYteER01cx37dkj2mf/bTdrB +nHAyOF8+84ItHiZjHpi7MIxcmvi40wcPszPsx2GKyQ1604TVR6p+ZT9Gt4qMaJ7h +I7FQCl2dUOEzSF/4NwIDAQABo4IHdjCCB3IwggVkBggrBgEFBQcBDASCBVYwggVS +ooIFTqCCBUowggVGMIIFQjCCBT4WDWltYWdlL3N2Zyt4bWwwMzAxMA0GCWCGSAFl +AwQCAQUABCDQkSARaDrob8re0CIWy2UxJ97L55pY729ITDKZYPUWLTCCBPYWggTy +ZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxINHNJQUFBQUFBQUFBSFZWNzIvYk5o +RDluQUw3SDFqdFV3R1JKaWxLb2x5N1JiTTJUWUVWR0xBdDN4MWFrNHhva21FcHR0 +T2kvM3Z2SFpVbXdGWUR0czZQOStQZHU2TzllbnYrdHhQSCtqRHVobjZkR0tVVFVm +ZGgyTzc2WnAzOC9kZVY5TW5iTjcrOFdMMlVVbnlzKy9xd21ZYkRVcnpiRHJlMStO +UjE5K1BFa0xCV1VYUXEvcno1S0Q2Yzk4TmhFbjkwOTQzODFBdkY0RTBzc2hTRjBs +cGMzdSs2cmRDdmhKQVMrY2RqODV5R1NRUVI2OGQxMGs3VGZybFluRTRuZGNyVWNH +Z1dWbXU5SVAvWlpYbnVkdjNkL3ptYXFxb1dmRXF1NjBUdno0bDRtSi9IWFgyNkhJ +QUtMYXozZUNkaW5CNjZlcDNVL2VhMnErWHRKdHcxaCtHKzN5NzcraVNlZWI3bTJz +dHh2d25rdmovVVkzMDQxZ2szZ2hSaWV0alR3VlNmcDBVWVJ4eGNxSEhTWC8vWmRk +M3kxeXQrdmY0V1VmT0k1dSt1dEgxRTdZeCt5RE9iK1VjMG0xR3RDL2YraDYrYlVW +OWNlbE1DWFMyWUJ3ZzFZcmRkSjVkM0RiTllIZW93aWRCdFJ0S1dHQ1hpdE50TzdU +cmgvdHQ2MTdSVC9MSkE4S0o1U3ZINzBBd3hCOENMaTlWK003VlBxV2hrNVBUWmxG +cVoxTGhDWlVGNlZhWmFaZEk0WUtxS1JxbUtvTk9NempLeXk5Um9sY01JQnFFNk5i +bHlNaWVNRFFySk95Mk5vTmR2cHZUS2NYYWJtdkxKK2xIemkvaHNLc094WGxrcVk1 +VlBjWXA4UkNYMUxiR3FndFRLU2l0Qmppanhzd2hrZW5Ja21sb1ZvQ21OWjJvRmln +ZHBESklCTkpMcVJzTmtLZzlhY2hNZUlXalJFc2pNUTh4dTZLamtwN0YwUWdaYW9y +Q1NhdWF5UWsxTEhNaUlwZkpZQ2Z4ZHpGMm92SVZsZ2tGVjlHSk1qS3RTYStCR1Zp +RE1rWWJXcE15RENoYkszTEFhWDNpbS94bWNqWVB6Sld0b1NEWGk1MlJGTGZySWls +cU1WcEFsWkFUZ1VnWWRwS2FUYTRTVCtEbEdidHlqWkZHVUV1UlRDcXJvaUJxREZY +THNCbWJ2cFVVdjBLVlVycTB3SFFOWDNoeDB4L1V0ZTVGRnA2Q3FwWFdrYVVWVTJj +QVBVS3hKckdobUZKSFJidEJadEFJR0JXVXlIbW1jVVVwUitaSGUxeUQrRTRHeWVi +TXR4bThLUXpyUUN2R2lra1lPRDRoTWhTdmlVV0E2L0RIRGtwM3BLNm5nOEFBYXQx +a1h5Smc3OUJnN1JmYjBXU1dTdENxeDRqcFhCV2xUZEJvdG1ZQ1dDY0lPV01rZTJO +Y1NmV3BXbGpyRER0dG8wSWVQNnBDR0VJMDdoMmdsV3pUWk9GZkNzTG94bWNNRjRy +VjF1Q0s0R3kyQ0EyNVB4bGU3NFB2Rm0zdkRKSDhpb29zaVdzZUxpeFk2YVVtdmxJ +VFBlTEhMeml1V3pIWThiT2xvb2kzNjZ3eGt6a2dndGlTc2E4NDBGNXQvcCtaUCtt +OTQ4eDB2cWU2eTJRWUFBQT09MB8GA1UdEQQYMBaCCGViYXkuY29tggplYmF5LmNv +LnVrMIGJBgorBgEEAdZ5AgQCBHsEeQB3AHUAVYHUwhaQNgFK6gubVzxT8MDkOHhw +JQgXL6OqHQcT0wwAAAFyFJ9ciQAABAMARjBEAiBI40aXqg6PJiDDf8vz4RP9cKay +kBSUjs5oGiPJlBmJCAIgAeJzF/JVCiXbjgxPL9QTjYe+wn1DHqhzsjBWEoKYiZYw +EwYDVR0lBAwwCgYIKwYBBQUHAx8wDgYDVR0PAQH/BAQDAgeAMGYGCCsGAQUFBwEB +BFowWDAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMQYIKwYB +BQUHMAKGJWh0dHA6Ly9haWEuZW50cnVzdC5uZXQvdm1jMS1jaGFpbi5jZXIwMgYD +VR0fBCswKTAnoCWgI4YhaHR0cDovL2NybC5lbnRydXN0Lm5ldC92bWMxY2EuY3Js +ME8GA1UdIARIMEYwNgYKYIZIAYb6bAoBCzAoMCYGCCsGAQUFBwIBFhpodHRwOi8v +d3d3LmVudHJ1c3QubmV0L3JwYTAMBgorBgEEAYOeXwEBMB8GA1UdIwQYMBaAFIu2 +OXbQNJCmP2LhZOo+vPR8RqFzMB0GA1UdDgQWBBRMIHPmuhcI/NyAybe3LKA1gblR +/zAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAjBJ/SPTRn8/kjfhLOBnhe +5QPkifZjsLqHJyWUCUoqFfKKazq6T6STMLl0drbsVWyc0Mh6sUSgUwh4Hn0DmGHu +ghDF5JCtoPYUz+G7l1BsAlGOvYd0H9ZcmgvfhiIjpn98Go4O/gXlK1oCd/jMIOMH +bOVB9BLb5ppf9uU2TCxTY67qUx5YylT3bfF4TVM0ZOYERQSZNByRNcFaku+FUpzU +JHHoDqokPw+0AFG2NgPiNhOg/nPh/pEWUYj5qjqgXP/hEvXerSFhdp6sN2OxES7p +GkO+J90tl9B7UQVtTO1bgGq98HIRdfusGzK5IG2MMT1CtPYR8S01mkf7KMiHK1zb -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIHLzCCBRegAwIBAgIQDZXVhKBTvJ0ZjW6meNxHhTANBgkqhkiG9w0BAQsFADCB -iDELMAkGA1UEBhMCVVMxDTALBgNVBAgTBFV0YWgxDTALBgNVBAcTBExlaGkxFzAV -BgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29t -MScwJQYDVQQDEx5EaWdpQ2VydCBWZXJpZmllZCBNYXJrIFJvb3QgQ0EwHhcNMTkw -OTIzMTIyNTQyWhcNMzQwOTIzMTIyNTQyWjCBkDELMAkGA1UEBhMCVVMxDTALBgNV -BAgTBFV0YWgxDTALBgNVBAcTBExlaGkxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu -MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBW -ZXJpZmllZCBNYXJrIEludGVybWVkaWF0ZSBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAPfhMd+2RBjNZpqq0GVUF0kKK72fQxhJbnxgYv7GFpmi69sX -dgeqH9RE07ShTDtkLks9G/GuiXsLEmjSCBDDTwfB3hpbdrZsNQFWOIRHXmU8ykuP -bCd/HVRZGULeWvbt93deEB1el5MpxP9Fs3LKjw7xytbuM/nkGJ4D2R1IHC953FoU -4BYsp+8VB1+7Gh8eKVh+HpmBeEfIB+cuq4FpZKxi+F5J7UjW5yO4SuDcTF4AMY0J -DPuKIy+Og6laNOtDS30P1CUu1N6BwLMYTbeqyYHJ7B3kLWsDceGMqIcxo8zrk1rT -sJctcXHXhB4k2PnVxt8qkQjg2Lo++kU0dFSUyrzvg3WrGypv9vphWMI+vmCjmu2K -0BZLZ4nKshoTX495R6pGbsecGaaGgACB/1NcGI7PVp7spY2ytLvHHZ+Hh446BGFy -AdM8lZCMXEhNftP8RRRVr8mwHHzyIa86r4yk0SkOlXUkNrGdTqqyMSDJ3W7DWGO/ -vCObzXiM0aq77ebD/0fE5LsZhEJYx7txF9NA1DoICgHp8zqF35i3UOp4+5IyJ8A9 -MjqYcX+LayH06B45bMgTHLmJKcsRYvXAtu+nIvIL0fk4+Ea7kJ7MNx5/udS89b2f -vSFC4hmA3OBDiJqGmldwqJL/HP7RI8O54yj10vpiH4obDo8QgfhKSVoX5HwDAgMB -AAGjggGJMIIBhTAdBgNVHQ4EFgQU6w3OZfRSdXtNs9SzPTDjUBir424wHwYDVR0j -BBgwFoAU7G8ipLME4sFjh+Z3Y+pGaU7u/OswDgYDVR0PAQH/BAQDAgGGMBMGA1Ud -JQQMMAoGCCsGAQUFBwMfMBIGA1UdEwEB/wQIMAYBAf8CAQAwfAYIKwYBBQUHAQEE -cDBuMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYB -BQUHMAKGOmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFZlcmlm -aWVkTWFya1Jvb3RDQS5jcnQwSAYDVR0fBEEwPzA9oDugOYY3aHR0cDovL2NybDMu -ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VmVyaWZpZWRNYXJrUm9vdENBLmNybDBCBgNV -HSAEOzA5MDcGCWCGSAGG/WwKATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5k -aWdpY2VydC5jb20vQ1BTMA0GCSqGSIb3DQEBCwUAA4ICAQA6v371ixHAA9WyGlFr -+RvmmqkZZg9pf6+j5sKImeTFAHfYz3TJa2wmDRpZxSRYy9VUFOMPVDEavsJ2i5Ua -jEpkJ/7VHbX60joKBxQHKCbMpbwGen6pTXRaeE6CET2zCMbyiIqT2E6OiBZL8cWT -sgLbdhVKspoOi+c3JwTR4khR24J9IQVxK90Nq3zeciYgBvM3G+ZJtZgkA58CRdex -xVO6O57bwe4ti4rlRgWOGgAFpFrJSD1jqhhHD3MWg17NI4k0ciBPoDHHBAI8hiqg -jPM+y6aEGww7BFSfkp5tl/Aq9uGXCwxNLOc3UlUd8Cc0qH1KfkvjrumVMmJhsk9I -88YefbCuGPZ5Q8V2LIz7LrNDh0VRq/HSENXn1sBGlAFahgUTk/cWJ8nKA+8mHMlE -NGmx205Rtbf9lVL1CbH3QFwlvGEfqoMXw6G9JW2hFQVTKpBKuzjQw43CEw12lstP -oa96ixNAXXVGJsdKpYCqTIWJ0x1DssvG2shvzdHxawvYQ3C+/jaEoQ6bxSIdanI2 -NMtBdy9Q0TjDc7uf/eaUYKkP4wskNc1Os23oHllFHVm++8wdDltNulc7B1TXIQ+2 -oD5EoULMFSVUHX8gtyd463GgOQtBDwf3aZ4Xe6eDrhdfI/4IW098kVcg+qFO841L -qzFkAKWjJj4KjfrbZX4C0Spfxw== +MIIFJzCCBA+gAwIBAgIRALPSJ9szCF4XAAAAAFHTkx8wDQYJKoZIhvcNAQELBQAw +gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL +Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg +MjAwOSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw +BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy +MB4XDTE5MDQxNjE1NDU0M1oXDTMwMTExNjE2MTU0M1owgbkxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 +c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxOCBFbnRydXN0LCBJ +bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxLTArBgNVBAMTJEVudHJ1c3Qg +Q2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gVk1DMTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAOrOE7nPsgxnWadbz0f0D+btzyoxflXpbrILq358XJUn6MRq +k1m9BmK35G7bf0myFreyx60Rxcj+SvNRsraMd6FUzDuOccfK3PzbUktMKPxMBFh7 +R4/ZSNBMTko2fn7jhRPdFW9k0N+sSKtHwhu0xw8qzGg8oFRJgJgpxZv1zzrny43E +IuRiozQgg2J3ZzY4ova0s/BM/SLqdsGo+Jc68S7jsI6K7zKvw0FB3T6SWYxrBc1p +GsYvlmbCrDs3AP0Jcuske1GlLzFUpUkrvx4na9i4t7XhxVcwz3AuMRbU4nHDIc0w +tLG9Fm24xB31kSqybtpxEGC/oNybhCWjQDqYW58CAwEAAaOCASEwggEdMA4GA1Ud +DwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMBMGA1UdJQQMMAoGCCsGAQUF +BwMfMDsGA1UdIAQ0MDIwMAYEVR0gADAoMCYGCCsGAQUFBwIBFhpodHRwOi8vd3d3 +LmVudHJ1c3QubmV0L3JwYTAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0 +dHA6Ly9vY3NwLmVudHJ1c3QubmV0MDAGA1UdHwQpMCcwJaAjoCGGH2h0dHA6Ly9j +cmwuZW50cnVzdC5uZXQvZzJjYS5jcmwwHQYDVR0OBBYEFIu2OXbQNJCmP2LhZOo+ +vPR8RqFzMB8GA1UdIwQYMBaAFGpyJnrQHu995ztpUdRsjZ+QEmarMA0GCSqGSIb3 +DQEBCwUAA4IBAQBphKvXT6JDtmuQAhgH8nZ5Xo9LlymnCw5fiGpQJ13rsr2A2Jnl +1Z8poTwskM71kIImRctlYs2Q52Sgvd0egxvcPELQSL7BMGPU42BijWCEvnD8GZvU +/1x5pOg0F2SiEQ5ycmC9ADr2EskcbqMh2QMOOlNV4JfFjtUY1JCTviOWJ7O29wsE +aVMiY6EdrsN1hjqmwaxfzTVikM5m+jgUKWqK3U+56outMWziOfxcpo+Ur67hTglc +fTUKIRMTGhDMVFbwW5O2jINlBjGt5yAbhI/LnRwPvB99LFkISKX50c2NDEkOzEPp +mDaPrsUl15evEah6amsBfpQiWRbKpDLKs1kF -----END CERTIFICATE-----'; $x509 = new File_X509(); From 40b67bf93972c4da8f41417e28c678c72c8af5ca Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 21 Nov 2020 11:55:24 -0600 Subject: [PATCH 18/69] README: travis-ci.org -> travis-ci.com --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 402ca5eb8..679113c0b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # phpseclib - PHP Secure Communications Library -[![Build Status](https://travis-ci.org/phpseclib/phpseclib.svg?branch=1.0)](https://travis-ci.org/phpseclib/phpseclib) +[![Build Status](https://travis-ci.com/phpseclib/phpseclib.svg?branch=1.0)](https://travis-ci.com/phpseclib/phpseclib) ## Supporting phpseclib From 9547587cb79aa98082cd778fb52c5b6fe2834df6 Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 26 Nov 2020 10:45:53 +0000 Subject: [PATCH 19/69] SFTP: add stream to get method --- phpseclib/Net/SFTP.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index a94215b8a..dbd231376 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -2278,7 +2278,7 @@ function get($remote_file, $local_file = false, $offset = 0, $length = -1, $prog $res_offset = $stat['size']; } else { $res_offset = 0; - if ($local_file !== false) { + if ($local_file !== false && !is_callable($local_file) ) { $fp = fopen($local_file, 'wb'); if (!$fp) { return false; @@ -2288,7 +2288,7 @@ function get($remote_file, $local_file = false, $offset = 0, $length = -1, $prog } } - $fclose_check = $local_file !== false && !is_resource($local_file); + $fclose_check = $local_file !== false && !is_callable($local_file) && !is_resource($local_file); $start = $offset; $read = 0; @@ -2335,6 +2335,8 @@ function get($remote_file, $local_file = false, $offset = 0, $length = -1, $prog $offset+= strlen($temp); if ($local_file === false) { $content.= $temp; + } elseif (is_callable($local_file)) { + $local_file($temp); } else { fputs($fp, $temp); } From 0b20aff6ffb6bc84cf4cf09120c0f4971ffb2d2c Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 26 Nov 2020 21:08:49 -0600 Subject: [PATCH 20/69] SFTP: CS adjustments --- phpseclib/Net/SFTP.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index dbd231376..72eafcadd 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -2278,7 +2278,7 @@ function get($remote_file, $local_file = false, $offset = 0, $length = -1, $prog $res_offset = $stat['size']; } else { $res_offset = 0; - if ($local_file !== false && !is_callable($local_file) ) { + if ($local_file !== false && !is_callable($local_file)) { $fp = fopen($local_file, 'wb'); if (!$fp) { return false; @@ -2336,7 +2336,7 @@ function get($remote_file, $local_file = false, $offset = 0, $length = -1, $prog if ($local_file === false) { $content.= $temp; } elseif (is_callable($local_file)) { - $local_file($temp); + $local_file($temp); } else { fputs($fp, $temp); } From ee4af462b68f28cb632375926c67963c03b9dcb4 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 7 Dec 2020 08:00:44 -0600 Subject: [PATCH 21/69] SSH2: end connection faster for algorithm mismatch --- phpseclib/Net/SSH2.php | 73 +++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index d3cbc1f4a..9f3a82af0 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1552,6 +1552,39 @@ function _key_exchange($kexinit_payload_server = false) user_error('No compatible key exchange algorithms found'); return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); } + + $server_host_key_algorithm = $this->_array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms); + if ($server_host_key_algorithm === false) { + user_error('No compatible server host key algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + } + + $mac_algorithm_out = $this->_array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server); + if ($mac_algorithm_out === false) { + user_error('No compatible client to server message authentication algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + } + + $mac_algorithm_in = $this->_array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client); + if ($mac_algorithm_in === false) { + user_error('No compatible server to client message authentication algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + } + + $compression_algorithm_out = $this->_array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server); + if ($compression_algorithm_out === false) { + user_error('No compatible client to server compression algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + } + //$this->decompress = $compression_algorithm_out == 'zlib'; + + $compression_algorithm_in = $this->_array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_client_to_server); + if ($compression_algorithm_in === false) { + user_error('No compatible server to client compression algorithms found'); + return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + } + //$this->compress = $compression_algorithm_in == 'zlib'; + if (strpos($kex_algorithm, 'diffie-hellman-group-exchange') === 0) { $dh_group_sizes_packed = pack( 'NNN', @@ -1759,12 +1792,6 @@ function _key_exchange($kexinit_payload_server = false) $this->session_id = $this->exchange_hash; } - $server_host_key_algorithm = $this->_array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms); - if ($server_host_key_algorithm === false) { - user_error('No compatible server host key algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - switch ($server_host_key_algorithm) { case 'ssh-dss': $expected_key_format = 'ssh-dss'; @@ -1884,14 +1911,8 @@ function _key_exchange($kexinit_payload_server = false) $this->decrypt->decrypt(str_repeat("\0", 1536)); } - $mac_algorithm = $this->_array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server); - if ($mac_algorithm === false) { - user_error('No compatible client to server message authentication algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - $createKeyLength = 0; // ie. $mac_algorithm == 'none' - switch ($mac_algorithm) { + switch ($mac_algorithm_out) { case 'hmac-sha2-256': $this->hmac_create = new Crypt_Hash('sha256'); $createKeyLength = 32; @@ -1912,17 +1933,11 @@ function _key_exchange($kexinit_payload_server = false) $this->hmac_create = new Crypt_Hash('md5-96'); $createKeyLength = 16; } - $this->hmac_create->name = $mac_algorithm; - - $mac_algorithm = $this->_array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client); - if ($mac_algorithm === false) { - user_error('No compatible server to client message authentication algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } + $this->hmac_create->name = $mac_algorithm_out; $checkKeyLength = 0; $this->hmac_size = 0; - switch ($mac_algorithm) { + switch ($mac_algorithm_in) { case 'hmac-sha2-256': $this->hmac_check = new Crypt_Hash('sha256'); $checkKeyLength = 32; @@ -1948,7 +1963,7 @@ function _key_exchange($kexinit_payload_server = false) $checkKeyLength = 16; $this->hmac_size = 12; } - $this->hmac_check->name = $mac_algorithm; + $this->hmac_check->name = $mac_algorithm_in; $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id); while ($createKeyLength > strlen($key)) { @@ -1962,20 +1977,6 @@ function _key_exchange($kexinit_payload_server = false) } $this->hmac_check->setKey(substr($key, 0, $checkKeyLength)); - $compression_algorithm = $this->_array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server); - if ($compression_algorithm === false) { - user_error('No compatible client to server compression algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - //$this->decompress = $compression_algorithm == 'zlib'; - - $compression_algorithm = $this->_array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_client_to_server); - if ($compression_algorithm === false) { - user_error('No compatible server to client compression algorithms found'); - return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - } - //$this->compress = $compression_algorithm == 'zlib'; - return true; } From 266f16816ae2001d1e064535761b96e21da52fdc Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 12 Dec 2020 15:11:04 -0600 Subject: [PATCH 22/69] enable unit tests for PHP 8 / PHPUnit 9 --- .travis.yml | 4 +- composer.json | 2 +- phpseclib/File/ANSI.php | 45 ++++++++++--------- tests/Functional/Net/SCPSSH2UserStoryTest.php | 4 ++ tests/Functional/Net/SFTPLargeFileTest.php | 4 ++ tests/Functional/Net/SFTPStreamTest.php | 4 ++ tests/Functional/Net/SFTPUserStoryTest.php | 20 ++++----- tests/Functional/Net/SSH2AgentTest.php | 4 ++ tests/Functional/Net/SSH2Test.php | 6 ++- tests/PhpseclibTestCase.php | 44 ++++++++++++++++++ tests/Unit/Crypt/AES/McryptTest.php | 4 ++ tests/Unit/Crypt/AES/OpenSSLTest.php | 4 ++ .../AES/{InternalTest.php => PurePHPTest.php} | 6 ++- tests/Unit/Crypt/BlowfishTest.php | 4 ++ tests/Unit/Crypt/DESTest.php | 4 ++ tests/Unit/Crypt/Hash/MD5Test.php | 4 ++ tests/Unit/Crypt/Hash/SHA256Test.php | 4 ++ tests/Unit/Crypt/Hash/SHA256_96Test.php | 26 +++++++++++ tests/Unit/Crypt/Hash/SHA512Test.php | 4 ++ tests/Unit/Crypt/Hash/SHA512_96Test.php | 26 +++++++++++ tests/Unit/Crypt/RC2Test.php | 4 ++ tests/Unit/Crypt/RC4Test.php | 4 ++ tests/Unit/Crypt/RSA/LoadKeyTest.php | 28 +++++++----- tests/Unit/Crypt/RSA/ModeTest.php | 6 ++- tests/Unit/Crypt/RandomTest.php | 4 ++ tests/Unit/Crypt/TripleDESTest.php | 4 ++ tests/Unit/Crypt/TwofishTest.php | 4 ++ tests/Unit/File/ANSITest.php | 4 ++ tests/Unit/File/ASN1Test.php | 14 +++--- tests/Unit/File/X509/CSRTest.php | 10 +++-- tests/Unit/File/X509/SPKACTest.php | 18 +++++--- tests/Unit/File/X509/X509Test.php | 6 ++- tests/Unit/Math/BigInteger/BCMathTest.php | 4 ++ tests/Unit/Math/BigInteger/GMPTest.php | 4 ++ .../Math/BigInteger/InternalOpenSSLTest.php | 4 ++ tests/Unit/Math/BigInteger/InternalTest.php | 4 ++ tests/Unit/Math/BigInteger/TestCase.php | 2 +- ...PStreamTest.php => SFTPStreamUnitTest.php} | 6 ++- tests/Unit/Net/SSH1Test.php | 4 ++ .../Net/{SSH2Test.php => SSH2UnitTest.php} | 30 +++++++------ travis/run-phpunit.sh | 11 +++++ 41 files changed, 318 insertions(+), 80 deletions(-) rename tests/Unit/Crypt/AES/{InternalTest.php => PurePHPTest.php} (68%) rename tests/Unit/Net/{SFTPStreamTest.php => SFTPStreamUnitTest.php} (86%) rename tests/Unit/Net/{SSH2Test.php => SSH2UnitTest.php} (74%) diff --git a/.travis.yml b/.travis.yml index 6f7b22c48..b6a5d303b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,13 +22,15 @@ matrix: dist: xenial - php: 7.4 dist: xenial + - php: 8.0 + dist: bionic before_install: true install: - wget http://ftp.gnu.org/gnu/parallel/parallel-20170822.tar.bz2 - tar -xvjf parallel* - - cd parallel* + - cd parallel-20170822 - ./configure - make - sudo make install diff --git a/composer.json b/composer.json index 6729e8f90..9ff1f45bf 100644 --- a/composer.json +++ b/composer.json @@ -55,7 +55,7 @@ }, "require-dev": { "phing/phing": "~2.7", - "phpunit/phpunit": "^4.8.35|^5.7|^6.0", + "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4", "squizlabs/php_codesniffer": "~2.0" }, "suggest": { diff --git a/phpseclib/File/ANSI.php b/phpseclib/File/ANSI.php index 51693be8f..153bd4430 100644 --- a/phpseclib/File/ANSI.php +++ b/phpseclib/File/ANSI.php @@ -342,19 +342,20 @@ function appendString($source) $mods = explode(';', $match[1]); foreach ($mods as $mod) { switch ($mod) { - case 0: // Turn off character attributes + case '': + case '0': // Turn off character attributes $attr_cell = clone($this->base_attr_cell); break; - case 1: // Turn bold mode on + case '1': // Turn bold mode on $attr_cell->bold = true; break; - case 4: // Turn underline mode on + case '4': // Turn underline mode on $attr_cell->underline = true; break; - case 5: // Turn blinking mode on + case '5': // Turn blinking mode on $attr_cell->blink = true; break; - case 7: // Turn reverse video on + case '7': // Turn reverse video on $attr_cell->reverse = !$attr_cell->reverse; $temp = $attr_cell->background; $attr_cell->background = $attr_cell->foreground; @@ -367,23 +368,23 @@ function appendString($source) $back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' }; switch ($mod) { // @codingStandardsIgnoreStart - case 30: $front = 'black'; break; - case 31: $front = 'red'; break; - case 32: $front = 'green'; break; - case 33: $front = 'yellow'; break; - case 34: $front = 'blue'; break; - case 35: $front = 'magenta'; break; - case 36: $front = 'cyan'; break; - case 37: $front = 'white'; break; - - case 40: $back = 'black'; break; - case 41: $back = 'red'; break; - case 42: $back = 'green'; break; - case 43: $back = 'yellow'; break; - case 44: $back = 'blue'; break; - case 45: $back = 'magenta'; break; - case 46: $back = 'cyan'; break; - case 47: $back = 'white'; break; + case '30': $front = 'black'; break; + case '31': $front = 'red'; break; + case '32': $front = 'green'; break; + case '33': $front = 'yellow'; break; + case '34': $front = 'blue'; break; + case '35': $front = 'magenta'; break; + case '36': $front = 'cyan'; break; + case '37': $front = 'white'; break; + + case '40': $back = 'black'; break; + case '41': $back = 'red'; break; + case '42': $back = 'green'; break; + case '43': $back = 'yellow'; break; + case '44': $back = 'blue'; break; + case '45': $back = 'magenta'; break; + case '46': $back = 'cyan'; break; + case '47': $back = 'white'; break; // @codingStandardsIgnoreEnd default: diff --git a/tests/Functional/Net/SCPSSH2UserStoryTest.php b/tests/Functional/Net/SCPSSH2UserStoryTest.php index 4ba69f14d..3413fa423 100644 --- a/tests/Functional/Net/SCPSSH2UserStoryTest.php +++ b/tests/Functional/Net/SCPSSH2UserStoryTest.php @@ -86,3 +86,7 @@ public function testGetFile($scp) ); } } + +class SCPSSH2UserStoryTest extends Functional_Net_SCPSSH2UserStoryTest +{ +} diff --git a/tests/Functional/Net/SFTPLargeFileTest.php b/tests/Functional/Net/SFTPLargeFileTest.php index 0da85ab89..006adaf91 100644 --- a/tests/Functional/Net/SFTPLargeFileTest.php +++ b/tests/Functional/Net/SFTPLargeFileTest.php @@ -40,3 +40,7 @@ public function testPutSizeLocalFile() ); } } + +class SFTPLargeFileTest extends Functional_Net_SFTPLargeFileTest +{ +} diff --git a/tests/Functional/Net/SFTPStreamTest.php b/tests/Functional/Net/SFTPStreamTest.php index 55115603d..fa10be9a8 100644 --- a/tests/Functional/Net/SFTPStreamTest.php +++ b/tests/Functional/Net/SFTPStreamTest.php @@ -46,3 +46,7 @@ protected function buildUrl($suffix) ); } } + +class SFTPStreamTest extends Functional_Net_SFTPStreamTest +{ +} diff --git a/tests/Functional/Net/SFTPUserStoryTest.php b/tests/Functional/Net/SFTPUserStoryTest.php index 8da91604f..0470f4754 100644 --- a/tests/Functional/Net/SFTPUserStoryTest.php +++ b/tests/Functional/Net/SFTPUserStoryTest.php @@ -133,7 +133,7 @@ public function testStatOnDir($sftp) return $sftp; } - static function callback($length) + static function demoCallback($length) { $r = substr(self::$buffer, 0, $length); self::$buffer = substr(self::$buffer, $length); @@ -150,7 +150,7 @@ public function testPutSizeGetFileCallback($sftp) { self::$buffer = self::$exampleData; $this->assertTrue( - $sftp->put('file1.txt', array(__CLASS__, 'callback'), NET_SFTP_CALLBACK), + $sftp->put('file1.txt', array(__CLASS__, 'demoCallback'), NET_SFTP_CALLBACK), 'Failed asserting that example data could be successfully put().' ); @@ -437,8 +437,7 @@ public function testLinkFile($sftp) */ public function testReadlink($sftp) { - $this->assertInternalType( - 'string', + $this->assertIsString( $sftp->readlink('symlink'), 'Failed asserting that a symlink\'s target could be read' ); @@ -453,14 +452,12 @@ public function testReadlink($sftp) public function testStatOnCWD($sftp) { $stat = $sftp->stat('.'); - $this->assertInternalType( - 'array', + $this->assertIsArray( $stat, 'Failed asserting that stat on . returns an array' ); $lstat = $sftp->lstat('.'); - $this->assertInternalType( - 'array', + $this->assertIsArray( $lstat, 'Failed asserting that lstat on . returns an array' ); @@ -602,8 +599,7 @@ public function testDeleteEmptyDir($sftp) 'Failed asserting that scratch directory could ' . 'be created.' ); - $this->assertInternalType( - 'array', + $this->assertIsArray( $sftp->stat(self::$scratchDir), 'Failed asserting that stat on an existant empty directory returns an array' ); @@ -750,3 +746,7 @@ public function testRawlistDisabledStatCache($sftp) $this->assertEquals($list_cache_enabled, $list_cache_disabled, 'The files should be the same regardless of stat cache', 0.0, 10, true); } } + +class SFTPUserStoryTest extends Functional_Net_SFTPUserStoryTest +{ +} diff --git a/tests/Functional/Net/SSH2AgentTest.php b/tests/Functional/Net/SSH2AgentTest.php index 7ba57d5c7..7bee05942 100644 --- a/tests/Functional/Net/SSH2AgentTest.php +++ b/tests/Functional/Net/SSH2AgentTest.php @@ -50,3 +50,7 @@ public function testAgentForward($args) return $args; } } + +class SSH2AgentTest extends Functional_Net_SSH2AgentTest +{ +} diff --git a/tests/Functional/Net/SSH2Test.php b/tests/Functional/Net/SSH2Test.php index 872c8e78a..cffb309b3 100644 --- a/tests/Functional/Net/SSH2Test.php +++ b/tests/Functional/Net/SSH2Test.php @@ -122,7 +122,7 @@ public function testGetServerPublicHostKey() { $ssh = new Net_SSH2($this->getEnv('SSH_HOSTNAME')); - $this->assertInternalType('string', $ssh->getServerPublicHostKey()); + $this->assertIsString($ssh->getServerPublicHostKey()); } public function testOpenSocketConnect() @@ -170,3 +170,7 @@ public function testChannelDataAfterOpen($ssh) $ssh->read(); } } + +class SSH2Test extends Functional_Net_SSH2Test +{ +} diff --git a/tests/PhpseclibTestCase.php b/tests/PhpseclibTestCase.php index a53448830..ca68596b1 100644 --- a/tests/PhpseclibTestCase.php +++ b/tests/PhpseclibTestCase.php @@ -101,4 +101,48 @@ protected static function reRequireFile($filename) } } } + + // assertIsArray was not introduced until PHPUnit 8 + public static function assertIsArray($actual, $message = '') + { + if (method_exists('\PHPUnit\Framework\TestCase', 'assertIsArray')) { + parent::assertIsArray($actual, $message); + return; + } + + parent::assertInternalType('array', $actual, $message); + } + + // assertIsString was not introduced until PHPUnit 8 + public static function assertIsString($actual, $message = '') + { + if (method_exists('\PHPUnit\Framework\TestCase', 'assertIsString')) { + parent::assertIsString($actual, $message); + return; + } + + parent::assertInternalType('string', $actual, $message); + } + + // assertContains is deprecated for strings in PHPUnit 8 + public static function assertStringContainsString($needle, $haystack, $message = '') + { + if (method_exists('\PHPUnit\Framework\TestCase', 'assertStringContainsString')) { + parent::assertStringContainsString($needle, $haystack, $message); + return; + } + + parent::assertContains($needle, $haystack, $message); + } + + // assertNotContains is deprecated for strings in PHPUnit 8 + public static function assertStringNotContainsString($needle, $haystack, $message = '') + { + if (method_exists('\PHPUnit\Framework\TestCase', 'assertStringContainsString')) { + parent::assertStringNotContainsString($needle, $haystack, $message); + return; + } + + parent::assertNotContains($needle, $haystack, $message); + } } diff --git a/tests/Unit/Crypt/AES/McryptTest.php b/tests/Unit/Crypt/AES/McryptTest.php index 41fa20413..633b1f734 100644 --- a/tests/Unit/Crypt/AES/McryptTest.php +++ b/tests/Unit/Crypt/AES/McryptTest.php @@ -12,3 +12,7 @@ protected function setUp() $this->engine = CRYPT_ENGINE_MCRYPT; } } + +class McryptTest extends Unit_Crypt_AES_McryptTest +{ +} diff --git a/tests/Unit/Crypt/AES/OpenSSLTest.php b/tests/Unit/Crypt/AES/OpenSSLTest.php index ddb5de674..dc8899ce2 100644 --- a/tests/Unit/Crypt/AES/OpenSSLTest.php +++ b/tests/Unit/Crypt/AES/OpenSSLTest.php @@ -12,3 +12,7 @@ protected function setUp() $this->engine = CRYPT_ENGINE_OPENSSL; } } + +class OpenSSLTest extends Unit_Crypt_AES_OpenSSLTest +{ +} diff --git a/tests/Unit/Crypt/AES/InternalTest.php b/tests/Unit/Crypt/AES/PurePHPTest.php similarity index 68% rename from tests/Unit/Crypt/AES/InternalTest.php rename to tests/Unit/Crypt/AES/PurePHPTest.php index 75e89edf2..2fe5d2c76 100644 --- a/tests/Unit/Crypt/AES/InternalTest.php +++ b/tests/Unit/Crypt/AES/PurePHPTest.php @@ -5,10 +5,14 @@ * @license http://www.opensource.org/licenses/mit-license.html MIT License */ -class Unit_Crypt_AES_InternalTest extends Unit_Crypt_AES_TestCase +class Unit_Crypt_AES_PurePHPTest extends Unit_Crypt_AES_TestCase { protected function setUp() { $this->engine = CRYPT_ENGINE_INTERNAL; } } + +class PurePHPTest extends Unit_Crypt_AES_PurePHPTest +{ +} diff --git a/tests/Unit/Crypt/BlowfishTest.php b/tests/Unit/Crypt/BlowfishTest.php index 87406c135..014ff6a2d 100644 --- a/tests/Unit/Crypt/BlowfishTest.php +++ b/tests/Unit/Crypt/BlowfishTest.php @@ -128,3 +128,7 @@ public function testKeySizes() } } } + +class BlowfishTest extends Unit_Crypt_BlowfishTest +{ +} diff --git a/tests/Unit/Crypt/DESTest.php b/tests/Unit/Crypt/DESTest.php index 2a51d6cfe..b568fc2e0 100644 --- a/tests/Unit/Crypt/DESTest.php +++ b/tests/Unit/Crypt/DESTest.php @@ -75,3 +75,7 @@ public function testDecryptPadding() } } } + +class DESTest extends Unit_Crypt_DESTest +{ +} diff --git a/tests/Unit/Crypt/Hash/MD5Test.php b/tests/Unit/Crypt/Hash/MD5Test.php index a29695989..90f2f458b 100644 --- a/tests/Unit/Crypt/Hash/MD5Test.php +++ b/tests/Unit/Crypt/Hash/MD5Test.php @@ -45,3 +45,7 @@ public static function hmacData() ); } } + +class MD5Test extends Unit_Crypt_Hash_MD5Test +{ +} diff --git a/tests/Unit/Crypt/Hash/SHA256Test.php b/tests/Unit/Crypt/Hash/SHA256Test.php index b4b1995ad..488cf5587 100644 --- a/tests/Unit/Crypt/Hash/SHA256Test.php +++ b/tests/Unit/Crypt/Hash/SHA256Test.php @@ -77,3 +77,7 @@ public static function hmacData() ); } } + +class SHA256Test extends Unit_Crypt_Hash_SHA256Test +{ +} diff --git a/tests/Unit/Crypt/Hash/SHA256_96Test.php b/tests/Unit/Crypt/Hash/SHA256_96Test.php index 3f2e1588b..564aae94a 100644 --- a/tests/Unit/Crypt/Hash/SHA256_96Test.php +++ b/tests/Unit/Crypt/Hash/SHA256_96Test.php @@ -5,6 +5,8 @@ * @license http://www.opensource.org/licenses/mit-license.html MIT License */ +require_once 'SHA256Test.php'; + class Unit_Crypt_Hash_SHA256_96Test extends Unit_Crypt_Hash_SHA256Test { public function getInstance() @@ -28,3 +30,27 @@ public function testHMAC($key, $message, $longResult) parent::testHMAC($key, $message, substr($longResult, 0, 24)); } } + +class SHA256_96Test extends SHA256Test +{ + public function getInstance() + { + return new Crypt_Hash('sha256-96'); + } + + /** + * @dataProvider hashData() + */ + public function testHash($message, $longResult) + { + parent::testHash($message, substr($longResult, 0, 24)); + } + + /** + * @dataProvider hmacData() + */ + public function testHMAC($key, $message, $longResult) + { + parent::testHMAC($key, $message, substr($longResult, 0, 24)); + } +} diff --git a/tests/Unit/Crypt/Hash/SHA512Test.php b/tests/Unit/Crypt/Hash/SHA512Test.php index 0a0e58181..cc1dce4f9 100644 --- a/tests/Unit/Crypt/Hash/SHA512Test.php +++ b/tests/Unit/Crypt/Hash/SHA512Test.php @@ -77,3 +77,7 @@ public static function hmacData() ); } } + +class SHA512Test extends Unit_Crypt_Hash_SHA512Test +{ +} diff --git a/tests/Unit/Crypt/Hash/SHA512_96Test.php b/tests/Unit/Crypt/Hash/SHA512_96Test.php index bcf7b45b6..caa4d49ef 100644 --- a/tests/Unit/Crypt/Hash/SHA512_96Test.php +++ b/tests/Unit/Crypt/Hash/SHA512_96Test.php @@ -5,6 +5,8 @@ * @license http://www.opensource.org/licenses/mit-license.html MIT License */ +require_once 'SHA512Test.php'; + class Unit_Crypt_Hash_SHA512_96Test extends Unit_Crypt_Hash_SHA512Test { public function getInstance() @@ -28,3 +30,27 @@ public function testHMAC($key, $message, $longResult) parent::testHMAC($key, $message, substr($longResult, 0, 24)); } } + +class SHA512_96Test extends SHA512Test +{ + public function getInstance() + { + return new Crypt_Hash('sha512-96'); + } + + /** + * @dataProvider hashData() + */ + public function testHash($message, $longResult) + { + parent::testHash($message, substr($longResult, 0, 24)); + } + + /** + * @dataProvider hmacData() + */ + public function testHMAC($key, $message, $longResult) + { + parent::testHMAC($key, $message, substr($longResult, 0, 24)); + } +} diff --git a/tests/Unit/Crypt/RC2Test.php b/tests/Unit/Crypt/RC2Test.php index 0ad664bbc..043b0605e 100644 --- a/tests/Unit/Crypt/RC2Test.php +++ b/tests/Unit/Crypt/RC2Test.php @@ -125,3 +125,7 @@ public function testVectors($engine, $engineName, $key, $keyLen, $plaintext, $ci $this->assertEquals($result, $plaintext, "Failed asserting that decrypted result yielded $plaintext as a result in $engineName engine"); } } + +class RC2Test extends Unit_Crypt_RC2Test +{ +} diff --git a/tests/Unit/Crypt/RC4Test.php b/tests/Unit/Crypt/RC4Test.php index 4ba34e3d8..4a956d31e 100644 --- a/tests/Unit/Crypt/RC4Test.php +++ b/tests/Unit/Crypt/RC4Test.php @@ -248,3 +248,7 @@ public function testKeySizes() } } } + +class RC4Test extends Unit_Crypt_RC4Test +{ +} diff --git a/tests/Unit/Crypt/RSA/LoadKeyTest.php b/tests/Unit/Crypt/RSA/LoadKeyTest.php index f4dc544ef..8d6af28c5 100644 --- a/tests/Unit/Crypt/RSA/LoadKeyTest.php +++ b/tests/Unit/Crypt/RSA/LoadKeyTest.php @@ -5,7 +5,7 @@ * @license http://www.opensource.org/licenses/mit-license.html MIT License */ -require_once 'Crypt/RSA.php' ; +require_once 'Crypt/RSA.php'; class Unit_Crypt_RSA_LoadKeyTest extends PhpseclibTestCase { @@ -37,7 +37,7 @@ public function testPKCS1Key() -----END RSA PRIVATE KEY-----'; $this->assertTrue($rsa->loadKey($key)); - $this->assertInternalType('string', $rsa->getPrivateKey()); + $this->assertIsString($rsa->getPrivateKey()); } public function testPKCS1SpacesKey() @@ -60,7 +60,7 @@ public function testPKCS1SpacesKey() $key = str_replace(array("\r", "\n", "\r\n"), ' ', $key); $this->assertTrue($rsa->loadKey($key)); - $this->assertInternalType('string', $rsa->getPrivateKey()); + $this->assertIsString($rsa->getPrivateKey()); } public function testPKCS1NoHeaderKey() @@ -80,7 +80,7 @@ public function testPKCS1NoHeaderKey() 37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0='; $this->assertTrue($rsa->loadKey($key)); - $this->assertInternalType('string', $rsa->getPrivateKey()); + $this->assertIsString($rsa->getPrivateKey()); } public function testPKCS1NoWhitespaceNoHeaderKey() @@ -100,7 +100,7 @@ public function testPKCS1NoWhitespaceNoHeaderKey() '37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0='; $this->assertTrue($rsa->loadKey($key)); - $this->assertInternalType('string', $rsa->getPrivateKey()); + $this->assertIsString($rsa->getPrivateKey()); } public function testRawPKCS1Key() @@ -121,7 +121,7 @@ public function testRawPKCS1Key() $key = base64_decode($key); $this->assertTrue($rsa->loadKey($key)); - $this->assertInternalType('string', $rsa->getPrivateKey()); + $this->assertIsString($rsa->getPrivateKey()); } public function testLoadPKCS8PrivateKey() @@ -160,7 +160,7 @@ public function testLoadPKCS8PrivateKey() -----END ENCRYPTED PRIVATE KEY-----'; $this->assertTrue($rsa->loadKey($key)); - $this->assertInternalType('string', $rsa->getPrivateKey()); + $this->assertIsString($rsa->getPrivateKey()); } public function testSavePKCS8PrivateKey() @@ -185,7 +185,7 @@ public function testSavePKCS8PrivateKey() $this->assertTrue($rsa->loadKey($key)); $key = $rsa->getPrivateKey(CRYPT_RSA_PRIVATE_FORMAT_PKCS8); - $this->assertInternalType('string', $key); + $this->assertIsString($key); $this->assertTrue($rsa->loadKey($key)); } @@ -204,7 +204,7 @@ public function testPubKey1() -----END RSA PUBLIC KEY-----'; $this->assertTrue($rsa->loadKey($key)); - $this->assertInternalType('string', $rsa->getPublicKey()); + $this->assertIsString($rsa->getPublicKey()); $this->assertFalse($rsa->getPrivateKey()); } @@ -223,7 +223,7 @@ public function testPubKey2() -----END PUBLIC KEY-----'; $this->assertTrue($rsa->loadKey($key)); - $this->assertInternalType('string', $rsa->getPublicKey()); + $this->assertIsString($rsa->getPublicKey()); $this->assertFalse($rsa->getPrivateKey()); } @@ -237,7 +237,7 @@ public function testSSHPubKey() 'phpseclib-generated-key'; $this->assertTrue($rsa->loadKey($key)); - $this->assertInternalType('string', $rsa->getPublicKey()); + $this->assertIsString($rsa->getPublicKey()); $this->assertFalse($rsa->getPrivateKey()); } @@ -415,7 +415,7 @@ public function testGoodBad() -----END RSA PUBLIC KEY-----'; $this->assertTrue($rsa->loadKey($key)); - $this->assertInternalType('string', $rsa->getPublicKey()); + $this->assertIsString($rsa->getPublicKey()); $this->assertFalse($rsa->loadKey('zzz')); $this->assertFalse($rsa->getPublicKey()); } @@ -478,3 +478,7 @@ public function testOpenSSHPrivate() $this->assertTrue($rsa->verify('zzz', $sig)); } } + +class LoadKeyTest extends Unit_Crypt_RSA_LoadKeyTest +{ +} diff --git a/tests/Unit/Crypt/RSA/ModeTest.php b/tests/Unit/Crypt/RSA/ModeTest.php index fce48110c..eea8e0bf9 100644 --- a/tests/Unit/Crypt/RSA/ModeTest.php +++ b/tests/Unit/Crypt/RSA/ModeTest.php @@ -5,7 +5,7 @@ * @license http://www.opensource.org/licenses/mit-license.html MIT License */ -require_once 'Crypt/RSA.php' ; +require_once 'Crypt/RSA.php'; class Unit_Crypt_RSA_ModeTest extends PhpseclibTestCase { @@ -116,3 +116,7 @@ public function testPSSSigsWithNonPowerOf2Key() $this->assertTrue($rsa->verify($payload, $sig)); } } + +class ModeTest extends Unit_Crypt_RSA_ModeTest +{ +} diff --git a/tests/Unit/Crypt/RandomTest.php b/tests/Unit/Crypt/RandomTest.php index e53efc8d5..94af2b39f 100644 --- a/tests/Unit/Crypt/RandomTest.php +++ b/tests/Unit/Crypt/RandomTest.php @@ -51,3 +51,7 @@ protected function wrap($x) return array($x); } } + +class RandomTest extends Unit_Crypt_RandomTest +{ +} diff --git a/tests/Unit/Crypt/TripleDESTest.php b/tests/Unit/Crypt/TripleDESTest.php index c1f09ba14..8cdd4fa68 100644 --- a/tests/Unit/Crypt/TripleDESTest.php +++ b/tests/Unit/Crypt/TripleDESTest.php @@ -186,3 +186,7 @@ public function testInnerChaining() } } } + +class TripleDESTest extends Unit_Crypt_TripleDESTest +{ +} diff --git a/tests/Unit/Crypt/TwofishTest.php b/tests/Unit/Crypt/TwofishTest.php index 53cfecd89..24a83a601 100644 --- a/tests/Unit/Crypt/TwofishTest.php +++ b/tests/Unit/Crypt/TwofishTest.php @@ -71,3 +71,7 @@ public function testVectors() } } } + +class TwofishTest extends Unit_Crypt_TwofishTest +{ +} diff --git a/tests/Unit/File/ANSITest.php b/tests/Unit/File/ANSITest.php index 7fa89d7ff..d64941bc7 100644 --- a/tests/Unit/File/ANSITest.php +++ b/tests/Unit/File/ANSITest.php @@ -47,3 +47,7 @@ public function testLineOverflow() $this->assertSame(str_repeat('z', 80), $lines[22]); } } + +class ANSITest extends Unit_File_ANSITest +{ +} diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index 1864eff5a..a28670a83 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -79,7 +79,7 @@ public function testAnyString() $decoded = $asn1->decodeBER(base64_decode($str)); $result = $asn1->asn1map($decoded[0], $AS_REP); - $this->assertInternalType('array', $result); + $this->assertIsArray($result); } /** @@ -231,7 +231,7 @@ public function testIncorrectString() $decoded = $asn1->decodeBER(base64_decode($str)); $result = $asn1->asn1map($decoded[0], $AS_REP); - $this->assertInternalType('array', $result); + $this->assertIsArray($result); } /** @@ -276,7 +276,7 @@ public function testContextSpecificNonConstructed() { $asn1 = new File_ASN1(); $decoded = $asn1->decodeBER(base64_decode('MBaAFJtUo7c00HsI5EPZ4bkICfkOY2Pv')); - $this->assertInternalType('string', $decoded[0]['content'][0]['content']); + $this->assertIsString($decoded[0]['content'][0]['content']); } /** @@ -286,7 +286,7 @@ public function testEmptyContextTag() { $asn1 = new File_ASN1(); $decoded = $asn1->decodeBER("\xa0\x00"); - $this->assertInternalType('array', $decoded); + $this->assertIsArray($decoded); $this->assertCount(0, $decoded[0]['content']); } @@ -390,6 +390,10 @@ public function testExplicitImplicitDate() $a = $asn1->decodeBER($a); $a = $asn1->asn1map($a[0], $map); - $this->assertInternalType('array', $a); + $this->assertIsArray($a); } } + +class ASN1Test extends Unit_File_ASN1Test +{ +} diff --git a/tests/Unit/File/X509/CSRTest.php b/tests/Unit/File/X509/CSRTest.php index fa86d356b..84736641f 100644 --- a/tests/Unit/File/X509/CSRTest.php +++ b/tests/Unit/File/X509/CSRTest.php @@ -27,7 +27,7 @@ public function testLoadCSR() $spkac = $x509->loadCSR($test); - $this->assertInternalType('array', $spkac); + $this->assertIsArray($spkac); } public function testCSRWithAttributes() @@ -67,7 +67,7 @@ public function testCSRWithAttributes() $csr = $x509->loadCSR($test); - $this->assertInternalType('array', $csr); + $this->assertIsArray($csr); } public function testCSRDER() @@ -92,7 +92,7 @@ public function testCSRDER() $csr = $x509->loadCSR($csr); - $this->assertInternalType('array', $csr); + $this->assertIsArray($csr); } // on PHP 7.1, with older versions of phpseclib, this would produce a "A non-numeric value encountered" warning @@ -119,3 +119,7 @@ public function testNewCSR() $x509->saveCSR($x509->signCSR('sha256WithRSAEncryption'), FILE_X509_FORMAT_DER); } } + +class CSRTest extends Unit_File_X509_CSRTest +{ +} diff --git a/tests/Unit/File/X509/SPKACTest.php b/tests/Unit/File/X509/SPKACTest.php index 59bda3aeb..2d7f0eca2 100644 --- a/tests/Unit/File/X509/SPKACTest.php +++ b/tests/Unit/File/X509/SPKACTest.php @@ -28,11 +28,11 @@ public function testLoadSPKAC() $spkac = $x509->loadSPKAC($test); - $this->assertInternalType('array', $spkac); + $this->assertIsArray($spkac); $spkac = $x509->loadSPKAC('SPKAC=' . $test); - $this->assertInternalType('array', $spkac); + $this->assertIsArray($spkac); $this->assertTrue( $x509->validateSignature(), @@ -41,7 +41,7 @@ public function testLoadSPKAC() $pubKey = $x509->getPublicKey(); - $this->assertInternalType('string', "$pubKey"); + $this->assertIsString("$pubKey"); } public function testSaveSPKAC() @@ -55,17 +55,17 @@ public function testSaveSPKAC() $x509->setChallenge('...'); $spkac = $x509->signSPKAC(); - $this->assertInternalType('array', $spkac); + $this->assertIsArray($spkac); - $this->assertInternalType('string', $x509->saveSPKAC($spkac)); + $this->assertIsString($x509->saveSPKAC($spkac)); $x509 = new File_X509(); $x509->setPrivateKey($privKey); $spkac = $x509->signSPKAC(); - $this->assertInternalType('array', $spkac); + $this->assertIsArray($spkac); - $this->assertInternalType('string', $x509->saveSPKAC($spkac)); + $this->assertIsString($x509->saveSPKAC($spkac)); } public function testBadSignatureSPKAC() @@ -96,3 +96,7 @@ public function testBadSignatureSPKAC() ); } } + +class SPKACTest extends Unit_File_X509_SPKACTest +{ +} diff --git a/tests/Unit/File/X509/X509Test.php b/tests/Unit/File/X509/X509Test.php index 8b86a6376..2fb49e84a 100644 --- a/tests/Unit/File/X509/X509Test.php +++ b/tests/Unit/File/X509/X509Test.php @@ -55,7 +55,7 @@ public function testExtensionMapping() $cert = $x509->loadX509($test); - $this->assertInternalType('array', $cert['tbsCertificate']['extensions'][3]['extnValue']); + $this->assertIsArray($cert['tbsCertificate']['extensions'][3]['extnValue']); } public function testLoadUnsupportedExtension() @@ -856,3 +856,7 @@ public function testMultiCertPEM() $this->assertFalse($r); } } + +class X509Test extends Unit_File_X509_X509Test +{ +} diff --git a/tests/Unit/Math/BigInteger/BCMathTest.php b/tests/Unit/Math/BigInteger/BCMathTest.php index 109f81d05..b03059947 100644 --- a/tests/Unit/Math/BigInteger/BCMathTest.php +++ b/tests/Unit/Math/BigInteger/BCMathTest.php @@ -18,3 +18,7 @@ public static function setUpBeforeClass() self::ensureConstant('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_BCMATH); } } + +class BCMathTest extends Unit_Math_BigInteger_BCMathTest +{ +} diff --git a/tests/Unit/Math/BigInteger/GMPTest.php b/tests/Unit/Math/BigInteger/GMPTest.php index 2ec2042fe..25ad88499 100644 --- a/tests/Unit/Math/BigInteger/GMPTest.php +++ b/tests/Unit/Math/BigInteger/GMPTest.php @@ -18,3 +18,7 @@ public static function setUpBeforeClass() self::ensureConstant('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_GMP); } } + +class GMPTest extends Unit_Math_BigInteger_GMPTest +{ +} diff --git a/tests/Unit/Math/BigInteger/InternalOpenSSLTest.php b/tests/Unit/Math/BigInteger/InternalOpenSSLTest.php index 4b297d9fb..21533b9c0 100644 --- a/tests/Unit/Math/BigInteger/InternalOpenSSLTest.php +++ b/tests/Unit/Math/BigInteger/InternalOpenSSLTest.php @@ -18,3 +18,7 @@ public static function setUpBeforeClass() self::ensureConstant('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_INTERNAL); } } + +class InternalOpenSSLTest extends Unit_Math_BigInteger_InternalOpenSSLTest +{ +} diff --git a/tests/Unit/Math/BigInteger/InternalTest.php b/tests/Unit/Math/BigInteger/InternalTest.php index f1fcae516..bbfe8ff0d 100644 --- a/tests/Unit/Math/BigInteger/InternalTest.php +++ b/tests/Unit/Math/BigInteger/InternalTest.php @@ -22,3 +22,7 @@ public function testInternalRepresentation() $this->assertSame($x->value, $y->value); } } + +class InternalTest extends Unit_Math_BigInteger_InternalTest +{ +} diff --git a/tests/Unit/Math/BigInteger/TestCase.php b/tests/Unit/Math/BigInteger/TestCase.php index 6120bb865..1ccaae2f3 100644 --- a/tests/Unit/Math/BigInteger/TestCase.php +++ b/tests/Unit/Math/BigInteger/TestCase.php @@ -402,7 +402,7 @@ public function testDebugInfo() { $num = $this->getInstance(50); $str = print_r($num, true); - $this->assertContains('[value] => 0x32', $str); + $this->assertStringContainsString('[value] => 0x32', $str); return $str; } diff --git a/tests/Unit/Net/SFTPStreamTest.php b/tests/Unit/Net/SFTPStreamUnitTest.php similarity index 86% rename from tests/Unit/Net/SFTPStreamTest.php rename to tests/Unit/Net/SFTPStreamUnitTest.php index f5f834541..fc23ec3dd 100644 --- a/tests/Unit/Net/SFTPStreamTest.php +++ b/tests/Unit/Net/SFTPStreamUnitTest.php @@ -7,7 +7,7 @@ require_once 'Net/SFTP/Stream.php'; -class Unit_Net_SFTPStreamTest extends PhpseclibTestCase +class Unit_Net_SFTPStreamUnitTest extends PhpseclibTestCase { protected $protocol = 'sftptest'; @@ -31,3 +31,7 @@ public function testRegisterWithArgument() $this->assertContains($this->protocol, stream_get_wrappers()); } } + +class SFTPStreamUnitTest extends Unit_Net_SFTPStreamUnitTest +{ +} diff --git a/tests/Unit/Net/SSH1Test.php b/tests/Unit/Net/SSH1Test.php index b0b2aaed4..042cfe96d 100644 --- a/tests/Unit/Net/SSH1Test.php +++ b/tests/Unit/Net/SSH1Test.php @@ -39,3 +39,7 @@ public function testFormatLog(array $message_log, array $message_number_log, $ex $this->assertEquals($expected, $result); } } + +class SSH1Test extends Unit_Net_SSH1Test +{ +} diff --git a/tests/Unit/Net/SSH2Test.php b/tests/Unit/Net/SSH2UnitTest.php similarity index 74% rename from tests/Unit/Net/SSH2Test.php rename to tests/Unit/Net/SSH2UnitTest.php index e13b54a3b..924b4bfef 100644 --- a/tests/Unit/Net/SSH2Test.php +++ b/tests/Unit/Net/SSH2UnitTest.php @@ -6,7 +6,7 @@ * @license http://www.opensource.org/licenses/mit-license.html MIT License */ -class Unit_Net_SSH2Test extends PhpseclibTestCase +class Unit_Net_SSH2UnitTest extends PhpseclibTestCase { public function formatLogDataProvider() { @@ -42,25 +42,25 @@ public function testGenerateIdentifier() $this->assertStringStartsWith('SSH-2.0-phpseclib_1.0', $identifier); if (extension_loaded('openssl')) { - $this->assertContains('openssl', $identifier); - $this->assertNotContains('mcrypt', $identifier); + $this->assertStringContainsString('openssl', $identifier); + $this->assertStringNotContainsString('mcrypt', $identifier); } elseif (extension_loaded('mcrypt')) { - $this->assertNotContains('openssl', $identifier); - $this->assertContains('mcrypt', $identifier); + $this->assertStringNotContainsString('openssl', $identifier); + $this->assertStringContainsString('mcrypt', $identifier); } else { - $this->assertNotContains('openssl', $identifier); - $this->assertNotContains('mcrypt', $identifier); + $this->assertStringNotContainsString('openssl', $identifier); + $this->assertStringNotContainsString('mcrypt', $identifier); } if (extension_loaded('gmp')) { - $this->assertContains('gmp', $identifier); - $this->assertNotContains('bcmath', $identifier); + $this->assertStringContainsString('gmp', $identifier); + $this->assertStringNotContainsString('bcmath', $identifier); } elseif (extension_loaded('bcmath')) { - $this->assertNotContains('gmp', $identifier); - $this->assertContains('bcmath', $identifier); + $this->assertStringNotContainsString('gmp', $identifier); + $this->assertStringContainsString('bcmath', $identifier); } else { - $this->assertNotContains('gmp', $identifier); - $this->assertNotContains('bcmath', $identifier); + $this->assertStringNotContainsString('gmp', $identifier); + $this->assertStringNotContainsString('bcmath', $identifier); } } @@ -117,3 +117,7 @@ protected function createSSHMock() ->getMock(); } } + +class SSH2UnitTest extends Unit_Net_SSH2UnitTest +{ +} diff --git a/travis/run-phpunit.sh b/travis/run-phpunit.sh index ce393a772..2b1d90cca 100755 --- a/travis/run-phpunit.sh +++ b/travis/run-phpunit.sh @@ -20,6 +20,17 @@ then PHPUNIT_ARGS="$PHPUNIT_ARGS -d zend.enable_gc=0" fi +if [ `php -r "echo (int) version_compare(PHP_VERSION, '7.3', '>=');"` = "1" ] +then + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/n setUpBeforeClass()/n setUpBeforeClass(): void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/n setUp()/n setUp(): void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/n tearDown()/n tearDown(): void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertIsArray([^)]*)\)/\1: void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertIsString([^)]*)\)/\1: void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertStringContainsString([^)]*)\)/\1: void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertStringNotContainsString([^)]*)\)/\1: void/g' +fi + if [ "$TRAVIS_PHP_VERSION" = 'hhvm' -o `php -r "echo (int) version_compare(PHP_VERSION, '7.0', '>=');"` = "1" ] then find tests -type f -name "*Test.php" | \ From 245a84b57fd394533ccf92196378a4e21177b659 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 12 Dec 2020 17:26:44 -0600 Subject: [PATCH 23/69] make unit tests pass without gnu parallel --- tests/Functional/Net/SFTPLargeFileTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Functional/Net/SFTPLargeFileTest.php b/tests/Functional/Net/SFTPLargeFileTest.php index 006adaf91..2d02ff221 100644 --- a/tests/Functional/Net/SFTPLargeFileTest.php +++ b/tests/Functional/Net/SFTPLargeFileTest.php @@ -15,6 +15,7 @@ public static function setUpBeforeClass() if (!extension_loaded('mcrypt') && !extension_loaded('openssl')) { self::markTestSkipped('This test depends on mcrypt or openssl for performance.'); } + self::ensureConstant('CRYPT_HASH_MODE', 3); parent::setUpBeforeClass(); } From 95432478c0d56f096ab020e9abd25f675064d62d Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 12 Dec 2020 17:15:52 -0600 Subject: [PATCH 24/69] fix bad merge --- build/code-sniffer-ruleset-tests.xml | 1 + tests/Functional/Net/SFTPUserStoryTest.php | 14 ++------------ tests/Unit/Crypt/Hash/SHA256_96Test.php | 2 +- tests/Unit/Crypt/Hash/SHA512_96Test.php | 2 +- tests/Unit/Crypt/RSA/LoadKeyTest.php | 5 ----- 5 files changed, 5 insertions(+), 19 deletions(-) diff --git a/build/code-sniffer-ruleset-tests.xml b/build/code-sniffer-ruleset-tests.xml index 7169012eb..17f00d1d8 100644 --- a/build/code-sniffer-ruleset-tests.xml +++ b/build/code-sniffer-ruleset-tests.xml @@ -11,6 +11,7 @@ using underscore. --> + diff --git a/tests/Functional/Net/SFTPUserStoryTest.php b/tests/Functional/Net/SFTPUserStoryTest.php index 0eec5ece2..015fea035 100644 --- a/tests/Functional/Net/SFTPUserStoryTest.php +++ b/tests/Functional/Net/SFTPUserStoryTest.php @@ -151,7 +151,7 @@ static function demoCallback($length) public function testPutSizeGetFile($sftp) { $this->assertTrue( - $sftp->put('file1.txt', array(__CLASS__, 'demoCallback'), NET_SFTP_CALLBACK), + $sftp->put('file1.txt', self::$exampleData), 'Failed asserting that example data could be successfully put().' ); @@ -170,16 +170,6 @@ public function testPutSizeGetFile($sftp) return $sftp; } - static function callback($length) - { - $r = substr(self::$buffer, 0, $length); - self::$buffer = substr(self::$buffer, $length); - if (strlen($r)) { - return $r; - } - return null; - } - /** * @depends testStatOnDir */ @@ -187,7 +177,7 @@ public function testPutSizeGetFileCallback($sftp) { self::$buffer = self::$exampleData; $this->assertTrue( - $sftp->put('file1.txt', array(__CLASS__, 'callback'), $sftp::SOURCE_CALLBACK), + $sftp->put('file1.txt', array(__CLASS__, 'demoCallback'), $sftp::SOURCE_CALLBACK), 'Failed asserting that example data could be successfully put().' ); diff --git a/tests/Unit/Crypt/Hash/SHA256_96Test.php b/tests/Unit/Crypt/Hash/SHA256_96Test.php index e7a950cc6..cc354b5dc 100644 --- a/tests/Unit/Crypt/Hash/SHA256_96Test.php +++ b/tests/Unit/Crypt/Hash/SHA256_96Test.php @@ -35,7 +35,7 @@ class SHA256_96Test extends SHA256Test { public function getInstance() { - return new Crypt_Hash('sha256-96'); + return new Hash('sha256-96'); } /** diff --git a/tests/Unit/Crypt/Hash/SHA512_96Test.php b/tests/Unit/Crypt/Hash/SHA512_96Test.php index 6ee9ede09..67f00ba24 100644 --- a/tests/Unit/Crypt/Hash/SHA512_96Test.php +++ b/tests/Unit/Crypt/Hash/SHA512_96Test.php @@ -35,7 +35,7 @@ class SHA512_96Test extends SHA512Test { public function getInstance() { - return new Crypt_Hash('sha512-96'); + return new Hash('sha512-96'); } /** diff --git a/tests/Unit/Crypt/RSA/LoadKeyTest.php b/tests/Unit/Crypt/RSA/LoadKeyTest.php index 6bec98759..31c3e1c87 100644 --- a/tests/Unit/Crypt/RSA/LoadKeyTest.php +++ b/tests/Unit/Crypt/RSA/LoadKeyTest.php @@ -184,13 +184,8 @@ public function testSavePKCS8PrivateKey() $this->assertTrue($rsa->loadKey($key)); -<<<<<<< HEAD $key = $rsa->getPrivateKey(RSA::PRIVATE_FORMAT_PKCS8); - $this->assertInternalType('string', $key); -======= - $key = $rsa->getPrivateKey(CRYPT_RSA_PRIVATE_FORMAT_PKCS8); $this->assertIsString($key); ->>>>>>> 1.0 $this->assertTrue($rsa->loadKey($key)); } From e6abc61f45b3121f545ac05271deac209ecdef11 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 12 Dec 2020 20:39:56 -0600 Subject: [PATCH 25/69] rm adding of dupe classes (they break annotations) --- tests/Functional/Net/SCPSSH2UserStoryTest.php | 4 ---- tests/Functional/Net/SFTPLargeFileTest.php | 4 ---- tests/Functional/Net/SFTPStreamTest.php | 4 ---- tests/Functional/Net/SFTPUserStoryTest.php | 4 ---- tests/Functional/Net/SSH2AgentTest.php | 4 ---- tests/Functional/Net/SSH2Test.php | 4 ---- tests/Unit/Crypt/AES/McryptTest.php | 4 ---- tests/Unit/Crypt/AES/OpenSSLTest.php | 4 ---- tests/Unit/Crypt/AES/PurePHPTest.php | 4 ---- tests/Unit/Crypt/BlowfishTest.php | 4 ---- tests/Unit/Crypt/DESTest.php | 4 ---- tests/Unit/Crypt/Hash/MD5Test.php | 4 ---- tests/Unit/Crypt/Hash/SHA256Test.php | 4 ---- tests/Unit/Crypt/Hash/SHA256_96Test.php | 24 ------------------- tests/Unit/Crypt/Hash/SHA512Test.php | 4 ---- tests/Unit/Crypt/Hash/SHA512_96Test.php | 24 ------------------- tests/Unit/Crypt/RC2Test.php | 4 ---- tests/Unit/Crypt/RC4Test.php | 4 ---- tests/Unit/Crypt/RSA/LoadKeyTest.php | 4 ---- tests/Unit/Crypt/RSA/ModeTest.php | 4 ---- tests/Unit/Crypt/RandomTest.php | 4 ---- tests/Unit/Crypt/TripleDESTest.php | 4 ---- tests/Unit/Crypt/TwofishTest.php | 4 ---- tests/Unit/File/ANSITest.php | 4 ---- tests/Unit/File/ASN1Test.php | 4 ---- tests/Unit/File/X509/CSRTest.php | 4 ---- tests/Unit/File/X509/SPKACTest.php | 4 ---- tests/Unit/File/X509/X509Test.php | 4 ---- tests/Unit/Math/BigInteger/BCMathTest.php | 4 ---- tests/Unit/Math/BigInteger/GMPTest.php | 4 ---- .../Math/BigInteger/InternalOpenSSLTest.php | 4 ---- tests/Unit/Math/BigInteger/InternalTest.php | 4 ---- tests/Unit/Net/SFTPStreamUnitTest.php | 4 ---- tests/Unit/Net/SSH1Test.php | 4 ---- tests/Unit/Net/SSH2UnitTest.php | 4 ---- travis/run-phpunit.sh | 6 +++++ 36 files changed, 6 insertions(+), 180 deletions(-) diff --git a/tests/Functional/Net/SCPSSH2UserStoryTest.php b/tests/Functional/Net/SCPSSH2UserStoryTest.php index 3413fa423..4ba69f14d 100644 --- a/tests/Functional/Net/SCPSSH2UserStoryTest.php +++ b/tests/Functional/Net/SCPSSH2UserStoryTest.php @@ -86,7 +86,3 @@ public function testGetFile($scp) ); } } - -class SCPSSH2UserStoryTest extends Functional_Net_SCPSSH2UserStoryTest -{ -} diff --git a/tests/Functional/Net/SFTPLargeFileTest.php b/tests/Functional/Net/SFTPLargeFileTest.php index 2d02ff221..36115d546 100644 --- a/tests/Functional/Net/SFTPLargeFileTest.php +++ b/tests/Functional/Net/SFTPLargeFileTest.php @@ -41,7 +41,3 @@ public function testPutSizeLocalFile() ); } } - -class SFTPLargeFileTest extends Functional_Net_SFTPLargeFileTest -{ -} diff --git a/tests/Functional/Net/SFTPStreamTest.php b/tests/Functional/Net/SFTPStreamTest.php index fa10be9a8..55115603d 100644 --- a/tests/Functional/Net/SFTPStreamTest.php +++ b/tests/Functional/Net/SFTPStreamTest.php @@ -46,7 +46,3 @@ protected function buildUrl($suffix) ); } } - -class SFTPStreamTest extends Functional_Net_SFTPStreamTest -{ -} diff --git a/tests/Functional/Net/SFTPUserStoryTest.php b/tests/Functional/Net/SFTPUserStoryTest.php index 0470f4754..6787b62fd 100644 --- a/tests/Functional/Net/SFTPUserStoryTest.php +++ b/tests/Functional/Net/SFTPUserStoryTest.php @@ -746,7 +746,3 @@ public function testRawlistDisabledStatCache($sftp) $this->assertEquals($list_cache_enabled, $list_cache_disabled, 'The files should be the same regardless of stat cache', 0.0, 10, true); } } - -class SFTPUserStoryTest extends Functional_Net_SFTPUserStoryTest -{ -} diff --git a/tests/Functional/Net/SSH2AgentTest.php b/tests/Functional/Net/SSH2AgentTest.php index 7bee05942..7ba57d5c7 100644 --- a/tests/Functional/Net/SSH2AgentTest.php +++ b/tests/Functional/Net/SSH2AgentTest.php @@ -50,7 +50,3 @@ public function testAgentForward($args) return $args; } } - -class SSH2AgentTest extends Functional_Net_SSH2AgentTest -{ -} diff --git a/tests/Functional/Net/SSH2Test.php b/tests/Functional/Net/SSH2Test.php index cffb309b3..09c9ff048 100644 --- a/tests/Functional/Net/SSH2Test.php +++ b/tests/Functional/Net/SSH2Test.php @@ -170,7 +170,3 @@ public function testChannelDataAfterOpen($ssh) $ssh->read(); } } - -class SSH2Test extends Functional_Net_SSH2Test -{ -} diff --git a/tests/Unit/Crypt/AES/McryptTest.php b/tests/Unit/Crypt/AES/McryptTest.php index 633b1f734..41fa20413 100644 --- a/tests/Unit/Crypt/AES/McryptTest.php +++ b/tests/Unit/Crypt/AES/McryptTest.php @@ -12,7 +12,3 @@ protected function setUp() $this->engine = CRYPT_ENGINE_MCRYPT; } } - -class McryptTest extends Unit_Crypt_AES_McryptTest -{ -} diff --git a/tests/Unit/Crypt/AES/OpenSSLTest.php b/tests/Unit/Crypt/AES/OpenSSLTest.php index dc8899ce2..ddb5de674 100644 --- a/tests/Unit/Crypt/AES/OpenSSLTest.php +++ b/tests/Unit/Crypt/AES/OpenSSLTest.php @@ -12,7 +12,3 @@ protected function setUp() $this->engine = CRYPT_ENGINE_OPENSSL; } } - -class OpenSSLTest extends Unit_Crypt_AES_OpenSSLTest -{ -} diff --git a/tests/Unit/Crypt/AES/PurePHPTest.php b/tests/Unit/Crypt/AES/PurePHPTest.php index 2fe5d2c76..12161a9d8 100644 --- a/tests/Unit/Crypt/AES/PurePHPTest.php +++ b/tests/Unit/Crypt/AES/PurePHPTest.php @@ -12,7 +12,3 @@ protected function setUp() $this->engine = CRYPT_ENGINE_INTERNAL; } } - -class PurePHPTest extends Unit_Crypt_AES_PurePHPTest -{ -} diff --git a/tests/Unit/Crypt/BlowfishTest.php b/tests/Unit/Crypt/BlowfishTest.php index 014ff6a2d..87406c135 100644 --- a/tests/Unit/Crypt/BlowfishTest.php +++ b/tests/Unit/Crypt/BlowfishTest.php @@ -128,7 +128,3 @@ public function testKeySizes() } } } - -class BlowfishTest extends Unit_Crypt_BlowfishTest -{ -} diff --git a/tests/Unit/Crypt/DESTest.php b/tests/Unit/Crypt/DESTest.php index b568fc2e0..2a51d6cfe 100644 --- a/tests/Unit/Crypt/DESTest.php +++ b/tests/Unit/Crypt/DESTest.php @@ -75,7 +75,3 @@ public function testDecryptPadding() } } } - -class DESTest extends Unit_Crypt_DESTest -{ -} diff --git a/tests/Unit/Crypt/Hash/MD5Test.php b/tests/Unit/Crypt/Hash/MD5Test.php index 90f2f458b..a29695989 100644 --- a/tests/Unit/Crypt/Hash/MD5Test.php +++ b/tests/Unit/Crypt/Hash/MD5Test.php @@ -45,7 +45,3 @@ public static function hmacData() ); } } - -class MD5Test extends Unit_Crypt_Hash_MD5Test -{ -} diff --git a/tests/Unit/Crypt/Hash/SHA256Test.php b/tests/Unit/Crypt/Hash/SHA256Test.php index 488cf5587..b4b1995ad 100644 --- a/tests/Unit/Crypt/Hash/SHA256Test.php +++ b/tests/Unit/Crypt/Hash/SHA256Test.php @@ -77,7 +77,3 @@ public static function hmacData() ); } } - -class SHA256Test extends Unit_Crypt_Hash_SHA256Test -{ -} diff --git a/tests/Unit/Crypt/Hash/SHA256_96Test.php b/tests/Unit/Crypt/Hash/SHA256_96Test.php index 564aae94a..5e1f11397 100644 --- a/tests/Unit/Crypt/Hash/SHA256_96Test.php +++ b/tests/Unit/Crypt/Hash/SHA256_96Test.php @@ -30,27 +30,3 @@ public function testHMAC($key, $message, $longResult) parent::testHMAC($key, $message, substr($longResult, 0, 24)); } } - -class SHA256_96Test extends SHA256Test -{ - public function getInstance() - { - return new Crypt_Hash('sha256-96'); - } - - /** - * @dataProvider hashData() - */ - public function testHash($message, $longResult) - { - parent::testHash($message, substr($longResult, 0, 24)); - } - - /** - * @dataProvider hmacData() - */ - public function testHMAC($key, $message, $longResult) - { - parent::testHMAC($key, $message, substr($longResult, 0, 24)); - } -} diff --git a/tests/Unit/Crypt/Hash/SHA512Test.php b/tests/Unit/Crypt/Hash/SHA512Test.php index cc1dce4f9..0a0e58181 100644 --- a/tests/Unit/Crypt/Hash/SHA512Test.php +++ b/tests/Unit/Crypt/Hash/SHA512Test.php @@ -77,7 +77,3 @@ public static function hmacData() ); } } - -class SHA512Test extends Unit_Crypt_Hash_SHA512Test -{ -} diff --git a/tests/Unit/Crypt/Hash/SHA512_96Test.php b/tests/Unit/Crypt/Hash/SHA512_96Test.php index caa4d49ef..f5cdce88b 100644 --- a/tests/Unit/Crypt/Hash/SHA512_96Test.php +++ b/tests/Unit/Crypt/Hash/SHA512_96Test.php @@ -30,27 +30,3 @@ public function testHMAC($key, $message, $longResult) parent::testHMAC($key, $message, substr($longResult, 0, 24)); } } - -class SHA512_96Test extends SHA512Test -{ - public function getInstance() - { - return new Crypt_Hash('sha512-96'); - } - - /** - * @dataProvider hashData() - */ - public function testHash($message, $longResult) - { - parent::testHash($message, substr($longResult, 0, 24)); - } - - /** - * @dataProvider hmacData() - */ - public function testHMAC($key, $message, $longResult) - { - parent::testHMAC($key, $message, substr($longResult, 0, 24)); - } -} diff --git a/tests/Unit/Crypt/RC2Test.php b/tests/Unit/Crypt/RC2Test.php index 043b0605e..0ad664bbc 100644 --- a/tests/Unit/Crypt/RC2Test.php +++ b/tests/Unit/Crypt/RC2Test.php @@ -125,7 +125,3 @@ public function testVectors($engine, $engineName, $key, $keyLen, $plaintext, $ci $this->assertEquals($result, $plaintext, "Failed asserting that decrypted result yielded $plaintext as a result in $engineName engine"); } } - -class RC2Test extends Unit_Crypt_RC2Test -{ -} diff --git a/tests/Unit/Crypt/RC4Test.php b/tests/Unit/Crypt/RC4Test.php index 4a956d31e..4ba34e3d8 100644 --- a/tests/Unit/Crypt/RC4Test.php +++ b/tests/Unit/Crypt/RC4Test.php @@ -248,7 +248,3 @@ public function testKeySizes() } } } - -class RC4Test extends Unit_Crypt_RC4Test -{ -} diff --git a/tests/Unit/Crypt/RSA/LoadKeyTest.php b/tests/Unit/Crypt/RSA/LoadKeyTest.php index 8d6af28c5..18a93619a 100644 --- a/tests/Unit/Crypt/RSA/LoadKeyTest.php +++ b/tests/Unit/Crypt/RSA/LoadKeyTest.php @@ -478,7 +478,3 @@ public function testOpenSSHPrivate() $this->assertTrue($rsa->verify('zzz', $sig)); } } - -class LoadKeyTest extends Unit_Crypt_RSA_LoadKeyTest -{ -} diff --git a/tests/Unit/Crypt/RSA/ModeTest.php b/tests/Unit/Crypt/RSA/ModeTest.php index eea8e0bf9..28e91643a 100644 --- a/tests/Unit/Crypt/RSA/ModeTest.php +++ b/tests/Unit/Crypt/RSA/ModeTest.php @@ -116,7 +116,3 @@ public function testPSSSigsWithNonPowerOf2Key() $this->assertTrue($rsa->verify($payload, $sig)); } } - -class ModeTest extends Unit_Crypt_RSA_ModeTest -{ -} diff --git a/tests/Unit/Crypt/RandomTest.php b/tests/Unit/Crypt/RandomTest.php index 94af2b39f..e53efc8d5 100644 --- a/tests/Unit/Crypt/RandomTest.php +++ b/tests/Unit/Crypt/RandomTest.php @@ -51,7 +51,3 @@ protected function wrap($x) return array($x); } } - -class RandomTest extends Unit_Crypt_RandomTest -{ -} diff --git a/tests/Unit/Crypt/TripleDESTest.php b/tests/Unit/Crypt/TripleDESTest.php index 8cdd4fa68..c1f09ba14 100644 --- a/tests/Unit/Crypt/TripleDESTest.php +++ b/tests/Unit/Crypt/TripleDESTest.php @@ -186,7 +186,3 @@ public function testInnerChaining() } } } - -class TripleDESTest extends Unit_Crypt_TripleDESTest -{ -} diff --git a/tests/Unit/Crypt/TwofishTest.php b/tests/Unit/Crypt/TwofishTest.php index 24a83a601..53cfecd89 100644 --- a/tests/Unit/Crypt/TwofishTest.php +++ b/tests/Unit/Crypt/TwofishTest.php @@ -71,7 +71,3 @@ public function testVectors() } } } - -class TwofishTest extends Unit_Crypt_TwofishTest -{ -} diff --git a/tests/Unit/File/ANSITest.php b/tests/Unit/File/ANSITest.php index d64941bc7..7fa89d7ff 100644 --- a/tests/Unit/File/ANSITest.php +++ b/tests/Unit/File/ANSITest.php @@ -47,7 +47,3 @@ public function testLineOverflow() $this->assertSame(str_repeat('z', 80), $lines[22]); } } - -class ANSITest extends Unit_File_ANSITest -{ -} diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index a28670a83..00ee7c8eb 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -393,7 +393,3 @@ public function testExplicitImplicitDate() $this->assertIsArray($a); } } - -class ASN1Test extends Unit_File_ASN1Test -{ -} diff --git a/tests/Unit/File/X509/CSRTest.php b/tests/Unit/File/X509/CSRTest.php index 84736641f..f57a0e6de 100644 --- a/tests/Unit/File/X509/CSRTest.php +++ b/tests/Unit/File/X509/CSRTest.php @@ -119,7 +119,3 @@ public function testNewCSR() $x509->saveCSR($x509->signCSR('sha256WithRSAEncryption'), FILE_X509_FORMAT_DER); } } - -class CSRTest extends Unit_File_X509_CSRTest -{ -} diff --git a/tests/Unit/File/X509/SPKACTest.php b/tests/Unit/File/X509/SPKACTest.php index 2d7f0eca2..1345f45e2 100644 --- a/tests/Unit/File/X509/SPKACTest.php +++ b/tests/Unit/File/X509/SPKACTest.php @@ -96,7 +96,3 @@ public function testBadSignatureSPKAC() ); } } - -class SPKACTest extends Unit_File_X509_SPKACTest -{ -} diff --git a/tests/Unit/File/X509/X509Test.php b/tests/Unit/File/X509/X509Test.php index 2fb49e84a..9f5eeba95 100644 --- a/tests/Unit/File/X509/X509Test.php +++ b/tests/Unit/File/X509/X509Test.php @@ -856,7 +856,3 @@ public function testMultiCertPEM() $this->assertFalse($r); } } - -class X509Test extends Unit_File_X509_X509Test -{ -} diff --git a/tests/Unit/Math/BigInteger/BCMathTest.php b/tests/Unit/Math/BigInteger/BCMathTest.php index b03059947..109f81d05 100644 --- a/tests/Unit/Math/BigInteger/BCMathTest.php +++ b/tests/Unit/Math/BigInteger/BCMathTest.php @@ -18,7 +18,3 @@ public static function setUpBeforeClass() self::ensureConstant('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_BCMATH); } } - -class BCMathTest extends Unit_Math_BigInteger_BCMathTest -{ -} diff --git a/tests/Unit/Math/BigInteger/GMPTest.php b/tests/Unit/Math/BigInteger/GMPTest.php index 25ad88499..2ec2042fe 100644 --- a/tests/Unit/Math/BigInteger/GMPTest.php +++ b/tests/Unit/Math/BigInteger/GMPTest.php @@ -18,7 +18,3 @@ public static function setUpBeforeClass() self::ensureConstant('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_GMP); } } - -class GMPTest extends Unit_Math_BigInteger_GMPTest -{ -} diff --git a/tests/Unit/Math/BigInteger/InternalOpenSSLTest.php b/tests/Unit/Math/BigInteger/InternalOpenSSLTest.php index 21533b9c0..4b297d9fb 100644 --- a/tests/Unit/Math/BigInteger/InternalOpenSSLTest.php +++ b/tests/Unit/Math/BigInteger/InternalOpenSSLTest.php @@ -18,7 +18,3 @@ public static function setUpBeforeClass() self::ensureConstant('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_INTERNAL); } } - -class InternalOpenSSLTest extends Unit_Math_BigInteger_InternalOpenSSLTest -{ -} diff --git a/tests/Unit/Math/BigInteger/InternalTest.php b/tests/Unit/Math/BigInteger/InternalTest.php index bbfe8ff0d..f1fcae516 100644 --- a/tests/Unit/Math/BigInteger/InternalTest.php +++ b/tests/Unit/Math/BigInteger/InternalTest.php @@ -22,7 +22,3 @@ public function testInternalRepresentation() $this->assertSame($x->value, $y->value); } } - -class InternalTest extends Unit_Math_BigInteger_InternalTest -{ -} diff --git a/tests/Unit/Net/SFTPStreamUnitTest.php b/tests/Unit/Net/SFTPStreamUnitTest.php index fc23ec3dd..663db6d9c 100644 --- a/tests/Unit/Net/SFTPStreamUnitTest.php +++ b/tests/Unit/Net/SFTPStreamUnitTest.php @@ -31,7 +31,3 @@ public function testRegisterWithArgument() $this->assertContains($this->protocol, stream_get_wrappers()); } } - -class SFTPStreamUnitTest extends Unit_Net_SFTPStreamUnitTest -{ -} diff --git a/tests/Unit/Net/SSH1Test.php b/tests/Unit/Net/SSH1Test.php index 042cfe96d..b0b2aaed4 100644 --- a/tests/Unit/Net/SSH1Test.php +++ b/tests/Unit/Net/SSH1Test.php @@ -39,7 +39,3 @@ public function testFormatLog(array $message_log, array $message_number_log, $ex $this->assertEquals($expected, $result); } } - -class SSH1Test extends Unit_Net_SSH1Test -{ -} diff --git a/tests/Unit/Net/SSH2UnitTest.php b/tests/Unit/Net/SSH2UnitTest.php index 924b4bfef..1c8436b9d 100644 --- a/tests/Unit/Net/SSH2UnitTest.php +++ b/tests/Unit/Net/SSH2UnitTest.php @@ -117,7 +117,3 @@ protected function createSSHMock() ->getMock(); } } - -class SSH2UnitTest extends Unit_Net_SSH2UnitTest -{ -} diff --git a/travis/run-phpunit.sh b/travis/run-phpunit.sh index 2b1d90cca..92351bb22 100755 --- a/travis/run-phpunit.sh +++ b/travis/run-phpunit.sh @@ -29,6 +29,12 @@ then find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertIsString([^)]*)\)/\1: void/g' find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertStringContainsString([^)]*)\)/\1: void/g' find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/\(n assertStringNotContainsString([^)]*)\)/\1: void/g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Unit_Crypt_\(AES\|Hash\|RSA\)_/class /g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Unit_File_\(X509\)_/class /g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Unit_Math_\(BigInteger\)_/class /g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Unit_\(Crypt\|File\|Math\|Net\)_/class /g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/^class Functional_Net_/class /g' + find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/extends Unit_Crypt_Hash_\(SHA512Test\|SHA256Test\)/extends \1/g' fi if [ "$TRAVIS_PHP_VERSION" = 'hhvm' -o `php -r "echo (int) version_compare(PHP_VERSION, '7.0', '>=');"` = "1" ] From 360afd93c80449e6c5dd70856c6fd83ad2a64805 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 12 Dec 2020 22:02:16 -0600 Subject: [PATCH 26/69] fix bad merge --- tests/Unit/Crypt/Hash/SHA256_96Test.php | 4 ++++ tests/Unit/Crypt/Hash/SHA512_96Test.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/tests/Unit/Crypt/Hash/SHA256_96Test.php b/tests/Unit/Crypt/Hash/SHA256_96Test.php index 85aaf295e..24a09be48 100644 --- a/tests/Unit/Crypt/Hash/SHA256_96Test.php +++ b/tests/Unit/Crypt/Hash/SHA256_96Test.php @@ -7,6 +7,10 @@ use phpseclib\Crypt\Hash; +if (version_compare(PHP_VERSION, '7.0', '>=')) { + require 'SHA256Test.php'; +} + class Unit_Crypt_Hash_SHA256_96Test extends Unit_Crypt_Hash_SHA256Test { public function getInstance() diff --git a/tests/Unit/Crypt/Hash/SHA512_96Test.php b/tests/Unit/Crypt/Hash/SHA512_96Test.php index 760fa243a..0d48a7fb4 100644 --- a/tests/Unit/Crypt/Hash/SHA512_96Test.php +++ b/tests/Unit/Crypt/Hash/SHA512_96Test.php @@ -7,6 +7,10 @@ use phpseclib\Crypt\Hash; +if (version_compare(PHP_VERSION, '7.0', '>=')) { + require 'SHA512Test.php'; +} + class Unit_Crypt_Hash_SHA512_96Test extends Unit_Crypt_Hash_SHA512Test { public function getInstance() From 61d885630f75e168fa738feed5ff88c35152f311 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 12 Dec 2020 22:32:46 -0600 Subject: [PATCH 27/69] CS adjustment --- build/code-sniffer-ruleset-tests.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/code-sniffer-ruleset-tests.xml b/build/code-sniffer-ruleset-tests.xml index 17f00d1d8..8767eee94 100644 --- a/build/code-sniffer-ruleset-tests.xml +++ b/build/code-sniffer-ruleset-tests.xml @@ -11,7 +11,7 @@ using underscore. --> - + From 194e64244824eee9fd37fc8fa0605fef26f951ba Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 15 Dec 2020 08:25:42 -0600 Subject: [PATCH 28/69] SSH2: handle keepalive@openssh.com packets --- phpseclib/Net/SSH2.php | 112 +++++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 50 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 17125801a..ce007b069 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -3351,6 +3351,57 @@ function _reset_connection($reason) */ function _get_binary_packet($skip_channel_filter = false) { + if ($skip_channel_filter) { + $read = array($this->fsock); + $write = $except = null; + + if ($this->curTimeout <= 0) { + if ($this->keepAlive <= 0) { + @stream_select($read, $write, $except, null); + } else { + if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + return $this->_get_binary_packet(true); + } + } + } else { + if ($this->curTimeout < 0) { + $this->is_timeout = true; + return true; + } + + $read = array($this->fsock); + $write = $except = null; + + $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 + + if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) { + if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + $elapsed = strtok(microtime(), ' ') + strtok('') - $start; + $this->curTimeout-= $elapsed; + return $this->_get_binary_packet(true); + } + $elapsed = strtok(microtime(), ' ') + strtok('') - $start; + $this->curTimeout-= $elapsed; + } + + $sec = floor($this->curTimeout); + $usec = 1000000 * ($this->curTimeout - $sec); + + // on windows this returns a "Warning: Invalid CRT parameters detected" error + if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) { + $this->is_timeout = true; + if ($client_channel == NET_SSH2_CHANNEL_EXEC && !$this->request_pty) { + $this->_close_channel($client_channel); + } + return true; + } + $elapsed = strtok(microtime(), ' ') + strtok('') - $start; + $this->curTimeout-= $elapsed; + } + } + if (!is_resource($this->fsock) || feof($this->fsock)) { $this->bitmap = 0; user_error('Connection closed prematurely'); @@ -3502,9 +3553,19 @@ function _filter($payload, $skip_channel_filter) // only called when we've already logged in if (($this->bitmap & NET_SSH2_MASK_CONNECTED) && $this->isAuthenticated()) { switch (ord($payload[0])) { + case NET_SSH2_MSG_CHANNEL_REQUEST: + if (strlen($payload) == 31) { + extract(unpack('cpacket_type/Nchannel/Nlength', $payload)); + if (substr($payload, 9, $length) == 'keepalive@openssh.com' && isset($this->server_channels[$channel])) { + if (ord(substr($payload, 9 + $length))) { // want reply + $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_SUCCESS, $this->server_channels[$channel])); + } + $payload = $this->_get_binary_packet($skip_channel_filter); + } + } + break; case NET_SSH2_MSG_CHANNEL_DATA: case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA: - case NET_SSH2_MSG_CHANNEL_REQUEST: case NET_SSH2_MSG_CHANNEL_CLOSE: case NET_SSH2_MSG_CHANNEL_EOF: if (!$skip_channel_filter && !empty($this->server_channels)) { @@ -3702,55 +3763,6 @@ function _get_channel_packet($client_channel, $skip_extended = false) $response = $this->binary_packet_buffer; $this->binary_packet_buffer = false; } else { - $read = array($this->fsock); - $write = $except = null; - - if ($this->curTimeout <= 0) { - if ($this->keepAlive <= 0) { - @stream_select($read, $write, $except, null); - } else { - if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { - $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); - continue; - } - } - } else { - if ($this->curTimeout < 0) { - $this->is_timeout = true; - return true; - } - - $read = array($this->fsock); - $write = $except = null; - - $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 - - if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) { - if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { - $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); - $elapsed = strtok(microtime(), ' ') + strtok('') - $start; - $this->curTimeout-= $elapsed; - continue; - } - $elapsed = strtok(microtime(), ' ') + strtok('') - $start; - $this->curTimeout-= $elapsed; - } - - $sec = floor($this->curTimeout); - $usec = 1000000 * ($this->curTimeout - $sec); - - // on windows this returns a "Warning: Invalid CRT parameters detected" error - if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) { - $this->is_timeout = true; - if ($client_channel == NET_SSH2_CHANNEL_EXEC && !$this->request_pty) { - $this->_close_channel($client_channel); - } - return true; - } - $elapsed = strtok(microtime(), ' ') + strtok('') - $start; - $this->curTimeout-= $elapsed; - } - $response = $this->_get_binary_packet(true); if ($response === false) { $this->bitmap = 0; From d904f08a46a36e17ee74ca49059f20961f37a279 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 15 Dec 2020 08:43:21 -0600 Subject: [PATCH 29/69] SSH2: last merge should have used microtime(true) but didn't --- phpseclib/Net/SSH2.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index c5f2e0156..3f6511902 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -3358,16 +3358,16 @@ function _get_binary_packet($skip_channel_filter = false) $read = array($this->fsock); $write = $except = null; - $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838 + $start = microtime(true); if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) { if (!@stream_select($read, $write, $except, $this->keepAlive) && !count($read)) { $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); - $elapsed = strtok(microtime(), ' ') + strtok('') - $start; + $elapsed = microtime(true) - $start; $this->curTimeout-= $elapsed; return $this->_get_binary_packet(true); } - $elapsed = strtok(microtime(), ' ') + strtok('') - $start; + $elapsed = microtime(true) - $start; $this->curTimeout-= $elapsed; } @@ -3382,7 +3382,7 @@ function _get_binary_packet($skip_channel_filter = false) } return true; } - $elapsed = strtok(microtime(), ' ') + strtok('') - $start; + $elapsed = microtime(true) - $start; $this->curTimeout-= $elapsed; } } From f0501ff72b5f3b90c0e66ff5d1b886771089af38 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 15 Dec 2020 23:11:54 -0600 Subject: [PATCH 30/69] SSH2: get_binary_packet() doesn't know about channel type --- phpseclib/Net/SSH2.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index ce007b069..fb4584662 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -3392,9 +3392,6 @@ function _get_binary_packet($skip_channel_filter = false) // on windows this returns a "Warning: Invalid CRT parameters detected" error if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) { $this->is_timeout = true; - if ($client_channel == NET_SSH2_CHANNEL_EXEC && !$this->request_pty) { - $this->_close_channel($client_channel); - } return true; } $elapsed = strtok(microtime(), ' ') + strtok('') - $start; @@ -3764,6 +3761,9 @@ function _get_channel_packet($client_channel, $skip_extended = false) $this->binary_packet_buffer = false; } else { $response = $this->_get_binary_packet(true); + if ($response === true && $this->is_timeout && $client_channel == NET_SSH2_CHANNEL_EXEC && !$this->request_pty) { + $this->_close_channel($client_channel); + } if ($response === false) { $this->bitmap = 0; user_error('Connection closed by server'); From 8d567cdf29531bfb425e4f3f09d7b53cf2974924 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 16 Dec 2020 08:26:03 -0600 Subject: [PATCH 31/69] SSH2: keepalive tweak --- phpseclib/Net/SSH2.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index fb4584662..5ebad7089 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -3761,8 +3761,11 @@ function _get_channel_packet($client_channel, $skip_extended = false) $this->binary_packet_buffer = false; } else { $response = $this->_get_binary_packet(true); - if ($response === true && $this->is_timeout && $client_channel == NET_SSH2_CHANNEL_EXEC && !$this->request_pty) { - $this->_close_channel($client_channel); + if ($response === true && $this->is_timeout)) { + if ($client_channel == NET_SSH2_CHANNEL_EXEC && !$this->request_pty) { + $this->_close_channel($client_channel); + } + return true; } if ($response === false) { $this->bitmap = 0; From 0399faa86b9c046be49a9deed2b28d28936afc13 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 16 Dec 2020 09:10:35 -0600 Subject: [PATCH 32/69] SSH2: syntax error --- phpseclib/Net/SSH2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 5ebad7089..ca559af5a 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -3761,7 +3761,7 @@ function _get_channel_packet($client_channel, $skip_extended = false) $this->binary_packet_buffer = false; } else { $response = $this->_get_binary_packet(true); - if ($response === true && $this->is_timeout)) { + if ($response === true && $this->is_timeout) { if ($client_channel == NET_SSH2_CHANNEL_EXEC && !$this->request_pty) { $this->_close_channel($client_channel); } From b2bdbaa4f422b962425645a2e35e090929789614 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 16 Dec 2020 23:32:16 -0600 Subject: [PATCH 33/69] README: update for 3.0.0 release --- README.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 679113c0b..ae14d6854 100644 --- a/README.md +++ b/README.md @@ -10,16 +10,16 @@ ## Introduction -MIT-licensed pure-PHP implementations of an arbitrary-precision integer -arithmetic library, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael, -AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509 +MIT-licensed pure-PHP implementations of the following: + +SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 / Ed449 / Curve25519 / Curve449, ECDSA / ECDH (with support for 66 curves), RSA (PKCS#1 v2.2 compliant), DSA / DH, DES / 3DES / RC4 / Rijndael / AES / Blowfish / Twofish / Salsa20 / ChaCha20, GCM / Poly1305 * [Browse Git](https://github.com/phpseclib/phpseclib) ## Documentation -* [Documentation / Manual](http://phpseclib.sourceforge.net/) -* [API Documentation](https://api.phpseclib.org/1.0/) (generated by Doctum) +* [Documentation / Manual](https://phpseclib.com/) +* [API Documentation](https://api.phpseclib.com/1.0/) (generated by Doctum) ## Branches @@ -29,6 +29,14 @@ AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509 * Unstable API * Do not use in production +### 3.0 + +* Long term support (LTS) release +* Major expansion of cryptographic primitives +* Minimum PHP version: 5.6.1 +* PSR-4 autoloading with namespace rooted at `\phpseclib3` +* Install via Composer: `composer require phpseclib/phpseclib:~3.0` + ### 2.0 * Long term support (LTS) release From 136b9ca7eebef78be14abf90d65c5e57b6bc5d36 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 16 Dec 2020 23:42:04 -0600 Subject: [PATCH 34/69] CHANGELOG: add 2.0.30 entry --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 671f50d64..5c98733b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 2.0.30 - 2020-12-16 + +- X509: don't attempt to parse multi-cert PEMs (#1542) +- SFTP: add stream to get method (#1546) +- SFTP: progress callback should report actual downloaded bytes (#1543) +- SSH2: end connection faster for algorithm mismatch +- SSH2: add setKeepAlive() method (#1529) +- ANSI: fix PHP8 compatibility issues + ## 2.0.29 - 2020-09-07 - SFTP: add enableDatePreservation() / disableDatePreservation() (#1496) From cfa7d491bff41038637077dbf7ba89e8f9a5a18c Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 17 Dec 2020 08:48:04 +0100 Subject: [PATCH 35/69] Simplify test --- travis/run-phpunit.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/travis/run-phpunit.sh b/travis/run-phpunit.sh index 92351bb22..31b98afcf 100755 --- a/travis/run-phpunit.sh +++ b/travis/run-phpunit.sh @@ -20,7 +20,7 @@ then PHPUNIT_ARGS="$PHPUNIT_ARGS -d zend.enable_gc=0" fi -if [ `php -r "echo (int) version_compare(PHP_VERSION, '7.3', '>=');"` = "1" ] +if $PHPUNIT --atleast-version 9 then find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/n setUpBeforeClass()/n setUpBeforeClass(): void/g' find tests -type f -name "*.php" -print0 | xargs -0 sed -i 's/n setUp()/n setUp(): void/g' From c21147a5bddf3277986c07d5f2d17c5c4a179ff7 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 19 Dec 2020 01:05:36 -0600 Subject: [PATCH 36/69] SFTP: clean up real time logging --- phpseclib/Net/SFTP.php | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index 72eafcadd..577027eb1 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -3065,9 +3065,17 @@ function _send_sftp_packet($type, $data, $request_id = 1) $packet_type = '-> ' . $this->packet_types[$type] . ' (' . round($stop - $start, 4) . 's)'; if (NET_SFTP_LOGGING == NET_SFTP_LOG_REALTIME) { - echo "
\r\n" . $this->_format_log(array($data), array($packet_type)) . "\r\n
\r\n"; - flush(); - ob_flush(); + switch (PHP_SAPI) { + case 'cli': + $start = $stop = "\r\n"; + break; + default: + $start = '
';
+                        $stop = '
'; + } + echo $start . $this->_format_log(array($data), array($packet_type)) . $stop; + @flush(); + @ob_flush(); } else { $this->packet_type_log[] = $packet_type; if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) { @@ -3174,9 +3182,17 @@ function _get_sftp_packet($request_id = null) $packet_type = '<- ' . $this->packet_types[$this->packet_type] . ' (' . round($stop - $start, 4) . 's)'; if (NET_SFTP_LOGGING == NET_SFTP_LOG_REALTIME) { - echo "
\r\n" . $this->_format_log(array($packet), array($packet_type)) . "\r\n
\r\n"; - flush(); - ob_flush(); + switch (PHP_SAPI) { + case 'cli': + $start = $stop = "\r\n"; + break; + default: + $start = '
';
+                        $stop = '
'; + } + echo $start . $this->_format_log(array($packet), array($packet_type)) . $stop; + @flush(); + @ob_flush(); } else { $this->packet_type_log[] = $packet_type; if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) { From 1f66009c1b833c08ae6d602769478c28efa79623 Mon Sep 17 00:00:00 2001 From: William Desportes Date: Sat, 19 Dec 2020 21:28:29 +0100 Subject: [PATCH 37/69] Fix a Doctum 5.3.0-dev phpdoc reported error --- phpseclib/Net/SSH2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index b86a3fc4d..494abf7aa 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -2705,7 +2705,7 @@ function setTimeout($timeout) * * Sends an SSH2_MSG_IGNORE message every x seconds, if x is a positive non-zero number. * - * @param mixed $timeout + * @param int $interval * @access public */ function setKeepAlive($interval) From 9de5f3f8ed134b1409cff2056a8db987a40229f8 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 7 Jan 2021 20:21:27 -0600 Subject: [PATCH 38/69] X509: always parse the first cert of a bundle --- phpseclib/File/X509.php | 9 +- tests/Unit/File/X509/X509Test.php | 191 ++++++++++++++++-------------- 2 files changed, 105 insertions(+), 95 deletions(-) diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 6dd598bd0..07fd911d1 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -5144,9 +5144,12 @@ function _extractBER($str) * subject=/O=organization/OU=org unit/CN=common name * issuer=/O=organization/CN=common name */ - $temp = strlen($str) <= ini_get('pcre.backtrack_limit') ? - preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1) : - $str; + if (strlen($str) > ini_get('pcre.backtrack_limit')) { + $temp = $str; + } else { + $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1); + $temp = preg_replace('#-+END.*[\r\n ]*.*#ms', '', $str, 1); + } // remove new lines $temp = str_replace(array("\r", "\n", ' '), '', $temp); // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff diff --git a/tests/Unit/File/X509/X509Test.php b/tests/Unit/File/X509/X509Test.php index 9f5eeba95..68c47a879 100644 --- a/tests/Unit/File/X509/X509Test.php +++ b/tests/Unit/File/X509/X509Test.php @@ -754,100 +754,107 @@ public function testRandomString() public function testMultiCertPEM() { $a = '-----BEGIN CERTIFICATE----- -MIIL/DCCCuSgAwIBAgIQNC96aabFWNAAAAAAXBAmjjANBgkqhkiG9w0BAQsFADCB -uTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsT -H1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAy -MDE4IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEtMCsG -A1UEAxMkRW50cnVzdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBWTUMxMB4XDTIw -MDUxNDE4NDgwNloXDTIwMTEwOTE5MTgwNFowggE+MQ4wDAYDVQQREwU5NTEyNTEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCFNhbiBK -b3NlMRowGAYDVQQJExEyMDY1IEhhbWlsdG9uIEF2ZTETMBEGCysGAQQBgjc8AgED -EwJVUzEZMBcGCysGAQQBgjc8AgECEwhEZWxhd2FyZTESMBAGA1UEChMJZUJheSBJ -bmMuMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4GA1UEBRMHMjg3 -MTM1MjEXMBUGCisGAQQBg55fAQQTBzQ0MDg0MjMxEjAQBgorBgEEAYOeXwEDEwJV -UzElMCMGCisGAQQBg55fAQITFWh0dHBzOi8vd3d3LnVzcHRvLmdvdjESMBAGA1UE -AxMJZUJheSBJbmMuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmaPd -qOlOyWc8n6MKXI8eIrKgketOTdxuoW1RzfmXB924j2WBzRqNFqcISCYN3a0VpMe3 -AqG9A+YyCWCJWmXdTZkAz3LeJCPTqbzf2nigXYfJX1KFhK96eVVcbirIhRtS4O5G -qYw8v4rokp8YFg/W+c+80i/egNYr4VZCC5zawaYBwtgMkUomSXqz3Yv7JkfZsv5q -pSLD5aO2wSIPjCiPpYzxDO2b/kX1goV6Oyvd4PTmvYteER01cx37dkj2mf/bTdrB -nHAyOF8+84ItHiZjHpi7MIxcmvi40wcPszPsx2GKyQ1604TVR6p+ZT9Gt4qMaJ7h -I7FQCl2dUOEzSF/4NwIDAQABo4IHdjCCB3IwggVkBggrBgEFBQcBDASCBVYwggVS -ooIFTqCCBUowggVGMIIFQjCCBT4WDWltYWdlL3N2Zyt4bWwwMzAxMA0GCWCGSAFl -AwQCAQUABCDQkSARaDrob8re0CIWy2UxJ97L55pY729ITDKZYPUWLTCCBPYWggTy -ZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxINHNJQUFBQUFBQUFBSFZWNzIvYk5o -RDluQUw3SDFqdFV3R1JKaWxLb2x5N1JiTTJUWUVWR0xBdDN4MWFrNHhva21FcHR0 -T2kvM3Z2SFpVbXdGWUR0czZQOStQZHU2TzllbnYrdHhQSCtqRHVobjZkR0tVVFVm -ZGgyTzc2WnAzOC9kZVY5TW5iTjcrOFdMMlVVbnlzKy9xd21ZYkRVcnpiRHJlMStO -UjE5K1BFa0xCV1VYUXEvcno1S0Q2Yzk4TmhFbjkwOTQzODFBdkY0RTBzc2hTRjBs -cGMzdSs2cmRDdmhKQVMrY2RqODV5R1NRUVI2OGQxMGs3VGZybFluRTRuZGNyVWNH -Z1dWbXU5SVAvWlpYbnVkdjNkL3ptYXFxb1dmRXF1NjBUdno0bDRtSi9IWFgyNkhJ -QUtMYXozZUNkaW5CNjZlcDNVL2VhMnErWHRKdHcxaCtHKzN5NzcraVNlZWI3bTJz -dHh2d25rdmovVVkzMDQxZ2szZ2hSaWV0alR3VlNmcDBVWVJ4eGNxSEhTWC8vWmRk -M3kxeXQrdmY0V1VmT0k1dSt1dEgxRTdZeCt5RE9iK1VjMG0xR3RDL2YraDYrYlVW -OWNlbE1DWFMyWUJ3ZzFZcmRkSjVkM0RiTllIZW93aWRCdFJ0S1dHQ1hpdE50TzdU -cmgvdHQ2MTdSVC9MSkE4S0o1U3ZINzBBd3hCOENMaTlWK003VlBxV2hrNVBUWmxG -cVoxTGhDWlVGNlZhWmFaZEk0WUtxS1JxbUtvTk9NempLeXk5Um9sY01JQnFFNk5i -bHlNaWVNRFFySk95Mk5vTmR2cHZUS2NYYWJtdkxKK2xIemkvaHNLc094WGxrcVk1 -VlBjWXA4UkNYMUxiR3FndFRLU2l0Qmppanhzd2hrZW5Ja21sb1ZvQ21OWjJvRmln -ZHBESklCTkpMcVJzTmtLZzlhY2hNZUlXalJFc2pNUTh4dTZLamtwN0YwUWdaYW9y -Q1NhdWF5UWsxTEhNaUlwZkpZQ2Z4ZHpGMm92SVZsZ2tGVjlHSk1qS3RTYStCR1Zp -RE1rWWJXcE15RENoYkszTEFhWDNpbS94bWNqWVB6Sld0b1NEWGk1MlJGTGZySWls -cU1WcEFsWkFUZ1VnWWRwS2FUYTRTVCtEbEdidHlqWkZHVUV1UlRDcXJvaUJxREZY -THNCbWJ2cFVVdjBLVlVycTB3SFFOWDNoeDB4L1V0ZTVGRnA2Q3FwWFdrYVVWVTJj -QVBVS3hKckdobUZKSFJidEJadEFJR0JXVXlIbW1jVVVwUitaSGUxeUQrRTRHeWVi -TXR4bThLUXpyUUN2R2lra1lPRDRoTWhTdmlVV0E2L0RIRGtwM3BLNm5nOEFBYXQx -a1h5Smc3OUJnN1JmYjBXU1dTdENxeDRqcFhCV2xUZEJvdG1ZQ1dDY0lPV01rZTJO -Y1NmV3BXbGpyRER0dG8wSWVQNnBDR0VJMDdoMmdsV3pUWk9GZkNzTG94bWNNRjRy -VjF1Q0s0R3kyQ0EyNVB4bGU3NFB2Rm0zdkRKSDhpb29zaVdzZUxpeFk2YVVtdmxJ -VFBlTEhMeml1V3pIWThiT2xvb2kzNjZ3eGt6a2dndGlTc2E4NDBGNXQvcCtaUCtt -OTQ4eDB2cWU2eTJRWUFBQT09MB8GA1UdEQQYMBaCCGViYXkuY29tggplYmF5LmNv -LnVrMIGJBgorBgEEAdZ5AgQCBHsEeQB3AHUAVYHUwhaQNgFK6gubVzxT8MDkOHhw -JQgXL6OqHQcT0wwAAAFyFJ9ciQAABAMARjBEAiBI40aXqg6PJiDDf8vz4RP9cKay -kBSUjs5oGiPJlBmJCAIgAeJzF/JVCiXbjgxPL9QTjYe+wn1DHqhzsjBWEoKYiZYw -EwYDVR0lBAwwCgYIKwYBBQUHAx8wDgYDVR0PAQH/BAQDAgeAMGYGCCsGAQUFBwEB -BFowWDAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMQYIKwYB -BQUHMAKGJWh0dHA6Ly9haWEuZW50cnVzdC5uZXQvdm1jMS1jaGFpbi5jZXIwMgYD -VR0fBCswKTAnoCWgI4YhaHR0cDovL2NybC5lbnRydXN0Lm5ldC92bWMxY2EuY3Js -ME8GA1UdIARIMEYwNgYKYIZIAYb6bAoBCzAoMCYGCCsGAQUFBwIBFhpodHRwOi8v -d3d3LmVudHJ1c3QubmV0L3JwYTAMBgorBgEEAYOeXwEBMB8GA1UdIwQYMBaAFIu2 -OXbQNJCmP2LhZOo+vPR8RqFzMB0GA1UdDgQWBBRMIHPmuhcI/NyAybe3LKA1gblR -/zAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAjBJ/SPTRn8/kjfhLOBnhe -5QPkifZjsLqHJyWUCUoqFfKKazq6T6STMLl0drbsVWyc0Mh6sUSgUwh4Hn0DmGHu -ghDF5JCtoPYUz+G7l1BsAlGOvYd0H9ZcmgvfhiIjpn98Go4O/gXlK1oCd/jMIOMH -bOVB9BLb5ppf9uU2TCxTY67qUx5YylT3bfF4TVM0ZOYERQSZNByRNcFaku+FUpzU -JHHoDqokPw+0AFG2NgPiNhOg/nPh/pEWUYj5qjqgXP/hEvXerSFhdp6sN2OxES7p -GkO+J90tl9B7UQVtTO1bgGq98HIRdfusGzK5IG2MMT1CtPYR8S01mkf7KMiHK1zb +MIILODCCCSCgAwIBAgIQDh0LGipJ++wxFLj8X5MXKDANBgkqhkiG9w0BAQsFADCB +kDELMAkGA1UEBhMCVVMxDTALBgNVBAgTBFV0YWgxDTALBgNVBAcTBExlaGkxFzAV +BgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29t +MS8wLQYDVQQDEyZEaWdpQ2VydCBWZXJpZmllZCBNYXJrIEludGVybWVkaWF0ZSBD +QTAeFw0yMDA3MzAwMDAwMDBaFw0yMTAxMjUxMjAwMDBaMIIBDjEdMBsGA1UEDxMU +UHJpdmF0ZSBPcmdhbml6YXRpb24xEzARBgsrBgEEAYI3PAIBAxMCVVMxGTAXBgsr +BgEEAYI3PAIBAhMIRGVsYXdhcmUxEDAOBgNVBAUTBzM2MzMwMTkxGTAXBgNVBAkT +EDEwMDAgVyBNYXVkZSBBdmUxDjAMBgNVBBETBTk0MDg1MQswCQYDVQQGEwJVUzET +MBEGA1UECBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJU3Vubnl2YWxlMR0wGwYDVQQK +ExRMaW5rZWRJbiBDb3Jwb3JhdGlvbjESMBAGCisGAQQBg55fAQMTAlVTMRcwFQYK +KwYBBAGDnl8BBBMHNTY3NTczOTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAOCl7WccAcvSaf5+pNsV82VjFuwdzEwjDYESZmIuurz95e+JtJZst/M3Hw90 +YxKSDV4LdaVFAogXy2F+Npit1KhbBEb8vbBkm4LJ3iM8teE/10JugLyxrcVi3LSj +iKHs+rqxcTJsVYoR+CuPLuAbu4xKi+xQ4tVafrFd0Y21n6OL8nB2SRISHF58kRXq +UDW/NippF1AhcdCc5L5EmXFPCpyWfv+UXgTj9i+/I9AWUC3diHckb5NXd/wS7Jmq +5FE0uixRGTixI5a9uZr0jasTtfhlVtvqFyDmzARB/q9IU0eXm3dtcCJISIXGum6o +yCFUk8pyYsGd/M5Fyw7zbmEqsucCAwEAAaOCBgswggYHMB8GA1UdIwQYMBaAFOsN +zmX0UnV7TbPUsz0w41AYq+NuMB0GA1UdDgQWBBSkuL0+t0wu/+y2xkUY/FOSsiuV +ODAXBgNVHREEEDAOggxsaW5rZWRpbi5jb20wEwYDVR0lBAwwCgYIKwYBBQUHAx8w +gZkGA1UdHwSBkTCBjjBFoEOgQYY/aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp +Z2lDZXJ0VmVyaWZpZWRNYXJrSW50ZXJtZWRpYXRlQ0EuY3JsMEWgQ6BBhj9odHRw +Oi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRWZXJpZmllZE1hcmtJbnRlcm1l +ZGlhdGVDQS5jcmwwUAYDVR0gBEkwRzA3BglghkgBhv1sCgEwKjAoBggrBgEFBQcC +ARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAMBgorBgEEAYOeXwEBMF4G +CCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2VydHMuZGlnaWNl +cnQuY29tL0RpZ2lDZXJ0VmVyaWZpZWRNYXJrSW50ZXJtZWRpYXRlQ0EuY3J0MAwG +A1UdEwEB/wQCMAAwggOsBggrBgEFBQcBDASCA54wggOaooIDlqCCA5IwggOOMIID +ijCCA4YWDWltYWdlL3N2Zyt4bWwwIzAhMAkGBSsOAwIaBQAEFGckN8uhuoNkcXXh +wRAm7wkz4JRLMIIDThaCA0pkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LEg0c0lB +QUFBQUFBQUNsMVR5MjdiTUJDODl5c0k5VXlhKytLanNITElJVWlCRnVqSjkxUlJR +cUdLSGNTQ25PYnJ1NVRVQkMwTVNKN2w3SEozZHJRL3o0OW03bC9PdytuWU51Q3dN +YTlQNC9IY05tV2Fuci9zZHBmTHhWM0luVjRlZCtpOTN5bS9NWmZoZmlwdEUySm9U +T21IeHpKdFlCNzZ5L1hwdFcyODhVWWpab24rdkR2M1AxNU9EOFBZdDgwMEhIL2I1 +M056dForR2FleXZ2ZzNIWC8zOTErTit0K0w5ODkxVWpITEh0dm5zWTB6WFd1Ryti +YjVMQkJkek5vR2NSTHdGenk1NzdpeWk4eHlzUXdETDNnR2dnZWlZWTBYczJWQjJu +T0ZRODFQb0hBcVltaFBGUUhLRXVSTDBIdk5CbHhBTGgrQlNsazZwb0R3VXJnUU1i +R3QxcVVBazJwVjlBRS9PQitxc0k1S2xwUlN0cG5GSWxSSlo3RWVDZHZQVzdQNmQ5 +T2JtWmgwVFdGd01ZakJrNXlHVnBFc0pNbU1BUjVHS1hmRmhPMzU3cWwwbnNFRGVl +Y29kQmcyVFZVblFjSFJBYkJBMHRDTGRpTDQ4OHRrdVVkZzRkbzF1SExzRlY0cjlD +Q3BsMXRJeDZKemVnMFZ4T2RGeUFTODhMMm03WU1sNnl1QkN5bVpycnNUb2N1YVpS +S094YUZhUXV5UTZGNXJ0cGI3UnUxd1N0SXdPcVV2NkZORjRWdFVqR1dGdEp2NUZn +S3p5d3d4TWprUnVXZFFBZEdEZEJqSjIzdXJGVEdvT0liU3FHRUZhNjc0RGJUQkg0 +eTBuOVFBWjBqWHE2WVpDckhZNmlGYlI3cXYwa04rVi8zK0RIdXB2WFdLQXJNcWdF +YThWTXBXbytXRkdVcURPVWkxVXh3M3BJR20yUzZ4VXgyU0FlVUc2V2xGVDUvVnN0 +S3FkVitlcWtwNHFTTHFnQlJTcmpnRzFTTlRCb0pETE10ZWpHTWEwT0hyNVg3Q3VZ +cXlPaC9WMFhwNjNJWUxTMTl4YUtlZGx0UHFsWDMzNkEwYlJhNW9nQkFBQTCBigYK +KwYBBAHWeQIEAgR8BHoAeAB2AFVZU64wlgCAbNLrUgimyZ6TGCisEFa0QhxVNhVM +X3WsAAABc6DTF3wAAAQDAEcwRQIgRsnN1miYsyCMT234C14MaMgSAgKHXmc7RrBM +a/1ovTMCIQCOc/THDvltzhZrtnoRSbjc2EYp57A0VVHvduQPa7FKBDANBgkqhkiG +9w0BAQsFAAOCAgEA8UQt5jcUeOaDkhvbLq380Oq1Jy8Vr1BO1GPisn20KRCz/NvE +56f8hhmZlZ1xXfOM+JCaGQnwVwcRBQtLQ/+6bmeT8/WM3hf9A5rP0g0ZxvaAlQtu +e6UjvgnNx02QOKNPrmxN0rW8s24kUi0OAf1ump3SY5Ab+S+ywRG7Ah+3qch+FwA8 +CYau9TgV5kvfYDRULBM84EeFhsPcwT+YJ5u7RvkGQobqNao21Ti5tupiks/9NzI8 +splBS77Z6bPdFGvZ7pJdXiiDB2+SZdyv8iqDFM6mKRbOcuwAHcTY2zVhcS46H7SO +8OU7L/2y0XQB1rMtQDarCKwdAcsAb2e+N8mYQ0glQX4k41Sf4saMXsU1EjnOCUas +YxvVgJRD+fe4JWf8EO59fElzkrQsT3guBIzV5Kg1dYaCHngCYQIakjKQM0eKxZ3d +vn4648A0vXynhJUThOSxN4jbvVA5uYYHqHDMjJtkBPDA7HtLSIxRNattshOAoeC5 +LMszAsL9th/WoXkAa2lTs2kashOHEpx+ncGactrL8tu7dvU01Yk6yP1QAjFEo1Nt +8umUG7jQQIuquB2ry4qzFuQvKpbNQZ//9RsSmq1nni+DEKd/S63N7T8M0FpioLVm +Z2OXFTCG5ORjPUOyMGjxzjEPZWmTOG+gqNOc0HKXbuBAsGZbK4dind+YdZE= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIFJzCCBA+gAwIBAgIRALPSJ9szCF4XAAAAAFHTkx8wDQYJKoZIhvcNAQELBQAw -gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL -Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg -MjAwOSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw -BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy -MB4XDTE5MDQxNjE1NDU0M1oXDTMwMTExNjE2MTU0M1owgbkxCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 -c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxOCBFbnRydXN0LCBJ -bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxLTArBgNVBAMTJEVudHJ1c3Qg -Q2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gVk1DMTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAOrOE7nPsgxnWadbz0f0D+btzyoxflXpbrILq358XJUn6MRq -k1m9BmK35G7bf0myFreyx60Rxcj+SvNRsraMd6FUzDuOccfK3PzbUktMKPxMBFh7 -R4/ZSNBMTko2fn7jhRPdFW9k0N+sSKtHwhu0xw8qzGg8oFRJgJgpxZv1zzrny43E -IuRiozQgg2J3ZzY4ova0s/BM/SLqdsGo+Jc68S7jsI6K7zKvw0FB3T6SWYxrBc1p -GsYvlmbCrDs3AP0Jcuske1GlLzFUpUkrvx4na9i4t7XhxVcwz3AuMRbU4nHDIc0w -tLG9Fm24xB31kSqybtpxEGC/oNybhCWjQDqYW58CAwEAAaOCASEwggEdMA4GA1Ud -DwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMBMGA1UdJQQMMAoGCCsGAQUF -BwMfMDsGA1UdIAQ0MDIwMAYEVR0gADAoMCYGCCsGAQUFBwIBFhpodHRwOi8vd3d3 -LmVudHJ1c3QubmV0L3JwYTAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0 -dHA6Ly9vY3NwLmVudHJ1c3QubmV0MDAGA1UdHwQpMCcwJaAjoCGGH2h0dHA6Ly9j -cmwuZW50cnVzdC5uZXQvZzJjYS5jcmwwHQYDVR0OBBYEFIu2OXbQNJCmP2LhZOo+ -vPR8RqFzMB8GA1UdIwQYMBaAFGpyJnrQHu995ztpUdRsjZ+QEmarMA0GCSqGSIb3 -DQEBCwUAA4IBAQBphKvXT6JDtmuQAhgH8nZ5Xo9LlymnCw5fiGpQJ13rsr2A2Jnl -1Z8poTwskM71kIImRctlYs2Q52Sgvd0egxvcPELQSL7BMGPU42BijWCEvnD8GZvU -/1x5pOg0F2SiEQ5ycmC9ADr2EskcbqMh2QMOOlNV4JfFjtUY1JCTviOWJ7O29wsE -aVMiY6EdrsN1hjqmwaxfzTVikM5m+jgUKWqK3U+56outMWziOfxcpo+Ur67hTglc -fTUKIRMTGhDMVFbwW5O2jINlBjGt5yAbhI/LnRwPvB99LFkISKX50c2NDEkOzEPp -mDaPrsUl15evEah6amsBfpQiWRbKpDLKs1kF +MIIHLzCCBRegAwIBAgIQDZXVhKBTvJ0ZjW6meNxHhTANBgkqhkiG9w0BAQsFADCB +iDELMAkGA1UEBhMCVVMxDTALBgNVBAgTBFV0YWgxDTALBgNVBAcTBExlaGkxFzAV +BgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29t +MScwJQYDVQQDEx5EaWdpQ2VydCBWZXJpZmllZCBNYXJrIFJvb3QgQ0EwHhcNMTkw +OTIzMTIyNTQyWhcNMzQwOTIzMTIyNTQyWjCBkDELMAkGA1UEBhMCVVMxDTALBgNV +BAgTBFV0YWgxDTALBgNVBAcTBExlaGkxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu +MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBW +ZXJpZmllZCBNYXJrIEludGVybWVkaWF0ZSBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAPfhMd+2RBjNZpqq0GVUF0kKK72fQxhJbnxgYv7GFpmi69sX +dgeqH9RE07ShTDtkLks9G/GuiXsLEmjSCBDDTwfB3hpbdrZsNQFWOIRHXmU8ykuP +bCd/HVRZGULeWvbt93deEB1el5MpxP9Fs3LKjw7xytbuM/nkGJ4D2R1IHC953FoU +4BYsp+8VB1+7Gh8eKVh+HpmBeEfIB+cuq4FpZKxi+F5J7UjW5yO4SuDcTF4AMY0J +DPuKIy+Og6laNOtDS30P1CUu1N6BwLMYTbeqyYHJ7B3kLWsDceGMqIcxo8zrk1rT +sJctcXHXhB4k2PnVxt8qkQjg2Lo++kU0dFSUyrzvg3WrGypv9vphWMI+vmCjmu2K +0BZLZ4nKshoTX495R6pGbsecGaaGgACB/1NcGI7PVp7spY2ytLvHHZ+Hh446BGFy +AdM8lZCMXEhNftP8RRRVr8mwHHzyIa86r4yk0SkOlXUkNrGdTqqyMSDJ3W7DWGO/ +vCObzXiM0aq77ebD/0fE5LsZhEJYx7txF9NA1DoICgHp8zqF35i3UOp4+5IyJ8A9 +MjqYcX+LayH06B45bMgTHLmJKcsRYvXAtu+nIvIL0fk4+Ea7kJ7MNx5/udS89b2f +vSFC4hmA3OBDiJqGmldwqJL/HP7RI8O54yj10vpiH4obDo8QgfhKSVoX5HwDAgMB +AAGjggGJMIIBhTAdBgNVHQ4EFgQU6w3OZfRSdXtNs9SzPTDjUBir424wHwYDVR0j +BBgwFoAU7G8ipLME4sFjh+Z3Y+pGaU7u/OswDgYDVR0PAQH/BAQDAgGGMBMGA1Ud +JQQMMAoGCCsGAQUFBwMfMBIGA1UdEwEB/wQIMAYBAf8CAQAwfAYIKwYBBQUHAQEE +cDBuMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wRgYIKwYB +BQUHMAKGOmh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFZlcmlm +aWVkTWFya1Jvb3RDQS5jcnQwSAYDVR0fBEEwPzA9oDugOYY3aHR0cDovL2NybDMu +ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VmVyaWZpZWRNYXJrUm9vdENBLmNybDBCBgNV +HSAEOzA5MDcGCWCGSAGG/WwKATAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5k +aWdpY2VydC5jb20vQ1BTMA0GCSqGSIb3DQEBCwUAA4ICAQA6v371ixHAA9WyGlFr ++RvmmqkZZg9pf6+j5sKImeTFAHfYz3TJa2wmDRpZxSRYy9VUFOMPVDEavsJ2i5Ua +jEpkJ/7VHbX60joKBxQHKCbMpbwGen6pTXRaeE6CET2zCMbyiIqT2E6OiBZL8cWT +sgLbdhVKspoOi+c3JwTR4khR24J9IQVxK90Nq3zeciYgBvM3G+ZJtZgkA58CRdex +xVO6O57bwe4ti4rlRgWOGgAFpFrJSD1jqhhHD3MWg17NI4k0ciBPoDHHBAI8hiqg +jPM+y6aEGww7BFSfkp5tl/Aq9uGXCwxNLOc3UlUd8Cc0qH1KfkvjrumVMmJhsk9I +88YefbCuGPZ5Q8V2LIz7LrNDh0VRq/HSENXn1sBGlAFahgUTk/cWJ8nKA+8mHMlE +NGmx205Rtbf9lVL1CbH3QFwlvGEfqoMXw6G9JW2hFQVTKpBKuzjQw43CEw12lstP +oa96ixNAXXVGJsdKpYCqTIWJ0x1DssvG2shvzdHxawvYQ3C+/jaEoQ6bxSIdanI2 +NMtBdy9Q0TjDc7uf/eaUYKkP4wskNc1Os23oHllFHVm++8wdDltNulc7B1TXIQ+2 +oD5EoULMFSVUHX8gtyd463GgOQtBDwf3aZ4Xe6eDrhdfI/4IW098kVcg+qFO841L +qzFkAKWjJj4KjfrbZX4C0Spfxw== -----END CERTIFICATE-----'; $x509 = new File_X509(); From df94788edfa169f31d201cd742dfdc853e2c2676 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Thu, 7 Jan 2021 20:36:09 -0600 Subject: [PATCH 39/69] Tests/X509: update unit test --- tests/Unit/File/X509/X509Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/File/X509/X509Test.php b/tests/Unit/File/X509/X509Test.php index 68c47a879..2702feb69 100644 --- a/tests/Unit/File/X509/X509Test.php +++ b/tests/Unit/File/X509/X509Test.php @@ -860,6 +860,6 @@ public function testMultiCertPEM() $x509 = new File_X509(); $r = $x509->loadX509($a); - $this->assertFalse($r); + $this->assertIsArray($r); } } From 7f1b53fb672b1e9226abe67445b69b9947ace0e3 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 12 Jan 2021 23:12:19 -0600 Subject: [PATCH 40/69] SSH2: behave like putty with broken publickey auth --- phpseclib/Net/SSH2.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 494abf7aa..3f9848451 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -2649,6 +2649,13 @@ function _privatekey_login($username, $privatekey) // we'll just take it on faith that the public key blob and the public key algorithm name are as // they should be $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK'); + break; + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= NET_SSH2_MASK_LOGIN; + return true; + default: + user_error('Unexpected response to publickey authentication pt 1'); + return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } $packet = $part1 . chr(1) . $part2; @@ -2683,7 +2690,8 @@ function _privatekey_login($username, $privatekey) return true; } - return false; + user_error('Unexpected response to publickey authentication pt 2'); + return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } /** From 2eae2989f47a8e4ec346c055bc2653929e59e681 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 12 Jan 2021 23:20:47 -0600 Subject: [PATCH 41/69] SSH2: adjustments for 2.0 branch --- phpseclib/Net/SSH2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 2927b7265..f3816c00f 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -2636,7 +2636,7 @@ function _privatekey_login($username, $privatekey) $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK'); break; case NET_SSH2_MSG_USERAUTH_SUCCESS: - $this->bitmap |= NET_SSH2_MASK_LOGIN; + $this->bitmap |= self::MASK_LOGIN; return true; default: user_error('Unexpected response to publickey authentication pt 1'); From e5a226f6be3db2b5e5ae8a86f7137c7a8da19f3a Mon Sep 17 00:00:00 2001 From: Jan Slabon Date: Fri, 15 Jan 2021 11:55:08 +0100 Subject: [PATCH 42/69] Added support of keys with PSS algorithm-identifier --- phpseclib/Crypt/RSA.php | 1 + tests/Unit/Crypt/RSA/LoadKeyTest.php | 58 ++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 28309e5b3..7671e8582 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -1298,6 +1298,7 @@ function. As is, the definitive authority on this encoding scheme isn't the IET $length = $this->_decodeLength($temp); switch ($this->_string_shift($temp, $length)) { case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption + case "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0A": // rsaPSS break; case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": // pbeWithMD5AndDES-CBC /* diff --git a/tests/Unit/Crypt/RSA/LoadKeyTest.php b/tests/Unit/Crypt/RSA/LoadKeyTest.php index 18a93619a..3b624e66f 100644 --- a/tests/Unit/Crypt/RSA/LoadKeyTest.php +++ b/tests/Unit/Crypt/RSA/LoadKeyTest.php @@ -227,6 +227,64 @@ public function testPubKey2() $this->assertFalse($rsa->getPrivateKey()); } + public function testPubKeyPssWithoutParams() + { + $rsa = new Crypt_RSA(); + + // extracted from a SubjectPublicKeyInfo of a CSR created by OpenSSL + $key = '-----BEGIN PUBLIC KEY----- +MIIBIDALBgkqhkiG9w0BAQoDggEPADCCAQoCggEBANHPPf5tjTmEHtQvzi6+rItj +G3OUvh6Nihc9bXSu0xNFjl/9TdyIXstRUG/Lh07isHgZFEfXn4pmm/iZIQh09ACg +TjEau8rpcLB0BS9dDgTh8hvgkbdxWR2UPxk34bFcdgIplckslAfB4+/ebL+ObvUa +W3sZosTq3D6/qh0fujGZg/EKLJcNCHI27XMiAT5yWztSjHWwQm7LBwJ5uKlFLEDC +Z/+LIV/vPEIMfE6lA/+OnLKwVFB540eXQPuWar1ARHXN8PpiCqJHanddYMA5l/Cw +5R7kJ+CBoHzaPePXjB9V1bfzEBzBHb2ddiSjum+qtLWuH0Q7B8gPX9EjxIwuCzMC +AwEAAQ== +-----END PUBLIC KEY-----'; + + $this->assertTrue($rsa->loadKey($key)); + $this->assertIsString($rsa->getPublicKey()); + $this->assertFalse($rsa->getPrivateKey()); + } + + public function testPrivateKeyPssWithoutParams() + { + $rsa = new Crypt_RSA(); + + $key = '-----BEGIN PRIVATE KEY----- +MIIEugIBADALBgkqhkiG9w0BAQoEggSmMIIEogIBAAKCAQEA0c89/m2NOYQe1C/O +Lr6si2Mbc5S+Ho2KFz1tdK7TE0WOX/1N3Ihey1FQb8uHTuKweBkUR9efimab+Jkh +CHT0AKBOMRq7yulwsHQFL10OBOHyG+CRt3FZHZQ/GTfhsVx2AimVySyUB8Hj795s +v45u9RpbexmixOrcPr+qHR+6MZmD8Qoslw0IcjbtcyIBPnJbO1KMdbBCbssHAnm4 +qUUsQMJn/4shX+88Qgx8TqUD/46csrBUUHnjR5dA+5ZqvUBEdc3w+mIKokdqd11g +wDmX8LDlHuQn4IGgfNo949eMH1XVt/MQHMEdvZ12JKO6b6q0ta4fRDsHyA9f0SPE +jC4LMwIDAQABAoIBAFPuTMWAO7Obh92oNhn7CvlDr1KgWSHNy0UavLOl0ChwddEu +erxTDWDWaZAfYkSLaL7SgYtv1ZG/FHvxfgZtCsNJXZ5FLISyt/LOpthYqGgJnxnJ +z2EMBfNQP6Gt+ipCa67XxeTRYXJs/OsTFnvW1cpVPe1TxwpxTaQIdlvqOkjmgCci +TRzH+Acj8unWDHAJpQkCOvmi+25sE0BMQYWnsfMSzm63Yk3SeZLIJKqoUdZhYMZU +6FK2DMDNR4TZps7s50MFlZfUUJfzgb4Hb4miiKzLPhf4q7rxS4VzrvUQ/81ySCwi +1LaSw5HoH1YMDT6rwcHMwHhzhu8X2CKlNIrri8ECgYEA7aiZAxmlY28LWcXHqqhZ +Yky76vLy/mbs0TfAVK2pSqyFhaGZe5daAJSIrVcZEEgAwR6/ZLITTWBuGdsHw6vF +GtSvkElLhopmQEs73kKqeBFLhpTqYXYVW0txi3jdWElie8fZa/Oa/sFLEeNsibQu +fbVWWGakf9458FDuR0i2k+ECgYEA4gBu2u6xkJzqOzOjBg5tNhxmzcPyt4Ds3ryA +e+C5hVCotd1EX6HZRPYjLEys0yUhiXDAn7ViEdtiXt9RYfpK+OKLGeTZ7pMCyZW+ +Yhc0i2XYqWSKUH3iNonp8B0JSkfEQBY2KlA7b5YZQZkr/Ml/WtoKeicHLBcdVxqa +t7krQZMCgYBMU7GQxVPQs4E5u8N8k8ThRTO1KYHRIs08BGPIzl1oli/r0xKwFtPZ +C9s5kJeEGxvi6jUd6fM5DpdNxoKf3TLYgyY/eMrA0wIz8/WuVErbdPKErp733izN +vVUiLhcom6j9iBnUCdDlsL6jaB8burqTtQGeMpjyWDTTcaqVSk0ZAQKBgCqc1EoZ +eYd/3rZc7R8mNzddsZCYorow5/izaDJzU+esJrNrzgmOFc5n7ofayTdip+knRlqW +s7AUQn8K8mhb7ijxZjLysJjIRV1HC8epAnJKOMjvuRimM7H+3Qo2H1tPHtTKm1nt +GNfYYFi7Dc0zHP0/YXxYwYRxs0mKLaP4mQxbAoGARHngPhGC0yM5KqxNrkHPVjLq +CHQy+e9GTPXtDLC3D7HAYyyzKqy4mdBDzMeLqA3a+iT2PXjn4w5zOEW8GAcRYRtG +3EyvclPmWtmCpU5xqD8ieFtQhMeW/XzJHjTXlcncz0PCkGVoQiuRvXWNAukNPg0D +BocC2CO6SNi4Qjr3NlM= +-----END PRIVATE KEY-----'; + + $this->assertTrue($rsa->loadKey($key)); + $this->assertIsString($rsa->getPublicKey()); + $this->assertIsString($rsa->getPrivateKey()); + } + public function testSSHPubKey() { $rsa = new Crypt_RSA(); From 6499451d4bc2c151ad096cf61217b9f233bc567a Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 16 Jan 2021 10:40:48 -0600 Subject: [PATCH 43/69] Tests/RSA: adjustments for 2.0 --- tests/Unit/Crypt/RSA/LoadKeyTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Crypt/RSA/LoadKeyTest.php b/tests/Unit/Crypt/RSA/LoadKeyTest.php index 8f133721d..dcac0a68a 100644 --- a/tests/Unit/Crypt/RSA/LoadKeyTest.php +++ b/tests/Unit/Crypt/RSA/LoadKeyTest.php @@ -229,7 +229,7 @@ public function testPubKey2() public function testPubKeyPssWithoutParams() { - $rsa = new Crypt_RSA(); + $rsa = new RSA(); // extracted from a SubjectPublicKeyInfo of a CSR created by OpenSSL $key = '-----BEGIN PUBLIC KEY----- @@ -249,7 +249,7 @@ public function testPubKeyPssWithoutParams() public function testPrivateKeyPssWithoutParams() { - $rsa = new Crypt_RSA(); + $rsa = new RSA(); $key = '-----BEGIN PRIVATE KEY----- MIIEugIBADALBgkqhkiG9w0BAQoEggSmMIIEogIBAAKCAQEA0c89/m2NOYQe1C/O From 72264ff91807eb7e6d25887a52a2670966b21ed8 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Wed, 3 Feb 2021 19:53:27 -0600 Subject: [PATCH 44/69] Tests/RSA: add unit test for raw keys --- tests/Unit/Crypt/RSA/LoadKeyTest.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/Unit/Crypt/RSA/LoadKeyTest.php b/tests/Unit/Crypt/RSA/LoadKeyTest.php index dcac0a68a..ee3bcc59f 100644 --- a/tests/Unit/Crypt/RSA/LoadKeyTest.php +++ b/tests/Unit/Crypt/RSA/LoadKeyTest.php @@ -6,6 +6,7 @@ */ use phpseclib\Crypt\RSA; +use phpseclib\Math\BigInteger; class Unit_Crypt_RSA_LoadKeyTest extends PhpseclibTestCase { @@ -439,6 +440,18 @@ public function testSetLoad() $rsa->loadKey($rsa); } + public function testRaw() + { + $key = array( + 'e' => new BigInteger('010001', 16), + 'n' => new BigInteger('00d0991cd1dc9519de1a5a935742cb3a0f998b0c7995eab3f204f2663b81229474105bd38e2e657e1acd095d8178a1bdcb0a7631e491771ff99d8e705017cff26d6632665f9171734aa5f5d80cc0ea10ef5e8dfa2199af3b7bf69703104b8bdab5db0510b6a7cf61ec9799f25000a0994ec287b711075cfdad79b90da273172dc0fd2127181b45564c602c102d8e63929d53597f8be7ee5709885d42a5ddf8e3142432e35a61e8baeeb1a6dd23a6a74672c2a95ad974ace161813df32daaca8ce008e67d3a48c1e3ce8aa4ddfd2df644783f582c669892b91a8613f2a5c67f520845c53f09f6faa760ae0d1b0fd64953cb26f22317494d2fd5d9bc72b5f56f3ea1', 16) + ); + + $rsa = new RSA; + $this->assertTrue($rsa->loadKey($key)); + $this->assertIsString("$rsa"); + } + /** * @group github980 */ From d20e842a5e9bb7c6873dbf3e5c5f296eb636c127 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sun, 21 Feb 2021 18:41:28 -0600 Subject: [PATCH 45/69] SFTP/Stream: make it so you can write past the end of a file --- phpseclib/Net/SFTP/Stream.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Net/SFTP/Stream.php b/phpseclib/Net/SFTP/Stream.php index 842ebab54..fb976fd0c 100644 --- a/phpseclib/Net/SFTP/Stream.php +++ b/phpseclib/Net/SFTP/Stream.php @@ -428,7 +428,7 @@ function _stream_seek($offset, $whence) { switch ($whence) { case SEEK_SET: - if ($offset >= $this->size || $offset < 0) { + if ($offset < 0) { return false; } break; From 488db53bf7cbd90d5910838162b275f43e16363b Mon Sep 17 00:00:00 2001 From: lightray22 Date: Sun, 21 Feb 2021 20:12:26 +0000 Subject: [PATCH 46/69] fix undefined index notice in stream touch() --- phpseclib/Net/SFTP/Stream.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/phpseclib/Net/SFTP/Stream.php b/phpseclib/Net/SFTP/Stream.php index fb976fd0c..161e734b3 100644 --- a/phpseclib/Net/SFTP/Stream.php +++ b/phpseclib/Net/SFTP/Stream.php @@ -465,7 +465,9 @@ function _stream_metadata($path, $option, $var) // and https://github.com/php/php-src/blob/master/main/php_streams.h#L592 switch ($option) { case 1: // PHP_STREAM_META_TOUCH - return $this->sftp->touch($path, $var[0], $var[1]); + $time = isset($var[0]) ? $var[0] : null; + $atime = isset($var[1]) ? $var[1] : null; + return $this->sftp->touch($path, $time, $atime); case 2: // PHP_STREAM_OWNER_NAME case 3: // PHP_STREAM_GROUP_NAME return false; From b2b867f032949fab435370061a2a00dc31b22d9a Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 26 Feb 2021 09:17:05 -0600 Subject: [PATCH 47/69] BigInteger: fix issue with toBits on 32-bit PHP 8 installs --- phpseclib/Math/BigInteger.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php index f48b5ec67..e4e7b428b 100644 --- a/phpseclib/Math/BigInteger.php +++ b/phpseclib/Math/BigInteger.php @@ -673,11 +673,11 @@ function toBits($twos_compliment = false) { $hex = $this->toHex($twos_compliment); $bits = ''; - for ($i = strlen($hex) - 8, $start = strlen($hex) & 7; $i >= $start; $i-=8) { - $bits = str_pad(decbin(hexdec(substr($hex, $i, 8))), 32, '0', STR_PAD_LEFT) . $bits; + for ($i = strlen($hex) - 6, $start = strlen($hex) % 6; $i >= $start; $i-=6) { + $bits = str_pad(decbin(hexdec(substr($hex, $i, 6))), 24, '0', STR_PAD_LEFT) . $bits; } if ($start) { // hexdec('') == 0 - $bits = str_pad(decbin(hexdec(substr($hex, 0, $start))), 8, '0', STR_PAD_LEFT) . $bits; + $bits = str_pad(decbin(hexdec(substr($hex, 0, $start))), 8 * $start, '0', STR_PAD_LEFT) . $bits; } $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0'); From a45ccbacb782098d520395b471d214af09e96c49 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Mon, 8 Mar 2021 23:03:38 -0600 Subject: [PATCH 48/69] SFTP: digit only filenames were converted to integers by php --- phpseclib/Net/SFTP.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index 577027eb1..dbc14ede7 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -1083,7 +1083,7 @@ function _list($dir, $raw = true) uasort($contents, array(&$this, '_comparator')); } - return $raw ? $contents : array_keys($contents); + return $raw ? $contents : array_map('strval', array_keys($contents)); } /** From e209db78b80c738f20c1c44a69d4c208fd7bdca9 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 19 Mar 2021 16:55:58 -0500 Subject: [PATCH 49/69] Crypt/Base: use a custom error handler for mcrypt --- phpseclib/Crypt/Base.php | 66 +++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index cad9c3829..1f11cf36a 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -821,12 +821,13 @@ function encrypt($plaintext) } if ($this->engine === CRYPT_ENGINE_MCRYPT) { + set_error_handler(array($this, 'do_nothing')); if ($this->changed) { $this->_setupMcrypt(); $this->changed = false; } if ($this->enchanged) { - @mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); + mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); $this->enchanged = false; } @@ -859,15 +860,15 @@ function encrypt($plaintext) if ($len >= $block_size) { if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) { if ($this->enbuffer['enmcrypt_init'] === true) { - @mcrypt_generic_init($this->enmcrypt, $this->key, $iv); + mcrypt_generic_init($this->enmcrypt, $this->key, $iv); $this->enbuffer['enmcrypt_init'] = false; } - $ciphertext.= @mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size)); + $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size)); $iv = substr($ciphertext, -$block_size); $len%= $block_size; } else { while ($len >= $block_size) { - $iv = @mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size); + $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size); $ciphertext.= $iv; $len-= $block_size; $i+= $block_size; @@ -876,22 +877,26 @@ function encrypt($plaintext) } if ($len) { - $iv = @mcrypt_generic($this->ecb, $iv); + $iv = mcrypt_generic($this->ecb, $iv); $block = $iv ^ substr($plaintext, -$len); $iv = substr_replace($iv, $block, 0, $len); $ciphertext.= $block; $pos = $len; } + restore_error_handler(); + return $ciphertext; } - $ciphertext = @mcrypt_generic($this->enmcrypt, $plaintext); + $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext); if (!$this->continuousBuffer) { - @mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); + mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV); } + restore_error_handler(); + return $ciphertext; } @@ -1132,13 +1137,14 @@ function decrypt($ciphertext) } if ($this->engine === CRYPT_ENGINE_MCRYPT) { + set_error_handler(array($this, 'do_nothing')); $block_size = $this->block_size; if ($this->changed) { $this->_setupMcrypt(); $this->changed = false; } if ($this->dechanged) { - @mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); + mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); $this->dechanged = false; } @@ -1166,26 +1172,30 @@ function decrypt($ciphertext) } if ($len >= $block_size) { $cb = substr($ciphertext, $i, $len - $len % $block_size); - $plaintext.= @mcrypt_generic($this->ecb, $iv . $cb) ^ $cb; + $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb; $iv = substr($cb, -$block_size); $len%= $block_size; } if ($len) { - $iv = @mcrypt_generic($this->ecb, $iv); + $iv = mcrypt_generic($this->ecb, $iv); $plaintext.= $iv ^ substr($ciphertext, -$len); $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len); $pos = $len; } + restore_error_handler(); + return $plaintext; } - $plaintext = @mdecrypt_generic($this->demcrypt, $ciphertext); + $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext); if (!$this->continuousBuffer) { - @mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); + mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV); } + restore_error_handler(); + return $this->paddable ? $this->_unpad($plaintext) : $plaintext; } @@ -1643,9 +1653,12 @@ function isValidEngine($engine) } return false; case CRYPT_ENGINE_MCRYPT: - return $this->cipher_name_mcrypt && + set_error_handler(array($this, 'do_nothing')); + $result = $this->cipher_name_mcrypt && extension_loaded('mcrypt') && - in_array($this->cipher_name_mcrypt, @mcrypt_list_algorithms()); + in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms()); + restore_error_handler(); + return $result; case CRYPT_ENGINE_INTERNAL: return true; } @@ -1722,17 +1735,19 @@ function _setEngine() } if ($this->engine != CRYPT_ENGINE_MCRYPT && $this->enmcrypt) { + set_error_handler(array($this, 'do_nothing')); // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed, // (re)open them with the module named in $this->cipher_name_mcrypt - @mcrypt_module_close($this->enmcrypt); - @mcrypt_module_close($this->demcrypt); + mcrypt_module_close($this->enmcrypt); + mcrypt_module_close($this->demcrypt); $this->enmcrypt = null; $this->demcrypt = null; if ($this->ecb) { - @mcrypt_module_close($this->ecb); + mcrypt_module_close($this->ecb); $this->ecb = null; } + restore_error_handler(); } $this->changed = true; @@ -1850,19 +1865,19 @@ function _setupMcrypt() CRYPT_MODE_STREAM => MCRYPT_MODE_STREAM, ); - $this->demcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); - $this->enmcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer() // to workaround mcrypt's broken ncfb implementation in buffered mode // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} if ($this->mode == CRYPT_MODE_CFB) { - $this->ecb = @mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, ''); + $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, ''); } } // else should mcrypt_generic_deinit be called? if ($this->mode == CRYPT_MODE_CFB) { - @mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size)); + mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size)); } } @@ -2657,4 +2672,13 @@ function safe_intval_inline() return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))'; } } + + /** + * Dummy error handler to suppress mcrypt errors + * + * @access private + */ + function do_nothing() + { + } } From 2d6705dfbdc36783ed29d5818a9353d575d06da1 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 30 Mar 2021 22:43:34 -0500 Subject: [PATCH 50/69] SSH2: don't close channel on unexpected response to channel request --- phpseclib/Net/SSH2.php | 45 ++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 3f9848451..bd79462f2 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -2951,28 +2951,6 @@ function _initShell() return false; } - $response = $this->_get_binary_packet(); - if ($response === false) { - $this->bitmap = 0; - user_error('Connection closed by server'); - return false; - } - - if (!strlen($response)) { - return false; - } - list(, $type) = unpack('C', $this->_string_shift($response, 1)); - - switch ($type) { - case NET_SSH2_MSG_CHANNEL_SUCCESS: - // if a pty can't be opened maybe commands can still be executed - case NET_SSH2_MSG_CHANNEL_FAILURE: - break; - default: - user_error('Unable to request pseudo-terminal'); - return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); - } - $packet = pack( 'CNNa*C', NET_SSH2_MSG_CHANNEL_REQUEST, @@ -2985,14 +2963,7 @@ function _initShell() return false; } - $this->channel_status[NET_SSH2_CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_REQUEST; - - $response = $this->_get_channel_packet(NET_SSH2_CHANNEL_SHELL); - if ($response === false) { - return false; - } - - $this->channel_status[NET_SSH2_CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_DATA; + $this->channel_status[NET_SSH2_CHANNEL_SHELL] = NET_SSH2_MSG_IGNORE; $this->bitmap |= NET_SSH2_MASK_SHELL; @@ -3923,6 +3894,16 @@ function _get_channel_packet($client_channel, $skip_extended = false) return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); } break; + case NET_SSH2_MSG_IGNORE: + switch ($type) { + case NET_SSH2_MSG_CHANNEL_SUCCESS: + //$this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_DATA; + continue 3; + case NET_SSH2_MSG_CHANNEL_FAILURE: + user_error('Error opening channel'); + return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION); + } + break; case NET_SSH2_MSG_CHANNEL_REQUEST: switch ($type) { case NET_SSH2_MSG_CHANNEL_SUCCESS: @@ -3942,6 +3923,10 @@ function _get_channel_packet($client_channel, $skip_extended = false) switch ($type) { case NET_SSH2_MSG_CHANNEL_DATA: + //if ($this->channel_status[$channel] == NET_SSH2_MSG_IGNORE) { + // $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_DATA; + //} + /* if ($channel == NET_SSH2_CHANNEL_EXEC) { // SCP requires null packets, such as this, be sent. further, in the case of the ssh.com SSH server From b90c33200e20c786fbe7c2acff2e35729a71af59 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 2 Apr 2021 10:43:15 -0500 Subject: [PATCH 51/69] ASN1: don't allow last octet in OID to have MSB set --- phpseclib/File/ASN1.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 00c913b83..13975ab74 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -517,6 +517,9 @@ function _decode_ber($encoded, $start = 0, $encoded_pos = 0) break; case FILE_ASN1_TYPE_OBJECT_IDENTIFIER: $current['content'] = $this->_decodeOID(substr($content, $content_pos)); + if ($current['content'] === false) { + return false; + } break; /* Each character string type shall be encoded as if it had been declared: [UNIVERSAL x] IMPLICIT OCTET STRING @@ -1228,6 +1231,11 @@ function _decodeOID($content) $oid = array(); $pos = 0; $len = strlen($content); + + if (ord($content[$len - 1]) & 0x80) { + return false; + } + $n = new Math_BigInteger(); while ($pos < $len) { $temp = ord($content[$pos++]); From 95f597cfb30e118236252884548b4c0be4320907 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Fri, 2 Apr 2021 13:46:14 -0500 Subject: [PATCH 52/69] ASN1: tweaks to tag decoding --- phpseclib/File/ASN1.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 13975ab74..8785c0617 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -317,7 +317,7 @@ function _decode_ber($encoded, $start = 0, $encoded_pos = 0) $current = array('start' => $start); $type = ord($encoded[$encoded_pos++]); - $start++; + $startOffset = 1; $constructed = ($type >> 5) & 1; @@ -327,13 +327,20 @@ function _decode_ber($encoded, $start = 0, $encoded_pos = 0) // process septets (since the eighth bit is ignored, it's not an octet) do { $temp = ord($encoded[$encoded_pos++]); + $startOffset++; $loop = $temp >> 7; $tag <<= 7; - $tag |= $temp & 0x7F; - $start++; + $temp &= 0x7F; + // "bits 7 to 1 of the first subsequent octet shall not all be zero" + if ($startOffset == 2 && $temp == 0) { + return false; + } + $tag |= $temp; } while ($loop); } + $start+= $startOffset; + // Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13 $length = ord($encoded[$encoded_pos++]); $start++; From a589442a78d9d7a52cb8312e8d44b8c40178864d Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 11:07:25 -0500 Subject: [PATCH 53/69] ASN1: uncomment out extra validation code --- phpseclib/File/ASN1.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 8785c0617..a53697840 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -433,9 +433,9 @@ function _decode_ber($encoded, $start = 0, $encoded_pos = 0) switch ($tag) { case FILE_ASN1_TYPE_BOOLEAN: // "The contents octets shall consist of a single octet." -- paragraph 8.2.1 - //if (strlen($content) != 1) { - // return false; - //} + if (strlen($content) != 1) { + return false; + } $current['content'] = (bool) ord($content[$content_pos]); break; case FILE_ASN1_TYPE_INTEGER: @@ -459,15 +459,15 @@ function _decode_ber($encoded, $start = 0, $encoded_pos = 0) $last = count($temp) - 1; for ($i = 0; $i < $last; $i++) { // all subtags should be bit strings - //if ($temp[$i]['type'] != FILE_ASN1_TYPE_BIT_STRING) { - // return false; - //} + if ($temp[$i]['type'] != FILE_ASN1_TYPE_BIT_STRING) { + return false; + } $current['content'].= substr($temp[$i]['content'], 1); } // all subtags should be bit strings - //if ($temp[$last]['type'] != FILE_ASN1_TYPE_BIT_STRING) { - // return false; - //} + if ($temp[$last]['type'] != FILE_ASN1_TYPE_BIT_STRING) { + return false; + } $current['content'] = $temp[$last]['content'][0] . $current['content'] . substr($temp[$i]['content'], 1); } break; @@ -484,9 +484,9 @@ function _decode_ber($encoded, $start = 0, $encoded_pos = 0) } $content_pos += $temp['length']; // all subtags should be octet strings - //if ($temp['type'] != FILE_ASN1_TYPE_OCTET_STRING) { - // return false; - //} + if ($temp['type'] != FILE_ASN1_TYPE_OCTET_STRING) { + return false; + } $current['content'].= $temp['content']; $length+= $temp['length']; } @@ -497,9 +497,9 @@ function _decode_ber($encoded, $start = 0, $encoded_pos = 0) break; case FILE_ASN1_TYPE_NULL: // "The contents octets shall not contain any octets." -- paragraph 8.8.2 - //if (strlen($content)) { - // return false; - //} + if (strlen($content)) { + return false; + } break; case FILE_ASN1_TYPE_SEQUENCE: case FILE_ASN1_TYPE_SET: From dbd210c4a7ffc652a15792ed83125a6f93306a80 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 11:38:11 -0500 Subject: [PATCH 54/69] Tests/ASN1: add test for null garbage bytes --- tests/Unit/File/ASN1Test.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index 00ee7c8eb..eda3ea361 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -392,4 +392,17 @@ public function testExplicitImplicitDate() $this->assertIsArray($a); } + + public function testNullGarbage() + { + $asn1 = new File_ASN1(); + + $em = pack('H*', '3080305c0609608648016503040201054f8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888804207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9'); + $decoded = $asn1->decodeBER($em); + $this->assertFalse($decoded[0]); + + $em = pack('H*', '3080307f0609608648016503040201057288888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888804207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca90000'); + $decoded = $asn1->decodeBER($em); + $this->assertFalse($decoded[0]); + } } From 6be326e7e7c73c472839bd446b42aa834dcbe5df Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 12:04:07 -0500 Subject: [PATCH 55/69] Tests/ASN1: add test for OID garbage bytes --- tests/Unit/File/ASN1Test.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index eda3ea361..84384b2cb 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -405,4 +405,17 @@ public function testNullGarbage() $decoded = $asn1->decodeBER($em); $this->assertFalse($decoded[0]); } + + public function testOIDGarbage() + { + $asn1 = new File_ASN1(); + + $em = pack('H*', '3080305c065860864801650304020188888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888050004207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9'); + $decoded = $asn1->decodeBER($em); + $this->assertFalse($decoded[0]); + + $em = pack('H*', '3080307f067d608648016503040201888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888804207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9'); + $decoded = $asn1->decodeBER($em); + $this->assertFalse($decoded[0]); + } } From 8b8cbecb9b97f4b7aa60a45aea828e3c563b897d Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 13:15:58 -0500 Subject: [PATCH 56/69] ASN1: make sure constructed bit is what it ought to be --- phpseclib/File/ASN1.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index a53697840..2424d3415 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -433,13 +433,16 @@ function _decode_ber($encoded, $start = 0, $encoded_pos = 0) switch ($tag) { case FILE_ASN1_TYPE_BOOLEAN: // "The contents octets shall consist of a single octet." -- paragraph 8.2.1 - if (strlen($content) != 1) { + if ($constructed || strlen($content) != 1) { return false; } $current['content'] = (bool) ord($content[$content_pos]); break; case FILE_ASN1_TYPE_INTEGER: case FILE_ASN1_TYPE_ENUMERATED: + if ($constructed) { + return false; + } $current['content'] = new Math_BigInteger(substr($content, $content_pos), -256); break; case FILE_ASN1_TYPE_REAL: // not currently supported @@ -497,12 +500,15 @@ function _decode_ber($encoded, $start = 0, $encoded_pos = 0) break; case FILE_ASN1_TYPE_NULL: // "The contents octets shall not contain any octets." -- paragraph 8.8.2 - if (strlen($content)) { + if ($constructed || strlen($content)) { return false; } break; case FILE_ASN1_TYPE_SEQUENCE: case FILE_ASN1_TYPE_SET: + if (!$constructed) { + return false; + } $offset = 0; $current['content'] = array(); $content_len = strlen($content); @@ -523,6 +529,9 @@ function _decode_ber($encoded, $start = 0, $encoded_pos = 0) } break; case FILE_ASN1_TYPE_OBJECT_IDENTIFIER: + if ($constructed) { + return false; + } $current['content'] = $this->_decodeOID(substr($content, $content_pos)); if ($current['content'] === false) { return false; @@ -556,10 +565,16 @@ function _decode_ber($encoded, $start = 0, $encoded_pos = 0) case FILE_ASN1_TYPE_UTF8_STRING: // ???? case FILE_ASN1_TYPE_BMP_STRING: + if ($constructed) { + return false; + } $current['content'] = substr($content, $content_pos); break; case FILE_ASN1_TYPE_UTC_TIME: case FILE_ASN1_TYPE_GENERALIZED_TIME: + if ($constructed) { + return false; + } $current['content'] = class_exists('DateTime') ? $this->_decodeDateTime(substr($content, $content_pos), $tag) : $this->_decodeUnixTime(substr($content, $content_pos), $tag); From 730070b78f08e83c2edd65d8c6a03c9da3b8b277 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 13:25:56 -0500 Subject: [PATCH 57/69] Tests/ASN1: update unit tests to work on 2.0 branch --- tests/Unit/File/ASN1Test.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index 35bf877f4..7b9d09438 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -395,7 +395,7 @@ public function testExplicitImplicitDate() public function testNullGarbage() { - $asn1 = new File_ASN1(); + $asn1 = new ASN1(); $em = pack('H*', '3080305c0609608648016503040201054f8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888804207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9'); $decoded = $asn1->decodeBER($em); @@ -408,7 +408,7 @@ public function testNullGarbage() public function testOIDGarbage() { - $asn1 = new File_ASN1(); + $asn1 = new ASN1(); $em = pack('H*', '3080305c065860864801650304020188888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888050004207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9'); $decoded = $asn1->decodeBER($em); From c1d21edb94793ba1093e3df3a7ea4ee9a59a382b Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 13:44:29 -0500 Subject: [PATCH 58/69] Tests/ASN1: add tests for constructed mismatches --- tests/Unit/File/ASN1Test.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index 84384b2cb..2a5ad9ea2 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -418,4 +418,25 @@ public function testOIDGarbage() $decoded = $asn1->decodeBER($em); $this->assertFalse($decoded[0]); } + + public function testConstructedMismatch() + { + $asn1 = new File_ASN1(); + + $em = pack('H*', '1031300d0609608648016503040201050004207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9'); + $decoded = $asn1->decodeBER($em); + $this->assertFalse($decoded[0]); + + $em = pack('H*', '3031100d0609608648016503040201050004207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9'); + $decoded = $asn1->decodeBER($em); + $this->assertFalse($decoded[0]); + + $em = pack('H*', '3031300d2609608648016503040201050004207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9'); + $decoded = $asn1->decodeBER($em); + $this->assertFalse($decoded[0]); + + $em = pack('H*', '3031300d06096086480165030402012d0004207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9'); + $decoded = $asn1->decodeBER($em); + $this->assertFalse($decoded[0]); + } } From 10cee4514cc9d160d4cd22378ec168415d483ea3 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 13:53:20 -0500 Subject: [PATCH 59/69] Tests/ASN1: test for bad tag --- tests/Unit/File/ASN1Test.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/Unit/File/ASN1Test.php b/tests/Unit/File/ASN1Test.php index 2a5ad9ea2..747e3c9aa 100644 --- a/tests/Unit/File/ASN1Test.php +++ b/tests/Unit/File/ASN1Test.php @@ -439,4 +439,13 @@ public function testConstructedMismatch() $decoded = $asn1->decodeBER($em); $this->assertFalse($decoded[0]); } + + public function testBadTagSecondOctet() + { + $asn1 = new File_ASN1(); + + $em = pack('H*', '3033300f1f808080060960864801650304020104207509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9'); + $decoded = $asn1->decodeBER($em); + $this->assertFalse($decoded[0]); + } } From e02c8452d41f643c5d6208078f45f4b0cb6335b7 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 15:54:27 -0500 Subject: [PATCH 60/69] ASN1: fail when encountering unsupported tags --- phpseclib/File/ASN1.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 2424d3415..1419c0973 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -578,7 +578,9 @@ function _decode_ber($encoded, $start = 0, $encoded_pos = 0) $current['content'] = class_exists('DateTime') ? $this->_decodeDateTime(substr($content, $content_pos), $tag) : $this->_decodeUnixTime(substr($content, $content_pos), $tag); + break; default: + return false; } $start+= $length; From 9af9d69c19788819ab467dce513c5941af7efc37 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 16:00:42 -0500 Subject: [PATCH 61/69] RSA: support "strict" PKCS1 sigs without NULLs --- phpseclib/Crypt/RSA.php | 56 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 7671e8582..de3d3ed5b 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -3001,6 +3001,56 @@ function _emsa_pkcs1_v1_5_encode($m, $emLen) return $em; } + /** + * EMSA-PKCS1-V1_5-ENCODE (without NULL) + * + * Quoting https://tools.ietf.org/html/rfc8017#page-65, + * + * "The parameters field associated with id-sha1, id-sha224, id-sha256, + * id-sha384, id-sha512, id-sha512/224, and id-sha512/256 should + * generally be omitted, but if present, it shall have a value of type + * NULL" + * + * @access private + * @param string $m + * @param int $emLen + * @return string + */ + function _emsa_pkcs1_v1_5_encode_without_null($m, $emLen) + { + $h = $this->hash->hash($m); + if ($h === false) { + return false; + } + + switch ($this->hashName) { + case 'sha1': + $t = pack('H*', '301f300706052b0e03021a0414'); + break; + case 'sha256': + $t = pack('H*', '302f300b06096086480165030402010420'); + break; + case 'sha384': + $t = pack('H*', '303f300b06096086480165030402020430'); + break; + case 'sha512': + $t = pack('H*', '304f300b06096086480165030402030440'); + } + $t.= $h; + $tLen = strlen($t); + + if ($emLen < $tLen + 11) { + user_error('Intended encoded message length too short'); + return false; + } + + $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); + + $em = "\0\1$ps\0$t"; + + return $em; + } + /** * RSASSA-PKCS1-V1_5-SIGN * @@ -3067,13 +3117,15 @@ function _rsassa_pkcs1_v1_5_verify($m, $s) // EMSA-PKCS1-v1_5 encoding $em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k); - if ($em2 === false) { + $em3 = $this->_emsa_pkcs1_v1_5_encode_without_null($m, $this->k); + + if ($em2 === false || $em3 === false) { user_error('RSA modulus too short'); return false; } // Compare - return $this->_equals($em, $em2); + return $this->_equals($em, $em2) || $this->_equals($em, $em3); } /** From 7a5846cceec90569451d8c53bb6443c0c724974d Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 16:13:54 -0500 Subject: [PATCH 62/69] Test/RSA: add test for "strict" PKCS1 sigs without NULLs --- tests/Unit/Crypt/RSA/ModeTest.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/Unit/Crypt/RSA/ModeTest.php b/tests/Unit/Crypt/RSA/ModeTest.php index 28e91643a..a070b3d37 100644 --- a/tests/Unit/Crypt/RSA/ModeTest.php +++ b/tests/Unit/Crypt/RSA/ModeTest.php @@ -115,4 +115,25 @@ public function testPSSSigsWithNonPowerOf2Key() $payload = 'eyJraWQiOiJ0RkMyVUloRnBUTV9FYTNxY09kX01xUVQxY0JCbTlrRkxTRGZlSmhzUkc4IiwiYWxnIjoiUFMyNTYifQ.eyJhcHAiOiJhY2NvdW50cG9ydGFsIiwic3ViIjoiNTliOGM4YzA5NTVhNDA5MDg2MGRmYmM3ZGQwMjVjZWEiLCJjbGlkIjoiZTQ5ZTA2N2JiMTFjNDcyMmEzNGIyYjNiOGE2YTYzNTUiLCJhbSI6InBhc3N3b3JkIiwicCI6ImVOcDFrRUZQd3pBTWhmXC9QdEVOYU5kQkc2bUZDNHNpbENNNXU0aTNXMHFSS0hFVDU5V1JzcXpZRUp4XC84M3ZQbkIxcUg3Rm5CZVNabEtNME9saGVZVUVWTXlHOEVUOEZnWDI4dkdqWG4wWkcrV2hSK01rWVBicGZacHI2U3E0N0RFYjBLYkRFT21CSUZuOTZKN1ZDaWg1Q2p4dWNRZDJmdHJlMCt2cSthZFFObUluK0poWEl0UlBvQ0xya1wvZ05VV3N3T09vSVwva0Q5ZVk4c05jRHFPUzNkanFWb3RPU21oRUo5b0hZZmFqZmpSRzFGSWpGRFwvOExtT2pKbVF3d0tBMnQ0aXJBQ2NncHo0dzBuN3BtXC84YXV2T0dFM2twVFZ2d0IzdzlQZk1YZnJJUTBhejRsaEtIdVBUMU42XC9sb1FJPSIsImlhaSI6IjU5YjhjOGMwOTU1YTQwOTA4NjBkZmJjN2RkMDI1Y2VhIiwiY2xzdmMiOiJhY2NvdW50cG9ydGFsIiwibHB2IjoxNTQ3Njc1NDM4LCJ0IjoicyIsImljIjp0cnVlLCJleHAiOjE1NDc3MDQyMzgsImlhdCI6MTU0NzY3NTQzOCwianRpIjoiZTE0N2UzM2UzNzVhNDkyNWJjMzdjZTRjMDIwMmJjNDYifQ'; $this->assertTrue($rsa->verify($payload, $sig)); } + + public function testPKCS1SigWithoutNull() + { + $rsa = new Crypt_RSA(); + $rsa->loadKey(array( + 'n' => new Math_BigInteger('0xE932AC92252F585B3A80A4DD76A897C8B7652952FE788F6EC8DD640587A1EE5647670A8AD +4C2BE0F9FA6E49C605ADF77B5174230AF7BD50E5D6D6D6D28CCF0A886A514CC72E51D209CC7 +72A52EF419F6A953F3135929588EBE9B351FCA61CED78F346FE00DBB6306E5C2A4C6DFC3779 +AF85AB417371CF34D8387B9B30AE46D7A5FF5A655B8D8455F1B94AE736989D60A6F2FD5CADB +FFBD504C5A756A2E6BB5CECC13BCA7503F6DF8B52ACE5C410997E98809DB4DC30D943DE4E81 +2A47553DCE54844A78E36401D13F77DC650619FED88D8B3926E3D8E319C80C744779AC5D6AB +E252896950917476ECE5E8FC27D5F053D6018D91B502C4787558A002B9283DA7', 16), + 'e' => new Math_BigInteger('3') + )); + + $message = 'hello world!'; + $signature = pack('H*', 'a0073057133ff3758e7e111b4d7441f1d8cbe4b2dd5ee4316a14264290dee5ed7f175716639bd9bb43a14e4f9fcb9e84dedd35e2205caac04828b2c053f68176d971ea88534dd2eeec903043c3469fc69c206b2a8694fd262488441ed8852280c3d4994e9d42bd1d575c7024095f1a20665925c2175e089c0d731471f6cc145404edf5559fd2276e45e448086f71c78d0cc6628fad394a34e51e8c10bc39bfe09ed2f5f742cc68bee899d0a41e4c75b7b80afd1c321d89ccd9fe8197c44624d91cc935dfa48de3c201099b5b417be748aef29248527e8bbb173cab76b48478d4177b338fe1f1244e64d7d23f07add560d5ad50b68d6649a49d7bc3db686daaa7'); + + $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1); + $this->assertTrue($rsa->verify($message, $signature)); + } } From 4a3e08c2733a40de94ee82c21085c915cc667f7e Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 16:33:23 -0500 Subject: [PATCH 63/69] RSA: tweak to new validation method --- phpseclib/Crypt/RSA.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index de3d3ed5b..770c67478 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -3119,7 +3119,7 @@ function _rsassa_pkcs1_v1_5_verify($m, $s) $em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k); $em3 = $this->_emsa_pkcs1_v1_5_encode_without_null($m, $this->k); - if ($em2 === false || $em3 === false) { + if ($em2 === false && $em3 === false) { user_error('RSA modulus too short'); return false; } From 5fca2bcb7b2cc57651f18cd6d3f469c905a185b0 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 16:33:52 -0500 Subject: [PATCH 64/69] Tests/RSA: test requires sha256 --- tests/Unit/Crypt/RSA/ModeTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Unit/Crypt/RSA/ModeTest.php b/tests/Unit/Crypt/RSA/ModeTest.php index a070b3d37..021352a17 100644 --- a/tests/Unit/Crypt/RSA/ModeTest.php +++ b/tests/Unit/Crypt/RSA/ModeTest.php @@ -134,6 +134,7 @@ public function testPKCS1SigWithoutNull() $signature = pack('H*', 'a0073057133ff3758e7e111b4d7441f1d8cbe4b2dd5ee4316a14264290dee5ed7f175716639bd9bb43a14e4f9fcb9e84dedd35e2205caac04828b2c053f68176d971ea88534dd2eeec903043c3469fc69c206b2a8694fd262488441ed8852280c3d4994e9d42bd1d575c7024095f1a20665925c2175e089c0d731471f6cc145404edf5559fd2276e45e448086f71c78d0cc6628fad394a34e51e8c10bc39bfe09ed2f5f742cc68bee899d0a41e4c75b7b80afd1c321d89ccd9fe8197c44624d91cc935dfa48de3c201099b5b417be748aef29248527e8bbb173cab76b48478d4177b338fe1f1244e64d7d23f07add560d5ad50b68d6649a49d7bc3db686daaa7'); $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1); + $rsa->setHash('sha256'); $this->assertTrue($rsa->verify($message, $signature)); } } From 581fbdb67195c1a578e21b497973e6a0e4168b15 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 16:41:10 -0500 Subject: [PATCH 65/69] CS adjustments --- tests/Unit/Crypt/RSA/ModeTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Crypt/RSA/ModeTest.php b/tests/Unit/Crypt/RSA/ModeTest.php index 021352a17..e900be3d0 100644 --- a/tests/Unit/Crypt/RSA/ModeTest.php +++ b/tests/Unit/Crypt/RSA/ModeTest.php @@ -120,14 +120,14 @@ public function testPKCS1SigWithoutNull() { $rsa = new Crypt_RSA(); $rsa->loadKey(array( - 'n' => new Math_BigInteger('0xE932AC92252F585B3A80A4DD76A897C8B7652952FE788F6EC8DD640587A1EE5647670A8AD + 'n' => new Math_BigInteger('0xE932AC92252F585B3A80A4DD76A897C8B7652952FE788F6EC8DD640587A1EE5647670A8AD 4C2BE0F9FA6E49C605ADF77B5174230AF7BD50E5D6D6D6D28CCF0A886A514CC72E51D209CC7 72A52EF419F6A953F3135929588EBE9B351FCA61CED78F346FE00DBB6306E5C2A4C6DFC3779 AF85AB417371CF34D8387B9B30AE46D7A5FF5A655B8D8455F1B94AE736989D60A6F2FD5CADB FFBD504C5A756A2E6BB5CECC13BCA7503F6DF8B52ACE5C410997E98809DB4DC30D943DE4E81 2A47553DCE54844A78E36401D13F77DC650619FED88D8B3926E3D8E319C80C744779AC5D6AB E252896950917476ECE5E8FC27D5F053D6018D91B502C4787558A002B9283DA7', 16), - 'e' => new Math_BigInteger('3') + 'e' => new Math_BigInteger('3') )); $message = 'hello world!'; From d70abb929005b419cd911cfd45738c2a1bfd6f50 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 17:13:19 -0500 Subject: [PATCH 66/69] fix broken unit test --- tests/Unit/Crypt/RSA/ModeTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Unit/Crypt/RSA/ModeTest.php b/tests/Unit/Crypt/RSA/ModeTest.php index 2763df29a..854f90829 100644 --- a/tests/Unit/Crypt/RSA/ModeTest.php +++ b/tests/Unit/Crypt/RSA/ModeTest.php @@ -6,6 +6,7 @@ */ use phpseclib\Crypt\RSA; +use phpseclib\Math\BigInteger; class Unit_Crypt_RSA_ModeTest extends PhpseclibTestCase { From 8af4280bdebf77b87b558510c925794380b84d16 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 17:55:12 -0500 Subject: [PATCH 67/69] RSA: misc fixes for 'without NULL' PKCS1 signature validation --- phpseclib/Crypt/RSA.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 770c67478..c5f697701 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -3035,6 +3035,9 @@ function _emsa_pkcs1_v1_5_encode_without_null($m, $emLen) break; case 'sha512': $t = pack('H*', '304f300b06096086480165030402030440'); + break; + default: + return false; } $t.= $h; $tLen = strlen($t); From 149b4d213131d4d453fe190700a4ecc3d09de9cc Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 3 Apr 2021 18:16:59 -0500 Subject: [PATCH 68/69] RSA: fix for PHP8 --- phpseclib/Crypt/RSA.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index c5f697701..49a61f3b3 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -3128,7 +3128,9 @@ function _rsassa_pkcs1_v1_5_verify($m, $s) } // Compare - return $this->_equals($em, $em2) || $this->_equals($em, $em3); + + return ($em2 !== false && $this->_equals($em, $em2)) || + ($em3 !== false && $this->_equals($em, $em3)); } /** From 233a920cb38636a43b18d428f9a8db1f0a1a08f4 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 6 Apr 2021 08:56:45 -0500 Subject: [PATCH 69/69] CHANGELOG: add 2.0.31 release --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c98733b2..25e253114 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 2.0.31 - 2021-04-06 + +- X509: always parse the first cert of a bundle (#1568) +- SSH2: behave like putty with broken publickey auth (#1572) +- SSH2: don't close channel on unexpected response to channel request (#1631) +- RSA: support keys with PSS algorithm identifier (#1584) +- RSA: cleanup RSA PKCS#1 v1.5 signature verification (CVE-2021-30130) +- SFTP/Stream: make it so you can write past the end of a file (#1618) +- SFTP: fix undefined index notice in stream touch() (#1615) +- SFTP: digit only filenames were converted to integers by php (#1623) +- BigInteger: fix issue with toBits on 32-bit PHP 8 installs +- Crypt: use a custom error handler for mcrypt to avoid deprecation errors + ## 2.0.30 - 2020-12-16 - X509: don't attempt to parse multi-cert PEMs (#1542)