Update v1.0.6

This commit is contained in:
Bhanu Slathia
2016-02-16 23:24:52 +05:30
parent c710c20b9e
commit b1f62846ab
7662 changed files with 1361647 additions and 0 deletions

View File

@@ -0,0 +1 @@
* text=auto

2
vendor/phpseclib/phpseclib/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/vendor
/composer.phar

View File

@@ -0,0 +1,7 @@
imports:
- php
tools:
external_code_coverage:
runs: 5 # No Code Coverage on PHP 5.2 and HHVM
timeout: 2700 # 45 minutes

35
vendor/phpseclib/phpseclib/.travis.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
language: php
# When adding environments here, the number of runs specified in .scrutinizer.yml
# may have to be adjusted.
php:
- 5.2
- 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
env:
global:
# Defines CODE_COVERAGE_PASSPHRASE which is the passphrase for unlocking
# the travis/code_coverage_id_rsa RSA private key.
- secure: "jtQTZKQBnzUlp/jz7NlM6470ZDnLGVAs53sgvIm4tcYqf9TWSXSXjIYvFsrS\nKPR2eyZaAevYysUkIGRFTUXTlG6tC36YngMp9+6FPxASl8mnGXsTbKcm613B\n59vD3242pgIgqhhmgFQ0c8gbvnE8PuF2aS4/hluP3r+AxhWN56E="
before_install: true
install:
- sudo apt-get install parallel
- 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' != '5.2' ]; then travis/setup-composer.sh; fi"
script:
- sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.5' ]; then vendor/bin/phing -f build/build.xml sniff; fi"
- travis/run-phpunit.sh
after_success:
- sh -c "if $TRAVIS_SECURE_ENV_VARS; then travis/upload-code-coverage-html.sh; fi"
- sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.2' -a '$TRAVIS_PHP_VERSION' != 'hhvm' ]; then travis/upload-code-coverage-scrutinizer.sh; fi"

5
vendor/phpseclib/phpseclib/AUTHORS vendored Normal file
View File

@@ -0,0 +1,5 @@
phpseclib Lead Developer: TerraFrost (Jim Wigginton)
phpseclib Developers: monnerat (Patrick Monnerat)
bantu (Andreas Fischer)
petrich (Hans-Jürgen Petrich)

