forked from GNUsocial/gnu-social
phpseclib updated, some new features that we won't use
This commit is contained in:
parent
a6390007b7
commit
28ca5d90d9
@ -1,28 +1,31 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of AES.
|
||||
*
|
||||
* Uses mcrypt, if available/possible, and an internal implementation, otherwise.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
* PHP version 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()}
|
||||
* NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
|
||||
* just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
|
||||
* to save one include_once().
|
||||
*
|
||||
* If {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
|
||||
* {@link self::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
|
||||
* it'll be null-padded to 192-bits and 192 bits will be the key length until {@link self::setKey() setKey()}
|
||||
* is called, again, at which point, it'll be recalculated.
|
||||
*
|
||||
* Since 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,
|
||||
* Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, some functions are available to be called that, in the context of AES, don't
|
||||
* make a whole lot of sense. {@link self::setBlockLength() setBlockLength()}, for instance. Calling that function,
|
||||
* however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
|
||||
*
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include('Crypt/AES.php');
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $aes = new Crypt_AES();
|
||||
* $aes = new \phpseclib\Crypt\AES();
|
||||
*
|
||||
* $aes->setKey('abcdefghijklmnop');
|
||||
*
|
||||
@ -36,153 +39,85 @@
|
||||
* ?>
|
||||
* </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 MMVIII Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
* @category Crypt
|
||||
* @package 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')) {
|
||||
require_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_AES::Crypt_AES()
|
||||
*/
|
||||
/**
|
||||
* Toggles the internal implementation
|
||||
*/
|
||||
define('CRYPT_AES_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
|
||||
/**
|
||||
* Toggles the mcrypt implementation
|
||||
*/
|
||||
define('CRYPT_AES_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
|
||||
/**#@-*/
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of AES.
|
||||
*
|
||||
* @package AES
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @version 0.1.0
|
||||
* @access public
|
||||
* @package Crypt_AES
|
||||
*/
|
||||
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';
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
*
|
||||
* $mode could be:
|
||||
*
|
||||
* - CRYPT_AES_MODE_ECB
|
||||
*
|
||||
* - CRYPT_AES_MODE_CBC
|
||||
*
|
||||
* - CRYPT_AES_MODE_CTR
|
||||
*
|
||||
* - CRYPT_AES_MODE_CFB
|
||||
*
|
||||
* - CRYPT_AES_MODE_OFB
|
||||
*
|
||||
* If not explictly set, CRYPT_AES_MODE_CBC will be used.
|
||||
*
|
||||
* @see Crypt_Rijndael::Crypt_Rijndael()
|
||||
* @see Crypt_Base::Crypt_Base()
|
||||
* @param optional Integer $mode
|
||||
* @access public
|
||||
*/
|
||||
function Crypt_AES($mode = CRYPT_AES_MODE_CBC)
|
||||
{
|
||||
parent::Crypt_Rijndael($mode);
|
||||
}
|
||||
|
||||
class AES extends Rijndael
|
||||
{
|
||||
/**
|
||||
* Dummy function
|
||||
*
|
||||
* Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.
|
||||
* Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything.
|
||||
*
|
||||
* @see Crypt_Rijndael::setBlockLength()
|
||||
* @see \phpseclib\Crypt\Rijndael::setBlockLength()
|
||||
* @access public
|
||||
* @param Integer $length
|
||||
* @param int $length
|
||||
* @throws \BadMethodCallException anytime it's called
|
||||
*/
|
||||
function setBlockLength($length)
|
||||
{
|
||||
return;
|
||||
throw new \BadMethodCallException('The block length cannot be set for AES.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length
|
||||
*
|
||||
* Valid key lengths are 128, 192, and 256. Set the link to bool(false) to disable a fixed key length
|
||||
*
|
||||
* @see \phpseclib\Crypt\Rijndael:setKeyLength()
|
||||
* @access public
|
||||
* @param int $length
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 192:
|
||||
case 256:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported');
|
||||
}
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Rijndael supports five different key lengths, AES only supports three.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Rijndael:setKey()
|
||||
* @see setKeyLength()
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
switch (strlen($key)) {
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
|
||||
}
|
||||
|
||||
parent::setKey($key);
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
// vim6: fdl=1:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Blowfish.
|
||||
*
|
||||
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
* PHP version 5
|
||||
*
|
||||
* Useful resources are as follows:
|
||||
*
|
||||
@ -15,9 +14,9 @@
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include('Crypt/Blowfish.php');
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $blowfish = new Crypt_Blowfish();
|
||||
* $blowfish = new \phpseclib\Crypt\Blowfish();
|
||||
*
|
||||
* $blowfish->setKey('12345678901234567890123456789012');
|
||||
*
|
||||
@ -27,139 +26,41 @@
|
||||
* ?>
|
||||
* </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 MMVII Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 1.0
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
* @category Crypt
|
||||
* @package 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')) {
|
||||
require_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_Blowfish::Crypt_Blowfish()
|
||||
*/
|
||||
/**
|
||||
* Toggles the internal implementation
|
||||
*/
|
||||
define('CRYPT_BLOWFISH_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
|
||||
/**
|
||||
* Toggles the mcrypt implementation
|
||||
*/
|
||||
define('CRYPT_BLOWFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
|
||||
/**#@-*/
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Blowfish.
|
||||
*
|
||||
* @package Blowfish
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
|
||||
* @version 1.0
|
||||
* @access public
|
||||
* @package Crypt_Blowfish
|
||||
*/
|
||||
class Crypt_Blowfish extends Crypt_Base {
|
||||
class Blowfish extends Base
|
||||
{
|
||||
/**
|
||||
* Block Length of the cipher
|
||||
*
|
||||
* @see Crypt_Base::block_size
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::block_size
|
||||
* @var int
|
||||
* @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
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'blowfish';
|
||||
@ -167,8 +68,8 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
/**
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see Crypt_Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 500;
|
||||
@ -176,12 +77,12 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
/**
|
||||
* The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
|
||||
*
|
||||
* S-Box 1
|
||||
* S-Box 0
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $sbox0 = array (
|
||||
var $sbox0 = array(
|
||||
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
|
||||
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
|
||||
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
||||
@ -342,7 +243,7 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
/**
|
||||
* P-Array consists of 18 32-bit subkeys
|
||||
*
|
||||
* @var array $parray
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $parray = array(
|
||||
@ -356,7 +257,7 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
*
|
||||
* Holds the expanded key [p] and the key-depended s-boxes [sb]
|
||||
*
|
||||
* @var array $bctx
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $bctx;
|
||||
@ -364,72 +265,86 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
/**
|
||||
* Holds the last used key
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $kl;
|
||||
|
||||
/**
|
||||
* The Key Length (in bytes)
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk
|
||||
* because the encryption / decryption / key schedule creation requires this number and not $key_length. We could
|
||||
* derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
|
||||
* of that, we'll just precompute it once.
|
||||
*/
|
||||
var $key_length = 16;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
*
|
||||
* $mode could be:
|
||||
*
|
||||
* - CRYPT_BLOWFISH_MODE_ECB
|
||||
*
|
||||
* - CRYPT_BLOWFISH_MODE_CBC
|
||||
*
|
||||
* - CRYPT_BLOWFISH_MODE_CTR
|
||||
*
|
||||
* - CRYPT_BLOWFISH_MODE_CFB
|
||||
*
|
||||
* - CRYPT_BLOWFISH_MODE_OFB
|
||||
*
|
||||
* If not explictly set, CRYPT_BLOWFISH_MODE_CBC will be used.
|
||||
*
|
||||
* @see Crypt_Base::Crypt_Base()
|
||||
* @param optional Integer $mode
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function Crypt_Blowfish($mode = CRYPT_BLOWFISH_MODE_CBC)
|
||||
function __construct($mode)
|
||||
{
|
||||
parent::Crypt_Base($mode);
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
* Sets the key length.
|
||||
*
|
||||
* 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.
|
||||
* Key lengths can be between 32 and 448 bits.
|
||||
*
|
||||
* @access public
|
||||
* @see Crypt_Base::setKey()
|
||||
* @param String $key
|
||||
* @param int $length
|
||||
*/
|
||||
function setKey($key)
|
||||
function setKeyLength($length)
|
||||
{
|
||||
$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);
|
||||
if ($length < 32 || $length > 448) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes between 32 and 448 bits are supported');
|
||||
}
|
||||
|
||||
parent::setKey($key);
|
||||
$this->key_length = $length >> 3;
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for engine validity
|
||||
*
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::isValidEngine()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
if ($engine == self::ENGINE_OPENSSL) {
|
||||
if ($this->key_length != 16) {
|
||||
return false;
|
||||
}
|
||||
$this->cipher_name_openssl_ecb = 'bf-ecb';
|
||||
$this->cipher_name_openssl = 'bf-' . $this->_openssl_translate_mode();
|
||||
}
|
||||
|
||||
return parent::isValidEngine($engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the key (expansion)
|
||||
*
|
||||
* @see Crypt_Base::_setupKey()
|
||||
* @see \phpseclib\Crypt\Base::_setupKey()
|
||||
* @access private
|
||||
*/
|
||||
function _setupKey()
|
||||
@ -486,8 +401,8 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
* Encrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
@ -503,17 +418,17 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
$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];
|
||||
$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];
|
||||
$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]);
|
||||
}
|
||||
@ -522,8 +437,8 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
* Decrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
@ -550,30 +465,28 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
$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()
|
||||
* @see \phpseclib\Crypt\Base::_setupInlineCrypt()
|
||||
* @access private
|
||||
*/
|
||||
function _setupInlineCrypt()
|
||||
{
|
||||
$lambda_functions =& Crypt_Blowfish::_getLambdaFunctions();
|
||||
$lambda_functions =& self::_getLambdaFunctions();
|
||||
|
||||
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
|
||||
// (Currently, for Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit)
|
||||
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
|
||||
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10);
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
|
||||
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}";
|
||||
// Generation of a unique hash for our generated code
|
||||
$code_hash = "Crypt_Blowfish, {$this->mode}";
|
||||
if ($gen_hi_opt_code) {
|
||||
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
if (!isset($lambda_functions[$code_hash])) {
|
||||
@ -673,6 +586,3 @@ class Crypt_Blowfish extends Crypt_Base {
|
||||
$this->inline_crypt = $lambda_functions[$code_hash];
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
// vim6: fdl=1:
|
||||
|
@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of DES.
|
||||
*
|
||||
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
* PHP version 5
|
||||
*
|
||||
* Useful resources are as follows:
|
||||
*
|
||||
@ -17,9 +16,9 @@
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include('Crypt/DES.php');
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $des = new Crypt_DES();
|
||||
* $des = new \phpseclib\Crypt\DES();
|
||||
*
|
||||
* $des->setKey('abcdefgh');
|
||||
*
|
||||
@ -33,170 +32,87 @@
|
||||
* ?>
|
||||
* </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_DES
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright MMVII Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
* @category Crypt
|
||||
* @package DES
|
||||
* @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')) {
|
||||
require_once('Base.php');
|
||||
}
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see Crypt_DES::_setupKey()
|
||||
* @see Crypt_DES::_processBlock()
|
||||
*/
|
||||
/**
|
||||
* Contains $keys[CRYPT_DES_ENCRYPT]
|
||||
*/
|
||||
define('CRYPT_DES_ENCRYPT', 0);
|
||||
/**
|
||||
* Contains $keys[CRYPT_DES_DECRYPT]
|
||||
*/
|
||||
define('CRYPT_DES_DECRYPT', 1);
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @access public
|
||||
* @see Crypt_DES::encrypt()
|
||||
* @see Crypt_DES::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_DES_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_DES_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_DES_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_DES_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_DES_MODE_OFB', CRYPT_MODE_OFB);
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see Crypt_DES::Crypt_DES()
|
||||
*/
|
||||
/**
|
||||
* Toggles the internal implementation
|
||||
*/
|
||||
define('CRYPT_DES_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
|
||||
/**
|
||||
* Toggles the mcrypt implementation
|
||||
*/
|
||||
define('CRYPT_DES_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
|
||||
/**#@-*/
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of DES.
|
||||
*
|
||||
* @package DES
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @version 0.1.0
|
||||
* @access public
|
||||
* @package Crypt_DES
|
||||
*/
|
||||
class Crypt_DES extends Crypt_Base {
|
||||
class DES extends Base
|
||||
{
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see \phpseclib\Crypt\DES::_setupKey()
|
||||
* @see \phpseclib\Crypt\DES::_processBlock()
|
||||
*/
|
||||
/**
|
||||
* Contains $keys[self::ENCRYPT]
|
||||
*/
|
||||
const ENCRYPT = 0;
|
||||
/**
|
||||
* Contains $keys[self::DECRYPT]
|
||||
*/
|
||||
const DECRYPT = 1;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Block Length of the cipher
|
||||
*
|
||||
* @see Crypt_Base::block_size
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::block_size
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $block_size = 8;
|
||||
|
||||
/**
|
||||
* The Key
|
||||
* Key Length (in bytes)
|
||||
*
|
||||
* @see Crypt_Base::key
|
||||
* @see setKey()
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $key = "\0\0\0\0\0\0\0\0";
|
||||
|
||||
/**
|
||||
* The default password key_size used by setPassword()
|
||||
*
|
||||
* @see Crypt_Base::password_key_size
|
||||
* @see Crypt_Base::setPassword()
|
||||
* @var Integer
|
||||
* @access private
|
||||
*/
|
||||
var $password_key_size = 8;
|
||||
|
||||
/**
|
||||
* The namespace used by the cipher for its constants.
|
||||
*
|
||||
* @see Crypt_Base::const_namespace
|
||||
* @var String
|
||||
* @access private
|
||||
*/
|
||||
var $const_namespace = 'DES';
|
||||
var $key_length = 8;
|
||||
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see Crypt_Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'des';
|
||||
|
||||
/**
|
||||
* The OpenSSL names of the cipher / modes
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::openssl_mode_names
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $openssl_mode_names = array(
|
||||
self::MODE_ECB => 'des-ecb',
|
||||
self::MODE_CBC => 'des-cbc',
|
||||
self::MODE_CFB => 'des-cfb',
|
||||
self::MODE_OFB => 'des-ofb'
|
||||
// self::MODE_CTR is undefined for DES
|
||||
);
|
||||
|
||||
/**
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see Crypt_Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 500;
|
||||
@ -204,11 +120,11 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Switch for DES/3DES encryption
|
||||
*
|
||||
* Used only if $engine == CRYPT_DES_MODE_INTERNAL
|
||||
* Used only if $engine == self::ENGINE_INTERNAL
|
||||
*
|
||||
* @see Crypt_DES::_setupKey()
|
||||
* @see Crypt_DES::_processBlock()
|
||||
* @var Integer
|
||||
* @see self::_setupKey()
|
||||
* @see self::_processBlock()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $des_rounds = 1;
|
||||
@ -216,17 +132,17 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* max possible size of $key
|
||||
*
|
||||
* @see Crypt_DES::setKey()
|
||||
* @var String
|
||||
* @see self::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key_size_max = 8;
|
||||
var $key_length_max = 8;
|
||||
|
||||
/**
|
||||
* The Key Schedule
|
||||
*
|
||||
* @see Crypt_DES::_setupKey()
|
||||
* @var Array
|
||||
* @see self::_setupKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $keys;
|
||||
@ -238,9 +154,9 @@ class Crypt_DES extends Crypt_Base {
|
||||
* with each byte containing all bits in the same state as the
|
||||
* corresponding bit in the index value.
|
||||
*
|
||||
* @see Crypt_DES::_processBlock()
|
||||
* @see Crypt_DES::_setupKey()
|
||||
* @var Array
|
||||
* @see self::_processBlock()
|
||||
* @see self::_setupKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $shuffle = array(
|
||||
@ -379,7 +295,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
*
|
||||
* Indexing this table with each source byte performs the initial bit permutation.
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $ipmap = array(
|
||||
@ -421,7 +337,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
* Inverse IP mapping helper table.
|
||||
* Indexing this table with a byte value reverses the bit order.
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $invipmap = array(
|
||||
@ -465,7 +381,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
* Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the
|
||||
* P table: concatenation can then be replaced by exclusive ORs.
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox1 = array(
|
||||
@ -490,7 +406,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Pre-permuted S-box2
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox2 = array(
|
||||
@ -515,7 +431,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Pre-permuted S-box3
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox3 = array(
|
||||
@ -540,7 +456,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Pre-permuted S-box4
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox4 = array(
|
||||
@ -565,7 +481,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Pre-permuted S-box5
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox5 = array(
|
||||
@ -590,7 +506,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Pre-permuted S-box6
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox6 = array(
|
||||
@ -615,7 +531,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Pre-permuted S-box7
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox7 = array(
|
||||
@ -640,7 +556,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Pre-permuted S-box8
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $sbox8 = array(
|
||||
@ -665,52 +581,56 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* If not explictly set, CRYPT_DES_MODE_CBC will be used.
|
||||
*
|
||||
* @see Crypt_Base::Crypt_Base()
|
||||
* @param optional Integer $mode
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function Crypt_DES($mode = CRYPT_DES_MODE_CBC)
|
||||
function __construct($mode)
|
||||
{
|
||||
parent::Crypt_Base($mode);
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for engine validity
|
||||
*
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::isValidEngine()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
if ($this->key_length_max == 8) {
|
||||
if ($engine == self::ENGINE_OPENSSL) {
|
||||
$this->cipher_name_openssl_ecb = 'des-ecb';
|
||||
$this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode();
|
||||
}
|
||||
}
|
||||
|
||||
return parent::isValidEngine($engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
|
||||
* only use the first eight, if $key has more then eight characters in it, and pad $key with the
|
||||
* null byte if it is less then eight characters long.
|
||||
* Keys must be 64-bits long or 8 bytes long.
|
||||
*
|
||||
* DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
|
||||
*
|
||||
* If the key is not explicitly set, it'll be assumed to be all zero's.
|
||||
*
|
||||
* @see Crypt_Base::setKey()
|
||||
* @see \phpseclib\Crypt\Base::setKey()
|
||||
* @access public
|
||||
* @param String $key
|
||||
* @param string $key
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
// We check/cut here only up to max length of the key.
|
||||
// Key padding to the proper length will be done in _setupKey()
|
||||
if (strlen($key) > $this->key_size_max) {
|
||||
$key = substr($key, 0, $this->key_size_max);
|
||||
if (!($this instanceof TripleDES) && strlen($key) != 8) {
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of size 8 are supported');
|
||||
}
|
||||
|
||||
// Sets the key
|
||||
@ -720,46 +640,46 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Encrypts a block
|
||||
*
|
||||
* @see Crypt_Base::_encryptBlock()
|
||||
* @see Crypt_Base::encrypt()
|
||||
* @see Crypt_DES::encrypt()
|
||||
* @see \phpseclib\Crypt\Base::_encryptBlock()
|
||||
* @see \phpseclib\Crypt\Base::encrypt()
|
||||
* @see self::encrypt()
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
return $this->_processBlock($in, CRYPT_DES_ENCRYPT);
|
||||
return $this->_processBlock($in, self::ENCRYPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a block
|
||||
*
|
||||
* @see Crypt_Base::_decryptBlock()
|
||||
* @see Crypt_Base::decrypt()
|
||||
* @see Crypt_DES::decrypt()
|
||||
* @see \phpseclib\Crypt\Base::_decryptBlock()
|
||||
* @see \phpseclib\Crypt\Base::decrypt()
|
||||
* @see self::decrypt()
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
return $this->_processBlock($in, CRYPT_DES_DECRYPT);
|
||||
return $this->_processBlock($in, self::DECRYPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts or decrypts a 64-bit block
|
||||
*
|
||||
* $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT. See
|
||||
* $mode should be either self::ENCRYPT or self::DECRYPT. See
|
||||
* {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
|
||||
* idea of what this function does.
|
||||
*
|
||||
* @see Crypt_DES::_encryptBlock()
|
||||
* @see Crypt_DES::_decryptBlock()
|
||||
* @see self::_encryptBlock()
|
||||
* @see self::_decryptBlock()
|
||||
* @access private
|
||||
* @param String $block
|
||||
* @param Integer $mode
|
||||
* @return String
|
||||
* @param string $block
|
||||
* @param int $mode
|
||||
* @return string
|
||||
*/
|
||||
function _processBlock($block, $mode)
|
||||
{
|
||||
@ -839,7 +759,7 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Creates the key schedule
|
||||
*
|
||||
* @see Crypt_Base::_setupKey()
|
||||
* @see \phpseclib\Crypt\Base::_setupKey()
|
||||
* @access private
|
||||
*/
|
||||
function _setupKey()
|
||||
@ -1320,8 +1240,8 @@ class Crypt_DES extends Crypt_Base {
|
||||
$d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F);
|
||||
|
||||
$keys[$des_round] = array(
|
||||
CRYPT_DES_ENCRYPT => array(),
|
||||
CRYPT_DES_DECRYPT => array_fill(0, 32, 0)
|
||||
self::ENCRYPT => array(),
|
||||
self::DECRYPT => array_fill(0, 32, 0)
|
||||
);
|
||||
for ($i = 0, $ki = 31; $i < 16; ++$i, $ki-= 2) {
|
||||
$c <<= $shifts[$i];
|
||||
@ -1336,35 +1256,37 @@ class Crypt_DES extends Crypt_Base {
|
||||
$pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[ $d & 0xFF];
|
||||
|
||||
// Reorder: odd bytes/even bytes. Push the result in key schedule.
|
||||
$keys[$des_round][CRYPT_DES_ENCRYPT][ ] =
|
||||
$keys[$des_round][CRYPT_DES_DECRYPT][$ki - 1] = ( $cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) |
|
||||
(($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF);
|
||||
$keys[$des_round][CRYPT_DES_ENCRYPT][ ] =
|
||||
$keys[$des_round][CRYPT_DES_DECRYPT][$ki ] = (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
|
||||
(($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF);
|
||||
$val1 = ( $cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) |
|
||||
(($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF);
|
||||
$val2 = (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
|
||||
(($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF);
|
||||
$keys[$des_round][self::ENCRYPT][ ] = $val1;
|
||||
$keys[$des_round][self::DECRYPT][$ki - 1] = $val1;
|
||||
$keys[$des_round][self::ENCRYPT][ ] = $val2;
|
||||
$keys[$des_round][self::DECRYPT][$ki ] = $val2;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($this->des_rounds) {
|
||||
case 3: // 3DES keys
|
||||
$this->keys = array(
|
||||
CRYPT_DES_ENCRYPT => array_merge(
|
||||
$keys[0][CRYPT_DES_ENCRYPT],
|
||||
$keys[1][CRYPT_DES_DECRYPT],
|
||||
$keys[2][CRYPT_DES_ENCRYPT]
|
||||
self::ENCRYPT => array_merge(
|
||||
$keys[0][self::ENCRYPT],
|
||||
$keys[1][self::DECRYPT],
|
||||
$keys[2][self::ENCRYPT]
|
||||
),
|
||||
CRYPT_DES_DECRYPT => array_merge(
|
||||
$keys[2][CRYPT_DES_DECRYPT],
|
||||
$keys[1][CRYPT_DES_ENCRYPT],
|
||||
$keys[0][CRYPT_DES_DECRYPT]
|
||||
self::DECRYPT => array_merge(
|
||||
$keys[2][self::DECRYPT],
|
||||
$keys[1][self::ENCRYPT],
|
||||
$keys[0][self::DECRYPT]
|
||||
)
|
||||
);
|
||||
break;
|
||||
// case 1: // DES keys
|
||||
default:
|
||||
$this->keys = array(
|
||||
CRYPT_DES_ENCRYPT => $keys[0][CRYPT_DES_ENCRYPT],
|
||||
CRYPT_DES_DECRYPT => $keys[0][CRYPT_DES_DECRYPT]
|
||||
self::ENCRYPT => $keys[0][self::ENCRYPT],
|
||||
self::DECRYPT => $keys[0][self::DECRYPT]
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1372,12 +1294,12 @@ class Crypt_DES extends Crypt_Base {
|
||||
/**
|
||||
* Setup the performance-optimized function for de/encrypt()
|
||||
*
|
||||
* @see Crypt_Base::_setupInlineCrypt()
|
||||
* @see \phpseclib\Crypt\Base::_setupInlineCrypt()
|
||||
* @access private
|
||||
*/
|
||||
function _setupInlineCrypt()
|
||||
{
|
||||
$lambda_functions =& Crypt_DES::_getLambdaFunctions();
|
||||
$lambda_functions =& self::_getLambdaFunctions();
|
||||
|
||||
// Engine configuration for:
|
||||
// - DES ($des_rounds == 1) or
|
||||
@ -1385,21 +1307,20 @@ class Crypt_DES extends Crypt_Base {
|
||||
$des_rounds = $this->des_rounds;
|
||||
|
||||
// We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
|
||||
// (Currently, for DES, one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit)
|
||||
// (Currently, for TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit)
|
||||
// After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one
|
||||
$gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
|
||||
|
||||
// Generation of a uniqe hash for our generated code
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
// For hi-optimized code, we create for each combination of
|
||||
// $mode, $des_rounds and $this->key its own encrypt/decrypt function.
|
||||
$code_hash = md5(str_pad("Crypt_DES, $des_rounds, {$this->mode}, ", 32, "\0") . $this->key);
|
||||
break;
|
||||
default:
|
||||
// After max 10 hi-optimized functions, we create generic
|
||||
// (still very fast.. but not ultra) functions for each $mode/$des_rounds
|
||||
// Currently 2 * 5 generic functions will be then max. possible.
|
||||
$code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
|
||||
$code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
|
||||
if ($gen_hi_opt_code) {
|
||||
// For hi-optimized code, we create for each combination of
|
||||
// $mode, $des_rounds and $this->key its own encrypt/decrypt function.
|
||||
// After max 10 hi-optimized functions, we create generic
|
||||
// (still very fast.. but not ultra) functions for each $mode/$des_rounds
|
||||
// Currently 2 * 5 generic functions will be then max. possible.
|
||||
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
// Is there a re-usable $lambda_functions in there? If not, we have to create it.
|
||||
@ -1429,8 +1350,8 @@ class Crypt_DES extends Crypt_Base {
|
||||
// No futher initialisation of the $keys schedule is necessary.
|
||||
// That is the extra performance boost.
|
||||
$k = array(
|
||||
CRYPT_DES_ENCRYPT => $this->keys[CRYPT_DES_ENCRYPT],
|
||||
CRYPT_DES_DECRYPT => $this->keys[CRYPT_DES_DECRYPT]
|
||||
self::ENCRYPT => $this->keys[self::ENCRYPT],
|
||||
self::DECRYPT => $this->keys[self::DECRYPT]
|
||||
);
|
||||
$init_encrypt = '';
|
||||
$init_decrypt = '';
|
||||
@ -1439,22 +1360,21 @@ class Crypt_DES extends Crypt_Base {
|
||||
// In generic optimized code mode, we have to use, as the best compromise [currently],
|
||||
// our key schedule as $ke/$kd arrays. (with hardcoded indexes...)
|
||||
$k = array(
|
||||
CRYPT_DES_ENCRYPT => array(),
|
||||
CRYPT_DES_DECRYPT => array()
|
||||
self::ENCRYPT => array(),
|
||||
self::DECRYPT => array()
|
||||
);
|
||||
for ($i = 0, $c = count($this->keys[CRYPT_DES_ENCRYPT]); $i < $c; ++$i) {
|
||||
$k[CRYPT_DES_ENCRYPT][$i] = '$ke[' . $i . ']';
|
||||
$k[CRYPT_DES_DECRYPT][$i] = '$kd[' . $i . ']';
|
||||
for ($i = 0, $c = count($this->keys[self::ENCRYPT]); $i < $c; ++$i) {
|
||||
$k[self::ENCRYPT][$i] = '$ke[' . $i . ']';
|
||||
$k[self::DECRYPT][$i] = '$kd[' . $i . ']';
|
||||
}
|
||||
$init_encrypt = '$ke = $self->keys[CRYPT_DES_ENCRYPT];';
|
||||
$init_decrypt = '$kd = $self->keys[CRYPT_DES_DECRYPT];';
|
||||
$init_encrypt = '$ke = $self->keys[self::ENCRYPT];';
|
||||
$init_decrypt = '$kd = $self->keys[self::DECRYPT];';
|
||||
break;
|
||||
}
|
||||
|
||||
// Creating code for en- and decryption.
|
||||
$crypt_block = array();
|
||||
foreach (array(CRYPT_DES_ENCRYPT, CRYPT_DES_DECRYPT) as $c) {
|
||||
|
||||
foreach (array(self::ENCRYPT, self::DECRYPT) as $c) {
|
||||
/* Do the initial IP permutation. */
|
||||
$crypt_block[$c] = '
|
||||
$in = unpack("N*", $in);
|
||||
@ -1521,8 +1441,8 @@ class Crypt_DES extends Crypt_Base {
|
||||
'init_crypt' => $init_crypt,
|
||||
'init_encrypt' => $init_encrypt,
|
||||
'init_decrypt' => $init_decrypt,
|
||||
'encrypt_block' => $crypt_block[CRYPT_DES_ENCRYPT],
|
||||
'decrypt_block' => $crypt_block[CRYPT_DES_DECRYPT]
|
||||
'encrypt_block' => $crypt_block[self::ENCRYPT],
|
||||
'decrypt_block' => $crypt_block[self::DECRYPT]
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -1531,6 +1451,3 @@ class Crypt_DES extends Crypt_Base {
|
||||
$this->inline_crypt = $lambda_functions[$code_hash];
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
// vim6: fdl=1:
|
||||
|
@ -1,27 +1,19 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
|
||||
* Wrapper around hash() and hash_hmac() functions supporting truncated hashes
|
||||
* such as sha256-96. Any hash algorithm returned by hash_algos() (and
|
||||
* truncated versions thereof) are supported.
|
||||
*
|
||||
* Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
|
||||
*
|
||||
* md2, md5, md5-96, sha1, sha1-96, sha256, sha384, and sha512
|
||||
*
|
||||
* 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}.}}
|
||||
* If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will
|
||||
* return the HMAC as opposed to the hash.
|
||||
*
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include('Crypt/Hash.php');
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $hash = new Crypt_Hash('sha1');
|
||||
* $hash = new \phpseclib\Crypt\Hash('sha512');
|
||||
*
|
||||
* $hash->setKey('abcdefg');
|
||||
*
|
||||
@ -29,82 +21,52 @@
|
||||
* ?>
|
||||
* </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 MMVII Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
* @category Crypt
|
||||
* @package Hash
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @copyright 2015 Andreas Fischer
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
* @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);
|
||||
/**#@-*/
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
use phpseclib\Math\BigInteger;
|
||||
use phpseclib\Exception\UnsupportedAlgorithmException;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
|
||||
*
|
||||
* @package Hash
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @version 0.1.0
|
||||
* @author Andreas Fischer <bantu@phpbb.com>
|
||||
* @access public
|
||||
* @package Crypt_Hash
|
||||
*/
|
||||
class Crypt_Hash {
|
||||
class Hash
|
||||
{
|
||||
/**
|
||||
* Byte-length of compression blocks / key (Internal HMAC)
|
||||
* Hash Parameter
|
||||
*
|
||||
* @see Crypt_Hash::setAlgorithm()
|
||||
* @var Integer
|
||||
* @see self::setHash()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $b;
|
||||
var $hashParam;
|
||||
|
||||
/**
|
||||
* Byte-length of hash output (Internal HMAC)
|
||||
*
|
||||
* @see Crypt_Hash::setHash()
|
||||
* @var Integer
|
||||
* @see self::setHash()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $l = false;
|
||||
var $length;
|
||||
|
||||
/**
|
||||
* Hash Algorithm
|
||||
*
|
||||
* @see Crypt_Hash::setHash()
|
||||
* @var String
|
||||
* @see self::setHash()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $hash;
|
||||
@ -112,17 +74,30 @@ class Crypt_Hash {
|
||||
/**
|
||||
* Key
|
||||
*
|
||||
* @see Crypt_Hash::setKey()
|
||||
* @var String
|
||||
* @see self::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key = false;
|
||||
|
||||
/**
|
||||
* Initial Hash
|
||||
*
|
||||
* Used only for sha512/*
|
||||
*
|
||||
* @see self::_sha512()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $initial = false;
|
||||
|
||||
/**
|
||||
* Outer XOR (Internal HMAC)
|
||||
*
|
||||
* @see Crypt_Hash::setKey()
|
||||
* @var String
|
||||
* Used only for sha512/*
|
||||
*
|
||||
* @see self::hash()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $opad;
|
||||
@ -130,8 +105,10 @@ class Crypt_Hash {
|
||||
/**
|
||||
* Inner XOR (Internal HMAC)
|
||||
*
|
||||
* @see Crypt_Hash::setKey()
|
||||
* @var String
|
||||
* Used only for sha512/*
|
||||
*
|
||||
* @see self::hash()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $ipad;
|
||||
@ -139,26 +116,15 @@ class Crypt_Hash {
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @param optional String $hash
|
||||
* @return Crypt_Hash
|
||||
* @param string $hash
|
||||
* @access public
|
||||
*/
|
||||
function Crypt_Hash($hash = 'sha1')
|
||||
function __construct($hash = 'sha256')
|
||||
{
|
||||
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);
|
||||
|
||||
$this->ipad = str_repeat(chr(0x36), 128);
|
||||
$this->opad = str_repeat(chr(0x5C), 128);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,421 +133,171 @@ class Crypt_Hash {
|
||||
* Keys can be of any length.
|
||||
*
|
||||
* @access public
|
||||
* @param optional String $key
|
||||
* @param 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
|
||||
* @param string $hash
|
||||
*/
|
||||
function setHash($hash)
|
||||
{
|
||||
$hash = strtolower($hash);
|
||||
$this->hashParam = $hash = strtolower($hash);
|
||||
switch ($hash) {
|
||||
case 'md2-96':
|
||||
case 'md5-96':
|
||||
case 'sha1-96':
|
||||
$this->l = 12; // 96 / 8 = 12
|
||||
case 'sha256-96':
|
||||
case 'sha512-96':
|
||||
case 'sha512/224-96':
|
||||
case 'sha512/256-96':
|
||||
$hash = substr($hash, 0, -3);
|
||||
$this->length = 12; // 96 / 8 = 12
|
||||
break;
|
||||
case 'md2':
|
||||
case 'md5':
|
||||
$this->l = 16;
|
||||
$this->length = 16;
|
||||
break;
|
||||
case 'sha1':
|
||||
$this->l = 20;
|
||||
$this->length = 20;
|
||||
break;
|
||||
case 'sha224':
|
||||
case 'sha512/224':
|
||||
$this->length = 28;
|
||||
break;
|
||||
case 'sha256':
|
||||
$this->l = 32;
|
||||
case 'sha512/256':
|
||||
$this->length = 32;
|
||||
break;
|
||||
case 'sha384':
|
||||
$this->l = 48;
|
||||
$this->length = 48;
|
||||
break;
|
||||
case 'sha512':
|
||||
$this->l = 64;
|
||||
}
|
||||
|
||||
switch ($hash) {
|
||||
case 'md2':
|
||||
$mode = CRYPT_HASH_MODE == 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;
|
||||
$this->length = 64;
|
||||
break;
|
||||
default:
|
||||
$mode = CRYPT_HASH_MODE;
|
||||
}
|
||||
|
||||
switch ( $mode ) {
|
||||
case CRYPT_HASH_MODE_MHASH:
|
||||
switch ($hash) {
|
||||
case 'md5':
|
||||
case 'md5-96':
|
||||
$this->hash = MHASH_MD5;
|
||||
break;
|
||||
case 'sha256':
|
||||
$this->hash = MHASH_SHA256;
|
||||
break;
|
||||
case 'sha1':
|
||||
case 'sha1-96':
|
||||
default:
|
||||
$this->hash = MHASH_SHA1;
|
||||
// see if the hash isn't "officially" supported see if it can
|
||||
// be "unofficially" supported and calculate the length
|
||||
// accordingly.
|
||||
if (in_array($hash, hash_algos())) {
|
||||
$this->length = strlen(hash($hash, '', true));
|
||||
break;
|
||||
}
|
||||
return;
|
||||
case CRYPT_HASH_MODE_HASH:
|
||||
switch ($hash) {
|
||||
case 'md5':
|
||||
case 'md5-96':
|
||||
$this->hash = 'md5';
|
||||
return;
|
||||
case 'md2':
|
||||
case 'sha256':
|
||||
case 'sha384':
|
||||
case 'sha512':
|
||||
$this->hash = $hash;
|
||||
return;
|
||||
case 'sha1':
|
||||
case 'sha1-96':
|
||||
default:
|
||||
$this->hash = 'sha1';
|
||||
// if the hash algorithm doens't exist maybe it's a truncated
|
||||
// hash, e.g. whirlpool-12 or some such.
|
||||
if (preg_match('#(-\d+)$#', $hash, $matches)) {
|
||||
$hash = substr($hash, 0, -strlen($matches[1]));
|
||||
if (in_array($hash, hash_algos())) {
|
||||
$this->length = abs($matches[1]) >> 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
throw new UnsupportedAlgorithmException(
|
||||
"$hash is not a supported algorithm"
|
||||
);
|
||||
}
|
||||
|
||||
switch ($hash) {
|
||||
case 'md2':
|
||||
$this->b = 16;
|
||||
$this->hash = array($this, '_md2');
|
||||
break;
|
||||
case 'md5':
|
||||
case 'md5-96':
|
||||
$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':
|
||||
case 'sha1-96':
|
||||
default:
|
||||
$this->b = 64;
|
||||
$this->hash = array($this, '_sha1');
|
||||
if ($hash == 'sha512/224' || $hash == 'sha512/256') {
|
||||
// from http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf#page=24
|
||||
$this->initial = $hash == 'sha512/256' ?
|
||||
array(
|
||||
'22312194FC2BF72C', '9F555FA3C84C64C2', '2393B86B6F53B151', '963877195940EABD',
|
||||
'96283EE2A88EFFE3', 'BE5E1E2553863992', '2B0199FC2C85B8AA', '0EB72DDC81C52CA2'
|
||||
) :
|
||||
array(
|
||||
'8C3D37C819544DA2', '73E1996689DCD4D6', '1DFAB7AE32FF9C82', '679DD514582F9FCF',
|
||||
'0F6D2B697BD44DA8', '77E36F7304C48942', '3F9D85A86A1D36C8', '1112E6AD91D692A1'
|
||||
);
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$this->initial[$i] = new BigInteger($this->initial[$i], 16);
|
||||
$this->initial[$i]->setPrecision(64);
|
||||
}
|
||||
}
|
||||
|
||||
$this->ipad = str_repeat(chr(0x36), $this->b);
|
||||
$this->opad = str_repeat(chr(0x5C), $this->b);
|
||||
$this->hash = $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the HMAC.
|
||||
*
|
||||
* @access public
|
||||
* @param String $text
|
||||
* @return String
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
function hash($text)
|
||||
{
|
||||
$mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
|
||||
switch ($this->hash) {
|
||||
case 'sha512/224':
|
||||
case 'sha512/256':
|
||||
if (empty($this->key) || !is_string($this->key)) {
|
||||
return substr(self::_sha512($text, $this->initial), 0, $this->length);
|
||||
}
|
||||
/* "Applications that use keys longer than B bytes will first hash the key using H and then use the
|
||||
resultant L byte string as the actual key to HMAC."
|
||||
|
||||
if (!empty($this->key) || is_string($this->key)) {
|
||||
switch ( $mode ) {
|
||||
case 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 ? self::_sha512($this->key, $this->initial) : $this->key;
|
||||
|
||||
-- http://tools.ietf.org/html/rfc2104#section-2 */
|
||||
$key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
|
||||
$key = str_pad($this->key, 128, chr(0)); // step 1
|
||||
$temp = $this->ipad ^ $this->key; // step 2
|
||||
$temp .= $text; // step 3
|
||||
$temp = self::_sha512($temp, $this->initial); // step 4
|
||||
$output = $this->opad ^ $this->key; // step 5
|
||||
$output.= $temp; // step 6
|
||||
$output = self::_sha512($output, $this->initial); // step 7
|
||||
|
||||
$key = str_pad($key, $this->b, chr(0)); // step 1
|
||||
$temp = $this->ipad ^ $key; // step 2
|
||||
$temp .= $text; // step 3
|
||||
$temp = call_user_func($this->hash, $temp); // step 4
|
||||
$output = $this->opad ^ $key; // step 5
|
||||
$output.= $temp; // step 6
|
||||
$output = call_user_func($this->hash, $output); // step 7
|
||||
}
|
||||
} else {
|
||||
switch ( $mode ) {
|
||||
case 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->length);
|
||||
}
|
||||
$output = !empty($this->key) || is_string($this->key) ?
|
||||
hash_hmac($this->hash, $text, $this->key, true) :
|
||||
hash($this->hash, $text, true);
|
||||
|
||||
return substr($output, 0, $this->l);
|
||||
return strlen($output) > $this->length
|
||||
? substr($output, 0, $this->length)
|
||||
: $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash length (in bytes)
|
||||
*
|
||||
* @access public
|
||||
* @return Integer
|
||||
* @return int
|
||||
*/
|
||||
function getLength()
|
||||
{
|
||||
return $this->l;
|
||||
return $this->length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for MD5
|
||||
* Pure-PHP implementation of SHA512
|
||||
*
|
||||
* @access private
|
||||
* @param String $m
|
||||
* @param string $m
|
||||
*/
|
||||
function _md5($m)
|
||||
static function _sha512($m, $hash)
|
||||
{
|
||||
return pack('H*', md5($m));
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for SHA1
|
||||
*
|
||||
* @access private
|
||||
* @param String $m
|
||||
*/
|
||||
function _sha1($m)
|
||||
{
|
||||
return pack('H*', sha1($m));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of MD2
|
||||
*
|
||||
* See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
|
||||
*
|
||||
* @access private
|
||||
* @param String $m
|
||||
*/
|
||||
function _md2($m)
|
||||
{
|
||||
static $s = array(
|
||||
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
|
||||
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
|
||||
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
|
||||
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
|
||||
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
|
||||
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
|
||||
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
|
||||
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
|
||||
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
|
||||
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
|
||||
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
|
||||
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
|
||||
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
|
||||
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
|
||||
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
|
||||
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
|
||||
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
|
||||
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
|
||||
);
|
||||
|
||||
// Step 1. Append Padding Bytes
|
||||
$pad = 16 - (strlen($m) & 0xF);
|
||||
$m.= str_repeat(chr($pad), $pad);
|
||||
|
||||
$length = strlen($m);
|
||||
|
||||
// Step 2. Append Checksum
|
||||
$c = str_repeat(chr(0), 16);
|
||||
$l = chr(0);
|
||||
for ($i = 0; $i < $length; $i+= 16) {
|
||||
for ($j = 0; $j < 16; $j++) {
|
||||
// RFC1319 incorrectly states that C[j] should be set to S[c xor L]
|
||||
//$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
|
||||
// per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j]
|
||||
$c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
|
||||
$l = $c[$j];
|
||||
}
|
||||
}
|
||||
$m.= $c;
|
||||
|
||||
$length+= 16;
|
||||
|
||||
// Step 3. Initialize MD Buffer
|
||||
$x = str_repeat(chr(0), 48);
|
||||
|
||||
// Step 4. Process Message in 16-Byte Blocks
|
||||
for ($i = 0; $i < $length; $i+= 16) {
|
||||
for ($j = 0; $j < 16; $j++) {
|
||||
$x[$j + 16] = $m[$i + $j];
|
||||
$x[$j + 32] = $x[$j + 16] ^ $x[$j];
|
||||
}
|
||||
$t = chr(0);
|
||||
for ($j = 0; $j < 18; $j++) {
|
||||
for ($k = 0; $k < 48; $k++) {
|
||||
$x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
|
||||
//$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
|
||||
}
|
||||
$t = chr(ord($t) + $j);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 5. Output
|
||||
return substr($x, 0, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of SHA256
|
||||
*
|
||||
* See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
|
||||
*
|
||||
* @access private
|
||||
* @param String $m
|
||||
*/
|
||||
function _sha256($m)
|
||||
{
|
||||
if (extension_loaded('suhosin')) {
|
||||
return pack('H*', sha256($m));
|
||||
}
|
||||
|
||||
// Initialize variables
|
||||
$hash = array(
|
||||
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
||||
);
|
||||
// Initialize table of round constants
|
||||
// (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
|
||||
static $k = array(
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
);
|
||||
|
||||
// Pre-processing
|
||||
$length = strlen($m);
|
||||
// to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
|
||||
$m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
|
||||
$m[$length] = chr(0x80);
|
||||
// we don't support hashing strings 512MB long
|
||||
$m.= pack('N2', 0, $length << 3);
|
||||
|
||||
// Process the message in successive 512-bit chunks
|
||||
$chunks = str_split($m, 64);
|
||||
foreach ($chunks as $chunk) {
|
||||
$w = array();
|
||||
for ($i = 0; $i < 16; $i++) {
|
||||
extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
|
||||
$w[] = $temp;
|
||||
}
|
||||
|
||||
// Extend the sixteen 32-bit words into sixty-four 32-bit words
|
||||
for ($i = 16; $i < 64; $i++) {
|
||||
$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')) {
|
||||
require_once('Math/BigInteger.php');
|
||||
}
|
||||
|
||||
static $init384, $init512, $k;
|
||||
static $k;
|
||||
|
||||
if (!isset($k)) {
|
||||
// Initialize variables
|
||||
$init384 = array( // initial values for SHA384
|
||||
'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
|
||||
'67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
|
||||
);
|
||||
$init512 = array( // initial values for SHA512
|
||||
'6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
|
||||
'510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
|
||||
);
|
||||
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$init384[$i] = new 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(
|
||||
@ -608,12 +324,10 @@ class Crypt_Hash {
|
||||
);
|
||||
|
||||
for ($i = 0; $i < 80; $i++) {
|
||||
$k[$i] = new Math_BigInteger($k[$i], 16);
|
||||
$k[$i] = new 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
|
||||
@ -627,7 +341,7 @@ class Crypt_Hash {
|
||||
foreach ($chunks as $chunk) {
|
||||
$w = array();
|
||||
for ($i = 0; $i < 16; $i++) {
|
||||
$temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256);
|
||||
$temp = new BigInteger(self::_string_shift($chunk, 8), 256);
|
||||
$temp->setPrecision(64);
|
||||
$w[] = $temp;
|
||||
}
|
||||
@ -648,21 +362,21 @@ class Crypt_Hash {
|
||||
);
|
||||
$s1 = $temp[0]->bitwise_xor($temp[1]);
|
||||
$s1 = $s1->bitwise_xor($temp[2]);
|
||||
$w[$i] = $w[$i - 16]->copy();
|
||||
$w[$i] = clone $w[$i - 16];
|
||||
$w[$i] = $w[$i]->add($s0);
|
||||
$w[$i] = $w[$i]->add($w[$i - 7]);
|
||||
$w[$i] = $w[$i]->add($s1);
|
||||
}
|
||||
|
||||
// Initialize hash value for this chunk
|
||||
$a = $hash[0]->copy();
|
||||
$b = $hash[1]->copy();
|
||||
$c = $hash[2]->copy();
|
||||
$d = $hash[3]->copy();
|
||||
$e = $hash[4]->copy();
|
||||
$f = $hash[5]->copy();
|
||||
$g = $hash[6]->copy();
|
||||
$h = $hash[7]->copy();
|
||||
$a = clone $hash[0];
|
||||
$b = clone $hash[1];
|
||||
$c = clone $hash[2];
|
||||
$d = clone $hash[3];
|
||||
$e = clone $hash[4];
|
||||
$f = clone $hash[5];
|
||||
$g = clone $hash[6];
|
||||
$h = clone $hash[7];
|
||||
|
||||
// Main loop
|
||||
for ($i = 0; $i < 80; $i++) {
|
||||
@ -699,13 +413,13 @@ class Crypt_Hash {
|
||||
$t1 = $t1->add($k[$i]);
|
||||
$t1 = $t1->add($w[$i]);
|
||||
|
||||
$h = $g->copy();
|
||||
$g = $f->copy();
|
||||
$f = $e->copy();
|
||||
$h = clone $g;
|
||||
$g = clone $f;
|
||||
$f = clone $e;
|
||||
$e = $d->add($t1);
|
||||
$d = $c->copy();
|
||||
$c = $b->copy();
|
||||
$b = $a->copy();
|
||||
$d = clone $c;
|
||||
$c = clone $b;
|
||||
$b = clone $a;
|
||||
$a = $t1->add($t2);
|
||||
}
|
||||
|
||||
@ -723,98 +437,24 @@ class Crypt_Hash {
|
||||
}
|
||||
|
||||
// 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)
|
||||
// (\phpseclib\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
|
||||
$temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
|
||||
$hash[4]->toBytes() . $hash[5]->toBytes();
|
||||
if ($this->l != 48) {
|
||||
$temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
|
||||
}
|
||||
$hash[4]->toBytes() . $hash[5]->toBytes() . $hash[6]->toBytes() . $hash[7]->toBytes();
|
||||
|
||||
return $temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Right Rotate
|
||||
*
|
||||
* @access private
|
||||
* @param Integer $int
|
||||
* @param Integer $amt
|
||||
* @see _sha256()
|
||||
* @return Integer
|
||||
*/
|
||||
function _rightRotate($int, $amt)
|
||||
{
|
||||
$invamt = 32 - $amt;
|
||||
$mask = (1 << $invamt) - 1;
|
||||
return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Right Shift
|
||||
*
|
||||
* @access private
|
||||
* @param Integer $int
|
||||
* @param Integer $amt
|
||||
* @see _sha256()
|
||||
* @return Integer
|
||||
*/
|
||||
function _rightShift($int, $amt)
|
||||
{
|
||||
$mask = (1 << (32 - $amt)) - 1;
|
||||
return ($int >> $amt) & $mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not
|
||||
*
|
||||
* @access private
|
||||
* @param Integer $int
|
||||
* @see _sha256()
|
||||
* @return Integer
|
||||
*/
|
||||
function _not($int)
|
||||
{
|
||||
return ~$int & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add
|
||||
*
|
||||
* _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
|
||||
* possibility of overflow exists, care has to be taken. 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
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function _string_shift(&$string, $index = 1)
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
|
@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of RC2.
|
||||
*
|
||||
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
* PHP version 5
|
||||
*
|
||||
* Useful resources are as follows:
|
||||
*
|
||||
@ -15,9 +14,9 @@
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include('Crypt/RC2.php');
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $rc2 = new Crypt_RC2();
|
||||
* $rc2 = new \phpseclib\Crypt\RC2();
|
||||
*
|
||||
* $rc2->setKey('abcdefgh');
|
||||
*
|
||||
@ -27,106 +26,28 @@
|
||||
* ?>
|
||||
* </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
|
||||
* @category Crypt
|
||||
* @package 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')) {
|
||||
require_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);
|
||||
/**#@-*/
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of RC2.
|
||||
*
|
||||
* @version 0.1.1
|
||||
* @package RC2
|
||||
* @access public
|
||||
* @package Crypt_RC2
|
||||
*/
|
||||
class Crypt_RC2 extends Crypt_Base {
|
||||
class RC2 extends Base
|
||||
{
|
||||
/**
|
||||
* Block Length of the cipher
|
||||
*
|
||||
* @see Crypt_Base::block_size
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::block_size
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $block_size = 8;
|
||||
@ -134,37 +55,48 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
/**
|
||||
* The Key
|
||||
*
|
||||
* @see Crypt_Base::key
|
||||
* @see setKey()
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::key
|
||||
* @see self::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key = "\0";
|
||||
var $key;
|
||||
|
||||
/**
|
||||
* The default password key_size used by setPassword()
|
||||
* The Original (unpadded) Key
|
||||
*
|
||||
* @see Crypt_Base::password_key_size
|
||||
* @see Crypt_Base::setPassword()
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::key
|
||||
* @see self::setKey()
|
||||
* @see self::encrypt()
|
||||
* @see self::decrypt()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $password_key_size = 16; // = 128 bits
|
||||
var $orig_key;
|
||||
|
||||
/**
|
||||
* The namespace used by the cipher for its constants.
|
||||
* Don't truncate / null pad key
|
||||
*
|
||||
* @see Crypt_Base::const_namespace
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::_clearBuffers()
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $const_namespace = 'RC2';
|
||||
var $skip_key_adjustment = true;
|
||||
|
||||
/**
|
||||
* Key Length (in bytes)
|
||||
*
|
||||
* @see \phpseclib\Crypt\RC2::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $key_length = 16; // = 128 bits
|
||||
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see Crypt_Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'rc2';
|
||||
@ -172,29 +104,40 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
/**
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see Crypt_Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 500;
|
||||
|
||||
/**
|
||||
/**
|
||||
* The key length in bits.
|
||||
*
|
||||
* @see Crypt_RC2::setKeyLength()
|
||||
* @see Crypt_RC2::setKey()
|
||||
* @var Integer
|
||||
* @see self::setKeyLength()
|
||||
* @see self::setKey()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal Should be in range [1..1024].
|
||||
* @internal Changing this value after setting the key has no effect.
|
||||
*/
|
||||
var $default_key_length = 1024;
|
||||
|
||||
/**
|
||||
* The key length in bits.
|
||||
*
|
||||
* @see self::isValidEnine()
|
||||
* @see self::setKey()
|
||||
* @var int
|
||||
* @access private
|
||||
* @internal Should be in range [1..1024].
|
||||
*/
|
||||
var $current_key_length;
|
||||
|
||||
/**
|
||||
* The Key Schedule
|
||||
*
|
||||
* @see Crypt_RC2::_setupKey()
|
||||
* @var Array
|
||||
* @see self::_setupKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $keys;
|
||||
@ -203,8 +146,8 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
* Key expansion randomization table.
|
||||
* Twice the same 256-value sequence to save a modulus in key expansion.
|
||||
*
|
||||
* @see Crypt_RC2::setKey()
|
||||
* @var Array
|
||||
* @see self::setKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $pitable = array(
|
||||
@ -277,8 +220,8 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
/**
|
||||
* Inverse key expansion randomization table.
|
||||
*
|
||||
* @see Crypt_RC2::setKey()
|
||||
* @var Array
|
||||
* @see self::setKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $invpitable = array(
|
||||
@ -319,53 +262,78 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
/**
|
||||
* 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 explictly set, CRYPT_RC2_MODE_CBC will be used.
|
||||
*
|
||||
* @see Crypt_Base::Crypt_Base()
|
||||
* @param optional Integer $mode
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function Crypt_RC2($mode = CRYPT_RC2_MODE_CBC)
|
||||
function __construct($mode)
|
||||
{
|
||||
parent::Crypt_Base($mode);
|
||||
$this->setKey('');
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length
|
||||
* Test for engine validity
|
||||
*
|
||||
* Valid key lengths are 1 to 1024.
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
switch ($engine) {
|
||||
case self::ENGINE_OPENSSL:
|
||||
if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) {
|
||||
return false;
|
||||
}
|
||||
$this->cipher_name_openssl_ecb = 'rc2-ecb';
|
||||
$this->cipher_name_openssl = 'rc2-' . $this->_openssl_translate_mode();
|
||||
}
|
||||
|
||||
return parent::isValidEngine($engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length.
|
||||
*
|
||||
* Valid key lengths are 8 to 1024.
|
||||
* Calling this function after setting the key has no effect until the next
|
||||
* Crypt_RC2::setKey() call.
|
||||
* \phpseclib\Crypt\RC2::setKey() call.
|
||||
*
|
||||
* @access public
|
||||
* @param Integer $length in bits
|
||||
* @param int $length in bits
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
if ($length >= 1 && $length <= 1024) {
|
||||
$this->default_key_length = $length;
|
||||
if ($length < 8 || $length > 1024) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported');
|
||||
}
|
||||
|
||||
$this->default_key_length = $this->current_key_length = $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current key length
|
||||
*
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
function getKeyLength()
|
||||
{
|
||||
return $this->current_key_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Keys can be of any length. RC2, itself, uses 1 to 1024 bit keys (eg.
|
||||
* Keys can be of any length. RC2, itself, uses 8 to 1024 bit keys (eg.
|
||||
* strlen($key) <= 128), however, we only use the first 128 bytes if $key
|
||||
* has more then 128 bytes in it, and set $key to a single null byte if
|
||||
* it is empty.
|
||||
@ -373,20 +341,27 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
* If the key is not explicitly set, it'll be assumed to be a single
|
||||
* null byte.
|
||||
*
|
||||
* @see Crypt_Base::setKey()
|
||||
* @see \phpseclib\Crypt\Base::setKey()
|
||||
* @access public
|
||||
* @param String $key
|
||||
* @param Integer $t1 optional Effective key length in bits.
|
||||
* @param string $key
|
||||
* @param int $t1 optional Effective key length in bits.
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKey($key, $t1 = 0)
|
||||
function setKey($key, $t1 = false)
|
||||
{
|
||||
if ($t1 <= 0) {
|
||||
$this->orig_key = $key;
|
||||
|
||||
if ($t1 === false) {
|
||||
$t1 = $this->default_key_length;
|
||||
} else if ($t1 > 1024) {
|
||||
$t1 = 1024;
|
||||
}
|
||||
|
||||
if ($t1 < 1 || $t1 > 1024) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported');
|
||||
}
|
||||
|
||||
$this->current_key_length = $t1;
|
||||
// Key byte count should be 1..128.
|
||||
$key = strlen($key) ? substr($key, 0, 128): "\x00";
|
||||
$key = strlen($key) ? substr($key, 0, 128) : "\x00";
|
||||
$t = strlen($key);
|
||||
|
||||
// The mcrypt RC2 implementation only supports effective key length
|
||||
@ -414,17 +389,64 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
// Prepare the key for mcrypt.
|
||||
$l[0] = $this->invpitable[$l[0]];
|
||||
array_unshift($l, 'C*');
|
||||
|
||||
parent::setKey(call_user_func_array('pack', $l));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a message.
|
||||
*
|
||||
* Mostly a wrapper for \phpseclib\Crypt\Base::encrypt, with some additional OpenSSL handling code
|
||||
*
|
||||
* @see self::decrypt()
|
||||
* @access public
|
||||
* @param string $plaintext
|
||||
* @return string $ciphertext
|
||||
*/
|
||||
function encrypt($plaintext)
|
||||
{
|
||||
if ($this->engine == self::ENGINE_OPENSSL) {
|
||||
$temp = $this->key;
|
||||
$this->key = $this->orig_key;
|
||||
$result = parent::encrypt($plaintext);
|
||||
$this->key = $temp;
|
||||
return $result;
|
||||
}
|
||||
|
||||
return parent::encrypt($plaintext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a message.
|
||||
*
|
||||
* Mostly a wrapper for \phpseclib\Crypt\Base::decrypt, with some additional OpenSSL handling code
|
||||
*
|
||||
* @see self::encrypt()
|
||||
* @access public
|
||||
* @param string $ciphertext
|
||||
* @return string $plaintext
|
||||
*/
|
||||
function decrypt($ciphertext)
|
||||
{
|
||||
if ($this->engine == self::ENGINE_OPENSSL) {
|
||||
$temp = $this->key;
|
||||
$this->key = $this->orig_key;
|
||||
$result = parent::decrypt($ciphertext);
|
||||
$this->key = $temp;
|
||||
return $result;
|
||||
}
|
||||
|
||||
return parent::decrypt($ciphertext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a block
|
||||
*
|
||||
* @see Crypt_Base::_encryptBlock()
|
||||
* @see Crypt_Base::encrypt()
|
||||
* @see \phpseclib\Crypt\Base::_encryptBlock()
|
||||
* @see \phpseclib\Crypt\Base::encrypt()
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
@ -445,8 +467,8 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
$r3 = (($r3 + $keys[$j++] + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
|
||||
$r3 |= $r3 >> 16;
|
||||
|
||||
if ($j == $limit) {
|
||||
if ($limit == 64) {
|
||||
if ($j === $limit) {
|
||||
if ($limit === 64) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -465,11 +487,11 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
/**
|
||||
* Decrypts a block
|
||||
*
|
||||
* @see Crypt_Base::_decryptBlock()
|
||||
* @see Crypt_Base::decrypt()
|
||||
* @see \phpseclib\Crypt\Base::_decryptBlock()
|
||||
* @see \phpseclib\Crypt\Base::decrypt()
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
@ -490,8 +512,8 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
$r0 = ($r0 | ($r0 << 16)) >> 1;
|
||||
$r0 = ($r0 - $keys[--$j] - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;
|
||||
|
||||
if ($j == $limit) {
|
||||
if (!$limit) {
|
||||
if ($j === $limit) {
|
||||
if ($limit === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -507,15 +529,34 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
return pack('vvvv', $r0, $r1, $r2, $r3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the \phpseclib\Crypt\Base::ENGINE_MCRYPT $engine
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::_setupMcrypt()
|
||||
* @access private
|
||||
*/
|
||||
function _setupMcrypt()
|
||||
{
|
||||
if (!isset($this->key)) {
|
||||
$this->setKey('');
|
||||
}
|
||||
|
||||
parent::_setupMcrypt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the key schedule
|
||||
*
|
||||
* @see Crypt_Base::_setupKey()
|
||||
* @see \phpseclib\Crypt\Base::_setupKey()
|
||||
* @access private
|
||||
*/
|
||||
function _setupKey()
|
||||
{
|
||||
// Key has already been expanded in Crypt_RC2::setKey():
|
||||
if (!isset($this->key)) {
|
||||
$this->setKey('');
|
||||
}
|
||||
|
||||
// Key has already been expanded in \phpseclib\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));
|
||||
@ -527,24 +568,24 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
/**
|
||||
* Setup the performance-optimized function for de/encrypt()
|
||||
*
|
||||
* @see Crypt_Base::_setupInlineCrypt()
|
||||
* @see \phpseclib\Crypt\Base::_setupInlineCrypt()
|
||||
* @access private
|
||||
*/
|
||||
function _setupInlineCrypt()
|
||||
{
|
||||
$lambda_functions = &Crypt_RC2::_getLambdaFunctions();
|
||||
$lambda_functions =& self::_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 . ']';
|
||||
}
|
||||
}
|
||||
// (Currently, for Crypt_RC2, one generated $lambda_function cost on php5.5@32bit ~60kb unfreeable mem and ~100kb on php5.5@64bit)
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
|
||||
$code_hash = md5(str_pad("Crypt_RC2, {$this->mode}, ", 32, "\0") . implode(',', $keys));
|
||||
// Generation of a uniqe hash for our generated code
|
||||
$code_hash = "Crypt_RC2, {$this->mode}";
|
||||
if ($gen_hi_opt_code) {
|
||||
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
// Is there a re-usable $lambda_functions in there?
|
||||
// If not, we have to create it.
|
||||
@ -552,6 +593,16 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
// Init code for both, encrypt and decrypt.
|
||||
$init_crypt = '$keys = $self->keys;';
|
||||
|
||||
switch (true) {
|
||||
case $gen_hi_opt_code:
|
||||
$keys = $this->keys;
|
||||
default:
|
||||
$keys = array();
|
||||
foreach ($this->keys as $k => $v) {
|
||||
$keys[$k] = '$keys[' . $k . ']';
|
||||
}
|
||||
}
|
||||
|
||||
// $in is the current 8 bytes block which has to be en/decrypt
|
||||
$encrypt_block = $decrypt_block = '
|
||||
$in = unpack("v4", $in);
|
||||
@ -582,8 +633,8 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
|
||||
$r3 |= $r3 >> 16;';
|
||||
|
||||
if ($j == $limit) {
|
||||
if ($limit == 64) {
|
||||
if ($j === $limit) {
|
||||
if ($limit === 64) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -620,8 +671,8 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
$r0 = ($r0 - ' . $keys[--$j] . ' -
|
||||
((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;';
|
||||
|
||||
if ($j == $limit) {
|
||||
if (!$limit) {
|
||||
if ($j === $limit) {
|
||||
if ($limit === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -651,6 +702,3 @@ class Crypt_RC2 extends Crypt_Base {
|
||||
$this->inline_crypt = $lambda_functions[$code_hash];
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
// vim6: fdl=1:
|
||||
|
@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of RC4.
|
||||
*
|
||||
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
* PHP version 5
|
||||
*
|
||||
* Useful resources are as follows:
|
||||
*
|
||||
@ -19,9 +18,9 @@
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include('Crypt/RC4.php');
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $rc4 = new Crypt_RC4();
|
||||
* $rc4 = new \phpseclib\Crypt\RC4();
|
||||
*
|
||||
* $rc4->setKey('abcdefgh');
|
||||
*
|
||||
@ -35,109 +34,59 @@
|
||||
* ?>
|
||||
* </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 MMVII Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
* @category Crypt
|
||||
* @package 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')) {
|
||||
require_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);
|
||||
/**#@-*/
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of RC4.
|
||||
*
|
||||
* @package RC4
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @version 0.1.0
|
||||
* @access public
|
||||
* @package Crypt_RC4
|
||||
*/
|
||||
class Crypt_RC4 extends Crypt_Base {
|
||||
class RC4 extends Base
|
||||
{
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see \phpseclib\Crypt\RC4::_crypt()
|
||||
*/
|
||||
const ENCRYPT = 0;
|
||||
const DECRYPT = 1;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Block Length of the cipher
|
||||
*
|
||||
* RC4 is a stream cipher
|
||||
* RC4 is a stream cipher
|
||||
* so we the block_size to 0
|
||||
*
|
||||
* @see Crypt_Base::block_size
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::block_size
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $block_size = 0;
|
||||
|
||||
/**
|
||||
* The default password key_size used by setPassword()
|
||||
* Key Length (in bytes)
|
||||
*
|
||||
* @see Crypt_Base::password_key_size
|
||||
* @see Crypt_Base::setPassword()
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\RC4::setKeyLength()
|
||||
* @var int
|
||||
* @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';
|
||||
|
||||
var $key_length = 128; // = 1024 bits
|
||||
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see Crypt_Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'arcfour';
|
||||
@ -145,7 +94,7 @@ class Crypt_RC4 extends Crypt_Base {
|
||||
/**
|
||||
* Holds whether performance-optimized $inline_crypt() can/should be used.
|
||||
*
|
||||
* @see Crypt_Base::inline_crypt
|
||||
* @see \phpseclib\Crypt\Base::inline_crypt
|
||||
* @var mixed
|
||||
* @access private
|
||||
*/
|
||||
@ -154,8 +103,8 @@ class Crypt_RC4 extends Crypt_Base {
|
||||
/**
|
||||
* The Key
|
||||
*
|
||||
* @see Crypt_RC4::setKey()
|
||||
* @var String
|
||||
* @see self::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key = "\0";
|
||||
@ -163,8 +112,8 @@ class Crypt_RC4 extends Crypt_Base {
|
||||
/**
|
||||
* The Key Stream for decryption and encryption
|
||||
*
|
||||
* @see Crypt_RC4::setKey()
|
||||
* @var Array
|
||||
* @see self::setKey()
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $stream;
|
||||
@ -172,107 +121,167 @@ class Crypt_RC4 extends Crypt_Base {
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
*
|
||||
* @see Crypt_Base::Crypt_Base()
|
||||
* @return Crypt_RC4
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @return \phpseclib\Crypt\RC4
|
||||
* @access public
|
||||
*/
|
||||
function Crypt_RC4()
|
||||
function __construct()
|
||||
{
|
||||
parent::Crypt_Base(CRYPT_MODE_STREAM);
|
||||
parent::__construct(Base::MODE_STREAM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy function.
|
||||
* Test for engine validity
|
||||
*
|
||||
* 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().
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* [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()
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
function setIV($iv)
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
switch ($engine) {
|
||||
case Base::ENGINE_OPENSSL:
|
||||
switch (strlen($this->key)) {
|
||||
case 5:
|
||||
$this->cipher_name_openssl = 'rc4-40';
|
||||
break;
|
||||
case 8:
|
||||
$this->cipher_name_openssl = 'rc4-64';
|
||||
break;
|
||||
case 16:
|
||||
$this->cipher_name_openssl = 'rc4';
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return parent::isValidEngine($engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* RC4 does not use an IV
|
||||
*
|
||||
* @access public
|
||||
* @see Crypt_Base::setKey()
|
||||
* @param String $key
|
||||
* @return bool
|
||||
*/
|
||||
function usesIV()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length
|
||||
*
|
||||
* Keys can be between 1 and 256 bytes long.
|
||||
*
|
||||
* @access public
|
||||
* @param int $length
|
||||
* @throws \LengthException if the key length is invalid
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
if ($length < 8 || $length > 2048) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 256 bytes are supported');
|
||||
}
|
||||
|
||||
$this->key_length = $length >> 3;
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length
|
||||
*
|
||||
* Keys can be between 1 and 256 bytes long.
|
||||
*
|
||||
* @access public
|
||||
* @param int $length
|
||||
* @throws \LengthException if the key length is invalid
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
parent::setKey(substr($key, 0, 256));
|
||||
$length = strlen($key);
|
||||
if ($length < 1 || $length > 256) {
|
||||
throw new \LengthException('Key size of ' . $length . ' bytes is not supported by RC4. Keys must be between 1 and 256 bytes long');
|
||||
}
|
||||
|
||||
parent::setKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a message.
|
||||
*
|
||||
* @see Crypt_Base::decrypt()
|
||||
* @see Crypt_RC4::_crypt()
|
||||
* @see \phpseclib\Crypt\Base::decrypt()
|
||||
* @see self::_crypt()
|
||||
* @access public
|
||||
* @param String $plaintext
|
||||
* @return String $ciphertext
|
||||
* @param string $plaintext
|
||||
* @return string $ciphertext
|
||||
*/
|
||||
function encrypt($plaintext)
|
||||
{
|
||||
if ($this->engine == CRYPT_MODE_MCRYPT) {
|
||||
if ($this->engine != Base::ENGINE_INTERNAL) {
|
||||
return parent::encrypt($plaintext);
|
||||
}
|
||||
return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT);
|
||||
return $this->_crypt($plaintext, self::ENCRYPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a message.
|
||||
*
|
||||
* $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
|
||||
* Atleast if the continuous buffer is disabled.
|
||||
* At least if the continuous buffer is disabled.
|
||||
*
|
||||
* @see Crypt_Base::encrypt()
|
||||
* @see Crypt_RC4::_crypt()
|
||||
* @see \phpseclib\Crypt\Base::encrypt()
|
||||
* @see self::_crypt()
|
||||
* @access public
|
||||
* @param String $ciphertext
|
||||
* @return String $plaintext
|
||||
* @param string $ciphertext
|
||||
* @return string $plaintext
|
||||
*/
|
||||
function decrypt($ciphertext)
|
||||
{
|
||||
if ($this->engine == CRYPT_MODE_MCRYPT) {
|
||||
if ($this->engine != Base::ENGINE_INTERNAL) {
|
||||
return parent::decrypt($ciphertext);
|
||||
}
|
||||
return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT);
|
||||
return $this->_crypt($ciphertext, self::DECRYPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param string $in
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
// RC4 does not utilize this method
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param string $in
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
// RC4 does not utilize this method
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the key (expansion)
|
||||
*
|
||||
* @see Crypt_Base::_setupKey()
|
||||
* @see \phpseclib\Crypt\Base::_setupKey()
|
||||
* @access private
|
||||
*/
|
||||
function _setupKey()
|
||||
{
|
||||
$key = $this->key;
|
||||
$keyLength = strlen($key);
|
||||
$keyStream = array();
|
||||
for ($i = 0; $i < 256; $i++) {
|
||||
$keyStream[$i] = $i;
|
||||
}
|
||||
$keyStream = range(0, 255);
|
||||
$j = 0;
|
||||
for ($i = 0; $i < 256; $i++) {
|
||||
$j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
|
||||
@ -282,7 +291,7 @@ class Crypt_RC4 extends Crypt_Base {
|
||||
}
|
||||
|
||||
$this->stream = array();
|
||||
$this->stream[CRYPT_RC4_DECRYPT] = $this->stream[CRYPT_RC4_ENCRYPT] = array(
|
||||
$this->stream[self::DECRYPT] = $this->stream[self::ENCRYPT] = array(
|
||||
0, // index $i
|
||||
0, // index $j
|
||||
$keyStream
|
||||
@ -292,12 +301,12 @@ class Crypt_RC4 extends Crypt_Base {
|
||||
/**
|
||||
* Encrypts or decrypts a message.
|
||||
*
|
||||
* @see Crypt_RC4::encrypt()
|
||||
* @see Crypt_RC4::decrypt()
|
||||
* @see self::encrypt()
|
||||
* @see self::decrypt()
|
||||
* @access private
|
||||
* @param String $text
|
||||
* @param Integer $mode
|
||||
* @return String $text
|
||||
* @param string $text
|
||||
* @param int $mode
|
||||
* @return string $text
|
||||
*/
|
||||
function _crypt($text, $mode)
|
||||
{
|
||||
@ -326,12 +335,9 @@ class Crypt_RC4 extends Crypt_Base {
|
||||
|
||||
$keyStream[$i] = $ksj;
|
||||
$keyStream[$j] = $ksi;
|
||||
$text[$k] = chr(ord($text[$k]) ^ $keyStream[($ksj + $ksi) & 255]);
|
||||
$text[$k] = $text[$k] ^ chr($keyStream[($ksj + $ksi) & 255]);
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
// vim6: fdl=1:
|
||||
|
File diff suppressed because it is too large
Load Diff
224
plugins/OStatus/extlib/phpseclib/Crypt/RSA/MSBLOB.php
Normal file
224
plugins/OStatus/extlib/phpseclib/Crypt/RSA/MSBLOB.php
Normal file
@ -0,0 +1,224 @@
|
||||
<?php
|
||||
/**
|
||||
* Miccrosoft BLOB Formatted RSA Key Handler
|
||||
*
|
||||
* More info:
|
||||
*
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375601(v=vs.85).aspx
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* Microsoft BLOB Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class MSBLOB
|
||||
{
|
||||
/**#@+
|
||||
* @access private
|
||||
*/
|
||||
/**
|
||||
* Public/Private Key Pair
|
||||
*/
|
||||
const PRIVATEKEYBLOB = 0x7;
|
||||
/**
|
||||
* Public Key
|
||||
*/
|
||||
const PUBLICKEYBLOB = 0x6;
|
||||
/**
|
||||
* Public Key
|
||||
*/
|
||||
const PUBLICKEYBLOBEX = 0xA;
|
||||
/**
|
||||
* RSA public key exchange algorithm
|
||||
*/
|
||||
const CALG_RSA_KEYX = 0x0000A400;
|
||||
/**
|
||||
* RSA public key exchange algorithm
|
||||
*/
|
||||
const CALG_RSA_SIGN = 0x00002400;
|
||||
/**
|
||||
* Public Key
|
||||
*/
|
||||
const RSA1 = 0x31415352;
|
||||
/**
|
||||
* Private Key
|
||||
*/
|
||||
const RSA2 = 0x32415352;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$key = Base64::decode($key);
|
||||
|
||||
if (!is_string($key) || strlen($key) < 20) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// PUBLICKEYSTRUC publickeystruc
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx
|
||||
extract(unpack('atype/aversion/vreserved/Valgo', self::_string_shift($key, 8)));
|
||||
switch (ord($type)) {
|
||||
case self::PUBLICKEYBLOB:
|
||||
case self::PUBLICKEYBLOBEX:
|
||||
$publickey = true;
|
||||
break;
|
||||
case self::PRIVATEKEYBLOB:
|
||||
$publickey = false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
$components = array('isPublicKey' => $publickey);
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx
|
||||
switch ($algo) {
|
||||
case self::CALG_RSA_KEYX:
|
||||
case self::CALG_RSA_SIGN:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// RSAPUBKEY rsapubkey
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa387685(v=vs.85).aspx
|
||||
// could do V for pubexp but that's unsigned 32-bit whereas some PHP installs only do signed 32-bit
|
||||
extract(unpack('Vmagic/Vbitlen/a4pubexp', self::_string_shift($key, 12)));
|
||||
switch ($magic) {
|
||||
case self::RSA2:
|
||||
$components['isPublicKey'] = false;
|
||||
case self::RSA1:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
$baseLength = $bitlen / 16;
|
||||
if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256);
|
||||
// BYTE modulus[rsapubkey.bitlen/8]
|
||||
$components['modulus'] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 8)), 256);
|
||||
|
||||
if ($publickey) {
|
||||
return $components;
|
||||
}
|
||||
|
||||
$components['isPublicKey'] = false;
|
||||
|
||||
// BYTE prime1[rsapubkey.bitlen/16]
|
||||
$components['primes'] = array(1 => new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256));
|
||||
// BYTE prime2[rsapubkey.bitlen/16]
|
||||
$components['primes'][] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256);
|
||||
// BYTE exponent1[rsapubkey.bitlen/16]
|
||||
$components['exponents'] = array(1 => new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256));
|
||||
// BYTE exponent2[rsapubkey.bitlen/16]
|
||||
$components['exponents'][] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256);
|
||||
// BYTE coefficient[rsapubkey.bitlen/16]
|
||||
$components['coefficients'] = array(2 => new BigInteger(strrev(self::_string_shift($key, $bitlen / 16)), 256));
|
||||
if (isset($components['privateExponent'])) {
|
||||
$components['publicExponent'] = $components['privateExponent'];
|
||||
}
|
||||
// BYTE privateExponent[rsapubkey.bitlen/8]
|
||||
$components['privateExponent'] = new BigInteger(strrev(self::_string_shift($key, $bitlen / 8)), 256);
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
$n = strrev($n->toBytes());
|
||||
$e = str_pad(strrev($e->toBytes()), 4, "\0");
|
||||
$key = pack('aavV', chr(self::PRIVATEKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX);
|
||||
$key.= pack('VVa*', self::RSA2, 8 * strlen($n), $e);
|
||||
$key.= $n;
|
||||
$key.= strrev($primes[1]->toBytes());
|
||||
$key.= strrev($primes[2]->toBytes());
|
||||
$key.= strrev($exponents[1]->toBytes());
|
||||
$key.= strrev($exponents[2]->toBytes());
|
||||
$key.= strrev($coefficients[1]->toBytes());
|
||||
$key.= strrev($d->toBytes());
|
||||
|
||||
return Base64::encode($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$n = strrev($n->toBytes());
|
||||
$e = str_pad(strrev($e->toBytes()), 4, "\0");
|
||||
$key = pack('aavV', chr(self::PUBLICKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX);
|
||||
$key.= pack('VVa*', self::RSA1, 8 * strlen($n), $e);
|
||||
$key.= $n;
|
||||
|
||||
return Base64::encode($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
}
|
141
plugins/OStatus/extlib/phpseclib/Crypt/RSA/OpenSSH.php
Normal file
141
plugins/OStatus/extlib/phpseclib/Crypt/RSA/OpenSSH.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* OpenSSH Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Place in $HOME/.ssh/authorized_keys
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* OpenSSH Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class OpenSSH
|
||||
{
|
||||
/**
|
||||
* Default comment
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
static $comment = 'phpseclib-generated-key';
|
||||
|
||||
/**
|
||||
* Sets the default comment
|
||||
*
|
||||
* @access public
|
||||
* @param string $comment
|
||||
*/
|
||||
static function setComment($comment)
|
||||
{
|
||||
self::$comment = str_replace(array("\r", "\n"), '', $comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parts = explode(' ', $key, 3);
|
||||
|
||||
$key = isset($parts[1]) ? Base64::decode($parts[1]) : Base64::decode($parts[0]);
|
||||
if ($key === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$comment = isset($parts[2]) ? $parts[2] : false;
|
||||
|
||||
if (substr($key, 0, 11) != "\0\0\0\7ssh-rsa") {
|
||||
return false;
|
||||
}
|
||||
self::_string_shift($key, 11);
|
||||
if (strlen($key) <= 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', self::_string_shift($key, 4)));
|
||||
if (strlen($key) <= $length) {
|
||||
return false;
|
||||
}
|
||||
$publicExponent = new BigInteger(self::_string_shift($key, $length), -256);
|
||||
if (strlen($key) <= 4) {
|
||||
return false;
|
||||
}
|
||||
extract(unpack('Nlength', self::_string_shift($key, 4)));
|
||||
if (strlen($key) != $length) {
|
||||
return false;
|
||||
}
|
||||
$modulus = new BigInteger(self::_string_shift($key, $length), -256);
|
||||
|
||||
return array(
|
||||
'isPublicKey' => true,
|
||||
'modulus' => $modulus,
|
||||
'publicExponent' => $publicExponent,
|
||||
'comment' => $comment
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$publicExponent = $e->toBytes(true);
|
||||
$modulus = $n->toBytes(true);
|
||||
|
||||
// from <http://tools.ietf.org/html/rfc4253#page-15>:
|
||||
// string "ssh-rsa"
|
||||
// mpint e
|
||||
// mpint n
|
||||
$RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
|
||||
$RSAPublicKey = 'ssh-rsa ' . Base64::encode($RSAPublicKey) . ' ' . self::$comment;
|
||||
|
||||
return $RSAPublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
}
|
487
plugins/OStatus/extlib/phpseclib/Crypt/RSA/PKCS.php
Normal file
487
plugins/OStatus/extlib/phpseclib/Crypt/RSA/PKCS.php
Normal file
@ -0,0 +1,487 @@
|
||||
<?php
|
||||
/**
|
||||
* PKCS Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use ParagonIE\ConstantTime\Hex;
|
||||
use phpseclib\Crypt\AES;
|
||||
use phpseclib\Crypt\Base;
|
||||
use phpseclib\Crypt\DES;
|
||||
use phpseclib\Crypt\TripleDES;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PKCS Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
abstract class PKCS
|
||||
{
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see \phpseclib\Crypt\RSA::createKey()
|
||||
*/
|
||||
/**
|
||||
* ASN1 Integer
|
||||
*/
|
||||
const ASN1_INTEGER = 2;
|
||||
/**
|
||||
* ASN1 Bit String
|
||||
*/
|
||||
const ASN1_BITSTRING = 3;
|
||||
/**
|
||||
* ASN1 Octet String
|
||||
*/
|
||||
const ASN1_OCTETSTRING = 4;
|
||||
/**
|
||||
* ASN1 Object Identifier
|
||||
*/
|
||||
const ASN1_OBJECT = 6;
|
||||
/**
|
||||
* ASN1 Sequence (with the constucted bit set)
|
||||
*/
|
||||
const ASN1_SEQUENCE = 48;
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
*/
|
||||
/**
|
||||
* Auto-detect the format
|
||||
*/
|
||||
const MODE_ANY = 0;
|
||||
/**
|
||||
* Require base64-encoded PEM's be supplied
|
||||
*/
|
||||
const MODE_PEM = 1;
|
||||
/**
|
||||
* Require raw DER's be supplied
|
||||
*/
|
||||
const MODE_DER = 2;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Is the key a base-64 encoded PEM, DER or should it be auto-detected?
|
||||
*
|
||||
* @access private
|
||||
* @param int
|
||||
*/
|
||||
static $format = self::MODE_ANY;
|
||||
|
||||
/**
|
||||
* Returns the mode constant corresponding to the mode string
|
||||
*
|
||||
* @access public
|
||||
* @param string $mode
|
||||
* @return int
|
||||
* @throws \UnexpectedValueException if the block cipher mode is unsupported
|
||||
*/
|
||||
static function getEncryptionMode($mode)
|
||||
{
|
||||
switch ($mode) {
|
||||
case 'CBC':
|
||||
return Base::MODE_CBC;
|
||||
case 'ECB':
|
||||
return Base::MODE_ECB;
|
||||
case 'CFB':
|
||||
return Base::MODE_CFB;
|
||||
case 'OFB':
|
||||
return Base::MODE_OFB;
|
||||
case 'CTR':
|
||||
return Base::MODE_CTR;
|
||||
}
|
||||
throw new \UnexpectedValueException('Unsupported block cipher mode of operation');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cipher object corresponding to a string
|
||||
*
|
||||
* @access public
|
||||
* @param string $algo
|
||||
* @return string
|
||||
* @throws \UnexpectedValueException if the encryption algorithm is unsupported
|
||||
*/
|
||||
static function getEncryptionObject($algo)
|
||||
{
|
||||
$modes = '(CBC|ECB|CFB|OFB|CTR)';
|
||||
switch (true) {
|
||||
case preg_match("#^AES-(128|192|256)-$modes$#", $algo, $matches):
|
||||
$cipher = new AES(self::getEncryptionMode($matches[2]));
|
||||
$cipher->setKeyLength($matches[1]);
|
||||
return $cipher;
|
||||
case preg_match("#^DES-EDE3-$modes$#", $algo, $matches):
|
||||
return new TripleDES(self::getEncryptionMode($matches[1]));
|
||||
case preg_match("#^DES-$modes$#", $algo, $matches):
|
||||
return new DES(self::getEncryptionMode($matches[1]));
|
||||
default:
|
||||
throw new \UnexpectedValueException('Unsupported encryption algorithmn');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a symmetric key for PKCS#1 keys
|
||||
*
|
||||
* @access public
|
||||
* @param string $password
|
||||
* @param string $iv
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
static function generateSymmetricKey($password, $iv, $length)
|
||||
{
|
||||
$symkey = '';
|
||||
$iv = substr($iv, 0, 8);
|
||||
while (strlen($symkey) < $length) {
|
||||
$symkey.= md5($symkey . $password . $iv, true);
|
||||
}
|
||||
return substr($symkey, 0, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$components = array('isPublicKey' => strpos($key, 'PUBLIC') !== false);
|
||||
|
||||
/* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is
|
||||
"outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to
|
||||
protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding
|
||||
two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here:
|
||||
|
||||
http://tools.ietf.org/html/rfc1421#section-4.6.1.1
|
||||
http://tools.ietf.org/html/rfc1421#section-4.6.1.3
|
||||
|
||||
DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell.
|
||||
DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation
|
||||
function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's
|
||||
own implementation. ie. the implementation *is* the standard and any bugs that may exist in that
|
||||
implementation are part of the standard, as well.
|
||||
|
||||
* OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */
|
||||
if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) {
|
||||
$iv = Hex::decode(trim($matches[2]));
|
||||
// remove the Proc-Type / DEK-Info sections as they're no longer needed
|
||||
$key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key);
|
||||
$ciphertext = self::_extractBER($key);
|
||||
if ($ciphertext === false) {
|
||||
$ciphertext = $key;
|
||||
}
|
||||
$crypto = self::getEncryptionObject($matches[1]);
|
||||
$crypto->setKey(self::generateSymmetricKey($password, $iv, $crypto->getKeyLength() >> 3));
|
||||
$crypto->setIV($iv);
|
||||
$key = $crypto->decrypt($ciphertext);
|
||||
if ($key === false) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (self::$format != self::MODE_DER) {
|
||||
$decoded = self::_extractBER($key);
|
||||
if ($decoded !== false) {
|
||||
$key = $decoded;
|
||||
} elseif (self::$format == self::MODE_PEM) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
if (self::_decodeLength($key) != strlen($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$tag = ord(self::_string_shift($key));
|
||||
/* intended for keys for which OpenSSL's asn1parse returns the following:
|
||||
|
||||
0:d=0 hl=4 l= 631 cons: SEQUENCE
|
||||
4:d=1 hl=2 l= 1 prim: INTEGER :00
|
||||
7:d=1 hl=2 l= 13 cons: SEQUENCE
|
||||
9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
|
||||
20:d=2 hl=2 l= 0 prim: NULL
|
||||
22:d=1 hl=4 l= 609 prim: OCTET STRING
|
||||
|
||||
ie. PKCS8 keys */
|
||||
|
||||
if ($tag == self::ASN1_INTEGER && substr($key, 0, 3) == "\x01\x00\x30") {
|
||||
self::_string_shift($key, 3);
|
||||
$tag = self::ASN1_SEQUENCE;
|
||||
}
|
||||
|
||||
if ($tag == self::ASN1_SEQUENCE) {
|
||||
$temp = self::_string_shift($key, self::_decodeLength($key));
|
||||
if (ord(self::_string_shift($temp)) != self::ASN1_OBJECT) {
|
||||
return false;
|
||||
}
|
||||
$length = self::_decodeLength($temp);
|
||||
switch (self::_string_shift($temp, $length)) {
|
||||
case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption
|
||||
break;
|
||||
case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": // pbeWithMD5AndDES-CBC
|
||||
/*
|
||||
PBEParameter ::= SEQUENCE {
|
||||
salt OCTET STRING (SIZE(8)),
|
||||
iterationCount INTEGER }
|
||||
*/
|
||||
if (ord(self::_string_shift($temp)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
if (self::_decodeLength($temp) != strlen($temp)) {
|
||||
return false;
|
||||
}
|
||||
self::_string_shift($temp); // assume it's an octet string
|
||||
$salt = self::_string_shift($temp, self::_decodeLength($temp));
|
||||
if (ord(self::_string_shift($temp)) != self::ASN1_INTEGER) {
|
||||
return false;
|
||||
}
|
||||
self::_decodeLength($temp);
|
||||
list(, $iterationCount) = unpack('N', str_pad($temp, 4, chr(0), STR_PAD_LEFT));
|
||||
self::_string_shift($key); // assume it's an octet string
|
||||
$length = self::_decodeLength($key);
|
||||
if (strlen($key) != $length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$crypto = new DES(DES::MODE_CBC);
|
||||
$crypto->setPassword($password, 'pbkdf1', 'md5', $salt, $iterationCount);
|
||||
$key = $crypto->decrypt($key);
|
||||
if ($key === false) {
|
||||
return false;
|
||||
}
|
||||
return self::load($key);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
/* intended for keys for which OpenSSL's asn1parse returns the following:
|
||||
|
||||
0:d=0 hl=4 l= 290 cons: SEQUENCE
|
||||
4:d=1 hl=2 l= 13 cons: SEQUENCE
|
||||
6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
|
||||
17:d=2 hl=2 l= 0 prim: NULL
|
||||
19:d=1 hl=4 l= 271 prim: BIT STRING */
|
||||
$tag = ord(self::_string_shift($key)); // skip over the BIT STRING / OCTET STRING tag
|
||||
self::_decodeLength($key); // skip over the BIT STRING / OCTET STRING length
|
||||
// "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of
|
||||
// unused bits in the final subsequent octet. The number shall be in the range zero to seven."
|
||||
// -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2)
|
||||
if ($tag == self::ASN1_BITSTRING) {
|
||||
self::_string_shift($key);
|
||||
}
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
if (self::_decodeLength($key) != strlen($key)) {
|
||||
return false;
|
||||
}
|
||||
$tag = ord(self::_string_shift($key));
|
||||
}
|
||||
if ($tag != self::ASN1_INTEGER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$length = self::_decodeLength($key);
|
||||
$temp = self::_string_shift($key, $length);
|
||||
if (strlen($temp) != 1 || ord($temp) > 2) {
|
||||
$components['modulus'] = new BigInteger($temp, 256);
|
||||
self::_string_shift($key); // skip over self::ASN1_INTEGER
|
||||
$length = self::_decodeLength($key);
|
||||
$components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
|
||||
return $components;
|
||||
}
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_INTEGER) {
|
||||
return false;
|
||||
}
|
||||
$length = self::_decodeLength($key);
|
||||
$components['modulus'] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['publicExponent'] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['privateExponent'] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['primes'] = array(1 => new BigInteger(self::_string_shift($key, $length), 256));
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['primes'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['exponents'] = array(1 => new BigInteger(self::_string_shift($key, $length), 256));
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['exponents'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['coefficients'] = array(2 => new BigInteger(self::_string_shift($key, $length), 256));
|
||||
|
||||
if (!empty($key)) {
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
self::_decodeLength($key);
|
||||
while (!empty($key)) {
|
||||
if (ord(self::_string_shift($key)) != self::ASN1_SEQUENCE) {
|
||||
return false;
|
||||
}
|
||||
self::_decodeLength($key);
|
||||
$key = substr($key, 1);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['primes'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['exponents'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
self::_string_shift($key);
|
||||
$length = self::_decodeLength($key);
|
||||
$components['coefficients'][] = new BigInteger(self::_string_shift($key, $length), 256);
|
||||
}
|
||||
}
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Require base64-encoded PEM's be supplied
|
||||
*
|
||||
* @see self::load()
|
||||
* @access public
|
||||
*/
|
||||
static function requirePEM()
|
||||
{
|
||||
self::$format = self::MODE_PEM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Require raw DER's be supplied
|
||||
*
|
||||
* @see self::load()
|
||||
* @access public
|
||||
*/
|
||||
static function requireDER()
|
||||
{
|
||||
self::$format = self::MODE_DER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept any format and auto detect the format
|
||||
*
|
||||
* This is the default setting
|
||||
*
|
||||
* @see self::load()
|
||||
* @access public
|
||||
*/
|
||||
static function requireAny()
|
||||
{
|
||||
self::$format = self::MODE_ANY;
|
||||
}
|
||||
|
||||
/**
|
||||
* DER-decode the length
|
||||
*
|
||||
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
|
||||
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
|
||||
*
|
||||
* @access private
|
||||
* @param string $string
|
||||
* @return int
|
||||
*/
|
||||
static function _decodeLength(&$string)
|
||||
{
|
||||
$length = ord(self::_string_shift($string));
|
||||
if ($length & 0x80) { // definite length, long form
|
||||
$length&= 0x7F;
|
||||
$temp = self::_string_shift($string, $length);
|
||||
list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
|
||||
}
|
||||
return $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* DER-encode the length
|
||||
*
|
||||
* DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
|
||||
* {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
|
||||
*
|
||||
* @access private
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
static function _encodeLength($length)
|
||||
{
|
||||
if ($length <= 0x7F) {
|
||||
return chr($length);
|
||||
}
|
||||
|
||||
$temp = ltrim(pack('N', $length), chr(0));
|
||||
return pack('Ca*', 0x80 | strlen($temp), $temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract raw BER from Base64 encoding
|
||||
*
|
||||
* @access private
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
static function _extractBER($str)
|
||||
{
|
||||
/* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them
|
||||
* above and beyond the ceritificate.
|
||||
* ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line:
|
||||
*
|
||||
* Bag Attributes
|
||||
* localKeyID: 01 00 00 00
|
||||
* subject=/O=organization/OU=org unit/CN=common name
|
||||
* issuer=/O=organization/CN=common name
|
||||
*/
|
||||
$temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1);
|
||||
// remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
|
||||
$temp = preg_replace('#-+[^-]+-+#', '', $temp);
|
||||
// remove new lines
|
||||
$temp = str_replace(array("\r", "\n", ' '), '', $temp);
|
||||
$temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Base64::decode($temp) : false;
|
||||
return $temp != false ? $temp : $str;
|
||||
}
|
||||
}
|
174
plugins/OStatus/extlib/phpseclib/Crypt/RSA/PKCS1.php
Normal file
174
plugins/OStatus/extlib/phpseclib/Crypt/RSA/PKCS1.php
Normal file
@ -0,0 +1,174 @@
|
||||
<?php
|
||||
/**
|
||||
* PKCS#1 Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Used by File/X509.php
|
||||
*
|
||||
* Has the following header:
|
||||
*
|
||||
* -----BEGIN RSA PUBLIC KEY-----
|
||||
*
|
||||
* Analogous to ssh-keygen's pem format (as specified by -m)
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use ParagonIE\ConstantTime\Hex;
|
||||
use phpseclib\Crypt\AES;
|
||||
use phpseclib\Crypt\DES;
|
||||
use phpseclib\Crypt\Random;
|
||||
use phpseclib\Crypt\TripleDES;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PKCS#1 Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class PKCS1 extends PKCS
|
||||
{
|
||||
/**
|
||||
* Default encryption algorithm
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
static $defaultEncryptionAlgorithm = 'DES-EDE3-CBC';
|
||||
|
||||
/**
|
||||
* Sets the default encryption algorithm
|
||||
*
|
||||
* @access public
|
||||
* @param string $algo
|
||||
*/
|
||||
static function setEncryptionAlgorithm($algo)
|
||||
{
|
||||
self::$defaultEncryptionAlgorithm = $algo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
$num_primes = count($primes);
|
||||
$raw = array(
|
||||
'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
|
||||
'modulus' => $n->toBytes(true),
|
||||
'publicExponent' => $e->toBytes(true),
|
||||
'privateExponent' => $d->toBytes(true),
|
||||
'prime1' => $primes[1]->toBytes(true),
|
||||
'prime2' => $primes[2]->toBytes(true),
|
||||
'exponent1' => $exponents[1]->toBytes(true),
|
||||
'exponent2' => $exponents[2]->toBytes(true),
|
||||
'coefficient' => $coefficients[2]->toBytes(true)
|
||||
);
|
||||
|
||||
$components = array();
|
||||
foreach ($raw as $name => $value) {
|
||||
$components[$name] = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($value)), $value);
|
||||
}
|
||||
|
||||
$RSAPrivateKey = implode('', $components);
|
||||
|
||||
if ($num_primes > 2) {
|
||||
$OtherPrimeInfos = '';
|
||||
for ($i = 3; $i <= $num_primes; $i++) {
|
||||
// OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
|
||||
//
|
||||
// OtherPrimeInfo ::= SEQUENCE {
|
||||
// prime INTEGER, -- ri
|
||||
// exponent INTEGER, -- di
|
||||
// coefficient INTEGER -- ti
|
||||
// }
|
||||
$OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
|
||||
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
|
||||
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
|
||||
$OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
|
||||
}
|
||||
$RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
|
||||
}
|
||||
|
||||
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
|
||||
|
||||
if (!empty($password) || is_string($password)) {
|
||||
$cipher = self::getEncryptionObject(self::$defaultEncryptionAlgorithm);
|
||||
$iv = Random::string($cipher->getBlockLength() >> 3);
|
||||
$cipher->setKey(self::generateSymmetricKey($password, $iv, $cipher->getKeyLength() >> 3));
|
||||
$cipher->setIV($iv);
|
||||
$iv = strtoupper(Hex::encode($iv));
|
||||
$RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
|
||||
"Proc-Type: 4,ENCRYPTED\r\n" .
|
||||
"DEK-Info: " . self::$defaultEncryptionAlgorithm . ",$iv\r\n" .
|
||||
"\r\n" .
|
||||
chunk_split(Base64::encode($cipher->encrypt($RSAPrivateKey)), 64) .
|
||||
'-----END RSA PRIVATE KEY-----';
|
||||
} else {
|
||||
$RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPrivateKey), 64) .
|
||||
'-----END RSA PRIVATE KEY-----';
|
||||
}
|
||||
|
||||
return $RSAPrivateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$modulus = $n->toBytes(true);
|
||||
$publicExponent = $e->toBytes(true);
|
||||
|
||||
// from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
|
||||
// RSAPublicKey ::= SEQUENCE {
|
||||
// modulus INTEGER, -- n
|
||||
// publicExponent INTEGER -- e
|
||||
// }
|
||||
$components = array(
|
||||
'modulus' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($modulus)), $modulus),
|
||||
'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($publicExponent)), $publicExponent)
|
||||
);
|
||||
|
||||
$RSAPublicKey = pack(
|
||||
'Ca*a*a*',
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
|
||||
$components['modulus'],
|
||||
$components['publicExponent']
|
||||
);
|
||||
|
||||
$RSAPublicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPublicKey), 64) .
|
||||
'-----END RSA PUBLIC KEY-----';
|
||||
|
||||
return $RSAPublicKey;
|
||||
}
|
||||
}
|
209
plugins/OStatus/extlib/phpseclib/Crypt/RSA/PKCS8.php
Normal file
209
plugins/OStatus/extlib/phpseclib/Crypt/RSA/PKCS8.php
Normal file
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
/**
|
||||
* PKCS#8 Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Used by PHP's openssl_public_encrypt() and openssl's rsautl (when -pubin is set)
|
||||
*
|
||||
* Has the following header:
|
||||
*
|
||||
* -----BEGIN PUBLIC KEY-----
|
||||
*
|
||||
* Analogous to ssh-keygen's pkcs8 format (as specified by -m). Although PKCS8
|
||||
* is specific to private keys it's basically creating a DER-encoded wrapper
|
||||
* for keys. This just extends that same concept to public keys (much like ssh-keygen)
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Crypt\DES;
|
||||
use phpseclib\Crypt\Random;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PKCS#8 Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class PKCS8 extends PKCS
|
||||
{
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
$num_primes = count($primes);
|
||||
$raw = array(
|
||||
'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
|
||||
'modulus' => $n->toBytes(true),
|
||||
'publicExponent' => $e->toBytes(true),
|
||||
'privateExponent' => $d->toBytes(true),
|
||||
'prime1' => $primes[1]->toBytes(true),
|
||||
'prime2' => $primes[2]->toBytes(true),
|
||||
'exponent1' => $exponents[1]->toBytes(true),
|
||||
'exponent2' => $exponents[2]->toBytes(true),
|
||||
'coefficient' => $coefficients[2]->toBytes(true)
|
||||
);
|
||||
|
||||
$components = array();
|
||||
foreach ($raw as $name => $value) {
|
||||
$components[$name] = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($value)), $value);
|
||||
}
|
||||
|
||||
$RSAPrivateKey = implode('', $components);
|
||||
|
||||
if ($num_primes > 2) {
|
||||
$OtherPrimeInfos = '';
|
||||
for ($i = 3; $i <= $num_primes; $i++) {
|
||||
// OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
|
||||
//
|
||||
// OtherPrimeInfo ::= SEQUENCE {
|
||||
// prime INTEGER, -- ri
|
||||
// exponent INTEGER, -- di
|
||||
// coefficient INTEGER -- ti
|
||||
// }
|
||||
$OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
|
||||
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
|
||||
$OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
|
||||
$OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
|
||||
}
|
||||
$RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
|
||||
}
|
||||
|
||||
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
|
||||
|
||||
$rsaOID = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00"; // hex version of MA0GCSqGSIb3DQEBAQUA
|
||||
$RSAPrivateKey = pack(
|
||||
'Ca*a*Ca*a*',
|
||||
self::ASN1_INTEGER,
|
||||
"\01\00",
|
||||
$rsaOID,
|
||||
4,
|
||||
self::_encodeLength(strlen($RSAPrivateKey)),
|
||||
$RSAPrivateKey
|
||||
);
|
||||
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
|
||||
if (!empty($password) || is_string($password)) {
|
||||
$salt = Random::string(8);
|
||||
$iterationCount = 2048;
|
||||
|
||||
$crypto = new DES(DES::MODE_CBC);
|
||||
$crypto->setPassword($password, 'pbkdf1', 'md5', $salt, $iterationCount);
|
||||
$RSAPrivateKey = $crypto->encrypt($RSAPrivateKey);
|
||||
|
||||
$parameters = pack(
|
||||
'Ca*a*Ca*N',
|
||||
self::ASN1_OCTETSTRING,
|
||||
self::_encodeLength(strlen($salt)),
|
||||
$salt,
|
||||
self::ASN1_INTEGER,
|
||||
self::_encodeLength(4),
|
||||
$iterationCount
|
||||
);
|
||||
$pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03";
|
||||
|
||||
$encryptionAlgorithm = pack(
|
||||
'Ca*a*Ca*a*',
|
||||
self::ASN1_OBJECT,
|
||||
self::_encodeLength(strlen($pbeWithMD5AndDES_CBC)),
|
||||
$pbeWithMD5AndDES_CBC,
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($parameters)),
|
||||
$parameters
|
||||
);
|
||||
|
||||
$RSAPrivateKey = pack(
|
||||
'Ca*a*Ca*a*',
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($encryptionAlgorithm)),
|
||||
$encryptionAlgorithm,
|
||||
self::ASN1_OCTETSTRING,
|
||||
self::_encodeLength(strlen($RSAPrivateKey)),
|
||||
$RSAPrivateKey
|
||||
);
|
||||
|
||||
$RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
|
||||
|
||||
$RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPrivateKey), 64) .
|
||||
'-----END ENCRYPTED PRIVATE KEY-----';
|
||||
} else {
|
||||
$RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPrivateKey), 64) .
|
||||
'-----END PRIVATE KEY-----';
|
||||
}
|
||||
|
||||
return $RSAPrivateKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$modulus = $n->toBytes(true);
|
||||
$publicExponent = $e->toBytes(true);
|
||||
|
||||
// from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
|
||||
// RSAPublicKey ::= SEQUENCE {
|
||||
// modulus INTEGER, -- n
|
||||
// publicExponent INTEGER -- e
|
||||
// }
|
||||
$components = array(
|
||||
'modulus' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($modulus)), $modulus),
|
||||
'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($publicExponent)), $publicExponent)
|
||||
);
|
||||
|
||||
$RSAPublicKey = pack(
|
||||
'Ca*a*a*',
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
|
||||
$components['modulus'],
|
||||
$components['publicExponent']
|
||||
);
|
||||
|
||||
// sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
|
||||
$rsaOID = "\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00"; // hex version of MA0GCSqGSIb3DQEBAQUA
|
||||
$RSAPublicKey = chr(0) . $RSAPublicKey;
|
||||
$RSAPublicKey = chr(3) . self::_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
|
||||
|
||||
$RSAPublicKey = pack(
|
||||
'Ca*a*',
|
||||
self::ASN1_SEQUENCE,
|
||||
self::_encodeLength(strlen($rsaOID . $RSAPublicKey)),
|
||||
$rsaOID . $RSAPublicKey
|
||||
);
|
||||
|
||||
$RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
|
||||
chunk_split(Base64::encode($RSAPublicKey), 64) .
|
||||
'-----END PUBLIC KEY-----';
|
||||
|
||||
return $RSAPublicKey;
|
||||
}
|
||||
}
|
313
plugins/OStatus/extlib/phpseclib/Crypt/RSA/PuTTY.php
Normal file
313
plugins/OStatus/extlib/phpseclib/Crypt/RSA/PuTTY.php
Normal file
@ -0,0 +1,313 @@
|
||||
<?php
|
||||
/**
|
||||
* PuTTY Formatted RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use ParagonIE\ConstantTime\Hex;
|
||||
use phpseclib\Crypt\AES;
|
||||
use phpseclib\Crypt\Hash;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* PuTTY Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class PuTTY
|
||||
{
|
||||
/**
|
||||
* Default comment
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
static $comment = 'phpseclib-generated-key';
|
||||
|
||||
/**
|
||||
* Sets the default comment
|
||||
*
|
||||
* @access public
|
||||
* @param string $comment
|
||||
*/
|
||||
static function setComment($comment)
|
||||
{
|
||||
self::$comment = str_replace(array("\r", "\n"), '', $comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a symmetric key for PuTTY keys
|
||||
*
|
||||
* @access public
|
||||
* @param string $password
|
||||
* @param string $iv
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
static function generateSymmetricKey($password, $length)
|
||||
{
|
||||
$symkey = '';
|
||||
$sequence = 0;
|
||||
while (strlen($symkey) < $length) {
|
||||
$temp = pack('Na*', $sequence++, $password);
|
||||
$symkey.= Hex::decode(sha1($temp));
|
||||
}
|
||||
return substr($symkey, 0, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static $one;
|
||||
if (!isset($one)) {
|
||||
$one = new BigInteger(1);
|
||||
}
|
||||
|
||||
if (strpos($key, 'BEGIN SSH2 PUBLIC KEY')) {
|
||||
$data = preg_split('#[\r\n]+#', $key);
|
||||
$data = array_splice($data, 2, -1);
|
||||
$data = implode('', $data);
|
||||
|
||||
$components = OpenSSH::load($data);
|
||||
if ($components === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!preg_match('#Comment: "(.+)"#', $key, $matches)) {
|
||||
return false;
|
||||
}
|
||||
$components['comment'] = str_replace(array('\\\\', '\"'), array('\\', '"'), $matches[1]);
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
$components = array('isPublicKey' => false);
|
||||
$key = preg_split('#\r\n|\r|\n#', $key);
|
||||
$type = trim(preg_replace('#PuTTY-User-Key-File-2: (.+)#', '$1', $key[0]));
|
||||
if ($type != 'ssh-rsa') {
|
||||
return false;
|
||||
}
|
||||
$encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1]));
|
||||
$components['comment'] = trim(preg_replace('#Comment: (.+)#', '$1', $key[2]));
|
||||
|
||||
$publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3]));
|
||||
$public = Base64::decode(implode('', array_map('trim', array_slice($key, 4, $publicLength))));
|
||||
$public = substr($public, 11);
|
||||
extract(unpack('Nlength', self::_string_shift($public, 4)));
|
||||
$components['publicExponent'] = new BigInteger(self::_string_shift($public, $length), -256);
|
||||
extract(unpack('Nlength', self::_string_shift($public, 4)));
|
||||
$components['modulus'] = new BigInteger(self::_string_shift($public, $length), -256);
|
||||
|
||||
$privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$publicLength + 4]));
|
||||
$private = Base64::decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength))));
|
||||
|
||||
switch ($encryption) {
|
||||
case 'aes256-cbc':
|
||||
$symkey = static::generateSymmetricKey($password, 32);
|
||||
$crypto = new AES(AES::MODE_CBC);
|
||||
}
|
||||
|
||||
if ($encryption != 'none') {
|
||||
$crypto->setKey($symkey);
|
||||
$crypto->setIV(str_repeat("\0", $crypto->getBlockLength() >> 3));
|
||||
$crypto->disablePadding();
|
||||
$private = $crypto->decrypt($private);
|
||||
if ($private === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
extract(unpack('Nlength', self::_string_shift($private, 4)));
|
||||
if (strlen($private) < $length) {
|
||||
return false;
|
||||
}
|
||||
$components['privateExponent'] = new BigInteger(self::_string_shift($private, $length), -256);
|
||||
extract(unpack('Nlength', self::_string_shift($private, 4)));
|
||||
if (strlen($private) < $length) {
|
||||
return false;
|
||||
}
|
||||
$components['primes'] = array(1 => new BigInteger(self::_string_shift($private, $length), -256));
|
||||
extract(unpack('Nlength', self::_string_shift($private, 4)));
|
||||
if (strlen($private) < $length) {
|
||||
return false;
|
||||
}
|
||||
$components['primes'][] = new BigInteger(self::_string_shift($private, $length), -256);
|
||||
|
||||
$temp = $components['primes'][1]->subtract($one);
|
||||
$components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
|
||||
$temp = $components['primes'][2]->subtract($one);
|
||||
$components['exponents'][] = $components['publicExponent']->modInverse($temp);
|
||||
|
||||
extract(unpack('Nlength', self::_string_shift($private, 4)));
|
||||
if (strlen($private) < $length) {
|
||||
return false;
|
||||
}
|
||||
$components['coefficients'] = array(2 => new BigInteger(self::_string_shift($private, $length), -256));
|
||||
|
||||
return $components;
|
||||
}
|
||||
|
||||
/**
|
||||
* String Shift
|
||||
*
|
||||
* Inspired by array_shift
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $index
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
static function _string_shift(&$string, $index = 1)
|
||||
{
|
||||
$substr = substr($string, 0, $index);
|
||||
$string = substr($string, $index);
|
||||
return $substr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
if (count($primes) != 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$raw = array(
|
||||
'modulus' => $n->toBytes(true),
|
||||
'publicExponent' => $e->toBytes(true),
|
||||
'privateExponent' => $d->toBytes(true),
|
||||
'prime1' => $primes[1]->toBytes(true),
|
||||
'prime2' => $primes[2]->toBytes(true),
|
||||
'exponent1' => $exponents[1]->toBytes(true),
|
||||
'exponent2' => $exponents[2]->toBytes(true),
|
||||
'coefficient' => $coefficients[2]->toBytes(true)
|
||||
);
|
||||
|
||||
$key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: ";
|
||||
$encryption = (!empty($password) || is_string($password)) ? 'aes256-cbc' : 'none';
|
||||
$key.= $encryption;
|
||||
$key.= "\r\nComment: " . self::$comment . "\r\n";
|
||||
$public = pack(
|
||||
'Na*Na*Na*',
|
||||
strlen('ssh-rsa'),
|
||||
'ssh-rsa',
|
||||
strlen($raw['publicExponent']),
|
||||
$raw['publicExponent'],
|
||||
strlen($raw['modulus']),
|
||||
$raw['modulus']
|
||||
);
|
||||
$source = pack(
|
||||
'Na*Na*Na*Na*',
|
||||
strlen('ssh-rsa'),
|
||||
'ssh-rsa',
|
||||
strlen($encryption),
|
||||
$encryption,
|
||||
strlen(self::$comment),
|
||||
self::$comment,
|
||||
strlen($public),
|
||||
$public
|
||||
);
|
||||
$public = Base64::encode($public);
|
||||
$key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n";
|
||||
$key.= chunk_split($public, 64);
|
||||
$private = pack(
|
||||
'Na*Na*Na*Na*',
|
||||
strlen($raw['privateExponent']),
|
||||
$raw['privateExponent'],
|
||||
strlen($raw['prime1']),
|
||||
$raw['prime1'],
|
||||
strlen($raw['prime2']),
|
||||
$raw['prime2'],
|
||||
strlen($raw['coefficient']),
|
||||
$raw['coefficient']
|
||||
);
|
||||
if (empty($password) && !is_string($password)) {
|
||||
$source.= pack('Na*', strlen($private), $private);
|
||||
$hashkey = 'putty-private-key-file-mac-key';
|
||||
} else {
|
||||
$private.= Random::string(16 - (strlen($private) & 15));
|
||||
$source.= pack('Na*', strlen($private), $private);
|
||||
$crypto = new AES();
|
||||
|
||||
$crypto->setKey(static::generateSymmetricKey($password, 32));
|
||||
$crypto->setIV(str_repeat("\0", $crypto->getBlockLength() >> 3));
|
||||
$crypto->disablePadding();
|
||||
$private = $crypto->encrypt($private);
|
||||
$hashkey = 'putty-private-key-file-mac-key' . $password;
|
||||
}
|
||||
|
||||
$private = Base64::encode($private);
|
||||
$key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n";
|
||||
$key.= chunk_split($private, 64);
|
||||
$hash = new Hash('sha1');
|
||||
$hash->setKey(sha1($hashkey, true));
|
||||
$key.= 'Private-MAC: ' . Hex::encode($hash->hash($source)) . "\r\n";
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
$n = $n->toBytes(true);
|
||||
$e = $e->toBytes(true);
|
||||
|
||||
$key = pack(
|
||||
'Na*Na*Na*',
|
||||
strlen('ssh-rsa'),
|
||||
'ssh-rsa',
|
||||
strlen($e),
|
||||
$e,
|
||||
strlen($n),
|
||||
$n
|
||||
);
|
||||
$key = "---- BEGIN SSH2 PUBLIC KEY ----\r\n" .
|
||||
'Comment: "' . str_replace(array('\\', '"'), array('\\\\', '\"'), self::$comment) . "\"\r\n";
|
||||
chunk_split(Base64::encode($key), 64) .
|
||||
'---- END SSH2 PUBLIC KEY ----';
|
||||
|
||||
return $key;
|
||||
}
|
||||
}
|
103
plugins/OStatus/extlib/phpseclib/Crypt/RSA/Raw.php
Normal file
103
plugins/OStatus/extlib/phpseclib/Crypt/RSA/Raw.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* Raw RSA Key Handler
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* An array containing two \phpseclib\Math\BigInteger objects.
|
||||
*
|
||||
* The exponent can be indexed with any of the following:
|
||||
*
|
||||
* 0, e, exponent, publicExponent
|
||||
*
|
||||
* The modulus can be indexed with any of the following:
|
||||
*
|
||||
* 1, n, modulo, modulus
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* Raw RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class Raw
|
||||
{
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_array($key)) {
|
||||
return false;
|
||||
}
|
||||
if (isset($key['isPublicKey']) && isset($key['modulus'])) {
|
||||
if (isset($key['privateExponent']) || isset($key['publicExponent'])) {
|
||||
if (!isset($key['primes'])) {
|
||||
return $key;
|
||||
}
|
||||
if (isset($key['exponents']) && isset($key['coefficients']) && isset($key['publicExponent']) && isset($key['privateExponent'])) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
$components = array('isPublicKey' => true);
|
||||
switch (true) {
|
||||
case isset($key['e']):
|
||||
$components['publicExponent'] = $key['e'];
|
||||
break;
|
||||
case isset($key['exponent']):
|
||||
$components['publicExponent'] = $key['exponent'];
|
||||
break;
|
||||
case isset($key['publicExponent']):
|
||||
$components['publicExponent'] = $key['publicExponent'];
|
||||
break;
|
||||
case isset($key[0]):
|
||||
$components['publicExponent'] = $key[0];
|
||||
}
|
||||
switch (true) {
|
||||
case isset($key['n']):
|
||||
$components['modulus'] = $key['n'];
|
||||
break;
|
||||
case isset($key['modulo']):
|
||||
$components['modulus'] = $key['modulo'];
|
||||
break;
|
||||
case isset($key['modulus']):
|
||||
$components['modulus'] = $key['modulus'];
|
||||
break;
|
||||
case isset($key[1]):
|
||||
$components['modulus'] = $key[1];
|
||||
}
|
||||
return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
return array('e' => clone $e, 'n' => clone $n);
|
||||
}
|
||||
}
|
147
plugins/OStatus/extlib/phpseclib/Crypt/RSA/XML.php
Normal file
147
plugins/OStatus/extlib/phpseclib/Crypt/RSA/XML.php
Normal file
@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/**
|
||||
* XML Formatted RSA Key Handler
|
||||
*
|
||||
* More info:
|
||||
*
|
||||
* http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
|
||||
* http://en.wikipedia.org/wiki/XML_Signature
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Crypt
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Crypt\RSA;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Math\BigInteger;
|
||||
|
||||
/**
|
||||
* XML Formatted RSA Key Handler
|
||||
*
|
||||
* @package RSA
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class XML
|
||||
{
|
||||
/**
|
||||
* Break a public or private key down into its constituent components
|
||||
*
|
||||
* @access public
|
||||
* @param string $key
|
||||
* @param string $password optional
|
||||
* @return array
|
||||
*/
|
||||
static function load($key, $password = '')
|
||||
{
|
||||
if (!is_string($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$components = array(
|
||||
'isPublicKey' => false,
|
||||
'primes' => array(),
|
||||
'exponents' => array(),
|
||||
'coefficients' => array()
|
||||
);
|
||||
|
||||
$use_errors = libxml_use_internal_errors(true);
|
||||
|
||||
$dom = new \DOMDocument();
|
||||
if (!$dom->loadXML('<xml>' . $key . '</xml>')) {
|
||||
return false;
|
||||
}
|
||||
$xpath = new \DOMXPath($dom);
|
||||
$keys = array('modulus', 'exponent', 'p', 'q', 'dp', 'dq', 'inverseq', 'd');
|
||||
foreach ($keys as $key) {
|
||||
// $dom->getElementsByTagName($key) is case-sensitive
|
||||
$temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']");
|
||||
if (!$temp->length) {
|
||||
continue;
|
||||
}
|
||||
$value = new BigInteger(Base64::decode($temp->item(0)->nodeValue), 256);
|
||||
switch ($key) {
|
||||
case 'modulus':
|
||||
$components['modulus'] = $value;
|
||||
break;
|
||||
case 'exponent':
|
||||
$components['publicExponent'] = $value;
|
||||
break;
|
||||
case 'p':
|
||||
$components['primes'][1] = $value;
|
||||
break;
|
||||
case 'q':
|
||||
$components['primes'][2] = $value;
|
||||
break;
|
||||
case 'dp':
|
||||
$components['exponents'][1] = $value;
|
||||
break;
|
||||
case 'dq':
|
||||
$components['exponents'][2] = $value;
|
||||
break;
|
||||
case 'inverseq':
|
||||
$components['coefficients'][2] = $value;
|
||||
break;
|
||||
case 'd':
|
||||
$components['privateExponent'] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
libxml_use_internal_errors($use_errors);
|
||||
|
||||
return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a private key to the appropriate format.
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @param \phpseclib\Math\BigInteger $d
|
||||
* @param array $primes
|
||||
* @param array $exponents
|
||||
* @param array $coefficients
|
||||
* @param string $password optional
|
||||
* @return string
|
||||
*/
|
||||
static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
|
||||
{
|
||||
if (count($primes) != 2) {
|
||||
return false;
|
||||
}
|
||||
return "<RSAKeyValue>\r\n" .
|
||||
' <Modulus>' . Base64::encode($n->toBytes()) . "</Modulus>\r\n" .
|
||||
' <Exponent>' . Base64::encode($e->toBytes()) . "</Exponent>\r\n" .
|
||||
' <P>' . Base64::encode($primes[1]->toBytes()) . "</P>\r\n" .
|
||||
' <Q>' . Base64::encode($primes[2]->toBytes()) . "</Q>\r\n" .
|
||||
' <DP>' . Base64::encode($exponents[1]->toBytes()) . "</DP>\r\n" .
|
||||
' <DQ>' . Base64::encode($exponents[2]->toBytes()) . "</DQ>\r\n" .
|
||||
' <InverseQ>' . Base64::encode($coefficients[2]->toBytes()) . "</InverseQ>\r\n" .
|
||||
' <D>' . Base64::encode($d->toBytes()) . "</D>\r\n" .
|
||||
'</RSAKeyValue>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a public key to the appropriate format
|
||||
*
|
||||
* @access public
|
||||
* @param \phpseclib\Math\BigInteger $n
|
||||
* @param \phpseclib\Math\BigInteger $e
|
||||
* @return string
|
||||
*/
|
||||
static function savePublicKey(BigInteger $n, BigInteger $e)
|
||||
{
|
||||
return "<RSAKeyValue>\r\n" .
|
||||
' <Modulus>' . Base64::encode($n->toBytes()) . "</Modulus>\r\n" .
|
||||
' <Exponent>' . Base64::encode($e->toBytes()) . "</Exponent>\r\n" .
|
||||
'</RSAKeyValue>';
|
||||
}
|
||||
}
|
@ -1,218 +1,172 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Random Number Generator
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
* PHP version 5
|
||||
*
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include('Crypt/Random.php');
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* echo bin2hex(crypt_random_string(8));
|
||||
* echo bin2hex(\phpseclib\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 MMVII Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
* @category Crypt
|
||||
* @package 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* "Is Windows" test
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
define('CRYPT_RANDOM_IS_WINDOWS', strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Generate a random string.
|
||||
* Pure-PHP Random Number Generator
|
||||
*
|
||||
* 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
|
||||
* @package Random
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
function crypt_random_string($length)
|
||||
class Random
|
||||
{
|
||||
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);
|
||||
/**
|
||||
* 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 int $length
|
||||
* @throws \RuntimeException if a symmetric cipher is needed but not loaded
|
||||
* @return string
|
||||
*/
|
||||
static function string($length)
|
||||
{
|
||||
try {
|
||||
return \random_bytes($length);
|
||||
} catch (\Exception $e) {
|
||||
// random_compat will throw an Exception, which in PHP 5 does not implement Throwable
|
||||
} catch (\Throwable $e) {
|
||||
// If a sufficient source of randomness is unavailable, random_bytes() will throw an
|
||||
// object that implements the Throwable interface (Exception, TypeError, Error).
|
||||
// We don't actually need to do anything here. The string() method should just continue
|
||||
// as normal. Note, however, that if we don't have a sufficient source of randomness for
|
||||
// random_bytes(), most of the other calls here will fail too, so we'll end up using
|
||||
// the PHP implementation.
|
||||
}
|
||||
// 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():
|
||||
// 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.
|
||||
//
|
||||
// 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();
|
||||
if (isset($_SESSION)) {
|
||||
$_OLD_SESSION = $_SESSION;
|
||||
}
|
||||
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 (isset($_OLD_SESSION)) {
|
||||
$_SESSION = $_OLD_SESSION;
|
||||
unset($_OLD_SESSION);
|
||||
} else {
|
||||
unset($_SESSION);
|
||||
// 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 = (isset($_SERVER) ? self::safe_serialize($_SERVER) : '') .
|
||||
(isset($_POST) ? self::safe_serialize($_POST) : '') .
|
||||
(isset($_GET) ? self::safe_serialize($_GET) : '') .
|
||||
(isset($_COOKIE) ? self::safe_serialize($_COOKIE) : '') .
|
||||
self::safe_serialize($GLOBALS) .
|
||||
self::safe_serialize($_SESSION) .
|
||||
self::safe_serialize($_OLD_SESSION);
|
||||
$v = $seed = $_SESSION['seed'] = sha1($v, true);
|
||||
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 = sha1($seed . 'A', true);
|
||||
$iv = sha1($seed . 'C', true);
|
||||
|
||||
// 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 class_exists('\phpseclib\Crypt\AES'):
|
||||
$crypto = new AES(Base::MODE_CTR);
|
||||
break;
|
||||
case class_exists('\phpseclib\Crypt\Twofish'):
|
||||
$crypto = new Twofish(Base::MODE_CTR);
|
||||
break;
|
||||
case class_exists('\phpseclib\Crypt\Blowfish'):
|
||||
$crypto = new Blowfish(Base::MODE_CTR);
|
||||
break;
|
||||
case class_exists('\phpseclib\Crypt\TripleDES'):
|
||||
$crypto = new TripleDES(Base::MODE_CTR);
|
||||
break;
|
||||
case class_exists('\phpseclib\Crypt\DES'):
|
||||
$crypto = new DES(Base::MODE_CTR);
|
||||
break;
|
||||
case class_exists('\phpseclib\Crypt\RC4'):
|
||||
$crypto = new RC4();
|
||||
break;
|
||||
default:
|
||||
throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded');
|
||||
}
|
||||
|
||||
$crypto->setKey($key);
|
||||
$crypto->setIV($iv);
|
||||
$crypto->enableContinuousBuffer();
|
||||
}
|
||||
|
||||
// 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'));
|
||||
//return $crypto->encrypt(str_repeat("\0", $length));
|
||||
|
||||
// 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 class_exists('Crypt_AES'):
|
||||
$crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);
|
||||
break;
|
||||
case class_exists('Crypt_TripleDES'):
|
||||
$crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
|
||||
break;
|
||||
case class_exists('Crypt_DES'):
|
||||
$crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);
|
||||
break;
|
||||
case class_exists('Crypt_RC4'):
|
||||
$crypto = new Crypt_RC4();
|
||||
break;
|
||||
default:
|
||||
$crypto = $seed;
|
||||
return crypt_random_string($length);
|
||||
}
|
||||
|
||||
$crypto->setKey($key);
|
||||
$crypto->setIV($iv);
|
||||
$crypto->enableContinuousBuffer();
|
||||
}
|
||||
|
||||
if (is_string($crypto)) {
|
||||
// the following is based off of ANSI X9.31:
|
||||
//
|
||||
// http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
|
||||
@ -221,29 +175,45 @@ function crypt_random_string($length)
|
||||
//
|
||||
// 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")
|
||||
//
|
||||
// ANSI X9.31 recommends ciphers be used and phpseclib does use them if they're available (see
|
||||
// later on in the code) but if they're not we'll use sha1
|
||||
$result = '';
|
||||
while (strlen($result) < $length) { // each loop adds 20 bytes
|
||||
// microtime() isn't packed as "densely" as it could be but then neither is that the idea.
|
||||
// the idea is simply to ensure that each "block" has a unique element to it.
|
||||
$i = pack('H*', sha1(microtime()));
|
||||
$r = pack('H*', sha1($i ^ $v));
|
||||
$v = pack('H*', sha1($r ^ $i));
|
||||
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);
|
||||
}
|
||||
|
||||
//return $crypto->encrypt(str_repeat("\0", $length));
|
||||
|
||||
$result = '';
|
||||
while (strlen($result) < $length) {
|
||||
$i = $crypto->encrypt(microtime());
|
||||
$r = $crypto->encrypt($i ^ $v);
|
||||
$v = $crypto->encrypt($r ^ $i);
|
||||
$result.= $r;
|
||||
/**
|
||||
* Safely serialize variables
|
||||
*
|
||||
* If a class has a private __sleep() it'll emit a warning
|
||||
*
|
||||
* @param mixed $arr
|
||||
* @access public
|
||||
*/
|
||||
function safe_serialize(&$arr)
|
||||
{
|
||||
if (is_object($arr)) {
|
||||
return '';
|
||||
}
|
||||
if (!is_array($arr)) {
|
||||
return serialize($arr);
|
||||
}
|
||||
// prevent circular array recursion
|
||||
if (isset($arr['__phpseclib_marker'])) {
|
||||
return '';
|
||||
}
|
||||
$safearr = array();
|
||||
$arr['__phpseclib_marker'] = true;
|
||||
foreach (array_keys($arr) as $key) {
|
||||
// do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage
|
||||
if ($key !== '__phpseclib_marker') {
|
||||
$safearr[$key] = self::safe_serialize($arr[$key]);
|
||||
}
|
||||
}
|
||||
unset($arr['__phpseclib_marker']);
|
||||
return serialize($safearr);
|
||||
}
|
||||
return substr($result, 0, $length);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,19 +1,18 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* 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
|
||||
* PHP version 5
|
||||
*
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include('Crypt/TripleDES.php');
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $des = new Crypt_TripleDES();
|
||||
* $des = new \phpseclib\Crypt\TripleDES();
|
||||
*
|
||||
* $des->setKey('abcdefghijklmnopqrstuvwx');
|
||||
*
|
||||
@ -27,99 +26,64 @@
|
||||
* ?>
|
||||
* </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 MMVII Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
* @category Crypt
|
||||
* @package 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')) {
|
||||
require_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);
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Triple DES.
|
||||
*
|
||||
* @package TripleDES
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @version 0.1.0
|
||||
* @access public
|
||||
* @package Crypt_TripleDES
|
||||
*/
|
||||
class Crypt_TripleDES extends Crypt_DES {
|
||||
class TripleDES extends DES
|
||||
{
|
||||
/**
|
||||
* The default password key_size used by setPassword()
|
||||
* Encrypt / decrypt using inner chaining
|
||||
*
|
||||
* @see Crypt_DES::password_key_size
|
||||
* @see Crypt_Base::password_key_size
|
||||
* @see Crypt_Base::setPassword()
|
||||
* @var Integer
|
||||
* Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (self::MODE_CBC3).
|
||||
*/
|
||||
const MODE_3CBC = -2;
|
||||
|
||||
/**
|
||||
* Encrypt / decrypt using outer chaining
|
||||
*
|
||||
* Outer chaining is used by SSH-2 and when the mode is set to \phpseclib\Crypt\Base::MODE_CBC.
|
||||
*/
|
||||
const MODE_CBC3 = Base::MODE_CBC;
|
||||
|
||||
/**
|
||||
* Key Length (in bytes)
|
||||
*
|
||||
* @see \phpseclib\Crypt\TripleDES::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $password_key_size = 24;
|
||||
var $key_length = 24;
|
||||
|
||||
/**
|
||||
* The default salt used by setPassword()
|
||||
*
|
||||
* @see Crypt_Base::password_default_salt
|
||||
* @see Crypt_Base::setPassword()
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::password_default_salt
|
||||
* @see \phpseclib\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
|
||||
* @see \phpseclib\Crypt\DES::cipher_name_mcrypt
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'tripledes';
|
||||
@ -127,8 +91,8 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
/**
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see Crypt_Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 750;
|
||||
@ -136,27 +100,27 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
/**
|
||||
* max possible size of $key
|
||||
*
|
||||
* @see Crypt_TripleDES::setKey()
|
||||
* @see Crypt_DES::setKey()
|
||||
* @var String
|
||||
* @see self::setKey()
|
||||
* @see \phpseclib\Crypt\DES::setKey()
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $key_size_max = 24;
|
||||
var $key_length_max = 24;
|
||||
|
||||
/**
|
||||
* Internal flag whether using CRYPT_DES_MODE_3CBC or not
|
||||
* Internal flag whether using self::MODE_3CBC or not
|
||||
*
|
||||
* @var Boolean
|
||||
* @var bool
|
||||
* @access private
|
||||
*/
|
||||
var $mode_3cbc;
|
||||
|
||||
/**
|
||||
* The Crypt_DES objects
|
||||
* The \phpseclib\Crypt\DES objects
|
||||
*
|
||||
* Used only if $mode_3cbc === true
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $des;
|
||||
@ -164,65 +128,83 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
* Determines whether or not the mcrypt or OpenSSL extensions should be used.
|
||||
*
|
||||
* $mode could be:
|
||||
*
|
||||
* - CRYPT_DES_MODE_ECB
|
||||
* - \phpseclib\Crypt\Base::MODE_ECB
|
||||
*
|
||||
* - CRYPT_DES_MODE_CBC
|
||||
* - \phpseclib\Crypt\Base::MODE_CBC
|
||||
*
|
||||
* - CRYPT_DES_MODE_CTR
|
||||
* - \phpseclib\Crypt\Base::MODE_CTR
|
||||
*
|
||||
* - CRYPT_DES_MODE_CFB
|
||||
* - \phpseclib\Crypt\Base::MODE_CFB
|
||||
*
|
||||
* - CRYPT_DES_MODE_OFB
|
||||
* - \phpseclib\Crypt\Base::MODE_OFB
|
||||
*
|
||||
* - CRYPT_DES_MODE_3CBC
|
||||
* - \phpseclib\Crypt\TripleDES::MODE_3CB
|
||||
*
|
||||
* If not explictly set, CRYPT_DES_MODE_CBC will be used.
|
||||
*
|
||||
* @see Crypt_DES::Crypt_DES()
|
||||
* @see Crypt_Base::Crypt_Base()
|
||||
* @param optional Integer $mode
|
||||
* @see \phpseclib\Crypt\DES::__construct()
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param int $mode
|
||||
* @access public
|
||||
*/
|
||||
function Crypt_TripleDES($mode = CRYPT_DES_MODE_CBC)
|
||||
function __construct($mode)
|
||||
{
|
||||
switch ($mode) {
|
||||
// In case of CRYPT_DES_MODE_3CBC, we init as CRYPT_DES_MODE_CBC
|
||||
// In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC
|
||||
// and additional flag us internally as 3CBC
|
||||
case CRYPT_DES_MODE_3CBC:
|
||||
parent::Crypt_DES(CRYPT_DES_MODE_CBC);
|
||||
case self::MODE_3CBC:
|
||||
parent::__construct(Base::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),
|
||||
new DES(Base::MODE_CBC),
|
||||
new DES(Base::MODE_CBC),
|
||||
new DES(Base::MODE_CBC),
|
||||
);
|
||||
|
||||
// we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects
|
||||
// we're going to be doing the padding, ourselves, so disable it in the \phpseclib\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_DES($mode);
|
||||
parent::__construct($mode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initialization vector. (optional)
|
||||
* Test for engine validity
|
||||
*
|
||||
* SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explictly set, it'll be assumed
|
||||
* to be all zero's.
|
||||
* This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
|
||||
*
|
||||
* @see Crypt_Base::setIV()
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @param String $iv
|
||||
* @return bool
|
||||
*/
|
||||
function isValidEngine($engine)
|
||||
{
|
||||
if ($engine == self::ENGINE_OPENSSL) {
|
||||
$this->cipher_name_openssl_ecb = 'des-ede3';
|
||||
$mode = $this->_openssl_translate_mode();
|
||||
$this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode;
|
||||
}
|
||||
|
||||
return parent::isValidEngine($engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initialization vector.
|
||||
*
|
||||
* SetIV is not required when \phpseclib\Crypt\Base::MODE_ECB is being used.
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::setIV()
|
||||
* @access public
|
||||
* @param string $iv
|
||||
*/
|
||||
function setIV($iv)
|
||||
{
|
||||
@ -234,39 +216,66 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length.
|
||||
*
|
||||
* Valid key lengths are 128 and 192 bits.
|
||||
*
|
||||
* If you want to use a 64-bit key use DES.php
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base:setKeyLength()
|
||||
* @access public
|
||||
* @throws \LengthException if the key length is invalid
|
||||
* @param int $length
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 192:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128 or 192 bits are supported');
|
||||
}
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* Keys can be of any length. Triple DES, itself, can use 128-bit (eg. strlen($key) == 16) or
|
||||
* 192-bit (eg. strlen($key) == 24) keys. This function pads and truncates $key as appropriate.
|
||||
* Triple DES can use 128-bit (eg. strlen($key) == 16) or 192-bit (eg. strlen($key) == 24) keys.
|
||||
*
|
||||
* DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
|
||||
*
|
||||
* If the key is not explicitly set, it'll be assumed to be all null bytes.
|
||||
*
|
||||
* @access public
|
||||
* @see Crypt_DES::setKey()
|
||||
* @see Crypt_Base::setKey()
|
||||
* @param String $key
|
||||
* @see \phpseclib\Crypt\DES::setKey()
|
||||
* @see \phpseclib\Crypt\Base::setKey()
|
||||
* @throws \LengthException if the key length is invalid
|
||||
* @param string $key
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
$length = strlen($key);
|
||||
if ($length > 8) {
|
||||
$key = str_pad(substr($key, 0, 24), 24, chr(0));
|
||||
// if $key is between 64 and 128-bits, use the first 64-bits as the last, per this:
|
||||
// http://php.net/function.mcrypt-encrypt#47973
|
||||
//$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
|
||||
} else {
|
||||
$key = str_pad($key, 8, chr(0));
|
||||
if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) {
|
||||
throw new \LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes');
|
||||
}
|
||||
parent::setKey($key);
|
||||
|
||||
// And in case of 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) {
|
||||
switch (strlen($key)) {
|
||||
case 16:
|
||||
$key.= substr($key, 0, 8);
|
||||
case 24:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 24 are supported');
|
||||
}
|
||||
|
||||
// copied from Base::setKey()
|
||||
$this->key = $key;
|
||||
$this->key_length = strlen($key);
|
||||
$this->changed = true;
|
||||
$this->_setEngine();
|
||||
|
||||
if ($this->mode_3cbc) {
|
||||
$this->des[0]->setKey(substr($key, 0, 8));
|
||||
$this->des[1]->setKey(substr($key, 8, 8));
|
||||
$this->des[2]->setKey(substr($key, 16, 8));
|
||||
@ -276,21 +285,25 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
/**
|
||||
* Encrypts a message.
|
||||
*
|
||||
* @see Crypt_Base::encrypt()
|
||||
* @see \phpseclib\Crypt\Base::encrypt()
|
||||
* @access public
|
||||
* @param String $plaintext
|
||||
* @return String $cipertext
|
||||
* @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
|
||||
// except for: self::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))));
|
||||
$this->des[1]->decrypt(
|
||||
$this->des[0]->encrypt(
|
||||
$this->_pad($plaintext)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return parent::encrypt($plaintext);
|
||||
@ -299,17 +312,23 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
/**
|
||||
* Decrypts a message.
|
||||
*
|
||||
* @see Crypt_Base::decrypt()
|
||||
* @see \phpseclib\Crypt\Base::decrypt()
|
||||
* @access public
|
||||
* @param String $ciphertext
|
||||
* @return String $plaintext
|
||||
* @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 $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);
|
||||
@ -344,13 +363,13 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
* 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
|
||||
* Put another way, when the continuous buffer is enabled, the state of the \phpseclib\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()
|
||||
* @see \phpseclib\Crypt\Base::enableContinuousBuffer()
|
||||
* @see self::disableContinuousBuffer()
|
||||
* @access public
|
||||
*/
|
||||
function enableContinuousBuffer()
|
||||
@ -368,8 +387,8 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
*
|
||||
* The default behavior.
|
||||
*
|
||||
* @see Crypt_Base::disableContinuousBuffer()
|
||||
* @see Crypt_TripleDES::enableContinuousBuffer()
|
||||
* @see \phpseclib\Crypt\Base::disableContinuousBuffer()
|
||||
* @see self::enableContinuousBuffer()
|
||||
* @access public
|
||||
*/
|
||||
function disableContinuousBuffer()
|
||||
@ -385,8 +404,8 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
/**
|
||||
* Creates the key schedule
|
||||
*
|
||||
* @see Crypt_DES::_setupKey()
|
||||
* @see Crypt_Base::_setupKey()
|
||||
* @see \phpseclib\Crypt\DES::_setupKey()
|
||||
* @see \phpseclib\Crypt\Base::_setupKey()
|
||||
* @access private
|
||||
*/
|
||||
function _setupKey()
|
||||
@ -416,7 +435,24 @@ class Crypt_TripleDES extends Crypt_DES {
|
||||
// setup our key
|
||||
parent::_setupKey();
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
// vim6: fdl=1:
|
||||
/**
|
||||
* Sets the internal crypt engine
|
||||
*
|
||||
* @see \phpseclib\Crypt\Base::__construct()
|
||||
* @see \phpseclib\Crypt\Base::setPreferredEngine()
|
||||
* @param int $engine
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
function setPreferredEngine($engine)
|
||||
{
|
||||
if ($this->mode_3cbc) {
|
||||
$this->des[0]->setPreferredEngine($engine);
|
||||
$this->des[1]->setPreferredEngine($engine);
|
||||
$this->des[2]->setPreferredEngine($engine);
|
||||
}
|
||||
|
||||
return parent::setPreferredEngine($engine);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Twofish.
|
||||
*
|
||||
* Uses mcrypt, if available, and an internal implementation, otherwise.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
* PHP version 5
|
||||
*
|
||||
* Useful resources are as follows:
|
||||
*
|
||||
@ -15,9 +14,9 @@
|
||||
* Here's a short example of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include('Crypt/Twofish.php');
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $twofish = new Crypt_Twofish();
|
||||
* $twofish = new \phpseclib\Crypt\Twofish();
|
||||
*
|
||||
* $twofish->setKey('12345678901234567890123456789012');
|
||||
*
|
||||
@ -27,120 +26,32 @@
|
||||
* ?>
|
||||
* </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 MMVII Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @version 1.0
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
* @category Crypt
|
||||
* @package 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')) {
|
||||
require_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_Twofish::Crypt_Twofish()
|
||||
*/
|
||||
/**
|
||||
* Toggles the internal implementation
|
||||
*/
|
||||
define('CRYPT_TWOFISH_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
|
||||
/**
|
||||
* Toggles the mcrypt implementation
|
||||
*/
|
||||
define('CRYPT_TWOFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
|
||||
/**#@-*/
|
||||
namespace phpseclib\Crypt;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of Twofish.
|
||||
*
|
||||
* @package Twofish
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @author Hans-Juergen Petrich <petrich@tronic-media.com>
|
||||
* @version 1.0
|
||||
* @access public
|
||||
* @package Crypt_Twofish
|
||||
*/
|
||||
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';
|
||||
|
||||
class Twofish extends Base
|
||||
{
|
||||
/**
|
||||
* The mcrypt specific name of the cipher
|
||||
*
|
||||
* @see Crypt_Base::cipher_name_mcrypt
|
||||
* @var String
|
||||
* @see \phpseclib\Crypt\Base::cipher_name_mcrypt
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $cipher_name_mcrypt = 'twofish';
|
||||
@ -148,8 +59,8 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* Optimizing value while CFB-encrypting
|
||||
*
|
||||
* @see Crypt_Base::cfb_init_len
|
||||
* @var Integer
|
||||
* @see \phpseclib\Crypt\Base::cfb_init_len
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $cfb_init_len = 800;
|
||||
@ -157,10 +68,10 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* Q-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $q0 = array (
|
||||
var $q0 = array(
|
||||
0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
|
||||
0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
|
||||
0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
|
||||
@ -198,10 +109,10 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* Q-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $q1 = array (
|
||||
var $q1 = array(
|
||||
0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
|
||||
0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
|
||||
0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
|
||||
@ -239,10 +150,10 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* M-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $m0 = array (
|
||||
var $m0 = array(
|
||||
0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8,
|
||||
0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B,
|
||||
0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
|
||||
@ -280,10 +191,10 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* M-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $m1 = array (
|
||||
var $m1 = array(
|
||||
0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4,
|
||||
0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A,
|
||||
0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
|
||||
@ -321,10 +232,10 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* M-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $m2 = array (
|
||||
var $m2 = array(
|
||||
0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA,
|
||||
0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7,
|
||||
0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
|
||||
@ -362,10 +273,10 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* M-Table
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $m3 = array (
|
||||
var $m3 = array(
|
||||
0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF,
|
||||
0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836,
|
||||
0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
|
||||
@ -403,7 +314,7 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* The Key Schedule Array
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $K = array();
|
||||
@ -411,7 +322,7 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* The Key depended S-Table 0
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $S0 = array();
|
||||
@ -419,7 +330,7 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* The Key depended S-Table 1
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $S1 = array();
|
||||
@ -427,7 +338,7 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* The Key depended S-Table 2
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $S2 = array();
|
||||
@ -435,7 +346,7 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* The Key depended S-Table 3
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $S3 = array();
|
||||
@ -443,75 +354,86 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
/**
|
||||
* Holds the last used key
|
||||
*
|
||||
* @var Array
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $kl;
|
||||
|
||||
/**
|
||||
* The Key Length (in bytes)
|
||||
*
|
||||
* @see Crypt_Twofish::setKeyLength()
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $key_length = 16;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Determines whether or not the mcrypt extension should be used.
|
||||
*
|
||||
* $mode could be:
|
||||
*
|
||||
* - CRYPT_TWOFISH_MODE_ECB
|
||||
*
|
||||
* - CRYPT_TWOFISH_MODE_CBC
|
||||
*
|
||||
* - CRYPT_TWOFISH_MODE_CTR
|
||||
*
|
||||
* - CRYPT_TWOFISH_MODE_CFB
|
||||
*
|
||||
* - CRYPT_TWOFISH_MODE_OFB
|
||||
*
|
||||
* If not explictly set, CRYPT_TWOFISH_MODE_CBC will be used.
|
||||
*
|
||||
* @see Crypt_Base::Crypt_Base()
|
||||
* @param optional Integer $mode
|
||||
* @param int $mode
|
||||
* @access public
|
||||
* @throws \InvalidArgumentException if an invalid / unsupported mode is provided
|
||||
*/
|
||||
function Crypt_Twofish($mode = CRYPT_TWOFISH_MODE_CBC)
|
||||
function __construct($mode)
|
||||
{
|
||||
parent::Crypt_Base($mode);
|
||||
if ($mode == self::MODE_STREAM) {
|
||||
throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode');
|
||||
}
|
||||
|
||||
parent::__construct($mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key length.
|
||||
*
|
||||
* Valid key lengths are 128, 192 or 256 bits
|
||||
*
|
||||
* @access public
|
||||
* @param int $length
|
||||
*/
|
||||
function setKeyLength($length)
|
||||
{
|
||||
switch ($length) {
|
||||
case 128:
|
||||
case 192:
|
||||
case 256:
|
||||
break;
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
|
||||
}
|
||||
|
||||
parent::setKeyLength($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key.
|
||||
*
|
||||
* 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.
|
||||
* Rijndael supports five different key lengths
|
||||
*
|
||||
* @see setKeyLength()
|
||||
* @access public
|
||||
* @see Crypt_Base::setKey()
|
||||
* @param String $key
|
||||
* @param string $key
|
||||
* @throws \LengthException if the key length isn't supported
|
||||
*/
|
||||
function setKey($key)
|
||||
{
|
||||
$keylength = strlen($key);
|
||||
switch (true) {
|
||||
case $keylength <= 16:
|
||||
$key = str_pad($key, 16, "\0");
|
||||
switch (strlen($key)) {
|
||||
case 16:
|
||||
case 24:
|
||||
case 32:
|
||||
break;
|
||||
case $keylength <= 24:
|
||||
$key = str_pad($key, 24, "\0");
|
||||
break;
|
||||
case $keylength < 32:
|
||||
$key = str_pad($key, 32, "\0");
|
||||
break;
|
||||
case $keylength > 32:
|
||||
$key = substr($key, 0, 32);
|
||||
default:
|
||||
throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported');
|
||||
}
|
||||
|
||||
parent::setKey($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the key (expansion)
|
||||
*
|
||||
* @see Crypt_Base::_setupKey()
|
||||
* @see \phpseclib\Crypt\Base::_setupKey()
|
||||
* @access private
|
||||
*/
|
||||
function _setupKey()
|
||||
@ -536,9 +458,9 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
|
||||
switch (strlen($this->key)) {
|
||||
case 16:
|
||||
list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
for ($i = 0, $j = 1; $i < 40; $i+= 2,$j+= 2) {
|
||||
list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
|
||||
$A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^
|
||||
$m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^
|
||||
$m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^
|
||||
@ -559,9 +481,9 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
|
||||
list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
|
||||
for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
|
||||
$A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
|
||||
$m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
|
||||
@ -583,10 +505,10 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
}
|
||||
break;
|
||||
default: // 32
|
||||
list ($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
|
||||
list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
|
||||
list($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
|
||||
list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
|
||||
list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
|
||||
list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
|
||||
for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
|
||||
$A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
|
||||
$m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
|
||||
@ -619,9 +541,9 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
* _mdsrem function using by the twofish cipher algorithm
|
||||
*
|
||||
* @access private
|
||||
* @param String $A
|
||||
* @param String $B
|
||||
* @return Array
|
||||
* @param string $A
|
||||
* @param string $B
|
||||
* @return array
|
||||
*/
|
||||
function _mdsrem($A, $B)
|
||||
{
|
||||
@ -648,7 +570,9 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
$u^= 0x7fffffff & ($t >> 1);
|
||||
|
||||
// Add the modular polynomial on underflow.
|
||||
if ($t & 0x01) $u^= 0xa6 ;
|
||||
if ($t & 0x01) {
|
||||
$u^= 0xa6 ;
|
||||
}
|
||||
|
||||
// Remove t * (a + 1/a) * (x^3 + x).
|
||||
$B^= ($u << 24) | ($u << 8);
|
||||
@ -665,8 +589,8 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
* Encrypts a block
|
||||
*
|
||||
* @access private
|
||||
* @param String $in
|
||||
* @return String
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _encryptBlock($in)
|
||||
{
|
||||
@ -709,18 +633,20 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
$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
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
function _decryptBlock($in)
|
||||
{
|
||||
@ -763,38 +689,38 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
$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()
|
||||
* @see \phpseclib\Crypt\Base::_setupInlineCrypt()
|
||||
* @access private
|
||||
*/
|
||||
function _setupInlineCrypt()
|
||||
{
|
||||
$lambda_functions =& Crypt_Twofish::_getLambdaFunctions();
|
||||
$lambda_functions =& self::_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 );
|
||||
// (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit)
|
||||
$gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
|
||||
|
||||
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}";
|
||||
// Generation of a uniqe hash for our generated code
|
||||
$code_hash = "Crypt_Twofish, {$this->mode}";
|
||||
if ($gen_hi_opt_code) {
|
||||
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -812,7 +738,6 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
for ($i = 0; $i < 40; ++$i) {
|
||||
$K[] = '$K_' . $i;
|
||||
}
|
||||
|
||||
$init_crypt = '
|
||||
$S0 = $self->S0;
|
||||
$S1 = $self->S1;
|
||||
@ -919,6 +844,3 @@ class Crypt_Twofish extends Crypt_Base {
|
||||
$this->inline_crypt = $lambda_functions[$code_hash];
|
||||
}
|
||||
}
|
||||
|
||||
// vim: ts=4:sw=4:et:
|
||||
// vim6: fdl=1:
|
||||
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* BadConfigurationException
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Exception
|
||||
* @package BadConfigurationException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Exception;
|
||||
|
||||
/**
|
||||
* BadConfigurationException
|
||||
*
|
||||
* @package BadConfigurationException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
class BadConfigurationException extends \RuntimeException
|
||||
{
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* FileNotFoundException
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Exception
|
||||
* @package FileNotFoundException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Exception;
|
||||
|
||||
/**
|
||||
* FileNotFoundException
|
||||
*
|
||||
* @package FileNotFoundException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
class FileNotFoundException extends \RuntimeException
|
||||
{
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* NoSupportedAlgorithmsException
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Exception
|
||||
* @package NoSupportedAlgorithmsException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Exception;
|
||||
|
||||
/**
|
||||
* NoSupportedAlgorithmsException
|
||||
*
|
||||
* @package NoSupportedAlgorithmsException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
class NoSupportedAlgorithmsException extends \RuntimeException
|
||||
{
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* UnsupportedAlgorithmException
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Exception
|
||||
* @package UnsupportedAlgorithmException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2015 Jim Wigginton
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
* @link http://phpseclib.sourceforge.net
|
||||
*/
|
||||
|
||||
namespace phpseclib\Exception;
|
||||
|
||||
/**
|
||||
* UnsupportedAlgorithmException
|
||||
*
|
||||
* @package UnsupportedAlgorithmException
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
*/
|
||||
class UnsupportedAlgorithmException extends \RuntimeException
|
||||
{
|
||||
}
|
574
plugins/OStatus/extlib/phpseclib/File/ANSI.php
Normal file
574
plugins/OStatus/extlib/phpseclib/File/ANSI.php
Normal file
@ -0,0 +1,574 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Pure-PHP ANSI Decoder
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* If you call read() in \phpseclib\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. \phpseclib\File\ANSI is a {@link http://en.wikipedia.org/wiki/VT100 VT100} terminal emulator.
|
||||
*
|
||||
* @category File
|
||||
* @package 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
|
||||
*/
|
||||
|
||||
namespace phpseclib\File;
|
||||
|
||||
/**
|
||||
* Pure-PHP ANSI Decoder
|
||||
*
|
||||
* @package ANSI
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class ANSI
|
||||
{
|
||||
/**
|
||||
* Max Width
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $max_x;
|
||||
|
||||
/**
|
||||
* Max Height
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $max_y;
|
||||
|
||||
/**
|
||||
* Max History
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $max_history;
|
||||
|
||||
/**
|
||||
* History
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $history;
|
||||
|
||||
/**
|
||||
* History Attributes
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $history_attrs;
|
||||
|
||||
/**
|
||||
* Current Column
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $x;
|
||||
|
||||
/**
|
||||
* Current Row
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $y;
|
||||
|
||||
/**
|
||||
* Old Column
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $old_x;
|
||||
|
||||
/**
|
||||
* Old Row
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $old_y;
|
||||
|
||||
/**
|
||||
* An empty attribute cell
|
||||
*
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $base_attr_cell;
|
||||
|
||||
/**
|
||||
* The current attribute cell
|
||||
*
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $attr_cell;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Current ANSI code
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $ansi;
|
||||
|
||||
/**
|
||||
* Tokenization
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $tokenization;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @return \phpseclib\File\ANSI
|
||||
* @access public
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
$attr_cell = new \stdClass();
|
||||
$attr_cell->bold = false;
|
||||
$attr_cell->underline = false;
|
||||
$attr_cell->blink = false;
|
||||
$attr_cell->background = 'black';
|
||||
$attr_cell->foreground = 'white';
|
||||
$attr_cell->reverse = false;
|
||||
$this->base_attr_cell = clone $attr_cell;
|
||||
$this->attr_cell = clone $attr_cell;
|
||||
|
||||
$this->setHistory(200);
|
||||
$this->setDimensions(80, 24);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set terminal width and height
|
||||
*
|
||||
* Resets the screen as well
|
||||
*
|
||||
* @param int $x
|
||||
* @param int $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 + 2, $this->base_attr_cell);
|
||||
$this->screen = array_fill(0, $this->max_y + 1, '');
|
||||
$this->attrs = array_fill(0, $this->max_y + 1, $this->attr_row);
|
||||
$this->ansi = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of lines that should be logged past the terminal height
|
||||
*
|
||||
* @param int $x
|
||||
* @param int $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)
|
||||
{
|
||||
$this->tokenization = array('');
|
||||
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;
|
||||
}
|
||||
$this->tokenization[] = $this->ansi;
|
||||
$this->tokenization[] = '';
|
||||
// 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, $this->max_x - $this->x, array_fill($this->x, $this->max_x - $this->x - 1, $this->base_attr_cell));
|
||||
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
|
||||
case "\x1B(B": // set united states g0 character set
|
||||
break;
|
||||
case "\x1BE": // Move to next line
|
||||
$this->_newLine();
|
||||
$this->x = 0;
|
||||
break;
|
||||
default:
|
||||
switch (true) {
|
||||
case preg_match('#\x1B\[(\d+)B#', $this->ansi, $match): // Move cursor down n lines
|
||||
$this->old_y = $this->y;
|
||||
$this->y+= $match[1];
|
||||
break;
|
||||
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;
|
||||
$this->x+= $match[1];
|
||||
break;
|
||||
case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines
|
||||
$this->old_x = $this->x;
|
||||
$this->x-= $match[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
|
||||
$attr_cell = &$this->attr_cell;
|
||||
$mods = explode(';', $match[1]);
|
||||
foreach ($mods as $mod) {
|
||||
switch ($mod) {
|
||||
case 0: // Turn off character attributes
|
||||
$attr_cell = clone $this->base_attr_cell;
|
||||
break;
|
||||
case 1: // Turn bold mode on
|
||||
$attr_cell->bold = true;
|
||||
break;
|
||||
case 4: // Turn underline mode on
|
||||
$attr_cell->underline = true;
|
||||
break;
|
||||
case 5: // Turn blinking mode on
|
||||
$attr_cell->blink = true;
|
||||
break;
|
||||
case 7: // Turn reverse video on
|
||||
$attr_cell->reverse = !$attr_cell->reverse;
|
||||
$temp = $attr_cell->background;
|
||||
$attr_cell->background = $attr_cell->foreground;
|
||||
$attr_cell->foreground = $temp;
|
||||
break;
|
||||
default: // set colors
|
||||
//$front = $attr_cell->reverse ? &$attr_cell->background : &$attr_cell->foreground;
|
||||
$front = &$attr_cell->{ $attr_cell->reverse ? 'background' : 'foreground' };
|
||||
//$back = $attr_cell->reverse ? &$attr_cell->foreground : &$attr_cell->background;
|
||||
$back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' };
|
||||
switch ($mod) {
|
||||
// @codingStandardsIgnoreStart
|
||||
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;
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
||||
default:
|
||||
//user_error('Unsupported attribute: ' . $mod);
|
||||
$this->ansi = '';
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//user_error("{$this->ansi} is unsupported\r\n");
|
||||
}
|
||||
}
|
||||
$this->ansi = '';
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->tokenization[count($this->tokenization) - 1].= $source[$i];
|
||||
switch ($source[$i]) {
|
||||
case "\r":
|
||||
$this->x = 0;
|
||||
break;
|
||||
case "\n":
|
||||
$this->_newLine();
|
||||
break;
|
||||
case "\x08": // backspace
|
||||
if ($this->x) {
|
||||
$this->x--;
|
||||
$this->attrs[$this->y][$this->x] = clone $this->base_attr_cell;
|
||||
$this->screen[$this->y] = substr_replace(
|
||||
$this->screen[$this->y],
|
||||
$source[$i],
|
||||
$this->x,
|
||||
1
|
||||
);
|
||||
}
|
||||
break;
|
||||
case "\x0F": // shift
|
||||
break;
|
||||
case "\x1B": // start ANSI escape code
|
||||
$this->tokenization[count($this->tokenization) - 1] = substr($this->tokenization[count($this->tokenization) - 1], 0, -1);
|
||||
//if (!strlen($this->tokenization[count($this->tokenization) - 1])) {
|
||||
// array_pop($this->tokenization);
|
||||
//}
|
||||
$this->ansi.= "\x1B";
|
||||
break;
|
||||
default:
|
||||
$this->attrs[$this->y][$this->x] = clone $this->attr_cell;
|
||||
if ($this->x > strlen($this->screen[$this->y])) {
|
||||
$this->screen[$this->y] = str_repeat(' ', $this->x);
|
||||
}
|
||||
$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 coordinate without preformating
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
function _processCoordinate($last_attr, $cur_attr, $char)
|
||||
{
|
||||
$output = '';
|
||||
|
||||
if ($last_attr != $cur_attr) {
|
||||
$close = $open = '';
|
||||
if ($last_attr->foreground != $cur_attr->foreground) {
|
||||
if ($cur_attr->foreground != 'white') {
|
||||
$open.= '<span style="color: ' . $cur_attr->foreground . '">';
|
||||
}
|
||||
if ($last_attr->foreground != 'white') {
|
||||
$close = '</span>' . $close;
|
||||
}
|
||||
}
|
||||
if ($last_attr->background != $cur_attr->background) {
|
||||
if ($cur_attr->background != 'black') {
|
||||
$open.= '<span style="background: ' . $cur_attr->background . '">';
|
||||
}
|
||||
if ($last_attr->background != 'black') {
|
||||
$close = '</span>' . $close;
|
||||
}
|
||||
}
|
||||
if ($last_attr->bold != $cur_attr->bold) {
|
||||
if ($cur_attr->bold) {
|
||||
$open.= '<b>';
|
||||
} else {
|
||||
$close = '</b>' . $close;
|
||||
}
|
||||
}
|
||||
if ($last_attr->underline != $cur_attr->underline) {
|
||||
if ($cur_attr->underline) {
|
||||
$open.= '<u>';
|
||||
} else {
|
||||
$close = '</u>' . $close;
|
||||
}
|
||||
}
|
||||
if ($last_attr->blink != $cur_attr->blink) {
|
||||
if ($cur_attr->blink) {
|
||||
$open.= '<blink>';
|
||||
} else {
|
||||
$close = '</blink>' . $close;
|
||||
}
|
||||
}
|
||||
$output.= $close . $open;
|
||||
}
|
||||
|
||||
$output.= htmlspecialchars($char);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current screen without preformating
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
function _getScreen()
|
||||
{
|
||||
$output = '';
|
||||
$last_attr = $this->base_attr_cell;
|
||||
for ($i = 0; $i <= $this->max_y; $i++) {
|
||||
for ($j = 0; $j <= $this->max_x; $j++) {
|
||||
$cur_attr = $this->attrs[$i][$j];
|
||||
$output.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->screen[$i][$j]) ? $this->screen[$i][$j] : '');
|
||||
$last_attr = $this->attrs[$i][$j];
|
||||
}
|
||||
$output.= "\r\n";
|
||||
}
|
||||
$output = substr($output, 0, -2);
|
||||
// close any remaining open tags
|
||||
$output.= $this->_processCoordinate($last_attr, $this->base_attr_cell, '');
|
||||
return rtrim($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current screen
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getScreen()
|
||||
{
|
||||
return '<pre width="' . ($this->max_x + 1) . '" style="color: white; background: black">' . $this->_getScreen() . '</pre>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current screen and the x previous lines
|
||||
*
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getHistory()
|
||||
{
|
||||
$scrollback = '';
|
||||
$last_attr = $this->base_attr_cell;
|
||||
for ($i = 0; $i < count($this->history); $i++) {
|
||||
for ($j = 0; $j <= $this->max_x + 1; $j++) {
|
||||
$cur_attr = $this->history_attrs[$i][$j];
|
||||
$scrollback.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->history[$i][$j]) ? $this->history[$i][$j] : '');
|
||||
$last_attr = $this->history_attrs[$i][$j];
|
||||
}
|
||||
$scrollback.= "\r\n";
|
||||
}
|
||||
$base_attr_cell = $this->base_attr_cell;
|
||||
$this->base_attr_cell = $last_attr;
|
||||
$scrollback.= $this->_getScreen();
|
||||
$this->base_attr_cell = $base_attr_cell;
|
||||
|
||||
return '<pre width="' . ($this->max_x + 1) . '" style="color: white; background: black">' . $scrollback . '</span></pre>';
|
||||
}
|
||||
}
|
1310
plugins/OStatus/extlib/phpseclib/File/ASN1.php
Normal file
1310
plugins/OStatus/extlib/phpseclib/File/ASN1.php
Normal file
File diff suppressed because it is too large
Load Diff
47
plugins/OStatus/extlib/phpseclib/File/ASN1/Element.php
Normal file
47
plugins/OStatus/extlib/phpseclib/File/ASN1/Element.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Pure-PHP ASN.1 Parser
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category File
|
||||
* @package ASN1
|
||||
* @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
|
||||
*/
|
||||
|
||||
namespace phpseclib\File\ASN1;
|
||||
|
||||
/**
|
||||
* ASN.1 Element
|
||||
*
|
||||
* Bypass normal encoding rules in phpseclib\File\ASN1::encodeDER()
|
||||
*
|
||||
* @package ASN1
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class Element
|
||||
{
|
||||
/**
|
||||
* Raw element value
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $element;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $encoded
|
||||
* @return \phpseclib\File\ASN1\Element
|
||||
* @access public
|
||||
*/
|
||||
function __construct($encoded)
|
||||
{
|
||||
$this->element = $encoded;
|
||||
}
|
||||
}
|
4746
plugins/OStatus/extlib/phpseclib/File/X509.php
Normal file
4746
plugins/OStatus/extlib/phpseclib/File/X509.php
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
338
plugins/OStatus/extlib/phpseclib/Net/SCP.php
Normal file
338
plugins/OStatus/extlib/phpseclib/Net/SCP.php
Normal file
@ -0,0 +1,338 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Pure-PHP implementation of SCP.
|
||||
*
|
||||
* PHP version 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 'vendor/autoload.php';
|
||||
*
|
||||
* $ssh = new \phpseclib\Net\SSH2('www.domain.tld');
|
||||
* if (!$ssh->login('username', 'password')) {
|
||||
* exit('bad login');
|
||||
* }
|
||||
* $scp = new \phpseclib\Net\SCP($ssh);
|
||||
*
|
||||
* $scp->put('abcd', str_repeat('x', 1024*1024));
|
||||
* ?>
|
||||
* </code>
|
||||
*
|
||||
* @category Net
|
||||
* @package 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
|
||||
*/
|
||||
|
||||
namespace phpseclib\Net;
|
||||
|
||||
use phpseclib\Exception\FileNotFoundException;
|
||||
|
||||
/**
|
||||
* Pure-PHP implementations of SCP.
|
||||
*
|
||||
* @package SCP
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class SCP
|
||||
{
|
||||
/**#@+
|
||||
* @access public
|
||||
* @see \phpseclib\Net\SCP::put()
|
||||
*/
|
||||
/**
|
||||
* Reads data from a local file.
|
||||
*/
|
||||
const SOURCE_LOCAL_FILE = 1;
|
||||
/**
|
||||
* Reads data from a string.
|
||||
*/
|
||||
const SOURCE_STRING = 2;
|
||||
/**#@-*/
|
||||
|
||||
/**#@+
|
||||
* @access private
|
||||
* @see \phpseclib\Net\SCP::_send()
|
||||
* @see \phpseclib\Net\SCP::_receive()
|
||||
*/
|
||||
/**
|
||||
* SSH1 is being used.
|
||||
*/
|
||||
const MODE_SSH1 = 1;
|
||||
/**
|
||||
* SSH2 is being used.
|
||||
*/
|
||||
const MODE_SSH2 = 2;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* SSH Object
|
||||
*
|
||||
* @var object
|
||||
* @access private
|
||||
*/
|
||||
var $ssh;
|
||||
|
||||
/**
|
||||
* Packet Size
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $packet_size;
|
||||
|
||||
/**
|
||||
* Mode
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $mode;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* Connects to an SSH server
|
||||
*
|
||||
* @param string $host
|
||||
* @param int $port
|
||||
* @param int $timeout
|
||||
* @return \phpseclib\Net\SCP
|
||||
* @access public
|
||||
*/
|
||||
function __construct($ssh)
|
||||
{
|
||||
if ($ssh instanceof SSH2) {
|
||||
$this->mode = self::MODE_SSH2;
|
||||
} elseif ($ssh instanceof SSH1) {
|
||||
$this->packet_size = 50000;
|
||||
$this->mode = self::MODE_SSH1;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->ssh = $ssh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads a file to the SCP server.
|
||||
*
|
||||
* By default, \phpseclib\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 \phpseclib\Net\SCP::get(), you will get a file, twelve bytes
|
||||
* long, containing 'filename.ext' as its contents.
|
||||
*
|
||||
* Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_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 int $mode
|
||||
* @param callable $callback
|
||||
* @throws \phpseclib\Exception\FileNotFoundException if you're uploading via a file and the file doesn't exist
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function put($remote_file, $data, $mode = self::SOURCE_STRING, $callback = null)
|
||||
{
|
||||
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 == self::MODE_SSH2) {
|
||||
$this->packet_size = $this->ssh->packet_size_client_to_server[SSH2::CHANNEL_EXEC] - 4;
|
||||
}
|
||||
|
||||
$remote_file = basename($remote_file);
|
||||
|
||||
if ($mode == self::SOURCE_STRING) {
|
||||
$size = strlen($data);
|
||||
} else {
|
||||
if (!is_file($data)) {
|
||||
throw new FileNotFoundException("$data is not a valid file");
|
||||
}
|
||||
|
||||
$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 & self::SOURCE_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 != self::SOURCE_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 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 self::MODE_SSH2:
|
||||
$this->ssh->_send_channel_packet(SSH2::CHANNEL_EXEC, $data);
|
||||
break;
|
||||
case self::MODE_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
|
||||
* @throws \UnexpectedValueException on receipt of an unexpected packet
|
||||
* @access private
|
||||
*/
|
||||
function _receive()
|
||||
{
|
||||
switch ($this->mode) {
|
||||
case self::MODE_SSH2:
|
||||
return $this->ssh->_get_channel_packet(SSH2::CHANNEL_EXEC, true);
|
||||
case self::MODE_SSH1:
|
||||
if (!$this->ssh->bitmap) {
|
||||
return false;
|
||||
}
|
||||
while (true) {
|
||||
$response = $this->ssh->_get_binary_packet();
|
||||
switch ($response[SSH1::RESPONSE_TYPE]) {
|
||||
case NET_SSH1_SMSG_STDOUT_DATA:
|
||||
extract(unpack('Nlength', $response[SSH1::RESPONSE_DATA]));
|
||||
return $this->ssh->_string_shift($response[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:
|
||||
throw new \UnexpectedValueException('Unknown packet received');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the connection to an SSH server
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _close()
|
||||
{
|
||||
switch ($this->mode) {
|
||||
case self::MODE_SSH2:
|
||||
$this->ssh->_close_channel(SSH2::CHANNEL_EXEC, true);
|
||||
break;
|
||||
case self::MODE_SSH1:
|
||||
$this->ssh->disconnect();
|
||||
}
|
||||
}
|
||||
}
|
2943
plugins/OStatus/extlib/phpseclib/Net/SFTP.php
Normal file
2943
plugins/OStatus/extlib/phpseclib/Net/SFTP.php
Normal file
File diff suppressed because it is too large
Load Diff
795
plugins/OStatus/extlib/phpseclib/Net/SFTP/Stream.php
Normal file
795
plugins/OStatus/extlib/phpseclib/Net/SFTP/Stream.php
Normal file
@ -0,0 +1,795 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* SFTP Stream Wrapper
|
||||
*
|
||||
* Creates an sftp:// protocol handler that can be used with, for example, fopen(), dir(), etc.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Net
|
||||
* @package SFTP
|
||||
* @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
|
||||
*/
|
||||
|
||||
namespace phpseclib\Net\SFTP;
|
||||
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\Net\SFTP;
|
||||
use phpseclib\Net\SSH2;
|
||||
|
||||
/**
|
||||
* SFTP Stream Wrapper
|
||||
*
|
||||
* @package SFTP
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access public
|
||||
*/
|
||||
class 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 int
|
||||
* @access private
|
||||
*/
|
||||
var $pos;
|
||||
|
||||
/**
|
||||
* Size
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $size;
|
||||
|
||||
/**
|
||||
* Directory entries
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $entries;
|
||||
|
||||
/**
|
||||
* EOF flag
|
||||
*
|
||||
* @var bool
|
||||
* @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 string $protocol The wrapper name to be registered.
|
||||
* @return bool True on success, false otherwise.
|
||||
* @access public
|
||||
*/
|
||||
static function register($protocol = 'sftp')
|
||||
{
|
||||
if (in_array($protocol, stream_get_wrappers(), true)) {
|
||||
return false;
|
||||
}
|
||||
return stream_wrapper_register($protocol, get_called_class());
|
||||
}
|
||||
|
||||
/**
|
||||
* The Constructor
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
if (defined('NET_SFTP_STREAM_LOGGING')) {
|
||||
echo "__construct()\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$orig = $path;
|
||||
extract(parse_url($path) + array('port' => 22));
|
||||
if (isset($query)) {
|
||||
$path.= '?' . $query;
|
||||
} elseif (preg_match('/(\?|\?#)$/', $orig)) {
|
||||
$path.= '?';
|
||||
}
|
||||
if (isset($fragment)) {
|
||||
$path.= '#' . $fragment;
|
||||
} elseif ($orig[strlen($orig) - 1] == '#') {
|
||||
$path.= '#';
|
||||
}
|
||||
|
||||
if (!isset($host)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($this->context)) {
|
||||
$context = stream_context_get_params($this->context);
|
||||
if (isset($context['notification'])) {
|
||||
$this->notification = $context['notification'];
|
||||
}
|
||||
}
|
||||
|
||||
if (preg_match('/^{[a-z0-9]+}$/i', $host)) {
|
||||
$host = SSH2::getConnectionByResourceId($host);
|
||||
if ($host === false) {
|
||||
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) && $sftp instanceof 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']) && $context[$scheme]['privkey'] instanceof 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 \phpseclib\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 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 int $options
|
||||
* @param string $opened_path
|
||||
* @return bool
|
||||
* @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 {
|
||||
$this->sftp->touch($path);
|
||||
$this->size = 0;
|
||||
}
|
||||
} else {
|
||||
switch ($this->mode[0]) {
|
||||
case 'x':
|
||||
return false;
|
||||
case 'w':
|
||||
$this->sftp->truncate($path, 0);
|
||||
$this->size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$this->pos = $this->mode[0] != 'a' ? 0 : $this->size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from stream
|
||||
*
|
||||
* @param int $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, SFTP::SOURCE_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 int
|
||||
* @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 bool
|
||||
* @access public
|
||||
*/
|
||||
function _stream_eof()
|
||||
{
|
||||
return $this->eof;
|
||||
}
|
||||
|
||||
/**
|
||||
* Seeks to specific location in a stream
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int $whence
|
||||
* @return bool
|
||||
* @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 int $option
|
||||
* @param mixed $var
|
||||
* @return bool
|
||||
* @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 int $cast_as
|
||||
* @return resource
|
||||
* @access public
|
||||
*/
|
||||
function _stream_cast($cast_as)
|
||||
{
|
||||
return $this->sftp->fsock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advisory file locking
|
||||
*
|
||||
* @param int $operation
|
||||
* @return bool
|
||||
* @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 \phpseclib\Net\SFTP
|
||||
* does.
|
||||
*
|
||||
* @param string $path_from
|
||||
* @param string $path_to
|
||||
* @return bool
|
||||
* @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 int $options
|
||||
* @return bool
|
||||
* @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 bool
|
||||
* @access public
|
||||
*/
|
||||
function _dir_rewinddir()
|
||||
{
|
||||
$this->pos = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close directory handle
|
||||
*
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function _dir_closedir()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a directory
|
||||
*
|
||||
* Only valid $options is STREAM_MKDIR_RECURSIVE
|
||||
*
|
||||
* @param string $path
|
||||
* @param int $mode
|
||||
* @param int $options
|
||||
* @return bool
|
||||
* @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 int $mode
|
||||
* @param int $options
|
||||
* @return bool
|
||||
* @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 \phpseclib\Net\SFTP doesn't cache stuff before writing
|
||||
*
|
||||
* @return bool
|
||||
* @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 bool
|
||||
* @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 \phpseclib\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 int $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 int $new_size
|
||||
* @return bool
|
||||
* @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 \phpseclib\Net\SFTP.
|
||||
*
|
||||
* @param int $option
|
||||
* @param int $arg1
|
||||
* @param int $arg2
|
||||
* @return bool
|
||||
* @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);
|
||||
}
|
||||
}
|
1607
plugins/OStatus/extlib/phpseclib/Net/SSH1.php
Normal file
1607
plugins/OStatus/extlib/phpseclib/Net/SSH1.php
Normal file
File diff suppressed because it is too large
Load Diff
4224
plugins/OStatus/extlib/phpseclib/Net/SSH2.php
Normal file
4224
plugins/OStatus/extlib/phpseclib/Net/SSH2.php
Normal file
File diff suppressed because it is too large
Load Diff
313
plugins/OStatus/extlib/phpseclib/System/SSH/Agent.php
Normal file
313
plugins/OStatus/extlib/phpseclib/System/SSH/Agent.php
Normal file
@ -0,0 +1,313 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Pure-PHP ssh-agent client.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* Here are some examples of how to use this library:
|
||||
* <code>
|
||||
* <?php
|
||||
* include 'vendor/autoload.php';
|
||||
*
|
||||
* $agent = new \phpseclib\System\SSH\Agent();
|
||||
*
|
||||
* $ssh = new \phpseclib\Net\SSH2('www.domain.tld');
|
||||
* if (!$ssh->login('username', $agent)) {
|
||||
* exit('Login Failed');
|
||||
* }
|
||||
*
|
||||
* echo $ssh->exec('pwd');
|
||||
* echo $ssh->exec('ls -la');
|
||||
* ?>
|
||||
* </code>
|
||||
*
|
||||
* @category System
|
||||
* @package 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
|
||||
*/
|
||||
|
||||
namespace phpseclib\System\SSH;
|
||||
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\Exception\BadConfigurationException;
|
||||
use phpseclib\System\SSH\Agent\Identity;
|
||||
|
||||
/**
|
||||
* Pure-PHP ssh-agent client identity factory
|
||||
*
|
||||
* requestIdentities() method pumps out \phpseclib\System\SSH\Agent\Identity objects
|
||||
*
|
||||
* @package SSH\Agent
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access internal
|
||||
*/
|
||||
class Agent
|
||||
{
|
||||
/**#@+
|
||||
* Message numbers
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
// to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1)
|
||||
const SSH_AGENTC_REQUEST_IDENTITIES = 11;
|
||||
// this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2).
|
||||
const SSH_AGENT_IDENTITIES_ANSWER = 12;
|
||||
// the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3)
|
||||
const SSH_AGENTC_SIGN_REQUEST = 13;
|
||||
// the SSH1 response is SSH_AGENT_RSA_RESPONSE (4)
|
||||
const SSH_AGENT_SIGN_RESPONSE = 14;
|
||||
/**#@-*/
|
||||
|
||||
/**@+
|
||||
* Agent forwarding status
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
// no forwarding requested and not active
|
||||
const FORWARD_NONE = 0;
|
||||
// request agent forwarding when opportune
|
||||
const FORWARD_REQUEST = 1;
|
||||
// forwarding has been request and is active
|
||||
const FORWARD_ACTIVE = 2;
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Unused
|
||||
*/
|
||||
const SSH_AGENT_FAILURE = 5;
|
||||
|
||||
/**
|
||||
* Socket Resource
|
||||
*
|
||||
* @var resource
|
||||
* @access private
|
||||
*/
|
||||
var $fsock;
|
||||
|
||||
/**
|
||||
* Agent forwarding status
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $forward_status = self::FORWARD_NONE;
|
||||
|
||||
/**
|
||||
* Buffer for accumulating forwarded authentication
|
||||
* agent data arriving on SSH data channel destined
|
||||
* for agent unix socket
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $socket_buffer = '';
|
||||
|
||||
/**
|
||||
* Tracking the number of bytes we are expecting
|
||||
* to arrive for the agent socket on the SSH data
|
||||
* channel
|
||||
*/
|
||||
var $expected_bytes = 0;
|
||||
|
||||
/**
|
||||
* Default Constructor
|
||||
*
|
||||
* @return \phpseclib\System\SSH\Agent
|
||||
* @throws \phpseclib\Exception\BadConfigurationException if SSH_AUTH_SOCK cannot be found
|
||||
* @throws \RuntimeException on connection errors
|
||||
* @access public
|
||||
*/
|
||||
function __construct()
|
||||
{
|
||||
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:
|
||||
throw new BadConfigurationException('SSH_AUTH_SOCK not found');
|
||||
}
|
||||
|
||||
$this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
|
||||
if (!$this->fsock) {
|
||||
throw new \RuntimeException("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 \phpseclib\System\SSH\Agent\Identity objects
|
||||
*
|
||||
* @return array
|
||||
* @throws \RuntimeException on receipt of unexpected packets
|
||||
* @access public
|
||||
*/
|
||||
function requestIdentities()
|
||||
{
|
||||
if (!$this->fsock) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES);
|
||||
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
||||
throw new \RuntimeException('Connection closed while requesting identities');
|
||||
}
|
||||
|
||||
$length = current(unpack('N', fread($this->fsock, 4)));
|
||||
$type = ord(fread($this->fsock, 1));
|
||||
if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) {
|
||||
throw new \RuntimeException('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);
|
||||
$key_str = 'ssh-rsa ' . Base64::encode($key_blob);
|
||||
$length = current(unpack('N', fread($this->fsock, 4)));
|
||||
if ($length) {
|
||||
$key_str.= ' ' . fread($this->fsock, $length);
|
||||
}
|
||||
$length = current(unpack('N', substr($key_blob, 0, 4)));
|
||||
$key_type = substr($key_blob, 4, $length);
|
||||
switch ($key_type) {
|
||||
case 'ssh-rsa':
|
||||
$key = new RSA();
|
||||
$key->load($key_str);
|
||||
break;
|
||||
case 'ssh-dss':
|
||||
// not currently supported
|
||||
break;
|
||||
}
|
||||
// resources are passed by reference by default
|
||||
if (isset($key)) {
|
||||
$identity = new Identity($this->fsock);
|
||||
$identity->setPublicKey($key);
|
||||
$identity->setPublicKeyBlob($key_blob);
|
||||
$identities[] = $identity;
|
||||
unset($key);
|
||||
}
|
||||
}
|
||||
|
||||
return $identities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal that agent forwarding should
|
||||
* be requested when a channel is opened
|
||||
*
|
||||
* @param Net_SSH2 $ssh
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
function startSSHForwarding($ssh)
|
||||
{
|
||||
if ($this->forward_status == self::FORWARD_NONE) {
|
||||
$this->forward_status = self::FORWARD_REQUEST;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request agent forwarding of remote server
|
||||
*
|
||||
* @param Net_SSH2 $ssh
|
||||
* @return bool
|
||||
* @access private
|
||||
*/
|
||||
function _request_forwarding($ssh)
|
||||
{
|
||||
$request_channel = $ssh->_get_open_channel();
|
||||
if ($request_channel === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$packet = pack(
|
||||
'CNNa*C',
|
||||
NET_SSH2_MSG_CHANNEL_REQUEST,
|
||||
$ssh->server_channels[$request_channel],
|
||||
strlen('auth-agent-req@openssh.com'),
|
||||
'auth-agent-req@openssh.com',
|
||||
1
|
||||
);
|
||||
|
||||
$ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST;
|
||||
|
||||
if (!$ssh->_send_binary_packet($packet)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = $ssh->_get_channel_packet($request_channel);
|
||||
if ($response === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN;
|
||||
$this->forward_status = self::FORWARD_ACTIVE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* On successful channel open
|
||||
*
|
||||
* This method is called upon successful channel
|
||||
* open to give the SSH Agent an opportunity
|
||||
* to take further action. i.e. request agent forwarding
|
||||
*
|
||||
* @param Net_SSH2 $ssh
|
||||
* @access private
|
||||
*/
|
||||
function _on_channel_open($ssh)
|
||||
{
|
||||
if ($this->forward_status == self::FORWARD_REQUEST) {
|
||||
$this->_request_forwarding($ssh);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forward data to SSH Agent and return data reply
|
||||
*
|
||||
* @param string $data
|
||||
* @return data from SSH Agent
|
||||
* @throws \RuntimeException on connection errors
|
||||
* @access private
|
||||
*/
|
||||
function _forward_data($data)
|
||||
{
|
||||
if ($this->expected_bytes > 0) {
|
||||
$this->socket_buffer.= $data;
|
||||
$this->expected_bytes -= strlen($data);
|
||||
} else {
|
||||
$agent_data_bytes = current(unpack('N', $data));
|
||||
$current_data_bytes = strlen($data);
|
||||
$this->socket_buffer = $data;
|
||||
if ($current_data_bytes != $agent_data_bytes + 4) {
|
||||
$this->expected_bytes = ($agent_data_bytes + 4) - $current_data_bytes;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) {
|
||||
throw new \RuntimeException('Connection closed attempting to forward data to SSH agent');
|
||||
}
|
||||
|
||||
$this->socket_buffer = '';
|
||||
$this->expected_bytes = 0;
|
||||
|
||||
$agent_reply_bytes = current(unpack('N', fread($this->fsock, 4)));
|
||||
|
||||
$agent_reply_data = fread($this->fsock, $agent_reply_bytes);
|
||||
$agent_reply_data = current(unpack('a*', $agent_reply_data));
|
||||
|
||||
return pack('Na*', $agent_reply_bytes, $agent_reply_data);
|
||||
}
|
||||
}
|
170
plugins/OStatus/extlib/phpseclib/System/SSH/Agent/Identity.php
Normal file
170
plugins/OStatus/extlib/phpseclib/System/SSH/Agent/Identity.php
Normal file
@ -0,0 +1,170 @@
|
||||
<?php
|
||||
/**
|
||||
* Pure-PHP ssh-agent client.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category System
|
||||
* @package SSH\Agent
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @copyright 2009 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
|
||||
*/
|
||||
|
||||
namespace phpseclib\System\SSH\Agent;
|
||||
|
||||
use phpseclib\Crypt\RSA;
|
||||
use phpseclib\Exception\UnsupportedAlgorithmException;
|
||||
use phpseclib\System\SSH\Agent;
|
||||
|
||||
/**
|
||||
* Pure-PHP ssh-agent client identity object
|
||||
*
|
||||
* Instantiation should only be performed by \phpseclib\System\SSH\Agent class.
|
||||
* This could be thought of as implementing an interface that phpseclib\Crypt\RSA
|
||||
* implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something.
|
||||
* The methods in this interface would be getPublicKey and sign since those are the
|
||||
* methods phpseclib looks for to perform public key authentication.
|
||||
*
|
||||
* @package SSH\Agent
|
||||
* @author Jim Wigginton <terrafrost@php.net>
|
||||
* @access internal
|
||||
*/
|
||||
class Identity
|
||||
{
|
||||
/**
|
||||
* Key Object
|
||||
*
|
||||
* @var \phpseclib\Crypt\RSA
|
||||
* @access private
|
||||
* @see self::getPublicKey()
|
||||
*/
|
||||
var $key;
|
||||
|
||||
/**
|
||||
* Key Blob
|
||||
*
|
||||
* @var string
|
||||
* @access private
|
||||
* @see self::sign()
|
||||
*/
|
||||
var $key_blob;
|
||||
|
||||
/**
|
||||
* Socket Resource
|
||||
*
|
||||
* @var resource
|
||||
* @access private
|
||||
* @see self::sign()
|
||||
*/
|
||||
var $fsock;
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
*
|
||||
* @param resource $fsock
|
||||
* @return \phpseclib\System\SSH\Agent\Identity
|
||||
* @access private
|
||||
*/
|
||||
function __construct($fsock)
|
||||
{
|
||||
$this->fsock = $fsock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Public Key
|
||||
*
|
||||
* Called by \phpseclib\System\SSH\Agent::requestIdentities()
|
||||
*
|
||||
* @param \phpseclib\Crypt\RSA $key
|
||||
* @access private
|
||||
*/
|
||||
function setPublicKey($key)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->key->setPublicKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Public Key
|
||||
*
|
||||
* Called by \phpseclib\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key
|
||||
* but this saves a small amount of computation.
|
||||
*
|
||||
* @param string $key_blob
|
||||
* @access private
|
||||
*/
|
||||
function setPublicKeyBlob($key_blob)
|
||||
{
|
||||
$this->key_blob = $key_blob;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Public Key
|
||||
*
|
||||
* Wrapper for $this->key->getPublicKey()
|
||||
*
|
||||
* @param int $type optional
|
||||
* @return mixed
|
||||
* @access public
|
||||
*/
|
||||
function getPublicKey($type = 'PKCS8')
|
||||
{
|
||||
return $this->key->getPublicKey($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hash
|
||||
*
|
||||
* ssh-agent only supports signatures with sha1 hashes but to maintain BC with RSA.php this function exists
|
||||
*
|
||||
* @param string $hash optional
|
||||
* @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
|
||||
* @access public
|
||||
*/
|
||||
function setHash($hash = 'sha1')
|
||||
{
|
||||
if ($hash != 'sha1') {
|
||||
throw new UnsupportedAlgorithmException('ssh-agent can only be used with the sha1 hash');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a signature
|
||||
*
|
||||
* See "2.6.2 Protocol 2 private key signature request"
|
||||
*
|
||||
* @param string $message
|
||||
* @param int $padding optional
|
||||
* @return string
|
||||
* @throws \RuntimeException on connection errors
|
||||
* @throws \phpseclib\Exception\UnsupportedAlgorithmException if the algorithm is unsupported
|
||||
* @access public
|
||||
*/
|
||||
function sign($message, $padding = RSA::PADDING_PKCS1)
|
||||
{
|
||||
if ($padding != RSA::PADDING_PKCS1 && $padding != RSA::PADDING_RELAXED_PKCS1) {
|
||||
throw new UnsupportedAlgorithmException('ssh-agent can only create PKCS1 signatures');
|
||||
}
|
||||
|
||||
// the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
|
||||
$packet = pack('CNa*Na*N', Agent::SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, 0);
|
||||
$packet = pack('Na*', strlen($packet), $packet);
|
||||
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
||||
throw new \RuntimeException('Connection closed during signing');
|
||||
}
|
||||
|
||||
$length = current(unpack('N', fread($this->fsock, 4)));
|
||||
$type = ord(fread($this->fsock, 1));
|
||||
if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) {
|
||||
throw new \RuntimeException('Unable to retreive signature');
|
||||
}
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
20
plugins/OStatus/extlib/phpseclib/bootstrap.php
Normal file
20
plugins/OStatus/extlib/phpseclib/bootstrap.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Bootstrapping File for phpseclib
|
||||
*
|
||||
* composer isn't a requirement for phpseclib 2.0 but this file isn't really required
|
||||
* either. it's a bonus for those using composer but if you're not phpseclib will
|
||||
* still work
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||
*/
|
||||
if (extension_loaded('mbstring')) {
|
||||
// 2 - MB_OVERLOAD_STRING
|
||||
if (ini_get('mbstring.func_overload') & 2) {
|
||||
throw new UnexpectedValueException(
|
||||
'Overloading of string functions using mbstring.func_overload ' .
|
||||
'is not supported by phpseclib.'
|
||||
);
|
||||
}
|
||||
}
|
@ -3,4 +3,4 @@
|
||||
HOME = .
|
||||
RANDFILE = $ENV::HOME/.rnd
|
||||
|
||||
[ v3_ca ]
|
||||
[ v3_ca ]
|
||||
|
Loading…
Reference in New Issue
Block a user