diff --git a/.travis.yml b/.travis.yml
index 3fb1d730..452b9a0e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,13 +1,12 @@
language: php
-# When adding environments here, the number of runs specified in .scrutinizer.yml
-# may have to be adjusted.
php:
- 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
+ - 7.0
- hhvm
env:
@@ -22,7 +21,7 @@ install:
- sudo apt-get install parallel
- eval `ssh-agent -s`
- travis/setup-secure-shell.sh
- - sh -c "if [ '$TRAVIS_PHP_VERSION' != 'hhvm' ]; then travis/install-php-extensions.sh; fi"
+ - sh -c "if [ '$TRAVIS_PHP_VERSION' != 'hhvm' -a '$TRAVIS_PHP_VERSION' != '7.0' ]; then travis/install-php-extensions.sh; fi"
- travis/setup-composer.sh
script:
@@ -31,3 +30,8 @@ script:
after_success:
- sh -c "if $TRAVIS_SECURE_ENV_VARS; then travis/upload-code-coverage-html.sh; fi"
+
+matrix:
+ allow_failures:
+ - php: 7.0
+ fast_finish: true
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2dd2c096..f0b03dc7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,21 @@
# Changelog
+## 1.0.0 - 2015-08-02
+
+- OpenSSL support for symmetric ciphers ([#507](https://github.com/phpseclib/phpseclib/pull/507))
+- rewritten vt100 terminal emulator (File_ANSI) ([#689](https://github.com/phpseclib/phpseclib/pull/689))
+- agent-forwarding support (System_SSH_Agent) ([#592](https://github.com/phpseclib/phpseclib/pull/592))
+- Net_SSH2 improvements
+ - diffie-hellman-group-exchange-sha1/sha256 support ([#714](https://github.com/phpseclib/phpseclib/pull/714))
+ - window size handling updates ([#717](https://github.com/phpseclib/phpseclib/pull/717))
+- Net_SFTP improvements
+ - add callback support to put() ([#655](https://github.com/phpseclib/phpseclib/pull/655))
+ - stat cache fixes ([#743](https://github.com/phpseclib/phpseclib/issues/743), [#730](https://github.com/phpseclib/phpseclib/issues/730), [#709](https://github.com/phpseclib/phpseclib/issues/709), [#726](https://github.com/phpseclib/phpseclib/issues/726))
+- add "none" encryption mode to Crypt_RSA ([#692](https://github.com/phpseclib/phpseclib/pull/692))
+- misc ASN.1 / X.509 parsing fixes ([#721](https://github.com/phpseclib/phpseclib/pull/721), [#627](https://github.com/phpseclib/phpseclib/pull/627))
+- use a random serial number for new X509 certs ([#740](https://github.com/phpseclib/phpseclib/pull/740))
+- add getPublicKeyFingerprint() to Crypt_RSA ([#677](https://github.com/phpseclib/phpseclib/pull/677))
+
## 0.3.10 - 2015-02-04
- simplify SSH2 window size handling ([#538](https://github.com/phpseclib/phpseclib/pull/538))
diff --git a/README.md b/README.md
index bb738a57..b75a6b66 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ MIT-licensed pure-PHP implementations of an arbitrary-precision integer
arithmetic library, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael,
AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509
-* [Download (0.3.10)](http://sourceforge.net/projects/phpseclib/files/phpseclib0.3.10.zip/download)
+* [Download (1.0.0)](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.0.zip/download)
* [Browse Git](https://github.com/phpseclib/phpseclib)
* [Code Coverage Report](http://phpseclib.bantux.org/code_coverage/php5/latest/)
diff --git a/build/code-sniffer-ruleset-tests.xml b/build/code-sniffer-ruleset-tests.xml
index f30722f7..7169012e 100644
--- a/build/code-sniffer-ruleset-tests.xml
+++ b/build/code-sniffer-ruleset-tests.xml
@@ -5,20 +5,12 @@
-
+
-
-
-
-
-
-
-
-
-
+
+
+
diff --git a/build/code-sniffer-ruleset.xml b/build/code-sniffer-ruleset.xml
index f6bf92c7..2e399139 100644
--- a/build/code-sniffer-ruleset.xml
+++ b/build/code-sniffer-ruleset.xml
@@ -3,35 +3,25 @@
phpseclib coding standard
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -42,46 +32,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/composer.json b/composer.json
index a81b0caf..db9e3031 100644
--- a/composer.json
+++ b/composer.json
@@ -52,13 +52,14 @@
"phing/phing": "~2.7",
"phpunit/phpunit": "~4.0",
"sami/sami": "~2.0",
- "squizlabs/php_codesniffer": "~1.5"
+ "squizlabs/php_codesniffer": "~2.0"
},
"suggest": {
- "ext-mcrypt": "Install the Mcrypt extension in order to speed up a wide variety of cryptographic operations.",
+ "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
+ "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.",
+ "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
"ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations."
},
- "include-path": ["phpseclib/"],
"autoload": {
"psr-4": {
"phpseclib\\": "phpseclib/"
diff --git a/composer.lock b/composer.lock
index 7561de0f..daed47bf 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1,10 +1,10 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
- "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "1973a3fc1c8f678a9cd0ff646f7a8bee",
+ "hash": "3c1701cdae74c93eba5311e59f11cdb6",
"packages": [],
"packages-dev": [
{
@@ -1201,32 +1201,31 @@
},
{
"name": "squizlabs/php_codesniffer",
- "version": "1.5.6",
+ "version": "2.3.3",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "6f3e42d311b882b25b4d409d23a289f4d3b803d5"
+ "reference": "c1a26c729508f73560c1a4f767f60b8ab6b4a666"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/6f3e42d311b882b25b4d409d23a289f4d3b803d5",
- "reference": "6f3e42d311b882b25b4d409d23a289f4d3b803d5",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/c1a26c729508f73560c1a4f767f60b8ab6b4a666",
+ "reference": "c1a26c729508f73560c1a4f767f60b8ab6b4a666",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
"php": ">=5.1.2"
},
- "suggest": {
- "phpunit/php-timer": "dev-master"
- },
"bin": [
- "scripts/phpcs"
+ "scripts/phpcs",
+ "scripts/phpcbf"
],
"type": "library",
"extra": {
"branch-alias": {
- "dev-phpcs-fixer": "2.0.x-dev"
+ "dev-master": "2.0.x-dev"
}
},
"autoload": {
@@ -1235,12 +1234,12 @@
"CodeSniffer/CLI.php",
"CodeSniffer/Exception.php",
"CodeSniffer/File.php",
+ "CodeSniffer/Fixer.php",
"CodeSniffer/Report.php",
"CodeSniffer/Reporting.php",
"CodeSniffer/Sniff.php",
"CodeSniffer/Tokens.php",
"CodeSniffer/Reports/",
- "CodeSniffer/CommentParser/",
"CodeSniffer/Tokenizers/",
"CodeSniffer/DocGenerators/",
"CodeSniffer/Standards/AbstractPatternSniff.php",
@@ -1266,13 +1265,13 @@
"role": "lead"
}
],
- "description": "PHP_CodeSniffer tokenises PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
+ "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
"homepage": "http://www.squizlabs.com/php-codesniffer",
"keywords": [
"phpcs",
"standards"
],
- "time": "2014-12-04 22:32:15"
+ "time": "2015-06-24 03:16:23"
},
{
"name": "symfony/console",
diff --git a/phpseclib/Crypt/AES.php b/phpseclib/Crypt/AES.php
index e206653a..2696e0ab 100644
--- a/phpseclib/Crypt/AES.php
+++ b/phpseclib/Crypt/AES.php
@@ -7,7 +7,7 @@
*
* PHP version 5
*
- * NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
+ * NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
* just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
* to save one include_once().
*
diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php
index 2021c00c..7096b662 100644
--- a/phpseclib/Crypt/Base.php
+++ b/phpseclib/Crypt/Base.php
@@ -707,7 +707,7 @@ abstract class Base
$iv = substr_replace($iv, $block, 0, $overflow);
$ciphertext.= $block;
$pos = $overflow;
- } else if ($len) {
+ } elseif ($len) {
$ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
$iv = substr($ciphertext, -$this->block_size);
}
@@ -1014,7 +1014,7 @@ abstract class Base
$plaintext.= $iv ^ substr($ciphertext, -$overflow);
$iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow);
$pos = $overflow;
- } else if ($len) {
+ } elseif ($len) {
$plaintext.= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
$iv = substr($ciphertext, -$this->block_size);
}
@@ -1290,7 +1290,7 @@ abstract class Base
$buffer['ciphertext'] = substr($temp, $overflow);
$encryptIV = $temp;
}
- } else if (!strlen($buffer['ciphertext'])) {
+ } elseif (!strlen($buffer['ciphertext'])) {
$ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
$temp = $this->_string_pop($ciphertext, $block_size);
if ($this->continuousBuffer) {
diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php
index b8169f7a..d748f1a5 100644
--- a/phpseclib/Crypt/DES.php
+++ b/phpseclib/Crypt/DES.php
@@ -1378,7 +1378,6 @@ class DES extends Base
// Creating code for en- and decryption.
$crypt_block = array();
foreach (array(self::ENCRYPT, self::DECRYPT) as $c) {
-
/* Do the initial IP permutation. */
$crypt_block[$c] = '
$in = unpack("N*", $in);
diff --git a/phpseclib/Crypt/Hash.php b/phpseclib/Crypt/Hash.php
index 647ca969..14b8a32a 100644
--- a/phpseclib/Crypt/Hash.php
+++ b/phpseclib/Crypt/Hash.php
@@ -139,7 +139,7 @@ class Hash
*/
function __construct($hash = 'sha1')
{
- if ( !defined('CRYPT_HASH_MODE') ) {
+ if (!defined('CRYPT_HASH_MODE')) {
switch (true) {
case extension_loaded('hash'):
define('CRYPT_HASH_MODE', self::MODE_HASH);
@@ -228,7 +228,7 @@ class Hash
$mode = CRYPT_HASH_MODE;
}
- switch ( $mode ) {
+ switch ($mode) {
case self::MODE_MHASH:
switch ($hash) {
case 'md5':
@@ -262,26 +262,26 @@ class Hash
switch ($hash) {
case 'md2':
- $this->b = 16;
- $this->hash = array($this, '_md2');
- break;
+ $this->b = 16;
+ $this->hash = array($this, '_md2');
+ break;
case 'md5':
- $this->b = 64;
- $this->hash = array($this, '_md5');
- break;
+ $this->b = 64;
+ $this->hash = array($this, '_md5');
+ break;
case 'sha256':
- $this->b = 64;
- $this->hash = array($this, '_sha256');
- break;
+ $this->b = 64;
+ $this->hash = array($this, '_sha256');
+ break;
case 'sha384':
case 'sha512':
- $this->b = 128;
- $this->hash = array($this, '_sha512');
- break;
+ $this->b = 128;
+ $this->hash = array($this, '_sha512');
+ break;
case 'sha1':
default:
- $this->b = 64;
- $this->hash = array($this, '_sha1');
+ $this->b = 64;
+ $this->hash = array($this, '_sha1');
}
$this->ipad = str_repeat(chr(0x36), $this->b);
@@ -300,7 +300,7 @@ class Hash
$mode = is_array($this->hash) ? self::MODE_INTERNAL : CRYPT_HASH_MODE;
if (!empty($this->key) || is_string($this->key)) {
- switch ( $mode ) {
+ switch ($mode) {
case self::MODE_MHASH:
$output = mhash($this->hash, $text, $this->key);
break;
@@ -323,7 +323,7 @@ class Hash
$output = call_user_func($this->hash, $output); // step 7
}
} else {
- switch ( $mode ) {
+ switch ($mode) {
case self::MODE_MHASH:
$output = mhash($this->hash, $text);
break;
@@ -497,12 +497,14 @@ class Hash
// Extend the sixteen 32-bit words into sixty-four 32-bit words
for ($i = 16; $i < 64; $i++) {
+ // @codingStandardsIgnoreStart
$s0 = $this->_rightRotate($w[$i - 15], 7) ^
$this->_rightRotate($w[$i - 15], 18) ^
$this->_rightShift( $w[$i - 15], 3);
$s1 = $this->_rightRotate($w[$i - 2], 17) ^
$this->_rightRotate($w[$i - 2], 19) ^
$this->_rightShift( $w[$i - 2], 10);
+ // @codingStandardsIgnoreEnd
$w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
}
diff --git a/phpseclib/Crypt/RC2.php b/phpseclib/Crypt/RC2.php
index 1a0c53d6..58351759 100644
--- a/phpseclib/Crypt/RC2.php
+++ b/phpseclib/Crypt/RC2.php
@@ -316,7 +316,7 @@ class RC2 extends Base
if ($t1 <= 0) {
$t1 = $this->default_key_length;
- } else if ($t1 > 1024) {
+ } elseif ($t1 > 1024) {
$t1 = 1024;
}
$this->current_key_length = $t1;
diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php
index 86b89dbc..9edb9f61 100644
--- a/phpseclib/Crypt/RSA.php
+++ b/phpseclib/Crypt/RSA.php
@@ -465,7 +465,7 @@ class RSA
{
$this->configFile = dirname(__FILE__) . '/../openssl.cnf';
- if ( !defined('CRYPT_RSA_MODE') ) {
+ if (!defined('CRYPT_RSA_MODE')) {
switch (true) {
// Math/BigInteger's openssl requirements are a little less stringent than Crypt/RSA's. in particular,
// Math/BigInteger doesn't require an openssl.cfg file whereas Crypt/RSA does. so if Math/BigInteger
@@ -558,7 +558,7 @@ class RSA
}
// OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum
- if ( CRYPT_RSA_MODE == self::MODE_OPENSSL && $bits >= 384 && CRYPT_RSA_EXPONENT == 65537) {
+ if (CRYPT_RSA_MODE == self::MODE_OPENSSL && $bits >= 384 && CRYPT_RSA_EXPONENT == 65537) {
$config = array();
if (isset($this->configFile)) {
$config['config'] = $this->configFile;
@@ -572,7 +572,8 @@ class RSA
$publickey = call_user_func_array(array($this, '_convertPublicKey'), array_values($this->_parseKey($publickey, self::PUBLIC_FORMAT_PKCS1)));
// clear the buffer of error strings stemming from a minimalistic openssl.cnf
- while (openssl_error_string() !== false);
+ while (openssl_error_string() !== false) {
+ }
return array(
'privatekey' => $privatekey,
@@ -762,19 +763,39 @@ class RSA
$encryption = (!empty($this->password) || is_string($this->password)) ? 'aes256-cbc' : 'none';
$key.= $encryption;
$key.= "\r\nComment: " . $this->comment . "\r\n";
- $public = pack('Na*Na*Na*',
- strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']
+ $public = pack(
+ 'Na*Na*Na*',
+ strlen('ssh-rsa'),
+ 'ssh-rsa',
+ strlen($raw['publicExponent']),
+ $raw['publicExponent'],
+ strlen($raw['modulus']),
+ $raw['modulus']
);
- $source = pack('Na*Na*Na*Na*',
- strlen('ssh-rsa'), 'ssh-rsa', strlen($encryption), $encryption,
- strlen($this->comment), $this->comment, strlen($public), $public
+ $source = pack(
+ 'Na*Na*Na*Na*',
+ strlen('ssh-rsa'),
+ 'ssh-rsa',
+ strlen($encryption),
+ $encryption,
+ strlen($this->comment),
+ $this->comment,
+ strlen($public),
+ $public
);
$public = base64_encode($public);
$key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n";
$key.= chunk_split($public, 64);
- $private = pack('Na*Na*Na*Na*',
- strlen($raw['privateExponent']), $raw['privateExponent'], strlen($raw['prime1']), $raw['prime1'],
- strlen($raw['prime2']), $raw['prime2'], strlen($raw['coefficient']), $raw['coefficient']
+ $private = pack(
+ 'Na*Na*Na*Na*',
+ strlen($raw['privateExponent']),
+ $raw['privateExponent'],
+ strlen($raw['prime1']),
+ $raw['prime1'],
+ strlen($raw['prime2']),
+ $raw['prime2'],
+ strlen($raw['coefficient']),
+ $raw['coefficient']
);
if (empty($this->password) && !is_string($this->password)) {
$source.= pack('Na*', strlen($private), $private);
@@ -835,8 +856,14 @@ class RSA
if ($this->privateKeyFormat == self::PRIVATE_FORMAT_PKCS8) {
$rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
- $RSAPrivateKey = pack('Ca*a*Ca*a*',
- self::ASN1_INTEGER, "\01\00", $rsaOID, 4, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey
+ $RSAPrivateKey = pack(
+ 'Ca*a*Ca*a*',
+ self::ASN1_INTEGER,
+ "\01\00",
+ $rsaOID,
+ 4,
+ $this->_encodeLength(strlen($RSAPrivateKey)),
+ $RSAPrivateKey
);
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
if (!empty($this->password) || is_string($this->password)) {
@@ -847,20 +874,35 @@ class RSA
$crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount);
$RSAPrivateKey = $crypto->encrypt($RSAPrivateKey);
- $parameters = pack('Ca*a*Ca*N',
- self::ASN1_OCTETSTRING, $this->_encodeLength(strlen($salt)), $salt,
- self::ASN1_INTEGER, $this->_encodeLength(4), $iterationCount
+ $parameters = pack(
+ 'Ca*a*Ca*N',
+ self::ASN1_OCTETSTRING,
+ $this->_encodeLength(strlen($salt)),
+ $salt,
+ self::ASN1_INTEGER,
+ $this->_encodeLength(4),
+ $iterationCount
);
$pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03";
- $encryptionAlgorithm = pack('Ca*a*Ca*a*',
- self::ASN1_OBJECT, $this->_encodeLength(strlen($pbeWithMD5AndDES_CBC)), $pbeWithMD5AndDES_CBC,
- self::ASN1_SEQUENCE, $this->_encodeLength(strlen($parameters)), $parameters
+ $encryptionAlgorithm = pack(
+ 'Ca*a*Ca*a*',
+ self::ASN1_OBJECT,
+ $this->_encodeLength(strlen($pbeWithMD5AndDES_CBC)),
+ $pbeWithMD5AndDES_CBC,
+ self::ASN1_SEQUENCE,
+ $this->_encodeLength(strlen($parameters)),
+ $parameters
);
- $RSAPrivateKey = pack('Ca*a*Ca*a*',
- self::ASN1_SEQUENCE, $this->_encodeLength(strlen($encryptionAlgorithm)), $encryptionAlgorithm,
- self::ASN1_OCTETSTRING, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey
+ $RSAPrivateKey = pack(
+ 'Ca*a*Ca*a*',
+ self::ASN1_SEQUENCE,
+ $this->_encodeLength(strlen($encryptionAlgorithm)),
+ $encryptionAlgorithm,
+ self::ASN1_OCTETSTRING,
+ $this->_encodeLength(strlen($RSAPrivateKey)),
+ $RSAPrivateKey
);
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
@@ -944,9 +986,12 @@ class RSA
'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($publicExponent)), $publicExponent)
);
- $RSAPublicKey = pack('Ca*a*a*',
- self::ASN1_SEQUENCE, $this->_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
- $components['modulus'], $components['publicExponent']
+ $RSAPublicKey = pack(
+ 'Ca*a*a*',
+ self::ASN1_SEQUENCE,
+ $this->_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
+ $components['modulus'],
+ $components['publicExponent']
);
if ($this->publicKeyFormat == self::PUBLIC_FORMAT_PKCS1_RAW) {
@@ -959,8 +1004,11 @@ class RSA
$RSAPublicKey = chr(0) . $RSAPublicKey;
$RSAPublicKey = chr(3) . $this->_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
- $RSAPublicKey = pack('Ca*a*',
- self::ASN1_SEQUENCE, $this->_encodeLength(strlen($rsaOID . $RSAPublicKey)), $rsaOID . $RSAPublicKey
+ $RSAPublicKey = pack(
+ 'Ca*a*',
+ self::ASN1_SEQUENCE,
+ $this->_encodeLength(strlen($rsaOID . $RSAPublicKey)),
+ $rsaOID . $RSAPublicKey
);
$RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
@@ -1734,8 +1782,7 @@ class RSA
$RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
- switch($algorithm)
- {
+ switch ($algorithm) {
case 'sha256':
$hash = new Hash('sha256');
$base = base64_encode($hash->hash($RSAPublicKey));
@@ -1861,7 +1908,7 @@ class RSA
function _decodeLength(&$string)
{
$length = ord($this->_string_shift($string));
- if ( $length & 0x80 ) { // definite length, long form
+ if ($length & 0x80) { // definite length, long form
$length&= 0x7F;
$temp = $this->_string_shift($string, $length);
list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
@@ -2518,7 +2565,7 @@ class RSA
// be output.
$emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8)
- $sLen = $this->sLen === false ? $this->hLen : $this->sLen;
+ $sLen = $this->sLen ? $this->sLen : $this->hLen;
$mHash = $this->hash->hash($m);
if ($emLen < $this->hLen + $sLen + 2) {
@@ -2555,7 +2602,7 @@ class RSA
// be output.
$emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8);
- $sLen = $this->sLen === false ? $this->hLen : $this->sLen;
+ $sLen = $this->sLen ? $this->sLen : $this->hLen;
$mHash = $this->hash->hash($m);
if ($emLen < $this->hLen + $sLen + 2) {
diff --git a/phpseclib/Crypt/Random.php b/phpseclib/Crypt/Random.php
index 1bcffe4d..e6269035 100644
--- a/phpseclib/Crypt/Random.php
+++ b/phpseclib/Crypt/Random.php
@@ -158,9 +158,9 @@ class Random
ini_set('session.use_cookies', $old_use_cookies);
session_cache_limiter($old_session_cache_limiter);
} else {
- if ($_OLD_SESSION !== false) {
- $_SESSION = $_OLD_SESSION;
- unset($_OLD_SESSION);
+ if ($_OLD_SESSION !== false) {
+ $_SESSION = $_OLD_SESSION;
+ unset($_OLD_SESSION);
} else {
unset($_SESSION);
}
diff --git a/phpseclib/Crypt/Rijndael.php b/phpseclib/Crypt/Rijndael.php
index 29d37f25..90c75d83 100644
--- a/phpseclib/Crypt/Rijndael.php
+++ b/phpseclib/Crypt/Rijndael.php
@@ -311,7 +311,7 @@ class Rijndael extends Base
$length >>= 5;
if ($length > 8) {
$length = 8;
- } else if ($length < 4) {
+ } elseif ($length < 4) {
$length = 4;
}
$this->Nb = $length;
@@ -614,7 +614,7 @@ class Rijndael extends Base
// with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.
$temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord
$temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk];
- } else if ($this->Nk > 6 && $i % $this->Nk == 4) {
+ } elseif ($this->Nk > 6 && $i % $this->Nk == 4) {
$temp = $this->_subWord($temp);
}
$w[$i] = $w[$i - $this->Nk] ^ $temp;
diff --git a/phpseclib/Crypt/Twofish.php b/phpseclib/Crypt/Twofish.php
index 517aeb49..9c32de67 100644
--- a/phpseclib/Crypt/Twofish.php
+++ b/phpseclib/Crypt/Twofish.php
@@ -533,7 +533,9 @@ class Twofish extends Base
$u^= 0x7fffffff & ($t >> 1);
// Add the modular polynomial on underflow.
- if ($t & 0x01) $u^= 0xa6 ;
+ if ($t & 0x01) {
+ $u^= 0xa6 ;
+ }
// Remove t * (a + 1/a) * (x^3 + x).
$B^= ($u << 24) | ($u << 8);
diff --git a/phpseclib/File/ANSI.php b/phpseclib/File/ANSI.php
index 2d03a199..1daf787a 100644
--- a/phpseclib/File/ANSI.php
+++ b/phpseclib/File/ANSI.php
@@ -337,6 +337,7 @@ class ANSI
//$back = $attr_cell->reverse ? &$attr_cell->foreground : &$attr_cell->background;
$back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' };
switch ($mod) {
+ // @codingStandardsIgnoreStart
case 30: $front = 'black'; break;
case 31: $front = 'red'; break;
case 32: $front = 'green'; break;
@@ -354,6 +355,7 @@ class ANSI
case 45: $back = 'magenta'; break;
case 46: $back = 'cyan'; break;
case 47: $back = 'white'; break;
+ // @codingStandardsIgnoreEnd
default:
//user_error('Unsupported attribute: ' . $mod);
diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php
index acfa5be8..fa58ec7f 100644
--- a/phpseclib/File/ASN1.php
+++ b/phpseclib/File/ASN1.php
@@ -245,17 +245,17 @@ class ASN1
$tag <<= 7;
$tag |= ord($this->_string_shift($encoded)) & 0x7F;
$start++;
- } while ( $loop );
+ } while ($loop);
}
// Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13
$length = ord($this->_string_shift($encoded));
$start++;
- if ( $length == 0x80 ) { // indefinite length
+ if ($length == 0x80) { // indefinite length
// "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all
// immediately available." -- paragraph 8.1.3.2.c
$length = strlen($encoded);
- } elseif ( $length & 0x80 ) { // definite length, long form
+ } elseif ($length & 0x80) { // definite length, long form
// technically, the long form of the length can be represented by up to 126 octets (bytes), but we'll only
// support it up to four.
$length&= 0x7F;
@@ -1028,7 +1028,7 @@ class ASN1
if ($outtype !== false) {
return $this->_encode_der($source[$typename], array('type' => $outtype) + $mapping, null, $special);
}
- }
+ }
$filters = $this->filters;
foreach ($loc as $part) {
diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php
index b50e7247..cbe16bae 100644
--- a/phpseclib/File/X509.php
+++ b/phpseclib/File/X509.php
@@ -28,6 +28,7 @@ namespace phpseclib\File;
use phpseclib\Crypt\Hash;
use phpseclib\Crypt\RSA;
+use phpseclib\Crypt\Random;
use phpseclib\File\ASN1;
use phpseclib\File\ASN1\Element;
use phpseclib\Math\BigInteger;
@@ -2502,7 +2503,7 @@ class X509
$asn1->loadFilters($filters);
$result = '';
foreach ($dn['rdnSequence'] as $rdn) {
- foreach ($rdn as $i=>$attr) {
+ foreach ($rdn as $i => $attr) {
$attr = &$rdn[$i];
if (is_array($attr['value'])) {
foreach ($attr['value'] as $type => $v) {
@@ -2723,7 +2724,7 @@ class X509
break;
}
}
- foreach ($chain as $key=>$value) {
+ foreach ($chain as $key => $value) {
$chain[$key] = new X509();
$chain[$key]->loadX509($value);
}
@@ -3179,9 +3180,9 @@ class X509
{
$year = @gmdate("Y", @strtotime($date)); // the same way ASN1.php parses this
if ($year < 2050) {
- return array('utcTime' => $date);
+ return array('utcTime' => $date);
} else {
- return array('generalTime' => $date);
+ return array('generalTime' => $date);
}
}
@@ -3235,7 +3236,7 @@ class X509
if (isset($subject->domains)) {
$this->removeExtension('id-ce-subjectAltName');
}
- } else if (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertList'])) {
+ } elseif (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertList'])) {
return false;
} else {
if (!isset($subject->publicKey)) {
@@ -3244,7 +3245,16 @@ class X509
$startDate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
$endDate = !empty($this->endDate) ? $this->endDate : @date('D, d M Y H:i:s O', strtotime('+1 year'));
- $serialNumber = !empty($this->serialNumber) ? $this->serialNumber : new BigInteger();
+ /* "The serial number MUST be a positive integer"
+ "Conforming CAs MUST NOT use serialNumber values longer than 20 octets."
+ -- https://tools.ietf.org/html/rfc5280#section-4.1.2.2
+
+ for the integer to be positive the leading bit needs to be 0 hence the
+ application of a bitmap
+ */
+ $serialNumber = !empty($this->serialNumber) ?
+ $this->serialNumber :
+ new BigInteger(Random::string(20) & ("\x7F" . str_repeat("\xFF", 19)), 256);
$this->currentCert = array(
'tbsCertificate' =>
@@ -3260,8 +3270,8 @@ class X509
'subject' => $subject->dn,
'subjectPublicKeyInfo' => $subjectPublicKey
),
- 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
- 'signature' => false // this is going to be overwritten later
+ 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+ 'signature' => false // this is going to be overwritten later
);
// Copy extensions from CSR.
@@ -3282,8 +3292,7 @@ class X509
// )
//),
'keyIdentifier' => $issuer->currentKeyIdentifier
- )
- );
+ ));
//$extensions = &$this->currentCert['tbsCertificate']['extensions'];
//if (isset($issuer->serialNumber)) {
// $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber;
@@ -3326,7 +3335,8 @@ class X509
$keyUsage = array();
}
- $this->setExtension('id-ce-keyUsage',
+ $this->setExtension(
+ 'id-ce-keyUsage',
array_values(array_unique(array_merge($keyUsage, array('cRLSign', 'keyCertSign'))))
);
@@ -3335,8 +3345,11 @@ class X509
$basicConstraints = array();
}
- $this->setExtension('id-ce-basicConstraints',
- array_unique(array_merge(array('cA' => true), $basicConstraints)), true);
+ $this->setExtension(
+ 'id-ce-basicConstraints',
+ array_unique(array_merge(array('cA' => true), $basicConstraints)),
+ true
+ );
if (!isset($subject->currentKeyIdentifier)) {
$this->setExtension('id-ce-subjectKeyIdentifier', base64_encode($this->computeKeyIdentifier($this->currentCert)), false, false);
@@ -3396,8 +3409,8 @@ class X509
'subject' => $this->dn,
'subjectPKInfo' => $publicKey
),
- 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
- 'signature' => false // this is going to be overwritten later
+ 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+ 'signature' => false // this is going to be overwritten later
);
}
@@ -3461,8 +3474,8 @@ class X509
// Random::string(8) & str_repeat("\x7F", 8)
'challenge' => !empty($this->challenge) ? $this->challenge : ''
),
- 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
- 'signature' => false // this is going to be overwritten later
+ 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+ 'signature' => false // this is going to be overwritten later
);
}
@@ -3514,8 +3527,8 @@ class X509
'issuer' => false, // this is going to be overwritten later
'thisUpdate' => $this->_timeField($thisUpdate) // $this->setStartDate()
),
- 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
- 'signature' => false // this is going to be overwritten later
+ 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+ 'signature' => false // this is going to be overwritten later
);
}
@@ -3533,6 +3546,11 @@ class X509
$crlNumber = $this->serialNumber;
} else {
$crlNumber = $this->getExtension('id-ce-cRLNumber');
+ // "The CRL number is a non-critical CRL extension that conveys a
+ // monotonically increasing sequence number for a given CRL scope and
+ // CRL issuer. This extension allows users to easily determine when a
+ // particular CRL supersedes another CRL."
+ // -- https://tools.ietf.org/html/rfc5280#section-5.2.3
$crlNumber = $crlNumber !== false ? $crlNumber->add(new BigInteger(1)) : null;
}
@@ -3571,8 +3589,7 @@ class X509
// )
//),
'keyIdentifier' => $issuer->currentKeyIdentifier
- )
- );
+ ));
//$extensions = &$tbsCertList['crlExtensions'];
//if (isset($issuer->serialNumber)) {
// $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber;
@@ -4354,7 +4371,6 @@ class X509
if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) {
if ($this->_revokedCertificate($rclist, $serial) === false) { // If not yet revoked
if (($i = $this->_revokedCertificate($rclist, $serial, true)) !== false) {
-
if (!empty($date)) {
$rclist[$i]['revocationDate'] = $this->_timeField($date);
}
diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php
index 21e0fafc..bc7b2269 100644
--- a/phpseclib/Math/BigInteger.php
+++ b/phpseclib/Math/BigInteger.php
@@ -258,7 +258,7 @@ class BigInteger
*/
function __construct($x = 0, $base = 10)
{
- if ( !defined('MATH_BIGINTEGER_MODE') ) {
+ if (!defined('MATH_BIGINTEGER_MODE')) {
switch (true) {
case extension_loaded('gmp'):
define('MATH_BIGINTEGER_MODE', self::MODE_GMP);
@@ -334,7 +334,7 @@ class BigInteger
}
}
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
switch (true) {
case is_resource($x) && get_resource_type($x) == 'GMP integer':
@@ -364,8 +364,8 @@ class BigInteger
$x = ~$x;
$this->is_negative = true;
}
- case 256:
- switch ( MATH_BIGINTEGER_MODE ) {
+ case 256:
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
$sign = $this->is_negative ? '-' : '';
$this->value = gmp_init($sign . '0x' . bin2hex($x));
@@ -401,7 +401,7 @@ class BigInteger
$this->value = $temp->value;
}
break;
- case 16:
+ case 16:
case -16:
if ($base > 0 && $x[0] == '-') {
$this->is_negative = true;
@@ -416,7 +416,7 @@ class BigInteger
$x = bin2hex(~pack('H*', $x));
}
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
$temp = $this->is_negative ? '-0x' . $x : '0x' . $x;
$this->value = gmp_init($temp);
@@ -439,14 +439,14 @@ class BigInteger
$this->value = $temp->value;
}
break;
- case 10:
+ case 10:
case -10:
// (?value = gmp_init($x);
break;
@@ -476,7 +476,7 @@ class BigInteger
$this->value = $temp->value;
}
break;
- case 2: // base-2 support originally implemented by Lluis Pamies - thanks!
+ case 2: // base-2 support originally implemented by Lluis Pamies - thanks!
case -2:
if ($base > 0 && $x[0] == '-') {
$this->is_negative = true;
@@ -549,7 +549,7 @@ class BigInteger
return $comparison < 0 ? ~$bytes : $bytes;
}
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
if (gmp_cmp($this->value, gmp_init(0)) == 0) {
return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
@@ -684,7 +684,7 @@ class BigInteger
*/
function toString()
{
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
return gmp_strval($this->value);
case self::MODE_BCMATH:
@@ -838,7 +838,7 @@ class BigInteger
*/
function add($y)
{
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
$temp = new static();
$temp->value = gmp_add($this->value, $y->value);
@@ -880,7 +880,7 @@ class BigInteger
self::VALUE => $y_value,
self::SIGN => $y_negative
);
- } else if ($y_size == 0) {
+ } elseif ($y_size == 0) {
return array(
self::VALUE => $x_value,
self::SIGN => $x_negative
@@ -888,8 +888,8 @@ class BigInteger
}
// subtract, if appropriate
- if ( $x_negative != $y_negative ) {
- if ( $x_value == $y_value ) {
+ if ($x_negative != $y_negative) {
+ if ($x_value == $y_value) {
return array(
self::VALUE => array(),
self::SIGN => false
@@ -967,7 +967,7 @@ class BigInteger
*/
function subtract($y)
{
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
$temp = new static();
$temp->value = gmp_sub($this->value, $y->value);
@@ -1009,7 +1009,7 @@ class BigInteger
self::VALUE => $y_value,
self::SIGN => !$y_negative
);
- } else if ($y_size == 0) {
+ } elseif ($y_size == 0) {
return array(
self::VALUE => $x_value,
self::SIGN => $x_negative
@@ -1017,7 +1017,7 @@ class BigInteger
}
// add, if appropriate (ie. -$x - +$y or +$x - -$y)
- if ( $x_negative != $y_negative ) {
+ if ($x_negative != $y_negative) {
$temp = $this->_add($x_value, false, $y_value, false);
$temp[self::SIGN] = $x_negative;
@@ -1026,7 +1026,7 @@ class BigInteger
$diff = $this->_compare($x_value, $x_negative, $y_value, $y_negative);
- if ( !$diff ) {
+ if (!$diff) {
return array(
self::VALUE => array(),
self::SIGN => false
@@ -1034,7 +1034,7 @@ class BigInteger
}
// switch $x and $y around, if appropriate.
- if ( (!$x_negative && $diff < 0) || ($x_negative && $diff > 0) ) {
+ if ((!$x_negative && $diff < 0) || ($x_negative && $diff > 0)) {
$temp = $x_value;
$x_value = $y_value;
$y_value = $temp;
@@ -1100,7 +1100,7 @@ class BigInteger
*/
function multiply($x)
{
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
$temp = new static();
$temp->value = gmp_mul($this->value, $x->value);
@@ -1144,7 +1144,7 @@ class BigInteger
$x_length = count($x_value);
$y_length = count($y_value);
- if ( !$x_length || !$y_length ) { // a 0 is being multiplied
+ if (!$x_length || !$y_length) { // a 0 is being multiplied
return array(
self::VALUE => array(),
self::SIGN => false
@@ -1174,11 +1174,11 @@ class BigInteger
$x_length = count($x_value);
$y_length = count($y_value);
- if ( !$x_length || !$y_length ) { // a 0 is being multiplied
+ if (!$x_length || !$y_length) { // a 0 is being multiplied
return array();
}
- if ( $x_length < $y_length ) {
+ if ($x_length < $y_length) {
$temp = $x_value;
$x_value = $y_value;
$y_value = $temp;
@@ -1291,7 +1291,7 @@ class BigInteger
*/
function _baseSquare($value)
{
- if ( empty($value) ) {
+ if (empty($value)) {
return array();
}
$square_value = $this->_array_repeat(0, 2 * count($value));
@@ -1385,7 +1385,7 @@ class BigInteger
*/
function divide($y)
{
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
$quotient = new static();
$remainder = new static();
@@ -1422,7 +1422,7 @@ class BigInteger
}
static $zero;
- if ( !isset($zero) ) {
+ if (!isset($zero)) {
$zero = new static();
}
@@ -1436,16 +1436,16 @@ class BigInteger
$diff = $x->compare($y);
- if ( !$diff ) {
+ if (!$diff) {
$temp = new static();
$temp->value = array(1);
$temp->is_negative = $x_sign != $y_sign;
return array($this->_normalize($temp), $this->_normalize(new static()));
}
- if ( $diff < 0 ) {
+ if ($diff < 0) {
// if $x is negative, "add" $y.
- if ( $x_sign ) {
+ if ($x_sign) {
$x = $y->subtract($x);
}
return array($this->_normalize(new static()), $this->_normalize($x));
@@ -1479,7 +1479,7 @@ class BigInteger
// $temp = $y << ($x_max - $y_max-1) in base 2**26
$temp_value = array_merge($this->_array_repeat(0, $x_max - $y_max), $y_value);
- while ( $x->compare($temp) >= 0 ) {
+ while ($x->compare($temp) >= 0) {
// calculate the "common residue"
++$quotient_value[$x_max - $y_max];
$x = $x->subtract($temp);
@@ -1515,7 +1515,7 @@ class BigInteger
$rhs_value = array($x_window[2], $x_window[1], $x_window[0]);
- while ( $lhs->compare($rhs) > 0 ) {
+ while ($lhs->compare($rhs) > 0) {
--$quotient_value[$q_index];
$lhs->value = array($quotient_value[$q_index]);
@@ -1546,7 +1546,7 @@ class BigInteger
$quotient->is_negative = $x_sign != $y_sign;
// calculate the "common residue", if appropriate
- if ( $x_sign ) {
+ if ($x_sign) {
$y->_rshift($shift);
$x = $y->subtract($x);
}
@@ -1633,7 +1633,7 @@ class BigInteger
return $this->_normalize($temp->modPow($e, $n));
}
- if ( MATH_BIGINTEGER_MODE == self::MODE_GMP ) {
+ if (MATH_BIGINTEGER_MODE == self::MODE_GMP) {
$temp = new static();
$temp->value = gmp_powm($this->value, $e->value, $n->value);
@@ -1656,17 +1656,23 @@ class BigInteger
'publicExponent' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['publicExponent'])), $components['publicExponent'])
);
- $RSAPublicKey = pack('Ca*a*a*',
- 48, $this->_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])),
- $components['modulus'], $components['publicExponent']
+ $RSAPublicKey = pack(
+ 'Ca*a*a*',
+ 48,
+ $this->_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])),
+ $components['modulus'],
+ $components['publicExponent']
);
$rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
$RSAPublicKey = chr(0) . $RSAPublicKey;
$RSAPublicKey = chr(3) . $this->_encodeASN1Length(strlen($RSAPublicKey)) . $RSAPublicKey;
- $encapsulated = pack('Ca*a*',
- 48, $this->_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)), $rsaOID . $RSAPublicKey
+ $encapsulated = pack(
+ 'Ca*a*',
+ 48,
+ $this->_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)),
+ $rsaOID . $RSAPublicKey
);
$RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
@@ -1680,25 +1686,25 @@ class BigInteger
}
}
- if ( MATH_BIGINTEGER_MODE == self::MODE_BCMATH ) {
+ if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
$temp = new static();
$temp->value = bcpowmod($this->value, $e->value, $n->value, 0);
return $this->_normalize($temp);
}
- if ( empty($e->value) ) {
+ if (empty($e->value)) {
$temp = new static();
$temp->value = array(1);
return $this->_normalize($temp);
}
- if ( $e->value == array(1) ) {
+ if ($e->value == array(1)) {
list(, $temp) = $this->divide($n);
return $this->_normalize($temp);
}
- if ( $e->value == array(2) ) {
+ if ($e->value == array(2)) {
$temp = new static();
$temp->value = $this->_square($this->value);
list(, $temp) = $temp->divide($n);
@@ -1713,14 +1719,14 @@ class BigInteger
// made uncallable
// is the modulo odd?
- if ( $n->value[0] & 1 ) {
+ if ($n->value[0] & 1) {
return $this->_normalize($this->_slidingWindow($e, $n, self::MONTGOMERY));
}
// if it's not, it's even
// find the lowest set bit (eg. the max pow of 2 that divides $n)
for ($i = 0; $i < count($n->value); ++$i) {
- if ( $n->value[$i] ) {
+ if ($n->value[$i]) {
$temp = decbin($n->value[$i]);
$j = strlen($temp) - strrpos($temp, '1') - 1;
$j+= 26 * $i;
@@ -1798,7 +1804,8 @@ class BigInteger
// calculate the appropriate window size.
// $window_size == 3 if $window_ranges is between 25 and 81, for example.
- for ($i = 0, $window_size = 1; $e_length > $window_ranges[$i] && $i < count($window_ranges); ++$window_size, ++$i);
+ for ($i = 0, $window_size = 1; $e_length > $window_ranges[$i] && $i < count($window_ranges); ++$window_size, ++$i) {
+ }
$n_value = $n->value;
@@ -1818,13 +1825,13 @@ class BigInteger
$result = array(1);
$result = $this->_prepareReduce($result, $n_value, $mode);
- for ($i = 0; $i < $e_length; ) {
- if ( !$e_bits[$i] ) {
+ for ($i = 0; $i < $e_length;) {
+ if (!$e_bits[$i]) {
$result = $this->_squareReduce($result, $n_value, $mode);
++$i;
} else {
for ($j = $window_size - 1; $j > 0; --$j) {
- if ( !empty($e_bits[$i + $j]) ) {
+ if (!empty($e_bits[$i + $j])) {
break;
}
}
@@ -2008,7 +2015,7 @@ class BigInteger
// n = 2 * m.length
- if ( ($key = array_search($m, $cache[self::VARIABLE])) === false ) {
+ if (($key = array_search($m, $cache[self::VARIABLE])) === false) {
$key = count($cache[self::VARIABLE]);
$cache[self::VARIABLE][] = $m;
@@ -2097,7 +2104,7 @@ class BigInteger
return $temp->value;
}
- if ( ($key = array_search($n, $cache[self::VARIABLE])) === false ) {
+ if (($key = array_search($n, $cache[self::VARIABLE])) === false) {
$key = count($cache[self::VARIABLE]);
$cache[self::VARIABLE][] = $n;
$lhs = new static();
@@ -2158,14 +2165,14 @@ class BigInteger
$x_length = count($x_value);
$y_length = count($y_value);
- if ( !$x_length || !$y_length ) { // a 0 is being multiplied
+ if (!$x_length || !$y_length) { // a 0 is being multiplied
return array(
self::VALUE => array(),
self::SIGN => false
);
}
- if ( $x_length < $y_length ) {
+ if ($x_length < $y_length) {
$temp = $x_value;
$x_value = $y_value;
$y_value = $temp;
@@ -2239,7 +2246,7 @@ class BigInteger
self::DATA => array()
);
- if ( ($key = array_search($n, $cache[self::VARIABLE])) === false ) {
+ if (($key = array_search($n, $cache[self::VARIABLE])) === false) {
$key = count($cache[self::VARIABLE]);
$cache[self::VARIABLE][] = $x;
$cache[self::DATA][] = $this->_modInverse67108864($n);
@@ -2295,7 +2302,7 @@ class BigInteger
self::DATA => array()
);
- if ( ($key = array_search($m, $cache[self::VARIABLE])) === false ) {
+ if (($key = array_search($m, $cache[self::VARIABLE])) === false) {
$key = count($cache[self::VARIABLE]);
$cache[self::VARIABLE][] = $m;
$cache[self::DATA][] = $this->_modInverse67108864($m);
@@ -2408,7 +2415,7 @@ class BigInteger
*/
function modInverse($n)
{
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
$temp = new static();
$temp->value = gmp_invert($this->value, $n->value);
@@ -2472,7 +2479,7 @@ class BigInteger
*/
function extendedGCD($n)
{
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
extract(gmp_gcdext($this->value, $n->value));
@@ -2522,7 +2529,7 @@ class BigInteger
$g = new static();
$g->value = array(1);
- while ( !(($x->value[0] & 1)|| ($y->value[0] & 1)) ) {
+ while (!(($x->value[0] & 1)|| ($y->value[0] & 1))) {
$x->_rshift(1);
$y->_rshift(1);
$g->_lshift(1);
@@ -2539,10 +2546,10 @@ class BigInteger
$a->value = $d->value = $g->value = array(1);
$b->value = $c->value = array();
- while ( !empty($u->value) ) {
- while ( !($u->value[0] & 1) ) {
+ while (!empty($u->value)) {
+ while (!($u->value[0] & 1)) {
$u->_rshift(1);
- if ( (!empty($a->value) && ($a->value[0] & 1)) || (!empty($b->value) && ($b->value[0] & 1)) ) {
+ if ((!empty($a->value) && ($a->value[0] & 1)) || (!empty($b->value) && ($b->value[0] & 1))) {
$a = $a->add($y);
$b = $b->subtract($x);
}
@@ -2550,9 +2557,9 @@ class BigInteger
$b->_rshift(1);
}
- while ( !($v->value[0] & 1) ) {
+ while (!($v->value[0] & 1)) {
$v->_rshift(1);
- if ( (!empty($d->value) && ($d->value[0] & 1)) || (!empty($c->value) && ($c->value[0] & 1)) ) {
+ if ((!empty($d->value) && ($d->value[0] & 1)) || (!empty($c->value) && ($c->value[0] & 1))) {
$c = $c->add($y);
$d = $d->subtract($x);
}
@@ -2615,7 +2622,7 @@ class BigInteger
{
$temp = new static();
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
$temp->value = gmp_abs($this->value);
break;
@@ -2649,7 +2656,7 @@ class BigInteger
*/
function compare($y)
{
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
return gmp_cmp($this->value, $y->value);
case self::MODE_BCMATH:
@@ -2672,13 +2679,13 @@ class BigInteger
*/
function _compare($x_value, $x_negative, $y_value, $y_negative)
{
- if ( $x_negative != $y_negative ) {
+ if ($x_negative != $y_negative) {
return ( !$x_negative && $y_negative ) ? 1 : -1;
}
$result = $x_negative ? -1 : 1;
- if ( count($x_value) != count($y_value) ) {
+ if (count($x_value) != count($y_value)) {
return ( count($x_value) > count($y_value) ) ? $result : -$result;
}
$size = max(count($x_value), count($y_value));
@@ -2707,7 +2714,7 @@ class BigInteger
*/
function equals($x)
{
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
return gmp_cmp($this->value, $x->value) == 0;
default:
@@ -2727,7 +2734,7 @@ class BigInteger
function setPrecision($bits)
{
$this->precision = $bits;
- if ( MATH_BIGINTEGER_MODE != self::MODE_BCMATH ) {
+ if (MATH_BIGINTEGER_MODE != self::MODE_BCMATH) {
$this->bitmask = new static(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256);
} else {
$this->bitmask = new static(bcpow('2', $bits, 0));
@@ -2747,7 +2754,7 @@ class BigInteger
*/
function bitwise_and($x)
{
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
$temp = new static();
$temp->value = gmp_and($this->value, $x->value);
@@ -2788,7 +2795,7 @@ class BigInteger
*/
function bitwise_or($x)
{
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
$temp = new static();
$temp->value = gmp_or($this->value, $x->value);
@@ -2828,7 +2835,7 @@ class BigInteger
*/
function bitwise_xor($x)
{
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
$temp = new static();
$temp->value = gmp_xor($this->value, $x->value);
@@ -2908,7 +2915,7 @@ class BigInteger
{
$temp = new static();
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
static $two;
@@ -2946,7 +2953,7 @@ class BigInteger
{
$temp = new static();
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
static $two;
@@ -2985,7 +2992,7 @@ class BigInteger
if ($this->precision > 0) {
$precision = $this->precision;
- if ( MATH_BIGINTEGER_MODE == self::MODE_BCMATH ) {
+ if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
$mask = $this->bitmask->subtract(new static(1));
$mask = $mask->toBytes();
} else {
@@ -2993,7 +3000,8 @@ class BigInteger
}
} else {
$temp = ord($bits[0]);
- for ($i = 0; $temp >> $i; ++$i);
+ for ($i = 0; $temp >> $i; ++$i) {
+ }
$precision = 8 * strlen($bits) - 8 + $i;
$mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3);
}
@@ -3092,7 +3100,7 @@ class BigInteger
if (!$compare) {
return $this->_normalize($min);
- } else if ($compare < 0) {
+ } elseif ($compare < 0) {
// if $min is bigger then $max, swap $min and $max
$temp = $max;
$max = $min;
@@ -3173,7 +3181,7 @@ class BigInteger
if (!$compare) {
return $min->isPrime() ? $min : false;
- } else if ($compare < 0) {
+ } elseif ($compare < 0) {
// if $min is bigger then $max, swap $min and $max
$temp = $max;
$max = $min;
@@ -3191,7 +3199,7 @@ class BigInteger
$x = $this->random($min, $max);
// gmp_nextprime() requires PHP 5 >= 5.2.0 per .
- if ( MATH_BIGINTEGER_MODE == self::MODE_GMP && function_exists('gmp_nextprime') ) {
+ if (MATH_BIGINTEGER_MODE == self::MODE_GMP && function_exists('gmp_nextprime')) {
$p = new static();
$p->value = gmp_nextprime($x->value);
@@ -3257,7 +3265,7 @@ class BigInteger
*/
function _make_odd()
{
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
gmp_setbit($this->value, 0);
break;
@@ -3309,7 +3317,7 @@ class BigInteger
// ie. gmp_testbit($this, 0)
// ie. isEven() or !isOdd()
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
return gmp_prob_prime($this->value, $t) != 0;
case self::MODE_BCMATH:
@@ -3346,7 +3354,7 @@ class BigInteger
953, 967, 971, 977, 983, 991, 997
);
- if ( MATH_BIGINTEGER_MODE != self::MODE_INTERNAL ) {
+ if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
for ($i = 0; $i < count($primes); ++$i) {
$primes[$i] = new static($primes[$i]);
}
@@ -3362,7 +3370,7 @@ class BigInteger
}
// see HAC 4.4.1 "Random search for probable primes"
- if ( MATH_BIGINTEGER_MODE != self::MODE_INTERNAL ) {
+ if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
foreach ($primes as $prime) {
list(, $r) = $this->divide($prime);
if ($r->equals($zero)) {
@@ -3386,7 +3394,7 @@ class BigInteger
$r = $n_1->copy();
$r_value = $r->value;
// ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s));
- if ( MATH_BIGINTEGER_MODE == self::MODE_BCMATH ) {
+ if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
$s = 0;
// if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals($one) check earlier
while ($r->value[strlen($r->value) - 1] % 2 == 0) {
@@ -3396,7 +3404,8 @@ class BigInteger
} else {
for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) {
$temp = ~$r_value[$i] & 0xFFFFFF;
- for ($j = 1; ($temp >> $j) & 1; ++$j);
+ for ($j = 1; ($temp >> $j) & 1; ++$j) {
+ }
if ($j != 25) {
break;
}
@@ -3435,7 +3444,7 @@ class BigInteger
*/
function _lshift($shift)
{
- if ( $shift == 0 ) {
+ if ($shift == 0) {
return;
}
@@ -3451,7 +3460,7 @@ class BigInteger
$this->value[$i] = (int) ($temp - $carry * self::$baseFull);
}
- if ( $carry ) {
+ if ($carry) {
$this->value[count($this->value)] = $carry;
}
@@ -3479,7 +3488,7 @@ class BigInteger
$carry_shift = self::$base - $shift;
$carry_mask = (1 << $shift) - 1;
- if ( $num_digits ) {
+ if ($num_digits) {
$this->value = array_slice($this->value, $num_digits);
}
@@ -3509,7 +3518,7 @@ class BigInteger
$result->precision = $this->precision;
$result->bitmask = $this->bitmask;
- switch ( MATH_BIGINTEGER_MODE ) {
+ switch (MATH_BIGINTEGER_MODE) {
case self::MODE_GMP:
if (!empty($result->bitmask->value)) {
$result->value = gmp_and($result->value, $result->bitmask->value);
@@ -3526,7 +3535,7 @@ class BigInteger
$value = &$result->value;
- if ( !count($value) ) {
+ if (!count($value)) {
return $result;
}
@@ -3556,7 +3565,7 @@ class BigInteger
function _trim($value)
{
for ($i = count($value) - 1; $i >= 0; --$i) {
- if ( $value[$i] ) {
+ if ($value[$i]) {
break;
}
unset($value[$i]);
diff --git a/phpseclib/Net/SCP.php b/phpseclib/Net/SCP.php
index 6853e072..ebfa999a 100644
--- a/phpseclib/Net/SCP.php
+++ b/phpseclib/Net/SCP.php
@@ -283,7 +283,7 @@ class SCP
case self::MODE_SSH1:
$data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($data), $data);
$this->ssh->_send_binary_packet($data);
- }
+ }
}
/**
@@ -319,7 +319,7 @@ class SCP
throw new \UnexpectedValueException('Unknown packet received');
}
}
- }
+ }
}
/**
@@ -335,6 +335,6 @@ class SCP
break;
case self::MODE_SSH1:
$this->ssh->disconnect();
- }
+ }
}
}
diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php
index e22a6ae5..8460a1c9 100644
--- a/phpseclib/Net/SFTP.php
+++ b/phpseclib/Net/SFTP.php
@@ -397,8 +397,15 @@ class SFTP extends SSH2
$this->window_size_server_to_client[self::CHANNEL] = $this->window_size;
- $packet = pack('CNa*N3',
- NET_SSH2_MSG_CHANNEL_OPEN, strlen('session'), 'session', self::CHANNEL, $this->window_size, 0x4000);
+ $packet = pack(
+ 'CNa*N3',
+ NET_SSH2_MSG_CHANNEL_OPEN,
+ strlen('session'),
+ 'session',
+ self::CHANNEL,
+ $this->window_size,
+ 0x4000
+ );
if (!$this->_send_binary_packet($packet)) {
return false;
@@ -411,8 +418,16 @@ class SFTP extends SSH2
return false;
}
- $packet = pack('CNNa*CNa*',
- NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL], strlen('subsystem'), 'subsystem', 1, strlen('sftp'), 'sftp');
+ $packet = pack(
+ 'CNNa*CNa*',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $this->server_channels[self::CHANNEL],
+ strlen('subsystem'),
+ 'subsystem',
+ 1,
+ strlen('sftp'),
+ 'sftp'
+ );
if (!$this->_send_binary_packet($packet)) {
return false;
}
@@ -427,8 +442,16 @@ class SFTP extends SSH2
"exec sftp-server";
// we don't do $this->exec($command, false) because exec() operates on a different channel and plus the SSH_MSG_CHANNEL_OPEN that exec() does
// is redundant
- $packet = pack('CNNa*CNa*',
- NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL], strlen('exec'), 'exec', 1, strlen($command), $command);
+ $packet = pack(
+ 'CNNa*CNa*',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $this->server_channels[self::CHANNEL],
+ strlen('exec'),
+ 'exec',
+ 1,
+ strlen($command),
+ $command
+ );
if (!$this->_send_binary_packet($packet)) {
return false;
}
@@ -768,7 +791,7 @@ class SFTP extends SSH2
static $depth = 0;
- foreach ($files as $key=>$value) {
+ foreach ($files as $key => $value) {
if ($depth != 0 && $key == '..') {
unset($files[$key]);
continue;
@@ -863,7 +886,7 @@ class SFTP extends SSH2
} else {
$temp = $dir . '/' . $shortname;
}
- $this->_update_stat_cache($temp, (object) array('stat' => $attributes));
+ $this->_update_stat_cache($temp, (object) array('lstat' => $attributes));
}
// SFTPv6 has an optional boolean end-of-list field, but we'll ignore that, since the
// final SSH_FXP_STATUS packet should tell us that, already.
@@ -1032,7 +1055,13 @@ class SFTP extends SSH2
$temp = &$this->stat_cache;
$max = count($dirs) - 1;
- foreach ($dirs as $i=>$dir) {
+ foreach ($dirs as $i => $dir) {
+ // if $temp is an object that means one of two things.
+ // 1. a file was deleted and changed to a directory behind phpseclib's back
+ // 2. it's a symlink. when lstat is done it's unclear what it's a symlink to
+ if (is_object($temp)) {
+ $temp = array();
+ }
if (!isset($temp[$dir])) {
$temp[$dir] = array();
}
@@ -1065,7 +1094,7 @@ class SFTP extends SSH2
$temp = &$this->stat_cache;
$max = count($dirs) - 1;
- foreach ($dirs as $i=>$dir) {
+ foreach ($dirs as $i => $dir) {
if ($i === $max) {
unset($temp[$dir]);
return true;
@@ -1122,7 +1151,7 @@ class SFTP extends SSH2
if ($this->use_stat_cache) {
$result = $this->_query_stat_cache($filename);
- if (is_array($result) && isset($result['.'])) {
+ if (is_array($result) && isset($result['.']) && isset($result['.']->stat)) {
return $result['.']->stat;
}
if (is_object($result) && isset($result->stat)) {
@@ -1495,7 +1524,7 @@ class SFTP extends SSH2
}
unset($entries['.'], $entries['..']);
- foreach ($entries as $filename=>$props) {
+ foreach ($entries as $filename => $props) {
if (!isset($props['type'])) {
return false;
}
@@ -2167,7 +2196,7 @@ class SFTP extends SSH2
}
unset($entries['.'], $entries['..']);
- foreach ($entries as $filename=>$props) {
+ foreach ($entries as $filename => $props) {
if (!isset($props['type'])) {
return false;
}
@@ -2369,13 +2398,20 @@ class SFTP extends SSH2
}
switch ($type) {
- case NET_SFTP_TYPE_BLOCK_DEVICE: return 'block';
- case NET_SFTP_TYPE_CHAR_DEVICE: return 'char';
- case NET_SFTP_TYPE_DIRECTORY: return 'dir';
- case NET_SFTP_TYPE_FIFO: return 'fifo';
- case NET_SFTP_TYPE_REGULAR: return 'file';
- case NET_SFTP_TYPE_SYMLINK: return 'link';
- default: return false;
+ case NET_SFTP_TYPE_BLOCK_DEVICE:
+ return 'block';
+ case NET_SFTP_TYPE_CHAR_DEVICE:
+ return 'char';
+ case NET_SFTP_TYPE_DIRECTORY:
+ return 'dir';
+ case NET_SFTP_TYPE_FIFO:
+ return 'fifo';
+ case NET_SFTP_TYPE_REGULAR:
+ return 'file';
+ case NET_SFTP_TYPE_SYMLINK:
+ return 'link';
+ default:
+ return false;
}
}
diff --git a/phpseclib/Net/SSH1.php b/phpseclib/Net/SSH1.php
index 5a504659..918c791e 100644
--- a/phpseclib/Net/SSH1.php
+++ b/phpseclib/Net/SSH1.php
@@ -597,7 +597,7 @@ class SSH1
// get a list of the supported ciphers
extract(unpack('Nsupported_ciphers_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4)));
- foreach ($this->supported_ciphers as $mask=>$name) {
+ foreach ($this->supported_ciphers as $mask => $name) {
if (($supported_ciphers_mask & (1 << $mask)) == 0) {
unset($this->supported_ciphers[$mask]);
}
@@ -605,7 +605,7 @@ class SSH1
// get a list of the supported authentications
extract(unpack('Nsupported_authentications_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4)));
- foreach ($this->supported_authentications as $mask=>$name) {
+ foreach ($this->supported_authentications as $mask => $name) {
if (($supported_authentications_mask & (1 << $mask)) == 0) {
unset($this->supported_authentications[$mask]);
}
@@ -727,7 +727,7 @@ class SSH1
if ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) {
$this->bitmap |= self::MASK_LOGIN;
return true;
- } else if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) {
+ } elseif ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) {
user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
return false;
}
@@ -753,7 +753,7 @@ class SSH1
if ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) {
$this->bitmap |= self::MASK_LOGIN;
return true;
- } else if ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) {
+ } elseif ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) {
return false;
} else {
user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
@@ -1266,7 +1266,7 @@ class SSH1
$crc = 0x00000000;
$length = strlen($data);
- for ($i=0;$i<$length;$i++) {
+ for ($i=0; $i<$length; $i++) {
// We AND $crc >> 8 with 0x00FFFFFF because we want the eight newly added bits to all
// be zero. PHP, unfortunately, doesn't always do this. 0x80000000 >> 8, as an example,
// yields 0xFF800000 - not 0x00800000. The following link elaborates:
@@ -1361,7 +1361,7 @@ class SSH1
{
$args = func_get_args();
foreach ($args as $arg) {
- foreach ($arg as $key=>$value) {
+ foreach ($arg as $key => $value) {
if (!defined($value)) {
define($value, $key);
} else {
diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php
index c4aa704c..0daf81dc 100644
--- a/phpseclib/Net/SSH2.php
+++ b/phpseclib/Net/SSH2.php
@@ -870,7 +870,9 @@ class SSH2
/**
* Default Constructor.
*
- * @param String $host
+ * $host can either be a string, representing the host, or a stream resource.
+ *
+ * @param Mixed $host
* @param optional Integer $port
* @param optional Integer $timeout
* @see \phpseclib\Net\SSH2::login()
@@ -952,12 +954,22 @@ class SSH2
31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP',
32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT',
33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY',
- 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST')
+ 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'),
+ // RFC 5656 - Elliptic Curves (for curve25519-sha256@libssh.org)
+ array(30 => 'NET_SSH2_MSG_KEX_ECDH_INIT',
+ 31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY')
);
- $this->host = $host;
- $this->port = $port;
- $this->timeout = $timeout;
+ if (is_resource($host)) {
+ $this->fsock = $host;
+ return;
+ }
+
+ if (is_string($host)) {
+ $this->host = $host;
+ $this->port = $port;
+ $this->timeout = $timeout;
+ }
}
/**
@@ -992,22 +1004,23 @@ class SSH2
$this->curTimeout = $this->timeout;
- $host = $this->host . ':' . $this->port;
-
$this->last_packet = microtime(true);
- $start = microtime(true);
- $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout);
- if (!$this->fsock) {
- throw new \RuntimeException(rtrim("Cannot connect to $host. Error $errno. $errstr"))_;
- }
- $elapsed = microtime(true) - $start;
+ if (!is_resource($this->fsock)) {
+ $start = microtime(true);
+ $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout);
+ if (!$this->fsock) {
+ $host = $this->host . ':' . $this->port;
+ throw new \RuntimeException(rtrim("Cannot connect to $host. Error $errno. $errstr"));
+ }
+ $elapsed = microtime(true) - $start;
- $this->curTimeout-= $elapsed;
+ $this->curTimeout-= $elapsed;
- if ($this->curTimeout <= 0) {
- $this->is_timeout = true;
- return false;
+ if ($this->curTimeout <= 0) {
+ $this->is_timeout = true;
+ return false;
+ }
}
/* According to the SSH2 specs,
@@ -1098,9 +1111,13 @@ class SSH2
*/
function _generate_identifier()
{
- $identifier = 'SSH-2.0-phpseclib_0.3';
+ $identifier = 'SSH-2.0-phpseclib_2.0';
$ext = array();
+ if (extension_loaded('libsodium')) {
+ $ext[] = 'libsodium';
+ }
+
if (extension_loaded('openssl')) {
$ext[] = 'openssl';
} elseif (extension_loaded('mcrypt')) {
@@ -1131,98 +1148,108 @@ class SSH2
*/
function _key_exchange($kexinit_payload_server)
{
- static $kex_algorithms = array(
+ $kex_algorithms = array(
+ // Elliptic Curve Diffie-Hellman Key Agreement (ECDH) using
+ // Curve25519. See doc/curve25519-sha256@libssh.org.txt in the
+ // libssh repository for more information.
+ 'curve25519-sha256@libssh.org',
+
+ // Diffie-Hellman Key Agreement (DH) using integer modulo prime
+ // groups.
'diffie-hellman-group1-sha1', // REQUIRED
'diffie-hellman-group14-sha1', // REQUIRED
'diffie-hellman-group-exchange-sha1', // RFC 4419
'diffie-hellman-group-exchange-sha256', // RFC 4419
);
+ if (!class_exists('\Sodium')) {
+ $kex_algorithms = array_diff(
+ $kex_algorithms,
+ array('curve25519-sha256@libssh.org')
+ );
+ }
- static $server_host_key_algorithms = array(
+ $server_host_key_algorithms = array(
'ssh-rsa', // RECOMMENDED sign Raw RSA Key
'ssh-dss' // REQUIRED sign Raw DSS Key
);
- static $encryption_algorithms = false;
- if ($encryption_algorithms === false) {
- $encryption_algorithms = array(
- // from :
- 'arcfour256',
- 'arcfour128',
+ $encryption_algorithms = array(
+ // from :
+ 'arcfour256',
+ 'arcfour128',
- //'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
+ //'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
- // CTR modes from :
- 'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key
- 'aes192-ctr', // RECOMMENDED AES with 192-bit key
- 'aes256-ctr', // RECOMMENDED AES with 256-bit key
+ // CTR modes from :
+ 'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key
+ 'aes192-ctr', // RECOMMENDED AES with 192-bit key
+ 'aes256-ctr', // RECOMMENDED AES with 256-bit key
- 'twofish128-ctr', // OPTIONAL Twofish in SDCTR mode, with 128-bit key
- 'twofish192-ctr', // OPTIONAL Twofish with 192-bit key
- 'twofish256-ctr', // OPTIONAL Twofish with 256-bit key
+ 'twofish128-ctr', // OPTIONAL Twofish in SDCTR mode, with 128-bit key
+ 'twofish192-ctr', // OPTIONAL Twofish with 192-bit key
+ 'twofish256-ctr', // OPTIONAL Twofish with 256-bit key
- 'aes128-cbc', // RECOMMENDED AES with a 128-bit key
- 'aes192-cbc', // OPTIONAL AES with a 192-bit key
- 'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key
+ 'aes128-cbc', // RECOMMENDED AES with a 128-bit key
+ 'aes192-cbc', // OPTIONAL AES with a 192-bit key
+ 'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key
- 'twofish128-cbc', // OPTIONAL Twofish with a 128-bit key
- 'twofish192-cbc', // OPTIONAL Twofish with a 192-bit key
- 'twofish256-cbc',
- 'twofish-cbc', // OPTIONAL alias for "twofish256-cbc"
- // (this is being retained for historical reasons)
+ 'twofish128-cbc', // OPTIONAL Twofish with a 128-bit key
+ 'twofish192-cbc', // OPTIONAL Twofish with a 192-bit key
+ 'twofish256-cbc',
+ 'twofish-cbc', // OPTIONAL alias for "twofish256-cbc"
+ // (this is being retained for historical reasons)
- 'blowfish-ctr', // OPTIONAL Blowfish in SDCTR mode
+ 'blowfish-ctr', // OPTIONAL Blowfish in SDCTR mode
- 'blowfish-cbc', // OPTIONAL Blowfish in CBC mode
+ 'blowfish-cbc', // OPTIONAL Blowfish in CBC mode
- '3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode
+ '3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode
- '3des-cbc', // REQUIRED three-key 3DES in CBC mode
- //'none' // OPTIONAL no encryption; NOT RECOMMENDED
+ '3des-cbc', // REQUIRED three-key 3DES in CBC mode
+ //'none' // OPTIONAL no encryption; NOT RECOMMENDED
+ );
+
+ if (extension_loaded('openssl') && !extension_loaded('mcrypt')) {
+ // OpenSSL does not support arcfour256 in any capacity and arcfour128 / arcfour support is limited to
+ // instances that do not use continuous buffers
+ $encryption_algorithms = array_diff(
+ $encryption_algorithms,
+ array('arcfour256', 'arcfour128', 'arcfour')
);
-
- if (extension_loaded('openssl') && !extension_loaded('mcrypt')) {
- // OpenSSL does not support arcfour256 in any capacity and arcfour128 / arcfour support is limited to
- // instances that do not use continuous buffers
- $encryption_algorithms = array_diff(
- $encryption_algorithms,
- array('arcfour256', 'arcfour128', 'arcfour')
- );
- }
-
- if (class_exists('\phpseclib\Crypt\RC4') === false) {
- $encryption_algorithms = array_diff(
- $encryption_algorithms,
- array('arcfour256', 'arcfour128', 'arcfour')
- );
- }
- if (class_exists('\phpseclib\Crypt\Rijndael') === false) {
- $encryption_algorithms = array_diff(
- $encryption_algorithms,
- array('aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-cbc', 'aes192-cbc', 'aes256-cbc')
- );
- }
- if (class_exists('\phpseclib\Crypt\Twofish') === false) {
- $encryption_algorithms = array_diff(
- $encryption_algorithms,
- array('twofish128-ctr', 'twofish192-ctr', 'twofish256-ctr', 'twofish128-cbc', 'twofish192-cbc', 'twofish256-cbc', 'twofish-cbc')
- );
- }
- if (class_exists('\phpseclib\Crypt\Blowfish') === false) {
- $encryption_algorithms = array_diff(
- $encryption_algorithms,
- array('blowfish-ctr', 'blowfish-cbc')
- );
- }
- if (class_exists('\phpseclib\Crypt\TripleDES') === false) {
- $encryption_algorithms = array_diff(
- $encryption_algorithms,
- array('3des-ctr', '3des-cbc')
- );
- }
- $encryption_algorithms = array_values($encryption_algorithms);
}
+ if (class_exists('\phpseclib\Crypt\RC4') === false) {
+ $encryption_algorithms = array_diff(
+ $encryption_algorithms,
+ array('arcfour256', 'arcfour128', 'arcfour')
+ );
+ }
+ if (class_exists('\phpseclib\Crypt\Rijndael') === false) {
+ $encryption_algorithms = array_diff(
+ $encryption_algorithms,
+ array('aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'aes128-cbc', 'aes192-cbc', 'aes256-cbc')
+ );
+ }
+ if (class_exists('\phpseclib\Crypt\Twofish') === false) {
+ $encryption_algorithms = array_diff(
+ $encryption_algorithms,
+ array('twofish128-ctr', 'twofish192-ctr', 'twofish256-ctr', 'twofish128-cbc', 'twofish192-cbc', 'twofish256-cbc', 'twofish-cbc')
+ );
+ }
+ if (class_exists('\phpseclib\Crypt\Blowfish') === false) {
+ $encryption_algorithms = array_diff(
+ $encryption_algorithms,
+ array('blowfish-ctr', 'blowfish-cbc')
+ );
+ }
+ if (class_exists('\phpseclib\Crypt\TripleDES') === false) {
+ $encryption_algorithms = array_diff(
+ $encryption_algorithms,
+ array('3des-ctr', '3des-cbc')
+ );
+ }
+ $encryption_algorithms = array_values($encryption_algorithms);
+
$mac_algorithms = array(
// from :
'hmac-sha2-256',// RECOMMENDED HMAC-SHA256 (digest length = key length = 32)
@@ -1234,7 +1261,7 @@ class SSH2
//'none' // OPTIONAL no MAC; NOT RECOMMENDED
);
- static $compression_algorithms = array(
+ $compression_algorithms = array(
'none' // REQUIRED no compression
//'zlib' // OPTIONAL ZLIB (LZ77) compression
);
@@ -1248,17 +1275,11 @@ class SSH2
));
}
- static $str_kex_algorithms, $str_server_host_key_algorithms,
- $encryption_algorithms_server_to_client, $mac_algorithms_server_to_client, $compression_algorithms_server_to_client,
- $encryption_algorithms_client_to_server, $mac_algorithms_client_to_server, $compression_algorithms_client_to_server;
-
- if (empty($str_kex_algorithms)) {
- $str_kex_algorithms = implode(',', $kex_algorithms);
- $str_server_host_key_algorithms = implode(',', $server_host_key_algorithms);
- $encryption_algorithms_server_to_client = $encryption_algorithms_client_to_server = implode(',', $encryption_algorithms);
- $mac_algorithms_server_to_client = $mac_algorithms_client_to_server = implode(',', $mac_algorithms);
- $compression_algorithms_server_to_client = $compression_algorithms_client_to_server = implode(',', $compression_algorithms);
- }
+ $str_kex_algorithms = implode(',', $kex_algorithms);
+ $str_server_host_key_algorithms = implode(',', $server_host_key_algorithms);
+ $encryption_algorithms_server_to_client = $encryption_algorithms_client_to_server = implode(',', $encryption_algorithms);
+ $mac_algorithms_server_to_client = $mac_algorithms_client_to_server = implode(',', $mac_algorithms);
+ $compression_algorithms_server_to_client = $compression_algorithms_client_to_server = implode(',', $compression_algorithms);
$client_cookie = Random::string(16);
@@ -1300,14 +1321,32 @@ class SSH2
$first_kex_packet_follows = $first_kex_packet_follows != 0;
// the sending of SSH2_MSG_KEXINIT could go in one of two places. this is the second place.
- $kexinit_payload_client = pack('Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN',
- NET_SSH2_MSG_KEXINIT, $client_cookie, strlen($str_kex_algorithms), $str_kex_algorithms,
- strlen($str_server_host_key_algorithms), $str_server_host_key_algorithms, strlen($encryption_algorithms_client_to_server),
- $encryption_algorithms_client_to_server, strlen($encryption_algorithms_server_to_client), $encryption_algorithms_server_to_client,
- strlen($mac_algorithms_client_to_server), $mac_algorithms_client_to_server, strlen($mac_algorithms_server_to_client),
- $mac_algorithms_server_to_client, strlen($compression_algorithms_client_to_server), $compression_algorithms_client_to_server,
- strlen($compression_algorithms_server_to_client), $compression_algorithms_server_to_client, 0, '', 0, '',
- 0, 0
+ $kexinit_payload_client = pack(
+ 'Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN',
+ NET_SSH2_MSG_KEXINIT,
+ $client_cookie,
+ strlen($str_kex_algorithms),
+ $str_kex_algorithms,
+ strlen($str_server_host_key_algorithms),
+ $str_server_host_key_algorithms,
+ strlen($encryption_algorithms_client_to_server),
+ $encryption_algorithms_client_to_server,
+ strlen($encryption_algorithms_server_to_client),
+ $encryption_algorithms_server_to_client,
+ strlen($mac_algorithms_client_to_server),
+ $mac_algorithms_client_to_server,
+ strlen($mac_algorithms_server_to_client),
+ $mac_algorithms_server_to_client,
+ strlen($compression_algorithms_client_to_server),
+ $compression_algorithms_client_to_server,
+ strlen($compression_algorithms_server_to_client),
+ $compression_algorithms_server_to_client,
+ 0,
+ '',
+ 0,
+ '',
+ 0,
+ 0
);
if (!$this->_send_binary_packet($kexinit_payload_client)) {
@@ -1316,199 +1355,141 @@ class SSH2
// here ends the second place.
// we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
- for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_server_to_client); $i++);
- if ($i == count($encryption_algorithms)) {
- $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
- throw new \RuntimeException('No compatible server to client encryption algorithms found');
- }
// we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the
// diffie-hellman key exchange as fast as possible
- $decrypt = $encryption_algorithms[$i];
- switch ($decrypt) {
- case '3des-cbc':
- case '3des-ctr':
- $decryptKeyLength = 24; // eg. 192 / 8
- break;
- case 'aes256-cbc':
- case 'aes256-ctr':
- case 'twofish-cbc':
- case 'twofish256-cbc':
- case 'twofish256-ctr':
- $decryptKeyLength = 32; // eg. 256 / 8
- break;
- case 'aes192-cbc':
- case 'aes192-ctr':
- case 'twofish192-cbc':
- case 'twofish192-ctr':
- $decryptKeyLength = 24; // eg. 192 / 8
- break;
- case 'aes128-cbc':
- case 'aes128-ctr':
- case 'twofish128-cbc':
- case 'twofish128-ctr':
- case 'blowfish-cbc':
- case 'blowfish-ctr':
- $decryptKeyLength = 16; // eg. 128 / 8
- break;
- case 'arcfour':
- case 'arcfour128':
- $decryptKeyLength = 16; // eg. 128 / 8
- break;
- case 'arcfour256':
- $decryptKeyLength = 32; // eg. 128 / 8
- break;
- case 'none':
- $decryptKeyLength = 0;
+ $decrypt = $this->_array_intersect_first($encryption_algorithms, $this->encryption_algorithms_server_to_client);
+ $decryptKeyLength = $this->_encryption_algorithm_to_key_size($decrypt);
+ if ($decryptKeyLength === null) {
+ $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ throw new NoSupportedAlgorithmsException('No compatible server to client encryption algorithms found');
}
- for ($i = 0; $i < count($encryption_algorithms) && !in_array($encryption_algorithms[$i], $this->encryption_algorithms_client_to_server); $i++);
- if ($i == count($encryption_algorithms)) {
+ $encrypt = $this->_array_intersect_first($encryption_algorithms, $this->encryption_algorithms_client_to_server);
+ $encryptKeyLength = $this->_encryption_algorithm_to_key_size($encrypt);
+ if ($encryptKeyLength === null) {
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
throw new NoSupportedAlgorithmsException('No compatible client to server encryption algorithms found');
}
- $encrypt = $encryption_algorithms[$i];
- switch ($encrypt) {
- case '3des-cbc':
- case '3des-ctr':
- $encryptKeyLength = 24;
- break;
- case 'aes256-cbc':
- case 'aes256-ctr':
- case 'twofish-cbc':
- case 'twofish256-cbc':
- case 'twofish256-ctr':
- $encryptKeyLength = 32;
- break;
- case 'aes192-cbc':
- case 'aes192-ctr':
- case 'twofish192-cbc':
- case 'twofish192-ctr':
- $encryptKeyLength = 24;
- break;
- case 'aes128-cbc':
- case 'aes128-ctr':
- case 'twofish128-cbc':
- case 'twofish128-ctr':
- case 'blowfish-cbc':
- case 'blowfish-ctr':
- $encryptKeyLength = 16;
- break;
- case 'arcfour':
- case 'arcfour128':
- $encryptKeyLength = 16;
- break;
- case 'arcfour256':
- $encryptKeyLength = 32;
- break;
- case 'none':
- $encryptKeyLength = 0;
- }
-
- $keyLength = $decryptKeyLength > $encryptKeyLength ? $decryptKeyLength : $encryptKeyLength;
-
// through diffie-hellman key exchange a symmetric key is obtained
- for ($i = 0; $i < count($kex_algorithms) && !in_array($kex_algorithms[$i], $this->kex_algorithms); $i++);
- if ($i == count($kex_algorithms)) {
+ $kex_algorithm = $this->_array_intersect_first($kex_algorithms, $this->kex_algorithms);
+ if ($kex_algorithm === false) {
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
throw new NoSupportedAlgorithmsException('No compatible key exchange algorithms found');
}
- if (strpos($kex_algorithms[$i], 'diffie-hellman-group-exchange') === 0) {
- $dh_group_sizes_packed = pack('NNN',
- $this->kex_dh_group_size_min,
- $this->kex_dh_group_size_preferred,
- $this->kex_dh_group_size_max
- );
- $packet = pack('Ca*',
- NET_SSH2_MSG_KEXDH_GEX_REQUEST,
- $dh_group_sizes_packed
- );
- if (!$this->_send_binary_packet($packet)) {
- return false;
- }
+ // Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty.
+ $exchange_hash_rfc4419 = '';
- $response = $this->_get_binary_packet();
- if ($response === false) {
- throw new \RuntimeException('Connection closed by server');
- }
- extract(unpack('Ctype', $this->_string_shift($response, 1)));
- if ($type != NET_SSH2_MSG_KEXDH_GEX_GROUP) {
- throw new \UnexpectedValueException('Expected SSH_MSG_KEX_DH_GEX_GROUP');
- }
-
- extract(unpack('NprimeLength', $this->_string_shift($response, 4)));
- $primeBytes = $this->_string_shift($response, $primeLength);
- $prime = new BigInteger($primeBytes, -256);
-
- extract(unpack('NgLength', $this->_string_shift($response, 4)));
- $gBytes = $this->_string_shift($response, $gLength);
- $g = new BigInteger($gBytes, -256);
-
- $exchange_hash_rfc4419 = pack('a*Na*Na*',
- $dh_group_sizes_packed,
- $primeLength, $primeBytes,
- $gLength, $gBytes
- );
-
- $clientKexInitMessage = NET_SSH2_MSG_KEXDH_GEX_INIT;
- $serverKexReplyMessage = NET_SSH2_MSG_KEXDH_GEX_REPLY;
+ if ($kex_algorithm === 'curve25519-sha256@libssh.org') {
+ $x = Random::string(32);
+ $eBytes = \Sodium::crypto_box_publickey_from_secretkey($x);
+ $clientKexInitMessage = NET_SSH2_MSG_KEX_ECDH_INIT;
+ $serverKexReplyMessage = NET_SSH2_MSG_KEX_ECDH_REPLY;
+ $kexHash = new Hash('sha256');
} else {
- switch ($kex_algorithms[$i]) {
- // see http://tools.ietf.org/html/rfc2409#section-6.2 and
- // http://tools.ietf.org/html/rfc2412, appendex E
- case 'diffie-hellman-group1-sha1':
- $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' .
- '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' .
- '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
- 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF';
- break;
- // see http://tools.ietf.org/html/rfc3526#section-3
- case 'diffie-hellman-group14-sha1':
- $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' .
- '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' .
- '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
- 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' .
- '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' .
- '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' .
- 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' .
- '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF';
- break;
+ if (strpos($kex_algorithm, 'diffie-hellman-group-exchange') === 0) {
+ $dh_group_sizes_packed = pack(
+ 'NNN',
+ $this->kex_dh_group_size_min,
+ $this->kex_dh_group_size_preferred,
+ $this->kex_dh_group_size_max
+ );
+ $packet = pack(
+ 'Ca*',
+ NET_SSH2_MSG_KEXDH_GEX_REQUEST,
+ $dh_group_sizes_packed
+ );
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ user_error('Connection closed by server');
+ return false;
+ }
+ extract(unpack('Ctype', $this->_string_shift($response, 1)));
+ if ($type != NET_SSH2_MSG_KEXDH_GEX_GROUP) {
+ user_error('Expected SSH_MSG_KEX_DH_GEX_GROUP');
+ return false;
+ }
+
+ extract(unpack('NprimeLength', $this->_string_shift($response, 4)));
+ $primeBytes = $this->_string_shift($response, $primeLength);
+ $prime = new BigInteger($primeBytes, -256);
+
+ extract(unpack('NgLength', $this->_string_shift($response, 4)));
+ $gBytes = $this->_string_shift($response, $gLength);
+ $g = new BigInteger($gBytes, -256);
+
+ $exchange_hash_rfc4419 = pack(
+ 'a*Na*Na*',
+ $dh_group_sizes_packed,
+ $primeLength,
+ $primeBytes,
+ $gLength,
+ $gBytes
+ );
+
+ $clientKexInitMessage = NET_SSH2_MSG_KEXDH_GEX_INIT;
+ $serverKexReplyMessage = NET_SSH2_MSG_KEXDH_GEX_REPLY;
+ } else {
+ switch ($kex_algorithm) {
+ // see http://tools.ietf.org/html/rfc2409#section-6.2 and
+ // http://tools.ietf.org/html/rfc2412, appendex E
+ case 'diffie-hellman-group1-sha1':
+ $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' .
+ '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' .
+ '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
+ 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF';
+ break;
+ // see http://tools.ietf.org/html/rfc3526#section-3
+ case 'diffie-hellman-group14-sha1':
+ $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' .
+ '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' .
+ '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
+ 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' .
+ '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' .
+ '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' .
+ 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' .
+ '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF';
+ break;
+ }
+ // For both diffie-hellman-group1-sha1 and diffie-hellman-group14-sha1
+ // the generator field element is 2 (decimal) and the hash function is sha1.
+ $g = new BigInteger(2);
+ $prime = new BigInteger($prime, 16);
+ $clientKexInitMessage = NET_SSH2_MSG_KEXDH_INIT;
+ $serverKexReplyMessage = NET_SSH2_MSG_KEXDH_REPLY;
}
- // For both diffie-hellman-group1-sha1 and diffie-hellman-group14-sha1
- // the generator field element is 2 (decimal) and the hash function is sha1.
- $g = new BigInteger(2);
- $prime = new BigInteger($prime, 16);
- $exchange_hash_rfc4419 = '';
- $clientKexInitMessage = NET_SSH2_MSG_KEXDH_INIT;
- $serverKexReplyMessage = NET_SSH2_MSG_KEXDH_REPLY;
+
+ switch ($kex_algorithm) {
+ case 'diffie-hellman-group-exchange-sha256':
+ $kexHash = new Hash('sha256');
+ break;
+ default:
+ $kexHash = new Hash('sha1');
+ }
+
+ /* To increase the speed of the key exchange, both client and server may
+ reduce the size of their private exponents. It should be at least
+ twice as long as the key material that is generated from the shared
+ secret. For more details, see the paper by van Oorschot and Wiener
+ [VAN-OORSCHOT].
+
+ -- http://tools.ietf.org/html/rfc4419#section-6.2 */
+ $one = new BigInteger(1);
+ $keyLength = min($kexHash->getLength(), max($encryptKeyLength, $decryptKeyLength));
+ $max = $one->bitwise_leftShift(16 * $keyLength); // 2 * 8 * $keyLength
+ $max = $max->subtract($one);
+
+ $x = $one->random($one, $max);
+ $e = $g->modPow($x, $prime);
+
+ $eBytes = $e->toBytes(true);
}
-
- switch ($kex_algorithms[$i]) {
- case 'diffie-hellman-group-exchange-sha256':
- $kexHash = new Hash('sha256');
- break;
- default:
- $kexHash = new Hash('sha1');
- }
-
- /* To increase the speed of the key exchange, both client and server may
- reduce the size of their private exponents. It should be at least
- twice as long as the key material that is generated from the shared
- secret. For more details, see the paper by van Oorschot and Wiener
- [VAN-OORSCHOT].
-
- -- http://tools.ietf.org/html/rfc4419#section-6.2 */
- $one = new BigInteger(1);
- $keyLength = min($keyLength, $kexHash->getLength());
- $max = $one->bitwise_leftShift(16 * $keyLength); // 2 * 8 * $keyLength
- $max = $max->subtract($one);
-
- $x = $one->random($one, $max);
- $e = $g->modPow($x, $prime);
-
- $eBytes = $e->toBytes(true);
$data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
if (!$this->_send_binary_packet($data)) {
@@ -1533,7 +1514,6 @@ class SSH2
$temp = unpack('Nlength', $this->_string_shift($response, 4));
$fBytes = $this->_string_shift($response, $temp['length']);
- $f = new BigInteger($fBytes, -256);
$temp = unpack('Nlength', $this->_string_shift($response, 4));
$this->signature = $this->_string_shift($response, $temp['length']);
@@ -1541,19 +1521,38 @@ class SSH2
$temp = unpack('Nlength', $this->_string_shift($this->signature, 4));
$this->signature_format = $this->_string_shift($this->signature, $temp['length']);
- $key = $f->modPow($x, $prime);
+ if ($kex_algorithm === 'curve25519-sha256@libssh.org') {
+ if (strlen($fBytes) !== 32) {
+ user_error('Received curve25519 public key of invalid length.');
+ return false;
+ }
+ $key = new BigInteger(\Sodium::crypto_scalarmult($x, $fBytes), 256);
+ \Sodium::sodium_memzero($x);
+ } else {
+ $f = new BigInteger($fBytes, -256);
+ $key = $f->modPow($x, $prime);
+ }
$keyBytes = $key->toBytes(true);
- $this->exchange_hash = pack('Na*Na*Na*Na*Na*a*Na*Na*Na*',
- strlen($this->identifier), $this->identifier,
- strlen($this->server_identifier), $this->server_identifier,
- strlen($kexinit_payload_client), $kexinit_payload_client,
- strlen($kexinit_payload_server), $kexinit_payload_server,
- strlen($this->server_public_host_key), $this->server_public_host_key,
+ $this->exchange_hash = pack(
+ 'Na*Na*Na*Na*Na*a*Na*Na*Na*',
+ strlen($this->identifier),
+ $this->identifier,
+ strlen($this->server_identifier),
+ $this->server_identifier,
+ strlen($kexinit_payload_client),
+ $kexinit_payload_client,
+ strlen($kexinit_payload_server),
+ $kexinit_payload_server,
+ strlen($this->server_public_host_key),
+ $this->server_public_host_key,
$exchange_hash_rfc4419,
- strlen($eBytes), $eBytes,
- strlen($fBytes), $fBytes,
- strlen($keyBytes), $keyBytes
+ strlen($eBytes),
+ $eBytes,
+ strlen($fBytes),
+ $fBytes,
+ strlen($keyBytes),
+ $keyBytes
);
$this->exchange_hash = $kexHash->hash($this->exchange_hash);
@@ -1562,18 +1561,19 @@ class SSH2
$this->session_id = $this->exchange_hash;
}
- for ($i = 0; $i < count($server_host_key_algorithms) && !in_array($server_host_key_algorithms[$i], $this->server_host_key_algorithms); $i++);
- if ($i == count($server_host_key_algorithms)) {
+ $server_host_key_algorithm = $this->_array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms);
+ if ($server_host_key_algorithm === false) {
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
throw new NoSupportedAlgorithmsException('No compatible server host key algorithms found');
}
- if ($public_key_format != $server_host_key_algorithms[$i] || $this->signature_format != $server_host_key_algorithms[$i]) {
+ if ($public_key_format != $server_host_key_algorithm || $this->signature_format != $server_host_key_algorithm) {
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
throw new \RuntimeException('Server Host Key Algorithm Mismatch');
}
- $packet = pack('C',
+ $packet = pack(
+ 'C',
NET_SSH2_MSG_NEWKEYS
);
@@ -1593,112 +1593,16 @@ class SSH2
throw new \UnexpectedValueException('Expected SSH_MSG_NEWKEYS');
}
- switch ($encrypt) {
- case '3des-cbc':
- $this->encrypt = new TripleDES();
- // $this->encrypt_block_size = 64 / 8 == the default
- break;
- case '3des-ctr':
- $this->encrypt = new TripleDES(Base::MODE_CTR);
- // $this->encrypt_block_size = 64 / 8 == the default
- break;
- case 'aes256-cbc':
- case 'aes192-cbc':
- case 'aes128-cbc':
- $this->encrypt = new Rijndael();
- $this->encrypt_block_size = 16; // eg. 128 / 8
- break;
- case 'aes256-ctr':
- case 'aes192-ctr':
- case 'aes128-ctr':
- $this->encrypt = new Rijndael(Base::MODE_CTR);
- $this->encrypt_block_size = 16; // eg. 128 / 8
- break;
- case 'blowfish-cbc':
- $this->encrypt = new Blowfish();
- $this->encrypt_block_size = 8;
- break;
- case 'blowfish-ctr':
- $this->encrypt = new Blowfish(Base::MODE_CTR);
- $this->encrypt_block_size = 8;
- break;
- case 'twofish128-cbc':
- case 'twofish192-cbc':
- case 'twofish256-cbc':
- case 'twofish-cbc':
- $this->encrypt = new Twofish();
- $this->encrypt_block_size = 16;
- break;
- case 'twofish128-ctr':
- case 'twofish192-ctr':
- case 'twofish256-ctr':
- $this->encrypt = new Twofish(Base::MODE_CTR);
- $this->encrypt_block_size = 16;
- break;
- case 'arcfour':
- case 'arcfour128':
- case 'arcfour256':
- $this->encrypt = new RC4();
- break;
- case 'none':
- //$this->encrypt = new Null();
- }
-
- switch ($decrypt) {
- case '3des-cbc':
- $this->decrypt = new TripleDES();
- break;
- case '3des-ctr':
- $this->decrypt = new TripleDES(Base::MODE_CTR);
- break;
- case 'aes256-cbc':
- case 'aes192-cbc':
- case 'aes128-cbc':
- $this->decrypt = new Rijndael();
- $this->decrypt_block_size = 16;
- break;
- case 'aes256-ctr':
- case 'aes192-ctr':
- case 'aes128-ctr':
- $this->decrypt = new Rijndael(Base::MODE_CTR);
- $this->decrypt_block_size = 16;
- break;
- case 'blowfish-cbc':
- $this->decrypt = new Blowfish();
- $this->decrypt_block_size = 8;
- break;
- case 'blowfish-ctr':
- $this->decrypt = new Blowfish(Base::MODE_CTR);
- $this->decrypt_block_size = 8;
- break;
- case 'twofish128-cbc':
- case 'twofish192-cbc':
- case 'twofish256-cbc':
- case 'twofish-cbc':
- $this->decrypt = new Twofish();
- $this->decrypt_block_size = 16;
- break;
- case 'twofish128-ctr':
- case 'twofish192-ctr':
- case 'twofish256-ctr':
- $this->decrypt = new Twofish(Base::MODE_CTR);
- $this->decrypt_block_size = 16;
- break;
- case 'arcfour':
- case 'arcfour128':
- case 'arcfour256':
- $this->decrypt = new RC4();
- break;
- case 'none':
- //$this->decrypt = new Null();
- }
-
$keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
+ $this->encrypt = $this->_encryption_algorithm_to_crypt_instance($encrypt);
if ($this->encrypt) {
if ($this->crypto_engine) {
$this->encrypt->setEngine($this->crypto_engine);
}
+ if ($this->encrypt->block_size) {
+ $this->encrypt_block_size = $this->encrypt->block_size;
+ }
$this->encrypt->enableContinuousBuffer();
$this->encrypt->disablePadding();
@@ -1715,10 +1619,14 @@ class SSH2
$this->encrypt->setKey(substr($key, 0, $encryptKeyLength));
}
+ $this->decrypt = $this->_encryption_algorithm_to_crypt_instance($decrypt);
if ($this->decrypt) {
if ($this->crypto_engine) {
$this->decrypt->setEngine($this->crypto_engine);
}
+ if ($this->decrypt->block_size) {
+ $this->decrypt_block_size = $this->decrypt->block_size;
+ }
$this->decrypt->enableContinuousBuffer();
$this->decrypt->disablePadding();
@@ -1749,14 +1657,14 @@ class SSH2
$this->decrypt->decrypt(str_repeat("\0", 1536));
}
- for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_client_to_server); $i++);
- if ($i == count($mac_algorithms)) {
+ $mac_algorithm = $this->_array_intersect_first($mac_algorithms, $this->mac_algorithms_client_to_server);
+ if ($mac_algorithm === false) {
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
throw new NoSupportedAlgorithmsException('No compatible client to server message authentication algorithms found');
}
- $createKeyLength = 0; // ie. $mac_algorithms[$i] == 'none'
- switch ($mac_algorithms[$i]) {
+ $createKeyLength = 0; // ie. $mac_algorithm == 'none'
+ switch ($mac_algorithm) {
case 'hmac-sha2-256':
$this->hmac_create = new Hash('sha256');
$createKeyLength = 32;
@@ -1778,15 +1686,15 @@ class SSH2
$createKeyLength = 16;
}
- for ($i = 0; $i < count($mac_algorithms) && !in_array($mac_algorithms[$i], $this->mac_algorithms_server_to_client); $i++);
- if ($i == count($mac_algorithms)) {
+ $mac_algorithm = $this->_array_intersect_first($mac_algorithms, $this->mac_algorithms_server_to_client);
+ if ($mac_algorithm === false) {
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
throw new NoSupportedAlgorithmsException('No compatible server to client message authentication algorithms found');
}
$checkKeyLength = 0;
$this->hmac_size = 0;
- switch ($mac_algorithms[$i]) {
+ switch ($mac_algorithm) {
case 'hmac-sha2-256':
$this->hmac_check = new Hash('sha256');
$checkKeyLength = 32;
@@ -1825,23 +1733,106 @@ class SSH2
}
$this->hmac_check->setKey(substr($key, 0, $checkKeyLength));
- for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_server_to_client); $i++);
- if ($i == count($compression_algorithms)) {
+ $compression_algorithm = $this->_array_intersect_first($compression_algorithms, $this->compression_algorithms_server_to_client);
+ if ($compression_algorithm === false) {
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
throw new NoSupportedAlgorithmsException('No compatible server to client compression algorithms found');
}
- $this->decompress = $compression_algorithms[$i] == 'zlib';
+ $this->decompress = $compression_algorithm == 'zlib';
- for ($i = 0; $i < count($compression_algorithms) && !in_array($compression_algorithms[$i], $this->compression_algorithms_client_to_server); $i++);
- if ($i == count($compression_algorithms)) {
+ $compression_algorithm = $this->_array_intersect_first($compression_algorithms, $this->compression_algorithms_client_to_server);
+ if ($compression_algorithm === false) {
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
throw new NoSupportedAlgorithmsException('No compatible client to server compression algorithms found');
}
- $this->compress = $compression_algorithms[$i] == 'zlib';
+ $this->compress = $compression_algorithm == 'zlib';
return true;
}
+ /**
+ * Maps an encryption algorithm name to the number of key bytes.
+ *
+ * @param String $algorithm Name of the encryption algorithm
+ * @return Mixed Number of bytes as an integer or null for unknown
+ * @access private
+ */
+ function _encryption_algorithm_to_key_size($algorithm)
+ {
+ switch ($algorithm) {
+ case 'none':
+ return 0;
+ case 'aes128-cbc':
+ case 'aes128-ctr':
+ case 'arcfour':
+ case 'arcfour128':
+ case 'blowfish-cbc':
+ case 'blowfish-ctr':
+ case 'twofish128-cbc':
+ case 'twofish128-ctr':
+ return 16;
+ case '3des-cbc':
+ case '3des-ctr':
+ case 'aes192-cbc':
+ case 'aes192-ctr':
+ case 'twofish192-cbc':
+ case 'twofish192-ctr':
+ return 24;
+ case 'aes256-cbc':
+ case 'aes256-ctr':
+ case 'arcfour256':
+ case 'twofish-cbc':
+ case 'twofish256-cbc':
+ case 'twofish256-ctr':
+ return 32;
+ }
+ return null;
+ }
+
+ /**
+ * Maps an encryption algorithm name to an instance of a subclass of
+ * \phpseclib\Crypt\Base.
+ *
+ * @param String $algorithm Name of the encryption algorithm
+ * @return Mixed Instance of \phpseclib\Crypt\Base or null for unknown
+ * @access private
+ */
+ function _encryption_algorithm_to_crypt_instance($algorithm)
+ {
+ switch ($algorithm) {
+ case '3des-cbc':
+ return new TripleDES();
+ case '3des-ctr':
+ return new TripleDES(Base::MODE_CTR);
+ case 'aes256-cbc':
+ case 'aes192-cbc':
+ case 'aes128-cbc':
+ return new Rijndael();
+ case 'aes256-ctr':
+ case 'aes192-ctr':
+ case 'aes128-ctr':
+ return new Rijndael(Base::MODE_CTR);
+ case 'blowfish-cbc':
+ return new Blowfish();
+ case 'blowfish-ctr':
+ return new Blowfish(Base::MODE_CTR);
+ case 'twofish128-cbc':
+ case 'twofish192-cbc':
+ case 'twofish256-cbc':
+ case 'twofish-cbc':
+ return new Twofish();
+ case 'twofish128-ctr':
+ case 'twofish192-ctr':
+ case 'twofish256-ctr':
+ return new Twofish(Base::MODE_CTR);
+ case 'arcfour':
+ case 'arcfour128':
+ case 'arcfour256':
+ return new RC4();
+ }
+ return null;
+ }
+
/**
* Login
*
@@ -1910,8 +1901,11 @@ class SSH2
}
if (!($this->bitmap & self::MASK_LOGIN_REQ)) {
- $packet = pack('CNa*',
- NET_SSH2_MSG_SERVICE_REQUEST, strlen('ssh-userauth'), 'ssh-userauth'
+ $packet = pack(
+ 'CNa*',
+ NET_SSH2_MSG_SERVICE_REQUEST,
+ strlen('ssh-userauth'),
+ 'ssh-userauth'
);
if (!$this->_send_binary_packet($packet)) {
@@ -1950,9 +1944,15 @@ class SSH2
}
if (!isset($password)) {
- $packet = pack('CNa*Na*Na*',
- NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',
- strlen('none'), 'none'
+ $packet = pack(
+ 'CNa*Na*Na*',
+ NET_SSH2_MSG_USERAUTH_REQUEST,
+ strlen($username),
+ $username,
+ strlen('ssh-connection'),
+ 'ssh-connection',
+ strlen('none'),
+ 'none'
);
if (!$this->_send_binary_packet($packet)) {
@@ -1976,18 +1976,36 @@ class SSH2
}
}
- $packet = pack('CNa*Na*Na*CNa*',
- NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',
- strlen('password'), 'password', 0, strlen($password), $password
+ $packet = pack(
+ 'CNa*Na*Na*CNa*',
+ NET_SSH2_MSG_USERAUTH_REQUEST,
+ strlen($username),
+ $username,
+ strlen('ssh-connection'),
+ 'ssh-connection',
+ strlen('password'),
+ 'password',
+ 0,
+ strlen($password),
+ $password
);
// remove the username and password from the logged packet
if (!defined('NET_SSH2_LOGGING')) {
$logged = null;
} else {
- $logged = pack('CNa*Na*Na*CNa*',
- NET_SSH2_MSG_USERAUTH_REQUEST, strlen('username'), 'username', strlen('ssh-connection'), 'ssh-connection',
- strlen('password'), 'password', 0, strlen('password'), 'password'
+ $logged = pack(
+ 'CNa*Na*Na*CNa*',
+ NET_SSH2_MSG_USERAUTH_REQUEST,
+ strlen('username'),
+ 'username',
+ strlen('ssh-connection'),
+ 'ssh-connection',
+ strlen('password'),
+ 'password',
+ 0,
+ strlen('password'),
+ 'password'
);
}
@@ -2046,9 +2064,19 @@ class SSH2
*/
function _keyboard_interactive_login($username, $password)
{
- $packet = pack('CNa*Na*Na*Na*Na*',
- NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',
- strlen('keyboard-interactive'), 'keyboard-interactive', 0, '', 0, ''
+ $packet = pack(
+ 'CNa*Na*Na*Na*Na*',
+ NET_SSH2_MSG_USERAUTH_REQUEST,
+ strlen($username),
+ $username,
+ strlen('ssh-connection'),
+ 'ssh-connection',
+ strlen('keyboard-interactive'),
+ 'keyboard-interactive',
+ 0,
+ '',
+ 0,
+ ''
);
if (!$this->_send_binary_packet($packet)) {
@@ -2119,7 +2147,7 @@ class SSH2
// see http://tools.ietf.org/html/rfc4256#section-3.2
if (strlen($this->last_interactive_response)) {
$this->last_interactive_response = '';
- } else if (defined('NET_SSH2_LOGGING')) {
+ } elseif (defined('NET_SSH2_LOGGING')) {
$this->message_number_log[count($this->message_number_log) - 1] = str_replace(
'UNKNOWN',
'NET_SSH2_MSG_USERAUTH_INFO_REQUEST',
@@ -2216,13 +2244,25 @@ class SSH2
'e' => $publickey['e']->toBytes(true),
'n' => $publickey['n']->toBytes(true)
);
- $publickey = pack('Na*Na*Na*',
- strlen('ssh-rsa'), 'ssh-rsa', strlen($publickey['e']), $publickey['e'], strlen($publickey['n']), $publickey['n']
+ $publickey = pack(
+ 'Na*Na*Na*',
+ strlen('ssh-rsa'),
+ 'ssh-rsa',
+ strlen($publickey['e']),
+ $publickey['e'],
+ strlen($publickey['n']),
+ $publickey['n']
);
- $part1 = pack('CNa*Na*Na*',
- NET_SSH2_MSG_USERAUTH_REQUEST, strlen($username), $username, strlen('ssh-connection'), 'ssh-connection',
- strlen('publickey'), 'publickey'
+ $part1 = pack(
+ 'CNa*Na*Na*',
+ NET_SSH2_MSG_USERAUTH_REQUEST,
+ strlen($username),
+ $username,
+ strlen('ssh-connection'),
+ 'ssh-connection',
+ strlen('publickey'),
+ 'publickey'
);
$part2 = pack('Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publickey), $publickey);
@@ -2339,8 +2379,15 @@ class SSH2
// uses 0x4000, that's what will be used here, as well.
$packet_size = 0x4000;
- $packet = pack('CNa*N3',
- NET_SSH2_MSG_CHANNEL_OPEN, strlen('session'), 'session', self::CHANNEL_EXEC, $this->window_size_server_to_client[self::CHANNEL_EXEC], $packet_size);
+ $packet = pack(
+ 'CNa*N3',
+ NET_SSH2_MSG_CHANNEL_OPEN,
+ strlen('session'),
+ 'session',
+ self::CHANNEL_EXEC,
+ $this->window_size_server_to_client[self::CHANNEL_EXEC],
+ $packet_size
+ );
if (!$this->_send_binary_packet($packet)) {
return false;
@@ -2355,9 +2402,22 @@ class SSH2
if ($this->request_pty === true) {
$terminal_modes = pack('C', NET_SSH2_TTY_OP_END);
- $packet = pack('CNNa*CNa*N5a*',
- NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_EXEC], strlen('pty-req'), 'pty-req', 1, strlen('vt100'), 'vt100',
- $this->windowColumns, $this->windowRows, 0, 0, strlen($terminal_modes), $terminal_modes);
+ $packet = pack(
+ 'CNNa*CNa*N5a*',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $this->server_channels[self::CHANNEL_EXEC],
+ strlen('pty-req'),
+ 'pty-req',
+ 1,
+ strlen('vt100'),
+ 'vt100',
+ $this->windowColumns,
+ $this->windowRows,
+ 0,
+ 0,
+ strlen($terminal_modes),
+ $terminal_modes
+ );
if (!$this->_send_binary_packet($packet)) {
return false;
@@ -2390,8 +2450,16 @@ class SSH2
// although, in theory, the size of SSH_MSG_CHANNEL_REQUEST could exceed the maximum packet size established by
// SSH_MSG_CHANNEL_OPEN_CONFIRMATION, RFC4254#section-5.1 states that the "maximum packet size" refers to the
// "maximum size of an individual data packet". ie. SSH_MSG_CHANNEL_DATA. RFC4254#section-5.2 corroborates.
- $packet = pack('CNNa*CNa*',
- NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_EXEC], strlen('exec'), 'exec', 1, strlen($command), $command);
+ $packet = pack(
+ 'CNNa*CNa*',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $this->server_channels[self::CHANNEL_EXEC],
+ strlen('exec'),
+ 'exec',
+ 1,
+ strlen($command),
+ $command
+ );
if (!$this->_send_binary_packet($packet)) {
return false;
}
@@ -2449,8 +2517,15 @@ class SSH2
$this->window_size_server_to_client[self::CHANNEL_SHELL] = $this->window_size;
$packet_size = 0x4000;
- $packet = pack('CNa*N3',
- NET_SSH2_MSG_CHANNEL_OPEN, strlen('session'), 'session', self::CHANNEL_SHELL, $this->window_size_server_to_client[self::CHANNEL_SHELL], $packet_size);
+ $packet = pack(
+ 'CNa*N3',
+ NET_SSH2_MSG_CHANNEL_OPEN,
+ strlen('session'),
+ 'session',
+ self::CHANNEL_SHELL,
+ $this->window_size_server_to_client[self::CHANNEL_SHELL],
+ $packet_size
+ );
if (!$this->_send_binary_packet($packet)) {
return false;
@@ -2464,9 +2539,22 @@ class SSH2
}
$terminal_modes = pack('C', NET_SSH2_TTY_OP_END);
- $packet = pack('CNNa*CNa*N5a*',
- NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_SHELL], strlen('pty-req'), 'pty-req', 1, strlen('vt100'), 'vt100',
- $this->windowColumns, $this->windowRows, 0, 0, strlen($terminal_modes), $terminal_modes);
+ $packet = pack(
+ 'CNNa*CNa*N5a*',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $this->server_channels[self::CHANNEL_SHELL],
+ strlen('pty-req'),
+ 'pty-req',
+ 1,
+ strlen('vt100'),
+ 'vt100',
+ $this->windowColumns,
+ $this->windowRows,
+ 0,
+ 0,
+ strlen($terminal_modes),
+ $terminal_modes
+ );
if (!$this->_send_binary_packet($packet)) {
return false;
@@ -2489,8 +2577,14 @@ class SSH2
throw new \UnexpectedValueException('Unable to request pseudo-terminal');
}
- $packet = pack('CNNa*C',
- NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_SHELL], strlen('shell'), 'shell', 1);
+ $packet = pack(
+ 'CNNa*C',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $this->server_channels[self::CHANNEL_SHELL],
+ strlen('shell'),
+ 'shell',
+ 1
+ );
if (!$this->_send_binary_packet($packet)) {
return false;
}
@@ -2578,7 +2672,7 @@ class SSH2
$match = $expect;
while (true) {
if ($mode == self::READ_REGEX) {
- preg_match($expect, $this->interactiveBuffer, $matches);
+ preg_match($expect, substr($this->interactiveBuffer, -1024), $matches);
$match = isset($matches[0]) ? $matches[0] : '';
}
$pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false;
@@ -2635,8 +2729,15 @@ class SSH2
{
$this->window_size_server_to_client[self::CHANNEL_SUBSYSTEM] = $this->window_size;
- $packet = pack('CNa*N3',
- NET_SSH2_MSG_CHANNEL_OPEN, strlen('session'), 'session', self::CHANNEL_SUBSYSTEM, $this->window_size, 0x4000);
+ $packet = pack(
+ 'CNa*N3',
+ NET_SSH2_MSG_CHANNEL_OPEN,
+ strlen('session'),
+ 'session',
+ self::CHANNEL_SUBSYSTEM,
+ $this->window_size,
+ 0x4000
+ );
if (!$this->_send_binary_packet($packet)) {
return false;
@@ -2649,8 +2750,16 @@ class SSH2
return false;
}
- $packet = pack('CNNa*CNa*',
- NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_SUBSYSTEM], strlen('subsystem'), 'subsystem', 1, strlen($subsystem), $subsystem);
+ $packet = pack(
+ 'CNNa*CNa*',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $this->server_channels[self::CHANNEL_SUBSYSTEM],
+ strlen('subsystem'),
+ 'subsystem',
+ 1,
+ strlen($subsystem),
+ $subsystem
+ );
if (!$this->_send_binary_packet($packet)) {
return false;
}
@@ -2660,7 +2769,7 @@ class SSH2
$response = $this->_get_channel_packet(self::CHANNEL_SUBSYSTEM);
if ($response === false) {
- return false;
+ return false;
}
$this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_DATA;
@@ -2899,34 +3008,48 @@ class SSH2
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
$data = $this->_string_shift($payload, $length);
extract(unpack('Nserver_channel', $this->_string_shift($payload, 4)));
- switch($data) {
+ switch ($data) {
case 'auth-agent':
case 'auth-agent@openssh.com':
if (isset($this->agent)) {
- $new_channel = self::CHANNEL_AGENT_FORWARD;
+ $new_channel = self::CHANNEL_AGENT_FORWARD;
- extract(unpack('Nremote_window_size', $this->_string_shift($payload, 4)));
- extract(unpack('Nremote_maximum_packet_size', $this->_string_shift($payload, 4)));
+ extract(unpack('Nremote_window_size', $this->_string_shift($payload, 4)));
+ extract(unpack('Nremote_maximum_packet_size', $this->_string_shift($payload, 4)));
- $this->packet_size_client_to_server[$new_channel] = $remote_window_size;
- $this->window_size_server_to_client[$new_channel] = $remote_maximum_packet_size;
- $this->window_size_client_to_server[$new_channel] = $this->window_size;
+ $this->packet_size_client_to_server[$new_channel] = $remote_window_size;
+ $this->window_size_server_to_client[$new_channel] = $remote_maximum_packet_size;
+ $this->window_size_client_to_server[$new_channel] = $this->window_size;
- $packet_size = 0x4000;
+ $packet_size = 0x4000;
- $packet = pack('CN4',
- NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, $server_channel, $new_channel, $packet_size, $packet_size);
+ $packet = pack(
+ 'CN4',
+ NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,
+ $server_channel,
+ $new_channel,
+ $packet_size,
+ $packet_size
+ );
- $this->server_channels[$new_channel] = $server_channel;
- $this->channel_status[$new_channel] = NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION;
- if (!$this->_send_binary_packet($packet)) {
- return false;
- }
+ $this->server_channels[$new_channel] = $server_channel;
+ $this->channel_status[$new_channel] = NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION;
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
}
break;
default:
- $packet = pack('CN3a*Na*',
- NET_SSH2_MSG_REQUEST_FAILURE, $server_channel, NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED, 0, '', 0, '');
+ $packet = pack(
+ 'CN3a*Na*',
+ NET_SSH2_MSG_REQUEST_FAILURE,
+ $server_channel,
+ NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED,
+ 0,
+ '',
+ 0,
+ ''
+ );
if (!$this->_send_binary_packet($packet)) {
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
@@ -3401,7 +3524,8 @@ class SSH2
);
$temp = $this->_string_shift($data, $max_size);
- $packet = pack('CN2a*',
+ $packet = pack(
+ 'CN2a*',
NET_SSH2_MSG_CHANNEL_DATA,
$this->server_channels[$client_channel],
strlen($temp),
@@ -3442,7 +3566,8 @@ class SSH2
$this->curTimeout = 0;
- while (!is_bool($this->_get_channel_packet($client_channel)));
+ while (!is_bool($this->_get_channel_packet($client_channel))) {
+ }
if ($want_reply) {
$this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel]));
@@ -3502,7 +3627,7 @@ class SSH2
{
$args = func_get_args();
foreach ($args as $arg) {
- foreach ($arg as $key=>$value) {
+ foreach ($arg as $key => $value) {
if (!defined($value)) {
define($value, $key);
} else {
@@ -3602,6 +3727,25 @@ class SSH2
}
}
+ /**
+ * Returns the first value of the intersection of two arrays or false if
+ * the intersection is empty. The order is defined by the first parameter.
+ *
+ * @param Array $array1
+ * @param Array $array2
+ * @return Mixed False if intersection is empty, else intersected value.
+ * @access private
+ */
+ function _array_intersect_first($array1, $array2)
+ {
+ foreach ($array1 as $value) {
+ if (in_array($value, $array2)) {
+ return $value;
+ }
+ }
+ return false;
+ }
+
/**
* Returns all errors
*
diff --git a/phpseclib/System/SSH/Agent.php b/phpseclib/System/SSH/Agent.php
index e53dfd5a..5ec47169 100644
--- a/phpseclib/System/SSH/Agent.php
+++ b/phpseclib/System/SSH/Agent.php
@@ -226,8 +226,14 @@ class Agent
return false;
}
- $packet = pack('CNNa*C',
- NET_SSH2_MSG_CHANNEL_REQUEST, $ssh->server_channels[$request_channel], strlen('auth-agent-req@openssh.com'), 'auth-agent-req@openssh.com', 1);
+ $packet = pack(
+ 'CNNa*C',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $ssh->server_channels[$request_channel],
+ strlen('auth-agent-req@openssh.com'),
+ 'auth-agent-req@openssh.com',
+ 1
+ );
$ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST;
diff --git a/tests/Functional/Net/SCPSSH2UserStoryTest.php b/tests/Functional/Net/SCPSSH2UserStoryTest.php
index 6abd7e5f..41e86e95 100644
--- a/tests/Functional/Net/SCPSSH2UserStoryTest.php
+++ b/tests/Functional/Net/SCPSSH2UserStoryTest.php
@@ -15,7 +15,7 @@ class Functional_Net_SCPSSH2UserStoryTest extends PhpseclibFunctionalTestCase
static protected $exampleData;
static protected $exampleDataLength;
- static public function setUpBeforeClass()
+ public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
self::$remoteFile = uniqid('phpseclib-scp-ssh2-') . '.txt';
diff --git a/tests/Functional/Net/SFTPLargeFileTest.php b/tests/Functional/Net/SFTPLargeFileTest.php
index 89d2c95a..cc170e8a 100644
--- a/tests/Functional/Net/SFTPLargeFileTest.php
+++ b/tests/Functional/Net/SFTPLargeFileTest.php
@@ -11,7 +11,7 @@ use phpseclib\Net\SFTP;
class Functional_Net_SFTPLargeFileTest extends Functional_Net_SFTPTestCase
{
- static public function setUpBeforeClass()
+ public static function setUpBeforeClass()
{
if (!extension_loaded('mcrypt') && !extension_loaded('openssl')) {
self::markTestSkipped('This test depends on mcrypt or openssl for performance.');
diff --git a/tests/Functional/Net/SFTPStreamTest.php b/tests/Functional/Net/SFTPStreamTest.php
index d8c42ca3..b596c4f8 100644
--- a/tests/Functional/Net/SFTPStreamTest.php
+++ b/tests/Functional/Net/SFTPStreamTest.php
@@ -10,7 +10,7 @@ use phpseclib\Net\SFTP\Stream;
class Functional_Net_SFTPStreamTest extends Functional_Net_SFTPTestCase
{
- static public function setUpBeforeClass()
+ public static function setUpBeforeClass()
{
Stream::register();
parent::setUpBeforeClass();
diff --git a/tests/Functional/Net/SFTPUserStoryTest.php b/tests/Functional/Net/SFTPUserStoryTest.php
index 3b468426..57102ecb 100644
--- a/tests/Functional/Net/SFTPUserStoryTest.php
+++ b/tests/Functional/Net/SFTPUserStoryTest.php
@@ -15,7 +15,7 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
static protected $exampleDataLength;
static protected $buffer;
- static public function setUpBeforeClass()
+ public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
@@ -164,7 +164,9 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
{
$r = substr(self::$buffer, 0, $length);
self::$buffer = substr(self::$buffer, $length);
- if (strlen($r)) return $r;
+ if (strlen($r)) {
+ return $r;
+ }
return null;
}
@@ -337,7 +339,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
if ($sftp->is_file($file)) {
$cur_size = $sftp->size($file);
$this->assertLessThanOrEqual(
- $last_size, $cur_size,
+ $last_size,
+ $cur_size,
'Failed asserting that nlist() is in descending order'
);
$last_size = $cur_size;
@@ -388,7 +391,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
$stat = $sftp->stat('symlink');
$lstat = $sftp->lstat('symlink');
$this->assertNotEquals(
- $stat, $lstat,
+ $stat,
+ $lstat,
'Failed asserting that stat and lstat returned different output for a symlink'
);
@@ -421,7 +425,9 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
*/
public function testReadlink($sftp)
{
- $this->assertInternalType('string', $sftp->readlink('symlink'),
+ $this->assertInternalType(
+ 'string',
+ $sftp->readlink('symlink'),
'Failed asserting that a symlink\'s target could be read'
);
@@ -436,12 +442,14 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
{
$stat = $sftp->stat('.');
$this->assertInternalType(
- 'array', $stat,
+ 'array',
+ $stat,
'Failed asserting that stat on . returns an array'
);
$lstat = $sftp->lstat('.');
$this->assertInternalType(
- 'array', $lstat,
+ 'array',
+ $lstat,
'Failed asserting that lstat on . returns an array'
);
@@ -596,5 +604,52 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
$sftp->stat(self::$scratchDir),
'Failed asserting that stat on a deleted directory returns false'
);
+
+ return $sftp;
+ }
+
+ /**
+ * @depends testDeleteEmptyDir
+ * @group github735
+ */
+ public function testStatVsLstat($sftp)
+ {
+ $this->assertTrue($sftp->mkdir(self::$scratchDir));
+ $this->assertTrue($sftp->chdir(self::$scratchDir));
+ $this->assertTrue($sftp->put('text.txt', 'zzzzz'));
+ $this->assertTrue($sftp->symlink('text.txt', 'link.txt'));
+ $this->assertTrue($sftp->mkdir('subdir'));
+ $this->assertTrue($sftp->symlink('subdir', 'linkdir'));
+
+ $sftp->clearStatCache();
+
+ // pre-populate the stat cache
+ $sftp->nlist();
+
+ $stat = $sftp->stat('link.txt');
+ $this->assertSame($stat['type'], NET_SFTP_TYPE_REGULAR);
+ $stat = $sftp->lstat('link.txt');
+ $this->assertSame($stat['type'], NET_SFTP_TYPE_SYMLINK);
+
+ $stat = $sftp->stat('linkdir');
+ $this->assertSame($stat['type'], NET_SFTP_TYPE_DIRECTORY);
+ $stat = $sftp->lstat('link.txt');
+ $this->assertSame($stat['type'], NET_SFTP_TYPE_SYMLINK);
+
+ $sftp->disableStatCache();
+
+ $sftp->nlist();
+
+ $stat = $sftp->stat('link.txt');
+ $this->assertSame($stat['type'], NET_SFTP_TYPE_REGULAR);
+ $stat = $sftp->lstat('link.txt');
+ $this->assertSame($stat['type'], NET_SFTP_TYPE_SYMLINK);
+
+ $stat = $sftp->stat('linkdir');
+ $this->assertSame($stat['type'], NET_SFTP_TYPE_DIRECTORY);
+ $stat = $sftp->lstat('link.txt');
+ $this->assertSame($stat['type'], NET_SFTP_TYPE_SYMLINK);
+
+ $sftp->enableStatCache();
}
}
diff --git a/tests/Functional/Net/SSH2Test.php b/tests/Functional/Net/SSH2Test.php
index 44f18d1e..51373705 100644
--- a/tests/Functional/Net/SSH2Test.php
+++ b/tests/Functional/Net/SSH2Test.php
@@ -87,4 +87,17 @@ class Functional_Net_SSH2Test extends PhpseclibFunctionalTestCase
$this->assertInternalType('string', $ssh->getServerPublicHostKey());
}
+
+ public function testOpenSocketConnect()
+ {
+ $fsock = fsockopen($this->getEnv('SSH_HOSTNAME'), 22);
+ $ssh = new SSH2($fsock);
+
+ $username = $this->getEnv('SSH_USERNAME');
+ $password = $this->getEnv('SSH_PASSWORD');
+ $this->assertTrue(
+ $ssh->login($username, $password),
+ 'SSH2 login using an open socket failed.'
+ );
+ }
}
diff --git a/tests/PhpseclibFunctionalTestCase.php b/tests/PhpseclibFunctionalTestCase.php
index bbde05a3..e0b3a7cf 100644
--- a/tests/PhpseclibFunctionalTestCase.php
+++ b/tests/PhpseclibFunctionalTestCase.php
@@ -10,7 +10,7 @@ use phpseclib\Math\BigInteger;
abstract class PhpseclibFunctionalTestCase extends PhpseclibTestCase
{
- static public function setUpBeforeClass()
+ public static function setUpBeforeClass()
{
if (extension_loaded('runkit')) {
if (extension_loaded('gmp')) {
diff --git a/tests/PhpseclibTestCase.php b/tests/PhpseclibTestCase.php
index f7fce154..8f594e04 100644
--- a/tests/PhpseclibTestCase.php
+++ b/tests/PhpseclibTestCase.php
@@ -53,7 +53,7 @@ abstract class PhpseclibTestCase extends PHPUnit_Framework_TestCase
*
* @return null
*/
- static protected function ensureConstant($constant, $expected)
+ protected static function ensureConstant($constant, $expected)
{
if (defined($constant)) {
$value = constant($constant);
@@ -82,15 +82,15 @@ abstract class PhpseclibTestCase extends PHPUnit_Framework_TestCase
}
/**
- * @param string $filename
+ * @param string $filename Filename relative to library directory.
*
* @return null
*/
- static protected function reRequireFile($filename)
+ protected static function reRequireFile($filename)
{
if (function_exists('runkit_import')) {
$result = runkit_import(
- $filename,
+ sprintf('%s/../phpseclib/%s', __DIR__, $filename),
RUNKIT_IMPORT_FUNCTIONS |
RUNKIT_IMPORT_CLASS_METHODS |
RUNKIT_IMPORT_OVERRIDE
diff --git a/tests/Unit/Crypt/Hash/MD5Test.php b/tests/Unit/Crypt/Hash/MD5Test.php
index 2de322da..431184ee 100644
--- a/tests/Unit/Crypt/Hash/MD5Test.php
+++ b/tests/Unit/Crypt/Hash/MD5Test.php
@@ -22,7 +22,7 @@ class Unit_Crypt_Hash_MD5Test extends Unit_Crypt_Hash_TestCase
$this->assertHashesTo($this->getInstance(), $message, $result);
}
- static public function hashData()
+ public static function hashData()
{
return array(
array('', 'd41d8cd98f00b204e9800998ecf8427e'),
@@ -39,7 +39,7 @@ class Unit_Crypt_Hash_MD5Test extends Unit_Crypt_Hash_TestCase
$this->assertHMACsTo($this->getInstance(), $key, $message, $result);
}
- static public function hmacData()
+ public static function hmacData()
{
return array(
array('', '', '74e6f7298a9c2d168935f58c001bad88'),
diff --git a/tests/Unit/Crypt/Hash/SHA256Test.php b/tests/Unit/Crypt/Hash/SHA256Test.php
index 584483b8..bad46b36 100644
--- a/tests/Unit/Crypt/Hash/SHA256Test.php
+++ b/tests/Unit/Crypt/Hash/SHA256Test.php
@@ -22,7 +22,7 @@ class Unit_Crypt_Hash_SHA256Test extends Unit_Crypt_Hash_TestCase
$this->assertHashesTo($this->getInstance(), $message, $result);
}
- static public function hashData()
+ public static function hashData()
{
return array(
array(
@@ -48,7 +48,7 @@ class Unit_Crypt_Hash_SHA256Test extends Unit_Crypt_Hash_TestCase
$this->assertHMACsTo($this->getInstance(), $key, $message, $result);
}
- static public function hmacData()
+ public static function hmacData()
{
return array(
// RFC 4231
diff --git a/tests/Unit/Crypt/Hash/SHA512Test.php b/tests/Unit/Crypt/Hash/SHA512Test.php
index 78aede77..ad2e63e3 100644
--- a/tests/Unit/Crypt/Hash/SHA512Test.php
+++ b/tests/Unit/Crypt/Hash/SHA512Test.php
@@ -22,7 +22,7 @@ class Unit_Crypt_Hash_SHA512Test extends Unit_Crypt_Hash_TestCase
$this->assertHashesTo($this->getInstance(), $message, $result);
}
- static public function hashData()
+ public static function hashData()
{
return array(
array(
@@ -48,7 +48,7 @@ class Unit_Crypt_Hash_SHA512Test extends Unit_Crypt_Hash_TestCase
$this->assertHMACsTo($this->getInstance(), $key, $message, $result);
}
- static public function hmacData()
+ public static function hmacData()
{
return array(
// RFC 4231
diff --git a/tests/Unit/Crypt/Hash/TestCase.php b/tests/Unit/Crypt/Hash/TestCase.php
index 967e72e0..2ef63c6b 100644
--- a/tests/Unit/Crypt/Hash/TestCase.php
+++ b/tests/Unit/Crypt/Hash/TestCase.php
@@ -9,7 +9,7 @@ use phpseclib\Crypt\Hash;
abstract class Unit_Crypt_Hash_TestCase extends PhpseclibTestCase
{
- static public function setUpBeforeClass()
+ public static function setUpBeforeClass()
{
if (!defined('CRYPT_HASH_MODE')) {
define('CRYPT_HASH_MODE', Hash::MODE_INTERNAL);
diff --git a/tests/Unit/Crypt/RSA/ModeTest.php b/tests/Unit/Crypt/RSA/ModeTest.php
index 0b90210e..b11ac05b 100644
--- a/tests/Unit/Crypt/RSA/ModeTest.php
+++ b/tests/Unit/Crypt/RSA/ModeTest.php
@@ -43,4 +43,24 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
$rsa->loadKey($privatekey);
$this->assertEquals(trim($rsa->decrypt($result), "\0"), $plaintext);
}
+
+ /**
+ * @group github768
+ */
+ public function testPSSSigs()
+ {
+ $rsa = new RSA();
+ $rsa->loadKey('-----BEGIN PUBLIC KEY-----
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVx
+wTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFnc
+CzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0T
+p0GbMJDyR4e9T04ZZwIDAQAB
+-----END PUBLIC KEY-----');
+
+ $sig = pack('H*', '1bd29a1d704a906cd7f726370ce1c63d8fb7b9a620871a05f3141a311c0d6e75fefb5d36dfb50d3ea2d37cd67992471419bfadd35da6e13b494' .
+ '058ddc9b568d4cfea13ddc3c62b86a6256f5f296980d1131d3eaec6089069a3de79983f73eae20198a18721338b4a66e9cfe80e4f8e4fcef7a5bead5cbb' .
+ 'b8ac4c76adffbc178c');
+
+ $this->assertTrue($rsa->verify('zzzz', $sig));
+ }
}
diff --git a/tests/Unit/Crypt/TwofishTest.php b/tests/Unit/Crypt/TwofishTest.php
index 7dc166cc..f47443e9 100644
--- a/tests/Unit/Crypt/TwofishTest.php
+++ b/tests/Unit/Crypt/TwofishTest.php
@@ -18,7 +18,7 @@ class Unit_Crypt_TwofishTest extends PhpseclibTestCase
Base::ENGINE_OPENSSL => 'OpenSSL',
);
- foreach ($engines as $engine=>$name) {
+ foreach ($engines as $engine => $name) {
$tf = new Twofish();
$tf->disablePadding();
diff --git a/tests/Unit/File/X509/X509Test.php b/tests/Unit/File/X509/X509Test.php
index 06c8efb3..045028aa 100644
--- a/tests/Unit/File/X509/X509Test.php
+++ b/tests/Unit/File/X509/X509Test.php
@@ -12,6 +12,55 @@ use phpseclib\Crypt\RSA;
class Unit_File_X509_X509Test extends PhpseclibTestCase
{
+ public function testExtensionMapping()
+ {
+ $test = '-----BEGIN CERTIFICATE-----
+MIIG1jCCBL6gAwIBAgITUAAAAA0qg8bE6DhrLAAAAAAADTANBgkqhkiG9w0BAQsF
+ADAiMSAwHgYDVQQDExcuU2VjdXJlIEVudGVycHJpc2UgQ0EgMTAeFw0xNTAyMjMx
+NTE1MDdaFw0xNjAyMjMxNTE1MDdaMD8xFjAUBgoJkiaJk/IsZAEZFgZzZWN1cmUx
+DjAMBgNVBAMTBVVzZXJzMRUwEwYDVQQDEwxtZXRhY2xhc3NpbmcwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMdG1CzR/gTalbLN9J+2cvMGeD7wsR7S78
+HU5hdwE+kECROjRAcjFBOR57ezSDrkmhkTzo28tj0oAHjOh8N9vuXtASfZSCXugx
+H+ImJ+E7PA4aXBp+0H2hohW9sXNNCFiVNmJLX66O4bxIeKtVRq/+eSNijV4OOEkC
+zMyTHAUbOFP0t6KoJtM1syNoQ1+fKdfcjz5XtiEzSVcp2zf0MwNFSeZSgGQ0jh8A
+Kd6YVKA8ZnrqOWZxKETT+bBNTjIT0ggjQfzcE4zW2RzrN7zWabUowoU92+DAp4s3
+sAEywX9ISSge62DEzTnZZSf9bpoScAfT8raRFA3BkoJ/s4c4CgfPAgMBAAGjggLm
+MIIC4jAdBgNVHQ4EFgQULlIyJL9+ZwAI/SkVdsJMxFOVp+EwHwYDVR0jBBgwFoAU
+5nEIMEUT5mMd1WepmviwgK7dIzwwggEKBgNVHR8EggEBMIH+MIH7oIH4oIH1hoG5
+bGRhcDovLy9DTj0uU2VjdXJlJTIwRW50ZXJwcmlzZSUyMENBJTIwMSxDTj1hdXRo
+LENOPUNEUCxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxD
+Tj1Db25maWd1cmF0aW9uLERDPXNlY3VyZT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25M
+aXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnSGN2h0dHA6
+Ly9jcmwuc2VjdXJlb2JzY3VyZS5jb20vP2FjdGlvbj1jcmwmY2E9ZW50ZXJwcmlz
+ZTEwgccGCCsGAQUFBwEBBIG6MIG3MIG0BggrBgEFBQcwAoaBp2xkYXA6Ly8vQ049
+LlNlY3VyZSUyMEVudGVycHJpc2UlMjBDQSUyMDEsQ049QUlBLENOPVB1YmxpYyUy
+MEtleSUyMFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9
+c2VjdXJlP2NBQ2VydGlmaWNhdGU/YmFzZT9vYmplY3RDbGFzcz1jZXJ0aWZpY2F0
+aW9uQXV0aG9yaXR5MBcGCSsGAQQBgjcUAgQKHggAVQBzAGUAcjAOBgNVHQ8BAf8E
+BAMCBaAwKQYDVR0lBCIwIAYKKwYBBAGCNwoDBAYIKwYBBQUHAwQGCCsGAQUFBwMC
+MC4GA1UdEQQnMCWgIwYKKwYBBAGCNxQCA6AVDBNtZXRhY2xhc3NpbmdAc2VjdXJl
+MEQGCSqGSIb3DQEJDwQ3MDUwDgYIKoZIhvcNAwICAgCAMA4GCCqGSIb3DQMEAgIA
+gDAHBgUrDgMCBzAKBggqhkiG9w0DBzANBgkqhkiG9w0BAQsFAAOCAgEAKNmjYh+h
+cObJEM0CWgz50jOYKZ4M5iIxoAWgrYY9Pv+0O9aPjvPLzjd5bY322L8lxh5wy5my
+DKmip+irzjdVdxzQfoyy+ceODmCbX9L6MfEDn0RBzdwjLe1/eOxE1na0sZztrVCc
+yt5nI91NNGZJUcVqVQsIA/25FWlkvo/FTfuqTuXdQiEVM5MCKJI915anmTdugy+G
+0CmBJALIxtyz5P7sZhaHZFNdpKnx82QsauErqjP9H0RXc6VXX5qt+tEDvYfSlFcc
+0lv3aQnV/eIdfm7APJkQ3lmNWWQwdkVf7adXJ7KAAPHSt1yvSbVxThJR/jmIkyeQ
+XW/TOP5m7JI/GrmvdlzI1AgwJ+zO8fOmCDuif99pDb1CvkzQ65RZ8p5J1ZV6hzlb
+VvOhn4LDnT1jnTcEqigmx1gxM/5ifvMorXn/ItMjKPlb72vHpeF7OeKE8GHsvZAm
+osHcKyJXbTIcXchmpZX1efbmCMJBqHgJ/qBTBMl9BX0+YqbTZyabRJSs9ezbTRn0
+oRYl21Q8EnvS71CemxEUkSsKJmfJKkQNCsOjc8AbX/V/X9R7LJkH3UEx6K2zQQKK
+k6m17mi63YW/+iPCGOWZ2qXmY5HPEyyF2L4L4IDryFJ+8xLyw3pH9/yp5aHZDtp6
+833K6qyjgHJT+fUzSEYpiwF5rSBJIGClOCY=
+-----END CERTIFICATE-----';
+
+ $x509 = new X509();
+
+ $cert = $x509->loadX509($test);
+
+ $this->assertInternalType('array', $cert['tbsCertificate']['extensions'][3]['extnValue']);
+ }
+
public function testLoadUnsupportedExtension()
{
$test = '-----BEGIN CERTIFICATE-----
diff --git a/tests/Unit/Math/BigInteger/BCMathTest.php b/tests/Unit/Math/BigInteger/BCMathTest.php
index a53fce8c..691d4031 100644
--- a/tests/Unit/Math/BigInteger/BCMathTest.php
+++ b/tests/Unit/Math/BigInteger/BCMathTest.php
@@ -7,7 +7,7 @@
class Unit_Math_BigInteger_BCMathTest extends Unit_Math_BigInteger_TestCase
{
- static public function setUpBeforeClass()
+ public static function setUpBeforeClass()
{
if (!extension_loaded('bcmath')) {
self::markTestSkipped('BCMath extension is not available.');
diff --git a/tests/Unit/Math/BigInteger/GMPTest.php b/tests/Unit/Math/BigInteger/GMPTest.php
index 9bcac212..f344a4e8 100644
--- a/tests/Unit/Math/BigInteger/GMPTest.php
+++ b/tests/Unit/Math/BigInteger/GMPTest.php
@@ -7,7 +7,7 @@
class Unit_Math_BigInteger_GMPTest extends Unit_Math_BigInteger_TestCase
{
- static public function setUpBeforeClass()
+ public static function setUpBeforeClass()
{
if (!extension_loaded('gmp')) {
self::markTestSkipped('GNU Multiple Precision (GMP) extension is not available.');
diff --git a/tests/Unit/Math/BigInteger/InternalOpenSSLTest.php b/tests/Unit/Math/BigInteger/InternalOpenSSLTest.php
index 83781407..495401fd 100644
--- a/tests/Unit/Math/BigInteger/InternalOpenSSLTest.php
+++ b/tests/Unit/Math/BigInteger/InternalOpenSSLTest.php
@@ -7,7 +7,7 @@
class Unit_Math_BigInteger_InternalOpenSSLTest extends Unit_Math_BigInteger_TestCase
{
- static public function setUpBeforeClass()
+ public static function setUpBeforeClass()
{
if (!function_exists('openssl_public_encrypt')) {
self::markTestSkipped('openssl_public_encrypt() function is not available.');
diff --git a/tests/Unit/Math/BigInteger/InternalTest.php b/tests/Unit/Math/BigInteger/InternalTest.php
index 0e4e3dc0..599d94ae 100644
--- a/tests/Unit/Math/BigInteger/InternalTest.php
+++ b/tests/Unit/Math/BigInteger/InternalTest.php
@@ -7,7 +7,7 @@
class Unit_Math_BigInteger_InternalTest extends Unit_Math_BigInteger_TestCase
{
- static public function setUpBeforeClass()
+ public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
diff --git a/tests/Unit/Math/BigInteger/TestCase.php b/tests/Unit/Math/BigInteger/TestCase.php
index 2bcc2fb9..0b236d2e 100644
--- a/tests/Unit/Math/BigInteger/TestCase.php
+++ b/tests/Unit/Math/BigInteger/TestCase.php
@@ -7,12 +7,9 @@
abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
{
- static public function setUpBeforeClass()
+ public static function setUpBeforeClass()
{
- include_once 'Math/BigInteger.php';
-
parent::setUpBeforeClass();
-
self::reRequireFile('Math/BigInteger.php');
}
@@ -63,7 +60,7 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
public function testAdd()
{
$x = $this->getInstance('18446744073709551615');
- $y = $this->getInstance( '100000000000');
+ $y = $this->getInstance('100000000000');
$a = $x->add($y);
$b = $y->add($x);
@@ -78,7 +75,7 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
public function testSubtract()
{
$x = $this->getInstance('18446744073709551618');
- $y = $this->getInstance( '4000000000000');
+ $y = $this->getInstance('4000000000000');
$this->assertSame('18446740073709551618', (string) $x->subtract($y));
}
diff --git a/tests/Unit/Net/SSH2Test.php b/tests/Unit/Net/SSH2Test.php
index b2beed74..df9651af 100644
--- a/tests/Unit/Net/SSH2Test.php
+++ b/tests/Unit/Net/SSH2Test.php
@@ -39,12 +39,16 @@ class Unit_Net_SSH2Test extends PhpseclibTestCase
public function testGenerateIdentifier()
{
$identifier = $this->createSSHMock()->_generate_identifier();
- $this->assertStringStartsWith('SSH-2.0-phpseclib_0.3', $identifier);
+ $this->assertStringStartsWith('SSH-2.0-phpseclib_2.0', $identifier);
+
+ if (extension_loaded('libsodium')) {
+ $this->assertContains('libsodium', $identifier);
+ }
if (extension_loaded('openssl')) {
$this->assertContains('openssl', $identifier);
$this->assertNotContains('mcrypt', $identifier);
- } else if (extension_loaded('mcrypt')) {
+ } elseif (extension_loaded('mcrypt')) {
$this->assertNotContains('openssl', $identifier);
$this->assertContains('mcrypt', $identifier);
} else {
@@ -55,7 +59,7 @@ class Unit_Net_SSH2Test extends PhpseclibTestCase
if (extension_loaded('gmp')) {
$this->assertContains('gmp', $identifier);
$this->assertNotContains('bcmath', $identifier);
- } else if (extension_loaded('bcmath')) {
+ } elseif (extension_loaded('bcmath')) {
$this->assertNotContains('gmp', $identifier);
$this->assertContains('bcmath', $identifier);
} else {
diff --git a/travis/run-phpunit.sh b/travis/run-phpunit.sh
index 600a1d94..5ee69d66 100755
--- a/travis/run-phpunit.sh
+++ b/travis/run-phpunit.sh
@@ -20,7 +20,7 @@ then
PHPUNIT_ARGS="$PHPUNIT_ARGS -d zend.enable_gc=0"
fi
-if [ "$TRAVIS_PHP_VERSION" = 'hhvm' ]
+if [ "$TRAVIS_PHP_VERSION" = 'hhvm' -o "$TRAVIS_PHP_VERSION" = '7.0' ]
then
find tests -type f -name "*Test.php" | \
parallel --gnu --keep-order \