Merge branch 'jworman'

This commit is contained in:
terrafrost 2022-08-20 23:19:34 -05:00
commit 71fa541c9a
52 changed files with 581 additions and 528 deletions

View File

@ -4,4 +4,4 @@ phpseclib Developers: monnerat (Patrick Monnerat)
bantu (Andreas Fischer) bantu (Andreas Fischer)
petrich (Hans-Jürgen Petrich) petrich (Hans-Jürgen Petrich)
GrahamCampbell (Graham Campbell) GrahamCampbell (Graham Campbell)
hc-jworman jack-worman (Jack Worman)

View File

@ -26,7 +26,7 @@ return (new PhpCsFixer\Config())
'phpdoc_trim_consecutive_blank_line_separation' => true, 'phpdoc_trim_consecutive_blank_line_separation' => true,
'phpdoc_trim' => true, 'phpdoc_trim' => true,
'@PHP71Migration:risky' => true, '@PHP81Migration' => true,
'@PHP73Migration' => true, '@PHP80Migration:risky' => true,
] ]
); );

View File

@ -6,7 +6,7 @@
<arg name="extensions" value="php"/> <arg name="extensions" value="php"/>
<arg name="basepath" value=".."/> <arg name="basepath" value=".."/>
<arg name="report" value="emacs"/> <arg name="report" value="diff"/>
<arg value="s"/> <arg value="s"/>
<arg value="n"/> <arg value="n"/>
<arg value="p"/> <arg value="p"/>

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,7 @@
"asn.1", "asn.1",
"BigInteger" "BigInteger"
], ],
"homepage": "http://phpseclib.sourceforge.net", "homepage": "https://phpseclib.com/",
"license": "MIT", "license": "MIT",
"authors": [ "authors": [
{ {
@ -48,10 +48,16 @@
"name": "Graham Campbell", "name": "Graham Campbell",
"email": "graham@alt-three.com", "email": "graham@alt-three.com",
"role": "Developer" "role": "Developer"
},
{
"name": "Jack Worman",
"email": "jack.worman@gmail.com",
"role": "Developer",
"homepage": "https://jackworman.com"
} }
], ],
"require": { "require": {
"php": ">=7.3", "php": ">=8.1",
"paragonie/constant_time_encoding": "^2" "paragonie/constant_time_encoding": "^2"
}, },
"require-dev": { "require-dev": {

View File

@ -536,20 +536,13 @@ class Blowfish extends BlockCipher
$p[14] ^ $key[14], $p[14] ^ $key[14],
$p[15] ^ $key[15], $p[15] ^ $key[15],
$p[16] ^ $key[0], $p[16] ^ $key[0],
$p[17] ^ $key[1] $p[17] ^ $key[1],
]; ];
// @codingStandardsIgnoreStart [$p[0], $p[1]] = self::encryptBlockHelper(0, 0, $sbox0, $sbox1, $sbox2, $sbox3, $p);
[ $p[0], $p[1]] = self::encryptBlockHelper( 0, 0, $sbox0, $sbox1, $sbox2, $sbox3, $p); for ($i = 2; $i < 18; $i += 2) {
[ $p[2], $p[3]] = self::encryptBlockHelper($p[ 0], $p[ 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); [$p[$i], $p[$i + 1]] = self::encryptBlockHelper($p[$i - 2], $p[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
[ $p[4], $p[5]] = self::encryptBlockHelper($p[ 2], $p[ 3], $sbox0, $sbox1, $sbox2, $sbox3, $p); }
[ $p[6], $p[7]] = self::encryptBlockHelper($p[ 4], $p[ 5], $sbox0, $sbox1, $sbox2, $sbox3, $p);
[ $p[8], $p[9]] = self::encryptBlockHelper($p[ 6], $p[ 7], $sbox0, $sbox1, $sbox2, $sbox3, $p);
[$p[10], $p[11]] = self::encryptBlockHelper($p[ 8], $p[ 9], $sbox0, $sbox1, $sbox2, $sbox3, $p);
[$p[12], $p[13]] = self::encryptBlockHelper($p[10], $p[11], $sbox0, $sbox1, $sbox2, $sbox3, $p);
[$p[14], $p[15]] = self::encryptBlockHelper($p[12], $p[13], $sbox0, $sbox1, $sbox2, $sbox3, $p);
[$p[16], $p[17]] = self::encryptBlockHelper($p[14], $p[15], $sbox0, $sbox1, $sbox2, $sbox3, $p);
// @codingStandardsIgnoreEnd
[$sbox0[0], $sbox0[1]] = self::encryptBlockHelper($p[16], $p[17], $sbox0, $sbox1, $sbox2, $sbox3, $p); [$sbox0[0], $sbox0[1]] = self::encryptBlockHelper($p[16], $p[17], $sbox0, $sbox1, $sbox2, $sbox3, $p);
for ($i = 2; $i < 256; $i += 2) { for ($i = 2; $i < 256; $i += 2) {
@ -605,20 +598,13 @@ class Blowfish extends BlockCipher
$p[14] ^ $key[14], $p[14] ^ $key[14],
$p[15] ^ $key[15], $p[15] ^ $key[15],
$p[16] ^ $key[0], $p[16] ^ $key[0],
$p[17] ^ $key[1] $p[17] ^ $key[1],
]; ];
// @codingStandardsIgnoreStart [$p[0], $p[1]] = self::encryptBlockHelper($data[0], $data[1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
[ $p[0], $p[1]] = self::encryptBlockHelper($data[ 0] , $data[ 1] , $sbox0, $sbox1, $sbox2, $sbox3, $p); for ($i = 2, $j = 2; $i < 18; $i += 2, $j = ($j + 2) % 16) {
[ $p[2], $p[3]] = self::encryptBlockHelper($data[ 2] ^ $p[ 0], $data[ 3] ^ $p[ 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); [$p[$i], $p[$i + 1]] = self::encryptBlockHelper($data[$j] ^ $p[$i - 2], $data[$j + 1] ^ $p[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p);
[ $p[4], $p[5]] = self::encryptBlockHelper($data[ 4] ^ $p[ 2], $data[ 5] ^ $p[ 3], $sbox0, $sbox1, $sbox2, $sbox3, $p); }
[ $p[6], $p[7]] = self::encryptBlockHelper($data[ 6] ^ $p[ 4], $data[ 7] ^ $p[ 5], $sbox0, $sbox1, $sbox2, $sbox3, $p);
[ $p[8], $p[9]] = self::encryptBlockHelper($data[ 8] ^ $p[ 6], $data[ 9] ^ $p[ 7], $sbox0, $sbox1, $sbox2, $sbox3, $p);
[$p[10], $p[11]] = self::encryptBlockHelper($data[10] ^ $p[ 8], $data[11] ^ $p[ 9], $sbox0, $sbox1, $sbox2, $sbox3, $p);
[$p[12], $p[13]] = self::encryptBlockHelper($data[12] ^ $p[10], $data[13] ^ $p[11], $sbox0, $sbox1, $sbox2, $sbox3, $p);
[$p[14], $p[15]] = self::encryptBlockHelper($data[14] ^ $p[12], $data[15] ^ $p[13], $sbox0, $sbox1, $sbox2, $sbox3, $p);
[$p[16], $p[17]] = self::encryptBlockHelper($data[ 0] ^ $p[14], $data[ 1] ^ $p[15], $sbox0, $sbox1, $sbox2, $sbox3, $p);
// @codingStandardsIgnoreEnd
[$sbox0[0], $sbox0[1]] = self::encryptBlockHelper($data[2] ^ $p[16], $data[3] ^ $p[17], $sbox0, $sbox1, $sbox2, $sbox3, $p); [$sbox0[0], $sbox0[1]] = self::encryptBlockHelper($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? for ($i = 2, $j = 4; $i < 256; $i += 2, $j = ($j + 2) % 16) { // instead of 16 maybe count($data) would be better?

View File

@ -15,9 +15,7 @@ declare(strict_types=1);
namespace phpseclib3\Crypt\Common; namespace phpseclib3\Crypt\Common;
use phpseclib3\Crypt\DSA;
use phpseclib3\Crypt\Hash; use phpseclib3\Crypt\Hash;
use phpseclib3\Crypt\RSA;
use phpseclib3\Exception\NoKeyLoadedException; use phpseclib3\Exception\NoKeyLoadedException;
use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\Exception\UnsupportedFormatException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -152,7 +150,7 @@ abstract class AsymmetricKey
} }
$components['format'] = $format; $components['format'] = $format;
$components['secret'] = $components['secret'] ?? ''; $components['secret'] ??= '';
$comment = $components['comment'] ?? null; $comment = $components['comment'] ?? null;
$new = static::onLoad($components); $new = static::onLoad($components);
$new->format = $format; $new->format = $format;
@ -226,7 +224,7 @@ abstract class AsymmetricKey
} }
$components['format'] = $format; $components['format'] = $format;
$components['secret'] = $components['secret'] ?? ''; $components['secret'] ??= '';
$new = static::onLoad($components); $new = static::onLoad($components);
$new->format = $format; $new->format = $format;

View File

@ -20,7 +20,6 @@ namespace phpseclib3\Crypt\Common\Formats\Keys;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\AES; use phpseclib3\Crypt\AES;
use phpseclib3\Crypt\Random; use phpseclib3\Crypt\Random;
use phpseclib3\Exception\UnsupportedFormatException;
/** /**
* OpenSSH Formatted RSA Key Handler * OpenSSH Formatted RSA Key Handler
@ -67,7 +66,7 @@ abstract class OpenSSH
// key format is described here: // key format is described here:
// https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.key?annotate=HEAD // https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.key?annotate=HEAD
if (strpos($key, 'BEGIN OPENSSH PRIVATE KEY') !== false) { if (str_contains($key, 'BEGIN OPENSSH PRIVATE KEY')) {
$key = preg_replace('#(?:^-.*?-[\r\n]*$)|\s#ms', '', $key); $key = preg_replace('#(?:^-.*?-[\r\n]*$)|\s#ms', '', $key);
$key = Strings::base64_decode($key); $key = Strings::base64_decode($key);
$magic = Strings::shift($key, 15); $magic = Strings::shift($key, 15);

View File

@ -120,7 +120,7 @@ abstract class PuTTY
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
} }
if (strpos($key, 'BEGIN SSH2 PUBLIC KEY') !== false) { if (str_contains($key, 'BEGIN SSH2 PUBLIC KEY')) {
$lines = preg_split('#[\r\n]+#', $key); $lines = preg_split('#[\r\n]+#', $key);
switch (true) { switch (true) {
case $lines[0] != '---- BEGIN SSH2 PUBLIC KEY ----': case $lines[0] != '---- BEGIN SSH2 PUBLIC KEY ----':
@ -129,9 +129,7 @@ abstract class PuTTY
throw new \UnexpectedValueException('Key doesn\'t end with ---- END SSH2 PUBLIC KEY ----'); throw new \UnexpectedValueException('Key doesn\'t end with ---- END SSH2 PUBLIC KEY ----');
} }
$lines = array_splice($lines, 1, -1); $lines = array_splice($lines, 1, -1);
$lines = array_map(function ($line) { $lines = array_map(fn ($line) => rtrim($line, "\r\n"), $lines);
return rtrim($line, "\r\n");
}, $lines);
$data = $current = ''; $data = $current = '';
$values = []; $values = [];
$in_value = false; $in_value = false;

View File

@ -66,7 +66,7 @@ abstract class PKCS8 extends Progenitor
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
} }
$isPublic = strpos($key, 'PUBLIC') !== false; $isPublic = str_contains($key, 'PUBLIC');
$key = parent::load($key, $password); $key = parent::load($key, $password);

View File

@ -70,7 +70,7 @@ abstract class PKCS8 extends Progenitor
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
} }
$isPublic = strpos($key, 'PUBLIC') !== false; $isPublic = str_contains($key, 'PUBLIC');
$key = parent::load($key, $password); $key = parent::load($key, $password);

View File

@ -18,7 +18,6 @@ use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards;
use phpseclib3\Crypt\Hash; use phpseclib3\Crypt\Hash;
use phpseclib3\Crypt\Random; use phpseclib3\Crypt\Random;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\PrimeField\Integer;
class Ed25519 extends TwistedEdwards class Ed25519 extends TwistedEdwards
{ {
@ -182,7 +181,7 @@ class Ed25519 extends TwistedEdwards
return [ return [
'dA' => $dA, 'dA' => $dA,
'secret' => $str 'secret' => $str,
]; ];
} }

View File

@ -123,7 +123,7 @@ class Ed448 extends TwistedEdwards
return [ return [
'dA' => $dA, 'dA' => $dA,
'secret' => $str 'secret' => $str,
]; ];
} }

View File

@ -110,9 +110,7 @@ abstract class OpenSSH extends Progenitor
$name = $reflect->getShortName(); $name = $reflect->getShortName();
$oid = self::$curveOIDs[$name]; $oid = self::$curveOIDs[$name];
$aliases = array_filter(self::$curveOIDs, function ($v) use ($oid) { $aliases = array_filter(self::$curveOIDs, fn ($v) => $v == $oid);
return $v == $oid;
});
$aliases = array_keys($aliases); $aliases = array_keys($aliases);
for ($i = 0; $i < count($aliases); $i++) { for ($i = 0; $i < count($aliases); $i++) {

View File

@ -79,7 +79,7 @@ abstract class PKCS8 extends Progenitor
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
} }
$isPublic = strpos($key, 'PUBLIC') !== false; $isPublic = str_contains($key, 'PUBLIC');
$key = parent::load($key, $password); $key = parent::load($key, $password);

View File

@ -49,9 +49,9 @@ abstract class PKCS1 extends Progenitor
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
} }
if (strpos($key, 'PUBLIC') !== false) { if (str_contains($key, 'PUBLIC')) {
$components = ['isPublicKey' => true]; $components = ['isPublicKey' => true];
} elseif (strpos($key, 'PRIVATE') !== false) { } elseif (str_contains($key, 'PRIVATE')) {
$components = ['isPublicKey' => false]; $components = ['isPublicKey' => false];
} else { } else {
$components = []; $components = [];

View File

@ -71,9 +71,9 @@ abstract class PKCS8 extends Progenitor
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
} }
if (strpos($key, 'PUBLIC') !== false) { if (str_contains($key, 'PUBLIC')) {
$components = ['isPublicKey' => true]; $components = ['isPublicKey' => true];
} elseif (strpos($key, 'PRIVATE') !== false) { } elseif (str_contains($key, 'PRIVATE')) {
$components = ['isPublicKey' => false]; $components = ['isPublicKey' => false];
} else { } else {
$components = []; $components = [];

View File

@ -103,7 +103,7 @@ abstract class PSS extends Progenitor
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
} }
$components = ['isPublicKey' => strpos($key, 'PUBLIC') !== false]; $components = ['isPublicKey' => str_contains($key, 'PUBLIC')];
$key = parent::load($key, $password); $key = parent::load($key, $password);

View File

@ -149,15 +149,9 @@ abstract class Raw
'e' => clone $e, 'e' => clone $e,
'n' => clone $n, 'n' => clone $n,
'd' => clone $d, 'd' => clone $d,
'primes' => array_map(function ($var) { 'primes' => array_map(fn ($var) => clone $var, $primes),
return clone $var; 'exponents' => array_map(fn ($var) => clone $var, $exponents),
}, $primes), 'coefficients' => array_map(fn ($var) => clone $var, $coefficients),
'exponents' => array_map(function ($var) {
return clone $var;
}, $exponents),
'coefficients' => array_map(function ($var) {
return clone $var;
}, $coefficients),
]); ]);
} }

View File

@ -20,6 +20,6 @@ namespace phpseclib3\Exception;
* *
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
*/ */
class BadConfigurationException extends \RuntimeException class BadConfigurationException extends \RuntimeException implements ExceptionInterface
{ {
} }

View File

@ -20,6 +20,6 @@ namespace phpseclib3\Exception;
* *
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
*/ */
class BadDecryptionException extends \RuntimeException class BadDecryptionException extends \RuntimeException implements ExceptionInterface
{ {
} }

View File

@ -20,6 +20,6 @@ namespace phpseclib3\Exception;
* *
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
*/ */
class BadModeException extends \RuntimeException class BadModeException extends \RuntimeException implements ExceptionInterface
{ {
} }

View File

@ -20,6 +20,6 @@ namespace phpseclib3\Exception;
* *
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
*/ */
class ConnectionClosedException extends \RuntimeException class ConnectionClosedException extends \RuntimeException implements ExceptionInterface
{ {
} }

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace phpseclib3\Exception;
/**
* Used to mark exceptions originating from this library.
*/
interface ExceptionInterface
{
}

View File

@ -20,6 +20,6 @@ namespace phpseclib3\Exception;
* *
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
*/ */
class FileNotFoundException extends \RuntimeException class FileNotFoundException extends \RuntimeException implements ExceptionInterface
{ {
} }

View File

@ -20,6 +20,6 @@ namespace phpseclib3\Exception;
* *
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
*/ */
class InconsistentSetupException extends \RuntimeException class InconsistentSetupException extends \RuntimeException implements ExceptionInterface
{ {
} }

View File

@ -20,6 +20,6 @@ namespace phpseclib3\Exception;
* *
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
*/ */
class InsufficientSetupException extends \RuntimeException class InsufficientSetupException extends \RuntimeException implements ExceptionInterface
{ {
} }

View File

@ -20,6 +20,6 @@ namespace phpseclib3\Exception;
* *
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
*/ */
class NoKeyLoadedException extends \RuntimeException class NoKeyLoadedException extends \RuntimeException implements ExceptionInterface
{ {
} }

View File

@ -20,6 +20,6 @@ namespace phpseclib3\Exception;
* *
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
*/ */
class NoSupportedAlgorithmsException extends \RuntimeException class NoSupportedAlgorithmsException extends \RuntimeException implements ExceptionInterface
{ {
} }

View File

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace phpseclib3\Exception;
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}

View File

@ -20,6 +20,6 @@ namespace phpseclib3\Exception;
* *
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
*/ */
class UnableToConnectException extends \RuntimeException class UnableToConnectException extends \RuntimeException implements ExceptionInterface
{ {
} }

View File

@ -20,6 +20,6 @@ namespace phpseclib3\Exception;
* *
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
*/ */
class UnsupportedAlgorithmException extends \RuntimeException class UnsupportedAlgorithmException extends \RuntimeException implements ExceptionInterface
{ {
} }

View File

@ -20,6 +20,6 @@ namespace phpseclib3\Exception;
* *
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
*/ */
class UnsupportedCurveException extends \RuntimeException class UnsupportedCurveException extends \RuntimeException implements ExceptionInterface
{ {
} }

View File

@ -20,6 +20,6 @@ namespace phpseclib3\Exception;
* *
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
*/ */
class UnsupportedFormatException extends \RuntimeException class UnsupportedFormatException extends \RuntimeException implements ExceptionInterface
{ {
} }

View File

@ -20,6 +20,6 @@ namespace phpseclib3\Exception;
* *
* @author Jim Wigginton <terrafrost@php.net> * @author Jim Wigginton <terrafrost@php.net>
*/ */
class UnsupportedOperationException extends \RuntimeException class UnsupportedOperationException extends \RuntimeException implements ExceptionInterface
{ {
} }

View File

@ -1252,7 +1252,7 @@ abstract class ASN1
} }
$prefix = substr($content, 0, 2) >= 50 ? '19' : '20'; $prefix = substr($content, 0, 2) >= 50 ? '19' : '20';
$content = $prefix . $content; $content = $prefix . $content;
} elseif (strpos($content, '.') !== false) { } elseif (str_contains($content, '.')) {
$format .= '.u'; $format .= '.u';
} }
@ -1260,7 +1260,7 @@ abstract class ASN1
$content = substr($content, 0, -1) . '+0000'; $content = substr($content, 0, -1) . '+0000';
} }
if (strpos($content, '-') !== false || strpos($content, '+') !== false) { if (str_contains($content, '-') || str_contains($content, '+')) {
$format .= 'O'; $format .= 'O';
} }

