Skip to content

Commit

Permalink
Merge branch '3.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
terrafrost committed Apr 19, 2020
2 parents 3be9465 + 881fbd7 commit b48181e
Show file tree
Hide file tree
Showing 31 changed files with 170 additions and 83 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## 2.0.26 - 2020-03-22

- SFTP: another attempt at speeding up uploads (#1455)
- SSH2: try logging in with none as an auth method first (#1454)
- ASN1: fix for malformed ASN1 strings (#1456)

## 2.0.25 - 2020-02-25

- SFTP: re-add buffering (#1455)

## 2.0.24 - 2020-02-22

- X509: fix PHP 5.3 compatability issue
Expand Down
14 changes: 13 additions & 1 deletion phpseclib/Common/Functions/Strings.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ public static function packSSH2(...$elements)
$result.= pack('N', $element);
break;
case 's':
if (!is_string($element)) {
if (!self::is_stringable($element)) {
throw new \InvalidArgumentException('A string was expected.');
}
$result.= pack('Na*', strlen($element), $element);
Expand Down Expand Up @@ -372,4 +372,16 @@ public static function increment_str(&$var)

return $var;
}

/**
* Find whether the type of a variable is string (or could be converted to one)
*
* @param string|object $var
* @return boolean
* @access public
*/
public static function is_stringable($var)
{
return is_string($var) || (is_object($var) && method_exists($var, '__toString'));
}
}
13 changes: 7 additions & 6 deletions phpseclib/Crypt/Common/AsymmetricKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
use phpseclib3\Crypt\ECDSA;

/**
* Base Class for all stream cipher classes
* Base Class for all asymmetric cipher classes
*
* @package AsymmetricKey
* @author Jim Wigginton <[email protected]>
Expand Down Expand Up @@ -173,8 +173,8 @@ public static function load($key, $password = false)
}

$components['format'] = $format;

$new = static::onLoad($components);
$new->format = $format;
return $new instanceof PrivateKey ?
$new->withPassword($password) :
$new;
Expand Down Expand Up @@ -206,6 +206,7 @@ public static function loadFormat($type, $key, $password = false)
$components['format'] = $format;

$new = static::onLoad($components);
$new->format = $format;
return $new instanceof PrivateKey ?
$new->withPassword($password) :
$new;
Expand Down Expand Up @@ -304,16 +305,16 @@ public static function addFileFormat($fullname)
* Returns the format of the loaded key.
*
* If the key that was loaded wasn't in a valid or if the key was auto-generated
* with RSA::createKey() then this will return false.
* with RSA::createKey() then this will throw an exception.
*
* @see self::load()
* @access public
* @return mixed
*/
public function getLoadedFormat()
{
if ($this->format === false) {
return false;
if (empty($this->format)) {
throw new NoKeyLoadedException('This key was created with createKey - it was not loaded with load. Therefore there is no "loaded format"');
}

$meta = new \ReflectionClass($this->format);
Expand Down Expand Up @@ -387,7 +388,7 @@ public function withHash($hash)
*/
public function getHash()
{
return $this->hash->getHash();
return clone $this->hash;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public static function setComment($comment)
*/
public static function load($key, $password = '')
{
if (!is_string($key)) {
if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
}

Expand Down
3 changes: 2 additions & 1 deletion phpseclib/Crypt/Common/Formats/Keys/PKCS1.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use phpseclib3\Crypt\DES;
use phpseclib3\Crypt\TripleDES;
use phpseclib3\File\ASN1;
use phpseclib3\Common\Functions\Strings;
use phpseclib3\Exception\UnsupportedAlgorithmException;

/**
Expand Down Expand Up @@ -127,7 +128,7 @@ private static function generateSymmetricKey($password, $iv, $length)
*/
protected static function load($key, $password)
{
if (!is_string($key)) {
if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
}

Expand Down
84 changes: 64 additions & 20 deletions phpseclib/Crypt/Common/Formats/Keys/PKCS8.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
use phpseclib3\Math\BigInteger;
use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps;
use phpseclib3\Common\Functions\Strings;
use phpseclib3\Exception\UnsupportedAlgorithmException;

/**
Expand Down Expand Up @@ -331,25 +332,7 @@ private static function initialize_static_variables()
*/
protected static function load($key, $password = '')
{
self::initialize_static_variables();

if (!is_string($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
}

if (self::$format != self::MODE_DER) {
$decoded = ASN1::extractBER($key);
if ($decoded !== false) {
$key = $decoded;
} elseif (self::$format == self::MODE_PEM) {
throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text');
}
}

$decoded = ASN1::decodeBER($key);
if (empty($decoded)) {
throw new \RuntimeException('Unable to decode BER');
}
$decoded = self::preParse($key);

$meta = [];

Expand Down Expand Up @@ -442,7 +425,7 @@ protected static function load($key, $password = '')
if (isset($keyLength)) {
$params[] = (int) $keyLength->toString();
}
call_user_func_array([$cipher, 'setPassword'], $params);
$cipher->setPassword(...$params);
$key = $cipher->decrypt($decrypted['encryptedData']);
$decoded = ASN1::decodeBER($key);
if (empty($decoded)) {
Expand Down Expand Up @@ -654,4 +637,65 @@ protected static function wrapPublicKey($key, $params, $oid = null)
chunk_split(Base64::encode($key), 64) .
"-----END PUBLIC KEY-----";
}

/**
* Perform some preliminary parsing of the key
*
* @param string $key
* @return array
*/
private static function preParse(&$key)
{
self::initialize_static_variables();

if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
}

if (self::$format != self::MODE_DER) {
$decoded = ASN1::extractBER($key);
if ($decoded !== false) {
$key = $decoded;
} elseif (self::$format == self::MODE_PEM) {
throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text');
}
}

$decoded = ASN1::decodeBER($key);
if (empty($decoded)) {
throw new \RuntimeException('Unable to decode BER');
}

return $decoded;
}

/**
* Returns the encryption parameters used by the key
*
* @param string $key
* @return array
*/
public static function extractEncryptionAlgorithm($key)
{
$decoded = self::preParse($key);

$r = ASN1::asn1map($decoded[0], ASN1\Maps\EncryptedPrivateKeyInfo::MAP);
if (!is_array($r)) {
throw new \RuntimeException('Unable to parse using EncryptedPrivateKeyInfo map');
}

if ($r['encryptionAlgorithm']['algorithm'] == 'id-PBES2') {
$decoded = ASN1::decodeBER($r['encryptionAlgorithm']['parameters']->element);
$r['encryptionAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], ASN1\Maps\PBES2params::MAP);

$kdf = &$r['encryptionAlgorithm']['parameters']['keyDerivationFunc'];
switch ($kdf['algorithm']) {
case 'id-PBKDF2':
$decoded = ASN1::decodeBER($kdf['parameters']->element);
$kdf['parameters'] = ASN1::asn1map($decoded[0], Maps\PBKDF2params::MAP);
}
}

return $r['encryptionAlgorithm'];
}
}
10 changes: 5 additions & 5 deletions phpseclib/Crypt/Common/Formats/Keys/PuTTY.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private static function generateSymmetricKey($password, $length)
*/
public static function load($key, $password)
{
if (!is_string($key)) {
if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
}

Expand Down Expand Up @@ -200,14 +200,14 @@ public static function load($key, $password)
*/
protected static function wrapPrivateKey($public, $private, $type, $password, array $options = [])
{
$key = "PuTTY-User-Key-File-2: " . $type . "\r\nEncryption: ";
$encryption = (!empty($password) || is_string($password)) ? 'aes256-cbc' : 'none';
$key.= $encryption;
$key.= "\r\nComment: " . self::$comment . "\r\n";
$comment = isset($options['comment']) ? $options['comment'] : self::$comment;

$key = "PuTTY-User-Key-File-2: " . $type . "\r\nEncryption: "; $key.= $encryption;
$key.= "\r\nComment: " . $comment . "\r\n";

$public = Strings::packSSH2('s', $type) . $public;

$comment = isset($options['comment']) ? $options['comment'] : self::$comment;
$source = Strings::packSSH2('ssss', $type, $encryption, $comment, $public);

$public = Base64::encode($public);
Expand Down
3 changes: 2 additions & 1 deletion phpseclib/Crypt/DH/Formats/Keys/PKCS8.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor;
use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps;
use phpseclib3\Common\Functions\Strings;

/**
* PKCS#8 Formatted DH Key Handler
Expand Down Expand Up @@ -69,7 +70,7 @@ abstract class PKCS8 extends Progenitor
*/
public static function load($key, $password = '')
{
if (!is_string($key)) {
if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
}

Expand Down
6 changes: 3 additions & 3 deletions phpseclib/Crypt/DSA.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ abstract class DSA extends AsymmetricKey
* @var string
* @access private
*/
protected $format;
protected $sigFormat;

/**
* Signature Format (Short)
Expand Down Expand Up @@ -263,7 +263,7 @@ protected static function onLoad($components)
*/
protected function __construct()
{
$this->format = self::validatePlugin('Signature', 'ASN1');
$this->sigFormat = self::validatePlugin('Signature', 'ASN1');
$this->shortFormat = 'ASN1';

parent::__construct();
Expand Down Expand Up @@ -329,7 +329,7 @@ public function withSignatureFormat($format)
{
$new = clone $this;
$new->shortFormat = $format;
$new->format = self::validatePlugin('Signature', $format);
$new->sigFormat = self::validatePlugin('Signature', $format);
return $new;
}

Expand Down
3 changes: 2 additions & 1 deletion phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor;
use phpseclib3\File\ASN1;
use phpseclib3\File\ASN1\Maps;
use phpseclib3\Common\Functions\Strings;

/**
* PKCS#8 Formatted DSA Key Handler
Expand Down Expand Up @@ -73,7 +74,7 @@ abstract class PKCS8 extends Progenitor
*/
public static function load($key, $password = '')
{
if (!is_string($key)) {
if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
}

Expand Down
3 changes: 2 additions & 1 deletion phpseclib/Crypt/DSA/Formats/Keys/XML.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

use ParagonIE\ConstantTime\Base64;
use phpseclib3\Math\BigInteger;
use phpseclib3\Common\Functions\Strings;

/**
* XML Formatted DSA Key Handler
Expand All @@ -43,7 +44,7 @@ abstract class XML
*/
public static function load($key, $password = '')
{
if (!is_string($key)) {
if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
}

Expand Down
2 changes: 1 addition & 1 deletion phpseclib/Crypt/DSA/PrivateKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public function getPublicKey()
*/
public function sign($message)
{
$format = $this->format;
$format = $this->sigFormat;

if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) {
$signature = '';
Expand Down
2 changes: 1 addition & 1 deletion phpseclib/Crypt/DSA/PublicKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class PublicKey extends DSA implements Common\PublicKey
*/
public function verify($message, $signature)
{
$format = $this->format;
$format = $this->sigFormat;

$params = $format::load($signature);
if ($params === false || count($params) != 2) {
Expand Down
4 changes: 2 additions & 2 deletions phpseclib/Crypt/EC.php
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ protected static function onLoad($components)
*/
protected function __construct()
{
$this->format = self::validatePlugin('Signature', 'ASN1');
$this->sigFormat = self::validatePlugin('Signature', 'ASN1');
$this->shortFormat = 'ASN1';

parent::__construct();
Expand Down Expand Up @@ -383,7 +383,7 @@ public function withSignatureFormat($format)

$new = clone $this;
$new->shortFormat = $format;
$new->format = self::validatePlugin('Signature', $format);
$new->sigFormat = self::validatePlugin('Signature', $format);
return $new;
}

Expand Down
3 changes: 2 additions & 1 deletion phpseclib/Crypt/EC/Formats/Keys/PKCS8.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
use phpseclib3\Crypt\EC\Curves\Ed25519;
use phpseclib3\Crypt\EC\Curves\Ed448;
use phpseclib3\Exception\UnsupportedCurveException;
use phpseclib3\Common\Functions\Strings;

/**
* PKCS#8 Formatted EC Key Handler
Expand Down Expand Up @@ -81,7 +82,7 @@ public static function load($key, $password = '')
// one that's called
self::initialize_static_variables();

if (!is_string($key)) {
if (!Strings::is_stringable($key)) {
throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key));
}

Expand Down
Loading

0 comments on commit b48181e

Please sign in to comment.