Throw \phpseclib3\Exception\ExceptionInterface exceptions

This commit is contained in:
Jack Worman 2022-08-18 08:05:57 -05:00
parent 2b937b413a
commit 985b3c4f7c
94 changed files with 1082 additions and 1260 deletions

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,8 @@ declare(strict_types=1);
namespace phpseclib3\Common; namespace phpseclib3\Common;
use phpseclib3\Exception\InvalidArgumentException;
/** /**
* @internal * @internal
*/ */
@ -35,7 +37,7 @@ trait ConstantUtilityTrait
{ {
$constantName = static::findConstantNameByValue($value); $constantName = static::findConstantNameByValue($value);
if ($constantName === null) { if ($constantName === null) {
throw new \InvalidArgumentException(sprintf('"%s" does not have constant with value "%s".', static::class, $value)); throw new InvalidArgumentException(sprintf('"%s" does not have constant with value "%s".', static::class, $value));
} }
return $constantName; return $constantName;
} }

View File

@ -18,6 +18,9 @@ namespace phpseclib3\Common\Functions;
use ParagonIE\ConstantTime\Base64; use ParagonIE\ConstantTime\Base64;
use ParagonIE\ConstantTime\Base64UrlSafe; use ParagonIE\ConstantTime\Base64UrlSafe;
use ParagonIE\ConstantTime\Hex; use ParagonIE\ConstantTime\Hex;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Exception\LengthException;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\Common\FiniteField; use phpseclib3\Math\Common\FiniteField;
@ -78,7 +81,7 @@ abstract class Strings
case 'C': case 'C':
case 'b': case 'b':
if (!strlen($data)) { if (!strlen($data)) {
throw new \LengthException('At least one byte needs to be present for successful C / b decodes'); throw new LengthException('At least one byte needs to be present for successful C / b decodes');
} }
break; break;
case 'N': case 'N':
@ -86,17 +89,17 @@ abstract class Strings
case 's': case 's':
case 'L': case 'L':
if (strlen($data) < 4) { if (strlen($data) < 4) {
throw new \LengthException('At least four byte needs to be present for successful N / i / s / L decodes'); throw new LengthException('At least four byte needs to be present for successful N / i / s / L decodes');
} }
break; break;
case 'Q': case 'Q':
if (strlen($data) < 8) { if (strlen($data) < 8) {
throw new \LengthException('At least eight byte needs to be present for successful N / i / s / L decodes'); throw new LengthException('At least eight byte needs to be present for successful N / i / s / L decodes');
} }
break; break;
default: default:
throw new \InvalidArgumentException('$format contains an invalid character'); throw new InvalidArgumentException('$format contains an invalid character');
} }
switch ($format[$i]) { switch ($format[$i]) {
case 'C': case 'C':
@ -125,7 +128,7 @@ abstract class Strings
} }
[, $length] = unpack('N', self::shift($data, 4)); [, $length] = unpack('N', self::shift($data, 4));
if (strlen($data) < $length) { if (strlen($data) < $length) {
throw new \LengthException("$length bytes needed; " . strlen($data) . ' bytes available'); throw new LengthException("$length bytes needed; " . strlen($data) . ' bytes available');
} }
$temp = self::shift($data, $length); $temp = self::shift($data, $length);
switch ($format[$i]) { switch ($format[$i]) {
@ -152,7 +155,7 @@ abstract class Strings
{ {
$format = self::formatPack($format); $format = self::formatPack($format);
if (strlen($format) != count($elements)) { if (strlen($format) != count($elements)) {
throw new \InvalidArgumentException('There must be as many arguments as there are characters in the $format string'); throw new InvalidArgumentException('There must be as many arguments as there are characters in the $format string');
} }
$result = ''; $result = '';
for ($i = 0; $i < strlen($format); $i++) { for ($i = 0; $i < strlen($format); $i++) {
@ -160,19 +163,19 @@ abstract class Strings
switch ($format[$i]) { switch ($format[$i]) {
case 'C': case 'C':
if (!is_int($element)) { if (!is_int($element)) {
throw new \InvalidArgumentException('Bytes must be represented as an integer between 0 and 255, inclusive.'); throw new InvalidArgumentException('Bytes must be represented as an integer between 0 and 255, inclusive.');
} }
$result .= pack('C', $element); $result .= pack('C', $element);
break; break;
case 'b': case 'b':
if (!is_bool($element)) { if (!is_bool($element)) {
throw new \InvalidArgumentException('A boolean parameter was expected.'); throw new InvalidArgumentException('A boolean parameter was expected.');
} }
$result .= $element ? "\1" : "\0"; $result .= $element ? "\1" : "\0";
break; break;
case 'Q': case 'Q':
if (!is_int($element) && !is_float($element)) { if (!is_int($element) && !is_float($element)) {
throw new \InvalidArgumentException('An integer was expected.'); throw new InvalidArgumentException('An integer was expected.');
} }
// 4294967296 == 1 << 32 // 4294967296 == 1 << 32
$result .= pack('NN', $element / 4294967296, $element); $result .= pack('NN', $element / 4294967296, $element);
@ -182,32 +185,32 @@ abstract class Strings
$element = (int) $element; $element = (int) $element;
} }
if (!is_int($element)) { if (!is_int($element)) {
throw new \InvalidArgumentException('An integer was expected.'); throw new InvalidArgumentException('An integer was expected.');
} }
$result .= pack('N', $element); $result .= pack('N', $element);
break; break;
case 's': case 's':
if (!self::is_stringable($element)) { if (!self::is_stringable($element)) {
throw new \InvalidArgumentException('A string was expected.'); throw new InvalidArgumentException('A string was expected.');
} }
$result .= pack('Na*', strlen($element), $element); $result .= pack('Na*', strlen($element), $element);
break; break;
case 'i': case 'i':
if (!$element instanceof BigInteger && !$element instanceof FiniteField\Integer) { if (!$element instanceof BigInteger && !$element instanceof FiniteField\Integer) {
throw new \InvalidArgumentException('A phpseclib3\Math\BigInteger or phpseclib3\Math\Common\FiniteField\Integer object was expected.'); throw new InvalidArgumentException('A phpseclib3\Math\BigInteger or phpseclib3\Math\Common\FiniteField\Integer object was expected.');
} }
$element = $element->toBytes(true); $element = $element->toBytes(true);
$result .= pack('Na*', strlen($element), $element); $result .= pack('Na*', strlen($element), $element);
break; break;
case 'L': case 'L':
if (!is_array($element)) { if (!is_array($element)) {
throw new \InvalidArgumentException('An array was expected.'); throw new InvalidArgumentException('An array was expected.');
} }
$element = implode(',', $element); $element = implode(',', $element);
$result .= pack('Na*', strlen($element), $element); $result .= pack('Na*', strlen($element), $element);
break; break;
default: default:
throw new \InvalidArgumentException('$format contains an invalid character'); throw new InvalidArgumentException('$format contains an invalid character');
} }
} }
return $result; return $result;
@ -248,7 +251,7 @@ abstract class Strings
*/ */
if (preg_match('#[^01]#', $x)) { if (preg_match('#[^01]#', $x)) {
throw new \RuntimeException('The only valid characters are 0 and 1'); throw new RuntimeException('The only valid characters are 0 and 1');
} }
if (!defined('PHP_INT_MIN')) { if (!defined('PHP_INT_MIN')) {

View File

@ -49,6 +49,9 @@ declare(strict_types=1);
namespace phpseclib3\Crypt; namespace phpseclib3\Crypt;
use phpseclib3\Exception\BadMethodCallException;
use phpseclib3\Exception\LengthException;
/** /**
* Pure-PHP implementation of AES. * Pure-PHP implementation of AES.
* *
@ -61,12 +64,12 @@ class AES extends Rijndael
* *
* Since \phpseclib3\Crypt\AES extends \phpseclib3\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything. * Since \phpseclib3\Crypt\AES extends \phpseclib3\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything.
* *
* @throws \BadMethodCallException anytime it's called * @throws BadMethodCallException anytime it's called
* @see \phpseclib3\Crypt\Rijndael::setBlockLength() * @see \phpseclib3\Crypt\Rijndael::setBlockLength()
*/ */
public function setBlockLength(int $length): void public function setBlockLength(int $length): void
{ {
throw new \BadMethodCallException('The block length cannot be set for AES.'); throw new BadMethodCallException('The block length cannot be set for AES.');
} }
/** /**
@ -74,7 +77,7 @@ class AES extends Rijndael
* *
* Valid key lengths are 128, 192, and 256. Set the link to bool(false) to disable a fixed key length * Valid key lengths are 128, 192, and 256. Set the link to bool(false) to disable a fixed key length
* *
* @throws \LengthException if the key length isn't supported * @throws LengthException if the key length isn't supported
* @see \phpseclib3\Crypt\Rijndael:setKeyLength() * @see \phpseclib3\Crypt\Rijndael:setKeyLength()
*/ */
public function setKeyLength(int $length): void public function setKeyLength(int $length): void
@ -85,7 +88,7 @@ class AES extends Rijndael
case 256: case 256:
break; break;
default: default:
throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported'); throw new LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported');
} }
parent::setKeyLength($length); parent::setKeyLength($length);
} }
@ -95,7 +98,7 @@ class AES extends Rijndael
* *
* Rijndael supports five different key lengths, AES only supports three. * Rijndael supports five different key lengths, AES only supports three.
* *
* @throws \LengthException if the key length isn't supported * @throws LengthException if the key length isn't supported
* @see \phpseclib3\Crypt\Rijndael:setKey() * @see \phpseclib3\Crypt\Rijndael:setKey()
* @see setKeyLength() * @see setKeyLength()
*/ */
@ -107,7 +110,7 @@ class AES extends Rijndael
case 32: case 32:
break; break;
default: default:
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); throw new LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
} }
parent::setKey($key); parent::setKey($key);

View File

