mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-11-20 12:05:10 +00:00
Revert "Merge branch '2.0'"
This reverts commit be5f4ef6b19c82f6c898708cc8e1828b05e3d4e8, reversing
changes made to 638fe6971c
.
This commit is contained in:
parent
2cc5dcdc89
commit
b4cf10fc94
8
.gitattributes
vendored
8
.gitattributes
vendored
@ -1 +1,9 @@
|
||||
* text=auto
|
||||
/build/ export-ignore
|
||||
/tests/ export-ignore
|
||||
/travis/ export-ignore
|
||||
/.gitattributes export-ignore
|
||||
/.gitignore export-ignore
|
||||
/.travis.yml export-ignore
|
||||
/CHANGELOG.md export-ignore
|
||||
/phpunit.xml.dist export-ignore
|
||||
|
15
.travis.yml
15
.travis.yml
@ -1,13 +1,12 @@
|
||||
language: php
|
||||
|
||||
# When adding environments here, the number of runs specified in .scrutinizer.yml
|
||||
# may have to be adjusted.
|
||||
php:
|
||||
- 5.3.3
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.5.9
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- hhvm
|
||||
|
||||
env:
|
||||
@ -19,10 +18,16 @@ env:
|
||||
before_install: true
|
||||
|
||||
install:
|
||||
- sudo apt-get install parallel
|
||||
- wget http://ftp.gnu.org/gnu/parallel/parallel-20120522.tar.bz2
|
||||
- tar -xvjf parallel*
|
||||
- cd parallel*
|
||||
- ./configure
|
||||
- make
|
||||
- sudo make install
|
||||
- cd ..
|
||||
- eval `ssh-agent -s`
|
||||
- travis/setup-secure-shell.sh
|
||||
- sh -c "if [ '$TRAVIS_PHP_VERSION' != 'hhvm' ]; then travis/install-php-extensions.sh; fi"
|
||||
- sh -c "if [ '$TRAVIS_PHP_VERSION' != 'hhvm' -a '$TRAVIS_PHP_VERSION' != '7.0' ]; then travis/install-php-extensions.sh; fi"
|
||||
- travis/setup-composer.sh
|
||||
|
||||
script:
|
||||
|
1
AUTHORS
1
AUTHORS
@ -3,3 +3,4 @@ phpseclib Lead Developer: TerraFrost (Jim Wigginton)
|
||||
phpseclib Developers: monnerat (Patrick Monnerat)
|
||||
bantu (Andreas Fischer)
|
||||
petrich (Hans-Jürgen Petrich)
|
||||
GrahamCampbell (Graham Campbell)
|
||||
|
53
CHANGELOG.md
53
CHANGELOG.md
@ -1,5 +1,56 @@
|
||||
# Changelog
|
||||
|
||||
## 2.0.1 - 2016-01-18
|
||||
|
||||
- RSA: fix regression in PSS mode ([#769](https://github.com/phpseclib/phpseclib/pull/769))
|
||||
- RSA: fix issue loading PKCS8 specific keys ([#861](https://github.com/phpseclib/phpseclib/pull/861))
|
||||
- X509: add getOID() method ([#789](https://github.com/phpseclib/phpseclib/pull/789))
|
||||
- X509: improve base64-encoded detection rules ([#855](https://github.com/phpseclib/phpseclib/pull/855))
|
||||
- SFTP: fix quirky behavior with put() ([#830](https://github.com/phpseclib/phpseclib/pull/830))
|
||||
- SFTP: fix E_NOTICE ([#883](https://github.com/phpseclib/phpseclib/pull/883))
|
||||
- SFTP/Stream: fix issue with filenames with hashes ([#901](https://github.com/phpseclib/phpseclib/pull/901))
|
||||
- SSH2: add isAuthenticated() method ([#897](https://github.com/phpseclib/phpseclib/pull/897))
|
||||
- SSH/Agent: fix possible PHP warning ([#923](https://github.com/phpseclib/phpseclib/issues/923))
|
||||
- BigInteger: add __debugInfo() magic method ([#881](https://github.com/phpseclib/phpseclib/pull/881))
|
||||
- BigInteger: fix issue with doing bitwise not on 0
|
||||
- add getBlockLength() method to symmetric ciphers
|
||||
|
||||
## 2.0.0 - 2015-08-04
|
||||
|
||||
- Classes were renamed and namespaced ([#243](https://github.com/phpseclib/phpseclib/issues/243))
|
||||
- The use of an autoloader is now required (e.g. Composer)
|
||||
|
||||
## 1.0.1 - 2016-01-18
|
||||
|
||||
- RSA: fix regression in PSS mode ([#769](https://github.com/phpseclib/phpseclib/pull/769))
|
||||
- RSA: fix issue loading PKCS8 specific keys ([#861](https://github.com/phpseclib/phpseclib/pull/861))
|
||||
- X509: add getOID() method ([#789](https://github.com/phpseclib/phpseclib/pull/789))
|
||||
- X509: improve base64-encoded detection rules ([#855](https://github.com/phpseclib/phpseclib/pull/855))
|
||||
- SFTP: fix quirky behavior with put() ([#830](https://github.com/phpseclib/phpseclib/pull/830))
|
||||
- SFTP: fix E_NOTICE ([#883](https://github.com/phpseclib/phpseclib/pull/883))
|
||||
- SFTP/Stream: fix issue with filenames with hashes ([#901](https://github.com/phpseclib/phpseclib/pull/901))
|
||||
- SSH2: add isAuthenticated() method ([#897](https://github.com/phpseclib/phpseclib/pull/897))
|
||||
- SSH/Agent: fix possible PHP warning ([#923](https://github.com/phpseclib/phpseclib/issues/923))
|
||||
- BigInteger: add __debugInfo() magic method ([#881](https://github.com/phpseclib/phpseclib/pull/881))
|
||||
- BigInteger: fix issue with doing bitwise not on 0
|
||||
- add getBlockLength() method to symmetric ciphers
|
||||
|
||||
## 1.0.0 - 2015-08-02
|
||||
|
||||
- OpenSSL support for symmetric ciphers ([#507](https://github.com/phpseclib/phpseclib/pull/507))
|
||||
- rewritten vt100 terminal emulator (File_ANSI) ([#689](https://github.com/phpseclib/phpseclib/pull/689))
|
||||
- agent-forwarding support (System_SSH_Agent) ([#592](https://github.com/phpseclib/phpseclib/pull/592))
|
||||
- Net_SSH2 improvements
|
||||
- diffie-hellman-group-exchange-sha1/sha256 support ([#714](https://github.com/phpseclib/phpseclib/pull/714))
|
||||
- window size handling updates ([#717](https://github.com/phpseclib/phpseclib/pull/717))
|
||||
- Net_SFTP improvements
|
||||
- add callback support to put() ([#655](https://github.com/phpseclib/phpseclib/pull/655))
|
||||
- stat cache fixes ([#743](https://github.com/phpseclib/phpseclib/issues/743), [#730](https://github.com/phpseclib/phpseclib/issues/730), [#709](https://github.com/phpseclib/phpseclib/issues/709), [#726](https://github.com/phpseclib/phpseclib/issues/726))
|
||||
- add "none" encryption mode to Crypt_RSA ([#692](https://github.com/phpseclib/phpseclib/pull/692))
|
||||
- misc ASN.1 / X.509 parsing fixes ([#721](https://github.com/phpseclib/phpseclib/pull/721), [#627](https://github.com/phpseclib/phpseclib/pull/627))
|
||||
- use a random serial number for new X509 certs ([#740](https://github.com/phpseclib/phpseclib/pull/740))
|
||||
- add getPublicKeyFingerprint() to Crypt_RSA ([#677](https://github.com/phpseclib/phpseclib/pull/677))
|
||||
|
||||
## 0.3.10 - 2015-02-04
|
||||
|
||||
- simplify SSH2 window size handling ([#538](https://github.com/phpseclib/phpseclib/pull/538))
|
||||
@ -86,4 +137,4 @@
|
||||
= add support for AES-128-CBC and DES-EDE3-CFB encrypted RSA private keys
|
||||
- add Net_SFTP::stat(), Net_SFTP::lstat() and Net_SFTP::rawlist()
|
||||
- logging was added to Net_SSH1
|
||||
- the license was changed to the less restrictive MIT license
|
||||
- the license was changed to the less restrictive MIT license
|
||||
|
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
||||
Copyright 2007-2013 TerraFrost and other contributors
|
||||
Copyright 2007-2016 TerraFrost and other contributors
|
||||
http://phpseclib.sourceforge.net/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
|
10
README.md
10
README.md
@ -1,14 +1,14 @@
|
||||
# phpseclib - PHP Secure Communications Library
|
||||
|
||||
[![Build Status](https://secure.travis-ci.org/phpseclib/phpseclib.png?branch=2.0)](http://travis-ci.org/phpseclib/phpseclib)
|
||||
[![Build Status](https://travis-ci.org/phpseclib/phpseclib.svg?branch=master)](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,
|
||||
AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509
|
||||
|
||||
* [Download (0.3.10)](http://sourceforge.net/projects/phpseclib/files/phpseclib0.3.10.zip/download)
|
||||
* [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/php5/latest/)
|
||||
* [Code Coverage Report](http://phpseclib.bantux.org/code_coverage/master/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/2.0/) (generated by Sami)
|
||||
* [API Documentation](http://phpseclib.bantux.org/api/master/) (generated by Sami)
|
||||
|
||||
## Support
|
||||
|
||||
@ -40,7 +40,7 @@ Dependencies are managed via Composer.
|
||||
2. Install Dependencies
|
||||
|
||||
``` sh
|
||||
php composer.phar install --dev
|
||||
php composer.phar install
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
@ -43,9 +43,15 @@
|
||||
"name": "Hans-Jürgen Petrich",
|
||||
"email": "petrich@tronic-media.com",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Graham Campbell",
|
||||
"email": "graham@alt-three.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"paragonie/random_compat": "^1.4|^2.0",
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
@ -56,10 +62,10 @@
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
|
||||
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a wide variety of cryptographic operations.",
|
||||
"ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.",
|
||||
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
|
||||
"ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations."
|
||||
},
|
||||
"include-path": ["phpseclib/"],
|
||||
"autoload": {
|
||||
"files": [
|
||||
"phpseclib/bootstrap.php"
|
||||
|
626
composer.lock
generated
626
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -11,13 +11,13 @@
|
||||
* just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
|
||||
* to save one include_once().
|
||||
*
|
||||
* If {@link \phpseclib\Crypt\AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
|
||||
* {@link \phpseclib\Crypt\AES::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
|
||||
* it'll be null-padded to 192-bits and 192 bits will be the key length until {@link \phpseclib\Crypt\AES::setKey() setKey()}
|
||||
* If {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
|
||||
* {@link self::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
|
||||
* it'll be null-padded to 192-bits and 192 bits will be the key length until {@link self::setKey() setKey()}
|
||||
* is called, again, at which point, it'll be recalculated.
|
||||
*
|
||||
* Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, some functions are available to be called that, in the context of AES, don't
|
||||
* make a whole lot of sense. {@link \phpseclib\Crypt\AES::setBlockLength() setBlockLength()}, for instance. Calling that function,
|
||||
* make a whole lot of sense. {@link self::setBlockLength() setBlockLength()}, for instance. Calling that function,
|
||||
* however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
|
||||
*
|
||||
* Here's a short example of how to use this library:
|
||||
@ -49,8 +49,6 @@
|
||||
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
use phpseclib\Crypt\Rijndael;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of AES.
|
||||
*
|
||||
@ -67,31 +65,33 @@ class AES extends Rijndael
|
||||
*
|
||||
* @see \phpseclib\Crypt\Rijndael::setBlockLength()
|
||||
* @access public
|
||||
* @param Integer $length
|
||||
* @param int $length
|
||||
* @throws \BadMethodCallException anytime it's called
|
||||
*/
|
||||
function setBlockLength($length)
|
||||
{
|
||||
return;
|
||||
throw new \BadMethodCallException('The block length cannot be set for AES.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 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.
|
||||
* Valid key lengths are 128, 192, and 256. Set the link to bool(false) to disable a fixed key length
|
||||
*
|
||||
* @see \phpseclib\Crypt\Rijndael:setKeyLength()
|
||||
* @access public
|
||||
* @param Integer $length
|
||||
* @param int $length
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 160:
|
||||
$length = 192;
|
||||
case 128:
|
||||
case 192:
|
||||
case 256:
|
||||
break;
|
||||
case 224:
|
||||
$length = 256;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported');
|
||||
}
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
@ -104,25 +104,20 @@ class AES extends Rijndael
|
||||
* @see \phpseclib\Crypt\Rijndael:setKey()
|
||||
* @see setKeyLength()
|
||||
* @access public
|
||||
* @param String $key
|
||||
* @param string $key
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
parent::setKey($key);
|
||||
|
||||
if (!$this->explicit_key_length) {
|
||||
$length = strlen($key);
|
||||
switch (true) {
|
||||
case $length <= 16:
|
||||
$this->key_size = 16;
|
||||
break;
|
||||
case $length <= 24:
|
||||
$this->key_size = 24;
|
||||
break;
|
||||
default:
|
||||
$this->key_size = 32;
|
||||
}
|
||||
$this->_setEngine();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -37,8 +37,6 @@
|
||||
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
use phpseclib\Crypt\Base;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Blowfish.
|
||||
*
|
||||
@ -53,26 +51,16 @@ class Blowfish extends Base
|
||||
* Block Length of the cipher
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::block_size
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $block_size = 8;
|
||||
|
||||
/**
|
||||
* The default password key_size used by setPassword()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::password_key_size
|
||||
* @see \phpseclib\Crypt\Base::setPassword()
|
||||
* @var Integer
|
||||
* @access private
|
||||
*/
|
||||
var $password_key_size = 56;
|
||||
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'blowfish';
|
||||
@ -81,7 +69,7 @@ class Blowfish extends Base
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 500;
|
||||
@ -94,7 +82,7 @@ class Blowfish extends Base
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $sbox0 = array (
|
||||
var $sbox0 = array(
|
||||
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
|
||||
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
|
||||
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
||||
@ -277,53 +265,73 @@ class Blowfish extends Base
|
||||
/**
|
||||
* Holds the last used key
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $kl;
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
* The Key Length (in bytes)
|
||||
*
|
||||
* Keys can be of any length. Blowfish, itself, requires the use of a key between 32 and max. 448-bits long.
|
||||
* If the key is less than 32-bits we NOT fill the key to 32bit but let the key as it is to be compatible
|
||||
* with mcrypt because mcrypt act this way with blowfish key's < 32 bits.
|
||||
*
|
||||
* If the key is more than 448-bits, we trim the excess bits.
|
||||
*
|
||||
* If the key is not explicitly set, or empty, it'll be assumed a 128 bits key to be all null bytes.
|
||||
*
|
||||
* @access public
|
||||
* @see \phpseclib\Crypt\Base::setKey()
|
||||
* @param String $key
|
||||
* @see \phpseclib\Crypt\Base::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk
|
||||
* because the encryption / decryption / key schedule creation requires this number and not $key_length. We could
|
||||
* derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
||||
* of that, we'll just precompute it once.
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
$keylength = strlen($key);
|
||||
var $key_length = 16;
|
||||
|
||||
if (!$keylength) {
|
||||
$key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||
} elseif ($keylength > 56) {
|
||||
$key = substr($key, 0, 56);
|
||||
/**
|
||||
* 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::setKey($key);
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length.
|
||||
*
|
||||
* Key lengths can be between 32 and 448 bits.
|
||||
*
|
||||
* @access public
|
||||
* @param int $length
|
||||
*/
|
||||
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');
|
||||
}
|
||||
|
||||
$this->key_length = $length >> 3;
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for engine validity
|
||||
*
|
||||
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::isValidEngine()
|
||||
* @param Integer $engine
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
if ($engine == self::ENGINE_OPENSSL) {
|
||||
if (strlen($this->key) != 16) {
|
||||
if ($this->key_length != 16) {
|
||||
return false;
|
||||
}
|
||||
$this->cipher_name_openssl_ecb = 'bf-ecb';
|
||||
@ -393,8 +401,8 @@ class Blowfish extends Base
|
||||
* Encrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
@ -429,8 +437,8 @@ class Blowfish extends Base
|
||||
* Decrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
@ -471,9 +479,9 @@ class Blowfish extends Base
|
||||
$lambda_functions =& self::_getLambdaFunctions();
|
||||
|
||||
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
|
||||
// (Currently, for Crypt_Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit)
|
||||
// (Currently, for Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit)
|
||||
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
|
||||
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
|
||||
// Generation of a unique hash for our generated code
|
||||
$code_hash = "Crypt_Blowfish, {$this->mode}";
|
||||
|
@ -42,8 +42,6 @@
|
||||
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
use phpseclib\Crypt\Base;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of DES.
|
||||
*
|
||||
@ -64,7 +62,7 @@ class DES extends Base
|
||||
const ENCRYPT = 0;
|
||||
/**
|
||||
* Contains $keys[self::DECRYPT]
|
||||
*/
|
||||
*/
|
||||
const DECRYPT = 1;
|
||||
/**#@-*/
|
||||
|
||||
@ -72,36 +70,25 @@ class DES extends Base
|
||||
* Block Length of the cipher
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::block_size
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $block_size = 8;
|
||||
|
||||
/**
|
||||
* The Key
|
||||
* Key Length (in bytes)
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::key
|
||||
* @see setKey()
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $key = "\0\0\0\0\0\0\0\0";
|
||||
|
||||
/**
|
||||
* The default password key_size used by setPassword()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::password_key_size
|
||||
* @see \phpseclib\Crypt\Base::setPassword()
|
||||
* @var Integer
|
||||
* @access private
|
||||
*/
|
||||
var $password_key_size = 8;
|
||||
var $key_length = 8;
|
||||
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'des';
|
||||
@ -110,7 +97,7 @@ class DES extends Base
|
||||
* The OpenSSL names of the cipher / modes
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::openssl_mode_names
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $openssl_mode_names = array(
|
||||
@ -125,7 +112,7 @@ class DES extends Base
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 500;
|
||||
@ -135,9 +122,9 @@ class DES extends Base
|
||||
*
|
||||
* Used only if $engine == self::ENGINE_INTERNAL
|
||||
*
|
||||
* @see \phpseclib\Crypt\DES::_setupKey()
|
||||
* @see \phpseclib\Crypt\DES::_processBlock()
|
||||
* @var Integer
|
||||
* @see self::_setupKey()
|
||||
* @see self::_processBlock()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $des_rounds = 1;
|
||||
@ -145,17 +132,17 @@ class DES extends Base
|
||||
/**
|
||||
* max possible size of $key
|
||||
*
|
||||
* @see \phpseclib\Crypt\DES::setKey()
|
||||
* @var String
|
||||
* @see self::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key_size_max = 8;
|
||||
var $key_length_max = 8;
|
||||
|
||||
/**
|
||||
* The Key Schedule
|
||||
*
|
||||
* @see \phpseclib\Crypt\DES::_setupKey()
|
||||
* @var Array
|
||||
* @see self::_setupKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $keys;
|
||||
@ -167,9 +154,9 @@ class DES extends Base
|
||||
* with each byte containing all bits in the same state as the
|
||||
* corresponding bit in the index value.
|
||||
*
|
||||
* @see \phpseclib\Crypt\DES::_processBlock()
|
||||
* @see \phpseclib\Crypt\DES::_setupKey()
|
||||
* @var Array
|
||||
* @see self::_processBlock()
|
||||
* @see self::_setupKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $shuffle = array(
|
||||
@ -308,7 +295,7 @@ class DES extends Base
|
||||
*
|
||||
* Indexing this table with each source byte performs the initial bit permutation.
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $ipmap = array(
|
||||
@ -350,7 +337,7 @@ class DES extends Base
|
||||
* Inverse IP mapping helper table.
|
||||
* Indexing this table with a byte value reverses the bit order.
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $invipmap = array(
|
||||
@ -394,7 +381,7 @@ class DES extends Base
|
||||
* Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the
|
||||
* P table: concatenation can then be replaced by exclusive ORs.
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox1 = array(
|
||||
@ -419,7 +406,7 @@ class DES extends Base
|
||||
/**
|
||||
* Pre-permuted S-box2
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox2 = array(
|
||||
@ -444,7 +431,7 @@ class DES extends Base
|
||||
/**
|
||||
* Pre-permuted S-box3
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox3 = array(
|
||||
@ -469,7 +456,7 @@ class DES extends Base
|
||||
/**
|
||||
* Pre-permuted S-box4
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox4 = array(
|
||||
@ -494,7 +481,7 @@ class DES extends Base
|
||||
/**
|
||||
* Pre-permuted S-box5
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox5 = array(
|
||||
@ -519,7 +506,7 @@ class DES extends Base
|
||||
/**
|
||||
* Pre-permuted S-box6
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox6 = array(
|
||||
@ -544,7 +531,7 @@ class DES extends Base
|
||||
/**
|
||||
* Pre-permuted S-box7
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox7 = array(
|
||||
@ -569,7 +556,7 @@ class DES extends Base
|
||||
/**
|
||||
* Pre-permuted S-box8
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox8 = array(
|
||||
@ -591,19 +578,35 @@ 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
|
||||
*
|
||||
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::isValidEngine()
|
||||
* @param Integer $engine
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
if ($this->key_size_max == 8) {
|
||||
if ($this->key_length_max == 8) {
|
||||
if ($engine == self::ENGINE_OPENSSL) {
|
||||
$this->cipher_name_openssl_ecb = 'des-ecb';
|
||||
$this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode();
|
||||
@ -616,24 +619,18 @@ class DES extends Base
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* 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.
|
||||
* Keys must be 64-bits long or 8 bytes 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
|
||||
* @param string $key
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
// 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_size_max) {
|
||||
$key = substr($key, 0, $this->key_size_max);
|
||||
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');
|
||||
}
|
||||
|
||||
// Sets the key
|
||||
@ -645,10 +642,10 @@ class DES extends Base
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::_encryptBlock()
|
||||
* @see \phpseclib\Crypt\Base::encrypt()
|
||||
* @see \phpseclib\Crypt\DES::encrypt()
|
||||
* @see self::encrypt()
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
@ -660,10 +657,10 @@ class DES extends Base
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::_decryptBlock()
|
||||
* @see \phpseclib\Crypt\Base::decrypt()
|
||||
* @see \phpseclib\Crypt\DES::decrypt()
|
||||
* @see self::decrypt()
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
@ -677,12 +674,12 @@ class DES extends Base
|
||||
* {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
|
||||
* idea of what this function does.
|
||||
*
|
||||
* @see \phpseclib\Crypt\DES::_encryptBlock()
|
||||
* @see \phpseclib\Crypt\DES::_decryptBlock()
|
||||
* @see self::_encryptBlock()
|
||||
* @see self::_decryptBlock()
|
||||
* @access private
|
||||
* @param String $block
|
||||
* @param Integer $mode
|
||||
* @return String
|
||||
* @param string $block
|
||||
* @param int $mode
|
||||
* @return string
|
||||
*/
|
||||
function _processBlock($block, $mode)
|
||||
{
|
||||
@ -1310,8 +1307,8 @@ class DES extends Base
|
||||
$des_rounds = $this->des_rounds;
|
||||
|
||||
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
|
||||
// (Currently, for Crypt_DES, one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit)
|
||||
// (Currently, for Crypt_TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit)
|
||||
// (Currently, for DES, one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit)
|
||||
// (Currently, for TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit)
|
||||
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one
|
||||
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
|
||||
|
||||
|
@ -1,26 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
|
||||
* 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.
|
||||
*
|
||||
* 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 \phpseclib\Crypt\Hash::setKey() setKey()} is called, {@link \phpseclib\Crypt\Hash::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}.}}
|
||||
* If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will
|
||||
* return the HMAC as opposed to the hash.
|
||||
*
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $hash = new \phpseclib\Crypt\Hash('sha1');
|
||||
* $hash = new \phpseclib\Crypt\Hash('sha512');
|
||||
*
|
||||
* $hash->setKey('abcdefg');
|
||||
*
|
||||
@ -31,7 +24,9 @@
|
||||
* @category Crypt
|
||||
* @package Hash
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2007 Jim Wigginton
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2015 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
@ -39,66 +34,39 @@
|
||||
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
|
||||
*
|
||||
* @see \phpseclib\Crypt\Hash::setHash()
|
||||
* @var Integer
|
||||
* @see self::setHash()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $hashParam;
|
||||
|
||||
/**
|
||||
* Byte-length of compression blocks / key (Internal HMAC)
|
||||
*
|
||||
* @see \phpseclib\Crypt\Hash::setAlgorithm()
|
||||
* @var Integer
|
||||
* @access private
|
||||
*/
|
||||
var $b;
|
||||
|
||||
/**
|
||||
* Byte-length of hash output (Internal HMAC)
|
||||
*
|
||||
* @see \phpseclib\Crypt\Hash::setHash()
|
||||
* @var Integer
|
||||
* @see self::setHash()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $l = false;
|
||||
var $length;
|
||||
|
||||
/**
|
||||
* Hash Algorithm
|
||||
*
|
||||
* @see \phpseclib\Crypt\Hash::setHash()
|
||||
* @var String
|
||||
* @see self::setHash()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $hash;
|
||||
@ -106,17 +74,30 @@ class Hash
|
||||
/**
|
||||
* Key
|
||||
*
|
||||
* @see \phpseclib\Crypt\Hash::setKey()
|
||||
* @var String
|
||||
* @see self::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key = false;
|
||||
|
||||
/**
|
||||
* Initial Hash
|
||||
*
|
||||
* Used only for sha512/*
|
||||
*
|
||||
* @see self::_sha512()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $initial = false;
|
||||
|
||||
/**
|
||||
* Outer XOR (Internal HMAC)
|
||||
*
|
||||
* @see \phpseclib\Crypt\Hash::setKey()
|
||||
* @var String
|
||||
* Used only for sha512/*
|
||||
*
|
||||
* @see self::hash()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $opad;
|
||||
@ -124,8 +105,10 @@ class Hash
|
||||
/**
|
||||
* Inner XOR (Internal HMAC)
|
||||
*
|
||||
* @see \phpseclib\Crypt\Hash::setKey()
|
||||
* @var String
|
||||
* Used only for sha512/*
|
||||
*
|
||||
* @see self::hash()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $ipad;
|
||||
@ -133,26 +116,15 @@ class Hash
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @param optional String $hash
|
||||
* @return \phpseclib\Crypt\Hash
|
||||
* @param string $hash
|
||||
* @access public
|
||||
*/
|
||||
function __construct($hash = 'sha1')
|
||||
function __construct($hash = 'sha256')
|
||||
{
|
||||
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->setHash($hash);
|
||||
|
||||
$this->ipad = str_repeat(chr(0x36), 128);
|
||||
$this->opad = str_repeat(chr(0x5C), 128);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -161,7 +133,7 @@ class Hash
|
||||
* Keys can be of any length.
|
||||
*
|
||||
* @access public
|
||||
* @param optional String $key
|
||||
* @param string $key
|
||||
*/
|
||||
function setKey($key = false)
|
||||
{
|
||||
@ -174,7 +146,7 @@ class Hash
|
||||
* As set by the constructor or by the setHash() method.
|
||||
*
|
||||
* @access public
|
||||
* @return String
|
||||
* @return string
|
||||
*/
|
||||
function getHash()
|
||||
{
|
||||
@ -185,405 +157,146 @@ class Hash
|
||||
* Sets the hash function.
|
||||
*
|
||||
* @access public
|
||||
* @param String $hash
|
||||
* @param string $hash
|
||||
*/
|
||||
function setHash($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->l = 12; // 96 / 8 = 12
|
||||
$this->length = 12; // 96 / 8 = 12
|
||||
break;
|
||||
case 'md2':
|
||||
case 'md5':
|
||||
$this->l = 16;
|
||||
$this->length = 16;
|
||||
break;
|
||||
case 'sha1':
|
||||
$this->l = 20;
|
||||
$this->length = 20;
|
||||
break;
|
||||
case 'sha512/224':
|
||||
$this->length = 28;
|
||||
break;
|
||||
case 'sha256':
|
||||
$this->l = 32;
|
||||
case 'sha512/256':
|
||||
$this->length = 32;
|
||||
break;
|
||||
case 'sha384':
|
||||
$this->l = 48;
|
||||
$this->length = 48;
|
||||
break;
|
||||
case 'sha512':
|
||||
$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;
|
||||
$this->length = 64;
|
||||
break;
|
||||
default:
|
||||
$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;
|
||||
// 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;
|
||||
}
|
||||
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';
|
||||
// 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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
throw new UnsupportedAlgorithmException(
|
||||
"$hash is not a supported algorithm"
|
||||
);
|
||||
}
|
||||
|
||||
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');
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
$this->ipad = str_repeat(chr(0x36), $this->b);
|
||||
$this->opad = str_repeat(chr(0x5C), $this->b);
|
||||
$this->hash = $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the HMAC.
|
||||
*
|
||||
* @access public
|
||||
* @param String $text
|
||||
* @return String
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
function hash($text)
|
||||
{
|
||||
$mode = is_array($this->hash) ? self::MODE_INTERNAL : CRYPT_HASH_MODE;
|
||||
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."
|
||||
|
||||
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."
|
||||
-- http://tools.ietf.org/html/rfc2104#section-2 */
|
||||
$key = strlen($this->key) > $this->b ? self::_sha512($this->key, $this->initial) : $this->key;
|
||||
|
||||
-- http://tools.ietf.org/html/rfc2104#section-2 */
|
||||
$key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
|
||||
$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
|
||||
|
||||
$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);
|
||||
}
|
||||
return substr($output, 0, $this->length);
|
||||
}
|
||||
$output = !empty($this->key) || is_string($this->key) ?
|
||||
hash_hmac($this->hash, $text, $this->key, true) :
|
||||
hash($this->hash, $text, true);
|
||||
|
||||
return substr($output, 0, $this->l);
|
||||
return strlen($output) > $this->length
|
||||
? substr($output, 0, $this->length)
|
||||
: $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash length (in bytes)
|
||||
*
|
||||
* @access public
|
||||
* @return Integer
|
||||
* @return int
|
||||
*/
|
||||
function getLength()
|
||||
{
|
||||
return $this->l;
|
||||
return $this->length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for MD5
|
||||
* Pure-PHP implementation of SHA512
|
||||
*
|
||||
* @access private
|
||||
* @param String $m
|
||||
* @param string $m
|
||||
*/
|
||||
function _md5($m)
|
||||
static function _sha512($m, $hash)
|
||||
{
|
||||
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;
|
||||
static $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(
|
||||
@ -614,8 +327,6 @@ 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
|
||||
@ -629,7 +340,7 @@ class Hash
|
||||
foreach ($chunks as $chunk) {
|
||||
$w = array();
|
||||
for ($i = 0; $i < 16; $i++) {
|
||||
$temp = new BigInteger($this->_string_shift($chunk, 8), 256);
|
||||
$temp = new BigInteger(self::_string_shift($chunk, 8), 256);
|
||||
$temp->setPrecision(64);
|
||||
$w[] = $temp;
|
||||
}
|
||||
@ -650,21 +361,21 @@ class Hash
|
||||
);
|
||||
$s1 = $temp[0]->bitwise_xor($temp[1]);
|
||||
$s1 = $s1->bitwise_xor($temp[2]);
|
||||
$w[$i] = $w[$i - 16]->copy();
|
||||
$w[$i] = clone $w[$i - 16];
|
||||
$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 = $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();
|
||||
$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];
|
||||
|
||||
// Main loop
|
||||
for ($i = 0; $i < 80; $i++) {
|
||||
@ -701,13 +412,13 @@ class Hash
|
||||
$t1 = $t1->add($k[$i]);
|
||||
$t1 = $t1->add($w[$i]);
|
||||
|
||||
$h = $g->copy();
|
||||
$g = $f->copy();
|
||||
$f = $e->copy();
|
||||
$h = clone $g;
|
||||
$g = clone $f;
|
||||
$f = clone $e;
|
||||
$e = $d->add($t1);
|
||||
$d = $c->copy();
|
||||
$c = $b->copy();
|
||||
$b = $a->copy();
|
||||
$d = clone $c;
|
||||
$c = clone $b;
|
||||
$b = clone $a;
|
||||
$a = $t1->add($t2);
|
||||
}
|
||||
|
||||
@ -727,96 +438,22 @@ 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();
|
||||
if ($this->l != 48) {
|
||||
$temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
|
||||
}
|
||||
$hash[4]->toBytes() . $hash[5]->toBytes() . $hash[6]->toBytes() . $hash[7]->toBytes();
|
||||
|
||||
return $temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Right Rotate
|
||||
*
|
||||
* @access private
|
||||
* @param Integer $int
|
||||
* @param Integer $amt
|
||||
* @see _sha256()
|
||||
* @return Integer
|
||||
*/
|
||||
function _rightRotate($int, $amt)
|
||||
{
|
||||
$invamt = 32 - $amt;
|
||||
$mask = (1 << $invamt) - 1;
|
||||
return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Right Shift
|
||||
*
|
||||
* @access private
|
||||
* @param Integer $int
|
||||
* @param Integer $amt
|
||||
* @see _sha256()
|
||||
* @return Integer
|
||||
*/
|
||||
function _rightShift($int, $amt)
|
||||
{
|
||||
$mask = (1 << (32 - $amt)) - 1;
|
||||
return ($int >> $amt) & $mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not
|
||||
*
|
||||
* @access private
|
||||
* @param Integer $int
|
||||
* @see _sha256()
|
||||
* @return Integer
|
||||
*/
|
||||
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 Integer $...
|
||||
* @return Integer
|
||||
* @see _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
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param String $string
|
||||
* @param optional Integer $index
|
||||
* @return String
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function _string_shift(&$string, $index = 1)
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
|
@ -35,8 +35,6 @@
|
||||
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
use phpseclib\Crypt\Base;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of RC2.
|
||||
*
|
||||
@ -49,7 +47,7 @@ class RC2 extends Base
|
||||
* Block Length of the cipher
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::block_size
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $block_size = 8;
|
||||
@ -58,8 +56,8 @@ class RC2 extends Base
|
||||
* The Key
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::key
|
||||
* @see setKey()
|
||||
* @var String
|
||||
* @see self::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key;
|
||||
@ -68,29 +66,37 @@ class RC2 extends Base
|
||||
* The Original (unpadded) Key
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::key
|
||||
* @see setKey()
|
||||
* @see encrypt()
|
||||
* @see decrypt()
|
||||
* @var String
|
||||
* @see self::setKey()
|
||||
* @see self::encrypt()
|
||||
* @see self::decrypt()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $orig_key;
|
||||
|
||||
/**
|
||||
* The default password key_size used by setPassword()
|
||||
* Don't truncate / null pad key
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::password_key_size
|
||||
* @see \phpseclib\Crypt\Base::setPassword()
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::_clearBuffers()
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $password_key_size = 16; // = 128 bits
|
||||
var $skip_key_adjustment = true;
|
||||
|
||||
/**
|
||||
* Key Length (in bytes)
|
||||
*
|
||||
* @see \phpseclib\Crypt\RC2::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $key_length = 16; // = 128 bits
|
||||
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'rc2';
|
||||
@ -99,7 +105,7 @@ class RC2 extends Base
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 500;
|
||||
@ -107,9 +113,9 @@ class RC2 extends Base
|
||||
/**
|
||||
* The key length in bits.
|
||||
*
|
||||
* @see \phpseclib\Crypt\RC2::setKeyLength()
|
||||
* @see \phpseclib\Crypt\RC2::setKey()
|
||||
* @var Integer
|
||||
* @see self::setKeyLength()
|
||||
* @see self::setKey()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal Should be in range [1..1024].
|
||||
* @internal Changing this value after setting the key has no effect.
|
||||
@ -119,9 +125,9 @@ class RC2 extends Base
|
||||
/**
|
||||
* The key length in bits.
|
||||
*
|
||||
* @see \phpseclib\Crypt\RC2::isValidEnine()
|
||||
* @see \phpseclib\Crypt\RC2::setKey()
|
||||
* @var Integer
|
||||
* @see self::isValidEnine()
|
||||
* @see self::setKey()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal Should be in range [1..1024].
|
||||
*/
|
||||
@ -130,8 +136,8 @@ class RC2 extends Base
|
||||
/**
|
||||
* The Key Schedule
|
||||
*
|
||||
* @see \phpseclib\Crypt\RC2::_setupKey()
|
||||
* @var Array
|
||||
* @see self::_setupKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $keys;
|
||||
@ -140,8 +146,8 @@ class RC2 extends Base
|
||||
* Key expansion randomization table.
|
||||
* Twice the same 256-value sequence to save a modulus in key expansion.
|
||||
*
|
||||
* @see \phpseclib\Crypt\RC2::setKey()
|
||||
* @var Array
|
||||
* @see self::setKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $pitable = array(
|
||||
@ -214,8 +220,8 @@ class RC2 extends Base
|
||||
/**
|
||||
* Inverse key expansion randomization table.
|
||||
*
|
||||
* @see \phpseclib\Crypt\RC2::setKey()
|
||||
* @var Array
|
||||
* @see self::setKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $invpitable = array(
|
||||
@ -253,21 +259,37 @@ 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
|
||||
*
|
||||
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::Crypt_Base()
|
||||
* @param Integer $engine
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
switch ($engine) {
|
||||
case self::ENGINE_OPENSSL:
|
||||
if ($this->current_key_length != 128 || strlen($this->orig_key) != 16) {
|
||||
if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) {
|
||||
return false;
|
||||
}
|
||||
$this->cipher_name_openssl_ecb = 'rc2-ecb';
|
||||
@ -278,26 +300,40 @@ class RC2 extends Base
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length
|
||||
* Sets the key length.
|
||||
*
|
||||
* Valid key lengths are 1 to 1024.
|
||||
* Valid key lengths are 8 to 1024.
|
||||
* Calling this function after setting the key has no effect until the next
|
||||
* \phpseclib\Crypt\RC2::setKey() call.
|
||||
*
|
||||
* @access public
|
||||
* @param Integer $length in bits
|
||||
* @param int $length in bits
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
if ($length >= 1 && $length <= 1024) {
|
||||
$this->default_key_length = $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');
|
||||
}
|
||||
|
||||
$this->default_key_length = $this->current_key_length = $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current key length
|
||||
*
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
function getKeyLength()
|
||||
{
|
||||
return $this->current_key_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Keys can be of any length. RC2, itself, uses 1 to 1024 bit keys (eg.
|
||||
* Keys can be of any length. RC2, itself, uses 8 to 1024 bit keys (eg.
|
||||
* strlen($key) <= 128), however, we only use the first 128 bytes if $key
|
||||
* has more then 128 bytes in it, and set $key to a single null byte if
|
||||
* it is empty.
|
||||
@ -307,18 +343,22 @@ class RC2 extends Base
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::setKey()
|
||||
* @access public
|
||||
* @param String $key
|
||||
* @param Integer $t1 optional Effective key length in bits.
|
||||
* @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 = 0)
|
||||
function setKey($key, $t1 = false)
|
||||
{
|
||||
$this->orig_key = $key;
|
||||
|
||||
if ($t1 <= 0) {
|
||||
if ($t1 === false) {
|
||||
$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";
|
||||
@ -349,18 +389,19 @@ class RC2 extends Base
|
||||
// Prepare the key for mcrypt.
|
||||
$l[0] = $this->invpitable[$l[0]];
|
||||
array_unshift($l, 'C*');
|
||||
|
||||
parent::setKey(call_user_func_array('pack', $l));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a message.
|
||||
*
|
||||
* Mostly a wrapper for Crypt_Base::encrypt, with some additional OpenSSL handling code
|
||||
* Mostly a wrapper for \phpseclib\Crypt\Base::encrypt, with some additional OpenSSL handling code
|
||||
*
|
||||
* @see decrypt()
|
||||
* @see self::decrypt()
|
||||
* @access public
|
||||
* @param String $plaintext
|
||||
* @return String $ciphertext
|
||||
* @param string $plaintext
|
||||
* @return string $ciphertext
|
||||
*/
|
||||
function encrypt($plaintext)
|
||||
{
|
||||
@ -378,12 +419,12 @@ class RC2 extends Base
|
||||
/**
|
||||
* Decrypts a message.
|
||||
*
|
||||
* Mostly a wrapper for Crypt_Base::decrypt, with some additional OpenSSL handling code
|
||||
* Mostly a wrapper for \phpseclib\Crypt\Base::decrypt, with some additional OpenSSL handling code
|
||||
*
|
||||
* @see encrypt()
|
||||
* @see self::encrypt()
|
||||
* @access public
|
||||
* @param String $ciphertext
|
||||
* @return String $plaintext
|
||||
* @param string $ciphertext
|
||||
* @return string $plaintext
|
||||
*/
|
||||
function decrypt($ciphertext)
|
||||
{
|
||||
@ -395,7 +436,7 @@ class RC2 extends Base
|
||||
return $result;
|
||||
}
|
||||
|
||||
return parent::encrypt($ciphertext);
|
||||
return parent::decrypt($ciphertext);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -404,8 +445,8 @@ class RC2 extends Base
|
||||
* @see \phpseclib\Crypt\Base::_encryptBlock()
|
||||
* @see \phpseclib\Crypt\Base::encrypt()
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
@ -449,8 +490,8 @@ class RC2 extends Base
|
||||
* @see \phpseclib\Crypt\Base::_decryptBlock()
|
||||
* @see \phpseclib\Crypt\Base::decrypt()
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
@ -538,7 +579,7 @@ class RC2 extends Base
|
||||
// for the mixing rounds, for better inline crypt performance [~20% faster].
|
||||
// But for memory reason we have to limit those ultra-optimized $lambda_functions to an amount of 10.
|
||||
// (Currently, for Crypt_RC2, one generated $lambda_function cost on php5.5@32bit ~60kb unfreeable mem and ~100kb on php5.5@64bit)
|
||||
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
|
||||
// Generation of a uniqe hash for our generated code
|
||||
$code_hash = "Crypt_RC2, {$this->mode}";
|
||||
|
@ -44,8 +44,6 @@
|
||||
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
use phpseclib\Crypt\Base;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of RC4.
|
||||
*
|
||||
@ -70,26 +68,25 @@ class RC4 extends Base
|
||||
* so we the block_size to 0
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::block_size
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $block_size = 0;
|
||||
|
||||
/**
|
||||
* The default password key_size used by setPassword()
|
||||
* Key Length (in bytes)
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::password_key_size
|
||||
* @see \phpseclib\Crypt\Base::setPassword()
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\RC4::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $password_key_size = 128; // = 1024 bits
|
||||
var $key_length = 128; // = 1024 bits
|
||||
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'arcfour';
|
||||
@ -106,8 +103,8 @@ class RC4 extends Base
|
||||
/**
|
||||
* The Key
|
||||
*
|
||||
* @see \phpseclib\Crypt\RC4::setKey()
|
||||
* @var String
|
||||
* @see self::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key = "\0";
|
||||
@ -115,8 +112,8 @@ class RC4 extends Base
|
||||
/**
|
||||
* The Key Stream for decryption and encryption
|
||||
*
|
||||
* @see \phpseclib\Crypt\RC4::setKey()
|
||||
* @var Array
|
||||
* @see self::setKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $stream;
|
||||
@ -124,8 +121,6 @@ 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
|
||||
@ -138,12 +133,12 @@ class RC4 extends Base
|
||||
/**
|
||||
* Test for engine validity
|
||||
*
|
||||
* This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see Crypt_Base::Crypt_Base()
|
||||
* @param Integer $engine
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
@ -168,51 +163,63 @@ class RC4 extends Base
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy function.
|
||||
* RC4 does not use an IV
|
||||
*
|
||||
* 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 \phpseclib\Crypt\RC4::setKey()
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function setIV($iv)
|
||||
function usesIV()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
* Sets the key length
|
||||
*
|
||||
* Keys can be between 1 and 256 bytes long. If they are longer then 256 bytes, the first 256 bytes will
|
||||
* be used. If no key is explicitly set, it'll be assumed to be a single null byte.
|
||||
* Keys can be between 1 and 256 bytes long.
|
||||
*
|
||||
* @access public
|
||||
* @see \phpseclib\Crypt\Base::setKey()
|
||||
* @param String $key
|
||||
* @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');
|
||||
}
|
||||
|
||||
$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)
|
||||
{
|
||||
parent::setKey(substr($key, 0, 256));
|
||||
$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.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::decrypt()
|
||||
* @see \phpseclib\Crypt\RC4::_crypt()
|
||||
* @see self::_crypt()
|
||||
* @access public
|
||||
* @param String $plaintext
|
||||
* @return String $ciphertext
|
||||
* @param string $plaintext
|
||||
* @return string $ciphertext
|
||||
*/
|
||||
function encrypt($plaintext)
|
||||
{
|
||||
@ -229,10 +236,10 @@ class RC4 extends Base
|
||||
* At least if the continuous buffer is disabled.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::encrypt()
|
||||
* @see \phpseclib\Crypt\RC4::_crypt()
|
||||
* @see self::_crypt()
|
||||
* @access public
|
||||
* @param String $ciphertext
|
||||
* @return String $plaintext
|
||||
* @param string $ciphertext
|
||||
* @return string $plaintext
|
||||
*/
|
||||
function decrypt($ciphertext)
|
||||
{
|
||||
@ -246,7 +253,7 @@ class RC4 extends Base
|
||||
* Encrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @param string $in
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
@ -257,7 +264,7 @@ class RC4 extends Base
|
||||
* Decrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @param string $in
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
@ -294,12 +301,12 @@ class RC4 extends Base
|
||||
/**
|
||||
* Encrypts or decrypts a message.
|
||||
*
|
||||
* @see \phpseclib\Crypt\RC4::encrypt()
|
||||
* @see \phpseclib\Crypt\RC4::decrypt()
|
||||
* @see self::encrypt()
|
||||
* @see self::decrypt()
|
||||
* @access private
|
||||
* @param String $text
|
||||
* @param Integer $mode
|
||||
* @return String $text
|
||||
* @param string $text
|
||||
* @param int $mode
|
||||
* @return string $text
|
||||
*/
|
||||
function _crypt($text, $mode)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
223
phpseclib/Crypt/RSA/MSBLOB.php
Normal file
223
phpseclib/Crypt/RSA/MSBLOB.php
Normal file
@ -0,0 +1,223 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
485
phpseclib/Crypt/RSA/PKCS.php
Normal file
485
phpseclib/Crypt/RSA/PKCS.php
Normal file
@ -0,0 +1,485 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
172
phpseclib/Crypt/RSA/PKCS1.php
Normal file
172
phpseclib/Crypt/RSA/PKCS1.php
Normal file
@ -0,0 +1,172 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
208
phpseclib/Crypt/RSA/PKCS8.php
Normal file
208
phpseclib/Crypt/RSA/PKCS8.php
Normal file
@ -0,0 +1,208 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
311
phpseclib/Crypt/RSA/PuTTY.php
Normal file
311
phpseclib/Crypt/RSA/PuTTY.php
Normal file
@ -0,0 +1,311 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
103
phpseclib/Crypt/RSA/Raw.php
Normal file
103
phpseclib/Crypt/RSA/Raw.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
146
phpseclib/Crypt/RSA/XML.php
Normal file
146
phpseclib/Crypt/RSA/XML.php
Normal file
@ -0,0 +1,146 @@
|
||||
<?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>';
|
||||
}
|
||||
}
|
@ -24,14 +24,6 @@
|
||||
|
||||
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
|
||||
*
|
||||
@ -48,56 +40,23 @@ class Random
|
||||
* microoptimizations because this function has the potential of being called a huge number of times.
|
||||
* eg. for RSA key generation.
|
||||
*
|
||||
* @param Integer $length
|
||||
* @return String
|
||||
* @param int $length
|
||||
* @throws \RuntimeException if a symmetric cipher is needed but not loaded
|
||||
* @return string
|
||||
*/
|
||||
public static function string($length)
|
||||
static function string($length)
|
||||
{
|
||||
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 (function_exists('mcrypt_create_iv') && 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 (function_exists('openssl_random_pseudo_bytes') && version_compare(PHP_VERSION, '5.3.4', '>=')) {
|
||||
return openssl_random_pseudo_bytes($length);
|
||||
}
|
||||
} else {
|
||||
// method 1. the fastest
|
||||
if (function_exists('openssl_random_pseudo_bytes')) {
|
||||
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 (function_exists('mcrypt_create_iv')) {
|
||||
return mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
|
||||
}
|
||||
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.
|
||||
}
|
||||
// at this point we have no choice but to use a pure-PHP CSPRNG
|
||||
|
||||
@ -135,13 +94,13 @@ class Random
|
||||
session_start();
|
||||
|
||||
$v = $seed = $_SESSION['seed'] = pack('H*', sha1(
|
||||
serialize($_SERVER) .
|
||||
serialize($_POST) .
|
||||
serialize($_GET) .
|
||||
serialize($_COOKIE) .
|
||||
serialize($GLOBALS) .
|
||||
serialize($_SESSION) .
|
||||
serialize($_OLD_SESSION)
|
||||
(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)
|
||||
));
|
||||
if (!isset($_SESSION['count'])) {
|
||||
$_SESSION['count'] = 0;
|
||||
@ -199,8 +158,7 @@ class Random
|
||||
$crypto = new RC4();
|
||||
break;
|
||||
default:
|
||||
user_error(__CLASS__ . ' requires at least one symmetric cipher be loaded');
|
||||
return false;
|
||||
throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded');
|
||||
}
|
||||
|
||||
$crypto->setKey($key);
|
||||
@ -227,4 +185,36 @@ class Random
|
||||
}
|
||||
return substr($result, 0, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely serialize variables
|
||||
*
|
||||
* If a class has a private __sleep() it'll emit a warning
|
||||
*
|
||||
* @param mixed $arr
|
||||
* @access public
|
||||
*/
|
||||
function safe_serialize(&$arr)
|
||||
{
|
||||
if (is_object($arr)) {
|
||||
return '';
|
||||
}
|
||||
if (!is_array($arr)) {
|
||||
return serialize($arr);
|
||||
}
|
||||
// prevent circular array recursion
|
||||
if (isset($arr['__phpseclib_marker'])) {
|
||||
return '';
|
||||
}
|
||||
$safearr = array();
|
||||
$arr['__phpseclib_marker'] = true;
|
||||
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]);
|
||||
}
|
||||
}
|
||||
unset($arr['__phpseclib_marker']);
|
||||
return serialize($safearr);
|
||||
}
|
||||
}
|
||||
|
@ -7,11 +7,11 @@
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* If {@link \phpseclib\Crypt\Rijndael::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits. If
|
||||
* {@link \phpseclib\Crypt\Rijndael::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
|
||||
* {@link \phpseclib\Crypt\Rijndael::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's
|
||||
* If {@link self::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits. If
|
||||
* {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
|
||||
* {@link self::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's
|
||||
* 136-bits it'll be null-padded to 192-bits and 192 bits will be the key length until
|
||||
* {@link \phpseclib\Crypt\Rijndael::setKey() setKey()} is called, again, at which point, it'll be recalculated.
|
||||
* {@link self::setKey() setKey()} is called, again, at which point, it'll be recalculated.
|
||||
*
|
||||
* Not all Rijndael implementations may support 160-bits or 224-bits as the block length / key length. mcrypt, for example,
|
||||
* does not. AES, itself, only supports block lengths of 128 and key lengths of 128, 192, and 256.
|
||||
@ -54,8 +54,6 @@
|
||||
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
use phpseclib\Crypt\Base;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Rijndael.
|
||||
*
|
||||
@ -65,28 +63,18 @@ use phpseclib\Crypt\Base;
|
||||
*/
|
||||
class Rijndael extends Base
|
||||
{
|
||||
/**
|
||||
* The default password key_size used by setPassword()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::password_key_size
|
||||
* @see \phpseclib\Crypt\Base::setPassword()
|
||||
* @var Integer
|
||||
* @access private
|
||||
*/
|
||||
var $password_key_size = 16;
|
||||
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* Mcrypt is useable for 128/192/256-bit $block_size/$key_size. For 160/224 not.
|
||||
* Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not.
|
||||
* \phpseclib\Crypt\Rijndael determines automatically whether mcrypt is useable
|
||||
* or not for the current $block_size/$key_size.
|
||||
* or not for the current $block_size/$key_length.
|
||||
* In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @see \phpseclib\Crypt\Base::engine
|
||||
* @see isValidEngine()
|
||||
* @var String
|
||||
* @see self::isValidEngine()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'rijndael-128';
|
||||
@ -96,25 +84,16 @@ class Rijndael extends Base
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::password_default_salt
|
||||
* @see \phpseclib\Crypt\Base::setPassword()
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $password_default_salt = 'phpseclib';
|
||||
|
||||
/**
|
||||
* Has the key length explicitly been set or should it be derived from the key, itself?
|
||||
*
|
||||
* @see setKeyLength()
|
||||
* @var Boolean
|
||||
* @access private
|
||||
*/
|
||||
var $explicit_key_length = false;
|
||||
|
||||
/**
|
||||
* The Key Schedule
|
||||
*
|
||||
* @see _setup()
|
||||
* @var Array
|
||||
* @see self::_setup()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $w;
|
||||
@ -122,8 +101,8 @@ class Rijndael extends Base
|
||||
/**
|
||||
* The Inverse Key Schedule
|
||||
*
|
||||
* @see _setup()
|
||||
* @var Array
|
||||
* @see self::_setup()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $dw;
|
||||
@ -131,8 +110,8 @@ class Rijndael extends Base
|
||||
/**
|
||||
* The Block Length divided by 32
|
||||
*
|
||||
* @see setBlockLength()
|
||||
* @var Integer
|
||||
* @see self::setBlockLength()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size
|
||||
* because the encryption / decryption / key schedule creation requires this number and not $block_size. We could
|
||||
@ -142,23 +121,23 @@ class Rijndael extends Base
|
||||
var $Nb = 4;
|
||||
|
||||
/**
|
||||
* The Key Length
|
||||
* The Key Length (in bytes)
|
||||
*
|
||||
* @see setKeyLength()
|
||||
* @var Integer
|
||||
* @see self::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk
|
||||
* because the encryption / decryption / key schedule creation requires this number and not $key_size. We could
|
||||
* derive this from $key_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
||||
* because the encryption / decryption / key schedule creation requires this number and not $key_length. We could
|
||||
* derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
||||
* of that, we'll just precompute it once.
|
||||
*/
|
||||
var $key_size = 16;
|
||||
var $key_length = 16;
|
||||
|
||||
/**
|
||||
* The Key Length divided by 32
|
||||
*
|
||||
* @see setKeyLength()
|
||||
* @var Integer
|
||||
* @see self::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4
|
||||
*/
|
||||
@ -167,7 +146,7 @@ class Rijndael extends Base
|
||||
/**
|
||||
* The Number of Rounds
|
||||
*
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal The max value is 14, the min value is 10.
|
||||
*/
|
||||
@ -176,7 +155,7 @@ class Rijndael extends Base
|
||||
/**
|
||||
* Shift offsets
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $c;
|
||||
@ -184,7 +163,7 @@ class Rijndael extends Base
|
||||
/**
|
||||
* Holds the last used key- and block_size information
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $kl;
|
||||
@ -192,72 +171,23 @@ class Rijndael extends Base
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
*
|
||||
* $mode could be:
|
||||
*
|
||||
* - \phpseclib\Crypt\Base::MODE_ECB
|
||||
*
|
||||
* - \phpseclib\Crypt\Base::MODE_CBC
|
||||
*
|
||||
* - \phpseclib\Crypt\Base::MODE_CTR
|
||||
*
|
||||
* - \phpseclib\Crypt\Base::MODE_CFB
|
||||
*
|
||||
* - \phpseclib\Crypt\Base::MODE_OFB
|
||||
*
|
||||
* If not explictly set, \phpseclib\Crypt\Base::MODE_CBC will be used.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::Crypt_Base()
|
||||
* @param optional Integer $mode
|
||||
* @param int $mode
|
||||
* @access public
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Keys can be of any length. Rijndael, itself, requires the use of a key that's between 128-bits and 256-bits long and
|
||||
* whose length is a multiple of 32. If the key is less than 256-bits and the key length isn't set, we round the length
|
||||
* up to the closest valid key length, padding $key with null bytes. If the key is more than 256-bits, we trim the
|
||||
* excess bits.
|
||||
*
|
||||
* If the key is not explicitly set, it'll be assumed to be all null bytes.
|
||||
*
|
||||
* Note: 160/224-bit keys must explicitly set by setKeyLength(), otherwise they will be round/pad up to 192/256 bits.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base:setKey()
|
||||
* @see setKeyLength()
|
||||
* @access public
|
||||
* @param String $key
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function setKey($key)
|
||||
function __construct($mode)
|
||||
{
|
||||
if (!$this->explicit_key_length) {
|
||||
$length = strlen($key);
|
||||
switch (true) {
|
||||
case $length <= 16:
|
||||
$this->key_size = 16;
|
||||
break;
|
||||
case $length <= 20:
|
||||
$this->key_size = 20;
|
||||
break;
|
||||
case $length <= 24:
|
||||
$this->key_size = 24;
|
||||
break;
|
||||
case $length <= 28:
|
||||
$this->key_size = 28;
|
||||
break;
|
||||
default:
|
||||
$this->key_size = 32;
|
||||
}
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
parent::setKey($key);
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length
|
||||
* Sets the key length.
|
||||
*
|
||||
* 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.
|
||||
* Valid key lengths are 128, 160, 192, 224, and 256.
|
||||
*
|
||||
* 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
|
||||
@ -271,51 +201,75 @@ class Rijndael extends Base
|
||||
* This results then in slower encryption.
|
||||
*
|
||||
* @access public
|
||||
* @param Integer $length
|
||||
* @throws \LengthException if the key length is invalid
|
||||
* @param int $length
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
switch (true) {
|
||||
case $length == 160:
|
||||
$this->key_size = 20;
|
||||
break;
|
||||
case $length == 224:
|
||||
$this->key_size = 28;
|
||||
break;
|
||||
case $length <= 128:
|
||||
$this->key_size = 16;
|
||||
break;
|
||||
case $length <= 192:
|
||||
$this->key_size = 24;
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 160:
|
||||
case 192:
|
||||
case 224:
|
||||
case 256:
|
||||
$this->key_length = $length >> 3;
|
||||
break;
|
||||
default:
|
||||
$this->key_size = 32;
|
||||
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->explicit_key_length = true;
|
||||
$this->changed = true;
|
||||
$this->_setEngine();
|
||||
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. 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.
|
||||
* Valid block lengths are 128, 160, 192, 224, and 256.
|
||||
*
|
||||
* @access public
|
||||
* @param Integer $length
|
||||
* @param int $length
|
||||
*/
|
||||
function setBlockLength($length)
|
||||
{
|
||||
$length >>= 5;
|
||||
if ($length > 8) {
|
||||
$length = 8;
|
||||
} elseif ($length < 4) {
|
||||
$length = 4;
|
||||
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');
|
||||
}
|
||||
$this->Nb = $length;
|
||||
$this->block_size = $length << 2;
|
||||
|
||||
$this->Nb = $length >> 5;
|
||||
$this->block_size = $length >> 3;
|
||||
$this->changed = true;
|
||||
$this->_setEngine();
|
||||
}
|
||||
@ -325,10 +279,10 @@ class Rijndael extends Base
|
||||
*
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::Crypt_Base()
|
||||
* @param Integer $engine
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
@ -337,12 +291,12 @@ class Rijndael extends Base
|
||||
if ($this->block_size != 16) {
|
||||
return false;
|
||||
}
|
||||
$this->cipher_name_openssl_ecb = 'aes-' . ($this->key_size << 3) . '-ecb';
|
||||
$this->cipher_name_openssl = 'aes-' . ($this->key_size << 3) . '-' . $this->_openssl_translate_mode();
|
||||
$this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb';
|
||||
$this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->_openssl_translate_mode();
|
||||
break;
|
||||
case self::ENGINE_MCRYPT:
|
||||
$this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3);
|
||||
if ($this->key_size % 8) { // is it a 160/224-bit key?
|
||||
if ($this->key_length % 8) { // is it a 160/224-bit key?
|
||||
// mcrypt is not usable for them, only for 128/192/256-bit keys
|
||||
return false;
|
||||
}
|
||||
@ -351,24 +305,12 @@ class Rijndael extends Base
|
||||
return parent::isValidEngine($engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the \phpseclib\Crypt\Base::ENGINE_MCRYPT $engine
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::_setupMcrypt()
|
||||
* @access private
|
||||
*/
|
||||
function _setupMcrypt()
|
||||
{
|
||||
$this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, "\0");
|
||||
parent::_setupMcrypt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
@ -468,8 +410,8 @@ class Rijndael extends Base
|
||||
* Decrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
@ -573,15 +515,13 @@ class Rijndael extends Base
|
||||
0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
|
||||
);
|
||||
|
||||
$this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, "\0");
|
||||
|
||||
if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_size === $this->kl['key_size'] && $this->block_size === $this->kl['block_size']) {
|
||||
if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) {
|
||||
// already expanded
|
||||
return;
|
||||
}
|
||||
$this->kl = array('key' => $this->key, 'key_size' => $this->key_size, 'block_size' => $this->block_size);
|
||||
$this->kl = array('key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size);
|
||||
|
||||
$this->Nk = $this->key_size >> 2;
|
||||
$this->Nk = $this->key_length >> 2;
|
||||
// see Rijndael-ammended.pdf#page=44
|
||||
$this->Nr = max($this->Nk, $this->Nb) + 6;
|
||||
|
||||
@ -673,13 +613,13 @@ class Rijndael extends Base
|
||||
* Performs S-Box substitutions
|
||||
*
|
||||
* @access private
|
||||
* @param Integer $word
|
||||
* @param int $word
|
||||
*/
|
||||
function _subWord($word)
|
||||
{
|
||||
static $sbox;
|
||||
if (empty($sbox)) {
|
||||
list(,,,, $sbox) = $this->_getTables();
|
||||
list(, , , , $sbox) = $this->_getTables();
|
||||
}
|
||||
|
||||
return $sbox[$word & 0x000000FF] |
|
||||
@ -691,11 +631,11 @@ class Rijndael extends Base
|
||||
/**
|
||||
* Provides the mixColumns and sboxes tables
|
||||
*
|
||||
* @see Crypt_Rijndael:_encryptBlock()
|
||||
* @see Crypt_Rijndael:_setupInlineCrypt()
|
||||
* @see Crypt_Rijndael:_subWord()
|
||||
* @see self::_encryptBlock()
|
||||
* @see self::_setupInlineCrypt()
|
||||
* @see self::_subWord()
|
||||
* @access private
|
||||
* @return Array &$tables
|
||||
* @return array &$tables
|
||||
*/
|
||||
function &_getTables()
|
||||
{
|
||||
@ -780,11 +720,11 @@ class Rijndael extends Base
|
||||
/**
|
||||
* Provides the inverse mixColumns and inverse sboxes tables
|
||||
*
|
||||
* @see Crypt_Rijndael:_decryptBlock()
|
||||
* @see Crypt_Rijndael:_setupInlineCrypt()
|
||||
* @see Crypt_Rijndael:_setupKey()
|
||||
* @see self::_decryptBlock()
|
||||
* @see self::_setupInlineCrypt()
|
||||
* @see self::_setupKey()
|
||||
* @access private
|
||||
* @return Array &$tables
|
||||
* @return array &$tables
|
||||
*/
|
||||
function &_getInvTables()
|
||||
{
|
||||
@ -878,7 +818,7 @@ class Rijndael extends Base
|
||||
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
|
||||
// (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit)
|
||||
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
|
||||
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
|
||||
// Generation of a uniqe hash for our generated code
|
||||
$code_hash = "Crypt_Rijndael, {$this->mode}, {$this->Nr}, {$this->Nb}";
|
||||
|
@ -36,9 +36,6 @@
|
||||
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
use phpseclib\Crypt\Base;
|
||||
use phpseclib\Crypt\DES;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Triple DES.
|
||||
*
|
||||
@ -48,7 +45,6 @@ use phpseclib\Crypt\DES;
|
||||
*/
|
||||
class TripleDES extends DES
|
||||
{
|
||||
|
||||
/**
|
||||
* Encrypt / decrypt using inner chaining
|
||||
*
|
||||
@ -60,26 +56,24 @@ class TripleDES extends DES
|
||||
* Encrypt / decrypt using outer chaining
|
||||
*
|
||||
* Outer chaining is used by SSH-2 and when the mode is set to \phpseclib\Crypt\Base::MODE_CBC.
|
||||
*/
|
||||
*/
|
||||
const MODE_CBC3 = Base::MODE_CBC;
|
||||
|
||||
/**
|
||||
* The default password key_size used by setPassword()
|
||||
* Key Length (in bytes)
|
||||
*
|
||||
* @see \phpseclib\Crypt\DES::password_key_size
|
||||
* @see \phpseclib\Crypt\Base::password_key_size
|
||||
* @see \phpseclib\Crypt\Base::setPassword()
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\TripleDES::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $password_key_size = 24;
|
||||
var $key_length = 24;
|
||||
|
||||
/**
|
||||
* The default salt used by setPassword()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::password_default_salt
|
||||
* @see \phpseclib\Crypt\Base::setPassword()
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $password_default_salt = 'phpseclib';
|
||||
@ -89,7 +83,7 @@ class TripleDES extends DES
|
||||
*
|
||||
* @see \phpseclib\Crypt\DES::cipher_name_mcrypt
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'tripledes';
|
||||
@ -98,7 +92,7 @@ class TripleDES extends DES
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 750;
|
||||
@ -106,17 +100,17 @@ class TripleDES extends DES
|
||||
/**
|
||||
* max possible size of $key
|
||||
*
|
||||
* @see \phpseclib\Crypt\TripleDES::setKey()
|
||||
* @see self::setKey()
|
||||
* @see \phpseclib\Crypt\DES::setKey()
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key_size_max = 24;
|
||||
var $key_length_max = 24;
|
||||
|
||||
/**
|
||||
* Internal flag whether using self::MODE_3CBC or not
|
||||
*
|
||||
* @var Boolean
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $mode_3cbc;
|
||||
@ -126,7 +120,7 @@ class TripleDES extends DES
|
||||
*
|
||||
* Used only if $mode_3cbc === true
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $des;
|
||||
@ -134,7 +128,7 @@ class TripleDES extends DES
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
* Determines whether or not the mcrypt or OpenSSL extensions should be used.
|
||||
*
|
||||
* $mode could be:
|
||||
*
|
||||
@ -148,16 +142,14 @@ class TripleDES extends DES
|
||||
*
|
||||
* - \phpseclib\Crypt\Base::MODE_OFB
|
||||
*
|
||||
* - \phpseclib\Crypt\TripleDES::MODE_3CBC
|
||||
*
|
||||
* If not explicitly set, \phpseclib\Crypt\Base::MODE_CBC will be used.
|
||||
* - \phpseclib\Crypt\TripleDES::MODE_3CB
|
||||
*
|
||||
* @see \phpseclib\Crypt\DES::__construct()
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param optional Integer $mode
|
||||
* @param int $mode
|
||||
* @access public
|
||||
*/
|
||||
function __construct($mode = Base::MODE_CBC)
|
||||
function __construct($mode)
|
||||
{
|
||||
switch ($mode) {
|
||||
// In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC
|
||||
@ -189,10 +181,10 @@ class TripleDES extends DES
|
||||
*
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::Crypt_Base()
|
||||
* @param Integer $engine
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
@ -206,14 +198,13 @@ class TripleDES extends DES
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initialization vector. (optional)
|
||||
* Sets the initialization vector.
|
||||
*
|
||||
* 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.
|
||||
* SetIV is not required when \phpseclib\Crypt\Base::MODE_ECB is being used.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::setIV()
|
||||
* @access public
|
||||
* @param String $iv
|
||||
* @param string $iv
|
||||
*/
|
||||
function setIV($iv)
|
||||
{
|
||||
@ -225,39 +216,66 @@ 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
|
||||
*
|
||||
* @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:
|
||||
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');
|
||||
}
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* 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.
|
||||
* Triple DES can use 128-bit (eg. strlen($key) == 16) or 192-bit (eg. strlen($key) == 24) keys.
|
||||
*
|
||||
* 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()
|
||||
* @param String $key
|
||||
* @throws \LengthException if the key length is invalid
|
||||
* @param string $key
|
||||
*/
|
||||
function setKey($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));
|
||||
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');
|
||||
}
|
||||
parent::setKey($key);
|
||||
|
||||
// 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) {
|
||||
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) {
|
||||
$this->des[0]->setKey(substr($key, 0, 8));
|
||||
$this->des[1]->setKey(substr($key, 8, 8));
|
||||
$this->des[2]->setKey(substr($key, 16, 8));
|
||||
@ -269,8 +287,8 @@ class TripleDES extends DES
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::encrypt()
|
||||
* @access public
|
||||
* @param String $plaintext
|
||||
* @return String $cipertext
|
||||
* @param string $plaintext
|
||||
* @return string $cipertext
|
||||
*/
|
||||
function encrypt($plaintext)
|
||||
{
|
||||
@ -296,8 +314,8 @@ class TripleDES extends DES
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::decrypt()
|
||||
* @access public
|
||||
* @param String $ciphertext
|
||||
* @return String $plaintext
|
||||
* @param string $ciphertext
|
||||
* @return string $plaintext
|
||||
*/
|
||||
function decrypt($ciphertext)
|
||||
{
|
||||
@ -351,7 +369,7 @@ class TripleDES extends DES
|
||||
* however, they are also less intuitive and more likely to cause you problems.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::enableContinuousBuffer()
|
||||
* @see \phpseclib\Crypt\TripleDES::disableContinuousBuffer()
|
||||
* @see self::disableContinuousBuffer()
|
||||
* @access public
|
||||
*/
|
||||
function enableContinuousBuffer()
|
||||
@ -370,7 +388,7 @@ class TripleDES extends DES
|
||||
* The default behavior.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::disableContinuousBuffer()
|
||||
* @see \phpseclib\Crypt\TripleDES::enableContinuousBuffer()
|
||||
* @see self::enableContinuousBuffer()
|
||||
* @access public
|
||||
*/
|
||||
function disableContinuousBuffer()
|
||||
@ -421,11 +439,11 @@ class TripleDES extends DES
|
||||
/**
|
||||
* Sets the internal crypt engine
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::Crypt_Base()
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @see \phpseclib\Crypt\Base::setPreferredEngine()
|
||||
* @param Integer $engine
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return Integer
|
||||
* @return int
|
||||
*/
|
||||
function setPreferredEngine($engine)
|
||||
{
|
||||
|
@ -37,8 +37,6 @@
|
||||
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
use phpseclib\Crypt\Base;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Twofish.
|
||||
*
|
||||
@ -53,7 +51,7 @@ class Twofish extends Base
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'twofish';
|
||||
@ -62,7 +60,7 @@ class Twofish extends Base
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 800;
|
||||
@ -70,10 +68,10 @@ class Twofish extends Base
|
||||
/**
|
||||
* Q-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $q0 = array (
|
||||
var $q0 = array(
|
||||
0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
|
||||
0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
|
||||
0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
|
||||
@ -111,10 +109,10 @@ class Twofish extends Base
|
||||
/**
|
||||
* Q-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $q1 = array (
|
||||
var $q1 = array(
|
||||
0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
|
||||
0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
|
||||
0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
|
||||
@ -152,10 +150,10 @@ class Twofish extends Base
|
||||
/**
|
||||
* M-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $m0 = array (
|
||||
var $m0 = array(
|
||||
0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8,
|
||||
0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B,
|
||||
0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
|
||||
@ -193,10 +191,10 @@ class Twofish extends Base
|
||||
/**
|
||||
* M-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $m1 = array (
|
||||
var $m1 = array(
|
||||
0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4,
|
||||
0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A,
|
||||
0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
|
||||
@ -234,10 +232,10 @@ class Twofish extends Base
|
||||
/**
|
||||
* M-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $m2 = array (
|
||||
var $m2 = array(
|
||||
0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA,
|
||||
0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7,
|
||||
0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
|
||||
@ -275,10 +273,10 @@ class Twofish extends Base
|
||||
/**
|
||||
* M-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $m3 = array (
|
||||
var $m3 = array(
|
||||
0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF,
|
||||
0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836,
|
||||
0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
|
||||
@ -316,7 +314,7 @@ class Twofish extends Base
|
||||
/**
|
||||
* The Key Schedule Array
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $K = array();
|
||||
@ -324,7 +322,7 @@ class Twofish extends Base
|
||||
/**
|
||||
* The Key depended S-Table 0
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $S0 = array();
|
||||
@ -332,7 +330,7 @@ class Twofish extends Base
|
||||
/**
|
||||
* The Key depended S-Table 1
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $S1 = array();
|
||||
@ -340,7 +338,7 @@ class Twofish extends Base
|
||||
/**
|
||||
* The Key depended S-Table 2
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $S2 = array();
|
||||
@ -348,7 +346,7 @@ class Twofish extends Base
|
||||
/**
|
||||
* The Key depended S-Table 3
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $S3 = array();
|
||||
@ -356,40 +354,79 @@ class Twofish extends Base
|
||||
/**
|
||||
* Holds the last used key
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $kl;
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
* The Key Length (in bytes)
|
||||
*
|
||||
* Keys can be of any length. Twofish, itself, requires the use of a key that's 128, 192 or 256-bits long.
|
||||
* If the key is less than 256-bits we round the length up to the closest valid key length,
|
||||
* padding $key with null bytes. If the key is more than 256-bits, we trim the excess bits.
|
||||
* @see Crypt_Twofish::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $key_length = 16;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* If the key is not explicitly set, it'll be assumed a 128 bits key to be all null bytes.
|
||||
* @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, 192 or 256 bits
|
||||
*
|
||||
* @access public
|
||||
* @see \phpseclib\Crypt\Base::setKey()
|
||||
* @param String $key
|
||||
* @param int $length
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 192:
|
||||
case 256:
|
||||
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::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)
|
||||
{
|
||||
$keylength = strlen($key);
|
||||
switch (true) {
|
||||
case $keylength <= 16:
|
||||
$key = str_pad($key, 16, "\0");
|
||||
switch (strlen($key)) {
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
break;
|
||||
case $keylength <= 24:
|
||||
$key = str_pad($key, 24, "\0");
|
||||
break;
|
||||
case $keylength < 32:
|
||||
$key = str_pad($key, 32, "\0");
|
||||
break;
|
||||
case $keylength > 32:
|
||||
$key = substr($key, 0, 32);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -421,9 +458,9 @@ class Twofish extends Base
|
||||
|
||||
switch (strlen($this->key)) {
|
||||
case 16:
|
||||
list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
for ($i = 0, $j = 1; $i < 40; $i+= 2,$j+= 2) {
|
||||
list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
|
||||
$A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^
|
||||
$m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^
|
||||
$m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^
|
||||
@ -444,9 +481,9 @@ class Twofish extends Base
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
|
||||
list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
|
||||
for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
|
||||
$A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
|
||||
$m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
|
||||
@ -468,10 +505,10 @@ class Twofish extends Base
|
||||
}
|
||||
break;
|
||||
default: // 32
|
||||
list ($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
|
||||
list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
|
||||
list($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
|
||||
list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
|
||||
for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
|
||||
$A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
|
||||
$m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
|
||||
@ -504,9 +541,9 @@ class Twofish extends Base
|
||||
* _mdsrem function using by the twofish cipher algorithm
|
||||
*
|
||||
* @access private
|
||||
* @param String $A
|
||||
* @param String $B
|
||||
* @return Array
|
||||
* @param string $A
|
||||
* @param string $B
|
||||
* @return array
|
||||
*/
|
||||
function _mdsrem($A, $B)
|
||||
{
|
||||
@ -552,8 +589,8 @@ class Twofish extends Base
|
||||
* Encrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
@ -608,8 +645,8 @@ class Twofish extends Base
|
||||
* Decrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
@ -672,7 +709,7 @@ class Twofish extends Base
|
||||
|
||||
// Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
|
||||
// (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit)
|
||||
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
|
||||
// Generation of a uniqe hash for our generated code
|
||||
$code_hash = "Crypt_Twofish, {$this->mode}";
|
||||
|
26
phpseclib/Exception/BadConfigurationException.php
Normal file
26
phpseclib/Exception/BadConfigurationException.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?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
|
||||
{
|
||||
}
|
26
phpseclib/Exception/FileNotFoundException.php
Normal file
26
phpseclib/Exception/FileNotFoundException.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?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
|
||||
{
|
||||
}
|
26
phpseclib/Exception/NoSupportedAlgorithmsException.php
Normal file
26
phpseclib/Exception/NoSupportedAlgorithmsException.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?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
|
||||
{
|
||||
}
|
26
phpseclib/Exception/UnsupportedAlgorithmException.php
Normal file
26
phpseclib/Exception/UnsupportedAlgorithmException.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?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
|
||||
{
|
||||
}
|
@ -32,7 +32,7 @@ class ANSI
|
||||
/**
|
||||
* Max Width
|
||||
*
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $max_x;
|
||||
@ -40,7 +40,7 @@ class ANSI
|
||||
/**
|
||||
* Max Height
|
||||
*
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $max_y;
|
||||
@ -48,7 +48,7 @@ class ANSI
|
||||
/**
|
||||
* Max History
|
||||
*
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $max_history;
|
||||
@ -56,7 +56,7 @@ class ANSI
|
||||
/**
|
||||
* History
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $history;
|
||||
@ -64,7 +64,7 @@ class ANSI
|
||||
/**
|
||||
* History Attributes
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $history_attrs;
|
||||
@ -72,7 +72,7 @@ class ANSI
|
||||
/**
|
||||
* Current Column
|
||||
*
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $x;
|
||||
@ -80,7 +80,7 @@ class ANSI
|
||||
/**
|
||||
* Current Row
|
||||
*
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $y;
|
||||
@ -88,7 +88,7 @@ class ANSI
|
||||
/**
|
||||
* Old Column
|
||||
*
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $old_x;
|
||||
@ -96,7 +96,7 @@ class ANSI
|
||||
/**
|
||||
* Old Row
|
||||
*
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $old_y;
|
||||
@ -104,7 +104,7 @@ class ANSI
|
||||
/**
|
||||
* An empty attribute cell
|
||||
*
|
||||
* @var Object
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $base_attr_cell;
|
||||
@ -112,7 +112,7 @@ class ANSI
|
||||
/**
|
||||
* The current attribute cell
|
||||
*
|
||||
* @var Object
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $attr_cell;
|
||||
@ -120,7 +120,7 @@ class ANSI
|
||||
/**
|
||||
* An empty attribute row
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $attr_row;
|
||||
@ -128,7 +128,7 @@ class ANSI
|
||||
/**
|
||||
* The current screen text
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $screen;
|
||||
@ -136,7 +136,7 @@ class ANSI
|
||||
/**
|
||||
* The current screen attributes
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $attrs;
|
||||
@ -144,7 +144,7 @@ class ANSI
|
||||
/**
|
||||
* Current ANSI code
|
||||
*
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $ansi;
|
||||
@ -152,7 +152,7 @@ class ANSI
|
||||
/**
|
||||
* Tokenization
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $tokenization;
|
||||
@ -184,8 +184,8 @@ class ANSI
|
||||
*
|
||||
* Resets the screen as well
|
||||
*
|
||||
* @param Integer $x
|
||||
* @param Integer $y
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
* @access public
|
||||
*/
|
||||
function setDimensions($x, $y)
|
||||
@ -203,8 +203,8 @@ class ANSI
|
||||
/**
|
||||
* Set the number of lines that should be logged past the terminal height
|
||||
*
|
||||
* @param Integer $x
|
||||
* @param Integer $y
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
* @access public
|
||||
*/
|
||||
function setHistory($history)
|
||||
@ -215,7 +215,7 @@ class ANSI
|
||||
/**
|
||||
* Load a string
|
||||
*
|
||||
* @param String $source
|
||||
* @param string $source
|
||||
* @access public
|
||||
*/
|
||||
function loadString($source)
|
||||
@ -227,7 +227,7 @@ class ANSI
|
||||
/**
|
||||
* Appdend a string
|
||||
*
|
||||
* @param String $source
|
||||
* @param string $source
|
||||
* @access public
|
||||
*/
|
||||
function appendString($source)
|
||||
@ -458,7 +458,7 @@ class ANSI
|
||||
* Returns the current coordinate without preformating
|
||||
*
|
||||
* @access private
|
||||
* @return String
|
||||
* @return string
|
||||
*/
|
||||
function _processCoordinate($last_attr, $cur_attr, $char)
|
||||
{
|
||||
@ -515,7 +515,7 @@ class ANSI
|
||||
* Returns the current screen without preformating
|
||||
*
|
||||
* @access private
|
||||
* @return String
|
||||
* @return string
|
||||
*/
|
||||
function _getScreen()
|
||||
{
|
||||
@ -539,7 +539,7 @@ class ANSI
|
||||
* Returns the current screen
|
||||
*
|
||||
* @access public
|
||||
* @return String
|
||||
* @return string
|
||||
*/
|
||||
function getScreen()
|
||||
{
|
||||
@ -550,7 +550,7 @@ class ANSI
|
||||
* Returns the current screen and the x previous lines
|
||||
*
|
||||
* @access public
|
||||
* @return String
|
||||
* @return string
|
||||
*/
|
||||
function getHistory()
|
||||
{
|
||||
|
@ -104,7 +104,7 @@ class ASN1
|
||||
/**
|
||||
* ASN.1 object identifier
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
* @link http://en.wikipedia.org/wiki/Object_identifier
|
||||
*/
|
||||
@ -113,7 +113,7 @@ class ASN1
|
||||
/**
|
||||
* Default date format
|
||||
*
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
* @link http://php.net/class.datetime
|
||||
*/
|
||||
@ -122,10 +122,10 @@ class ASN1
|
||||
/**
|
||||
* Default date format
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
* @see \phpseclib\File\ASN1::setTimeFormat()
|
||||
* @see \phpseclib\File\ASN1::asn1map()
|
||||
* @see self::setTimeFormat()
|
||||
* @see self::asn1map()
|
||||
* @link http://php.net/class.datetime
|
||||
*/
|
||||
var $encoded;
|
||||
@ -135,9 +135,9 @@ class ASN1
|
||||
*
|
||||
* If the mapping type is self::TYPE_ANY what do we actually encode it as?
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
* @see \phpseclib\File\ASN1::_encode_der()
|
||||
* @see self::_encode_der()
|
||||
*/
|
||||
var $filters;
|
||||
|
||||
@ -148,7 +148,7 @@ class ASN1
|
||||
* Unambiguous types get the direct mapping (int/real/bool).
|
||||
* Others are mapped as a choice, with an extra indexing level.
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $ANYmap = array(
|
||||
@ -182,7 +182,7 @@ class ASN1
|
||||
* Non-convertable types are absent from this table.
|
||||
* size == 0 indicates variable length encoding.
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $stringTypeSize = array(
|
||||
@ -200,8 +200,8 @@ class ASN1
|
||||
*
|
||||
* Serves a similar purpose to openssl's asn1parse
|
||||
*
|
||||
* @param String $encoded
|
||||
* @return Array
|
||||
* @param string $encoded
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function decodeBER($encoded)
|
||||
@ -222,9 +222,9 @@ class ASN1
|
||||
* $encoded is passed by reference for the recursive calls done for self::TYPE_BIT_STRING and
|
||||
* self::TYPE_OCTET_STRING. In those cases, the indefinite length is used.
|
||||
*
|
||||
* @param String $encoded
|
||||
* @param Integer $start
|
||||
* @return Array
|
||||
* @param string $encoded
|
||||
* @param int $start
|
||||
* @return array
|
||||
* @access private
|
||||
*/
|
||||
function _decode_ber($encoded, $start = 0)
|
||||
@ -482,10 +482,10 @@ class ASN1
|
||||
*
|
||||
* "Special" mappings may be applied on a per tag-name basis via $special.
|
||||
*
|
||||
* @param Array $decoded
|
||||
* @param Array $mapping
|
||||
* @param Array $special
|
||||
* @return Array
|
||||
* @param array $decoded
|
||||
* @param array $mapping
|
||||
* @param array $special
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function asn1map($decoded, $mapping, $special = array())
|
||||
@ -616,7 +616,7 @@ class ASN1
|
||||
}
|
||||
|
||||
// Fail mapping if all input items have not been consumed.
|
||||
return $i < $n? null: $map;
|
||||
return $i < $n ? null: $map;
|
||||
|
||||
// the main diff between sets and sequences is the encapsulation of the foreach in another for loop
|
||||
case self::TYPE_SET:
|
||||
@ -774,10 +774,10 @@ class ASN1
|
||||
*
|
||||
* "Special" mappings can be applied via $special.
|
||||
*
|
||||
* @param String $source
|
||||
* @param String $mapping
|
||||
* @param Integer $idx
|
||||
* @return String
|
||||
* @param string $source
|
||||
* @param string $mapping
|
||||
* @param int $idx
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function encodeDER($source, $mapping, $special = array())
|
||||
@ -789,10 +789,11 @@ class ASN1
|
||||
/**
|
||||
* ASN.1 Encode (Helper function)
|
||||
*
|
||||
* @param String $source
|
||||
* @param String $mapping
|
||||
* @param Integer $idx
|
||||
* @return String
|
||||
* @param string $source
|
||||
* @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())
|
||||
@ -985,7 +986,7 @@ class ASN1
|
||||
case self::TYPE_OBJECT_IDENTIFIER:
|
||||
$oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids);
|
||||
if ($oid === false) {
|
||||
user_error('Invalid OID');
|
||||
throw new \RuntimeException('Invalid OID');
|
||||
return false;
|
||||
}
|
||||
$value = '';
|
||||
@ -1038,7 +1039,7 @@ class ASN1
|
||||
$filters = $filters[$part];
|
||||
}
|
||||
if ($filters === false) {
|
||||
user_error('No filters defined for ' . implode('/', $loc));
|
||||
throw new \RuntimeException('No filters defined for ' . implode('/', $loc));
|
||||
return false;
|
||||
}
|
||||
return $this->_encode_der($source, $filters + $mapping, null, $special);
|
||||
@ -1062,7 +1063,7 @@ class ASN1
|
||||
$value = $source ? "\xFF" : "\x00";
|
||||
break;
|
||||
default:
|
||||
user_error('Mapping provides no type definition for ' . implode('/', $this->location));
|
||||
throw new \RuntimeException('Mapping provides no type definition for ' . implode('/', $this->location));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1089,8 +1090,8 @@ class ASN1
|
||||
* {@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 Integer $length
|
||||
* @return String
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
function _encodeLength($length)
|
||||
{
|
||||
@ -1108,9 +1109,9 @@ class ASN1
|
||||
* Called by _decode_ber() and in the case of implicit tags asn1map().
|
||||
*
|
||||
* @access private
|
||||
* @param String $content
|
||||
* @param Integer $tag
|
||||
* @return String
|
||||
* @param string $content
|
||||
* @param int $tag
|
||||
* @return string
|
||||
*/
|
||||
function _decodeTime($content, $tag)
|
||||
{
|
||||
@ -1157,7 +1158,7 @@ class ASN1
|
||||
* Sets the time / date format for asn1map().
|
||||
*
|
||||
* @access public
|
||||
* @param String $format
|
||||
* @param string $format
|
||||
*/
|
||||
function setTimeFormat($format)
|
||||
{
|
||||
@ -1170,7 +1171,7 @@ class ASN1
|
||||
* Load the relevant OIDs for a particular ASN.1 semantic mapping.
|
||||
*
|
||||
* @access public
|
||||
* @param Array $oids
|
||||
* @param array $oids
|
||||
*/
|
||||
function loadOIDs($oids)
|
||||
{
|
||||
@ -1183,7 +1184,7 @@ class ASN1
|
||||
* See \phpseclib\File\X509, etc, for an example.
|
||||
*
|
||||
* @access public
|
||||
* @param Array $filters
|
||||
* @param array $filters
|
||||
*/
|
||||
function loadFilters($filters)
|
||||
{
|
||||
@ -1195,9 +1196,9 @@ class ASN1
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param String $string
|
||||
* @param optional Integer $index
|
||||
* @return String
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function _string_shift(&$string, $index = 1)
|
||||
@ -1213,10 +1214,10 @@ class ASN1
|
||||
* This is a lazy conversion, dealing only with character size.
|
||||
* No real conversion table is used.
|
||||
*
|
||||
* @param String $in
|
||||
* @param optional Integer $from
|
||||
* @param optional Integer $to
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @param int $from
|
||||
* @param int $to
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function convert($in, $from = self::TYPE_UTF8_STRING, $to = self::TYPE_UTF8_STRING)
|
||||
|
@ -28,7 +28,7 @@ class Element
|
||||
/**
|
||||
* Raw element value
|
||||
*
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $element;
|
||||
@ -36,7 +36,7 @@ class Element
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param String $encoded
|
||||
* @param string $encoded
|
||||
* @return \phpseclib\File\ASN1\Element
|
||||
* @access public
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@
|
||||
* exit('bad login');
|
||||
* }
|
||||
* $scp = new \phpseclib\Net\SCP($ssh);
|
||||
|
||||
*
|
||||
* $scp->put('abcd', str_repeat('x', 1024*1024));
|
||||
* ?>
|
||||
* </code>
|
||||
@ -32,8 +32,7 @@
|
||||
|
||||
namespace phpseclib\Net;
|
||||
|
||||
use phpseclib\Net\SSH1;
|
||||
use phpseclib\Net\SSH2;
|
||||
use phpseclib\Exception\FileNotFoundException;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementations of SCP.
|
||||
@ -54,7 +53,7 @@ class SCP
|
||||
const SOURCE_LOCAL_FILE = 1;
|
||||
/**
|
||||
* Reads data from a string.
|
||||
*/
|
||||
*/
|
||||
const SOURCE_STRING = 2;
|
||||
/**#@-*/
|
||||
|
||||
@ -65,18 +64,18 @@ class SCP
|
||||
*/
|
||||
/**
|
||||
* SSH1 is being used.
|
||||
*/
|
||||
*/
|
||||
const MODE_SSH1 = 1;
|
||||
/**
|
||||
* SSH2 is being used.
|
||||
*/
|
||||
*/
|
||||
const MODE_SSH2 = 2;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* SSH Object
|
||||
*
|
||||
* @var Object
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $ssh;
|
||||
@ -84,7 +83,7 @@ class SCP
|
||||
/**
|
||||
* Packet Size
|
||||
*
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $packet_size;
|
||||
@ -92,7 +91,7 @@ class SCP
|
||||
/**
|
||||
* Mode
|
||||
*
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $mode;
|
||||
@ -102,9 +101,9 @@ class SCP
|
||||
*
|
||||
* Connects to an SSH server
|
||||
*
|
||||
* @param String $host
|
||||
* @param optional Integer $port
|
||||
* @param optional Integer $timeout
|
||||
* @param string $host
|
||||
* @param int $port
|
||||
* @param int $timeout
|
||||
* @return \phpseclib\Net\SCP
|
||||
* @access public
|
||||
*/
|
||||
@ -136,11 +135,12 @@ class SCP
|
||||
* Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take
|
||||
* care of that, yourself.
|
||||
*
|
||||
* @param String $remote_file
|
||||
* @param String $data
|
||||
* @param optional Integer $mode
|
||||
* @param optional Callable $callback
|
||||
* @return Boolean
|
||||
* @param string $remote_file
|
||||
* @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
|
||||
*/
|
||||
function put($remote_file, $data, $mode = self::SOURCE_STRING, $callback = null)
|
||||
@ -168,8 +168,7 @@ class SCP
|
||||
$size = strlen($data);
|
||||
} else {
|
||||
if (!is_file($data)) {
|
||||
user_error("$data is not a valid file", E_USER_NOTICE);
|
||||
return false;
|
||||
throw new FileNotFoundException("$data is not a valid file");
|
||||
}
|
||||
|
||||
$fp = @fopen($data, 'rb');
|
||||
@ -212,9 +211,9 @@ class SCP
|
||||
* the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the
|
||||
* operation
|
||||
*
|
||||
* @param String $remote_file
|
||||
* @param optional String $local_file
|
||||
* @return Mixed
|
||||
* @param string $remote_file
|
||||
* @param string $local_file
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function get($remote_file, $local_file = false)
|
||||
@ -270,7 +269,7 @@ class SCP
|
||||
/**
|
||||
* Sends a packet to an SSH server
|
||||
*
|
||||
* @param String $data
|
||||
* @param string $data
|
||||
* @access private
|
||||
*/
|
||||
function _send($data)
|
||||
@ -288,7 +287,8 @@ class SCP
|
||||
/**
|
||||
* Receives a packet from an SSH server
|
||||
*
|
||||
* @return String
|
||||
* @return string
|
||||
* @throws \UnexpectedValueException on receipt of an unexpected packet
|
||||
* @access private
|
||||
*/
|
||||
function _receive()
|
||||
@ -314,8 +314,7 @@ class SCP
|
||||
$this->ssh->bitmap = 0;
|
||||
return false;
|
||||
default:
|
||||
user_error('Unknown packet received', E_USER_NOTICE);
|
||||
return false;
|
||||
throw new \UnexpectedValueException('Unknown packet received');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,7 @@ namespace phpseclib\Net\SFTP;
|
||||
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\Net\SFTP;
|
||||
use phpseclib\Net\SSH2;
|
||||
|
||||
/**
|
||||
* SFTP Stream Wrapper
|
||||
@ -34,14 +35,14 @@ class Stream
|
||||
*
|
||||
* Rather than re-create the connection we re-use instances if possible
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
*/
|
||||
static $instances;
|
||||
|
||||
/**
|
||||
* SFTP instance
|
||||
*
|
||||
* @var Object
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $sftp;
|
||||
@ -49,7 +50,7 @@ class Stream
|
||||
/**
|
||||
* Path
|
||||
*
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $path;
|
||||
@ -57,7 +58,7 @@ class Stream
|
||||
/**
|
||||
* Mode
|
||||
*
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $mode;
|
||||
@ -65,7 +66,7 @@ class Stream
|
||||
/**
|
||||
* Position
|
||||
*
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $pos;
|
||||
@ -73,7 +74,7 @@ class Stream
|
||||
/**
|
||||
* Size
|
||||
*
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $size;
|
||||
@ -81,7 +82,7 @@ class Stream
|
||||
/**
|
||||
* Directory entries
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $entries;
|
||||
@ -89,7 +90,7 @@ class Stream
|
||||
/**
|
||||
* EOF flag
|
||||
*
|
||||
* @var Boolean
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $eof;
|
||||
@ -99,7 +100,7 @@ class Stream
|
||||
*
|
||||
* Technically this needs to be publically accessible so PHP can set it directly
|
||||
*
|
||||
* @var Resource
|
||||
* @var resource
|
||||
* @access public
|
||||
*/
|
||||
var $context;
|
||||
@ -107,7 +108,7 @@ class Stream
|
||||
/**
|
||||
* Notification callback function
|
||||
*
|
||||
* @var Callable
|
||||
* @var callable
|
||||
* @access public
|
||||
*/
|
||||
var $notification;
|
||||
@ -115,8 +116,8 @@ class Stream
|
||||
/**
|
||||
* Registers this class as a URL wrapper.
|
||||
*
|
||||
* @param optional String $protocol The wrapper name to be registered.
|
||||
* @return Boolean True on success, false otherwise.
|
||||
* @param string $protocol The wrapper name to be registered.
|
||||
* @return bool True on success, false otherwise.
|
||||
* @access public
|
||||
*/
|
||||
static function register($protocol = 'sftp')
|
||||
@ -147,13 +148,24 @@ class Stream
|
||||
* If "notification" is set as a context parameter the message code for successful login is
|
||||
* NET_SSH2_MSG_USERAUTH_SUCCESS. For a failed login it's NET_SSH2_MSG_USERAUTH_FAILURE.
|
||||
*
|
||||
* @param String $path
|
||||
* @return String
|
||||
* @param string $path
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function _parse_path($path)
|
||||
{
|
||||
$orig = $path;
|
||||
extract(parse_url($path) + array('port' => 22));
|
||||
if (isset($query)) {
|
||||
$path.= '?' . $query;
|
||||
} elseif (preg_match('/(\?|\?#)$/', $orig)) {
|
||||
$path.= '?';
|
||||
}
|
||||
if (isset($fragment)) {
|
||||
$path.= '#' . $fragment;
|
||||
} elseif ($orig[strlen($orig) - 1] == '#') {
|
||||
$path.= '#';
|
||||
}
|
||||
|
||||
if (!isset($host)) {
|
||||
return false;
|
||||
@ -166,13 +178,12 @@ class Stream
|
||||
}
|
||||
}
|
||||
|
||||
if ($host[0] == '$') {
|
||||
$host = substr($host, 1);
|
||||
global $$host;
|
||||
if (($$host instanceof SFTP) === false) {
|
||||
if (preg_match('/^{[a-z0-9]+}$/i', $host)) {
|
||||
$host = SSH2::getConnectionByResourceId($host);
|
||||
if ($host === false) {
|
||||
return false;
|
||||
}
|
||||
$this->sftp = $$host;
|
||||
$this->sftp = $host;
|
||||
} else {
|
||||
if (isset($this->context)) {
|
||||
$context = stream_context_get_options($this->context);
|
||||
@ -239,11 +250,11 @@ class Stream
|
||||
/**
|
||||
* Opens file or URL
|
||||
*
|
||||
* @param String $path
|
||||
* @param String $mode
|
||||
* @param Integer $options
|
||||
* @param String $opened_path
|
||||
* @return Boolean
|
||||
* @param string $path
|
||||
* @param string $mode
|
||||
* @param int $options
|
||||
* @param string $opened_path
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _stream_open($path, $mode, $options, &$opened_path)
|
||||
@ -284,8 +295,8 @@ class Stream
|
||||
/**
|
||||
* Read from stream
|
||||
*
|
||||
* @param Integer $count
|
||||
* @return Mixed
|
||||
* @param int $count
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function _stream_read($count)
|
||||
@ -326,8 +337,8 @@ class Stream
|
||||
/**
|
||||
* Write to stream
|
||||
*
|
||||
* @param String $data
|
||||
* @return Mixed
|
||||
* @param string $data
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function _stream_write($data)
|
||||
@ -361,7 +372,7 @@ class Stream
|
||||
/**
|
||||
* Retrieve the current position of a stream
|
||||
*
|
||||
* @return Integer
|
||||
* @return int
|
||||
* @access public
|
||||
*/
|
||||
function _stream_tell()
|
||||
@ -379,7 +390,7 @@ class Stream
|
||||
* will return false. do fread($fp, 1) and feof() will then return true. do fseek($fp, 10) on ablank file and feof()
|
||||
* will return false. do fread($fp, 1) and feof() will then return true.
|
||||
*
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _stream_eof()
|
||||
@ -390,9 +401,9 @@ class Stream
|
||||
/**
|
||||
* Seeks to specific location in a stream
|
||||
*
|
||||
* @param Integer $offset
|
||||
* @param Integer $whence
|
||||
* @return Boolean
|
||||
* @param int $offset
|
||||
* @param int $whence
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _stream_seek($offset, $whence)
|
||||
@ -418,10 +429,10 @@ class Stream
|
||||
/**
|
||||
* Change stream options
|
||||
*
|
||||
* @param String $path
|
||||
* @param Integer $option
|
||||
* @param Mixed $var
|
||||
* @return Boolean
|
||||
* @param string $path
|
||||
* @param int $option
|
||||
* @param mixed $var
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _stream_metadata($path, $option, $var)
|
||||
@ -452,8 +463,8 @@ class Stream
|
||||
/**
|
||||
* Retrieve the underlaying resource
|
||||
*
|
||||
* @param Integer $cast_as
|
||||
* @return Resource
|
||||
* @param int $cast_as
|
||||
* @return resource
|
||||
* @access public
|
||||
*/
|
||||
function _stream_cast($cast_as)
|
||||
@ -464,8 +475,8 @@ class Stream
|
||||
/**
|
||||
* Advisory file locking
|
||||
*
|
||||
* @param Integer $operation
|
||||
* @return Boolean
|
||||
* @param int $operation
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _stream_lock($operation)
|
||||
@ -480,9 +491,9 @@ class Stream
|
||||
* If newname exists, it will be overwritten. This is a departure from what \phpseclib\Net\SFTP
|
||||
* does.
|
||||
*
|
||||
* @param String $path_from
|
||||
* @param String $path_to
|
||||
* @return Boolean
|
||||
* @param string $path_from
|
||||
* @param string $path_to
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _rename($path_from, $path_to)
|
||||
@ -532,9 +543,9 @@ class Stream
|
||||
* string longname
|
||||
* ATTRS attrs
|
||||
*
|
||||
* @param String $path
|
||||
* @param Integer $options
|
||||
* @return Boolean
|
||||
* @param string $path
|
||||
* @param int $options
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _dir_opendir($path, $options)
|
||||
@ -551,7 +562,7 @@ class Stream
|
||||
/**
|
||||
* Read entry from directory handle
|
||||
*
|
||||
* @return Mixed
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function _dir_readdir()
|
||||
@ -565,7 +576,7 @@ class Stream
|
||||
/**
|
||||
* Rewind directory handle
|
||||
*
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _dir_rewinddir()
|
||||
@ -577,7 +588,7 @@ class Stream
|
||||
/**
|
||||
* Close directory handle
|
||||
*
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _dir_closedir()
|
||||
@ -590,10 +601,10 @@ class Stream
|
||||
*
|
||||
* Only valid $options is STREAM_MKDIR_RECURSIVE
|
||||
*
|
||||
* @param String $path
|
||||
* @param Integer $mode
|
||||
* @param Integer $options
|
||||
* @return Boolean
|
||||
* @param string $path
|
||||
* @param int $mode
|
||||
* @param int $options
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _mkdir($path, $mode, $options)
|
||||
@ -614,10 +625,10 @@ class Stream
|
||||
* STREAM_MKDIR_RECURSIVE is supposed to be set. Also, when I try it out with rmdir() I get 8 as
|
||||
* $options. What does 8 correspond to?
|
||||
*
|
||||
* @param String $path
|
||||
* @param Integer $mode
|
||||
* @param Integer $options
|
||||
* @return Boolean
|
||||
* @param string $path
|
||||
* @param int $mode
|
||||
* @param int $options
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _rmdir($path, $options)
|
||||
@ -635,7 +646,7 @@ class Stream
|
||||
*
|
||||
* See <http://php.net/fflush>. Always returns true because \phpseclib\Net\SFTP doesn't cache stuff before writing
|
||||
*
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _stream_flush()
|
||||
@ -646,7 +657,7 @@ class Stream
|
||||
/**
|
||||
* Retrieve information about a file resource
|
||||
*
|
||||
* @return Mixed
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function _stream_stat()
|
||||
@ -661,8 +672,8 @@ class Stream
|
||||
/**
|
||||
* Delete a file
|
||||
*
|
||||
* @param String $path
|
||||
* @return Boolean
|
||||
* @param string $path
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _unlink($path)
|
||||
@ -682,9 +693,9 @@ class Stream
|
||||
* might be worthwhile to reconstruct bits 12-16 (ie. the file type) if mode doesn't have them but we'll
|
||||
* cross that bridge when and if it's reached
|
||||
*
|
||||
* @param String $path
|
||||
* @param Integer $flags
|
||||
* @return Mixed
|
||||
* @param string $path
|
||||
* @param int $flags
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function _url_stat($path, $flags)
|
||||
@ -705,8 +716,8 @@ class Stream
|
||||
/**
|
||||
* Truncate stream
|
||||
*
|
||||
* @param Integer $new_size
|
||||
* @return Boolean
|
||||
* @param int $new_size
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _stream_truncate($new_size)
|
||||
@ -727,10 +738,10 @@ class Stream
|
||||
* STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush isn't.
|
||||
* The other two aren't supported because of limitations in \phpseclib\Net\SFTP.
|
||||
*
|
||||
* @param Integer $option
|
||||
* @param Integer $arg1
|
||||
* @param Integer $arg2
|
||||
* @return Boolean
|
||||
* @param int $option
|
||||
* @param int $arg1
|
||||
* @param int $arg2
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _stream_set_option($option, $arg1, $arg2)
|
||||
@ -757,9 +768,9 @@ class Stream
|
||||
* If NET_SFTP_STREAM_LOGGING is defined all calls will be output on the screen and then (regardless of whether or not
|
||||
* NET_SFTP_STREAM_LOGGING is enabled) the parameters will be passed through to the appropriate method.
|
||||
*
|
||||
* @param String
|
||||
* @param Array
|
||||
* @return Mixed
|
||||
* @param string
|
||||
* @param array
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function __call($name, $arguments)
|
||||
|
@ -78,24 +78,24 @@ class SSH1
|
||||
* IDEA in CFB mode
|
||||
*
|
||||
* Not supported.
|
||||
*/
|
||||
*/
|
||||
const CIPHER_IDEA = 1;
|
||||
/**
|
||||
* DES in CBC mode
|
||||
*/
|
||||
*/
|
||||
const CIPHER_DES = 2;
|
||||
/**
|
||||
* Triple-DES in CBC mode
|
||||
*
|
||||
* All implementations are required to support this
|
||||
*/
|
||||
*/
|
||||
const CIPHER_3DES = 3;
|
||||
/**
|
||||
* TRI's Simple Stream encryption CBC
|
||||
*
|
||||
* Not supported nor is it defined in the official SSH1 specs. OpenSSH, however, does define it (see cipher.h),
|
||||
* although it doesn't use it (see cipher.c)
|
||||
*/
|
||||
*/
|
||||
const CIPHER_BROKEN_TSS = 4;
|
||||
/**
|
||||
* RC4
|
||||
@ -111,14 +111,14 @@ class SSH1
|
||||
*
|
||||
* This library currently only supports encryption when the same key is being used for both directions. This is
|
||||
* because there's only one $crypto object. Two could be added ($encrypt and $decrypt, perhaps).
|
||||
*/
|
||||
*/
|
||||
const CIPHER_RC4 = 5;
|
||||
/**
|
||||
* Blowfish
|
||||
*
|
||||
* Not supported nor is it defined in the official SSH1 specs. OpenSSH, however, defines it (see cipher.h) and
|
||||
* uses it (see cipher.c)
|
||||
*/
|
||||
*/
|
||||
const CIPHER_BLOWFISH = 6;
|
||||
/**#@-*/
|
||||
|
||||
@ -130,21 +130,21 @@ class SSH1
|
||||
*/
|
||||
/**
|
||||
* .rhosts or /etc/hosts.equiv
|
||||
*/
|
||||
*/
|
||||
const AUTH_RHOSTS = 1;
|
||||
/**
|
||||
* pure RSA authentication
|
||||
*/
|
||||
*/
|
||||
const AUTH_RSA = 2;
|
||||
/**
|
||||
* password authentication
|
||||
*
|
||||
* This is the only method that is supported by this library.
|
||||
*/
|
||||
*/
|
||||
const AUTH_PASSWORD = 3;
|
||||
/**
|
||||
* .rhosts with RSA host authentication
|
||||
*/
|
||||
*/
|
||||
const AUTH_RHOSTS_RSA = 4;
|
||||
/**#@-*/
|
||||
|
||||
@ -162,7 +162,7 @@ class SSH1
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::_get_binary_packet()
|
||||
* @access private
|
||||
*/
|
||||
*/
|
||||
const RESPONSE_TYPE = 1;
|
||||
|
||||
/**
|
||||
@ -170,7 +170,7 @@ class SSH1
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::_get_binary_packet()
|
||||
* @access private
|
||||
*/
|
||||
*/
|
||||
const RESPONSE_DATA = 2;
|
||||
|
||||
/**#@+
|
||||
@ -191,19 +191,19 @@ class SSH1
|
||||
*/
|
||||
/**
|
||||
* Returns the message numbers
|
||||
*/
|
||||
*/
|
||||
const LOG_SIMPLE = 1;
|
||||
/**
|
||||
* Returns the message content
|
||||
*/
|
||||
*/
|
||||
const LOG_COMPLEX = 2;
|
||||
/**
|
||||
* Outputs the content real-time
|
||||
*/
|
||||
*/
|
||||
const LOG_REALTIME = 3;
|
||||
/**
|
||||
* Dumps the content real-time to a file
|
||||
*/
|
||||
*/
|
||||
const LOG_REALTIME_FILE = 4;
|
||||
/**#@-*/
|
||||
|
||||
@ -213,18 +213,18 @@ class SSH1
|
||||
*/
|
||||
/**
|
||||
* Returns when a string matching $expect exactly is found
|
||||
*/
|
||||
*/
|
||||
const READ_SIMPLE = 1;
|
||||
/**
|
||||
* Returns when a string matching the regular expression $expect is found
|
||||
*/
|
||||
*/
|
||||
const READ_REGEX = 2;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* The SSH identifier
|
||||
*
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $identifier = 'SSH-1.5-phpseclib';
|
||||
@ -232,7 +232,7 @@ class SSH1
|
||||
/**
|
||||
* The Socket Object
|
||||
*
|
||||
* @var Object
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $fsock;
|
||||
@ -240,7 +240,7 @@ class SSH1
|
||||
/**
|
||||
* The cryptography object
|
||||
*
|
||||
* @var Object
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $crypto = false;
|
||||
@ -251,7 +251,7 @@ class SSH1
|
||||
* The bits that are set represent functions that have been called already. This is used to determine
|
||||
* if a requisite function has been successfully executed. If not, an error should be thrown.
|
||||
*
|
||||
* @var Integer
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $bitmap = 0;
|
||||
@ -261,8 +261,8 @@ class SSH1
|
||||
*
|
||||
* Logged for debug purposes
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::getServerKeyPublicExponent()
|
||||
* @var String
|
||||
* @see self::getServerKeyPublicExponent()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $server_key_public_exponent;
|
||||
@ -272,8 +272,8 @@ class SSH1
|
||||
*
|
||||
* Logged for debug purposes
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::getServerKeyPublicModulus()
|
||||
* @var String
|
||||
* @see self::getServerKeyPublicModulus()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $server_key_public_modulus;
|
||||
@ -283,8 +283,8 @@ class SSH1
|
||||
*
|
||||
* Logged for debug purposes
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::getHostKeyPublicExponent()
|
||||
* @var String
|
||||
* @see self::getHostKeyPublicExponent()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $host_key_public_exponent;
|
||||
@ -294,8 +294,8 @@ class SSH1
|
||||
*
|
||||
* Logged for debug purposes
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::getHostKeyPublicModulus()
|
||||
* @var String
|
||||
* @see self::getHostKeyPublicModulus()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $host_key_public_modulus;
|
||||
@ -305,8 +305,8 @@ class SSH1
|
||||
*
|
||||
* Logged for debug purposes
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::getSupportedCiphers()
|
||||
* @var Array
|
||||
* @see self::getSupportedCiphers()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $supported_ciphers = array(
|
||||
@ -324,8 +324,8 @@ class SSH1
|
||||
*
|
||||
* Logged for debug purposes
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::getSupportedAuthentications()
|
||||
* @var Array
|
||||
* @see self::getSupportedAuthentications()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $supported_authentications = array(
|
||||
@ -338,8 +338,8 @@ class SSH1
|
||||
/**
|
||||
* Server Identification
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::getServerIdentification()
|
||||
* @var String
|
||||
* @see self::getServerIdentification()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $server_identification = '';
|
||||
@ -347,8 +347,8 @@ class SSH1
|
||||
/**
|
||||
* Protocol Flags
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::__construct()
|
||||
* @var Array
|
||||
* @see self::__construct()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $protocol_flags = array();
|
||||
@ -356,8 +356,8 @@ class SSH1
|
||||
/**
|
||||
* Protocol Flag Log
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::getLog()
|
||||
* @var Array
|
||||
* @see self::getLog()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $protocol_flag_log = array();
|
||||
@ -365,8 +365,8 @@ class SSH1
|
||||
/**
|
||||
* Message Log
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::getLog()
|
||||
* @var Array
|
||||
* @see self::getLog()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $message_log = array();
|
||||
@ -374,8 +374,8 @@ class SSH1
|
||||
/**
|
||||
* Real-time log file pointer
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::_append_log()
|
||||
* @var Resource
|
||||
* @see self::_append_log()
|
||||
* @var resource
|
||||
* @access private
|
||||
*/
|
||||
var $realtime_log_file;
|
||||
@ -383,8 +383,8 @@ class SSH1
|
||||
/**
|
||||
* Real-time log file size
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::_append_log()
|
||||
* @var Integer
|
||||
* @see self::_append_log()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $realtime_log_size;
|
||||
@ -392,8 +392,8 @@ class SSH1
|
||||
/**
|
||||
* Real-time log file wrap boolean
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::_append_log()
|
||||
* @var Boolean
|
||||
* @see self::_append_log()
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $realtime_log_wrap;
|
||||
@ -401,8 +401,8 @@ class SSH1
|
||||
/**
|
||||
* Interactive Buffer
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::read()
|
||||
* @var Array
|
||||
* @see self::read()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $interactiveBuffer = '';
|
||||
@ -410,7 +410,7 @@ class SSH1
|
||||
/**
|
||||
* Timeout
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::setTimeout()
|
||||
* @see self::setTimeout()
|
||||
* @access private
|
||||
*/
|
||||
var $timeout;
|
||||
@ -418,7 +418,7 @@ class SSH1
|
||||
/**
|
||||
* Current Timeout
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::_get_channel_packet()
|
||||
* @see self::_get_channel_packet()
|
||||
* @access private
|
||||
*/
|
||||
var $curTimeout;
|
||||
@ -426,7 +426,7 @@ class SSH1
|
||||
/**
|
||||
* Log Boundary
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::_format_log
|
||||
* @see self::_format_log()
|
||||
* @access private
|
||||
*/
|
||||
var $log_boundary = ':';
|
||||
@ -434,7 +434,7 @@ class SSH1
|
||||
/**
|
||||
* Log Long Width
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::_format_log
|
||||
* @see self::_format_log()
|
||||
* @access private
|
||||
*/
|
||||
var $log_long_width = 65;
|
||||
@ -442,7 +442,7 @@ class SSH1
|
||||
/**
|
||||
* Log Short Width
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::_format_log
|
||||
* @see self::_format_log()
|
||||
* @access private
|
||||
*/
|
||||
var $log_short_width = 16;
|
||||
@ -450,9 +450,9 @@ class SSH1
|
||||
/**
|
||||
* Hostname
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::__construct()
|
||||
* @see \phpseclib\Net\SSH1::_connect()
|
||||
* @var String
|
||||
* @see self::__construct()
|
||||
* @see self::_connect()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $host;
|
||||
@ -460,9 +460,9 @@ class SSH1
|
||||
/**
|
||||
* Port Number
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::__construct()
|
||||
* @see \phpseclib\Net\SSH1::_connect()
|
||||
* @var Integer
|
||||
* @see self::__construct()
|
||||
* @see self::_connect()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $port;
|
||||
@ -475,9 +475,9 @@ class SSH1
|
||||
* however, is non-optional. There will be a timeout, whether or not you set it. If you don't it'll be
|
||||
* 10 seconds. It is used by fsockopen() in that function.
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::__construct()
|
||||
* @see \phpseclib\Net\SSH1::_connect()
|
||||
* @var Integer
|
||||
* @see self::__construct()
|
||||
* @see self::_connect()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $connectionTimeout;
|
||||
@ -485,9 +485,9 @@ class SSH1
|
||||
/**
|
||||
* Default cipher
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::__construct()
|
||||
* @see \phpseclib\Net\SSH1::_connect()
|
||||
* @var Integer
|
||||
* @see self::__construct()
|
||||
* @see self::_connect()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cipher;
|
||||
@ -497,10 +497,10 @@ class SSH1
|
||||
*
|
||||
* Connects to an SSHv1 server
|
||||
*
|
||||
* @param String $host
|
||||
* @param optional Integer $port
|
||||
* @param optional Integer $timeout
|
||||
* @param optional Integer $cipher
|
||||
* @param string $host
|
||||
* @param int $port
|
||||
* @param int $timeout
|
||||
* @param int $cipher
|
||||
* @return \phpseclib\Net\SSH1
|
||||
* @access public
|
||||
*/
|
||||
@ -536,15 +536,16 @@ class SSH1
|
||||
/**
|
||||
* Connect to an SSHv1 server
|
||||
*
|
||||
* @return Boolean
|
||||
* @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) {
|
||||
user_error(rtrim("Cannot connect to {$this->host}:{$this->port}. Error $errno. $errstr"));
|
||||
return false;
|
||||
throw new \RuntimeException(rtrim("Cannot connect to $host. Error $errno. $errstr"));
|
||||
}
|
||||
|
||||
$this->server_identification = $init_line = fgets($this->fsock, 255);
|
||||
@ -555,20 +556,17 @@ class SSH1
|
||||
}
|
||||
|
||||
if (!preg_match('#SSH-([0-9\.]+)-(.+)#', $init_line, $parts)) {
|
||||
user_error('Can only connect to SSH servers');
|
||||
return false;
|
||||
throw new \RuntimeException('Can only connect to SSH servers');
|
||||
}
|
||||
if ($parts[1][0] != 1) {
|
||||
user_error("Cannot connect to SSH $parts[1] servers");
|
||||
return false;
|
||||
throw new \RuntimeException("Cannot connect to $parts[1] servers");
|
||||
}
|
||||
|
||||
fputs($this->fsock, $this->identifier."\r\n");
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) {
|
||||
user_error('Expected SSH_SMSG_PUBLIC_KEY');
|
||||
return false;
|
||||
throw new \UnexpectedValueException('Expected SSH_SMSG_PUBLIC_KEY');
|
||||
}
|
||||
|
||||
$anti_spoofing_cookie = $this->_string_shift($response[self::RESPONSE_DATA], 8);
|
||||
@ -652,8 +650,7 @@ 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)) {
|
||||
user_error('Error sending SSH_CMSG_SESSION_KEY');
|
||||
return false;
|
||||
throw new \RuntimeException('Error sending SSH_CMSG_SESSION_KEY');
|
||||
}
|
||||
|
||||
switch ($cipher) {
|
||||
@ -661,16 +658,20 @@ class SSH1
|
||||
// $this->crypto = new \phpseclib\Crypt\Null();
|
||||
// break;
|
||||
case self::CIPHER_DES:
|
||||
$this->crypto = new DES();
|
||||
$this->crypto = new DES(DES::MODE_CBC);
|
||||
$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();
|
||||
@ -682,8 +683,7 @@ class SSH1
|
||||
$response = $this->_get_binary_packet();
|
||||
|
||||
if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
|
||||
user_error('Expected SSH_SMSG_SUCCESS');
|
||||
return false;
|
||||
throw new \UnexpectedValueException('Expected SSH_SMSG_SUCCESS');
|
||||
}
|
||||
|
||||
$this->bitmap = self::MASK_CONNECTED;
|
||||
@ -694,9 +694,11 @@ class SSH1
|
||||
/**
|
||||
* Login
|
||||
*
|
||||
* @param String $username
|
||||
* @param optional String $password
|
||||
* @return Boolean
|
||||
* @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 = '')
|
||||
@ -715,8 +717,7 @@ class SSH1
|
||||
$data = pack('CNa*', NET_SSH1_CMSG_USER, strlen($username), $username);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
user_error('Error sending SSH_CMSG_USER');
|
||||
return false;
|
||||
throw new \RuntimeException('Error sending SSH_CMSG_USER');
|
||||
}
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
@ -728,15 +729,13 @@ class SSH1
|
||||
$this->bitmap |= self::MASK_LOGIN;
|
||||
return true;
|
||||
} elseif ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) {
|
||||
user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
|
||||
return false;
|
||||
throw new \UnexpectedValueException('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
|
||||
}
|
||||
|
||||
$data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen($password), $password);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
user_error('Error sending SSH_CMSG_AUTH_PASSWORD');
|
||||
return false;
|
||||
throw new \RuntimeException('Error sending SSH_CMSG_AUTH_PASSWORD');
|
||||
}
|
||||
|
||||
// remove the username and password from the last logged packet
|
||||
@ -756,8 +755,7 @@ class SSH1
|
||||
} elseif ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) {
|
||||
return false;
|
||||
} else {
|
||||
user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
|
||||
return false;
|
||||
throw new \UnexpectedValueException('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
|
||||
}
|
||||
}
|
||||
|
||||
@ -767,7 +765,7 @@ class SSH1
|
||||
* $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely. setTimeout() makes it so it'll timeout.
|
||||
* Setting $timeout to false or 0 will mean there is no timeout.
|
||||
*
|
||||
* @param Mixed $timeout
|
||||
* @param mixed $timeout
|
||||
*/
|
||||
function setTimeout($timeout)
|
||||
{
|
||||
@ -788,24 +786,23 @@ class SSH1
|
||||
*
|
||||
* Returns false on failure and the output, otherwise.
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::interactiveRead()
|
||||
* @see \phpseclib\Net\SSH1::interactiveWrite()
|
||||
* @param String $cmd
|
||||
* @see self::interactiveRead()
|
||||
* @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)) {
|
||||
user_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
throw new \RuntimeException('Operation disallowed prior to login()');
|
||||
}
|
||||
|
||||
$data = pack('CNa*', NET_SSH1_CMSG_EXEC_CMD, strlen($cmd), $cmd);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
user_error('Error sending SSH_CMSG_EXEC_CMD');
|
||||
return false;
|
||||
throw new \RuntimeException('Error sending SSH_CMSG_EXEC_CMD');
|
||||
}
|
||||
|
||||
if (!$block) {
|
||||
@ -838,9 +835,11 @@ class SSH1
|
||||
/**
|
||||
* Creates an interactive shell
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::interactiveRead()
|
||||
* @see \phpseclib\Net\SSH1::interactiveWrite()
|
||||
* @return Boolean
|
||||
* @see self::interactiveRead()
|
||||
* @see self::interactiveWrite()
|
||||
* @return bool
|
||||
* @throws \UnexpectedValueException on receipt of unexpected packets
|
||||
* @throws \RuntimeException on other errors
|
||||
* @access private
|
||||
*/
|
||||
function _initShell()
|
||||
@ -851,8 +850,7 @@ 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)) {
|
||||
user_error('Error sending SSH_CMSG_REQUEST_PTY');
|
||||
return false;
|
||||
throw new \RuntimeException('Error sending SSH_CMSG_REQUEST_PTY');
|
||||
}
|
||||
|
||||
$response = $this->_get_binary_packet();
|
||||
@ -861,15 +859,13 @@ class SSH1
|
||||
return false;
|
||||
}
|
||||
if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
|
||||
user_error('Expected SSH_SMSG_SUCCESS');
|
||||
return false;
|
||||
throw new \UnexpectedValueException('Expected SSH_SMSG_SUCCESS');
|
||||
}
|
||||
|
||||
$data = pack('C', NET_SSH1_CMSG_EXEC_SHELL);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
user_error('Error sending SSH_CMSG_EXEC_SHELL');
|
||||
return false;
|
||||
throw new \RuntimeException('Error sending SSH_CMSG_EXEC_SHELL');
|
||||
}
|
||||
|
||||
$this->bitmap |= self::MASK_SHELL;
|
||||
@ -882,9 +878,9 @@ class SSH1
|
||||
/**
|
||||
* Inputs a command into an interactive shell.
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::interactiveWrite()
|
||||
* @param String $cmd
|
||||
* @return Boolean
|
||||
* @see self::interactiveWrite()
|
||||
* @param string $cmd
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function write($cmd)
|
||||
@ -898,22 +894,21 @@ class SSH1
|
||||
* $expect can take the form of a string literal or, if $mode == self::READ__REGEX,
|
||||
* a regular expression.
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::write()
|
||||
* @param String $expect
|
||||
* @param Integer $mode
|
||||
* @return Boolean
|
||||
* @see self::write()
|
||||
* @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)) {
|
||||
user_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
throw new \RuntimeException('Operation disallowed prior to login()');
|
||||
}
|
||||
|
||||
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
|
||||
user_error('Unable to initiate an interactive shell session');
|
||||
return false;
|
||||
throw new \RuntimeException('Unable to initiate an interactive shell session');
|
||||
}
|
||||
|
||||
$match = $expect;
|
||||
@ -938,28 +933,26 @@ class SSH1
|
||||
/**
|
||||
* Inputs a command into an interactive shell.
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::interactiveRead()
|
||||
* @param String $cmd
|
||||
* @return Boolean
|
||||
* @see self::interactiveRead()
|
||||
* @param string $cmd
|
||||
* @return bool
|
||||
* @throws \RuntimeException on connection error
|
||||
* @access public
|
||||
*/
|
||||
function interactiveWrite($cmd)
|
||||
{
|
||||
if (!($this->bitmap & self::MASK_LOGIN)) {
|
||||
user_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
throw new \RuntimeException('Operation disallowed prior to login()');
|
||||
}
|
||||
|
||||
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
|
||||
user_error('Unable to initiate an interactive shell session');
|
||||
return false;
|
||||
throw new \RuntimeException('Unable to initiate an interactive shell session');
|
||||
}
|
||||
|
||||
$data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($cmd), $cmd);
|
||||
|
||||
if (!$this->_send_binary_packet($data)) {
|
||||
user_error('Error sending SSH_CMSG_STDIN');
|
||||
return false;
|
||||
throw new \RuntimeException('Error sending SSH_CMSG_STDIN');
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -974,20 +967,19 @@ class SSH1
|
||||
* does not support ANSI escape sequences in Win32 Console applications", so if you're a Windows user,
|
||||
* there's not going to be much recourse.
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::interactiveRead()
|
||||
* @return String
|
||||
* @see self::interactiveRead()
|
||||
* @return string
|
||||
* @throws \RuntimeException on connection error
|
||||
* @access public
|
||||
*/
|
||||
function interactiveRead()
|
||||
{
|
||||
if (!($this->bitmap & self::MASK_LOGIN)) {
|
||||
user_error('Operation disallowed prior to login()');
|
||||
return false;
|
||||
throw new \RuntimeException('Operation disallowed prior to login()');
|
||||
}
|
||||
|
||||
if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
|
||||
user_error('Unable to initiate an interactive shell session');
|
||||
return false;
|
||||
throw new \RuntimeException('Unable to initiate an interactive shell session');
|
||||
}
|
||||
|
||||
$read = array($this->fsock);
|
||||
@ -1026,7 +1018,7 @@ class SSH1
|
||||
/**
|
||||
* Disconnect
|
||||
*
|
||||
* @param String $msg
|
||||
* @param string $msg
|
||||
* @access private
|
||||
*/
|
||||
function _disconnect($msg = 'Client Quit')
|
||||
@ -1063,8 +1055,8 @@ class SSH1
|
||||
* Also, this function could be improved upon by adding detection for the following exploit:
|
||||
* http://www.securiteam.com/securitynews/5LP042K3FY.html
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::_send_binary_packet()
|
||||
* @return Array
|
||||
* @see self::_send_binary_packet()
|
||||
* @return array
|
||||
* @access private
|
||||
*/
|
||||
function _get_binary_packet()
|
||||
@ -1139,9 +1131,9 @@ class SSH1
|
||||
*
|
||||
* Returns true on success, false on failure.
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::_get_binary_packet()
|
||||
* @param String $data
|
||||
* @return Boolean
|
||||
* @see self::_get_binary_packet()
|
||||
* @param string $data
|
||||
* @return bool
|
||||
* @access private
|
||||
*/
|
||||
function _send_binary_packet($data)
|
||||
@ -1186,10 +1178,10 @@ class SSH1
|
||||
* we've reimplemented it. A more detailed discussion of the differences can be found after
|
||||
* $crc_lookup_table's initialization.
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::_get_binary_packet()
|
||||
* @see \phpseclib\Net\SSH1::_send_binary_packet()
|
||||
* @param String $data
|
||||
* @return Integer
|
||||
* @see self::_get_binary_packet()
|
||||
* @see self::_send_binary_packet()
|
||||
* @param string $data
|
||||
* @return int
|
||||
* @access private
|
||||
*/
|
||||
function _crc($data)
|
||||
@ -1284,9 +1276,9 @@ class SSH1
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param String $string
|
||||
* @param optional Integer $index
|
||||
* @return String
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function _string_shift(&$string, $index = 1)
|
||||
@ -1303,9 +1295,9 @@ class SSH1
|
||||
* should be a number with the property that gcd($e, ($p - 1) * ($q - 1)) == 1. Could just make anything that
|
||||
* calls this call modexp, instead, but I think this makes things clearer, maybe...
|
||||
*
|
||||
* @see \phpseclib\Net\SSH1::__construct()
|
||||
* @see self::__construct()
|
||||
* @param BigInteger $m
|
||||
* @param Array $key
|
||||
* @param array $key
|
||||
* @return BigInteger
|
||||
* @access private
|
||||
*/
|
||||
@ -1313,9 +1305,9 @@ class SSH1
|
||||
{
|
||||
/*
|
||||
$rsa = new RSA();
|
||||
$rsa->loadKey($key, RSA::PUBLIC_FORMAT_RAW);
|
||||
$rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
|
||||
return $rsa->encrypt($m);
|
||||
$rsa->load($key, 'raw');
|
||||
$rsa->setHash('sha1');
|
||||
return $rsa->encrypt($m, RSA::PADDING_PKCS1);
|
||||
*/
|
||||
|
||||
// To quote from protocol-1.5.txt:
|
||||
@ -1354,7 +1346,7 @@ class SSH1
|
||||
* named constants from it, using the value as the name of the constant and the index as the value of the constant.
|
||||
* If any of the constants that would be defined already exists, none of the constants will be defined.
|
||||
*
|
||||
* @param Array $array
|
||||
* @param array $array
|
||||
* @access private
|
||||
*/
|
||||
function _define_array()
|
||||
@ -1377,7 +1369,7 @@ class SSH1
|
||||
* Returns a string if NET_SSH1_LOGGING == self::LOG_COMPLEX, an array if NET_SSH1_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SSH1_LOGGING')
|
||||
*
|
||||
* @access public
|
||||
* @return String or Array
|
||||
* @return array|false|string
|
||||
*/
|
||||
function getLog()
|
||||
{
|
||||
@ -1400,10 +1392,10 @@ class SSH1
|
||||
/**
|
||||
* Formats a log for printing
|
||||
*
|
||||
* @param Array $message_log
|
||||
* @param Array $message_number_log
|
||||
* @param array $message_log
|
||||
* @param array $message_number_log
|
||||
* @access private
|
||||
* @return String
|
||||
* @return string
|
||||
*/
|
||||
function _format_log($message_log, $message_number_log)
|
||||
{
|
||||
@ -1436,9 +1428,9 @@ class SSH1
|
||||
*
|
||||
* For use with preg_replace_callback()
|
||||
*
|
||||
* @param Array $matches
|
||||
* @param array $matches
|
||||
* @access private
|
||||
* @return String
|
||||
* @return string
|
||||
*/
|
||||
function _format_log_helper($matches)
|
||||
{
|
||||
@ -1451,8 +1443,8 @@ class SSH1
|
||||
* Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead,
|
||||
* the raw bytes. This behavior is similar to PHP's md5() function.
|
||||
*
|
||||
* @param optional Boolean $raw_output
|
||||
* @return String
|
||||
* @param bool $raw_output
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function getServerKeyPublicExponent($raw_output = false)
|
||||
@ -1466,8 +1458,8 @@ class SSH1
|
||||
* Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead,
|
||||
* the raw bytes. This behavior is similar to PHP's md5() function.
|
||||
*
|
||||
* @param optional Boolean $raw_output
|
||||
* @return String
|
||||
* @param bool $raw_output
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function getServerKeyPublicModulus($raw_output = false)
|
||||
@ -1481,8 +1473,8 @@ class SSH1
|
||||
* Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead,
|
||||
* the raw bytes. This behavior is similar to PHP's md5() function.
|
||||
*
|
||||
* @param optional Boolean $raw_output
|
||||
* @return String
|
||||
* @param bool $raw_output
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function getHostKeyPublicExponent($raw_output = false)
|
||||
@ -1496,8 +1488,8 @@ class SSH1
|
||||
* Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead,
|
||||
* the raw bytes. This behavior is similar to PHP's md5() function.
|
||||
*
|
||||
* @param optional Boolean $raw_output
|
||||
* @return String
|
||||
* @param bool $raw_output
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function getHostKeyPublicModulus($raw_output = false)
|
||||
@ -1512,8 +1504,8 @@ class SSH1
|
||||
* is set to true, returns, instead, an array of constants. ie. instead of array('Triple-DES in CBC mode'), you'll
|
||||
* get array(self::CIPHER_3DES).
|
||||
*
|
||||
* @param optional Boolean $raw_output
|
||||
* @return Array
|
||||
* @param bool $raw_output
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function getSupportedCiphers($raw_output = false)
|
||||
@ -1528,8 +1520,8 @@ class SSH1
|
||||
* is set to true, returns, instead, an array of constants. ie. instead of array('password authentication'), you'll
|
||||
* get array(self::AUTH_PASSWORD).
|
||||
*
|
||||
* @param optional Boolean $raw_output
|
||||
* @return Array
|
||||
* @param bool $raw_output
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function getSupportedAuthentications($raw_output = false)
|
||||
@ -1540,7 +1532,7 @@ class SSH1
|
||||
/**
|
||||
* Return the server identification.
|
||||
*
|
||||
* @return String
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
function getServerIdentification()
|
||||
@ -1553,7 +1545,7 @@ class SSH1
|
||||
*
|
||||
* Makes sure that only the last 1MB worth of packets will be logged
|
||||
*
|
||||
* @param String $data
|
||||
* @param string $data
|
||||
* @access private
|
||||
*/
|
||||
function _append_log($protocol_flags, $message)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -34,6 +34,7 @@
|
||||
namespace phpseclib\System\SSH;
|
||||
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\Exception\BadConfigurationException;
|
||||
use phpseclib\System\SSH\Agent\Identity;
|
||||
|
||||
/**
|
||||
@ -83,7 +84,7 @@ class Agent
|
||||
/**
|
||||
* Socket Resource
|
||||
*
|
||||
* @var Resource
|
||||
* @var resource
|
||||
* @access private
|
||||
*/
|
||||
var $fsock;
|
||||
@ -115,6 +116,8 @@ 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()
|
||||
@ -127,13 +130,12 @@ class Agent
|
||||
$address = $_ENV['SSH_AUTH_SOCK'];
|
||||
break;
|
||||
default:
|
||||
user_error('SSH_AUTH_SOCK not found');
|
||||
return false;
|
||||
throw new \BadConfigurationException('SSH_AUTH_SOCK not found');
|
||||
}
|
||||
|
||||
$this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
|
||||
if (!$this->fsock) {
|
||||
user_error("Unable to connect to ssh-agent (Error $errno: $errstr)");
|
||||
throw new \RuntimeException("Unable to connect to ssh-agent (Error $errno: $errstr)");
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,7 +145,8 @@ class Agent
|
||||
* See "2.5.2 Requesting a list of protocol 2 keys"
|
||||
* Returns an array containing zero or more \phpseclib\System\SSH\Agent\Identity objects
|
||||
*
|
||||
* @return Array
|
||||
* @return array
|
||||
* @throws \RuntimeException on receipt of unexpected packets
|
||||
* @access public
|
||||
*/
|
||||
function requestIdentities()
|
||||
@ -154,13 +157,13 @@ class Agent
|
||||
|
||||
$packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES);
|
||||
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
||||
user_error('Connection closed while requesting identities');
|
||||
throw new \RuntimeException('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) {
|
||||
user_error('Unable to request identities');
|
||||
throw new \RuntimeException('Unable to request identities');
|
||||
}
|
||||
|
||||
$identities = array();
|
||||
@ -169,13 +172,15 @@ class Agent
|
||||
$length = current(unpack('N', fread($this->fsock, 4)));
|
||||
$key_blob = fread($this->fsock, $length);
|
||||
$length = current(unpack('N', fread($this->fsock, 4)));
|
||||
$key_comment = fread($this->fsock, $length);
|
||||
if ($length) {
|
||||
$key_comment = fread($this->fsock, $length);
|
||||
}
|
||||
$length = current(unpack('N', substr($key_blob, 0, 4)));
|
||||
$key_type = substr($key_blob, 4, $length);
|
||||
switch ($key_type) {
|
||||
case 'ssh-rsa':
|
||||
$key = new RSA();
|
||||
$key->loadKey('ssh-rsa ' . base64_encode($key_blob) . ' ' . $key_comment);
|
||||
$key->load('ssh-rsa ' . base64_encode($key_blob) . ' ' . $key_comment);
|
||||
break;
|
||||
case 'ssh-dss':
|
||||
// not currently supported
|
||||
@ -199,7 +204,7 @@ class Agent
|
||||
* be requested when a channel is opened
|
||||
*
|
||||
* @param Net_SSH2 $ssh
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function startSSHForwarding($ssh)
|
||||
@ -213,7 +218,7 @@ class Agent
|
||||
* Request agent forwarding of remote server
|
||||
*
|
||||
* @param Net_SSH2 $ssh
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
* @access private
|
||||
*/
|
||||
function _request_forwarding($ssh)
|
||||
@ -269,8 +274,9 @@ class Agent
|
||||
/**
|
||||
* Forward data to SSH Agent and return data reply
|
||||
*
|
||||
* @param String $data
|
||||
* @param string $data
|
||||
* @return data from SSH Agent
|
||||
* @throws \RuntimeException on connection errors
|
||||
* @access private
|
||||
*/
|
||||
function _forward_data($data)
|
||||
@ -289,7 +295,7 @@ class Agent
|
||||
}
|
||||
|
||||
if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) {
|
||||
user_error('Connection closed attempting to forward data to SSH agent');
|
||||
throw new \RuntimeException('Connection closed attempting to forward data to SSH agent');
|
||||
}
|
||||
|
||||
$this->socket_buffer = '';
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
namespace phpseclib\System\SSH\Agent;
|
||||
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\Exception\UnsupportedAlgorithmException;
|
||||
use phpseclib\System\SSH\Agent;
|
||||
|
||||
/**
|
||||
@ -23,9 +25,8 @@ 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, setSignatureMode
|
||||
* and sign since those are the methods phpseclib looks for to perform
|
||||
* public key authentication.
|
||||
* The methods in this interface would be getPublicKey and sign since those are the
|
||||
* methods phpseclib looks for to perform public key authentication.
|
||||
*
|
||||
* @package SSH\Agent
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
@ -38,32 +39,32 @@ class Identity
|
||||
*
|
||||
* @var \phpseclib\Crypt\RSA
|
||||
* @access private
|
||||
* @see \phpseclib\System\SSH\Agent\Identity::getPublicKey()
|
||||
* @see self::getPublicKey()
|
||||
*/
|
||||
var $key;
|
||||
|
||||
/**
|
||||
* Key Blob
|
||||
*
|
||||
* @var String
|
||||
* @var string
|
||||
* @access private
|
||||
* @see \phpseclib\System\SSH\Agent\Identity::sign()
|
||||
* @see self::sign()
|
||||
*/
|
||||
var $key_blob;
|
||||
|
||||
/**
|
||||
* Socket Resource
|
||||
*
|
||||
* @var Resource
|
||||
* @var resource
|
||||
* @access private
|
||||
* @see \phpseclib\System\SSH\Agent\Identity::sign()
|
||||
* @see self::sign()
|
||||
*/
|
||||
var $fsock;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @param Resource $fsock
|
||||
* @param resource $fsock
|
||||
* @return \phpseclib\System\SSH\Agent\Identity
|
||||
* @access private
|
||||
*/
|
||||
@ -92,7 +93,7 @@ class Identity
|
||||
* Called by \phpseclib\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key
|
||||
* but this saves a small amount of computation.
|
||||
*
|
||||
* @param String $key_blob
|
||||
* @param string $key_blob
|
||||
* @access private
|
||||
*/
|
||||
function setPublicKeyBlob($key_blob)
|
||||
@ -105,26 +106,29 @@ class Identity
|
||||
*
|
||||
* Wrapper for $this->key->getPublicKey()
|
||||
*
|
||||
* @param Integer $format optional
|
||||
* @return Mixed
|
||||
* @param int $type optional
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function getPublicKey($format = null)
|
||||
function getPublicKey($type = 'PKCS8')
|
||||
{
|
||||
return !isset($format) ? $this->key->getPublicKey() : $this->key->getPublicKey($format);
|
||||
return $this->key->getPublicKey($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Signature Mode
|
||||
* Sets the hash
|
||||
*
|
||||
* 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
|
||||
* ssh-agent only supports signatures with sha1 hashes but to maintain BC with RSA.php this function exists
|
||||
*
|
||||
* @param Integer $mode
|
||||
* @param string $hash optional
|
||||
* @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
|
||||
* @access public
|
||||
*/
|
||||
function setSignatureMode($mode)
|
||||
function setHash($hash = 'sha1')
|
||||
{
|
||||
if ($hash != 'sha1') {
|
||||
throw new UnsupportedAlgorithmException('ssh-agent can only be used with the sha1 hash');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,23 +136,30 @@ class Identity
|
||||
*
|
||||
* See "2.6.2 Protocol 2 private key signature request"
|
||||
*
|
||||
* @param String $message
|
||||
* @return String
|
||||
* @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)
|
||||
function sign($message, $padding = RSA::PADDING_PKCS1)
|
||||
{
|
||||
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)) {
|
||||
user_error('Connection closed during signing');
|
||||
throw new \RuntimeException('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) {
|
||||
user_error('Unable to retreive signature');
|
||||
throw new \RuntimeException('Unable to retreive signature');
|
||||
}
|
||||
|
||||
$signature_blob = fread($this->fsock, $length - 1);
|
||||
|
@ -27,6 +27,34 @@ class Functional_Net_SFTPStreamTest extends Functional_Net_SFTPTestCase
|
||||
$this->assertSame(0, $this->sftp->size('fooo.txt'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github778
|
||||
*/
|
||||
public function testFilenameWithHash()
|
||||
{
|
||||
$context = stream_context_create(array(
|
||||
'sftp' => array('session' => $this->sftp),
|
||||
));
|
||||
$fp = fopen($this->buildUrl('te#st.txt'), 'wb', false, $context);
|
||||
fputs($fp, 'zzzz');
|
||||
fclose($fp);
|
||||
|
||||
$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(
|
||||
|
@ -13,6 +13,9 @@ use phpseclib\Net\SFTP;
|
||||
*/
|
||||
abstract class Functional_Net_SFTPTestCase extends PhpseclibFunctionalTestCase
|
||||
{
|
||||
/**
|
||||
* @var SFTP
|
||||
*/
|
||||
protected $sftp;
|
||||
protected $scratchDir;
|
||||
|
||||
|
@ -171,8 +171,8 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testStatOnDir
|
||||
*/
|
||||
* @depends testStatOnDir
|
||||
*/
|
||||
public function testPutSizeGetFileCallback($sftp)
|
||||
{
|
||||
self::$buffer = self::$exampleData;
|
||||
@ -240,6 +240,20 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
|
||||
|
||||
/**
|
||||
* @depends testTruncate
|
||||
* @group github850
|
||||
*/
|
||||
public function testChModOnFile($sftp)
|
||||
{
|
||||
$this->assertNotFalse(
|
||||
$sftp->chmod(0755, 'file1.txt'),
|
||||
'Failed asserting that chmod() was successful.'
|
||||
);
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testChModOnFile
|
||||
*/
|
||||
public function testChDirOnFile($sftp)
|
||||
{
|
||||
@ -651,5 +665,28 @@ class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
|
||||
$this->assertSame($stat['type'], NET_SFTP_TYPE_SYMLINK);
|
||||
|
||||
$sftp->enableStatCache();
|
||||
|
||||
return $sftp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testStatVsLstat
|
||||
* @group github830
|
||||
*/
|
||||
public function testUploadOffsets($sftp)
|
||||
{
|
||||
$sftp->put('offset.txt', 'res.txt', SFTP::SOURCE_LOCAL_FILE, 0, 10);
|
||||
$this->assertSame(
|
||||
substr(self::$exampleData, 10),
|
||||
$sftp->get('offset.txt'),
|
||||
'Failed asserting that portions of a file could be uploaded.'
|
||||
);
|
||||
|
||||
$sftp->put('offset.txt', 'res.txt', SFTP::SOURCE_LOCAL_FILE, self::$exampleDataLength - 100);
|
||||
$this->assertSame(
|
||||
substr(self::$exampleData, 10, -90) . self::$exampleData,
|
||||
$sftp->get('offset.txt'),
|
||||
'Failed asserting that you could upload into the middle of a file.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,11 @@ class Functional_Net_SSH2Test extends PhpseclibFunctionalTestCase
|
||||
'Failed asserting that SSH2 is not connected after construction.'
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$ssh->isAuthenticated(),
|
||||
'Failed asserting that SSH2 is not authenticated after construction.'
|
||||
);
|
||||
|
||||
$this->assertNotEmpty(
|
||||
$ssh->getServerPublicHostKey(),
|
||||
'Failed asserting that a non-empty public host key was fetched.'
|
||||
@ -55,6 +60,31 @@ class Functional_Net_SSH2Test extends PhpseclibFunctionalTestCase
|
||||
/**
|
||||
* @depends testPreLogin
|
||||
*/
|
||||
public function testBadPassword($ssh)
|
||||
{
|
||||
$username = $this->getEnv('SSH_USERNAME');
|
||||
$password = $this->getEnv('SSH_PASSWORD');
|
||||
$this->assertFalse(
|
||||
$ssh->login($username, 'zzz' . $password),
|
||||
'SSH2 login using password succeeded.'
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$ssh->isConnected(),
|
||||
'Failed asserting that SSH2 is connected after bad login attempt.'
|
||||
);
|
||||
|
||||
$this->assertFalse(
|
||||
$ssh->isAuthenticated(),
|
||||
'Failed asserting that SSH2 is not authenticated after bad login attempt.'
|
||||
);
|
||||
|
||||
return $ssh;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testBadPassword
|
||||
*/
|
||||
public function testPasswordLogin($ssh)
|
||||
{
|
||||
$username = $this->getEnv('SSH_USERNAME');
|
||||
@ -64,6 +94,11 @@ class Functional_Net_SSH2Test extends PhpseclibFunctionalTestCase
|
||||
'SSH2 login using password failed.'
|
||||
);
|
||||
|
||||
$this->assertTrue(
|
||||
$ssh->isAuthenticated(),
|
||||
'Failed asserting that SSH2 is authenticated after good login attempt.'
|
||||
);
|
||||
|
||||
return $ssh;
|
||||
}
|
||||
|
||||
|
@ -28,9 +28,7 @@ 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();
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ abstract class PhpseclibTestCase extends PHPUnit_Framework_TestCase
|
||||
$value = constant($constant);
|
||||
|
||||
if ($value !== $expected) {
|
||||
if (function_exists('runkit_constant_redefine')) {
|
||||
if (extension_loaded('runkit')) {
|
||||
if (!runkit_constant_redefine($constant, $expected)) {
|
||||
self::markTestSkipped(sprintf(
|
||||
"Failed to redefine constant %s to %s",
|
||||
@ -82,15 +82,15 @@ abstract class PhpseclibTestCase extends PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @param string $filename Filename relative to library directory.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
protected static function reRequireFile($filename)
|
||||
{
|
||||
if (function_exists('runkit_import')) {
|
||||
if (extension_loaded('runkit')) {
|
||||
$result = runkit_import(
|
||||
$filename,
|
||||
sprintf('%s/../phpseclib/%s', __DIR__, $filename),
|
||||
RUNKIT_IMPORT_FUNCTIONS |
|
||||
RUNKIT_IMPORT_CLASS_METHODS |
|
||||
RUNKIT_IMPORT_OVERRIDE
|
||||
|
@ -47,24 +47,26 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
|
||||
':-):-):-):-):-):-)', // https://github.com/phpseclib/phpseclib/pull/43
|
||||
);
|
||||
$ivs = array(
|
||||
'',
|
||||
'test123',
|
||||
str_repeat("\0", 16),
|
||||
str_pad('test123', 16, "\0"),
|
||||
);
|
||||
$keys = array(
|
||||
'',
|
||||
':-8', // https://github.com/phpseclib/phpseclib/pull/43
|
||||
'FOOBARZ',
|
||||
str_repeat("\0", 16),
|
||||
str_pad(':-8', 16, "\0"), // https://github.com/phpseclib/phpseclib/pull/43
|
||||
str_pad('FOOBARZ', 16, "\0"),
|
||||
);
|
||||
|
||||
$result = array();
|
||||
|
||||
// @codingStandardsIgnoreStart
|
||||
foreach ($modes as $mode)
|
||||
foreach ($plaintexts as $plaintext)
|
||||
foreach ($ivs as $iv)
|
||||
foreach ($keys as $key)
|
||||
$result[] = array($mode, $plaintext, $iv, $key);
|
||||
// @codingStandardsIgnoreEnd
|
||||
foreach ($modes as $mode) {
|
||||
foreach ($plaintexts as $plaintext) {
|
||||
foreach ($ivs as $iv) {
|
||||
foreach ($keys as $key) {
|
||||
$result[] = array($mode, $plaintext, $iv, $key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
@ -98,10 +100,11 @@ 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();
|
||||
$aes = new Rijndael(Base::MODE_CBC);
|
||||
$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'));
|
||||
@ -109,25 +112,27 @@ 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();
|
||||
$aes = new AES(Base::MODE_CBC);
|
||||
$aes->setPreferredEngine($this->engine);
|
||||
$aes->disablePadding();
|
||||
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. AES should null pad to 192-bits
|
||||
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. supported by Rijndael - not AES
|
||||
$aes->setIV(str_repeat("\0", 16));
|
||||
$this->_checkEngine($aes);
|
||||
$ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734'));
|
||||
$this->assertEquals($ciphertext, pack('H*', 'c109292b173f841b88e0ee49f13db8c0'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces all combinations of test values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
* Produces all combinations of test values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function continuousBufferBatteryCombos()
|
||||
{
|
||||
$modes = array(
|
||||
@ -155,19 +160,20 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
|
||||
|
||||
$result = array();
|
||||
|
||||
// @codingStandardsIgnoreStart
|
||||
foreach ($modes as $mode)
|
||||
foreach ($combos as $combo)
|
||||
foreach (array('encrypt', 'decrypt') as $op)
|
||||
$result[] = array($op, $mode, $combo);
|
||||
// @codingStandardsIgnoreEnd
|
||||
foreach ($modes as $mode) {
|
||||
foreach ($combos as $combo) {
|
||||
foreach (array('encrypt', 'decrypt') as $op) {
|
||||
$result[] = array($op, $mode, $combo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider continuousBufferBatteryCombos
|
||||
*/
|
||||
* @dataProvider continuousBufferBatteryCombos
|
||||
*/
|
||||
public function testContinuousBufferBattery($op, $mode, $test)
|
||||
{
|
||||
$iv = str_repeat('x', 16);
|
||||
@ -211,9 +217,10 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider continuousBufferBatteryCombos
|
||||
*/
|
||||
// pretty much the same as testContinuousBufferBattery with the caveat that continuous mode is not enabled
|
||||
* Pretty much the same as testContinuousBufferBattery with the caveat that continuous mode is not enabled.
|
||||
*
|
||||
* @dataProvider continuousBufferBatteryCombos
|
||||
*/
|
||||
public function testNonContinuousBufferBattery($op, $mode, $test)
|
||||
{
|
||||
if (count($test) == 1) {
|
||||
@ -260,7 +267,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();
|
||||
$aes = new AES(Base::MODE_CBC);
|
||||
|
||||
$aes->setKey(pack('H*', '00000000000000000000000000000000'));
|
||||
$aes->setIV(pack('H*', '00000000000000000000000000000000'));
|
||||
@ -287,7 +294,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
|
||||
|
||||
public function testGFSBox192()
|
||||
{
|
||||
$aes = new AES();
|
||||
$aes = new AES(Base::MODE_CBC);
|
||||
|
||||
$aes->setKey(pack('H*', '000000000000000000000000000000000000000000000000'));
|
||||
$aes->setIV(pack('H*', '00000000000000000000000000000000'));
|
||||
@ -312,7 +319,7 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
|
||||
|
||||
public function testGFSBox256()
|
||||
{
|
||||
$aes = new AES();
|
||||
$aes = new AES(Base::MODE_CBC);
|
||||
|
||||
$aes->setKey(pack('H*', '00000000000000000000000000000000' . '00000000000000000000000000000000'));
|
||||
$aes->setIV(pack('H*', '00000000000000000000000000000000'));
|
||||
@ -332,4 +339,63 @@ abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
|
||||
$result = bin2hex($aes->encrypt(pack('H*', '91fbef2d15a97816060bee1feaa49afe')));
|
||||
$this->assertSame($result, '1bc704f1bce135ceb810341b216d7abe');
|
||||
}
|
||||
|
||||
public function testGetKeyLengthDefault()
|
||||
{
|
||||
$aes = new AES(Base::MODE_CBC);
|
||||
$this->assertSame($aes->getKeyLength(), 128);
|
||||
}
|
||||
|
||||
public function testGetKeyLengthWith192BitKey()
|
||||
{
|
||||
$aes = new AES(Base::MODE_CBC);
|
||||
$aes->setKey(str_repeat('a', 24));
|
||||
$this->assertSame($aes->getKeyLength(), 192);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LengthException
|
||||
*/
|
||||
public function testSetKeyLengthWithLargerKey()
|
||||
{
|
||||
$aes = new AES(Base::MODE_CBC);
|
||||
$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->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');
|
||||
$this->assertSame($aes->getKeyLength(), 256);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github938
|
||||
*/
|
||||
public function testContinuousBuffer()
|
||||
{
|
||||
$aes = new AES(AES::MODE_CBC);
|
||||
$aes->disablePadding();
|
||||
$aes->enableContinuousBuffer();
|
||||
$aes->setIV(pack('H*', '0457bdb4a6712986688349a29eb82535'));
|
||||
$aes->setKey(pack('H*', '00d596e2c8189b2592fac358e7396ad2'));
|
||||
$aes->decrypt(pack('H*', '9aa234ea7c750a8109a0f32d768b964e'));
|
||||
$plaintext = $aes->decrypt(pack('H*', '0457bdb4a6712986688349a29eb82535'));
|
||||
$expected = pack('H*', '6572617574689e1be8d2d8d43c594cf3');
|
||||
$this->assertSame($plaintext, $expected);
|
||||
}
|
||||
}
|
||||
|
@ -56,22 +56,26 @@ class Unit_Crypt_BlowfishTest extends PhpseclibTestCase
|
||||
array(pack('H*', '0123456789ABCDEF'), pack('H*', '0000000000000000'), pack('H*', '245946885754369A')),
|
||||
array(pack('H*', 'FEDCBA9876543210'), pack('H*', 'FFFFFFFFFFFFFFFF'), pack('H*', '6B5C5A9C5D9E0A5A'))
|
||||
);
|
||||
|
||||
$result = array();
|
||||
// @codingStandardsIgnoreStart
|
||||
foreach ($engines as $engine => $engineName)
|
||||
foreach ($tests as $test)
|
||||
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2]);
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
||||
foreach ($engines as $engine => $engineName) {
|
||||
foreach ($tests as $test) {
|
||||
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2]);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider engineVectors
|
||||
*/
|
||||
* @dataProvider engineVectors
|
||||
*/
|
||||
public function testVectors($engine, $engineName, $key, $plaintext, $expected)
|
||||
{
|
||||
$bf = new Blowfish();
|
||||
$bf = new Blowfish(Blowfish::MODE_CBC);
|
||||
$bf->setKey($key);
|
||||
$bf->setIV(str_repeat("\0", $bf->getBlockLength() >> 3));
|
||||
if (!$bf->isValidEngine($engine)) {
|
||||
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
|
||||
}
|
||||
|
@ -1,78 +0,0 @@
|
||||
<?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');
|
||||
}
|
||||
}
|
||||
}
|
@ -1,49 +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_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'),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
<?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',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
<?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));
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
<?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',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
<?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));
|
||||
}
|
||||
}
|
@ -1,52 +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;
|
||||
|
||||
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
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
423
tests/Unit/Crypt/HashTest.php
Normal file
423
tests/Unit/Crypt/HashTest.php
Normal file
@ -0,0 +1,423 @@
|
||||
<?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),
|
||||
);
|
||||
}
|
||||
}
|
@ -30,12 +30,15 @@ class Unit_Crypt_RC2Test extends PhpseclibTestCase
|
||||
array('88bca90e90875a7f0f79c384627bafb2', 128, '0000000000000000', '2269552ab0f85ca6'),
|
||||
array('88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e', 129, '0000000000000000', '5b78d3a43dfff1f1')
|
||||
);
|
||||
|
||||
$result = array();
|
||||
// @codingStandardsIgnoreStart
|
||||
foreach ($this->engines as $engine => $engineName)
|
||||
foreach ($tests as $test)
|
||||
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2], $test[3]);
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
||||
foreach ($this->engines as $engine => $engineName) {
|
||||
foreach ($tests as $test) {
|
||||
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2], $test[3]);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@ -103,14 +106,15 @@ class Unit_Crypt_RC2Test extends PhpseclibTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider engineVectors
|
||||
*/
|
||||
* @dataProvider engineVectors
|
||||
*/
|
||||
public function testVectors($engine, $engineName, $key, $keyLen, $plaintext, $ciphertext)
|
||||
{
|
||||
$rc2 = new RC2();
|
||||
$rc2 = new RC2(RC2::MODE_CBC);
|
||||
$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');
|
||||
}
|
||||
@ -118,5 +122,8 @@ class Unit_Crypt_RC2Test extends PhpseclibTestCase
|
||||
|
||||
$result = bin2hex($rc2->encrypt(pack('H*', $plaintext)));
|
||||
$this->assertEquals($result, $ciphertext, "Failed asserting that $plaintext yielded expected output in $engineName engine");
|
||||
|
||||
$result = bin2hex($rc2->decrypt(pack('H*', $ciphertext)));
|
||||
$this->assertEquals($result, $plaintext, "Failed asserting that decrypted result yielded $plaintext as a result in $engineName engine");
|
||||
}
|
||||
}
|
||||
|
@ -181,19 +181,23 @@ class Unit_Crypt_RC4Test extends PhpseclibTestCase
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$result = array();
|
||||
// @codingStandardsIgnoreStart
|
||||
foreach ($engines as $engine => $engineName)
|
||||
foreach ($tests as $test)
|
||||
foreach ($test['output'] as $output)
|
||||
$result[] = array($engine, $engineName, $test['key'], $output['offset'], $output['result']);
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
||||
foreach ($engines as $engine => $engineName) {
|
||||
foreach ($tests as $test) {
|
||||
foreach ($test['output'] as $output) {
|
||||
$result[] = array($engine, $engineName, $test['key'], $output['offset'], $output['result']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider engineVectors
|
||||
*/
|
||||
* @dataProvider engineVectors
|
||||
*/
|
||||
public function testVectors($engine, $engineName, $key, $offset, $expected)
|
||||
{
|
||||
$rc4 = new RC4();
|
||||
|
34
tests/Unit/Crypt/RSA/CreateKeyTest.php
Normal file
34
tests/Unit/Crypt/RSA/CreateKeyTest.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?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');
|
||||
}
|
||||
}
|
@ -6,6 +6,9 @@
|
||||
*/
|
||||
|
||||
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
|
||||
{
|
||||
@ -15,7 +18,7 @@ class Unit_Crypt_RSA_LoadKeyTest extends PhpseclibTestCase
|
||||
|
||||
$key = 'zzzzzzzzzzzzzz';
|
||||
|
||||
$this->assertFalse($rsa->loadKey($key));
|
||||
$this->assertFalse($rsa->load($key));
|
||||
}
|
||||
|
||||
public function testPKCS1Key()
|
||||
@ -36,7 +39,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
|
||||
-----END RSA PRIVATE KEY-----';
|
||||
|
||||
$this->assertTrue($rsa->loadKey($key));
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
@ -59,7 +62,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
-----END RSA PRIVATE KEY-----';
|
||||
$key = str_replace(array("\r", "\n", "\r\n"), ' ', $key);
|
||||
|
||||
$this->assertTrue($rsa->loadKey($key));
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
@ -79,7 +82,7 @@ X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
|
||||
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
|
||||
|
||||
$this->assertTrue($rsa->loadKey($key));
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
@ -99,7 +102,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
'U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ' .
|
||||
'37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
|
||||
|
||||
$this->assertTrue($rsa->loadKey($key));
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
@ -120,7 +123,7 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
'37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
|
||||
$key = base64_decode($key);
|
||||
|
||||
$this->assertTrue($rsa->loadKey($key));
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
@ -159,7 +162,7 @@ GF/qoZyC1mbqdtyyeWgHtVbJVUORmpbNnXOII9duEqBUNDiO9VSZNn/8h/VsYeAB
|
||||
xryZaRDVmtMuf/OZBQ==
|
||||
-----END ENCRYPTED PRIVATE KEY-----';
|
||||
|
||||
$this->assertTrue($rsa->loadKey($key));
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPrivateKey());
|
||||
}
|
||||
|
||||
@ -182,12 +185,12 @@ U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
-----END RSA PRIVATE KEY-----';
|
||||
$rsa->setPassword('password');
|
||||
|
||||
$this->assertTrue($rsa->loadKey($key));
|
||||
$this->assertTrue($rsa->load($key));
|
||||
|
||||
$key = $rsa->getPrivateKey(RSA::PRIVATE_FORMAT_PKCS8);
|
||||
$key = $rsa->getPrivateKey('PKCS8');
|
||||
$this->assertInternalType('string', $key);
|
||||
|
||||
$this->assertTrue($rsa->loadKey($key));
|
||||
$this->assertTrue($rsa->load($key));
|
||||
}
|
||||
|
||||
public function testPubKey1()
|
||||
@ -203,7 +206,7 @@ gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
|
||||
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
|
||||
-----END RSA PUBLIC KEY-----';
|
||||
|
||||
$this->assertTrue($rsa->loadKey($key));
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPublicKey());
|
||||
$this->assertFalse($rsa->getPrivateKey());
|
||||
}
|
||||
@ -222,7 +225,7 @@ lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26
|
||||
ZQIDAQAB
|
||||
-----END PUBLIC KEY-----';
|
||||
|
||||
$this->assertTrue($rsa->loadKey($key));
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPublicKey());
|
||||
$this->assertFalse($rsa->getPrivateKey());
|
||||
}
|
||||
@ -236,7 +239,7 @@ ZQIDAQAB
|
||||
'GkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZw== ' .
|
||||
'phpseclib-generated-key';
|
||||
|
||||
$this->assertTrue($rsa->loadKey($key));
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertInternalType('string', $rsa->getPublicKey());
|
||||
$this->assertFalse($rsa->getPrivateKey());
|
||||
}
|
||||
@ -252,7 +255,7 @@ ZQIDAQAB
|
||||
'b6wYtY/q/WtUFr3nK+x0lgOtokhnJfRR/6fnmC1CztPnIT4BWK81VGKWONAxuhMyQ5XChyu6S9'.
|
||||
'mWG5tUlUI/5';
|
||||
|
||||
$this->assertTrue($rsa->loadKey($key));
|
||||
$this->assertTrue($rsa->load($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');
|
||||
}
|
||||
@ -270,7 +273,7 @@ gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
|
||||
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
|
||||
-----END RSA PUBLIC KEY-----';
|
||||
|
||||
$this->assertTrue($rsa->loadKey($key));
|
||||
$this->assertTrue($rsa->load($key));
|
||||
$this->assertTrue($rsa->setPrivateKey());
|
||||
$this->assertGreaterThanOrEqual(1, strlen("$rsa"));
|
||||
$this->assertFalse($rsa->getPublicKey());
|
||||
@ -290,11 +293,11 @@ Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
|
||||
<Exponent>AQAB</Exponent>
|
||||
</RSAKeyValue>';
|
||||
|
||||
$rsa->loadKey($key);
|
||||
$rsa->load($key);
|
||||
$rsa->setPublicKey();
|
||||
$newkey = $rsa->getPublicKey(RSA::PUBLIC_FORMAT_XML);
|
||||
$newkey = $rsa->getPublicKey('XML');
|
||||
|
||||
$this->assertSame(preg_replace('#\s#', '', $key), preg_replace('#\s#', '', $newkey));
|
||||
$this->assertSame(strtolower(preg_replace('#\s#', '', $key)), strtolower(preg_replace('#\s#', '', $newkey)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -311,10 +314,224 @@ JWrQdxx/WNN+ABG426rgYYbeGcIlWLZCw6Bx/1HtN5ef6nVEoiGNChYKIRB4QFOi
|
||||
01smFxps1w8ZIQnD6wIDAQAB
|
||||
-----END PUBLIC KEY-----';
|
||||
|
||||
$rsa->loadKey($key);
|
||||
$rsa->load($key);
|
||||
$rsa->setPublicKey();
|
||||
$newkey = $rsa->getPublicKey();
|
||||
|
||||
$this->assertSame(preg_replace('#\s#', '', $key), preg_replace('#\s#', '', $newkey));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github861
|
||||
*/
|
||||
public function testPKCS8Only()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
|
||||
$key = '-----BEGIN PRIVATE KEY-----
|
||||
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKB0yPMAbUHKqJxP
|
||||
5sjG9AOrQSAYNDc34NsnZ1tsi7fZ9lHlBaKZ6gjm2U9q+/qCKv2BuGINxWo2CMJp
|
||||
DHNY0QTt7hThr3B4U62z1CWWGnfLhFtHKH6jNYYOGc4x0jgT88uSrKFvUOLhjkjW
|
||||
bURmJMpN+OjLJuZQZ7uwoqtT3IEDAgMBAAECgYBaElS/fEzYst/Fp2DA8lYGPTs4
|
||||
vf2JxbdWrp7phlxEH3mTbUGljkr/Jj90wnSiojFpz0jm2h4oyh5Oq9OOaJwkCYcu
|
||||
2lcHJvFlhR2XEJpd1bHHcvDwZHdUjSpnO8kvwQtjuTnho2ntRzAA4wIJVSd7Tynj
|
||||
0IFEKmzhSKIvIIeN8QJBANLa10R1vs+YqpLdpAuc6Z9GYhHuh1TysBPw2xNtw3Xf
|
||||
tGPx4/53eQ0RwiHdw9Opgt8CBHErD6KzziflfxUrIXkCQQDCz4t01qYWT43kxS6k
|
||||
TcnZb/obho6akGc8C1hSxFIIGUa9hAhMpY2W6GXeGpv5TZtEJZIJE1VHTLvcLSGm
|
||||
ILNbAkEAgq9mWqULxYket3Yt1ZDEb5Zk9C49rJXaMhHHBoyyZ51mJcfngnE0Erid
|
||||
9PWJCOf4GBYdALMqtrHwpWOlV05rKQJAd6Tz50w1MRqm8MvRe4Ny5qIJH4Kibncl
|
||||
kBD/q8V7BBJSCe7fEgPTU81jUudQx+pL46yXZg+DnoiYD/9/3QHUZQJBAMBiKiZ7
|
||||
qMnD/pkHR/NFcYSYShUJS0cHyryVl7/eCclsQlZTRdnVTtKF9xPGTQC8fK0G7BDN
|
||||
Z2sKniRCcDT1ZP4=
|
||||
-----END PRIVATE KEY-----';
|
||||
|
||||
$result = $rsa->load($key, '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
|
||||
*/
|
||||
public function testSetLoad()
|
||||
{
|
||||
$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';
|
||||
|
||||
$rsa = new RSA();
|
||||
$rsa->setPrivateKey($key);
|
||||
$rsa->load($key);
|
||||
|
||||
$rsa = new RSA();
|
||||
$rsa->load($key);
|
||||
$rsa->setPrivateKey();
|
||||
$rsa->load($rsa);
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
class Unit_Crypt_RSA_ModeTest extends PhpseclibTestCase
|
||||
{
|
||||
@ -28,19 +29,74 @@ X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
|
||||
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
|
||||
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
|
||||
-----END RSA PRIVATE KEY-----';
|
||||
$rsa->loadKey($privatekey);
|
||||
$rsa->loadKey($rsa->getPublicKey());
|
||||
$rsa->load($privatekey);
|
||||
$rsa->load($rsa->getPublicKey());
|
||||
|
||||
$rsa->setEncryptionMode(RSA::ENCRYPTION_NONE);
|
||||
$expected = '105b92f59a87a8ad4da52c128b8c99491790ef5a54770119e0819060032fb9e772ed6772828329567f3d7e9472154c1530f8156ba7fd732f52ca1c06' .
|
||||
'5a3f5ed8a96c442e4662e0464c97f133aed31262170201993085a589565d67cc9e727e0d087e3b225c8965203b271e38a499c92fc0d6502297eca712' .
|
||||
'4d04bd467f6f1e7c';
|
||||
$expected = pack('H*', $expected);
|
||||
$result = $rsa->encrypt($plaintext);
|
||||
$result = $rsa->encrypt($plaintext, RSA::PADDING_NONE);
|
||||
|
||||
$this->assertEquals($result, $expected);
|
||||
|
||||
$rsa->loadKey($privatekey);
|
||||
$this->assertEquals(trim($rsa->decrypt($result), "\0"), $plaintext);
|
||||
$rsa->load($privatekey);
|
||||
$this->assertEquals(trim($rsa->decrypt($result, RSA::PADDING_NONE), "\0"), $plaintext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github768
|
||||
*/
|
||||
public function testPSSSigs()
|
||||
{
|
||||
$rsa = new RSA();
|
||||
$rsa->setHash('sha1');
|
||||
$rsa->setMGFHash('sha1');
|
||||
$rsa->load('-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqGKukO1De7zhZj6+H0qtjTkVx
|
||||
wTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFnc
|
||||
CzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0T
|
||||
p0GbMJDyR4e9T04ZZwIDAQAB
|
||||
-----END PUBLIC KEY-----');
|
||||
|
||||
$sig = pack('H*', '1bd29a1d704a906cd7f726370ce1c63d8fb7b9a620871a05f3141a311c0d6e75fefb5d36dfb50d3ea2d37cd67992471419bfadd35da6e13b494' .
|
||||
'058ddc9b568d4cfea13ddc3c62b86a6256f5f296980d1131d3eaec6089069a3de79983f73eae20198a18721338b4a66e9cfe80e4f8e4fcef7a5bead5cbb' .
|
||||
'b8ac4c76adffbc178c');
|
||||
|
||||
$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));
|
||||
}
|
||||
}
|
||||
|
@ -87,26 +87,30 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase
|
||||
array(str_repeat("\x01", 24), pack('H*', '0000000000000002'), pack('H*', '06E7EA22CE92708F')),
|
||||
array(str_repeat("\x01", 24), pack('H*', '0000000000000001'), pack('H*', '166B40B44ABA4BD6'))
|
||||
);
|
||||
|
||||
$result = array();
|
||||
// @codingStandardsIgnoreStart
|
||||
foreach ($this->engines as $engine => $engineName)
|
||||
foreach ($tests as $test)
|
||||
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2]);
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
||||
foreach ($this->engines as $engine => $engineName) {
|
||||
foreach ($tests as $test) {
|
||||
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2]);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider engineVectors
|
||||
*/
|
||||
* @dataProvider engineVectors
|
||||
*/
|
||||
public function testVectors($engine, $engineName, $key, $plaintext, $expected)
|
||||
{
|
||||
$des = new TripleDES();
|
||||
$des = new TripleDES(TripleDES::MODE_CBC);
|
||||
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);
|
||||
@ -135,21 +139,24 @@ class Unit_Crypt_TripleDESTest extends PhpseclibTestCase
|
||||
pack('H*', '84401f78fe6c10876d8ea23094ea5309'),
|
||||
pack('H*', '7b1f7c7e3b1c948ebd04a75ffba7d2f5'))
|
||||
);
|
||||
|
||||
$result = array();
|
||||
// @codingStandardsIgnoreStart
|
||||
foreach ($engines as $engine => $engineName)
|
||||
foreach ($tests as $test)
|
||||
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2], $test[3]);
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
||||
foreach ($engines as $engine => $engineName) {
|
||||
foreach ($tests as $test) {
|
||||
$result[] = array($engine, $engineName, $test[0], $test[1], $test[2], $test[3]);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider engineIVVectors
|
||||
*/
|
||||
* @dataProvider engineIVVectors
|
||||
*/
|
||||
public function testVectorsWithIV($engine, $engineName, $key, $iv, $plaintext, $expected)
|
||||
{
|
||||
$des = new TripleDES();
|
||||
$des = new TripleDES(TripleDES::MODE_CBC);
|
||||
if (!$des->isValidEngine($engine)) {
|
||||
self::markTestSkipped('Unable to initialize ' . $engineName . ' engine');
|
||||
}
|
||||
@ -170,6 +177,7 @@ 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);
|
||||
|
@ -19,7 +19,8 @@ class Unit_Crypt_TwofishTest extends PhpseclibTestCase
|
||||
);
|
||||
|
||||
foreach ($engines as $engine => $name) {
|
||||
$tf = new Twofish();
|
||||
$tf = new Twofish(Twofish::MODE_CBC);
|
||||
$tf->setIV(str_repeat("\0", $tf->getBlockLength() >> 3));
|
||||
$tf->disablePadding();
|
||||
|
||||
// tests from https://www.schneier.com/code/ecb_ival.txt
|
||||
|
@ -18,7 +18,7 @@ class Unit_File_ASN1Test extends PhpseclibTestCase
|
||||
$KDC_REP = array(
|
||||
'type' => ASN1::TYPE_SEQUENCE,
|
||||
'children' => array(
|
||||
'pvno' => array(
|
||||
'pvno' => array(
|
||||
'constant' => 0,
|
||||
'optional' => true,
|
||||
'explicit' => true,
|
||||
|
@ -68,4 +68,29 @@ draiRBZruwMPwPIP
|
||||
|
||||
$this->assertInternalType('array', $csr);
|
||||
}
|
||||
|
||||
public function testCSRDER()
|
||||
{
|
||||
$csr = 'MIICdzCCAV8CAQEwDDEKMAgGA1UEAwwBeDCCASIwDQYJKoZIhvcNAQEBBQADggEP' .
|
||||
'ADCCAQoCggEBALtcrFDD2AHe3x2bR00wPDsPH6FJLxr5uc1ybb+ldDB5xNVImC8P' .
|
||||
'LU6VXDZ5z68KjSovs1q0OWJWfCjlAuGLzqO35s86LI1CFuTFdkScVHMwh8zUVFoP' .
|
||||
'pG7/9rKaNxCgaHs4evxjxQP2+Ny7tBqPLb/KV0exm6Twocf963jC/Tyn57G5erRf' .
|
||||
'zpFrfK7DozhxY7znumJ4FuSn0TVkD6PPwZFn9VoTjv2ZoJmacGK+0r5yNKG799F5' .
|
||||
'K8EgDrOCfbzCZjX6GJctyn2SNPTeBuXS9piH21FGnJAryv80zG+zUqFdEyoLUGJt' .
|
||||
'4Vy6+tDP9cW68fiwTZS1Oc1VeFdL1G/CrjkCAwEAAaAmMCQGCSqGSIb3DQEJDjEX' .
|
||||
'MBUwEwYKKwYBBAGCqlsBCQQFMAOCAQEwDQYJKoZIhvcNAQELBQADggEBAF4XOd+1' .
|
||||
'jkJOYRInNpHfhzSD/ktDY50gpLPuDvl4f/ZBlKrb1eDYQG5F3bnYzoZWHN4n+6Zs' .
|
||||
'CkljXs5ZPUZ5LuVpASumoG/aHXGz8c8NC3asJ1V73ljEPAfIXwqoIUoaP9jLL+Ee' .
|
||||
'zy/ZCi2NKWVo2D7ocnn79oblAem9ksSeQl4z3Gvhuug6MsMqn96NU/ZY/vjYzAjb' .
|
||||
'MAvJIVRY0rbCxbFa0K+XNJtF7GLyBxyPNFWCvADhvm9C4uPmoypYg7MY6EewJInN' .
|
||||
'xzMH7I4xDLjNu0VBa6lAxTvflp0joQHKlTYX0SDIKPbQivjZMuObPuxDtkVZ0rQl' .
|
||||
'AjmgMowaN5otTXM=';
|
||||
$csr = base64_decode($csr);
|
||||
|
||||
$x509 = new X509();
|
||||
|
||||
$csr = $x509->loadCSR($csr);
|
||||
|
||||
$this->assertInternalType('array', $csr);
|
||||
}
|
||||
}
|
||||
|
@ -48,10 +48,9 @@ class Unit_File_X509_SPKACTest extends PhpseclibTestCase
|
||||
{
|
||||
$privKey = new RSA();
|
||||
extract($privKey->createKey());
|
||||
$privKey->loadKey($privatekey);
|
||||
|
||||
$x509 = new X509();
|
||||
$x509->setPrivateKey($privKey);
|
||||
$x509->setPrivateKey($privatekey);
|
||||
$x509->setChallenge('...');
|
||||
|
||||
$spkac = $x509->signSPKAC();
|
||||
@ -94,6 +93,5 @@ class Unit_File_X509_SPKACTest extends PhpseclibTestCase
|
||||
$x509->validateSignature(),
|
||||
'Failed asserting that the signature is invalid'
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,55 @@ use phpseclib\Crypt\RSA;
|
||||
|
||||
class Unit_File_X509_X509Test extends PhpseclibTestCase
|
||||
{
|
||||
public function testExtensionMapping()
|
||||
{
|
||||
$test = '-----BEGIN CERTIFICATE-----
|
||||
MIIG1jCCBL6gAwIBAgITUAAAAA0qg8bE6DhrLAAAAAAADTANBgkqhkiG9w0BAQsF
|
||||
ADAiMSAwHgYDVQQDExcuU2VjdXJlIEVudGVycHJpc2UgQ0EgMTAeFw0xNTAyMjMx
|
||||
NTE1MDdaFw0xNjAyMjMxNTE1MDdaMD8xFjAUBgoJkiaJk/IsZAEZFgZzZWN1cmUx
|
||||
DjAMBgNVBAMTBVVzZXJzMRUwEwYDVQQDEwxtZXRhY2xhc3NpbmcwggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMdG1CzR/gTalbLN9J+2cvMGeD7wsR7S78
|
||||
HU5hdwE+kECROjRAcjFBOR57ezSDrkmhkTzo28tj0oAHjOh8N9vuXtASfZSCXugx
|
||||
H+ImJ+E7PA4aXBp+0H2hohW9sXNNCFiVNmJLX66O4bxIeKtVRq/+eSNijV4OOEkC
|
||||
zMyTHAUbOFP0t6KoJtM1syNoQ1+fKdfcjz5XtiEzSVcp2zf0MwNFSeZSgGQ0jh8A
|
||||
Kd6YVKA8ZnrqOWZxKETT+bBNTjIT0ggjQfzcE4zW2RzrN7zWabUowoU92+DAp4s3
|
||||
sAEywX9ISSge62DEzTnZZSf9bpoScAfT8raRFA3BkoJ/s4c4CgfPAgMBAAGjggLm
|
||||
MIIC4jAdBgNVHQ4EFgQULlIyJL9+ZwAI/SkVdsJMxFOVp+EwHwYDVR0jBBgwFoAU
|
||||
5nEIMEUT5mMd1WepmviwgK7dIzwwggEKBgNVHR8EggEBMIH+MIH7oIH4oIH1hoG5
|
||||
bGRhcDovLy9DTj0uU2VjdXJlJTIwRW50ZXJwcmlzZSUyMENBJTIwMSxDTj1hdXRo
|
||||
LENOPUNEUCxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxD
|
||||
Tj1Db25maWd1cmF0aW9uLERDPXNlY3VyZT9jZXJ0aWZpY2F0ZVJldm9jYXRpb25M
|
||||
aXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnSGN2h0dHA6
|
||||
Ly9jcmwuc2VjdXJlb2JzY3VyZS5jb20vP2FjdGlvbj1jcmwmY2E9ZW50ZXJwcmlz
|
||||
ZTEwgccGCCsGAQUFBwEBBIG6MIG3MIG0BggrBgEFBQcwAoaBp2xkYXA6Ly8vQ049
|
||||
LlNlY3VyZSUyMEVudGVycHJpc2UlMjBDQSUyMDEsQ049QUlBLENOPVB1YmxpYyUy
|
||||
MEtleSUyMFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9
|
||||
c2VjdXJlP2NBQ2VydGlmaWNhdGU/YmFzZT9vYmplY3RDbGFzcz1jZXJ0aWZpY2F0
|
||||
aW9uQXV0aG9yaXR5MBcGCSsGAQQBgjcUAgQKHggAVQBzAGUAcjAOBgNVHQ8BAf8E
|
||||
BAMCBaAwKQYDVR0lBCIwIAYKKwYBBAGCNwoDBAYIKwYBBQUHAwQGCCsGAQUFBwMC
|
||||
MC4GA1UdEQQnMCWgIwYKKwYBBAGCNxQCA6AVDBNtZXRhY2xhc3NpbmdAc2VjdXJl
|
||||
MEQGCSqGSIb3DQEJDwQ3MDUwDgYIKoZIhvcNAwICAgCAMA4GCCqGSIb3DQMEAgIA
|
||||
gDAHBgUrDgMCBzAKBggqhkiG9w0DBzANBgkqhkiG9w0BAQsFAAOCAgEAKNmjYh+h
|
||||
cObJEM0CWgz50jOYKZ4M5iIxoAWgrYY9Pv+0O9aPjvPLzjd5bY322L8lxh5wy5my
|
||||
DKmip+irzjdVdxzQfoyy+ceODmCbX9L6MfEDn0RBzdwjLe1/eOxE1na0sZztrVCc
|
||||
yt5nI91NNGZJUcVqVQsIA/25FWlkvo/FTfuqTuXdQiEVM5MCKJI915anmTdugy+G
|
||||
0CmBJALIxtyz5P7sZhaHZFNdpKnx82QsauErqjP9H0RXc6VXX5qt+tEDvYfSlFcc
|
||||
0lv3aQnV/eIdfm7APJkQ3lmNWWQwdkVf7adXJ7KAAPHSt1yvSbVxThJR/jmIkyeQ
|
||||
XW/TOP5m7JI/GrmvdlzI1AgwJ+zO8fOmCDuif99pDb1CvkzQ65RZ8p5J1ZV6hzlb
|
||||
VvOhn4LDnT1jnTcEqigmx1gxM/5ifvMorXn/ItMjKPlb72vHpeF7OeKE8GHsvZAm
|
||||
osHcKyJXbTIcXchmpZX1efbmCMJBqHgJ/qBTBMl9BX0+YqbTZyabRJSs9ezbTRn0
|
||||
oRYl21Q8EnvS71CemxEUkSsKJmfJKkQNCsOjc8AbX/V/X9R7LJkH3UEx6K2zQQKK
|
||||
k6m17mi63YW/+iPCGOWZ2qXmY5HPEyyF2L4L4IDryFJ+8xLyw3pH9/yp5aHZDtp6
|
||||
833K6qyjgHJT+fUzSEYpiwF5rSBJIGClOCY=
|
||||
-----END CERTIFICATE-----';
|
||||
|
||||
$x509 = new X509();
|
||||
|
||||
$cert = $x509->loadX509($test);
|
||||
|
||||
$this->assertInternalType('array', $cert['tbsCertificate']['extensions'][3]['extnValue']);
|
||||
}
|
||||
|
||||
public function testLoadUnsupportedExtension()
|
||||
{
|
||||
$test = '-----BEGIN CERTIFICATE-----
|
||||
@ -105,7 +154,7 @@ IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==
|
||||
public function testSaveNullRSAParam()
|
||||
{
|
||||
$privKey = new RSA();
|
||||
$privKey->loadKey('-----BEGIN RSA PRIVATE KEY-----
|
||||
$privKey->load('-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQDMswfEpAgnUDWA74zZw5XcPsWh1ly1Vk99tsqwoFDkLF7jvXy1
|
||||
dDLHYfuquvfxCgcp8k/4fQhx4ubR8bbGgEq9B05YRnViK0R0iBB5Ui4IaxWYYhKE
|
||||
8xqAEH2fL+/7nsqqNFKkEN9KeFwc7WbMY49U2adlMrpBdRjk1DqIEW3QTwIDAQAB
|
||||
@ -122,7 +171,7 @@ aBtsWpliLSex/HHhtRW9AkBGcq67zKmEpJ9kXcYLEjJii3flFS+Ct/rNm+Hhm1l7
|
||||
-----END RSA PRIVATE KEY-----');
|
||||
|
||||
$pubKey = new RSA();
|
||||
$pubKey->loadKey($privKey->getPublicKey());
|
||||
$pubKey->load($privKey->getPublicKey());
|
||||
$pubKey->setPublicKey();
|
||||
|
||||
$subject = new X509();
|
||||
@ -168,4 +217,47 @@ aBtsWpliLSex/HHhtRW9AkBGcq67zKmEpJ9kXcYLEjJii3flFS+Ct/rNm+Hhm1l7
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function testGetOID()
|
||||
{
|
||||
$x509 = new X509();
|
||||
$this->assertEquals($x509->getOID('2.16.840.1.101.3.4.2.1'), '2.16.840.1.101.3.4.2.1');
|
||||
$this->assertEquals($x509->getOID('id-sha256'), '2.16.840.1.101.3.4.2.1');
|
||||
$this->assertEquals($x509->getOID('zzz'), 'zzz');
|
||||
}
|
||||
|
||||
public function testIPAddressSubjectAltNamesDecoding()
|
||||
{
|
||||
$test = '-----BEGIN CERTIFICATE-----
|
||||
MIIEcTCCAlmgAwIBAgIBDjANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBQuU2Vj
|
||||
dXJlIElzc3VpbmcgQ0EgMTAeFw0xNjAxMjUyMzIwMjZaFw0yMTAxMjYyMzIwMjZa
|
||||
MBoxGDAWBgNVBAMMDzIwNC4xNTIuMjAwLjI1MDCCASIwDQYJKoZIhvcNAQEBBQAD
|
||||
ggEPADCCAQoCggEBAM9lMPiYQ26L5qXR1rlUXM0Z3DeRhDsJ/9NadLFJnvxKCV5L
|
||||
M9rlrThpK6V5VbgPgEwKVLXGtJoGSEUkLd4roJ25ZTH08GcYszWyp8nLPQRovYnN
|
||||
+aeE1aefnHcpt524f0Es9NFXh0uwRWV3ZCWSwN+mo9Qo6507KZq+q34if7/q9+De
|
||||
O5RJumVQWc9OCjCt6pQBnBua9oCAca+SIHftOdgWXqVw+Xvl6/dLeF70jJD43P00
|
||||
+bdAnGDgBdgO+p+K+XrOCaCWMcCsRX5xiK4hUG54UM5ayBST+McyfjsKxpO2djPg
|
||||
FlSL0RLg+Nj8WehANUUuaNU874Pp3FV5GTI0ZbUCAwEAAaOBvDCBuTAMBgNVHRMB
|
||||
Af8EAjAAMAsGA1UdDwQEAwIF4DATBgNVHSUEDDAKBggrBgEFBQcDATAhBgNVHREE
|
||||
GjAYhwTMmMj6hxAgAQRw8wkACQAAAAAAAAADMEMGA1UdHwQ8MDowOKA2oDSGMmh0
|
||||
dHA6Ly9jcmwuc2VjdXJlb2JzY3VyZS5jb20vP2FjdGlvbj1jcmwmY2E9aXNzdWUx
|
||||
MB8GA1UdIwQYMBaAFOJWVCX4poZSBzemgihf9dAhFNHJMA0GCSqGSIb3DQEBCwUA
|
||||
A4ICAQAce9whx4InRtzk1to6oeRxTCbeNDjNFuTkotphSws4hDoaz3nyFLSYyMT4
|
||||
aKFnNP9AmMS5nEXphtP4HP9wAluTcAFMuip0rDJjiRA/khIE27KurO6cg1faFWHl
|
||||
6lh6xnEf9UFZZzTLsXt2miBiMb8olgPrBuVFWjPZ/ConesJRZRFqMd5mfntXC+2V
|
||||
zRcXdtwp9h/Am/WuvjsG/gBAPdeRNKffCokIcgfvffd2oklSDD0T9baG2MTgaxnX
|
||||
oG6e5saWjoN8bLWuCJpvjA7aErXQwXUyXx1nrTWQ1TCR2N+M62X7e07jZLKSAECP
|
||||
v6SqZ9/LDmCacVQbfg4wDC/gbpjDSKaD5fkusH6leXleWQ7X8Z03LsKvVq43a71z
|
||||
jO61kkiFAh3CegWsY+TSYjZxDq58xGMiE7y/fK+SHQXDLyY7HU4eky2l3DSy8bXQ
|
||||
p64vTJ/OmAcXVNUASfBCNw0kpxuFjlxers/+6zheowB1RIKo0xvSRC4cEDRl/jFA
|
||||
b7WUT/MIe6B1r0v1gxHnFG2bFI/MhTT9V+tICOLo7+69z4jf/OFkzjYvqq2QWPgc
|
||||
sE3f2TNnmKFRJx67bEMoaaWLIR94Yuq/TWB6dTiWwk9meZkGG3OjQg/YbO6vl/Am
|
||||
NDEuGt30Vl2de7G1glnhaceB6Q9KfH7p2gAwNP9JMTtx3PtEcA==
|
||||
-----END CERTIFICATE-----';
|
||||
|
||||
$x509 = new X509();
|
||||
$cert = $x509->loadX509($test);
|
||||
$this->assertEquals($cert['tbsCertificate']['extensions'][3]['extnValue'][0]['iPAddress'], '204.152.200.250');
|
||||
$this->assertEquals($cert['tbsCertificate']['extensions'][3]['extnValue'][1]['iPAddress'], '2001:470:f309:9::3');
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ class Unit_Math_BigInteger_InternalOpenSSLTest extends Unit_Math_BigInteger_Test
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
if (!function_exists('openssl_public_encrypt')) {
|
||||
if (!extension_loaded('openssl')) {
|
||||
self::markTestSkipped('openssl_public_encrypt() function is not available.');
|
||||
}
|
||||
|
||||
|
@ -9,10 +9,7 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
include_once 'Math/BigInteger.php';
|
||||
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
self::reRequireFile('Math/BigInteger.php');
|
||||
}
|
||||
|
||||
@ -52,7 +49,7 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
|
||||
|
||||
public function testToHex()
|
||||
{
|
||||
$this->assertSame('41', $this->getInstance('65')->toHex());
|
||||
$this->assertSame('41', $this->getInstance('65')->toHex());
|
||||
}
|
||||
|
||||
public function testToBits()
|
||||
@ -220,6 +217,11 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
|
||||
$z = $this->getInstance('11111111111111111111111', 16);
|
||||
|
||||
$this->assertSame($z->toHex(), $x->bitwise_NOT()->toHex());
|
||||
|
||||
$a = $this->getInstance(0);
|
||||
$a->bitwise_not();
|
||||
|
||||
$this->assertSame($a->toString(), '0');
|
||||
}
|
||||
|
||||
public function testBitwiseLeftShift()
|
||||
@ -271,29 +273,13 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
|
||||
$min = $this->getInstance(0);
|
||||
$max = $this->getInstance('18446744073709551616');
|
||||
|
||||
$rand1 = $min->random($min, $max);
|
||||
$rand1 = \phpseclib\Math\BigInteger::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
|
||||
*/
|
||||
@ -329,8 +315,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 = $one->random($one, $max);
|
||||
$bobPrivate = $one->random($one, $max);
|
||||
$alicePrivate = \phpseclib\Math\BigInteger::random($one, $max);
|
||||
$bobPrivate = \phpseclib\Math\BigInteger::random($one, $max);
|
||||
var_dump($alicePrivate->toHex(), $bobPrivate->toHex());
|
||||
*/
|
||||
|
||||
@ -358,4 +344,40 @@ abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
|
||||
'Failed asserting that Alice and Bob share the same BigInteger.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 5.6
|
||||
*/
|
||||
public function testDebugInfo()
|
||||
{
|
||||
$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');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group github954
|
||||
*/
|
||||
public function testSlidingWindow()
|
||||
{
|
||||
$e = $this->getInstance(str_repeat('1', 1794), 2);
|
||||
$x = $this->getInstance(1);
|
||||
$n = $this->getInstance(2);
|
||||
$x->powMod($e, $n);
|
||||
}
|
||||
}
|
||||
|
@ -110,6 +110,18 @@ 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
|
||||
*/
|
||||
|
@ -10,7 +10,7 @@ date_default_timezone_set('UTC');
|
||||
$loader_path = __DIR__ . '/../vendor/autoload.php';
|
||||
if (!file_exists($loader_path)) {
|
||||
echo "Dependencies must be installed using composer:\n\n";
|
||||
echo "php composer.phar install --dev\n\n";
|
||||
echo "php composer.phar install\n\n";
|
||||
echo "See http://getcomposer.org for help with installing composer\n";
|
||||
exit(1);
|
||||
}
|
||||
|
@ -21,10 +21,5 @@ function install_php_extension
|
||||
}
|
||||
|
||||
# runkit
|
||||
if [ "$TRAVIS_PHP_VERSION" == "5.6" ]
|
||||
then
|
||||
git clone https://github.com/adrianguenter/runkit.git
|
||||
else
|
||||
git clone https://github.com/zenovich/runkit.git
|
||||
fi
|
||||
git clone https://github.com/zenovich/runkit.git
|
||||
install_php_extension 'runkit'
|
||||
|
@ -20,7 +20,7 @@ then
|
||||
PHPUNIT_ARGS="$PHPUNIT_ARGS -d zend.enable_gc=0"
|
||||
fi
|
||||
|
||||
if [ "$TRAVIS_PHP_VERSION" = 'hhvm' ]
|
||||
if [ "$TRAVIS_PHP_VERSION" = 'hhvm' -o "$TRAVIS_PHP_VERSION" = '7.0' ]
|
||||
then
|
||||
find tests -type f -name "*Test.php" | \
|
||||
parallel --gnu --keep-order \
|
||||
|
Loading…
Reference in New Issue
Block a user