View File

@ -1102,8 +1102,8 @@ class X509
if (isset($parts['query'])) { if (isset($parts['query'])) {
$path .= '?' . $parts['query']; $path .= '?' . $parts['query'];
} }
fputs($fsock, "GET $path HTTP/1.0\r\n"); fwrite($fsock, "GET $path HTTP/1.0\r\n");
fputs($fsock, "Host: $parts[host]\r\n\r\n"); fwrite($fsock, "Host: $parts[host]\r\n\r\n");
$line = fgets($fsock, 1024); $line = fgets($fsock, 1024);
if (strlen($line) < 3) { if (strlen($line) < 3) {
return false; return false;
@ -1842,9 +1842,7 @@ class X509
$value = array_pop($value); // Always strip data type. $value = array_pop($value); // Always strip data type.
} }
} elseif (is_object($value) && $value instanceof Element) { } elseif (is_object($value) && $value instanceof Element) {
$callback = function ($x) { $callback = fn ($x) => '\x' . bin2hex($x[0]);
return '\x' . bin2hex($x[0]);
};
$value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element)); $value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element));
} }
$output .= $desc . '=' . $value; $output .= $desc . '=' . $value;

View File

@ -665,9 +665,7 @@ class BigInteger implements \JsonSerializable
public static function min(BigInteger ...$nums): BigInteger public static function min(BigInteger ...$nums): BigInteger
{ {
$class = self::$mainEngine; $class = self::$mainEngine;
$nums = array_map(function ($num) { $nums = array_map(fn ($num) => $num->value, $nums);
return $num->value;
}, $nums);
return new static($class::min(...$nums)); return new static($class::min(...$nums));
} }
@ -677,9 +675,7 @@ class BigInteger implements \JsonSerializable
public static function max(BigInteger ...$nums): BigInteger public static function max(BigInteger ...$nums): BigInteger
{ {
$class = self::$mainEngine; $class = self::$mainEngine;
$nums = array_map(function ($num) { $nums = array_map(fn ($num) => $num->value, $nums);
return $num->value;
}, $nums);
return new static($class::max(...$nums)); return new static($class::max(...$nums));
} }
@ -755,9 +751,7 @@ class BigInteger implements \JsonSerializable
public function createRecurringModuloFunction() public function createRecurringModuloFunction()
{ {
$func = $this->value->createRecurringModuloFunction(); $func = $this->value->createRecurringModuloFunction();
return function (BigInteger $x) use ($func) { return fn (BigInteger $x) => new static($func($x->value));
return new static($func($x->value));
};
} }
/** /**
@ -769,8 +763,6 @@ class BigInteger implements \JsonSerializable
*/ */
public function bitwise_split(int $split): array public function bitwise_split(int $split): array
{ {
return array_map(function ($val) { return array_map(fn ($val) => new static($val), $this->value->bitwise_split($split));
return new static($val);
}, $this->value->bitwise_split($split));
} }
} }

