undo merging of master to 2.0 branch

This commit is contained in:
terrafrost 2016-04-28 15:34:10 -05:00
parent b3171cc63f
commit 8fb4c3363d
61 changed files with 3192 additions and 4400 deletions

View File

@ -1,6 +1,6 @@
# phpseclib - PHP Secure Communications Library
[![Build Status](https://travis-ci.org/phpseclib/phpseclib.svg?branch=master)](https://travis-ci.org/phpseclib/phpseclib)
[![Build Status](https://travis-ci.org/phpseclib/phpseclib.svg?branch=2.0)](https://travis-ci.org/phpseclib/phpseclib)
MIT-licensed pure-PHP implementations of an arbitrary-precision integer
arithmetic library, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael,
@ -8,7 +8,7 @@ AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509
* [Download (1.0.1)](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.1.zip/download)
* [Browse Git](https://github.com/phpseclib/phpseclib)
* [Code Coverage Report](http://phpseclib.bantux.org/code_coverage/master/latest/)
* [Code Coverage Report](http://phpseclib.bantux.org/code_coverage/2.0/latest/)
<img src="http://phpseclib.sourceforge.net/pear-icon.png" alt="PEAR Channel" width="16" height="16">
PEAR Channel: [phpseclib.sourceforge.net](http://phpseclib.sourceforge.net/pear.htm)
@ -16,7 +16,7 @@ PEAR Channel: [phpseclib.sourceforge.net](http://phpseclib.sourceforge.net/pear.
## Documentation
* [Documentation / Manual](http://phpseclib.sourceforge.net/)
* [API Documentation](http://phpseclib.bantux.org/api/master/) (generated by Sami)
* [API Documentation](http://phpseclib.bantux.org/api/2.0/) (generated by Sami)
## Support

View File

@ -51,7 +51,6 @@
}
],
"require": {
"paragonie/random_compat": "^1.4|^2.0",
"php": ">=5.3.3"
},
"require-dev": {

55
composer.lock generated
View File

@ -4,58 +4,9 @@
"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",
"packages": [
{
"name": "paragonie/random_compat",
"version": "v2.0.2",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "088c04e2f261c33bed6ca5245491cfca69195ccf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/088c04e2f261c33bed6ca5245491cfca69195ccf",
"reference": "088c04e2f261c33bed6ca5245491cfca69195ccf",
"shasum": ""
},
"require": {
"php": ">=5.2.0"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"type": "library",
"autoload": {
"files": [
"lib/random.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"pseudorandom",
"random"
],
"time": "2016-04-03 06:00:07"
}
],
"hash": "8599992bf6058a9da82372eb8bcae2c2",
"content-hash": "fde47c84178c55c06de858a2128e3d07",
"packages": [],
"packages-dev": [
{
"name": "doctrine/instantiator",

View File

@ -49,6 +49,8 @@
namespace phpseclib\Crypt;
use phpseclib\Crypt\Rijndael;
/**
* Pure-PHP implementation of AES.
*
@ -66,32 +68,30 @@ class AES extends Rijndael
* @see \phpseclib\Crypt\Rijndael::setBlockLength()
* @access public
* @param int $length
* @throws \BadMethodCallException anytime it's called
*/
function setBlockLength($length)
{
throw new \BadMethodCallException('The block length cannot be set for AES.');
return;
}
/**
* Sets the key length
*
* Valid key lengths are 128, 192, and 256. Set the link to bool(false) to disable a fixed key length
* Valid key lengths are 128, 192, and 256. If the length is less than 128, it will be rounded up to
* 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
*
* @see \phpseclib\Crypt\Rijndael:setKeyLength()
* @access public
* @param int $length
* @throws \LengthException if the key length isn't supported
*/
function setKeyLength($length)
{
switch ($length) {
case 128:
case 192:
case 256:
case 160:
$length = 192;
break;
default:
throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported');
case 224:
$length = 256;
}
parent::setKeyLength($length);
}
@ -105,19 +105,24 @@ class AES extends Rijndael
* @see setKeyLength()
* @access public
* @param string $key
* @throws \LengthException if the key length isn't supported
*/
function setKey($key)
{
switch (strlen($key)) {
case 16:
case 24:
case 32:
break;
default:
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
}
parent::setKey($key);
if (!$this->explicit_key_length) {
$length = strlen($key);
switch (true) {
case $length <= 16:
$this->key_length = 16;
break;
case $length <= 24:
$this->key_length = 24;
break;
default:
$this->key_length = 32;
}
$this->_setEngine();
}
}
}

View File

@ -36,6 +36,8 @@
namespace phpseclib\Crypt;
use phpseclib\Crypt\Hash;
/**
* Base Class for all \phpseclib\Crypt\* cipher classes
*
@ -139,7 +141,7 @@ abstract class Base
* @var string
* @access private
*/
var $key = false;
var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
/**
* The Initialization Vector
@ -148,7 +150,7 @@ abstract class Base
* @var string
* @access private
*/
var $iv = false;
var $iv;
/**
* A "sliding" Initialization Vector
@ -429,15 +431,6 @@ abstract class Base
*/
var $openssl_options;
/**
* Don't truncate / null pad key
*
* @see self::_clearBuffers()
* @var bool
* @access private
*/
var $skip_key_adjustment = false;
/**
* Has the key length explicitly been set or should it be derived from the key, itself?
*
@ -447,9 +440,20 @@ abstract class Base
*/
var $explicit_key_length = false;
/**
* Don't truncate / null pad key
*
* @see self::_clearBuffers()
* @var bool
* @access private
*/
var $skip_key_adjustment = false;
/**
* Default Constructor.
*
* Determines whether or not the mcrypt extension should be used.
*
* $mode could be:
*
* - self::MODE_ECB
@ -462,29 +466,32 @@ abstract class Base
*
* - self::MODE_OFB
*
* If not explicitly set, self::MODE_CBC will be used.
*
* @param int $mode
* @access public
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
*/
function __construct($mode)
function __construct($mode = self::MODE_CBC)
{
// $mode dependent settings
switch ($mode) {
case self::MODE_ECB:
case self::MODE_CBC:
$this->paddable = true;
$this->mode = self::MODE_ECB;
break;
case self::MODE_CTR:
case self::MODE_CFB:
case self::MODE_OFB:
case self::MODE_STREAM:
$this->paddable = false;
$this->mode = $mode;
break;
case self::MODE_CBC:
default:
throw new \InvalidArgumentException('No valid mode has been specified');
$this->paddable = true;
$this->mode = self::MODE_CBC;
}
$this->mode = $mode;
$this->_setEngine();
// Determining whether inline crypting can be used by the cipher
if ($this->use_inline_crypt !== false && function_exists('create_function')) {
@ -493,28 +500,19 @@ abstract class Base
}
/**
* Sets the initialization vector.
* Sets the initialization vector. (optional)
*
* setIV() is not required when self::MODE_ECB (or ie for AES: \phpseclib\Crypt\AES::MODE_ECB) is being used.
* SetIV is not required when self::MODE_ECB (or ie for AES: \phpseclib\Crypt\AES::MODE_ECB) is being used. If not explicitly set, it'll be assumed
* to be all zero's.
*
* @access public
* @param string $iv
* @throws \LengthException if the IV length isn't equal to the block size
* @throws \InvalidArgumentException if an IV is provided when one shouldn't be
* @internal Can be overwritten by a sub class, but does not have to be
*/
function setIV($iv)
{
if ($this->mode == self::MODE_ECB) {
throw new \InvalidArgumentException('This mode does not require an IV.');
}
if ($this->mode == self::MODE_STREAM && $this->usesIV()) {
throw new \InvalidArgumentException('This algorithm does not use an IV.');
}
if (strlen($iv) != $this->block_size) {
throw new \LengthException('Received initialization vector of size ' . strlen($iv) . ', but size ' . $this->block_size . ' is required');
return;
}
$this->iv = $iv;
@ -522,14 +520,18 @@ abstract class Base
}
/**
* Returns whether or not the algorithm uses an IV
* Sets the key length.
*
* Keys with explicitly set lengths need to be treated accordingly
*
* @access public
* @return bool
* @param int $length
*/
function usesIV()
function setKeyLength($length)
{
return true;
$this->explicit_key_length = true;
$this->changed = true;
$this->_setEngine();
}
/**
@ -554,24 +556,6 @@ abstract class Base
return $this->block_size << 3;
}
/**
* Sets the key length.
*
* Keys with explicitly set lengths need to be treated accordingly
*
* @access public
* @param int $length
*/
function setKeyLength($length)
{
$this->explicit_key_length = $length >> 3;
if (is_string($this->key) && strlen($this->key) != $this->explicit_key_length) {
$this->key = false;
throw new \LengthException('Key has already been set and is not ' .$this->explicit_key_length . ' bytes long');
}
}
/**
* Sets the key.
*
@ -588,12 +572,12 @@ abstract class Base
*/
function setKey($key)
{
if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) {
throw new \LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes');
if (!$this->explicit_key_length) {
$this->setKeyLength(strlen($key) << 3);
$this->explicit_key_length = false;
}
$this->key = $key;
$this->key_length = strlen($key);
$this->changed = true;
$this->_setEngine();
}
@ -610,7 +594,6 @@ abstract class Base
* @see Crypt/Hash.php
* @param string $password
* @param string $method
* @throws \LengthException if pbkdf1 is being used and the derived key length exceeds the hash length
* @return bool
* @access public
* @internal Could, but not must, extend by the child Crypt_* class
@ -637,8 +620,7 @@ abstract class Base
if (isset($func_args[5])) {
$dkLen = $func_args[5];
} else {
$key_length = $this->explicit_key_length !== false ? $this->explicit_key_length : $this->key_length;
$dkLen = $method == 'pbkdf1' ? 2 * $key_length : $key_length;
$dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length;
}
switch (true) {
@ -646,7 +628,8 @@ abstract class Base
$hashObj = new Hash();
$hashObj->setHash($hash);
if ($dkLen > $hashObj->getLength()) {
throw new \LengthException('Derived key length cannot be longer than the hash length');
user_error('Derived key too long');
return false;
}
$t = $password . $salt;
for ($i = 0; $i < $count; ++$i) {
@ -793,7 +776,7 @@ abstract class Base
$this->changed = false;
}
if ($this->enchanged) {
mcrypt_generic_init($this->enmcrypt, $this->key, $this->_getIV($this->encryptIV));
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
$this->enchanged = false;
}
@ -856,7 +839,7 @@ abstract class Base
$ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
if (!$this->continuousBuffer) {
mcrypt_generic_init($this->enmcrypt, $this->key, $this->_getIV($this->encryptIV));
mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
}
return $ciphertext;
@ -1005,13 +988,14 @@ abstract class Base
* @access public
* @param string $ciphertext
* @return string $plaintext
* @throws \LengthException if we're inside a block cipher and the ciphertext length is not a multiple of the block size
* @internal Could, but not must, extend by the child Crypt_* class
*/
function decrypt($ciphertext)
{
if ($this->paddable && strlen($ciphertext) % $this->block_size) {
throw new \LengthException('The ciphertext length (' . strlen($ciphertext) . ') needs to be a multiple of the block size (' . $this->block_size . ')');
if ($this->paddable) {
// we pad with chr(0) since that's what mcrypt_generic does. to quote from {@link http://www.php.net/function.mcrypt-generic}:
// "The data is padded with "\0" to make sure the length of the data is n * blocksize."
$ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0));
}
if ($this->engine === self::ENGINE_OPENSSL) {
@ -1104,7 +1088,7 @@ abstract class Base
$this->changed = false;
}
if ($this->dechanged) {
mcrypt_generic_init($this->demcrypt, $this->key, $this->_getIV($this->decryptIV));
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
$this->dechanged = false;
}
@ -1149,7 +1133,7 @@ abstract class Base
$plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
if (!$this->continuousBuffer) {
mcrypt_generic_init($this->demcrypt, $this->key, $this->_getIV($this->decryptIV));
mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
}
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
@ -1286,22 +1270,6 @@ abstract class Base
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
}
/**
* Get the IV
*
* mcrypt requires an IV even if ECB is used
*
* @see self::encrypt()
* @see self::decrypt()
* @param string $iv
* @return string
* @access private
*/
function _getIV($iv)
{
return $this->mode == self::MODE_ECB ? str_repeat("\0", $this->block_size) : $iv;
}
/**
* OpenSSL CTR Processor
*
@ -1854,7 +1822,6 @@ abstract class Base
*
* @see self::_unpad()
* @param string $text
* @throws \LengthException if padding is disabled and the plaintext's length is not a multiple of the block size
* @access private
* @return string
*/
@ -1866,7 +1833,8 @@ abstract class Base
if ($length % $this->block_size == 0) {
return $text;
} else {
throw new \LengthException("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size}). Try enabling padding.");
user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})");
$this->padding = true;
}
}
@ -1883,7 +1851,6 @@ abstract class Base
*
* @see self::_pad()
* @param string $text
* @throws \LengthException if the ciphertext's length is not a multiple of the block size
* @access private
* @return string
*/
@ -1896,7 +1863,7 @@ abstract class Base
$length = ord($text[strlen($text) - 1]);
if (!$length || $length > $this->block_size) {
throw new \LengthException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})");
return false;
}
return substr($text, 0, -$length);
@ -1909,19 +1876,20 @@ abstract class Base
* after disableContinuousBuffer() or on cipher $engine (re)init
* ie after setKey() or setIV()
*
* @access private
* @access public
* @internal Could, but not must, extend by the child Crypt_* class
* @throws \UnexpectedValueException when an IV is required but not defined
*/
function _clearBuffers()
{
$this->enbuffer = $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
if ($this->iv === false && !in_array($this->mode, array(self::MODE_STREAM, self::MODE_ECB))) {
throw new \UnexpectedValueException('No IV has been defined');
}
// mcrypt's handling of invalid's $iv:
// $this->encryptIV = $this->decryptIV = strlen($this->iv) == $this->block_size ? $this->iv : str_repeat("\0", $this->block_size);
$this->encryptIV = $this->decryptIV = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, "\0");
$this->encryptIV = $this->decryptIV = $this->iv;
if (!$this->skip_key_adjustment) {
$this->key = str_pad(substr($this->key, 0, $this->key_length), $this->key_length, "\0");
}
}
/**

View File

@ -37,6 +37,8 @@
namespace phpseclib\Crypt;
use phpseclib\Crypt\Base;
/**
* Pure-PHP implementation of Blowfish.
*
@ -283,22 +285,6 @@ class Blowfish extends Base
*/
var $key_length = 16;
/**
* Default Constructor.
*
* @param int $mode
* @access public
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
*/
function __construct($mode)
{
if ($mode == self::MODE_STREAM) {
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
}
parent::__construct($mode);
}
/**
* Sets the key length.
*
@ -309,12 +295,14 @@ class Blowfish extends Base
*/
function setKeyLength($length)
{
if ($length < 32 || $length > 448) {
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes between 32 and 448 bits are supported');
if ($length < 32) {
$this->key_length = 7;
} elseif ($length > 448) {
$this->key_length = 56;
} else {
$this->key_length = $length >> 3;
}
$this->key_length = $length >> 3;
parent::setKeyLength($length);
}

View File

@ -42,6 +42,8 @@
namespace phpseclib\Crypt;
use phpseclib\Crypt\Base;
/**
* Pure-PHP implementation of DES.
*
@ -578,22 +580,6 @@ class DES extends Base
0x00000820, 0x00020020, 0x08000000, 0x08020800
);
/**
* Default Constructor.
*
* @param int $mode
* @access public
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
*/
function __construct($mode)
{
if ($mode == self::MODE_STREAM) {
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
}
parent::__construct($mode);
}
/**
* Test for engine validity
*
@ -619,18 +605,24 @@ class DES extends Base
/**
* Sets the key.
*
* Keys must be 64-bits long or 8 bytes long.
* Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
* only use the first eight, if $key has more then eight characters in it, and pad $key with the
* null byte if it is less then eight characters long.
*
* DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
*
* If the key is not explicitly set, it'll be assumed to be all zero's.
*
* @see \phpseclib\Crypt\Base::setKey()
* @access public
* @param string $key
*/
function setKey($key)
{
if (!($this instanceof TripleDES) && strlen($key) != 8) {
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of size 8 are supported');
// We check/cut here only up to max length of the key.
// Key padding to the proper length will be done in _setupKey()
if (strlen($key) > $this->key_length_max) {
$key = substr($key, 0, $this->key_length_max);
}
// Sets the key

View File

@ -1,19 +1,26 @@
<?php
/**
* Wrapper around hash() and hash_hmac() functions supporting truncated hashes
* such as sha256-96. Any hash algorithm returned by hash_algos() (and
* truncated versions thereof) are supported.
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
*
* If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will
* return the HMAC as opposed to the hash.
* Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
*
* md2, md5, md5-96, sha1, sha1-96, sha256, sha256-96, sha384, and sha512, sha512-96
*
* If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will return the HMAC as opposed to
* the hash. If no valid algorithm is provided, sha1 will be used.
*
* PHP version 5
*
* {@internal The variable names are the same as those in
* {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'vendor/autoload.php';
*
* $hash = new \phpseclib\Crypt\Hash('sha512');
* $hash = new \phpseclib\Crypt\Hash('sha1');
*
* $hash->setKey('abcdefg');
*
@ -24,9 +31,7 @@
* @category Crypt
* @package Hash
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2015 Andreas Fischer
* @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
@ -34,16 +39,34 @@
namespace phpseclib\Crypt;
use phpseclib\Math\BigInteger;
use phpseclib\Exception\UnsupportedAlgorithmException;
/**
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
*
* @package Hash
* @author Jim Wigginton <terrafrost@php.net>
* @author Andreas Fischer <bantu@phpbb.com>
* @access public
*/
class Hash
{
/**#@+
* @access private
* @see \phpseclib\Crypt\Hash::__construct()
*/
/**
* Toggles the internal implementation
*/
const MODE_INTERNAL = 1;
/**
* Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
*/
const MODE_MHASH = 2;
/**
* Toggles the hash() implementation, which works on PHP 5.1.2+.
*/
const MODE_HASH = 3;
/**#@-*/
/**
* Hash Parameter
*
@ -53,6 +76,15 @@ class Hash
*/
var $hashParam;
/**
* Byte-length of compression blocks / key (Internal HMAC)
*
* @see self::setAlgorithm()
* @var int
* @access private
*/
var $b;
/**
* Byte-length of hash output (Internal HMAC)
*
@ -60,7 +92,7 @@ class Hash
* @var int
* @access private
*/
var $length;
var $l = false;
/**
* Hash Algorithm
@ -80,23 +112,10 @@ class Hash
*/
var $key = false;
/**
* Initial Hash
*
* Used only for sha512/*
*
* @see self::_sha512()
* @var array
* @access private
*/
var $initial = false;
/**
* Outer XOR (Internal HMAC)
*
* Used only for sha512/*
*
* @see self::hash()
* @see self::setKey()
* @var string
* @access private
*/
@ -105,9 +124,7 @@ class Hash
/**
* Inner XOR (Internal HMAC)
*
* Used only for sha512/*
*
* @see self::hash()
* @see self::setKey()
* @var string
* @access private
*/
@ -117,14 +134,25 @@ class Hash
* Default Constructor.
*
* @param string $hash
* @return \phpseclib\Crypt\Hash
* @access public
*/
function __construct($hash = 'sha256')
function __construct($hash = 'sha1')
{
$this->setHash($hash);
if (!defined('CRYPT_HASH_MODE')) {
switch (true) {
case extension_loaded('hash'):
define('CRYPT_HASH_MODE', self::MODE_HASH);
break;
case extension_loaded('mhash'):
define('CRYPT_HASH_MODE', self::MODE_MHASH);
break;
default:
define('CRYPT_HASH_MODE', self::MODE_INTERNAL);
}
}
$this->ipad = str_repeat(chr(0x36), 128);
$this->opad = str_repeat(chr(0x5C), 128);
$this->setHash($hash);
}
/**
@ -163,76 +191,101 @@ class Hash
{
$this->hashParam = $hash = strtolower($hash);
switch ($hash) {
case 'md2-96':
case 'md5-96':
case 'sha1-96':
case 'sha256-96':
case 'sha512-96':
case 'sha512/224-96':
case 'sha512/256-96':
$hash = substr($hash, 0, -3);
$this->length = 12; // 96 / 8 = 12
$this->l = 12; // 96 / 8 = 12
break;
case 'md2':
case 'md5':
$this->length = 16;
$this->l = 16;
break;
case 'sha1':
$this->length = 20;
break;
case 'sha512/224':
$this->length = 28;
$this->l = 20;
break;
case 'sha256':
case 'sha512/256':
$this->length = 32;
$this->l = 32;
break;
case 'sha384':
$this->length = 48;
$this->l = 48;
break;
case 'sha512':
$this->length = 64;
$this->l = 64;
}
switch ($hash) {
case 'md2':
$mode = CRYPT_HASH_MODE == self::MODE_HASH && in_array('md2', hash_algos()) ?
self::MODE_HASH : self::MODE_INTERNAL;
break;
case 'sha384':
case 'sha512':
$mode = CRYPT_HASH_MODE == self::MODE_MHASH ? self::MODE_INTERNAL : CRYPT_HASH_MODE;
break;
default:
// see if the hash isn't "officially" supported see if it can
// be "unofficially" supported and calculate the length
// accordingly.
if (in_array($hash, hash_algos())) {
$this->length = strlen(hash($hash, '', true));
break;
}
// if the hash algorithm doens't exist maybe it's a truncated
// hash, e.g. whirlpool-12 or some such.
if (preg_match('#(-\d+)$#', $hash, $matches)) {
$hash = substr($hash, 0, -strlen($matches[1]));
if (in_array($hash, hash_algos())) {
$this->length = abs($matches[1]) >> 3;
$mode = CRYPT_HASH_MODE;
}
switch ($mode) {
case self::MODE_MHASH:
switch ($hash) {
case 'md5':
$this->hash = MHASH_MD5;
break;
}
case 'sha256':
$this->hash = MHASH_SHA256;
break;
case 'sha1':
default:
$this->hash = MHASH_SHA1;
}
throw new UnsupportedAlgorithmException(
"$hash is not a supported algorithm"
);
return;
case self::MODE_HASH:
switch ($hash) {
case 'md5':
$this->hash = 'md5';
return;
case 'md2':
case 'sha256':
case 'sha384':
case 'sha512':
$this->hash = $hash;
return;
case 'sha1':
default:
$this->hash = 'sha1';
}
return;
}
if ($hash == 'sha512/224' || $hash == 'sha512/256') {
// from http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf#page=24
$this->initial = $hash == 'sha512/256' ?
array(
'22312194FC2BF72C', '9F555FA3C84C64C2', '2393B86B6F53B151', '963877195940EABD',
'96283EE2A88EFFE3', 'BE5E1E2553863992', '2B0199FC2C85B8AA', '0EB72DDC81C52CA2'
) :
array(
'8C3D37C819544DA2', '73E1996689DCD4D6', '1DFAB7AE32FF9C82', '679DD514582F9FCF',
'0F6D2B697BD44DA8', '77E36F7304C48942', '3F9D85A86A1D36C8', '1112E6AD91D692A1'
);
for ($i = 0; $i < 8; $i++) {
$this->initial[$i] = new BigInteger($this->initial[$i], 16);
$this->initial[$i]->setPrecision(64);
}
switch ($hash) {
case 'md2':
$this->b = 16;
$this->hash = array($this, '_md2');
break;
case 'md5':
$this->b = 64;
$this->hash = array($this, '_md5');
break;
case 'sha256':
$this->b = 64;
$this->hash = array($this, '_sha256');
break;
case 'sha384':
case 'sha512':
$this->b = 128;
$this->hash = array($this, '_sha512');
break;
case 'sha1':
default:
$this->b = 64;
$this->hash = array($this, '_sha1');
}
$this->hash = $hash;
$this->ipad = str_repeat(chr(0x36), $this->b);
$this->opad = str_repeat(chr(0x5C), $this->b);
}
/**
@ -244,35 +297,45 @@ class Hash
*/
function hash($text)
{
switch ($this->hash) {
case 'sha512/224':
case 'sha512/256':
if (empty($this->key) || !is_string($this->key)) {
return substr(self::_sha512($text, $this->initial), 0, $this->length);
}
/* "Applications that use keys longer than B bytes will first hash the key using H and then use the
resultant L byte string as the actual key to HMAC."
$mode = is_array($this->hash) ? self::MODE_INTERNAL : CRYPT_HASH_MODE;
-- http://tools.ietf.org/html/rfc2104#section-2 */
$key = strlen($this->key) > $this->b ? self::_sha512($this->key, $this->initial) : $this->key;
if (!empty($this->key) || is_string($this->key)) {
switch ($mode) {
case self::MODE_MHASH:
$output = mhash($this->hash, $text, $this->key);
break;
case self::MODE_HASH:
$output = hash_hmac($this->hash, $text, $this->key, true);
break;
case self::MODE_INTERNAL:
/* "Applications that use keys longer than B bytes will first hash the key using H and then use the
resultant L byte string as the actual key to HMAC."
$key = str_pad($this->key, 128, chr(0)); // step 1
$temp = $this->ipad ^ $this->key; // step 2
$temp .= $text; // step 3
$temp = self::_sha512($temp, $this->initial); // step 4
$output = $this->opad ^ $this->key; // step 5
$output.= $temp; // step 6
$output = self::_sha512($output, $this->initial); // step 7
-- http://tools.ietf.org/html/rfc2104#section-2 */
$key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
return substr($output, 0, $this->length);
$key = str_pad($key, $this->b, chr(0)); // step 1
$temp = $this->ipad ^ $key; // step 2
$temp .= $text; // step 3
$temp = call_user_func($this->hash, $temp); // step 4
$output = $this->opad ^ $key; // step 5
$output.= $temp; // step 6
$output = call_user_func($this->hash, $output); // step 7
}
} else {
switch ($mode) {
case self::MODE_MHASH:
$output = mhash($this->hash, $text);
break;
case self::MODE_HASH:
$output = hash($this->hash, $text, true);
break;
case self::MODE_INTERNAL:
$output = call_user_func($this->hash, $text);
}
}
$output = !empty($this->key) || is_string($this->key) ?
hash_hmac($this->hash, $text, $this->key, true) :
hash($this->hash, $text, true);
return strlen($output) > $this->length
? substr($output, 0, $this->length)
: $output;
return substr($output, 0, $this->l);
}
/**
@ -283,20 +346,243 @@ class Hash
*/
function getLength()
{
return $this->length;
return $this->l;
}
/**
* Pure-PHP implementation of SHA512
* Wrapper for MD5
*
* @access private
* @param string $m
*/
static function _sha512($m, $hash)
function _md5($m)
{
static $k;
return pack('H*', md5($m));
}
/**
* Wrapper for SHA1
*
* @access private
* @param string $m
*/
function _sha1($m)
{
return pack('H*', sha1($m));
}
/**
* Pure-PHP implementation of MD2
*
* See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
*
* @access private
* @param string $m
*/
function _md2($m)
{
static $s = array(
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
);
// Step 1. Append Padding Bytes
$pad = 16 - (strlen($m) & 0xF);
$m.= str_repeat(chr($pad), $pad);
$length = strlen($m);
// Step 2. Append Checksum
$c = str_repeat(chr(0), 16);
$l = chr(0);
for ($i = 0; $i < $length; $i+= 16) {
for ($j = 0; $j < 16; $j++) {
// RFC1319 incorrectly states that C[j] should be set to S[c xor L]
//$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
// per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j]
$c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
$l = $c[$j];
}
}
$m.= $c;
$length+= 16;
// Step 3. Initialize MD Buffer
$x = str_repeat(chr(0), 48);
// Step 4. Process Message in 16-Byte Blocks
for ($i = 0; $i < $length; $i+= 16) {
for ($j = 0; $j < 16; $j++) {
$x[$j + 16] = $m[$i + $j];
$x[$j + 32] = $x[$j + 16] ^ $x[$j];
}
$t = chr(0);
for ($j = 0; $j < 18; $j++) {
for ($k = 0; $k < 48; $k++) {
$x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
//$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
}
$t = chr(ord($t) + $j);
}
}
// Step 5. Output
return substr($x, 0, 16);
}
/**
* Pure-PHP implementation of SHA256
*
* See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
*
* @access private
* @param string $m
*/
function _sha256($m)
{
if (extension_loaded('suhosin')) {
return pack('H*', sha256($m));
}
// Initialize variables
$hash = array(
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
);
// Initialize table of round constants
// (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
static $k = array(
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
);
// Pre-processing
$length = strlen($m);
// to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
$m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
$m[$length] = chr(0x80);
// we don't support hashing strings 512MB long
$m.= pack('N2', 0, $length << 3);
// Process the message in successive 512-bit chunks
$chunks = str_split($m, 64);
foreach ($chunks as $chunk) {
$w = array();
for ($i = 0; $i < 16; $i++) {
extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
$w[] = $temp;
}
// 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);
}
// Initialize hash value for this chunk
list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
// Main loop
for ($i = 0; $i < 64; $i++) {
$s0 = $this->_rightRotate($a, 2) ^
$this->_rightRotate($a, 13) ^
$this->_rightRotate($a, 22);
$maj = ($a & $b) ^
($a & $c) ^
($b & $c);
$t2 = $this->_add($s0, $maj);
$s1 = $this->_rightRotate($e, 6) ^
$this->_rightRotate($e, 11) ^
$this->_rightRotate($e, 25);
$ch = ($e & $f) ^
($this->_not($e) & $g);
$t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
$h = $g;
$g = $f;
$f = $e;
$e = $this->_add($d, $t1);
$d = $c;
$c = $b;
$b = $a;
$a = $this->_add($t1, $t2);
}
// Add this chunk's hash to result so far
$hash = array(
$this->_add($hash[0], $a),
$this->_add($hash[1], $b),
$this->_add($hash[2], $c),
$this->_add($hash[3], $d),
$this->_add($hash[4], $e),
$this->_add($hash[5], $f),
$this->_add($hash[6], $g),
$this->_add($hash[7], $h)
);
}
// Produce the final hash value (big-endian)
return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
}
/**
* Pure-PHP implementation of SHA384 and SHA512
*
* @access private
* @param string $m
*/
function _sha512($m)
{
static $init384, $init512, $k;
if (!isset($k)) {
// Initialize variables
$init384 = array( // initial values for SHA384
'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
'67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
);
$init512 = array( // initial values for SHA512
'6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
'510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
);
for ($i = 0; $i < 8; $i++) {
$init384[$i] = new BigInteger($init384[$i], 16);
$init384[$i]->setPrecision(64);
$init512[$i] = new BigInteger($init512[$i], 16);
$init512[$i]->setPrecision(64);
}
// Initialize table of round constants
// (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
$k = array(
@ -327,6 +613,8 @@ class Hash
}
}
$hash = $this->l == 48 ? $init384 : $init512;
// Pre-processing
$length = strlen($m);
// to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
@ -340,7 +628,7 @@ class Hash
foreach ($chunks as $chunk) {
$w = array();
for ($i = 0; $i < 16; $i++) {
$temp = new BigInteger(self::_string_shift($chunk, 8), 256);
$temp = new BigInteger($this->_string_shift($chunk, 8), 256);
$temp->setPrecision(64);
$w[] = $temp;
}
@ -361,21 +649,21 @@ class Hash
);
$s1 = $temp[0]->bitwise_xor($temp[1]);
$s1 = $s1->bitwise_xor($temp[2]);
$w[$i] = clone $w[$i - 16];
$w[$i] = $w[$i - 16]->copy();
$w[$i] = $w[$i]->add($s0);
$w[$i] = $w[$i]->add($w[$i - 7]);
$w[$i] = $w[$i]->add($s1);
}
// Initialize hash value for this chunk
$a = clone $hash[0];
$b = clone $hash[1];
$c = clone $hash[2];
$d = clone $hash[3];
$e = clone $hash[4];
$f = clone $hash[5];
$g = clone $hash[6];
$h = clone $hash[7];
$a = $hash[0]->copy();
$b = $hash[1]->copy();
$c = $hash[2]->copy();
$d = $hash[3]->copy();
$e = $hash[4]->copy();
$f = $hash[5]->copy();
$g = $hash[6]->copy();
$h = $hash[7]->copy();
// Main loop
for ($i = 0; $i < 80; $i++) {
@ -412,13 +700,13 @@ class Hash
$t1 = $t1->add($k[$i]);
$t1 = $t1->add($w[$i]);
$h = clone $g;
$g = clone $f;
$f = clone $e;
$h = $g->copy();
$g = $f->copy();
$f = $e->copy();
$e = $d->add($t1);
$d = clone $c;
$c = clone $b;
$b = clone $a;
$d = $c->copy();
$c = $b->copy();
$b = $a->copy();
$a = $t1->add($t2);
}
@ -438,11 +726,85 @@ class Hash
// Produce the final hash value (big-endian)
// (\phpseclib\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
$temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
$hash[4]->toBytes() . $hash[5]->toBytes() . $hash[6]->toBytes() . $hash[7]->toBytes();
$hash[4]->toBytes() . $hash[5]->toBytes();
if ($this->l != 48) {
$temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
}
return $temp;
}
/**
* Right Rotate
*
* @access private
* @param int $int
* @param int $amt
* @see self::_sha256()
* @return int
*/
function _rightRotate($int, $amt)
{
$invamt = 32 - $amt;
$mask = (1 << $invamt) - 1;
return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
}
/**
* Right Shift
*
* @access private
* @param int $int
* @param int $amt
* @see self::_sha256()
* @return int
*/
function _rightShift($int, $amt)
{
$mask = (1 << (32 - $amt)) - 1;
return ($int >> $amt) & $mask;
}
/**
* Not
*
* @access private
* @param int $int
* @see self::_sha256()
* @return int
*/
function _not($int)
{
return ~$int & 0xFFFFFFFF;
}
/**
* Add
*
* _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
* possibility of overflow exists, care has to be taken. BigInteger could be used but this should be faster.
*
* @param int $...
* @return int
* @see self::_sha256()
* @access private
*/
function _add()
{
static $mod;
if (!isset($mod)) {
$mod = pow(2, 32);
}
$result = 0;
$arguments = func_get_args();
foreach ($arguments as $argument) {
$result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
}
return fmod($result, $mod);
}
/**
* String Shift
*
@ -453,7 +815,7 @@ class Hash
* @return string
* @access private
*/
static function _string_shift(&$string, $index = 1)
function _string_shift(&$string, $index = 1)
{
$substr = substr($string, 0, $index);
$string = substr($string, $index);

View File

@ -35,6 +35,8 @@
namespace phpseclib\Crypt;
use phpseclib\Crypt\Base;
/**
* Pure-PHP implementation of RC2.
*
@ -259,22 +261,6 @@ class RC2 extends Base
0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6
);
/**
* Default Constructor.
*
* @param int $mode
* @access public
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
*/
function __construct($mode)
{
if ($mode == self::MODE_STREAM) {
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
}
parent::__construct($mode);
}
/**
* Test for engine validity
*
@ -308,15 +294,19 @@ class RC2 extends Base
*
* @access public
* @param int $length in bits
* @throws \LengthException if the key length isn't supported
*/
function setKeyLength($length)
{
if ($length < 8 || $length > 1024) {
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported');
if ($length < 8) {
$this->default_key_length = 8;
} elseif ($length > 1024) {
$this->default_key_length = 128;
} else {
$this->default_key_length = $length;
}
$this->current_key_length = $this->default_key_length;
$this->default_key_length = $this->current_key_length = $length;
parent::setKeyLength($length);
}
/**
@ -345,20 +335,16 @@ class RC2 extends Base
* @access public
* @param string $key
* @param int $t1 optional Effective key length in bits.
* @throws \LengthException if the key length isn't supported
*/
function setKey($key, $t1 = false)
function setKey($key, $t1 = 0)
{
$this->orig_key = $key;
if ($t1 === false) {
if ($t1 <= 0) {
$t1 = $this->default_key_length;
} elseif ($t1 > 1024) {
$t1 = 1024;
}
if ($t1 < 1 || $t1 > 1024) {
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported');
}
$this->current_key_length = $t1;
// Key byte count should be 1..128.
$key = strlen($key) ? substr($key, 0, 128) : "\x00";

View File

@ -44,6 +44,8 @@
namespace phpseclib\Crypt;
use phpseclib\Crypt\Base;
/**
* Pure-PHP implementation of RC4.
*
@ -121,6 +123,8 @@ class RC4 extends Base
/**
* Default Constructor.
*
* Determines whether or not the mcrypt extension should be used.
*
* @see \phpseclib\Crypt\Base::__construct()
* @return \phpseclib\Crypt\RC4
* @access public
@ -163,14 +167,26 @@ class RC4 extends Base
}
/**
* RC4 does not use an IV
* Dummy function.
*
* Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].
* If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before
* calling setKey().
*
* [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol,
* the IV's are relatively easy to predict, an attack described by
* {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}
* can be used to quickly guess at the rest of the key. The following links elaborate:
*
* {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009}
* {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack}
*
* @param string $iv
* @see self::setKey()
* @access public
* @return bool
*/
function usesIV()
function setIV($iv)
{
return false;
}
/**
@ -180,38 +196,20 @@ class RC4 extends Base
*
* @access public
* @param int $length
* @throws \LengthException if the key length is invalid
*/
function setKeyLength($length)
{
if ($length < 8 || $length > 2048) {
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 256 bytes are supported');
if ($length < 8) {
$this->key_length = 1;
} elseif ($length > 2048) {
$this->key_length = 256;
} else {
$this->key_length = $length >> 3;
}
$this->key_length = $length >> 3;
parent::setKeyLength($length);
}
/**
* Sets the key length
*
* Keys can be between 1 and 256 bytes long.
*
* @access public
* @param int $length
* @throws \LengthException if the key length is invalid
*/
function setKey($key)
{
$length = strlen($key);
if ($length < 1 || $length > 256) {
throw new \LengthException('Key size of ' . $length . ' bytes is not supported by RC4. Keys must be between 1 and 256 bytes long');
}
parent::setKey($key);
}
/**
* Encrypts a message.
*

File diff suppressed because it is too large Load Diff

View File

@ -1,223 +0,0 @@
<?php
/**
* Miccrosoft BLOB Formatted RSA Key Handler
*
* More info:
*
* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375601(v=vs.85).aspx
*
* PHP version 5
*
* @category Crypt
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Crypt\RSA;
use phpseclib\Math\BigInteger;
/**
* Microsoft BLOB Formatted RSA Key Handler
*
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class MSBLOB
{
/**#@+
* @access private
*/
/**
* Public/Private Key Pair
*/
const PRIVATEKEYBLOB = 0x7;
/**
* Public Key
*/
const PUBLICKEYBLOB = 0x6;
/**
* Public Key
*/
const PUBLICKEYBLOBEX = 0xA;
/**
* RSA public key exchange algorithm
*/
const CALG_RSA_KEYX = 0x0000A400;
/**
* RSA public key exchange algorithm
*/
const CALG_RSA_SIGN = 0x00002400;
/**
* Public Key
*/
const RSA1 = 0x31415352;
/**
* Private Key
*/
const RSA2 = 0x32415352;
/**#@-*/
/**
* Break a public or private key down into its constituent components
*
* @access public
* @param string $key
* @param string $password optional
* @return array
*/
static function load($key, $password = '')
{
if (!is_string($key)) {
return false;
}
$key = base64_decode($key);
if (!is_string($key) || strlen($key) < 20) {
return false;
}
// PUBLICKEYSTRUC publickeystruc
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx
extract(unpack('atype/aversion/vreserved/Valgo', self::_string_shift($key, 8)));
switch (ord($type)) {
case self::PUBLICKEYBLOB:
case self::PUBLICKEYBLOBEX:
$publickey = true;
break;
case self::PRIVATEKEYBLOB:
$publickey = false;
break;
default:
return false;
}
$components = array('isPublicKey' => $publickey);
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx
switch ($algo) {
case self::CALG_RSA_KEYX:
case self::CALG_RSA_SIGN:
break;
default:
return false;
}
// RSAPUBKEY rsapubkey
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa387685(v=vs.85).aspx
// could do V for pubexp but that's unsigned 32-bit whereas some PHP installs only do signed 32-bit
extract(unpack('Vmagic/Vbitlen/a4pubexp', self::_string_shift($key, 12)));
switch ($magic) {
case self::RSA2:
$components['isPublicKey'] = false;
case self::RSA1:
break;
default:
return false;
}
$baseLength = $bitlen / 16;
if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) {
return false;
}
$components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256);
// BYTE modulus[rsapubkey.bitlen/8]
$components['modulus'] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 8)), 256);
if ($publickey) {
return $components;
}
$components['isPublicKey'] = false;
// BYTE prime1[rsapubkey.bitlen/16]
$components['primes'] = array(1 => new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256));
// BYTE prime2[rsapubkey.bitlen/16]
$components['primes'][] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256);
// BYTE exponent1[rsapubkey.bitlen/16]
$components['exponents'] = array(1 => new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256));
// BYTE exponent2[rsapubkey.bitlen/16]
$components['exponents'][] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256);
// BYTE coefficient[rsapubkey.bitlen/16]
$components['coefficients'] = array(2 => new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256));
if (isset($components['privateExponent'])) {
$components['publicExponent'] = $components['privateExponent'];
}
// BYTE privateExponent[rsapubkey.bitlen/8]
$components['privateExponent'] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 8)), 256);
return $components;
}
/**
* Convert a private key to the appropriate format.
*
* @access public
* @param \phpseclib\Math\BigInteger $n
* @param \phpseclib\Math\BigInteger $e
* @param \phpseclib\Math\BigInteger $d
* @param array $primes
* @param array $exponents
* @param array $coefficients
* @param string $password optional
* @return string
*/
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
{
$n = strrev($n->toBytes());
$e = str_pad(strrev($e->toBytes()), 4, "\0");
$key = pack('aavV', chr(self::PRIVATEKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX);
$key.= pack('VVa*', self::RSA2, 8 * strlen($n), $e);
$key.= $n;
$key.= strrev($primes[1]->toBytes());
$key.= strrev($primes[2]->toBytes());
$key.= strrev($exponents[1]->toBytes());
$key.= strrev($exponents[2]->toBytes());
$key.= strrev($coefficients[1]->toBytes());
$key.= strrev($d->toBytes());
return base64_encode($key);
}
/**
* Convert a public key to the appropriate format
*
* @access public
* @param \phpseclib\Math\BigInteger $n
* @param \phpseclib\Math\BigInteger $e
* @return string
*/
static function savePublicKey(BigInteger $n, BigInteger $e)
{
$n = strrev($n->toBytes());
$e = str_pad(strrev($e->toBytes()), 4, "\0");
$key = pack('aavV', chr(self::PUBLICKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX);
$key.= pack('VVa*', self::RSA1, 8 * strlen($n), $e);
$key.= $n;
return base64_encode($key);
}
/**
* String Shift
*
* Inspired by array_shift
*
* @param string $string
* @param int $index
* @return string
* @access private
*/
static function _string_shift(&$string, $index = 1)
{
$substr = substr($string, 0, $index);
$string = substr($string, $index);
return $substr;
}
}

View File

@ -1,140 +0,0 @@
<?php
/**
* OpenSSH Formatted RSA Key Handler
*
* PHP version 5
*
* Place in $HOME/.ssh/authorized_keys
*
* @category Crypt
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Crypt\RSA;
use phpseclib\Math\BigInteger;
/**
* OpenSSH Formatted RSA Key Handler
*
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class OpenSSH
{
/**
* Default comment
*
* @var string
* @access private
*/
static $comment = 'phpseclib-generated-key';
/**
* Sets the default comment
*
* @access public
* @param string $comment
*/
static function setComment($comment)
{
self::$comment = str_replace(array("\r", "\n"), '', $comment);
}
/**
* Break a public or private key down into its constituent components
*
* @access public
* @param string $key
* @param string $password optional
* @return array
*/
static function load($key, $password = '')
{
if (!is_string($key)) {
return false;
}
$parts = explode(' ', $key, 3);
$key = isset($parts[1]) ? base64_decode($parts[1]) : base64_decode($parts[0]);
if ($key === false) {
return false;
}
$comment = isset($parts[2]) ? $parts[2] : false;
if (substr($key, 0, 11) != "\0\0\0\7ssh-rsa") {
return false;
}
self::_string_shift($key, 11);
if (strlen($key) <= 4) {
return false;
}
extract(unpack('Nlength', self::_string_shift($key, 4)));
if (strlen($key) <= $length) {
return false;
}
$publicExponent = new BigInteger(self::_string_shift($key, $length), -256);
if (strlen($key) <= 4) {
return false;
}
extract(unpack('Nlength', self::_string_shift($key, 4)));
if (strlen($key) != $length) {
return false;
}
$modulus = new BigInteger(self::_string_shift($key, $length), -256);
return array(
'isPublicKey' => true,
'modulus' => $modulus,
'publicExponent' => $publicExponent,
'comment' => $comment
);
}
/**
* Convert a public key to the appropriate format
*
* @access public
* @param \phpseclib\Math\BigInteger $n
* @param \phpseclib\Math\BigInteger $e
* @return string
*/
static function savePublicKey(BigInteger $n, BigInteger $e)
{
$publicExponent = $e->toBytes(true);
$modulus = $n->toBytes(true);
// from <http://tools.ietf.org/html/rfc4253#page-15>:
// string "ssh-rsa"
// 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;
return $RSAPublicKey;
}
/**
* String Shift
*
* Inspired by array_shift
*
* @param string $string
* @param int $index
* @return string
* @access private
*/
static function _string_shift(&$string, $index = 1)
{
$substr = substr($string, 0, $index);
$string = substr($string, $index);
return $substr;
}
}

View File

@ -1,485 +0,0 @@
<?php
/**
* PKCS Formatted RSA Key Handler
*
* PHP version 5
*
* @category Crypt
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Crypt\RSA;
use phpseclib\Crypt\AES;
use phpseclib\Crypt\Base;
use phpseclib\Crypt\DES;
use phpseclib\Crypt\TripleDES;
use phpseclib\Math\BigInteger;
/**
* PKCS Formatted RSA Key Handler
*
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
abstract class PKCS
{
/**#@+
* @access private
* @see \phpseclib\Crypt\RSA::createKey()
*/
/**
* ASN1 Integer
*/
const ASN1_INTEGER = 2;
/**
* ASN1 Bit String
*/
const ASN1_BITSTRING = 3;
/**
* ASN1 Octet String
*/
const ASN1_OCTETSTRING = 4;
/**
* ASN1 Object Identifier
*/
const ASN1_OBJECT = 6;
/**
* ASN1 Sequence (with the constucted bit set)
*/
const ASN1_SEQUENCE = 48;
/**#@-*/
/**#@+
* @access private
*/
/**
* Auto-detect the format
*/
const MODE_ANY = 0;
/**
* Require base64-encoded PEM's be supplied
*/
const MODE_PEM = 1;
/**
* Require raw DER's be supplied
*/
const MODE_DER = 2;
/**#@-*/
/**
* Is the key a base-64 encoded PEM, DER or should it be auto-detected?
*
* @access private
* @param int
*/
static $format = self::MODE_ANY;
/**
* Returns the mode constant corresponding to the mode string
*
* @access public
* @param string $mode
* @return int
* @throws \UnexpectedValueException if the block cipher mode is unsupported
*/
static function getEncryptionMode($mode)
{
switch ($mode) {
case 'CBC':
return Base::MODE_CBC;
case 'ECB':
return Base::MODE_ECB;
case 'CFB':
return Base::MODE_CFB;
case 'OFB':
return Base::MODE_OFB;
case 'CTR':
return Base::MODE_CTR;
}
throw new \UnexpectedValueException('Unsupported block cipher mode of operation');
}
/**
* Returns a cipher object corresponding to a string
*
* @access public
* @param string $algo
* @return string
* @throws \UnexpectedValueException if the encryption algorithm is unsupported
*/
static function getEncryptionObject($algo)
{
$modes = '(CBC|ECB|CFB|OFB|CTR)';
switch (true) {
case preg_match("#^AES-(128|192|256)-$modes$#", $algo, $matches):
$cipher = new AES(self::getEncryptionMode($matches[2]));
$cipher->setKeyLength($matches[1]);
return $cipher;
case preg_match("#^DES-EDE3-$modes$#", $algo, $matches):
return new TripleDES(self::getEncryptionMode($matches[1]));
case preg_match("#^DES-$modes$#", $algo, $matches):
return new DES(self::getEncryptionMode($matches[1]));
default:
throw new \UnexpectedValueException('Unsupported encryption algorithmn');
}
}
/**
* Generate a symmetric key for PKCS#1 keys
*
* @access public
* @param string $password
* @param string $iv
* @param int $length
* @return string
*/
static function generateSymmetricKey($password, $iv, $length)
{
$symkey = '';
$iv = substr($iv, 0, 8);
while (strlen($symkey) < $length) {
$symkey.= pack('H*', md5($symkey . $password . $iv));
}
return substr($symkey, 0, $length);
}
/**
* Break a public or private key down into its constituent components
*
* @access public
* @param string $key
* @param string $password optional
* @return array
*/
static function load($key, $password = '')
{
if (!is_string($key)) {
return false;
}
$components = array('isPublicKey' => strpos($key, 'PUBLIC') !== false);
/* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is
"outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to
protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding
two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here:
http://tools.ietf.org/html/rfc1421#section-4.6.1.1
http://tools.ietf.org/html/rfc1421#section-4.6.1.3
DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell.
DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation
function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's
own implementation. ie. the implementation *is* the standard and any bugs that may exist in that
implementation are part of the standard, as well.
* 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]));
// 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);
if ($ciphertext === false) {
$ciphertext = $key;
}
$crypto = self::getEncryptionObject($matches[1]);
$crypto->setKey(self::generateSymmetricKey($password, $iv, $crypto->getKeyLength() >> 3));
$crypto->setIV($iv);
$key = $crypto->decrypt($ciphertext);
if ($key === false) {
return false;
}
} else {
if (self::$format != self::MODE_DER) {
$decoded = self::_extractBER($key);
if ($decoded !== false) {
$key = $decoded;
} elseif (self::$format == self::MODE_PEM) {
return false;
}
}
}
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
return false;
}
if (self::_decodeLength($key) != strlen($key)) {
return false;
}
$tag = ord(self::_string_shift($key));
/* intended for keys for which OpenSSL's asn1parse returns the following:
0:d=0 hl=4 l= 631 cons: SEQUENCE
4:d=1 hl=2 l= 1 prim: INTEGER :00
7:d=1 hl=2 l= 13 cons: SEQUENCE
9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
20:d=2 hl=2 l= 0 prim: NULL
22:d=1 hl=4 l= 609 prim: OCTET STRING
ie. PKCS8 keys */
if ($tag == self::ASN1_INTEGER && substr($key, 0, 3) == "\x01\x00\x30") {
self::_string_shift($key, 3);
$tag = self::ASN1_SEQUENCE;
}
if ($tag == self::ASN1_SEQUENCE) {
$temp = self::_string_shift($key, self::_decodeLength($key));
if (ord(self::_string_shift($temp)) != self::ASN1_OBJECT) {
return false;
}
$length = self::_decodeLength($temp);
switch (self::_string_shift($temp, $length)) {
case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption
break;
case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": // pbeWithMD5AndDES-CBC
/*
PBEParameter ::= SEQUENCE {
salt OCTET STRING (SIZE(8)),
iterationCount INTEGER }
*/
if (ord(self::_string_shift($temp)) != self::ASN1_SEQUENCE) {
return false;
}
if (self::_decodeLength($temp) != strlen($temp)) {
return false;
}
self::_string_shift($temp); // assume it's an octet string
$salt = self::_string_shift($temp, self::_decodeLength($temp));
if (ord(self::_string_shift($temp)) != self::ASN1_INTEGER) {
return false;
}
self::_decodeLength($temp);
list(, $iterationCount) = unpack('N', str_pad($temp, 4, chr(0), STR_PAD_LEFT));
self::_string_shift($key); // assume it's an octet string
$length = self::_decodeLength($key);
if (strlen($key) != $length) {
return false;
}
$crypto = new DES(DES::MODE_CBC);
$crypto->setPassword($password, 'pbkdf1', 'md5', $salt, $iterationCount);
$key = $crypto->decrypt($key);
if ($key === false) {
return false;
}
return self::load($key);
default:
return false;
}
/* intended for keys for which OpenSSL's asn1parse returns the following:
0:d=0 hl=4 l= 290 cons: SEQUENCE
4:d=1 hl=2 l= 13 cons: SEQUENCE
6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
17:d=2 hl=2 l= 0 prim: NULL
19:d=1 hl=4 l= 271 prim: BIT STRING */
$tag = ord(self::_string_shift($key)); // skip over the BIT STRING / OCTET STRING tag
self::_decodeLength($key); // skip over the BIT STRING / OCTET STRING length
// "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, 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 (section 8.6.2.2)
if ($tag == self::ASN1_BITSTRING) {
self::_string_shift($key);
}
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
return false;
}
if (self::_decodeLength($key) != strlen($key)) {
return false;
}
$tag = ord(self::_string_shift($key));
}
if ($tag != self::ASN1_INTEGER) {
return false;
}
$length = self::_decodeLength($key);
$temp = self::_string_shift($key, $length);
if (strlen($temp) != 1 || ord($temp) > 2) {
$components['modulus'] = new BigInteger($temp, 256);
self::_string_shift($key); // skip over self::ASN1_INTEGER
$length = self::_decodeLength($key);
$components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(self::_string_shift($key, $length), 256);
return $components;
}
if (ord(self::_string_shift($key)) != self::ASN1_INTEGER) {
return false;
}
$length = self::_decodeLength($key);
$components['modulus'] = new BigInteger(self::_string_shift($key, $length), 256);
self::_string_shift($key);
$length = self::_decodeLength($key);
$components['publicExponent'] = new BigInteger(self::_string_shift($key, $length), 256);
self::_string_shift($key);
$length = self::_decodeLength($key);
$components['privateExponent'] = new BigInteger(self::_string_shift($key, $length), 256);
self::_string_shift($key);
$length = self::_decodeLength($key);
$components['primes'] = array(1 => new BigInteger(self::_string_shift($key, $length), 256));
self::_string_shift($key);
$length = self::_decodeLength($key);
$components['primes'][] = new BigInteger(self::_string_shift($key, $length), 256);
self::_string_shift($key);
$length = self::_decodeLength($key);
$components['exponents'] = array(1 => new BigInteger(self::_string_shift($key, $length), 256));
self::_string_shift($key);
$length = self::_decodeLength($key);
$components['exponents'][] = new BigInteger(self::_string_shift($key, $length), 256);
self::_string_shift($key);
$length = self::_decodeLength($key);
$components['coefficients'] = array(2 => new BigInteger(self::_string_shift($key, $length), 256));
if (!empty($key)) {
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
return false;
}
self::_decodeLength($key);
while (!empty($key)) {
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
return false;
}
self::_decodeLength($key);
$key = substr($key, 1);
$length = self::_decodeLength($key);
$components['primes'][] = new BigInteger(self::_string_shift($key, $length), 256);
self::_string_shift($key);
$length = self::_decodeLength($key);
$components['exponents'][] = new BigInteger(self::_string_shift($key, $length), 256);
self::_string_shift($key);
$length = self::_decodeLength($key);
$components['coefficients'][] = new BigInteger(self::_string_shift($key, $length), 256);
}
}
return $components;
}
/**
* Require base64-encoded PEM's be supplied
*
* @see self::load()
* @access public
*/
static function requirePEM()
{
self::$format = self::MODE_PEM;
}
/**
* Require raw DER's be supplied
*
* @see self::load()
* @access public
*/
static function requireDER()
{
self::$format = self::MODE_DER;
}
/**
* Accept any format and auto detect the format
*
* This is the default setting
*
* @see self::load()
* @access public
*/
static function requireAny()
{
self::$format = self::MODE_ANY;
}
/**
* DER-decode the length
*
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
*
* @access private
* @param string $string
* @return int
*/
static function _decodeLength(&$string)
{
$length = ord(self::_string_shift($string));
if ($length & 0x80) { // definite length, long form
$length&= 0x7F;
$temp = self::_string_shift($string, $length);
list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
}
return $length;
}
/**
* DER-encode the length
*
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
*
* @access private
* @param int $length
* @return string
*/
static function _encodeLength($length)
{
if ($length <= 0x7F) {
return chr($length);
}
$temp = ltrim(pack('N', $length), chr(0));
return pack('Ca*', 0x80 | strlen($temp), $temp);
}
/**
* String Shift
*
* Inspired by array_shift
*
* @param string $string
* @param int $index
* @return string
* @access private
*/
static function _string_shift(&$string, $index = 1)
{
$substr = substr($string, 0, $index);
$string = substr($string, $index);
return $substr;
}
/**
* Extract raw BER from Base64 encoding
*
* @access private
* @param string $str
* @return string
*/
static function _extractBER($str)
{
/* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them
* above and beyond the ceritificate.
* ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line:
*
* Bag Attributes
* localKeyID: 01 00 00 00
* subject=/O=organization/OU=org unit/CN=common name
* issuer=/O=organization/CN=common name
*/
$temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1);
// remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
$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;
return $temp != false ? $temp : $str;
}
}