@ -115,6 +115,8 @@ declare(strict_types=1);
namespace phpseclib3\Crypt; namespace phpseclib3\Crypt;
use phpseclib3\Crypt\Common\BlockCipher; use phpseclib3\Crypt\Common\BlockCipher;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Exception\LengthException;
/** /**
* Pure-PHP implementation of Blowfish. * Pure-PHP implementation of Blowfish.
@ -336,14 +338,14 @@ class Blowfish extends BlockCipher
/** /**
* Default Constructor. * Default Constructor.
* *
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided * @throws InvalidArgumentException if an invalid / unsupported mode is provided
*/ */
public function __construct(string $mode) public function __construct(string $mode)
{ {
parent::__construct($mode); parent::__construct($mode);
if ($this->mode == self::MODE_STREAM) { if ($this->mode == self::MODE_STREAM) {
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode'); throw new InvalidArgumentException('Block ciphers cannot be ran in stream mode');
} }
} }
@ -355,7 +357,7 @@ class Blowfish extends BlockCipher
public function setKeyLength(int $length): void public function setKeyLength(int $length): void
{ {
if ($length < 32 || $length > 448) { if ($length < 32 || $length > 448) {
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes between 32 and 448 bits are supported'); throw new LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes between 32 and 448 bits are supported');
} }
$this->key_length = $length >> 3; $this->key_length = $length >> 3;

View File

@ -17,6 +17,8 @@ namespace phpseclib3\Crypt;
use phpseclib3\Exception\BadDecryptionException; use phpseclib3\Exception\BadDecryptionException;
use phpseclib3\Exception\InsufficientSetupException; use phpseclib3\Exception\InsufficientSetupException;
use phpseclib3\Exception\LengthException;
use phpseclib3\Exception\UnexpectedValueException;
/** /**
* Pure-PHP implementation of ChaCha20. * Pure-PHP implementation of ChaCha20.
@ -177,7 +179,7 @@ class ChaCha20 extends Salsa20
public function setNonce(string $nonce): void public function setNonce(string $nonce): void
{ {
if (!is_string($nonce)) { if (!is_string($nonce)) {
throw new \UnexpectedValueException('The nonce should be a string'); throw new UnexpectedValueException('The nonce should be a string');
} }
/* /*
@ -192,7 +194,7 @@ class ChaCha20 extends Salsa20
case 12: // 96 bits case 12: // 96 bits
break; break;
default: default:
throw new \LengthException('Nonce of size ' . strlen($nonce) . ' not supported by this algorithm. Only 64-bit nonces or 96-bit nonces are supported'); throw new LengthException('Nonce of size ' . strlen($nonce) . ' not supported by this algorithm. Only 64-bit nonces or 96-bit nonces are supported');
} }
$this->nonce = $nonce; $this->nonce = $nonce;

View File

@ -30,14 +30,14 @@ abstract class AsymmetricKey
/** /**
* Precomputed Zero * Precomputed Zero
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected static $zero; protected static $zero;
/** /**
* Precomputed One * Precomputed One
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected static $one; protected static $one;
@ -51,14 +51,14 @@ abstract class AsymmetricKey
/** /**
* Hash function * Hash function
* *
* @var \phpseclib3\Crypt\Hash * @var Hash
*/ */
protected $hash; protected $hash;
/** /**
* HMAC function * HMAC function
* *
* @var \phpseclib3\Crypt\Hash * @var Hash
*/ */
private $hmac; private $hmac;

View File

@ -20,6 +20,8 @@ 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\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
/** /**
* OpenSSH Formatted RSA Key Handler * OpenSSH Formatted RSA Key Handler
@ -60,7 +62,7 @@ abstract class OpenSSH
public static function load($key, ?string $password = null): array public static function load($key, ?string $password = null): array
{ {
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); throw new UnexpectedValueException('Key should be a string - not a ' . gettype($key));
} }
// key format is described here: // key format is described here:
@ -71,14 +73,14 @@ abstract class OpenSSH
$key = Strings::base64_decode($key); $key = Strings::base64_decode($key);
$magic = Strings::shift($key, 15); $magic = Strings::shift($key, 15);
if ($magic != "openssh-key-v1\0") { if ($magic != "openssh-key-v1\0") {
throw new \RuntimeException('Expected openssh-key-v1'); throw new RuntimeException('Expected openssh-key-v1');
} }
[$ciphername, $kdfname, $kdfoptions, $numKeys] = Strings::unpackSSH2('sssN', $key); [$ciphername, $kdfname, $kdfoptions, $numKeys] = Strings::unpackSSH2('sssN', $key);
if ($numKeys != 1) { if ($numKeys != 1) {
// if we wanted to support multiple keys we could update PublicKeyLoader to preview what the # of keys // if we wanted to support multiple keys we could update PublicKeyLoader to preview what the # of keys
// would be; it'd then call Common\Keys\OpenSSH.php::load() and get the paddedKey. it'd then pass // would be; it'd then call Common\Keys\OpenSSH.php::load() and get the paddedKey. it'd then pass
// that to the appropriate key loading parser $numKey times or something // that to the appropriate key loading parser $numKey times or something
throw new \RuntimeException('Although the OpenSSH private key format supports multiple keys phpseclib does not'); throw new RuntimeException('Although the OpenSSH private key format supports multiple keys phpseclib does not');
} }
switch ($ciphername) { switch ($ciphername) {
@ -86,7 +88,7 @@ abstract class OpenSSH
break; break;
case 'aes256-ctr': case 'aes256-ctr':
if ($kdfname != 'bcrypt') { if ($kdfname != 'bcrypt') {
throw new \RuntimeException('Only the bcrypt kdf is supported (' . $kdfname . ' encountered)'); throw new RuntimeException('Only the bcrypt kdf is supported (' . $kdfname . ' encountered)');
} }
[$salt, $rounds] = Strings::unpackSSH2('sN', $kdfoptions); [$salt, $rounds] = Strings::unpackSSH2('sN', $kdfoptions);
$crypto = new AES('ctr'); $crypto = new AES('ctr');
@ -95,7 +97,7 @@ abstract class OpenSSH
$crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32); $crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32);
break; break;
default: default:
throw new \RuntimeException('The only supported cipherse are: none, aes256-ctr (' . $ciphername . ' is being used)'); throw new RuntimeException('The only supported cipherse are: none, aes256-ctr (' . $ciphername . ' is being used)');
} }
[$publicKey, $paddedKey] = Strings::unpackSSH2('ss', $key); [$publicKey, $paddedKey] = Strings::unpackSSH2('ss', $key);
@ -106,7 +108,7 @@ abstract class OpenSSH
[$checkint1, $checkint2] = Strings::unpackSSH2('NN', $paddedKey); [$checkint1, $checkint2] = Strings::unpackSSH2('NN', $paddedKey);
// any leftover bytes in $paddedKey are for padding? but they should be sequential bytes. eg. 1, 2, 3, etc. // any leftover bytes in $paddedKey are for padding? but they should be sequential bytes. eg. 1, 2, 3, etc.
if ($checkint1 != $checkint2) { if ($checkint1 != $checkint2) {
throw new \RuntimeException('The two checkints do not match'); throw new RuntimeException('The two checkints do not match');
} }
self::checkType($type); self::checkType($type);
@ -125,16 +127,16 @@ abstract class OpenSSH
$comment = $parts[2] ?? false; $comment = $parts[2] ?? false;
} }
if ($key === false) { if ($key === false) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); throw new UnexpectedValueException('Key should be a string - not a ' . gettype($key));
} }
[$type] = Strings::unpackSSH2('s', $key); [$type] = Strings::unpackSSH2('s', $key);
self::checkType($type); self::checkType($type);
if (isset($asciiType) && $asciiType != $type) { if (isset($asciiType) && $asciiType != $type) {
throw new \RuntimeException('Two different types of keys are claimed: ' . $asciiType . ' and ' . $type); throw new RuntimeException('Two different types of keys are claimed: ' . $asciiType . ' and ' . $type);
} }
if (strlen($key) <= 4) { if (strlen($key) <= 4) {
throw new \UnexpectedValueException('Key appears to be malformed'); throw new UnexpectedValueException('Key appears to be malformed');
} }
$publicKey = $key; $publicKey = $key;
@ -159,7 +161,7 @@ abstract class OpenSSH
private static function checkType(string $candidate): void private static function checkType(string $candidate): void
{ {
if (!in_array($candidate, static::$types)) { if (!in_array($candidate, static::$types)) {
throw new \RuntimeException("The key type ($candidate) is not equal to: " . implode(',', static::$types)); throw new RuntimeException("The key type ($candidate) is not equal to: " . implode(',', static::$types));
} }
} }

View File

@ -20,6 +20,7 @@ use phpseclib3\Crypt\AES;
use phpseclib3\Crypt\DES; use phpseclib3\Crypt\DES;
use phpseclib3\Crypt\Random; use phpseclib3\Crypt\Random;
use phpseclib3\Crypt\TripleDES; use phpseclib3\Crypt\TripleDES;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedAlgorithmException;
use phpseclib3\File\ASN1; use phpseclib3\File\ASN1;
@ -49,7 +50,7 @@ abstract class PKCS1 extends PKCS
* Returns the mode constant corresponding to the mode string * Returns the mode constant corresponding to the mode string
* *
* @return int * @return int
* @throws \UnexpectedValueException if the block cipher mode is unsupported * @throws UnexpectedValueException if the block cipher mode is unsupported
*/ */
private static function getEncryptionMode(string $mode) private static function getEncryptionMode(string $mode)
{ {
@ -61,14 +62,14 @@ abstract class PKCS1 extends PKCS
case 'CTR': case 'CTR':
return $mode; return $mode;
} }
throw new \UnexpectedValueException('Unsupported block cipher mode of operation'); throw new UnexpectedValueException('Unsupported block cipher mode of operation');
} }
/** /**
* Returns a cipher object corresponding to a string * Returns a cipher object corresponding to a string
* *
* @return AES|DES|TripleDES * @return AES|DES|TripleDES
* @throws \UnexpectedValueException if the encryption algorithm is unsupported * @throws UnexpectedValueException if the encryption algorithm is unsupported
*/ */
private static function getEncryptionObject(string $algo) private static function getEncryptionObject(string $algo)
{ {
@ -109,7 +110,7 @@ abstract class PKCS1 extends PKCS
protected static function load($key, ?string $password = null) protected static function load($key, ?string $password = null)
{ {
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); throw new UnexpectedValueException('Key should be a string - not a ' . gettype($key));
} }
/* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is
@ -145,7 +146,7 @@ abstract class PKCS1 extends PKCS
if ($decoded !== false) { if ($decoded !== false) {
$key = $decoded; $key = $decoded;
} elseif (self::$format == self::MODE_PEM) { } elseif (self::$format == self::MODE_PEM) {
throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); throw new UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text');
} }
} }
} }

View File

@ -36,6 +36,8 @@ use phpseclib3\Crypt\RC2;
use phpseclib3\Crypt\RC4; use phpseclib3\Crypt\RC4;
use phpseclib3\Crypt\TripleDES; use phpseclib3\Crypt\TripleDES;
use phpseclib3\Exception\InsufficientSetupException; use phpseclib3\Exception\InsufficientSetupException;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedAlgorithmException;
use phpseclib3\File\ASN1; use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1\Maps;
@ -121,7 +123,7 @@ abstract class PKCS8 extends PKCS
/** /**
* Returns a SymmetricKey object based on a PBES1 $algo * Returns a SymmetricKey object based on a PBES1 $algo
* *
* @return \phpseclib3\Crypt\Common\SymmetricKey * @return SymmetricKey
*/ */
private static function getPBES1EncryptionObject(string $algo) private static function getPBES1EncryptionObject(string $algo)
{ {
@ -326,7 +328,7 @@ abstract class PKCS8 extends PKCS
$temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']);
if (!$temp) { if (!$temp) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
extract(ASN1::asn1map($temp[0], Maps\PBEParameter::MAP)); extract(ASN1::asn1map($temp[0], Maps\PBEParameter::MAP));
$iterationCount = (int) $iterationCount->toString(); $iterationCount = (int) $iterationCount->toString();
@ -334,7 +336,7 @@ abstract class PKCS8 extends PKCS
$key = $cipher->decrypt($decrypted['encryptedData']); $key = $cipher->decrypt($decrypted['encryptedData']);
$decoded = ASN1::decodeBER($key); $decoded = ASN1::decodeBER($key);
if (!$decoded) { if (!$decoded) {
throw new \RuntimeException('Unable to decode BER 2'); throw new RuntimeException('Unable to decode BER 2');
} }
break; break;
@ -343,7 +345,7 @@ abstract class PKCS8 extends PKCS
$temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']);
if (!$temp) { if (!$temp) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
$temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP);
extract($temp); extract($temp);
@ -353,7 +355,7 @@ abstract class PKCS8 extends PKCS
$temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']);
if (!$temp) { if (!$temp) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
$temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP);
extract($temp); extract($temp);
@ -363,7 +365,7 @@ abstract class PKCS8 extends PKCS
} else { } else {
$temp = ASN1::decodeBER($encryptionScheme['parameters']); $temp = ASN1::decodeBER($encryptionScheme['parameters']);
if (!$temp) { if (!$temp) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
extract(ASN1::asn1map($temp[0], Maps\RC2CBCParameter::MAP)); extract(ASN1::asn1map($temp[0], Maps\RC2CBCParameter::MAP));
$effectiveKeyLength = (int) $rc2ParametersVersion->toString(); $effectiveKeyLength = (int) $rc2ParametersVersion->toString();
@ -388,7 +390,7 @@ abstract class PKCS8 extends PKCS
case 'id-PBKDF2': case 'id-PBKDF2':
$temp = ASN1::decodeBER($keyDerivationFunc['parameters']); $temp = ASN1::decodeBER($keyDerivationFunc['parameters']);
if (!$temp) { if (!$temp) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
$prf = ['algorithm' => 'id-hmacWithSHA1']; $prf = ['algorithm' => 'id-hmacWithSHA1'];
$params = ASN1::asn1map($temp[0], Maps\PBKDF2params::MAP); $params = ASN1::asn1map($temp[0], Maps\PBKDF2params::MAP);
@ -409,7 +411,7 @@ abstract class PKCS8 extends PKCS
$key = $cipher->decrypt($decrypted['encryptedData']); $key = $cipher->decrypt($decrypted['encryptedData']);
$decoded = ASN1::decodeBER($key); $decoded = ASN1::decodeBER($key);
if (!$decoded) { if (!$decoded) {
throw new \RuntimeException('Unable to decode BER 3'); throw new RuntimeException('Unable to decode BER 3');
} }
break; break;
default: default:
@ -442,7 +444,7 @@ abstract class PKCS8 extends PKCS
} }
if (isset($private['publicKey'])) { if (isset($private['publicKey'])) {
if ($private['publicKey'][0] != "\0") { if ($private['publicKey'][0] != "\0") {
throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($private['publicKey'][0])); throw new UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($private['publicKey'][0]));
} }
$private['publicKey'] = substr($private['publicKey'], 1); $private['publicKey'] = substr($private['publicKey'], 1);
} }
@ -457,7 +459,7 @@ abstract class PKCS8 extends PKCS
if (is_array($public)) { if (is_array($public)) {
if ($public['publicKey'][0] != "\0") { if ($public['publicKey'][0] != "\0") {
throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($public['publicKey'][0])); throw new UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($public['publicKey'][0]));
} }
if (is_array(static::OID_NAME)) { if (is_array(static::OID_NAME)) {
if (!in_array($public['publicKeyAlgorithm']['algorithm'], static::OID_NAME)) { if (!in_array($public['publicKeyAlgorithm']['algorithm'], static::OID_NAME)) {
@ -476,7 +478,7 @@ abstract class PKCS8 extends PKCS
return $public; return $public;
} }
throw new \RuntimeException('Unable to parse using either OneAsymmetricKey or PublicKeyInfo ASN1 maps'); throw new RuntimeException('Unable to parse using either OneAsymmetricKey or PublicKeyInfo ASN1 maps');
} }
/** /**
@ -622,7 +624,7 @@ abstract class PKCS8 extends PKCS
self::initialize_static_variables(); self::initialize_static_variables();
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
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 (self::$format != self::MODE_DER) { if (self::$format != self::MODE_DER) {
@ -630,13 +632,13 @@ abstract class PKCS8 extends PKCS
if ($decoded !== false) { if ($decoded !== false) {
$key = $decoded; $key = $decoded;
} elseif (self::$format == self::MODE_PEM) { } elseif (self::$format == self::MODE_PEM) {
throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); throw new UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text');
} }
} }
$decoded = ASN1::decodeBER($key); $decoded = ASN1::decodeBER($key);
if (!$decoded) { if (!$decoded) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
return $decoded; return $decoded;
@ -651,13 +653,13 @@ abstract class PKCS8 extends PKCS
$r = ASN1::asn1map($decoded[0], ASN1\Maps\EncryptedPrivateKeyInfo::MAP); $r = ASN1::asn1map($decoded[0], ASN1\Maps\EncryptedPrivateKeyInfo::MAP);
if (!is_array($r)) { if (!is_array($r)) {
throw new \RuntimeException('Unable to parse using EncryptedPrivateKeyInfo map'); throw new RuntimeException('Unable to parse using EncryptedPrivateKeyInfo map');
} }
if ($r['encryptionAlgorithm']['algorithm'] == 'id-PBES2') { if ($r['encryptionAlgorithm']['algorithm'] == 'id-PBES2') {
$decoded = ASN1::decodeBER($r['encryptionAlgorithm']['parameters']->element); $decoded = ASN1::decodeBER($r['encryptionAlgorithm']['parameters']->element);
if (!$decoded) { if (!$decoded) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
$r['encryptionAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], ASN1\Maps\PBES2params::MAP); $r['encryptionAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], ASN1\Maps\PBES2params::MAP);
@ -666,7 +668,7 @@ abstract class PKCS8 extends PKCS
case 'id-PBKDF2': case 'id-PBKDF2':
$decoded = ASN1::decodeBER($kdf['parameters']->element); $decoded = ASN1::decodeBER($kdf['parameters']->element);
if (!$decoded) { if (!$decoded) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
$kdf['parameters'] = ASN1::asn1map($decoded[0], Maps\PBKDF2params::MAP); $kdf['parameters'] = ASN1::asn1map($decoded[0], Maps\PBKDF2params::MAP);
} }

View File

@ -21,6 +21,8 @@ use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\AES; use phpseclib3\Crypt\AES;
use phpseclib3\Crypt\Hash; use phpseclib3\Crypt\Hash;
use phpseclib3\Crypt\Random; use phpseclib3\Crypt\Random;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedAlgorithmException;
/** /**
@ -58,7 +60,7 @@ abstract class PuTTY
public static function setVersion(int $version): void public static function setVersion(int $version): void
{ {
if ($version != 2 && $version != 3) { if ($version != 2 && $version != 3) {
throw new \RuntimeException('Only supported versions are 2 and 3'); throw new RuntimeException('Only supported versions are 2 and 3');
} }
self::$version = $version; self::$version = $version;
} }
@ -83,7 +85,7 @@ abstract class PuTTY
private static function generateV3Key(string $password, string $flavour, int $memory, int $passes, string $salt): array private static function generateV3Key(string $password, string $flavour, int $memory, int $passes, string $salt): array
{ {
if (!function_exists('sodium_crypto_pwhash')) { if (!function_exists('sodium_crypto_pwhash')) {
throw new \RuntimeException('sodium_crypto_pwhash needs to exist for Argon2 password hasing'); throw new RuntimeException('sodium_crypto_pwhash needs to exist for Argon2 password hasing');
} }
switch ($flavour) { switch ($flavour) {
@ -117,16 +119,16 @@ abstract class PuTTY
public static function load($key, $password) public static function load($key, $password)
{ {
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
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 (str_contains($key, 'BEGIN SSH2 PUBLIC KEY')) { 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 ----':
throw new \UnexpectedValueException('Key doesn\'t start with ---- BEGIN SSH2 PUBLIC KEY ----'); throw new UnexpectedValueException('Key doesn\'t start with ---- BEGIN SSH2 PUBLIC KEY ----');
case $lines[count($lines) - 1] != '---- END SSH2 PUBLIC KEY ----': case $lines[count($lines) - 1] != '---- END SSH2 PUBLIC KEY ----':
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(fn ($line) => rtrim($line, "\r\n"), $lines); $lines = array_map(fn ($line) => rtrim($line, "\r\n"), $lines);
@ -151,7 +153,7 @@ abstract class PuTTY
$components = call_user_func([static::PUBLIC_HANDLER, 'load'], $data); $components = call_user_func([static::PUBLIC_HANDLER, 'load'], $data);
if ($components === false) { if ($components === false) {
throw new \UnexpectedValueException('Unable to decode public key'); throw new UnexpectedValueException('Unable to decode public key');
} }
$components += $values; $components += $values;
$components['comment'] = str_replace(['\\\\', '\"'], ['\\', '"'], $values['comment']); $components['comment'] = str_replace(['\\\\', '\"'], ['\\', '"'], $values['comment']);
@ -167,7 +169,7 @@ abstract class PuTTY
} }
$version = (int) Strings::shift($key[0], 3); // should be either "2: " or "3: 0" prior to int casting $version = (int) Strings::shift($key[0], 3); // should be either "2: " or "3: 0" prior to int casting
if ($version != 2 && $version != 3) { if ($version != 2 && $version != 3) {
throw new \RuntimeException('Only v2 and v3 PuTTY private keys are supported'); throw new RuntimeException('Only v2 and v3 PuTTY private keys are supported');
} }
$components['type'] = $type = rtrim($key[0]); $components['type'] = $type = rtrim($key[0]);
if (!in_array($type, static::$types)) { if (!in_array($type, static::$types)) {
@ -187,7 +189,7 @@ abstract class PuTTY
extract(unpack('Nlength', Strings::shift($public, 4))); extract(unpack('Nlength', Strings::shift($public, 4)));
$newtype = Strings::shift($public, $length); $newtype = Strings::shift($public, $length);
if ($newtype != $type) { if ($newtype != $type) {
throw new \RuntimeException('The binary type does not match the human readable type field'); throw new RuntimeException('The binary type does not match the human readable type field');
} }
$components['public'] = $public; $components['public'] = $public;
@ -248,7 +250,7 @@ abstract class PuTTY
$hmac = Strings::hex2bin($hmac); $hmac = Strings::hex2bin($hmac);
if (!hash_equals($hash->hash($source), $hmac)) { if (!hash_equals($hash->hash($source), $hmac)) {
throw new \UnexpectedValueException('MAC validation error'); throw new UnexpectedValueException('MAC validation error');
} }
$components['private'] = $private; $components['private'] = $private;

View File

@ -37,7 +37,7 @@ abstract class StreamCipher extends SymmetricKey
* Default Constructor. * Default Constructor.
* *
* @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct()
* @return \phpseclib3\Crypt\Common\StreamCipher * @return StreamCipher
*/ */
public function __construct() public function __construct()
{ {

View File

@ -40,9 +40,13 @@ use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Blowfish; use phpseclib3\Crypt\Blowfish;
use phpseclib3\Crypt\Hash; use phpseclib3\Crypt\Hash;
use phpseclib3\Exception\BadDecryptionException; use phpseclib3\Exception\BadDecryptionException;
use phpseclib3\Exception\BadMethodCallException;
use phpseclib3\Exception\BadModeException; use phpseclib3\Exception\BadModeException;
use phpseclib3\Exception\InconsistentSetupException; use phpseclib3\Exception\InconsistentSetupException;
use phpseclib3\Exception\InsufficientSetupException; use phpseclib3\Exception\InsufficientSetupException;
use phpseclib3\Exception\LengthException;
use phpseclib3\Exception\LogicException;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedAlgorithmException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\BinaryField; use phpseclib3\Math\BinaryField;
@ -559,25 +563,25 @@ abstract class SymmetricKey
* *
* {@internal Can be overwritten by a sub class, but does not have to be} * {@internal Can be overwritten by a sub class, but does not have to be}
* *
* @throws \LengthException if the IV length isn't equal to the block size * @throws LengthException if the IV length isn't equal to the block size
* @throws \BadMethodCallException if an IV is provided when one shouldn't be * @throws BadMethodCallException if an IV is provided when one shouldn't be
*/ */
public function setIV(string $iv): void public function setIV(string $iv): void
{ {
if ($this->mode == self::MODE_ECB) { if ($this->mode == self::MODE_ECB) {
throw new \BadMethodCallException('This mode does not require an IV.'); throw new BadMethodCallException('This mode does not require an IV.');
} }
if ($this->mode == self::MODE_GCM) { if ($this->mode == self::MODE_GCM) {
throw new \BadMethodCallException('Use setNonce instead'); throw new BadMethodCallException('Use setNonce instead');
} }
if (!$this->usesIV()) { if (!$this->usesIV()) {
throw new \BadMethodCallException('This algorithm does not use an IV.'); throw new BadMethodCallException('This algorithm does not use an IV.');
} }
if (strlen($iv) != $this->block_size) { if (strlen($iv) != $this->block_size) {
throw new \LengthException('Received initialization vector of size ' . strlen($iv) . ', but size ' . $this->block_size . ' is required'); throw new LengthException('Received initialization vector of size ' . strlen($iv) . ', but size ' . $this->block_size . ' is required');
} }
$this->iv = $this->origIV = $iv; $this->iv = $this->origIV = $iv;
@ -589,12 +593,12 @@ abstract class SymmetricKey
* *
* Once enabled Poly1305 cannot be disabled. * Once enabled Poly1305 cannot be disabled.
* *
* @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode * @throws BadMethodCallException if Poly1305 is enabled whilst in GCM mode
*/ */
public function enablePoly1305(): void public function enablePoly1305(): void
{ {
if ($this->mode == self::MODE_GCM) { if ($this->mode == self::MODE_GCM) {
throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); throw new BadMethodCallException('Poly1305 cannot be used in GCM mode');
} }
$this->usePoly1305 = true; $this->usePoly1305 = true;
@ -607,17 +611,17 @@ abstract class SymmetricKey
* will be made. * will be made.
* *
* @param string|null $key optional * @param string|null $key optional
* @throws \LengthException if the key isn't long enough * @throws LengthException if the key isn't long enough
* @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode * @throws BadMethodCallException if Poly1305 is enabled whilst in GCM mode
*/ */
public function setPoly1305Key(string $key = null): void public function setPoly1305Key(string $key = null): void
{ {
if ($this->mode == self::MODE_GCM) { if ($this->mode == self::MODE_GCM) {
throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); throw new BadMethodCallException('Poly1305 cannot be used in GCM mode');
} }
if (!is_string($key) || strlen($key) != 32) { if (!is_string($key) || strlen($key) != 32) {
throw new \LengthException('The Poly1305 key must be 32 bytes long (256 bits)'); throw new LengthException('The Poly1305 key must be 32 bytes long (256 bits)');
} }
if (!isset(self::$poly1305Field)) { if (!isset(self::$poly1305Field)) {
@ -634,12 +638,12 @@ abstract class SymmetricKey
* *
* setNonce() is only required when gcm is used * setNonce() is only required when gcm is used
* *
* @throws \BadMethodCallException if an nonce is provided when one shouldn't be * @throws BadMethodCallException if an nonce is provided when one shouldn't be
*/ */
public function setNonce(string $nonce): void public function setNonce(string $nonce): void
{ {
if ($this->mode != self::MODE_GCM) { if ($this->mode != self::MODE_GCM) {
throw new \BadMethodCallException('Nonces are only used in GCM mode.'); throw new BadMethodCallException('Nonces are only used in GCM mode.');
} }
$this->nonce = $nonce; $this->nonce = $nonce;
@ -651,12 +655,12 @@ abstract class SymmetricKey
* *
* setAAD() is only used by gcm or in poly1305 mode * setAAD() is only used by gcm or in poly1305 mode
* *
* @throws \BadMethodCallException if mode isn't GCM or if poly1305 isn't being utilized * @throws BadMethodCallException if mode isn't GCM or if poly1305 isn't being utilized
*/ */
public function setAAD(string $aad): void public function setAAD(string $aad): void
{ {
if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { if ($this->mode != self::MODE_GCM && !$this->usePoly1305) {
throw new \BadMethodCallException('Additional authenticated data is only utilized in GCM mode or with Poly1305'); throw new BadMethodCallException('Additional authenticated data is only utilized in GCM mode or with Poly1305');
} }
$this->aad = $aad; $this->aad = $aad;
@ -756,8 +760,8 @@ abstract class SymmetricKey
* {@internal Could, but not must, extend by the child Crypt_* class} * {@internal Could, but not must, extend by the child Crypt_* class}
* *
* @param string[] ...$func_args * @param string[] ...$func_args
* @throws \LengthException if pbkdf1 is being used and the derived key length exceeds the hash length * @throws LengthException if pbkdf1 is being used and the derived key length exceeds the hash length
* @throws \RuntimeException if bcrypt is being used and a salt isn't provided * @throws RuntimeException if bcrypt is being used and a salt isn't provided
* @see Crypt/Hash.php * @see Crypt/Hash.php
*/ */
public function setPassword(string $password, string $method = 'pbkdf2', ...$func_args): bool public function setPassword(string $password, string $method = 'pbkdf2', ...$func_args): bool
@ -768,7 +772,7 @@ abstract class SymmetricKey
switch ($method) { switch ($method) {
case 'bcrypt': case 'bcrypt':
if (!isset($func_args[2])) { if (!isset($func_args[2])) {
throw new \RuntimeException('A salt must be provided for bcrypt to work'); throw new RuntimeException('A salt must be provided for bcrypt to work');
} }
$salt = $func_args[0]; $salt = $func_args[0];
@ -800,7 +804,7 @@ abstract class SymmetricKey
// Keylength // Keylength
if (isset($func_args[3])) { if (isset($func_args[3])) {
if ($func_args[3] <= 0) { if ($func_args[3] <= 0) {
throw new \LengthException('Derived key length cannot be longer 0 or less'); throw new LengthException('Derived key length cannot be longer 0 or less');
} }
$dkLen = $func_args[3]; $dkLen = $func_args[3];
} else { } else {
@ -866,7 +870,7 @@ abstract class SymmetricKey
return true; return true;
case $method == 'pbkdf1': case $method == 'pbkdf1':
if ($dkLen > $hashObj->getLengthInBytes()) { if ($dkLen > $hashObj->getLengthInBytes()) {
throw new \LengthException('Derived key length cannot be longer than the hash length'); throw new LengthException('Derived key length cannot be longer than the hash length');
} }
$t = $password . $salt; $t = $password . $salt;
for ($i = 0; $i < $count; ++$i) { for ($i = 0; $i < $count; ++$i) {
@ -1272,13 +1276,13 @@ abstract class SymmetricKey
* {@internal Could, but not must, extend by the child Crypt_* class} * {@internal Could, but not must, extend by the child Crypt_* class}
* *
* @return string $plaintext * @return string $plaintext
* @throws \LengthException if we're inside a block cipher and the ciphertext length is not a multiple of the block size * @throws LengthException if we're inside a block cipher and the ciphertext length is not a multiple of the block size
* @see self::encrypt() * @see self::encrypt()
*/ */
public function decrypt(string $ciphertext): string public function decrypt(string $ciphertext): string
{ {
if ($this->paddable && strlen($ciphertext) % $this->block_size) { if ($this->paddable && strlen($ciphertext) % $this->block_size) {
throw new \LengthException('The ciphertext length (' . strlen($ciphertext) . ') needs to be a multiple of the block size (' . $this->block_size . ')'); throw new LengthException('The ciphertext length (' . strlen($ciphertext) . ') needs to be a multiple of the block size (' . $this->block_size . ')');
} }
$this->setup(); $this->setup();
@ -1580,18 +1584,18 @@ abstract class SymmetricKey
* *
* @param int $length optional * @param int $length optional
* @return string * @return string
* @throws \LengthException if $length isn't of a sufficient length * @throws LengthException if $length isn't of a sufficient length
* @throws \RuntimeException if GCM mode isn't being used * @throws RuntimeException if GCM mode isn't being used
* @see self::encrypt() * @see self::encrypt()
*/ */
public function getTag(int $length = 16) public function getTag(int $length = 16)
{ {
if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { if ($this->mode != self::MODE_GCM && !$this->usePoly1305) {
throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); throw new BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305');
} }
if ($this->newtag === false) { if ($this->newtag === false) {
throw new \BadMethodCallException('A tag can only be returned after a round of encryption has been performed'); throw new BadMethodCallException('A tag can only be returned after a round of encryption has been performed');
} }
// the tag is 128-bits. it can't be greater than 16 bytes because that's bigger than the tag is. if it // the tag is 128-bits. it can't be greater than 16 bytes because that's bigger than the tag is. if it
@ -1600,7 +1604,7 @@ abstract class SymmetricKey
// see https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=36 // see https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=36
// for more info // for more info
if ($length < 4 || $length > 16) { if ($length < 4 || $length > 16) {
throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); throw new LengthException('The authentication tag must be between 4 and 16 bytes long');
} }
return $length == 16 ? return $length == 16 ?
@ -1613,8 +1617,8 @@ abstract class SymmetricKey
* *
* Only used in GCM mode * Only used in GCM mode
* *
* @throws \LengthException if $length isn't of a sufficient length * @throws LengthException if $length isn't of a sufficient length
* @throws \RuntimeException if GCM mode isn't being used * @throws RuntimeException if GCM mode isn't being used
* @see self::decrypt() * @see self::decrypt()
*/ */
public function setTag(string $tag): void public function setTag(string $tag): void
@ -1624,12 +1628,12 @@ abstract class SymmetricKey
} }
if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { if ($this->mode != self::MODE_GCM && !$this->usePoly1305) {
throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); throw new BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305');
} }
$length = strlen($tag); $length = strlen($tag);
if ($length < 4 || $length > 16) { if ($length < 4 || $length > 16) {
throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); throw new LengthException('The authentication tag must be between 4 and 16 bytes long');
} }
$this->oldtag = $tag; $this->oldtag = $tag;
} }
@ -1865,7 +1869,7 @@ abstract class SymmetricKey
} }
if ($this->mode == self::MODE_GCM) { if ($this->mode == self::MODE_GCM) {
throw new \BadMethodCallException('This mode does not run in continuous mode'); throw new BadMethodCallException('This mode does not run in continuous mode');
} }
$this->continuousBuffer = true; $this->continuousBuffer = true;
@ -2142,7 +2146,7 @@ abstract class SymmetricKey
* If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
* and padding will, hence forth, be enabled. * and padding will, hence forth, be enabled.
* *
* @throws \LengthException if padding is disabled and the plaintext's length is not a multiple of the block size * @throws LengthException if padding is disabled and the plaintext's length is not a multiple of the block size
* @see self::unpad() * @see self::unpad()
*/ */
protected function pad(string $text): string protected function pad(string $text): string
@ -2153,7 +2157,7 @@ abstract class SymmetricKey
if ($length % $this->block_size == 0) { if ($length % $this->block_size == 0) {
return $text; return $text;
} else { } else {
throw new \LengthException("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size}). Try enabling padding."); throw new LengthException("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size}). Try enabling padding.");
} }
} }
@ -2168,7 +2172,7 @@ abstract class SymmetricKey
* If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
* and false will be returned. * and false will be returned.
* *
* @throws \LengthException if the ciphertext's length is not a multiple of the block size * @throws LengthException if the ciphertext's length is not a multiple of the block size
* @see self::pad() * @see self::pad()
*/ */
protected function unpad(string $text): string protected function unpad(string $text): string
@ -2807,7 +2811,7 @@ abstract class SymmetricKey
if ($bindedClosure instanceof \Closure) { if ($bindedClosure instanceof \Closure) {
return $bindedClosure; return $bindedClosure;
} }
throw new \LogicException('\Closure::bind() failed.'); throw new LogicException('\Closure::bind() failed.');
} }
/** /**

View File

@ -44,6 +44,7 @@ namespace phpseclib3\Crypt;
use phpseclib3\Crypt\Common\BlockCipher; use phpseclib3\Crypt\Common\BlockCipher;
use phpseclib3\Exception\BadModeException; use phpseclib3\Exception\BadModeException;
use phpseclib3\Exception\LengthException;
/** /**
* Pure-PHP implementation of DES. * Pure-PHP implementation of DES.
@ -597,7 +598,7 @@ class DES extends BlockCipher
public function setKey(string $key): void public function setKey(string $key): void
{ {
if (!($this instanceof TripleDES) && strlen($key) != 8) { if (!($this instanceof TripleDES) && strlen($key) != 8) {
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of size 8 are supported'); throw new LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of size 8 are supported');
} }
// Sets the key // Sets the key

View File

@ -30,6 +30,7 @@ use phpseclib3\Crypt\Common\AsymmetricKey;
use phpseclib3\Crypt\DH\Parameters; use phpseclib3\Crypt\DH\Parameters;
use phpseclib3\Crypt\DH\PrivateKey; use phpseclib3\Crypt\DH\PrivateKey;
use phpseclib3\Crypt\DH\PublicKey; use phpseclib3\Crypt\DH\PublicKey;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Exception\NoKeyLoadedException; use phpseclib3\Exception\NoKeyLoadedException;
use phpseclib3\Exception\UnsupportedOperationException; use phpseclib3\Exception\UnsupportedOperationException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -51,7 +52,7 @@ abstract class DH extends AsymmetricKey
/** /**
* DH prime * DH prime
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected $prime; protected $prime;
@ -60,7 +61,7 @@ abstract class DH extends AsymmetricKey
* *
* Prime divisor of p-1 * Prime divisor of p-1
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected $base; protected $base;
@ -84,7 +85,7 @@ abstract class DH extends AsymmetricKey
$params = new Parameters(); $params = new Parameters();
if (count($args) == 2 && $args[0] instanceof BigInteger && $args[1] instanceof BigInteger) { if (count($args) == 2 && $args[0] instanceof BigInteger && $args[1] instanceof BigInteger) {
//if (!$args[0]->isPrime()) { //if (!$args[0]->isPrime()) {
// throw new \InvalidArgumentException('The first parameter should be a prime number'); // throw new \phpseclib3\Exception\InvalidArgumentException('The first parameter should be a prime number');
//} //}
$params->prime = $args[0]; $params->prime = $args[0];
$params->base = $args[1]; $params->base = $args[1];
@ -94,7 +95,7 @@ abstract class DH extends AsymmetricKey
$params->base = new BigInteger(2); $params->base = new BigInteger(2);
return $params; return $params;
} elseif (count($args) != 1 || !is_string($args[0])) { } elseif (count($args) != 1 || !is_string($args[0])) {
throw new \InvalidArgumentException('Valid parameters are either: two BigInteger\'s (prime and base), a single integer (the length of the prime; base is assumed to be 2) or a string'); throw new InvalidArgumentException('Valid parameters are either: two BigInteger\'s (prime and base), a single integer (the length of the prime; base is assumed to be 2) or a string');
} }
switch ($args[0]) { switch ($args[0]) {
// see http://tools.ietf.org/html/rfc2409#section-6.2 and // see http://tools.ietf.org/html/rfc2409#section-6.2 and
@ -214,7 +215,7 @@ abstract class DH extends AsymmetricKey
'9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF'; '9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF';
break; break;
default: default:
throw new \InvalidArgumentException('Invalid named prime provided'); throw new InvalidArgumentException('Invalid named prime provided');
} }
$params->prime = new BigInteger($prime, 16); $params->prime = new BigInteger($prime, 16);
@ -269,7 +270,7 @@ abstract class DH extends AsymmetricKey
switch (true) { switch (true) {
case $public instanceof PublicKey: case $public instanceof PublicKey:
if (!$private->prime->equals($public->prime) || !$private->base->equals($public->base)) { if (!$private->prime->equals($public->prime) || !$private->base->equals($public->base)) {
throw new \InvalidArgumentException('The public and private key do not share the same prime and / or base numbers'); throw new InvalidArgumentException('The public and private key do not share the same prime and / or base numbers');
} }
return $public->publicKey->powMod($private->privateKey, $private->prime)->toBytes(true); return $public->publicKey->powMod($private->privateKey, $private->prime)->toBytes(true);
case is_string($public): case is_string($public):
@ -278,7 +279,7 @@ abstract class DH extends AsymmetricKey
case $public instanceof BigInteger: case $public instanceof BigInteger:
return $public->powMod($private->privateKey, $private->prime)->toBytes(true); return $public->powMod($private->privateKey, $private->prime)->toBytes(true);
default: default:
throw new \InvalidArgumentException('$public needs to be an instance of DH\PublicKey, a BigInteger or a string'); throw new InvalidArgumentException('$public needs to be an instance of DH\PublicKey, a BigInteger or a string');
} }
} }
@ -305,7 +306,7 @@ abstract class DH extends AsymmetricKey
*/ */
return $secret; return $secret;
default: default:
throw new \InvalidArgumentException('$public needs to be an instance of EC\PublicKey or a string (an encoded coordinate)'); throw new InvalidArgumentException('$public needs to be an instance of EC\PublicKey or a string (an encoded coordinate)');
} }
} }
} }

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace phpseclib3\Crypt\DH\Formats\Keys; namespace phpseclib3\Crypt\DH\Formats\Keys;
use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\File\ASN1; use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1\Maps;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -46,12 +47,12 @@ abstract class PKCS1 extends Progenitor
$decoded = ASN1::decodeBER($key); $decoded = ASN1::decodeBER($key);
if (!$decoded) { if (!$decoded) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
$components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP); $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP);
if (!is_array($components)) { if (!is_array($components)) {
throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); throw new RuntimeException('Unable to perform ASN1 mapping on parameters');
} }
return $components; return $components;

View File

@ -23,6 +23,8 @@ namespace phpseclib3\Crypt\DH\Formats\Keys;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\File\ASN1; use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1\Maps;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -63,7 +65,7 @@ abstract class PKCS8 extends Progenitor
public static function load($key, ?string $password = null): array public static function load($key, ?string $password = null): array
{ {
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
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 = str_contains($key, 'PUBLIC'); $isPublic = str_contains($key, 'PUBLIC');
@ -74,18 +76,18 @@ abstract class PKCS8 extends Progenitor
switch (true) { switch (true) {
case !$isPublic && $type == 'publicKey': case !$isPublic && $type == 'publicKey':
throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key'); throw new UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key');
case $isPublic && $type == 'privateKey': case $isPublic && $type == 'privateKey':
throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); throw new UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key');
} }
$decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element);
if (empty($decoded)) { if (empty($decoded)) {
throw new \RuntimeException('Unable to decode BER of parameters'); throw new RuntimeException('Unable to decode BER of parameters');
} }
$components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP); $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP);
if (!is_array($components)) { if (!is_array($components)) {
throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); throw new RuntimeException('Unable to perform ASN1 mapping on parameters');
} }
$decoded = ASN1::decodeBER($key[$type]); $decoded = ASN1::decodeBER($key[$type]);
@ -93,7 +95,7 @@ abstract class PKCS8 extends Progenitor
case !isset($decoded): case !isset($decoded):
case !isset($decoded[0]['content']): case !isset($decoded[0]['content']):
case !$decoded[0]['content'] instanceof BigInteger: case !$decoded[0]['content'] instanceof BigInteger:
throw new \RuntimeException('Unable to decode BER of parameters'); throw new RuntimeException('Unable to decode BER of parameters');
} }
$components[$type] = $decoded[0]['content']; $components[$type] = $decoded[0]['content'];

View File

@ -15,6 +15,7 @@ namespace phpseclib3\Crypt\DH;
use phpseclib3\Crypt\Common; use phpseclib3\Crypt\Common;
use phpseclib3\Crypt\DH; use phpseclib3\Crypt\DH;
use phpseclib3\Math\BigInteger;
/** /**
* DH Private Key * DH Private Key
@ -28,14 +29,14 @@ class PrivateKey extends DH
/** /**
* Private Key * Private Key
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected $privateKey; protected $privateKey;
/** /**
* Public Key * Public Key
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected $publicKey; protected $publicKey;

View File

@ -36,6 +36,7 @@ use phpseclib3\Crypt\DSA\Parameters;
use phpseclib3\Crypt\DSA\PrivateKey; use phpseclib3\Crypt\DSA\PrivateKey;
use phpseclib3\Crypt\DSA\PublicKey; use phpseclib3\Crypt\DSA\PublicKey;
use phpseclib3\Exception\InsufficientSetupException; use phpseclib3\Exception\InsufficientSetupException;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
/** /**
@ -55,7 +56,7 @@ abstract class DSA extends AsymmetricKey
/** /**
* DSA Prime P * DSA Prime P
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected $p; protected $p;
@ -64,21 +65,21 @@ abstract class DSA extends AsymmetricKey
* *
* Prime divisor of p-1 * Prime divisor of p-1
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected $q; protected $q;
/** /**
* DSA Group Generator G * DSA Group Generator G
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected $g; protected $g;
/** /**
* DSA public key value y * DSA public key value y
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected $y; protected $y;
@ -99,7 +100,7 @@ abstract class DSA extends AsymmetricKey
/** /**
* Create DSA parameters * Create DSA parameters
* *
* @return \phpseclib3\Crypt\DSA|bool * @return DSA|bool
*/ */
public static function createParameters(int $L = 2048, int $N = 224) public static function createParameters(int $L = 2048, int $N = 224)
{ {
@ -127,7 +128,7 @@ abstract class DSA extends AsymmetricKey
case $L == 3072 && $N == 256: case $L == 3072 && $N == 256:
break; break;
default: default:
throw new \InvalidArgumentException('Invalid values for N and L'); throw new InvalidArgumentException('Invalid values for N and L');
} }
$two = new BigInteger(2); $two = new BigInteger(2);

