From 0e8fa9367636e2d90ded915eebac510bd8aaa192 Mon Sep 17 00:00:00 2001 From: Paragon Initiative Enterprises Date: Thu, 12 May 2016 16:28:40 -0400 Subject: [PATCH] Use paragonie/constant_time_encoding --- composer.json | 1 + composer.lock | 131 ++++++++++++++++++++++++-------- phpseclib/Crypt/Base.php | 5 +- phpseclib/Crypt/RSA.php | 24 +++--- phpseclib/Crypt/RSA/MSBLOB.php | 8 +- phpseclib/Crypt/RSA/OpenSSH.php | 5 +- phpseclib/Crypt/RSA/PKCS.php | 8 +- phpseclib/Crypt/RSA/PKCS1.php | 11 ++- phpseclib/Crypt/RSA/PKCS8.php | 12 +-- phpseclib/Crypt/RSA/PuTTY.php | 18 +++-- phpseclib/Crypt/RSA/XML.php | 23 +++--- phpseclib/Crypt/Random.php | 9 ++- phpseclib/File/ASN1.php | 5 +- phpseclib/File/X509.php | 54 ++++++------- phpseclib/Math/BigInteger.php | 18 +++-- phpseclib/Net/SFTP.php | 2 +- phpseclib/Net/SSH1.php | 3 +- phpseclib/Net/SSH2.php | 5 +- phpseclib/System/SSH/Agent.php | 3 +- 19 files changed, 219 insertions(+), 126 deletions(-) diff --git a/composer.json b/composer.json index da2e1c22..9f728103 100644 --- a/composer.json +++ b/composer.json @@ -51,6 +51,7 @@ } ], "require": { + "paragonie/constant_time_encoding": "^1|^2", "paragonie/random_compat": "^1.4|^2.0", "php": ">=5.3.3" }, diff --git a/composer.lock b/composer.lock index 7fbfdcb1..2a1bc6c9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,9 +4,71 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "deb73cf7e6004dbc2550a38c4082df2d", - "content-hash": "39f9dd8d2c209ff69eebbb83e367257e", + "hash": "b54600d5b96647f1c6f4db8b67f9dd49", + "content-hash": "bbcd086ca303cc52841266906eb6e174", "packages": [ + { + "name": "paragonie/constant_time_encoding", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "fdb1e311153233315e0f7699711e3845d81ed00f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/fdb1e311153233315e0f7699711e3845d81ed00f", + "reference": "fdb1e311153233315e0f7699711e3845d81ed00f", + "shasum": "" + }, + "require": { + "php": "^5.3|^7" + }, + "require-dev": { + "paragonie/random_compat": "^1.4|^2.0", + "phpunit/phpunit": "4.*|5.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "time": "2016-04-08 16:58:39" + }, { "name": "paragonie/random_compat", "version": "v2.0.2", @@ -561,21 +623,24 @@ }, { "name": "phpunit/php-timer", - "version": "1.0.7", + "version": "1.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b" + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b", - "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", + "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "require-dev": { + "phpunit/phpunit": "~4|~5" + }, "type": "library", "autoload": { "classmap": [ @@ -598,7 +663,7 @@ "keywords": [ "timer" ], - "time": "2015-06-21 08:01:12" + "time": "2016-05-12 18:03:57" }, { "name": "phpunit/php-token-stream", @@ -998,16 +1063,16 @@ }, { "name": "sebastian/environment", - "version": "1.3.5", + "version": "1.3.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf" + "reference": "2292b116f43c272ff4328083096114f84ea46a56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf", - "reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/2292b116f43c272ff4328083096114f84ea46a56", + "reference": "2292b116f43c272ff4328083096114f84ea46a56", "shasum": "" }, "require": { @@ -1044,7 +1109,7 @@ "environment", "hhvm" ], - "time": "2016-02-26 18:40:46" + "time": "2016-05-04 07:59:13" }, { "name": "sebastian/exporter", @@ -1331,16 +1396,16 @@ }, { "name": "symfony/console", - "version": "v2.8.4", + "version": "v2.8.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154" + "reference": "48221d3de4dc22d2cd57c97e8b9361821da86609" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/9a5aef5fc0d4eff86853d44202b02be8d5a20154", - "reference": "9a5aef5fc0d4eff86853d44202b02be8d5a20154", + "url": "https://api.github.com/repos/symfony/console/zipball/48221d3de4dc22d2cd57c97e8b9361821da86609", + "reference": "48221d3de4dc22d2cd57c97e8b9361821da86609", "shasum": "" }, "require": { @@ -1387,20 +1452,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-03-17 09:19:04" + "time": "2016-04-26 12:00:47" }, { "name": "symfony/filesystem", - "version": "v2.8.4", + "version": "v2.8.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "f08ffdf229252cd2745558cb2112df43903bcae4" + "reference": "dee379131dceed90a429e951546b33edfe7dccbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/f08ffdf229252cd2745558cb2112df43903bcae4", - "reference": "f08ffdf229252cd2745558cb2112df43903bcae4", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/dee379131dceed90a429e951546b33edfe7dccbb", + "reference": "dee379131dceed90a429e951546b33edfe7dccbb", "shasum": "" }, "require": { @@ -1436,11 +1501,11 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2016-03-27 10:20:16" + "time": "2016-04-12 18:01:21" }, { "name": "symfony/finder", - "version": "v2.8.4", + "version": "v2.8.6", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", @@ -1548,16 +1613,16 @@ }, { "name": "symfony/process", - "version": "v2.8.4", + "version": "v2.8.6", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "fb467471952ef5cf8497c029980e556b47545333" + "reference": "1276bd9be89be039748cf753a2137f4ef149cd74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/fb467471952ef5cf8497c029980e556b47545333", - "reference": "fb467471952ef5cf8497c029980e556b47545333", + "url": "https://api.github.com/repos/symfony/process/zipball/1276bd9be89be039748cf753a2137f4ef149cd74", + "reference": "1276bd9be89be039748cf753a2137f4ef149cd74", "shasum": "" }, "require": { @@ -1593,20 +1658,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-03-23 13:11:46" + "time": "2016-04-14 15:22:22" }, { "name": "symfony/yaml", - "version": "v2.8.4", + "version": "v2.8.6", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb" + "reference": "e4fbcc65f90909c999ac3b4dfa699ee6563a9940" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/584e52cb8f788a887553ba82db6caacb1d6260bb", - "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb", + "url": "https://api.github.com/repos/symfony/yaml/zipball/e4fbcc65f90909c999ac3b4dfa699ee6563a9940", + "reference": "e4fbcc65f90909c999ac3b4dfa699ee6563a9940", "shasum": "" }, "require": { @@ -1642,7 +1707,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-03-04 07:54:35" + "time": "2016-03-29 19:00:15" }, { "name": "twig/twig", diff --git a/phpseclib/Crypt/Base.php b/phpseclib/Crypt/Base.php index 92a6f62b..e6907a82 100644 --- a/phpseclib/Crypt/Base.php +++ b/phpseclib/Crypt/Base.php @@ -35,6 +35,7 @@ */ namespace phpseclib\Crypt; +use ParagonIE\ConstantTime\Hex; /** * Base Class for all \phpseclib\Crypt\* cipher classes @@ -2578,10 +2579,10 @@ abstract class Base $len = strlen($bytes); for ($i = 0; $i < $len; $i+=20) { $t = substr($bytes, $i, 20); - $hash = pack('H*', sha1($hash)); + $hash = Hex::decode($hash); $result .= $t ^ $hash; } - return $result . pack('H*', sha1($hash)); + return $result . Hex::decode(sha1($hash)); } } } diff --git a/phpseclib/Crypt/RSA.php b/phpseclib/Crypt/RSA.php index 244e4915..6de1f458 100644 --- a/phpseclib/Crypt/RSA.php +++ b/phpseclib/Crypt/RSA.php @@ -45,6 +45,8 @@ namespace phpseclib\Crypt; +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Hex; use phpseclib\File\ASN1; use phpseclib\Math\BigInteger; @@ -1033,7 +1035,7 @@ class RSA switch ($algorithm) { case 'sha256': $hash = new Hash('sha256'); - $base = base64_encode($hash->hash($RSAPublicKey)); + $base = Base64::encode($hash->hash($RSAPublicKey)); return substr($base, 0, strlen($base) - 1); case 'md5': return substr(chunk_split(md5($RSAPublicKey), 2, ':'), 0, -1); @@ -1951,32 +1953,32 @@ class RSA // see http://tools.ietf.org/html/rfc3447#page-43 switch ($this->hashName) { case 'md2': - $t = pack('H*', '3020300c06082a864886f70d020205000410'); + $t = Hex::decode('3020300c06082a864886f70d020205000410'); break; case 'md5': - $t = pack('H*', '3020300c06082a864886f70d020505000410'); + $t = Hex::decode('3020300c06082a864886f70d020505000410'); break; case 'sha1': - $t = pack('H*', '3021300906052b0e03021a05000414'); + $t = Hex::decode('3021300906052b0e03021a05000414'); break; case 'sha256': - $t = pack('H*', '3031300d060960864801650304020105000420'); + $t = Hex::decode('3031300d060960864801650304020105000420'); break; case 'sha384': - $t = pack('H*', '3041300d060960864801650304020205000430'); + $t = Hex::decode('3041300d060960864801650304020205000430'); break; case 'sha512': - $t = pack('H*', '3051300d060960864801650304020305000440'); + $t = Hex::decode('3051300d060960864801650304020305000440'); break; // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40 case 'sha224': - $t = pack('H*', '302d300d06096086480165030402040500041c'); + $t = Hex::decode('302d300d06096086480165030402040500041c'); break; case 'sha512/224': - $t = pack('H*', '302d300d06096086480165030402050500041c'); + $t = Hex::decode('302d300d06096086480165030402050500041c'); break; case 'sha512/256': - $t = pack('H*', '3031300d060960864801650304020605000420'); + $t = Hex::decode('3031300d060960864801650304020605000420'); } $t.= $h; $tLen = strlen($t); @@ -2166,7 +2168,7 @@ class RSA $hash = new Hash($decoded['digestAlgorithm']['algorithm']); $em = $hash->hash($m); - $em2 = base64_decode($decoded['digest']); + $em2 = Base64::decode($decoded['digest']); return $this->_equals($em, $em2); } diff --git a/phpseclib/Crypt/RSA/MSBLOB.php b/phpseclib/Crypt/RSA/MSBLOB.php index 2f04a1c3..e450c344 100644 --- a/phpseclib/Crypt/RSA/MSBLOB.php +++ b/phpseclib/Crypt/RSA/MSBLOB.php @@ -18,6 +18,8 @@ namespace phpseclib\Crypt\RSA; +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Binary; use phpseclib\Math\BigInteger; /** @@ -76,7 +78,7 @@ class MSBLOB return false; } - $key = base64_decode($key); + $key = Base64::decode($key); if (!is_string($key) || strlen($key) < 20) { return false; @@ -182,7 +184,7 @@ class MSBLOB $key.= strrev($coefficients[1]->toBytes()); $key.= strrev($d->toBytes()); - return base64_encode($key); + return Base64::encode($key); } /** @@ -201,7 +203,7 @@ class MSBLOB $key.= pack('VVa*', self::RSA1, 8 * strlen($n), $e); $key.= $n; - return base64_encode($key); + return Base64::encode($key); } /** diff --git a/phpseclib/Crypt/RSA/OpenSSH.php b/phpseclib/Crypt/RSA/OpenSSH.php index f8aa11bf..8cd53282 100644 --- a/phpseclib/Crypt/RSA/OpenSSH.php +++ b/phpseclib/Crypt/RSA/OpenSSH.php @@ -16,6 +16,7 @@ namespace phpseclib\Crypt\RSA; +use ParagonIE\ConstantTime\Base64; use phpseclib\Math\BigInteger; /** @@ -62,7 +63,7 @@ class OpenSSH $parts = explode(' ', $key, 3); - $key = isset($parts[1]) ? base64_decode($parts[1]) : base64_decode($parts[0]); + $key = isset($parts[1]) ? Base64::decode($parts[1]) : Base64::decode($parts[0]); if ($key === false) { return false; } @@ -116,7 +117,7 @@ class OpenSSH // mpint e // mpint n $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus); - $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . self::$comment; + $RSAPublicKey = 'ssh-rsa ' . Base64::encode($RSAPublicKey) . ' ' . self::$comment; return $RSAPublicKey; } diff --git a/phpseclib/Crypt/RSA/PKCS.php b/phpseclib/Crypt/RSA/PKCS.php index 9d3e6425..27cc493f 100644 --- a/phpseclib/Crypt/RSA/PKCS.php +++ b/phpseclib/Crypt/RSA/PKCS.php @@ -14,6 +14,8 @@ namespace phpseclib\Crypt\RSA; +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Hex; use phpseclib\Crypt\AES; use phpseclib\Crypt\Base; use phpseclib\Crypt\DES; @@ -144,7 +146,7 @@ abstract class PKCS $symkey = ''; $iv = substr($iv, 0, 8); while (strlen($symkey) < $length) { - $symkey.= pack('H*', md5($symkey . $password . $iv)); + $symkey.= Hex::decode(md5($symkey . $password . $iv)); } return substr($symkey, 0, $length); } @@ -181,7 +183,7 @@ abstract class PKCS * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */ if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) { - $iv = pack('H*', trim($matches[2])); + $iv = Hex::decode(trim($matches[2])); // remove the Proc-Type / DEK-Info sections as they're no longer needed $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key); $ciphertext = self::_extractBER($key); @@ -479,7 +481,7 @@ abstract class PKCS $temp = preg_replace('#-+[^-]+-+#', '', $temp); // remove new lines $temp = str_replace(array("\r", "\n", ' '), '', $temp); - $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Base64::decode($temp) : false; return $temp != false ? $temp : $str; } } diff --git a/phpseclib/Crypt/RSA/PKCS1.php b/phpseclib/Crypt/RSA/PKCS1.php index ae208d15..7d9430ae 100644 --- a/phpseclib/Crypt/RSA/PKCS1.php +++ b/phpseclib/Crypt/RSA/PKCS1.php @@ -22,7 +22,10 @@ namespace phpseclib\Crypt\RSA; +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Hex; use phpseclib\Crypt\AES; +use phpseclib\Crypt\Base; use phpseclib\Crypt\DES; use phpseclib\Crypt\Random; use phpseclib\Crypt\TripleDES; @@ -116,16 +119,16 @@ class PKCS1 extends PKCS $iv = Random::string($cipher->getBlockLength() >> 3); $cipher->setKey(self::generateSymmetricKey($password, $iv, $cipher->getKeyLength() >> 3)); $cipher->setIV($iv); - $iv = strtoupper(bin2hex($iv)); + $iv = strtoupper(Hex::encode($iv)); $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" . "Proc-Type: 4,ENCRYPTED\r\n" . "DEK-Info: " . self::$defaultEncryptionAlgorithm . ",$iv\r\n" . "\r\n" . - chunk_split(base64_encode($cipher->encrypt($RSAPrivateKey)), 64) . + chunk_split(Base64::encode($cipher->encrypt($RSAPrivateKey)), 64) . '-----END RSA PRIVATE KEY-----'; } else { $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" . - chunk_split(base64_encode($RSAPrivateKey), 64) . + chunk_split(Base64::encode($RSAPrivateKey), 64) . '-----END RSA PRIVATE KEY-----'; } @@ -164,7 +167,7 @@ class PKCS1 extends PKCS ); $RSAPublicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" . - chunk_split(base64_encode($RSAPublicKey), 64) . + chunk_split(Base64::encode($RSAPublicKey), 64) . '-----END RSA PUBLIC KEY-----'; return $RSAPublicKey; diff --git a/phpseclib/Crypt/RSA/PKCS8.php b/phpseclib/Crypt/RSA/PKCS8.php index 164fca19..8c8a08ec 100644 --- a/phpseclib/Crypt/RSA/PKCS8.php +++ b/phpseclib/Crypt/RSA/PKCS8.php @@ -24,6 +24,8 @@ namespace phpseclib\Crypt\RSA; +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Hex; use phpseclib\Crypt\DES; use phpseclib\Crypt\Random; use phpseclib\Math\BigInteger; @@ -92,7 +94,7 @@ class PKCS8 extends PKCS $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); - $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA + $rsaOID = Hex::decode('300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA $RSAPrivateKey = pack( 'Ca*a*Ca*a*', self::ASN1_INTEGER, @@ -145,11 +147,11 @@ class PKCS8 extends PKCS $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey); $RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" . - chunk_split(base64_encode($RSAPrivateKey), 64) . + chunk_split(Base64::encode($RSAPrivateKey), 64) . '-----END ENCRYPTED PRIVATE KEY-----'; } else { $RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" . - chunk_split(base64_encode($RSAPrivateKey), 64) . + chunk_split(Base64::encode($RSAPrivateKey), 64) . '-----END PRIVATE KEY-----'; } @@ -188,7 +190,7 @@ class PKCS8 extends PKCS ); // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption. - $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA + $rsaOID = Hex::decode('300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA $RSAPublicKey = chr(0) . $RSAPublicKey; $RSAPublicKey = chr(3) . self::_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey; @@ -200,7 +202,7 @@ class PKCS8 extends PKCS ); $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" . - chunk_split(base64_encode($RSAPublicKey), 64) . + chunk_split(Base64::encode($RSAPublicKey), 64) . '-----END PUBLIC KEY-----'; return $RSAPublicKey; diff --git a/phpseclib/Crypt/RSA/PuTTY.php b/phpseclib/Crypt/RSA/PuTTY.php index 302eb2b1..cf2868fa 100644 --- a/phpseclib/Crypt/RSA/PuTTY.php +++ b/phpseclib/Crypt/RSA/PuTTY.php @@ -14,6 +14,8 @@ namespace phpseclib\Crypt\RSA; +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Hex; use phpseclib\Crypt\AES; use phpseclib\Crypt\Hash; use phpseclib\Math\BigInteger; @@ -61,7 +63,7 @@ class PuTTY $sequence = 0; while (strlen($symkey) < $length) { $temp = pack('Na*', $sequence++, $password); - $symkey.= pack('H*', sha1($temp)); + $symkey.= Hex::decode(sha1($temp)); } return substr($symkey, 0, $length); } @@ -113,7 +115,7 @@ class PuTTY $components['comment'] = trim(preg_replace('#Comment: (.+)#', '$1', $key[2])); $publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3])); - $public = base64_decode(implode('', array_map('trim', array_slice($key, 4, $publicLength)))); + $public = Base64::decode(implode('', array_map('trim', array_slice($key, 4, $publicLength)))); $public = substr($public, 11); extract(unpack('Nlength', self::_string_shift($public, 4))); $components['publicExponent'] = new BigInteger(self::_string_shift($public, $length), -256); @@ -121,7 +123,7 @@ class PuTTY $components['modulus'] = new BigInteger(self::_string_shift($public, $length), -256); $privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$publicLength + 4])); - $private = base64_decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength)))); + $private = Base64::decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength)))); switch ($encryption) { case 'aes256-cbc': @@ -240,7 +242,7 @@ class PuTTY strlen($public), $public ); - $public = base64_encode($public); + $public = Base64::encode($public); $key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n"; $key.= chunk_split($public, 64); $private = pack( @@ -269,12 +271,12 @@ class PuTTY $hashkey = 'putty-private-key-file-mac-key' . $password; } - $private = base64_encode($private); + $private = Base64::encode($private); $key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n"; $key.= chunk_split($private, 64); $hash = new Hash('sha1'); - $hash->setKey(pack('H*', sha1($hashkey))); - $key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n"; + $hash->setKey(Hex::decode(sha1($hashkey))); + $key.= 'Private-MAC: ' . Hex::encode($hash->hash($source)) . "\r\n"; return $key; } @@ -303,7 +305,7 @@ class PuTTY ); $key = "---- BEGIN SSH2 PUBLIC KEY ----\r\n" . 'Comment: "' . str_replace(array('\\', '"'), array('\\\\', '\"'), self::$comment) . "\"\r\n"; - chunk_split(base64_encode($key), 64) . + chunk_split(Base64::encode($key), 64) . '---- END SSH2 PUBLIC KEY ----'; return $key; diff --git a/phpseclib/Crypt/RSA/XML.php b/phpseclib/Crypt/RSA/XML.php index 00b4d910..a257033b 100644 --- a/phpseclib/Crypt/RSA/XML.php +++ b/phpseclib/Crypt/RSA/XML.php @@ -19,6 +19,7 @@ namespace phpseclib\Crypt\RSA; +use ParagonIE\ConstantTime\Base64; use phpseclib\Math\BigInteger; /** @@ -65,7 +66,7 @@ class XML if (!$temp->length) { continue; } - $value = new BigInteger(base64_decode($temp->item(0)->nodeValue), 256); + $value = new BigInteger(Base64::decode($temp->item(0)->nodeValue), 256); switch ($key) { case 'modulus': $components['modulus'] = $value; @@ -117,14 +118,14 @@ class XML return false; } return "\r\n" . - ' ' . base64_encode($n->toBytes()) . "\r\n" . - ' ' . base64_encode($e->toBytes()) . "\r\n" . - '

' . base64_encode($primes[1]->toBytes()) . "

\r\n" . - ' ' . base64_encode($primes[2]->toBytes()) . "\r\n" . - ' ' . base64_encode($exponents[1]->toBytes()) . "\r\n" . - ' ' . base64_encode($exponents[2]->toBytes()) . "\r\n" . - ' ' . base64_encode($coefficients[2]->toBytes()) . "\r\n" . - ' ' . base64_encode($d->toBytes()) . "\r\n" . + ' ' . Base64::encode($n->toBytes()) . "\r\n" . + ' ' . Base64::encode($e->toBytes()) . "\r\n" . + '

' . Base64::encode($primes[1]->toBytes()) . "

\r\n" . + ' ' . Base64::encode($primes[2]->toBytes()) . "\r\n" . + ' ' . Base64::encode($exponents[1]->toBytes()) . "\r\n" . + ' ' . Base64::encode($exponents[2]->toBytes()) . "\r\n" . + ' ' . Base64::encode($coefficients[2]->toBytes()) . "\r\n" . + ' ' . Base64::encode($d->toBytes()) . "\r\n" . '
'; } @@ -139,8 +140,8 @@ class XML static function savePublicKey(BigInteger $n, BigInteger $e) { return "\r\n" . - ' ' . base64_encode($n->toBytes()) . "\r\n" . - ' ' . base64_encode($e->toBytes()) . "\r\n" . + ' ' . Base64::encode($n->toBytes()) . "\r\n" . + ' ' . Base64::encode($e->toBytes()) . "\r\n" . ''; } } diff --git a/phpseclib/Crypt/Random.php b/phpseclib/Crypt/Random.php index 766eeb4f..d8dea40b 100644 --- a/phpseclib/Crypt/Random.php +++ b/phpseclib/Crypt/Random.php @@ -24,6 +24,9 @@ namespace phpseclib\Crypt; +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Hex; + /** * Pure-PHP Random Number Generator * @@ -93,7 +96,7 @@ class Random session_cache_limiter(''); session_start(); - $v = $seed = $_SESSION['seed'] = pack('H*', sha1( + $v = $seed = $_SESSION['seed'] = Hex::decode(sha1( (isset($_SERVER) ? self::safe_serialize($_SERVER) : '') . (isset($_POST) ? self::safe_serialize($_POST) : '') . (isset($_GET) ? self::safe_serialize($_GET) : '') . @@ -132,8 +135,8 @@ class Random // http://tools.ietf.org/html/rfc4253#section-7.2 // // see the is_string($crypto) part for an example of how to expand the keys - $key = pack('H*', sha1($seed . 'A')); - $iv = pack('H*', sha1($seed . 'C')); + $key = Hex::decode(sha1($seed . 'A')); + $iv = Hex::decode(sha1($seed . 'C')); // ciphers are used as per the nist.gov link below. also, see this link: // diff --git a/phpseclib/File/ASN1.php b/phpseclib/File/ASN1.php index 180b0e67..ad59f69b 100644 --- a/phpseclib/File/ASN1.php +++ b/phpseclib/File/ASN1.php @@ -23,6 +23,7 @@ namespace phpseclib\File; +use ParagonIE\ConstantTime\Base64; use phpseclib\File\ASN1\Element; use phpseclib\Math\BigInteger; @@ -733,7 +734,7 @@ class ASN1 return $values; } case self::TYPE_OCTET_STRING: - return base64_encode($decoded['content']); + return Base64::encode($decoded['content']); case self::TYPE_NULL: return ''; case self::TYPE_BOOLEAN: @@ -981,7 +982,7 @@ class ASN1 the number of unused bits in the final subsequent octet. The number shall be in the range zero to seven. -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=16 */ - $value = base64_decode($source); + $value = Base64::decode($source); break; case self::TYPE_OBJECT_IDENTIFIER: $oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids); diff --git a/phpseclib/File/X509.php b/phpseclib/File/X509.php index 9022ae7c..51af17bc 100644 --- a/phpseclib/File/X509.php +++ b/phpseclib/File/X509.php @@ -26,6 +26,8 @@ namespace phpseclib\File; +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Hex; use phpseclib\Crypt\Hash; use phpseclib\Crypt\Random; use phpseclib\Crypt\RSA; @@ -1497,7 +1499,7 @@ class X509 switch ($algorithm) { case 'rsaEncryption': $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] - = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']))); + = Base64::encode("\0" . Base64::decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']))); /* "[For RSA keys] the parameters field MUST have ASN.1 type NULL for this algorithm identifier." -- https://tools.ietf.org/html/rfc3279#section-2.3.1 @@ -1545,7 +1547,7 @@ class X509 return $cert; // case self::FORMAT_PEM: default: - return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(base64_encode($cert), 64) . '-----END CERTIFICATE-----'; + return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(Base64::encode($cert), 64) . '-----END CERTIFICATE-----'; } } @@ -1566,7 +1568,7 @@ class X509 for ($i = 0; $i < count($extensions); $i++) { $id = $extensions[$i]['extnId']; $value = &$extensions[$i]['extnValue']; - $value = base64_decode($value); + $value = Base64::decode($value); $decoded = $asn1->decodeBER($value); /* [extnValue] contains the DER encoding of an ASN.1 value corresponding to the extension type identified by extnID */ @@ -1593,7 +1595,7 @@ class X509 } } } else { - $value = base64_encode($value); + $value = Base64::encode($value); } } } @@ -1659,7 +1661,7 @@ class X509 } } else { $temp = $asn1->encodeDER($value, $map, array('iPAddress' => array($this, '_encodeIP'))); - $value = base64_encode($temp); + $value = Base64::encode($temp); } } } @@ -1698,7 +1700,7 @@ class X509 $this->_mapInExtensions($values, $j, $asn1); } } elseif ($map) { - $values[$j] = base64_encode($value); + $values[$j] = Base64::encode($value); } } } @@ -2067,7 +2069,7 @@ class X509 $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], - substr(base64_decode($this->currentCert['signature']), 1), + substr(Base64::decode($this->currentCert['signature']), 1), $this->signatureSubject ); case isset($this->currentCert['certificationRequestInfo']): @@ -2075,7 +2077,7 @@ class X509 $this->currentCert['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm'], $this->currentCert['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], - substr(base64_decode($this->currentCert['signature']), 1), + substr(Base64::decode($this->currentCert['signature']), 1), $this->signatureSubject ); case isset($this->currentCert['publicKeyAndChallenge']): @@ -2083,7 +2085,7 @@ class X509 $this->currentCert['publicKeyAndChallenge']['spki']['algorithm']['algorithm'], $this->currentCert['publicKeyAndChallenge']['spki']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], - substr(base64_decode($this->currentCert['signature']), 1), + substr(Base64::decode($this->currentCert['signature']), 1), $this->signatureSubject ); case isset($this->currentCert['tbsCertList']): @@ -2109,7 +2111,7 @@ class X509 $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], - substr(base64_decode($this->currentCert['signature']), 1), + substr(Base64::decode($this->currentCert['signature']), 1), $this->signatureSubject ); default: @@ -2182,7 +2184,7 @@ class X509 // subjectPublicKey is stored as a bit string in X.509 certs. the first byte of a bit string represents how many bits // in the last byte should be ignored. the following only supports non-zero stuff but as none of the X.509 certs Firefox // uses as a cert authority actually use a non-zero bit I think it's safe to assume that none do. - chunk_split(base64_encode(substr(base64_decode($key), 1)), 64) . + chunk_split(Base64::encode(substr(Base64::decode($key), 1)), 64) . '-----END RSA PUBLIC KEY-----'; default: return $key; @@ -2200,7 +2202,7 @@ class X509 */ function _decodeIP($ip) { - return inet_ntop(base64_decode($ip)); + return inet_ntop(Base64::decode($ip)); } /** @@ -2214,7 +2216,7 @@ class X509 */ function _encodeIP($ip) { - return base64_encode(inet_pton($ip)); + return Base64::encode(inet_pton($ip)); } /** @@ -2536,7 +2538,7 @@ class X509 $hash = new Hash('sha1'); $hash = $hash->hash($dn); extract(unpack('Vhash', $hash)); - return strtolower(bin2hex(pack('N', $hash))); + return strtolower(Hex::encode(pack('N', $hash))); } // Default is to return a string. @@ -2923,7 +2925,7 @@ class X509 switch ($algorithm) { case 'rsaEncryption': $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'] - = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']))); + = Base64::encode("\0" . Base64::decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']))); } } @@ -2945,7 +2947,7 @@ class X509 return $csr; // case self::FORMAT_PEM: default: - return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(base64_encode($csr), 64) . '-----END CERTIFICATE REQUEST-----'; + return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(Base64::encode($csr), 64) . '-----END CERTIFICATE REQUEST-----'; } } @@ -2976,7 +2978,7 @@ class X509 // OpenSSL produces SPKAC's that are preceeded by the string SPKAC= $temp = preg_replace('#(?:SPKAC=)|[ \r\n\\\]#', '', $spkac); - $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Base64::decode($temp) : false; if ($temp != false) { $spkac = $temp; } @@ -3047,7 +3049,7 @@ class X509 switch ($algorithm) { case 'rsaEncryption': $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'] - = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']))); + = Base64::encode("\0" . Base64::decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']))); } } @@ -3063,7 +3065,7 @@ class X509 default: // OpenSSL's implementation of SPKAC requires the SPKAC be preceeded by SPKAC= and since there are pretty much // no other SPKAC decoders phpseclib will use that same format - return 'SPKAC=' . base64_encode($spkac); + return 'SPKAC=' . Base64::encode($spkac); } } @@ -3181,7 +3183,7 @@ class X509 return $crl; // case self::FORMAT_PEM: default: - return "-----BEGIN X509 CRL-----\r\n" . chunk_split(base64_encode($crl), 64) . '-----END X509 CRL-----'; + return "-----BEGIN X509 CRL-----\r\n" . chunk_split(Base64::encode($crl), 64) . '-----END X509 CRL-----'; } } @@ -3373,7 +3375,7 @@ class X509 ); if (!isset($subject->currentKeyIdentifier)) { - $this->setExtension('id-ce-subjectKeyIdentifier', base64_encode($this->computeKeyIdentifier($this->currentCert)), false, false); + $this->setExtension('id-ce-subjectKeyIdentifier', Base64::encode($this->computeKeyIdentifier($this->currentCert)), false, false); } } @@ -3668,7 +3670,7 @@ class X509 case 'sha512WithRSAEncryption': $key->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm)); - $this->currentCert['signature'] = base64_encode("\0" . $key->sign($this->signatureSubject, RSA::PADDING_PKCS1)); + $this->currentCert['signature'] = Base64::encode("\0" . $key->sign($this->signatureSubject, RSA::PADDING_PKCS1)); return $this->currentCert; default: throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); @@ -4181,7 +4183,7 @@ class X509 if (empty($value)) { unset($this->currentKeyIdentifier); } else { - $this->currentKeyIdentifier = base64_encode($value); + $this->currentKeyIdentifier = Base64::encode($value); } } @@ -4229,7 +4231,7 @@ class X509 if (empty($raw)) { return false; } - $raw = base64_decode($raw); + $raw = Base64::decode($raw); // If the key is private, compute identifier from its corresponding public key. $key = new RSA(); if (!$key->load($raw)) { @@ -4282,7 +4284,7 @@ class X509 if ($this->publicKey instanceof RSA) { // the following two return statements do the same thing. i dunno.. i just prefer the later for some reason. // the former is a good example of how to do fuzzing on the public key - //return new Element(base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->getPublicKey()))); + //return new Element(Base64::decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->getPublicKey()))); return array( 'algorithm' => array('algorithm' => 'rsaEncryption'), 'subjectPublicKey' => $this->publicKey->getPublicKey('PKCS1') @@ -4585,7 +4587,7 @@ class X509 $temp = preg_replace('#-+[^-]+-+#', '', $temp); // remove new lines $temp = str_replace(array("\r", "\n", ' '), '', $temp); - $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false; + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Base64::decode($temp) : false; return $temp != false ? $temp : $str; } diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php index bde7213d..22c5b863 100644 --- a/phpseclib/Math/BigInteger.php +++ b/phpseclib/Math/BigInteger.php @@ -50,6 +50,8 @@ namespace phpseclib\Math; +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Hex; use phpseclib\Crypt\Random; /** @@ -360,7 +362,7 @@ class BigInteger switch (MATH_BIGINTEGER_MODE) { case self::MODE_GMP: $sign = $this->is_negative ? '-' : ''; - $this->value = gmp_init($sign . '0x' . bin2hex($x)); + $this->value = gmp_init($sign . '0x' . Hex::encode($x)); break; case self::MODE_BCMATH: // round $len to the nearest 4 (thanks, DavidMJ!) @@ -405,7 +407,7 @@ class BigInteger $is_negative = false; if ($base < 0 && hexdec($x[0]) >= 8) { $this->is_negative = $is_negative = true; - $x = bin2hex(~pack('H*', $x)); + $x = Hex::encode(~Hex::decode($x)); } switch (MATH_BIGINTEGER_MODE) { @@ -416,13 +418,13 @@ class BigInteger break; case self::MODE_BCMATH: $x = (strlen($x) & 1) ? '0' . $x : $x; - $temp = new static(pack('H*', $x), 256); + $temp = new static(Hex::decode($x), 256); $this->value = $this->is_negative ? '-' . $temp->value : $temp->value; $this->is_negative = false; break; default: $x = (strlen($x) & 1) ? '0' . $x : $x; - $temp = new static(pack('H*', $x), 256); + $temp = new static(Hex::decode($x), 256); $this->value = $temp->value; } @@ -549,7 +551,7 @@ class BigInteger $temp = gmp_strval(gmp_abs($this->value), 16); $temp = (strlen($temp) & 1) ? '0' . $temp : $temp; - $temp = pack('H*', $temp); + $temp = Hex::decode($temp); return $this->precision > 0 ? substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : @@ -614,7 +616,7 @@ class BigInteger */ function toHex($twos_compliment = false) { - return bin2hex($this->toBytes($twos_compliment)); + return Hex::encode($this->toBytes($twos_compliment)); } /** @@ -1643,7 +1645,7 @@ class BigInteger $components['publicExponent'] ); - $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA + $rsaOID = Hex::decode('300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA $RSAPublicKey = chr(0) . $RSAPublicKey; $RSAPublicKey = chr(3) . self::_encodeASN1Length(strlen($RSAPublicKey)) . $RSAPublicKey; @@ -1655,7 +1657,7 @@ class BigInteger ); $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" . - chunk_split(base64_encode($encapsulated)) . + chunk_split(Base64::encode($encapsulated)) . '-----END PUBLIC KEY-----'; $plaintext = str_pad($this->toBytes(), strlen($n->toBytes(true)) - 1, "\0", STR_PAD_LEFT); diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php index c7069aaf..3e6bcd37 100644 --- a/phpseclib/Net/SFTP.php +++ b/phpseclib/Net/SFTP.php @@ -2643,7 +2643,7 @@ class SFTP extends SSH2 // IEEE 754 binary64 "double precision" on such platforms and // as such can represent integers of at least 2^50 without loss // of precision. Interpreted in filesize, 2^50 bytes = 1024 TiB. - $attr['size'] = hexdec(bin2hex($this->_string_shift($response, 8))); + $attr['size'] = hexdec(Hex::encode($this->_string_shift($response, 8))); break; case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only) $attr+= unpack('Nuid/Ngid', $this->_string_shift($response, 8)); diff --git a/phpseclib/Net/SSH1.php b/phpseclib/Net/SSH1.php index 2a8c1d8d..9e73337a 100644 --- a/phpseclib/Net/SSH1.php +++ b/phpseclib/Net/SSH1.php @@ -48,6 +48,7 @@ namespace phpseclib\Net; +use ParagonIE\ConstantTime\Hex; use phpseclib\Crypt\DES; use phpseclib\Crypt\Random; use phpseclib\Crypt\TripleDES; @@ -609,7 +610,7 @@ class SSH1 } } - $session_id = pack('H*', md5($host_key_public_modulus->toBytes() . $server_key_public_modulus->toBytes() . $anti_spoofing_cookie)); + $session_id = Hex::decode(md5($host_key_public_modulus->toBytes() . $server_key_public_modulus->toBytes() . $anti_spoofing_cookie)); $session_key = Random::string(32); $double_encrypted_session_key = $session_key ^ str_pad($session_id, 32, chr(0)); diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 01fe14df..e7f3e88a 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -49,6 +49,7 @@ namespace phpseclib\Net; +use ParagonIE\ConstantTime\Base64; use phpseclib\Crypt\Base; use phpseclib\Crypt\Blowfish; use phpseclib\Crypt\Hash; @@ -3980,7 +3981,7 @@ class SSH2 if ($this->signature_validated) { return $this->bitmap ? - $this->signature_format . ' ' . base64_encode($this->server_public_host_key) : + $this->signature_format . ' ' . Base64::encode($this->server_public_host_key) : false; } @@ -4096,7 +4097,7 @@ class SSH2 throw new NoSupportedAlgorithmsException('Unsupported signature format'); } - return $this->signature_format . ' ' . base64_encode($this->server_public_host_key); + return $this->signature_format . ' ' . Base64::encode($this->server_public_host_key); } /** diff --git a/phpseclib/System/SSH/Agent.php b/phpseclib/System/SSH/Agent.php index 4d373f17..23bf027a 100644 --- a/phpseclib/System/SSH/Agent.php +++ b/phpseclib/System/SSH/Agent.php @@ -33,6 +33,7 @@ namespace phpseclib\System\SSH; +use ParagonIE\ConstantTime\Base64; use phpseclib\Crypt\RSA; use phpseclib\Exception\BadConfigurationException; use phpseclib\System\SSH\Agent\Identity; @@ -171,7 +172,7 @@ class Agent for ($i = 0; $i < $keyCount; $i++) { $length = current(unpack('N', fread($this->fsock, 4))); $key_blob = fread($this->fsock, $length); - $key_str = 'ssh-rsa ' . base64_encode($key_blob); + $key_str = 'ssh-rsa ' . Base64::encode($key_blob); $length = current(unpack('N', fread($this->fsock, 4))); if ($length) { $key_str.= ' ' . fread($this->fsock, $length);