View File

@ -1,172 +0,0 @@
<?php
/**
* PKCS#1 Formatted RSA Key Handler
*
* PHP version 5
*
* Used by File/X509.php
*
* Has the following header:
*
* -----BEGIN RSA PUBLIC KEY-----
*
* Analogous to ssh-keygen's pem format (as specified by -m)
*
* @category Crypt
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Crypt\RSA;
use phpseclib\Crypt\AES;
use phpseclib\Crypt\DES;
use phpseclib\Crypt\Random;
use phpseclib\Crypt\TripleDES;
use phpseclib\Math\BigInteger;
/**
* PKCS#1 Formatted RSA Key Handler
*
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class PKCS1 extends PKCS
{
/**
* Default encryption algorithm
*
* @var string
* @access private
*/
static $defaultEncryptionAlgorithm = 'DES-EDE3-CBC';
/**
* Sets the default encryption algorithm
*
* @access public
* @param string $algo
*/
static function setEncryptionAlgorithm($algo)
{
self::$defaultEncryptionAlgorithm = $algo;
}
/**
* Convert a private key to the appropriate format.
*
* @access public
* @param \phpseclib\Math\BigInteger $n
* @param \phpseclib\Math\BigInteger $e
* @param \phpseclib\Math\BigInteger $d
* @param array $primes
* @param array $exponents
* @param array $coefficients
* @param string $password optional
* @return string
*/
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
{
$num_primes = count($primes);
$raw = array(
'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
'modulus' => $n->toBytes(true),
'publicExponent' => $e->toBytes(true),
'privateExponent' => $d->toBytes(true),
'prime1' => $primes[1]->toBytes(true),
'prime2' => $primes[2]->toBytes(true),
'exponent1' => $exponents[1]->toBytes(true),
'exponent2' => $exponents[2]->toBytes(true),
'coefficient' => $coefficients[2]->toBytes(true)
);
$components = array();
foreach ($raw as $name => $value) {
$components[$name] = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($value)), $value);
}
$RSAPrivateKey = implode('', $components);
if ($num_primes > 2) {
$OtherPrimeInfos = '';
for ($i = 3; $i <= $num_primes; $i++) {
// OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
//
// OtherPrimeInfo ::= SEQUENCE {
// prime INTEGER, -- ri
// exponent INTEGER, -- di
// coefficient INTEGER -- ti
// }
$OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
$OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
}
$RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
}
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
if (!empty($password) || is_string($password)) {
$cipher = self::getEncryptionObject(self::$defaultEncryptionAlgorithm);
$iv = Random::string($cipher->getBlockLength() >> 3);
$cipher->setKey(self::generateSymmetricKey($password, $iv, $cipher->getKeyLength() >> 3));
$cipher->setIV($iv);
$iv = strtoupper(bin2hex($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) .
'-----END RSA PRIVATE KEY-----';
} else {
$RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
chunk_split(base64_encode($RSAPrivateKey), 64) .
'-----END RSA PRIVATE KEY-----';
}
return $RSAPrivateKey;
}
/**
* Convert a public key to the appropriate format
*
* @access public
* @param \phpseclib\Math\BigInteger $n
* @param \phpseclib\Math\BigInteger $e
* @return string
*/
static function savePublicKey(BigInteger $n, BigInteger $e)
{
$modulus = $n->toBytes(true);
$publicExponent = $e->toBytes(true);
// from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
// RSAPublicKey ::= SEQUENCE {
// modulus INTEGER, -- n
// publicExponent INTEGER -- e
// }
$components = array(
'modulus' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($modulus)), $modulus),
'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($publicExponent)), $publicExponent)
);
$RSAPublicKey = pack(
'Ca*a*a*',
self::ASN1_SEQUENCE,
self::_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
$components['modulus'],
$components['publicExponent']
);
$RSAPublicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" .
chunk_split(base64_encode($RSAPublicKey), 64) .
'-----END RSA PUBLIC KEY-----';
return $RSAPublicKey;
}
}