83
vendor/phpseclib/phpseclib/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,83 @@
# Changelog
## 0.3.9 - 2014-11-09
- PHP 5.6 improvements ([#482](https://github.com/phpseclib/phpseclib/pull/482), [#491](https://github.com/phpseclib/phpseclib/issues/491))
## 0.3.8 - 2014-09-12
- improve support for indef lengths in File_ASN1
- add hmac-sha2-256 support to Net_SSH2
- make it so negotiated algorithms can be seen before Net_SSH2 login
- add sha256-96 and sha512-96 to Crypt_Hash
- window size handling adjustments in Net_SSH2
## 0.3.7 - 2014-07-05
- auto-detect public vs private keys
- add file_exists, is_dir, is_file, readlink and symlink to Net_SFTP
- add support for recursive nlist and rawlist
- make it so nlist and rawlist can return pre-sorted output
- make it so callback functions can make exec() return early
- add signSPKAC and saveSPKAC methods to File_X509
- add support for PKCS8 keys in Crypt_RSA
- add pbkdf1 support to setPassword() in Crypt_Base
- add getWindowColumns, getWindowRows, setWindowColumns, setWindowRows to Net_SSH2
- add support for filenames with spaces in them to Net_SCP
## 0.3.6 - 2014-02-23
- add preliminary support for custom SSH subsystems
- add ssh-agent support
## 0.3.5 - 2013-07-11
- numerous SFTP changes:
- chown
- chgrp
- truncate
- improved file type detection
- put() can write to te middle of a file
- mkdir accepts the same paramters that PHP's mkdir does
- the ability to upload/download 2GB files
- across-the-board speedups for the various encryption algorithms
- multi-factor authentication support for Net_SSH2
- a $callback parameter for Net_SSH2::exec
- new classes:
- Net_SFTP_StreamWrapper
- Net_SCP
- Crypt_Twofish
- Crypt_Blowfish
## 0.3.1 - 2012-11-20
- add Net_SSH2::enableQuietMode() for suppressing stderr
- add Crypt_RSA::__toString() and Crypt_RSA::getSize()
- fix problems with File_X509::validateDate(), File_X509::sign() and Crypt_RSA::verify()
- use OpenSSL to speed up modular exponention in Math_BigInteger
- improved timeout functionality in Net_SSH2
- add support for SFTPv2
- add support for CRLs in File_X509
- SSH-2.0-SSH doesn't implement hmac-*-96 correctly
## 0.3.0 - 2012-07-08
- add support for reuming Net_SFTP::put()
- add support for recursive deletes and recursive chmods to Net_SFTP
- add setTimeout() to Net_SSH2
- add support for PBKDF2 to the various Crypt_* classes via setPassword()
- add File_X509 and File_ASN1
- add the ability to decode various formats in Crypt_RSA
- make Net_SSH2::getServerPublicHostKey() return a printer-friendly version of the public key
## 0.2.2 - 2011-05-09
- CFB and OFB modes were added to all block ciphers
- support for interactive mode was added to Net_SSH2
- Net_SSH2 now has limited keyboard_interactive authentication support
- support was added for PuTTY formatted RSA private keys and XML formatted RSA private keys
- Crypt_RSA::loadKey() will now try all key types automatically
= 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

21
vendor/phpseclib/phpseclib/LICENSE vendored Normal file
View File

@@ -0,0 +1,21 @@
Copyright 2007-2013 TerraFrost and other contributors
http://phpseclib.sourceforge.net/
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

65
vendor/phpseclib/phpseclib/README.md vendored Normal file
View File

@@ -0,0 +1,65 @@
# phpseclib - PHP Secure Communications Library
[![Build Status](https://secure.travis-ci.org/phpseclib/phpseclib.png?branch=master)](http://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.9)](http://sourceforge.net/projects/phpseclib/files/phpseclib0.3.9.zip/download)
* [Browse Git](https://github.com/phpseclib/phpseclib)
* [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)
## Documentation
* [Documentation / Manual](http://phpseclib.sourceforge.net/)
* [API Documentation](http://phpseclib.bantux.org/api/master/) (generated by Sami)
## Support
Need Support?
* [Checkout Questions and Answers on Stack Overflow](http://stackoverflow.com/questions/tagged/phpseclib)
* [Create a Support Ticket on GitHub](https://github.com/phpseclib/phpseclib/issues/new)
* [Browse the Support Forum](http://www.frostjedi.com/phpbb/viewforum.php?f=46) (no longer in use)
## Installing Development Dependencies
Dependencies are managed via Composer.
1. Download the [`composer.phar`](https://getcomposer.org/composer.phar) executable as per the
[Composer Download Instructions](https://getcomposer.org/download/), e.g. by running
``` sh
curl -sS https://getcomposer.org/installer | php
```
2. Install Dependencies
``` sh
php composer.phar install --dev
```
## Contributing
1. Fork the Project
2. Install Development Dependencies
3. Create a Feature Branch
4. (Recommended) Run the Test Suite
``` sh
vendor/bin/phpunit
```
5. (Recommended) Check whether your code conforms to our Coding Standards by running
``` sh
vendor/bin/phing -f build/build.xml sniff
```
6. Send us a Pull Request

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="phpseclib"
description="PHP Secure Communications Library"
default="all"
>
<target name="all" depends="sniff,api" />
<!-- Code Sniffer -->
<target name="sniff" depends="sniff-php-code,sniff-php-tests" />
<target name="sniff-php-code">
<exec command="vendor/bin/phpcs -s
--extensions=php
--standard=build/code-sniffer-ruleset.xml
phpseclib/"
dir=".." checkreturn="true" passthru="true" />
</target>
<target name="sniff-php-tests">
<exec command="vendor/bin/phpcs -s
--extensions=php
--standard=build/code-sniffer-ruleset-tests.xml
tests/"
dir=".." checkreturn="true" passthru="true" />
</target>
<!-- API Generation -->
<target name="api">
<exec command="vendor/bin/sami.php update build/sami.conf.php"
dir=".." passthru="true" />
</target>
</project>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0"?>
<ruleset name="phpseclib Test Standard">
<description>phpseclib coding standard for tests</description>
<!-- In general rules that apply to library code also apply to tests. -->
<rule ref="./code-sniffer-ruleset.xml">
<!-- Exceptions to the library coding standard follow. -->
<!-- We do not care too much about method, class and file documentation,
but having @author, @copyright and @license tags would be nice.
The following configuration does not check for these tags, but
complains if the file doc block is missing completely. -->
<exclude name="PEAR.Commenting.ClassComment" />
<exclude name="PEAR.Commenting.FunctionComment" />
<exclude name="PEAR.Commenting.FileComment.MissingTag" />
<exclude name="PEAR.Commenting.FileComment.MissingVersion" />
<exclude name="PEAR.Commenting.FileComment.SpacingBeforeTags" />
</rule>
</ruleset>

View File

@@ -0,0 +1,75 @@
<?xml version="1.0"?>
<ruleset name="phpseclib Standard">
<description>phpseclib coding standard</description>
<!-- We are using the PEAR standard as a base -->
<rule ref="PEAR">
<!-- Temporary exceptions to the PEAR standard follow -->
<exclude name="Generic.ControlStructures.InlineControlStructure.Discouraged" />
<exclude name="Generic.Files.LineLength.TooLong" />
<exclude name="PEAR.NamingConventions.ValidFunctionName.FunctionNoCapital" />
<exclude name="PEAR.NamingConventions.ValidFunctionName.NotCamelCaps" />
<exclude name="PEAR.Commenting.ClassComment.InvalidVersion" />
<exclude name="PEAR.Commenting.ClassComment.MissingTag" />
<exclude name="PEAR.Commenting.FileComment.EmptyCopyright" />
<exclude name="PEAR.Commenting.FileComment.InvalidVersion" />
<exclude name="PEAR.Commenting.FunctionComment.ExtraParamComment" />
<exclude name="PEAR.Commenting.FunctionComment.MissingReturn" />
<exclude name="PEAR.Commenting.FunctionComment.MissingParamComment" />
<exclude name="PEAR.Commenting.FunctionComment.MissingParamName" />
<exclude name="PEAR.Commenting.FunctionComment.MissingParamTag" />
<exclude name="PEAR.Commenting.FunctionComment.ParameterCommentsNotAligned" />
<exclude name="PEAR.Commenting.FunctionComment.ParameterNamesNotAligned" />
<exclude name="PEAR.Commenting.FunctionComment.ParamNameNoMatch" />
<exclude name="PEAR.Commenting.FunctionComment.SpacingAfterParams" />
<exclude name="PEAR.Commenting.FunctionComment.SpacingBeforeParams" />
<exclude name="PEAR.Commenting.FunctionComment.SpacingBeforeTags" />
<exclude name="PEAR.Functions.FunctionCallSignature.ContentAfterOpenBracket" />
<exclude name="PEAR.Functions.FunctionCallSignature.CloseBracketLine" />
<exclude name="PEAR.Functions.FunctionCallSignature.SpaceAfterOpenBracket" />
<exclude name="PEAR.WhiteSpace.ScopeClosingBrace.BreakIdent" />
<exclude name="PEAR.WhiteSpace.ScopeClosingBrace.Indent" />
<exclude name="PEAR.WhiteSpace.ScopeClosingBrace.Line" />
<exclude name="PEAR.WhiteSpace.ScopeIndent.Incorrect" />
</rule>
<!-- Useful additional rules follow -->
<!-- "for (; bar; )" should be "while (bar)" instead -->
<rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop" />
<!-- A method MUST not only call its parent -->
<rule ref="Generic.CodeAnalysis.UselessOverridingMethod" />
<!-- All code files MUST use only UTF-8 without BOM. -->
<rule ref="Generic.Files.ByteOrderMark" />
<!-- Each file MUST end with exactly one newline character -->
<rule ref="PSR2.Files.EndFileNewline" />
<!-- In the argument list, there MUST NOT be a space before each comma,
and there MUST be one space after each comma. -->
<rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing">
<properties>
<property name="equalsSpacing" value="1"/>
</properties>
</rule>
<rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingAfterHint" />
<!-- There MUST NOT be trailing whitespace at the end of lines. -->
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace" />
<!-- There MUST NOT be whitespace before the first content of a file -->
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.StartFile" />
<!-- There MUST NOT be whitespace after the last content of a file -->
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EndFile" />
<!-- Functions MUST NOT contain multiple empty lines in a row -->
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EmptyLines" />
<!-- The ?> closing tag MUST be omitted from files containing only PHP. -->
<rule ref="Zend.Files.ClosingTag" />
</ruleset>

View File

@@ -0,0 +1,31 @@
<?php
// Prevent e.g. 'Notice: Constant MATH_BIGINTEGER_MONTGOMERY already defined'.
class MyArrayStore extends Sami\Store\ArrayStore
{
public function removeClass(Sami\Project $project, $name)
{
unset($this->classes[$name]);
}
}
$iterator = Symfony\Component\Finder\Finder::create()
->files()
->name('*.php')
->in(__DIR__ . '/../phpseclib/')
;
$versions = Sami\Version\GitVersionCollection::create(__DIR__ . '/../')
->add('master')
->add('php5')
;
return new Sami\Sami($iterator, array(
'theme' => 'enhanced',
'versions' => $versions,
'title' => 'phpseclib API Documentation',
'build_dir' => __DIR__.'/api/output/%version%',
'cache_dir' => __DIR__.'/api/cache/%version%',
'default_opened_level' => 2,
'store' => new MyArrayStore,
));

View File

@@ -0,0 +1,80 @@
{
"name": "phpseclib/phpseclib",
"type": "library",
"description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
"keywords": [
"security",
"crypto",
"cryptography",
"encryption",
"signature",
"signing",
"rsa",
"aes",
"blowfish",
"twofish",
"ssh",
"sftp",
"x509",
"x.509",
"asn1",
"asn.1",
"BigInteger"
],
"homepage": "http://phpseclib.sourceforge.net",
"license": "MIT",
"authors": [
{
"name": "Jim Wigginton",
"email": "terrafrost@php.net",
"role": "Lead Developer"
},
{
"name": "Patrick Monnerat",
"email": "pm@datasphere.ch",
"role": "Developer"
},
{
"name": "Andreas Fischer",
"email": "bantu@phpbb.com",
"role": "Developer"
},
{
"name": "Hans-Jürgen Petrich",
"email": "petrich@tronic-media.com",
"role": "Developer"
}
],
"require": {
"php": ">=5.0.0"
},
"require-dev": {
"phing/phing": "~2.7",
"phpunit/phpunit": "~4.0",
"sami/sami": "~2.0",
"squizlabs/php_codesniffer": "~1.5"
},
"suggest": {
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a wide variety of cryptographic operations.",
"ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
"pear-pear/PHP_Compat": "Install PHP_Compat to get phpseclib working on PHP < 4.3.3."
},
"include-path": ["phpseclib/"],
"autoload": {
"psr-0": {
"Crypt": "phpseclib/",
"File": "phpseclib/",
"Math": "phpseclib/",
"Net": "phpseclib/",
"System": "phpseclib/"
},
"files": [
"phpseclib/Crypt/Random.php"
]
},
"extra": {
"branch-alias": {
"dev-master": "0.3-dev"
}
}
}

1380
vendor/phpseclib/phpseclib/composer.lock generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,207 @@
<?php
/**
* Pure-PHP implementation of AES.
*
* Uses mcrypt, if available/possible, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
*
* If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
* {@link 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 Crypt_AES::setKey() setKey()}
* is called, again, at which point, it'll be recalculated.
*
* Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
* make a whole lot of sense. {@link Crypt_AES::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:
* <code>
* <?php
* include 'Crypt/AES.php';
*
* $aes = new Crypt_AES();
*
* $aes->setKey('abcdefghijklmnop');
*
* $size = 10 * 1024;
* $plaintext = '';
* for ($i = 0; $i < $size; $i++) {
* $plaintext.= 'a';
* }
*
* echo $aes->decrypt($aes->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_AES
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2008 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_Rijndael
*/
if (!class_exists('Crypt_Rijndael')) {
include_once 'Rijndael.php';
}
/**#@+
* @access public
* @see Crypt_AES::encrypt()
* @see Crypt_AES::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_AES_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_AES_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_AES_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_AES_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_AES_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/**#@+
* @access private
* @see Crypt_Base::Crypt_Base()
*/
/**
* Toggles the internal implementation
*/
define('CRYPT_AES_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
/**
* Toggles the mcrypt implementation
*/
define('CRYPT_AES_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
/**#@-*/
/**
* Pure-PHP implementation of AES.
*
* @package Crypt_AES
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Crypt_AES extends Crypt_Rijndael
{
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'AES';
/**
* Dummy function
*
* Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.
*
* @see Crypt_Rijndael::setBlockLength()
* @access public
* @param Integer $length
*/
function setBlockLength($length)
{
return;
}
/**
* 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.
*
* @see Crypt_Rijndael:setKeyLength()
* @access public
* @param Integer $length
*/
function setKeyLength($length)
{
switch ($length) {
case 160:
$length = 192;
break;
case 224:
$length = 256;
}
parent::setKeyLength($length);
}
/**
* Sets the key.
*
* Rijndael supports five different key lengths, AES only supports three.
*
* @see Crypt_Rijndael:setKey()
* @see setKeyLength()
* @access public
* @param String $key
*/
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->_setupEngine();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,644 @@
<?php
/**
* Pure-PHP implementation of Blowfish.
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
*
* Useful resources are as follows:
*
* - {@link http://en.wikipedia.org/wiki/Blowfish_(cipher) Wikipedia description of Blowfish}
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/Blowfish.php';
*
* $blowfish = new Crypt_Blowfish();
*
* $blowfish->setKey('12345678901234567890123456789012');
*
* $plaintext = str_repeat('a', 1024);
*
* echo $blowfish->decrypt($blowfish->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_Blowfish
* @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
include_once 'Base.php';
}
/**#@+
* @access public
* @see Crypt_Blowfish::encrypt()
* @see Crypt_Blowfish::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_BLOWFISH_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_BLOWFISH_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_BLOWFISH_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_BLOWFISH_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_BLOWFISH_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/**#@+
* @access private
* @see Crypt_Base::Crypt_Base()
*/
/**
* Toggles the internal implementation
*/
define('CRYPT_BLOWFISH_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
/**
* Toggles the mcrypt implementation
*/
define('CRYPT_BLOWFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
/**#@-*/
/**
* Pure-PHP implementation of Blowfish.
*
* @package Crypt_Blowfish
* @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @access public
*/
class Crypt_Blowfish extends Crypt_Base
{
/**
* Block Length of the cipher
*
* @see Crypt_Base::block_size
* @var Integer
* @access private
*/
var $block_size = 8;
/**
* The default password key_size used by setPassword()
*
* @see Crypt_Base::password_key_size
* @see Crypt_Base::setPassword()
* @var Integer
* @access private
*/
var $password_key_size = 56;
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'BLOWFISH';
/**
* The mcrypt specific name of the cipher
*
* @see Crypt_Base::cipher_name_mcrypt
* @var String
* @access private
*/
var $cipher_name_mcrypt = 'blowfish';
/**
* Optimizing value while CFB-encrypting
*
* @see Crypt_Base::cfb_init_len
* @var Integer
* @access private
*/
var $cfb_init_len = 500;
/**
* The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
*
* S-Box 1
*
* @access private
* @var 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,
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
);
/**
* S-Box 1
*
* @access private
* @var array
*/
var $sbox1 = array(
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
);
/**
* S-Box 2
*
* @access private
* @var array
*/
var $sbox2 = array(
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
);
/**
* S-Box 3
*
* @access private
* @var array
*/
var $sbox3 = array(
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
);
/**
* P-Array consists of 18 32-bit subkeys
*
* @var array $parray
* @access private
*/
var $parray = array(
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
);
/**
* The BCTX-working Array
*
* Holds the expanded key [p] and the key-depended s-boxes [sb]
*
* @var array $bctx
* @access private
*/
var $bctx;
/**
* Holds the last used key
*
* @var Array
* @access private
*/
var $kl;
/**
* Sets the key.
*
* 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 Crypt_Base::setKey()
* @param String $key
*/
function setKey($key)
{
$keylength = strlen($key);
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);
}
parent::setKey($key);
}
/**
* Setup the key (expansion)
*
* @see Crypt_Base::_setupKey()
* @access private
*/
function _setupKey()
{
if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
// already expanded
return;
}
$this->kl = array('key' => $this->key);
/* key-expanding p[] and S-Box building sb[] */
$this->bctx = array(
'p' => array(),
'sb' => array(
$this->sbox0,
$this->sbox1,
$this->sbox2,
$this->sbox3
)
);
// unpack binary string in unsigned chars
$key = array_values(unpack('C*', $this->key));
$keyl = count($key);
for ($j = 0, $i = 0; $i < 18; ++$i) {
// xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ...
for ($data = 0, $k = 0; $k < 4; ++$k) {
$data = ($data << 8) | $key[$j];
if (++$j >= $keyl) {
$j = 0;
}
}
$this->bctx['p'][] = $this->parray[$i] ^ $data;
}
// encrypt the zero-string, replace P1 and P2 with the encrypted data,
// encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys
$data = "\0\0\0\0\0\0\0\0";
for ($i = 0; $i < 18; $i += 2) {
list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
$this->bctx['p'][$i ] = $l;
$this->bctx['p'][$i + 1] = $r;
}
for ($i = 0; $i < 4; ++$i) {
for ($j = 0; $j < 256; $j += 2) {
list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
$this->bctx['sb'][$i][$j ] = $l;
$this->bctx['sb'][$i][$j + 1] = $r;
}
}
}
/**
* Encrypts a block
*
* @access private
* @param String $in
* @return String
*/
function _encryptBlock($in)
{
$p = $this->bctx["p"];
// extract($this->bctx["sb"], EXTR_PREFIX_ALL, "sb"); // slower
$sb_0 = $this->bctx["sb"][0];
$sb_1 = $this->bctx["sb"][1];
$sb_2 = $this->bctx["sb"][2];
$sb_3 = $this->bctx["sb"][3];
$in = unpack("N*", $in);
$l = $in[1];
$r = $in[2];
for ($i = 0; $i < 16; $i+= 2) {
$l^= $p[$i];
$r^= ($sb_0[$l >> 24 & 0xff] +
$sb_1[$l >> 16 & 0xff] ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff];
$r^= $p[$i + 1];
$l^= ($sb_0[$r >> 24 & 0xff] +
$sb_1[$r >> 16 & 0xff] ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff];
}
return pack("N*", $r ^ $p[17], $l ^ $p[16]);
}
/**
* Decrypts a block
*
* @access private
* @param String $in
* @return String
*/
function _decryptBlock($in)
{
$p = $this->bctx["p"];
$sb_0 = $this->bctx["sb"][0];
$sb_1 = $this->bctx["sb"][1];
$sb_2 = $this->bctx["sb"][2];
$sb_3 = $this->bctx["sb"][3];
$in = unpack("N*", $in);
$l = $in[1];
$r = $in[2];
for ($i = 17; $i > 2; $i-= 2) {
$l^= $p[$i];
$r^= ($sb_0[$l >> 24 & 0xff] +
$sb_1[$l >> 16 & 0xff] ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff];
$r^= $p[$i - 1];
$l^= ($sb_0[$r >> 24 & 0xff] +
$sb_1[$r >> 16 & 0xff] ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff];
}
return pack("N*", $r ^ $p[0], $l ^ $p[1]);
}
/**
* Setup the performance-optimized function for de/encrypt()
*
* @see Crypt_Base::_setupInlineCrypt()
* @access private
*/
function _setupInlineCrypt()
{
$lambda_functions =& Crypt_Blowfish::_getLambdaFunctions();
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
// 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);
switch (true) {
case $gen_hi_opt_code:
$code_hash = md5(str_pad("Crypt_Blowfish, {$this->mode}, ", 32, "\0") . $this->key);
break;
default:
$code_hash = "Crypt_Blowfish, {$this->mode}";
}
if (!isset($lambda_functions[$code_hash])) {
switch (true) {
case $gen_hi_opt_code:
$p = $this->bctx['p'];
$init_crypt = '
static $sb_0, $sb_1, $sb_2, $sb_3;
if (!$sb_0) {
$sb_0 = $self->bctx["sb"][0];
$sb_1 = $self->bctx["sb"][1];
$sb_2 = $self->bctx["sb"][2];
$sb_3 = $self->bctx["sb"][3];
}
';
break;
default:
$p = array();
for ($i = 0; $i < 18; ++$i) {
$p[] = '$p_' . $i;
}
$init_crypt = '
list($sb_0, $sb_1, $sb_2, $sb_3) = $self->bctx["sb"];
list(' . implode(',', $p) . ') = $self->bctx["p"];
';
}
// Generating encrypt code:
$encrypt_block = '
$in = unpack("N*", $in);
$l = $in[1];
$r = $in[2];
';
for ($i = 0; $i < 16; $i+= 2) {
$encrypt_block.= '
$l^= ' . $p[$i] . ';
$r^= ($sb_0[$l >> 24 & 0xff] +
$sb_1[$l >> 16 & 0xff] ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff];
$r^= ' . $p[$i + 1] . ';
$l^= ($sb_0[$r >> 24 & 0xff] +
$sb_1[$r >> 16 & 0xff] ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff];
';
}
$encrypt_block.= '
$in = pack("N*",
$r ^ ' . $p[17] . ',
$l ^ ' . $p[16] . '
);
';
// Generating decrypt code:
$decrypt_block = '
$in = unpack("N*", $in);
$l = $in[1];
$r = $in[2];
';
for ($i = 17; $i > 2; $i-= 2) {
$decrypt_block.= '
$l^= ' . $p[$i] . ';
$r^= ($sb_0[$l >> 24 & 0xff] +
$sb_1[$l >> 16 & 0xff] ^
$sb_2[$l >> 8 & 0xff]) +
$sb_3[$l & 0xff];
$r^= ' . $p[$i - 1] . ';
$l^= ($sb_0[$r >> 24 & 0xff] +
$sb_1[$r >> 16 & 0xff] ^
$sb_2[$r >> 8 & 0xff]) +
$sb_3[$r & 0xff];
';
}
$decrypt_block.= '
$in = pack("N*",
$r ^ ' . $p[0] . ',
$l ^ ' . $p[1] . '
);
';
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
array(
'init_crypt' => $init_crypt,
'init_encrypt' => '',
'init_decrypt' => '',
'encrypt_block' => $encrypt_block,
'decrypt_block' => $decrypt_block
)
);
}
$this->inline_crypt = $lambda_functions[$code_hash];
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,841 @@
<?php
/**
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
*
* 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 Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
* the hash. If no valid algorithm is provided, sha1 will be used.
*
* PHP versions 4 and 5
*
* {@internal The variable names are the same as those in
* {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/Hash.php';
*
* $hash = new Crypt_Hash('sha1');
*
* $hash->setKey('abcdefg');
*
* echo base64_encode($hash->hash('abcdefg'));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_Hash
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**#@+
* @access private
* @see Crypt_Hash::Crypt_Hash()
*/
/**
* Toggles the internal implementation
*/
define('CRYPT_HASH_MODE_INTERNAL', 1);
/**
* Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
*/
define('CRYPT_HASH_MODE_MHASH', 2);
/**
* Toggles the hash() implementation, which works on PHP 5.1.2+.
*/
define('CRYPT_HASH_MODE_HASH', 3);
/**#@-*/
/**
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
*
* @package Crypt_Hash
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Crypt_Hash
{
/**
* Hash Parameter
*
* @see Crypt_Hash::setHash()
* @var Integer
* @access private
*/
var $hashParam;
/**
* Byte-length of compression blocks / key (Internal HMAC)
*
* @see Crypt_Hash::setAlgorithm()
* @var Integer
* @access private
*/
var $b;
/**
* Byte-length of hash output (Internal HMAC)
*
* @see Crypt_Hash::setHash()
* @var Integer
* @access private
*/
var $l = false;
/**
* Hash Algorithm
*
* @see Crypt_Hash::setHash()
* @var String
* @access private
*/
var $hash;
/**
* Key
*
* @see Crypt_Hash::setKey()
* @var String
* @access private
*/
var $key = false;
/**
* Outer XOR (Internal HMAC)
*
* @see Crypt_Hash::setKey()
* @var String
* @access private
*/
var $opad;
/**
* Inner XOR (Internal HMAC)
*
* @see Crypt_Hash::setKey()
* @var String
* @access private
*/
var $ipad;
/**
* Default Constructor.
*
* @param optional String $hash
* @return Crypt_Hash
* @access public
*/
function Crypt_Hash($hash = 'sha1')
{
if ( !defined('CRYPT_HASH_MODE') ) {
switch (true) {
case extension_loaded('hash'):
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
break;
case extension_loaded('mhash'):
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH);
break;
default:
define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL);
}
}
$this->setHash($hash);
}
/**
* Sets the key for HMACs
*
* Keys can be of any length.
*
* @access public
* @param optional String $key
*/
function setKey($key = false)
{
$this->key = $key;
}
/**
* Gets the hash function.
*
* As set by the constructor or by the setHash() method.
*
* @access public
* @return String
*/
function getHash()
{
return $this->hashParam;
}
/**
* Sets the hash function.
*
* @access public
* @param String $hash
*/
function setHash($hash)
{
$this->hashParam = $hash = strtolower($hash);
switch ($hash) {
case 'md5-96':
case 'sha1-96':
case 'sha256-96':
case 'sha512-96':
$hash = substr($hash, 0, -3);
$this->l = 12; // 96 / 8 = 12
break;
case 'md2':
case 'md5':
$this->l = 16;
break;
case 'sha1':
$this->l = 20;
break;
case 'sha256':
$this->l = 32;
break;
case 'sha384':
$this->l = 48;
break;
case 'sha512':
$this->l = 64;
}
switch ($hash) {
case 'md2':
$mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
break;
case 'sha384':
case 'sha512':
$mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
break;
default:
$mode = CRYPT_HASH_MODE;
}
switch ( $mode ) {
case CRYPT_HASH_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;
}
return;
case CRYPT_HASH_MODE_HASH:
switch ($hash) {
case 'md5':
$this->hash = 'md5';
return;
case 'md2':
case 'sha256':
case 'sha384':
case 'sha512':
$this->hash = $hash;
return;
case 'sha1':
default:
$this->hash = 'sha1';
}
return;
}
switch ($hash) {
case 'md2':
$this->b = 16;
$this->hash = array($this, '_md2');
break;
case 'md5':
$this->b = 64;
$this->hash = array($this, '_md5');
break;
case 'sha256':
$this->b = 64;
$this->hash = array($this, '_sha256');
break;
case 'sha384':
case 'sha512':
$this->b = 128;
$this->hash = array($this, '_sha512');
break;
case 'sha1':
default:
$this->b = 64;
$this->hash = array($this, '_sha1');
}
$this->ipad = str_repeat(chr(0x36), $this->b);
$this->opad = str_repeat(chr(0x5C), $this->b);
}
/**
* Compute the HMAC.
*
* @access public
* @param String $text
* @return String
*/
function hash($text)
{
$mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
if (!empty($this->key) || is_string($this->key)) {
switch ( $mode ) {
case CRYPT_HASH_MODE_MHASH:
$output = mhash($this->hash, $text, $this->key);
break;
case CRYPT_HASH_MODE_HASH:
$output = hash_hmac($this->hash, $text, $this->key, true);
break;
case CRYPT_HASH_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 ? call_user_func($this->hash, $this->key) : $this->key;
$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 CRYPT_HASH_MODE_MHASH:
$output = mhash($this->hash, $text);
break;
case CRYPT_HASH_MODE_HASH:
$output = hash($this->hash, $text, true);
break;
case CRYPT_HASH_MODE_INTERNAL:
$output = call_user_func($this->hash, $text);
}
}
return substr($output, 0, $this->l);
}
/**
* Returns the hash length (in bytes)
*
* @access public
* @return Integer
*/
function getLength()
{
return $this->l;
}
/**
* Wrapper for MD5
*
* @access private
* @param String $m
*/
function _md5($m)
{
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++) {
$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);
$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)
{
if (!class_exists('Math_BigInteger')) {
include_once 'Math/BigInteger.php';
}
static $init384, $init512, $k;
if (!isset($k)) {
// Initialize variables
$init384 = array( // initial values for SHA384
'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
'67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
);
$init512 = array( // initial values for SHA512
'6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
'510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
);
for ($i = 0; $i < 8; $i++) {
$init384[$i] = new Math_BigInteger($init384[$i], 16);
$init384[$i]->setPrecision(64);
$init512[$i] = new Math_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(
'428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
'3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
'72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
'2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
'983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
'27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
'650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
'19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
'391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
'748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
'90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
'06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
'28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
'4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
);
for ($i = 0; $i < 80; $i++) {
$k[$i] = new Math_BigInteger($k[$i], 16);
}
}
$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
$m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
$m[$length] = chr(0x80);
// we don't support hashing strings 512MB long
$m.= pack('N4', 0, 0, 0, $length << 3);
// Process the message in successive 1024-bit chunks
$chunks = str_split($m, 128);
foreach ($chunks as $chunk) {
$w = array();
for ($i = 0; $i < 16; $i++) {
$temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256);
$temp->setPrecision(64);
$w[] = $temp;
}
// Extend the sixteen 32-bit words into eighty 32-bit words
for ($i = 16; $i < 80; $i++) {
$temp = array(
$w[$i - 15]->bitwise_rightRotate(1),
$w[$i - 15]->bitwise_rightRotate(8),
$w[$i - 15]->bitwise_rightShift(7)
);
$s0 = $temp[0]->bitwise_xor($temp[1]);
$s0 = $s0->bitwise_xor($temp[2]);
$temp = array(
$w[$i - 2]->bitwise_rightRotate(19),
$w[$i - 2]->bitwise_rightRotate(61),
$w[$i - 2]->bitwise_rightShift(6)
);
$s1 = $temp[0]->bitwise_xor($temp[1]);
$s1 = $s1->bitwise_xor($temp[2]);
$w[$i] = $w[$i - 16]->copy();
$w[$i] = $w[$i]->add($s0);
$w[$i] = $w[$i]->add($w[$i - 7]);
$w[$i] = $w[$i]->add($s1);
}
// Initialize hash value for this chunk
$a = $hash[0]->copy();
$b = $hash[1]->copy();
$c = $hash[2]->copy();
$d = $hash[3]->copy();
$e = $hash[4]->copy();
$f = $hash[5]->copy();
$g = $hash[6]->copy();
$h = $hash[7]->copy();
// Main loop
for ($i = 0; $i < 80; $i++) {
$temp = array(
$a->bitwise_rightRotate(28),
$a->bitwise_rightRotate(34),
$a->bitwise_rightRotate(39)
);
$s0 = $temp[0]->bitwise_xor($temp[1]);
$s0 = $s0->bitwise_xor($temp[2]);
$temp = array(
$a->bitwise_and($b),
$a->bitwise_and($c),
$b->bitwise_and($c)
);
$maj = $temp[0]->bitwise_xor($temp[1]);
$maj = $maj->bitwise_xor($temp[2]);
$t2 = $s0->add($maj);
$temp = array(
$e->bitwise_rightRotate(14),
$e->bitwise_rightRotate(18),
$e->bitwise_rightRotate(41)
);
$s1 = $temp[0]->bitwise_xor($temp[1]);
$s1 = $s1->bitwise_xor($temp[2]);
$temp = array(
$e->bitwise_and($f),
$g->bitwise_and($e->bitwise_not())
);
$ch = $temp[0]->bitwise_xor($temp[1]);
$t1 = $h->add($s1);
$t1 = $t1->add($ch);
$t1 = $t1->add($k[$i]);
$t1 = $t1->add($w[$i]);
$h = $g->copy();
$g = $f->copy();
$f = $e->copy();
$e = $d->add($t1);
$d = $c->copy();
$c = $b->copy();
$b = $a->copy();
$a = $t1->add($t2);
}
// Add this chunk's hash to result so far
$hash = array(
$hash[0]->add($a),
$hash[1]->add($b),
$hash[2]->add($c),
$hash[3]->add($d),
$hash[4]->add($e),
$hash[5]->add($f),
$hash[6]->add($g),
$hash[7]->add($h)
);
}
// Produce the final hash value (big-endian)
// (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();
}
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. Math_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
* @access private
*/
function _string_shift(&$string, $index = 1)
{
$substr = substr($string, 0, $index);
$string = substr($string, $index);
return $substr;
}
}

View File

@@ -0,0 +1,652 @@
<?php
/**
* Pure-PHP implementation of RC2.
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
*
* Useful resources are as follows:
*
* - {@link http://tools.ietf.org/html/rfc2268}
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/RC2.php';
*
* $rc2 = new Crypt_RC2();
*
* $rc2->setKey('abcdefgh');
*
* $plaintext = str_repeat('a', 1024);
*
* echo $rc2->decrypt($rc2->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_RC2
* @author Patrick Monnerat <pm@datasphere.ch>
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
include_once 'Base.php';
}
/**#@+
* @access public
* @see Crypt_RC2::encrypt()
* @see Crypt_RC2::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_RC2_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_RC2_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_RC2_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_RC2_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_RC2_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/**#@+
* @access private
* @see Crypt_RC2::Crypt_RC2()
*/
/**
* Toggles the internal implementation
*/
define('CRYPT_RC2_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
/**
* Toggles the mcrypt implementation
*/
define('CRYPT_RC2_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
/**#@-*/
/**
* Pure-PHP implementation of RC2.
*
* @package Crypt_RC2
* @access public
*/
class Crypt_RC2 extends Crypt_Base
{
/**
* Block Length of the cipher
*
* @see Crypt_Base::block_size
* @var Integer
* @access private
*/
var $block_size = 8;
/**
* The Key
*
* @see Crypt_Base::key
* @see setKey()
* @var String
* @access private
*/
var $key = "\0";
/**
* The default password key_size used by setPassword()
*
* @see Crypt_Base::password_key_size
* @see Crypt_Base::setPassword()
* @var Integer
* @access private
*/
var $password_key_size = 16; // = 128 bits
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'RC2';
/**
* The mcrypt specific name of the cipher
*
* @see Crypt_Base::cipher_name_mcrypt
* @var String
* @access private
*/
var $cipher_name_mcrypt = 'rc2';
/**
* Optimizing value while CFB-encrypting
*
* @see Crypt_Base::cfb_init_len
* @var Integer
* @access private
*/
var $cfb_init_len = 500;
/**
* The key length in bits.
*
* @see Crypt_RC2::setKeyLength()
* @see Crypt_RC2::setKey()
* @var Integer
* @access private
* @internal Should be in range [1..1024].
* @internal Changing this value after setting the key has no effect.
*/
var $default_key_length = 1024;
/**
* The Key Schedule
*
* @see Crypt_RC2::_setupKey()
* @var Array
* @access private
*/
var $keys;
/**
* Key expansion randomization table.
* Twice the same 256-value sequence to save a modulus in key expansion.
*
* @see Crypt_RC2::setKey()
* @var Array
* @access private
*/
var $pitable = array(
0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD,
0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD
);
/**
* Inverse key expansion randomization table.
*
* @see Crypt_RC2::setKey()
* @var Array
* @access private
*/
var $invpitable = array(
0xD1, 0xDA, 0xB9, 0x6F, 0x9C, 0xC8, 0x78, 0x66,
0x80, 0x2C, 0xF8, 0x37, 0xEA, 0xE0, 0x62, 0xA4,
0xCB, 0x71, 0x50, 0x27, 0x4B, 0x95, 0xD9, 0x20,
0x9D, 0x04, 0x91, 0xE3, 0x47, 0x6A, 0x7E, 0x53,
0xFA, 0x3A, 0x3B, 0xB4, 0xA8, 0xBC, 0x5F, 0x68,
0x08, 0xCA, 0x8F, 0x14, 0xD7, 0xC0, 0xEF, 0x7B,
0x5B, 0xBF, 0x2F, 0xE5, 0xE2, 0x8C, 0xBA, 0x12,
0xE1, 0xAF, 0xB2, 0x54, 0x5D, 0x59, 0x76, 0xDB,
0x32, 0xA2, 0x58, 0x6E, 0x1C, 0x29, 0x64, 0xF3,
0xE9, 0x96, 0x0C, 0x98, 0x19, 0x8D, 0x3E, 0x26,
0xAB, 0xA5, 0x85, 0x16, 0x40, 0xBD, 0x49, 0x67,
0xDC, 0x22, 0x94, 0xBB, 0x3C, 0xC1, 0x9B, 0xEB,
0x45, 0x28, 0x18, 0xD8, 0x1A, 0x42, 0x7D, 0xCC,
0xFB, 0x65, 0x8E, 0x3D, 0xCD, 0x2A, 0xA3, 0x60,
0xAE, 0x93, 0x8A, 0x48, 0x97, 0x51, 0x15, 0xF7,
0x01, 0x0B, 0xB7, 0x36, 0xB1, 0x2E, 0x11, 0xFD,
0x84, 0x2D, 0x3F, 0x13, 0x88, 0xB3, 0x34, 0x24,
0x1B, 0xDE, 0xC5, 0x1D, 0x4D, 0x2B, 0x17, 0x31,
0x74, 0xA9, 0xC6, 0x43, 0x6D, 0x39, 0x90, 0xBE,
0xC3, 0xB0, 0x21, 0x6B, 0xF6, 0x0F, 0xD5, 0x99,
0x0D, 0xAC, 0x1F, 0x5C, 0x9E, 0xF5, 0xF9, 0x4C,
0xD6, 0xDF, 0x89, 0xE4, 0x8B, 0xFF, 0xC7, 0xAA,
0xE7, 0xED, 0x46, 0x25, 0xB6, 0x06, 0x5E, 0x35,
0xB5, 0xEC, 0xCE, 0xE8, 0x6C, 0x30, 0x55, 0x61,
0x4A, 0xFE, 0xA0, 0x79, 0x03, 0xF0, 0x10, 0x72,
0x7C, 0xCF, 0x52, 0xA6, 0xA7, 0xEE, 0x44, 0xD3,
0x9A, 0x57, 0x92, 0xD0, 0x5A, 0x7A, 0x41, 0x7F,
0x0E, 0x00, 0x63, 0xF2, 0x4F, 0x05, 0x83, 0xC9,
0xA1, 0xD4, 0xDD, 0xC4, 0x56, 0xF4, 0xD2, 0x77,
0x81, 0x09, 0x82, 0x33, 0x9F, 0x07, 0x86, 0x75,
0x38, 0x4E, 0x69, 0xF1, 0xAD, 0x23, 0x73, 0x87,
0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6
);
/**
* Default Constructor.
*
* Determines whether or not the mcrypt extension should be used.
*
* $mode could be:
*
* - CRYPT_RC2_MODE_ECB
*
* - CRYPT_RC2_MODE_CBC
*
* - CRYPT_RC2_MODE_CTR
*
* - CRYPT_RC2_MODE_CFB
*
* - CRYPT_RC2_MODE_OFB
*
* If not explicitly set, CRYPT_RC2_MODE_CBC will be used.
*
* @see Crypt_Base::Crypt_Base()
* @param optional Integer $mode
* @access public
*/
function Crypt_RC2($mode = CRYPT_RC2_MODE_CBC)
{
parent::Crypt_Base($mode);
$this->setKey('');
}
/**
* Sets the key length
*
* Valid key lengths are 1 to 1024.
* Calling this function after setting the key has no effect until the next
* Crypt_RC2::setKey() call.
*
* @access public
* @param Integer $length in bits
*/
function setKeyLength($length)
{
if ($length >= 1 && $length <= 1024) {
$this->default_key_length = $length;
}
}
/**
* Sets the key.
*
* Keys can be of any length. RC2, itself, uses 1 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.
*
* If the key is not explicitly set, it'll be assumed to be a single
* null byte.
*
* @see Crypt_Base::setKey()
* @access public
* @param String $key
* @param Integer $t1 optional Effective key length in bits.
*/
function setKey($key, $t1 = 0)
{
if ($t1 <= 0) {
$t1 = $this->default_key_length;
} else if ($t1 > 1024) {
$t1 = 1024;
}
// Key byte count should be 1..128.
$key = strlen($key) ? substr($key, 0, 128) : "\x00";
$t = strlen($key);
// The mcrypt RC2 implementation only supports effective key length
// of 1024 bits. It is however possible to handle effective key
// lengths in range 1..1024 by expanding the key and applying
// inverse pitable mapping to the first byte before submitting it
// to mcrypt.
// Key expansion.
$l = array_values(unpack('C*', $key));
$t8 = ($t1 + 7) >> 3;
$tm = 0xFF >> (8 * $t8 - $t1);
// Expand key.
$pitable = $this->pitable;
for ($i = $t; $i < 128; $i++) {
$l[$i] = $pitable[$l[$i - 1] + $l[$i - $t]];
}
$i = 128 - $t8;
$l[$i] = $pitable[$l[$i] & $tm];
while ($i--) {
$l[$i] = $pitable[$l[$i + 1] ^ $l[$i + $t8]];
}
// 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 block
*
* @see Crypt_Base::_encryptBlock()
* @see Crypt_Base::encrypt()
* @access private
* @param String $in
* @return String
*/
function _encryptBlock($in)
{
list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
$keys = $this->keys;
$limit = 20;
$actions = array($limit => 44, 44 => 64);
$j = 0;
for (;;) {
// Mixing round.
$r0 = (($r0 + $keys[$j++] + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
$r0 |= $r0 >> 16;
$r1 = (($r1 + $keys[$j++] + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
$r1 |= $r1 >> 16;
$r2 = (($r2 + $keys[$j++] + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
$r2 |= $r2 >> 16;
$r3 = (($r3 + $keys[$j++] + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
$r3 |= $r3 >> 16;
if ($j === $limit) {
if ($limit === 64) {
break;
}
// Mashing round.
$r0 += $keys[$r3 & 0x3F];
$r1 += $keys[$r0 & 0x3F];
$r2 += $keys[$r1 & 0x3F];
$r3 += $keys[$r2 & 0x3F];
$limit = $actions[$limit];
}
}
return pack('vvvv', $r0, $r1, $r2, $r3);
}
/**
* Decrypts a block
*
* @see Crypt_Base::_decryptBlock()
* @see Crypt_Base::decrypt()
* @access private
* @param String $in
* @return String
*/
function _decryptBlock($in)
{
list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
$keys = $this->keys;
$limit = 44;
$actions = array($limit => 20, 20 => 0);
$j = 64;
for (;;) {
// R-mixing round.
$r3 = ($r3 | ($r3 << 16)) >> 5;
$r3 = ($r3 - $keys[--$j] - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
$r2 = ($r2 | ($r2 << 16)) >> 3;
$r2 = ($r2 - $keys[--$j] - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
$r1 = ($r1 | ($r1 << 16)) >> 2;
$r1 = ($r1 - $keys[--$j] - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
$r0 = ($r0 | ($r0 << 16)) >> 1;
$r0 = ($r0 - $keys[--$j] - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;
if ($j === $limit) {
if ($limit === 0) {
break;
}
// R-mashing round.
$r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
$r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
$r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
$r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;
$limit = $actions[$limit];
}
}
return pack('vvvv', $r0, $r1, $r2, $r3);
}
/**
* Creates the key schedule
*
* @see Crypt_Base::_setupKey()
* @access private
*/
function _setupKey()
{
// Key has already been expanded in Crypt_RC2::setKey():
// Only the first value must be altered.
$l = unpack('Ca/Cb/v*', $this->key);
array_unshift($l, $this->pitable[$l['a']] | ($l['b'] << 8));
unset($l['a']);
unset($l['b']);
$this->keys = $l;
}
/**
* Setup the performance-optimized function for de/encrypt()
*
* @see Crypt_Base::_setupInlineCrypt()
* @access private
*/
function _setupInlineCrypt()
{
$lambda_functions = &Crypt_RC2::_getLambdaFunctions();
// The first 10 generated $lambda_functions will use the $keys hardcoded as integers
// 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.
$keys = $this->keys;
if (count($lambda_functions) >= 10) {
foreach ($this->keys as $k => $v) {
$keys[$k] = '$keys[' . $k . ']';
}
}
$code_hash = md5(str_pad("Crypt_RC2, {$this->mode}, ", 32, "\0") . implode(',', $keys));
// Is there a re-usable $lambda_functions in there?
// If not, we have to create it.
if (!isset($lambda_functions[$code_hash])) {
// Init code for both, encrypt and decrypt.
$init_crypt = '$keys = $self->keys;';
// $in is the current 8 bytes block which has to be en/decrypt
$encrypt_block = $decrypt_block = '
$in = unpack("v4", $in);
$r0 = $in[1];
$r1 = $in[2];
$r2 = $in[3];
$r3 = $in[4];
';
// Create code for encryption.
$limit = 20;
$actions = array($limit => 44, 44 => 64);
$j = 0;
for (;;) {
// Mixing round.
$encrypt_block .= '
$r0 = (($r0 + ' . $keys[$j++] . ' +
((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
$r0 |= $r0 >> 16;
$r1 = (($r1 + ' . $keys[$j++] . ' +
((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
$r1 |= $r1 >> 16;
$r2 = (($r2 + ' . $keys[$j++] . ' +
((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
$r2 |= $r2 >> 16;
$r3 = (($r3 + ' . $keys[$j++] . ' +
((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
$r3 |= $r3 >> 16;';
if ($j === $limit) {
if ($limit === 64) {
break;
}
// Mashing round.
$encrypt_block .= '
$r0 += $keys[$r3 & 0x3F];
$r1 += $keys[$r0 & 0x3F];
$r2 += $keys[$r1 & 0x3F];
$r3 += $keys[$r2 & 0x3F];';
$limit = $actions[$limit];
}
}
$encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
// Create code for decryption.
$limit = 44;
$actions = array($limit => 20, 20 => 0);
$j = 64;
for (;;) {
// R-mixing round.
$decrypt_block .= '
$r3 = ($r3 | ($r3 << 16)) >> 5;
$r3 = ($r3 - ' . $keys[--$j] . ' -
((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
$r2 = ($r2 | ($r2 << 16)) >> 3;
$r2 = ($r2 - ' . $keys[--$j] . ' -
((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
$r1 = ($r1 | ($r1 << 16)) >> 2;
$r1 = ($r1 - ' . $keys[--$j] . ' -
((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
$r0 = ($r0 | ($r0 << 16)) >> 1;
$r0 = ($r0 - ' . $keys[--$j] . ' -
((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;';
if ($j === $limit) {
if ($limit === 0) {
break;
}
// R-mashing round.
$decrypt_block .= '
$r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
$r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
$r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
$r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;';
$limit = $actions[$limit];
}
}
$decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
// Creates the inline-crypt function
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
array(
'init_crypt' => $init_crypt,
'encrypt_block' => $encrypt_block,
'decrypt_block' => $decrypt_block
)
);
}
// Set the inline-crypt function as callback in: $this->inline_crypt
$this->inline_crypt = $lambda_functions[$code_hash];
}
}

View File

@@ -0,0 +1,329 @@
<?php
/**
* Pure-PHP implementation of RC4.
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
*
* Useful resources are as follows:
*
* - {@link http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}
* - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
*
* RC4 is also known as ARCFOUR or ARC4. The reason is elaborated upon at Wikipedia. This class is named RC4 and not
* ARCFOUR or ARC4 because RC4 is how it is referred to in the SSH1 specification.
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/RC4.php';
*
* $rc4 = new Crypt_RC4();
*
* $rc4->setKey('abcdefgh');
*
* $size = 10 * 1024;
* $plaintext = '';
* for ($i = 0; $i < $size; $i++) {
* $plaintext.= 'a';
* }
*
* echo $rc4->decrypt($rc4->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_RC4
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
include_once 'Base.php';
}
/**#@+
* @access private
* @see Crypt_RC4::Crypt_RC4()
*/
/**
* Toggles the internal implementation
*/
define('CRYPT_RC4_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
/**
* Toggles the mcrypt implementation
*/
define('CRYPT_RC4_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
/**#@-*/
/**#@+
* @access private
* @see Crypt_RC4::_crypt()
*/
define('CRYPT_RC4_ENCRYPT', 0);
define('CRYPT_RC4_DECRYPT', 1);
/**#@-*/
/**
* Pure-PHP implementation of RC4.
*
* @package Crypt_RC4
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Crypt_RC4 extends Crypt_Base
{
/**
* Block Length of the cipher
*
* RC4 is a stream cipher
* so we the block_size to 0
*
* @see Crypt_Base::block_size
* @var Integer
* @access private
*/
var $block_size = 0;
/**
* The default password key_size used by setPassword()
*
* @see Crypt_Base::password_key_size
* @see Crypt_Base::setPassword()
* @var Integer
* @access private
*/
var $password_key_size = 128; // = 1024 bits
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'RC4';
/**
* The mcrypt specific name of the cipher
*
* @see Crypt_Base::cipher_name_mcrypt
* @var String
* @access private
*/
var $cipher_name_mcrypt = 'arcfour';
/**
* Holds whether performance-optimized $inline_crypt() can/should be used.
*
* @see Crypt_Base::inline_crypt
* @var mixed
* @access private
*/
var $use_inline_crypt = false; // currently not available
/**
* The Key
*
* @see Crypt_RC4::setKey()
* @var String
* @access private
*/
var $key = "\0";
/**
* The Key Stream for decryption and encryption
*
* @see Crypt_RC4::setKey()
* @var Array
* @access private
*/
var $stream;
/**
* Default Constructor.
*
* Determines whether or not the mcrypt extension should be used.
*
* @see Crypt_Base::Crypt_Base()
* @return Crypt_RC4
* @access public
*/
function Crypt_RC4()
{
parent::Crypt_Base(CRYPT_MODE_STREAM);
}
/**
* Dummy function.
*
* Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].
* If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before
* calling setKey().
*
* [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol,
* the IV's are relatively easy to predict, an attack described by
* {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}
* can be used to quickly guess at the rest of the key. The following links elaborate:
*
* {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009}
* {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack}
*
* @param String $iv
* @see Crypt_RC4::setKey()
* @access public
*/
function setIV($iv)
{
}
/**
* Sets the key.
*
* 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.
*
* @access public
* @see Crypt_Base::setKey()
* @param String $key
*/
function setKey($key)
{
parent::setKey(substr($key, 0, 256));
}
/**
* Encrypts a message.
*
* @see Crypt_Base::decrypt()
* @see Crypt_RC4::_crypt()
* @access public
* @param String $plaintext
* @return String $ciphertext
*/
function encrypt($plaintext)
{
if ($this->engine == CRYPT_MODE_MCRYPT) {
return parent::encrypt($plaintext);
}
return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT);
}
/**
* Decrypts a message.
*
* $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
* At least if the continuous buffer is disabled.
*
* @see Crypt_Base::encrypt()
* @see Crypt_RC4::_crypt()
* @access public
* @param String $ciphertext
* @return String $plaintext
*/
function decrypt($ciphertext)
{
if ($this->engine == CRYPT_MODE_MCRYPT) {
return parent::decrypt($ciphertext);
}
return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT);
}
/**
* Setup the key (expansion)
*
* @see Crypt_Base::_setupKey()
* @access private
*/
function _setupKey()
{
$key = $this->key;
$keyLength = strlen($key);
$keyStream = range(0, 255);
$j = 0;
for ($i = 0; $i < 256; $i++) {
$j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
$temp = $keyStream[$i];
$keyStream[$i] = $keyStream[$j];
$keyStream[$j] = $temp;
}
$this->stream = array();
$this->stream[CRYPT_RC4_DECRYPT] = $this->stream[CRYPT_RC4_ENCRYPT] = array(
0, // index $i
0, // index $j
$keyStream
);
}
/**
* Encrypts or decrypts a message.
*
* @see Crypt_RC4::encrypt()
* @see Crypt_RC4::decrypt()
* @access private
* @param String $text
* @param Integer $mode
* @return String $text
*/
function _crypt($text, $mode)
{
if ($this->changed) {
$this->_setup();
$this->changed = false;
}
$stream = &$this->stream[$mode];
if ($this->continuousBuffer) {
$i = &$stream[0];
$j = &$stream[1];
$keyStream = &$stream[2];
} else {
$i = $stream[0];
$j = $stream[1];
$keyStream = $stream[2];
}
$len = strlen($text);
for ($k = 0; $k < $len; ++$k) {
$i = ($i + 1) & 255;
$ksi = $keyStream[$i];
$j = ($j + $ksi) & 255;
$ksj = $keyStream[$j];
$keyStream[$i] = $ksj;
$keyStream[$j] = $ksi;
$text[$k] = $text[$k] ^ chr($keyStream[($ksj + $ksi) & 255]);
}
return $text;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,300 @@
<?php
/**
* Random Number Generator
*
* The idea behind this function is that it can be easily replaced with your own crypt_random_string()
* function. eg. maybe you have a better source of entropy for creating the initial states or whatever.
*
* PHP versions 4 and 5
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/Random.php';
*
* echo bin2hex(crypt_random_string(8));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_Random
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
// laravel is a PHP framework that utilizes phpseclib. laravel workbenches may, independently,
// have phpseclib as a requirement as well. if you're developing such a program you may encounter
// a "Cannot redeclare crypt_random_string()" error.
if (!function_exists('crypt_random_string')) {
/**
* "Is Windows" test
*
* @access private
*/
define('CRYPT_RANDOM_IS_WINDOWS', strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
/**
* Generate a random string.
*
* Although microoptimizations are generally discouraged as they impair readability this function is ripe with
* 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
* @access public
*/
function crypt_random_string($length)
{
if (CRYPT_RANDOM_IS_WINDOWS) {
// 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);
}
}
// at this point we have no choice but to use a pure-PHP CSPRNG
// cascade entropy across multiple PHP instances by fixing the session and collecting all
// environmental variables, including the previous session data and the current session
// data.
//
// mt_rand seeds itself by looking at the PID and the time, both of which are (relatively)
// easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but
// PHP isn't low level to be able to use those as sources and on a web server there's not likely
// going to be a ton of keyboard or mouse action. web servers do have one thing that we can use
// however, a ton of people visiting the website. obviously you don't want to base your seeding
// soley on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled
// by the user and (2) this isn't just looking at the data sent by the current user - it's based
// on the data sent by all users. one user requests the page and a hash of their info is saved.
// another user visits the page and the serialization of their data is utilized along with the
// server envirnment stuff and a hash of the previous http request data (which itself utilizes
// a hash of the session data before that). certainly an attacker should be assumed to have
// full control over his own http requests. he, however, is not going to have control over
// everyone's http requests.
static $crypto = false, $v;
if ($crypto === false) {
// save old session data
$old_session_id = session_id();
$old_use_cookies = ini_get('session.use_cookies');
$old_session_cache_limiter = session_cache_limiter();
$_OLD_SESSION = isset($_SESSION) ? $_SESSION : false;
if ($old_session_id != '') {
session_write_close();
}
session_id(1);
ini_set('session.use_cookies', 0);
session_cache_limiter('');
session_start();
$v = $seed = $_SESSION['seed'] = pack('H*', sha1(
serialize($_SERVER) .
serialize($_POST) .
serialize($_GET) .
serialize($_COOKIE) .
serialize($GLOBALS) .
serialize($_SESSION) .
serialize($_OLD_SESSION)
));
if (!isset($_SESSION['count'])) {
$_SESSION['count'] = 0;
}
$_SESSION['count']++;
session_write_close();
// restore old session data
if ($old_session_id != '') {
session_id($old_session_id);
session_start();
ini_set('session.use_cookies', $old_use_cookies);
session_cache_limiter($old_session_cache_limiter);
} else {
if ($_OLD_SESSION !== false) {
$_SESSION = $_OLD_SESSION;
unset($_OLD_SESSION);
} else {
unset($_SESSION);
}
}
// in SSH2 a shared secret and an exchange hash are generated through the key exchange process.
// the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C.
// if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the
// original hash and the current hash. we'll be emulating that. for more info see the following URL:
//
// http://tools.ietf.org/html/rfc4253#section-7.2
//
// see the is_string($crypto) part for an example of how to expand the keys
$key = pack('H*', sha1($seed . 'A'));
$iv = pack('H*', sha1($seed . 'C'));
// ciphers are used as per the nist.gov link below. also, see this link:
//
// http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives
switch (true) {
case phpseclib_resolve_include_path('Crypt/AES.php'):
if (!class_exists('Crypt_AES')) {
include_once 'AES.php';
}
$crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/Twofish.php'):
if (!class_exists('Crypt_Twofish')) {
include_once 'Twofish.php';
}
$crypto = new Crypt_Twofish(CRYPT_TWOFISH_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/Blowfish.php'):
if (!class_exists('Crypt_Blowfish')) {
include_once 'Blowfish.php';
}
$crypto = new Crypt_Blowfish(CRYPT_BLOWFISH_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/TripleDES.php'):
if (!class_exists('Crypt_TripleDES')) {
include_once 'TripleDES.php';
}
$crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/DES.php'):
if (!class_exists('Crypt_DES')) {
include_once 'DES.php';
}
$crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);
break;
case phpseclib_resolve_include_path('Crypt/RC4.php'):
if (!class_exists('Crypt_RC4')) {
include_once 'RC4.php';
}
$crypto = new Crypt_RC4();
break;
default:
user_error('crypt_random_string requires at least one symmetric cipher be loaded');
return false;
}
$crypto->setKey($key);
$crypto->setIV($iv);
$crypto->enableContinuousBuffer();
}
//return $crypto->encrypt(str_repeat("\0", $length));
// the following is based off of ANSI X9.31:
//
// http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
//
// OpenSSL uses that same standard for it's random numbers:
//
// http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c
// (do a search for "ANS X9.31 A.2.4")
$result = '';
while (strlen($result) < $length) {
$i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21
$r = $crypto->encrypt($i ^ $v); // strlen($v) == 20
$v = $crypto->encrypt($r ^ $i); // strlen($r) == 20
$result.= $r;
}
return substr($result, 0, $length);
}
}
if (!function_exists('phpseclib_resolve_include_path')) {
/**
* Resolve filename against the include path.
*
* Wrapper around stream_resolve_include_path() (which was introduced in
* PHP 5.3.2) with fallback implementation for earlier PHP versions.
*
* @param string $filename
* @return mixed Filename (string) on success, false otherwise.
* @access public
*/
function phpseclib_resolve_include_path($filename)
{
if (function_exists('stream_resolve_include_path')) {
return stream_resolve_include_path($filename);
}
// handle non-relative paths
if (file_exists($filename)) {
return realpath($filename);
}
$paths = PATH_SEPARATOR == ':' ?
preg_split('#(?<!phar):#', get_include_path()) :
explode(PATH_SEPARATOR, get_include_path());
foreach ($paths as $prefix) {
// path's specified in include_path don't always end in /
$ds = substr($prefix, -1) == DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR;
$file = $prefix . $ds . $filename;
if (file_exists($file)) {
return realpath($file);
}
}
return false;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,428 @@
<?php
/**
* Pure-PHP implementation of Triple DES.
*
* Uses mcrypt, if available, and an internal implementation, otherwise. Operates in the EDE3 mode (encrypt-decrypt-encrypt).
*
* PHP versions 4 and 5
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/TripleDES.php';
*
* $des = new Crypt_TripleDES();
*
* $des->setKey('abcdefghijklmnopqrstuvwx');
*
* $size = 10 * 1024;
* $plaintext = '';
* for ($i = 0; $i < $size; $i++) {
* $plaintext.= 'a';
* }
*
* echo $des->decrypt($des->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_TripleDES
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_DES
*/
if (!class_exists('Crypt_DES')) {
include_once 'DES.php';
}
/**
* Encrypt / decrypt using inner chaining
*
* Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (CRYPT_DES_MODE_CBC3).
*/
define('CRYPT_DES_MODE_3CBC', -2);
/**
* Encrypt / decrypt using outer chaining
*
* Outer chaining is used by SSH-2 and when the mode is set to CRYPT_DES_MODE_CBC.
*/
define('CRYPT_DES_MODE_CBC3', CRYPT_DES_MODE_CBC);
/**
* Pure-PHP implementation of Triple DES.
*
* @package Crypt_TripleDES
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Crypt_TripleDES extends Crypt_DES
{
/**
* The default password key_size used by setPassword()
*
* @see Crypt_DES::password_key_size
* @see Crypt_Base::password_key_size
* @see Crypt_Base::setPassword()
* @var Integer
* @access private
*/
var $password_key_size = 24;
/**
* The default salt used by setPassword()
*
* @see Crypt_Base::password_default_salt
* @see Crypt_Base::setPassword()
* @var String
* @access private
*/
var $password_default_salt = 'phpseclib';
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_DES::const_namespace
* @see Crypt_Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'DES';
/**
* The mcrypt specific name of the cipher
*
* @see Crypt_DES::cipher_name_mcrypt
* @see Crypt_Base::cipher_name_mcrypt
* @var String
* @access private
*/
var $cipher_name_mcrypt = 'tripledes';
/**
* Optimizing value while CFB-encrypting
*
* @see Crypt_Base::cfb_init_len
* @var Integer
* @access private
*/
var $cfb_init_len = 750;
/**
* max possible size of $key
*
* @see Crypt_TripleDES::setKey()
* @see Crypt_DES::setKey()
* @var String
* @access private
*/
var $key_size_max = 24;
/**
* Internal flag whether using CRYPT_DES_MODE_3CBC or not
*
* @var Boolean
* @access private
*/
var $mode_3cbc;
/**
* The Crypt_DES objects
*
* Used only if $mode_3cbc === true
*
* @var Array
* @access private
*/
var $des;
/**
* Default Constructor.
*
* Determines whether or not the mcrypt extension should be used.
*
* $mode could be:
*
* - CRYPT_DES_MODE_ECB
*
* - CRYPT_DES_MODE_CBC
*
* - CRYPT_DES_MODE_CTR
*
* - CRYPT_DES_MODE_CFB
*
* - CRYPT_DES_MODE_OFB
*
* - CRYPT_DES_MODE_3CBC
*
* If not explicitly set, CRYPT_DES_MODE_CBC will be used.
*
* @see Crypt_DES::Crypt_DES()
* @see Crypt_Base::Crypt_Base()
* @param optional Integer $mode
* @access public
*/
function Crypt_TripleDES($mode = CRYPT_DES_MODE_CBC)
{
switch ($mode) {
// In case of CRYPT_DES_MODE_3CBC, we init as CRYPT_DES_MODE_CBC
// and additional flag us internally as 3CBC
case CRYPT_DES_MODE_3CBC:
parent::Crypt_Base(CRYPT_DES_MODE_CBC);
$this->mode_3cbc = true;
// This three $des'es will do the 3CBC work (if $key > 64bits)
$this->des = array(
new Crypt_DES(CRYPT_DES_MODE_CBC),
new Crypt_DES(CRYPT_DES_MODE_CBC),
new Crypt_DES(CRYPT_DES_MODE_CBC),
);
// we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects
$this->des[0]->disablePadding();
$this->des[1]->disablePadding();
$this->des[2]->disablePadding();
break;
// If not 3CBC, we init as usual
default:
parent::Crypt_Base($mode);
}
}
/**
* Sets the initialization vector. (optional)
*
* SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explicitly set, it'll be assumed
* to be all zero's.
*
* @see Crypt_Base::setIV()
* @access public
* @param String $iv
*/
function setIV($iv)
{
parent::setIV($iv);
if ($this->mode_3cbc) {
$this->des[0]->setIV($iv);
$this->des[1]->setIV($iv);
$this->des[2]->setIV($iv);
}
}
/**
* 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.
*
* 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 Crypt_DES::setKey()
* @see Crypt_Base::setKey()
* @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));
}
parent::setKey($key);
// And in case of CRYPT_DES_MODE_3CBC:
// if key <= 64bits we not need the 3 $des to work,
// because we will then act as regular DES-CBC with just a <= 64bit key.
// So only if the key > 64bits (> 8 bytes) we will call setKey() for the 3 $des.
if ($this->mode_3cbc && $length > 8) {
$this->des[0]->setKey(substr($key, 0, 8));
$this->des[1]->setKey(substr($key, 8, 8));
$this->des[2]->setKey(substr($key, 16, 8));
}
}
/**
* Encrypts a message.
*
* @see Crypt_Base::encrypt()
* @access public
* @param String $plaintext
* @return String $cipertext
*/
function encrypt($plaintext)
{
// parent::en/decrypt() is able to do all the work for all modes and keylengths,
// except for: CRYPT_DES_MODE_3CBC (inner chaining CBC) with a key > 64bits
// if the key is smaller then 8, do what we'd normally do
if ($this->mode_3cbc && strlen($this->key) > 8) {
return $this->des[2]->encrypt(
$this->des[1]->decrypt(
$this->des[0]->encrypt(
$this->_pad($plaintext)
)
)
);
}
return parent::encrypt($plaintext);
}
/**
* Decrypts a message.
*
* @see Crypt_Base::decrypt()
* @access public
* @param String $ciphertext
* @return String $plaintext
*/
function decrypt($ciphertext)
{
if ($this->mode_3cbc && strlen($this->key) > 8) {
return $this->_unpad(
$this->des[0]->decrypt(
$this->des[1]->encrypt(
$this->des[2]->decrypt(
str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, "\0")
)
)
)
);
}
return parent::decrypt($ciphertext);
}
/**
* Treat consecutive "packets" as if they are a continuous buffer.
*
* Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
* will yield different outputs:
*
* <code>
* echo $des->encrypt(substr($plaintext, 0, 8));
* echo $des->encrypt(substr($plaintext, 8, 8));
* </code>
* <code>
* echo $des->encrypt($plaintext);
* </code>
*
* The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
* another, as demonstrated with the following:
*
* <code>
* $des->encrypt(substr($plaintext, 0, 8));
* echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
* </code>
* <code>
* echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
* </code>
*
* With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
* outputs. The reason is due to the fact that the initialization vector's change after every encryption /
* decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
*
* Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
* encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
* continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
* however, they are also less intuitive and more likely to cause you problems.
*
* @see Crypt_Base::enableContinuousBuffer()
* @see Crypt_TripleDES::disableContinuousBuffer()
* @access public
*/
function enableContinuousBuffer()
{
parent::enableContinuousBuffer();
if ($this->mode_3cbc) {
$this->des[0]->enableContinuousBuffer();
$this->des[1]->enableContinuousBuffer();
$this->des[2]->enableContinuousBuffer();
}
}
/**
* Treat consecutive packets as if they are a discontinuous buffer.
*
* The default behavior.
*
* @see Crypt_Base::disableContinuousBuffer()
* @see Crypt_TripleDES::enableContinuousBuffer()
* @access public
*/
function disableContinuousBuffer()
{
parent::disableContinuousBuffer();
if ($this->mode_3cbc) {
$this->des[0]->disableContinuousBuffer();
$this->des[1]->disableContinuousBuffer();
$this->des[2]->disableContinuousBuffer();
}
}
/**
* Creates the key schedule
*
* @see Crypt_DES::_setupKey()
* @see Crypt_Base::_setupKey()
* @access private
*/
function _setupKey()
{
switch (true) {
// if $key <= 64bits we configure our internal pure-php cipher engine
// to act as regular [1]DES, not as 3DES. mcrypt.so::tripledes does the same.
case strlen($this->key) <= 8:
$this->des_rounds = 1;
break;
// otherwise, if $key > 64bits, we configure our engine to work as 3DES.
default:
$this->des_rounds = 3;
// (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately.
if ($this->mode_3cbc) {
$this->des[0]->_setupKey();
$this->des[1]->_setupKey();
$this->des[2]->_setupKey();
// because $des[0-2] will, now, do all the work we can return here
// not need unnecessary stress parent::_setupKey() with our, now unused, $key.
return;
}
}
// setup our key
parent::_setupKey();
}
}

View File

@@ -0,0 +1,895 @@
<?php
/**
* Pure-PHP implementation of Twofish.
*
* Uses mcrypt, if available, and an internal implementation, otherwise.
*
* PHP versions 4 and 5
*
* Useful resources are as follows:
*
* - {@link http://en.wikipedia.org/wiki/Twofish Wikipedia description of Twofish}
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Crypt/Twofish.php';
*
* $twofish = new Crypt_Twofish();
*
* $twofish->setKey('12345678901234567890123456789012');
*
* $plaintext = str_repeat('a', 1024);
*
* echo $twofish->decrypt($twofish->encrypt($plaintext));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Crypt
* @package Crypt_Twofish
* @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @copyright 2007 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Include Crypt_Base
*
* Base cipher class
*/
if (!class_exists('Crypt_Base')) {
include_once 'Base.php';
}
/**#@+
* @access public
* @see Crypt_Twofish::encrypt()
* @see Crypt_Twofish::decrypt()
*/
/**
* Encrypt / decrypt using the Counter mode.
*
* Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
*/
define('CRYPT_TWOFISH_MODE_CTR', CRYPT_MODE_CTR);
/**
* Encrypt / decrypt using the Electronic Code Book mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
*/
define('CRYPT_TWOFISH_MODE_ECB', CRYPT_MODE_ECB);
/**
* Encrypt / decrypt using the Code Book Chaining mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
*/
define('CRYPT_TWOFISH_MODE_CBC', CRYPT_MODE_CBC);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
*/
define('CRYPT_TWOFISH_MODE_CFB', CRYPT_MODE_CFB);
/**
* Encrypt / decrypt using the Cipher Feedback mode.
*
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
*/
define('CRYPT_TWOFISH_MODE_OFB', CRYPT_MODE_OFB);
/**#@-*/
/**#@+
* @access private
* @see Crypt_Base::Crypt_Base()
*/
/**
* Toggles the internal implementation
*/
define('CRYPT_TWOFISH_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
/**
* Toggles the mcrypt implementation
*/
define('CRYPT_TWOFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
/**#@-*/
/**
* Pure-PHP implementation of Twofish.
*
* @package Crypt_Twofish
* @author Jim Wigginton <terrafrost@php.net>
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
* @access public
*/
class Crypt_Twofish extends Crypt_Base
{
/**
* The namespace used by the cipher for its constants.
*
* @see Crypt_Base::const_namespace
* @var String
* @access private
*/
var $const_namespace = 'TWOFISH';
/**
* The mcrypt specific name of the cipher
*
* @see Crypt_Base::cipher_name_mcrypt
* @var String
* @access private
*/
var $cipher_name_mcrypt = 'twofish';
/**
* Optimizing value while CFB-encrypting
*
* @see Crypt_Base::cfb_init_len
* @var Integer
* @access private
*/
var $cfb_init_len = 800;
/**
* Q-Table
*
* @var Array
* @access private
*/
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,
0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48,
0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23,
0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C,
0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61,
0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1,
0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66,
0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA,
0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71,
0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7,
0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2,
0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB,
0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF,
0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64,
0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A,
0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02,
0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D,
0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8,
0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00,
0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0
);
/**
* Q-Table
*
* @var Array
* @access private
*/
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,
0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F,
0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D,
0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3,
0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51,
0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C,
0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70,
0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC,
0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2,
0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17,
0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3,
0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49,
0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9,
0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48,
0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19,
0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5,
0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69,
0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC,
0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB,
0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2,
0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91
);
/**
* M-Table
*
* @var Array
* @access private
*/
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,
0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, 0xB0B0B306, 0x7575DE3F,
0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D,
0xAEAE2C6D, 0x7F7FABC1, 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, 0x3131272C, 0x808065A3,
0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51,
0x2A2A3638, 0xC4C49CB0, 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, 0x6767C027, 0xE9E9AF8C,
0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70,
0x29294CCA, 0xF0F035E3, 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, 0xC8C81DC3, 0x9999FFCC,
0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2,
0xB5B53D79, 0x09090F0C, 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, 0xEDEDD07A, 0x4343FC17,
0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3,
0x5656E70B, 0xE3E3DA72, 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, 0x8181942A, 0x91910149,
0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9,
0x7878AEC5, 0xC5C56D39, 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, 0x55559DF9, 0x7E7E5A48,
0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519,
0x0606F48D, 0x404086E5, 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, 0x2D2D333C, 0x3030D6A5,
0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969,
0xD9D97929, 0x8686912E, 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, 0xC1C112CF, 0x8585EBDC,
0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB,
0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2,
0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91
);
/**
* M-Table
*
* @var Array
* @access private
*/
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,
0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, 0x94B1FBFB, 0x485A7E7E,
0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060,
0x1945FDFD, 0x5BA33A3A, 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, 0x9B53AAAA, 0x7C635D5D,
0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7,
0xC0F09090, 0x8CAFE9E9, 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, 0xB499C3C3, 0xF1975B5B,
0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8,
0xCCFF9999, 0x95EA1414, 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, 0xBF7E9595, 0xBA207D7D,
0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB,
0x81FB0F0F, 0x793DB5B5, 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, 0x86135050, 0xE730F7F7,
0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B,
0x410B9F9F, 0x7B8B0202, 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, 0xB1C72B2B, 0xAB6F8E8E,
0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9,
0x91EF1313, 0x85FE0808, 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, 0x6929A9A9, 0x647D4F4F,
0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED,
0xAC87D1D1, 0x7F8E0505, 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, 0x4C5F7979, 0x02B6B7B7,
0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2,
0x57AC3333, 0xC718CFCF, 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, 0x99E51D1D, 0x34392323,
0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA,
0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000,
0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8
);
/**
* M-Table
*
* @var Array
* @access private
*/
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,
0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, 0xB006B0B3, 0x753F75DE,
0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0,
0xAE6DAE2C, 0x7FC17FAB, 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, 0x312C3127, 0x80A38065,
0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F,
0x2A382A36, 0xC4B0C49C, 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, 0x672767C0, 0xE98CE9AF,
0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C,
0x29CA294C, 0xF0E3F035, 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, 0xC8C3C81D, 0x99CC99FF,
0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E,
0xB579B53D, 0x090C090F, 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, 0xED7AEDD0, 0x431743FC,
0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71,
0x560B56E7, 0xE372E3DA, 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, 0x812A8194, 0x91499101,
0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5,
0x78C578AE, 0xC539C56D, 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, 0x55F9559D, 0x7E487E5A,
0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45,
0x068D06F4, 0x40E54086, 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, 0x2D3C2D33, 0x30A530D6,
0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929,
0xD929D979, 0x862E8691, 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, 0xC1CFC112, 0x85DC85EB,
0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F,
0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746,
0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF
);
/**
* M-Table
*
* @var Array
* @access private
*/
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,
0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, 0xB1FB94B1, 0x5A7E485A,
0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5,
0x45FD1945, 0xA33A5BA3, 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, 0x53AA9B53, 0x635D7C63,
0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123,
0xF090C0F0, 0xAFE98CAF, 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, 0x99C3B499, 0x975BF197,
0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB,
0xFF99CCFF, 0xEA1495EA, 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, 0x7E95BF7E, 0x207DBA20,
0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137,
0xFB0F81FB, 0x3DB5793D, 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, 0x13508613, 0x30F7E730,
0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252,
0x0B9F410B, 0x8B027B8B, 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, 0xC72BB1C7, 0x6F8EAB6F,
0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A,
0xEF1391EF, 0xFE0885FE, 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, 0x29A96929, 0x7D4F647D,
0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0,
0x87D1AC87, 0x8E057F8E, 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, 0x5F794C5F, 0xB6B702B6,
0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38,
0xAC3357AC, 0x18CFC718, 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, 0xE51D99E5, 0x39233439,
0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6,
0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000,
0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8
);
/**
* The Key Schedule Array
*
* @var Array
* @access private
*/
var $K = array();
/**
* The Key depended S-Table 0
*
* @var Array
* @access private
*/
var $S0 = array();
/**
* The Key depended S-Table 1
*
* @var Array
* @access private
*/
var $S1 = array();
/**
* The Key depended S-Table 2
*
* @var Array
* @access private
*/
var $S2 = array();
/**
* The Key depended S-Table 3
*
* @var Array
* @access private
*/
var $S3 = array();
/**
* Holds the last used key
*
* @var Array
* @access private
*/
var $kl;
/**
* Sets the key.
*
* 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.
*
* If the key is not explicitly set, it'll be assumed a 128 bits key to be all null bytes.
*
* @access public
* @see Crypt_Base::setKey()
* @param String $key
*/
function setKey($key)
{
$keylength = strlen($key);
switch (true) {
case $keylength <= 16:
$key = str_pad($key, 16, "\0");
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);
}
parent::setKey($key);
}
/**
* Setup the key (expansion)
*
* @see Crypt_Base::_setupKey()
* @access private
*/
function _setupKey()
{
if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
// already expanded
return;
}
$this->kl = array('key' => $this->key);
/* Key expanding and generating the key-depended s-boxes */
$le_longs = unpack('V*', $this->key);
$key = unpack('C*', $this->key);
$m0 = $this->m0;
$m1 = $this->m1;
$m2 = $this->m2;
$m3 = $this->m3;
$q0 = $this->q0;
$q1 = $this->q1;
$K = $S0 = $S1 = $S2 = $S3 = array();
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) {
$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]] ^
$m3[$q1[$q1[$i] ^ $key[12]] ^ $key[4]];
$B = $m0[$q0[$q0[$j] ^ $key[13]] ^ $key[5]] ^
$m1[$q0[$q1[$j] ^ $key[14]] ^ $key[6]] ^
$m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^
$m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]];
$B = ($B << 8) | ($B >> 24 & 0xff);
$K[] = $A+= $B;
$K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
}
for ($i = 0; $i < 256; ++$i) {
$S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0];
$S1[$i] = $m1[$q0[$q1[$i] ^ $s5] ^ $s1];
$S2[$i] = $m2[$q1[$q0[$i] ^ $s6] ^ $s2];
$S3[$i] = $m3[$q1[$q1[$i] ^ $s7] ^ $s3];
}
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]);
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]] ^
$m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
$m3[$q1[$q1[$q0[$i] ^ $key[20]] ^ $key[12]] ^ $key[4]];
$B = $m0[$q0[$q0[$q1[$j] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
$m1[$q0[$q1[$q1[$j] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
$m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
$m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]];
$B = ($B << 8) | ($B >> 24 & 0xff);
$K[] = $A+= $B;
$K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
}
for ($i = 0; $i < 256; ++$i) {
$S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0];
$S1[$i] = $m1[$q0[$q1[$q1[$i] ^ $s9] ^ $s5] ^ $s1];
$S2[$i] = $m2[$q1[$q0[$q0[$i] ^ $sa] ^ $s6] ^ $s2];
$S3[$i] = $m3[$q1[$q1[$q0[$i] ^ $sb] ^ $s7] ^ $s3];
}
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]);
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]] ^
$m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
$m3[$q1[$q1[$q0[$q1[$i] ^ $key[28]] ^ $key[20]] ^ $key[12]] ^ $key[4]];
$B = $m0[$q0[$q0[$q1[$q1[$j] ^ $key[29]] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
$m1[$q0[$q1[$q1[$q0[$j] ^ $key[30]] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
$m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
$m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]];
$B = ($B << 8) | ($B >> 24 & 0xff);
$K[] = $A+= $B;
$K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
}
for ($i = 0; $i < 256; ++$i) {
$S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0];
$S1[$i] = $m1[$q0[$q1[$q1[$q0[$i] ^ $sd] ^ $s9] ^ $s5] ^ $s1];
$S2[$i] = $m2[$q1[$q0[$q0[$q0[$i] ^ $se] ^ $sa] ^ $s6] ^ $s2];
$S3[$i] = $m3[$q1[$q1[$q0[$q1[$i] ^ $sf] ^ $sb] ^ $s7] ^ $s3];
}
}
$this->K = $K;
$this->S0 = $S0;
$this->S1 = $S1;
$this->S2 = $S2;
$this->S3 = $S3;
}
/**
* _mdsrem function using by the twofish cipher algorithm
*
* @access private
* @param String $A
* @param String $B
* @return Array
*/
function _mdsrem($A, $B)
{
// No gain by unrolling this loop.
for ($i = 0; $i < 8; ++$i) {
// Get most significant coefficient.
$t = 0xff & ($B >> 24);
// Shift the others up.
$B = ($B << 8) | (0xff & ($A >> 24));
$A<<= 8;
$u = $t << 1;
// Subtract the modular polynomial on overflow.
if ($t & 0x80) {
$u^= 0x14d;
}
// Remove t * (a * x^2 + 1).
$B ^= $t ^ ($u << 16);
// Form u = a*t + t/a = t*(a + 1/a).
$u^= 0x7fffffff & ($t >> 1);
// Add the modular polynomial on underflow.
if ($t & 0x01) $u^= 0xa6 ;
// Remove t * (a + 1/a) * (x^3 + x).
$B^= ($u << 24) | ($u << 8);
}
return array(
0xff & $B >> 24,
0xff & $B >> 16,
0xff & $B >> 8,
0xff & $B);
}
/**
* Encrypts a block
*
* @access private
* @param String $in
* @return String
*/
function _encryptBlock($in)
{
$S0 = $this->S0;
$S1 = $this->S1;
$S2 = $this->S2;
$S3 = $this->S3;
$K = $this->K;
$in = unpack("V4", $in);
$R0 = $K[0] ^ $in[1];
$R1 = $K[1] ^ $in[2];
$R2 = $K[2] ^ $in[3];
$R3 = $K[3] ^ $in[4];
$ki = 7;
while ($ki < 39) {
$t0 = $S0[ $R0 & 0xff] ^
$S1[($R0 >> 8) & 0xff] ^
$S2[($R0 >> 16) & 0xff] ^
$S3[($R0 >> 24) & 0xff];
$t1 = $S0[($R1 >> 24) & 0xff] ^
$S1[ $R1 & 0xff] ^
$S2[($R1 >> 8) & 0xff] ^
$S3[($R1 >> 16) & 0xff];
$R2^= $t0 + $t1 + $K[++$ki];
$R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
$t0 = $S0[ $R2 & 0xff] ^
$S1[($R2 >> 8) & 0xff] ^
$S2[($R2 >> 16) & 0xff] ^
$S3[($R2 >> 24) & 0xff];
$t1 = $S0[($R3 >> 24) & 0xff] ^
$S1[ $R3 & 0xff] ^
$S2[($R3 >> 8) & 0xff] ^
$S3[($R3 >> 16) & 0xff];
$R0^= ($t0 + $t1 + $K[++$ki]);
$R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
}
// @codingStandardsIgnoreStart
return pack("V4", $K[4] ^ $R2,
$K[5] ^ $R3,
$K[6] ^ $R0,
$K[7] ^ $R1);
// @codingStandardsIgnoreEnd
}
/**
* Decrypts a block
*
* @access private
* @param String $in
* @return String
*/
function _decryptBlock($in)
{
$S0 = $this->S0;
$S1 = $this->S1;
$S2 = $this->S2;
$S3 = $this->S3;
$K = $this->K;
$in = unpack("V4", $in);
$R0 = $K[4] ^ $in[1];
$R1 = $K[5] ^ $in[2];
$R2 = $K[6] ^ $in[3];
$R3 = $K[7] ^ $in[4];
$ki = 40;
while ($ki > 8) {
$t0 = $S0[$R0 & 0xff] ^
$S1[$R0 >> 8 & 0xff] ^
$S2[$R0 >> 16 & 0xff] ^
$S3[$R0 >> 24 & 0xff];
$t1 = $S0[$R1 >> 24 & 0xff] ^
$S1[$R1 & 0xff] ^
$S2[$R1 >> 8 & 0xff] ^
$S3[$R1 >> 16 & 0xff];
$R3^= $t0 + ($t1 << 1) + $K[--$ki];
$R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + $K[--$ki]);
$t0 = $S0[$R2 & 0xff] ^
$S1[$R2 >> 8 & 0xff] ^
$S2[$R2 >> 16 & 0xff] ^
$S3[$R2 >> 24 & 0xff];
$t1 = $S0[$R3 >> 24 & 0xff] ^
$S1[$R3 & 0xff] ^
$S2[$R3 >> 8 & 0xff] ^
$S3[$R3 >> 16 & 0xff];
$R1^= $t0 + ($t1 << 1) + $K[--$ki];
$R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + $K[--$ki]);
}
// @codingStandardsIgnoreStart
return pack("V4", $K[0] ^ $R2,
$K[1] ^ $R3,
$K[2] ^ $R0,
$K[3] ^ $R1);
// @codingStandardsIgnoreEnd
}
/**
* Setup the performance-optimized function for de/encrypt()
*
* @see Crypt_Base::_setupInlineCrypt()
* @access private
*/
function _setupInlineCrypt()
{
$lambda_functions =& Crypt_Twofish::_getLambdaFunctions();
// Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
switch (true) {
case $gen_hi_opt_code:
$code_hash = md5(str_pad("Crypt_Twofish, {$this->mode}, ", 32, "\0") . $this->key);
break;
default:
$code_hash = "Crypt_Twofish, {$this->mode}";
}
if (!isset($lambda_functions[$code_hash])) {
switch (true) {
case $gen_hi_opt_code:
$K = $this->K;
$init_crypt = '
static $S0, $S1, $S2, $S3;
if (!$S0) {
for ($i = 0; $i < 256; ++$i) {
$S0[] = (int)$self->S0[$i];
$S1[] = (int)$self->S1[$i];
$S2[] = (int)$self->S2[$i];
$S3[] = (int)$self->S3[$i];
}
}
';
break;
default:
$K = array();
for ($i = 0; $i < 40; ++$i) {
$K[] = '$K_' . $i;
}
$init_crypt = '
$S0 = $self->S0;
$S1 = $self->S1;
$S2 = $self->S2;
$S3 = $self->S3;
list(' . implode(',', $K) . ') = $self->K;
';
}
// Generating encrypt code:
$encrypt_block = '
$in = unpack("V4", $in);
$R0 = '.$K[0].' ^ $in[1];
$R1 = '.$K[1].' ^ $in[2];
$R2 = '.$K[2].' ^ $in[3];
$R3 = '.$K[3].' ^ $in[4];
';
for ($ki = 7, $i = 0; $i < 8; ++$i) {
$encrypt_block.= '
$t0 = $S0[ $R0 & 0xff] ^
$S1[($R0 >> 8) & 0xff] ^
$S2[($R0 >> 16) & 0xff] ^
$S3[($R0 >> 24) & 0xff];
$t1 = $S0[($R1 >> 24) & 0xff] ^
$S1[ $R1 & 0xff] ^
$S2[($R1 >> 8) & 0xff] ^
$S3[($R1 >> 16) & 0xff];
$R2^= ($t0 + $t1 + '.$K[++$ki].');
$R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
$t0 = $S0[ $R2 & 0xff] ^
$S1[($R2 >> 8) & 0xff] ^
$S2[($R2 >> 16) & 0xff] ^
$S3[($R2 >> 24) & 0xff];
$t1 = $S0[($R3 >> 24) & 0xff] ^
$S1[ $R3 & 0xff] ^
$S2[($R3 >> 8) & 0xff] ^
$S3[($R3 >> 16) & 0xff];
$R0^= ($t0 + $t1 + '.$K[++$ki].');
$R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
';
}
$encrypt_block.= '
$in = pack("V4", '.$K[4].' ^ $R2,
'.$K[5].' ^ $R3,
'.$K[6].' ^ $R0,
'.$K[7].' ^ $R1);
';
// Generating decrypt code:
$decrypt_block = '
$in = unpack("V4", $in);
$R0 = '.$K[4].' ^ $in[1];
$R1 = '.$K[5].' ^ $in[2];
$R2 = '.$K[6].' ^ $in[3];
$R3 = '.$K[7].' ^ $in[4];
';
for ($ki = 40, $i = 0; $i < 8; ++$i) {
$decrypt_block.= '
$t0 = $S0[$R0 & 0xff] ^
$S1[$R0 >> 8 & 0xff] ^
$S2[$R0 >> 16 & 0xff] ^
$S3[$R0 >> 24 & 0xff];
$t1 = $S0[$R1 >> 24 & 0xff] ^
$S1[$R1 & 0xff] ^
$S2[$R1 >> 8 & 0xff] ^
$S3[$R1 >> 16 & 0xff];
$R3^= $t0 + ($t1 << 1) + '.$K[--$ki].';
$R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
$t0 = $S0[$R2 & 0xff] ^
$S1[$R2 >> 8 & 0xff] ^
$S2[$R2 >> 16 & 0xff] ^
$S3[$R2 >> 24 & 0xff];
$t1 = $S0[$R3 >> 24 & 0xff] ^
$S1[$R3 & 0xff] ^
$S2[$R3 >> 8 & 0xff] ^
$S3[$R3 >> 16 & 0xff];
$R1^= $t0 + ($t1 << 1) + '.$K[--$ki].';
$R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
';
}
$decrypt_block.= '
$in = pack("V4", '.$K[0].' ^ $R2,
'.$K[1].' ^ $R3,
'.$K[2].' ^ $R0,
'.$K[3].' ^ $R1);
';
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
array(
'init_crypt' => $init_crypt,
'init_encrypt' => '',
'init_decrypt' => '',
'encrypt_block' => $encrypt_block,
'decrypt_block' => $decrypt_block
)
);
}
$this->inline_crypt = $lambda_functions[$code_hash];
}
}

View File

@@ -0,0 +1,559 @@
<?php
/**
* Pure-PHP ANSI Decoder
*
* PHP versions 4 and 5
*
* If you call read() in Net_SSH2 you may get {@link http://en.wikipedia.org/wiki/ANSI_escape_code ANSI escape codes} back.
* They'd look like chr(0x1B) . '[00m' or whatever (0x1B = ESC). They tell a
* {@link http://en.wikipedia.org/wiki/Terminal_emulator terminal emulator} how to format the characters, what
* color to display them in, etc. File_ANSI is a {@link http://en.wikipedia.org/wiki/VT100 VT100} terminal emulator.
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category File
* @package File_ANSI
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2012 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* Pure-PHP ANSI Decoder
*
* @package File_ANSI
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class File_ANSI
{
/**
* Max Width
*
* @var Integer
* @access private
*/
var $max_x;
/**
* Max Height
*
* @var Integer
* @access private
*/
var $max_y;
/**
* Max History
*
* @var Integer
* @access private
*/
var $max_history;
/**
* History
*
* @var Array
* @access private
*/
var $history;
/**
* History Attributes
*
* @var Array
* @access private
*/
var $history_attrs;
/**
* Current Column
*
* @var Integer
* @access private
*/
var $x;
/**
* Current Row
*
* @var Integer
* @access private
*/
var $y;
/**
* Old Column
*
* @var Integer
* @access private
*/
var $old_x;
/**
* Old Row
*
* @var Integer
* @access private
*/
var $old_y;
/**
* An empty attribute row
*
* @var Array
* @access private
*/
var $attr_row;
/**
* The current screen text
*
* @var Array
* @access private
*/
var $screen;
/**
* The current screen attributes
*
* @var Array
* @access private
*/
var $attrs;
/**
* The current foreground color
*
* @var String
* @access private
*/
var $foreground;
/**
* The current background color
*
* @var String
* @access private
*/
var $background;
/**
* Bold flag
*
* @var Boolean
* @access private
*/
var $bold;
/**
* Underline flag
*
* @var Boolean
* @access private
*/
var $underline;
/**
* Blink flag
*
* @var Boolean
* @access private
*/
var $blink;
/**
* Reverse flag
*
* @var Boolean
* @access private
*/
var $reverse;
/**
* Color flag
*
* @var Boolean
* @access private
*/
var $color;
/**
* Current ANSI code
*
* @var String
* @access private
*/
var $ansi;
/**
* Default Constructor.
*
* @return File_ANSI
* @access public
*/
function File_ANSI()
{
$this->setHistory(200);
$this->setDimensions(80, 24);
}
/**
* Set terminal width and height
*
* Resets the screen as well
*
* @param Integer $x
* @param Integer $y
* @access public
*/
function setDimensions($x, $y)
{
$this->max_x = $x - 1;
$this->max_y = $y - 1;
$this->x = $this->y = 0;
$this->history = $this->history_attrs = array();
$this->attr_row = array_fill(0, $this->max_x + 1, '');
$this->screen = array_fill(0, $this->max_y + 1, '');
$this->attrs = array_fill(0, $this->max_y + 1, $this->attr_row);
$this->foreground = 'white';
$this->background = 'black';
$this->bold = false;
$this->underline = false;
$this->blink = false;
$this->reverse = false;
$this->color = false;
$this->ansi = '';
}
/**
* Set the number of lines that should be logged past the terminal height
*
* @param Integer $x
* @param Integer $y
* @access public
*/
function setHistory($history)
{
$this->max_history = $history;
}
/**
* Load a string
*
* @param String $source
* @access public
*/
function loadString($source)
{
$this->setDimensions($this->max_x + 1, $this->max_y + 1);
$this->appendString($source);
}
/**
* Appdend a string
*
* @param String $source
* @access public
*/
function appendString($source)
{
for ($i = 0; $i < strlen($source); $i++) {
if (strlen($this->ansi)) {
$this->ansi.= $source[$i];
$chr = ord($source[$i]);
// http://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements
// single character CSI's not currently supported
switch (true) {
case $this->ansi == "\x1B=":
$this->ansi = '';
continue 2;
case strlen($this->ansi) == 2 && $chr >= 64 && $chr <= 95 && $chr != ord('['):
case strlen($this->ansi) > 2 && $chr >= 64 && $chr <= 126:
break;
default:
continue 2;
}
// http://ascii-table.com/ansi-escape-sequences-vt-100.php
switch ($this->ansi) {
case "\x1B[H": // Move cursor to upper left corner
$this->old_x = $this->x;
$this->old_y = $this->y;
$this->x = $this->y = 0;
break;
case "\x1B[J": // Clear screen from cursor down
$this->history = array_merge($this->history, array_slice(array_splice($this->screen, $this->y + 1), 0, $this->old_y));
$this->screen = array_merge($this->screen, array_fill($this->y, $this->max_y, ''));
$this->history_attrs = array_merge($this->history_attrs, array_slice(array_splice($this->attrs, $this->y + 1), 0, $this->old_y));
$this->attrs = array_merge($this->attrs, array_fill($this->y, $this->max_y, $this->attr_row));
if (count($this->history) == $this->max_history) {
array_shift($this->history);
array_shift($this->history_attrs);
}
case "\x1B[K": // Clear screen from cursor right
$this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x);
array_splice($this->attrs[$this->y], $this->x + 1);
break;
case "\x1B[2K": // Clear entire line
$this->screen[$this->y] = str_repeat(' ', $this->x);
$this->attrs[$this->y] = $this->attr_row;
break;
case "\x1B[?1h": // set cursor key to application
case "\x1B[?25h": // show the cursor
break;
case "\x1BE": // Move to next line
$this->_newLine();
$this->x = 0;
break;
default:
switch (true) {
case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h
$this->old_x = $this->x;
$this->old_y = $this->y;
$this->x = $match[2] - 1;
$this->y = $match[1] - 1;
break;
case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines
$this->old_x = $this->x;
$x = $match[1] - 1;
break;
case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
break;
case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): // character attributes
$mods = explode(';', $match[1]);
foreach ($mods as $mod) {
switch ($mod) {
case 0: // Turn off character attributes
$this->attrs[$this->y][$this->x] = '';
if ($this->bold) $this->attrs[$this->y][$this->x].= '</b>';
if ($this->underline) $this->attrs[$this->y][$this->x].= '</u>';
if ($this->blink) $this->attrs[$this->y][$this->x].= '</blink>';
if ($this->color) $this->attrs[$this->y][$this->x].= '</span>';
if ($this->reverse) {
$temp = $this->background;
$this->background = $this->foreground;
$this->foreground = $temp;
}
$this->bold = $this->underline = $this->blink = $this->color = $this->reverse = false;
break;
case 1: // Turn bold mode on
if (!$this->bold) {
$this->attrs[$this->y][$this->x] = '<b>';
$this->bold = true;
}
break;
case 4: // Turn underline mode on
if (!$this->underline) {
$this->attrs[$this->y][$this->x] = '<u>';
$this->underline = true;
}
break;
case 5: // Turn blinking mode on
if (!$this->blink) {
$this->attrs[$this->y][$this->x] = '<blink>';
$this->blink = true;
}
break;
case 7: // Turn reverse video on
$this->reverse = !$this->reverse;
$temp = $this->background;
$this->background = $this->foreground;
$this->foreground = $temp;
$this->attrs[$this->y][$this->x] = '<span style="color: ' . $this->foreground . '; background: ' . $this->background . '">';
if ($this->color) {
$this->attrs[$this->y][$this->x] = '</span>' . $this->attrs[$this->y][$this->x];
}
$this->color = true;
break;
default: // set colors
//$front = $this->reverse ? &$this->background : &$this->foreground;
$front = &$this->{ $this->reverse ? 'background' : 'foreground' };
//$back = $this->reverse ? &$this->foreground : &$this->background;
$back = &$this->{ $this->reverse ? 'foreground' : 'background' };
switch ($mod) {
case 30: $front = 'black'; break;
case 31: $front = 'red'; break;
case 32: $front = 'green'; break;
case 33: $front = 'yellow'; break;
case 34: $front = 'blue'; break;
case 35: $front = 'magenta'; break;
case 36: $front = 'cyan'; break;
case 37: $front = 'white'; break;
case 40: $back = 'black'; break;
case 41: $back = 'red'; break;
case 42: $back = 'green'; break;
case 43: $back = 'yellow'; break;
case 44: $back = 'blue'; break;
case 45: $back = 'magenta'; break;
case 46: $back = 'cyan'; break;
case 47: $back = 'white'; break;
default:
user_error('Unsupported attribute: ' . $mod);
$this->ansi = '';
break 2;
}
unset($temp);
$this->attrs[$this->y][$this->x] = '<span style="color: ' . $this->foreground . '; background: ' . $this->background . '">';
if ($this->color) {
$this->attrs[$this->y][$this->x] = '</span>' . $this->attrs[$this->y][$this->x];
}
$this->color = true;
}
}
break;
default:
user_error("{$this->ansi} unsupported\r\n");
}
}
$this->ansi = '';
continue;
}
switch ($source[$i]) {
case "\r":
$this->x = 0;
break;
case "\n":
$this->_newLine();
break;
case "\x0F": // shift
break;
case "\x1B": // start ANSI escape code
$this->ansi.= "\x1B";
break;
default:
$this->screen[$this->y] = substr_replace(
$this->screen[$this->y],
$source[$i],
$this->x,
1
);
if ($this->x > $this->max_x) {
$this->x = 0;
$this->y++;
} else {
$this->x++;
}
}
}
}
/**
* Add a new line
*
* Also update the $this->screen and $this->history buffers
*
* @access private
*/
function _newLine()
{
//if ($this->y < $this->max_y) {
// $this->y++;
//}
while ($this->y >= $this->max_y) {
$this->history = array_merge($this->history, array(array_shift($this->screen)));
$this->screen[] = '';
$this->history_attrs = array_merge($this->history_attrs, array(array_shift($this->attrs)));
$this->attrs[] = $this->attr_row;
if (count($this->history) >= $this->max_history) {
array_shift($this->history);
array_shift($this->history_attrs);
}
$this->y--;
}
$this->y++;
}
/**
* Returns the current screen without preformating
*
* @access private
* @return String
*/
function _getScreen()
{
$output = '';
for ($i = 0; $i <= $this->max_y; $i++) {
for ($j = 0; $j <= $this->max_x + 1; $j++) {
if (isset($this->attrs[$i][$j])) {
$output.= $this->attrs[$i][$j];
}
if (isset($this->screen[$i][$j])) {
$output.= htmlspecialchars($this->screen[$i][$j]);
}
}
$output.= "\r\n";
}
return rtrim($output);
}
/**
* Returns the current screen
*
* @access public
* @return String
*/
function getScreen()
{
return '<pre style="color: white; background: black" width="' . ($this->max_x + 1) . '">' . $this->_getScreen() . '</pre>';
}
/**
* Returns the current screen and the x previous lines
*
* @access public
* @return String
*/
function getHistory()
{
$scrollback = '';
for ($i = 0; $i < count($this->history); $i++) {
for ($j = 0; $j <= $this->max_x + 1; $j++) {
if (isset($this->history_attrs[$i][$j])) {
$scrollback.= $this->history_attrs[$i][$j];
}
if (isset($this->history[$i][$j])) {
$scrollback.= htmlspecialchars($this->history[$i][$j]);
}
}
$scrollback.= "\r\n";
}
$scrollback.= $this->_getScreen();
return '<pre style="color: white; background: black" width="' . ($this->max_x + 1) . '">' . $scrollback . '</pre>';
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,360 @@
<?php
/**
* Pure-PHP implementation of SCP.
*
* PHP versions 4 and 5
*
* The API for this library is modeled after the API from PHP's {@link http://php.net/book.ftp FTP extension}.
*
* Here's a short example of how to use this library:
* <code>
* <?php
* include 'Net/SCP.php';
* include 'Net/SSH2.php';
*
* $ssh = new Net_SSH2('www.domain.tld');
* if (!$ssh->login('username', 'password')) {
* exit('bad login');
* }
* $scp = new Net_SCP($ssh);
* $scp->put('abcd', str_repeat('x', 1024*1024));
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Net
* @package Net_SCP
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2010 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**#@+
* @access public
* @see Net_SCP::put()
*/
/**
* Reads data from a local file.
*/
define('NET_SCP_LOCAL_FILE', 1);
/**
* Reads data from a string.
*/
define('NET_SCP_STRING', 2);
/**#@-*/
/**#@+
* @access private
* @see Net_SCP::_send()
* @see Net_SCP::_receive()
*/
/**
* SSH1 is being used.
*/
define('NET_SCP_SSH1', 1);
/**
* SSH2 is being used.
*/
define('NET_SCP_SSH2', 2);
/**#@-*/
/**
* Pure-PHP implementations of SCP.
*
* @package Net_SCP
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Net_SCP
{
/**
* SSH Object
*
* @var Object
* @access private
*/
var $ssh;
/**
* Packet Size
*
* @var Integer
* @access private
*/
var $packet_size;
/**
* Mode
*
* @var Integer
* @access private
*/
var $mode;
/**
* Default Constructor.
*
* Connects to an SSH server
*
* @param String $host
* @param optional Integer $port
* @param optional Integer $timeout
* @return Net_SCP
* @access public
*/
function Net_SCP($ssh)
{
if (!is_object($ssh)) {
return;
}
switch (strtolower(get_class($ssh))) {
case 'net_ssh2':
$this->mode = NET_SCP_SSH2;
break;
case 'net_ssh1':
$this->packet_size = 50000;
$this->mode = NET_SCP_SSH1;
break;
default:
return;
}
$this->ssh = $ssh;
}
/**
* Uploads a file to the SCP server.
*
* By default, Net_SCP::put() does not read from the local filesystem. $data is dumped directly into $remote_file.
* So, for example, if you set $data to 'filename.ext' and then do Net_SCP::get(), you will get a file, twelve bytes
* long, containing 'filename.ext' as its contents.
*
* Setting $mode to NET_SCP_LOCAL_FILE will change the above behavior. With NET_SCP_LOCAL_FILE, $remote_file will
* contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how
* large $remote_file will be, as well.
*
* 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
* @access public
*/
function put($remote_file, $data, $mode = NET_SCP_STRING, $callback = null)
{
if (!isset($this->ssh)) {
return false;
}
if (!$this->ssh->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to
return false;
}
$temp = $this->_receive();
if ($temp !== chr(0)) {
return false;
}
if ($this->mode == NET_SCP_SSH2) {
$this->packet_size = $this->ssh->packet_size_client_to_server[NET_SSH2_CHANNEL_EXEC] - 4;
}
$remote_file = basename($remote_file);
if ($mode == NET_SCP_STRING) {
$size = strlen($data);
} else {
if (!is_file($data)) {
user_error("$data is not a valid file", E_USER_NOTICE);
return false;
}
$fp = @fopen($data, 'rb');
if (!$fp) {
return false;
}
$size = filesize($data);
}
$this->_send('C0644 ' . $size . ' ' . $remote_file . "\n");
$temp = $this->_receive();
if ($temp !== chr(0)) {
return false;
}
$sent = 0;
while ($sent < $size) {
$temp = $mode & NET_SCP_STRING ? substr($data, $sent, $this->packet_size) : fread($fp, $this->packet_size);
$this->_send($temp);
$sent+= strlen($temp);
if (is_callable($callback)) {
call_user_func($callback, $sent);
}
}
$this->_close();
if ($mode != NET_SCP_STRING) {
fclose($fp);
}
return true;
}
/**
* Downloads a file from the SCP server.
*
* Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if
* 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
* @access public
*/
function get($remote_file, $local_file = false)
{
if (!isset($this->ssh)) {
return false;
}
if (!$this->ssh->exec('scp -f ' . escapeshellarg($remote_file), false)) { // -f = from
return false;
}
$this->_send("\0");
if (!preg_match('#(?<perms>[^ ]+) (?<size>\d+) (?<name>.+)#', rtrim($this->_receive()), $info)) {
return false;
}
$this->_send("\0");
$size = 0;
if ($local_file !== false) {
$fp = @fopen($local_file, 'wb');
if (!$fp) {
return false;
}
}
$content = '';
while ($size < $info['size']) {
$data = $this->_receive();
// SCP usually seems to split stuff out into 16k chunks
$size+= strlen($data);
if ($local_file === false) {
$content.= $data;
} else {
fputs($fp, $data);
}
}
$this->_close();
if ($local_file !== false) {
fclose($fp);
return true;
}
return $content;
}
/**
* Sends a packet to an SSH server
*
* @param String $data
* @access private
*/
function _send($data)
{
switch ($this->mode) {
case NET_SCP_SSH2:
$this->ssh->_send_channel_packet(NET_SSH2_CHANNEL_EXEC, $data);
break;
case NET_SCP_SSH1:
$data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($data), $data);
$this->ssh->_send_binary_packet($data);
}
}
/**
* Receives a packet from an SSH server
*
* @return String
* @access private
*/
function _receive()
{
switch ($this->mode) {
case NET_SCP_SSH2:
return $this->ssh->_get_channel_packet(NET_SSH2_CHANNEL_EXEC, true);
case NET_SCP_SSH1:
if (!$this->ssh->bitmap) {
return false;
}
while (true) {
$response = $this->ssh->_get_binary_packet();
switch ($response[NET_SSH1_RESPONSE_TYPE]) {
case NET_SSH1_SMSG_STDOUT_DATA:
extract(unpack('Nlength', $response[NET_SSH1_RESPONSE_DATA]));
return $this->ssh->_string_shift($response[NET_SSH1_RESPONSE_DATA], $length);
case NET_SSH1_SMSG_STDERR_DATA:
break;
case NET_SSH1_SMSG_EXITSTATUS:
$this->ssh->_send_binary_packet(chr(NET_SSH1_CMSG_EXIT_CONFIRMATION));
fclose($this->ssh->fsock);
$this->ssh->bitmap = 0;
return false;
default:
user_error('Unknown packet received', E_USER_NOTICE);
return false;
}
}
}
}
/**
* Closes the connection to an SSH server
*
* @access private
*/
function _close()
{
switch ($this->mode) {
case NET_SCP_SSH2:
$this->ssh->_close_channel(NET_SSH2_CHANNEL_EXEC, true);
break;
case NET_SCP_SSH1:
$this->ssh->disconnect();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,801 @@
<?php
/**
* SFTP Stream Wrapper
*
* Creates an sftp:// protocol handler that can be used with, for example, fopen(), dir(), etc.
*
* PHP version 5
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category Net
* @package Net_SFTP_Stream
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2013 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
*/
/**
* SFTP Stream Wrapper
*
* @package Net_SFTP_Stream
* @author Jim Wigginton <terrafrost@php.net>
* @access public
*/
class Net_SFTP_Stream
{
/**
* SFTP instances
*
* Rather than re-create the connection we re-use instances if possible
*
* @var Array
*/
static $instances;
/**
* SFTP instance
*
* @var Object
* @access private
*/
var $sftp;
/**
* Path
*
* @var String
* @access private
*/
var $path;
/**
* Mode
*
* @var String
* @access private
*/
var $mode;
/**
* Position
*
* @var Integer
* @access private
*/
var $pos;
/**
* Size
*
* @var Integer
* @access private
*/
var $size;
/**
* Directory entries
*
* @var Array
* @access private
*/
var $entries;
/**
* EOF flag
*
* @var Boolean
* @access private
*/
var $eof;
/**
* Context resource
*
* Technically this needs to be publically accessible so PHP can set it directly
*
* @var Resource
* @access public
*/
var $context;
/**
* Notification callback function
*
* @var Callable
* @access public
*/
var $notification;
/**
* Registers this class as a URL wrapper.
*
* @param optional String $protocol The wrapper name to be registered.
* @return Boolean True on success, false otherwise.
* @access public
*/
static function register($protocol = 'sftp')
{
if (in_array($protocol, stream_get_wrappers(), true)) {
return false;
}
$class = function_exists('get_called_class') ? get_called_class() : __CLASS__;
return stream_wrapper_register($protocol, $class);
}
/**
* The Constructor
*
* @access public
*/
function Net_SFTP_Stream()
{
if (defined('NET_SFTP_STREAM_LOGGING')) {
echo "__construct()\r\n";
}
if (!class_exists('Net_SFTP')) {
include_once 'Net/SFTP.php';
}
}
/**
* Path Parser
*
* Extract a path from a URI and actually connect to an SSH server if appropriate
*
* 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
* @access private
*/
function _parse_path($path)
{
extract(parse_url($path) + array('port' => 22));
if (!isset($host)) {
return false;
}
if (isset($this->context)) {
$context = stream_context_get_params($this->context);
if (isset($context['notification'])) {
$this->notification = $context['notification'];
}
}
if ($host[0] == '$') {
$host = substr($host, 1);
global $$host;
if (!is_object($$host) || get_class($$host) != 'Net_SFTP') {
return false;
}
$this->sftp = $$host;
} else {
if (isset($this->context)) {
$context = stream_context_get_options($this->context);
}
if (isset($context[$scheme]['session'])) {
$sftp = $context[$scheme]['session'];
}
if (isset($context[$scheme]['sftp'])) {
$sftp = $context[$scheme]['sftp'];
}
if (isset($sftp) && is_object($sftp) && get_class($sftp) == 'Net_SFTP') {
$this->sftp = $sftp;
return $path;
}
if (isset($context[$scheme]['username'])) {
$user = $context[$scheme]['username'];
}
if (isset($context[$scheme]['password'])) {
$pass = $context[$scheme]['password'];
}
if (isset($context[$scheme]['privkey']) && is_object($context[$scheme]['privkey']) && get_Class($context[$scheme]['privkey']) == 'Crypt_RSA') {
$pass = $context[$scheme]['privkey'];
}
if (!isset($user) || !isset($pass)) {
return false;
}
// casting $pass to a string is necessary in the event that it's a Crypt_RSA object
if (isset(self::$instances[$host][$port][$user][(string) $pass])) {
$this->sftp = self::$instances[$host][$port][$user][(string) $pass];
} else {
$this->sftp = new Net_SFTP($host, $port);
$this->sftp->disableStatCache();
if (isset($this->notification) && is_callable($this->notification)) {
/* if !is_callable($this->notification) we could do this:
user_error('fopen(): failed to call user notifier', E_USER_WARNING);
the ftp wrapper gives errors like that when the notifier isn't callable.
i've opted not to do that, however, since the ftp wrapper gives the line
on which the fopen occurred as the line number - not the line that the
user_error is on.
*/
call_user_func($this->notification, STREAM_NOTIFY_CONNECT, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0);
call_user_func($this->notification, STREAM_NOTIFY_AUTH_REQUIRED, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0);
if (!$this->sftp->login($user, $pass)) {
call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_ERR, 'Login Failure', NET_SSH2_MSG_USERAUTH_FAILURE, 0, 0);
return false;
}
call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_INFO, 'Login Success', NET_SSH2_MSG_USERAUTH_SUCCESS, 0, 0);
} else {
if (!$this->sftp->login($user, $pass)) {
return false;
}
}
self::$instances[$host][$port][$user][(string) $pass] = $this->sftp;
}
}
return $path;
}
/**
* Opens file or URL
*
* @param String $path
* @param String $mode
* @param Integer $options
* @param String $opened_path
* @return Boolean
* @access public
*/
function _stream_open($path, $mode, $options, &$opened_path)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
$this->path = $path;
$this->size = $this->sftp->size($path);
$this->mode = preg_replace('#[bt]$#', '', $mode);
$this->eof = false;
if ($this->size === false) {
if ($this->mode[0] == 'r') {
return false;
}
} else {
switch ($this->mode[0]) {
case 'x':
return false;
case 'w':
case 'c':
$this->sftp->truncate($path, 0);
}
}
$this->pos = $this->mode[0] != 'a' ? 0 : $this->size;
return true;
}
/**
* Read from stream
*
* @param Integer $count
* @return Mixed
* @access public
*/
function _stream_read($count)
{
switch ($this->mode) {
case 'w':
case 'a':
case 'x':
case 'c':
return false;
}
// commented out because some files - eg. /dev/urandom - will say their size is 0 when in fact it's kinda infinite
//if ($this->pos >= $this->size) {
// $this->eof = true;
// return false;
//}
$result = $this->sftp->get($this->path, false, $this->pos, $count);
if (isset($this->notification) && is_callable($this->notification)) {
if ($result === false) {
call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0);
return 0;
}
// seems that PHP calls stream_read in 8k chunks
call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($result), $this->size);
}
if (empty($result)) { // ie. false or empty string
$this->eof = true;
return false;
}
$this->pos+= strlen($result);
return $result;
}
/**
* Write to stream
*
* @param String $data
* @return Mixed
* @access public
*/
function _stream_write($data)
{
switch ($this->mode) {
case 'r':
return false;
}
$result = $this->sftp->put($this->path, $data, NET_SFTP_STRING, $this->pos);
if (isset($this->notification) && is_callable($this->notification)) {
if (!$result) {
call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0);
return 0;
}
// seems that PHP splits up strings into 8k blocks before calling stream_write
call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($data), strlen($data));
}
if ($result === false) {
return false;
}
$this->pos+= strlen($data);
if ($this->pos > $this->size) {
$this->size = $this->pos;
}
$this->eof = false;
return strlen($data);
}
/**
* Retrieve the current position of a stream
*
* @return Integer
* @access public
*/
function _stream_tell()
{
return $this->pos;
}
/**
* Tests for end-of-file on a file pointer
*
* In my testing there are four classes functions that normally effect the pointer:
* fseek, fputs / fwrite, fgets / fread and ftruncate.
*
* Only fgets / fread, however, results in feof() returning true. do fputs($fp, 'aaa') on a blank file and feof()
* 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
* @access public
*/
function _stream_eof()
{
return $this->eof;
}
/**
* Seeks to specific location in a stream
*
* @param Integer $offset
* @param Integer $whence
* @return Boolean
* @access public
*/
function _stream_seek($offset, $whence)
{
switch ($whence) {
case SEEK_SET:
if ($offset >= $this->size || $offset < 0) {
return false;
}
break;
case SEEK_CUR:
$offset+= $this->pos;
break;
case SEEK_END:
$offset+= $this->size;
}
$this->pos = $offset;
$this->eof = false;
return true;
}
/**
* Change stream options
*
* @param String $path
* @param Integer $option
* @param Mixed $var
* @return Boolean
* @access public
*/
function _stream_metadata($path, $option, $var)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
// stream_metadata was introduced in PHP 5.4.0 but as of 5.4.11 the constants haven't been defined
// see http://www.php.net/streamwrapper.stream-metadata and https://bugs.php.net/64246
// and https://github.com/php/php-src/blob/master/main/php_streams.h#L592
switch ($option) {
case 1: // PHP_STREAM_META_TOUCH
return $this->sftp->touch($path, $var[0], $var[1]);
case 2: // PHP_STREAM_OWNER_NAME
case 3: // PHP_STREAM_GROUP_NAME
return false;
case 4: // PHP_STREAM_META_OWNER
return $this->sftp->chown($path, $var);
case 5: // PHP_STREAM_META_GROUP
return $this->sftp->chgrp($path, $var);
case 6: // PHP_STREAM_META_ACCESS
return $this->sftp->chmod($path, $var) !== false;
}
}
/**
* Retrieve the underlaying resource
*
* @param Integer $cast_as
* @return Resource
* @access public
*/
function _stream_cast($cast_as)
{
return $this->sftp->fsock;
}
/**
* Advisory file locking
*
* @param Integer $operation
* @return Boolean
* @access public
*/
function _stream_lock($operation)
{
return false;
}
/**
* Renames a file or directory
*
* Attempts to rename oldname to newname, moving it between directories if necessary.
* If newname exists, it will be overwritten. This is a departure from what Net_SFTP
* does.
*
* @param String $path_from
* @param String $path_to
* @return Boolean
* @access public
*/
function _rename($path_from, $path_to)
{
$path1 = parse_url($path_from);
$path2 = parse_url($path_to);
unset($path1['path'], $path2['path']);
if ($path1 != $path2) {
return false;
}
$path_from = $this->_parse_path($path_from);
$path_to = parse_url($path_to);
if ($path_from == false) {
return false;
}
$path_to = $path_to['path']; // the $component part of parse_url() was added in PHP 5.1.2
// "It is an error if there already exists a file with the name specified by newpath."
// -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-6.5
if (!$this->sftp->rename($path_from, $path_to)) {
if ($this->sftp->stat($path_to)) {
return $this->sftp->delete($path_to, true) && $this->sftp->rename($path_from, $path_to);
}
return false;
}
return true;
}
/**
* Open directory handle
*
* The only $options is "whether or not to enforce safe_mode (0x04)". Since safe mode was deprecated in 5.3 and
* removed in 5.4 I'm just going to ignore it.
*
* Also, nlist() is the best that this function is realistically going to be able to do. When an SFTP client
* sends a SSH_FXP_READDIR packet you don't generally get info on just one file but on multiple files. Quoting
* the SFTP specs:
*
* The SSH_FXP_NAME response has the following format:
*
* uint32 id
* uint32 count
* repeats count times:
* string filename
* string longname
* ATTRS attrs
*
* @param String $path
* @param Integer $options
* @return Boolean
* @access public
*/
function _dir_opendir($path, $options)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
$this->pos = 0;
$this->entries = $this->sftp->nlist($path);
return $this->entries !== false;
}
/**
* Read entry from directory handle
*
* @return Mixed
* @access public
*/
function _dir_readdir()
{
if (isset($this->entries[$this->pos])) {
return $this->entries[$this->pos++];
}
return false;
}
/**
* Rewind directory handle
*
* @return Boolean
* @access public
*/
function _dir_rewinddir()
{
$this->pos = 0;
return true;
}
/**
* Close directory handle
*
* @return Boolean
* @access public
*/
function _dir_closedir()
{
return true;
}
/**
* Create a directory
*
* Only valid $options is STREAM_MKDIR_RECURSIVE
*
* @param String $path
* @param Integer $mode
* @param Integer $options
* @return Boolean
* @access public
*/
function _mkdir($path, $mode, $options)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
return $this->sftp->mkdir($path, $mode, $options & STREAM_MKDIR_RECURSIVE);
}
/**
* Removes a directory
*
* Only valid $options is STREAM_MKDIR_RECURSIVE per <http://php.net/streamwrapper.rmdir>, however,
* <http://php.net/rmdir> does not have a $recursive parameter as mkdir() does so I don't know how
* 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
* @access public
*/
function _rmdir($path, $options)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
return $this->sftp->rmdir($path);
}
/**
* Flushes the output
*
* See <http://php.net/fflush>. Always returns true because Net_SFTP doesn't cache stuff before writing
*
* @return Boolean
* @access public
*/
function _stream_flush()
{
return true;
}
/**
* Retrieve information about a file resource
*
* @return Mixed
* @access public
*/
function _stream_stat()
{
$results = $this->sftp->stat($this->path);
if ($results === false) {
return false;
}
return $results;
}
/**
* Delete a file
*
* @param String $path
* @return Boolean
* @access public
*/
function _unlink($path)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
return $this->sftp->delete($path, false);
}
/**
* Retrieve information about a file
*
* Ignores the STREAM_URL_STAT_QUIET flag because the entirety of Net_SFTP_Stream is quiet by default
* 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
* @access public
*/
function _url_stat($path, $flags)
{
$path = $this->_parse_path($path);
if ($path === false) {
return false;
}
$results = $flags & STREAM_URL_STAT_LINK ? $this->sftp->lstat($path) : $this->sftp->stat($path);
if ($results === false) {
return false;
}
return $results;
}
/**
* Truncate stream
*
* @param Integer $new_size
* @return Boolean
* @access public
*/
function _stream_truncate($new_size)
{
if (!$this->sftp->truncate($this->path, $new_size)) {
return false;
}
$this->eof = false;
$this->size = $new_size;
return true;
}
/**
* Change stream options
*
* 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 Net_SFTP.
*
* @param Integer $option
* @param Integer $arg1
* @param Integer $arg2
* @return Boolean
* @access public
*/
function _stream_set_option($option, $arg1, $arg2)
{
return false;
}
/**
* Close an resource
*
* @access public
*/
function _stream_close()
{
}
/**
* __call Magic Method
*
* When you're utilizing an SFTP stream you're not calling the methods in this class directly - PHP is calling them for you.
* Which kinda begs the question... what methods is PHP calling and what parameters is it passing to them? This function
* lets you figure that out.
*
* 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
* @access public
*/
function __call($name, $arguments)
{
if (defined('NET_SFTP_STREAM_LOGGING')) {
echo $name . '(';
$last = count($arguments) - 1;
foreach ($arguments as $i => $argument) {
var_export($argument);
if ($i != $last) {
echo ',';
}
}
echo ")\r\n";
}
$name = '_' . $name;
if (!method_exists($this, $name)) {
return false;
}
return call_user_func_array(array($this, $name), $arguments);
}
}
Net_SFTP_Stream::register();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,313 @@
<?php
/**
* Pure-PHP ssh-agent client.
*
* PHP versions 4 and 5
*
* Here are some examples of how to use this library:
* <code>
* <?php
* include 'System/SSH/Agent.php';
* include 'Net/SSH2.php';
*
* $agent = new System_SSH_Agent();
*
* $ssh = new Net_SSH2('www.domain.tld');
* if (!$ssh->login('username', $agent)) {
* exit('Login Failed');
* }
*
* echo $ssh->exec('pwd');
* echo $ssh->exec('ls -la');
* ?>
* </code>
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category System
* @package System_SSH_Agent
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2014 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
* @internal See http://api.libssh.org/rfc/PROTOCOL.agent
*/
/**#@+
* Message numbers
*
* @access private
*/
// to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1)
define('SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES', 11);
// this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2).
define('SYSTEM_SSH_AGENT_IDENTITIES_ANSWER', 12);
define('SYSTEM_SSH_AGENT_FAILURE', 5);
// the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3)
define('SYSTEM_SSH_AGENTC_SIGN_REQUEST', 13);
// the SSH1 response is SSH_AGENT_RSA_RESPONSE (4)
define('SYSTEM_SSH_AGENT_SIGN_RESPONSE', 14);
/**#@-*/
/**
* Pure-PHP ssh-agent client identity object
*
* Instantiation should only be performed by System_SSH_Agent class.
* This could be thought of as implementing an interface that 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.
*
* @package System_SSH_Agent
* @author Jim Wigginton <terrafrost@php.net>
* @access internal
*/
class System_SSH_Agent_Identity
{
/**
* Key Object
*
* @var Crypt_RSA
* @access private
* @see System_SSH_Agent_Identity::getPublicKey()
*/
var $key;
/**
* Key Blob
*
* @var String
* @access private
* @see System_SSH_Agent_Identity::sign()
*/
var $key_blob;
/**
* Socket Resource
*
* @var Resource
* @access private
* @see System_SSH_Agent_Identity::sign()
*/
var $fsock;
/**
* Default Constructor.
*
* @param Resource $fsock
* @return System_SSH_Agent_Identity
* @access private
*/
function System_SSH_Agent_Identity($fsock)
{
$this->fsock = $fsock;
}
/**
* Set Public Key
*
* Called by System_SSH_Agent::requestIdentities()
*
* @param Crypt_RSA $key
* @access private
*/
function setPublicKey($key)
{
$this->key = $key;
$this->key->setPublicKey();
}
/**
* Set Public Key
*
* Called by 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
* @access private
*/
function setPublicKeyBlob($key_blob)
{
$this->key_blob = $key_blob;
}
/**
* Get Public Key
*
* Wrapper for $this->key->getPublicKey()
*
* @param Integer $format optional
* @return Mixed
* @access public
*/
function getPublicKey($format = null)
{
return !isset($format) ? $this->key->getPublicKey() : $this->key->getPublicKey($format);
}
/**
* Set Signature Mode
*
* 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 CRYPT_RSA_SIGNATURE_PKCS1
*
* @param Integer $mode
* @access public
*/
function setSignatureMode($mode)
{
}
/**
* Create a signature
*
* See "2.6.2 Protocol 2 private key signature request"
*
* @param String $message
* @return String
* @access public
*/
function sign($message)
{
// 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', SYSTEM_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');
}
$length = current(unpack('N', fread($this->fsock, 4)));
$type = ord(fread($this->fsock, 1));
if ($type != SYSTEM_SSH_AGENT_SIGN_RESPONSE) {
user_error('Unable to retreive signature');
}
$signature_blob = fread($this->fsock, $length - 1);
// the only other signature format defined - ssh-dss - is the same length as ssh-rsa
// the + 12 is for the other various SSH added length fields
return substr($signature_blob, strlen('ssh-rsa') + 12);
}
}
/**
* Pure-PHP ssh-agent client identity factory
*
* requestIdentities() method pumps out System_SSH_Agent_Identity objects
*
* @package System_SSH_Agent
* @author Jim Wigginton <terrafrost@php.net>
* @access internal
*/
class System_SSH_Agent
{
/**
* Socket Resource
*
* @var Resource
* @access private
*/
var $fsock;
/**
* Default Constructor
*
* @return System_SSH_Agent
* @access public
*/
function System_SSH_Agent()
{
switch (true) {
case isset($_SERVER['SSH_AUTH_SOCK']):
$address = $_SERVER['SSH_AUTH_SOCK'];
break;
case isset($_ENV['SSH_AUTH_SOCK']):
$address = $_ENV['SSH_AUTH_SOCK'];
break;
default:
user_error('SSH_AUTH_SOCK not found');
return false;
}
$this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
if (!$this->fsock) {
user_error("Unable to connect to ssh-agent (Error $errno: $errstr)");
}
}
/**
* Request Identities
*
* See "2.5.2 Requesting a list of protocol 2 keys"
* Returns an array containing zero or more System_SSH_Agent_Identity objects
*
* @return Array
* @access public
*/
function requestIdentities()
{
if (!$this->fsock) {
return array();
}
$packet = pack('NC', 1, SYSTEM_SSH_AGENTC_REQUEST_IDENTITIES);
if (strlen($packet) != fputs($this->fsock, $packet)) {
user_error('Connection closed while requesting identities');
}
$length = current(unpack('N', fread($this->fsock, 4)));
$type = ord(fread($this->fsock, 1));
if ($type != SYSTEM_SSH_AGENT_IDENTITIES_ANSWER) {
user_error('Unable to request identities');
}
$identities = array();
$keyCount = current(unpack('N', fread($this->fsock, 4)));
for ($i = 0; $i < $keyCount; $i++) {
$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);
$length = current(unpack('N', substr($key_blob, 0, 4)));
$key_type = substr($key_blob, 4, $length);
switch ($key_type) {
case 'ssh-rsa':
if (!class_exists('Crypt_RSA')) {
include_once 'Crypt/RSA.php';
}
$key = new Crypt_RSA();
$key->loadKey('ssh-rsa ' . base64_encode($key_blob) . ' ' . $key_comment);
break;
case 'ssh-dss':
// not currently supported
break;
}
// resources are passed by reference by default
if (isset($key)) {
$identity = new System_SSH_Agent_Identity($this->fsock);
$identity->setPublicKey($key);
$identity->setPublicKeyBlob($key_blob);
$identities[] = $identity;
unset($key);
}
}
return $identities;
}
}

View File

@@ -0,0 +1,39 @@
<?php
/**
* Pure-PHP ssh-agent client wrapper
*
* PHP versions 4 and 5
*
* Originally System_SSH_Agent was accessed as System/SSH_Agent.php instead of
* System/SSH/Agent.php. The problem with this is that PSR0 compatible autoloaders
* don't support that kind of directory layout hence the package being moved and
* this "alias" being created to maintain backwards compatibility.
*
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @category System
* @package System_SSH_Agent
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2014 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
* @internal See http://api.libssh.org/rfc/PROTOCOL.agent
*/
require_once 'SSH/Agent.php';

View File

@@ -0,0 +1,6 @@
# minimalist openssl.cnf file for use with phpseclib
HOME = .
RANDFILE = $ENV::HOME/.rnd
[ v3_ca ]

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="tests/bootstrap.php"
colors="true"
>
<testsuites>
<testsuite name="phpseclib Unit Test Suite">
<directory>./tests/Unit/</directory>
</testsuite>
<testsuite name="phpseclib Functional Test Suite">
<directory>./tests/Functional/</directory>
</testsuite>
</testsuites>
<!-- Code Coverage -->
<filter>
<whitelist>
<directory>./phpseclib/</directory>
</whitelist>
</filter>
</phpunit>

View File

@@ -0,0 +1,88 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2014 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Functional_Net_SCPSSH2UserStoryTest extends PhpseclibFunctionalTestCase
{
static protected $remoteFile;
static protected $exampleData;
static protected $exampleDataLength;
static public function setUpBeforeClass()
{
parent::setUpBeforeClass();
self::$remoteFile = uniqid('phpseclib-scp-ssh2-') . '.txt';
self::$exampleData = str_repeat('abscp12345', 1000);
self::$exampleDataLength = 10000;
}
public function testConstructSSH2()
{
$ssh = new Net_SSH2($this->getEnv('SSH_HOSTNAME'));
$this->assertTrue(
$ssh->login(
$this->getEnv('SSH_USERNAME'),
$this->getEnv('SSH_PASSWORD')
)
);
return $ssh;
}
/** @depends testConstructSSH2 */
public function testConstructor($ssh)
{
$scp = new Net_SCP($ssh);
$this->assertTrue(
is_object($scp),
'Could not construct Net_SCP object.'
);
return $scp;
}
/** @depends testConstructor */
public function testPutGetString($scp)
{
$this->assertTrue(
$scp->put(self::$remoteFile, self::$exampleData),
'Failed asserting that data could successfully be put() into file.'
);
$content = $scp->get(self::$remoteFile);
// TODO: Address https://github.com/phpseclib/phpseclib/issues/146
$this->assertContains(
strlen($content),
array(self::$exampleDataLength, self::$exampleDataLength + 1),
'Failed asserting that string length matches expected length.'
);
$this->assertContains(
$content,
array(self::$exampleData, self::$exampleData . "\0"),
'Failed asserting that string content matches expected content.'
);
return $scp;
}
/** @depends testPutGetString */
public function testGetFile($scp)
{
$localFilename = $this->createTempFile();
$this->assertTrue(
$scp->get(self::$remoteFile, $localFilename),
'Failed asserting that get() into file was successful.'
);
// TODO: Address https://github.com/phpseclib/phpseclib/issues/146
$this->assertContains(
filesize($localFilename),
array(self::$exampleDataLength, self::$exampleDataLength + 1),
'Failed asserting that filesize matches expected data size.'
);
$this->assertContains(
file_get_contents($localFilename),
array(self::$exampleData, self::$exampleData . "\0"),
'Failed asserting that file content matches expected content.'
);
}
}

View File

@@ -0,0 +1,74 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2014 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
require_once 'Crypt/Base.php';
class Functional_Net_SFTPLargeFileTest extends PhpseclibFunctionalTestCase
{
protected $sftp;
protected $scratchDir;
static public function setUpBeforeClass()
{
if (!extension_loaded('mcrypt')) {
self::markTestSkipped('This test depends on mcrypt for performance.');
}
parent::setUpBeforeClass();
self::ensureConstant('CRYPT_AES_MODE', CRYPT_MODE_MCRYPT);
self::ensureConstant('CRYPT_BLOWFISH_MODE', CRYPT_MODE_MCRYPT);
self::ensureConstant('CRYPT_DES_MODE', CRYPT_MODE_MCRYPT);
self::ensureConstant('CRYPT_RC2_MODE', CRYPT_MODE_MCRYPT);
self::ensureConstant('CRYPT_RC4_MODE', CRYPT_MODE_MCRYPT);
self::ensureConstant('CRYPT_RIJNDAEL_MODE', CRYPT_MODE_MCRYPT);
self::ensureConstant('CRYPT_TWOFISH_MODE', CRYPT_MODE_MCRYPT);
}
public function setUp()
{
$this->scratchDir = uniqid('phpseclib-sftp-large-scratch-');
$this->sftp = new Net_SFTP($this->getEnv('SSH_HOSTNAME'));
$this->assertTrue($this->sftp->login(
$this->getEnv('SSH_USERNAME'),
$this->getEnv('SSH_PASSWORD')
));
$this->assertTrue($this->sftp->mkdir($this->scratchDir));
$this->assertTrue($this->sftp->chdir($this->scratchDir));
}
public function tearDown()
{
if ($this->sftp) {
$this->sftp->chdir($this->getEnv('SSH_HOME'));
$this->sftp->delete($this->scratchDir);
}
parent::tearDown();
}
/**
* @group github298
* @group github455
* @group github457
*/
public function testPutSizeLocalFile()
{
$tmp_filename = $this->createTempFile(128, 1024 * 1024);
$filename = 'file-large-from-local.txt';
$this->assertTrue(
$this->sftp->put($filename, $tmp_filename, NET_SFTP_LOCAL_FILE),
'Failed asserting that local file could be successfully put().'
);
$this->assertSame(
128 * 1024 * 1024,
$this->sftp->size($filename),
'Failed asserting that uploaded local file has the expected length.'
);
}
}

View File

@@ -0,0 +1,478 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2014 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Functional_Net_SFTPUserStoryTest extends PhpseclibFunctionalTestCase
{
static protected $scratchDir;
static protected $exampleData;
static protected $exampleDataLength;
static public function setUpBeforeClass()
{
parent::setUpBeforeClass();
self::$scratchDir = uniqid('phpseclib-sftp-scratch-');
self::$exampleData = str_repeat('abcde12345', 1000);
self::$exampleDataLength = 10000;
}
public function testConstructor()
{
$sftp = new Net_SFTP($this->getEnv('SSH_HOSTNAME'));
$this->assertTrue(
is_object($sftp),
'Could not construct NET_SFTP object.'
);
return $sftp;
}
/**
* @depends testConstructor
*/
public function testPasswordLogin($sftp)
{
$username = $this->getEnv('SSH_USERNAME');
$password = $this->getEnv('SSH_PASSWORD');
$this->assertTrue(
$sftp->login($username, $password),
'SSH2/SFTP login using password failed.'
);
return $sftp;
}
/**
* @depends testPasswordLogin
*/
public function testPwdHome($sftp)
{
$this->assertEquals(
$this->getEnv('SSH_HOME'),
$sftp->pwd(),
'Failed asserting that pwd() returns home directory after login.'
);
return $sftp;
}
/**
* @depends testPwdHome
*/
public function testMkDirScratch($sftp)
{
$dirname = self::$scratchDir;
$this->assertTrue(
$sftp->mkdir($dirname),
"Failed asserting that a new scratch directory $dirname could " .
'be created.'
);
$this->assertFalse(
$sftp->mkdir($dirname),
"Failed asserting that a new scratch directory $dirname could " .
'not be created (because it already exists).'
);
return $sftp;
}
/**
* @depends testMkDirScratch
*/
public function testChDirScratch($sftp)
{
$this->assertTrue(
$sftp->chdir(self::$scratchDir),
sprintf(
'Failed asserting that working directory could be changed ' .
'to scratch directory %s.',
self::$scratchDir
)
);
$pwd = $sftp->pwd();
$this->assertStringStartsWith(
$this->getEnv('SSH_HOME'),
$pwd,
'Failed asserting that the home directory is a prefix of the ' .
'current working directory.'
);
$this->assertStringEndsWith(
self::$scratchDir,
$pwd,
'Failed asserting that the scratch directory name is a suffix ' .
'of the current working directory.'
);
return $sftp;
}
/**
* @depends testChDirScratch
*/
public function testStatOnDir($sftp)
{
$this->assertNotSame(
array(),
$sftp->stat('.'),
'Failed asserting that the cwd has a non-empty stat.'
);
return $sftp;
}
/**
* @depends testStatOnDir
*/
public function testPutSizeGetFile($sftp)
{
$this->assertTrue(
$sftp->put('file1.txt', self::$exampleData),
'Failed asserting that example data could be successfully put().'
);
$this->assertSame(
self::$exampleDataLength,
$sftp->size('file1.txt'),
'Failed asserting that put example data has the expected length'
);
$this->assertSame(
self::$exampleData,
$sftp->get('file1.txt'),
'Failed asserting that get() returns expected example data.'
);
return $sftp;
}
/**
* @depends testPutSizeGetFile
*/
public function testTouch($sftp)
{
$this->assertTrue(
$sftp->touch('file2.txt'),
'Failed asserting that touch() successfully ran.'
);
$this->assertTrue(
$sftp->file_exists('file2.txt'),
'Failed asserting that touch()\'d file exists'
);
return $sftp;
}
/**
* @depends testTouch
*/
public function testTruncate($sftp)
{
$this->assertTrue(
$sftp->touch('file3.txt'),
'Failed asserting that touch() successfully ran.'
);
$this->assertTrue(
$sftp->truncate('file3.txt', 1024 * 1024),
'Failed asserting that touch() successfully ran.'
);
$this->assertSame(
1024 * 1024,
$sftp->size('file3.txt'),
'Failed asserting that truncate()\'d file has the expected length'
);
return $sftp;
}
/**
* @depends testTruncate
*/
public function testChDirOnFile($sftp)
{
$this->assertFalse(
$sftp->chdir('file1.txt'),
'Failed to assert that the cwd cannot be changed to a file'
);
return $sftp;
}
/**
* @depends testChDirOnFile
*/
public function testFileExistsIsFileIsDirFile($sftp)
{
$this->assertTrue(
$sftp->file_exists('file1.txt'),
'Failed asserting that file_exists() on example file returns true.'
);
$this->assertTrue(
$sftp->is_file('file1.txt'),
'Failed asserting that is_file() on example file returns true.'
);
$this->assertFalse(
$sftp->is_dir('file1.txt'),
'Failed asserting that is_dir() on example file returns false.'
);
return $sftp;
}
/**
* @depends testFileExistsIsFileIsDirFile
*/
public function testFileExistsIsFileIsDirFileNonexistent($sftp)
{
$this->assertFalse(
$sftp->file_exists('file4.txt'),
'Failed asserting that a nonexistent file does not exist.'
);
$this->assertFalse(
$sftp->is_file('file4.txt'),
'Failed asserting that is_file() on nonexistent file returns false.'
);
$this->assertFalse(
$sftp->is_dir('file4.txt'),
'Failed asserting that is_dir() on nonexistent file returns false.'
);
return $sftp;
}
/**
* @depends testFileExistsIsFileIsDirFileNonexistent
*/
public function testSortOrder($sftp)
{
$this->assertTrue(
$sftp->mkdir('temp'),
"Failed asserting that a new scratch directory temp could " .
'be created.'
);
$sftp->setListOrder('filename', SORT_DESC);
$list = $sftp->nlist();
$expected = array('.', '..', 'temp', 'file3.txt', 'file2.txt', 'file1.txt');
$this->assertSame(
$list,
$expected,
'Failed asserting that list sorted correctly.'
);
$sftp->setListOrder('filename', SORT_ASC);
$list = $sftp->nlist();
$expected = array('.', '..', 'temp', 'file1.txt', 'file2.txt', 'file3.txt');
$this->assertSame(
$list,
$expected,
'Failed asserting that list sorted correctly.'
);
$sftp->setListOrder('size', SORT_DESC);
$files = $sftp->nlist();
$last_size = 0x7FFFFFFF;
foreach ($files as $file) {
if ($sftp->is_file($file)) {
$cur_size = $sftp->size($file);
$this->assertLessThanOrEqual(
$last_size, $cur_size,
'Failed asserting that nlist() is in descending order'
);
$last_size = $cur_size;
}
}
return $sftp;
}
/**
* @depends testSortOrder
*/
public function testResourceXfer($sftp)
{
$fp = fopen('res.txt', 'w+');
$sftp->get('file1.txt', $fp);
rewind($fp);
$sftp->put('file4.txt', $fp);
fclose($fp);
$this->assertSame(
self::$exampleData,
$sftp->get('file4.txt'),
'Failed asserting that a file downloaded into a resource and reuploaded from a resource has the correct data'
);
return $sftp;
}
/**
* @depends testResourceXfer
*/
public function testSymlink($sftp)
{
$this->assertTrue(
$sftp->symlink('file3.txt', 'symlink'),
'Failed asserting that a symlink could be created'
);
return $sftp;
}
/**
* @depends testSymlink
*/
public function testReadlink($sftp)
{
$this->assertInternalType('string', $sftp->readlink('symlink'),
'Failed asserting that a symlink\'s target could be read'
);
return $sftp;
}
/**
* on older versions this would result in a fatal error
* @depends testReadlink
* @group github402
*/
public function testStatcacheFix($sftp)
{
// Name used for both directory and file.
$name = 'stattestdir';
$this->assertTrue($sftp->mkdir($name));
$this->assertTrue($sftp->is_dir($name));
$this->assertTrue($sftp->chdir($name));
$this->assertStringEndsWith(self::$scratchDir . '/' . $name, $sftp->pwd());
$this->assertFalse($sftp->file_exists($name));
$this->assertTrue($sftp->touch($name));
$this->assertTrue($sftp->is_file($name));
$this->assertTrue($sftp->chdir('..'));
$this->assertStringEndsWith(self::$scratchDir, $sftp->pwd());
$this->assertTrue($sftp->is_dir($name));
$this->assertTrue($sftp->is_file("$name/$name"));
$this->assertTrue($sftp->delete($name, true));
return $sftp;
}
/**
* @depends testStatcacheFix
*/
public function testChDirUpHome($sftp)
{
$this->assertTrue(
$sftp->chdir('../'),
'Failed asserting that directory could be changed one level up.'
);
$this->assertEquals(
$this->getEnv('SSH_HOME'),
$sftp->pwd(),
'Failed asserting that pwd() returns home directory.'
);
return $sftp;
}
/**
* @depends testChDirUpHome
*/
public function testFileExistsIsFileIsDirDir($sftp)
{
$this->assertTrue(
$sftp->file_exists(self::$scratchDir),
'Failed asserting that file_exists() on scratch dir returns true.'
);
$this->assertFalse(
$sftp->is_file(self::$scratchDir),
'Failed asserting that is_file() on example file returns false.'
);
$this->assertTrue(
$sftp->is_dir(self::$scratchDir),
'Failed asserting that is_dir() on example file returns true.'
);
return $sftp;
}
/**
* @depends testFileExistsIsFileIsDirDir
*/
public function testTruncateLargeFile($sftp)
{
$filesize = (4 * 1024 + 16) * 1024 * 1024;
$filename = 'file-large-from-truncate-4112MiB.txt';
$this->assertTrue($sftp->touch($filename));
$this->assertTrue($sftp->truncate($filename, $filesize));
$this->assertSame($filesize, $sftp->size($filename));
return $sftp;
}
/**
* @depends testTruncateLargeFile
*/
public function testRmDirScratch($sftp)
{
$this->assertFalse(
$sftp->rmdir(self::$scratchDir),
'Failed asserting that non-empty scratch directory could ' .
'not be deleted using rmdir().'
);
return $sftp;
}
/**
* @depends testRmDirScratch
*/
public function testDeleteRecursiveScratch($sftp)
{
$this->assertTrue(
$sftp->delete(self::$scratchDir),
'Failed asserting that non-empty scratch directory could ' .
'be deleted using recursive delete().'
);
return $sftp;
}
/**
* @depends testDeleteRecursiveScratch
*/
public function testRmDirScratchNonexistent($sftp)
{
$this->assertFalse(
$sftp->rmdir(self::$scratchDir),
'Failed asserting that nonexistent scratch directory could ' .
'not be deleted using rmdir().'
);
}
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2014 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Functional_Net_SSH2AgentTest extends PhpseclibFunctionalTestCase
{
public static function setUpBeforeClass()
{
if (!isset($_SERVER['SSH_AUTH_SOCK'])) {
self::markTestSkipped(
'This test requires an SSH Agent (SSH_AUTH_SOCK env variable).'
);
}
parent::setUpBeforeClass();
}
public function testAgentLogin()
{
$ssh = new Net_SSH2($this->getEnv('SSH_HOSTNAME'));
$agent = new System_SSH_Agent;
$this->assertTrue(
$ssh->login($this->getEnv('SSH_USERNAME'), $agent),
'SSH2 login using Agent failed.'
);
}
}

View File

@@ -0,0 +1,88 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2014 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Functional_Net_SSH2Test extends PhpseclibFunctionalTestCase
{
public function testConstructor()
{
$ssh = new Net_SSH2($this->getEnv('SSH_HOSTNAME'));
$this->assertTrue(
is_object($ssh),
'Could not construct NET_SSH2 object.'
);
return $ssh;
}
/**
* @depends testConstructor
* @group github408
* @group github412
*/
public function testPreLogin($ssh)
{
$this->assertFalse(
$ssh->isConnected(),
'Failed asserting that SSH2 is not connected after construction.'
);
$this->assertNotEmpty(
$ssh->getServerPublicHostKey(),
'Failed asserting that a non-empty public host key was fetched.'
);
$this->assertTrue(
$ssh->isConnected(),
'Failed asserting that SSH2 is connected after public key fetch.'
);
$this->assertNotEmpty(
$ssh->getServerIdentification(),
'Failed asserting that the server identifier was set after connect.'
);
return $ssh;
}
/**
* @depends testPreLogin
*/
public function testPasswordLogin($ssh)
{
$username = $this->getEnv('SSH_USERNAME');
$password = $this->getEnv('SSH_PASSWORD');
$this->assertTrue(
$ssh->login($username, $password),
'SSH2 login using password failed.'
);
return $ssh;
}
/**
* @depends testPasswordLogin
* @group github280
*/
public function testExecWithMethodCallback($ssh)
{
$callbackObject = $this->getMock('stdClass', array('callbackMethod'));
$callbackObject
->expects($this->atLeastOnce())
->method('callbackMethod')
->will($this->returnValue(true));
$ssh->exec('pwd', array($callbackObject, 'callbackMethod'));
}
public function testGetServerPublicHostKey()
{
$ssh = new Net_SSH2($this->getEnv('SSH_HOSTNAME'));
$this->assertInternalType('string', $ssh->getServerPublicHostKey());
}
}

View File

@@ -0,0 +1,72 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2014 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
abstract class PhpseclibFunctionalTestCase extends PhpseclibTestCase
{
static public function setUpBeforeClass()
{
if (extension_loaded('runkit')) {
if (extension_loaded('gmp')) {
self::ensureConstant(
'MATH_BIGINTEGER_MODE',
MATH_BIGINTEGER_MODE_GMP
);
} elseif (extension_loaded('bcmath')) {
self::ensureConstant(
'MATH_BIGINTEGER_MODE',
MATH_BIGINTEGER_MODE_BCMATH
);
} else {
self::markTestSkipped(
'Should have gmp or bcmath extension for functional test.'
);
}
self::ensureConstant('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
self::reRequireFile('Math/BigInteger.php');
self::reRequireFile('Crypt/Hash.php');
}
parent::setUpBeforeClass();
}
/**
* @param string $variable
* @param string|null $message
*
* @return null
*/
protected function requireEnv($variable, $message = null)
{
if ($this->_getEnv($variable) === false) {
$msg = $message ? $message : sprintf(
"This test requires the '%s' environment variable.",
$this->_prefixEnvVariable($variable)
);
$this->markTestSkipped($msg);
}
}
/**
* @param string $variable
*
* @return string
*/
protected function getEnv($variable)
{
$this->requireEnv($variable);
return $this->_getEnv($variable);
}
private function _getEnv($variable)
{
return getenv($this->_prefixEnvVariable($variable));
}
private function _prefixEnvVariable($variable)
{
return 'PHPSECLIB_' . $variable;
}
}

View File

@@ -0,0 +1,104 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2013 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
abstract class PhpseclibTestCase extends PHPUnit_Framework_TestCase
{
protected $tempFilesToUnlinkOnTearDown = array();
public function tearDown()
{
foreach ($this->tempFilesToUnlinkOnTearDown as $filename) {
if (!file_exists($filename) || unlink($filename)) {
unset($this->tempFilesToUnlinkOnTearDown[$filename]);
}
}
parent::tearDown();
}
/**
* Creates a temporary file on the local filesystem and returns its path.
* The $number_of_writes and $bytes_per_write parameters can be used to
* write $number_of_writes * $bytes_per_write times the character 'a' to the
* temporary file. All files created using this method will be deleted from
* the filesystem on tearDown(), i.e. after each test method was run.
*
* @param int $number_of_writes
* @param int $bytes_per_write
*
* @return string
*/
protected function createTempFile($number_of_writes = 0, $bytes_per_write = 0)
{
$filename = tempnam(sys_get_temp_dir(), 'phpseclib-test-');
$this->assertTrue(file_exists($filename));
$this->tempFilesToUnlinkOnTearDown[] = $filename;
if ($number_of_writes > 0 && $bytes_per_write > 0) {
$fp = fopen($filename, 'wb');
for ($i = 0; $i < $number_of_writes; ++$i) {
fwrite($fp, str_repeat('a', $bytes_per_write));
}
fclose($fp);
$this->assertSame($number_of_writes * $bytes_per_write, filesize($filename));
}
return $filename;
}
/**
* @param string $constant
* @param mixed $expected
*
* @return null
*/
static protected function ensureConstant($constant, $expected)
{
if (defined($constant)) {
$value = constant($constant);
if ($value !== $expected) {
if (function_exists('runkit_constant_redefine')) {
if (!runkit_constant_redefine($constant, $expected)) {
self::markTestSkipped(sprintf(
"Failed to redefine constant %s to %s",
$constant,
$expected
));
}
} else {
self::markTestSkipped(sprintf(
"Skipping test because constant %s is %s instead of %s",
$constant,
$value,
$expected
));
}
}
} else {
define($constant, $expected);
}
}
/**
* @param string $filename
*
* @return null
*/
static protected function reRequireFile($filename)
{
if (function_exists('runkit_import')) {
$result = runkit_import(
$filename,
RUNKIT_IMPORT_FUNCTIONS |
RUNKIT_IMPORT_CLASS_METHODS |
RUNKIT_IMPORT_OVERRIDE
);
if (!$result) {
self::markTestSkipped("Failed to reimport file $filename");
}
}
}
}

View File

@@ -0,0 +1,17 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2013 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Unit_Crypt_AES_InternalTest extends Unit_Crypt_AES_TestCase
{
static public function setUpBeforeClass()
{
parent::setUpBeforeClass();
self::ensureConstant('CRYPT_AES_MODE', CRYPT_AES_MODE_INTERNAL);
self::ensureConstant('CRYPT_RIJNDAEL_MODE', CRYPT_RIJNDAEL_MODE_INTERNAL);
}
}

View File

@@ -0,0 +1,21 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2013 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Unit_Crypt_AES_McryptTest extends Unit_Crypt_AES_TestCase
{
static public function setUpBeforeClass()
{
if (!extension_loaded('mcrypt')) {
self::markTestSkipped('mcrypt extension is not available.');
}
parent::setUpBeforeClass();
self::ensureConstant('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);
self::ensureConstant('CRYPT_RIJNDAEL_MODE', CRYPT_RIJNDAEL_MODE_MCRYPT);
}
}

View File

@@ -0,0 +1,107 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2013 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
require_once 'Crypt/AES.php';
abstract class Unit_Crypt_AES_TestCase extends PhpseclibTestCase
{
static public function setUpBeforeClass()
{
parent::setUpBeforeClass();
self::reRequireFile('Crypt/Rijndael.php');
self::reRequireFile('Crypt/AES.php');
}
/**
* Produces all combinations of test values.
*
* @return array
*/
public function continuousBufferCombos()
{
$modes = array(
'CRYPT_AES_MODE_CTR',
'CRYPT_AES_MODE_OFB',
'CRYPT_AES_MODE_CFB',
);
$plaintexts = array(
'',
'12345678901234567', // https://github.com/phpseclib/phpseclib/issues/39
"\xDE\xAD\xBE\xAF",
':-):-):-):-):-):-)', // https://github.com/phpseclib/phpseclib/pull/43
);
$ivs = array(
'',
'test123',
);
$keys = array(
'',
':-8', // https://github.com/phpseclib/phpseclib/pull/43
'FOOBARZ',
);
$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
return $result;
}
/**
* @dataProvider continuousBufferCombos
*/
public function testEncryptDecryptWithContinuousBuffer($mode, $plaintext, $iv, $key)
{
$aes = new Crypt_AES(constant($mode));
$aes->enableContinuousBuffer();
$aes->setIV($iv);
$aes->setKey($key);
$actual = '';
for ($i = 0, $strlen = strlen($plaintext); $i < $strlen; ++$i) {
$actual .= $aes->decrypt($aes->encrypt($plaintext[$i]));
}
$this->assertEquals($plaintext, $actual);
}
/**
* @group github451
*/
public function testKeyPaddingRijndael()
{
// 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 Crypt_Rijndael();
$aes->disablePadding();
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. Valid in Rijndael.
$ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734'));
$this->assertEquals($ciphertext, pack('H*', '231d844639b31b412211cfe93712b880'));
}
/**
* @group github451
*/
public function testKeyPaddingAES()
{
// same as the above - just with a different ciphertext
$aes = new Crypt_AES();
$aes->disablePadding();
$aes->setKey(pack('H*', '2b7e151628aed2a6abf7158809cf4f3c762e7160')); // 160-bit key. AES should null pad to 192-bits
$ciphertext = $aes->encrypt(pack('H*', '3243f6a8885a308d313198a2e0370734'));
$this->assertEquals($ciphertext, pack('H*', 'c109292b173f841b88e0ee49f13db8c0'));
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2012 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Unit_Crypt_Hash_MD5Test extends Unit_Crypt_Hash_TestCase
{
public function getInstance()
{
return new Crypt_Hash('md5');
}
/**
* @dataProvider hashData()
*/
public function testHash($message, $result)
{
$this->assertHashesTo($this->getInstance(), $message, $result);
}
static public 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);
}
static public function hmacData()
{
return array(
array('', '', '74e6f7298a9c2d168935f58c001bad88'),
array('key', 'The quick brown fox jumps over the lazy dog', '80070713463e7749b90c2dc24911e275'),
);
}
}

View File

@@ -0,0 +1,79 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2014 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Unit_Crypt_Hash_SHA256Test extends Unit_Crypt_Hash_TestCase
{
public function getInstance()
{
return new Crypt_Hash('sha256');
}
/**
* @dataProvider hashData()
*/
public function testHash($message, $result)
{
$this->assertHashesTo($this->getInstance(), $message, $result);
}
static public 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);
}
static public function hmacData()
{
return array(
// RFC 4231
// Test Case 1
array(
pack('H*', '0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b'),
pack('H*', '4869205468657265'),
'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7',
),
// Test Case 2
array(
pack('H*', '4a656665'),
pack('H*', '7768617420646f2079612077616e7420666f72206e6f7468696e673f'),
'5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843',
),
// Test Case 3
array(
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
pack('H*', 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd'),
'773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe',
),
// Test Case 4
array(
pack('H*', '0102030405060708090a0b0c0d0e0f10111213141516171819'),
pack('H*', 'cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd'),
'82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b',
),
);
}
}

View File

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

View File

@@ -0,0 +1,79 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2014 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Unit_Crypt_Hash_SHA512Test extends Unit_Crypt_Hash_TestCase
{
public function getInstance()
{
return new Crypt_Hash('sha512');
}
/**
* @dataProvider hashData()
*/
public function testHash($message, $result)
{
$this->assertHashesTo($this->getInstance(), $message, $result);
}
static public 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);
}
static public function hmacData()
{
return array(
// RFC 4231
// Test Case 1
array(
pack('H*', '0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b'),
pack('H*', '4869205468657265'),
'87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854',
),
// Test Case 2
array(
pack('H*', '4a656665'),
pack('H*', '7768617420646f2079612077616e7420666f72206e6f7468696e673f'),
'164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737',
),
// Test Case 3
array(
pack('H*', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
pack('H*', 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd'),
'fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb',
),
// Test Case 4
array(
pack('H*', '0102030405060708090a0b0c0d0e0f10111213141516171819'),
pack('H*', 'cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd'),
'b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd',
),
);
}
}

View File

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

View File

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

View File

@@ -0,0 +1,304 @@
<?php
/**
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2013 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
require_once 'Crypt/RSA.php' ;
class Unit_Crypt_RSA_LoadKeyTest extends PhpseclibTestCase
{
public function testBadKey()
{
$rsa = new Crypt_RSA();
$key = 'zzzzzzzzzzzzzz';
$this->assertFalse($rsa->loadKey($key));
}
public function testPKCS1Key()
{
$rsa = new Crypt_RSA();
$key = '-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----';
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPrivateKey());
}
public function testPKCS1SpacesKey()
{
$rsa = new Crypt_RSA();
$key = '-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----';
$key = str_replace(array("\r", "\n", "\r\n"), ' ', $key);
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPrivateKey());
}
public function testPKCS1NoHeaderKey()
{
$rsa = new Crypt_RSA();
$key = 'MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPrivateKey());
}
public function testPKCS1NoWhitespaceNoHeaderKey()
{
$rsa = new Crypt_RSA();
$key = 'MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp' .
'wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5' .
'1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh' .
'3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2' .
'pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX' .
'GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il' .
'AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF' .
'L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k' .
'X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl' .
'U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ' .
'37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPrivateKey());
}
public function testRawPKCS1Key()
{
$rsa = new Crypt_RSA();
$key = 'MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp' .
'wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5' .
'1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh' .
'3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2' .
'pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX' .
'GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il' .
'AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF' .
'L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k' .
'X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl' .
'U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ' .
'37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=';
$key = base64_decode($key);
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPrivateKey());
}
public function testLoadPKCS8PrivateKey()
{
$rsa = new Crypt_RSA();
$rsa->setPassword('password');
$key = '-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIE6TAbBgkqhkiG9w0BBQMwDgQIcWWgZeQYPTcCAggABIIEyLoa5b3ktcPmy4VB
hHkpHzVSEsKJPmQTUaQvUwIp6+hYZeuOk78EPehrYJ/QezwJRdyBoD51oOxqWCE2
fZ5Wf6Mi/9NIuPyqQccP2ouErcMAcDLaAx9C0Ot37yoG0S6hOZgaxqwnCdGYKHgS
7cYUv40kLOJmTOJlHJbatfXHocrHcHkCBJ1q8wApA1KVQIZsqmyBUBuwbrfFwpC9
d/R674XxCWJpXvU63VNZRFYUvd7YEWCrdSeleb99p0Vn1kxI5463PXurgs/7GPiO
SLSdX44DESP9l7lXenC4gbuT8P0xQRDzGrB5l9HHoV3KMXFODWTMnLcp1nuhA0OT
fPS2yzT9zJgqHiVKWgcUUJ5uDelVfnsmDhnh428p0GBFbniH07qREC9kq78UqQNI
Kybp4jQ4sPs64zdYm/VyLWtAYz8QNAKHLcnPwmTPr/XlJmox8rlQhuSQTK8E+lDr
TOKpydrijN3lF+pgyUuUj6Ha8TLMcOOwqcrpBig4SGYoB56gjAO0yTE9uCPdBakj
yxi3ksn51ErigGM2pGMNcVdwkpJ/x+DEBBO0auy3t9xqM6LK8pwNcOT1EWO+16zY
79LVSavc49t+XxMc3Xasz/G5xQgD1FBp6pEnsg5JhTTG/ih6Y/DQD8z3prjC3qKc
rpL4NA9KBI/IF1iIXlrfmN/zCKbBuEOEGqwcHBDHPySZbhL2XLSpGcK/NBl1bo1Z
G+2nUTauoC67Qb0+fnzTcvOiMNAbHMiqkirs4anHX33MKL2gR/3dp8ca9hhWWXZz
Mkk2FK9sC/ord9F6mTtvTiOSDzpiEhb94uTxXqBhIbsrGXCUUd0QQN5s2dmW2MfS
M35KeSv2rwDGzC1+Qf3MhHGIZDqoQwuZEzM5yHHafCatAbZd2sjaFWegg0r2ca7a
eZkZFj3ZuDYXJFnL82guOASh7rElWO2Ys7ncXAKnaV3WkkF+JDv/CUHr+Q/h6Ae5
qEvgubTCVSYHzRP37XJItlcdywTIcTY+t6jymmyEBJ66LmUoD47gt/vDUSbhT6Oa
GlcZ+MZGlUnPOSq4YknOgwKH8izboY4UgVCrmXvlaZYQhZemNDkVbpYVDf+s6cPf
tJwVoZf+qf2SsRTUsI10isoIzCyGw2ie8kmipdP434Z/99uVU3zxD6raNDlyp33q
FWMgpr2JU6NVAla7N51g7Jk8VjIIn7SvCYyWkmvv4kLB1UHl3NFqYb9YuIZUaDyt
j/NMcKMLLOaEorRZ2N2mDNoihMxMf8J3J9APnzUigAtaalGKNOrd2Fom5OVADePv
Tb5sg1uVQzfcpFrjIlLVh+2cekX0JM84phbMpHmm5vCjjfYvUvcMy0clCf0x3jz6
LZf5Fzc8xbZmpse5OnOrsDLCNh+SlcYOzsagSZq4TgvSeI9Tr4lv48dLJHCCcYKL
eymS9nhlCFuuHbi7zI7edcI49wKUW1Sj+kvKq3LMIEkMlgzqGKA6JqSVxHP51VH5
FqV4aKq70H6dNJ43bLVRPhtF5Bip5P7k/6KIsGTPUd54PHey+DuWRjitfheL0G2w
GF/qoZyC1mbqdtyyeWgHtVbJVUORmpbNnXOII9duEqBUNDiO9VSZNn/8h/VsYeAB
xryZaRDVmtMuf/OZBQ==
-----END ENCRYPTED PRIVATE KEY-----';
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPrivateKey());
}
public function testSavePKCS8PrivateKey()
{
$rsa = new Crypt_RSA();
$key = '-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----';
$rsa->setPassword('password');
$this->assertTrue($rsa->loadKey($key));
$key = $rsa->getPrivateKey(CRYPT_RSA_PRIVATE_FORMAT_PKCS8);
$this->assertInternalType('string', $key);
$this->assertTrue($rsa->loadKey($key));
}
public function testPubKey1()
{
$rsa = new Crypt_RSA();
$key = '-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa
D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw
luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB
o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV
gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
-----END RSA PUBLIC KEY-----';
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPublicKey());
$this->assertFalse($rsa->getPrivateKey());
}
public function testPubKey2()
{
$rsa = new Crypt_RSA();
$key = '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61BjmfXGEvWmegnBGSuS
+rU9soUg2FnODva32D1AqhwdziwHINFaD1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBS
EVCgJjtHAGZIm5GL/KA86KDp/CwDFMSwluowcXwDwoyinmeOY9eKyh6aY72xJh7n
oLBBq1N0bWi1e2i+83txOCg4yV2oVXhBo8pYEJ8LT3el6Smxol3C1oFMVdwPgc0v
Tl25XucMcG/ALE/KNY6pqC2AQ6R2ERlVgPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeu
lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26
ZQIDAQAB
-----END PUBLIC KEY-----';
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPublicKey());
$this->assertFalse($rsa->getPrivateKey());
}
public function testSSHPubKey()
{
$rsa = new Crypt_RSA();
$key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4e' .
'CZ0FPqri0cb2JZfXJ/DgYSF6vUpwmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMS' .
'GkVb1/3j+skZ6UtW+5u09lHNsj6tQ51s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZw== ' .
'phpseclib-generated-key';
$this->assertTrue($rsa->loadKey($key));
$this->assertInternalType('string', $rsa->getPublicKey());
$this->assertFalse($rsa->getPrivateKey());
}
public function testSetPrivate()
{
$rsa = new Crypt_RSA();
$key = '-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa
D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw
luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB
o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV
gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
-----END RSA PUBLIC KEY-----';
$this->assertTrue($rsa->loadKey($key));
$this->assertTrue($rsa->setPrivateKey());
$this->assertGreaterThanOrEqual(1, strlen("$rsa"));
$this->assertFalse($rsa->getPublicKey());
}
/**
* make phpseclib generated XML keys be unsigned. this may need to be reverted
* if it is later learned that XML keys are, in fact, supposed to be signed
* @group github468
*/
public function testUnsignedXML()
{
$rsa = new Crypt_RSA();
$key = '<RSAKeyValue>
<Modulus>v5OxcEgxPUfa701NpxnScCmlRkbwSGBiTWobHkIWZEB+AlRTHaVoZg/D8l6YzR7VdQidG6gF+nuUMjY75dBXgY/XcyVq0Hccf1jTfgARuNuq4GGG3hnCJVi2QsOgcf9R7TeXn+p1RKIhjQoWCiEQeEBTotNbJhcabNcPGSEJw+s=</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>';
$rsa->loadKey($key);
$rsa->setPublicKey();
$newkey = $rsa->getPublicKey(CRYPT_RSA_PUBLIC_FORMAT_XML);
$this->assertSame(preg_replace('#\s#', '', $key), preg_replace('#\s#', '', $newkey));
}
/**
* @group github468
*/
public function testSignedPKCS1()
{
$rsa = new Crypt_RSA();
$key = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/k7FwSDE9R9rvTU2nGdJwKaVG
RvBIYGJNahseQhZkQH4CVFMdpWhmD8PyXpjNHtV1CJ0bqAX6e5QyNjvl0FeBj9dz
JWrQdxx/WNN+ABG426rgYYbeGcIlWLZCw6Bx/1HtN5ef6nVEoiGNChYKIRB4QFOi
01smFxps1w8ZIQnD6wIDAQAB
-----END PUBLIC KEY-----';
$rsa->loadKey($key);
$rsa->setPublicKey();
$newkey = $rsa->getPublicKey();
$this->assertSame(preg_replace('#\s#', '', $key), preg_replace('#\s#', '', $newkey));
}
}

View File

@@ -0,0 +1,53 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2014 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Unit_Crypt_RandomTest extends PhpseclibTestCase
{
public function stringLengthData()
{
return array_map(array($this, 'wrap'), array(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 17, 19, 20, 23, 29, 31, 37,
41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 111, 128, 1000,
1024, 10000, 12345, 100000, 123456
));
}
/** @dataProvider stringLengthData */
public function testStringLength($length)
{
$this->assertSame(
$length,
strlen(crypt_random_string($length)),
'Failed asserting that a string of expected length was generated.'
);
}
/**
* Takes a set of random values of length 128 bits and asserts all taken
* values are unique.
*/
public function testStringUniqueness()
{
$values = array();
for ($i = 0; $i < 10000; ++$i) {
$rand = crypt_random_string(16);
$this->assertSame(16, strlen($rand));
$this->assertArrayNotHasKey(
$rand,
$values,
'Failed asserting that generated value does not exist in set.'
);
$values[$rand] = true;
}
}
protected function wrap($x)
{
// array() is not a function, but $this->wrap() is.
return array($x);
}
}

Binary file not shown.

View File

@@ -0,0 +1,292 @@
<?php
/**
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2014 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
require_once 'File/ASN1.php';
class Unit_File_ASN1Test extends PhpseclibTestCase
{
/**
* on older versions of File_ASN1 this would yield a PHP Warning
* @group github275
*/
public function testAnyString()
{
$KDC_REP = array(
'type' => FILE_ASN1_TYPE_SEQUENCE,
'children' => array(
'pvno' => array(
'constant' => 0,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_ANY),
'msg-type' => array(
'constant' => 1,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_ANY),
'padata' => array(
'constant' => 2,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_ANY),
'crealm' => array(
'constant' => 3,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_ANY),
'cname' => array(
'constant' => 4,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_ANY),
'ticket' => array(
'constant' => 5,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_ANY),
'enc-part' => array(
'constant' => 6,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_ANY)
)
);
$AS_REP = array(
'class' => FILE_ASN1_CLASS_APPLICATION,
'cast' => 11,
'optional' => true,
'explicit' => true
) + $KDC_REP;
$str = 'a4IC3jCCAtqgAwIBBaEDAgELoi8wLTAroQMCAROiJAQiMCAwHqADAgEXoRcbFUNSRUFUVUlUWS5ORVR0ZXN0dXNlcqMPGw' .
'1DUkVBVFVJVFkuTkVUpBUwE6ADAgEBoQwwChsIdGVzdHVzZXKlggFOYYIBSjCCAUagAwIBBaEPGw1DUkVBVFVJVFkuTkVU' .
'oiIwIKADAgECoRkwFxsGa3JidGd0Gw1DUkVBVFVJVFkuTkVUo4IBCDCCAQSgAwIBF6EDAgEBooH3BIH0AQlxgm/j4z74Ki' .
'GsJJnROhh8JAiN7pdvlnkxCYKdG6UgdfK/K0NZ+yz+Xg4kgFO1cQ4XYT4Fm3MTmOHzlFmbzlVkUqBI/RnWA9YTREC9Q7Mf' .
'PPYfRxRG/C6FlahxHCOKj9GUj7bXg7Oq3Sm+QsKTS2bZT05biNf1s7tPCkdIOO0AAd7hvTCpTNAKl+OLN4cpA6pwwk5c3h' .
'58Ce5/Uri5yBmrfwgkCD5AJUAI/WH56SEEvpifLc6C96w/7y2krAiZm5PyEO0HVhTzUjKGSHoSMb+Z3HI/ul+G9z0Z4qDu' .
'NjvgP0jKdrKiwWN00NjpiQ0byZd4y6aCASEwggEdoAMCAReiggEUBIIBEHyi8DIbdcfw2DpniBJ3Sh8dDaEbQx+gWx3omC' .
'TBEyts4sQGTwgQcqkWfeer8M+SkZs/GGZq2YYkyeF+9b6TxlYuX145NuB3KcyzaS7VNrX37E5nGgG8K6r5gTFOhLCqsjjv' .
'gPXXqLeJo5D1nV+c8BPIEVsu/bbBPgSqpDwUs2mX1WkEg5vfb7kZMC8+LHiRy+sItvIiTtxxEsQ/GEF/ono3hZrEnDa/C+' .
'4P3wep6uNMLnLzXJmUaAMaopjE+MOcai/t6T9Vg4pERF5Waqwg5ibAbVGK19HuS4LiKiaY3JsyYBuNkEDwiqM7i1Ekw3V+' .
'+zoEIxqgXjGgPdrWkzU/H6rnXiqMtiZZqUXwWY0zkCmy';
$asn1 = new File_ASN1();
$decoded = $asn1->decodeBER(base64_decode($str));
$result = $asn1->asn1map($decoded[0], $AS_REP);
$this->assertInternalType('array', $result);
}
/**
* on older versions of File_ASN1 this would produce a null instead of an array
* @group github275
*/
public function testIncorrectString()
{
$PA_DATA = array(
'type' => FILE_ASN1_TYPE_SEQUENCE,
'children' => array(
'padata-type' => array(
'constant' => 1,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_INTEGER
),
'padata-value' => array(
'constant' => 2,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_OCTET_STRING
)
)
);
$PrincipalName = array(
'type' => FILE_ASN1_TYPE_SEQUENCE,
'children' => array(
'name-type' => array(
'constant' => 0,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_INTEGER
),
'name-string' => array(
'constant' => 1,
'optional' => true,
'explicit' => true,
'min' => 0,
'max' => -1,
'type' => FILE_ASN1_TYPE_SEQUENCE,
'children' => array('type' => FILE_ASN1_TYPE_IA5_STRING) // should be FILE_ASN1_TYPE_GENERAL_STRING
)
)
);
$Ticket = array(
'class' => FILE_ASN1_CLASS_APPLICATION,
'cast' => 1,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_SEQUENCE,
'children' => array(
'tkt-vno' => array(
'constant' => 0,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_INTEGER
),
'realm' => array(
'constant' => 1,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_ANY
),
'sname' => array(
'constant' => 2,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_ANY
),
'enc-part' => array(
'constant' => 3,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_ANY
)
)
);
$KDC_REP = array(
'type' => FILE_ASN1_TYPE_SEQUENCE,
'children' => array(
'pvno' => array(
'constant' => 0,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_INTEGER),
'msg-type' => array(
'constant' => 1,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_INTEGER),
'padata' => array(
'constant' => 2,
'optional' => true,
'explicit' => true,
'min' => 0,
'max' => -1,
'type' => FILE_ASN1_TYPE_SEQUENCE,
'children' => $PA_DATA),
'crealm' => array(
'constant' => 3,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_OCTET_STRING),
'cname' => array(
'constant' => 4,
'optional' => true,
'explicit' => true) + $PrincipalName,
//'type' => FILE_ASN1_TYPE_ANY),
'ticket' => array(
'constant' => 5,
'optional' => true,
'implicit' => true,
'min' => 0,
'max' => 1,
'type' => FILE_ASN1_TYPE_SEQUENCE,
'children' => $Ticket),
'enc-part' => array(
'constant' => 6,
'optional' => true,
'explicit' => true,
'type' => FILE_ASN1_TYPE_ANY)
)
);
$AS_REP = array(
'class' => FILE_ASN1_CLASS_APPLICATION,
'cast' => 11,
'optional' => true,
'explicit' => true
) + $KDC_REP;
$str = 'a4IC3jCCAtqgAwIBBaEDAgELoi8wLTAroQMCAROiJAQiMCAwHqADAgEXoRcbFUNSRUFUVUlUWS5ORVR0ZXN0dXNlcqMPGw' .
'1DUkVBVFVJVFkuTkVUpBUwE6ADAgEBoQwwChsIdGVzdHVzZXKlggFOYYIBSjCCAUagAwIBBaEPGw1DUkVBVFVJVFkuTkVU' .
'oiIwIKADAgECoRkwFxsGa3JidGd0Gw1DUkVBVFVJVFkuTkVUo4IBCDCCAQSgAwIBF6EDAgEBooH3BIH0AQlxgm/j4z74Ki' .
'GsJJnROhh8JAiN7pdvlnkxCYKdG6UgdfK/K0NZ+yz+Xg4kgFO1cQ4XYT4Fm3MTmOHzlFmbzlVkUqBI/RnWA9YTREC9Q7Mf' .
'PPYfRxRG/C6FlahxHCOKj9GUj7bXg7Oq3Sm+QsKTS2bZT05biNf1s7tPCkdIOO0AAd7hvTCpTNAKl+OLN4cpA6pwwk5c3h' .
'58Ce5/Uri5yBmrfwgkCD5AJUAI/WH56SEEvpifLc6C96w/7y2krAiZm5PyEO0HVhTzUjKGSHoSMb+Z3HI/ul+G9z0Z4qDu' .
'NjvgP0jKdrKiwWN00NjpiQ0byZd4y6aCASEwggEdoAMCAReiggEUBIIBEHyi8DIbdcfw2DpniBJ3Sh8dDaEbQx+gWx3omC' .
'TBEyts4sQGTwgQcqkWfeer8M+SkZs/GGZq2YYkyeF+9b6TxlYuX145NuB3KcyzaS7VNrX37E5nGgG8K6r5gTFOhLCqsjjv' .
'gPXXqLeJo5D1nV+c8BPIEVsu/bbBPgSqpDwUs2mX1WkEg5vfb7kZMC8+LHiRy+sItvIiTtxxEsQ/GEF/ono3hZrEnDa/C+' .
'4P3wep6uNMLnLzXJmUaAMaopjE+MOcai/t6T9Vg4pERF5Waqwg5ibAbVGK19HuS4LiKiaY3JsyYBuNkEDwiqM7i1Ekw3V+' .
'+zoEIxqgXjGgPdrWkzU/H6rnXiqMtiZZqUXwWY0zkCmy';
$asn1 = new File_ASN1();
$decoded = $asn1->decodeBER(base64_decode($str));
$result = $asn1->asn1map($decoded[0], $AS_REP);
$this->assertInternalType('array', $result);
}
/**
* older versions of File_ASN1 didn't handle indefinite length tags very well
*/
public function testIndefiniteLength()
{
$asn1 = new File_ASN1();
$decoded = $asn1->decodeBER(file_get_contents(dirname(__FILE__) . '/ASN1/FE.pdf.p7m'));
$this->assertCount(5, $decoded[0]['content'][1]['content'][0]['content']); // older versions would have returned 3
}
public function testDefiniteLength()
{
// the following base64-encoded string is the X.509 cert from <http://phpseclib.sourceforge.net/x509/decoder.php>
$str = 'MIIDITCCAoqgAwIBAgIQT52W2WawmStUwpV8tBV9TTANBgkqhkiG9w0BAQUFADBM' .
'MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg' .
'THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0xMTEwMjYwMDAwMDBaFw0x' .
'MzA5MzAyMzU5NTlaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh' .
'MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRcw' .
'FQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC' .
'gYEA3rcmQ6aZhc04pxUJuc8PycNVjIjujI0oJyRLKl6g2Bb6YRhLz21ggNM1QDJy' .
'wI8S2OVOj7my9tkVXlqGMaO6hqpryNlxjMzNJxMenUJdOPanrO/6YvMYgdQkRn8B' .
'd3zGKokUmbuYOR2oGfs5AER9G5RqeC1prcB6LPrQ2iASmNMCAwEAAaOB5zCB5DAM' .
'BgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwudGhhd3Rl' .
'LmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYIKwYBBQUHAwEGCCsGAQUF' .
'BwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzABhhZodHRw' .
'Oi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0' .
'ZS5jb20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUF' .
'AAOBgQAhrNWuyjSJWsKrUtKyNGadeqvu5nzVfsJcKLt0AMkQH0IT/GmKHiSgAgDp' .
'ulvKGQSy068Bsn5fFNum21K5mvMSf3yinDtvmX3qUA12IxL/92ZzKbeVCq3Yi7Le' .
'IOkKcGQRCMha8X2e7GmlpdWC1ycenlbN0nbVeSv3JUMcafC4+Q==';
$asn1 = new File_ASN1();
$decoded = $asn1->decodeBER(base64_decode($str));
$this->assertCount(3, $decoded[0]['content']);
}
/**
* @group github477
*/
public function testContextSpecificNonConstructed()
{
$asn1 = new File_ASN1();
$decoded = $asn1->decodeBER(base64_decode('MBaAFJtUo7c00HsI5EPZ4bkICfkOY2Pv'));
$this->assertInternalType('string', $decoded[0]['content'][0]['content']);
}
/**
* @group github602
*/
public function testEmptyContextTag()
{
$asn1 = new File_ASN1();
$decoded = $asn1->decodeBER("\xa0\x00");
$this->assertInternalType('array', $decoded);
$this->assertCount(0, $decoded[0]['content']);
}
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2014 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
require_once 'File/X509.php';
class Unit_File_X509_CSRTest extends PhpseclibTestCase
{
public function testLoadCSR()
{
$test = '-----BEGIN CERTIFICATE REQUEST-----
MIIBWzCBxQIBADAeMRwwGgYDVQQKDBNwaHBzZWNsaWIgZGVtbyBjZXJ0MIGdMAsG
CSqGSIb3DQEBAQOBjQAwgYkCgYEAtHDb4zoUyiRYsJ5PZrF/IJKAF9ZoHRpTxMA8
a7iyFdsl/vvZLNPsNnFTXXnGdvsyFDEsF7AubaIXw8UKFPYqQRTzSVsvnNgIoVYj
tTAXlB4oHipr7Kxcn4CXfmR0TYogyLvVZSZJYxh+CAuG4V9XM4HqkeE5gyBOsKGy
5FUU8zMCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4GBAJjdaA9K9DN5xvSiOlCmmV1E
npzHkI1Trraveu0gtRjT/EzHoqjCBI0ekCZ9+fhrex8Sm6Nsq9IgHYyrqnE+PQko
4Nf2w2U3DWxU26D5E9DlI+bLyOCq4jqATLjHyyAsOZY/2+U73AZ82MJM/mGdh5fQ
v5RwaQHmQEzHofTzF7I+
-----END CERTIFICATE REQUEST-----';
$x509 = new File_X509();
$spkac = $x509->loadCSR($test);
$this->assertInternalType('array', $spkac);
}
}

View File

@@ -0,0 +1,99 @@
<?php
/**
* @author Jim Wigginton <terrafrost@php.net>
* @copyright 2014 Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
require_once 'File/X509.php';
require_once 'Crypt/RSA.php';
class Unit_File_X509_SPKACTest extends PhpseclibTestCase
{
public function testLoadSPKAC()
{
$test = 'MIICQDCCASgwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQChgo9mWzQm3TSwGgpZnIc54' .
'TZ8gYpfAO/AI0etvyWDqnFfdNCUQsqxTdSi6/rtrJdLGBsszRGrRIc/0JqmjM+jCHGYutLeo4xwgr' .
'a3HAZrWDypL5IlRWnLmLA4U/qGXCXNSk+9NrJl39X3IDA8o/aOJyr9iMUJMvswcWjVjPom3NhAgmJ' .
'ZwW0vUEMw9zszExpiRnGSO5XXntQW2qvfzo+J3NzS3BBbKxEmTsfOLHextcXeFQUaBQHXB/WOtweW' .
'Y/Bd4iZ8ETmhal28g1HWVcTFPD+V+KPRFeARlVEW6JmcJucW2WdJlBGKXXXPEfdHrDS3OgD/eDWfM' .
'JE4mChZ/icxAgMBAAEWADANBgkqhkiG9w0BAQQFAAOCAQEAUMvIKhlSgEgbC081b/FJwh6mbuVgYN' .
'ZV37Ts2WjrHoDFlabu9WXU8xzgaXct3sO51vJM5I36rY4UPyc6w3y9dLaamEwKUoWnpHG8mlXs2JG' .
'GEUOvxh5z9yfk/2ZmdCVBlKnU1LDB+ZDyNyNh5B0YULrJKw9e0jV+ymP7srwUSBcdUfZh1KEKGVIN' .
'Uv4J3GuL8V63E2unWCHGRPw4EmFVTbWpgMx96XR7p/pMavu6/pVKgYQqWLOmEeOK+dmT/QVon28d5' .
'dmeL7aWrpP+3x3L0A9cATksracQX676XogdAEXJ59fcr/S5AGw1TFErbyBbfyeAWvzDZIXeMXpb9h' .
'yNtA==';
$x509 = new File_X509();
$spkac = $x509->loadSPKAC($test);
$this->assertInternalType('array', $spkac);
$spkac = $x509->loadSPKAC('SPKAC=' . $test);
$this->assertInternalType('array', $spkac);
$this->assertTrue(
$x509->validateSignature(),
'Failed asserting that the signature is valid'
);
$pubKey = $x509->getPublicKey();
$this->assertInternalType('string', "$pubKey");
}
public function testSaveSPKAC()
{
$privKey = new Crypt_RSA();
extract($privKey->createKey());
$privKey->loadKey($privatekey);
$x509 = new File_X509();
$x509->setPrivateKey($privKey);
$x509->setChallenge('...');
$spkac = $x509->signSPKAC();
$this->assertInternalType('array', $spkac);
$this->assertInternalType('string', $x509->saveSPKAC($spkac));
$x509 = new File_X509();
$x509->setPrivateKey($privKey);
$spkac = $x509->signSPKAC();
$this->assertInternalType('array', $spkac);
$this->assertInternalType('string', $x509->saveSPKAC($spkac));
}
public function testBadSignatureSPKAC()
{
$test = 'MIICQDCCASgwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQChgo9mWzQm3TSwGgpZnIc54' .
'TZ8gYpfAO/AI0etvyWDqnFfdNCUQsqxTdSi6/rtrJdLGBsszRGrRIc/0JqmjM+jCHGYutLeo4xwgr' .
'a3HAZrWDypL5IlRWnLmLA4U/qGXCXNSk+9NrJl39X3IDA8o/aOJyr9iMUJMvswcWjVjPom3NhAgmJ' .
'ZwW0vUEMw9zszExpiRnGSO5XXntQW2qvfzo+J3NzS3BBbKxEmTsfOLHextcXeFQUaBQHXB/WOtweW' .
'Y/Bd4iZ8ETmhal28g1HWVcTFPD+V+KPRFeARlVEW6JmcJucW2WdJlBGKXXXPEfdHrDS3OgD/eDWfM' .
'JE4mChZ/icxAgMBAAEWADANBgkqhkiG9w0BAQQFAAOCAQEAUMvIKhlSgEgbC081b/FJwh6mbuVgYN' .
'ZV37Ts2WjrHoDFlabu9WXU8xzgaXct3sO51vJM5I36rY4UPyc6w3y9dLaamEwKUoWnpHG8mlXs2JG' .
'GEUOvxh5z9yfk/2ZmdCVBlKnU1LDB+ZDyNyNh5B0YULrJKw9e0jV+ymP7srwUSBcdUfZh1KEKGVIN' .
'Uv4J3GuL8V63E2unWCHGRPw4EmFVTbWpgMx96XR7p/pMavu6/pVKgYQqWLOmEeOK+dmT/QVon28d5' .
'dmeL7aWrpP+3x3L0A9cATksracQX676XogdAEXJ59fcr/S5AGw1TFErbyBbfyeAWvzDZIXeMXpb9h' .
'yNtA==';
$x509 = new File_X509();
$spkac = $x509->loadSPKAC($test);
$spkac['publicKeyAndChallenge']['challenge'] = 'zzzz';
$x509->loadSPKAC($x509->saveSPKAC($spkac));
$this->assertFalse(
$x509->validateSignature(),
'Failed asserting that the signature is invalid'
);
}
}

View File

@@ -0,0 +1,20 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2013 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Unit_Math_BigInteger_BCMathTest extends Unit_Math_BigInteger_TestCase
{
static public function setUpBeforeClass()
{
if (!extension_loaded('bcmath')) {
self::markTestSkipped('BCMath extension is not available.');
}
parent::setUpBeforeClass();
self::ensureConstant('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_BCMATH);
}
}

View File

@@ -0,0 +1,20 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2013 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Unit_Math_BigInteger_GMPTest extends Unit_Math_BigInteger_TestCase
{
static public function setUpBeforeClass()
{
if (!extension_loaded('gmp')) {
self::markTestSkipped('GNU Multiple Precision (GMP) extension is not available.');
}
parent::setUpBeforeClass();
self::ensureConstant('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_GMP);
}
}

View File

@@ -0,0 +1,20 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2013 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Unit_Math_BigInteger_InternalOpenSSLTest extends Unit_Math_BigInteger_TestCase
{
static public function setUpBeforeClass()
{
if (!function_exists('openssl_public_encrypt')) {
self::markTestSkipped('openssl_public_encrypt() function is not available.');
}
parent::setUpBeforeClass();
self::ensureConstant('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_INTERNAL);
}
}

View File

@@ -0,0 +1,24 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2013 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Unit_Math_BigInteger_InternalTest extends Unit_Math_BigInteger_TestCase
{
static public function setUpBeforeClass()
{
parent::setUpBeforeClass();
self::ensureConstant('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_INTERNAL);
self::ensureConstant('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
}
public function testInternalRepresentation()
{
$x = new Math_BigInteger('FFFFFFFFFFFFFFFFC90FDA', 16);
$y = new Math_BigInteger("$x");
$this->assertSame($x->value, $y->value);
}
}

View File

@@ -0,0 +1,361 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2012 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
require_once 'Math/BigInteger.php';
abstract class Unit_Math_BigInteger_TestCase extends PhpseclibTestCase
{
static public function setUpBeforeClass()
{
parent::setUpBeforeClass();
self::reRequireFile('Math/BigInteger.php');
}
public function getInstance($x = 0, $base = 10)
{
return new Math_BigInteger($x, $base);
}
public function testConstructorBase2()
{
// 2**65 = 36893488147419103232
$this->assertSame('36893488147419103232', (string) $this->getInstance('1' . str_repeat('0', 65), 2));
}
public function testConstructorBase10()
{
$this->assertSame('18446744073709551616', (string) $this->getInstance('18446744073709551616'));
}
public function testConstructorBase16()
{
$this->assertSame('50', (string) $this->getInstance('0x32', 16));
$this->assertSame('12345678910', (string) $this->getInstance('0x2DFDC1C3E', 16));
$this->assertSame('18446744073709551615', (string) $this->getInstance('0xFFFFFFFFFFFFFFFF', 16));
$this->assertSame('18446744073709551616', (string) $this->getInstance('0x10000000000000000', 16));
}
public function testToBytes()
{
$this->assertSame(chr(65), $this->getInstance('65')->toBytes());
}
public function testToBytesTwosCompliment()
{
$this->assertSame(chr(126), $this->getInstance('01111110', 2)->toBytes(true));
}
public function testToHex()
{
$this->assertSame('41', $this->getInstance('65')->toHex());
}
public function testToBits()
{
$this->assertSame('1000001', $this->getInstance('65')->toBits());
}
public function testAdd()
{
$x = $this->getInstance('18446744073709551615');
$y = $this->getInstance( '100000000000');
$a = $x->add($y);
$b = $y->add($x);
$this->assertTrue($a->equals($b));
$this->assertTrue($b->equals($a));
$this->assertSame('18446744173709551615', (string) $a);
$this->assertSame('18446744173709551615', (string) $b);
}
public function testSubtract()
{
$x = $this->getInstance('18446744073709551618');
$y = $this->getInstance( '4000000000000');
$this->assertSame('18446740073709551618', (string) $x->subtract($y));
}
public function testMultiply()
{
$x = $this->getInstance('8589934592'); // 2**33
$y = $this->getInstance('36893488147419103232'); // 2**65
$a = $x->multiply($y); // 2**98
$b = $y->multiply($x); // 2**98
$this->assertTrue($a->equals($b));
$this->assertTrue($b->equals($a));
$this->assertSame('316912650057057350374175801344', (string) $a);
$this->assertSame('316912650057057350374175801344', (string) $b);
}
public function testDivide()
{
$x = $this->getInstance('1180591620717411303425'); // 2**70 + 1
$y = $this->getInstance('12345678910');
list($q, $r) = $x->divide($y);
$this->assertSame('95627922070', (string) $q);
$this->assertSame('10688759725', (string) $r);
}
public function testModPow()
{
$a = $this->getInstance('10');
$b = $this->getInstance('20');
$c = $this->getInstance('30');
$d = $a->modPow($b, $c);
$this->assertSame('10', (string) $d);
}
public function testModInverse()
{
$a = $this->getInstance(30);
$b = $this->getInstance(17);
$c = $a->modInverse($b);
$this->assertSame('4', (string) $c);
$d = $a->multiply($c);
list($q, $r) = $d->divide($b);
$this->assertSame('1', (string) $r);
}
public function testExtendedGCD()
{
$a = $this->getInstance(693);
$b = $this->getInstance(609);
$arr = $a->extendedGCD($b);
$this->assertSame('21', (string) $arr['gcd']);
$this->assertSame(21, $a->toString() * $arr['x']->toString() + $b->toString() * $arr['y']->toString());
}
public function testGCD()
{
$x = $this->getInstance(693);
$y = $this->getInstance(609);
$this->assertSame('21', (string) $x->gcd($y));
}
public function testAbs()
{
$x = $this->getInstance('-18446744073709551617');
$y = $x->abs();
$this->assertSame('-18446744073709551617', (string) $x);
$this->assertSame('18446744073709551617', (string) $y);
}
public function testEquals()
{
$x = $this->getInstance('18446744073709551616');
$y = $this->getInstance('18446744073709551616');
$this->assertTrue($x->equals($y));
$this->assertTrue($y->equals($x));
}
public function testCompare()
{
$a = $this->getInstance('-18446744073709551616');
$b = $this->getInstance('36893488147419103232');
$c = $this->getInstance('36893488147419103232');
$d = $this->getInstance('316912650057057350374175801344');
// a < b
$this->assertLessThan(0, $a->compare($b));
$this->assertGreaterThan(0, $b->compare($a));
// b = c
$this->assertSame(0, $b->compare($c));
$this->assertSame(0, $c->compare($b));
// c < d
$this->assertLessThan(0, $c->compare($d));
$this->assertGreaterThan(0, $d->compare($c));
}
public function testBitwiseAND()
{
$x = $this->getInstance('66666666666666666666666', 16);
$y = $this->getInstance('33333333333333333333333', 16);
$z = $this->getInstance('22222222222222222222222', 16);
$this->assertSame($z->toHex(), $x->bitwise_AND($y)->toHex());
}
public function testBitwiseOR()
{
$x = $this->getInstance('11111111111111111111111', 16);
$y = $this->getInstance('EEEEEEEEEEEEEEEEEEEEEEE', 16);
$z = $this->getInstance('FFFFFFFFFFFFFFFFFFFFFFF', 16);
$this->assertSame($z->toHex(), $x->bitwise_OR($y)->toHex());
}
public function testBitwiseXOR()
{
$x = $this->getInstance('AFAFAFAFAFAFAFAFAFAFAFAF', 16);
$y = $this->getInstance('133713371337133713371337', 16);
$z = $this->getInstance('BC98BC98BC98BC98BC98BC98', 16);
$this->assertSame($z->toHex(), $x->bitwise_XOR($y)->toHex());
}
public function testBitwiseNOT()
{
$x = $this->getInstance('EEEEEEEEEEEEEEEEEEEEEEE', 16);
$z = $this->getInstance('11111111111111111111111', 16);
$this->assertSame($z->toHex(), $x->bitwise_NOT()->toHex());
}
public function testBitwiseLeftShift()
{
$x = $this->getInstance('0x0000000FF0000000', 16);
$y = $this->getInstance('0x000FF00000000000', 16);
$this->assertSame($y->toHex(), $x->bitwise_LeftShift(16)->toHex());
}
public function testBitwiseRightShift()
{
$x = $this->getInstance('0x0000000FF0000000', 16);
$y = $this->getInstance('0x00000000000FF000', 16);
$z = $this->getInstance('0x000000000000000F', 16);
$n = $this->getInstance(0);
$this->assertSame($y->toHex(), $x->bitwise_RightShift(16)->toHex());
$this->assertSame($z->toHex(), $x->bitwise_RightShift(32)->toHex());
$this->assertSame($n->toHex(), $x->bitwise_RightShift(36)->toHex());
}
public function testSerializable()
{
$x = $this->getInstance('18446744073709551616');
$y = unserialize(serialize($x));
$this->assertTrue($x->equals($y));
$this->assertTrue($y->equals($x));
$this->assertSame('18446744073709551616', (string) $x);
$this->assertSame('18446744073709551616', (string) $y);
}
public function testClone()
{
$x = $this->getInstance('18446744073709551616');
$y = clone $x;
$this->assertTrue($x->equals($y));
$this->assertTrue($y->equals($x));
$this->assertSame('18446744073709551616', (string) $x);
$this->assertSame('18446744073709551616', (string) $y);
}
public function testRandomTwoArgument()
{
$min = $this->getInstance(0);
$max = $this->getInstance('18446744073709551616');
$rand1 = $min->random($min, $max);
// technically $rand1 can equal $min but with the $min and $max we've
// chosen it's just not that likely
$this->assertTrue($rand1->compare($min) > 0);
$this->assertTrue($rand1->compare($max) < 0);
}
public function testRandomOneArgument()
{
$min = $this->getInstance(0);
$max = $this->getInstance('18446744073709551616');
$rand1 = $min->random($max);
$this->assertTrue($rand1->compare($min) > 0);
$this->assertTrue($rand1->compare($max) < 0);
$rand2 = $max->random($min);
$this->assertTrue($rand2->compare($min) > 0);
$this->assertTrue($rand2->compare($max) < 0);
$this->assertFalse($rand1->equals($rand2));
}
/**
* @group github279
*/
public function testDiffieHellmanKeyAgreement()
{
if (getenv('TRAVIS') && PHP_VERSION === '5.3.3'
&& MATH_BIGINTEGER_MODE === MATH_BIGINTEGER_MODE_INTERNAL
) {
$this->markTestIncomplete(
'This test hangs on PHP 5.3.3 using internal mode.'
);
}
// "Oakley Group 14" 2048-bit modular exponentiation group as used in
// SSH2 diffie-hellman-group14-sha1
$prime = $this->getInstance(
'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1' .
'29024E088A67CC74020BBEA63B139B22514A08798E3404DD' .
'EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245' .
'E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D' .
'C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F' .
'83655D23DCA3AD961C62F356208552BB9ED529077096966D' .
'670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' .
'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9' .
'DE2BCBF6955817183995497CEA956AE515D2261898FA0510' .
'15728E5A8AACAA68FFFFFFFFFFFFFFFF',
16
);
$generator = $this->getInstance(2);
/*
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);
var_dump($alicePrivate->toHex(), $bobPrivate->toHex());
*/
$alicePrivate = $this->getInstance(
'22606EDA7960458BC9D65F46DD96F114F9A004F0493C1F26' .
'2139D2C8063B733162E876182CA3BF063AB1A167ABDB7F03' .
'E0A225A6205660439F6CE46D252069FF',
16
);
$bobPrivate = $this->getInstance(
'6E3EFA13A96025D63E4B0D88A09B3A46DDFE9DD3BC9D1655' .
'4898C02B4AC181F0CEB4E818664B12F02C71A07215C400F9' .
'88352A4779F3E88836F7C3D3B3C739DE',
16
);
$alicePublic = $generator->modPow($alicePrivate, $prime);
$bobPublic = $generator->modPow($bobPrivate, $prime);
$aliceShared = $bobPublic->modPow($alicePrivate, $prime);
$bobShared = $alicePublic->modPow($bobPrivate, $prime);
$this->assertTrue(
$aliceShared->equals($bobShared),
'Failed asserting that Alice and Bob share the same BigInteger.'
);
}
}

View File

@@ -0,0 +1,33 @@
<?php
/**
* @author Andreas Fischer <bantu@phpbb.com>
* @copyright 2014 Andreas Fischer
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
require_once 'Net/SFTP/Stream.php';
class Unit_Net_SFTPStreamTest extends PhpseclibTestCase
{
protected $protocol = 'sftptest';
public function setUp()
{
parent::setUp();
if (in_array($this->protocol, stream_get_wrappers())) {
stream_wrapper_unregister($this->protocol);
}
}
public function testRegisterFromSideEffect()
{
// Including the file registers 'sftp' as a stream.
$this->assertContains('sftp', stream_get_wrappers());
}
public function testRegisterWithArgument()
{
Net_SFTP_Stream::register($this->protocol);
$this->assertContains($this->protocol, stream_get_wrappers());
}
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* @author Marc Scholten <marc@pedigital.de>
* @copyright 2013 Marc Scholten
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Unit_Net_SSH1Test extends PhpseclibTestCase
{
public function formatLogDataProvider()
{
return array(
array(
array('hello world'),
array('<--'),
"<--\r\n00000000 68:65:6c:6c:6f:20:77:6f:72:6c:64 hello world\r\n\r\n"
),
array(
array('hello', 'world'),
array('<--', '<--'),
"<--\r\n00000000 68:65:6c:6c:6f hello\r\n\r\n" .
"<--\r\n00000000 77:6f:72:6c:64 world\r\n\r\n"
),
);
}
/**
* @dataProvider formatLogDataProvider
*/
public function testFormatLog(array $message_log, array $message_number_log, $expected)
{
$ssh = $this->getMockBuilder('Net_SSH1')
->disableOriginalConstructor()
->setMethods(null)
->getMock();
$result = $ssh->_format_log($message_log, $message_number_log);
$this->assertEquals($expected, $result);
}
}

View File

@@ -0,0 +1,114 @@
<?php
/**
* @author Marc Scholten <marc@pedigital.de>
* @copyright 2013 Marc Scholten
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class Unit_Net_SSH2Test extends PhpseclibTestCase
{
public function formatLogDataProvider()
{
return array(
array(
array('hello world'),
array('<--'),
"<--\r\n00000000 68:65:6c:6c:6f:20:77:6f:72:6c:64 hello world\r\n\r\n"
),
array(
array('hello', 'world'),
array('<--', '<--'),
"<--\r\n00000000 68:65:6c:6c:6f hello\r\n\r\n" .
"<--\r\n00000000 77:6f:72:6c:64 world\r\n\r\n"
),
);
}
/**
* @dataProvider formatLogDataProvider
*/
public function testFormatLog(array $message_log, array $message_number_log, $expected)
{
$ssh = $this->createSSHMock();
$result = $ssh->_format_log($message_log, $message_number_log);
$this->assertEquals($expected, $result);
}
public function testGenerateIdentifier()
{
$identifier = $this->createSSHMock()->_generate_identifier();
$this->assertStringStartsWith('SSH-2.0-phpseclib_0.3', $identifier);
if (extension_loaded('mcrypt')) {
$this->assertContains('mcrypt', $identifier);
} else {
$this->assertNotContains('mcrypt', $identifier);
}
if (extension_loaded('gmp')) {
$this->assertContains('gmp', $identifier);
$this->assertNotContains('bcmath', $identifier);
} else if (extension_loaded('bcmath')) {
$this->assertNotContains('gmp', $identifier);
$this->assertContains('bcmath', $identifier);
} else {
$this->assertNotContains('gmp', $identifier);
$this->assertNotContains('bcmath', $identifier);
}
}
public function testGetExitStatusIfNotConnected()
{
$ssh = $this->createSSHMock();
$this->assertFalse($ssh->getExitStatus());
}
public function testPTYIDefaultValue()
{
$ssh = $this->createSSHMock();
$this->assertFalse($ssh->isPTYEnabled());
}
public function testEnablePTY()
{
$ssh = $this->createSSHMock();
$ssh->enablePTY();
$this->assertTrue($ssh->isPTYEnabled());
$ssh->disablePTY();
$this->assertFalse($ssh->isPTYEnabled());
}
public function testQuietModeDefaultValue()
{
$ssh = $this->createSSHMock();
$this->assertFalse($ssh->isQuietModeEnabled());
}
public function testEnableQuietMode()
{
$ssh = $this->createSSHMock();
$ssh->enableQuietMode();
$this->assertTrue($ssh->isQuietModeEnabled());
$ssh->disableQuietMode();
$this->assertFalse($ssh->isQuietModeEnabled());
}
/**
* @return Net_SSH2
*/
protected function createSSHMock()
{
return $this->getMockBuilder('Net_SSH2')
->disableOriginalConstructor()
->setMethods(array('__destruct'))
->getMock();
}
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* Bootstrapping File for phpseclib Test Suite
*
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
date_default_timezone_set('UTC');
// Set up include path accordingly. This is especially required because some
// class files of phpseclib require() other dependencies.
set_include_path(implode(PATH_SEPARATOR, array(
dirname(__FILE__) . '/../phpseclib/',
dirname(__FILE__) . '/',
get_include_path(),
)));
require_once 'Crypt/Random.php';
function phpseclib_autoload($class)
{
$file = str_replace('_', '/', $class) . '.php';
if (phpseclib_resolve_include_path($file)) {
// @codingStandardsIgnoreStart
require $file;
// @codingStandardsIgnoreEnd
}
}
spl_autoload_register('phpseclib_autoload');

View File

@@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,2F15FCF0B21FCFB5A37D709322F9B9EB
JpGgJqRnr0+3mHQoeYXXUzSWeA1wGwMzm6KOPnQLEmA9ztPlBQulzZRh6QJckCwy
TC7BMo+XRnYVXF3e0rjji0k7cfEk5Gs8saNcxxOa0u0SUOCXelGnZeqzwiT0a6Fe
qAc7NLgTEo9zul9s+MHsplkVk71Oke+1dL7kksMRT0TdXIaqSvk/+nyAeLzAot04
wo61T3+Y7/v/8oVxlCbxI5YfYZkm/4jTy7AfbXZBvC0R+F0ZYvIDRCuBe6h6XvcH
AiYtw5+Qek6FwIa2CFVxsefvsEnZQYaiJpEFAq2xVHlTjQHHYrfd5cgu1koUNsAt
nX1zpsK7tIregXFa07KfDaBBPxfEBqVJQInzj0Rc8HUt0AZ+MrPldrZ28+YQ4RXk
/qk5UyKkdHMSKBb4va3mxcpDq1As9HREfeUeOjjduRh1LnNQCJaOhydXBqCFvhFy
+Q9utDXP6q4OUxeDHCPGQ7K1I7erwiwuTeSXB3BEDZyZywHXABvJpsidkDlD/aNo
QmM19V8y0IAxEAZvc8N0MIOO8hmd8R9U1RK4S24o9M8mgRrmuXjViJjZd5E3h6tX
Mgxm8dpOiT77i+NsJwyp2A+MhkAHg2ruwlCIrSCC81zvdphVTfuc/vx3JpXYvhTP
Xf9R8ppGnDUFauroN7E7odJKDhLVuAbmU1lWwue2iaNEKZ3L/o9dpRz4Td4NzzSf
HKvKbJR35FCsqZq2krmNVd6ynF5PzWfYmz850yn/qdU8zwnW0fV+iHKS2oXuH9X1
ZW02/MDdCylpRftNJMntR4Yxim7WEZ5Dif9ZLj8IGRQdWbbIn0WjtiVrFrcUbIfk
TCP/3GeEcUa/XbE9hO9APw+7rO3sOehGJ84n4tXxFTFSnOJ5ZxTKpLvxRrmC8DaD
cvqy8bbjPfn1EjZmRpCjanLZ1UJbLitFfpUT55aTrcozS4FMHmFm74X2xZGeBhxC
CpWQe/agxhWxG+ZXdxt9ExI78ftQCQoGE0Si1KZXH5KQ/xiGmebY9wbtEHWG+q25
sKqvjQHQsE3NZq7kne3mnyvjzMDDFYPLDlQLgcKInNrLZ3GszyemtzqcVf3YVur4
N+nN0gu6LCx0vtw3yNRqjjmGN1V6sKMCqmIAtFDh9zRTlDTs7ZUBGPgakmmJLLVM
ESme0JrRxCP+eEU8JNti9pKlKPGOFVpu4shLjmnmKuDpOytFNpcB/NylkGwZCxvE
1KI+EQMZOE5VROAfkvwBLE0SsVxMq7H87zSEOtOqr+QN8RoY1V6N/woBVWda9GFk
HI44PM2ZywQbLGthaQV/Kxwf9YZruJdunNoTfEufZgv2Vp+3VAs+gCTGIsbblTnH
J8QGfs/lHRBqK1pMZrYy0ubFqifA+b9Xa6VJWToCgcQuWbOVWn1zKQTTXZPksVbB
qyE8BJkQCDGgoeq4kdxm0XUR5p3UZWQv0HoykQt33U06TCzU9HOcp0z+Glhrzsvd
rbNBhRK0zXF/BFSNBHwKEg02TNlj7gSFJXmvZqvyCAFo5D6nSDbzqm6ARuscsrF0
6Zd3toOZTWmrVsKvTlsNPfHXyoGqP3+0NXcTY+kKXG58u4TbEtw8pVyPikuVdh/m
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,30 @@
#!/bin/bash
#
# This file is part of the phpseclib project.
#
# (c) Andreas Fischer <bantu@phpbb.com>
#
# For the full copyright and license information, please view the LICENSE
# file that was distributed with this source code.
#
set -e
function install_php_extension
{
cd "$1"
phpize
./configure
make
make install
cd ..
echo "extension=$1.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
}
# 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
install_php_extension 'runkit'

View File

@@ -0,0 +1,34 @@
#!/bin/sh
set -e
set -x
export PHPSECLIB_SSH_HOSTNAME='localhost'
export PHPSECLIB_SSH_USERNAME='phpseclib'
export PHPSECLIB_SSH_PASSWORD='EePoov8po1aethu2kied1ne0'
export PHPSECLIB_SSH_HOME='/home/phpseclib'
if [ "$TRAVIS_PHP_VERSION" = '5.2' ]
then
PHPUNIT="phpunit"
else
PHPUNIT="$(dirname "$0")/../vendor/bin/phpunit"
fi
PHPUNIT_ARGS='--verbose'
if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.4', '<');"` = "1" ]
then
PHPUNIT_ARGS="$PHPUNIT_ARGS -d zend.enable_gc=0"
fi
if [ "$TRAVIS_PHP_VERSION" = 'hhvm' ]
then
find tests -type f -name "*Test.php" | \
parallel --gnu --keep-order \
"echo '== {} =='; \"$PHPUNIT\" $PHPUNIT_ARGS {};"
else
"$PHPUNIT" \
$PHPUNIT_ARGS \
--coverage-text \
--coverage-clover code_coverage/clover.xml \
--coverage-html code_coverage/
fi

View File

@@ -0,0 +1,3 @@
#!/bin/sh
composer self-update --no-interaction
composer install --no-interaction

View File

@@ -0,0 +1,31 @@
#!/bin/sh
#
# This file is part of the phpseclib project.
#
# (c) Andreas Fischer <bantu@phpbb.com>
#
# For the full copyright and license information, please view the LICENSE
# file that was distributed with this source code.
#
set -e
set -x
USERNAME='phpseclib'
PASSWORD='EePoov8po1aethu2kied1ne0'
# Create phpseclib user and home directory
sudo useradd --create-home --base-dir /home "$USERNAME"
# Set phpseclib user password
echo "$USERNAME:$PASSWORD" | sudo chpasswd
# Create a 1024 bit RSA SSH key pair without passphrase for the travis user
ssh-keygen -t rsa -b 1024 -f "$HOME/.ssh/id_rsa" -q -N ""
# Add the generated private key to SSH agent of travis user
ssh-add "$HOME/.ssh/id_rsa"
# Allow the private key of the travis user to log in as phpseclib user
sudo mkdir -p "/home/$USERNAME/.ssh/"
sudo cp "$HOME/.ssh/id_rsa.pub" "/home/$USERNAME/.ssh/authorized_keys"
sudo chown "$USERNAME:$USERNAME" "/home/$USERNAME/.ssh/" -R

View File

@@ -0,0 +1,50 @@
#!/bin/sh
#
# This file is part of the phpseclib project.
#
# (c) Andreas Fischer <bantu@phpbb.com>
#
# For the full copyright and license information, please view the LICENSE
# file that was distributed with this source code.
#
USERNAME='phpseclib'
HOSTNAME='phpseclib.bantux.org'
HOSTRSAF='09:40:96:14:6a:cd:67:46:17:e5:b4:39:24:24:6e:9d'
LDIRNAME='code_coverage'
RDIRNAME='code_coverage'
ID_RSA='travis/code_coverage_id_rsa'
# Install expect if necessary
if ! which expect > /dev/null
then
sudo apt-get update -qq
sudo apt-get install -qq expect
fi
# Workaround for rsync not creating target directories with depth > 1
mv "$LDIRNAME" "x$LDIRNAME"
RROOT="$RDIRNAME/$TRAVIS_BRANCH/$TRAVIS_BUILD_NUMBER"
mkdir -p "$RROOT"
mv "x$LDIRNAME" "$RROOT/PHP-$TRAVIS_PHP_VERSION/"
# Update latest symlink
ln -s "$TRAVIS_BUILD_NUMBER" "$RDIRNAME/$TRAVIS_BRANCH/latest"
# Stop complaints about world-readable key file.
chmod 600 "$ID_RSA"
export RSYNC_RSH="ssh -4 -i $ID_RSA -o ConnectTimeout=5"
RSYNC_OPT="--recursive --times --links --progress"
expect << EOF
spawn rsync $RSYNC_OPT "$RDIRNAME/" "$USERNAME@$HOSTNAME:$RDIRNAME/"
expect "RSA key fingerprint is $HOSTRSAF."
send "yes\n"
expect "Enter passphrase for key '$ID_RSA':"
send "$CODE_COVERAGE_PASSPHRASE\n"
expect eof
EOF

View File

@@ -0,0 +1,13 @@
#!/bin/sh
#
# This file is part of the phpseclib project.
#
# (c) Andreas Fischer <bantu@phpbb.com>
#
# For the full copyright and license information, please view the LICENSE
# file that was distributed with this source code.
#
set -e
wget https://scrutinizer-ci.com/ocular.phar
php ocular.phar code-coverage:upload --format=php-clover code_coverage/clover.xml