View File

@ -19,6 +19,8 @@ namespace phpseclib3\Crypt\DSA\Formats\Keys;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
/** /**
@ -47,7 +49,7 @@ abstract class OpenSSH extends Progenitor
if (isset($parsed['paddedKey'])) { if (isset($parsed['paddedKey'])) {
[$type] = Strings::unpackSSH2('s', $parsed['paddedKey']); [$type] = Strings::unpackSSH2('s', $parsed['paddedKey']);
if ($type != $parsed['type']) { if ($type != $parsed['type']) {
throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); throw new RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])");
} }
[$p, $q, $g, $y, $x, $comment] = Strings::unpackSSH2('i5s', $parsed['paddedKey']); [$p, $q, $g, $y, $x, $comment] = Strings::unpackSSH2('i5s', $parsed['paddedKey']);
@ -70,7 +72,7 @@ abstract class OpenSSH extends Progenitor
public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = []): string public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = []): string
{ {
if ($q->getLength() != 160) { if ($q->getLength() != 160) {
throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); throw new InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160');
} }
// from <http://tools.ietf.org/html/rfc4253#page-15>: // from <http://tools.ietf.org/html/rfc4253#page-15>:

View File

@ -31,6 +31,7 @@ namespace phpseclib3\Crypt\DSA\Formats\Keys;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\File\ASN1; use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1\Maps;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -53,7 +54,7 @@ abstract class PKCS1 extends Progenitor
$decoded = ASN1::decodeBER($key); $decoded = ASN1::decodeBER($key);
if (!$decoded) { if (!$decoded) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
$key = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP); $key = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP);
@ -71,7 +72,7 @@ abstract class PKCS1 extends Progenitor
return $key; return $key;
} }
throw new \RuntimeException('Unable to perform ASN1 mapping'); throw new RuntimeException('Unable to perform ASN1 mapping');
} }
/** /**

View File

@ -27,6 +27,8 @@ namespace phpseclib3\Crypt\DSA\Formats\Keys;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\File\ASN1; use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1\Maps;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -67,7 +69,7 @@ abstract class PKCS8 extends Progenitor
public static function load($key, ?string $password = null): array public static function load($key, ?string $password = null): array
{ {
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
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 = str_contains($key, 'PUBLIC'); $isPublic = str_contains($key, 'PUBLIC');
@ -78,29 +80,29 @@ abstract class PKCS8 extends Progenitor
switch (true) { switch (true) {
case !$isPublic && $type == 'publicKey': case !$isPublic && $type == 'publicKey':
throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key'); throw new UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key');
case $isPublic && $type == 'privateKey': case $isPublic && $type == 'privateKey':
throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); throw new UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key');
} }
$decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element);
if (!$decoded) { if (!$decoded) {
throw new \RuntimeException('Unable to decode BER of parameters'); throw new RuntimeException('Unable to decode BER of parameters');
} }
$components = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP); $components = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP);
if (!is_array($components)) { if (!is_array($components)) {
throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); throw new RuntimeException('Unable to perform ASN1 mapping on parameters');
} }
$decoded = ASN1::decodeBER($key[$type]); $decoded = ASN1::decodeBER($key[$type]);
if (empty($decoded)) { if (empty($decoded)) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
$var = $type == 'privateKey' ? 'x' : 'y'; $var = $type == 'privateKey' ? 'x' : 'y';
$components[$var] = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP); $components[$var] = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP);
if (!$components[$var] instanceof BigInteger) { if (!$components[$var] instanceof BigInteger) {
throw new \RuntimeException('Unable to perform ASN1 mapping'); throw new RuntimeException('Unable to perform ASN1 mapping');
} }
if (isset($key['meta'])) { if (isset($key['meta'])) {

View File

@ -22,6 +22,7 @@ namespace phpseclib3\Crypt\DSA\Formats\Keys;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
/** /**
@ -73,7 +74,7 @@ abstract class PuTTY extends Progenitor
public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, ?string $password = null, array $options = []): string public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, ?string $password = null, array $options = []): string
{ {
if ($q->getLength() != 160) { if ($q->getLength() != 160) {
throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); throw new InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160');
} }
$public = Strings::packSSH2('iiii', $p, $q, $g, $y); $public = Strings::packSSH2('iiii', $p, $q, $g, $y);
@ -88,7 +89,7 @@ abstract class PuTTY extends Progenitor
public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y): string public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y): string
{ {
if ($q->getLength() != 160) { if ($q->getLength() != 160) {
throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); throw new InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160');
} }
return self::wrapPublicKey(Strings::packSSH2('iiii', $p, $q, $g, $y), 'ssh-dsa'); return self::wrapPublicKey(Strings::packSSH2('iiii', $p, $q, $g, $y), 'ssh-dsa');

View File

@ -17,6 +17,7 @@ declare(strict_types=1);
namespace phpseclib3\Crypt\DSA\Formats\Keys; namespace phpseclib3\Crypt\DSA\Formats\Keys;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
/** /**
@ -34,7 +35,7 @@ abstract class Raw
public static function load($key, ?string $password = null): array public static function load($key, ?string $password = null): array
{ {
if (!is_array($key)) { if (!is_array($key)) {
throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); throw new UnexpectedValueException('Key should be a array - not a ' . gettype($key));
} }
switch (true) { switch (true) {
@ -45,7 +46,7 @@ abstract class Raw
case !isset($key['x']) && !isset($key['y']): case !isset($key['x']) && !isset($key['y']):
case isset($key['x']) && !$key['x'] instanceof BigInteger: case isset($key['x']) && !$key['x'] instanceof BigInteger:
case isset($key['y']) && !$key['y'] instanceof BigInteger: case isset($key['y']) && !$key['y'] instanceof BigInteger:
throw new \UnexpectedValueException('Key appears to be malformed'); throw new UnexpectedValueException('Key appears to be malformed');
} }
$options = ['p' => 1, 'q' => 1, 'g' => 1, 'x' => 1, 'y' => 1]; $options = ['p' => 1, 'q' => 1, 'g' => 1, 'x' => 1, 'y' => 1];

View File

@ -23,6 +23,7 @@ namespace phpseclib3\Crypt\DSA\Formats\Keys;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
/** /**
@ -38,7 +39,7 @@ abstract class XML
public static function load(string $key, ?string $password = null): array public static function load(string $key, ?string $password = null): array
{ {
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
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 (!class_exists('DOMDocument')) { if (!class_exists('DOMDocument')) {
@ -53,7 +54,7 @@ abstract class XML
} }
if (!$dom->loadXML($key)) { if (!$dom->loadXML($key)) {
libxml_use_internal_errors($use_errors); libxml_use_internal_errors($use_errors);
throw new \UnexpectedValueException('Key does not appear to contain XML'); throw new UnexpectedValueException('Key does not appear to contain XML');
} }
$xpath = new \DOMXPath($dom); $xpath = new \DOMXPath($dom);
$keys = ['p', 'q', 'g', 'y', 'j', 'seed', 'pgencounter']; $keys = ['p', 'q', 'g', 'y', 'j', 'seed', 'pgencounter'];
@ -94,7 +95,7 @@ abstract class XML
libxml_use_internal_errors($use_errors); libxml_use_internal_errors($use_errors);
if (!isset($components['y'])) { if (!isset($components['y'])) {
throw new \UnexpectedValueException('Key is missing y component'); throw new UnexpectedValueException('Key is missing y component');
} }
switch (true) { switch (true) {

View File

@ -30,7 +30,7 @@ class PrivateKey extends DSA implements Common\PrivateKey
/** /**
* DSA secret exponent x * DSA secret exponent x
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected $x; protected $x;

View File

@ -32,6 +32,7 @@ declare(strict_types=1);
namespace phpseclib3\Crypt; namespace phpseclib3\Crypt;
use phpseclib3\Crypt\Common\AsymmetricKey; use phpseclib3\Crypt\Common\AsymmetricKey;
use phpseclib3\Crypt\EC\BaseCurves\Base;
use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve;
use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve;
use phpseclib3\Crypt\EC\Curves\Curve25519; use phpseclib3\Crypt\EC\Curves\Curve25519;
@ -41,6 +42,8 @@ use phpseclib3\Crypt\EC\Formats\Keys\PKCS1;
use phpseclib3\Crypt\EC\Parameters; use phpseclib3\Crypt\EC\Parameters;
use phpseclib3\Crypt\EC\PrivateKey; use phpseclib3\Crypt\EC\PrivateKey;
use phpseclib3\Crypt\EC\PublicKey; use phpseclib3\Crypt\EC\PublicKey;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Exception\LengthException;
use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedAlgorithmException;
use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\Exception\UnsupportedCurveException;
use phpseclib3\Exception\UnsupportedOperationException; use phpseclib3\Exception\UnsupportedOperationException;
@ -72,7 +75,7 @@ abstract class EC extends AsymmetricKey
/** /**
* Curve * Curve
* *
* @var \phpseclib3\Crypt\EC\BaseCurves\Base * @var Base
*/ */
protected $curve; protected $curve;
@ -102,7 +105,7 @@ abstract class EC extends AsymmetricKey
* *
* Used for deterministic ECDSA * Used for deterministic ECDSA
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected $q; protected $q;
@ -114,7 +117,7 @@ abstract class EC extends AsymmetricKey
* public key. But the x is different depending on which side of the equal sign * public key. But the x is different depending on which side of the equal sign
* you're on. It's less ambiguous if you do dA * base point = (x, y)-coordinate. * you're on. It's less ambiguous if you do dA * base point = (x, y)-coordinate.
* *
* @var \phpseclib3\Math\BigInteger * @var BigInteger
*/ */
protected $x; protected $x;
@ -411,10 +414,10 @@ abstract class EC extends AsymmetricKey
return $new; return $new;
} }
if (!is_string($context)) { if (!is_string($context)) {
throw new \InvalidArgumentException('setContext expects a string'); throw new InvalidArgumentException('setContext expects a string');
} }
if (strlen($context) > 255) { if (strlen($context) > 255) {
throw new \LengthException('The context is supposed to be, at most, 255 bytes long'); throw new LengthException('The context is supposed to be, at most, 255 bytes long');
} }
$new->context = $context; $new->context = $context;
return $new; return $new;

View File

@ -15,7 +15,10 @@ declare(strict_types=1);
namespace phpseclib3\Crypt\EC\BaseCurves; namespace phpseclib3\Crypt\EC\BaseCurves;
use phpseclib3\Exception\RangeException;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\FiniteField\Integer;
/** /**
* Base * Base
@ -34,7 +37,7 @@ abstract class Base
/** /**
* Finite Field Integer factory * Finite Field Integer factory
* *
* @var \phpseclib3\Math\FiniteField\Integer * @var Integer
*/ */
protected $factory; protected $factory;
@ -127,10 +130,10 @@ abstract class Base
} }
if (!isset($this->order)) { if (!isset($this->order)) {
throw new \RuntimeException('setOrder needs to be called before this method'); throw new RuntimeException('setOrder needs to be called before this method');
} }
if ($x->compare($this->order) > 0 || $x->compare($zero) <= 0) { if ($x->compare($this->order) > 0 || $x->compare($zero) <= 0) {
throw new \RangeException('x must be between 1 and the order of the curve'); throw new RangeException('x must be between 1 and the order of the curve');
} }
} }

View File