View File

@ -1,208 +0,0 @@
<?php
/**
* PKCS#8 Formatted RSA Key Handler
*
* PHP version 5
*
* Used by PHP's openssl_public_encrypt() and openssl's rsautl (when -pubin is set)
*
* Has the following header:
*
* -----BEGIN PUBLIC KEY-----
*
* Analogous to ssh-keygen's pkcs8 format (as specified by -m). Although PKCS8
* is specific to private keys it's basically creating a DER-encoded wrapper
* for keys. This just extends that same concept to public keys (much like ssh-keygen)
*
* @category Crypt
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Crypt\RSA;
use phpseclib\Crypt\DES;
use phpseclib\Crypt\Random;
use phpseclib\Math\BigInteger;
/**
* PKCS#8 Formatted RSA Key Handler
*
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class PKCS8 extends PKCS
{
/**
* Convert a private key to the appropriate format.
*
* @access public
* @param \phpseclib\Math\BigInteger $n
* @param \phpseclib\Math\BigInteger $e
* @param \phpseclib\Math\BigInteger $d
* @param array $primes
* @param array $exponents
* @param array $coefficients
* @param string $password optional
* @return string
*/
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
{
$num_primes = count($primes);
$raw = array(
'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
'modulus' => $n->toBytes(true),
'publicExponent' => $e->toBytes(true),
'privateExponent' => $d->toBytes(true),
'prime1' => $primes[1]->toBytes(true),
'prime2' => $primes[2]->toBytes(true),
'exponent1' => $exponents[1]->toBytes(true),
'exponent2' => $exponents[2]->toBytes(true),
'coefficient' => $coefficients[2]->toBytes(true)
);
$components = array();
foreach ($raw as $name => $value) {
$components[$name] = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($value)), $value);
}
$RSAPrivateKey = implode('', $components);
if ($num_primes > 2) {
$OtherPrimeInfos = '';
for ($i = 3; $i <= $num_primes; $i++) {
// OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
//
// OtherPrimeInfo ::= SEQUENCE {
// prime INTEGER, -- ri
// exponent INTEGER, -- di
// coefficient INTEGER -- ti
// }
$OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
$OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
}
$RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
}
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
$rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
$RSAPrivateKey = pack(
'Ca*a*Ca*a*',
self::ASN1_INTEGER,
"\01\00",
$rsaOID,
4,
self::_encodeLength(strlen($RSAPrivateKey)),
$RSAPrivateKey
);
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
if (!empty($password) || is_string($password)) {
$salt = Random::string(8);
$iterationCount = 2048;
$crypto = new DES(DES::MODE_CBC);
$crypto->setPassword($password, 'pbkdf1', 'md5', $salt, $iterationCount);
$RSAPrivateKey = $crypto->encrypt($RSAPrivateKey);
$parameters = pack(
'Ca*a*Ca*N',
self::ASN1_OCTETSTRING,
self::_encodeLength(strlen($salt)),
$salt,
self::ASN1_INTEGER,
self::_encodeLength(4),
$iterationCount
);
$pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03";
$encryptionAlgorithm = pack(
'Ca*a*Ca*a*',
self::ASN1_OBJECT,
self::_encodeLength(strlen($pbeWithMD5AndDES_CBC)),
$pbeWithMD5AndDES_CBC,
self::ASN1_SEQUENCE,
self::_encodeLength(strlen($parameters)),
$parameters
);
$RSAPrivateKey = pack(
'Ca*a*Ca*a*',
self::ASN1_SEQUENCE,
self::_encodeLength(strlen($encryptionAlgorithm)),
$encryptionAlgorithm,
self::ASN1_OCTETSTRING,
self::_encodeLength(strlen($RSAPrivateKey)),
$RSAPrivateKey
);
$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) .
'-----END ENCRYPTED PRIVATE KEY-----';
} else {
$RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" .
chunk_split(base64_encode($RSAPrivateKey), 64) .
'-----END PRIVATE KEY-----';
}
return $RSAPrivateKey;
}
/**
* Convert a public key to the appropriate format
*
* @access public
* @param \phpseclib\Math\BigInteger $n
* @param \phpseclib\Math\BigInteger $e
* @return string
*/
static function savePublicKey(BigInteger $n, BigInteger $e)
{
$modulus = $n->toBytes(true);
$publicExponent = $e->toBytes(true);
// from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
// RSAPublicKey ::= SEQUENCE {
// modulus INTEGER, -- n
// publicExponent INTEGER -- e
// }
$components = array(
'modulus' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($modulus)), $modulus),
'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($publicExponent)), $publicExponent)
);
$RSAPublicKey = pack(
'Ca*a*a*',
self::ASN1_SEQUENCE,
self::_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
$components['modulus'],
$components['publicExponent']
);
// sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
$rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
$RSAPublicKey = chr(0) . $RSAPublicKey;
$RSAPublicKey = chr(3) . self::_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
$RSAPublicKey = pack(
'Ca*a*',
self::ASN1_SEQUENCE,
self::_encodeLength(strlen($rsaOID . $RSAPublicKey)),
$rsaOID . $RSAPublicKey
);
$RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
chunk_split(base64_encode($RSAPublicKey), 64) .
'-----END PUBLIC KEY-----';
return $RSAPublicKey;
}
}

View File

@ -1,311 +0,0 @@
<?php
/**
* PuTTY Formatted RSA Key Handler
*
* PHP version 5
*
* @category Crypt
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Crypt\RSA;
use phpseclib\Crypt\AES;
use phpseclib\Crypt\Hash;
use phpseclib\Math\BigInteger;
/**
* PuTTY Formatted RSA Key Handler
*
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class PuTTY
{
/**
* Default comment
*
* @var string
* @access private
*/
static $comment = 'phpseclib-generated-key';
/**
* Sets the default comment
*
* @access public
* @param string $comment
*/
static function setComment($comment)
{
self::$comment = str_replace(array("\r", "\n"), '', $comment);
}
/**
* Generate a symmetric key for PuTTY keys
*
* @access public
* @param string $password
* @param string $iv
* @param int $length
* @return string
*/
static function generateSymmetricKey($password, $length)
{
$symkey = '';
$sequence = 0;
while (strlen($symkey) < $length) {
$temp = pack('Na*', $sequence++, $password);
$symkey.= pack('H*', sha1($temp));
}
return substr($symkey, 0, $length);
}
/**
* Break a public or private key down into its constituent components
*
* @access public
* @param string $key
* @param string $password optional
* @return array
*/
static function load($key, $password = '')
{
if (!is_string($key)) {
return false;
}
static $one;
if (!isset($one)) {
$one = new BigInteger(1);
}
if (strpos($key, 'BEGIN SSH2 PUBLIC KEY')) {
$data = preg_split('#[\r\n]+#', $key);
$data = array_splice($data, 2, -1);
$data = implode('', $data);
$components = OpenSSH::load($data);
if ($components === false) {
return false;
}
if (!preg_match('#Comment: "(.+)"#', $key, $matches)) {
return false;
}
$components['comment'] = str_replace(array('\\\\', '\"'), array('\\', '"'), $matches[1]);
return $components;
}
$components = array('isPublicKey' => false);
$key = preg_split('#\r\n|\r|\n#', $key);
$type = trim(preg_replace('#PuTTY-User-Key-File-2: (.+)#', '$1', $key[0]));
if ($type != 'ssh-rsa') {
return false;
}
$encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1]));
$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 = substr($public, 11);
extract(unpack('Nlength', self::_string_shift($public, 4)));
$components['publicExponent'] = new BigInteger(self::_string_shift($public, $length), -256);
extract(unpack('Nlength', self::_string_shift($public, 4)));
$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))));
switch ($encryption) {
case 'aes256-cbc':
$symkey = static::generateSymmetricKey($password, 32);
$crypto = new AES(AES::MODE_CBC);
}
if ($encryption != 'none') {
$crypto->setKey($symkey);
$crypto->setIV(str_repeat("\0", $crypto->getBlockLength() >> 3));
$crypto->disablePadding();
$private = $crypto->decrypt($private);
if ($private === false) {
return false;
}
}
extract(unpack('Nlength', self::_string_shift($private, 4)));
if (strlen($private) < $length) {
return false;
}
$components['privateExponent'] = new BigInteger(self::_string_shift($private, $length), -256);
extract(unpack('Nlength', self::_string_shift($private, 4)));
if (strlen($private) < $length) {
return false;
}
$components['primes'] = array(1 => new BigInteger(self::_string_shift($private, $length), -256));
extract(unpack('Nlength', self::_string_shift($private, 4)));
if (strlen($private) < $length) {
return false;
}
$components['primes'][] = new BigInteger(self::_string_shift($private, $length), -256);
$temp = $components['primes'][1]->subtract($one);
$components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
$temp = $components['primes'][2]->subtract($one);
$components['exponents'][] = $components['publicExponent']->modInverse($temp);
extract(unpack('Nlength', self::_string_shift($private, 4)));
if (strlen($private) < $length) {
return false;
}
$components['coefficients'] = array(2 => new BigInteger(self::_string_shift($private, $length), -256));
return $components;
}
/**
* String Shift
*
* Inspired by array_shift
*
* @param string $string
* @param int $index
* @return string
* @access private
*/
static function _string_shift(&$string, $index = 1)
{
$substr = substr($string, 0, $index);
$string = substr($string, $index);
return $substr;
}
/**
* Convert a private key to the appropriate format.
*
* @access public
* @param \phpseclib\Math\BigInteger $n
* @param \phpseclib\Math\BigInteger $e
* @param \phpseclib\Math\BigInteger $d
* @param array $primes
* @param array $exponents
* @param array $coefficients
* @param string $password optional
* @return string
*/
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
{
if (count($primes) != 2) {
return false;
}
$raw = array(
'modulus' => $n->toBytes(true),
'publicExponent' => $e->toBytes(true),
'privateExponent' => $d->toBytes(true),
'prime1' => $primes[1]->toBytes(true),
'prime2' => $primes[2]->toBytes(true),
'exponent1' => $exponents[1]->toBytes(true),
'exponent2' => $exponents[2]->toBytes(true),
'coefficient' => $coefficients[2]->toBytes(true)
);
$key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: ";
$encryption = (!empty($password) || is_string($password)) ? 'aes256-cbc' : 'none';
$key.= $encryption;
$key.= "\r\nComment: " . self::$comment . "\r\n";
$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(self::$comment),
self::$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']
);
if (empty($password) && !is_string($password)) {
$source.= pack('Na*', strlen($private), $private);
$hashkey = 'putty-private-key-file-mac-key';
} else {
$private.= Random::string(16 - (strlen($private) & 15));
$source.= pack('Na*', strlen($private), $private);
$crypto = new AES();
$crypto->setKey(static::generateSymmetricKey($password, 32));
$crypto->setIV(str_repeat("\0", $crypto->getBlockLength() >> 3));
$crypto->disablePadding();
$private = $crypto->encrypt($private);
$hashkey = 'putty-private-key-file-mac-key' . $password;
}
$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";
return $key;
}
/**
* Convert a public key to the appropriate format
*
* @access public
* @param \phpseclib\Math\BigInteger $n
* @param \phpseclib\Math\BigInteger $e
* @return string
*/
static function savePublicKey(BigInteger $n, BigInteger $e)
{
$n = $n->toBytes(true);
$e = $e->toBytes(true);
$key = pack(
'Na*Na*Na*',
strlen('ssh-rsa'),
'ssh-rsa',
strlen($e),
$e,
strlen($n),
$n
);
$key = "---- BEGIN SSH2 PUBLIC KEY ----\r\n" .
'Comment: "' . str_replace(array('\\', '"'), array('\\\\', '\"'), self::$comment) . "\"\r\n";
chunk_split(base64_encode($key), 64) .
'---- END SSH2 PUBLIC KEY ----';
return $key;
}
}

View File

@ -1,103 +0,0 @@
<?php
/**
* Raw RSA Key Handler
*
* PHP version 5
*
* An array containing two \phpseclib\Math\BigInteger objects.
*
* The exponent can be indexed with any of the following:
*
* 0, e, exponent, publicExponent
*
* The modulus can be indexed with any of the following:
*
* 1, n, modulo, modulus
*
* @category Crypt
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Crypt\RSA;
use phpseclib\Math\BigInteger;
/**
* Raw RSA Key Handler
*
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Raw
{
/**
* Break a public or private key down into its constituent components
*
* @access public
* @param string $key
* @param string $password optional
* @return array
*/
static function load($key, $password = '')
{
if (!is_array($key)) {
return false;
}
if (isset($key['isPublicKey']) && isset($key['modulus'])) {
if (isset($key['privateExponent']) || isset($key['publicExponent'])) {
if (!isset($key['primes'])) {
return $key;
}
if (isset($key['exponents']) && isset($key['coefficients']) && isset($key['publicExponent']) && isset($key['privateExponent'])) {
return $key;
}
}
}
$components = array('isPublicKey' => true);
switch (true) {
case isset($key['e']):
$components['publicExponent'] = $key['e'];
break;
case isset($key['exponent']):
$components['publicExponent'] = $key['exponent'];
break;
case isset($key['publicExponent']):
$components['publicExponent'] = $key['publicExponent'];
break;
case isset($key[0]):
$components['publicExponent'] = $key[0];
}
switch (true) {
case isset($key['n']):
$components['modulus'] = $key['n'];
break;
case isset($key['modulo']):
$components['modulus'] = $key['modulo'];
break;
case isset($key['modulus']):
$components['modulus'] = $key['modulus'];
break;
case isset($key[1]):
$components['modulus'] = $key[1];
}
return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false;
}
/**
* Convert a public key to the appropriate format
*
* @access public
* @param \phpseclib\Math\BigInteger $n
* @param \phpseclib\Math\BigInteger $e
* @return string
*/
static function savePublicKey(BigInteger $n, BigInteger $e)
{
return array('e' => clone $e, 'n' => clone $n);
}
}

View File