View File

@ -537,9 +537,7 @@ class GMP extends Engine
public function createRecurringModuloFunction(): \Closure public function createRecurringModuloFunction(): \Closure
{ {
$temp = $this->value; $temp = $this->value;
return function (GMP $x) use ($temp) { return fn (GMP $x) => new GMP($x->value % $temp);
return new GMP($x->value % $temp);
};
} }
/** /**

View File

@ -57,7 +57,7 @@ abstract class OpenSSL
throw new \UnexpectedValueException(openssl_error_string()); throw new \UnexpectedValueException(openssl_error_string());
} }
$class = get_class($x); $class = $x::class;
return new $class($result, 256); return new $class($result, 256);
} }
} }

View File

@ -550,7 +550,7 @@ abstract class PHP extends Engine
$lhs = new static(); $lhs = new static();
$rhs = new static(); $rhs = new static();
} }
if (static::class != get_class($temp)) { if (static::class != $temp::class) {
$temp = new static(); $temp = new static();
$lhs = new static(); $lhs = new static();
$rhs = new static(); $rhs = new static();

View File

@ -1027,8 +1027,8 @@ class SFTP extends SSH2
} }
break; break;
case 'mode': case 'mode':
$a[$sort] &= 07777; $a[$sort] &= 0o7777;
$b[$sort] &= 07777; $b[$sort] &= 0o7777;
// fall-through // fall-through
default: default:
if ($a[$sort] === $b[$sort]) { if ($a[$sort] === $b[$sort]) {
@ -1450,7 +1450,7 @@ class SFTP extends SSH2
$filename = $temp; $filename = $temp;
} }
$attr = pack('N2', Attribute::PERMISSIONS, $mode & 07777); $attr = pack('N2', Attribute::PERMISSIONS, $mode & 0o7777);
if (!$this->setstat($filename, $attr, $recursive)) { if (!$this->setstat($filename, $attr, $recursive)) {
return false; return false;
} }
@ -2183,7 +2183,7 @@ class SFTP extends SSH2
} elseif (is_callable($local_file)) { } elseif (is_callable($local_file)) {
$local_file($temp); $local_file($temp);
} else { } else {
fputs($fp, $temp); fwrite($fp, $temp);
} }
if (is_callable($progressCallback)) { if (is_callable($progressCallback)) {
call_user_func($progressCallback, $offset); call_user_func($progressCallback, $offset);
@ -2825,26 +2825,26 @@ class SFTP extends SSH2
{ {
// values come from http://lxr.free-electrons.com/source/include/uapi/linux/stat.h#L12 // values come from http://lxr.free-electrons.com/source/include/uapi/linux/stat.h#L12
// see, also, http://linux.die.net/man/2/stat // see, also, http://linux.die.net/man/2/stat
switch ($mode & 0170000) {// ie. 1111 0000 0000 0000 switch ($mode & 0o170000) {// ie. 1111 0000 0000 0000
case 0000000: // no file type specified - figure out the file type using alternative means case 0: // no file type specified - figure out the file type using alternative means
return false; return false;
case 0040000: case 0o040000:
return FileType::DIRECTORY; return FileType::DIRECTORY;
case 0100000: case 0o100000:
return FileType::REGULAR; return FileType::REGULAR;
case 0120000: case 0o120000:
return FileType::SYMLINK; return FileType::SYMLINK;
// new types introduced in SFTPv5+ // new types introduced in SFTPv5+
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2
case 0010000: // named pipe (fifo) case 0o010000: // named pipe (fifo)
return FileType::FIFO; return FileType::FIFO;
case 0020000: // character special case 0o020000: // character special
return FileType::CHAR_DEVICE; return FileType::CHAR_DEVICE;
case 0060000: // block special case 0o060000: // block special
return FileType::BLOCK_DEVICE; return FileType::BLOCK_DEVICE;
case 0140000: // socket case 0o140000: // socket
return FileType::SOCKET; return FileType::SOCKET;
case 0160000: // whiteout case 0o160000: // whiteout
// "SPECIAL should be used for files that are of // "SPECIAL should be used for files that are of
// a known type which cannot be expressed in the protocol" // a known type which cannot be expressed in the protocol"
return FileType::SPECIAL; return FileType::SPECIAL;
@ -3030,7 +3030,7 @@ class SFTP extends SSH2
* *
* Makes sure that only the last 1MB worth of packets will be logged * Makes sure that only the last 1MB worth of packets will be logged
*/ */
private function append_log(string $message_number, string $message) private function append_log(string $message_number, string $message): void
{ {
$this->append_log_helper( $this->append_log_helper(
NET_SFTP_LOGGING, NET_SFTP_LOGGING,

View File

@ -67,6 +67,7 @@ use phpseclib3\Crypt\Twofish;
use phpseclib3\Exception\ConnectionClosedException; use phpseclib3\Exception\ConnectionClosedException;
use phpseclib3\Exception\InsufficientSetupException; use phpseclib3\Exception\InsufficientSetupException;
use phpseclib3\Exception\NoSupportedAlgorithmsException; use phpseclib3\Exception\NoSupportedAlgorithmsException;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnableToConnectException; use phpseclib3\Exception\UnableToConnectException;
use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedAlgorithmException;
use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\Exception\UnsupportedCurveException;
@ -155,7 +156,7 @@ class SSH2
/** /**
* Outputs the message numbers real-time * Outputs the message numbers real-time
*/ */
const LOG_SIMPLE_REALTIME = 5; public const LOG_SIMPLE_REALTIME = 5;
/** /**
* Make sure that the log never gets larger than this * Make sure that the log never gets larger than this
* *
@ -1172,7 +1173,7 @@ class SSH2
$this->identifier = $this->generate_identifier(); $this->identifier = $this->generate_identifier();
if ($this->send_id_string_first) { if ($this->send_id_string_first) {
fputs($this->fsock, $this->identifier . "\r\n"); fwrite($this->fsock, $this->identifier . "\r\n");
} }
/* According to the SSH2 specs, /* According to the SSH2 specs,
@ -1251,7 +1252,7 @@ class SSH2
} }
if (!$this->send_id_string_first) { if (!$this->send_id_string_first) {
fputs($this->fsock, $this->identifier . "\r\n"); fwrite($this->fsock, $this->identifier . "\r\n");
} }
if (!$this->send_kex_first) { if (!$this->send_kex_first) {
@ -1500,8 +1501,8 @@ class SSH2
$exchange_hash_rfc4419 = ''; $exchange_hash_rfc4419 = '';
if (strpos($this->kex_algorithm, 'curve25519-sha256') === 0 || strpos($this->kex_algorithm, 'ecdh-sha2-nistp') === 0) { if (str_starts_with($this->kex_algorithm, 'curve25519-sha256') || str_starts_with($this->kex_algorithm, 'ecdh-sha2-nistp')) {
$curve = strpos($this->kex_algorithm, 'curve25519-sha256') === 0 ? $curve = str_starts_with($this->kex_algorithm, 'curve25519-sha256') ?
'Curve25519' : 'Curve25519' :
substr($this->kex_algorithm, 10); substr($this->kex_algorithm, 10);
$ourPrivate = EC::createKey($curve); $ourPrivate = EC::createKey($curve);
@ -1509,7 +1510,7 @@ class SSH2
$clientKexInitMessage = MessageTypeExtra::KEX_ECDH_INIT; $clientKexInitMessage = MessageTypeExtra::KEX_ECDH_INIT;
$serverKexReplyMessage = MessageTypeExtra::KEX_ECDH_REPLY; $serverKexReplyMessage = MessageTypeExtra::KEX_ECDH_REPLY;
} else { } else {
if (strpos($this->kex_algorithm, 'diffie-hellman-group-exchange') === 0) { if (str_starts_with($this->kex_algorithm, 'diffie-hellman-group-exchange')) {
$dh_group_sizes_packed = pack( $dh_group_sizes_packed = pack(
'NNN', 'NNN',
$this->kex_dh_group_size_min, $this->kex_dh_group_size_min,
@ -3264,18 +3265,18 @@ class SSH2
$cmf = ord($payload[0]); $cmf = ord($payload[0]);
$cm = $cmf & 0x0F; $cm = $cmf & 0x0F;
if ($cm != 8) { // deflate if ($cm != 8) { // deflate
user_error("Only CM = 8 ('deflate') is supported ($cm)"); throw new UnsupportedAlgorithmException("Only CM = 8 ('deflate') is supported ($cm)");
} }
$cinfo = ($cmf & 0xF0) >> 4; $cinfo = ($cmf & 0xF0) >> 4;
if ($cinfo > 7) { if ($cinfo > 7) {
user_error("CINFO above 7 is not allowed ($cinfo)"); throw new RuntimeException("CINFO above 7 is not allowed ($cinfo)");
} }
$windowSize = 1 << ($cinfo + 8); $windowSize = 1 << ($cinfo + 8);
$flg = ord($payload[1]); $flg = ord($payload[1]);
//$fcheck = $flg && 0x0F; //$fcheck = $flg && 0x0F;
if ((($cmf << 8) | $flg) % 31) { if ((($cmf << 8) | $flg) % 31) {
user_error('fcheck failed'); throw new RuntimeException('fcheck failed');
} }
$fdict = boolval($flg & 0x20); $fdict = boolval($flg & 0x20);
$flevel = ($flg & 0xC0) >> 6; $flevel = ($flg & 0xC0) >> 6;
@ -3930,7 +3931,7 @@ class SSH2
$packet .= $this->encrypt && $this->encrypt->usesNonce() ? $this->encrypt->getTag() : $hmac; $packet .= $this->encrypt && $this->encrypt->usesNonce() ? $this->encrypt->getTag() : $hmac;
$start = microtime(true); $start = microtime(true);
$sent = @fputs($this->fsock, $packet); $sent = @fwrite($this->fsock, $packet);
$stop = microtime(true); $stop = microtime(true);
if (defined('NET_SSH2_LOGGING')) { if (defined('NET_SSH2_LOGGING')) {
@ -3976,17 +3977,9 @@ class SSH2
/** /**
* Logs data packet helper * Logs data packet helper
* *
* @param int $constant
* @param string $message_number
* @param string $message
* @param array &$message_number_log
* @param array &$message_log
* @param int &$log_size
* @param resource &$realtime_log_file * @param resource &$realtime_log_file
* @param bool &$realtime_log_wrap
* @param int &$realtime_log_size
*/ */
protected function append_log_helper(int $constant, string $message_number, string $message, array &$message_number_log, array &$message_log, int &$log_size, &$realtime_log_file, bool &$realtime_log_wrap, int &$realtime_log_size) protected function append_log_helper(int $constant, string $message_number, string $message, array &$message_number_log, array &$message_log, int &$log_size, &$realtime_log_file, bool &$realtime_log_wrap, int &$realtime_log_size): void
{ {
// remove the byte identifying the message type from all but the first two messages (ie. the identification strings) // remove the byte identifying the message type from all but the first two messages (ie. the identification strings)
if (strlen($message_number) > 2) { if (strlen($message_number) > 2) {
@ -4056,7 +4049,7 @@ class SSH2
$realtime_log_size = strlen($entry); $realtime_log_size = strlen($entry);
$realtime_log_wrap = true; $realtime_log_wrap = true;
} }
fputs($realtime_log_file, $entry); fwrite($realtime_log_file, $entry);
} }
} }
@ -4195,9 +4188,7 @@ class SSH2
$output .= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 '; $output .= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 ';
} }
$fragment = Strings::shift($current_log, $this->log_short_width); $fragment = Strings::shift($current_log, $this->log_short_width);
$hex = substr(preg_replace_callback('#.#s', function ($matches) { $hex = substr(preg_replace_callback('#.#s', fn ($matches) => $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT), $fragment), strlen($this->log_boundary));
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 // replace non ASCII printable characters with dots
// http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters
// also replace < with a . since < messes up the output on web browsers // also replace < with a . since < messes up the output on web browsers

View File

@ -36,7 +36,6 @@ namespace phpseclib3\System\SSH;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\PublicKeyLoader; use phpseclib3\Crypt\PublicKeyLoader;
use phpseclib3\Crypt\RSA;
use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Net\SSH2; use phpseclib3\Net\SSH2;
use phpseclib3\System\SSH\Agent\Identity; use phpseclib3\System\SSH\Agent\Identity;
@ -152,7 +151,7 @@ class Agent
} }
$packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES); $packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES);
if (strlen($packet) != fputs($this->fsock, $packet)) { if (strlen($packet) != fwrite($this->fsock, $packet)) {
throw new \RuntimeException('Connection closed while requesting identities'); throw new \RuntimeException('Connection closed while requesting identities');
} }