@ -23,9 +23,12 @@ declare(strict_types=1);
namespace phpseclib3\Crypt\EC\BaseCurves; namespace phpseclib3\Crypt\EC\BaseCurves;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\BinaryField; use phpseclib3\Math\BinaryField;
use phpseclib3\Math\BinaryField\Integer as BinaryInteger; use phpseclib3\Math\BinaryField\Integer as BinaryInteger;
use phpseclib3\Math\PrimeField\Integer;
/** /**
* Curves over y^2 + x*y = x^3 + a*x^2 + b * Curves over y^2 + x*y = x^3 + a*x^2 + b
@ -37,7 +40,7 @@ class Binary extends Base
/** /**
* Binary Field Integer factory * Binary Field Integer factory
* *
* @var \phpseclib3\Math\BinaryField * @var BinaryField
*/ */
protected $factory; protected $factory;
@ -100,7 +103,7 @@ class Binary extends Base
public function setCoefficients(string $a, string $b): void public function setCoefficients(string $a, string $b): void
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
$this->a = $this->factory->newInteger(pack('H*', $a)); $this->a = $this->factory->newInteger(pack('H*', $a));
$this->b = $this->factory->newInteger(pack('H*', $b)); $this->b = $this->factory->newInteger(pack('H*', $b));
@ -116,12 +119,12 @@ class Binary extends Base
{ {
switch (true) { switch (true) {
case !is_string($x) && !$x instanceof BinaryInteger: case !is_string($x) && !$x instanceof BinaryInteger:
throw new \UnexpectedValueException('Argument 1 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer'); throw new UnexpectedValueException('Argument 1 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer');
case !is_string($y) && !$y instanceof BinaryInteger: case !is_string($y) && !$y instanceof BinaryInteger:
throw new \UnexpectedValueException('Argument 2 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer'); throw new UnexpectedValueException('Argument 2 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer');
} }
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
$this->p = [ $this->p = [
is_string($x) ? $this->factory->newInteger(pack('H*', $x)) : $x, is_string($x) ? $this->factory->newInteger(pack('H*', $x)) : $x,
@ -137,11 +140,11 @@ class Binary extends Base
public function getBasePoint() public function getBasePoint()
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
/* /*
if (!isset($this->p)) { if (!isset($this->p)) {
throw new \RuntimeException('setBasePoint needs to be called before this method'); throw new \phpseclib3\Exception\RuntimeException('setBasePoint needs to be called before this method');
} }
*/ */
return $this->p; return $this->p;
@ -155,7 +158,7 @@ class Binary extends Base
public function addPoint(array $p, array $q): array public function addPoint(array $p, array $q): array
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
if (!count($p) || !count($q)) { if (!count($p) || !count($q)) {
@ -169,7 +172,7 @@ class Binary extends Base
} }
if (!isset($p[2]) || !isset($q[2])) { if (!isset($p[2]) || !isset($q[2])) {
throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); throw new RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa');
} }
if ($p[0]->equals($q[0])) { if ($p[0]->equals($q[0])) {
@ -228,7 +231,7 @@ class Binary extends Base
public function doublePoint(array $p): array public function doublePoint(array $p): array
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
if (!count($p)) { if (!count($p)) {
@ -236,7 +239,7 @@ class Binary extends Base
} }
if (!isset($p[2])) { if (!isset($p[2])) {
throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); throw new RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa');
} }
// formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html
@ -279,7 +282,7 @@ class Binary extends Base
*/ */
public function derivePoint($m): array public function derivePoint($m): array
{ {
throw new \RuntimeException('Point compression on binary finite field elliptic curves is not supported'); throw new RuntimeException('Point compression on binary finite field elliptic curves is not supported');
} }
/** /**
@ -310,7 +313,7 @@ class Binary extends Base
/** /**
* Returns the a coefficient * Returns the a coefficient
* *
* @return \phpseclib3\Math\PrimeField\Integer * @return Integer
*/ */
public function getA() public function getA()
{ {
@ -320,7 +323,7 @@ class Binary extends Base
/** /**
* Returns the a coefficient * Returns the a coefficient
* *
* @return \phpseclib3\Math\PrimeField\Integer * @return Integer
*/ */
public function getB() public function getB()
{ {
@ -334,7 +337,7 @@ class Binary extends Base
* To convert a Jacobian Coordinate to an Affine Point * To convert a Jacobian Coordinate to an Affine Point
* you do (x / z^2, y / z^3) * you do (x / z^2, y / z^3)
* *
* @return \phpseclib3\Math\PrimeField\Integer[] * @return Integer[]
*/ */
public function convertToAffine(array $p): array public function convertToAffine(array $p): array
{ {
@ -353,7 +356,7 @@ class Binary extends Base
/** /**
* Converts an affine point to a jacobian coordinate * Converts an affine point to a jacobian coordinate
* *
* @return \phpseclib3\Math\PrimeField\Integer[] * @return Integer[]
*/ */
public function convertToInternal(array $p): array public function convertToInternal(array $p): array
{ {

View File

@ -27,6 +27,8 @@ declare(strict_types=1);
namespace phpseclib3\Crypt\EC\BaseCurves; namespace phpseclib3\Crypt\EC\BaseCurves;
use phpseclib3\Crypt\EC\Curves\Curve25519; use phpseclib3\Crypt\EC\Curves\Curve25519;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\PrimeField; use phpseclib3\Math\PrimeField;
use phpseclib3\Math\PrimeField\Integer as PrimeInteger; use phpseclib3\Math\PrimeField\Integer as PrimeInteger;
@ -41,7 +43,7 @@ class Montgomery extends Base
/** /**
* Prime Field Integer factory * Prime Field Integer factory
* *
* @var \phpseclib3\Math\PrimeField * @var PrimeField
*/ */
protected $factory; protected $factory;
@ -111,7 +113,7 @@ class Montgomery extends Base
public function setCoefficients(BigInteger $a): void public function setCoefficients(BigInteger $a): void
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
$this->a = $this->factory->newInteger($a); $this->a = $this->factory->newInteger($a);
$two = $this->factory->newInteger(new BigInteger(2)); $two = $this->factory->newInteger(new BigInteger(2));
@ -130,12 +132,12 @@ class Montgomery extends Base
{ {
switch (true) { switch (true) {
case !$x instanceof BigInteger && !$x instanceof PrimeInteger: case !$x instanceof BigInteger && !$x instanceof PrimeInteger:
throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); throw new UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer');
case !$y instanceof BigInteger && !$y instanceof PrimeInteger: case !$y instanceof BigInteger && !$y instanceof PrimeInteger:
throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); throw new UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer');
} }
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
$this->p = [ $this->p = [
$x instanceof BigInteger ? $this->factory->newInteger($x) : $x, $x instanceof BigInteger ? $this->factory->newInteger($x) : $x,
@ -151,11 +153,11 @@ class Montgomery extends Base
public function getBasePoint() public function getBasePoint()
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
/* /*
if (!isset($this->p)) { if (!isset($this->p)) {
throw new \RuntimeException('setBasePoint needs to be called before this method'); throw new \phpseclib3\Exception\RuntimeException('setBasePoint needs to be called before this method');
} }
*/ */
return $this->p; return $this->p;
@ -171,7 +173,7 @@ class Montgomery extends Base
private function doubleAndAddPoint(array $p, array $q, PrimeInteger $x1): array private function doubleAndAddPoint(array $p, array $q, PrimeInteger $x1): array
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
if (!count($p) || !count($q)) { if (!count($p) || !count($q)) {
@ -179,7 +181,7 @@ class Montgomery extends Base
} }
if (!isset($p[1])) { if (!isset($p[1])) {
throw new \RuntimeException('Affine coordinates need to be manually converted to XZ coordinates'); throw new RuntimeException('Affine coordinates need to be manually converted to XZ coordinates');
} }
[$x2, $z2] = $p; [$x2, $z2] = $p;
@ -246,7 +248,7 @@ class Montgomery extends Base
* *
* x=X/Z * x=X/Z
* *
* @return \phpseclib3\Math\PrimeField\Integer[] * @return PrimeInteger[]
*/ */
public function convertToInternal(array $p): array public function convertToInternal(array $p): array
{ {
@ -266,7 +268,7 @@ class Montgomery extends Base
/** /**
* Returns the affine point * Returns the affine point
* *
* @return \phpseclib3\Math\PrimeField\Integer[] * @return PrimeInteger[]
*/ */
public function convertToAffine(array $p): array public function convertToAffine(array $p): array
{ {

View File

@ -24,10 +24,13 @@ declare(strict_types=1);
namespace phpseclib3\Crypt\EC\BaseCurves; namespace phpseclib3\Crypt\EC\BaseCurves;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\Common\FiniteField\Integer; use phpseclib3\Math\Common\FiniteField\Integer;
use phpseclib3\Math\PrimeField; use phpseclib3\Math\PrimeField;
use phpseclib3\Math\PrimeField\Integer as PrimeInteger; use phpseclib3\Math\PrimeField\Integer as PrimeInteger;
use phpseclib3\Math\PrimeFields;
/** /**
* Curves over y^2 = x^3 + a*x + b * Curves over y^2 = x^3 + a*x + b
@ -39,7 +42,7 @@ class Prime extends Base
/** /**
* Prime Field Integer factory * Prime Field Integer factory
* *
* @var \phpseclib3\Math\PrimeFields * @var PrimeFields
*/ */
protected $factory; protected $factory;
@ -134,7 +137,7 @@ class Prime extends Base
public function setCoefficients(BigInteger $a, BigInteger $b): void public function setCoefficients(BigInteger $a, BigInteger $b): void
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
$this->a = $this->factory->newInteger($a); $this->a = $this->factory->newInteger($a);
$this->b = $this->factory->newInteger($b); $this->b = $this->factory->newInteger($b);
@ -150,12 +153,12 @@ class Prime extends Base
{ {
switch (true) { switch (true) {
case !$x instanceof BigInteger && !$x instanceof PrimeInteger: case !$x instanceof BigInteger && !$x instanceof PrimeInteger:
throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); throw new UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer');
case !$y instanceof BigInteger && !$y instanceof PrimeInteger: case !$y instanceof BigInteger && !$y instanceof PrimeInteger:
throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); throw new UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer');
} }
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
$this->p = [ $this->p = [
$x instanceof BigInteger ? $this->factory->newInteger($x) : $x, $x instanceof BigInteger ? $this->factory->newInteger($x) : $x,
@ -171,11 +174,11 @@ class Prime extends Base
public function getBasePoint() public function getBasePoint()
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
/* /*
if (!isset($this->p)) { if (!isset($this->p)) {
throw new \RuntimeException('setBasePoint needs to be called before this method'); throw new \phpseclib3\Exception\RuntimeException('setBasePoint needs to be called before this method');
} }
*/ */
return $this->p; return $this->p;
@ -296,7 +299,7 @@ class Prime extends Base
public function addPoint(array $p, array $q): array public function addPoint(array $p, array $q): array
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
if (!count($p) || !count($q)) { if (!count($p) || !count($q)) {
@ -324,7 +327,7 @@ class Prime extends Base
} }
if (isset($p[2]) || isset($q[2])) { if (isset($p[2]) || isset($q[2])) {
throw new \RuntimeException('Affine coordinates need to be manually converted to Jacobi coordinates or vice versa'); throw new RuntimeException('Affine coordinates need to be manually converted to Jacobi coordinates or vice versa');
} }
if ($p[0]->equals($q[0])) { if ($p[0]->equals($q[0])) {
@ -408,7 +411,7 @@ class Prime extends Base
public function doublePoint(array $p): array public function doublePoint(array $p): array
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
if (!count($p)) { if (!count($p)) {
@ -449,14 +452,14 @@ class Prime extends Base
$ypn = true; $ypn = true;
break; break;
default: default:
throw new \RuntimeException('Coordinate not in recognized format'); throw new RuntimeException('Coordinate not in recognized format');
} }
$temp = $xp->multiply($this->a); $temp = $xp->multiply($this->a);
$temp = $xp->multiply($xp)->multiply($xp)->add($temp); $temp = $xp->multiply($xp)->multiply($xp)->add($temp);
$temp = $temp->add($this->b); $temp = $temp->add($this->b);
$b = $temp->squareRoot(); $b = $temp->squareRoot();
if (!$b) { if (!$b) {
throw new \RuntimeException('Unable to derive Y coordinate'); throw new RuntimeException('Unable to derive Y coordinate');
} }
$bn = $b->isOdd(); $bn = $b->isOdd();
$yp = $ypn == $bn ? $b : $b->negate(); $yp = $ypn == $bn ? $b : $b->negate();
@ -490,7 +493,7 @@ class Prime extends Base
/** /**
* Returns the a coefficient * Returns the a coefficient
* *
* @return \phpseclib3\Math\PrimeField\Integer * @return PrimeInteger
*/ */
public function getA() public function getA()
{ {
@ -500,7 +503,7 @@ class Prime extends Base
/** /**
* Returns the a coefficient * Returns the a coefficient
* *
* @return \phpseclib3\Math\PrimeField\Integer * @return PrimeInteger
*/ */
public function getB() public function getB()
{ {
@ -748,7 +751,7 @@ class Prime extends Base
* To convert a Jacobian Coordinate to an Affine Point * To convert a Jacobian Coordinate to an Affine Point
* you do (x / z^2, y / z^3) * you do (x / z^2, y / z^3)
* *
* @return \phpseclib3\Math\PrimeField\Integer[] * @return PrimeInteger[]
*/ */
public function convertToAffine(array $p): array public function convertToAffine(array $p): array
{ {
@ -767,7 +770,7 @@ class Prime extends Base
/** /**
* Converts an affine point to a jacobian coordinate * Converts an affine point to a jacobian coordinate
* *
* @return \phpseclib3\Math\PrimeField\Integer[] * @return PrimeInteger[]
*/ */
public function convertToInternal(array $p): array public function convertToInternal(array $p): array
{ {

View File

@ -28,6 +28,8 @@ declare(strict_types=1);
namespace phpseclib3\Crypt\EC\BaseCurves; namespace phpseclib3\Crypt\EC\BaseCurves;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\PrimeField; use phpseclib3\Math\PrimeField;
use phpseclib3\Math\PrimeField\Integer as PrimeInteger; use phpseclib3\Math\PrimeField\Integer as PrimeInteger;
@ -106,7 +108,7 @@ class TwistedEdwards extends Base
public function setCoefficients(BigInteger $a, BigInteger $d): void public function setCoefficients(BigInteger $a, BigInteger $d): void
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
$this->a = $this->factory->newInteger($a); $this->a = $this->factory->newInteger($a);
$this->d = $this->factory->newInteger($d); $this->d = $this->factory->newInteger($d);
@ -119,12 +121,12 @@ class TwistedEdwards extends Base
{ {
switch (true) { switch (true) {
case !$x instanceof BigInteger && !$x instanceof PrimeInteger: case !$x instanceof BigInteger && !$x instanceof PrimeInteger:
throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); throw new UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer');
case !$y instanceof BigInteger && !$y instanceof PrimeInteger: case !$y instanceof BigInteger && !$y instanceof PrimeInteger:
throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); throw new UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer');
} }
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
$this->p = [ $this->p = [
$x instanceof BigInteger ? $this->factory->newInteger($x) : $x, $x instanceof BigInteger ? $this->factory->newInteger($x) : $x,
@ -135,7 +137,7 @@ class TwistedEdwards extends Base
/** /**
* Returns the a coefficient * Returns the a coefficient
* *
* @return \phpseclib3\Math\PrimeField\Integer * @return PrimeInteger
*/ */
public function getA() public function getA()
{ {
@ -145,7 +147,7 @@ class TwistedEdwards extends Base
/** /**
* Returns the a coefficient * Returns the a coefficient
* *
* @return \phpseclib3\Math\PrimeField\Integer * @return PrimeInteger
*/ */
public function getD() public function getD()
{ {
@ -158,11 +160,11 @@ class TwistedEdwards extends Base
public function getBasePoint(): array public function getBasePoint(): array
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
/* /*
if (!isset($this->p)) { if (!isset($this->p)) {
throw new \RuntimeException('setBasePoint needs to be called before this method'); throw new \phpseclib3\Exception\RuntimeException('setBasePoint needs to be called before this method');
} }
*/ */
return $this->p; return $this->p;
@ -171,7 +173,7 @@ class TwistedEdwards extends Base
/** /**
* Returns the affine point * Returns the affine point
* *
* @return \phpseclib3\Math\PrimeField\Integer[] * @return PrimeInteger[]
*/ */
public function convertToAffine(array $p): array public function convertToAffine(array $p): array
{ {

View File

@ -16,6 +16,7 @@ declare(strict_types=1);
namespace phpseclib3\Crypt\EC\Curves; namespace phpseclib3\Crypt\EC\Curves;
use phpseclib3\Crypt\EC\BaseCurves\Montgomery; use phpseclib3\Crypt\EC\BaseCurves\Montgomery;
use phpseclib3\Exception\RangeException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
class Curve25519 extends Montgomery class Curve25519 extends Montgomery
@ -73,7 +74,7 @@ class Curve25519 extends Montgomery
public function rangeCheck(BigInteger $x): void public function rangeCheck(BigInteger $x): void
{ {
if ($x->getLength() > 256 || $x->isNegative()) { if ($x->getLength() > 256 || $x->isNegative()) {
throw new \RangeException('x must be a positive integer less than 256 bytes in length'); throw new RangeException('x must be a positive integer less than 256 bytes in length');
} }
} }
} }

View File

@ -16,6 +16,7 @@ declare(strict_types=1);
namespace phpseclib3\Crypt\EC\Curves; namespace phpseclib3\Crypt\EC\Curves;
use phpseclib3\Crypt\EC\BaseCurves\Montgomery; use phpseclib3\Crypt\EC\BaseCurves\Montgomery;
use phpseclib3\Exception\RangeException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
class Curve448 extends Montgomery class Curve448 extends Montgomery
@ -84,7 +85,7 @@ class Curve448 extends Montgomery
public function rangeCheck(BigInteger $x): void public function rangeCheck(BigInteger $x): void
{ {
if ($x->getLength() > 448 || $x->isNegative()) { if ($x->getLength() > 448 || $x->isNegative()) {
throw new \RangeException('x must be a positive integer less than 446 bytes in length'); throw new RangeException('x must be a positive integer less than 446 bytes in length');
} }
} }
} }

View File

@ -17,6 +17,8 @@ namespace phpseclib3\Crypt\EC\Curves;
use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards;
use phpseclib3\Crypt\Hash; use phpseclib3\Crypt\Hash;
use phpseclib3\Crypt\Random; use phpseclib3\Crypt\Random;
use phpseclib3\Exception\LengthException;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
class Ed25519 extends TwistedEdwards class Ed25519 extends TwistedEdwards
@ -115,7 +117,7 @@ class Ed25519 extends TwistedEdwards
$x2 = $u->divide($v); $x2 = $u->divide($v);
if ($x2->equals($this->zero)) { if ($x2->equals($this->zero)) {
if ($sign) { if ($sign) {
throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); throw new RuntimeException('Unable to recover X coordinate (x2 = 0)');
} }
return clone $this->zero; return clone $this->zero;
} }
@ -139,7 +141,7 @@ class Ed25519 extends TwistedEdwards
$temp = $this->two->pow($temp); $temp = $this->two->pow($temp);
$x = $x->multiply($temp); $x = $x->multiply($temp);
if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) {
throw new \RuntimeException('Unable to recover X coordinate'); throw new RuntimeException('Unable to recover X coordinate');
} }
} }
if ($x->isOdd() != $sign) { if ($x->isOdd() != $sign) {
@ -161,7 +163,7 @@ class Ed25519 extends TwistedEdwards
public function extractSecret(string $str) public function extractSecret(string $str)
{ {
if (strlen($str) != 32) { if (strlen($str) != 32) {
throw new \LengthException('Private Key should be 32-bytes long'); throw new LengthException('Private Key should be 32-bytes long');
} }
// 1. Hash the 32-byte private key using SHA-512, storing the digest in // 1. Hash the 32-byte private key using SHA-512, storing the digest in
// a 64-octet large buffer, denoted h. Only the lower 32 bytes are // a 64-octet large buffer, denoted h. Only the lower 32 bytes are
@ -217,7 +219,7 @@ class Ed25519 extends TwistedEdwards
* A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T),
* with x = X/Z, y = Y/Z, x * y = T/Z. * with x = X/Z, y = Y/Z, x * y = T/Z.
* *
* @return \phpseclib3\Math\PrimeField\Integer[] * @return Integer[]
*/ */
public function convertToInternal(array $p): array public function convertToInternal(array $p): array
{ {
@ -243,7 +245,7 @@ class Ed25519 extends TwistedEdwards
public function doublePoint(array $p): array public function doublePoint(array $p): array
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
if (!count($p)) { if (!count($p)) {
@ -251,7 +253,7 @@ class Ed25519 extends TwistedEdwards
} }
if (!isset($p[2])) { if (!isset($p[2])) {
throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); throw new RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa');
} }
// from https://tools.ietf.org/html/rfc8032#page-12 // from https://tools.ietf.org/html/rfc8032#page-12
@ -283,7 +285,7 @@ class Ed25519 extends TwistedEdwards
public function addPoint(array $p, array $q): array public function addPoint(array $p, array $q): array
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
if (!count($p) || !count($q)) { if (!count($p) || !count($q)) {
@ -297,7 +299,7 @@ class Ed25519 extends TwistedEdwards
} }
if (!isset($p[2]) || !isset($q[2])) { if (!isset($p[2]) || !isset($q[2])) {
throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); throw new RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa');
} }
if ($p[0]->equals($q[0])) { if ($p[0]->equals($q[0])) {

View File

@ -17,7 +17,10 @@ namespace phpseclib3\Crypt\EC\Curves;
use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards;
use phpseclib3\Crypt\Hash; use phpseclib3\Crypt\Hash;
use phpseclib3\Crypt\Random; use phpseclib3\Crypt\Random;
use phpseclib3\Exception\LengthException;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\PrimeField\Integer;
class Ed448 extends TwistedEdwards class Ed448 extends TwistedEdwards
{ {
@ -71,7 +74,7 @@ class Ed448 extends TwistedEdwards
$x2 = $u->divide($v); $x2 = $u->divide($v);
if ($x2->equals($this->zero)) { if ($x2->equals($this->zero)) {
if ($sign) { if ($sign) {
throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); throw new RuntimeException('Unable to recover X coordinate (x2 = 0)');
} }
return clone $this->zero; return clone $this->zero;
} }
@ -81,7 +84,7 @@ class Ed448 extends TwistedEdwards
$x = $x2->pow($exp); $x = $x2->pow($exp);
if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) {
throw new \RuntimeException('Unable to recover X coordinate'); throw new RuntimeException('Unable to recover X coordinate');
} }
if ($x->isOdd() != $sign) { if ($x->isOdd() != $sign) {
$x = $x->negate(); $x = $x->negate();
@ -102,7 +105,7 @@ class Ed448 extends TwistedEdwards
public function extractSecret(string $str) public function extractSecret(string $str)
{ {
if (strlen($str) != 57) { if (strlen($str) != 57) {
throw new \LengthException('Private Key should be 57-bytes long'); throw new LengthException('Private Key should be 57-bytes long');
} }
// 1. Hash the 57-byte private key using SHAKE256(x, 114), storing the // 1. Hash the 57-byte private key using SHAKE256(x, 114), storing the
// digest in a 114-octet large buffer, denoted h. Only the lower 57 // digest in a 114-octet large buffer, denoted h. Only the lower 57
@ -158,7 +161,7 @@ class Ed448 extends TwistedEdwards
* A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T),
* with x = X/Z, y = Y/Z, x * y = T/Z. * with x = X/Z, y = Y/Z, x * y = T/Z.
* *
* @return \phpseclib3\Math\PrimeField\Integer[] * @return Integer[]
*/ */
public function convertToInternal(array $p): array public function convertToInternal(array $p): array
{ {
@ -183,7 +186,7 @@ class Ed448 extends TwistedEdwards
public function doublePoint(array $p): array public function doublePoint(array $p): array
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
if (!count($p)) { if (!count($p)) {
@ -191,7 +194,7 @@ class Ed448 extends TwistedEdwards
} }
if (!isset($p[2])) { if (!isset($p[2])) {
throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); throw new RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa');
} }
// from https://tools.ietf.org/html/rfc8032#page-18 // from https://tools.ietf.org/html/rfc8032#page-18
@ -221,7 +224,7 @@ class Ed448 extends TwistedEdwards
public function addPoint(array $p, array $q): array public function addPoint(array $p, array $q): array
{ {
if (!isset($this->factory)) { if (!isset($this->factory)) {
throw new \RuntimeException('setModulo needs to be called before this method'); throw new RuntimeException('setModulo needs to be called before this method');
} }
if (!count($p) || !count($q)) { if (!count($p) || !count($q)) {
@ -235,7 +238,7 @@ class Ed448 extends TwistedEdwards
} }
if (!isset($p[2]) || !isset($q[2])) { if (!isset($p[2]) || !isset($q[2])) {
throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); throw new RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa');
} }
if ($p[0]->equals($q[0])) { if ($p[0]->equals($q[0])) {

View File

@ -20,6 +20,8 @@ use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve;
use phpseclib3\Crypt\EC\BaseCurves\Binary as BinaryCurve; use phpseclib3\Crypt\EC\BaseCurves\Binary as BinaryCurve;
use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve;
use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\Exception\UnsupportedCurveException;
use phpseclib3\File\ASN1; use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1\Maps;
@ -194,12 +196,12 @@ trait Common
* Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based
* on the curve parameters * on the curve parameters
* *
* @return \phpseclib3\Crypt\EC\BaseCurves\Base|false * @return BaseCurve|false
*/ */
protected static function loadCurveByParam(array $params) protected static function loadCurveByParam(array $params)
{ {
if (count($params) > 1) { if (count($params) > 1) {
throw new \RuntimeException('No parameters are present'); throw new RuntimeException('No parameters are present');
} }
if (isset($params['namedCurve'])) { if (isset($params['namedCurve'])) {
$curve = '\phpseclib3\Crypt\EC\Curves\\' . $params['namedCurve']; $curve = '\phpseclib3\Crypt\EC\Curves\\' . $params['namedCurve'];
@ -210,7 +212,7 @@ trait Common
} }
if (isset($params['implicitCurve'])) { if (isset($params['implicitCurve'])) {
if (!isset(self::$implicitCurve)) { if (!isset(self::$implicitCurve)) {
throw new \RuntimeException('Implicit curves can be provided by calling setImplicitCurve'); throw new RuntimeException('Implicit curves can be provided by calling setImplicitCurve');
} }
return self::$implicitCurve; return self::$implicitCurve;
} }
@ -259,7 +261,7 @@ trait Common
throw new UnsupportedCurveException('Field Type of ' . $data['fieldID']['fieldType'] . ' is not supported'); throw new UnsupportedCurveException('Field Type of ' . $data['fieldID']['fieldType'] . ' is not supported');
} }
} }
throw new \RuntimeException('No valid parameters are present'); throw new RuntimeException('No valid parameters are present');
} }
/** /**
@ -281,11 +283,11 @@ trait Common
$y[0] = $y[0] & chr(0x7F); $y[0] = $y[0] & chr(0x7F);
$y = new BigInteger($y, 256); $y = new BigInteger($y, 256);
if ($y->compare($curve->getModulo()) >= 0) { if ($y->compare($curve->getModulo()) >= 0) {
throw new \RuntimeException('The Y coordinate should not be >= the modulo'); throw new RuntimeException('The Y coordinate should not be >= the modulo');
} }
$point = $curve->recoverX($y, $sign); $point = $curve->recoverX($y, $sign);
if (!$curve->verifyPoint($point)) { if (!$curve->verifyPoint($point)) {
throw new \RuntimeException('Unable to verify that point exists on curve'); throw new RuntimeException('Unable to verify that point exists on curve');
} }
return $point; return $point;
} }
@ -293,7 +295,7 @@ trait Common
// the first byte of a bit string represents the number of bits in the last byte that are to be ignored but, // the first byte of a bit string represents the number of bits in the last byte that are to be ignored but,
// currently, bit strings wanting a non-zero amount of bits trimmed are not supported // currently, bit strings wanting a non-zero amount of bits trimmed are not supported
if (($val = Strings::shift($str)) != "\0") { if (($val = Strings::shift($str)) != "\0") {
throw new \UnexpectedValueException('extractPoint expects the first byte to be null - not ' . Strings::bin2hex($val)); throw new UnexpectedValueException('extractPoint expects the first byte to be null - not ' . Strings::bin2hex($val));
} }
if ($str == "\0") { if ($str == "\0") {
return []; return [];
@ -311,7 +313,7 @@ trait Common
preg_match("#(.)(.{{$order}})(.{{$order}})#s", $str, $matches); preg_match("#(.)(.{{$order}})(.{{$order}})#s", $str, $matches);
[, $w, $x, $y] = $matches; [, $w, $x, $y] = $matches;
if ($w != "\4") { if ($w != "\4") {
throw new \UnexpectedValueException('The first byte of an uncompressed point should be 04 - not ' . Strings::bin2hex($val)); throw new UnexpectedValueException('The first byte of an uncompressed point should be 04 - not ' . Strings::bin2hex($val));
} }
$point = [ $point = [
$curve->convertInteger(new BigInteger($x, 256)), $curve->convertInteger(new BigInteger($x, 256)),
@ -319,13 +321,13 @@ trait Common
]; ];
if (!$curve->verifyPoint($point)) { if (!$curve->verifyPoint($point)) {
throw new \RuntimeException('Unable to verify that point exists on curve'); throw new RuntimeException('Unable to verify that point exists on curve');
} }
return $point; return $point;
} }
throw new \UnexpectedValueException('The string representation of the points is not of an appropriate length'); throw new UnexpectedValueException('The string representation of the points is not of an appropriate length');
} }
/** /**
@ -425,7 +427,7 @@ trait Common
// https://crypto.stackexchange.com/a/27914/4520 // https://crypto.stackexchange.com/a/27914/4520
// https://en.wikipedia.org/wiki/Schoof%E2%80%93Elkies%E2%80%93Atkin_algorithm // https://en.wikipedia.org/wiki/Schoof%E2%80%93Elkies%E2%80%93Atkin_algorithm
if (!$order) { if (!$order) {
throw new \RuntimeException('Specified Curves need the order to be specified'); throw new RuntimeException('Specified Curves need the order to be specified');
} }
$point = $curve->getBasePoint(); $point = $curve->getBasePoint();
$x = $point[0]->toBytes(); $x = $point[0]->toBytes();

View File

@ -25,6 +25,7 @@ namespace phpseclib3\Crypt\EC\Formats\Keys;
use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve;
use phpseclib3\Crypt\EC\Curves\Curve25519; use phpseclib3\Crypt\EC\Curves\Curve25519;
use phpseclib3\Crypt\EC\Curves\Curve448; use phpseclib3\Crypt\EC\Curves\Curve448;
use phpseclib3\Exception\LengthException;
use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\Exception\UnsupportedFormatException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\Common\FiniteField\Integer; use phpseclib3\Math\Common\FiniteField\Integer;
@ -54,7 +55,7 @@ abstract class MontgomeryPrivate
$curve = new Curve448(); $curve = new Curve448();
break; break;
default: default:
throw new \LengthException('The only supported lengths are 32 and 56'); throw new LengthException('The only supported lengths are 32 and 56');
} }
$components = ['curve' => $curve]; $components = ['curve' => $curve];

View File

@ -18,7 +18,9 @@ namespace phpseclib3\Crypt\EC\Formats\Keys;
use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve;
use phpseclib3\Crypt\EC\Curves\Curve25519; use phpseclib3\Crypt\EC\Curves\Curve25519;
use phpseclib3\Crypt\EC\Curves\Curve448; use phpseclib3\Crypt\EC\Curves\Curve448;
use phpseclib3\Exception\LengthException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\Common\FiniteField\Integer;
/** /**
* Montgomery Public Key Handler * Montgomery Public Key Handler
@ -45,7 +47,7 @@ abstract class MontgomeryPublic
$curve = new Curve448(); $curve = new Curve448();
break; break;
default: default:
throw new \LengthException('The only supported lengths are 32 and 56'); throw new LengthException('The only supported lengths are 32 and 56');
} }
$components = ['curve' => $curve]; $components = ['curve' => $curve];
@ -57,7 +59,7 @@ abstract class MontgomeryPublic
/** /**
* Convert an EC public key to the appropriate format * Convert an EC public key to the appropriate format
* *
* @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param Integer[] $publicKey
*/ */
public static function savePublicKey(MontgomeryCurve $curve, array $publicKey): string public static function savePublicKey(MontgomeryCurve $curve, array $publicKey): string
{ {

View File

@ -21,8 +21,10 @@ use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor;
use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve;
use phpseclib3\Crypt\EC\Curves\Ed25519; use phpseclib3\Crypt\EC\Curves\Ed25519;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\Exception\UnsupportedCurveException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\Common\FiniteField\Integer;
/** /**
* OpenSSH Formatted EC Key Handler * OpenSSH Formatted EC Key Handler
@ -58,7 +60,7 @@ abstract class OpenSSH extends Progenitor
$paddedKey = $parsed['paddedKey']; $paddedKey = $parsed['paddedKey'];
[$type] = Strings::unpackSSH2('s', $paddedKey); [$type] = Strings::unpackSSH2('s', $paddedKey);
if ($type != $parsed['type']) { if ($type != $parsed['type']) {
throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); throw new RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])");
} }
if ($type == 'ssh-ed25519') { if ($type == 'ssh-ed25519') {
[, $key, $comment] = Strings::unpackSSH2('sss', $paddedKey); [, $key, $comment] = Strings::unpackSSH2('sss', $paddedKey);
@ -79,7 +81,7 @@ abstract class OpenSSH extends Progenitor
if ($parsed['type'] == 'ssh-ed25519') { if ($parsed['type'] == 'ssh-ed25519') {
if (Strings::shift($parsed['publicKey'], 4) != "\0\0\0\x20") { if (Strings::shift($parsed['publicKey'], 4) != "\0\0\0\x20") {
throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); throw new RuntimeException('Length of ssh-ed25519 key should be 32');
} }
$curve = new Ed25519(); $curve = new Ed25519();
@ -130,7 +132,7 @@ abstract class OpenSSH extends Progenitor
/** /**
* Convert an EC public key to the appropriate format * Convert an EC public key to the appropriate format
* *
* @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param Integer[] $publicKey
* @param array $options optional * @param array $options optional
*/ */
public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []): string public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []): string
@ -165,8 +167,8 @@ abstract class OpenSSH extends Progenitor
/** /**
* Convert a private key to the appropriate format. * Convert a private key to the appropriate format.
* *
* @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve * @param Ed25519 $curve
* @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param Integer[] $publicKey
* @param string|false $password * @param string|false $password
* @param array $options optional * @param array $options optional
*/ */
@ -180,10 +182,10 @@ abstract class OpenSSH extends Progenitor
): string { ): string {
if ($curve instanceof Ed25519) { if ($curve instanceof Ed25519) {
if (!isset($secret)) { if (!isset($secret)) {
throw new \RuntimeException('Private Key does not have a secret set'); throw new RuntimeException('Private Key does not have a secret set');
} }
if (strlen($secret) != 32) { if (strlen($secret) != 32) {
throw new \RuntimeException('Private Key secret is not of the correct length'); throw new RuntimeException('Private Key secret is not of the correct length');
} }
$pubKey = $curve->encodePoint($publicKey); $pubKey = $curve->encodePoint($publicKey);

View File

@ -32,6 +32,8 @@ use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor;
use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve;
use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve;
use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\Exception\UnsupportedCurveException;
use phpseclib3\File\ASN1; use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1\Maps;
@ -57,7 +59,7 @@ abstract class PKCS1 extends Progenitor
self::initialize_static_variables(); self::initialize_static_variables();
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
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 EC PARAMETERS') && strpos($key, 'BEGIN EC PRIVATE KEY')) { if (strpos($key, 'BEGIN EC PARAMETERS') && strpos($key, 'BEGIN EC PRIVATE KEY')) {
@ -67,12 +69,12 @@ abstract class PKCS1 extends Progenitor
$decoded = parent::load($matches[0], $password); $decoded = parent::load($matches[0], $password);
$decoded = ASN1::decodeBER($decoded); $decoded = ASN1::decodeBER($decoded);
if (!$decoded) { if (!$decoded) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
$ecPrivate = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); $ecPrivate = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP);
if (!is_array($ecPrivate)) { if (!is_array($ecPrivate)) {
throw new \RuntimeException('Unable to perform ASN1 mapping'); throw new RuntimeException('Unable to perform ASN1 mapping');
} }
if (isset($ecPrivate['parameters'])) { if (isset($ecPrivate['parameters'])) {
@ -83,18 +85,18 @@ abstract class PKCS1 extends Progenitor
$decoded = parent::load($matches[0], ''); $decoded = parent::load($matches[0], '');
$decoded = ASN1::decodeBER($decoded); $decoded = ASN1::decodeBER($decoded);
if (!$decoded) { if (!$decoded) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
$ecParams = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); $ecParams = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP);
if (!is_array($ecParams)) { if (!is_array($ecParams)) {
throw new \RuntimeException('Unable to perform ASN1 mapping'); throw new RuntimeException('Unable to perform ASN1 mapping');
} }
$ecParams = self::loadCurveByParam($ecParams); $ecParams = self::loadCurveByParam($ecParams);
// comparing $ecParams and $components['curve'] directly won't work because they'll have different Math\Common\FiniteField classes // comparing $ecParams and $components['curve'] directly won't work because they'll have different Math\Common\FiniteField classes
// even if the modulo is the same // even if the modulo is the same
if (isset($components['curve']) && self::encodeParameters($ecParams, false, []) != self::encodeParameters($components['curve'], false, [])) { if (isset($components['curve']) && self::encodeParameters($ecParams, false, []) != self::encodeParameters($components['curve'], false, [])) {
throw new \RuntimeException('EC PARAMETERS does not correspond to EC PRIVATE KEY'); throw new RuntimeException('EC PARAMETERS does not correspond to EC PRIVATE KEY');
} }
if (!isset($components['curve'])) { if (!isset($components['curve'])) {
@ -114,7 +116,7 @@ abstract class PKCS1 extends Progenitor
$decoded = ASN1::decodeBER($key); $decoded = ASN1::decodeBER($key);
if (!$decoded) { if (!$decoded) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
$key = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); $key = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP);
@ -124,10 +126,10 @@ abstract class PKCS1 extends Progenitor
$key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); $key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP);
if (!is_array($key)) { if (!is_array($key)) {
throw new \RuntimeException('Unable to perform ASN1 mapping'); throw new RuntimeException('Unable to perform ASN1 mapping');
} }
if (!isset($key['parameters'])) { if (!isset($key['parameters'])) {
throw new \RuntimeException('Key cannot be loaded without parameters'); throw new RuntimeException('Key cannot be loaded without parameters');
} }
$components = []; $components = [];

View File

@ -32,6 +32,8 @@ use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve;
use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve;
use phpseclib3\Crypt\EC\Curves\Ed25519; use phpseclib3\Crypt\EC\Curves\Ed25519;
use phpseclib3\Crypt\EC\Curves\Ed448; use phpseclib3\Crypt\EC\Curves\Ed448;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\Exception\UnsupportedCurveException;
use phpseclib3\File\ASN1; use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1\Maps;
@ -76,7 +78,7 @@ abstract class PKCS8 extends Progenitor
self::initialize_static_variables(); self::initialize_static_variables();
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
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 = str_contains($key, 'PUBLIC'); $isPublic = str_contains($key, 'PUBLIC');
@ -87,9 +89,9 @@ abstract class PKCS8 extends Progenitor
switch (true) { switch (true) {
case !$isPublic && $type == 'publicKey': case !$isPublic && $type == 'publicKey':
throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key'); throw new UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key');
case $isPublic && $type == 'privateKey': case $isPublic && $type == 'privateKey':
throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); throw new UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key');
} }
switch ($key[$type . 'Algorithm']['algorithm']) { switch ($key[$type . 'Algorithm']['algorithm']) {
@ -100,11 +102,11 @@ abstract class PKCS8 extends Progenitor
$decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element);
if (!$decoded) { if (!$decoded) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
$params = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); $params = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP);
if (!$params) { if (!$params) {
throw new \RuntimeException('Unable to decode the parameters using Maps\ECParameters'); throw new RuntimeException('Unable to decode the parameters using Maps\ECParameters');
} }
$components = []; $components = [];
@ -118,11 +120,11 @@ abstract class PKCS8 extends Progenitor
$decoded = ASN1::decodeBER($key['privateKey']); $decoded = ASN1::decodeBER($key['privateKey']);
if (!$decoded) { if (!$decoded) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
$key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); $key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP);
if (isset($key['parameters']) && $params != $key['parameters']) { if (isset($key['parameters']) && $params != $key['parameters']) {
throw new \RuntimeException('The PKCS8 parameter field does not match the private key parameter field'); throw new RuntimeException('The PKCS8 parameter field does not match the private key parameter field');
} }
$components['dA'] = new BigInteger($key['privateKey'], 256); $components['dA'] = new BigInteger($key['privateKey'], 256);
@ -147,7 +149,7 @@ abstract class PKCS8 extends Progenitor
// 0x04 == octet string // 0x04 == octet string
// 0x20 == length (32 bytes) // 0x20 == length (32 bytes)
if (substr($key['privateKey'], 0, 2) != "\x04\x20") { if (substr($key['privateKey'], 0, 2) != "\x04\x20") {
throw new \RuntimeException('The first two bytes of the private key field should be 0x0420'); throw new RuntimeException('The first two bytes of the private key field should be 0x0420');
} }
$arr = $components['curve']->extractSecret(substr($key['privateKey'], 2)); $arr = $components['curve']->extractSecret(substr($key['privateKey'], 2));
$components['dA'] = $arr['dA']; $components['dA'] = $arr['dA'];

View File

@ -19,7 +19,10 @@ use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor;
use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve;
use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\Common\FiniteField;
use phpseclib3\Math\Common\FiniteField\Integer;
/** /**
* PuTTY Formatted EC Key Handler * PuTTY Formatted EC Key Handler
@ -70,7 +73,7 @@ abstract class PuTTY extends Progenitor
if ($components['curve'] instanceof TwistedEdwardsCurve) { if ($components['curve'] instanceof TwistedEdwardsCurve) {
if (Strings::shift($private, 4) != "\0\0\0\x20") { if (Strings::shift($private, 4) != "\0\0\0\x20") {
throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); throw new RuntimeException('Length of ssh-ed25519 key should be 32');
} }
$arr = $components['curve']->extractSecret($private); $arr = $components['curve']->extractSecret($private);
$components['dA'] = $arr['dA']; $components['dA'] = $arr['dA'];
@ -86,7 +89,7 @@ abstract class PuTTY extends Progenitor
/** /**
* Convert a private key to the appropriate format. * Convert a private key to the appropriate format.
* *
* @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param Integer[] $publicKey
*/ */
public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, ?string $secret = null, ?string $password = null, array $options = []): string public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, ?string $secret = null, ?string $password = null, array $options = []): string
{ {
@ -117,7 +120,7 @@ abstract class PuTTY extends Progenitor
/** /**
* Convert an EC public key to the appropriate format * Convert an EC public key to the appropriate format
* *
* @param \phpseclib3\Math\Common\FiniteField[] $publicKey * @param FiniteField[] $publicKey
*/ */
public static function savePublicKey(BaseCurve $curve, array $publicKey): string public static function savePublicKey(BaseCurve $curve, array $publicKey): string
{ {

View File

@ -26,8 +26,11 @@ use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve;
use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve;
use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve;
use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\Exception\UnsupportedCurveException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\Common\FiniteField\Integer;
/** /**
* XML Formatted EC Key Handler * XML Formatted EC Key Handler
@ -62,7 +65,7 @@ abstract class XML
self::initialize_static_variables(); self::initialize_static_variables();
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
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 (!class_exists('DOMDocument')) { if (!class_exists('DOMDocument')) {
@ -88,7 +91,7 @@ abstract class XML
if (!$dom->loadXML($key)) { if (!$dom->loadXML($key)) {
libxml_use_internal_errors($use_errors); libxml_use_internal_errors($use_errors);
throw new \UnexpectedValueException('Key does not appear to contain XML'); throw new UnexpectedValueException('Key does not appear to contain XML');
} }
$xpath = new \DOMXPath($dom); $xpath = new \DOMXPath($dom);
libxml_use_internal_errors($use_errors); libxml_use_internal_errors($use_errors);
@ -125,7 +128,7 @@ abstract class XML
} }
if (!$result->length) { if (!$result->length) {
throw new \RuntimeException($error); throw new RuntimeException($error);
} }
return $decode ? self::decodeValue($result->item(0)->textContent) : $result->item(0)->textContent; return $decode ? self::decodeValue($result->item(0)->textContent) : $result->item(0)->textContent;
} }
@ -170,17 +173,17 @@ abstract class XML
$x = self::query($xpath, 'publickey/x'); $x = self::query($xpath, 'publickey/x');
$y = self::query($xpath, 'publickey/y'); $y = self::query($xpath, 'publickey/y');
if (!$x->length || !$x->item(0)->hasAttribute('Value')) { if (!$x->length || !$x->item(0)->hasAttribute('Value')) {
throw new \RuntimeException('Public Key / X coordinate not found'); throw new RuntimeException('Public Key / X coordinate not found');
} }
if (!$y->length || !$y->item(0)->hasAttribute('Value')) { if (!$y->length || !$y->item(0)->hasAttribute('Value')) {
throw new \RuntimeException('Public Key / Y coordinate not found'); throw new RuntimeException('Public Key / Y coordinate not found');
} }
$point = [ $point = [
$curve->convertInteger(new BigInteger($x->item(0)->getAttribute('Value'))), $curve->convertInteger(new BigInteger($x->item(0)->getAttribute('Value'))),
$curve->convertInteger(new BigInteger($y->item(0)->getAttribute('Value'))), $curve->convertInteger(new BigInteger($y->item(0)->getAttribute('Value'))),
]; ];
if (!$curve->verifyPoint($point)) { if (!$curve->verifyPoint($point)) {
throw new \RuntimeException('Unable to verify that point exists on curve'); throw new RuntimeException('Unable to verify that point exists on curve');
} }
return $point; return $point;
} }
@ -189,7 +192,7 @@ abstract class XML
* Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based
* on the curve parameters * on the curve parameters
* *
* @return \phpseclib3\Crypt\EC\BaseCurves\Base|false * @return BaseCurve|false
*/ */
private static function loadCurveByParam(\DOMXPath $xpath) private static function loadCurveByParam(\DOMXPath $xpath)
{ {
@ -216,7 +219,7 @@ abstract class XML
$params = self::query($xpath, 'ecparameters'); $params = self::query($xpath, 'ecparameters');
if (!$params->length) { if (!$params->length) {
throw new \RuntimeException('No parameters are present'); throw new RuntimeException('No parameters are present');
} }
$fieldTypes = [ $fieldTypes = [
@ -268,7 +271,7 @@ abstract class XML
* Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based
* on the curve parameters * on the curve parameters
* *
* @return \phpseclib3\Crypt\EC\BaseCurves\Base|false * @return BaseCurve|false
*/ */
private static function loadCurveByParamRFC4050(\DOMXPath $xpath) private static function loadCurveByParamRFC4050(\DOMXPath $xpath)
{ {
@ -353,7 +356,7 @@ abstract class XML
/** /**
* Convert a public key to the appropriate format * Convert a public key to the appropriate format
* *
* @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param Integer[] $publicKey
* @param array $options optional * @param array $options optional
*/ */
public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []): string public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []): string

View File

@ -20,8 +20,10 @@ declare(strict_types=1);
namespace phpseclib3\Crypt\EC\Formats\Keys; namespace phpseclib3\Crypt\EC\Formats\Keys;
use phpseclib3\Crypt\EC\Curves\Ed25519; use phpseclib3\Crypt\EC\Curves\Ed25519;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\Exception\UnsupportedFormatException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\Common\FiniteField\Integer;
/** /**
* libsodium Key Handler * libsodium Key Handler
@ -53,12 +55,12 @@ abstract class libsodium
case 96: case 96:
$public = substr($key, -32); $public = substr($key, -32);
if (substr($key, 32, 32) != $public) { if (substr($key, 32, 32) != $public) {
throw new \RuntimeException('Keys with 96 bytes should have the 2nd and 3rd set of 32 bytes match'); throw new RuntimeException('Keys with 96 bytes should have the 2nd and 3rd set of 32 bytes match');
} }
$private = substr($key, 0, 32); $private = substr($key, 0, 32);
break; break;
default: default:
throw new \RuntimeException('libsodium keys need to either be 32 bytes long, 64 bytes long or 96 bytes long'); throw new RuntimeException('libsodium keys need to either be 32 bytes long, 64 bytes long or 96 bytes long');
} }
$curve = new Ed25519(); $curve = new Ed25519();
@ -78,7 +80,7 @@ abstract class libsodium
/** /**
* Convert an EC public key to the appropriate format * Convert an EC public key to the appropriate format
* *
* @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param Integer[] $publicKey
*/ */
public static function savePublicKey(Ed25519 $curve, array $publicKey): string public static function savePublicKey(Ed25519 $curve, array $publicKey): string
{ {
@ -88,15 +90,15 @@ abstract class libsodium
/** /**
* Convert a private key to the appropriate format. * Convert a private key to the appropriate format.
* *
* @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param Integer[] $publicKey
*/ */
public static function savePrivateKey(BigInteger $privateKey, Ed25519 $curve, array $publicKey, ?string $secret = null, ?string $password = null): string public static function savePrivateKey(BigInteger $privateKey, Ed25519 $curve, array $publicKey, ?string $secret = null, ?string $password = null): string
{ {
if (!isset($secret)) { if (!isset($secret)) {
throw new \RuntimeException('Private Key does not have a secret set'); throw new RuntimeException('Private Key does not have a secret set');
} }
if (strlen($secret) != 32) { if (strlen($secret) != 32) {
throw new \RuntimeException('Private Key secret is not of the correct length'); throw new RuntimeException('Private Key secret is not of the correct length');
} }
if (!empty($password) && is_string($password)) { if (!empty($password) && is_string($password)) {
throw new UnsupportedFormatException('libsodium private keys do not support encryption'); throw new UnsupportedFormatException('libsodium private keys do not support encryption');

View File

@ -23,6 +23,7 @@ use phpseclib3\Crypt\EC\Curves\Ed25519;
use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; use phpseclib3\Crypt\EC\Formats\Keys\PKCS1;
use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature;
use phpseclib3\Crypt\Hash; use phpseclib3\Crypt\Hash;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnsupportedOperationException; use phpseclib3\Exception\UnsupportedOperationException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -76,7 +77,7 @@ class PrivateKey extends EC implements Common\PrivateKey
return $this->curve->encodePoint($point); return $this->curve->encodePoint($point);
} }
if (empty($point)) { if (empty($point)) {
throw new \RuntimeException('The infinity point is invalid'); throw new RuntimeException('The infinity point is invalid');
} }
return "\4" . $point[0]->toBytes(true) . $point[1]->toBytes(true); return "\4" . $point[0]->toBytes(true) . $point[1]->toBytes(true);
} }

View File

@ -35,6 +35,7 @@ namespace phpseclib3\Crypt;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Exception\InsufficientSetupException; use phpseclib3\Exception\InsufficientSetupException;
use phpseclib3\Exception\LengthException;
use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedAlgorithmException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\PrimeField; use phpseclib3\Math\PrimeField;
@ -158,7 +159,7 @@ class Hash
* umac cipher object * umac cipher object
* *
* @see self::hash() * @see self::hash()
* @var \phpseclib3\Crypt\AES * @var AES
*/ */
private $c; private $c;
@ -232,7 +233,7 @@ class Hash
return; return;
} }
throw new \LengthException('The nonce length must be between 1 and 16 bytes, inclusive'); throw new LengthException('The nonce length must be between 1 and 16 bytes, inclusive');
} }
/** /**
@ -780,7 +781,7 @@ class Hash
throw new InsufficientSetupException('No key has been set'); throw new InsufficientSetupException('No key has been set');
} }
if (strlen($this->key) != 16) { if (strlen($this->key) != 16) {
throw new \LengthException('Key must be 16 bytes long'); throw new LengthException('Key must be 16 bytes long');
} }
if (!isset(self::$maxwordrange64)) { if (!isset(self::$maxwordrange64)) {

View File

@ -37,6 +37,8 @@ namespace phpseclib3\Crypt;
use phpseclib3\Crypt\Common\BlockCipher; use phpseclib3\Crypt\Common\BlockCipher;
use phpseclib3\Exception\BadModeException; use phpseclib3\Exception\BadModeException;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Exception\LengthException;
/** /**
* Pure-PHP implementation of RC2. * Pure-PHP implementation of RC2.
@ -229,7 +231,7 @@ class RC2 extends BlockCipher
/** /**
* Default Constructor. * Default Constructor.
* *
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided * @throws InvalidArgumentException if an invalid / unsupported mode is provided
*/ */
public function __construct(string $mode) public function __construct(string $mode)
{ {
@ -269,12 +271,12 @@ class RC2 extends BlockCipher
* \phpseclib3\Crypt\RC2::setKey() call. * \phpseclib3\Crypt\RC2::setKey() call.
* *
* @param int $length in bits * @param int $length in bits
* @throws \LengthException if the key length isn't supported * @throws LengthException if the key length isn't supported
*/ */
public function setKeyLength(int $length): void public function setKeyLength(int $length): void
{ {
if ($length < 8 || $length > 1024) { if ($length < 8 || $length > 1024) {
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported'); throw new LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported');
} }
$this->default_key_length = $this->current_key_length = $length; $this->default_key_length = $this->current_key_length = $length;
@ -297,7 +299,7 @@ class RC2 extends BlockCipher
* has more then 128 bytes in it, and set $key to a single null byte if * has more then 128 bytes in it, and set $key to a single null byte if
* it is empty. * it is empty.
* *
* @throws \LengthException if the key length isn't supported * @throws LengthException if the key length isn't supported
* @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey()
*/ */
public function setKey(string $key, ?int $t1 = null): void public function setKey(string $key, ?int $t1 = null): void
@ -309,12 +311,12 @@ class RC2 extends BlockCipher
} }
if ($t1 < 1 || $t1 > 1024) { if ($t1 < 1 || $t1 > 1024) {
throw new \LengthException('Key size of ' . $t1 . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported'); throw new LengthException('Key size of ' . $t1 . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported');
} }
$this->current_key_length = $t1; $this->current_key_length = $t1;
if (strlen($key) < 1 || strlen($key) > 128) { if (strlen($key) < 1 || strlen($key) > 128) {
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes between 8 and 1024 bits, inclusive, are supported'); throw new LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes between 8 and 1024 bits, inclusive, are supported');
} }
$t = strlen($key); $t = strlen($key);

View File

@ -45,6 +45,7 @@ declare(strict_types=1);
namespace phpseclib3\Crypt; namespace phpseclib3\Crypt;
use phpseclib3\Crypt\Common\StreamCipher; use phpseclib3\Crypt\Common\StreamCipher;
use phpseclib3\Exception\LengthException;
/** /**
* Pure-PHP implementation of RC4. * Pure-PHP implementation of RC4.
@ -127,12 +128,12 @@ class RC4 extends StreamCipher
* *
* Keys can be between 1 and 256 bytes long. * Keys can be between 1 and 256 bytes long.
* *
* @throws \LengthException if the key length is invalid * @throws LengthException if the key length is invalid
*/ */
public function setKeyLength(int $length): void public function setKeyLength(int $length): void
{ {
if ($length < 8 || $length > 2048) { if ($length < 8 || $length > 2048) {
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 256 bytes are supported'); throw new LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 256 bytes are supported');
} }
$this->key_length = $length >> 3; $this->key_length = $length >> 3;
@ -149,7 +150,7 @@ class RC4 extends StreamCipher
{ {
$length = strlen($key); $length = strlen($key);
if ($length < 1 || $length > 256) { if ($length < 1 || $length > 256) {
throw new \LengthException('Key size of ' . $length . ' bytes is not supported by RC4. Keys must be between 1 and 256 bytes long'); throw new LengthException('Key size of ' . $length . ' bytes is not supported by RC4. Keys must be between 1 and 256 bytes long');
} }
parent::setKey($key); parent::setKey($key);

View File

@ -60,6 +60,8 @@ use phpseclib3\Crypt\RSA\Formats\Keys\PSS;
use phpseclib3\Crypt\RSA\PrivateKey; use phpseclib3\Crypt\RSA\PrivateKey;
use phpseclib3\Crypt\RSA\PublicKey; use phpseclib3\Crypt\RSA\PublicKey;
use phpseclib3\Exception\InconsistentSetupException; use phpseclib3\Exception\InconsistentSetupException;
use phpseclib3\Exception\LengthException;
use phpseclib3\Exception\OutOfRangeException;
use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedAlgorithmException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -182,7 +184,7 @@ abstract class RSA extends AsymmetricKey
/** /**
* Hash function for the Mask Generation Function * Hash function for the Mask Generation Function
* *
* @var \phpseclib3\Crypt\Hash * @var Hash
*/ */
protected $mgfHash; protected $mgfHash;
@ -501,7 +503,7 @@ abstract class RSA extends AsymmetricKey
{ {
$x = $x->toBytes(); $x = $x->toBytes();
if (strlen($x) > $xLen) { if (strlen($x) > $xLen) {
throw new \OutOfRangeException('Resultant string length out of range'); throw new OutOfRangeException('Resultant string length out of range');
} }
return str_pad($x, $xLen, chr(0), STR_PAD_LEFT); return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
} }
@ -521,7 +523,7 @@ abstract class RSA extends AsymmetricKey
* *
* See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}. * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}.
* *
* @throws \LengthException if the intended encoded message length is too short * @throws LengthException if the intended encoded message length is too short
*/ */
protected function emsa_pkcs1_v1_5_encode(string $m, int $emLen): string protected function emsa_pkcs1_v1_5_encode(string $m, int $emLen): string
{ {
@ -561,7 +563,7 @@ abstract class RSA extends AsymmetricKey
$tLen = strlen($t); $tLen = strlen($t);
if ($emLen < $tLen + 11) { if ($emLen < $tLen + 11) {
throw new \LengthException('Intended encoded message length too short'); throw new LengthException('Intended encoded message length too short');
} }
$ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
@ -616,7 +618,7 @@ abstract class RSA extends AsymmetricKey
$tLen = strlen($t); $tLen = strlen($t);
if ($emLen < $tLen + 11) { if ($emLen < $tLen + 11) {
throw new \LengthException('Intended encoded message length too short'); throw new LengthException('Intended encoded message length too short');
} }
$ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);

View File

@ -20,6 +20,8 @@ declare(strict_types=1);
namespace phpseclib3\Crypt\RSA\Formats\Keys; namespace phpseclib3\Crypt\RSA\Formats\Keys;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\Exception\UnsupportedFormatException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -67,16 +69,16 @@ abstract class MSBLOB
public static function load($key, ?string $password = null): array public static function load($key, ?string $password = null): array
{ {
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); throw new UnexpectedValueException('Key should be a string - not a ' . gettype($key));
} }
$key = Strings::base64_decode($key); $key = Strings::base64_decode($key);
if (!is_string($key)) { if (!is_string($key)) {
throw new \UnexpectedValueException('Base64 decoding produced an error'); throw new UnexpectedValueException('Base64 decoding produced an error');
} }
if (strlen($key) < 20) { if (strlen($key) < 20) {
throw new \UnexpectedValueException('Key appears to be malformed'); throw new UnexpectedValueException('Key appears to be malformed');
} }
// PUBLICKEYSTRUC publickeystruc // PUBLICKEYSTRUC publickeystruc
@ -97,7 +99,7 @@ abstract class MSBLOB
$publickey = false; $publickey = false;
break; break;
default: default:
throw new \UnexpectedValueException('Key appears to be malformed'); throw new UnexpectedValueException('Key appears to be malformed');
} }
$components = ['isPublicKey' => $publickey]; $components = ['isPublicKey' => $publickey];
@ -108,7 +110,7 @@ abstract class MSBLOB
case self::CALG_RSA_SIGN: case self::CALG_RSA_SIGN:
break; break;
default: default:
throw new \UnexpectedValueException('Key appears to be malformed'); throw new UnexpectedValueException('Key appears to be malformed');
} }
// RSAPUBKEY rsapubkey // RSAPUBKEY rsapubkey
@ -127,12 +129,12 @@ abstract class MSBLOB
case self::RSA1: case self::RSA1:
break; break;
default: default:
throw new \UnexpectedValueException('Key appears to be malformed'); throw new UnexpectedValueException('Key appears to be malformed');
} }
$baseLength = $bitlen / 16; $baseLength = $bitlen / 16;
if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) { if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) {
throw new \UnexpectedValueException('Key appears to be malformed'); throw new UnexpectedValueException('Key appears to be malformed');
} }
$components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256); $components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256);
@ -170,7 +172,7 @@ abstract class MSBLOB
public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, ?string $password = null): string public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, ?string $password = null): string
{ {
if (count($primes) != 2) { if (count($primes) != 2) {
throw new \InvalidArgumentException('MSBLOB does not support multi-prime RSA keys'); throw new InvalidArgumentException('MSBLOB does not support multi-prime RSA keys');
} }
if (!empty($password) && is_string($password)) { if (!empty($password) && is_string($password)) {

View File

@ -19,6 +19,7 @@ namespace phpseclib3\Crypt\RSA\Formats\Keys;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
/** /**
@ -52,7 +53,7 @@ abstract class OpenSSH extends Progenitor
if (isset($parsed['paddedKey'])) { if (isset($parsed['paddedKey'])) {
[$type] = Strings::unpackSSH2('s', $parsed['paddedKey']); [$type] = Strings::unpackSSH2('s', $parsed['paddedKey']);
if ($type != $parsed['type']) { if ($type != $parsed['type']) {
throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); throw new RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])");
} }
$primes = $coefficients = []; $primes = $coefficients = [];

View File

@ -26,6 +26,8 @@ namespace phpseclib3\Crypt\RSA\Formats\Keys;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\File\ASN1; use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1\Maps;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -46,7 +48,7 @@ abstract class PKCS1 extends Progenitor
public static function load($key, ?string $password = null): array public static function load($key, ?string $password = null): array
{ {
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
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 (str_contains($key, 'PUBLIC')) { if (str_contains($key, 'PUBLIC')) {
@ -61,7 +63,7 @@ abstract class PKCS1 extends Progenitor
$decoded = ASN1::decodeBER($key); $decoded = ASN1::decodeBER($key);
if (!$decoded) { if (!$decoded) {
throw new \RuntimeException('Unable to decode BER'); throw new RuntimeException('Unable to decode BER');
} }
$key = ASN1::asn1map($decoded[0], Maps\RSAPrivateKey::MAP); $key = ASN1::asn1map($decoded[0], Maps\RSAPrivateKey::MAP);
@ -90,7 +92,7 @@ abstract class PKCS1 extends Progenitor
$key = ASN1::asn1map($decoded[0], Maps\RSAPublicKey::MAP); $key = ASN1::asn1map($decoded[0], Maps\RSAPublicKey::MAP);
if (!is_array($key)) { if (!is_array($key)) {
throw new \RuntimeException('Unable to perform ASN1 mapping'); throw new RuntimeException('Unable to perform ASN1 mapping');
} }
if (!isset($components['isPublicKey'])) { if (!isset($components['isPublicKey'])) {

View File

@ -29,6 +29,7 @@ namespace phpseclib3\Crypt\RSA\Formats\Keys;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\File\ASN1; use phpseclib3\File\ASN1;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -68,7 +69,7 @@ abstract class PKCS8 extends Progenitor
public static function load($key, ?string $password = null): array public static function load($key, ?string $password = null): array
{ {
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
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 (str_contains($key, 'PUBLIC')) { if (str_contains($key, 'PUBLIC')) {

View File

@ -27,6 +27,7 @@ namespace phpseclib3\Crypt\RSA\Formats\Keys;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\File\ASN1; use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1\Maps;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -100,7 +101,7 @@ abstract class PSS extends Progenitor
self::initialize_static_variables(); self::initialize_static_variables();
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
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' => str_contains($key, 'PUBLIC')]; $components = ['isPublicKey' => str_contains($key, 'PUBLIC')];
@ -114,7 +115,7 @@ abstract class PSS extends Progenitor
if (isset($key[$type . 'KeyAlgorithm']['parameters'])) { if (isset($key[$type . 'KeyAlgorithm']['parameters'])) {
$decoded = ASN1::decodeBER($key[$type . 'KeyAlgorithm']['parameters']); $decoded = ASN1::decodeBER($key[$type . 'KeyAlgorithm']['parameters']);
if ($decoded === false) { if ($decoded === false) {
throw new \UnexpectedValueException('Unable to decode parameters'); throw new UnexpectedValueException('Unable to decode parameters');
} }
$params = ASN1::asn1map($decoded[0], Maps\RSASSA_PSS_params::MAP); $params = ASN1::asn1map($decoded[0], Maps\RSASSA_PSS_params::MAP);
} else { } else {
@ -124,7 +125,7 @@ abstract class PSS extends Progenitor
if (isset($params['maskGenAlgorithm']['parameters'])) { if (isset($params['maskGenAlgorithm']['parameters'])) {
$decoded = ASN1::decodeBER($params['maskGenAlgorithm']['parameters']); $decoded = ASN1::decodeBER($params['maskGenAlgorithm']['parameters']);
if ($decoded === false) { if ($decoded === false) {
throw new \UnexpectedValueException('Unable to decode parameters'); throw new UnexpectedValueException('Unable to decode parameters');
} }
$params['maskGenAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], Maps\HashAlgorithm::MAP); $params['maskGenAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], Maps\HashAlgorithm::MAP);
} else { } else {

View File

@ -17,6 +17,8 @@ namespace phpseclib3\Crypt\RSA\Formats\Keys;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
/** /**
@ -65,13 +67,13 @@ abstract class PuTTY extends Progenitor
$result = Strings::unpackSSH2('ii', $public); $result = Strings::unpackSSH2('ii', $public);
if ($result === false) { if ($result === false) {
throw new \UnexpectedValueException('Key appears to be malformed'); throw new UnexpectedValueException('Key appears to be malformed');
} }
[$publicExponent, $modulus] = $result; [$publicExponent, $modulus] = $result;
$result = Strings::unpackSSH2('iiii', $private); $result = Strings::unpackSSH2('iiii', $private);
if ($result === false) { if ($result === false) {
throw new \UnexpectedValueException('Key appears to be malformed'); throw new UnexpectedValueException('Key appears to be malformed');
} }
$primes = $coefficients = []; $primes = $coefficients = [];
[$privateExponent, $primes[1], $primes[2], $coefficients[2]] = $result; [$privateExponent, $primes[1], $primes[2], $coefficients[2]] = $result;
@ -90,7 +92,7 @@ abstract class PuTTY extends Progenitor
public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, ?string $password = null, array $options = []): string public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, ?string $password = null, array $options = []): string
{ {
if (count($primes) != 2) { if (count($primes) != 2) {
throw new \InvalidArgumentException('PuTTY does not support multi-prime RSA keys'); throw new InvalidArgumentException('PuTTY does not support multi-prime RSA keys');
} }
$public = Strings::packSSH2('ii', $e, $n); $public = Strings::packSSH2('ii', $e, $n);

View File

@ -25,6 +25,7 @@ declare(strict_types=1);
namespace phpseclib3\Crypt\RSA\Formats\Keys; namespace phpseclib3\Crypt\RSA\Formats\Keys;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\Exception\UnsupportedFormatException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -43,7 +44,7 @@ abstract class Raw
public static function load($key, ?string $password = null): array public static function load($key, ?string $password = null): array
{ {
if (!is_array($key)) { if (!is_array($key)) {
throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); throw new UnexpectedValueException('Key should be a array - not a ' . gettype($key));
} }
$key = array_change_key_case($key, CASE_LOWER); $key = array_change_key_case($key, CASE_LOWER);
@ -65,7 +66,7 @@ abstract class Raw
} }
if (!isset($components['publicExponent']) || !isset($components['modulus'])) { if (!isset($components['publicExponent']) || !isset($components['modulus'])) {
throw new \UnexpectedValueException('Modulus / exponent not present'); throw new UnexpectedValueException('Modulus / exponent not present');
} }
if (isset($key['primes'])) { if (isset($key['primes'])) {

View File

@ -24,6 +24,8 @@ namespace phpseclib3\Crypt\RSA\Formats\Keys;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\Exception\UnsupportedFormatException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -42,7 +44,7 @@ abstract class XML
public static function load($key): array public static function load($key): array
{ {
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
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 (!class_exists('DOMDocument')) { if (!class_exists('DOMDocument')) {
@ -64,7 +66,7 @@ abstract class XML
} }
if (!$dom->loadXML($key)) { if (!$dom->loadXML($key)) {
libxml_use_internal_errors($use_errors); libxml_use_internal_errors($use_errors);
throw new \UnexpectedValueException('Key does not appear to contain XML'); throw new UnexpectedValueException('Key does not appear to contain XML');
} }
$xpath = new \DOMXPath($dom); $xpath = new \DOMXPath($dom);
$keys = ['modulus', 'exponent', 'p', 'q', 'dp', 'dq', 'inverseq', 'd']; $keys = ['modulus', 'exponent', 'p', 'q', 'dp', 'dq', 'inverseq', 'd'];
@ -117,7 +119,7 @@ abstract class XML
return $components; return $components;
} }
throw new \UnexpectedValueException('Modulus / exponent not present'); throw new UnexpectedValueException('Modulus / exponent not present');
} }
/** /**
@ -128,7 +130,7 @@ abstract class XML
public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, string $password = ''): string public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, string $password = ''): string
{ {
if (count($primes) != 2) { if (count($primes) != 2) {
throw new \InvalidArgumentException('XML does not support multi-prime RSA keys'); throw new InvalidArgumentException('XML does not support multi-prime RSA keys');
} }
if (!empty($password) && is_string($password)) { if (!empty($password) && is_string($password)) {

View File

@ -17,6 +17,9 @@ use phpseclib3\Crypt\Common;
use phpseclib3\Crypt\Random; use phpseclib3\Crypt\Random;
use phpseclib3\Crypt\RSA; use phpseclib3\Crypt\RSA;
use phpseclib3\Crypt\RSA\Formats\Keys\PSS; use phpseclib3\Crypt\RSA\Formats\Keys\PSS;
use phpseclib3\Exception\LengthException;
use phpseclib3\Exception\OutOfRangeException;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\Exception\UnsupportedFormatException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -62,12 +65,12 @@ class PrivateKey extends RSA implements Common\PrivateKey
* *
* See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}. * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}.
* *
* @return bool|\phpseclib3\Math\BigInteger * @return bool|BigInteger
*/ */
private function rsadp(BigInteger $c) private function rsadp(BigInteger $c)
{ {
if ($c->compare(self::$zero) < 0 || $c->compare($this->modulus) > 0) { if ($c->compare(self::$zero) < 0 || $c->compare($this->modulus) > 0) {
throw new \OutOfRangeException('Ciphertext representative out of range'); throw new OutOfRangeException('Ciphertext representative out of range');
} }
return $this->exponentiate($c); return $this->exponentiate($c);
} }
@ -77,12 +80,12 @@ class PrivateKey extends RSA implements Common\PrivateKey
* *
* See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}. * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}.
* *
* @return bool|\phpseclib3\Math\BigInteger * @return bool|BigInteger
*/ */
private function rsasp1(BigInteger $m) private function rsasp1(BigInteger $m)
{ {
if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) {
throw new \OutOfRangeException('Signature representative out of range'); throw new OutOfRangeException('Signature representative out of range');
} }
return $this->exponentiate($m); return $this->exponentiate($m);
} }
@ -185,7 +188,7 @@ class PrivateKey extends RSA implements Common\PrivateKey
* *
* See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}. * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}.
* *
* @throws \RuntimeException on encoding error * @throws RuntimeException on encoding error
*/ */
private function emsa_pss_encode(string $m, int $emBits): string private function emsa_pss_encode(string $m, int $emBits): string
{ {
@ -197,7 +200,7 @@ class PrivateKey extends RSA implements Common\PrivateKey
$mHash = $this->hash->hash($m); $mHash = $this->hash->hash($m);
if ($emLen < $this->hLen + $sLen + 2) { if ($emLen < $this->hLen + $sLen + 2) {
throw new \LengthException('RSA modulus too short'); throw new LengthException('RSA modulus too short');
} }
$salt = Random::string($sLen); $salt = Random::string($sLen);
@ -243,7 +246,7 @@ class PrivateKey extends RSA implements Common\PrivateKey
* See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}. * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}.
* *
* @return bool|string * @return bool|string
* @throws \LengthException if the RSA modulus is too short * @throws LengthException if the RSA modulus is too short
*/ */
private function rsassa_pkcs1_v1_5_sign(string $m) private function rsassa_pkcs1_v1_5_sign(string $m)
{ {
@ -254,7 +257,7 @@ class PrivateKey extends RSA implements Common\PrivateKey
try { try {
$em = $this->emsa_pkcs1_v1_5_encode($m, $this->k); $em = $this->emsa_pkcs1_v1_5_encode($m, $this->k);
} catch (\LengthException $e) { } catch (\LengthException $e) {
throw new \LengthException('RSA modulus too short'); throw new LengthException('RSA modulus too short');
} }
// RSA signature // RSA signature
@ -299,7 +302,7 @@ class PrivateKey extends RSA implements Common\PrivateKey
// Length checking // Length checking
if (strlen($c) != $this->k) { // or if k < 11 if (strlen($c) != $this->k) { // or if k < 11
throw new \LengthException('Ciphertext representative too long'); throw new LengthException('Ciphertext representative too long');
} }
// RSA decryption // RSA decryption
@ -311,14 +314,14 @@ class PrivateKey extends RSA implements Common\PrivateKey
// EME-PKCS1-v1_5 decoding // EME-PKCS1-v1_5 decoding
if (ord($em[0]) != 0 || ord($em[1]) > 2) { if (ord($em[0]) != 0 || ord($em[1]) > 2) {
throw new \RuntimeException('Decryption error'); throw new RuntimeException('Decryption error');
} }
$ps = substr($em, 2, strpos($em, chr(0), 2) - 2); $ps = substr($em, 2, strpos($em, chr(0), 2) - 2);
$m = substr($em, strlen($ps) + 3); $m = substr($em, strlen($ps) + 3);
if (strlen($ps) < 8) { if (strlen($ps) < 8) {
throw new \RuntimeException('Decryption error'); throw new RuntimeException('Decryption error');
} }
// Output M // Output M
@ -350,7 +353,7 @@ class PrivateKey extends RSA implements Common\PrivateKey
// be output. // be output.
if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) { if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) {
throw new \LengthException('Ciphertext representative too long'); throw new LengthException('Ciphertext representative too long');
} }
// RSA decryption // RSA decryption
@ -384,7 +387,7 @@ class PrivateKey extends RSA implements Common\PrivateKey
// we do | instead of || to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation // we do | instead of || to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation
// to protect against timing attacks // to protect against timing attacks
if (!$hashesMatch | !$patternMatch) { if (!$hashesMatch | !$patternMatch) {
throw new \RuntimeException('Decryption error'); throw new RuntimeException('Decryption error');
} }
// Output the message M // Output the message M
@ -398,12 +401,12 @@ class PrivateKey extends RSA implements Common\PrivateKey
* Doesn't use padding and is not recommended. * Doesn't use padding and is not recommended.
* *
* @return bool|string * @return bool|string
* @throws \LengthException if strlen($m) > $this->k * @throws LengthException if strlen($m) > $this->k
*/ */
private function raw_encrypt(string $m) private function raw_encrypt(string $m)
{ {
if (strlen($m) > $this->k) { if (strlen($m) > $this->k) {
throw new \LengthException('Ciphertext representative too long'); throw new LengthException('Ciphertext representative too long');
} }
$temp = $this->os2ip($m); $temp = $this->os2ip($m);
@ -437,7 +440,7 @@ class PrivateKey extends RSA implements Common\PrivateKey
{ {
$type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey');
if (empty($this->modulus) || empty($this->publicExponent)) { if (empty($this->modulus) || empty($this->publicExponent)) {
throw new \RuntimeException('Public key components not found'); throw new RuntimeException('Public key components not found');
} }
$key = $type::savePublicKey($this->modulus, $this->publicExponent); $key = $type::savePublicKey($this->modulus, $this->publicExponent);

View File

@ -19,6 +19,8 @@ use phpseclib3\Crypt\Hash;
use phpseclib3\Crypt\Random; use phpseclib3\Crypt\Random;
use phpseclib3\Crypt\RSA; use phpseclib3\Crypt\RSA;
use phpseclib3\Crypt\RSA\Formats\Keys\PSS; use phpseclib3\Crypt\RSA\Formats\Keys\PSS;
use phpseclib3\Exception\LengthException;
use phpseclib3\Exception\OutOfRangeException;
use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedAlgorithmException;
use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\Exception\UnsupportedFormatException;
use phpseclib3\File\ASN1; use phpseclib3\File\ASN1;
@ -47,7 +49,7 @@ class PublicKey extends RSA implements Common\PublicKey
* *
* See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}. * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}.
* *
* @return bool|\phpseclib3\Math\BigInteger * @return bool|BigInteger
*/ */
private function rsavp1(BigInteger $s) private function rsavp1(BigInteger $s)
{ {
@ -62,7 +64,7 @@ class PublicKey extends RSA implements Common\PublicKey
* *
* See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}. * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}.
* *
* @throws \LengthException if the RSA modulus is too short * @throws LengthException if the RSA modulus is too short
*/ */
private function rsassa_pkcs1_v1_5_verify(string $m, string $s): bool private function rsassa_pkcs1_v1_5_verify(string $m, string $s): bool
{ {
@ -107,7 +109,7 @@ class PublicKey extends RSA implements Common\PublicKey
} }
if ($exception) { if ($exception) {
throw new \LengthException('RSA modulus too short'); throw new LengthException('RSA modulus too short');
} }
// Compare // Compare
@ -305,7 +307,7 @@ class PublicKey extends RSA implements Common\PublicKey
* *
* @param bool $pkcs15_compat optional * @param bool $pkcs15_compat optional
* @return bool|string * @return bool|string
* @throws \LengthException if strlen($m) > $this->k - 11 * @throws LengthException if strlen($m) > $this->k - 11
*/ */
private function rsaes_pkcs1_v1_5_encrypt(string $m, bool $pkcs15_compat = false) private function rsaes_pkcs1_v1_5_encrypt(string $m, bool $pkcs15_compat = false)
{ {
@ -314,7 +316,7 @@ class PublicKey extends RSA implements Common\PublicKey
// Length checking // Length checking
if ($mLen > $this->k - 11) { if ($mLen > $this->k - 11) {
throw new \LengthException('Message too long'); throw new LengthException('Message too long');
} }
// EME-PKCS1-v1_5 encoding // EME-PKCS1-v1_5 encoding
@ -345,7 +347,7 @@ class PublicKey extends RSA implements Common\PublicKey
* See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and
* {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}. * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}.
* *
* @throws \LengthException if strlen($m) > $this->k - 2 * $this->hLen - 2 * @throws LengthException if strlen($m) > $this->k - 2 * $this->hLen - 2
*/ */
private function rsaes_oaep_encrypt(string $m): string private function rsaes_oaep_encrypt(string $m): string
{ {
@ -357,7 +359,7 @@ class PublicKey extends RSA implements Common\PublicKey
// be output. // be output.
if ($mLen > $this->k - 2 * $this->hLen - 2) { if ($mLen > $this->k - 2 * $this->hLen - 2) {
throw new \LengthException('Message too long'); throw new LengthException('Message too long');
} }
// EME-OAEP encoding // EME-OAEP encoding
@ -388,12 +390,12 @@ class PublicKey extends RSA implements Common\PublicKey
* *
* See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}. * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}.
* *
* @return bool|\phpseclib3\Math\BigInteger * @return bool|BigInteger
*/ */
private function rsaep(BigInteger $m) private function rsaep(BigInteger $m)
{ {
if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) {
throw new \OutOfRangeException('Message representative out of range'); throw new OutOfRangeException('Message representative out of range');
} }
return $this->exponentiate($m); return $this->exponentiate($m);
} }
@ -404,12 +406,12 @@ class PublicKey extends RSA implements Common\PublicKey
* Doesn't use padding and is not recommended. * Doesn't use padding and is not recommended.
* *
* @return bool|string * @return bool|string
* @throws \LengthException if strlen($m) > $this->k * @throws LengthException if strlen($m) > $this->k
*/ */
private function raw_encrypt(string $m) private function raw_encrypt(string $m)
{ {
if (strlen($m) > $this->k) { if (strlen($m) > $this->k) {
throw new \LengthException('Message too long'); throw new LengthException('Message too long');
} }
$temp = $this->os2ip($m); $temp = $this->os2ip($m);
@ -425,7 +427,7 @@ class PublicKey extends RSA implements Common\PublicKey
* be concatenated together. * be concatenated together.
* *
* @return bool|string * @return bool|string
* @throws \LengthException if the RSA modulus is too short * @throws LengthException if the RSA modulus is too short
* @see self::decrypt() * @see self::decrypt()
*/ */
public function encrypt(string $plaintext) public function encrypt(string $plaintext)

View File

@ -24,6 +24,8 @@ declare(strict_types=1);
namespace phpseclib3\Crypt; namespace phpseclib3\Crypt;
use phpseclib3\Exception\RuntimeException;
/** /**
* Pure-PHP Random Number Generator * Pure-PHP Random Number Generator
* *
@ -38,7 +40,7 @@ abstract class Random
* microoptimizations because this function has the potential of being called a huge number of times. * microoptimizations because this function has the potential of being called a huge number of times.
* eg. for RSA key generation. * eg. for RSA key generation.
* *
* @throws \RuntimeException if a symmetric cipher is needed but not loaded * @throws RuntimeException if a symmetric cipher is needed but not loaded
*/ */
public static function string(int $length): string public static function string(int $length): string
{ {
@ -160,7 +162,7 @@ abstract class Random
$crypto = new RC4(); $crypto = new RC4();
break; break;
default: default:
throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded'); throw new RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded');
} }
$crypto->setKey(substr($key, 0, $crypto->getKeyLength() >> 3)); $crypto->setKey(substr($key, 0, $crypto->getKeyLength() >> 3));

View File

@ -60,6 +60,8 @@ use phpseclib3\Exception\BadDecryptionException;
use phpseclib3\Exception\BadModeException; use phpseclib3\Exception\BadModeException;
use phpseclib3\Exception\InconsistentSetupException; use phpseclib3\Exception\InconsistentSetupException;
use phpseclib3\Exception\InsufficientSetupException; use phpseclib3\Exception\InsufficientSetupException;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Exception\LengthException;
/** /**
* Pure-PHP implementation of Rijndael. * Pure-PHP implementation of Rijndael.
@ -145,7 +147,7 @@ class Rijndael extends BlockCipher
/** /**
* Default Constructor. * Default Constructor.
* *
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided * @throws InvalidArgumentException if an invalid / unsupported mode is provided
*/ */
public function __construct(string $mode) public function __construct(string $mode)
{ {
@ -168,7 +170,7 @@ class Rijndael extends BlockCipher
* That said, if you want be compatible with other Rijndael and AES implementations, * That said, if you want be compatible with other Rijndael and AES implementations,
* you should not setKeyLength(160) or setKeyLength(224). * you should not setKeyLength(160) or setKeyLength(224).
* *
* @throws \LengthException if the key length is invalid * @throws LengthException if the key length is invalid
*/ */
public function setKeyLength(int $length): void public function setKeyLength(int $length): void
{ {
@ -181,7 +183,7 @@ class Rijndael extends BlockCipher
$this->key_length = $length >> 3; $this->key_length = $length >> 3;
break; break;
default: default:
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); throw new LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported');
} }
parent::setKeyLength($length); parent::setKeyLength($length);
@ -192,7 +194,7 @@ class Rijndael extends BlockCipher
* *
* Rijndael supports five different key lengths * Rijndael supports five different key lengths
* *
* @throws \LengthException if the key length isn't supported * @throws LengthException if the key length isn't supported
* @see setKeyLength() * @see setKeyLength()
*/ */
public function setKey(string $key): void public function setKey(string $key): void
@ -205,7 +207,7 @@ class Rijndael extends BlockCipher
case 32: case 32:
break; break;
default: default:
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 20, 24, 28 or 32 are supported'); throw new LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 20, 24, 28 or 32 are supported');
} }
parent::setKey($key); parent::setKey($key);
@ -226,7 +228,7 @@ class Rijndael extends BlockCipher
case 256: case 256:
break; break;
default: default:
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); throw new LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported');
} }
$this->Nb = $length >> 5; $this->Nb = $length >> 5;

View File

@ -19,6 +19,7 @@ use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Common\StreamCipher; use phpseclib3\Crypt\Common\StreamCipher;
use phpseclib3\Exception\BadDecryptionException; use phpseclib3\Exception\BadDecryptionException;
use phpseclib3\Exception\InsufficientSetupException; use phpseclib3\Exception\InsufficientSetupException;
use phpseclib3\Exception\LengthException;
/** /**
* Pure-PHP implementation of Salsa20. * Pure-PHP implementation of Salsa20.
@ -97,7 +98,7 @@ class Salsa20 extends StreamCipher
/** /**
* Sets the key. * Sets the key.
* *
* @throws \LengthException if the key length isn't supported * @throws LengthException if the key length isn't supported
*/ */
public function setKey(string $key): void public function setKey(string $key): void
{ {
@ -106,7 +107,7 @@ class Salsa20 extends StreamCipher
case 32: case 32:
break; break;
default: default:
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 32 are supported'); throw new LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 32 are supported');
} }
parent::setKey($key); parent::setKey($key);
@ -118,7 +119,7 @@ class Salsa20 extends StreamCipher
public function setNonce(string $nonce): void public function setNonce(string $nonce): void
{ {
if (strlen($nonce) != 8) { if (strlen($nonce) != 8) {
throw new \LengthException('Nonce of size ' . strlen($key) . ' not supported by this algorithm. Only an 64-bit nonce is supported'); throw new LengthException('Nonce of size ' . strlen($key) . ' not supported by this algorithm. Only an 64-bit nonce is supported');
} }
$this->nonce = $nonce; $this->nonce = $nonce;

View File

@ -39,6 +39,7 @@ declare(strict_types=1);
namespace phpseclib3\Crypt; namespace phpseclib3\Crypt;
use phpseclib3\Exception\BadModeException; use phpseclib3\Exception\BadModeException;
use phpseclib3\Exception\LengthException;
/** /**
* Pure-PHP implementation of Triple DES. * Pure-PHP implementation of Triple DES.
@ -192,7 +193,7 @@ class TripleDES extends DES
* *
* If you want to use a 64-bit key use DES.php * If you want to use a 64-bit key use DES.php
* *
* @throws \LengthException if the key length is invalid * @throws LengthException if the key length is invalid
* @see \phpseclib3\Crypt\Common\SymmetricKey:setKeyLength() * @see \phpseclib3\Crypt\Common\SymmetricKey:setKeyLength()
*/ */
public function setKeyLength(int $length): void public function setKeyLength(int $length): void
@ -202,7 +203,7 @@ class TripleDES extends DES
case 192: case 192:
break; break;
default: default:
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128 or 192 bits are supported'); throw new LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128 or 192 bits are supported');
} }
parent::setKeyLength($length); parent::setKeyLength($length);
@ -215,14 +216,14 @@ class TripleDES extends DES
* *
* DES also requires that every eighth bit be a parity bit, however, we'll ignore that. * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
* *
* @throws \LengthException if the key length is invalid * @throws LengthException if the key length is invalid
* @see \phpseclib3\Crypt\DES::setKey() * @see \phpseclib3\Crypt\DES::setKey()
* @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey()
*/ */
public function setKey(string $key): void public function setKey(string $key): void
{ {
if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) { if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) {
throw new \LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes'); throw new LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes');
} }
switch (strlen($key)) { switch (strlen($key)) {
@ -232,7 +233,7 @@ class TripleDES extends DES
case 24: case 24:
break; break;
default: default:
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 24 are supported'); throw new LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 24 are supported');
} }
// copied from self::setKey() // copied from self::setKey()

View File

@ -39,6 +39,7 @@ namespace phpseclib3\Crypt;
use phpseclib3\Crypt\Common\BlockCipher; use phpseclib3\Crypt\Common\BlockCipher;
use phpseclib3\Exception\BadModeException; use phpseclib3\Exception\BadModeException;
use phpseclib3\Exception\LengthException;
/** /**
* Pure-PHP implementation of Twofish. * Pure-PHP implementation of Twofish.
@ -382,7 +383,7 @@ class Twofish extends BlockCipher
case 256: case 256:
break; break;
default: default:
throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); throw new LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
} }
parent::setKeyLength($length); parent::setKeyLength($length);
@ -393,7 +394,7 @@ class Twofish extends BlockCipher
* *
* Rijndael supports five different key lengths * Rijndael supports five different key lengths
* *
* @throws \LengthException if the key length isn't supported * @throws LengthException if the key length isn't supported
* @see setKeyLength() * @see setKeyLength()
*/ */
public function setKey(string $key): void public function setKey(string $key): void
@ -404,7 +405,7 @@ class Twofish extends BlockCipher
case 32: case 32:
break; break;
default: default:
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); throw new LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
} }
parent::setKey($key); parent::setKey($key);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -142,7 +142,7 @@ class ANSI
/** /**
* Default Constructor. * Default Constructor.
* *
* @return \phpseclib3\File\ANSI * @return ANSI
*/ */
public function __construct() public function __construct()
{ {

View File

@ -23,8 +23,8 @@ declare(strict_types=1);
namespace phpseclib3\File; namespace phpseclib3\File;
use DateTime;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\File\ASN1\Element; use phpseclib3\File\ASN1\Element;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -1077,7 +1077,7 @@ abstract class ASN1
$filters = $filters[$part]; $filters = $filters[$part];
} }
if ($filters === false) { if ($filters === false) {
throw new \RuntimeException('No filters defined for ' . implode('/', $loc)); throw new RuntimeException('No filters defined for ' . implode('/', $loc));
} }
return self::encode_der($source, $filters + $mapping, null, $special); return self::encode_der($source, $filters + $mapping, null, $special);
case self::TYPE_NULL: case self::TYPE_NULL:
@ -1100,7 +1100,7 @@ abstract class ASN1
$value = $source ? "\xFF" : "\x00"; $value = $source ? "\xFF" : "\x00";
break; break;
default: default:
throw new \RuntimeException('Mapping provides no type definition for ' . implode('/', self::$location)); throw new RuntimeException('Mapping provides no type definition for ' . implode('/', self::$location));
} }
if (isset($idx)) { if (isset($idx)) {
@ -1190,7 +1190,7 @@ abstract class ASN1
$oid = $source; $oid = $source;
} }
if ($oid === false) { if ($oid === false) {
throw new \RuntimeException('Invalid OID'); throw new RuntimeException('Invalid OID');
} }
$parts = explode('.', $oid); $parts = explode('.', $oid);

View File

@ -35,7 +35,7 @@ class Element
/** /**
* Constructor * Constructor
* *
* @return \phpseclib3\File\ASN1\Element * @return Element
*/ */
public function __construct(string $encoded) public function __construct(string $encoded)
{ {

View File

@ -36,6 +36,7 @@ use phpseclib3\Crypt\PublicKeyLoader;
use phpseclib3\Crypt\Random; use phpseclib3\Crypt\Random;
use phpseclib3\Crypt\RSA; use phpseclib3\Crypt\RSA;
use phpseclib3\Crypt\RSA\Formats\Keys\PSS; use phpseclib3\Crypt\RSA\Formats\Keys\PSS;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedAlgorithmException;
use phpseclib3\File\ASN1\Element; use phpseclib3\File\ASN1\Element;
use phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1\Maps;
@ -1340,7 +1341,7 @@ class X509
* Returns true if the signature is verified and false if it is not correct. * Returns true if the signature is verified and false if it is not correct.
* If the algorithms are unsupposed an exception is thrown. * If the algorithms are unsupposed an exception is thrown.
* *
* @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported * @throws UnsupportedAlgorithmException if the algorithm is unsupported
*/ */
private function validateSignatureHelper(string $publicKeyAlgorithm, string $publicKey, string $signatureAlgorithm, string $signature, string $signatureSubject): bool private function validateSignatureHelper(string $publicKeyAlgorithm, string $publicKey, string $signatureAlgorithm, string $signature, string $signatureSubject): bool
{ {
@ -2841,7 +2842,7 @@ class X509
/** /**
* Identify signature algorithm from key settings * Identify signature algorithm from key settings
* *
* @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported * @throws UnsupportedAlgorithmException if the algorithm is unsupported
*/ */
private static function identifySignatureAlgorithm(PrivateKey $key): array private static function identifySignatureAlgorithm(PrivateKey $key): array
{ {
@ -3768,7 +3769,7 @@ class X509
public static function registerExtension(string $id, array $mapping): void public static function registerExtension(string $id, array $mapping): void
{ {
if (isset(self::$extensions[$id]) && self::$extensions[$id] !== $mapping) { if (isset(self::$extensions[$id]) && self::$extensions[$id] !== $mapping) {
throw new \RuntimeException( throw new RuntimeException(
'Extension ' . $id . ' has already been defined with a different mapping.' 'Extension ' . $id . ' has already been defined with a different mapping.'
); );
} }

View File

@ -30,6 +30,7 @@ declare(strict_types=1);
namespace phpseclib3\Math; namespace phpseclib3\Math;
use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Math\BigInteger\Engines\Engine; use phpseclib3\Math\BigInteger\Engines\Engine;
/** /**
@ -92,7 +93,7 @@ class BigInteger implements \JsonSerializable
$fqmain = 'phpseclib3\\Math\\BigInteger\\Engines\\' . $main; $fqmain = 'phpseclib3\\Math\\BigInteger\\Engines\\' . $main;
if (!class_exists($fqmain) || !method_exists($fqmain, 'isValidEngine')) { if (!class_exists($fqmain) || !method_exists($fqmain, 'isValidEngine')) {
throw new \InvalidArgumentException("$main is not a valid engine"); throw new InvalidArgumentException("$main is not a valid engine");
} }
if (!$fqmain::isValidEngine()) { if (!$fqmain::isValidEngine()) {
throw new BadConfigurationException("$main is not setup correctly on this system"); throw new BadConfigurationException("$main is not setup correctly on this system");

View File

@ -18,6 +18,8 @@ namespace phpseclib3\Math\BigInteger\Engines;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\Random; use phpseclib3\Crypt\Random;
use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
/** /**
@ -226,7 +228,7 @@ abstract class Engine implements \JsonSerializable
{ {
$fqengine = '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\' . $engine; $fqengine = '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\' . $engine;
if (!class_exists($fqengine) || !method_exists($fqengine, 'isValidEngine')) { if (!class_exists($fqengine) || !method_exists($fqengine, 'isValidEngine')) {
throw new \InvalidArgumentException("$engine is not a valid engine"); throw new InvalidArgumentException("$engine is not a valid engine");
} }
if (!$fqengine::isValidEngine()) { if (!$fqengine::isValidEngine()) {
throw new BadConfigurationException("$engine is not setup correctly on this system"); throw new BadConfigurationException("$engine is not setup correctly on this system");
@ -1130,7 +1132,7 @@ abstract class Engine implements \JsonSerializable
public function bitwise_split(int $split): array public function bitwise_split(int $split): array
{ {
if ($split < 1) { if ($split < 1) {
throw new \RuntimeException('Offset must be greater than 1'); throw new RuntimeException('Offset must be greater than 1');
} }
$mask = static::$one[static::class]->bitwise_leftShift($split)->subtract(static::$one[static::class]); $mask = static::$one[static::class]->bitwise_leftShift($split)->subtract(static::$one[static::class]);

View File

@ -16,6 +16,8 @@ declare(strict_types=1);
namespace phpseclib3\Math\BigInteger\Engines; namespace phpseclib3\Math\BigInteger\Engines;
use phpseclib3\Crypt\RSA\Formats\Keys\PKCS8; use phpseclib3\Crypt\RSA\Formats\Keys\PKCS8;
use phpseclib3\Exception\OutOfRangeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
/** /**
@ -39,7 +41,7 @@ abstract class OpenSSL
public static function powModHelper(Engine $x, Engine $e, Engine $n): Engine public static function powModHelper(Engine $x, Engine $e, Engine $n): Engine
{ {
if ($n->getLengthInBytes() < 31 || $n->getLengthInBytes() > 16384) { if ($n->getLengthInBytes() < 31 || $n->getLengthInBytes() > 16384) {
throw new \OutOfRangeException('Only modulo between 31 and 16384 bits are accepted'); throw new OutOfRangeException('Only modulo between 31 and 16384 bits are accepted');
} }
$key = PKCS8::savePublicKey( $key = PKCS8::savePublicKey(
@ -54,7 +56,7 @@ abstract class OpenSSL
// error. i suppose, for even numbers, we could do what PHP\Montgomery.php does, but then what // error. i suppose, for even numbers, we could do what PHP\Montgomery.php does, but then what
// about odd numbers divisible by 3, by 5, etc? // about odd numbers divisible by 3, by 5, etc?
if (!openssl_public_encrypt($plaintext, $result, $key, OPENSSL_NO_PADDING)) { if (!openssl_public_encrypt($plaintext, $result, $key, OPENSSL_NO_PADDING)) {
throw new \UnexpectedValueException(openssl_error_string()); throw new UnexpectedValueException(openssl_error_string());
} }
$class = $x::class; $class = $x::class;

View File

@ -17,6 +17,7 @@ namespace phpseclib3\Math\BigInteger\Engines;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\RuntimeException;
/** /**
* Pure-PHP Engine. * Pure-PHP Engine.
@ -1132,7 +1133,7 @@ abstract class PHP extends Engine
public function bitwise_split(int $split): array public function bitwise_split(int $split): array
{ {
if ($split < 1) { if ($split < 1) {
throw new \RuntimeException('Offset must be greater than 1'); throw new RuntimeException('Offset must be greater than 1');
} }
$width = (int)($split / static::BASE); $width = (int)($split / static::BASE);

View File

@ -23,6 +23,7 @@ declare(strict_types=1);
namespace phpseclib3\Math\BinaryField; namespace phpseclib3\Math\BinaryField;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\BinaryField; use phpseclib3\Math\BinaryField;
use phpseclib3\Math\Common\FiniteField\Integer as Base; use phpseclib3\Math\Common\FiniteField\Integer as Base;
@ -100,7 +101,7 @@ class Integer extends Base
private static function checkInstance(self $x, self $y): void private static function checkInstance(self $x, self $y): void
{ {
if ($x->instanceID != $y->instanceID) { if ($x->instanceID != $y->instanceID) {
throw new \UnexpectedValueException('The instances of the two BinaryField\Integer objects do not match'); throw new UnexpectedValueException('The instances of the two BinaryField\Integer objects do not match');
} }
} }

View File

@ -47,7 +47,7 @@ class PrimeField extends FiniteField
public function __construct(BigInteger $modulo) public function __construct(BigInteger $modulo)
{ {
//if (!$modulo->isPrime()) { //if (!$modulo->isPrime()) {
// throw new \UnexpectedValueException('PrimeField requires a prime number be passed to the constructor'); // throw new \phpseclib3\Exception\UnexpectedValueException('PrimeField requires a prime number be passed to the constructor');
//} //}
$this->instanceID = self::$instanceCounter++; $this->instanceID = self::$instanceCounter++;

View File

@ -15,6 +15,7 @@ declare(strict_types=1);
namespace phpseclib3\Math\PrimeField; namespace phpseclib3\Math\PrimeField;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use phpseclib3\Math\Common\FiniteField\Integer as Base; use phpseclib3\Math\Common\FiniteField\Integer as Base;
@ -118,7 +119,7 @@ class Integer extends Base
public static function checkInstance(self $x, self $y): void public static function checkInstance(self $x, self $y): void
{ {
if ($x->instanceID != $y->instanceID) { if ($x->instanceID != $y->instanceID) {
throw new \UnexpectedValueException('The instances of the two PrimeField\Integer objects do not match'); throw new UnexpectedValueException('The instances of the two PrimeField\Integer objects do not match');
} }
} }

View File

@ -36,7 +36,10 @@ declare(strict_types=1);
namespace phpseclib3\Net; namespace phpseclib3\Net;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Exception\BadFunctionCallException;
use phpseclib3\Exception\FileNotFoundException; use phpseclib3\Exception\FileNotFoundException;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Net\SFTP\Attribute; use phpseclib3\Net\SFTP\Attribute;
use phpseclib3\Net\SFTP\FileType; use phpseclib3\Net\SFTP\FileType;
use phpseclib3\Net\SFTP\OpenFlag; use phpseclib3\Net\SFTP\OpenFlag;
@ -370,7 +373,7 @@ class SFTP extends SSH2
/** /**
* Partially initialize an SFTP connection * Partially initialize an SFTP connection
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
private function partial_init_sftp_connection(): bool private function partial_init_sftp_connection(): bool
{ {
@ -439,7 +442,7 @@ class SFTP extends SSH2
$response = $this->get_sftp_packet(); $response = $this->get_sftp_packet();
if ($this->packet_type != SFTPPacketType::VERSION) { if ($this->packet_type != SFTPPacketType::VERSION) {
throw new \UnexpectedValueException('Expected PacketType::VERSION. ' throw new UnexpectedValueException('Expected PacketType::VERSION. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -506,13 +509,13 @@ class SFTP extends SSH2
$this->send_sftp_packet(SFTPPacketType::EXTENDED, $packet); $this->send_sftp_packet(SFTPPacketType::EXTENDED, $packet);
$response = $this->get_sftp_packet(); $response = $this->get_sftp_packet();
if ($this->packet_type != SFTPPacketType::STATUS) { if ($this->packet_type != SFTPPacketType::STATUS) {
throw new \UnexpectedValueException('Expected PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
[$status] = Strings::unpackSSH2('N', $response); [$status] = Strings::unpackSSH2('N', $response);
if ($status != StatusCode::OK) { if ($status != StatusCode::OK) {
$this->logError($response, $status); $this->logError($response, $status);
throw new \UnexpectedValueException('Expected StatusCode::OK. ' throw new UnexpectedValueException('Expected StatusCode::OK. '
. ' Got ' . $status); . ' Got ' . $status);
} }
break; break;
@ -652,7 +655,7 @@ class SFTP extends SSH2
* *
* If canonicalize_paths has been disabled using disablePathCanonicalization(), $path is returned as-is. * If canonicalize_paths has been disabled using disablePathCanonicalization(), $path is returned as-is.
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
* @see self::chdir() * @see self::chdir()
* @see self::disablePathCanonicalization() * @see self::disablePathCanonicalization()
*/ */
@ -707,7 +710,7 @@ class SFTP extends SSH2
$this->logError($response); $this->logError($response);
return false; return false;
default: default:
throw new \UnexpectedValueException('Expected PacketType::NAME or PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::NAME or PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
} }
@ -739,7 +742,7 @@ class SFTP extends SSH2
/** /**
* Changes the current directory * Changes the current directory
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
public function chdir(string $dir): bool public function chdir(string $dir): bool
{ {
@ -780,7 +783,7 @@ class SFTP extends SSH2
$this->logError($response); $this->logError($response);
return false; return false;
default: default:
throw new \UnexpectedValueException('Expected PacketType::HANDLE or PacketType::STATUS' . throw new UnexpectedValueException('Expected PacketType::HANDLE or PacketType::STATUS' .
'Got packet type: ' . $this->packet_type); 'Got packet type: ' . $this->packet_type);
} }
@ -880,7 +883,7 @@ class SFTP extends SSH2
* Reads a list, be it detailed or not, of files in the given directory * Reads a list, be it detailed or not, of files in the given directory
* *
* @return array|false * @return array|false
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
private function readlist(string $dir, bool $raw = true) private function readlist(string $dir, bool $raw = true)
{ {
@ -909,7 +912,7 @@ class SFTP extends SSH2
$this->logError($response); $this->logError($response);
return false; return false;
default: default:
throw new \UnexpectedValueException('Expected PacketType::HANDLE or PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::HANDLE or PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -964,7 +967,7 @@ class SFTP extends SSH2
} }
break 2; break 2;
default: default:
throw new \UnexpectedValueException('Expected PacketType::NAME or PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::NAME or PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
} }
@ -1286,7 +1289,7 @@ class SFTP extends SSH2
* The second parameter can be either PacketType::STAT or PacketType::LSTAT. * The second parameter can be either PacketType::STAT or PacketType::LSTAT.
* *
* @return array|false * @return array|false
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
private function stat_helper(string $filename, int $type) private function stat_helper(string $filename, int $type)
{ {
@ -1303,7 +1306,7 @@ class SFTP extends SSH2
return false; return false;
} }
throw new \UnexpectedValueException('Expected PacketType::ATTRS or PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::ATTRS or PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -1322,7 +1325,7 @@ class SFTP extends SSH2
* *
* If the file does not exist, it will be created. * If the file does not exist, it will be created.
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
public function touch(string $filename, int $time = null, int $atime = null): bool public function touch(string $filename, int $time = null, int $atime = null): bool
{ {
@ -1362,7 +1365,7 @@ class SFTP extends SSH2
$this->logError($response); $this->logError($response);
break; break;
default: default:
throw new \UnexpectedValueException('Expected PacketType::HANDLE or PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::HANDLE or PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -1440,7 +1443,7 @@ class SFTP extends SSH2
* Returns the new file permissions on success or false on error. * Returns the new file permissions on success or false on error.
* If $recursive is true than this just returns true or false. * If $recursive is true than this just returns true or false.
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
public function chmod(int $mode, string $filename, bool $recursive = false) public function chmod(int $mode, string $filename, bool $recursive = false)
{ {
@ -1475,14 +1478,14 @@ class SFTP extends SSH2
return false; return false;
} }
throw new \UnexpectedValueException('Expected PacketType::ATTRS or PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::ATTRS or PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
/** /**
* Sets information about a file * Sets information about a file
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
private function setstat(string $filename, string $attr, bool $recursive): bool private function setstat(string $filename, string $attr, bool $recursive): bool
{ {
@ -1519,7 +1522,7 @@ class SFTP extends SSH2
*/ */
$response = $this->get_sftp_packet(); $response = $this->get_sftp_packet();
if ($this->packet_type != SFTPPacketType::STATUS) { if ($this->packet_type != SFTPPacketType::STATUS) {
throw new \UnexpectedValueException('Expected PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -1605,7 +1608,7 @@ class SFTP extends SSH2
/** /**
* Return the target of a symbolic link * Return the target of a symbolic link
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
public function readlink(string $link) public function readlink(string $link)
{ {
@ -1625,7 +1628,7 @@ class SFTP extends SSH2
$this->logError($response); $this->logError($response);
return false; return false;
default: default:
throw new \UnexpectedValueException('Expected PacketType::NAME or PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::NAME or PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -1645,7 +1648,7 @@ class SFTP extends SSH2
* *
* symlink() creates a symbolic link to the existing target with the specified name link. * symlink() creates a symbolic link to the existing target with the specified name link.
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
public function symlink(string $target, string $link): bool public function symlink(string $target, string $link): bool
{ {
@ -1690,7 +1693,7 @@ class SFTP extends SSH2
$response = $this->get_sftp_packet(); $response = $this->get_sftp_packet();
if ($this->packet_type != SFTPPacketType::STATUS) { if ($this->packet_type != SFTPPacketType::STATUS) {
throw new \UnexpectedValueException('Expected PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -1741,7 +1744,7 @@ class SFTP extends SSH2
$response = $this->get_sftp_packet(); $response = $this->get_sftp_packet();
if ($this->packet_type != SFTPPacketType::STATUS) { if ($this->packet_type != SFTPPacketType::STATUS) {
throw new \UnexpectedValueException('Expected PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -1761,7 +1764,7 @@ class SFTP extends SSH2
/** /**
* Removes a directory. * Removes a directory.
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
public function rmdir(string $dir): bool public function rmdir(string $dir): bool
{ {
@ -1778,7 +1781,7 @@ class SFTP extends SSH2
$response = $this->get_sftp_packet(); $response = $this->get_sftp_packet();
if ($this->packet_type != SFTPPacketType::STATUS) { if ($this->packet_type != SFTPPacketType::STATUS) {
throw new \UnexpectedValueException('Expected PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -1837,9 +1840,9 @@ class SFTP extends SSH2
* {@internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib3\Net\SFTP::setMode().} * {@internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib3\Net\SFTP::setMode().}
* *
* @param resource|array|string $data * @param resource|array|string $data
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
* @throws \BadFunctionCallException if you're uploading via a callback and the callback function is invalid * @throws BadFunctionCallException if you're uploading via a callback and the callback function is invalid
* @throws \phpseclib3\Exception\FileNotFoundException if you're uploading via a file and the file doesn't exist * @throws FileNotFoundException if you're uploading via a file and the file doesn't exist
*/ */
public function put(string $remote_file, $data, int $mode = self::SOURCE_STRING, int $start = -1, int $local_start = -1, callable $progressCallback = null): bool public function put(string $remote_file, $data, int $mode = self::SOURCE_STRING, int $start = -1, int $local_start = -1, callable $progressCallback = null): bool
{ {
@ -1895,7 +1898,7 @@ class SFTP extends SSH2
$this->logError($response); $this->logError($response);
return false; return false;
default: default:
throw new \UnexpectedValueException('Expected PacketType::HANDLE or PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::HANDLE or PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -1904,7 +1907,7 @@ class SFTP extends SSH2
switch (true) { switch (true) {
case $mode & self::SOURCE_CALLBACK: case $mode & self::SOURCE_CALLBACK:
if (!is_callable($data)) { if (!is_callable($data)) {
throw new \BadFunctionCallException("\$data should be is_callable() if you specify SOURCE_CALLBACK flag"); throw new BadFunctionCallException("\$data should be is_callable() if you specify SOURCE_CALLBACK flag");
} }
$dataCallback = $data; $dataCallback = $data;
// do nothing // do nothing
@ -2011,7 +2014,7 @@ class SFTP extends SSH2
pack('N3', Attribute::ACCESSTIME, $stat['atime'], $stat['mtime']) : pack('N3', Attribute::ACCESSTIME, $stat['atime'], $stat['mtime']) :
Strings::packSSH2('NQ2', Attribute::ACCESSTIME | Attribute::MODIFYTIME, $stat['atime'], $stat['mtime']); Strings::packSSH2('NQ2', Attribute::ACCESSTIME | Attribute::MODIFYTIME, $stat['atime'], $stat['mtime']);
if (!$this->setstat($remote_file, $attr, false)) { if (!$this->setstat($remote_file, $attr, false)) {
throw new \RuntimeException('Error setting file time'); throw new RuntimeException('Error setting file time');
} }
} }
} }
@ -2025,14 +2028,14 @@ class SFTP extends SSH2
* Sending an SSH_FXP_WRITE packet and immediately reading its response isn't as efficient as blindly sending out $i * Sending an SSH_FXP_WRITE packet and immediately reading its response isn't as efficient as blindly sending out $i
* SSH_FXP_WRITEs, in succession, and then reading $i responses. * SSH_FXP_WRITEs, in succession, and then reading $i responses.
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
private function read_put_responses(int $i): bool private function read_put_responses(int $i): bool
{ {
while ($i--) { while ($i--) {
$response = $this->get_sftp_packet(); $response = $this->get_sftp_packet();
if ($this->packet_type != SFTPPacketType::STATUS) { if ($this->packet_type != SFTPPacketType::STATUS) {
throw new \UnexpectedValueException('Expected PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -2049,7 +2052,7 @@ class SFTP extends SSH2
/** /**
* Close handle * Close handle
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
private function close_handle(string $handle): bool private function close_handle(string $handle): bool
{ {
@ -2059,7 +2062,7 @@ class SFTP extends SSH2
// -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3 // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3
$response = $this->get_sftp_packet(); $response = $this->get_sftp_packet();
if ($this->packet_type != SFTPPacketType::STATUS) { if ($this->packet_type != SFTPPacketType::STATUS) {
throw new \UnexpectedValueException('Expected PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -2083,7 +2086,7 @@ class SFTP extends SSH2
* *
* @param string|bool|resource|callable $local_file * @param string|bool|resource|callable $local_file
* @return string|bool * @return string|bool
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
public function get(string $remote_file, $local_file = false, int $offset = 0, int $length = -1, callable $progressCallback = null) public function get(string $remote_file, $local_file = false, int $offset = 0, int $length = -1, callable $progressCallback = null)
{ {
@ -2111,7 +2114,7 @@ class SFTP extends SSH2
$this->logError($response); $this->logError($response);
return false; return false;
default: default:
throw new \UnexpectedValueException('Expected PacketType::HANDLE or PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::HANDLE or PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -2204,7 +2207,7 @@ class SFTP extends SSH2
$this->init_sftp_connection(); $this->init_sftp_connection();
return false; return false;
} else { } else {
throw new \UnexpectedValueException('Expected PacketType::DATA or PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::DATA or PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
} }
@ -2244,7 +2247,7 @@ class SFTP extends SSH2
/** /**
* Deletes a file on the SFTP server. * Deletes a file on the SFTP server.
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
public function delete(string $path, bool $recursive = true): bool public function delete(string $path, bool $recursive = true): bool
{ {
@ -2271,7 +2274,7 @@ class SFTP extends SSH2
$response = $this->get_sftp_packet(); $response = $this->get_sftp_packet();
if ($this->packet_type != SFTPPacketType::STATUS) { if ($this->packet_type != SFTPPacketType::STATUS) {
throw new \UnexpectedValueException('Expected PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -2432,7 +2435,7 @@ class SFTP extends SSH2
case SFTPPacketType::STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED case SFTPPacketType::STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
return false; return false;
default: default:
throw new \UnexpectedValueException('Expected PacketType::HANDLE or PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::HANDLE or PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
} }
@ -2456,7 +2459,7 @@ class SFTP extends SSH2
case SFTPPacketType::STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED case SFTPPacketType::STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
return false; return false;
default: default:
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS. ' throw new UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
} }
@ -2604,7 +2607,7 @@ class SFTP extends SSH2
* *
* If the file already exists this will return false * If the file already exists this will return false
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
*/ */
public function rename(string $oldname, string $newname): bool public function rename(string $oldname, string $newname): bool
{ {
@ -2636,7 +2639,7 @@ class SFTP extends SSH2
$response = $this->get_sftp_packet(); $response = $this->get_sftp_packet();
if ($this->packet_type != SFTPPacketType::STATUS) { if ($this->packet_type != SFTPPacketType::STATUS) {
throw new \UnexpectedValueException('Expected PacketType::STATUS. ' throw new UnexpectedValueException('Expected PacketType::STATUS. '
. 'Got packet type: ' . $this->packet_type); . 'Got packet type: ' . $this->packet_type);
} }
@ -2967,7 +2970,7 @@ class SFTP extends SSH2
$this->packet_buffer .= $temp; $this->packet_buffer .= $temp;
} }
if (strlen($this->packet_buffer) < 4) { if (strlen($this->packet_buffer) < 4) {
throw new \RuntimeException('Packet is too small'); throw new RuntimeException('Packet is too small');
} }
extract(unpack('Nlength', Strings::shift($this->packet_buffer, 4))); extract(unpack('Nlength', Strings::shift($this->packet_buffer, 4)));
/** @var integer $length */ /** @var integer $length */
@ -2977,7 +2980,7 @@ class SFTP extends SSH2
// 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h // 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h
if (!$this->allow_arbitrary_length_packets && !$this->use_request_id && $tempLength > 256 * 1024) { if (!$this->allow_arbitrary_length_packets && !$this->use_request_id && $tempLength > 256 * 1024) {
throw new \RuntimeException('Invalid Size'); throw new RuntimeException('Invalid Size');
} }
// SFTP packet type and data payload // SFTP packet type and data payload

View File

@ -66,9 +66,13 @@ use phpseclib3\Crypt\TripleDES;
use phpseclib3\Crypt\Twofish; use phpseclib3\Crypt\Twofish;
use phpseclib3\Exception\ConnectionClosedException; use phpseclib3\Exception\ConnectionClosedException;
use phpseclib3\Exception\InsufficientSetupException; use phpseclib3\Exception\InsufficientSetupException;
use phpseclib3\Exception\InvalidArgumentException;
use phpseclib3\Exception\LengthException;
use phpseclib3\Exception\LogicException;
use phpseclib3\Exception\NoSupportedAlgorithmsException; use phpseclib3\Exception\NoSupportedAlgorithmsException;
use phpseclib3\Exception\RuntimeException; use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnableToConnectException; use phpseclib3\Exception\UnableToConnectException;
use phpseclib3\Exception\UnexpectedValueException;
use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedAlgorithmException;
use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\Exception\UnsupportedCurveException;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
@ -1135,8 +1139,8 @@ class SSH2
/** /**
* Connect to an SSHv2 server * Connect to an SSHv2 server
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
* @throws \RuntimeException on other errors * @throws RuntimeException on other errors
*/ */
private function connect() private function connect()
{ {
@ -1165,7 +1169,7 @@ class SSH2
if ($this->curTimeout) { if ($this->curTimeout) {
$this->curTimeout -= $elapsed; $this->curTimeout -= $elapsed;
if ($this->curTimeout < 0) { if ($this->curTimeout < 0) {
throw new \RuntimeException('Connection timed out whilst attempting to open socket connection'); throw new RuntimeException('Connection timed out whilst attempting to open socket connection');
} }
} }
} }
@ -1189,7 +1193,7 @@ class SSH2
while (true) { while (true) {
if ($this->curTimeout) { if ($this->curTimeout) {
if ($this->curTimeout < 0) { if ($this->curTimeout < 0) {
throw new \RuntimeException('Connection timed out whilst receiving server identification string'); throw new RuntimeException('Connection timed out whilst receiving server identification string');
} }
$read = [$this->fsock]; $read = [$this->fsock];
$write = $except = null; $write = $except = null;
@ -1197,7 +1201,7 @@ class SSH2
$sec = (int) floor($this->curTimeout); $sec = (int) floor($this->curTimeout);
$usec = (int) (1000000 * ($this->curTimeout - $sec)); $usec = (int) (1000000 * ($this->curTimeout - $sec));
if (@stream_select($read, $write, $except, $sec, $usec) === false) { if (@stream_select($read, $write, $except, $sec, $usec) === false) {
throw new \RuntimeException('Connection timed out whilst receiving server identification string'); throw new RuntimeException('Connection timed out whilst receiving server identification string');
} }
$elapsed = microtime(true) - $start; $elapsed = microtime(true) - $start;
$this->curTimeout -= $elapsed; $this->curTimeout -= $elapsed;
@ -1205,7 +1209,7 @@ class SSH2
$temp = stream_get_line($this->fsock, 255, "\n"); $temp = stream_get_line($this->fsock, 255, "\n");
if ($temp === false) { if ($temp === false) {
throw new \RuntimeException('Error reading from socket'); throw new RuntimeException('Error reading from socket');
} }
if (strlen($temp) == 255) { if (strlen($temp) == 255) {
continue; continue;
@ -1260,7 +1264,7 @@ class SSH2
if (is_bool($response) || !strlen($response) || ord($response[0]) != MessageType::KEXINIT) { if (is_bool($response) || !strlen($response) || ord($response[0]) != MessageType::KEXINIT) {
$this->bitmap = 0; $this->bitmap = 0;
throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT'); throw new UnexpectedValueException('Expected SSH_MSG_KEXINIT');
} }
$this->key_exchange($response); $this->key_exchange($response);
@ -1310,9 +1314,9 @@ class SSH2
* Key Exchange * Key Exchange
* *
* @param string|bool $kexinit_payload_server optional * @param string|bool $kexinit_payload_server optional
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
* @throws \RuntimeException on other errors * @throws RuntimeException on other errors
* @throws \phpseclib3\Exception\NoSupportedAlgorithmsException when none of the algorithms phpseclib has loaded are compatible * @throws NoSupportedAlgorithmsException when none of the algorithms phpseclib has loaded are compatible
*/ */
private function key_exchange($kexinit_payload_server = false): bool private function key_exchange($kexinit_payload_server = false): bool
{ {
@ -1384,7 +1388,7 @@ class SSH2
|| ord($kexinit_payload_server[0]) != MessageType::KEXINIT || ord($kexinit_payload_server[0]) != MessageType::KEXINIT
) { ) {
$this->disconnect_helper(DisconnectReason::PROTOCOL_ERROR); $this->disconnect_helper(DisconnectReason::PROTOCOL_ERROR);
throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT'); throw new UnexpectedValueException('Expected SSH_MSG_KEXINIT');
} }
$send_kex = false; $send_kex = false;
@ -1530,7 +1534,7 @@ class SSH2
[$type, $primeBytes, $gBytes] = Strings::unpackSSH2('Css', $response); [$type, $primeBytes, $gBytes] = Strings::unpackSSH2('Css', $response);
if ($type != MessageTypeExtra::KEXDH_GEX_GROUP) { if ($type != MessageTypeExtra::KEXDH_GEX_GROUP) {
$this->disconnect_helper(DisconnectReason::PROTOCOL_ERROR); $this->disconnect_helper(DisconnectReason::PROTOCOL_ERROR);
throw new \UnexpectedValueException('Expected SSH_MSG_KEX_DH_GEX_GROUP'); throw new UnexpectedValueException('Expected SSH_MSG_KEX_DH_GEX_GROUP');
} }
$this->updateLogHistory('UNKNOWN (31)', 'SSH_MSG_KEXDH_GEX_GROUP'); $this->updateLogHistory('UNKNOWN (31)', 'SSH_MSG_KEXDH_GEX_GROUP');
$prime = new BigInteger($primeBytes, -256); $prime = new BigInteger($primeBytes, -256);
@ -1581,7 +1585,7 @@ class SSH2
if ($type != $serverKexReplyMessage) { if ($type != $serverKexReplyMessage) {
$this->disconnect_helper(DisconnectReason::PROTOCOL_ERROR); $this->disconnect_helper(DisconnectReason::PROTOCOL_ERROR);
throw new \UnexpectedValueException("Expected $serverKexReplyMessage"); throw new UnexpectedValueException("Expected $serverKexReplyMessage");
} }
switch ($serverKexReplyMessage) { switch ($serverKexReplyMessage) {
case MessageTypeExtra::KEX_ECDH_REPLY: case MessageTypeExtra::KEX_ECDH_REPLY:
@ -1594,7 +1598,7 @@ class SSH2
$this->server_public_host_key = $server_public_host_key; $this->server_public_host_key = $server_public_host_key;
[$public_key_format] = Strings::unpackSSH2('s', $server_public_host_key); [$public_key_format] = Strings::unpackSSH2('s', $server_public_host_key);
if (strlen($this->signature) < 4) { if (strlen($this->signature) < 4) {
throw new \LengthException('The signature needs at least four bytes'); throw new LengthException('The signature needs at least four bytes');
} }
$temp = unpack('Nlength', substr($this->signature, 0, 4)); $temp = unpack('Nlength', substr($this->signature, 0, 4));
$this->signature_format = substr($this->signature, 4, $temp['length']); $this->signature_format = substr($this->signature, 4, $temp['length']);
@ -1643,7 +1647,7 @@ class SSH2
case $server_host_key_algorithm != 'rsa-sha2-256' && $server_host_key_algorithm != 'rsa-sha2-512': case $server_host_key_algorithm != 'rsa-sha2-256' && $server_host_key_algorithm != 'rsa-sha2-512':
case $this->signature_format != 'ssh-rsa': case $this->signature_format != 'ssh-rsa':
$this->disconnect_helper(DisconnectReason::HOST_KEY_NOT_VERIFIABLE); $this->disconnect_helper(DisconnectReason::HOST_KEY_NOT_VERIFIABLE);
throw new \RuntimeException('Server Host Key Algorithm Mismatch (' . $this->signature_format . ' vs ' . $server_host_key_algorithm . ')'); throw new RuntimeException('Server Host Key Algorithm Mismatch (' . $this->signature_format . ' vs ' . $server_host_key_algorithm . ')');
} }
} }
@ -1660,7 +1664,7 @@ class SSH2
[$type] = Strings::unpackSSH2('C', $response); [$type] = Strings::unpackSSH2('C', $response);
if ($type != MessageType::NEWKEYS) { if ($type != MessageType::NEWKEYS) {
$this->disconnect_helper(DisconnectReason::PROTOCOL_ERROR); $this->disconnect_helper(DisconnectReason::PROTOCOL_ERROR);
throw new \UnexpectedValueException('Expected SSH_MSG_NEWKEYS'); throw new UnexpectedValueException('Expected SSH_MSG_NEWKEYS');
} }
$keyBytes = pack('Na*', strlen($keyBytes), $keyBytes); $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
@ -2010,14 +2014,14 @@ class SSH2
foreach ($args as $arg) { foreach ($args as $arg) {
switch (true) { switch (true) {
case $arg instanceof PublicKey: case $arg instanceof PublicKey:
throw new \UnexpectedValueException('A PublicKey object was passed to the login method instead of a PrivateKey object'); throw new UnexpectedValueException('A PublicKey object was passed to the login method instead of a PrivateKey object');
case $arg instanceof PrivateKey: case $arg instanceof PrivateKey:
case $arg instanceof Agent: case $arg instanceof Agent:
case is_array($arg): case is_array($arg):
case Strings::is_stringable($arg): case Strings::is_stringable($arg):
break; break;
default: default:
throw new \UnexpectedValueException('$password needs to either be an instance of \phpseclib3\Crypt\Common\PrivateKey, \System\SSH\Agent, an array or a string'); throw new UnexpectedValueException('$password needs to either be an instance of \phpseclib3\Crypt\Common\PrivateKey, \System\SSH\Agent, an array or a string');
} }
} }
@ -2088,8 +2092,8 @@ class SSH2
* {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} * {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
* by sending dummy SSH_MSG_IGNORE messages.} * by sending dummy SSH_MSG_IGNORE messages.}
* *
* @throws \UnexpectedValueException on receipt of unexpected packets * @throws UnexpectedValueException on receipt of unexpected packets
* @throws \RuntimeException on other errors * @throws RuntimeException on other errors
*/ */
private function login_helper(string $username, $password = null): bool private function login_helper(string $username, $password = null): bool
{ {
@ -2116,7 +2120,7 @@ class SSH2
[$type, $service] = Strings::unpackSSH2('Cs', $response); [$type, $service] = Strings::unpackSSH2('Cs', $response);
if ($type != MessageType::SERVICE_ACCEPT || $service != 'ssh-userauth') { if ($type != MessageType::SERVICE_ACCEPT || $service != 'ssh-userauth') {
$this->disconnect_helper(DisconnectReason::PROTOCOL_ERROR); $this->disconnect_helper(DisconnectReason::PROTOCOL_ERROR);
throw new \UnexpectedValueException('Expected SSH_MSG_SERVICE_ACCEPT'); throw new UnexpectedValueException('Expected SSH_MSG_SERVICE_ACCEPT');
} }
$this->bitmap |= self::MASK_LOGIN_REQ; $this->bitmap |= self::MASK_LOGIN_REQ;
} }
@ -2255,7 +2259,7 @@ class SSH2
/** /**
* Handle the keyboard-interactive requests / responses. * Handle the keyboard-interactive requests / responses.
* *
* @throws \RuntimeException on connection error * @throws RuntimeException on connection error
*/ */
private function keyboard_interactive_process(...$responses) private function keyboard_interactive_process(...$responses)
{ {
@ -2368,7 +2372,7 @@ class SSH2
* {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} * {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
* by sending dummy SSH_MSG_IGNORE messages.} * by sending dummy SSH_MSG_IGNORE messages.}
* *
* @throws \RuntimeException on connection error * @throws RuntimeException on connection error
*/ */
private function privatekey_login(string $username, PrivateKey $privatekey): bool private function privatekey_login(string $username, PrivateKey $privatekey): bool
{ {
@ -2530,7 +2534,7 @@ class SSH2
* *
* @return string|bool * @return string|bool
* @psalm-return ($callback is callable ? bool : string|bool) * @psalm-return ($callback is callable ? bool : string|bool)
* @throws \RuntimeException on connection error * @throws RuntimeException on connection error
*/ */
public function exec(string $command, callable $callback = null) public function exec(string $command, callable $callback = null)
{ {
@ -2543,7 +2547,7 @@ class SSH2
} }
if ($this->in_request_pty_exec) { if ($this->in_request_pty_exec) {
throw new \RuntimeException('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.'); throw new RuntimeException('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.');
} }
// RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to // RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to
@ -2590,7 +2594,7 @@ class SSH2
$this->channel_status[self::CHANNEL_EXEC] = MessageType::CHANNEL_REQUEST; $this->channel_status[self::CHANNEL_EXEC] = MessageType::CHANNEL_REQUEST;
if (!$this->get_channel_packet(self::CHANNEL_EXEC)) { if (!$this->get_channel_packet(self::CHANNEL_EXEC)) {
$this->disconnect_helper(DisconnectReason::BY_APPLICATION); $this->disconnect_helper(DisconnectReason::BY_APPLICATION);
throw new \RuntimeException('Unable to request pseudo-terminal'); throw new RuntimeException('Unable to request pseudo-terminal');
} }
$this->in_request_pty_exec = true; $this->in_request_pty_exec = true;
@ -2651,10 +2655,10 @@ class SSH2
/** /**
* Creates an interactive shell * Creates an interactive shell
* *
* @see self::read() * @throws UnexpectedValueException on receipt of unexpected packets
* @throws RuntimeException on other errors
*@see self::read()
* @see self::write() * @see self::write()
* @throws \UnexpectedValueException on receipt of unexpected packets
* @throws \RuntimeException on other errors
*/ */
private function initShell(): bool private function initShell(): bool
{ {
@ -2700,7 +2704,7 @@ class SSH2
$this->channel_status[self::CHANNEL_SHELL] = MessageType::CHANNEL_REQUEST; $this->channel_status[self::CHANNEL_SHELL] = MessageType::CHANNEL_REQUEST;
if (!$this->get_channel_packet(self::CHANNEL_SHELL)) { if (!$this->get_channel_packet(self::CHANNEL_SHELL)) {
throw new \RuntimeException('Unable to request pty'); throw new RuntimeException('Unable to request pty');
} }
$packet = Strings::packSSH2( $packet = Strings::packSSH2(
@ -2714,7 +2718,7 @@ class SSH2
$response = $this->get_channel_packet(self::CHANNEL_SHELL); $response = $this->get_channel_packet(self::CHANNEL_SHELL);
if ($response === false) { if ($response === false) {
throw new \RuntimeException('Unable to request shell'); throw new RuntimeException('Unable to request shell');
} }
$this->channel_status[self::CHANNEL_SHELL] = MessageType::CHANNEL_DATA; $this->channel_status[self::CHANNEL_SHELL] = MessageType::CHANNEL_DATA;
@ -2797,7 +2801,7 @@ class SSH2
* if $mode == self::READ_REGEX, a regular expression. * if $mode == self::READ_REGEX, a regular expression.
* *
* @return string|bool|null * @return string|bool|null
* @throws \RuntimeException on connection error * @throws RuntimeException on connection error
* @see self::write() * @see self::write()
*/ */
public function read(string $expect = '', int $mode = self::READ_SIMPLE) public function read(string $expect = '', int $mode = self::READ_SIMPLE)
@ -2810,7 +2814,7 @@ class SSH2
} }
if (!($this->bitmap & self::MASK_SHELL) && !$this->initShell()) { if (!($this->bitmap & self::MASK_SHELL) && !$this->initShell()) {
throw new \RuntimeException('Unable to initiate an interactive shell session'); throw new RuntimeException('Unable to initiate an interactive shell session');
} }
$channel = $this->get_interactive_channel(); $channel = $this->get_interactive_channel();
@ -2842,7 +2846,7 @@ class SSH2
/** /**
* Inputs a command into an interactive shell. * Inputs a command into an interactive shell.
* *
* @throws \RuntimeException on connection error * @throws RuntimeException on connection error
* @see SSH2::read() * @see SSH2::read()
*/ */
public function write(string $cmd): void public function write(string $cmd): void
@ -2852,7 +2856,7 @@ class SSH2
} }
if (!($this->bitmap & self::MASK_SHELL) && !$this->initShell()) { if (!($this->bitmap & self::MASK_SHELL) && !$this->initShell()) {
throw new \RuntimeException('Unable to initiate an interactive shell session'); throw new RuntimeException('Unable to initiate an interactive shell session');
} }
$this->send_channel_packet($this->get_interactive_channel(), $cmd); $this->send_channel_packet($this->get_interactive_channel(), $cmd);
@ -3065,7 +3069,7 @@ class SSH2
{ {
if ($skip_channel_filter) { if ($skip_channel_filter) {
if (!is_resource($this->fsock)) { if (!is_resource($this->fsock)) {
throw new \InvalidArgumentException('fsock is not a resource.'); throw new InvalidArgumentException('fsock is not a resource.');
} }
$read = [$this->fsock]; $read = [$this->fsock];
$write = $except = null; $write = $except = null;
@ -3154,7 +3158,7 @@ class SSH2
case 'chacha20-poly1305@openssh.com': case 'chacha20-poly1305@openssh.com':
// This should be impossible, but we are checking anyway to narrow the type for Psalm. // This should be impossible, but we are checking anyway to narrow the type for Psalm.
if (!($this->decrypt instanceof ChaCha20)) { if (!($this->decrypt instanceof ChaCha20)) {
throw new \LogicException('$this->decrypt is not a ' . ChaCha20::class); throw new LogicException('$this->decrypt is not a ' . ChaCha20::class);
} }
$nonce = pack('N2', 0, $this->get_seq_no); $nonce = pack('N2', 0, $this->get_seq_no);
@ -3204,7 +3208,7 @@ class SSH2
if (strlen($raw) < 5) { if (strlen($raw) < 5) {
$this->bitmap = 0; $this->bitmap = 0;
throw new \RuntimeException('Plaintext is too short'); throw new RuntimeException('Plaintext is too short');
} }
extract(unpack('Npacket_length/Cpadding_length', Strings::shift($raw, 5))); extract(unpack('Npacket_length/Cpadding_length', Strings::shift($raw, 5)));
/** /**
@ -3232,7 +3236,7 @@ class SSH2
$hmac = stream_get_contents($this->fsock, $this->hmac_size); $hmac = stream_get_contents($this->fsock, $this->hmac_size);
if ($hmac === false || strlen($hmac) != $this->hmac_size) { if ($hmac === false || strlen($hmac) != $this->hmac_size) {
$this->disconnect_helper(DisconnectReason::MAC_ERROR); $this->disconnect_helper(DisconnectReason::MAC_ERROR);
throw new \RuntimeException('Error reading socket'); throw new RuntimeException('Error reading socket');
} }
$reconstructed = !$this->hmac_check_etm ? $reconstructed = !$this->hmac_check_etm ?
@ -3242,12 +3246,12 @@ class SSH2
$this->hmac_check->setNonce("\0\0\0\0" . pack('N', $this->get_seq_no)); $this->hmac_check->setNonce("\0\0\0\0" . pack('N', $this->get_seq_no));
if ($hmac != $this->hmac_check->hash($reconstructed)) { if ($hmac != $this->hmac_check->hash($reconstructed)) {
$this->disconnect_helper(DisconnectReason::MAC_ERROR); $this->disconnect_helper(DisconnectReason::MAC_ERROR);
throw new \RuntimeException('Invalid UMAC'); throw new RuntimeException('Invalid UMAC');
} }
} else { } else {
if ($hmac != $this->hmac_check->hash(pack('Na*', $this->get_seq_no, $reconstructed))) { if ($hmac != $this->hmac_check->hash(pack('Na*', $this->get_seq_no, $reconstructed))) {
$this->disconnect_helper(DisconnectReason::MAC_ERROR); $this->disconnect_helper(DisconnectReason::MAC_ERROR);
throw new \RuntimeException('Invalid HMAC'); throw new RuntimeException('Invalid HMAC');
} }
} }
} }
@ -3342,7 +3346,7 @@ class SSH2
$this->reset_connection(DisconnectReason::KEY_EXCHANGE_FAILED); $this->reset_connection(DisconnectReason::KEY_EXCHANGE_FAILED);
return false; return false;
} }
throw new \RuntimeException('Invalid size'); throw new RuntimeException('Invalid size');
} }
if ($adjustLength) { if ($adjustLength) {
@ -3354,7 +3358,7 @@ class SSH2
$temp = stream_get_contents($this->fsock, $remaining_length); $temp = stream_get_contents($this->fsock, $remaining_length);
if ($temp === false || feof($this->fsock)) { if ($temp === false || feof($this->fsock)) {
$this->disconnect_helper(DisconnectReason::CONNECTION_LOST); $this->disconnect_helper(DisconnectReason::CONNECTION_LOST);
throw new \RuntimeException('Error reading from socket'); throw new RuntimeException('Error reading from socket');
} }
$buffer .= $temp; $buffer .= $temp;
$remaining_length -= strlen($temp); $remaining_length -= strlen($temp);
@ -3591,7 +3595,7 @@ class SSH2
* *
* - if the channel status is CHANNEL_REQUEST and the response was CHANNEL_FAILURE * - if the channel status is CHANNEL_REQUEST and the response was CHANNEL_FAILURE
* *
* @throws \RuntimeException on connection error * @throws RuntimeException on connection error
*/ */
protected function get_channel_packet(int $client_channel, bool $skip_extended = false) protected function get_channel_packet(int $client_channel, bool $skip_extended = false)
{ {
@ -3726,11 +3730,11 @@ class SSH2
return $result; return $result;
case MessageType::CHANNEL_OPEN_FAILURE: case MessageType::CHANNEL_OPEN_FAILURE:
$this->disconnect_helper(DisconnectReason::BY_APPLICATION); $this->disconnect_helper(DisconnectReason::BY_APPLICATION);
throw new \RuntimeException('Unable to open channel'); throw new RuntimeException('Unable to open channel');
default: default:
if ($client_channel == $channel) { if ($client_channel == $channel) {
$this->disconnect_helper(DisconnectReason::BY_APPLICATION); $this->disconnect_helper(DisconnectReason::BY_APPLICATION);
throw new \RuntimeException('Unexpected response to open request'); throw new RuntimeException('Unexpected response to open request');
} }
return $this->get_channel_packet($client_channel, $skip_extended); return $this->get_channel_packet($client_channel, $skip_extended);
} }
@ -3747,7 +3751,7 @@ class SSH2
return $this->get_channel_packet($client_channel, $skip_extended); return $this->get_channel_packet($client_channel, $skip_extended);
default: default:
$this->disconnect_helper(DisconnectReason::BY_APPLICATION); $this->disconnect_helper(DisconnectReason::BY_APPLICATION);
throw new \RuntimeException('Unable to fulfill channel request'); throw new RuntimeException('Unable to fulfill channel request');
} }
case MessageType::CHANNEL_CLOSE: case MessageType::CHANNEL_CLOSE:
return $type == MessageType::CHANNEL_CLOSE ? true : $this->get_channel_packet($client_channel, $skip_extended); return $type == MessageType::CHANNEL_CLOSE ? true : $this->get_channel_packet($client_channel, $skip_extended);
@ -3801,7 +3805,7 @@ class SSH2
break; break;
default: default:
$this->disconnect_helper(DisconnectReason::BY_APPLICATION); $this->disconnect_helper(DisconnectReason::BY_APPLICATION);
throw new \RuntimeException("Error reading channel data ($type)"); throw new RuntimeException("Error reading channel data ($type)");
} }
} }
} }
@ -3889,7 +3893,7 @@ class SSH2
case 'chacha20-poly1305@openssh.com': case 'chacha20-poly1305@openssh.com':
// This should be impossible, but we are checking anyway to narrow the type for Psalm. // This should be impossible, but we are checking anyway to narrow the type for Psalm.
if (!($this->encrypt instanceof ChaCha20)) { if (!($this->encrypt instanceof ChaCha20)) {
throw new \LogicException('$this->encrypt is not a ' . ChaCha20::class); throw new LogicException('$this->encrypt is not a ' . ChaCha20::class);
} }
$nonce = pack('N2', 0, $this->send_seq_no); $nonce = pack('N2', 0, $this->send_seq_no);
@ -3950,7 +3954,7 @@ class SSH2
if (strlen($packet) != $sent) { if (strlen($packet) != $sent) {
$this->bitmap = 0; $this->bitmap = 0;
throw new \RuntimeException("Only $sent of " . strlen($packet) . " bytes were sent"); throw new RuntimeException("Only $sent of " . strlen($packet) . " bytes were sent");
} }
} }
@ -4623,8 +4627,8 @@ class SSH2
* is recommended. Returns false if the server signature is not signed correctly with the public host key. * is recommended. Returns false if the server signature is not signed correctly with the public host key.
* *
* @return string|false * @return string|false
* @throws \RuntimeException on badly formatted keys * @throws RuntimeException on badly formatted keys
* @throws \phpseclib3\Exception\NoSupportedAlgorithmsException when the key isn't in a supported format * @throws NoSupportedAlgorithmsException when the key isn't in a supported format
*/ */
public function getServerPublicHostKey() public function getServerPublicHostKey()
{ {

View File

@ -37,6 +37,7 @@ namespace phpseclib3\System\SSH;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\PublicKeyLoader; use phpseclib3\Crypt\PublicKeyLoader;
use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Exception\BadConfigurationException;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Net\SSH2; use phpseclib3\Net\SSH2;
use phpseclib3\System\SSH\Agent\Identity; use phpseclib3\System\SSH\Agent\Identity;
@ -111,9 +112,9 @@ class Agent
/** /**
* Default Constructor * Default Constructor
* *
* @return \phpseclib3\System\SSH\Agent * @return Agent
* @throws \phpseclib3\Exception\BadConfigurationException if SSH_AUTH_SOCK cannot be found * @throws BadConfigurationException if SSH_AUTH_SOCK cannot be found
* @throws \RuntimeException on connection errors * @throws RuntimeException on connection errors
*/ */
public function __construct($address = null) public function __construct($address = null)
{ {
@ -132,7 +133,7 @@ class Agent
$this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr); $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
if (!$this->fsock) { if (!$this->fsock) {
throw new \RuntimeException("Unable to connect to ssh-agent (Error $errno: $errstr)"); throw new RuntimeException("Unable to connect to ssh-agent (Error $errno: $errstr)");
} }
} }
@ -142,7 +143,7 @@ class Agent
* See "2.5.2 Requesting a list of protocol 2 keys" * See "2.5.2 Requesting a list of protocol 2 keys"
* Returns an array containing zero or more \phpseclib3\System\SSH\Agent\Identity objects * Returns an array containing zero or more \phpseclib3\System\SSH\Agent\Identity objects
* *
* @throws \RuntimeException on receipt of unexpected packets * @throws RuntimeException on receipt of unexpected packets
*/ */
public function requestIdentities(): array public function requestIdentities(): array
{ {
@ -152,7 +153,7 @@ class Agent
$packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES); $packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES);
if (strlen($packet) != fwrite($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');
} }
$length = current(unpack('N', $this->readBytes(4))); $length = current(unpack('N', $this->readBytes(4)));
@ -160,7 +161,7 @@ class Agent
[$type, $keyCount] = Strings::unpackSSH2('CN', $packet); [$type, $keyCount] = Strings::unpackSSH2('CN', $packet);
if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) { if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) {
throw new \RuntimeException('Unable to request identities'); throw new RuntimeException('Unable to request identities');
} }
$identities = []; $identities = [];
@ -233,7 +234,7 @@ class Agent
* Forward data to SSH Agent and return data reply * Forward data to SSH Agent and return data reply
* *
* @return string Data from SSH Agent * @return string Data from SSH Agent
* @throws \RuntimeException on connection errors * @throws RuntimeException on connection errors
*/ */
public function forwardData(string $data) public function forwardData(string $data)
{ {
@ -251,7 +252,7 @@ class Agent
} }
if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) { if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) {
throw new \RuntimeException('Connection closed attempting to forward data to SSH agent'); throw new RuntimeException('Connection closed attempting to forward data to SSH agent');
} }
$this->socket_buffer = ''; $this->socket_buffer = '';

View File

@ -23,6 +23,7 @@ use phpseclib3\Crypt\Common\PublicKey;
use phpseclib3\Crypt\DSA; use phpseclib3\Crypt\DSA;
use phpseclib3\Crypt\EC; use phpseclib3\Crypt\EC;
use phpseclib3\Crypt\RSA; use phpseclib3\Crypt\RSA;
use phpseclib3\Exception\RuntimeException;
use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedAlgorithmException;
use phpseclib3\System\SSH\Agent; use phpseclib3\System\SSH\Agent;
use phpseclib3\System\SSH\Common\Traits\ReadBytes; use phpseclib3\System\SSH\Common\Traits\ReadBytes;
@ -250,8 +251,8 @@ class Identity implements PrivateKey
* See "2.6.2 Protocol 2 private key signature request" * See "2.6.2 Protocol 2 private key signature request"
* *
* @param string $message * @param string $message
* @throws \RuntimeException on connection errors * @throws RuntimeException on connection errors
* @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported * @throws UnsupportedAlgorithmException if the algorithm is unsupported
*/ */
public function sign($message): string public function sign($message): string
{ {
@ -265,7 +266,7 @@ class Identity implements PrivateKey
); );
$packet = Strings::packSSH2('s', $packet); $packet = Strings::packSSH2('s', $packet);
if (strlen($packet) != fwrite($this->fsock, $packet)) { if (strlen($packet) != fwrite($this->fsock, $packet)) {
throw new \RuntimeException('Connection closed during signing'); throw new RuntimeException('Connection closed during signing');
} }
$length = current(unpack('N', $this->readBytes(4))); $length = current(unpack('N', $this->readBytes(4)));
@ -273,7 +274,7 @@ class Identity implements PrivateKey
[$type, $signature_blob] = Strings::unpackSSH2('Cs', $packet); [$type, $signature_blob] = Strings::unpackSSH2('Cs', $packet);
if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) { if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) {
throw new \RuntimeException('Unable to retrieve signature'); throw new RuntimeException('Unable to retrieve signature');
} }
if (!$this->key instanceof RSA) { if (!$this->key instanceof RSA) {
@ -292,7 +293,7 @@ class Identity implements PrivateKey
*/ */
public function toString(string $type, array $options = []): string public function toString(string $type, array $options = []): string
{ {
throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key'); throw new RuntimeException('ssh-agent does not provide a mechanism to get the private key');
} }
/** /**
@ -302,6 +303,6 @@ class Identity implements PrivateKey
*/ */
public function withPassword(?string $password = null): PrivateKey public function withPassword(?string $password = null): PrivateKey
{ {
throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key'); throw new RuntimeException('ssh-agent does not provide a mechanism to get the private key');
} }
} }

View File

@ -15,6 +15,8 @@ declare(strict_types=1);
namespace phpseclib3\System\SSH\Common\Traits; namespace phpseclib3\System\SSH\Common\Traits;
use phpseclib3\Exception\RuntimeException;
/** /**
* ReadBytes trait * ReadBytes trait
* *
@ -25,16 +27,16 @@ trait ReadBytes
/** /**
* Read data * Read data
* *
* @throws \RuntimeException on connection errors * @throws RuntimeException on connection errors
*/ */
public function readBytes(int $length): string public function readBytes(int $length): string
{ {
$temp = fread($this->fsock, $length); $temp = fread($this->fsock, $length);
if ($temp === false) { if ($temp === false) {
throw new \RuntimeException('\fread() failed.'); throw new RuntimeException('\fread() failed.');
} }
if (strlen($temp) !== $length) { if (strlen($temp) !== $length) {
throw new \RuntimeException("Expected $length bytes; got " . strlen($temp)); throw new RuntimeException("Expected $length bytes; got " . strlen($temp));
} }
return $temp; return $temp;
} }

View File

@ -11,6 +11,7 @@ declare(strict_types=1);
namespace phpseclib3\Tests\Functional\Net; namespace phpseclib3\Tests\Functional\Net;
use phpseclib3\Net\SFTP\Stream; use phpseclib3\Net\SFTP\Stream;
use phpseclib3\Net\SSH2;
class SFTPStreamTest extends SFTPTestCase class SFTPStreamTest extends SFTPTestCase
{ {
@ -52,10 +53,10 @@ class SFTPStreamTest extends SFTPTestCase
*/ */
public function testConnectionReuse(): void public function testConnectionReuse(): void
{ {
$originalConnectionsCount = count(\phpseclib3\Net\SSH2::getConnections()); $originalConnectionsCount = count(SSH2::getConnections());
$session = $this->sftp; $session = $this->sftp;
$dirs = scandir("sftp://$session/"); $dirs = scandir("sftp://$session/");
$this->assertCount($originalConnectionsCount, \phpseclib3\Net\SSH2::getConnections()); $this->assertCount($originalConnectionsCount, SSH2::getConnections());
$this->assertEquals(['.', '..'], array_slice($dirs, 0, 2)); $this->assertEquals(['.', '..'], array_slice($dirs, 0, 2));
} }

View File

@ -6,13 +6,14 @@ namespace phpseclib3\Tests\Unit\Crypt\EC;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\EC\Curves\Ed448; use phpseclib3\Crypt\EC\Curves\Ed448;
use phpseclib3\Exception\UnexpectedValueException;
class Ed448PrivateKey class Ed448PrivateKey
{ {
public static function load($key, ?string $password = null): array public static function load($key, ?string $password = null): array
{ {
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
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 = ['curve' => new Ed448()]; $components = ['curve' => new Ed448()];

View File

@ -7,6 +7,7 @@ namespace phpseclib3\Tests\Unit\Crypt\EC;
use phpseclib3\Common\Functions\Strings; use phpseclib3\Common\Functions\Strings;
use phpseclib3\Crypt\EC\Curves\Ed448; use phpseclib3\Crypt\EC\Curves\Ed448;
use phpseclib3\Crypt\EC\Formats\Keys\Common; use phpseclib3\Crypt\EC\Formats\Keys\Common;
use phpseclib3\Exception\UnexpectedValueException;
class Ed448PublicKey class Ed448PublicKey
{ {
@ -15,7 +16,7 @@ class Ed448PublicKey
public static function load($key, ?string $password = null): array public static function load($key, ?string $password = null): array
{ {
if (!Strings::is_stringable($key)) { if (!Strings::is_stringable($key)) {
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 = ['curve' => new Ed448()]; $components = ['curve' => new Ed448()];

View File

@ -12,7 +12,6 @@ namespace phpseclib3\Tests\Unit\File\X509;
use phpseclib3\Crypt\RSA; use phpseclib3\Crypt\RSA;
use phpseclib3\File\X509; use phpseclib3\File\X509;
use phpseclib3\Math\BigInteger;
use phpseclib3\Tests\PhpseclibTestCase; use phpseclib3\Tests\PhpseclibTestCase;
class CRLTest extends PhpseclibTestCase class CRLTest extends PhpseclibTestCase

View File

@ -10,6 +10,7 @@ declare(strict_types=1);
namespace phpseclib3\Tests\Unit\Net; namespace phpseclib3\Tests\Unit\Net;
use phpseclib3\Net\SSH2;
use phpseclib3\Tests\PhpseclibTestCase; use phpseclib3\Tests\PhpseclibTestCase;
class SSH2UnitTest extends PhpseclibTestCase class SSH2UnitTest extends PhpseclibTestCase
@ -113,19 +114,19 @@ class SSH2UnitTest extends PhpseclibTestCase
public function testGetConnectionByResourceId(): void public function testGetConnectionByResourceId(): void
{ {
$ssh = new \phpseclib3\Net\SSH2('localhost'); $ssh = new SSH2('localhost');
$this->assertSame($ssh, \phpseclib3\Net\SSH2::getConnectionByResourceId($ssh->getResourceId())); $this->assertSame($ssh, SSH2::getConnectionByResourceId($ssh->getResourceId()));
} }
public function testGetResourceId(): void public function testGetResourceId(): void
{ {
$ssh = new \phpseclib3\Net\SSH2('localhost'); $ssh = new SSH2('localhost');
$this->assertSame('{' . spl_object_hash($ssh) . '}', $ssh->getResourceId()); $this->assertSame('{' . spl_object_hash($ssh) . '}', $ssh->getResourceId());
} }
/** /**
*/ */
protected function createSSHMock(): \phpseclib3\Net\SSH2 protected function createSSHMock(): SSH2
{ {
return $this->getMockBuilder('phpseclib3\Net\SSH2') return $this->getMockBuilder('phpseclib3\Net\SSH2')
->disableOriginalConstructor() ->disableOriginalConstructor()