@ -1,146 +0,0 @@
<?php
/**
* XML Formatted RSA Key Handler
*
* More info:
*
* http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
* http://en.wikipedia.org/wiki/XML_Signature
*
* PHP version 5
*
* @category Crypt
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Crypt\RSA;
use phpseclib\Math\BigInteger;
/**
* XML Formatted RSA Key Handler
*
* @package RSA
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class XML
{
/**
* Break a public or private key down into its constituent components
*
* @access public
* @param string $key
* @param string $password optional
* @return array
*/
static function load($key, $password = '')
{
if (!is_string($key)) {
return false;
}
$components = array(
'isPublicKey' => false,
'primes' => array(),
'exponents' => array(),
'coefficients' => array()
);
$use_errors = libxml_use_internal_errors(true);
$dom = new \DOMDocument();
if (!$dom->loadXML('<xml>' . $key . '</xml>')) {
return false;
}
$xpath = new \DOMXPath($dom);
$keys = array('modulus', 'exponent', 'p', 'q', 'dp', 'dq', 'inverseq', 'd');
foreach ($keys as $key) {
// $dom->getElementsByTagName($key) is case-sensitive
$temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']");
if (!$temp->length) {
continue;
}
$value = new BigInteger(base64_decode($temp->item(0)->nodeValue), 256);
switch ($key) {
case 'modulus':
$components['modulus'] = $value;
break;
case 'exponent':
$components['publicExponent'] = $value;
break;
case 'p':
$components['primes'][1] = $value;
break;
case 'q':
$components['primes'][2] = $value;
break;
case 'dp':
$components['exponents'][1] = $value;
break;
case 'dq':
$components['exponents'][2] = $value;
break;
case 'inverseq':
$components['coefficients'][2] = $value;
break;
case 'd':
$components['privateExponent'] = $value;
}
}
libxml_use_internal_errors($use_errors);
return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false;
}
/**
* Convert a private key to the appropriate format.
*
* @access public
* @param \phpseclib\Math\BigInteger $n
* @param \phpseclib\Math\BigInteger $e
* @param \phpseclib\Math\BigInteger $d
* @param array $primes
* @param array $exponents
* @param array $coefficients
* @param string $password optional
* @return string
*/
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
{
if (count($primes) != 2) {
return false;
}
return "<RSAKeyValue>\r\n" .
' <Modulus>' . base64_encode($n->toBytes()) . "</Modulus>\r\n" .
' <Exponent>' . base64_encode($e->toBytes()) . "</Exponent>\r\n" .
' <P>' . base64_encode($primes[1]->toBytes()) . "</P>\r\n" .
' <Q>' . base64_encode($primes[2]->toBytes()) . "</Q>\r\n" .
' <DP>' . base64_encode($exponents[1]->toBytes()) . "</DP>\r\n" .
' <DQ>' . base64_encode($exponents[2]->toBytes()) . "</DQ>\r\n" .
' <InverseQ>' . base64_encode($coefficients[2]->toBytes()) . "</InverseQ>\r\n" .
' <D>' . base64_encode($d->toBytes()) . "</D>\r\n" .
'</RSAKeyValue>';
}
/**
* Convert a public key to the appropriate format
*
* @access public
* @param \phpseclib\Math\BigInteger $n
* @param \phpseclib\Math\BigInteger $e
* @return string
*/
static function savePublicKey(BigInteger $n, BigInteger $e)
{
return "<RSAKeyValue>\r\n" .
' <Modulus>' . base64_encode($n->toBytes()) . "</Modulus>\r\n" .
' <Exponent>' . base64_encode($e->toBytes()) . "</Exponent>\r\n" .
'</RSAKeyValue>';
}
}

View File

