diff --git a/CHANGELOG.md b/CHANGELOG.md index f8874fea..947ad115 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 2.0.26 - 2020-03-22 + +- SFTP: another attempt at speeding up uploads (#1455) +- SSH2: try logging in with none as an auth method first (#1454) +- ASN1: fix for malformed ASN1 strings (#1456) + +## 2.0.25 - 2020-02-25 + +- SFTP: re-add buffering (#1455) + ## 2.0.24 - 2020-02-22 - X509: fix PHP 5.3 compatability issue diff --git a/phpseclib/Common/Functions/Strings.php b/phpseclib/Common/Functions/Strings.php index 166e1a17..0ed27c8c 100644 --- a/phpseclib/Common/Functions/Strings.php +++ b/phpseclib/Common/Functions/Strings.php @@ -175,7 +175,7 @@ abstract class Strings $result.= pack('N', $element); break; case 's': - if (!is_string($element)) { + if (!self::is_stringable($element)) { throw new \InvalidArgumentException('A string was expected.'); } $result.= pack('Na*', strlen($element), $element); @@ -372,4 +372,16 @@ abstract class Strings return $var; } + + /** + * Find whether the type of a variable is string (or could be converted to one) + * + * @param string|object $var + * @return boolean + * @access public + */ + public static function is_stringable($var) + { + return is_string($var) || (is_object($var) && method_exists($var, '__toString')); + } } diff --git a/phpseclib/Crypt/Common/AsymmetricKey.php b/phpseclib/Crypt/Common/AsymmetricKey.php index 60ca9bb4..f3efb733 100644 --- a/phpseclib/Crypt/Common/AsymmetricKey.php +++ b/phpseclib/Crypt/Common/AsymmetricKey.php @@ -24,7 +24,7 @@ use phpseclib3\Crypt\DSA; use phpseclib3\Crypt\ECDSA; /** - * Base Class for all stream cipher classes + * Base Class for all asymmetric cipher classes * * @package AsymmetricKey * @author Jim Wigginton @@ -173,8 +173,8 @@ abstract class AsymmetricKey } $components['format'] = $format; - $new = static::onLoad($components); + $new->format = $format; return $new instanceof PrivateKey ? $new->withPassword($password) : $new; @@ -206,6 +206,7 @@ abstract class AsymmetricKey $components['format'] = $format; $new = static::onLoad($components); + $new->format = $format; return $new instanceof PrivateKey ? $new->withPassword($password) : $new; @@ -304,7 +305,7 @@ abstract class AsymmetricKey * Returns the format of the loaded key. * * If the key that was loaded wasn't in a valid or if the key was auto-generated - * with RSA::createKey() then this will return false. + * with RSA::createKey() then this will throw an exception. * * @see self::load() * @access public @@ -312,8 +313,8 @@ abstract class AsymmetricKey */ public function getLoadedFormat() { - if ($this->format === false) { - return false; + if (empty($this->format)) { + throw new NoKeyLoadedException('This key was created with createKey - it was not loaded with load. Therefore there is no "loaded format"'); } $meta = new \ReflectionClass($this->format); diff --git a/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php b/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php index fc4e2906..9291f32e 100644 --- a/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php +++ b/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php @@ -70,7 +70,7 @@ abstract class OpenSSH */ public static function load($key, $password = '') { - if (!is_string($key)) { + if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } diff --git a/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php b/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php index adaeb6b6..a362d938 100644 --- a/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php +++ b/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php @@ -22,6 +22,7 @@ use phpseclib3\Crypt\AES; use phpseclib3\Crypt\DES; use phpseclib3\Crypt\TripleDES; use phpseclib3\File\ASN1; +use phpseclib3\Common\Functions\Strings; use phpseclib3\Exception\UnsupportedAlgorithmException; /** @@ -127,7 +128,7 @@ abstract class PKCS1 extends PKCS */ protected static function load($key, $password) { - if (!is_string($key)) { + if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } diff --git a/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php b/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php index f8c199de..638a58bf 100644 --- a/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php +++ b/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php @@ -37,6 +37,7 @@ use phpseclib3\Crypt\Random; use phpseclib3\Math\BigInteger; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; +use phpseclib3\Common\Functions\Strings; use phpseclib3\Exception\UnsupportedAlgorithmException; /** @@ -331,25 +332,7 @@ abstract class PKCS8 extends PKCS */ protected static function load($key, $password = '') { - self::initialize_static_variables(); - - if (!is_string($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - if (self::$format != self::MODE_DER) { - $decoded = ASN1::extractBER($key); - if ($decoded !== false) { - $key = $decoded; - } elseif (self::$format == self::MODE_PEM) { - throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); - } - } - - $decoded = ASN1::decodeBER($key); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER'); - } + $decoded = self::preParse($key); $meta = []; @@ -442,7 +425,7 @@ abstract class PKCS8 extends PKCS if (isset($keyLength)) { $params[] = (int) $keyLength->toString(); } - call_user_func_array([$cipher, 'setPassword'], $params); + $cipher->setPassword(...$params); $key = $cipher->decrypt($decrypted['encryptedData']); $decoded = ASN1::decodeBER($key); if (empty($decoded)) { @@ -654,4 +637,65 @@ abstract class PKCS8 extends PKCS chunk_split(Base64::encode($key), 64) . "-----END PUBLIC KEY-----"; } + + /** + * Perform some preliminary parsing of the key + * + * @param string $key + * @return array + */ + private static function preParse(&$key) + { + self::initialize_static_variables(); + + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (self::$format != self::MODE_DER) { + $decoded = ASN1::extractBER($key); + if ($decoded !== false) { + $key = $decoded; + } elseif (self::$format == self::MODE_PEM) { + throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); + } + } + + $decoded = ASN1::decodeBER($key); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER'); + } + + return $decoded; + } + + /** + * Returns the encryption parameters used by the key + * + * @param string $key + * @return array + */ + public static function extractEncryptionAlgorithm($key) + { + $decoded = self::preParse($key); + + $r = ASN1::asn1map($decoded[0], ASN1\Maps\EncryptedPrivateKeyInfo::MAP); + if (!is_array($r)) { + throw new \RuntimeException('Unable to parse using EncryptedPrivateKeyInfo map'); + } + + if ($r['encryptionAlgorithm']['algorithm'] == 'id-PBES2') { + $decoded = ASN1::decodeBER($r['encryptionAlgorithm']['parameters']->element); + $r['encryptionAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], ASN1\Maps\PBES2params::MAP); + + $kdf = &$r['encryptionAlgorithm']['parameters']['keyDerivationFunc']; + switch ($kdf['algorithm']) { + case 'id-PBKDF2': + $decoded = ASN1::decodeBER($kdf['parameters']->element); + $kdf['parameters'] = ASN1::asn1map($decoded[0], Maps\PBKDF2params::MAP); + } + } + + return $r['encryptionAlgorithm']; + } } diff --git a/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php b/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php index fb2ffa77..ccd06f75 100644 --- a/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php +++ b/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php @@ -80,7 +80,7 @@ abstract class PuTTY */ public static function load($key, $password) { - if (!is_string($key)) { + if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } @@ -200,14 +200,14 @@ abstract class PuTTY */ protected static function wrapPrivateKey($public, $private, $type, $password, array $options = []) { - $key = "PuTTY-User-Key-File-2: " . $type . "\r\nEncryption: "; $encryption = (!empty($password) || is_string($password)) ? 'aes256-cbc' : 'none'; - $key.= $encryption; - $key.= "\r\nComment: " . self::$comment . "\r\n"; + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + + $key = "PuTTY-User-Key-File-2: " . $type . "\r\nEncryption: "; $key.= $encryption; + $key.= "\r\nComment: " . $comment . "\r\n"; $public = Strings::packSSH2('s', $type) . $public; - $comment = isset($options['comment']) ? $options['comment'] : self::$comment; $source = Strings::packSSH2('ssss', $type, $encryption, $comment, $public); $public = Base64::encode($public); diff --git a/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php b/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php index 59b42646..e69fcee6 100644 --- a/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php +++ b/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php @@ -25,6 +25,7 @@ use phpseclib3\Math\BigInteger; use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; +use phpseclib3\Common\Functions\Strings; /** * PKCS#8 Formatted DH Key Handler @@ -69,7 +70,7 @@ abstract class PKCS8 extends Progenitor */ public static function load($key, $password = '') { - if (!is_string($key)) { + if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } diff --git a/phpseclib/Crypt/DSA.php b/phpseclib/Crypt/DSA.php index ff62a290..71f32aae 100644 --- a/phpseclib/Crypt/DSA.php +++ b/phpseclib/Crypt/DSA.php @@ -95,7 +95,7 @@ abstract class DSA extends AsymmetricKey * @var string * @access private */ - protected $format; + protected $sigFormat; /** * Signature Format (Short) @@ -263,7 +263,7 @@ abstract class DSA extends AsymmetricKey */ protected function __construct() { - $this->format = self::validatePlugin('Signature', 'ASN1'); + $this->sigFormat = self::validatePlugin('Signature', 'ASN1'); $this->shortFormat = 'ASN1'; parent::__construct(); @@ -329,7 +329,7 @@ abstract class DSA extends AsymmetricKey { $new = clone $this; $new->shortFormat = $format; - $new->format = self::validatePlugin('Signature', $format); + $new->sigFormat = self::validatePlugin('Signature', $format); return $new; } diff --git a/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php b/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php index 4c79c969..e56f455f 100644 --- a/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php +++ b/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php @@ -29,6 +29,7 @@ use phpseclib3\Math\BigInteger; use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; +use phpseclib3\Common\Functions\Strings; /** * PKCS#8 Formatted DSA Key Handler @@ -73,7 +74,7 @@ abstract class PKCS8 extends Progenitor */ public static function load($key, $password = '') { - if (!is_string($key)) { + if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } diff --git a/phpseclib/Crypt/DSA/Formats/Keys/XML.php b/phpseclib/Crypt/DSA/Formats/Keys/XML.php index 4251b77d..42b3bbb9 100644 --- a/phpseclib/Crypt/DSA/Formats/Keys/XML.php +++ b/phpseclib/Crypt/DSA/Formats/Keys/XML.php @@ -23,6 +23,7 @@ namespace phpseclib3\Crypt\DSA\Formats\Keys; use ParagonIE\ConstantTime\Base64; use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; /** * XML Formatted DSA Key Handler @@ -43,7 +44,7 @@ abstract class XML */ public static function load($key, $password = '') { - if (!is_string($key)) { + if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } diff --git a/phpseclib/Crypt/DSA/PrivateKey.php b/phpseclib/Crypt/DSA/PrivateKey.php index a8e70346..17e9ada3 100644 --- a/phpseclib/Crypt/DSA/PrivateKey.php +++ b/phpseclib/Crypt/DSA/PrivateKey.php @@ -85,7 +85,7 @@ class PrivateKey extends DSA implements Common\PrivateKey */ public function sign($message) { - $format = $this->format; + $format = $this->sigFormat; if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { $signature = ''; diff --git a/phpseclib/Crypt/DSA/PublicKey.php b/phpseclib/Crypt/DSA/PublicKey.php index e352e905..b9741aa5 100644 --- a/phpseclib/Crypt/DSA/PublicKey.php +++ b/phpseclib/Crypt/DSA/PublicKey.php @@ -40,7 +40,7 @@ class PublicKey extends DSA implements Common\PublicKey */ public function verify($message, $signature) { - $format = $this->format; + $format = $this->sigFormat; $params = $format::load($signature); if ($params === false || count($params) != 2) { diff --git a/phpseclib/Crypt/EC.php b/phpseclib/Crypt/EC.php index 1576b4fe..af6b2a22 100644 --- a/phpseclib/Crypt/EC.php +++ b/phpseclib/Crypt/EC.php @@ -244,7 +244,7 @@ abstract class EC extends AsymmetricKey */ protected function __construct() { - $this->format = self::validatePlugin('Signature', 'ASN1'); + $this->sigFormat = self::validatePlugin('Signature', 'ASN1'); $this->shortFormat = 'ASN1'; parent::__construct(); @@ -383,7 +383,7 @@ abstract class EC extends AsymmetricKey $new = clone $this; $new->shortFormat = $format; - $new->format = self::validatePlugin('Signature', $format); + $new->sigFormat = self::validatePlugin('Signature', $format); return $new; } diff --git a/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php b/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php index 9132807f..171d4b45 100644 --- a/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php +++ b/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php @@ -36,6 +36,7 @@ use phpseclib3\Math\Common\FiniteField\Integer; use phpseclib3\Crypt\EC\Curves\Ed25519; use phpseclib3\Crypt\EC\Curves\Ed448; use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Common\Functions\Strings; /** * PKCS#8 Formatted EC Key Handler @@ -81,7 +82,7 @@ abstract class PKCS8 extends Progenitor // one that's called self::initialize_static_variables(); - if (!is_string($key)) { + if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } diff --git a/phpseclib/Crypt/EC/Formats/Keys/XML.php b/phpseclib/Crypt/EC/Formats/Keys/XML.php index 0bfd81e1..d6d8018a 100644 --- a/phpseclib/Crypt/EC/Formats/Keys/XML.php +++ b/phpseclib/Crypt/EC/Formats/Keys/XML.php @@ -26,6 +26,7 @@ use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Common\Functions\Strings; use phpseclib3\Exception\UnsupportedCurveException; /** @@ -65,7 +66,7 @@ abstract class XML { self::initialize_static_variables(); - if (!is_string($key)) { + if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } diff --git a/phpseclib/Crypt/EC/PrivateKey.php b/phpseclib/Crypt/EC/PrivateKey.php index 4ab15688..4ffa5fdf 100644 --- a/phpseclib/Crypt/EC/PrivateKey.php +++ b/phpseclib/Crypt/EC/PrivateKey.php @@ -100,7 +100,7 @@ class PrivateKey extends EC implements Common\PrivateKey $order = $this->curve->getOrder(); $shortFormat = $this->shortFormat; - $format = $this->format; + $format = $this->sigFormat; if ($format === false) { return false; } diff --git a/phpseclib/Crypt/EC/PublicKey.php b/phpseclib/Crypt/EC/PublicKey.php index ef749470..2cb92ab6 100644 --- a/phpseclib/Crypt/EC/PublicKey.php +++ b/phpseclib/Crypt/EC/PublicKey.php @@ -52,7 +52,7 @@ class PublicKey extends EC implements Common\PublicKey } $shortFormat = $this->shortFormat; - $format = $this->format; + $format = $this->sigFormat; if ($format === false) { return false; } diff --git a/phpseclib/Crypt/Hash.php b/phpseclib/Crypt/Hash.php index 6c91dcd1..e0b9e464 100644 --- a/phpseclib/Crypt/Hash.php +++ b/phpseclib/Crypt/Hash.php @@ -93,7 +93,7 @@ class Hash * @var string * @access private */ - private $hash; + private $algo; /** * Key @@ -268,9 +268,9 @@ class Hash return; } - $this->computedKey = is_array($this->hash) ? - call_user_func($this->hash, $this->key) : - hash($this->hash, $this->key, true); + $this->computedKey = is_array($this->algo) ? + call_user_func($this->algo, $this->key) : + hash($this->algo, $this->key, true); } /** @@ -302,7 +302,7 @@ class Hash case 'umac-128': $this->blockSize = 128; $this->length = abs(substr($hash, -3)) >> 3; - $this->hash = 'umac'; + $this->algo = 'umac'; return; case 'md2-96': case 'md5-96': @@ -439,7 +439,7 @@ class Hash $this->opad = str_repeat(chr(0x5C), $b); } - $this->hash = $hash; + $this->algo = $hash; $this->computeKey(); } @@ -785,7 +785,8 @@ class Hash */ public function hash($text) { - if ($this->hash == 'umac') { + $algo = $this->algo; + if ($algo == 'umac') { if ($this->recomputeAESKey) { if (!is_string($this->nonce)) { throw new InsufficientSetupException('No nonce has been set'); @@ -837,9 +838,9 @@ class Hash return $hashedmessage ^ $this->pad; } - if (is_array($this->hash)) { + if (is_array($algo)) { if (empty($this->key) || !is_string($this->key)) { - return substr(call_user_func($this->hash, $text, ...array_values($this->parameters)), 0, $this->length); + return substr($algo($text, ...array_values($this->parameters)), 0, $this->length); } // SHA3 HMACs are discussed at https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=30 @@ -847,17 +848,17 @@ class Hash $key = str_pad($this->computedKey, $b, chr(0)); $temp = $this->ipad ^ $key; $temp .= $text; - $temp = substr(call_user_func($this->hash, $temp, ...array_values($this->parameters)), 0, $this->length); + $temp = substr($algo($temp, ...array_values($this->parameters)), 0, $this->length); $output = $this->opad ^ $key; $output.= $temp; - $output = call_user_func($this->hash, $output, ...array_values($this->parameters)); + $output = $algo($output, ...array_values($this->parameters)); return substr($output, 0, $this->length); } $output = !empty($this->key) || is_string($this->key) ? - hash_hmac($this->hash, $text, $this->computedKey, true) : - hash($this->hash, $text, true); + hash_hmac($algo, $text, $this->computedKey, true) : + hash($algo, $text, true); return strlen($output) > $this->length ? substr($output, 0, $this->length) diff --git a/phpseclib/Crypt/RC2.php b/phpseclib/Crypt/RC2.php index 43f76c40..0e8ec502 100644 --- a/phpseclib/Crypt/RC2.php +++ b/phpseclib/Crypt/RC2.php @@ -393,7 +393,7 @@ class RC2 extends BlockCipher $l[0] = self::$invpitable[$l[0]]; array_unshift($l, 'C*'); - $this->key = call_user_func_array('pack', $l); + $this->key = pack(...$l); $this->key_length = strlen($this->key); $this->changed = $this->nonIVChanged = true; $this->setEngine(); diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index dd3c3e71..b1952028 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -407,7 +407,6 @@ abstract class RSA extends AsymmetricKey new PublicKey : new PrivateKey; - $key->format = $components['format']; $key->modulus = $components['modulus']; $key->publicExponent = $components['publicExponent']; $key->k = $key->modulus->getLengthInBytes(); diff --git a/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php b/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php index 06469913..4d95080d 100644 --- a/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php +++ b/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php @@ -76,7 +76,7 @@ abstract class MSBLOB */ public static function load($key, $password = '') { - if (!is_string($key)) { + if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } diff --git a/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php b/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php index 6ca838d5..64e707e0 100644 --- a/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php +++ b/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php @@ -28,6 +28,7 @@ use phpseclib3\Math\BigInteger; use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; +use phpseclib3\Common\Functions\Strings; /** * PKCS#1 Formatted RSA Key Handler @@ -48,7 +49,7 @@ abstract class PKCS1 extends Progenitor */ public static function load($key, $password = '') { - if (!is_string($key)) { + if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } diff --git a/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php b/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php index 45a25683..1fcfeae1 100644 --- a/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php +++ b/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php @@ -30,6 +30,7 @@ namespace phpseclib3\Crypt\RSA\Formats\Keys; use phpseclib3\Math\BigInteger; use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; use phpseclib3\File\ASN1; +use phpseclib3\Common\Functions\Strings; /** * PKCS#8 Formatted RSA Key Handler @@ -74,7 +75,7 @@ abstract class PKCS8 extends Progenitor */ public static function load($key, $password = '') { - if (!is_string($key)) { + if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } diff --git a/phpseclib/Crypt/RSA/Formats/Keys/PSS.php b/phpseclib/Crypt/RSA/Formats/Keys/PSS.php index 4e2276a0..c1cc7f89 100644 --- a/phpseclib/Crypt/RSA/Formats/Keys/PSS.php +++ b/phpseclib/Crypt/RSA/Formats/Keys/PSS.php @@ -29,6 +29,7 @@ use phpseclib3\Math\BigInteger; use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; +use phpseclib3\Common\Functions\Strings; /** * PKCS#8 Formatted RSA-PSS Key Handler @@ -107,7 +108,7 @@ abstract class PSS extends Progenitor { self::initialize_static_variables(); - if (!is_string($key)) { + if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } diff --git a/phpseclib/Crypt/RSA/Formats/Keys/XML.php b/phpseclib/Crypt/RSA/Formats/Keys/XML.php index ef51c783..389f93a8 100644 --- a/phpseclib/Crypt/RSA/Formats/Keys/XML.php +++ b/phpseclib/Crypt/RSA/Formats/Keys/XML.php @@ -24,6 +24,7 @@ namespace phpseclib3\Crypt\RSA\Formats\Keys; use ParagonIE\ConstantTime\Base64; use phpseclib3\Math\BigInteger; +use phpseclib3\Common\Functions\Strings; use phpseclib3\Exception\UnsupportedFormatException; /** @@ -45,7 +46,7 @@ abstract class XML */ public static function load($key, $password = '') { - if (!is_string($key)) { + if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index ac10661f..e566b41f 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -553,7 +553,7 @@ abstract class ASN1 } if (isset($value)) { if (isset($special[$key])) { - $value = call_user_func($special[$key], $value); + $value = $special[$key]($value); } return [$key => $value]; } @@ -637,7 +637,7 @@ abstract class ASN1 if ($maymatch) { // Got the match: use it. if (isset($special[$key])) { - $candidate = call_user_func($special[$key], $candidate); + $candidate = $special[$key]($candidate); } $map[$key] = $candidate; $i++; @@ -722,7 +722,7 @@ abstract class ASN1 // Got the match: use it. if (isset($special[$key])) { - $candidate = call_user_func($special[$key], $candidate); + $candidate = $special[$key]($candidate); } $map[$key] = $candidate; break; @@ -881,7 +881,7 @@ abstract class ASN1 if (isset($idx)) { if (isset($special[$idx])) { - $source = call_user_func($special[$idx], $source); + $source = $special[$idx]($source); } self::$location[] = $idx; } diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index cb648c04..75847962 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -1941,7 +1941,7 @@ class SFTP extends SSH2 $i = $j = 0; while ($dataCallback || ($size === 0 || $sent < $size)) { if ($dataCallback) { - $temp = call_user_func($dataCallback, $sftp_packet_size); + $temp = $dataCallback($sftp_packet_size); if (is_null($temp)) { break; } @@ -1962,7 +1962,7 @@ class SFTP extends SSH2 } $sent+= strlen($temp); if (is_callable($progressCallback)) { - call_user_func($progressCallback, $sent); + $progressCallback($sent); } $i++; @@ -2137,7 +2137,7 @@ class SFTP extends SSH2 $packet = null; $read+= $packet_size; if (is_callable($progressCallback)) { - call_user_func($progressCallback, $read); + $progressCallback($read); } $i++; } diff --git a/phpseclib/Net/SFTP/Stream.php b/phpseclib/Net/SFTP/Stream.php index 0c08266b..dca9b975 100644 --- a/phpseclib/Net/SFTP/Stream.php +++ b/phpseclib/Net/SFTP/Stream.php @@ -789,6 +789,6 @@ class Stream if (!method_exists($this, $name)) { return false; } - return call_user_func_array([$this, $name], $arguments); + return $this->$name(...$arguments); } } diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 5cc839ac..8c0fbce7 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -2675,7 +2675,7 @@ class SSH2 return false; default: if (is_callable($callback)) { - if (call_user_func($callback, $temp) === true) { + if ($callback($temp) === true) { $this->close_channel(self::CHANNEL_EXEC); return true; } @@ -4190,7 +4190,9 @@ class SSH2 $output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 '; } $fragment = Strings::shift($current_log, $this->log_short_width); - $hex = substr(preg_replace_callback('#.#s', [$this, 'format_log_helper'], $fragment), strlen($this->log_boundary)); + $hex = substr(preg_replace_callback('#.#s', function ($matches) { + return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT); + }, $fragment), strlen($this->log_boundary)); // replace non ASCII printable characters with dots // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters // also replace < with a . since < messes up the output on web browsers