diff options
| author | David Prévot <taffit@debian.org> | 2026-06-16 00:13:58 +0200 |
|---|---|---|
| committer | git-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com> | 2026-06-16 04:37:31 +0000 |
| commit | 643c65f662c4d56ae92f886cdd35f7cd9f1886c6 (patch) | |
| tree | 992fe394b0cd159704182cd82c4a42b22cef3caa | |
| parent | 04b06a5c587fb085b7ac7ebabf86a717cfb2dd70 (diff) | |
2.0.55-1 (patches unapplied)HEADimport/2.0.55-1ubuntu/stonking-proposedubuntu/stonking-develubuntu/stonkingubuntu/develdebian/sid
Imported using git-ubuntu import.
Notes
Notes:
[ terrafrost ]
* CHANGELOG: add CVE
* ASN1: speed up OID calculation
* X509: add setURLFetchCallback() method
* CHANGELOG: add new release
[ David Prévot ]
* Update CVE ID in previous changelog entry
| -rw-r--r-- | CHANGELOG.md | 13 | ||||
| -rw-r--r-- | README.md | 11 | ||||
| -rw-r--r-- | debian/changelog | 15 | ||||
| -rw-r--r-- | phpseclib/File/ASN1.php | 22 | ||||
| -rw-r--r-- | phpseclib/File/X509.php | 71 |
5 files changed, 117 insertions, 15 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 7074aea..82a8ec8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,13 @@ # Changelog +## 2.0.55 - 2026-06-14 + +- X509: add setURLFetchCallback() method +- ASN1: speed up OID calculations + ## 2.0.54 - 2026-04-27 -- ASN1: more stringent OID length limits +- ASN1: more stringent OID length limits (CVE-2026-44167) ## 2.0.53 - 2026-04-09 @@ -416,9 +421,13 @@ - Classes were renamed and namespaced ([#243](https://github.com/phpseclib/phpseclib/issues/243)) - The use of an autoloader is now required (e.g. Composer) +## 1.0.30 - 2026-06-14 + +- X509: add setURLFetchCallback() method + ## 1.0.29 - 2026-04-27 -- ASN1: more stringent OID length limits +- ASN1: more stringent OID length limits (CVE-2026-44167) ## 1.0.28 - 2026-04-09 @@ -29,6 +29,17 @@ SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 / * Unstable API * Do not use in production +### 4.0 + +* Expected Release Date: September 2026 +* Long term support (LTS) release +* X509 split into separate X509, CRL, CSR and SPKAC classes +* PFX and CMS classes added +* All ASN1 classes are lazy loaded by default +* Minimum PHP version: 8.1.0 +* PSR-4 autoloading with namespace rooted at `\phpseclib4` +* Install via Composer: `composer require phpseclib/phpseclib:4.0.x-dev` + ### 3.0 * Long term support (LTS) release diff --git a/debian/changelog b/debian/changelog index b3053a3..6eeaea0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,21 @@ +php-phpseclib (2.0.55-1) unstable; urgency=medium + + [ terrafrost ] + * CHANGELOG: add CVE + * ASN1: speed up OID calculation + * X509: add setURLFetchCallback() method + * CHANGELOG: add new release + + [ David Prévot ] + * Update CVE ID in previous changelog entry + + -- David Prévot <taffit@debian.org> Tue, 16 Jun 2026 00:13:58 +0200 + php-phpseclib (2.0.54-1) unstable; urgency=medium [ terrafrost ] * ASN1: reduce length of supported OIDs from 4096 bytes to 128 bytes - [CVE-2024-27355] (GHSA-3qpq-r242-jqj7) + [CVE-2026-44167] (GHSA-3qpq-r242-jqj7) * CHANGELOG: add new entry [ David Prévot ] diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 704826c..afe714d 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -1172,6 +1172,10 @@ class ASN1 */ function _decodeOID($content) { + if (!defined('PHP_INT_SIZE')) { + define('PHP_INT_SIZE', 4); + } + static $eighty; if (!$eighty) { $eighty = new BigInteger(80); @@ -1191,13 +1195,21 @@ class ASN1 } $n = new BigInteger(); + $subn = $numBytes = 0; while ($pos < $len) { $temp = ord($content[$pos++]); - $n = $n->bitwise_leftShift(7); - $n = $n->bitwise_or(new BigInteger($temp & 0x7F)); - if (~$temp & 0x80) { - $oid[] = $n; - $n = new BigInteger(); + $subn <<= 7; + $subn |= ($temp & 0x7F); + $numBytes++; + $endByte = ~$temp & 0x80; + if ($numBytes === PHP_INT_SIZE || $endByte) { + $n = $n->bitwise_leftShift($numBytes * 7); + $n = $n->bitwise_or(new BigInteger($subn)); + $subn = $numBytes = 0; + if ($endByte) { + $oid[] = $n; + $n = new BigInteger(); + } } } $part1 = array_shift($oid); diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 4991f85..cdc112f 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -323,6 +323,14 @@ class X509 static $disable_url_fetch = false; /** + * URL fetch callback + * + * @var string|array|null + * @access private + */ + static $urlFetchCallback = null; + + /** * Default Constructor. * * @return \phpseclib\File\X509 @@ -2152,6 +2160,10 @@ class X509 /** * Fetches a URL * + * If a fetch callback is set via setURLFetchCallback(), the host is resolved + * once and the connection is pinned to that IP (the callback judges the + * resolved IP, preventing DNS-rebinding bypass). + * * @param string $url * @access private * @return bool|string @@ -2163,25 +2175,58 @@ class X509 } $parts = parse_url($url); + if ($parts === false || !isset($parts['scheme']) || !isset($parts['host'])) { + return false; + } + $host = $parts['host']; + $port = isset($parts['port']) ? $parts['port'] : 80; + + if (isset(self::$urlFetchCallback)) { + if (filter_var($host, FILTER_VALIDATE_IP)) { + $ip = $host; + // unwrap IPv4-mapped IPv6 so the callback judges the real v4 address + if (preg_match('/^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i', $ip, $m)) { + $ip = $m[1]; + } + } else { + $records = dns_get_record($host, DNS_A | DNS_AAAA); + if (!$records) { + return false; + } + if (isset($records[0]['ip'])) { + $ip = $records[0]['ip']; + } elseif (isset($records[0]['ipv6'])) { + $ip = $records[0]['ipv6']; + } else { + return false; + } + } + if (!call_user_func(self::$urlFetchCallback, $host, $ip, $port, $parts['scheme'])) { + return false; + } + $target = strpos($ip, ':') !== false ? "[$ip]" : $ip; + } else { + $target = $host; + } + $data = ''; switch ($parts['scheme']) { case 'http': - $fsock = @fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80); + $fsock = @fsockopen($target, $port); if (!$fsock) { return false; } - $path = $parts['path']; + $path = isset($parts['path']) ? $parts['path'] : '/'; if (isset($parts['query'])) { $path.= '?' . $parts['query']; } fputs($fsock, "GET $path HTTP/1.0\r\n"); - fputs($fsock, "Host: $parts[host]\r\n\r\n"); + fputs($fsock, "Host: $host\r\n\r\n"); $line = fgets($fsock, 1024); - if (strlen($line) < 3) { + if ($line === false || strlen($line) < 3) { return false; } - preg_match('#HTTP/1.\d (\d{3})#', $line, $temp); - if ($temp[1] != '200') { + if (!preg_match('#HTTP/1.\d (\d{3})#', $line, $temp) || $temp[1] != '200') { return false; } @@ -2200,7 +2245,8 @@ class X509 break; //case 'ftp': //case 'ldap': - //default: + default: + return false; } return $data; @@ -5123,4 +5169,15 @@ class X509 } return isset($reverseMap[$name]) ? $reverseMap[$name] : $name; } + + /** + * Returns the OID corresponding to a name + * + * @access public + * @param array|string|null $callback + */ + static function setURLFetchCallback($callback) + { + self::$urlFetchCallback = $callback; + } } |