@ -24,6 +24,14 @@
namespace phpseclib\Crypt;
use phpseclib\Crypt\AES;
use phpseclib\Crypt\Base;
use phpseclib\Crypt\Blowfish;
use phpseclib\Crypt\DES;
use phpseclib\Crypt\RC4;
use phpseclib\Crypt\TripleDES;
use phpseclib\Crypt\Twofish;
/**
* Pure-PHP Random Number Generator
*
@ -41,22 +49,68 @@ class Random
* eg. for RSA key generation.
*
* @param int $length
* @throws \RuntimeException if a symmetric cipher is needed but not loaded
* @return string
*/
static function string($length)
{
try {
return \random_bytes($length);
} catch (\Exception $e) {
// random_compat will throw an Exception, which in PHP 5 does not implement Throwable
} catch (\Throwable $e) {
// If a sufficient source of randomness is unavailable, random_bytes() will throw an
// object that implements the Throwable interface (Exception, TypeError, Error).
// We don't actually need to do anything here. The string() method should just continue
// as normal. Note, however, that if we don't have a sufficient source of randomness for
// random_bytes(), most of the other calls here will fail too, so we'll end up using
// the PHP implementation.
if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
try {
return \random_bytes($length);
} catch (\Throwable $e) {
// If a sufficient source of randomness is unavailable, random_bytes() will throw an
// object that implements the Throwable interface (Exception, TypeError, Error).
// We don't actually need to do anything here. The string() method should just continue
// as normal. Note, however, that if we don't have a sufficient source of randomness for
// random_bytes(), most of the other calls here will fail too, so we'll end up using
// the PHP implementation.
}
}
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
// method 1. prior to PHP 5.3 this would call rand() on windows hence the function_exists('class_alias') call.
// ie. class_alias is a function that was introduced in PHP 5.3
if (extension_loaded('mcrypt') && function_exists('class_alias')) {
return mcrypt_create_iv($length);
}
// method 2. openssl_random_pseudo_bytes was introduced in PHP 5.3.0 but prior to PHP 5.3.4 there was,
// to quote <http://php.net/ChangeLog-5.php#5.3.4>, "possible blocking behavior". as of 5.3.4
// openssl_random_pseudo_bytes and mcrypt_create_iv do the exact same thing on Windows. ie. they both
// call php_win32_get_random_bytes():
//
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/openssl/openssl.c#L5008
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1392
//
// php_win32_get_random_bytes() is defined thusly:
//
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/win32/winutil.c#L80
//
// we're calling it, all the same, in the off chance that the mcrypt extension is not available
if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.4', '>=')) {
return openssl_random_pseudo_bytes($length);
}
} else {
// method 1. the fastest
if (extension_loaded('openssl')) {
return openssl_random_pseudo_bytes($length);
}
// method 2
static $fp = true;
if ($fp === true) {
// warning's will be output unles the error suppression operator is used. errors such as
// "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc.
$fp = @fopen('/dev/urandom', 'rb');
}
if ($fp !== true && $fp !== false) { // surprisingly faster than !is_bool() or is_resource()
return fread($fp, $length);
}
// method 3. pretty much does the same thing as method 2 per the following url:
// https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1391
// surprisingly slower than method 2. maybe that's because mcrypt_create_iv does a bunch of error checking that we're
// not doing. regardless, this'll only be called if this PHP script couldn't open /dev/urandom due to open_basedir
// restrictions or some such
if (extension_loaded('mcrypt')) {
return mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
}
}
// at this point we have no choice but to use a pure-PHP CSPRNG
@ -94,13 +148,13 @@ class Random
session_start();
$v = $seed = $_SESSION['seed'] = pack('H*', sha1(
(isset($_SERVER) ? self::safe_serialize($_SERVER) : '') .
(isset($_POST) ? self::safe_serialize($_POST) : '') .
(isset($_GET) ? self::safe_serialize($_GET) : '') .
(isset($_COOKIE) ? self::safe_serialize($_COOKIE) : '') .
self::safe_serialize($GLOBALS) .
self::safe_serialize($_SESSION) .
self::safe_serialize($_OLD_SESSION)
(isset($_SERVER) ? phpseclib_safe_serialize($_SERVER) : '') .
(isset($_POST) ? phpseclib_safe_serialize($_POST) : '') .
(isset($_GET) ? phpseclib_safe_serialize($_GET) : '') .
(isset($_COOKIE) ? phpseclib_safe_serialize($_COOKIE) : '') .
phpseclib_safe_serialize($GLOBALS) .
phpseclib_safe_serialize($_SESSION) .
phpseclib_safe_serialize($_OLD_SESSION)
));
if (!isset($_SESSION['count'])) {
$_SESSION['count'] = 0;
@ -158,7 +212,8 @@ class Random
$crypto = new RC4();
break;
default:
throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded');
user_error(__CLASS__ . ' requires at least one symmetric cipher be loaded');
return false;
}
$crypto->setKey($key);
@ -185,16 +240,19 @@ class Random
}
return substr($result, 0, $length);
}
}
if (!function_exists('phpseclib_safe_serialize')) {
/**
* Safely serialize variables
*
* If a class has a private __sleep() it'll emit a warning
* If a class has a private __sleep() method it'll give a fatal error on PHP 5.2 and earlier.
* PHP 5.3 will emit a warning.
*
* @param mixed $arr
* @access public
*/
function safe_serialize(&$arr)
function phpseclib_safe_serialize(&$arr)
{
if (is_object($arr)) {
return '';
@ -211,7 +269,7 @@ class Random
foreach (array_keys($arr) as $key) {
// do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage
if ($key !== '__phpseclib_marker') {
$safearr[$key] = self::safe_serialize($arr[$key]);
$safearr[$key] = phpseclib_safe_serialize($arr[$key]);
}
}
unset($arr['__phpseclib_marker']);

View File

@ -54,6 +54,8 @@
namespace phpseclib\Crypt;
use phpseclib\Crypt\Base;
/**
* Pure-PHP implementation of Rijndael.
*
@ -168,26 +170,11 @@ class Rijndael extends Base
*/
var $kl;
/**
* Default Constructor.
*
* @param int $mode
* @access public
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
*/
function __construct($mode)
{
if ($mode == self::MODE_STREAM) {
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
}
parent::__construct($mode);
}
/**
* Sets the key length.
*
* Valid key lengths are 128, 160, 192, 224, and 256.
* Valid key lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
* 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
*
* Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined
* and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to
@ -201,75 +188,49 @@ class Rijndael extends Base
* This results then in slower encryption.
*
* @access public
* @throws \LengthException if the key length is invalid
* @param int $length
*/
function setKeyLength($length)
{
switch ($length) {
case 128:
case 160:
case 192:
case 224:
case 256:
$this->key_length = $length >> 3;
switch (true) {
case $length <= 128:
$this->key_length = 16;
break;
case $length <= 160:
$this->key_length = 20;
break;
case $length <= 192:
$this->key_length = 24;
break;
case $length <= 224:
$this->key_length = 28;
break;
default:
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported');
$this->key_length = 32;
}
parent::setKeyLength($length);
}
/**
* Sets the key.
*
* Rijndael supports five different key lengths
*
* @see setKeyLength()
* @access public
* @param string $key
* @throws \LengthException if the key length isn't supported
*/
function setKey($key)
{
switch (strlen($key)) {
case 16:
case 20:
case 24:
case 28:
case 32:
break;
default:
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 20, 24, 28 or 32 are supported');
}
parent::setKey($key);
}
/**
* Sets the block length
*
* Valid block lengths are 128, 160, 192, 224, and 256.
* Valid block lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
* 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
*
* @access public
* @param int $length
*/
function setBlockLength($length)
{
switch ($length) {
case 128:
case 160:
case 192:
case 224:
case 256:
break;
default:
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported');
$length >>= 5;
if ($length > 8) {
$length = 8;
} elseif ($length < 4) {
$length = 4;
}
$this->Nb = $length >> 5;
$this->block_size = $length >> 3;
$this->Nb = $length;
$this->block_size = $length << 2;
$this->changed = true;
$this->_setEngine();
}

View File

@ -36,6 +36,9 @@
namespace phpseclib\Crypt;
use phpseclib\Crypt\Base;
use phpseclib\Crypt\DES;
/**
* Pure-PHP implementation of Triple DES.
*
@ -128,7 +131,7 @@ class TripleDES extends DES
/**
* Default Constructor.
*
* Determines whether or not the mcrypt or OpenSSL extensions should be used.
* Determines whether or not the mcrypt extension should be used.
*
* $mode could be:
*
@ -142,14 +145,16 @@ class TripleDES extends DES
*
* - \phpseclib\Crypt\Base::MODE_OFB
*
* - \phpseclib\Crypt\TripleDES::MODE_3CB
* - \phpseclib\Crypt\TripleDES::MODE_3CBC
*
* If not explicitly set, \phpseclib\Crypt\Base::MODE_CBC will be used.
*
* @see \phpseclib\Crypt\DES::__construct()
* @see \phpseclib\Crypt\Base::__construct()
* @param int $mode
* @access public
*/
function __construct($mode)
function __construct($mode = Base::MODE_CBC)
{
switch ($mode) {
// In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC
@ -198,9 +203,10 @@ class TripleDES extends DES
}
/**
* Sets the initialization vector.
* Sets the initialization vector. (optional)
*
* SetIV is not required when \phpseclib\Crypt\Base::MODE_ECB is being used.
* SetIV is not required when \phpseclib\Crypt\Base::MODE_ECB is being used. If not explicitly set, it'll be assumed
* to be all zero's.
*
* @see \phpseclib\Crypt\Base::setIV()
* @access public
@ -219,23 +225,24 @@ class TripleDES extends DES
/**
* Sets the key length.
*
* Valid key lengths are 128 and 192 bits.
*
* If you want to use a 64-bit key use DES.php
* Valid key lengths are 64, 128 and 192
*
* @see \phpseclib\Crypt\Base:setKeyLength()
* @access public
* @throws \LengthException if the key length is invalid
* @param int $length
*/
function setKeyLength($length)
{
switch ($length) {
case 128:
case 192:
$length >>= 3;
switch (true) {
case $length <= 8:
$this->key_length = 8;
break;
case $length <= 16:
$this->key_length = 16;
break;
default:
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128 or 192 bits are supported');
$this->key_length = 24;
}
parent::setKeyLength($length);
@ -244,38 +251,36 @@ class TripleDES extends DES
/**
* Sets the key.
*
* Triple DES can use 128-bit (eg. strlen($key) == 16) or 192-bit (eg. strlen($key) == 24) keys.
* Keys can be of any length. Triple DES, itself, can use 128-bit (eg. strlen($key) == 16) or
* 192-bit (eg. strlen($key) == 24) keys. This function pads and truncates $key as appropriate.
*
* DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
*
* If the key is not explicitly set, it'll be assumed to be all null bytes.
*
* @access public
* @see \phpseclib\Crypt\DES::setKey()
* @see \phpseclib\Crypt\Base::setKey()
* @throws \LengthException if the key length is invalid
* @param string $key
*/
function setKey($key)
{
if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) {
throw new \LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes');
$length = $this->explicit_key_length ? $this->key_length : strlen($key);
if ($length > 8) {
$key = str_pad(substr($key, 0, 24), 24, chr(0));
// if $key is between 64 and 128-bits, use the first 64-bits as the last, per this:
// http://php.net/function.mcrypt-encrypt#47973
$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
} else {
$key = str_pad($key, 8, chr(0));
}
parent::setKey($key);
switch (strlen($key)) {
case 16:
$key.= substr($key, 0, 8);
case 24:
break;
default:
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 24 are supported');
}
// copied from Base::setKey()
$this->key = $key;
$this->key_length = strlen($key);
$this->changed = true;
$this->_setEngine();
if ($this->mode_3cbc) {
// And in case of self::MODE_3CBC:
// if key <= 64bits we not need the 3 $des to work,
// because we will then act as regular DES-CBC with just a <= 64bit key.
// So only if the key > 64bits (> 8 bytes) we will call setKey() for the 3 $des.
if ($this->mode_3cbc && $length > 8) {
$this->des[0]->setKey(substr($key, 0, 8));
$this->des[1]->setKey(substr($key, 8, 8));
$this->des[2]->setKey(substr($key, 16, 8));

View File

@ -37,6 +37,8 @@
namespace phpseclib\Crypt;
use phpseclib\Crypt\Base;
/**
* Pure-PHP implementation of Twofish.
*
@ -368,22 +370,6 @@ class Twofish extends Base
*/
var $key_length = 16;
/**
* Default Constructor.
*
* @param int $mode
* @access public
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
*/
function __construct($mode)
{
if ($mode == self::MODE_STREAM) {
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
}
parent::__construct($mode);
}
/**
* Sets the key length.
*
@ -394,42 +380,20 @@ class Twofish extends Base
*/
function setKeyLength($length)
{
switch ($length) {
case 128:
case 192:
case 256:
switch (true) {
case $length <= 128:
$this->key_length = 16;
break;
case $length <= 192:
$this->key_length = 24;
break;
default:
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
$this->key_length = 32;
}
parent::setKeyLength($length);
}
/**
* Sets the key.
*
* Rijndael supports five different key lengths
*
* @see setKeyLength()
* @access public
* @param string $key
* @throws \LengthException if the key length isn't supported
*/
function setKey($key)
{
switch (strlen($key)) {
case 16:
case 24:
case 32:
break;
default:
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
}
parent::setKey($key);
}
/**
* Setup the key (expansion)
*

View File

@ -1,26 +0,0 @@
<?php
/**
* BadConfigurationException
*
* PHP version 5
*
* @category Exception
* @package BadConfigurationException
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Exception;
/**
* BadConfigurationException
*
* @package BadConfigurationException
* @author Jim Wigginton <terrafrost@php.net>
*/
class BadConfigurationException extends \RuntimeException
{
}

View File

@ -1,26 +0,0 @@
<?php
/**
* FileNotFoundException
*
* PHP version 5
*
* @category Exception
* @package FileNotFoundException
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Exception;
/**
* FileNotFoundException
*
* @package FileNotFoundException
* @author Jim Wigginton <terrafrost@php.net>
*/
class FileNotFoundException extends \RuntimeException
{
}

View File

@ -1,26 +0,0 @@
<?php
/**
* NoSupportedAlgorithmsException
*
* PHP version 5
*
* @category Exception
* @package NoSupportedAlgorithmsException
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Exception;
/**
* NoSupportedAlgorithmsException
*
* @package NoSupportedAlgorithmsException
* @author Jim Wigginton <terrafrost@php.net>
*/
class NoSupportedAlgorithmsException extends \RuntimeException
{
}

View File

@ -1,26 +0,0 @@
<?php
/**
* UnsupportedAlgorithmException
*
* PHP version 5
*
* @category Exception
* @package UnsupportedAlgorithmException
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
namespace phpseclib\Exception;
/**
* UnsupportedAlgorithmException
*
* @package UnsupportedAlgorithmException
* @author Jim Wigginton <terrafrost@php.net>
*/
class UnsupportedAlgorithmException extends \RuntimeException
{
}

View File

@ -793,7 +793,6 @@ class ASN1
* @param string $mapping
* @param int $idx
* @return string
* @throws \RuntimeException if the input has an error in it
* @access private
*/
function _encode_der($source, $mapping, $idx = null, $special = array())
@ -986,7 +985,7 @@ class ASN1
case self::TYPE_OBJECT_IDENTIFIER:
$oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids);
if ($oid === false) {
throw new \RuntimeException('Invalid OID');
user_error('Invalid OID');
return false;
}
$value = '';
@ -1039,7 +1038,7 @@ class ASN1
$filters = $filters[$part];
}
if ($filters === false) {
throw new \RuntimeException('No filters defined for ' . implode('/', $loc));
user_error('No filters defined for ' . implode('/', $loc));
return false;
}
return $this->_encode_der($source, $filters + $mapping, null, $special);
@ -1063,7 +1062,7 @@ class ASN1
$value = $source ? "\xFF" : "\x00";
break;
default:
throw new \RuntimeException('Mapping provides no type definition for ' . implode('/', $this->location));
user_error('Mapping provides no type definition for ' . implode('/', $this->location));
return false;
}

View File

@ -27,9 +27,9 @@
namespace phpseclib\File;
use phpseclib\Crypt\Hash;
use phpseclib\Crypt\Random;
use phpseclib\Crypt\RSA;
use phpseclib\Exception\UnsupportedAlgorithmException;
use phpseclib\Crypt\Random;
use phpseclib\File\ASN1;
use phpseclib\File\ASN1\Element;
use phpseclib\Math\BigInteger;
@ -1654,7 +1654,7 @@ class X509
$map = $this->_getMapping($id);
if (is_bool($map)) {
if (!$map) {
//user_error($id . ' is not a currently supported extension');
user_error($id . ' is not a currently supported extension');
unset($extensions[$i]);
}
} else {
@ -1727,7 +1727,7 @@ class X509
$id = $attributes[$i]['type'];
$map = $this->_getMapping($id);
if ($map === false) {
//user_error($id . ' is not a currently supported attribute', E_USER_NOTICE);
user_error($id . ' is not a currently supported attribute', E_USER_NOTICE);
unset($attributes[$i]);
} elseif (is_array($attributes[$i]['value'])) {
$values = &$attributes[$i]['value'];
@ -2120,8 +2120,7 @@ class X509
/**
* Validates a signature
*
* Returns true if the signature is verified and false if it is not correct.
* If the algorithms are unsupposed an exception is thrown.
* Returns true if the signature is verified, false if it is not correct or null on error
*
* @param string $publicKeyAlgorithm
* @param string $publicKey
@ -2129,15 +2128,14 @@ class X509
* @param string $signature
* @param string $signatureSubject
* @access private
* @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
* @return bool
* @return int
*/
function _validateSignature($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject)
{
switch ($publicKeyAlgorithm) {
case 'rsaEncryption':
$rsa = new RSA();
$rsa->load($publicKey);
$rsa->loadKey($publicKey);
switch ($signatureAlgorithm) {
case 'md2WithRSAEncryption':
@ -2148,16 +2146,17 @@ class X509
case 'sha384WithRSAEncryption':
case 'sha512WithRSAEncryption':
$rsa->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm));
if (!@$rsa->verify($signatureSubject, $signature, RSA::PADDING_PKCS1)) {
$rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
if (!@$rsa->verify($signatureSubject, $signature)) {
return false;
}
break;
default:
throw new UnsupportedAlgorithmException('Signature algorithm unsupported');
return null;
}
break;
default:
throw new UnsupportedAlgorithmException('Public key algorithm unsupported');
return null;
}
return true;
@ -2812,7 +2811,7 @@ class X509
switch ($keyinfo['algorithm']['algorithm']) {
case 'rsaEncryption':
$publicKey = new RSA();
$publicKey->load($key);
$publicKey->loadKey($key);
$publicKey->setPublicKey();
break;
default:
@ -2888,7 +2887,7 @@ class X509
switch ($algorithm) {
case 'rsaEncryption':
$this->publicKey = new RSA();
$this->publicKey->load($key);
$this->publicKey->loadKey($key);
$this->publicKey->setPublicKey();
break;
default:
@ -3011,7 +3010,7 @@ class X509
switch ($algorithm) {
case 'rsaEncryption':
$this->publicKey = new RSA();
$this->publicKey->load($key);
$this->publicKey->loadKey($key);
$this->publicKey->setPublicKey();
break;
default:
@ -3406,7 +3405,7 @@ class X509
$origPublicKey = $this->publicKey;
$class = get_class($this->privateKey);
$this->publicKey = new $class();
$this->publicKey->load($this->privateKey->getPublicKey());
$this->publicKey->loadKey($this->privateKey->getPublicKey());
$this->publicKey->setPublicKey();
if (!($publicKey = $this->_formatSubjectPublicKey())) {
return false;
@ -3464,7 +3463,7 @@ class X509
$origPublicKey = $this->publicKey;
$class = get_class($this->privateKey);
$this->publicKey = new $class();
$this->publicKey->load($this->privateKey->getPublicKey());
$this->publicKey->loadKey($this->privateKey->getPublicKey());
$this->publicKey->setPublicKey();
$publicKey = $this->_formatSubjectPublicKey();
if (!$publicKey) {
@ -3652,7 +3651,6 @@ class X509
* @param \phpseclib\File\X509 $subject
* @param string $signatureAlgorithm
* @access public
* @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
* @return mixed
*/
function _sign($key, $signatureAlgorithm)
@ -3667,15 +3665,14 @@ class X509
case 'sha384WithRSAEncryption':
case 'sha512WithRSAEncryption':
$key->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm));
$key->setSignatureMode(RSA::SIGNATURE_PKCS1);
$this->currentCert['signature'] = base64_encode("\0" . $key->sign($this->signatureSubject, RSA::PADDING_PKCS1));
$this->currentCert['signature'] = base64_encode("\0" . $key->sign($this->signatureSubject));
return $this->currentCert;
default:
throw new UnsupportedAlgorithmException('Signature algorithm unsupported');
}
}
throw new UnsupportedAlgorithmException('Unsupported public key algorithm');
return false;
}
/**
@ -4232,7 +4229,7 @@ class X509
$raw = base64_decode($raw);
// If the key is private, compute identifier from its corresponding public key.
$key = new RSA();
if (!$key->load($raw)) {
if (!$key->loadKey($raw)) {
return false; // Not an unencrypted RSA key.
}
if ($key->getPrivateKey() !== false) { // If private.
@ -4252,7 +4249,7 @@ class X509
}
return false;
default: // Should be a key object (i.e.: \phpseclib\Crypt\RSA).
$key = $key->getPublicKey('PKCS1');
$key = $key->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1);
break;
}
@ -4285,7 +4282,7 @@ class X509
//return new Element(base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->getPublicKey())));
return array(
'algorithm' => array('algorithm' => 'rsaEncryption'),
'subjectPublicKey' => $this->publicKey->getPublicKey('PKCS1')
'subjectPublicKey' => $this->publicKey->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1)
);
}

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,8 @@
namespace phpseclib\Net;
use phpseclib\Exception\FileNotFoundException;
use phpseclib\Net\SSH1;
use phpseclib\Net\SSH2;
/**
* Pure-PHP implementations of SCP.
@ -139,7 +140,6 @@ class SCP
* @param string $data
* @param int $mode
* @param callable $callback
* @throws \phpseclib\Exception\FileNotFoundException if you're uploading via a file and the file doesn't exist
* @return bool
* @access public
*/
@ -168,7 +168,8 @@ class SCP
$size = strlen($data);
} else {
if (!is_file($data)) {
throw new FileNotFoundException("$data is not a valid file");
user_error("$data is not a valid file", E_USER_NOTICE);
return false;
}
$fp = @fopen($data, 'rb');
@ -288,7 +289,6 @@ class SCP
* Receives a packet from an SSH server
*
* @return string
* @throws \UnexpectedValueException on receipt of an unexpected packet
* @access private
*/
function _receive()
@ -314,7 +314,8 @@ class SCP
$this->ssh->bitmap = 0;
return false;
default:
throw new \UnexpectedValueException('Unknown packet received');
user_error('Unknown packet received', E_USER_NOTICE);
return false;
}
}
}

View File

@ -37,7 +37,7 @@
namespace phpseclib\Net;
use phpseclib\Exception\FileNotFoundException;
use phpseclib\Net\SSH2;
/**
* Pure-PHP implementations of SFTP.
@ -383,7 +383,6 @@ class SFTP extends SSH2
*
* @param string $username
* @param string $password
* @throws \UnexpectedValueException on receipt of unexpected packets
* @return bool
* @access public
*/
@ -471,7 +470,8 @@ class SFTP extends SSH2
$response = $this->_get_sftp_packet();
if ($this->packet_type != NET_SFTP_VERSION) {
throw new \UnexpectedValueException('Expected SSH_FXP_VERSION');
user_error('Expected SSH_FXP_VERSION');
return false;
}
extract(unpack('Nversion', $this->_string_shift($response, 4)));
@ -610,7 +610,6 @@ class SFTP extends SSH2
*
* @see self::chdir()
* @param string $path
* @throws \UnexpectedValueException on receipt of unexpected packets
* @return mixed
* @access private
*/
@ -635,7 +634,8 @@ class SFTP extends SSH2
$this->_logError($response);
return false;
default:
throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
return false;
}
}
@ -666,7 +666,6 @@ class SFTP extends SSH2
* Changes the current directory
*
* @param string $dir
* @throws \UnexpectedValueException on receipt of unexpected packets
* @return bool
* @access public
*/
@ -711,7 +710,8 @@ class SFTP extends SSH2
$this->_logError($response);
return false;
default:
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
return false;
}
if (!$this->_close_handle($handle)) {
@ -813,7 +813,6 @@ class SFTP extends SSH2
* @param string $dir
* @param bool $raw
* @return mixed
* @throws \UnexpectedValueException on receipt of unexpected packets
* @access private
*/
function _list($dir, $raw = true)
@ -845,7 +844,8 @@ class SFTP extends SSH2
$this->_logError($response);
return false;
default:
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
return false;
}
$this->_update_stat_cache($dir, array());
@ -899,7 +899,8 @@ class SFTP extends SSH2
}
break 2;
default:
throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
return false;
}
}
@ -1258,7 +1259,6 @@ class SFTP extends SSH2
*
* @param string $filename
* @param int $type
* @throws \UnexpectedValueException on receipt of unexpected packets
* @return mixed
* @access private
*/
@ -1279,7 +1279,8 @@ class SFTP extends SSH2
return false;
}
throw new \UnexpectedValueException('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
return false;
}
/**
@ -1305,7 +1306,6 @@ class SFTP extends SSH2
* @param string $filename
* @param int $time
* @param int $atime
* @throws \UnexpectedValueException on receipt of unexpected packets
* @return bool
* @access public
*/
@ -1342,7 +1342,8 @@ class SFTP extends SSH2
$this->_logError($response);
break;
default:
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
return false;
}
return $this->_setstat($filename, $attr, false);
@ -1395,7 +1396,6 @@ class SFTP extends SSH2
* @param int $mode
* @param string $filename
* @param bool $recursive
* @throws \UnexpectedValueException on receipt of unexpected packets
* @return mixed
* @access public
*/
@ -1434,7 +1434,8 @@ class SFTP extends SSH2
return false;
}
throw new \UnexpectedValueException('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
return false;
}
/**
@ -1443,7 +1444,6 @@ class SFTP extends SSH2
* @param string $filename
* @param string $attr
* @param bool $recursive
* @throws \UnexpectedValueException on receipt of unexpected packets
* @return bool
* @access private
*/
@ -1482,7 +1482,8 @@ class SFTP extends SSH2
*/
$response = $this->_get_sftp_packet();
if ($this->packet_type != NET_SFTP_STATUS) {
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
user_error('Expected SSH_FXP_STATUS');
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
@ -1570,7 +1571,6 @@ class SFTP extends SSH2
* Return the target of a symbolic link
*
* @param string $link
* @throws \UnexpectedValueException on receipt of unexpected packets
* @return mixed
* @access public
*/
@ -1594,7 +1594,8 @@ class SFTP extends SSH2
$this->_logError($response);
return false;
default:
throw new \UnexpectedValueException('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
return false;
}
extract(unpack('Ncount', $this->_string_shift($response, 4)));
@ -1614,7 +1615,6 @@ class SFTP extends SSH2
*
* @param string $target
* @param string $link
* @throws \UnexpectedValueException on receipt of unexpected packets
* @return bool
* @access public
*/
@ -1634,7 +1634,8 @@ class SFTP extends SSH2
$response = $this->_get_sftp_packet();
if ($this->packet_type != NET_SFTP_STATUS) {
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
user_error('Expected SSH_FXP_STATUS');
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
@ -1686,7 +1687,6 @@ class SFTP extends SSH2
*
* @param string $dir
* @return bool
* @throws \UnexpectedValueException on receipt of unexpected packets
* @access private
*/
function _mkdir_helper($dir, $attr)
@ -1697,7 +1697,8 @@ class SFTP extends SSH2
$response = $this->_get_sftp_packet();
if ($this->packet_type != NET_SFTP_STATUS) {
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
user_error('Expected SSH_FXP_STATUS');
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
@ -1713,7 +1714,6 @@ class SFTP extends SSH2
* Removes a directory.
*
* @param string $dir
* @throws \UnexpectedValueException on receipt of unexpected packets
* @return bool
* @access public
*/
@ -1734,7 +1734,8 @@ class SFTP extends SSH2
$response = $this->_get_sftp_packet();
if ($this->packet_type != NET_SFTP_STATUS) {
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
user_error('Expected SSH_FXP_STATUS');
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
@ -1794,9 +1795,6 @@ class SFTP extends SSH2
* @param int $start
* @param int $local_start
* @param callable|null $progressCallback
* @throws \UnexpectedValueException on receipt of unexpected packets
* @throws \BadFunctionCallException if you're uploading via a callback and the callback function is invalid
* @throws \phpseclib\Exception\FileNotFoundException if you're uploading via a file and the file doesn't exist
* @return bool
* @access public
* @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib\Net\SFTP::setMode().
@ -1844,7 +1842,8 @@ class SFTP extends SSH2
$this->_logError($response);
return false;
default:
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
return false;
}
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
@ -1852,7 +1851,7 @@ class SFTP extends SSH2
switch (true) {
case $mode & self::SOURCE_CALLBACK:
if (!is_callable($data)) {
throw new \BadFunctionCallException("\$data should be is_callable() if you specify SOURCE_CALLBACK flag");
user_error("\$data should be is_callable() if you specify SOURCE_CALLBACK flag");
}
$dataCallback = $data;
// do nothing
@ -1863,7 +1862,8 @@ class SFTP extends SSH2
break;
case $mode & self::SOURCE_LOCAL_FILE:
if (!is_file($data)) {
throw new FileNotFoundException("$data is not a valid file");
user_error("$data is not a valid file");
return false;
}
$fp = @fopen($data, 'rb');
if (!$fp) {
@ -1948,7 +1948,6 @@ class SFTP extends SSH2
*
* @param int $i
* @return bool
* @throws \UnexpectedValueException on receipt of unexpected packets
* @access private
*/
function _read_put_responses($i)
@ -1956,7 +1955,8 @@ class SFTP extends SSH2
while ($i--) {
$response = $this->_get_sftp_packet();
if ($this->packet_type != NET_SFTP_STATUS) {
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
user_error('Expected SSH_FXP_STATUS');
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
@ -1974,7 +1974,6 @@ class SFTP extends SSH2
*
* @param string $handle
* @return bool
* @throws \UnexpectedValueException on receipt of unexpected packets
* @access private
*/
function _close_handle($handle)
@ -1987,7 +1986,8 @@ class SFTP extends SSH2
// -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3
$response = $this->_get_sftp_packet();
if ($this->packet_type != NET_SFTP_STATUS) {
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
user_error('Expected SSH_FXP_STATUS');
return false;
}
extract(unpack('Nstatus', $this->_string_shift($response, 4)));
@ -2012,7 +2012,6 @@ class SFTP extends SSH2
* @param string $local_file
* @param int $offset
* @param int $length
* @throws \UnexpectedValueException on receipt of unexpected packets
* @return mixed
* @access public
*/
@ -2041,7 +2040,8 @@ class SFTP extends SSH2
$this->_logError($response);
return false;
default:
throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
return false;
}
if (is_resource($local_file)) {
@ -2063,68 +2063,40 @@ class SFTP extends SSH2
$fclose_check = $local_file !== false && !is_resource($local_file);
$start = $offset;
$read = 0;
$size = $this->max_sftp_packet < $length || $length < 0 ? $this->max_sftp_packet : $length;
while (true) {
$i = 0;
$packet = pack('Na*N3', strlen($handle), $handle, $offset / 4294967296, $offset, $size);
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
if ($fclose_check) {
fclose($fp);
}
return false;
}
while ($i < NET_SFTP_QUEUE_SIZE && ($length < 0 || $read < $length)) {
$tempoffset = $start + $read;
$packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
$packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size);
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
$response = $this->_get_sftp_packet();
switch ($this->packet_type) {
case NET_SFTP_DATA:
$temp = substr($response, 4);
$offset+= strlen($temp);
if ($local_file === false) {
$content.= $temp;
} else {
fputs($fp, $temp);
}
break;
case NET_SFTP_STATUS:
// could, in theory, return false if !strlen($content) but we'll hold off for the time being
$this->_logError($response);
break 2;
default:
user_error('Expected SSH_FXP_DATA or SSH_FXP_STATUS');
if ($fclose_check) {
fclose($fp);
}
return false;
}
$packet = null;
$read+= $packet_size;
$i++;
}
if (!$i) {
break;
}
$clear_responses = false;
while ($i > 0) {
$i--;
if ($clear_responses) {
$this->_get_sftp_packet();
continue;
} else {
$response = $this->_get_sftp_packet();
}
switch ($this->packet_type) {
case NET_SFTP_DATA:
$temp = substr($response, 4);
$offset+= strlen($temp);
if ($local_file === false) {
$content.= $temp;
} else {
fputs($fp, $temp);
}
$temp = null;
break;
case NET_SFTP_STATUS:
// could, in theory, return false if !strlen($content) but we'll hold off for the time being
$this->_logError($response);
$clear_responses = true; // don't break out of the loop yet, so we can read the remaining responses
break;
default:
if ($fclose_check) {
fclose($fp);
}
throw new \UnexpectedValueException('Expected SSH_FXP_DATA or SSH_FXP_STATUS');
}
$response = null;
}
if ($clear_responses) {
if ($length > 0 && $length <= $offset - $start) {
break;
}
}
@ -2155,7 +2127,6 @@ class SFTP extends SSH2
* @param string $path
* @param bool $recursive
* @return bool
* @throws \UnexpectedValueException on receipt of unexpected packets
* @access public
*/
function delete($path, $recursive = true)
@ -2176,7 +2147,8 @@ class SFTP extends SSH2
$response = $this->_get_sftp_packet();
if ($this->packet_type != NET_SFTP_STATUS) {
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
user_error('Expected SSH_FXP_STATUS');
return false;
}
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
@ -2508,7 +2480,6 @@ class SFTP extends SSH2
* @param string $oldname
* @param string $newname
* @return bool
* @throws \UnexpectedValueException on receipt of unexpected packets
* @access public
*/
function rename($oldname, $newname)
@ -2531,7 +2502,8 @@ class SFTP extends SSH2
$response = $this->_get_sftp_packet();
if ($this->packet_type != NET_SFTP_STATUS) {
throw new \UnexpectedValueException('Expected SSH_FXP_STATUS');
user_error('Expected SSH_FXP_STATUS');
return false;
}
// if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
@ -2705,13 +2677,13 @@ class SFTP extends SSH2
if (defined('NET_SFTP_LOGGING')) {
$packet_type = '-> ' . $this->packet_types[$type] .
' (' . round($stop - $start, 4) . 's)';
if (NET_SFTP_LOGGING == self::LOG_REALTIME) {
if (NET_SFTP_LOGGING == NET_SFTP_LOG_REALTIME) {
echo "<pre>\r\n" . $this->_format_log(array($data), array($packet_type)) . "\r\n</pre>\r\n";
flush();
ob_flush();
} else {
$this->packet_type_log[] = $packet_type;
if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) {
$this->packet_log[] = $data;
}
}
@ -2781,13 +2753,13 @@ class SFTP extends SSH2
if (defined('NET_SFTP_LOGGING')) {
$packet_type = '<- ' . $this->packet_types[$this->packet_type] .
' (' . round($stop - $start, 4) . 's)';
if (NET_SFTP_LOGGING == self::LOG_REALTIME) {
if (NET_SFTP_LOGGING == NET_SFTP_LOG_REALTIME) {
echo "<pre>\r\n" . $this->_format_log(array($packet), array($packet_type)) . "\r\n</pre>\r\n";
flush();
ob_flush();
} else {
$this->packet_type_log[] = $packet_type;
if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
if (NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX) {
$this->packet_log[] = $packet;
}
}
@ -2799,7 +2771,7 @@ class SFTP extends SSH2
/**
* Returns a log of the packets that have been sent and received.
*
* Returns a string if NET_SFTP_LOGGING == self::LOG_COMPLEX, an array if NET_SFTP_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING')
* Returns a string if NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX, an array if NET_SFTP_LOGGING == NET_SFTP_LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING')
*
* @access public
* @return string or Array
@ -2811,10 +2783,10 @@ class SFTP extends SSH2
}
switch (NET_SFTP_LOGGING) {
case self::LOG_COMPLEX:
case NET_SFTP_LOG_COMPLEX:
return $this->_format_log($this->packet_log, $this->packet_type_log);
break;
//case self::LOG_SIMPLE:
//case NET_SFTP_LOG_SIMPLE:
default:
return $this->packet_type_log;
}

View File

@ -19,7 +19,6 @@ namespace phpseclib\Net\SFTP;
use phpseclib\Crypt\RSA;
use phpseclib\Net\SFTP;
use phpseclib\Net\SSH2;
/**
* SFTP Stream Wrapper
@ -178,12 +177,13 @@ class Stream
}
}
if (preg_match('/^{[a-z0-9]+}$/i', $host)) {
$host = SSH2::getConnectionByResourceId($host);
if ($host === false) {
if ($host[0] == '$') {
$host = substr($host, 1);
global $$host;
if (($$host instanceof SFTP) === false) {
return false;
}
$this->sftp = $host;
$this->sftp = $$host;
} else {
if (isset($this->context)) {
$context = stream_context_get_options($this->context);

View File

@ -537,15 +537,14 @@ class SSH1
* Connect to an SSHv1 server
*
* @return bool
* @throws \UnexpectedValueException on receipt of unexpected packets
* @throws \RuntimeException on other errors
* @access private
*/
function _connect()
{
$this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->connectionTimeout);
if (!$this->fsock) {
throw new \RuntimeException(rtrim("Cannot connect to $host. Error $errno. $errstr"));
user_error(rtrim("Cannot connect to {$this->host}:{$this->port}. Error $errno. $errstr"));
return false;
}
$this->server_identification = $init_line = fgets($this->fsock, 255);
@ -556,17 +555,20 @@ class SSH1
}
if (!preg_match('#SSH-([0-9\.]+)-(.+)#', $init_line, $parts)) {
throw new \RuntimeException('Can only connect to SSH servers');
user_error('Can only connect to SSH servers');
return false;
}
if ($parts[1][0] != 1) {
throw new \RuntimeException("Cannot connect to $parts[1] servers");
user_error("Cannot connect to SSH $parts[1] servers");
return false;
}
fputs($this->fsock, $this->identifier."\r\n");
$response = $this->_get_binary_packet();
if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) {
throw new \UnexpectedValueException('Expected SSH_SMSG_PUBLIC_KEY');
user_error('Expected SSH_SMSG_PUBLIC_KEY');
return false;
}
$anti_spoofing_cookie = $this->_string_shift($response[self::RESPONSE_DATA], 8);
@ -650,7 +652,8 @@ class SSH1
$data = pack('C2a*na*N', NET_SSH1_CMSG_SESSION_KEY, $cipher, $anti_spoofing_cookie, 8 * strlen($double_encrypted_session_key), $double_encrypted_session_key, 0);
if (!$this->_send_binary_packet($data)) {
throw new \RuntimeException('Error sending SSH_CMSG_SESSION_KEY');
user_error('Error sending SSH_CMSG_SESSION_KEY');
return false;
}
switch ($cipher) {
@ -658,20 +661,16 @@ class SSH1
// $this->crypto = new \phpseclib\Crypt\Null();
// break;
case self::CIPHER_DES:
$this->crypto = new DES(DES::MODE_CBC);
$this->crypto = new DES();
$this->crypto->disablePadding();
$this->crypto->enableContinuousBuffer();
$this->crypto->setKey(substr($session_key, 0, 8));
// "The iv (initialization vector) is initialized to all zeroes."
$this->crypto->setIV(str_repeat("\0", 8));
break;
case self::CIPHER_3DES:
$this->crypto = new TripleDES(TripleDES::MODE_3CBC);
$this->crypto->disablePadding();
$this->crypto->enableContinuousBuffer();
$this->crypto->setKey(substr($session_key, 0, 24));
// "All three initialization vectors are initialized to zero."
$this->crypto->setIV(str_repeat("\0", 8));
break;
//case self::CIPHER_RC4:
// $this->crypto = new RC4();
@ -683,7 +682,8 @@ class SSH1
$response = $this->_get_binary_packet();
if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
throw new \UnexpectedValueException('Expected SSH_SMSG_SUCCESS');
user_error('Expected SSH_SMSG_SUCCESS');
return false;
}
$this->bitmap = self::MASK_CONNECTED;
@ -697,8 +697,6 @@ class SSH1
* @param string $username
* @param string $password
* @return bool
* @throws \UnexpectedValueException on receipt of unexpected packets
* @throws \RuntimeException on other errors
* @access public
*/
function login($username, $password = '')
@ -717,7 +715,8 @@ class SSH1
$data = pack('CNa*', NET_SSH1_CMSG_USER, strlen($username), $username);
if (!$this->_send_binary_packet($data)) {
throw new \RuntimeException('Error sending SSH_CMSG_USER');
user_error('Error sending SSH_CMSG_USER');
return false;
}
$response = $this->_get_binary_packet();
@ -729,13 +728,15 @@ class SSH1
$this->bitmap |= self::MASK_LOGIN;
return true;
} elseif ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) {
throw new \UnexpectedValueException('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
return false;
}
$data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen($password), $password);
if (!$this->_send_binary_packet($data)) {
throw new \RuntimeException('Error sending SSH_CMSG_AUTH_PASSWORD');
user_error('Error sending SSH_CMSG_AUTH_PASSWORD');
return false;
}
// remove the username and password from the last logged packet
@ -755,7 +756,8 @@ class SSH1
} elseif ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) {
return false;
} else {
throw new \UnexpectedValueException('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
return false;
}
}
@ -790,19 +792,20 @@ class SSH1
* @see self::interactiveWrite()
* @param string $cmd
* @return mixed
* @throws \RuntimeException on error sending command
* @access public
*/
function exec($cmd, $block = true)
{
if (!($this->bitmap & self::MASK_LOGIN)) {
throw new \RuntimeException('Operation disallowed prior to login()');
user_error('Operation disallowed prior to login()');
return false;
}
$data = pack('CNa*', NET_SSH1_CMSG_EXEC_CMD, strlen($cmd), $cmd);
if (!$this->_send_binary_packet($data)) {
throw new \RuntimeException('Error sending SSH_CMSG_EXEC_CMD');
user_error('Error sending SSH_CMSG_EXEC_CMD');
return false;
}
if (!$block) {
@ -838,8 +841,6 @@ class SSH1
* @see self::interactiveRead()
* @see self::interactiveWrite()
* @return bool
* @throws \UnexpectedValueException on receipt of unexpected packets
* @throws \RuntimeException on other errors
* @access private
*/
function _initShell()
@ -850,7 +851,8 @@ class SSH1
$data = pack('CNa*N4C', NET_SSH1_CMSG_REQUEST_PTY, strlen('vt100'), 'vt100', 24, 80, 0, 0, self::TTY_OP_END);
if (!$this->_send_binary_packet($data)) {
throw new \RuntimeException('Error sending SSH_CMSG_REQUEST_PTY');
user_error('Error sending SSH_CMSG_REQUEST_PTY');
return false;
}
$response = $this->_get_binary_packet();
@ -859,13 +861,15 @@ class SSH1
return false;
}
if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
throw new \UnexpectedValueException('Expected SSH_SMSG_SUCCESS');
user_error('Expected SSH_SMSG_SUCCESS');
return false;
}
$data = pack('C', NET_SSH1_CMSG_EXEC_SHELL);
if (!$this->_send_binary_packet($data)) {
throw new \RuntimeException('Error sending SSH_CMSG_EXEC_SHELL');
user_error('Error sending SSH_CMSG_EXEC_SHELL');
return false;
}
$this->bitmap |= self::MASK_SHELL;
@ -898,17 +902,18 @@ class SSH1
* @param string $expect
* @param int $mode
* @return bool
* @throws \RuntimeException on connection error
* @access public
*/
function read($expect, $mode = self::READ__SIMPLE)
{
if (!($this->bitmap & self::MASK_LOGIN)) {
throw new \RuntimeException('Operation disallowed prior to login()');
user_error('Operation disallowed prior to login()');
return false;
}
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
throw new \RuntimeException('Unable to initiate an interactive shell session');
user_error('Unable to initiate an interactive shell session');
return false;
}
$match = $expect;
@ -936,23 +941,25 @@ class SSH1
* @see self::interactiveRead()
* @param string $cmd
* @return bool
* @throws \RuntimeException on connection error
* @access public
*/
function interactiveWrite($cmd)
{
if (!($this->bitmap & self::MASK_LOGIN)) {
throw new \RuntimeException('Operation disallowed prior to login()');
user_error('Operation disallowed prior to login()');
return false;
}
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
throw new \RuntimeException('Unable to initiate an interactive shell session');
user_error('Unable to initiate an interactive shell session');
return false;
}
$data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($cmd), $cmd);
if (!$this->_send_binary_packet($data)) {
throw new \RuntimeException('Error sending SSH_CMSG_STDIN');
user_error('Error sending SSH_CMSG_STDIN');
return false;
}
return true;
@ -969,17 +976,18 @@ class SSH1
*
* @see self::interactiveRead()
* @return string
* @throws \RuntimeException on connection error
* @access public
*/
function interactiveRead()
{
if (!($this->bitmap & self::MASK_LOGIN)) {
throw new \RuntimeException('Operation disallowed prior to login()');
user_error('Operation disallowed prior to login()');
return false;
}
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
throw new \RuntimeException('Unable to initiate an interactive shell session');
user_error('Unable to initiate an interactive shell session');
return false;
}
$read = array($this->fsock);
@ -1305,9 +1313,9 @@ class SSH1
{
/*
$rsa = new RSA();
$rsa->load($key, 'raw');
$rsa->setHash('sha1');
return $rsa->encrypt($m, RSA::PADDING_PKCS1);
$rsa->loadKey($key, RSA::PUBLIC_FORMAT_RAW);
$rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
return $rsa->encrypt($m);
*/
// To quote from protocol-1.5.txt:

View File

@ -26,7 +26,7 @@
*
* $key = new \phpseclib\Crypt\RSA();
* //$key->setPassword('whatever');
* $key->load(file_get_contents('privatekey'));
* $key->loadKey(file_get_contents('privatekey'));
*
* $ssh = new \phpseclib\Net\SSH2('www.domain.tld');
* if (!$ssh->login('username', $key)) {
@ -60,7 +60,6 @@ use phpseclib\Crypt\TripleDES;
use phpseclib\Crypt\Twofish;
use phpseclib\Math\BigInteger; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification.
use phpseclib\System\SSH\Agent;
use phpseclib\Exception\NoSupportedAlgorithmsException;
/**
* Pure-PHP implementation of SSHv2.
@ -867,14 +866,6 @@ class SSH2
*/
var $agent;
/**
* Connection storage to replicates ssh2 extension functionality:
* {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples}
*
* @var SSH2[]
*/
static $connections;
/**
* Default Constructor.
*
@ -968,8 +959,6 @@ class SSH2
31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY')
);
self::$connections[$this->getResourceId()] = $this;
if (is_resource($host)) {
$this->fsock = $host;
return;
@ -1000,8 +989,6 @@ class SSH2
* Connect to an SSHv2 server
*
* @return bool
* @throws \UnexpectedValueException on receipt of unexpected packets
* @throws \RuntimeException on other errors
* @access private
*/
function _connect()
@ -1021,7 +1008,8 @@ class SSH2
$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"));
user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"));
return false;
}
$elapsed = microtime(true) - $start;
@ -1072,7 +1060,8 @@ class SSH2
}
if (feof($this->fsock)) {
throw new \RuntimeException('Connection closed by server');
user_error('Connection closed by server');
return false;
}
$this->identifier = $this->_generate_identifier();
@ -1088,18 +1077,21 @@ class SSH2
}
if ($matches[1] != '1.99' && $matches[1] != '2.0') {
throw new \RuntimeException("Cannot connect to SSH $matches[1] servers");
user_error("Cannot connect to SSH $matches[1] servers");
return false;
}
fputs($this->fsock, $this->identifier . "\r\n");
$response = $this->_get_binary_packet();
if ($response === false) {
throw new \RuntimeException('Connection closed by server');
user_error('Connection closed by server');
return false;
}
if (ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT');
user_error('Expected SSH_MSG_KEXINIT');
return false;
}
if (!$this->_key_exchange($response)) {
@ -1151,9 +1143,6 @@ class SSH2
* Key Exchange
*
* @param string $kexinit_payload_server
* @throws \UnexpectedValueException on receipt of unexpected packets
* @throws \RuntimeException on other errors
* @throws \phpseclib\Exception\NoSupportedAlgorithmsException when none of the algorithms phpseclib has loaded are compatible
* @access private
*/
function _key_exchange($kexinit_payload_server)
@ -1365,28 +1354,27 @@ class SSH2
// here ends the second place.
// we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
// 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 = $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');
user_error('No compatible server to client encryption algorithms found');
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
}
$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');
user_error('No compatible client to server encryption algorithms found');
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
}
// through diffie-hellman key exchange a symmetric key is obtained
$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');
user_error('No compatible key exchange algorithms found');
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
}
// Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty.
@ -1495,7 +1483,7 @@ class SSH2
$max = $one->bitwise_leftShift(16 * $keyLength); // 2 * 8 * $keyLength
$max = $max->subtract($one);
$x = BigInteger::random($one, $max);
$x = $one->random($one, $max);
$e = $g->modPow($x, $prime);
$eBytes = $e->toBytes(true);
@ -1503,17 +1491,20 @@ class SSH2
$data = pack('CNa*', $clientKexInitMessage, strlen($eBytes), $eBytes);
if (!$this->_send_binary_packet($data)) {
throw new \RuntimeException('Connection closed by server');
user_error('Connection closed by server');
return false;
}
$response = $this->_get_binary_packet();
if ($response === false) {
throw new \RuntimeException('Connection closed by server');
user_error('Connection closed by server');
return false;
}
extract(unpack('Ctype', $this->_string_shift($response, 1)));
if ($type != $serverKexReplyMessage) {
throw new \UnexpectedValueException('Expected SSH_MSG_KEXDH_REPLY');
user_error('Expected SSH_MSG_KEXDH_REPLY');
return false;
}
$temp = unpack('Nlength', $this->_string_shift($response, 4));
@ -1573,13 +1564,13 @@ class SSH2
$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');
user_error('No compatible server host key algorithms found');
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
}
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');
user_error('Server Host Key Algorithm Mismatch');
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
}
$packet = pack(
@ -1594,13 +1585,15 @@ class SSH2
$response = $this->_get_binary_packet();
if ($response === false) {
throw new \RuntimeException('Connection closed by server');
user_error('Connection closed by server');
return false;
}
extract(unpack('Ctype', $this->_string_shift($response, 1)));
if ($type != NET_SSH2_MSG_NEWKEYS) {
throw new \UnexpectedValueException('Expected SSH_MSG_NEWKEYS');
user_error('Expected SSH_MSG_NEWKEYS');
return false;
}
$keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
@ -1616,13 +1609,11 @@ class SSH2
$this->encrypt->enableContinuousBuffer();
$this->encrypt->disablePadding();
if ($this->encrypt->usesIV()) {
$iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id);
while ($this->encrypt_block_size > strlen($iv)) {
$iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
}
$this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size));
$iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id);
while ($this->encrypt_block_size > strlen($iv)) {
$iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
}
$this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size));
$key = $kexHash->hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id);
while ($encryptKeyLength > strlen($key)) {
@ -1642,13 +1633,11 @@ class SSH2
$this->decrypt->enableContinuousBuffer();
$this->decrypt->disablePadding();
if ($this->decrypt->usesIV()) {
$iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id);
while ($this->decrypt_block_size > strlen($iv)) {
$iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
}
$this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size));
$iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id);
while ($this->decrypt_block_size > strlen($iv)) {
$iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
}
$this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size));
$key = $kexHash->hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id);
while ($decryptKeyLength > strlen($key)) {
@ -1673,8 +1662,8 @@ class SSH2
$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');
user_error('No compatible client to server message authentication algorithms found');
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
}
$createKeyLength = 0; // ie. $mac_algorithm == 'none'
@ -1702,8 +1691,8 @@ class SSH2
$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');
user_error('No compatible server to client message authentication algorithms found');
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
}
$checkKeyLength = 0;
@ -1749,15 +1738,15 @@ class SSH2
$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');
user_error('No compatible server to client compression algorithms found');
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
}
$this->decompress = $compression_algorithm == 'zlib';
$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');
user_error('No compatible client to server compression algorithms found');
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
}
$this->compress = $compression_algorithm == 'zlib';
@ -1815,26 +1804,26 @@ class SSH2
{
switch ($algorithm) {
case '3des-cbc':
return new TripleDES(Base::MODE_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(Base::MODE_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(Base::MODE_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(Base::MODE_CBC);
return new Twofish();
case 'twofish128-ctr':
case 'twofish192-ctr':
case 'twofish256-ctr':
@ -1902,8 +1891,6 @@ class SSH2
* @param string $username
* @param string $password
* @return bool
* @throws \UnexpectedValueException on receipt of unexpected packets
* @throws \RuntimeException on other errors
* @access private
* @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
* by sending dummy SSH_MSG_IGNORE messages.
@ -1928,13 +1915,15 @@ class SSH2
$response = $this->_get_binary_packet();
if ($response === false) {
throw new \RuntimeException('Connection closed by server');
user_error('Connection closed by server');
return false;
}
extract(unpack('Ctype', $this->_string_shift($response, 1)));
if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) {
throw new \UnexpectedValueException('Expected SSH_MSG_SERVICE_ACCEPT');
user_error('Expected SSH_MSG_SERVICE_ACCEPT');
return false;
}
$this->bitmap |= self::MASK_LOGIN_REQ;
}
@ -1975,7 +1964,8 @@ class SSH2
$response = $this->_get_binary_packet();
if ($response === false) {
throw new \RuntimeException('Connection closed by server');
user_error('Connection closed by server');
return false;
}
extract(unpack('Ctype', $this->_string_shift($response, 1)));
@ -2029,7 +2019,8 @@ class SSH2
$response = $this->_get_binary_packet();
if ($response === false) {
throw new \RuntimeException('Connection closed by server');
user_error('Connection closed by server');
return false;
}
extract(unpack('Ctype', $this->_string_shift($response, 1)));
@ -2105,7 +2096,6 @@ class SSH2
*
* @param string $responses...
* @return bool
* @throws \RuntimeException on connection error
* @access private
*/
function _keyboard_interactive_process()
@ -2117,7 +2107,8 @@ class SSH2
} else {
$orig = $response = $this->_get_binary_packet();
if ($response === false) {
throw new \RuntimeException('Connection closed by server');
user_error('Connection closed by server');
return false;
}
}
@ -2241,7 +2232,6 @@ class SSH2
* @param string $username
* @param \phpseclib\Crypt\RSA $password
* @return bool
* @throws \RuntimeException on connection error
* @access private
* @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
* by sending dummy SSH_MSG_IGNORE messages.
@ -2249,7 +2239,7 @@ class SSH2
function _privatekey_login($username, $privatekey)
{
// see http://tools.ietf.org/html/rfc4253#page-15
$publickey = $privatekey->getPublicKey('Raw');
$publickey = $privatekey->getPublicKey(RSA::PUBLIC_FORMAT_RAW);
if ($publickey === false) {
return false;
}
@ -2287,7 +2277,8 @@ class SSH2
$response = $this->_get_binary_packet();
if ($response === false) {
throw new \RuntimeException('Connection closed by server');
user_error('Connection closed by server');
return false;
}
extract(unpack('Ctype', $this->_string_shift($response, 1)));
@ -2310,8 +2301,8 @@ class SSH2
}
$packet = $part1 . chr(1) . $part2;
$privatekey->setHash('sha1');
$signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet), RSA::PADDING_PKCS1);
$privatekey->setSignatureMode(RSA::SIGNATURE_PKCS1);
$signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet));
$signature = pack('Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($signature), $signature);
$packet.= pack('Na*', strlen($signature), $signature);
@ -2321,7 +2312,8 @@ class SSH2
$response = $this->_get_binary_packet();
if ($response === false) {
throw new \RuntimeException('Connection closed by server');
user_error('Connection closed by server');
return false;
}
extract(unpack('Ctype', $this->_string_shift($response, 1)));
@ -2371,7 +2363,6 @@ class SSH2
* @param string $command
* @param Callback $callback
* @return string
* @throws \RuntimeException on connection error
* @access public
*/
function exec($command, $callback = null)
@ -2439,7 +2430,8 @@ class SSH2
$response = $this->_get_binary_packet();
if ($response === false) {
throw new \RuntimeException('Connection closed by server');
user_error('Connection closed by server');
return false;
}
list(, $type) = unpack('C', $this->_string_shift($response, 1));
@ -2449,8 +2441,8 @@ class SSH2
break;
case NET_SSH2_MSG_CHANNEL_FAILURE:
default:
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
throw new \RuntimeException('Unable to request pseudo-terminal');
user_error('Unable to request pseudo-terminal');
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
}
$this->in_request_pty_exec = true;
}
@ -2518,8 +2510,6 @@ class SSH2
* @see self::read()
* @see self::write()
* @return bool
* @throws \UnexpectedValueException on receipt of unexpected packets
* @throws \RuntimeException on other errors
* @access private
*/
function _initShell()
@ -2576,7 +2566,8 @@ class SSH2
$response = $this->_get_binary_packet();
if ($response === false) {
throw new \RuntimeException('Connection closed by server');
user_error('Connection closed by server');
return false;
}
list(, $type) = unpack('C', $this->_string_shift($response, 1));
@ -2587,8 +2578,8 @@ class SSH2
case NET_SSH2_MSG_CHANNEL_FAILURE:
break;
default:
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
throw new \UnexpectedValueException('Unable to request pseudo-terminal');
user_error('Unable to request pseudo-terminal');
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
}
$packet = pack(
@ -2665,7 +2656,6 @@ class SSH2
* @param string $expect
* @param int $mode
* @return string
* @throws \RuntimeException on connection error
* @access public
*/
function read($expect = '', $mode = self::READ_SIMPLE)
@ -2674,11 +2664,13 @@ class SSH2
$this->is_timeout = false;
if (!($this->bitmap & self::MASK_LOGIN)) {
throw new \RuntimeException('Operation disallowed prior to login()');
user_error('Operation disallowed prior to login()');
return false;
}
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
throw new \RuntimeException('Unable to initiate an interactive shell session');
user_error('Unable to initiate an interactive shell session');
return false;
}
$channel = $this->_get_interactive_channel();
@ -2709,17 +2701,18 @@ class SSH2
* @see self::read()
* @param string $cmd
* @return bool
* @throws \RuntimeException on connection error
* @access public
*/
function write($cmd)
{
if (!($this->bitmap & self::MASK_LOGIN)) {
throw new \RuntimeException('Operation disallowed prior to login()');
user_error('Operation disallowed prior to login()');
return false;
}
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
throw new \RuntimeException('Unable to initiate an interactive shell session');
user_error('Unable to initiate an interactive shell session');
return false;
}
return $this->_send_channel_packet($this->_get_interactive_channel(), $cmd);
@ -2843,7 +2836,6 @@ class SSH2
if (isset($this->realtime_log_file) && is_resource($this->realtime_log_file)) {
fclose($this->realtime_log_file);
}
unset(self::$connections[$this->getResourceId()]);
}
/**
@ -2888,14 +2880,14 @@ class SSH2
*
* @see self::_send_binary_packet()
* @return string
* @throws \RuntimeException on connection errors
* @access private
*/
function _get_binary_packet()
{
if (!is_resource($this->fsock) || feof($this->fsock)) {
user_error('Connection closed prematurely');
$this->bitmap = 0;
throw new \RuntimeException('Connection closed prematurely');
return false;
}
$start = microtime(true);
@ -2909,7 +2901,8 @@ class SSH2
$raw = $this->decrypt->decrypt($raw);
}
if ($raw === false) {
throw new \RuntimeException('Unable to decrypt content');
user_error('Unable to decrypt content');
return false;
}
extract(unpack('Npacket_length/Cpadding_length', $this->_string_shift($raw, 5)));
@ -2920,15 +2913,17 @@ class SSH2
// "implementations SHOULD check that the packet length is reasonable"
// PuTTY uses 0x9000 as the actual max packet size and so to shall we
if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) {
throw new \RuntimeException('Invalid size');
user_error('Invalid size');
return false;
}
$buffer = '';
while ($remaining_length > 0) {
$temp = fread($this->fsock, $remaining_length);
if ($temp === false || feof($this->fsock)) {
user_error('Error reading from socket');
$this->bitmap = 0;
throw new \RuntimeException('Error reading from socket');
return false;
}
$buffer.= $temp;
$remaining_length-= strlen($temp);
@ -2944,10 +2939,12 @@ class SSH2
if ($this->hmac_check !== false) {
$hmac = fread($this->fsock, $this->hmac_size);
if ($hmac === false || strlen($hmac) != $this->hmac_size) {
user_error('Error reading socket');
$this->bitmap = 0;
throw new \RuntimeException('Error reading socket');
return false;
} elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
throw new \RuntimeException('Invalid HMAC');
user_error('Invalid HMAC');
return false;
}
}
@ -3173,7 +3170,6 @@ class SSH2
*
* @param $client_channel
* @return mixed
* @throws \RuntimeException on connection error
* @access private
*/
function _get_channel_packet($client_channel, $skip_extended = false)
@ -3206,7 +3202,8 @@ class SSH2
$response = $this->_get_binary_packet();
if ($response === false) {
throw new \RuntimeException('Connection closed by server');
user_error('Connection closed by server');
return false;
}
if ($client_channel == -1 && $response === true) {
return true;
@ -3255,8 +3252,8 @@ class SSH2
return $result;
//case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE:
default:
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
throw new \RuntimeException('Unable to open channel');
user_error('Unable to open channel');
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
}
break;
case NET_SSH2_MSG_CHANNEL_REQUEST:
@ -3266,8 +3263,8 @@ class SSH2
case NET_SSH2_MSG_CHANNEL_FAILURE:
return false;
default:
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
throw new \RuntimeException('Unable to fulfill channel request');
user_error('Unable to fulfill channel request');
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
}
case NET_SSH2_MSG_CHANNEL_CLOSE:
return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->_get_channel_packet($client_channel, $skip_extended);
@ -3376,8 +3373,8 @@ class SSH2
case NET_SSH2_MSG_CHANNEL_EOF:
break;
default:
$this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
throw new \RuntimeException('Error reading channel data');
user_error('Error reading channel data');
return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
}
}
}
@ -3396,8 +3393,9 @@ class SSH2
function _send_binary_packet($data, $logged = null)
{
if (!is_resource($this->fsock) || feof($this->fsock)) {
user_error('Connection closed prematurely');
$this->bitmap = 0;
throw new \RuntimeException('Connection closed prematurely');
return false;
}
//if ($this->compress) {
@ -3488,14 +3486,14 @@ class SSH2
@flush();
@ob_flush();
break;
// basically the same thing as self::LOG_REALTIME with the caveat that NET_SFTP_LOG_REALTIME_FILENAME
// basically the same thing as self::LOG_REALTIME with the caveat that self::LOG_REALTIME_FILE
// needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE.
// the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily
// at the beginning of the file
case self::LOG_REALTIME_FILE:
if (!isset($this->realtime_log_file)) {
// PHP doesn't seem to like using constants in fopen()
$filename = NET_SSH2_LOG_REALTIME_FILENAME;
$filename = self::LOG_REALTIME_FILENAME;
$fp = fopen($filename, 'w');
$this->realtime_log_file = $fp;
}
@ -3960,8 +3958,6 @@ class SSH2
* is recommended. Returns false if the server signature is not signed correctly with the public host key.
*
* @return mixed
* @throws \RuntimeException on badly formatted keys
* @throws \phpseclib\Exception\NoSupportedAlgorithmsException when the key isn't in a supported format
* @access public
*/
function getServerPublicHostKey()
@ -4007,8 +4003,8 @@ class SSH2
padding, unsigned, and in network byte order). */
$temp = unpack('Nlength', $this->_string_shift($signature, 4));
if ($temp['length'] != 40) {
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
throw new \RuntimeException('Invalid signature');
user_error('Invalid signature');
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
}
$r = new BigInteger($this->_string_shift($signature, 20), 256);
@ -4019,8 +4015,8 @@ class SSH2
case $r->compare($q) >= 0:
case $s->equals($zero):
case $s->compare($q) >= 0:
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
throw new \RuntimeException('Invalid signature');
user_error('Invalid signature');
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
}
$w = $s->modInverse($q);
@ -4039,7 +4035,7 @@ class SSH2
list(, $v) = $v->divide($q);
if (!$v->equals($r)) {
//user_error('Bad server signature');
user_error('Bad server signature');
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
}
@ -4058,10 +4054,10 @@ class SSH2
$signature = $this->_string_shift($signature, $temp['length']);
$rsa = new RSA();
$rsa->load(array('e' => $e, 'n' => $n), 'raw');
$rsa->setHash('sha1');
if (!$rsa->verify($this->exchange_hash, $signature, RSA::PADDING_PKCS1)) {
//user_error('Bad server signature');
$rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
$rsa->loadKey(array('e' => $e, 'n' => $n), RSA::PUBLIC_FORMAT_RAW);
if (!$rsa->verify($this->exchange_hash, $signature)) {
user_error('Bad server signature');
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
}
*/
@ -4076,8 +4072,8 @@ class SSH2
// also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source.
if ($s->compare(new BigInteger()) < 0 || $s->compare($n->subtract(new BigInteger(1))) > 0) {
$this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
throw new \RuntimeException('Invalid signature');
user_error('Invalid signature');
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
}
$s = $s->modPow($e, $n);
@ -4087,13 +4083,13 @@ class SSH2
$h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
if ($s != $h) {
//user_error('Bad server signature');
user_error('Bad server signature');
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
}
break;
default:
$this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
throw new NoSupportedAlgorithmsException('Unsupported signature format');
user_error('Unsupported signature format');
return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
}
return $this->signature_format . ' ' . base64_encode($this->server_public_host_key);
@ -4169,47 +4165,4 @@ class SSH2
$this->windowColumns = $columns;
$this->windowRows = $rows;
}
/**
* @return string
*/
function __toString()
{
return $this->getResourceId();
}
/**
* We use {} because that symbols should not be in URL according to
* {@link http://tools.ietf.org/html/rfc3986#section-2 RFC}.
* It will safe us from any conflicts, because otherwise regexp will
* match all alphanumeric domains.
*
* @return string
*/
function getResourceId()
{
return '{' . spl_object_hash($this) . '}';
}
/**
* Return existing connection
*
* @param string $id
*
* @return bool|SSH2 will return false if no such connection
*/
static function getConnectionByResourceId($id)
{
return isset(self::$connections[$id]) ? self::$connections[$id] : false;
}
/**
* Return all excising connections
*
* @return SSH2[]
*/
static function getConnections()
{
return self::$connections;
}
}