View File

@ -264,7 +264,7 @@ class Identity implements PrivateKey
$this->flags $this->flags
); );
$packet = Strings::packSSH2('s', $packet); $packet = Strings::packSSH2('s', $packet);
if (strlen($packet) != fputs($this->fsock, $packet)) { if (strlen($packet) != fwrite($this->fsock, $packet)) {
throw new \RuntimeException('Connection closed during signing'); throw new \RuntimeException('Connection closed during signing');
} }

View File

@ -40,7 +40,7 @@ class SFTPStreamTest extends SFTPTestCase
'sftp' => ['session' => $this->sftp], 'sftp' => ['session' => $this->sftp],
]); ]);
$fp = fopen($this->buildUrl('te#st.txt'), 'wb', false, $context); $fp = fopen($this->buildUrl('te#st.txt'), 'wb', false, $context);
fputs($fp, 'zzzz'); fwrite($fp, 'zzzz');
fclose($fp); fclose($fp);
$this->assertContains('te#st.txt', $this->sftp->nlist()); $this->assertContains('te#st.txt', $this->sftp->nlist());

View File

@ -268,7 +268,7 @@ class SFTPUserStoryTest extends PhpseclibFunctionalTestCase
public function testChModOnFile($sftp) public function testChModOnFile($sftp)
{ {
$this->assertNotFalse( $this->assertNotFalse(
$sftp->chmod(0755, 'file1.txt'), $sftp->chmod(0o755, 'file1.txt'),
'Failed asserting that chmod() was successful.' 'Failed asserting that chmod() was successful.'
); );
@ -717,12 +717,12 @@ class SFTPUserStoryTest extends PhpseclibFunctionalTestCase
*/ */
public function testReadableWritable($sftp) public function testReadableWritable($sftp)
{ {
$sftp->chmod(0000, 'offset.txt'); $sftp->chmod(0, 'offset.txt');
$this->assertFalse($sftp->is_writable('offset.txt')); $this->assertFalse($sftp->is_writable('offset.txt'));
$this->assertFalse($sftp->is_writeable('offset.txt')); $this->assertFalse($sftp->is_writeable('offset.txt'));
$this->assertFalse($sftp->is_readable('offset.txt')); $this->assertFalse($sftp->is_readable('offset.txt'));
$sftp->chmod(0777, 'offset.txt'); $sftp->chmod(0o777, 'offset.txt');
$this->assertTrue($sftp->is_writable('offset.txt')); $this->assertTrue($sftp->is_writable('offset.txt'));
$this->assertTrue($sftp->is_writeable('offset.txt')); $this->assertTrue($sftp->is_writeable('offset.txt'));
$this->assertTrue($sftp->is_readable('offset.txt')); $this->assertTrue($sftp->is_readable('offset.txt'));

View File

@ -82,7 +82,7 @@ abstract class PhpseclibTestCase extends TestCase
protected static function getVar($obj, $var) protected static function getVar($obj, $var)
{ {
$reflection = new \ReflectionClass(get_class($obj)); $reflection = new \ReflectionClass($obj::class);
$prop = $reflection->getProperty($var); $prop = $reflection->getProperty($var);
$prop->setAccessible(true); $prop->setAccessible(true);
return $prop->getValue($obj); return $prop->getValue($obj);
@ -90,7 +90,7 @@ abstract class PhpseclibTestCase extends TestCase
public static function callFunc($obj, $func, $params = []) public static function callFunc($obj, $func, $params = [])
{ {
$reflection = new \ReflectionClass(get_class($obj)); $reflection = new \ReflectionClass($obj::class);
$method = $reflection->getMethod($func); $method = $reflection->getMethod($func);
$method->setAccessible(true); $method->setAccessible(true);
return $method->invokeArgs($obj, $params); return $method->invokeArgs($obj, $params);

View File

@ -34,7 +34,7 @@ class PsalmBaselineTest extends TestCase
/** @var array{level: int, type: string, tag: string, attributes: array{OCCURRENCES?: int}} $element */ /** @var array{level: int, type: string, tag: string, attributes: array{OCCURRENCES?: int}} $element */
foreach ($values as $element) { foreach ($values as $element) {
if ($element['level'] === 3 && ($element['type'] === 'open' || $element['type'] === 'complete')) { if ($element['level'] === 3 && ($element['type'] === 'open' || $element['type'] === 'complete')) {
$errorCounts[$element['tag']] = $errorCounts[$element['tag']] ?? 0; $errorCounts[$element['tag']] ??= 0;
$occurrences = $element['attributes']['OCCURRENCES'] ?? 1; $occurrences = $element['attributes']['OCCURRENCES'] ?? 1;
$errorCounts[$element['tag']] += $occurrences; $errorCounts[$element['tag']] += $occurrences;
} }

View File

@ -178,9 +178,7 @@ abstract class TestCase extends PhpseclibTestCase
*/ */
public function continuousBufferBatteryCombosWithoutSingleCombos(): array public function continuousBufferBatteryCombosWithoutSingleCombos(): array
{ {
return array_filter($this->continuousBufferBatteryCombos(), function (array $continuousBufferBatteryCombo) { return array_filter($this->continuousBufferBatteryCombos(), fn (array $continuousBufferBatteryCombo) => count($continuousBufferBatteryCombo[2]) > 1);
return count($continuousBufferBatteryCombo[2]) > 1;
});
} }
/** /**

View File

@ -100,7 +100,7 @@ class ChaCha20Test extends PhpseclibTestCase
$c = new ChaCha20(); $c = new ChaCha20();
$c->setPoly1305Key($key); $c->setPoly1305Key($key);
$r = new \ReflectionClass(get_class($c)); $r = new \ReflectionClass($c::class);
// this unit test is testing Poly1305 independent of ChaCha20, which phpseclib doesn't // this unit test is testing Poly1305 independent of ChaCha20, which phpseclib doesn't
// really support, hence this hackish approach // really support, hence this hackish approach
$m = $r->getMethod('poly1305'); $m = $r->getMethod('poly1305');
@ -128,7 +128,7 @@ class ChaCha20Test extends PhpseclibTestCase
$c->setKey($key); $c->setKey($key);
$c->setNonce($nonce); $c->setNonce($nonce);
$r = new \ReflectionClass(get_class($c)); $r = new \ReflectionClass($c::class);
$m = $r->getMethod('createPoly1305Key'); $m = $r->getMethod('createPoly1305Key');
$m->setAccessible(true); $m->setAccessible(true);
$result = $m->invoke($c); $result = $m->invoke($c);

View File

@ -568,7 +568,7 @@ MIIEDwIBADATBgcqhkjOPQIBBggqhkjOPQMBBwSCA/MwggPvAgEBBIID6P//////
$this->assertSameNL($raw, $key->toString('MontgomeryPrivate')); $this->assertSameNL($raw, $key->toString('MontgomeryPrivate'));
} }
public function testOpenSSHEncryptedCreation() public function testOpenSSHEncryptedCreation(): void
{ {
$key = EC::createKey('Ed25519'); $key = EC::createKey('Ed25519');
$key = $key->withPassword('test')->toString('OpenSSH'); $key = $key->withPassword('test')->toString('OpenSSH');