aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/phpseclib
diff options
context:
space:
mode:
authorMario <mario@mariovavti.com>2024-03-06 13:57:07 +0000
committerMario <mario@mariovavti.com>2024-03-06 13:57:07 +0000
commit5eb6572277ab8f83acc51f96ec94db4e074d01b2 (patch)
tree720a70f81ae1b23bb57f520c61bce74fdbc53484 /vendor/phpseclib
parent69bed9c889a5c153f7b9cece49be3b81bde24e32 (diff)
downloadvolse-hubzilla-5eb6572277ab8f83acc51f96ec94db4e074d01b2.tar.gz
volse-hubzilla-5eb6572277ab8f83acc51f96ec94db4e074d01b2.tar.bz2
volse-hubzilla-5eb6572277ab8f83acc51f96ec94db4e074d01b2.zip
update composer libs
Diffstat (limited to 'vendor/phpseclib')
-rw-r--r--vendor/phpseclib/phpseclib/AUTHORS1
-rw-r--r--vendor/phpseclib/phpseclib/BACKERS.md6
-rw-r--r--vendor/phpseclib/phpseclib/README.md3
-rw-r--r--vendor/phpseclib/phpseclib/composer.json3
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php42
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php99
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php446
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php10
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php2
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php8
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php12
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php53
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php5
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php43
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php12
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php36
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php17
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/File/X509.php28
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php67
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php7
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php141
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php20
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php169
-rw-r--r--vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php17
24 files changed, 1076 insertions, 171 deletions
diff --git a/vendor/phpseclib/phpseclib/AUTHORS b/vendor/phpseclib/phpseclib/AUTHORS
index a08b3099c..9f10d2671 100644
--- a/vendor/phpseclib/phpseclib/AUTHORS
+++ b/vendor/phpseclib/phpseclib/AUTHORS
@@ -4,3 +4,4 @@ phpseclib Developers: monnerat (Patrick Monnerat)
bantu (Andreas Fischer)
petrich (Hans-Jürgen Petrich)
GrahamCampbell (Graham Campbell)
+ hc-jworman \ No newline at end of file
diff --git a/vendor/phpseclib/phpseclib/BACKERS.md b/vendor/phpseclib/phpseclib/BACKERS.md
index 558293b55..efca482ad 100644
--- a/vendor/phpseclib/phpseclib/BACKERS.md
+++ b/vendor/phpseclib/phpseclib/BACKERS.md
@@ -10,4 +10,8 @@ phpseclib ongoing development is made possible by [Tidelift](https://tidelift.co
- Zane Hooper
- [Setasign](https://www.setasign.com/)
- [Charles Severance](https://github.com/csev)
-- [Rachel Fish](https://github.com/itsrachelfish) \ No newline at end of file
+- [Rachel Fish](https://github.com/itsrachelfish)
+- Tharyrok
+- [cjhaas](https://github.com/cjhaas)
+- [istiak-tridip](https://github.com/istiak-tridip)
+- [Anna Filina](https://github.com/afilina) \ No newline at end of file
diff --git a/vendor/phpseclib/phpseclib/README.md b/vendor/phpseclib/phpseclib/README.md
index 9be5517e6..1bdee151d 100644
--- a/vendor/phpseclib/phpseclib/README.md
+++ b/vendor/phpseclib/phpseclib/README.md
@@ -51,8 +51,7 @@ SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 /
* PHP4 compatible
* Composer compatible (PSR-0 autoloading)
* Install using Composer: `composer require phpseclib/phpseclib:~1.0`
-* Install using PEAR: See [phpseclib PEAR Channel Documentation](http://phpseclib.sourceforge.net/pear.htm)
-* [Download 1.0.20 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.20.zip/download)
+* [Download 1.0.23 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.23.zip/download)
## Security contact information
diff --git a/vendor/phpseclib/phpseclib/composer.json b/vendor/phpseclib/phpseclib/composer.json
index 08b9c7c91..3fbffa67c 100644
--- a/vendor/phpseclib/phpseclib/composer.json
+++ b/vendor/phpseclib/phpseclib/composer.json
@@ -62,7 +62,8 @@
"ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
"ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.",
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
- "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations."
+ "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
+ "ext-xml": "Install the XML extension to load XML formatted public keys."
},
"autoload": {
"files": [
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php
index 7d8cb8b03..9903db105 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php
@@ -84,43 +84,13 @@ class AES extends Rijndael
*/
function setKeyLength($length)
{
- switch ($length) {
- case 160:
- $length = 192;
- break;
- case 224:
- $length = 256;
- }
parent::setKeyLength($length);
- }
-
- /**
- * Sets the key.
- *
- * Rijndael supports five different key lengths, AES only supports three.
- *
- * @see \phpseclib\Crypt\Rijndael:setKey()
- * @see setKeyLength()
- * @access public
- * @param string $key
- */
- function setKey($key)
- {
- parent::setKey($key);
-
- if (!$this->explicit_key_length) {
- $length = strlen($key);
- switch (true) {
- case $length <= 16:
- $this->key_length = 16;
- break;
- case $length <= 24:
- $this->key_length = 24;
- break;
- default:
- $this->key_length = 32;
- }
- $this->_setEngine();
+ switch ($this->key_length) {
+ case 20:
+ $this->key_length = 24;
+ break;
+ case 28:
+ $this->key_length = 32;
}
}
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
index 2c143940b..ab5944cde 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
@@ -500,6 +500,46 @@ abstract class Base
}
$this->_setEngine();
+
+ // Determining whether inline crypting can be used by the cipher
+ if ($this->use_inline_crypt !== false) {
+ $this->use_inline_crypt = version_compare(PHP_VERSION, '5.3.0') >= 0 || function_exists('create_function');
+ }
+
+ if (!defined('PHP_INT_SIZE')) {
+ define('PHP_INT_SIZE', 4);
+ }
+
+ if (!defined('CRYPT_BASE_USE_REG_INTVAL')) {
+ switch (true) {
+ // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
+ case (PHP_OS & "\xDF\xDF\xDF") === 'WIN':
+ case !function_exists('php_uname'):
+ case !is_string(php_uname('m')):
+ case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
+ case PHP_INT_SIZE == 8:
+ define('CRYPT_BASE_USE_REG_INTVAL', true);
+ break;
+ case (php_uname('m') & "\xDF\xDF\xDF") == 'ARM':
+ switch (true) {
+ /* PHP 7.0.0 introduced a bug that affected 32-bit ARM processors:
+
+ https://github.com/php/php-src/commit/716da71446ebbd40fa6cf2cea8a4b70f504cc3cd
+
+ altho the changelogs make no mention of it, this bug was fixed with this commit:
+
+ https://github.com/php/php-src/commit/c1729272b17a1fe893d1a54e423d3b71470f3ee8
+
+ affected versions of PHP are: 7.0.x, 7.1.0 - 7.1.23 and 7.2.0 - 7.2.11 */
+ case PHP_VERSION_ID >= 70000 && PHP_VERSION_ID <= 70123:
+ case PHP_VERSION_ID >= 70200 && PHP_VERSION_ID <= 70211:
+ define('CRYPT_BASE_USE_REG_INTVAL', false);
+ break;
+ default:
+ define('CRYPT_BASE_USE_REG_INTVAL', true);
+ }
+ }
+ }
}
/**
@@ -593,6 +633,10 @@ abstract class Base
* $hash, $salt, $count, $dkLen
*
* Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php
+ * {@link https://en.wikipedia.org/wiki/Bcrypt bcypt}:
+ * $salt, $rounds, $keylen
+ *
+ * This is a modified version of bcrypt used by OpenSSH.
*
* @see Crypt/Hash.php
* @param string $password
@@ -606,6 +650,28 @@ abstract class Base
$key = '';
switch ($method) {
+ case 'bcrypt':
+ $func_args = func_get_args();
+
+ if (!isset($func_args[2])) {
+ return false;
+ }
+
+ $salt = $func_args[2];
+
+ $rounds = isset($func_args[3]) ? $func_args[3] : 16;
+ $keylen = isset($func_args[4]) ? $func_args[4] : $this->key_length;
+
+ $bf = new Blowfish();
+ $key = $bf->bcrypt_pbkdf($password, $salt, $keylen + $this->block_size, $rounds);
+ if (!$key) {
+ return false;
+ }
+
+ $this->setKey(substr($key, 0, $keylen));
+ $this->setIV(substr($key, $keylen));
+
+ return true;
default: // 'pbkdf2' or 'pbkdf1'
$func_args = func_get_args();
@@ -1105,7 +1171,7 @@ abstract class Base
$plaintext = '';
if ($this->continuousBuffer) {
$iv = &$this->decryptIV;
- $pos = &$this->buffer['pos'];
+ $pos = &$this->debuffer['pos'];
} else {
$iv = $this->decryptIV;
$pos = 0;
@@ -2798,11 +2864,8 @@ abstract class Base
*/
function safe_intval($x)
{
- switch (true) {
- case is_int($x):
- // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
- case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
- return $x;
+ if (is_int($x)) {
+ return $x;
}
return (fmod($x, 0x80000000) & 0x7FFFFFFF) |
((fmod(floor($x / 0x80000000), 2) & 1) << 31);
@@ -2816,15 +2879,12 @@ abstract class Base
*/
function safe_intval_inline()
{
- switch (true) {
- case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8:
- case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
- return '%s';
- break;
- default:
- $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | ';
- return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))';
+ if (CRYPT_BASE_USE_REG_INTVAL) {
+ return PHP_INT_SIZE == 4 ? 'intval(%s)' : '%s';
}
+
+ $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | ';
+ return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))';
}
/**
@@ -2835,4 +2895,15 @@ abstract class Base
function do_nothing()
{
}
+
+ /**
+ * Is the continuous buffer enabled?
+ *
+ * @access public
+ * @return boolean
+ */
+ function continuousBufferEnabled()
+ {
+ return $this->continuousBuffer;
+ }
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
index 74cc49de8..346c064b8 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
@@ -11,6 +11,87 @@
*
* - {@link http://en.wikipedia.org/wiki/Blowfish_(cipher) Wikipedia description of Blowfish}
*
+ * # An overview of bcrypt vs Blowfish
+ *
+ * OpenSSH private keys use a customized version of bcrypt. Specifically, instead of
+ * encrypting OrpheanBeholderScryDoubt 64 times OpenSSH's bcrypt variant encrypts
+ * OxychromaticBlowfishSwatDynamite 64 times. so we can't use crypt().
+ *
+ * bcrypt is basically Blowfish but instead of performing the key expansion once it performs
+ * the expansion 129 times for each round, with the first key expansion interleaving the salt
+ * and password. This renders OpenSSL unusable and forces us to use a pure-PHP implementation
+ * of blowfish.
+ *
+ * # phpseclib's four different _encryptBlock() implementations
+ *
+ * When using Blowfish as an encryption algorithm, _encryptBlock() is called 9 + 512 +
+ * (the number of blocks in the plaintext) times.
+ *
+ * Each of the first 9 calls to _encryptBlock() modify the P-array. Each of the next 512
+ * calls modify the S-boxes. The remaining _encryptBlock() calls operate on the plaintext to
+ * produce the ciphertext. In the pure-PHP implementation of Blowfish these remaining
+ * _encryptBlock() calls are highly optimized through the use of eval(). Among other things,
+ * P-array lookups are eliminated by hard-coding the key-dependent P-array values, and thus we
+ * have explained 2 of the 4 different _encryptBlock() implementations.
+ *
+ * With bcrypt things are a bit different. _encryptBlock() is called 1,079,296 times,
+ * assuming 16 rounds (which is what OpenSSH's bcrypt defaults to). The eval()-optimized
+ * _encryptBlock() isn't as beneficial because the P-array values are not constant. Well, they
+ * are constant, but only for, at most, 777 _encryptBlock() calls, which is equivalent to ~6KB
+ * of data. The average length of back to back _encryptBlock() calls with a fixed P-array is
+ * 514.12, which is ~4KB of data. Creating an eval()-optimized _encryptBlock() has an upfront
+ * cost, which is CPU dependent and is probably not going to be worth it for just ~4KB of
+ * data. Conseqeuently, bcrypt does not benefit from the eval()-optimized _encryptBlock().
+ *
+ * The regular _encryptBlock() does unpack() and pack() on every call, as well, and that can
+ * begin to add up after one million function calls.
+ *
+ * In theory, one might think that it might be beneficial to rewrite all block ciphers so
+ * that, instead of passing strings to _encryptBlock(), you convert the string to an array of
+ * integers and then pass successive subarrays of that array to _encryptBlock. This, however,
+ * kills PHP's memory use. Like let's say you have a 1MB long string. After doing
+ * $in = str_repeat('a', 1024 * 1024); PHP's memory utilization jumps up by ~1MB. After doing
+ * $blocks = str_split($in, 4); it jumps up by an additional ~16MB. After
+ * $blocks = array_map(fn($x) => unpack('N*', $x), $blocks); it jumps up by an additional
+ * ~90MB, yielding a 106x increase in memory usage. Consequently, it bcrypt calls a different
+ * _encryptBlock() then the regular Blowfish does. That said, the Blowfish _encryptBlock() is
+ * basically just a thin wrapper around the bcrypt _encryptBlock(), so there's that.
+ *
+ * This explains 3 of the 4 _encryptBlock() implementations. the last _encryptBlock()
+ * implementation can best be understood by doing Ctrl + F and searching for where
+ * CRYPT_BASE_USE_REG_INTVAL is defined.
+ *
+ * # phpseclib's three different _setupKey() implementations
+ *
+ * Every bcrypt round is the equivalent of encrypting 512KB of data. Since OpenSSH uses 16
+ * rounds by default that's ~8MB of data that's essentially being encrypted whenever
+ * you use bcrypt. That's a lot of data, however, bcrypt operates within tighter constraints
+ * than regular Blowfish, so we can use that to our advantage. In particular, whereas Blowfish
+ * supports variable length keys, in bcrypt, the initial "key" is the sha512 hash of the
+ * password. sha512 hashes are 512 bits or 64 bytes long and thus the bcrypt keys are of a
+ * fixed length whereas Blowfish keys are not of a fixed length.
+ *
+ * bcrypt actually has two different key expansion steps. The first one (expandstate) is
+ * constantly XOR'ing every _encryptBlock() parameter against the salt prior _encryptBlock()'s
+ * being called. The second one (expand0state) is more similar to Blowfish's _setupKey()
+ * but it can still use the fixed length key optimization discussed above and can do away with
+ * the pack() / unpack() calls.
+ *
+ * I suppose _setupKey() could be made to be a thin wrapper around expandstate() but idk it's
+ * just a lot of work for very marginal benefits as _setupKey() is only called once for
+ * regular Blowfish vs the 128 times it's called --per round-- with bcrypt.
+ *
+ * # blowfish + bcrypt in the same class
+ *
+ * Altho there's a lot of Blowfish code that bcrypt doesn't re-use, bcrypt does re-use the
+ * initial S-boxes, the initial P-array and the int-only _encryptBlock() implementation.
+ *
+ * # Credit
+ *
+ * phpseclib's bcrypt implementation is based losely off of OpenSSH's implementation:
+ *
+ * https://github.com/openssh/openssh-portable/blob/master/openbsd-compat/bcrypt_pbkdf.c
+ *
* Here's a short example of how to use this library:
* <code>
* <?php
@@ -75,6 +156,15 @@ class Blowfish extends Base
var $cfb_init_len = 500;
/**
+ * SHA512 Object
+ *
+ * @see self::bcrypt_pbkdf
+ * @var object
+ * @access private
+ */
+ var $sha512;
+
+ /**
* The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
*
* S-Box 0
@@ -284,6 +374,41 @@ class Blowfish extends Base
var $key_length = 16;
/**
+ * Default Constructor.
+ *
+ * Determines whether or not the mcrypt extension should be used.
+ *
+ * $mode could be:
+ *
+ * - CRYPT_MODE_ECB
+ *
+ * - CRYPT_MODE_CBC
+ *
+ * - CRYPT_MODE_CTR
+ *
+ * - CRYPT_MODE_CFB
+ *
+ * - CRYPT_MODE_OFB
+ *
+ * (or the alias constants of the chosen cipher, for example for AES: CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC ...)
+ *
+ * If not explicitly set, CRYPT_MODE_CBC will be used.
+ *
+ * @param int $mode
+ * @access public
+ */
+ function __construct($mode = self::MODE_CBC)
+ {
+ parent::__construct($mode);
+
+ $this->sbox0 = array_map('intval', $this->sbox0);
+ $this->sbox1 = array_map('intval', $this->sbox1);
+ $this->sbox2 = array_map('intval', $this->sbox2);
+ $this->sbox3 = array_map('intval', $this->sbox3);
+ $this->parray = array_map('intval', $this->parray);
+ }
+
+ /**
* Sets the key length.
*
* Key lengths can be between 32 and 448 bits.
@@ -317,6 +442,12 @@ class Blowfish extends Base
function isValidEngine($engine)
{
if ($engine == self::ENGINE_OPENSSL) {
+ // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1
+ // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider"
+ // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not
+ if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) {
+ return false;
+ }
if (version_compare(PHP_VERSION, '5.3.7') < 0 && $this->key_length != 16) {
return false;
}
@@ -358,6 +489,7 @@ class Blowfish extends Base
// unpack binary string in unsigned chars
$key = array_values(unpack('C*', $this->key));
$keyl = count($key);
+ // with bcrypt $keyl will always be 16 (because the key is the sha512 of the key you provide)
for ($j = 0, $i = 0; $i < 18; ++$i) {
// xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ...
for ($data = 0, $k = 0; $k < 4; ++$k) {
@@ -366,7 +498,7 @@ class Blowfish extends Base
$j = 0;
}
}
- $this->bctx['p'][] = $this->parray[$i] ^ $data;
+ $this->bctx['p'][] = $this->parray[$i] ^ intval($data);
}
// encrypt the zero-string, replace P1 and P2 with the encrypted data,
@@ -387,6 +519,230 @@ class Blowfish extends Base
}
/**
+ * bcrypt
+ *
+ * @param string $sha2pass
+ * @param string $sha2salt
+ * @access private
+ * @return string
+ */
+ function _bcrypt_hash($sha2pass, $sha2salt)
+ {
+ $p = $this->parray;
+ $sbox0 = $this->sbox0;
+ $sbox1 = $this->sbox1;
+ $sbox2 = $this->sbox2;
+ $sbox3 = $this->sbox3;
+
+ $cdata = array_values(unpack('N*', 'OxychromaticBlowfishSwatDynamite'));
+ $sha2pass = array_values(unpack('N*', $sha2pass));
+ $sha2salt = array_values(unpack('N*', $sha2salt));
+
+ $this->_expandstate($sha2salt, $sha2pass, $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ for ($i = 0; $i < 64; $i++) {
+ $this->_expand0state($sha2salt, $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ $this->_expand0state($sha2pass, $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ }
+
+ for ($i = 0; $i < 64; $i++) {
+ for ($j = 0; $j < 8; $j+= 2) { // count($cdata) == 8
+ list($cdata[$j], $cdata[$j + 1]) = $this->_encryptBlockHelperFast($cdata[$j], $cdata[$j + 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ }
+ }
+
+ $output = '';
+ for ($i = 0; $i < count($cdata); $i++) {
+ $output.= pack('L*', $cdata[$i]);
+ }
+ return $output;
+ }
+
+ /**
+ * Performs OpenSSH-style bcrypt
+ *
+ * @param string $pass
+ * @param string $salt
+ * @param int $keylen
+ * @param int $rounds
+ * @access public
+ * @return false|string
+ */
+ function bcrypt_pbkdf($pass, $salt, $keylen, $rounds)
+ {
+ if (PHP_INT_SIZE == 4) {
+ user_error('bcrypt is far too slow to be practical on 32-bit versions of PHP');
+ return false;
+ }
+
+ if (!isset($this->sha512)) {
+ $this->sha512 = new Hash('sha512');
+ }
+
+ $sha2pass = $this->sha512->hash($pass);
+ $results = array();
+ $count = 1;
+ while (32 * count($results) < $keylen) {
+ $countsalt = $salt . pack('N', $count++);
+ $sha2salt = $this->sha512->hash($countsalt);
+ $out = $tmpout = $this->_bcrypt_hash($sha2pass, $sha2salt);
+ for ($i = 1; $i < $rounds; $i++) {
+ $sha2salt = $this->sha512->hash($tmpout);
+ $tmpout = $this->_bcrypt_hash($sha2pass, $sha2salt);
+ $out^= $tmpout;
+ }
+ $results[] = $out;
+ }
+ $output = '';
+ for ($i = 0; $i < 32; $i++) {
+ foreach ($results as $result) {
+ $output.= $result[$i];
+ }
+ }
+ return substr($output, 0, $keylen);
+ }
+
+ /**
+ * Key expansion without salt
+ *
+ * @access private
+ * @param int[] $key
+ * @param int[] $sbox0
+ * @param int[] $sbox1
+ * @param int[] $sbox2
+ * @param int[] $sbox3
+ * @param int[] $p
+ * @see self::_bcrypt_hash()
+ */
+ function _expand0state($key, &$sbox0, &$sbox1, &$sbox2, &$sbox3, &$p)
+ {
+ // expand0state is basically the same thing as this:
+ //return $this->_expandstate(array_fill(0, 16, 0), $key);
+ // but this separate function eliminates a bunch of XORs and array lookups
+
+ $p = array(
+ $p[0] ^ $key[0],
+ $p[1] ^ $key[1],
+ $p[2] ^ $key[2],
+ $p[3] ^ $key[3],
+ $p[4] ^ $key[4],
+ $p[5] ^ $key[5],
+ $p[6] ^ $key[6],
+ $p[7] ^ $key[7],
+ $p[8] ^ $key[8],
+ $p[9] ^ $key[9],
+ $p[10] ^ $key[10],
+ $p[11] ^ $key[11],
+ $p[12] ^ $key[12],
+ $p[13] ^ $key[13],
+ $p[14] ^ $key[14],
+ $p[15] ^ $key[15],
+ $p[16] ^ $key[0],
+ $p[17] ^ $key[1]
+ );
+
+ // @codingStandardsIgnoreStart
+ list( $p[0], $p[1]) = $this->_encryptBlockHelperFast( 0, 0, $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list( $p[2], $p[3]) = $this->_encryptBlockHelperFast($p[ 0], $p[ 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list( $p[4], $p[5]) = $this->_encryptBlockHelperFast($p[ 2], $p[ 3], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list( $p[6], $p[7]) = $this->_encryptBlockHelperFast($p[ 4], $p[ 5], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list( $p[8], $p[9]) = $this->_encryptBlockHelperFast($p[ 6], $p[ 7], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list($p[10], $p[11]) = $this->_encryptBlockHelperFast($p[ 8], $p[ 9], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list($p[12], $p[13]) = $this->_encryptBlockHelperFast($p[10], $p[11], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list($p[14], $p[15]) = $this->_encryptBlockHelperFast($p[12], $p[13], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list($p[16], $p[17]) = $this->_encryptBlockHelperFast($p[14], $p[15], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ // @codingStandardsIgnoreEnd
+
+ list($sbox0[0], $sbox0[1]) = $this->_encryptBlockHelperFast($p[16], $p[17], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ for ($i = 2; $i < 256; $i+= 2) {
+ list($sbox0[$i], $sbox0[$i + 1]) = $this->_encryptBlockHelperFast($sbox0[$i - 2], $sbox0[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ }
+
+ list($sbox1[0], $sbox1[1]) = $this->_encryptBlockHelperFast($sbox0[254], $sbox0[255], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ for ($i = 2; $i < 256; $i+= 2) {
+ list($sbox1[$i], $sbox1[$i + 1]) = $this->_encryptBlockHelperFast($sbox1[$i - 2], $sbox1[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ }
+
+ list($sbox2[0], $sbox2[1]) = $this->_encryptBlockHelperFast($sbox1[254], $sbox1[255], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ for ($i = 2; $i < 256; $i+= 2) {
+ list($sbox2[$i], $sbox2[$i + 1]) = $this->_encryptBlockHelperFast($sbox2[$i - 2], $sbox2[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ }
+
+ list($sbox3[0], $sbox3[1]) = $this->_encryptBlockHelperFast($sbox2[254], $sbox2[255], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ for ($i = 2; $i < 256; $i+= 2) {
+ list($sbox3[$i], $sbox3[$i + 1]) = $this->_encryptBlockHelperFast($sbox3[$i - 2], $sbox3[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ }
+ }
+
+ /**
+ * Key expansion with salt
+ *
+ * @access private
+ * @param int[] $data
+ * @param int[] $key
+ * @param int[] $sbox0
+ * @param int[] $sbox1
+ * @param int[] $sbox2
+ * @param int[] $sbox3
+ * @param int[] $p
+ * @see self::_bcrypt_hash()
+ */
+ function _expandstate($data, $key, &$sbox0, &$sbox1, &$sbox2, &$sbox3, &$p)
+ {
+ $p = array(
+ $p[0] ^ $key[0],
+ $p[1] ^ $key[1],
+ $p[2] ^ $key[2],
+ $p[3] ^ $key[3],
+ $p[4] ^ $key[4],
+ $p[5] ^ $key[5],
+ $p[6] ^ $key[6],
+ $p[7] ^ $key[7],
+ $p[8] ^ $key[8],
+ $p[9] ^ $key[9],
+ $p[10] ^ $key[10],
+ $p[11] ^ $key[11],
+ $p[12] ^ $key[12],
+ $p[13] ^ $key[13],
+ $p[14] ^ $key[14],
+ $p[15] ^ $key[15],
+ $p[16] ^ $key[0],
+ $p[17] ^ $key[1]
+ );
+
+ // @codingStandardsIgnoreStart
+ list( $p[0], $p[1]) = $this->_encryptBlockHelperFast($data[ 0] , $data[ 1] , $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list( $p[2], $p[3]) = $this->_encryptBlockHelperFast($data[ 2] ^ $p[ 0], $data[ 3] ^ $p[ 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list( $p[4], $p[5]) = $this->_encryptBlockHelperFast($data[ 4] ^ $p[ 2], $data[ 5] ^ $p[ 3], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list( $p[6], $p[7]) = $this->_encryptBlockHelperFast($data[ 6] ^ $p[ 4], $data[ 7] ^ $p[ 5], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list( $p[8], $p[9]) = $this->_encryptBlockHelperFast($data[ 8] ^ $p[ 6], $data[ 9] ^ $p[ 7], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list($p[10], $p[11]) = $this->_encryptBlockHelperFast($data[10] ^ $p[ 8], $data[11] ^ $p[ 9], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list($p[12], $p[13]) = $this->_encryptBlockHelperFast($data[12] ^ $p[10], $data[13] ^ $p[11], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list($p[14], $p[15]) = $this->_encryptBlockHelperFast($data[14] ^ $p[12], $data[15] ^ $p[13], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ list($p[16], $p[17]) = $this->_encryptBlockHelperFast($data[ 0] ^ $p[14], $data[ 1] ^ $p[15], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ // @codingStandardsIgnoreEnd
+
+ list($sbox0[0], $sbox0[1]) = $this->_encryptBlockHelperFast($data[2] ^ $p[16], $data[3] ^ $p[17], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ for ($i = 2, $j = 4; $i < 256; $i+= 2, $j = ($j + 2) % 16) { // instead of 16 maybe count($data) would be better?
+ list($sbox0[$i], $sbox0[$i + 1]) = $this->_encryptBlockHelperFast($data[$j] ^ $sbox0[$i - 2], $data[$j + 1] ^ $sbox0[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ }
+
+ list($sbox1[0], $sbox1[1]) = $this->_encryptBlockHelperFast($data[2] ^ $sbox0[254], $data[3] ^ $sbox0[255], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ for ($i = 2, $j = 4; $i < 256; $i+= 2, $j = ($j + 2) % 16) {
+ list($sbox1[$i], $sbox1[$i + 1]) = $this->_encryptBlockHelperFast($data[$j] ^ $sbox1[$i - 2], $data[$j + 1] ^ $sbox1[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ }
+
+ list($sbox2[0], $sbox2[1]) = $this->_encryptBlockHelperFast($data[2] ^ $sbox1[254], $data[3] ^ $sbox1[255], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ for ($i = 2, $j = 4; $i < 256; $i+= 2, $j = ($j + 2) % 16) {
+ list($sbox2[$i], $sbox2[$i + 1]) = $this->_encryptBlockHelperFast($data[$j] ^ $sbox2[$i - 2], $data[$j + 1] ^ $sbox2[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ }
+
+ list($sbox3[0], $sbox3[1]) = $this->_encryptBlockHelperFast($data[2] ^ $sbox2[254], $data[3] ^ $sbox2[255], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ for ($i = 2, $j = 4; $i < 256; $i+= 2, $j = ($j + 2) % 16) {
+ list($sbox3[$i], $sbox3[$i + 1]) = $this->_encryptBlockHelperFast($data[$j] ^ $sbox3[$i - 2], $data[$j + 1] ^ $sbox3[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
+ }
+ }
+
+ /**
* Encrypts a block
*
* @access private
@@ -406,18 +762,84 @@ class Blowfish extends Base
$l = $in[1];
$r = $in[2];
- for ($i = 0; $i < 16; $i+= 2) {
- $l^= $p[$i];
- $r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^
- $sb_2[$l >> 8 & 0xff]) +
- $sb_3[$l & 0xff]);
+ list($r, $l) = PHP_INT_SIZE === 8 ?
+ $this->_encryptBlockHelperFast($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p) :
+ $this->_encryptBlockHelperSlow($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p);
- $r^= $p[$i + 1];
- $l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^
- $sb_2[$r >> 8 & 0xff]) +
- $sb_3[$r & 0xff]);
- }
- return pack("N*", $r ^ $p[17], $l ^ $p[16]);
+ return pack("N*", $r, $l);
+ }
+
+ /**
+ * Fast helper function for block encryption
+ *
+ * @access private
+ * @param int $x0
+ * @param int $x1
+ * @param int[] $sbox0
+ * @param int[] $sbox1
+ * @param int[] $sbox2
+ * @param int[] $sbox3
+ * @param int[] $p
+ * @return int[]
+ */
+ function _encryptBlockHelperFast($x0, $x1, $sbox0, $sbox1, $sbox2, $sbox3, $p)
+ {
+ $x0 ^= $p[0];
+ $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[1];
+ $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[2];
+ $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[3];
+ $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[4];
+ $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[5];
+ $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[6];
+ $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[7];
+ $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[8];
+ $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[9];
+ $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[10];
+ $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[11];
+ $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[12];
+ $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[13];
+ $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[14];
+ $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[15];
+ $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[16];
+
+ return array($x1 & 0xFFFFFFFF ^ $p[17], $x0 & 0xFFFFFFFF);
+ }
+
+ /**
+ * Slow helper function for block encryption
+ *
+ * @access private
+ * @param int $x0
+ * @param int $x1
+ * @param int[] $sbox0
+ * @param int[] $sbox1
+ * @param int[] $sbox2
+ * @param int[] $sbox3
+ * @param int[] $p
+ * @return int[]
+ */
+ function _encryptBlockHelperSlow($x0, $x1, $sbox0, $sbox1, $sbox2, $sbox3, $p)
+ {
+ // -16777216 == intval(0xFF000000) on 32-bit PHP installs
+ $x0^= $p[0];
+ $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[1];
+ $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[2];
+ $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[3];
+ $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[4];
+ $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[5];
+ $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[6];
+ $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[7];
+ $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[8];
+ $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[9];
+ $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[10];
+ $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[11];
+ $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[12];
+ $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[13];
+ $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[14];
+ $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[15];
+ $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[16];
+
+ return array($x1 ^ $p[17], $x0);
}
/**
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
index 9a8225fb5..26bd385f5 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
@@ -592,6 +592,12 @@ class DES extends Base
{
if ($this->key_length_max == 8) {
if ($engine == self::ENGINE_OPENSSL) {
+ // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1
+ // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider"
+ // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not
+ if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) {
+ return false;
+ }
$this->cipher_name_openssl_ecb = 'des-ecb';
$this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode();
}
@@ -1246,9 +1252,9 @@ class DES extends Base
$pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[ $d & 0xFF];
// Reorder: odd bytes/even bytes. Push the result in key schedule.
- $val1 = ( $cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) |
+ $val1 = ( $cp & intval(0xFF000000)) | (($cp << 8) & 0x00FF0000) |
(($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF);
- $val2 = (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
+ $val2 = (($cp << 8) & intval(0xFF000000)) | (($cp << 16) & 0x00FF0000) |
(($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF);
$keys[$des_round][self::ENCRYPT][ ] = $val1;
$keys[$des_round][self::DECRYPT][$ki - 1] = $val1;
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
index 248b65ef7..5e5d13d4c 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
@@ -866,7 +866,7 @@ class Hash
$result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
}
- if ((php_uname('m') & "\xDF\xDF\xDF") != 'ARM') {
+ if (function_exists('php_uname') && is_string(php_uname('m')) && (php_uname('m') & "\xDF\xDF\xDF") != 'ARM') {
return fmod($result, $mod);
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php
index b2b9d48ea..e0511b32f 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php
@@ -72,7 +72,7 @@ class RC2 extends Base
* @var string
* @access private
*/
- var $orig_key;
+ var $orig_key = '';
/**
* Don't truncate / null pad key
@@ -273,6 +273,12 @@ class RC2 extends Base
{
switch ($engine) {
case self::ENGINE_OPENSSL:
+ // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1
+ // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider"
+ // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not
+ if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) {
+ return false;
+ }
if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) {
return false;
}
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php
index 25e4ff854..2e5c05567 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php
@@ -144,7 +144,13 @@ class RC4 extends Base
*/
function isValidEngine($engine)
{
- if ($engine == Base::ENGINE_OPENSSL) {
+ if ($engine == self::ENGINE_OPENSSL) {
+ // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1
+ // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider"
+ // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not
+ if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) {
+ return false;
+ }
if (version_compare(PHP_VERSION, '5.3.7') >= 0) {
$this->cipher_name_openssl = 'rc4-40';
} else {
@@ -222,7 +228,7 @@ class RC4 extends Base
*/
function encrypt($plaintext)
{
- if ($this->engine != Base::ENGINE_INTERNAL) {
+ if ($this->engine != self::ENGINE_INTERNAL) {
return parent::encrypt($plaintext);
}
return $this->_crypt($plaintext, self::ENCRYPT);
@@ -242,7 +248,7 @@ class RC4 extends Base
*/
function decrypt($ciphertext)
{
- if ($this->engine != Base::ENGINE_INTERNAL) {
+ if ($this->engine != self::ENGINE_INTERNAL) {
return parent::decrypt($ciphertext);
}
return $this->_crypt($ciphertext, self::DECRYPT);
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
index 122d281a8..fec689585 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
@@ -570,6 +570,7 @@ class RSA
$publickey = call_user_func_array(array($this, '_convertPublicKey'), array_values($this->_parseKey($publickey, self::PUBLIC_FORMAT_PKCS1)));
// clear the buffer of error strings stemming from a minimalistic openssl.cnf
+ // https://github.com/php/php-src/issues/11054 talks about other errors this'll pick up
while (openssl_error_string() !== false) {
}
@@ -1388,6 +1389,10 @@ class RSA
// http://en.wikipedia.org/wiki/XML_Signature
case self::PRIVATE_FORMAT_XML:
case self::PUBLIC_FORMAT_XML:
+ if (!extension_loaded('xml')) {
+ return false;
+ }
+
$this->components = array();
$xml = xml_parser_create('UTF-8');
@@ -1522,14 +1527,44 @@ class RSA
if ($magic !== "openssh-key-v1\0") {
return false;
}
- $options = $this->_string_shift($decoded, 24);
- // \0\0\0\4none = ciphername
- // \0\0\0\4none = kdfname
- // \0\0\0\0 = kdfoptions
- // \0\0\0\1 = numkeys
- if ($options != "\0\0\0\4none\0\0\0\4none\0\0\0\0\0\0\0\1") {
+ extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
+ if (strlen($decoded) < $length) {
+ return false;
+ }
+ $ciphername = $this->_string_shift($decoded, $length);
+ extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
+ if (strlen($decoded) < $length) {
return false;
}
+ $kdfname = $this->_string_shift($decoded, $length);
+ extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
+ if (strlen($decoded) < $length) {
+ return false;
+ }
+ $kdfoptions = $this->_string_shift($decoded, $length);
+ extract(unpack('Nnumkeys', $this->_string_shift($decoded, 4)));
+ if ($numkeys != 1 || ($ciphername != 'none' && $kdfname != 'bcrypt')) {
+ return false;
+ }
+ switch ($ciphername) {
+ case 'none':
+ break;
+ case 'aes256-ctr':
+ extract(unpack('Nlength', $this->_string_shift($kdfoptions, 4)));
+ if (strlen($kdfoptions) < $length) {
+ return false;
+ }
+ $salt = $this->_string_shift($kdfoptions, $length);
+ extract(unpack('Nrounds', $this->_string_shift($kdfoptions, 4)));
+ $crypto = new AES(AES::MODE_CTR);
+ $crypto->disablePadding();
+ if (!$crypto->setPassword($this->password, 'bcrypt', $salt, $rounds, 32)) {
+ return false;
+ }
+ break;
+ default:
+ return false;
+ }
extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
if (strlen($decoded) < $length) {
return false;
@@ -1539,12 +1574,16 @@ class RSA
if (strlen($decoded) < $length) {
return false;
}
- $paddedKey = $this->_string_shift($decoded, $length);
if ($this->_string_shift($publicKey, 11) !== "\0\0\0\7ssh-rsa") {
return false;
}
+ $paddedKey = $this->_string_shift($decoded, $length);
+ if (isset($crypto)) {
+ $paddedKey = $crypto->decrypt($paddedKey);
+ }
+
$checkint1 = $this->_string_shift($paddedKey, 4);
$checkint2 = $this->_string_shift($paddedKey, 4);
if (strlen($checkint1) != 4 || $checkint1 !== $checkint2) {
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php
index 8f53eb319..e039340c5 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php
@@ -151,7 +151,10 @@ class Random
(isset($_POST) ? phpseclib_safe_serialize($_POST) : '') .
(isset($_GET) ? phpseclib_safe_serialize($_GET) : '') .
(isset($_COOKIE) ? phpseclib_safe_serialize($_COOKIE) : '') .
- phpseclib_safe_serialize($GLOBALS) .
+ // as of PHP 8.1 $GLOBALS can't be accessed by reference, which eliminates
+ // the need for phpseclib_safe_serialize. see https://wiki.php.net/rfc/restrict_globals_usage
+ // for more info
+ (version_compare(PHP_VERSION, '8.1.0', '>=') ? serialize($GLOBALS) : phpseclib_safe_serialize($GLOBALS)) .
phpseclib_safe_serialize($_SESSION) .
phpseclib_safe_serialize($_OLD_SESSION)
));
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
index 3648a1972..4665738e1 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
@@ -340,7 +340,7 @@ class Rijndael extends Base
$k = $c[2];
$l = $c[3];
while ($i < $Nb) {
- $temp[$i] = ($state[$i] & 0xFF000000) ^
+ $temp[$i] = ($state[$i] & intval(0xFF000000)) ^
($state[$j] & 0x00FF0000) ^
($state[$k] & 0x0000FF00) ^
($state[$l] & 0x000000FF) ^
@@ -426,7 +426,7 @@ class Rijndael extends Base
$l = $Nb - $c[3];
while ($i < $Nb) {
- $word = ($state[$i] & 0xFF000000) |
+ $word = ($state[$i] & intval(0xFF000000)) |
($state[$j] & 0x00FF0000) |
($state[$k] & 0x0000FF00) |
($state[$l] & 0x000000FF);
@@ -465,14 +465,19 @@ class Rijndael extends Base
{
// Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field.
// See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse
- static $rcon = array(0,
- 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
- 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
- 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000,
- 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000,
- 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000,
- 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
- );
+ static $rcon;
+
+ if (!isset($rcon)) {
+ $rcon = array(0,
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
+ 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
+ 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000,
+ 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000,
+ 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000,
+ 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
+ );
+ $rcon = array_map('intval', $rcon);
+ }
if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) {
// already expanded
@@ -511,7 +516,7 @@ class Rijndael extends Base
// on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine,
// 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and'
// with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.
- $temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord
+ $temp = (($temp << 8) & intval(0xFFFFFF00)) | (($temp >> 24) & 0x000000FF); // rotWord
$temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk];
} elseif ($this->Nk > 6 && $i % $this->Nk == 4) {
$temp = $this->_subWord($temp);
@@ -641,9 +646,9 @@ class Rijndael extends Base
));
foreach ($t3 as $t3i) {
- $t0[] = (($t3i << 24) & 0xFF000000) | (($t3i >> 8) & 0x00FFFFFF);
- $t1[] = (($t3i << 16) & 0xFFFF0000) | (($t3i >> 16) & 0x0000FFFF);
- $t2[] = (($t3i << 8) & 0xFFFFFF00) | (($t3i >> 24) & 0x000000FF);
+ $t0[] = (($t3i << 24) & intval(0xFF000000)) | (($t3i >> 8) & 0x00FFFFFF);
+ $t1[] = (($t3i << 16) & intval(0xFFFF0000)) | (($t3i >> 16) & 0x0000FFFF);
+ $t2[] = (($t3i << 8) & intval(0xFFFFFF00)) | (($t3i >> 24) & 0x000000FF);
}
$tables = array(
@@ -725,9 +730,9 @@ class Rijndael extends Base
));
foreach ($dt3 as $dt3i) {
- $dt0[] = (($dt3i << 24) & 0xFF000000) | (($dt3i >> 8) & 0x00FFFFFF);
- $dt1[] = (($dt3i << 16) & 0xFFFF0000) | (($dt3i >> 16) & 0x0000FFFF);
- $dt2[] = (($dt3i << 8) & 0xFFFFFF00) | (($dt3i >> 24) & 0x000000FF);
+ $dt0[] = (($dt3i << 24) & intval(0xFF000000)) | (($dt3i >> 8) & 0x00FFFFFF);
+ $dt1[] = (($dt3i << 16) & intval(0xFFFF0000)) | (($dt3i >> 16) & 0x0000FFFF);
+ $dt2[] = (($dt3i << 8) & intval(0xFFFFFF00)) | (($dt3i >> 24) & 0x000000FF);
};
$tables = array(
@@ -809,7 +814,6 @@ class Rijndael extends Base
// Generating encrypt code:
$init_encrypt.= '
- static $tables;
if (empty($tables)) {
$tables = &$self->_getTables();
}
@@ -866,7 +870,6 @@ class Rijndael extends Base
// Generating decrypt code:
$init_decrypt.= '
- static $invtables;
if (empty($invtables)) {
$invtables = &$self->_getInvTables();
}
@@ -923,7 +926,7 @@ class Rijndael extends Base
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
array(
- 'init_crypt' => '',
+ 'init_crypt' => 'static $tables; static $invtables;',
'init_encrypt' => $init_encrypt,
'init_decrypt' => $init_decrypt,
'encrypt_block' => $encrypt_block,
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php
index a2c41668a..bf2df95ed 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php
@@ -57,7 +57,7 @@ class TripleDES extends DES
*
* Outer chaining is used by SSH-2 and when the mode is set to \phpseclib\Crypt\Base::MODE_CBC.
*/
- const MODE_CBC3 = Base::MODE_CBC;
+ const MODE_CBC3 = self::MODE_CBC;
/**
* Key Length (in bytes)
@@ -151,20 +151,20 @@ class TripleDES extends DES
* @param int $mode
* @access public
*/
- function __construct($mode = Base::MODE_CBC)
+ function __construct($mode = self::MODE_CBC)
{
switch ($mode) {
// In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC
// and additional flag us internally as 3CBC
case self::MODE_3CBC:
- parent::__construct(Base::MODE_CBC);
+ parent::__construct(self::MODE_CBC);
$this->mode_3cbc = true;
// This three $des'es will do the 3CBC work (if $key > 64bits)
$this->des = array(
- new DES(Base::MODE_CBC),
- new DES(Base::MODE_CBC),
- new DES(Base::MODE_CBC),
+ new DES(self::MODE_CBC),
+ new DES(self::MODE_CBC),
+ new DES(self::MODE_CBC),
);
// we're going to be doing the padding, ourselves, so disable it in the \phpseclib\Crypt\DES objects
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
index 70980a2ff..1c020481a 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
@@ -369,6 +369,42 @@ class Twofish extends Base
var $key_length = 16;
/**
+ * Default Constructor.
+ *
+ * Determines whether or not the mcrypt extension should be used.
+ *
+ * $mode could be:
+ *
+ * - CRYPT_MODE_ECB
+ *
+ * - CRYPT_MODE_CBC
+ *
+ * - CRYPT_MODE_CTR
+ *
+ * - CRYPT_MODE_CFB
+ *
+ * - CRYPT_MODE_OFB
+ *
+ * (or the alias constants of the chosen cipher, for example for AES: CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC ...)
+ *
+ * If not explicitly set, CRYPT_MODE_CBC will be used.
+ *
+ * @param int $mode
+ * @access public
+ */
+ function __construct($mode = self::MODE_CBC)
+ {
+ parent::__construct($mode);
+
+ $this->m0 = array_map('intval', $this->m0);
+ $this->m1 = array_map('intval', $this->m1);
+ $this->m2 = array_map('intval', $this->m2);
+ $this->m3 = array_map('intval', $this->m3);
+ $this->q0 = array_map('intval', $this->q0);
+ $this->q1 = array_map('intval', $this->q1);
+ }
+
+ /**
* Sets the key length.
*
* Valid key lengths are 128, 192 or 256 bits
diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
index fb2d64485..dba99de73 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
@@ -144,6 +144,16 @@ class ASN1
var $filters;
/**
+ * Current Location of most recent ASN.1 encode process
+ *
+ * Useful for debug purposes
+ *
+ * @var array
+ * @see self::encode_der()
+ */
+ var $location;
+
+ /**
* Type mapping table for the ANY type.
*
* Structured or unknown types are mapped to a \phpseclib\File\ASN1\Element.
@@ -1166,6 +1176,11 @@ class ASN1
$oid = array();
$pos = 0;
$len = strlen($content);
+ // see https://github.com/openjdk/jdk/blob/2deb318c9f047ec5a4b160d66a4b52f93688ec42/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java#L55
+ if ($len > 4096) {
+ //user_error('Object Identifier size is limited to 4096 bytes');
+ return false;
+ }
if (ord($content[$len - 1]) & 0x80) {
return false;
@@ -1431,7 +1446,7 @@ class ASN1
return false;
}
break;
- case ($c & 0x80000000) != 0:
+ case ($c & (PHP_INT_SIZE == 8 ? 0x80000000 : (1 << 31))) != 0:
return false;
case $c >= 0x04000000:
$v .= chr(0x80 | ($c & 0x3F));
diff --git a/vendor/phpseclib/phpseclib/phpseclib/File/X509.php b/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
index 0da0b83cc..7b8d96e29 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
@@ -145,6 +145,7 @@ class X509
var $AuthorityKeyIdentifier;
var $CertificatePolicies;
var $AuthorityInfoAccessSyntax;
+ var $SubjectInfoAccessSyntax;
var $SubjectAltName;
var $SubjectDirectoryAttributes;
var $PrivateKeyUsagePeriod;
@@ -1320,6 +1321,10 @@ class X509
'2.5.4.45' => 'id-at-uniqueIdentifier',
'2.5.4.72' => 'id-at-role',
'2.5.4.16' => 'id-at-postalAddress',
+ '1.3.6.1.4.1.311.60.2.1.3' => 'jurisdictionOfIncorporationCountryName',
+ '1.3.6.1.4.1.311.60.2.1.2' => 'jurisdictionOfIncorporationStateOrProvinceName',
+ '1.3.6.1.4.1.311.60.2.1.1' => 'jurisdictionLocalityName',
+ '2.5.4.15' => 'id-at-businessCategory',
'0.9.2342.19200300.100.1.25' => 'id-domainComponent',
'1.2.840.113549.1.9' => 'pkcs-9',
@@ -2065,7 +2070,8 @@ class X509
if ($names = $this->getExtension('id-ce-subjectAltName')) {
foreach ($names as $name) {
foreach ($name as $key => $value) {
- $value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value);
+ $value = preg_quote($value);
+ $value = str_replace('\*', '[^.]*', $value);
switch ($key) {
case 'dNSName':
/* From RFC2818 "HTTP over TLS":
@@ -2163,7 +2169,11 @@ class X509
if (!$fsock) {
return false;
}
- fputs($fsock, "GET $parts[path] HTTP/1.0\r\n");
+ $path = $parts['path'];
+ if (isset($parts['query'])) {
+ $path.= '?' . $parts['query'];
+ }
+ fputs($fsock, "GET $path HTTP/1.0\r\n");
fputs($fsock, "Host: $parts[host]\r\n\r\n");
$line = fgets($fsock, 1024);
if (strlen($line) < 3) {
@@ -2571,6 +2581,20 @@ class X509
function _translateDNProp($propName)
{
switch (strtolower($propName)) {
+ case 'jurisdictionofincorporationcountryname':
+ case 'jurisdictioncountryname':
+ case 'jurisdictionc':
+ return 'jurisdictionOfIncorporationCountryName';
+ case 'jurisdictionofincorporationstateorprovincename':
+ case 'jurisdictionstateorprovincename':
+ case 'jurisdictionst':
+ return 'jurisdictionOfIncorporationStateOrProvinceName';
+ case 'jurisdictionlocalityname':
+ case 'jurisdictionl':
+ return 'jurisdictionLocalityName';
+ case 'id-at-businesscategory':
+ case 'businesscategory':
+ return 'id-at-businessCategory';
case 'id-at-countryname':
case 'countryname':
case 'c':
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
index 52adcd450..7747a95b6 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
@@ -163,23 +163,23 @@ class BigInteger
*
* @see __construct()
*/
- protected static $base;
- protected static $baseFull;
- protected static $maxDigit;
- protected static $msb;
+ static $base;
+ static $baseFull;
+ static $maxDigit;
+ static $msb;
/**
* $max10 in greatest $max10Len satisfying
* $max10 = 10**$max10Len <= 2**$base.
*/
- protected static $max10;
+ static $max10;
/**
* $max10Len in greatest $max10Len satisfying
* $max10 = 10**$max10Len <= 2**$base.
*/
- protected static $max10Len;
- protected static $maxDigit2;
+ static $max10Len;
+ static $maxDigit2;
/**#@-*/
/**
@@ -263,12 +263,12 @@ class BigInteger
}
}
- if (function_exists('phpinfo') && extension_loaded('openssl') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
+ if (extension_loaded('openssl') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
// some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
$versions = array();
// avoid generating errors (even with suppression) when phpinfo() is disabled (common in production systems)
- if (strpos(ini_get('disable_functions'), 'phpinfo') === false) {
+ if (function_exists('phpinfo')) {
ob_start();
@phpinfo();
$content = ob_get_contents();
@@ -372,7 +372,7 @@ class BigInteger
break;
case self::MODE_BCMATH:
// round $len to the nearest 4 (thanks, DavidMJ!)
- $len = (strlen($x) + 3) & 0xFFFFFFFC;
+ $len = (strlen($x) + 3) & ~3;
$x = str_pad($x, $len, chr(0), STR_PAD_LEFT);
@@ -408,7 +408,7 @@ class BigInteger
$x = substr($x, 1);
}
- $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#', '$1', $x);
+ $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#s', '$1', $x);
$is_negative = false;
if ($base < 0 && hexdec($x[0]) >= 8) {
@@ -444,7 +444,7 @@ class BigInteger
// (?<!^)(?:-).*: find any -'s that aren't at the beginning and then any characters that follow that
// (?<=^|-)0*: find any 0's that are preceded by the start of the string or by a - (ie. octals)
// [^-0-9].*: find any non-numeric characters and then any characters that follow that
- $x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#', '', $x);
+ $x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#s', '', $x);
if (!strlen($x) || $x == '-') {
$x = '0';
}
@@ -486,7 +486,7 @@ class BigInteger
$x = substr($x, 1);
}
- $x = preg_replace('#^([01]*).*#', '$1', $x);
+ $x = preg_replace('#^([01]*).*#s', '$1', $x);
$x = str_pad($x, strlen($x) + (3 * strlen($x)) % 4, 0, STR_PAD_LEFT);
$str = '0x';
@@ -730,6 +730,33 @@ class BigInteger
}
/**
+ * Return the size of a BigInteger in bits
+ *
+ * @return int
+ */
+ function getLength()
+ {
+ if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
+ return strlen($this->toBits());
+ }
+
+ $max = count($this->value) - 1;
+ return $max != -1 ?
+ $max * self::$base + intval(ceil(log($this->value[$max] + 1, 2))) :
+ 0;
+ }
+
+ /**
+ * Return the size of a BigInteger in bytes
+ *
+ * @return int
+ */
+ function getLengthInBytes()
+ {
+ return (int) ceil($this->getLength() / 8);
+ }
+
+ /**
* Copy an object
*
* PHP5 passes objects by reference while PHP4 passes by value. As such, we need a function to guarantee
@@ -3237,6 +3264,11 @@ class BigInteger
$min = $temp;
}
+ $length = $max->getLength();
+ if ($length > 8196) {
+ user_error('Generation of random prime numbers larger than 8196 has been disabled');
+ }
+
static $one, $two;
if (!isset($one)) {
$one = new static(1);
@@ -3344,7 +3376,14 @@ class BigInteger
*/
function isPrime($t = false)
{
- $length = strlen($this->toBytes());
+ $length = $this->getLength();
+ // OpenSSL limits RSA keys to 16384 bits. The length of an RSA key is equal to the length of the modulo, which is
+ // produced by multiplying the primes p and q by one another. The largest number two 8196 bit primes can produce is
+ // a 16384 bit number so, basically, 8196 bit primes are the largest OpenSSL will generate and if that's the largest
+ // that it'll generate it also stands to reason that that's the largest you'll be able to test primality on
+ if ($length > 8196) {
+ user_error('Primality testing is not supported for numbers larger than 8196 bits');
+ }
if (!$t) {
// see HAC 4.49 "Note (controlling the error probability)"
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
index cf13496cd..ee6e1c9d9 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
@@ -247,6 +247,13 @@ class SCP
$content = '';
while ($size < $info['size']) {
$data = $this->_receive();
+
+ // Terminate the loop in case the server repeatedly sends an empty response
+ if ($data === false) {
+ user_error('No data received from server', E_USER_NOTICE);
+ return false;
+ }
+
// SCP usually seems to split stuff out into 16k chunks
$size+= strlen($data);
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
index 0c06c35f4..28b568062 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
@@ -319,6 +319,38 @@ class SFTP extends SSH2
var $partial_init = false;
/**
+ * http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1
+ * the order, in this case, matters quite a lot - see \phpseclib3\Net\SFTP::_parseAttributes() to understand why
+ *
+ * @var array
+ * @access private
+ */
+ var $attributes = array();
+
+ /**
+ * @var array
+ * @access private
+ */
+ var $open_flags = array();
+
+ /**
+ * SFTPv5+ changed the flags up:
+ * https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-8.1.1.3
+ *
+ * @var array
+ * @access private
+ */
+ var $open_flags5 = array();
+
+ /**
+ * http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2
+ * see \phpseclib\Net\SFTP::_parseLongname() for an explanation
+ *
+ * @var array
+ */
+ var $file_types = array();
+
+ /**
* Default Constructor.
*
* Connects to an SFTP server
@@ -422,7 +454,7 @@ class SFTP extends SSH2
// yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in
// two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000.
// that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored.
- (-1 << 31) & 0xFFFFFFFF => 'NET_SFTP_ATTR_EXTENDED'
+ (PHP_INT_SIZE == 4 ? (-1 << 31) : 0x80000000) => 'NET_SFTP_ATTR_EXTENDED'
);
$this->open_flags = array(
0x00000001 => 'NET_SFTP_OPEN_READ',
@@ -718,7 +750,16 @@ class SFTP extends SSH2
return false;
}
+ $this->pwd = true;
$this->pwd = $this->_realpath('.');
+ if ($this->pwd === false) {
+ if (!$this->canonicalize_paths) {
+ user_error('Unable to canonicalize current working directory');
+ return false;
+ }
+ $this->canonicalize_paths = false;
+ $this->_reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST);
+ }
$this->_update_stat_cache($this->pwd, array());
@@ -766,7 +807,9 @@ class SFTP extends SSH2
}
/**
- * Enable path canonicalization
+ * Disable path canonicalization
+ *
+ * If this is enabled then $sftp->pwd() will not return the canonicalized absolute path
*
* @access public
*/
@@ -828,7 +871,7 @@ class SFTP extends SSH2
$error = $this->status_codes[$status];
- if ($this->version > 2 || strlen($response) < 4) {
+ if ($this->version > 2) {
extract(unpack('Nlength', $this->_string_shift($response, 4)));
$this->sftp_errors[] = $error . ': ' . $this->_string_shift($response, $length);
} else {
@@ -872,10 +915,37 @@ class SFTP extends SSH2
function _realpath($path)
{
if (!$this->canonicalize_paths) {
- return $path;
+ if ($this->pwd === true) {
+ return '.';
+ }
+ if (!strlen($path) || $path[0] != '/') {
+ $path = $this->pwd . '/' . $path;
+ }
+
+ $parts = explode('/', $path);
+ $afterPWD = $beforePWD = array();
+ foreach ($parts as $part) {
+ switch ($part) {
+ //case '': // some SFTP servers /require/ double /'s. see https://github.com/phpseclib/phpseclib/pull/1137
+ case '.':
+ break;
+ case '..':
+ if (!empty($afterPWD)) {
+ array_pop($afterPWD);
+ } else {
+ $beforePWD[] = '..';
+ }
+ break;
+ default:
+ $afterPWD[] = $part;
+ }
+ }
+
+ $beforePWD = count($beforePWD) ? implode('/', $beforePWD) : '.';
+ return $beforePWD . '/' . implode('/', $afterPWD);
}
- if ($this->pwd === false) {
+ if ($this->pwd === true) {
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9
if (!$this->_send_sftp_packet(NET_SFTP_REALPATH, pack('Na*', strlen($path), $path))) {
return false;
@@ -897,7 +967,6 @@ class SFTP extends SSH2
$this->_logError($response);
return false;
default:
- user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
return false;
}
}
@@ -1013,6 +1082,12 @@ class SFTP extends SSH2
{
$files = $this->_list($dir, false);
+ // If we get an int back, then that is an "unexpected" status.
+ // We do not have a file list, so return false.
+ if (is_int($files)) {
+ return false;
+ }
+
if (!$recursive || $files === false) {
return $files;
}
@@ -1048,6 +1123,13 @@ class SFTP extends SSH2
function rawlist($dir = '.', $recursive = false)
{
$files = $this->_list($dir, true);
+
+ // If we get an int back, then that is an "unexpected" status.
+ // We do not have a file list, so return false.
+ if (is_int($files)) {
+ return false;
+ }
+
if (!$recursive || $files === false) {
return $files;
}
@@ -1115,8 +1197,12 @@ class SFTP extends SSH2
break;
case NET_SFTP_STATUS:
// presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
- $this->_logError($response);
- return false;
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+ $this->_logError($response, $status);
+ return $status;
default:
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
return false;
@@ -1185,7 +1271,7 @@ class SFTP extends SSH2
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
if ($status != NET_SFTP_STATUS_EOF) {
$this->_logError($response, $status);
- return false;
+ return $status;
}
break 2;
default:
@@ -1861,7 +1947,7 @@ class SFTP extends SSH2
$i = 0;
$entries = $this->_list($path, true);
- if ($entries === false) {
+ if ($entries === false || is_int($entries)) {
return $this->_setstat($path, $attr, false);
}
@@ -2226,7 +2312,7 @@ class SFTP extends SSH2
if ($start >= 0) {
$offset = $start;
- } elseif ($mode & self::RESUME) {
+ } elseif ($mode & (self::RESUME | self::RESUME_START)) {
// if NET_SFTP_OPEN_APPEND worked as it should _size() wouldn't need to be called
$size = $this->size($remote_file);
$offset = $size !== false ? $size : 0;
@@ -2273,7 +2359,7 @@ class SFTP extends SSH2
case is_resource($data):
$mode = $mode & ~self::SOURCE_LOCAL_FILE;
$info = stream_get_meta_data($data);
- if ($info['wrapper_type'] == 'PHP' && $info['stream_type'] == 'Input') {
+ if (isset($info['wrapper_type']) && $info['wrapper_type'] == 'PHP' && $info['stream_type'] == 'Input') {
$fp = fopen('php://memory', 'w+');
stream_copy_to_stream($data, $fp);
rewind($fp);
@@ -2299,7 +2385,11 @@ class SFTP extends SSH2
if ($local_start >= 0) {
fseek($fp, $local_start);
$size-= $local_start;
+ } elseif ($mode & self::RESUME) {
+ fseek($fp, $offset);
+ $size-= $offset;
}
+
} elseif ($dataCallback) {
$size = 0;
} else {
@@ -2603,14 +2693,6 @@ class SFTP extends SSH2
}
}
- if ($length > 0 && $length <= $offset - $start) {
- if ($local_file === false) {
- $content = substr($content, 0, $length);
- } else {
- ftruncate($fp, $length + $res_offset);
- }
- }
-
if ($fclose_check) {
fclose($fp);
@@ -2706,12 +2788,17 @@ class SFTP extends SSH2
$i = 0;
$entries = $this->_list($path, true);
- // normally $entries would have at least . and .. but it might not if the directories
- // permissions didn't allow reading
- if (empty($entries)) {
+ // The folder does not exist at all, so we cannot delete it.
+ if ($entries === NET_SFTP_STATUS_NO_SUCH_FILE) {
return false;
}
+ // Normally $entries would have at least . and .. but it might not if the directories
+ // permissions didn't allow reading. If this happens then default to an empty list of files.
+ if ($entries === false || is_int($entries)) {
+ $entries = array();
+ }
+
unset($entries['.'], $entries['..']);
foreach ($entries as $filename => $props) {
if (!isset($props['type'])) {
@@ -3553,6 +3640,7 @@ class SFTP extends SSH2
$this->use_request_id = false;
$this->pwd = false;
$this->requestBuffer = array();
+ $this->partial_init = false;
}
/**
@@ -3618,6 +3706,9 @@ class SFTP extends SSH2
while ($tempLength > 0) {
$temp = $this->_get_channel_packet(self::CHANNEL, true);
if (is_bool($temp)) {
+ if ($temp && $this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) {
+ $this->channel_close = true;
+ }
$this->packet_type = false;
$this->packet_buffer = '';
return false;
@@ -3698,7 +3789,7 @@ class SFTP extends SSH2
}
/**
- * Returns all errors
+ * Returns all errors on the SFTP layer
*
* @return array
* @access public
@@ -3709,7 +3800,7 @@ class SFTP extends SSH2
}
/**
- * Returns the last error
+ * Returns the last error on the SFTP layer
*
* @return string
* @access public
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php
index e372b8b92..fc8d2acd8 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php
@@ -205,6 +205,10 @@ class SSH1
* Dumps the content real-time to a file
*/
const LOG_REALTIME_FILE = 4;
+ /**
+ * Make sure that the log never gets larger than this
+ */
+ const LOG_MAX_SIZE = 1048576; // 1024 * 1024
/**#@-*/
/**#@+
@@ -360,7 +364,7 @@ class SSH1
* @var array
* @access private
*/
- var $protocol_flag_log = array();
+ var $protocol_flags_log = array();
/**
* Message Log
@@ -408,6 +412,18 @@ class SSH1
var $interactiveBuffer = '';
/**
+ * Current log size
+ *
+ * Should never exceed self::LOG_MAX_SIZE
+ *
+ * @see self::_send_binary_packet()
+ * @see self::_get_binary_packet()
+ * @var int
+ * @access private
+ */
+ var $log_size;
+
+ /**
* Timeout
*
* @see self::setTimeout()
@@ -1418,7 +1434,7 @@ class SSH1
switch (NET_SSH1_LOGGING) {
case self::LOG_SIMPLE:
- return $this->message_number_log;
+ return $this->protocol_flags_log;
break;
case self::LOG_COMPLEX:
return $this->_format_log($this->message_log, $this->protocol_flags_log);
diff --git a/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php b/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
index 7ec4a1e36..607cc2145 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
@@ -274,6 +274,18 @@ class SSH2
var $server_host_key_algorithms = false;
/**
+ * Supported Private Key Algorithms
+ *
+ * In theory this should be the same as the Server Host Key Algorithms but, in practice,
+ * some servers (eg. Azure) will support rsa-sha2-512 as a server host key algorithm but
+ * not a private key algorithm
+ *
+ * @see self::privatekey_login()
+ * @var array|false
+ */
+ var $supported_private_key_algorithms = false;
+
+ /**
* Encryption Algorithms: Client to Server
*
* @see self::getEncryptionAlgorithmsClient2Server()
@@ -391,6 +403,14 @@ class SSH2
var $decrypt = false;
/**
+ * Decryption Algorithm Name
+ *
+ * @var string|null
+ * @access private
+ */
+ var $decryptName;
+
+ /**
* Client to Server Encryption Object
*
* @see self::_send_binary_packet()
@@ -400,6 +420,14 @@ class SSH2
var $encrypt = false;
/**
+ * Encryption Algorithm Name
+ *
+ * @var string|null
+ * @access private
+ */
+ var $encryptName;
+
+ /**
* Client to Server HMAC Object
*
* @see self::_send_binary_packet()
@@ -409,6 +437,13 @@ class SSH2
var $hmac_create = false;
/**
+ * Client to Server HMAC Name
+ *
+ * @var string|false
+ */
+ private $hmac_create_name;
+
+ /**
* Server to Client HMAC Object
*
* @see self::_get_binary_packet()
@@ -418,6 +453,13 @@ class SSH2
var $hmac_check = false;
/**
+ * Server to Client HMAC Name
+ *
+ * @var string|false
+ */
+ var $hmac_check_name;
+
+ /**
* Size of server to client HMAC
*
* We need to know how big the HMAC will be for the server to client direction so that we know how many bytes to read.
@@ -1055,9 +1097,19 @@ class SSH2
var $smartMFA = true;
/**
+ * Extra packets counter
+ *
+ * @var bool
+ * @access private
+ */
+ var $extra_packets;
+
+ /**
* Default Constructor.
*
* $host can either be a string, representing the host, or a stream resource.
+ * If $host is a stream resource then $port doesn't do anything, altho $timeout
+ * still will be used
*
* @param mixed $host
* @param int $port
@@ -1075,6 +1127,7 @@ class SSH2
4 => 'NET_SSH2_MSG_DEBUG',
5 => 'NET_SSH2_MSG_SERVICE_REQUEST',
6 => 'NET_SSH2_MSG_SERVICE_ACCEPT',
+ 7 => 'NET_SSH2_MSG_EXT_INFO', // RFC 8308
20 => 'NET_SSH2_MSG_KEXINIT',
21 => 'NET_SSH2_MSG_NEWKEYS',
30 => 'NET_SSH2_MSG_KEXDH_INIT',
@@ -1147,6 +1200,8 @@ class SSH2
31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY')
);
+ $this->timeout = $timeout;
+
if (is_resource($host)) {
$this->fsock = $host;
return;
@@ -1155,7 +1210,6 @@ class SSH2
if (is_string($host)) {
$this->host = $host;
$this->port = $port;
- $this->timeout = $timeout;
}
}
@@ -1459,6 +1513,8 @@ class SSH2
$preferred['client_to_server']['comp'] :
$this->getSupportedCompressionAlgorithms();
+ $kex_algorithms = array_merge($kex_algorithms, array('ext-info-c', 'kex-strict-c-v00@openssh.com'));
+
// some SSH servers have buggy implementations of some of the above algorithms
switch (true) {
case $this->server_identifier == 'SSH-2.0-SSHD':
@@ -1521,6 +1577,7 @@ class SSH2
return false;
}
+ $this->extra_packets = 0;
$kexinit_payload_server = $this->_get_binary_packet();
if ($kexinit_payload_server === false) {
$this->bitmap = 0;
@@ -1545,6 +1602,12 @@ class SSH2
}
$temp = unpack('Nlength', $this->_string_shift($response, 4));
$this->kex_algorithms = explode(',', $this->_string_shift($response, $temp['length']));
+ if (in_array('kex-strict-s-v00@openssh.com', $this->kex_algorithms)) {
+ if ($this->session_id === false && $this->extra_packets) {
+ user_error('Possible Terrapin Attack detected');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ }
+ }
if (strlen($response) < 4) {
return false;
@@ -1552,6 +1615,8 @@ class SSH2
$temp = unpack('Nlength', $this->_string_shift($response, 4));
$this->server_host_key_algorithms = explode(',', $this->_string_shift($response, $temp['length']));
+ $this->supported_private_key_algorithms = $this->server_host_key_algorithms;
+
if (strlen($response) < 4) {
return false;
}
@@ -1949,6 +2014,10 @@ class SSH2
return false;
}
+ if (in_array('kex-strict-s-v00@openssh.com', $this->kex_algorithms)) {
+ $this->get_seq_no = $this->send_seq_no = 0;
+ }
+
$keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
$this->encrypt = $this->_encryption_algorithm_to_crypt_instance($encrypt);
@@ -1978,7 +2047,7 @@ class SSH2
}
$this->encrypt->setKey(substr($key, 0, $encryptKeyLength));
- $this->encrypt->name = $decrypt;
+ $this->encryptName = $encrypt;
}
$this->decrypt = $this->_encryption_algorithm_to_crypt_instance($decrypt);
@@ -2008,7 +2077,7 @@ class SSH2
}
$this->decrypt->setKey(substr($key, 0, $decryptKeyLength));
- $this->decrypt->name = $decrypt;
+ $this->decryptName = $decrypt;
}
/* The "arcfour128" algorithm is the RC4 cipher, as described in
@@ -2053,7 +2122,7 @@ class SSH2
$this->hmac_create = new Hash('md5-96');
$createKeyLength = 16;
}
- $this->hmac_create->name = $mac_algorithm_out;
+ $this->hmac_create_name = $mac_algorithm_out;
$checkKeyLength = 0;
$this->hmac_size = 0;
@@ -2083,7 +2152,7 @@ class SSH2
$checkKeyLength = 16;
$this->hmac_size = 12;
}
- $this->hmac_check->name = $mac_algorithm_in;
+ $this->hmac_check_name = $mac_algorithm_in;
$key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id);
while ($createKeyLength > strlen($key)) {
@@ -2223,7 +2292,9 @@ class SSH2
function login($username)
{
$args = func_get_args();
- $this->auth[] = $args;
+ if (!$this->retry_connect) {
+ $this->auth[] = $args;
+ }
// try logging with 'none' as an authentication method first since that's what
// PuTTY does
@@ -2366,6 +2437,35 @@ class SSH2
}
extract(unpack('Ctype', $this->_string_shift($response, 1)));
+ if ($type == NET_SSH2_MSG_EXT_INFO) {
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $nr_extensions = unpack('Nlength', $this->_string_shift($response, 4));
+ for ($i = 0; $i < $nr_extensions['length']; $i++) {
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $extension_name = $this->_string_shift($response, $temp['length']);
+ if ($extension_name == 'server-sig-algs') {
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $this->supported_private_key_algorithms = explode(',', $this->_string_shift($response, $temp['length']));
+ }
+ }
+
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+ extract(unpack('Ctype', $this->_string_shift($response, 1)));
+ }
+
if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) {
user_error('Expected SSH_MSG_SERVICE_ACCEPT');
return false;
@@ -2731,7 +2831,13 @@ class SSH2
$publickey['n']
);
- switch ($this->signature_format) {
+ $algos = array('rsa-sha2-256', 'rsa-sha2-512', 'ssh-rsa');
+ if (isset($this->preferred['hostkey'])) {
+ $algos = array_intersect($algos, $this->preferred['hostkey']);
+ }
+ $algo = $this->_array_intersect_first($algos, $this->supported_private_key_algorithms);
+
+ switch ($algo) {
case 'rsa-sha2-512':
$hash = 'sha512';
$signatureType = 'rsa-sha2-512';
@@ -2781,7 +2887,12 @@ class SSH2
return false;
}
extract(unpack('Nmethodlistlen', $this->_string_shift($response, 4)));
- $this->auth_methods_to_continue = explode(',', $this->_string_shift($response, $methodlistlen));
+ $auth_methods = explode(',', $this->_string_shift($response, $methodlistlen));
+ if (in_array('publickey', $auth_methods) && substr($signatureType, 0, 9) == 'rsa-sha2-') {
+ $this->supported_private_key_algorithms = array_diff($this->supported_private_key_algorithms, array('rsa-sha2-256', 'rsa-sha2-512'));
+ return $this->_privatekey_login($username, $privatekey);
+ }
+ $this->auth_methods_to_continue = $auth_methods;
$this->errors[] = 'SSH_MSG_USERAUTH_FAILURE';
return false;
case NET_SSH2_MSG_USERAUTH_PK_OK:
@@ -2836,6 +2947,16 @@ class SSH2
}
/**
+ * Return the currently configured timeout
+ *
+ * @return int
+ */
+ function getTimeout()
+ {
+ return $this->timeout;
+ }
+
+ /**
* Set Timeout
*
* $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely. setTimeout() makes it so it'll timeout.
@@ -3363,7 +3484,7 @@ class SSH2
*/
function isConnected()
{
- return (bool) ($this->bitmap & self::MASK_CONNECTED);
+ return ($this->bitmap & self::MASK_CONNECTED) && is_resource($this->fsock) && !feof($this->fsock);
}
/**
@@ -3519,11 +3640,18 @@ class SSH2
if (!is_resource($this->fsock) || feof($this->fsock)) {
$this->bitmap = 0;
- user_error('Connection closed (by server) prematurely ' . $elapsed . 's');
+ $str = 'Connection closed (by server) prematurely';
+ if (isset($elapsed)) {
+ $str.= ' ' . $elapsed . 's';
+ }
+ user_error($str);
return false;
}
$start = microtime(true);
+ $sec = (int) floor($this->curTimeout);
+ $usec = (int) (1000000 * ($this->curTimeout - $sec));
+ stream_set_timeout($this->fsock, $sec, $usec);
$raw = stream_get_contents($this->fsock, $this->decrypt_block_size);
if (!strlen($raw)) {
@@ -3550,7 +3678,7 @@ class SSH2
// "implementations SHOULD check that the packet length is reasonable"
// PuTTY uses 0x9000 as the actual max packet size and so to shall we
if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) {
- if (!$this->bad_key_size_fix && $this->_bad_algorithm_candidate($this->decrypt->name) && !($this->bitmap & SSH2::MASK_LOGIN)) {
+ if (!$this->bad_key_size_fix && $this->_bad_algorithm_candidate($this->decryptName) && !($this->bitmap & SSH2::MASK_LOGIN)) {
$this->bad_key_size_fix = true;
$this->_reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
return false;
@@ -3663,9 +3791,11 @@ class SSH2
$this->bitmap = 0;
return false;
case NET_SSH2_MSG_IGNORE:
+ $this->extra_packets++;
$payload = $this->_get_binary_packet($skip_channel_filter);
break;
case NET_SSH2_MSG_DEBUG:
+ $this->extra_packets++;
$this->_string_shift($payload, 2);
if (strlen($payload) < 4) {
return false;
@@ -3677,6 +3807,7 @@ class SSH2
case NET_SSH2_MSG_UNIMPLEMENTED:
return false;
case NET_SSH2_MSG_KEXINIT:
+ // this is here for key re-exchanges after the initial key exchange
if ($this->session_id !== false) {
$this->send_kex_first = false;
if (!$this->_key_exchange($payload)) {
@@ -4573,7 +4704,9 @@ class SSH2
}
/**
- * Returns all errors
+ * Returns all errors / debug messages on the SSH layer
+ *
+ * If you are looking for messages from the SFTP layer, please see SFTP::getSFTPErrors()
*
* @return string[]
* @access public
@@ -4584,7 +4717,9 @@ class SSH2
}
/**
- * Returns the last error
+ * Returns the last error received on the SSH layer
+ *
+ * If you are looking for messages from the SFTP layer, please see SFTP::getLastSFTPError()
*
* @return string
* @access public
@@ -4955,13 +5090,13 @@ class SSH2
'kex' => $this->kex_algorithm,
'hostkey' => $this->signature_format,
'client_to_server' => array(
- 'crypt' => $this->encrypt->name,
- 'mac' => $this->hmac_create->name,
+ 'crypt' => $this->encryptName,
+ 'mac' => $this->hmac_create_name,
'comp' => $compression_map[$this->compress],
),
'server_to_client' => array(
- 'crypt' => $this->decrypt->name,
- 'mac' => $this->hmac_check->name,
+ 'crypt' => $this->decryptName,
+ 'mac' => $this->hmac_check_name,
'comp' => $compression_map[$this->decompress],
)
);
diff --git a/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php b/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php
index f65b587cb..ec1d9773e 100644
--- a/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php
+++ b/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php
@@ -133,9 +133,20 @@ class Agent
}
}
- $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
- if (!$this->fsock) {
- user_error("Unable to connect to ssh-agent (Error $errno: $errstr)");
+ if (in_array('unix', stream_get_transports())) {
+ $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
+ if (!$this->fsock) {
+ user_error("Unable to connect to ssh-agent (Error $errno: $errstr)");
+ }
+ } else {
+ if (substr($address, 0, 9) != '\\\\.\\pipe\\' || strpos(substr($address, 9), '\\') !== false) {
+ user_error('Address is not formatted as a named pipe should be');
+ } else {
+ $this->fsock = fopen($address, 'r+b');
+ if (!$this->fsock) {
+ user_error('Unable to open address');
+ }
+ }
}
}