View File

@ -34,7 +34,6 @@
namespace phpseclib\System\SSH;
use phpseclib\Crypt\RSA;
use phpseclib\Exception\BadConfigurationException;
use phpseclib\System\SSH\Agent\Identity;
/**
@ -116,8 +115,6 @@ class Agent
* Default Constructor
*
* @return \phpseclib\System\SSH\Agent
* @throws \phpseclib\Exception\BadConfigurationException if SSH_AUTH_SOCK cannot be found
* @throws \RuntimeException on connection errors
* @access public
*/
function __construct()
@ -130,12 +127,13 @@ class Agent
$address = $_ENV['SSH_AUTH_SOCK'];
break;
default:
throw new BadConfigurationException('SSH_AUTH_SOCK not found');
user_error('SSH_AUTH_SOCK not found');
return false;
}
$this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
if (!$this->fsock) {
throw new \RuntimeException("Unable to connect to ssh-agent (Error $errno: $errstr)");
user_error("Unable to connect to ssh-agent (Error $errno: $errstr)");
}
}
@ -146,7 +144,6 @@ class Agent
* Returns an array containing zero or more \phpseclib\System\SSH\Agent\Identity objects
*
* @return array
* @throws \RuntimeException on receipt of unexpected packets
* @access public
*/
function requestIdentities()
@ -157,13 +154,13 @@ class Agent
$packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES);
if (strlen($packet) != fputs($this->fsock, $packet)) {
throw new \RuntimeException('Connection closed while requesting identities');
user_error('Connection closed while requesting identities');
}
$length = current(unpack('N', fread($this->fsock, 4)));
$type = ord(fread($this->fsock, 1));
if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) {
throw new \RuntimeException('Unable to request identities');
user_error('Unable to request identities');
}
$identities = array();
@ -181,7 +178,7 @@ class Agent
switch ($key_type) {
case 'ssh-rsa':
$key = new RSA();
$key->load($key_str);
$key->loadKey($key_str);
break;
case 'ssh-dss':
// not currently supported
@ -277,7 +274,6 @@ class Agent
*
* @param string $data
* @return data from SSH Agent
* @throws \RuntimeException on connection errors
* @access private
*/
function _forward_data($data)
@ -296,7 +292,7 @@ class Agent
}
if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) {
throw new \RuntimeException('Connection closed attempting to forward data to SSH agent');
user_error('Connection closed attempting to forward data to SSH agent');
}
$this->socket_buffer = '';

View File

@ -15,8 +15,6 @@
namespace phpseclib\System\SSH\Agent;
use phpseclib\Crypt\RSA;
use phpseclib\Exception\UnsupportedAlgorithmException;
use phpseclib\System\SSH\Agent;
/**
@ -25,8 +23,9 @@ use phpseclib\System\SSH\Agent;
* Instantiation should only be performed by \phpseclib\System\SSH\Agent class.
* This could be thought of as implementing an interface that phpseclib\Crypt\RSA
* implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something.
* The methods in this interface would be getPublicKey and sign since those are the
* methods phpseclib looks for to perform public key authentication.
* The methods in this interface would be getPublicKey, setSignatureMode
* and sign since those are the methods phpseclib looks for to perform
* public key authentication.
*
* @package SSH\Agent
* @author Jim Wigginton <terrafrost@php.net>
@ -106,29 +105,26 @@ class Identity
*
* Wrapper for $this->key->getPublicKey()
*
* @param int $type optional
* @param int $format optional
* @return mixed
* @access public
*/
function getPublicKey($type = 'PKCS8')
function getPublicKey($format = null)
{
return $this->key->getPublicKey($type);
return !isset($format) ? $this->key->getPublicKey() : $this->key->getPublicKey($format);
}
/**
* Sets the hash
* Set Signature Mode
*
* ssh-agent only supports signatures with sha1 hashes but to maintain BC with RSA.php this function exists
* Doesn't do anything as ssh-agent doesn't let you pick and choose the signature mode. ie.
* ssh-agent's only supported mode is \phpseclib\Crypt\RSA::SIGNATURE_PKCS1
*
* @param string $hash optional
* @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
* @param int $mode
* @access public
*/
function setHash($hash = 'sha1')
function setSignatureMode($mode)
{
if ($hash != 'sha1') {
throw new UnsupportedAlgorithmException('ssh-agent can only be used with the sha1 hash');
}
}
/**
@ -137,29 +133,22 @@ class Identity
* See "2.6.2 Protocol 2 private key signature request"
*
* @param string $message
* @param int $padding optional
* @return string
* @throws \RuntimeException on connection errors
* @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
* @access public
*/
function sign($message, $padding = RSA::PADDING_PKCS1)
function sign($message)
{
if ($padding != RSA::PADDING_PKCS1 && $padding != RSA::PADDING_RELAXED_PKCS1) {
throw new UnsupportedAlgorithmException('ssh-agent can only create PKCS1 signatures');
}
// the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
$packet = pack('CNa*Na*N', Agent::SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, 0);
$packet = pack('Na*', strlen($packet), $packet);
if (strlen($packet) != fputs($this->fsock, $packet)) {
throw new \RuntimeException('Connection closed during signing');
user_error('Connection closed during signing');
}
$length = current(unpack('N', fread($this->fsock, 4)));
$type = ord(fread($this->fsock, 1));
if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) {
throw new \RuntimeException('Unable to retreive signature');
user_error('Unable to retreive signature');
}
$signature_blob = fread($this->fsock, $length - 1);

View File

@ -1,18 +1,14 @@
<?php
/**
* Bootstrapping File for phpseclib
*
* composer isn't a requirement for phpseclib 2.0 but this file isn't really required
* either. it's a bonus for those using composer but if you're not phpseclib will
* still work
*
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
if (extension_loaded('mbstring')) {
// 2 - MB_OVERLOAD_STRING
if (ini_get('mbstring.func_overload') & 2) {
throw new UnexpectedValueException(
throw new \UnexpectedValueException(
'Overloading of string functions using mbstring.func_overload ' .
'is not supported by phpseclib.'
);

View File

@ -42,19 +42,6 @@ class Functional_Net_SFTPStreamTest extends Functional_Net_SFTPTestCase
$this->assertTrue(in_array('te#st.txt', $this->sftp->nlist()));
}
/**
* Tests connection reuse functionality same as ssh2 extension:
* {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples}
*/
public function testConnectionReuse()
{
$originalConnectionsCount = count(\phpseclib\Net\SSH2::getConnections());
$session = $this->sftp;
$dirs = scandir("sftp://$session/");
$this->assertCount($originalConnectionsCount, \phpseclib\Net\SSH2::getConnections());
$this->assertEquals(array('.', '..'), array_slice($dirs, 0, 2));
}
protected function buildUrl($suffix)
{
return sprintf(

View File

@ -13,9 +13,6 @@ use phpseclib\Net\SFTP;
*/
abstract class Functional_Net_SFTPTestCase extends PhpseclibFunctionalTestCase
{
/**
* @var SFTP
*/
protected $sftp;
protected $scratchDir;

View File

@ -28,7 +28,9 @@ abstract class PhpseclibFunctionalTestCase extends PhpseclibTestCase
'Should have gmp or bcmath extension for functional test.'
);
}
self::ensureConstant('CRYPT_HASH_MODE', Hash::MODE_HASH);
self::reRequireFile('Math/BigInteger.php');
self::reRequireFile('Crypt/Hash.php');
}
parent::setUpBeforeClass();
}

