From 1b1e729632b621d8698e3a4dffb4bab4e6f55270 Mon Sep 17 00:00:00 2001 From: terrafrost Date: Sat, 11 Feb 2023 21:32:21 -0600 Subject: [PATCH] backport enhancements from the 2.0 branch --- .github/workflows/ci.yml | 76 +++++++++++++++++++++++ .travis.yml | 39 ------------ phpseclib/Crypt/Blowfish.php | 80 ++++++++++++++++++------- phpseclib/Crypt/DES.php | 2 +- phpseclib/Crypt/RC2.php | 2 +- phpseclib/Crypt/RC4.php | 2 +- phpseclib/Math/BigInteger.php | 6 +- phpseclib/Net/SFTP.php | 2 +- phpseclib/Net/SSH2.php | 2 +- tests/Unit/Crypt/RSA/LoadKeyTest.php | 4 ++ tests/Unit/Crypt/RSA/ModeTest.php | 14 ++--- tests/Unit/Math/BigInteger/TestCase.php | 14 +++++ tests/make_compatible_with_phpunit9.php | 35 +++++++++++ 13 files changed, 204 insertions(+), 74 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml create mode 100644 tests/make_compatible_with_phpunit9.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..b55a1595 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,76 @@ +name: CI +on: [push, pull_request] + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + lint: + name: Lint + timeout-minutes: 5 + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + tools: php-parallel-lint/php-parallel-lint:1 + - name: Lint + run: parallel-lint --show-deprecated build phpseclib tests + strategy: + fail-fast: false + matrix: + php-version: ['5.3', '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] + tests: + name: Tests + timeout-minutes: 10 + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + - name: Composer Install + run: composer install --no-interaction --no-cache + - name: Make Tests Compatiable With PHPUnit 9+ + if: contains(fromJSON('["7.3", "7.4", "8.0", "8.1", "8.2"]'), matrix.php-version) + run: php tests/make_compatible_with_phpunit9.php + - name: Setup Secure Shell Functional Tests + if: matrix.os == 'ubuntu-latest' + run: | + PHPSECLIB_SSH_USERNAME='phpseclib' + PHPSECLIB_SSH_PASSWORD='EePoov8po1aethu2kied1ne0' + + sudo useradd --create-home --base-dir /home "$PHPSECLIB_SSH_USERNAME" + echo "$PHPSECLIB_SSH_USERNAME:$PHPSECLIB_SSH_PASSWORD" | sudo chpasswd + ssh-keygen -t rsa -b 1024 -f "$HOME/.ssh/id_rsa" -q -N "" + eval `ssh-agent -s` + ssh-add "$HOME/.ssh/id_rsa" + sudo mkdir -p "/home/$PHPSECLIB_SSH_USERNAME/.ssh/" + sudo cp "$HOME/.ssh/id_rsa.pub" "/home/$PHPSECLIB_SSH_USERNAME/.ssh/authorized_keys" + sudo ssh-keyscan -t rsa localhost > "/tmp/known_hosts" + sudo cp "/tmp/known_hosts" "/home/$PHPSECLIB_SSH_USERNAME/.ssh/known_hosts" + sudo chown "$PHPSECLIB_SSH_USERNAME:$PHPSECLIB_SSH_USERNAME" "/home/$PHPSECLIB_SSH_USERNAME/.ssh/" -R + + echo "PHPSECLIB_SSH_HOSTNAME=localhost" >> $GITHUB_ENV + echo "PHPSECLIB_SSH_USERNAME=$PHPSECLIB_SSH_USERNAME" >> $GITHUB_ENV + echo "PHPSECLIB_SSH_PASSWORD=$PHPSECLIB_SSH_PASSWORD" >> $GITHUB_ENV + echo "PHPSECLIB_SSH_HOME=/home/phpseclib" >> $GITHUB_ENV + echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" >> $GITHUB_ENV + - name: PHPUnit + run: vendor/bin/phpunit + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + php-version: ['5.3', '5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] + exclude: + # PHP 5.3 / 5.4 on windows don't have openssl or curl installed, which prevents composer from running + - os: windows-latest + php-version: '5.3' + - os: windows-latest + php-version: '5.4' \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b32fc3d8..00000000 --- a/.travis.yml +++ /dev/null @@ -1,39 +0,0 @@ -language: php - -matrix: - include: - - php: 5.4 - dist: trusty - - php: 5.5.9 - dist: trusty - - php: 5.5 - dist: trusty - - php: 5.6 - dist: xenial - - php: 7.0 - dist: xenial - - php: 7.1 - dist: xenial - - php: 7.2 - dist: xenial - - php: 7.3 - dist: xenial - - php: 7.4 - dist: xenial - - php: 8.0 - dist: bionic - - php: 8.1 - dist: bionic - -before_install: true - -install: - - phpenv config-rm xdebug.ini - - eval `ssh-agent -s` - - travis/setup-secure-shell.sh - - sh -c "if [ '$TRAVIS_PHP_VERSION' != 'hhvm' -a `php -r "echo (int) version_compare(PHP_VERSION, '7.0', '<');"` = "1" ]; then travis/install-php-extensions.sh; fi" - - travis/setup-composer.sh - -script: - - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.5' ]; then vendor/bin/phing -f build/build.xml sniff; fi" - - travis/run-phpunit.sh diff --git a/phpseclib/Crypt/Blowfish.php b/phpseclib/Crypt/Blowfish.php index b3257d67..687002e4 100644 --- a/phpseclib/Crypt/Blowfish.php +++ b/phpseclib/Crypt/Blowfish.php @@ -518,7 +518,7 @@ class Crypt_Blowfish extends Crypt_Base // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not - if (version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { + if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { return false; } if (version_compare(PHP_VERSION, '5.3.7') < 0 && $this->key_length != 16) { @@ -839,9 +839,13 @@ class Crypt_Blowfish extends Crypt_Base $l = $in[1]; $r = $in[2]; - list($r, $l) = CRYPT_BASE_USE_REG_INTVAL ? - $this->_encryptBlockHelperFast($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p) : - $this->_encryptBlockHelperSlow($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p); + if (CRYPT_BASE_USE_REG_INTVAL) { + list($r, $l) = PHP_INT_SIZE === 8 ? + $this->_encryptBlockHelperFast($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p) : + $this->_encryptBlockHelperFast32($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p); + } else { + list($r, $l) = $this->_encryptBlockHelperSlow($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p); + } return pack("N*", $r, $l); } @@ -882,6 +886,42 @@ class Crypt_Blowfish extends Crypt_Base return array($x1 & 0xFFFFFFFF ^ $p[17], $x0 & 0xFFFFFFFF); } + /** + * Fast helper function for block encryption (32-bit) + * + * @access private + * @param int $x0 + * @param int $x1 + * @param int[] $sbox0 + * @param int[] $sbox1 + * @param int[] $sbox2 + * @param int[] $sbox3 + * @param int[] $p + * @return int[] + */ + function _encryptBlockHelperFast32($x0, $x1, $sbox0, $sbox1, $sbox2, $sbox3, $p) + { + $x0 ^= $p[0]; + $x1 ^= ((($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[1]; + $x0 ^= ((($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[2]; + $x1 ^= ((($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[3]; + $x0 ^= ((($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[4]; + $x1 ^= ((($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[5]; + $x0 ^= ((($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[6]; + $x1 ^= ((($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[7]; + $x0 ^= ((($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[8]; + $x1 ^= ((($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[9]; + $x0 ^= ((($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[10]; + $x1 ^= ((($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[11]; + $x0 ^= ((($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[12]; + $x1 ^= ((($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[13]; + $x0 ^= ((($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[14]; + $x1 ^= ((($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[15]; + $x0 ^= ((($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[16]; + + return array($x1 & 0xFFFFFFFF ^ $p[17], $x0 & 0xFFFFFFFF); + } + /** * Slow helper function for block encryption * @@ -898,22 +938,22 @@ class Crypt_Blowfish extends Crypt_Base function _encryptBlockHelperSlow($x0, $x1, $sbox0, $sbox1, $sbox2, $sbox3, $p) { $x0^= $p[0]; - $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[1]; - $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[2]; - $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[3]; - $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[4]; - $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[5]; - $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[6]; - $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[7]; - $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[8]; - $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[9]; - $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[10]; - $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[11]; - $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[12]; - $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[13]; - $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[14]; - $x1^= $this->safe_intval(($this->safe_intval($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[15]; - $x0^= $this->safe_intval(($this->safe_intval($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[16]; + $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[1]; + $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[2]; + $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[3]; + $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[4]; + $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[5]; + $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[6]; + $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[7]; + $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[8]; + $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[9]; + $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[10]; + $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[11]; + $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[12]; + $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[13]; + $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[14]; + $x1^= $this->safe_intval(($this->safe_intval($sbox0[(($x0 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[15]; + $x0^= $this->safe_intval(($this->safe_intval($sbox0[(($x1 & 0xFF000000) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[16]; return array($x1 & 0xFFFFFFFF ^ $p[17], $x0 & 0xFFFFFFFF); } diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php index 80766f63..edcd8ea0 100644 --- a/phpseclib/Crypt/DES.php +++ b/phpseclib/Crypt/DES.php @@ -668,7 +668,7 @@ class Crypt_DES extends Crypt_Base // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not - if (version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { + if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { return false; } $this->cipher_name_openssl_ecb = 'des-ecb'; diff --git a/phpseclib/Crypt/RC2.php b/phpseclib/Crypt/RC2.php index 2a11e0b7..96567c51 100644 --- a/phpseclib/Crypt/RC2.php +++ b/phpseclib/Crypt/RC2.php @@ -349,7 +349,7 @@ class Crypt_RC2 extends Crypt_Base // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not - if (version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { + if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { return false; } if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) { diff --git a/phpseclib/Crypt/RC4.php b/phpseclib/Crypt/RC4.php index 488ff84c..11337378 100644 --- a/phpseclib/Crypt/RC4.php +++ b/phpseclib/Crypt/RC4.php @@ -193,7 +193,7 @@ class Crypt_RC4 extends Crypt_Base // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not - if (version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { + if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { return false; } if (version_compare(PHP_VERSION, '5.3.7') >= 0) { diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php index c2bccae2..38e86d5b 100644 --- a/phpseclib/Math/BigInteger.php +++ b/phpseclib/Math/BigInteger.php @@ -407,7 +407,7 @@ class Math_BigInteger $x = substr($x, 1); } - $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#', '$1', $x); + $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#s', '$1', $x); $is_negative = false; if ($base < 0 && hexdec($x[0]) >= 8) { @@ -443,7 +443,7 @@ class Math_BigInteger // (?preferred['hostkey'])) { $algos = array_intersect($this->preferred['hostkey'], $algos); } diff --git a/tests/Unit/Crypt/RSA/LoadKeyTest.php b/tests/Unit/Crypt/RSA/LoadKeyTest.php index 19fc9bdc..2eacd99d 100644 --- a/tests/Unit/Crypt/RSA/LoadKeyTest.php +++ b/tests/Unit/Crypt/RSA/LoadKeyTest.php @@ -619,6 +619,10 @@ Private-MAC: d26baf87446604974287b682ed9e0c00ce54e460e1cb719953a81291147b3c59 public function testOpenSSHEncrypted() { + if (PHP_INT_SIZE === 4) { + self::markTestSkipped('bcrypt is far too slow to be practical on 32-bit versions of PHP'); + } + $key = '-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABBN2Ff3Kw SIOWyzRiboPRIhAAAAEAAAAAEAAAGXAAAAB3NzaC1yc2EAAAADAQABAAABgQCpxMxDEG0S diff --git a/tests/Unit/Crypt/RSA/ModeTest.php b/tests/Unit/Crypt/RSA/ModeTest.php index c7ecf534..ded13f42 100644 --- a/tests/Unit/Crypt/RSA/ModeTest.php +++ b/tests/Unit/Crypt/RSA/ModeTest.php @@ -120,13 +120,13 @@ k12yS6pCS3c+1wZ9cYFVtgfpSL4XpylLe9EnRT2GRVYCqUkR4AUeTuvnAgMBAAE= { $rsa = new Crypt_RSA(); $rsa->loadKey(array( - 'n' => new Math_BigInteger('0xE932AC92252F585B3A80A4DD76A897C8B7652952FE788F6EC8DD640587A1EE5647670A8AD -4C2BE0F9FA6E49C605ADF77B5174230AF7BD50E5D6D6D6D28CCF0A886A514CC72E51D209CC7 -72A52EF419F6A953F3135929588EBE9B351FCA61CED78F346FE00DBB6306E5C2A4C6DFC3779 -AF85AB417371CF34D8387B9B30AE46D7A5FF5A655B8D8455F1B94AE736989D60A6F2FD5CADB -FFBD504C5A756A2E6BB5CECC13BCA7503F6DF8B52ACE5C410997E98809DB4DC30D943DE4E81 -2A47553DCE54844A78E36401D13F77DC650619FED88D8B3926E3D8E319C80C744779AC5D6AB -E252896950917476ECE5E8FC27D5F053D6018D91B502C4787558A002B9283DA7', 16), + 'n' => new Math_BigInteger('0xE932AC92252F585B3A80A4DD76A897C8B7652952FE788F6EC8DD640587A1EE5647670A8AD' . + '4C2BE0F9FA6E49C605ADF77B5174230AF7BD50E5D6D6D6D28CCF0A886A514CC72E51D209CC7' . + '72A52EF419F6A953F3135929588EBE9B351FCA61CED78F346FE00DBB6306E5C2A4C6DFC3779' . + 'AF85AB417371CF34D8387B9B30AE46D7A5FF5A655B8D8455F1B94AE736989D60A6F2FD5CADB' . + 'FFBD504C5A756A2E6BB5CECC13BCA7503F6DF8B52ACE5C410997E98809DB4DC30D943DE4E81' . + '2A47553DCE54844A78E36401D13F77DC650619FED88D8B3926E3D8E319C80C744779AC5D6AB' . + 'E252896950917476ECE5E8FC27D5F053D6018D91B502C4787558A002B9283DA7', 16), 'e' => new Math_BigInteger('3') )); diff --git a/tests/Unit/Math/BigInteger/TestCase.php b/tests/Unit/Math/BigInteger/TestCase.php index 1ccaae2f..292e75e6 100644 --- a/tests/Unit/Math/BigInteger/TestCase.php +++ b/tests/Unit/Math/BigInteger/TestCase.php @@ -451,4 +451,18 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase $this->assertSame(0, $x->compare($x2)); } } + + public function testHexWithNewLines() + { + $x = $this->getInstance('0xE932AC92252F585B3A80A4DD76A897C8B7652952FE788F6EC8DD640587A1EE5647670A8AD +4C2BE0F9FA6E49C605ADF77B5174230AF7BD50E5D6D6D6D28CCF0A886A514CC72E51D209CC7 +72A52EF419F6A953F3135929588EBE9B351FCA61CED78F346FE00DBB6306E5C2A4C6DFC3779 +AF85AB417371CF34D8387B9B30AE46D7A5FF5A655B8D8455F1B94AE736989D60A6F2FD5CADB +FFBD504C5A756A2E6BB5CECC13BCA7503F6DF8B52ACE5C410997E98809DB4DC30D943DE4E81 +2A47553DCE54844A78E36401D13F77DC650619FED88D8B3926E3D8E319C80C744779AC5D6AB +E252896950917476ECE5E8FC27D5F053D6018D91B502C4787558A002B9283DA7', 16); + + $y = $this->getInstance('0xE932AC92252F585B3A80A4DD76A897C8B7652952FE788F6EC8DD640587A1EE5647670A8AD', 16); + $this->assertSame("$x", "$y"); + } } diff --git a/tests/make_compatible_with_phpunit9.php b/tests/make_compatible_with_phpunit9.php new file mode 100644 index 00000000..1e066b70 --- /dev/null +++ b/tests/make_compatible_with_phpunit9.php @@ -0,0 +1,35 @@ + $files */ +$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(__DIR__)); +foreach ($files as $file) { + if ($file->getExtension() === 'php' && $file->getPathname() !== __FILE__) { + $fileContents = file_get_contents($file->getPathname()); + if ($fileContents === false) { + throw new \RuntimeException('file_get_contents() failed: ' . $file->getPathname()); + } + $patternToReplacementMap = array( + '~n setUpBeforeClass\(\)~' => 'n setUpBeforeClass(): void', + '~n setUp\(\)~' => 'n setUp(): void', + '~n tearDown\(\)~' => 'n tearDown(): void', + '~(n assertIsArray\([^\)]*\))~' => '$1: void', + '~(n assertIsString\([^\)]*\))~' => '$1: void', + '~(n assertStringContainsString\([^\)]*\))~' => '$1: void', + '~(n assertStringNotContainsString\([^\)]*\))~' => '$1: void', + '~^class Unit_Crypt_(AES|Hash|RSA)_~m' => 'class ', + '~^class Unit_File_X509_~m' => 'class ', + '~^class Unit_Math_BigInteger_~m' => 'class ', + '~^class Unit_(Crypt|File|Math|Net)_~m' => 'class ', + '~^class Functional_Net__~m' => 'class ', + '~extends Unit_Crypt_Hash_(SHA512Test|SHA256Test)~' => 'extends $1' + ); + $updatedFileContents = preg_replace( + array_keys($patternToReplacementMap), + array_values($patternToReplacementMap), + $fileContents + ); + if (file_put_contents($file->getPathname(), $updatedFileContents) === false) { + throw new \RuntimeException('file_put_contents() failed: ' . $file->getPathname()); + } + } +} \ No newline at end of file