View File

@ -47,13 +47,13 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
':-):-):-):-):-):-)', // https://github.com/phpseclib/phpseclib/pull/43
);
$ivs = array(
str_repeat("\0", 16),
str_pad('test123', 16, "\0"),
'',
'test123',
);
$keys = array(
str_repeat("\0", 16),
str_pad(':-8', 16, "\0"), // https://github.com/phpseclib/phpseclib/pull/43
str_pad('FOOBARZ', 16, "\0"),
'',
':-8', // https://github.com/phpseclib/phpseclib/pull/43
'FOOBARZ',
);
$result = array();
@ -100,11 +100,10 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
// this test case is from the following URL:
// https://web.archive.org/web/20070209120224/http://fp.gladman.plus.com/cryptography_technology/rijndael/aesdvec.zip
$aes = new Rijndael(Base::MODE_CBC);
$aes = new Rijndael();
$aes->setPreferredEngine($this->engine);
$aes->disablePadding();
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. Valid in Rijndael.
$aes->setIV(str_repeat("\0", 16));
//$this->_checkEngine($aes); // should only work in internal mode
$ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734'));
$this->assertEquals($ciphertext, pack('H*', '231d844639b31b412211cfe93712b880'));
@ -112,17 +111,15 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
/**
* @group github451
* @expectedException \LengthException
*/
public function testKeyPaddingAES()
{
// same as the above - just with a different ciphertext
$aes = new AES(Base::MODE_CBC);
$aes = new AES();
$aes->setPreferredEngine($this->engine);
$aes->disablePadding();
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. supported by Rijndael - not AES
$aes->setIV(str_repeat("\0", 16));
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. AES should null pad to 192-bits
$this->_checkEngine($aes);
$ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734'));
$this->assertEquals($ciphertext, pack('H*', 'c109292b173f841b88e0ee49f13db8c0'));
@ -267,7 +264,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
// from http://csrc.nist.gov/groups/STM/cavp/documents/aes/AESAVS.pdf#page=16
public function testGFSBox128()
{
$aes = new AES(Base::MODE_CBC);
$aes = new AES();
$aes->setKey(pack('H*', '00000000000000000000000000000000'));
$aes->setIV(pack('H*', '00000000000000000000000000000000'));
@ -294,7 +291,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
public function testGFSBox192()
{
$aes = new AES(Base::MODE_CBC);
$aes = new AES();
$aes->setKey(pack('H*', '000000000000000000000000000000000000000000000000'));
$aes->setIV(pack('H*', '00000000000000000000000000000000'));
@ -319,7 +316,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
public function testGFSBox256()
{
$aes = new AES(Base::MODE_CBC);
$aes = new AES();
$aes->setKey(pack('H*', '00000000000000000000000000000000' . '00000000000000000000000000000000'));
$aes->setIV(pack('H*', '00000000000000000000000000000000'));
@ -342,41 +339,33 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
public function testGetKeyLengthDefault()
{
$aes = new AES(Base::MODE_CBC);
$aes = new AES();
$this->assertSame($aes->getKeyLength(), 128);
}
public function testGetKeyLengthWith192BitKey()
{
$aes = new AES(Base::MODE_CBC);
$aes = new AES();
$aes->setKey(str_repeat('a', 24));
$this->assertSame($aes->getKeyLength(), 192);
}
/**
* @expectedException \LengthException
*/
public function testSetKeyLengthWithLargerKey()
{
$aes = new AES(Base::MODE_CBC);
$aes = new AES();
$aes->setKeyLength(128);
$aes->setKey(str_repeat('a', 24));
$aes->setIV(str_repeat("\0", 16));
$this->assertSame($aes->getKeyLength(), 128);
$ciphertext = bin2hex($aes->encrypt('a'));
$this->assertSame($ciphertext, '82b7b068dfc60ed2a46893b69fecd6c2');
$this->assertSame($aes->getKeyLength(), 128);
}
/**
* @expectedException \LengthException
*/
public function testSetKeyLengthWithSmallerKey()
{
$aes = new AES(Base::MODE_CBC);
$aes = new AES();
$aes->setKeyLength(256);
$aes->setKey(str_repeat('a', 16));
$aes->setIV(str_repeat("\0", 16));
$this->assertSame($aes->getKeyLength(), 256);
$ciphertext = bin2hex($aes->encrypt('a'));
$this->assertSame($ciphertext, 'fd4250c0d234aa7e1aa592820aa8406b');
@ -388,7 +377,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
*/
public function testContinuousBuffer()
{
$aes = new AES(AES::MODE_CBC);
$aes = new AES();
$aes->disablePadding();
$aes->enableContinuousBuffer();
$aes->setIV(pack('H*', '0457bdb4a6712986688349a29eb82535'));

View File

@ -73,9 +73,8 @@ class Unit_Crypt_BlowfishTest extends PhpseclibTestCase
*/
public function testVectors($engine, $engineName, $key, $plaintext, $expected)
{
$bf = new Blowfish(Blowfish::MODE_CBC);
$bf = new Blowfish();
$bf->setKey($key);
$bf->setIV(str_repeat("\0", $bf->getBlockLength() >> 3));
if (!$bf->isValidEngine($engine)) {
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
}

View File

@ -0,0 +1,78 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright MMXIII Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Base;
use phpseclib\Crypt\DES;
// the AES tests establish the correctness of the modes of operation. this test is inteded to establish the consistency of
// key and iv padding between the multiple engines
class Unit_Crypt_DESTest extends PhpseclibTestCase
{
public function testEncryptPadding()
{
$des = new DES(Base::MODE_CBC);
$des->setKey('d');
$des->setIV('d');
$des->setPreferredEngine(Base::ENGINE_INTERNAL);
$result = pack('H*', '3e7613642049af1e');
$internal = $des->encrypt('d');
$this->assertEquals($result, $internal, 'Failed asserting that the internal engine produced the correct result');
$des->setPreferredEngine(Base::ENGINE_MCRYPT);
if ($des->getEngine() == Base::ENGINE_MCRYPT) {
$mcrypt = $des->encrypt('d');
$this->assertEquals($result, $mcrypt, 'Failed asserting that the mcrypt engine produced the correct result');
} else {
self::markTestSkipped('Unable to initialize mcrypt engine');
}
$des->setPreferredEngine(Base::ENGINE_OPENSSL);
if ($des->getEngine() == Base::ENGINE_OPENSSL) {
$openssl = $des->encrypt('d');
$this->assertEquals($result, $openssl, 'Failed asserting that the OpenSSL engine produced the correct result');
} else {
self::markTestSkipped('Unable to initialize OpenSSL engine');
}
}
// phpseclib null pads ciphertext's if they're not long enough and you're in ecb / cbc mode. this silent failure mode is consistent
// with mcrypt's behavior. maybe throwing an exception would be better but whatever. this test is more intended to establish consistent
// behavior between the various engine's
public function testDecryptPadding()
{
$des = new DES(Base::MODE_CBC);
$des->disablePadding();
// when the key and iv are not specified they should be null padded
//$des->setKey();
//$des->setIV();
$des->setPreferredEngine(Base::ENGINE_INTERNAL);
$internal = $des->decrypt('d');
$result = pack('H*', '79b305d1ce555221');
$this->assertEquals($result, $internal, 'Failed asserting that the internal engine produced the correct result');
$des->setPreferredEngine(Base::ENGINE_MCRYPT);
if ($des->getEngine() == Base::ENGINE_MCRYPT) {
$mcrypt = $des->decrypt('d');
$this->assertEquals($result, $mcrypt, 'Failed asserting that the mcrypt engine produced the correct result');
} else {
self::markTestSkipped('Unable to initialize mcrypt engine');
}
$des->setPreferredEngine(Base::ENGINE_OPENSSL);
if ($des->getEngine() == Base::ENGINE_OPENSSL) {
$openssl = $des->decrypt('d');
$this->assertEquals($result, $openssl, 'Failed asserting that the OpenSSL engine produced the correct result');
} else {
self::markTestSkipped('Unable to initialize OpenSSL engine');
}
}
}

View File

@ -0,0 +1,49 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2012 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Hash;
class Unit_Crypt_Hash_MD5Test extends Unit_Crypt_Hash_TestCase
{
public function getInstance()
{
return new Hash('md5');
}
/**
* @dataProvider hashData()
*/
public function testHash($message, $result)
{
$this->assertHashesTo($this->getInstance(), $message, $result);
}
public static function hashData()
{
return array(
array('', 'd41d8cd98f00b204e9800998ecf8427e'),
array('The quick brown fox jumps over the lazy dog', '9e107d9d372bb6826bd81d3542a419d6'),
array('The quick brown fox jumps over the lazy dog.', 'e4d909c290d0fb1ca068ffaddf22cbd0'),
);
}
/**
* @dataProvider hmacData()
*/
public function testHMAC($key, $message, $result)
{
$this->assertHMACsTo($this->getInstance(), $key, $message, $result);
}
public static function hmacData()
{
return array(
array('', '', '74e6f7298a9c2d168935f58c001bad88'),
array('key', 'The quick brown fox jumps over the lazy dog', '80070713463e7749b90c2dc24911e275'),
);
}
}

View File

@ -0,0 +1,81 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2014 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Hash;
class Unit_Crypt_Hash_SHA256Test extends Unit_Crypt_Hash_TestCase
{
public function getInstance()
{
return new Hash('sha256');
}
/**
* @dataProvider hashData()
*/
public function testHash($message, $result)
{
$this->assertHashesTo($this->getInstance(), $message, $result);
}
public static function hashData()
{
return array(
array(
'',
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
),
array(
'The quick brown fox jumps over the lazy dog',
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592',
),
array(
'The quick brown fox jumps over the lazy dog.',
'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c',
),
);
}
/**
* @dataProvider hmacData()
*/
public function testHMAC($key, $message, $result)
{
$this->assertHMACsTo($this->getInstance(), $key, $message, $result);
}
public static function hmacData()
{
return array(
// RFC 4231
// Test Case 1
array(
pack('H*', '0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b'),
pack('H*', '4869205468657265'),
'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7',
),
// Test Case 2
array(
pack('H*', '4a656665'),
pack('H*', '7768617420646f2079612077616e7420666f72206e6f7468696e673f'),
'5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843',
),
// Test Case 3
array(
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
pack('H*', 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd'),
'773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe',
),
// Test Case 4
array(
pack('H*', '0102030405060708090a0b0c0d0e0f10111213141516171819'),
pack('H*', 'cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd'),
'82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b',
),
);
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2014 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Hash;
class Unit_Crypt_Hash_SHA256_96Test extends Unit_Crypt_Hash_SHA256Test
{
public function getInstance()
{
return new Hash('sha256-96');
}
/**
* @dataProvider hashData()
*/
public function testHash($message, $longResult)
{
parent::testHash($message, substr($longResult, 0, 24));
}
/**
* @dataProvider hmacData()
*/
public function testHMAC($key, $message, $longResult)
{
parent::testHMAC($key, $message, substr($longResult, 0, 24));
}
}

View File

@ -0,0 +1,81 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2014 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Hash;
class Unit_Crypt_Hash_SHA512Test extends Unit_Crypt_Hash_TestCase
{
public function getInstance()
{
return new Hash('sha512');
}
/**
* @dataProvider hashData()
*/
public function testHash($message, $result)
{
$this->assertHashesTo($this->getInstance(), $message, $result);
}
public static function hashData()
{
return array(
array(
'',
'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'
),
array(
'The quick brown fox jumps over the lazy dog',
'07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6',
),
array(
'The quick brown fox jumps over the lazy dog.',
'91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed',
),
);
}
/**
* @dataProvider hmacData()
*/
public function testHMAC($key, $message, $result)
{
$this->assertHMACsTo($this->getInstance(), $key, $message, $result);
}
public static function hmacData()
{
return array(
// RFC 4231
// Test Case 1
array(
pack('H*', '0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b'),
pack('H*', '4869205468657265'),
'87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854',
),
// Test Case 2
array(
pack('H*', '4a656665'),
pack('H*', '7768617420646f2079612077616e7420666f72206e6f7468696e673f'),
'164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737',
),
// Test Case 3
array(
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
pack('H*', 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd'),
'fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb',
),
// Test Case 4
array(
pack('H*', '0102030405060708090a0b0c0d0e0f10111213141516171819'),
pack('H*', 'cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd'),
'b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd',
),
);
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2014 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Hash;
class Unit_Crypt_Hash_SHA512_96Test extends Unit_Crypt_Hash_SHA512Test
{
public function getInstance()
{
return new Hash('sha512-96');
}
/**
* @dataProvider hashData()
*/
public function testHash($message, $longResult)
{
parent::testHash($message, substr($longResult, 0, 24));
}
/**
* @dataProvider hmacData()
*/
public function testHMAC($key, $message, $longResult)
{
parent::testHMAC($key, $message, substr($longResult, 0, 24));
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2012 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Hash;
abstract class Unit_Crypt_Hash_TestCase extends PhpseclibTestCase
{
public static function setUpBeforeClass()
{
if (!defined('CRYPT_HASH_MODE')) {
define('CRYPT_HASH_MODE', Hash::MODE_INTERNAL);
}
}
public function setUp()
{
if (defined('CRYPT_HASH_MODE') && CRYPT_HASH_MODE !== Hash::MODE_INTERNAL) {
$this->markTestSkipped(
'Skipping test because CRYPT_HASH_MODE is not defined as \phpseclib\Crypt\Hash::MODE_INTERNAL.'
);
}
}
protected function assertHashesTo(Hash $hash, $message, $expected)
{
$this->assertEquals(
strtolower($expected),
bin2hex($hash->hash($message)),
sprintf("Failed asserting that '%s' hashes to '%s'.", $message, $expected)
);
}
protected function assertHMACsTo(Hash $hash, $key, $message, $expected)
{
$hash->setKey($key);
$this->assertEquals(
strtolower($expected),
bin2hex($hash->hash($message)),
sprintf(
"Failed asserting that '%s' HMACs to '%s' with key '%s'.",
$message,
$expected,
$key
)
);
}
}

View File

@ -1,423 +0,0 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2012 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\Hash;
class Unit_Crypt_HashTest extends PhpseclibTestCase
{
protected function assertHashesTo($hash, $message, $expected)
{
$hash = new Hash($hash);
$this->assertSame(
strtolower($expected),
bin2hex($hash->hash($message)),
sprintf("Failed asserting that '%s' hashes to '%s'.", $message, $expected)
);
}
protected function assertHMACsTo($hash, $key, $message, $expected)
{
$hash = new Hash($hash);
$hash->setKey($key);
$this->assertSame(
strtolower($expected),
bin2hex($hash->hash($message)),
sprintf(
"Failed asserting that '%s' HMACs to '%s' with key '%s'.",
$message,
$expected,
$key
)
);
}
public static function hashData()
{
return array(
array('md5', '', 'd41d8cd98f00b204e9800998ecf8427e'),
array('md5', 'The quick brown fox jumps over the lazy dog', '9e107d9d372bb6826bd81d3542a419d6'),
array('md5', 'The quick brown fox jumps over the lazy dog.', 'e4d909c290d0fb1ca068ffaddf22cbd0'),
array('sha1', 'The quick brown fox jumps over the lazy dog', '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12'),
array('sha1', 'The quick brown fox jumps over the lazy dog.', '408d94384216f890ff7a0c3528e8bed1e0b01621'),
array(
'sha256',
'',
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
),
array(
'sha256',
'The quick brown fox jumps over the lazy dog',
'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592',
),
array(
'sha256',
'The quick brown fox jumps over the lazy dog.',
'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c',
),
array(
'sha384',
'',
'38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b'
),
array(
'sha384',
'The quick brown fox jumps over the lazy dog',
'ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1',
),
array(
'sha512',
'',
'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e'
),
array(
'sha512',
'The quick brown fox jumps over the lazy dog',
'07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6',
),
array(
'sha512',
'The quick brown fox jumps over the lazy dog.',
'91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed',
),
array(
'whirlpool',
'The quick brown fox jumps over the lazy dog.',
'87a7ff096082e3ffeb86db10feb91c5af36c2c71bc426fe310ce662e0338223e217def0eab0b02b80eecf875657802bc5965e48f5c0a05467756f0d3f396faba'
),
array(
'whirlpool',
'The quick brown fox jumps over the lazy dog.',
'87a7ff096082e3ffeb86db10feb91c5af36c2c71bc426fe310ce662e0338223e217def0eab0b02b80eecf875657802bc5965e48f5c0a05467756f0d3f396faba'
),
array(
'whirlpool',
'The quick brown fox jumps over the lazy dog.',
'87a7ff096082e3ffeb86db10feb91c5af36c2c71bc426fe310ce662e0338223e217def0eab0b02b80eecf875657802bc5965e48f5c0a05467756f0d3f396faba'
),
// from http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA512_224.pdf
array(
'sha512/224',
'abc',
'4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa'
),
array(
'sha512/224',
'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu',
'23fec5bb94d60b23308192640b0c453335d664734fe40e7268674af9'
),
// from http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA512_256.pdf
array(
'sha512/256',
'abc',
'53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23'
),
array(
'sha512/256',
'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu',
'3928e184fb8690f840da3988121d31be65cb9d3ef83ee6146feac861e19b563a'
),
// from http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA224.pdf
array(
'sha224',
'abc',
'23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7'
),
array(
'sha224',
'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq',
'75388B16512776CC5DBA5DA1FD890150B0C6455CB4F58B1952522525'
),
);
}
/**
* @dataProvider hmacData()
*/
public function testHMAC($hash, $key, $message, $result)
{
$this->assertHMACsTo($hash, $key, $message, $result);
}
/**
* @dataProvider hmacData()
*/
public function testHMAC96($hash, $key, $message, $result)
{
$this->assertHMACsTo($hash . '-96', $key, $message, substr($result, 0, 24));
}
public static function hmacData()
{
return array(
array('md5', '', '', '74e6f7298a9c2d168935f58c001bad88'),
array('md5', 'key', 'The quick brown fox jumps over the lazy dog', '80070713463e7749b90c2dc24911e275'),
array(
'whirlpool',
'abcd',
'The quick brown fox jumps over the lazy dog',
'e71aabb2588d789292fa6fef00b35cc269ec3ea912b1c1cd7127daf95f004a5df5392ee563d322bac7e19d9eab161932fe9c257d63e0d09eca0d91ab4010125e',
),
// from https://tools.ietf.org/rfc/rfc4231.txt
// test case 1
array(
'sha224',
str_repeat("\x0b", 20),
'Hi There',
'896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22',
),
// test case 2
array(
'sha224',
'Jefe',
'what do ya want for nothing?',
'a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44',
),
// test case 3
array(
'sha224',
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
pack('H*', 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd'),
'7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea',
),
// test case 4
array(
'sha224',
pack('H*', '0102030405060708090a0b0c0d0e0f10111213141516171819'),
pack('H*', 'cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd'),
'6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a',
),
// skip test case 5; truncation is only supported to 96 bits (eg. sha1-96) and that's already unit tested
// test case 6
array(
'sha224',
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
'Test Using Larger Than Block-Size Key - Hash Key First',
'95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e',
),
// test case 7
array(
'sha224',
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
'This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.',
'3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1'
),
// test case 1
array(
'sha256',
str_repeat("\x0b", 20),
'Hi There',
'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7',
),
// test case 2
array(
'sha256',
'Jefe',
'what do ya want for nothing?',
'5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843',
),
// test case 3
array(
'sha256',
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
pack('H*', 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd'),
'773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe',
),
// test case 4
array(
'sha256',
pack('H*', '0102030405060708090a0b0c0d0e0f10111213141516171819'),
pack('H*', 'cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd'),
'82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b',
),
// skip test case 5; truncation is only supported to 96 bits (eg. sha1-96) and that's already unit tested
// test case 6
array(
'sha256',
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
'Test Using Larger Than Block-Size Key - Hash Key First',
'60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54',
),
// test case 7
array(
'sha256',
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
'This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.',
'9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2'
),
// test case 1
array(
'sha384',
str_repeat("\x0b", 20),
'Hi There',
'afd03944d84895626b0825f4ab46907f15f9dadbe4101ec682aa034c7cebc59cfaea9ea9076ede7f4af152e8b2fa9cb6',
),
// test case 2
array(
'sha384',
'Jefe',
'what do ya want for nothing?',
'af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649',
),
// test case 3
array(
'sha384',
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
pack('H*', 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd'),
'88062608d3e6ad8a0aa2ace014c8a86f0aa635d947ac9febe83ef4e55966144b2a5ab39dc13814b94e3ab6e101a34f27',
),
// test case 4
array(
'sha384',
pack('H*', '0102030405060708090a0b0c0d0e0f10111213141516171819'),
pack('H*', 'cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd'),
'3e8a69b7783c25851933ab6290af6ca77a9981480850009cc5577c6e1f573b4e6801dd23c4a7d679ccf8a386c674cffb',
),
// skip test case 5; truncation is only supported to 96 bits (eg. sha1-96) and that's already unit tested
// test case 6
array(
'sha384',
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
'Test Using Larger Than Block-Size Key - Hash Key First',
'4ece084485813e9088d2c63a041bc5b44f9ef1012a2b588f3cd11f05033ac4c60c2ef6ab4030fe8296248df163f44952',
),
// test case 7
array(
'sha384',
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
'This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.',
'6617178e941f020d351e2f254e8fd32c602420feb0b8fb9adccebb82461e99c5a678cc31e799176d3860e6110c46523e'
),
// test case 1
array(
'sha512',
str_repeat("\x0b", 20),
'Hi There',
'87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854',
),
// test case 2
array(
'sha512',
'Jefe',
'what do ya want for nothing?',
'164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737',
),
// test case 3
array(
'sha512',
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
pack('H*', 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd'),
'fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb',
),
// test case 4
array(
'sha512',
pack('H*', '0102030405060708090a0b0c0d0e0f10111213141516171819'),
pack('H*', 'cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd'),
'b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd',
),
// skip test case 5; truncation is only supported to 96 bits (eg. sha1-96) and that's already unit tested
// test case 6
array(
'sha512',
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
'Test Using Larger Than Block-Size Key - Hash Key First',
'80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598',
),
// test case 7
array(
'sha512',
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
'This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.',
'e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58'
),
);
}
/**
* @dataProvider hashData()
*/
public function testHash($hash, $message, $result)
{
$this->assertHashesTo($hash, $message, $result);
}
/**
* @dataProvider hashData()
*/
public function testHash96($hash, $message, $result)
{
$this->assertHashesTo($hash . '-96', $message, substr($result, 0, 24));
}
public function testConstructorDefault()
{
$hash = new Hash();
$this->assertSame($hash->getHash(), 'sha256');
}
/**
* @expectedException \phpseclib\Exception\UnsupportedAlgorithmException
*/
public function testConstructorArgumentInvalid()
{
new Hash('abcdefghijklmnopqrst');
}
public function testConstructorArgumentValid()
{
$hash = new Hash('whirlpool');
$this->assertSame($hash->getHash(), 'whirlpool');
}
/**
* @expectedException \phpseclib\Exception\UnsupportedAlgorithmException
*/
public function testSetHashInvalid()
{
$hash = new Hash('md5');
$hash->setHash('abcdefghijklmnopqrst-96');
}
public function testSetHashValid()
{
$hash = new Hash('md5');
$this->assertSame($hash->getHash(), 'md5');
$hash->setHash('sha1');
$this->assertSame($hash->getHash(), 'sha1');
}
/**
* @dataProvider lengths
*/
public function testGetLengthKnown($algorithm, $length)
{
$hash = new Hash($algorithm);
$this->assertSame($hash->getLength(), $length);
}
public function lengths()
{
return array(
// known
array('md5-96', 12),
array('md5', 16),
array('sha1', 20),
array('sha256', 32),
array('sha384', 48),
array('sha512', 64),
// unknown
array('whirlpool', 64),
);
}
}

View File

@ -110,11 +110,10 @@ class Unit_Crypt_RC2Test extends PhpseclibTestCase
*/
public function testVectors($engine, $engineName, $key, $keyLen, $plaintext, $ciphertext)
{
$rc2 = new RC2(RC2::MODE_CBC);
$rc2 = new RC2();
$rc2->disablePadding();
$rc2->setKeyLength($keyLen);
$rc2->setKey(pack('H*', $key)); // could also do $rc2->setKey(pack('H*', $key), $keyLen)
$rc2->setIV(str_repeat("\0", $rc2->getBlockLength() >> 3));
if (!$rc2->isValidEngine($engine)) {
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
}

View File

@ -1,34 +0,0 @@
<?php
/**
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2015 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use phpseclib\Crypt\RSA;
class Unit_Crypt_RSA_CreateKeyTest extends PhpseclibTestCase
{
public function testCreateKey()
{
extract(RSA::createKey(768));
$this->assertInstanceOf('\phpseclib\Crypt\RSA', $privatekey);
$this->assertInstanceOf('\phpseclib\Crypt\RSA', $publickey);
$this->assertNotEmpty("$privatekey");
$this->assertNotEmpty("$publickey");
return array($publickey, $privatekey);
}
/**
* @depends testCreateKey
*/
public function testEncryptDecrypt($args)
{
list($publickey, $privatekey) = $args;
$ciphertext = $publickey->encrypt('zzz');
$this->assertInternalType('string', $ciphertext);
$plaintext = $privatekey->decrypt($ciphertext);
$this->assertSame($plaintext, 'zzz');
}
}

View File

@ -6,9 +6,6 @@
*/
use phpseclib\Crypt\RSA;
use phpseclib\Crypt\RSA\PKCS1;
use phpseclib\Crypt\RSA\PuTTY;
use phpseclib\Math\BigInteger;
class Unit_Crypt_RSA_LoadKeyTest extends PhpseclibTestCase
{
@ -18,7 +15,7 @@ class Unit_Crypt_RSA_LoadKeyTest extends PhpseclibTestCase
$key = 'zzzzzzzzzzzzzz';
$this->assertFalse($rsa->load($key));
$this->assertFalse($rsa->loadKey($key));
}
public function testPKCS1Key()
@ -39,7 +36,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----';
$this->assertTrue($rsa->load($key));
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPrivateKey());
}
@ -62,7 +59,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
-----END RSA PRIVATE KEY-----';
$key = str_replace(array("\r", "\n", "\r\n"), ' ', $key);
$this->assertTrue($rsa->load($key));
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPrivateKey());
}
@ -82,7 +79,7 @@ X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
$this->assertTrue($rsa->load($key));
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPrivateKey());
}
@ -102,7 +99,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
'U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ' .
'37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
$this->assertTrue($rsa->load($key));
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPrivateKey());
}
@ -123,7 +120,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
'37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
$key = base64_decode($key);
$this->assertTrue($rsa->load($key));
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPrivateKey());
}
@ -162,7 +159,7 @@ GF/qoZyC1mbqdtyyeWgHtVbJVUORmpbNnXOII9duEqBUNDiO9VSZNn/8h/VsYeAB
xryZaRDVmtMuf/OZBQ==
-----END ENCRYPTED PRIVATE KEY-----';
$this->assertTrue($rsa->load($key));
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPrivateKey());
}
@ -185,12 +182,12 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
-----END RSA PRIVATE KEY-----';
$rsa->setPassword('password');
$this->assertTrue($rsa->load($key));
$this->assertTrue($rsa->loadKey($key));
$key = $rsa->getPrivateKey('PKCS8');
$key = $rsa->getPrivateKey(RSA::PRIVATE_FORMAT_PKCS8);
$this->assertInternalType('string', $key);
$this->assertTrue($rsa->load($key));
$this->assertTrue($rsa->loadKey($key));
}
public function testPubKey1()
@ -206,7 +203,7 @@ gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
-----END RSA PUBLIC KEY-----';
$this->assertTrue($rsa->load($key));
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPublicKey());
$this->assertFalse($rsa->getPrivateKey());
}
@ -225,7 +222,7 @@ lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26
ZQIDAQAB
-----END PUBLIC KEY-----';
$this->assertTrue($rsa->load($key));
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPublicKey());
$this->assertFalse($rsa->getPrivateKey());
}
@ -239,7 +236,7 @@ ZQIDAQAB
'GkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZw== ' .
'phpseclib-generated-key';
$this->assertTrue($rsa->load($key));
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPublicKey());
$this->assertFalse($rsa->getPrivateKey());
}
@ -255,7 +252,7 @@ ZQIDAQAB
'b6wYtY/q/WtUFr3nK+x0lgOtokhnJfRR/6fnmC1CztPnIT4BWK81VGKWONAxuhMyQ5XChyu6S9'.
'mWG5tUlUI/5';
$this->assertTrue($rsa->load($key));
$this->assertTrue($rsa->loadKey($key));
$this->assertSame($rsa->getPublicKeyFingerprint('md5'), 'bd:2c:2f:31:b9:ef:b8:f8:ad:fc:40:a6:94:4f:28:82');
$this->assertSame($rsa->getPublicKeyFingerprint('sha256'), 'N9sV2uSNZEe8TITODku0pRI27l+Zk0IY0TrRTw3ozwM');
}
@ -273,7 +270,7 @@ gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
-----END RSA PUBLIC KEY-----';
$this->assertTrue($rsa->load($key));
$this->assertTrue($rsa->loadKey($key));
$this->assertTrue($rsa->setPrivateKey());
$this->assertGreaterThanOrEqual(1, strlen("$rsa"));
$this->assertFalse($rsa->getPublicKey());
@ -293,11 +290,11 @@ Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
<Exponent>AQAB</Exponent>
</RSAKeyValue>';
$rsa->load($key);
$rsa->loadKey($key);
$rsa->setPublicKey();
$newkey = $rsa->getPublicKey('XML');
$newkey = $rsa->getPublicKey(RSA::PUBLIC_FORMAT_XML);
$this->assertSame(strtolower(preg_replace('#\s#', '', $key)), strtolower(preg_replace('#\s#', '', $newkey)));
$this->assertSame(preg_replace('#\s#', '', $key), preg_replace('#\s#', '', $newkey));
}
/**
@ -314,7 +311,7 @@ JWrQdxx/WNN+ABG426rgYYbeGcIlWLZCw6Bx/1HtN5ef6nVEoiGNChYKIRB4QFOi
01smFxps1w8ZIQnD6wIDAQAB
-----END PUBLIC KEY-----';
$rsa->load($key);
$rsa->loadKey($key);
$rsa->setPublicKey();
$newkey = $rsa->getPublicKey();
@ -345,162 +342,11 @@ qMnD/pkHR/NFcYSYShUJS0cHyryVl7/eCclsQlZTRdnVTtKF9xPGTQC8fK0G7BDN
Z2sKniRCcDT1ZP4=
-----END PRIVATE KEY-----';
$result = $rsa->load($key, 'PKCS8');
$result = $rsa->loadKey($key, RSA::PRIVATE_FORMAT_PKCS8);
$this->assertTrue($result);
}
public function testPKCS1EncryptionChange()
{
$rsa = new RSA();
$key = 'PuTTY-User-Key-File-2: ssh-rsa
Encryption: none
Comment: phpseclib-generated-key
Public-Lines: 4
AAAAB3NzaC1yc2EAAAADAQABAAAAgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4
eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RK
NUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDy
R4e9T04ZZw==
Private-Lines: 8
AAAAgBYo5KOevqhsjfDNEVcmkQF8/vsU6hwS4d7ceFYDLa0PlhIAo4aE8KNtyjAQ
LiRkmJ0ZqAWTN5TH0ynryJAInTxMb2AnZuXWKt106C5JC7+S9qSCFThTAxvihEpw
BVe5dnPnJ80TFtPm+n/JkdQic2bsVSy+kNNn7y4uef5m0mMRAAAAQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJ
rmfPwIGm63ilAAAAQQDEIvkdBvZtCvgHKitwxab+EQ/YxnNE5XvfIXjWE+xEL2br
oquF470c9Mm6jf/2zmn6yobE6UUvQ0O3hKSiyOAbAAAAQBGoiuSoSjafUhV7i1cE
Gpb88h5NBYZzWXGZ37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ
4p0=
Private-MAC: 03e2cb74e1d67652fbad063d2ed0478f31bdf256
';
$key = preg_replace('#(?<!\r)\n#', "\r\n", $key);
$this->assertTrue($rsa->load($key));
PKCS1::setEncryptionAlgorithm('AES-256-CBC');
$rsa->setPassword('demo');
$encryptedKey = (string) $rsa;
$this->assertRegExp('#AES-256-CBC#', $encryptedKey);
$rsa = new RSA();
$rsa->setPassword('demo');
$this->assertTrue($rsa->load($encryptedKey));
$rsa->setPassword();
$rsa->setPrivateKeyFormat('PuTTY');
$key2 = (string) $rsa;
$this->assertSame($key, $key2);
}
public function testRawKey()
{
$rsa = new RSA();
$key = array(
'e' => new BigInteger('10001', 16),
'n' => new BigInteger('aa18aba43b50deef38598faf87d2ab634e4571c130a9bca7b878267414faab8b471bd8965f5c9fc3' .
'818485eaf529c26246f3055064a8de19c8c338be5496cbaeb059dc0b358143b44a35449eb2641131' .
'21a455bd7fde3fac919e94b56fb9bb4f651cdb23ead439d6cd523eb08191e75b35fd13a7419b3090' .
'f24787bd4f4e1967', 16)
);
$this->assertTrue($rsa->load($key));
$rsa->setPublicKeyFormat('raw');
$this->assertEmpty("$rsa");
}
public function testRawComment()
{
$key = 'PuTTY-User-Key-File-2: ssh-rsa
Encryption: aes256-cbc
Comment: phpseclib-generated-key
Public-Lines: 4
AAAAB3NzaC1yc2EAAAADAQABAAAAgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4
eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RK
NUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDy
R4e9T04ZZw==
Private-Lines: 8
llx04QMegql0/nE5RvcJSrGrodxt6ytuv/JX2caeZBUyQwQc2WBNYagLHyHPM9jI
9OUWz59FLhjFXZMDNMoUXxVmjwQpOAaVPYNxxFM9AF6/NXFji64K7huD9n4A+kLn
sHwMLWPR5a/tZA0r05DZNz9ULA3mQu7Hz4EQ8ifu3uTPJuTmL51x6RmudYKysb20
fM8VzC3ukvzzRh0pujUVTr/yQdmciASVFnZlt4xQy+ZEOVUAOfwjd//AFfXTvk6x
7A45rNlU/uicHwLgoY1APvRHCFxw7F+uVW5L4mSX7NNzqBKkZ+1qpQTAfQvIfEIb
444+CXsgIyOpqt6VxJH2u6elAtE1wau3YaFR8Alm8m97rFYzRi3oDP5NZYkTCWSV
EOpSeghXSs7IilJu8I6/sB1w5dakdeBSFkIynrlFXkO0uUw+QJJWjxY8SypzgIuP
DzduF6XsQrCyo6dnIpGQCQ==
Private-MAC: 35134b7434bf828b21404099861d455e660e8740';
$raw = PuTTY::load($key, 'password');
$this->assertArrayHasKey('comment', $raw);
$this->assertEquals($raw['comment'], 'phpseclib-generated-key');
$rsa = new RSA();
$rsa->load($raw);
$this->assertGreaterThanOrEqual(1, strlen("$rsa"));
}
public function testPrivateMSBlob()
{
$key = 'BwIAAACkAABSU0EyAAQAAAEAAQAnh6FFs6kYe/gmb9dzqsQKmtjFE9mxNAe9mEU3OwOEEfyI' .
'wkAx0/8dwh12fuP4wzNbdZAq4mmqCE6Lo8wTNNIJVNYEhKq5chHg1+hPDgfETFgtEO54JZSg' .
'3cBZWEV/Tq3LHEX8CaLvHZxMEfFXbTfliFYMLoJ+YK1mpg9GYcmbrVmMAKSoOgETkkiJJzYm' .
'XftO3KOveBtvkAzjHxxSS1yP/Ba10BzeIleH96SbTuQtQRLXwRykdX9uazK+YsiSud9/PyLb' .
'gy5TI+o28OHq5P+0y5+a9IaAQ/92UwlrkHUYfhN/xTVlUIxKlTEdUQTIf+iHif8d4ABb3OdY' .
'JXZOW6fGeUP10jMyvbnrEoPDsYy9qfNk++0/8UP2NeO1IATszuZYg1nEXOW/5jmUxMCdiFyd' .
'p9ES211kpEZ4XcvjGaDlaQ+bLWj05i2m/9aHYcBrfcxxvlMa/9ZvrX4DfPWeydUDDDQ4+ntp' .
'T50BunSvmyf7cUk76Bf2sPgLXUQFoufEQ5g1Qo/v1uyhWBJzh6OSUO/DDXN/s8ec/tN05RQQ' .
'FZQ0na+v0hOCrV9IuRqtBuj4WAj1I/A1JjwyyP9Y/6yWFPM6EcS/6lyPy30lJPoULh7G29zk' .
'n7NVdTEkDtthdDjtX7Qhgd9qWvm5ADlmnvsS9A5m7ToOgQyOxtJoSlLitLbf/09LRycl/cdI' .
'zoMOCEdPe3DQcyEKqUPsghAq+DKw3uZpXwHzwTdfqlHSWAnHDggFKV1HZuWc1c4rV4k4b513TqE=';
$plaintext = 'zzz';
$privKey = new RSA();
$privKey->load($key);
$this->assertSame($privKey->getLoadedFormat(), 'MSBLOB');
$this->assertGreaterThanOrEqual(1, strlen("$privKey"));
$pubKey = new RSA();
$pubKey->load($privKey->getPublicKey('msblob'));
$this->assertGreaterThanOrEqual(1, strlen("$pubKey"));
$ciphertext = $pubKey->encrypt($plaintext);
$this->assertSame($privKey->decrypt($ciphertext), $plaintext);
}
public function testNakedOpenSSHKey()
{
$key = 'AAAAB3NzaC1yc2EAAAABIwAAAIEA/NcGSQFZ0ZgN1EbDusV6LLwLnQjs05ljKcVVP7Z6aKIJUyhUDHE30uJa5XfwPPBsZ3L3Q7S0yycVcuuHjdauugmpn9xx+gyoYs7UiV5G5rvxNcA/Tc+MofGhAMiTmNicorNAs5mv6fRoVbkpIONRXPz6WK0kjx/X04EV42Vm9Qk=';
$rsa = new RSA();
$rsa->load($key);
$this->assertSame($rsa->getLoadedFormat(), 'OpenSSH');
$this->assertGreaterThanOrEqual(1, strlen("$rsa"));
}
public function testPuttyPublicKey()
{
$key = '---- BEGIN SSH2 PUBLIC KEY ----
Comment: "rsa-key-20151023"
AAAAB3NzaC1yc2EAAAABJQAAAIEAhC/CSqJ+8vgeQ4H7fJru29h/McqAC9zdGzw0
9QsifLQ7s5MvXCavhjUPYIfV0KsdLQydNPLJcbKpXmpVD9azo61zLXwsYr8d1eHr
C/EwUYl8b0fAwEsEF3myb+ryzgA9ihY08Zs9NZdmt1Maa+I7lQcLX9F/65YdcAch
ILaEujU=
---- END SSH2 PUBLIC KEY ----';
$rsa = new RSA();
$rsa->load($key);
$this->assertSame($rsa->getLoadedFormat(), 'PuTTY');
$this->assertGreaterThanOrEqual(1, strlen("$rsa"));
}
/**
* @group github960
*/
@ -527,11 +373,11 @@ Private-MAC: 35134b7434bf828b21404099861d455e660e8740';
$rsa = new RSA();
$rsa->setPrivateKey($key);
$rsa->load($key);
$rsa->loadKey($key);
$rsa = new RSA();
$rsa->load($key);
$rsa->loadKey($key);
$rsa->setPrivateKey();
$rsa->load($rsa);
$rsa->loadKey($rsa);
}
}

View File

@ -6,7 +6,6 @@
*/
use phpseclib\Crypt\RSA;
use phpseclib\Math\BigInteger;
class Unit_Crypt_RSA_ModeTest extends PhpseclibTestCase
{
@ -29,19 +28,20 @@ X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----';
$rsa->load($privatekey);
$rsa->load($rsa->getPublicKey());
$rsa->loadKey($privatekey);
$rsa->loadKey($rsa->getPublicKey());
$rsa->setEncryptionMode(RSA::ENCRYPTION_NONE);
$expected = '105b92f59a87a8ad4da52c128b8c99491790ef5a54770119e0819060032fb9e772ed6772828329567f3d7e9472154c1530f8156ba7fd732f52ca1c06' .
'5a3f5ed8a96c442e4662e0464c97f133aed31262170201993085a589565d67cc9e727e0d087e3b225c8965203b271e38a499c92fc0d6502297eca712' .
'4d04bd467f6f1e7c';
$expected = pack('H*', $expected);
$result = $rsa->encrypt($plaintext, RSA::PADDING_NONE);
$result = $rsa->encrypt($plaintext);
$this->assertEquals($result, $expected);
$rsa->load($privatekey);
$this->assertEquals(trim($rsa->decrypt($result, RSA::PADDING_NONE), "\0"), $plaintext);
$rsa->loadKey($privatekey);
$this->assertEquals(trim($rsa->decrypt($result), "\0"), $plaintext);
}
/**
@ -50,9 +50,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
public function testPSSSigs()
{
$rsa = new RSA();
$rsa->setHash('sha1');
$rsa->setMGFHash('sha1');
$rsa->load('-----BEGIN PUBLIC KEY-----
$rsa->loadKey('-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVx
wTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFnc
CzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0T
@ -65,38 +63,4 @@ p0GbMJDyR4e9T04ZZwIDAQAB
$this->assertTrue($rsa->verify('zzzz', $sig));
}
/**
* @expectedException \OutOfBoundsException
*/
public function testSmallModulo()
{
$plaintext = 'x';
$n = new BigInteger(base64_decode('272435F22706FA96DE26E980D22DFF67'), 256);
$e = new BigInteger(base64_decode('158753FF2AF4D1E5BBAB574D5AE6B54D'), 256);
$rsa = new RSA();
$rsa->load(array('n' => $n, 'e' => $e));
$rsa->encrypt($plaintext);
}
public function testPKCS1LooseVerify()
{
$rsa = new RSA();
$rsa->load('-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAMuqkz8ij+ESAaNvgocVGmapjlrIldmhRo4h2NX4e6IXiCLTSxASQtY4
iqRnmyxqQSfaan2okTfQ6sP95bl8Qz8lgneW3ClC6RXG/wpJgsx7TXQ2kodlcKBF
m4k72G75QXhZ+I40ZG7cjBf1/9egakR0a0X0MpeOrKCzMBLv9+mpAgMBAAE=
-----END RSA PUBLIC KEY-----');
$message = base64_decode('MYIBLjAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNDA1MTUxNDM4MzRaMC8GCSqGSIb3DQEJBDEiBCBLzLIBGdOf0L2WRrIY' .
'9KTwiHnReBW48S9C7LNRaPp5mDCBwgYLKoZIhvcNAQkQAi8xgbIwga8wgawwgakEIJDB9ZGwihf+TaiwrHQNkNHkqbN8Nuws0e77QNObkvFZMIGEMHCkbjBs' .
'MQswCQYDVQQGEwJJVDEYMBYGA1UECgwPQXJ1YmFQRUMgUy5wLkEuMSEwHwYDVQQLDBhDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eUMxIDAeBgNVBAMMF0FydWJh' .
'UEVDIFMucC5BLiBORyBDQSAzAhAv4L3QcFssQNLDYN/Vu40R');
$sig = base64_decode('XDSZWw6IcUj8ICxRJf04HzF8stzoiFAZSR2a0Rw3ziZxTOT0/NVUYJO5+9TaaREXEgxuCLpgmA+6W2SWrrGoxbbNfaI90ZoKeOAws4IX+9RfiWuooibjKcvt' .
'GJYVVOCcjvQYxUUNbQ4EjCUonk3h7ECXfCCmWqbeq2LsyXeeYGE=');
$this->assertTrue($rsa->verify($message, $sig, RSA::PADDING_RELAXED_PKCS1));
}
}

View File

@ -104,13 +104,12 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase
*/
public function testVectors($engine, $engineName, $key, $plaintext, $expected)
{
$des = new TripleDES(TripleDES::MODE_CBC);
$des = new TripleDES();
if (!$des->isValidEngine($engine)) {
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
}
$des->setPreferredEngine($engine);
$des->setKey($key);
$des->setIV(str_repeat("\0", $des->getBlockLength() >> 3));
$des->disablePadding();
$result = $des->encrypt($plaintext);
$plaintext = bin2hex($plaintext);
@ -156,7 +155,7 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase
*/
public function testVectorsWithIV($engine, $engineName, $key, $iv, $plaintext, $expected)
{
$des = new TripleDES(TripleDES::MODE_CBC);
$des = new TripleDES();
if (!$des->isValidEngine($engine)) {
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
}
@ -177,7 +176,6 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase
$des = new TripleDES(TripleDES::MODE_3CBC);
$des->setKey('abcdefghijklmnopqrstuvwx');
$des->setIV(str_repeat("\0", $des->getBlockLength() >> 3));
foreach ($this->engines as $engine => $engineName) {
$des->setPreferredEngine($engine);

View File

@ -19,8 +19,7 @@ class Unit_Crypt_TwofishTest extends PhpseclibTestCase
);
foreach ($engines as $engine => $name) {
$tf = new Twofish(Twofish::MODE_CBC);
$tf->setIV(str_repeat("\0", $tf->getBlockLength() >> 3));
$tf = new Twofish();
$tf->disablePadding();
// tests from https://www.schneier.com/code/ecb_ival.txt

View File

@ -48,9 +48,10 @@ class Unit_File_X509_SPKACTest extends PhpseclibTestCase
{
$privKey = new RSA();
extract($privKey->createKey());
$privKey->loadKey($privatekey);
$x509 = new X509();
$x509->setPrivateKey($privatekey);
$x509->setPrivateKey($privKey);
$x509->setChallenge('...');
$spkac = $x509->signSPKAC();

View File

@ -154,7 +154,7 @@ IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==
public function testSaveNullRSAParam()
{
$privKey = new RSA();
$privKey->load('-----BEGIN RSA PRIVATE KEY-----
$privKey->loadKey('-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDMswfEpAgnUDWA74zZw5XcPsWh1ly1Vk99tsqwoFDkLF7jvXy1
dDLHYfuquvfxCgcp8k/4fQhx4ubR8bbGgEq9B05YRnViK0R0iBB5Ui4IaxWYYhKE
8xqAEH2fL+/7nsqqNFKkEN9KeFwc7WbMY49U2adlMrpBdRjk1DqIEW3QTwIDAQAB
@ -171,7 +171,7 @@ aBtsWpliLSex/HHhtRW9AkBGcq67zKmEpJ9kXcYLEjJii3flFS+Ct/rNm+Hhm1l7
-----END RSA PRIVATE KEY-----');
$pubKey = new RSA();
$pubKey->load($privKey->getPublicKey());
$pubKey->loadKey($privKey->getPublicKey());
$pubKey->setPublicKey();
$subject = new X509();

View File

@ -273,13 +273,29 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
$min = $this->getInstance(0);
$max = $this->getInstance('18446744073709551616');
$rand1 = \phpseclib\Math\BigInteger::random($min, $max);
$rand1 = $min->random($min, $max);
// technically $rand1 can equal $min but with the $min and $max we've
// chosen it's just not that likely
$this->assertTrue($rand1->compare($min) > 0);
$this->assertTrue($rand1->compare($max) < 0);
}
public function testRandomOneArgument()
{
$min = $this->getInstance(0);
$max = $this->getInstance('18446744073709551616');
$rand1 = $min->random($max);
$this->assertTrue($rand1->compare($min) > 0);
$this->assertTrue($rand1->compare($max) < 0);
$rand2 = $max->random($min);
$this->assertTrue($rand2->compare($min) > 0);
$this->assertTrue($rand2->compare($max) < 0);
$this->assertFalse($rand1->equals($rand2));
}
/**
* @group github279
*/
@ -315,8 +331,8 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
Code for generation of $alicePrivate and $bobPrivate.
$one = $this->getInstance(1);
$max = $one->bitwise_leftShift(512)->subtract($one);
$alicePrivate = \phpseclib\Math\BigInteger::random($one, $max);
$bobPrivate = \phpseclib\Math\BigInteger::random($one, $max);
$alicePrivate = $one->random($one, $max);
$bobPrivate = $one->random($one, $max);
var_dump($alicePrivate->toHex(), $bobPrivate->toHex());
*/
@ -353,21 +369,7 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
$num = $this->getInstance(50);
$str = print_r($num, true);
$this->assertContains('[value] => 0x32', $str);
}
public function testPrecision()
{
$a = $this->getInstance(51);
$this->assertSame($a->getPrecision(), -1);
$b = $a;
$c = clone $a;
$b->setPrecision(1);
$this->assertSame($a->getPrecision(), 1);
$this->assertSame("$a", '1');
$this->assertSame($b->getPrecision(), 1);
$this->assertSame("$b", '1');
$this->assertSame($c->getPrecision(), -1);
$this->assertSame("$c", '51');
return $str;
}
/**

View File

@ -110,18 +110,6 @@ class Unit_Net_SSH2Test extends PhpseclibTestCase
$this->assertFalse($ssh->isQuietModeEnabled());
}
public function testGetConnectionByResourceId()
{
$ssh = new \phpseclib\Net\SSH2('localhost');
$this->assertSame($ssh, \phpseclib\Net\SSH2::getConnectionByResourceId($ssh->getResourceId()));
}
public function testGetResourceId()
{
$ssh = new \phpseclib\Net\SSH2('localhost');
$this->assertSame('{' . spl_object_hash($ssh) . '}', $ssh->getResourceId());
}
/**
* @return \phpseclib\Net\SSH2
*/