phpceclib 2.0.21
This commit is contained in:
parent
c7c1d030e3
commit
d73ffee957
|
@ -422,7 +422,7 @@ main license and authors:
|
||||||
lib/3rdParty/tcpdf D 2018 Nicola Asuni - Tecnick.com LTD
|
lib/3rdParty/tcpdf D 2018 Nicola Asuni - Tecnick.com LTD
|
||||||
lib/3rdParty/tcpdf/fonts/DejaVu*.ttf A Public Domain, Bitstream, Inc., Tavmjong Bah
|
lib/3rdParty/tcpdf/fonts/DejaVu*.ttf A Public Domain, Bitstream, Inc., Tavmjong Bah
|
||||||
lib/3rdParty/tcpdf/fonts/DejaVu*.z A Public Domain, Bitstream, Inc., Tavmjong Bah
|
lib/3rdParty/tcpdf/fonts/DejaVu*.z A Public Domain, Bitstream, Inc., Tavmjong Bah
|
||||||
lib/3rdParty/phpseclib B Jim Wigginton
|
lib/3rdParty/phpseclib B 2019 TerraFrost and other contributors
|
||||||
lib/3rdParty/Monolog B 2011 Jordi Boggiano
|
lib/3rdParty/Monolog B 2011 Jordi Boggiano
|
||||||
lib/3rdParty/Psr B 2012 PHP Framework Interoperability Group
|
lib/3rdParty/Psr B 2012 PHP Framework Interoperability Group
|
||||||
lib/3rdParty/yubico/Yubico.php C 2015 Yubico AB
|
lib/3rdParty/yubico/Yubico.php C 2015 Yubico AB
|
||||||
|
|
|
@ -421,7 +421,7 @@ main license and authors:
|
||||||
lib/3rdParty/tcpdf D 2018 Nicola Asuni - Tecnick.com LTD
|
lib/3rdParty/tcpdf D 2018 Nicola Asuni - Tecnick.com LTD
|
||||||
lib/3rdParty/tcpdf/fonts/DejaVu*.ttf A Public Domain, Bitstream, Inc., Tavmjong Bah
|
lib/3rdParty/tcpdf/fonts/DejaVu*.ttf A Public Domain, Bitstream, Inc., Tavmjong Bah
|
||||||
lib/3rdParty/tcpdf/fonts/DejaVu*.z A Public Domain, Bitstream, Inc., Tavmjong Bah
|
lib/3rdParty/tcpdf/fonts/DejaVu*.z A Public Domain, Bitstream, Inc., Tavmjong Bah
|
||||||
lib/3rdParty/phpseclib B Jim Wigginton
|
lib/3rdParty/phpseclib B 2019 TerraFrost and other contributors
|
||||||
lib/3rdParty/Monolog B 2011 Jordi Boggiano
|
lib/3rdParty/Monolog B 2011 Jordi Boggiano
|
||||||
lib/3rdParty/Psr B 2012 PHP Framework Interoperability Group
|
lib/3rdParty/Psr B 2012 PHP Framework Interoperability Group
|
||||||
lib/3rdParty/yubico/Yubico.php C 2015 Yubico AB
|
lib/3rdParty/yubico/Yubico.php C 2015 Yubico AB
|
||||||
|
|
|
@ -76,6 +76,10 @@ abstract class Base
|
||||||
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
* @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
|
||||||
*/
|
*/
|
||||||
const MODE_CFB = 3;
|
const MODE_CFB = 3;
|
||||||
|
/**
|
||||||
|
* Encrypt / decrypt using the Cipher Feedback mode (8bit)
|
||||||
|
*/
|
||||||
|
const MODE_CFB8 = 38;
|
||||||
/**
|
/**
|
||||||
* Encrypt / decrypt using the Output Feedback mode.
|
* Encrypt / decrypt using the Output Feedback mode.
|
||||||
*
|
*
|
||||||
|
@ -479,6 +483,7 @@ abstract class Base
|
||||||
break;
|
break;
|
||||||
case self::MODE_CTR:
|
case self::MODE_CTR:
|
||||||
case self::MODE_CFB:
|
case self::MODE_CFB:
|
||||||
|
case self::MODE_CFB8:
|
||||||
case self::MODE_OFB:
|
case self::MODE_OFB:
|
||||||
case self::MODE_STREAM:
|
case self::MODE_STREAM:
|
||||||
$this->mode = $mode;
|
$this->mode = $mode;
|
||||||
|
@ -492,8 +497,8 @@ abstract class Base
|
||||||
$this->_setEngine();
|
$this->_setEngine();
|
||||||
|
|
||||||
// Determining whether inline crypting can be used by the cipher
|
// Determining whether inline crypting can be used by the cipher
|
||||||
if ($this->use_inline_crypt !== false && function_exists('create_function')) {
|
if ($this->use_inline_crypt !== false) {
|
||||||
$this->use_inline_crypt = true;
|
$this->use_inline_crypt = version_compare(PHP_VERSION, '5.3.0') >= 0 || function_exists('create_function');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,10 +649,10 @@ abstract class Base
|
||||||
case !function_exists('hash_algos'):
|
case !function_exists('hash_algos'):
|
||||||
case !in_array($hash, hash_algos()):
|
case !in_array($hash, hash_algos()):
|
||||||
$i = 1;
|
$i = 1;
|
||||||
|
$hmac = new Hash();
|
||||||
|
$hmac->setHash($hash);
|
||||||
|
$hmac->setKey($password);
|
||||||
while (strlen($key) < $dkLen) {
|
while (strlen($key) < $dkLen) {
|
||||||
$hmac = new Hash();
|
|
||||||
$hmac->setHash($hash);
|
|
||||||
$hmac->setKey($password);
|
|
||||||
$f = $u = $hmac->hash($salt . pack('N', $i++));
|
$f = $u = $hmac->hash($salt . pack('N', $i++));
|
||||||
for ($j = 2; $j <= $count; ++$j) {
|
for ($j = 2; $j <= $count; ++$j) {
|
||||||
$u = $hmac->hash($u);
|
$u = $hmac->hash($u);
|
||||||
|
@ -702,7 +707,7 @@ abstract class Base
|
||||||
case self::MODE_STREAM:
|
case self::MODE_STREAM:
|
||||||
return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
||||||
case self::MODE_ECB:
|
case self::MODE_ECB:
|
||||||
$result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
$result = @openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
||||||
return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
|
return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
|
||||||
case self::MODE_CBC:
|
case self::MODE_CBC:
|
||||||
$result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
|
$result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
|
||||||
|
@ -762,6 +767,16 @@ abstract class Base
|
||||||
$iv = substr($ciphertext, -$this->block_size);
|
$iv = substr($ciphertext, -$this->block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $ciphertext;
|
||||||
|
case self::MODE_CFB8:
|
||||||
|
$ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
|
||||||
|
if ($this->continuousBuffer) {
|
||||||
|
if (($len = strlen($ciphertext)) >= $this->block_size) {
|
||||||
|
$this->encryptIV = substr($ciphertext, -$this->block_size);
|
||||||
|
} else {
|
||||||
|
$this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len);
|
||||||
|
}
|
||||||
|
}
|
||||||
return $ciphertext;
|
return $ciphertext;
|
||||||
case self::MODE_OFB:
|
case self::MODE_OFB:
|
||||||
return $this->_openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer);
|
return $this->_openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer);
|
||||||
|
@ -942,6 +957,24 @@ abstract class Base
|
||||||
$pos = $len;
|
$pos = $len;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case self::MODE_CFB8:
|
||||||
|
$ciphertext = '';
|
||||||
|
$len = strlen($plaintext);
|
||||||
|
$iv = $this->encryptIV;
|
||||||
|
|
||||||
|
for ($i = 0; $i < $len; ++$i) {
|
||||||
|
$ciphertext .= ($c = $plaintext[$i] ^ $this->_encryptBlock($iv));
|
||||||
|
$iv = substr($iv, 1) . $c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->continuousBuffer) {
|
||||||
|
if ($len >= $block_size) {
|
||||||
|
$this->encryptIV = substr($ciphertext, -$block_size);
|
||||||
|
} else {
|
||||||
|
$this->encryptIV = substr($this->encryptIV, $len - $block_size) . substr($ciphertext, -$len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case self::MODE_OFB:
|
case self::MODE_OFB:
|
||||||
$xor = $this->encryptIV;
|
$xor = $this->encryptIV;
|
||||||
if (strlen($buffer['xor'])) {
|
if (strlen($buffer['xor'])) {
|
||||||
|
@ -1007,14 +1040,14 @@ abstract class Base
|
||||||
break;
|
break;
|
||||||
case self::MODE_ECB:
|
case self::MODE_ECB:
|
||||||
if (!defined('OPENSSL_RAW_DATA')) {
|
if (!defined('OPENSSL_RAW_DATA')) {
|
||||||
$ciphertext.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true);
|
$ciphertext.= @openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true);
|
||||||
}
|
}
|
||||||
$plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
$plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
|
||||||
break;
|
break;
|
||||||
case self::MODE_CBC:
|
case self::MODE_CBC:
|
||||||
if (!defined('OPENSSL_RAW_DATA')) {
|
if (!defined('OPENSSL_RAW_DATA')) {
|
||||||
$padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size);
|
$padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size);
|
||||||
$ciphertext.= substr(openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size);
|
$ciphertext.= substr(@openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size);
|
||||||
$offset = 2 * $this->block_size;
|
$offset = 2 * $this->block_size;
|
||||||
} else {
|
} else {
|
||||||
$offset = $this->block_size;
|
$offset = $this->block_size;
|
||||||
|
@ -1072,6 +1105,16 @@ abstract class Base
|
||||||
$iv = substr($ciphertext, -$this->block_size);
|
$iv = substr($ciphertext, -$this->block_size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case self::MODE_CFB8:
|
||||||
|
$plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV);
|
||||||
|
if ($this->continuousBuffer) {
|
||||||
|
if (($len = strlen($ciphertext)) >= $this->block_size) {
|
||||||
|
$this->decryptIV = substr($ciphertext, -$this->block_size);
|
||||||
|
} else {
|
||||||
|
$this->decryptIV = substr($this->decryptIV, $len - $this->block_size) . substr($ciphertext, -$len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case self::MODE_OFB:
|
case self::MODE_OFB:
|
||||||
$plaintext = $this->_openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer);
|
$plaintext = $this->_openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer);
|
||||||
}
|
}
|
||||||
|
@ -1235,6 +1278,24 @@ abstract class Base
|
||||||
$pos = $len;
|
$pos = $len;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case self::MODE_CFB8:
|
||||||
|
$plaintext = '';
|
||||||
|
$len = strlen($ciphertext);
|
||||||
|
$iv = $this->decryptIV;
|
||||||
|
|
||||||
|
for ($i = 0; $i < $len; ++$i) {
|
||||||
|
$plaintext .= $ciphertext[$i] ^ $this->_encryptBlock($iv);
|
||||||
|
$iv = substr($iv, 1) . $ciphertext[$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->continuousBuffer) {
|
||||||
|
if ($len >= $block_size) {
|
||||||
|
$this->decryptIV = substr($ciphertext, -$block_size);
|
||||||
|
} else {
|
||||||
|
$this->decryptIV = substr($this->decryptIV, $len - $block_size) . substr($ciphertext, -$len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case self::MODE_OFB:
|
case self::MODE_OFB:
|
||||||
$xor = $this->decryptIV;
|
$xor = $this->decryptIV;
|
||||||
if (strlen($buffer['xor'])) {
|
if (strlen($buffer['xor'])) {
|
||||||
|
@ -1297,7 +1358,7 @@ abstract class Base
|
||||||
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
||||||
$block = substr($plaintext, $i, $block_size);
|
$block = substr($plaintext, $i, $block_size);
|
||||||
if (strlen($block) > strlen($buffer['ciphertext'])) {
|
if (strlen($block) > strlen($buffer['ciphertext'])) {
|
||||||
$result = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
$result = @openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
||||||
$result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
|
$result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
|
||||||
$buffer['ciphertext'].= $result;
|
$buffer['ciphertext'].= $result;
|
||||||
}
|
}
|
||||||
|
@ -1308,7 +1369,7 @@ abstract class Base
|
||||||
} else {
|
} else {
|
||||||
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
|
||||||
$block = substr($plaintext, $i, $block_size);
|
$block = substr($plaintext, $i, $block_size);
|
||||||
$otp = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
$otp = @openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
||||||
$otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp;
|
$otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp;
|
||||||
$this->_increment_str($xor);
|
$this->_increment_str($xor);
|
||||||
$ciphertext.= $block ^ $otp;
|
$ciphertext.= $block ^ $otp;
|
||||||
|
@ -1352,7 +1413,7 @@ abstract class Base
|
||||||
}
|
}
|
||||||
if ($this->continuousBuffer) {
|
if ($this->continuousBuffer) {
|
||||||
if (!defined('OPENSSL_RAW_DATA')) {
|
if (!defined('OPENSSL_RAW_DATA')) {
|
||||||
$encryptIV.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
$encryptIV.= @openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
||||||
}
|
}
|
||||||
$encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
$encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
|
||||||
if ($overflow) {
|
if ($overflow) {
|
||||||
|
@ -1435,6 +1496,8 @@ abstract class Base
|
||||||
return 'ctr';
|
return 'ctr';
|
||||||
case self::MODE_CFB:
|
case self::MODE_CFB:
|
||||||
return 'cfb';
|
return 'cfb';
|
||||||
|
case self::MODE_CFB8:
|
||||||
|
return 'cfb8';
|
||||||
case self::MODE_OFB:
|
case self::MODE_OFB:
|
||||||
return 'ofb';
|
return 'ofb';
|
||||||
}
|
}
|
||||||
|
@ -1788,6 +1851,7 @@ abstract class Base
|
||||||
self::MODE_ECB => MCRYPT_MODE_ECB,
|
self::MODE_ECB => MCRYPT_MODE_ECB,
|
||||||
self::MODE_CBC => MCRYPT_MODE_CBC,
|
self::MODE_CBC => MCRYPT_MODE_CBC,
|
||||||
self::MODE_CFB => 'ncfb',
|
self::MODE_CFB => 'ncfb',
|
||||||
|
self::MODE_CFB8 => MCRYPT_MODE_CFB,
|
||||||
self::MODE_OFB => MCRYPT_MODE_NOFB,
|
self::MODE_OFB => MCRYPT_MODE_NOFB,
|
||||||
self::MODE_STREAM => MCRYPT_MODE_STREAM,
|
self::MODE_STREAM => MCRYPT_MODE_STREAM,
|
||||||
);
|
);
|
||||||
|
@ -2359,6 +2423,52 @@ abstract class Base
|
||||||
$_pos = $_len;
|
$_pos = $_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $_plaintext;
|
||||||
|
';
|
||||||
|
break;
|
||||||
|
case self::MODE_CFB8:
|
||||||
|
$encrypt = $init_encrypt . '
|
||||||
|
$_ciphertext = "";
|
||||||
|
$_len = strlen($_text);
|
||||||
|
$_iv = $self->encryptIV;
|
||||||
|
|
||||||
|
for ($_i = 0; $_i < $_len; ++$_i) {
|
||||||
|
$in = $_iv;
|
||||||
|
'.$encrypt_block.'
|
||||||
|
$_ciphertext .= ($_c = $_text[$_i] ^ $in);
|
||||||
|
$_iv = substr($_iv, 1) . $_c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($self->continuousBuffer) {
|
||||||
|
if ($_len >= '.$block_size.') {
|
||||||
|
$self->encryptIV = substr($_ciphertext, -'.$block_size.');
|
||||||
|
} else {
|
||||||
|
$self->encryptIV = substr($self->encryptIV, $_len - '.$block_size.') . substr($_ciphertext, -$_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $_ciphertext;
|
||||||
|
';
|
||||||
|
$decrypt = $init_encrypt . '
|
||||||
|
$_plaintext = "";
|
||||||
|
$_len = strlen($_text);
|
||||||
|
$_iv = $self->decryptIV;
|
||||||
|
|
||||||
|
for ($_i = 0; $_i < $_len; ++$_i) {
|
||||||
|
$in = $_iv;
|
||||||
|
'.$encrypt_block.'
|
||||||
|
$_plaintext .= $_text[$_i] ^ $in;
|
||||||
|
$_iv = substr($_iv, 1) . $_text[$_i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($self->continuousBuffer) {
|
||||||
|
if ($_len >= '.$block_size.') {
|
||||||
|
$self->decryptIV = substr($_text, -'.$block_size.');
|
||||||
|
} else {
|
||||||
|
$self->decryptIV = substr($self->decryptIV, $_len - '.$block_size.') . substr($_text, -$_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $_plaintext;
|
return $_plaintext;
|
||||||
';
|
';
|
||||||
break;
|
break;
|
||||||
|
@ -2492,6 +2602,11 @@ abstract class Base
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the $inline function and return its name as string. Ready to run!
|
// Create the $inline function and return its name as string. Ready to run!
|
||||||
|
if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
|
||||||
|
eval('$func = function ($_action, &$self, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' } };');
|
||||||
|
return $func;
|
||||||
|
}
|
||||||
|
|
||||||
return create_function('$_action, &$self, $_text', $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }');
|
return create_function('$_action, &$self, $_text', $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2550,4 +2665,44 @@ abstract class Base
|
||||||
return $result . pack('H*', sha1($hash));
|
return $result . pack('H*', sha1($hash));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert float to int
|
||||||
|
*
|
||||||
|
* On ARM CPUs converting floats to ints doesn't always work
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param string $x
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
function safe_intval($x)
|
||||||
|
{
|
||||||
|
switch (true) {
|
||||||
|
case is_int($x):
|
||||||
|
// PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
|
||||||
|
case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
return (fmod($x, 0x80000000) & 0x7FFFFFFF) |
|
||||||
|
((fmod(floor($x / 0x80000000), 2) & 1) << 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eval()'able string for in-line float to int
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function safe_intval_inline()
|
||||||
|
{
|
||||||
|
switch (true) {
|
||||||
|
case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8:
|
||||||
|
case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
|
||||||
|
return '%s';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | ';
|
||||||
|
return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -294,7 +294,7 @@ class Blowfish extends Base
|
||||||
function setKeyLength($length)
|
function setKeyLength($length)
|
||||||
{
|
{
|
||||||
if ($length < 32) {
|
if ($length < 32) {
|
||||||
$this->key_length = 7;
|
$this->key_length = 4;
|
||||||
} elseif ($length > 448) {
|
} elseif ($length > 448) {
|
||||||
$this->key_length = 56;
|
$this->key_length = 56;
|
||||||
} else {
|
} else {
|
||||||
|
@ -408,16 +408,14 @@ class Blowfish extends Base
|
||||||
|
|
||||||
for ($i = 0; $i < 16; $i+= 2) {
|
for ($i = 0; $i < 16; $i+= 2) {
|
||||||
$l^= $p[$i];
|
$l^= $p[$i];
|
||||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
$r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^
|
||||||
$sb_1[$l >> 16 & 0xff] ^
|
|
||||||
$sb_2[$l >> 8 & 0xff]) +
|
$sb_2[$l >> 8 & 0xff]) +
|
||||||
$sb_3[$l & 0xff];
|
$sb_3[$l & 0xff]);
|
||||||
|
|
||||||
$r^= $p[$i + 1];
|
$r^= $p[$i + 1];
|
||||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
$l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^
|
||||||
$sb_1[$r >> 16 & 0xff] ^
|
|
||||||
$sb_2[$r >> 8 & 0xff]) +
|
$sb_2[$r >> 8 & 0xff]) +
|
||||||
$sb_3[$r & 0xff];
|
$sb_3[$r & 0xff]);
|
||||||
}
|
}
|
||||||
return pack("N*", $r ^ $p[17], $l ^ $p[16]);
|
return pack("N*", $r ^ $p[17], $l ^ $p[16]);
|
||||||
}
|
}
|
||||||
|
@ -443,16 +441,14 @@ class Blowfish extends Base
|
||||||
|
|
||||||
for ($i = 17; $i > 2; $i-= 2) {
|
for ($i = 17; $i > 2; $i-= 2) {
|
||||||
$l^= $p[$i];
|
$l^= $p[$i];
|
||||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
$r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^
|
||||||
$sb_1[$l >> 16 & 0xff] ^
|
|
||||||
$sb_2[$l >> 8 & 0xff]) +
|
$sb_2[$l >> 8 & 0xff]) +
|
||||||
$sb_3[$l & 0xff];
|
$sb_3[$l & 0xff]);
|
||||||
|
|
||||||
$r^= $p[$i - 1];
|
$r^= $p[$i - 1];
|
||||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
$l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^
|
||||||
$sb_1[$r >> 16 & 0xff] ^
|
|
||||||
$sb_2[$r >> 8 & 0xff]) +
|
$sb_2[$r >> 8 & 0xff]) +
|
||||||
$sb_3[$r & 0xff];
|
$sb_3[$r & 0xff]);
|
||||||
}
|
}
|
||||||
return pack("N*", $r ^ $p[0], $l ^ $p[1]);
|
return pack("N*", $r ^ $p[0], $l ^ $p[1]);
|
||||||
}
|
}
|
||||||
|
@ -478,6 +474,8 @@ class Blowfish extends Base
|
||||||
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$safeint = $this->safe_intval_inline();
|
||||||
|
|
||||||
if (!isset($lambda_functions[$code_hash])) {
|
if (!isset($lambda_functions[$code_hash])) {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case $gen_hi_opt_code:
|
case $gen_hi_opt_code:
|
||||||
|
@ -513,16 +511,14 @@ class Blowfish extends Base
|
||||||
for ($i = 0; $i < 16; $i+= 2) {
|
for ($i = 0; $i < 16; $i+= 2) {
|
||||||
$encrypt_block.= '
|
$encrypt_block.= '
|
||||||
$l^= ' . $p[$i] . ';
|
$l^= ' . $p[$i] . ';
|
||||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
$r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
|
||||||
$sb_1[$l >> 16 & 0xff] ^
|
|
||||||
$sb_2[$l >> 8 & 0xff]) +
|
$sb_2[$l >> 8 & 0xff]) +
|
||||||
$sb_3[$l & 0xff];
|
$sb_3[$l & 0xff]') . ';
|
||||||
|
|
||||||
$r^= ' . $p[$i + 1] . ';
|
$r^= ' . $p[$i + 1] . ';
|
||||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
$l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^
|
||||||
$sb_1[$r >> 16 & 0xff] ^
|
|
||||||
$sb_2[$r >> 8 & 0xff]) +
|
$sb_2[$r >> 8 & 0xff]) +
|
||||||
$sb_3[$r & 0xff];
|
$sb_3[$r & 0xff]') . ';
|
||||||
';
|
';
|
||||||
}
|
}
|
||||||
$encrypt_block.= '
|
$encrypt_block.= '
|
||||||
|
@ -542,16 +538,14 @@ class Blowfish extends Base
|
||||||
for ($i = 17; $i > 2; $i-= 2) {
|
for ($i = 17; $i > 2; $i-= 2) {
|
||||||
$decrypt_block.= '
|
$decrypt_block.= '
|
||||||
$l^= ' . $p[$i] . ';
|
$l^= ' . $p[$i] . ';
|
||||||
$r^= ($sb_0[$l >> 24 & 0xff] +
|
$r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
|
||||||
$sb_1[$l >> 16 & 0xff] ^
|
|
||||||
$sb_2[$l >> 8 & 0xff]) +
|
$sb_2[$l >> 8 & 0xff]) +
|
||||||
$sb_3[$l & 0xff];
|
$sb_3[$l & 0xff]') . ';
|
||||||
|
|
||||||
$r^= ' . $p[$i - 1] . ';
|
$r^= ' . $p[$i - 1] . ';
|
||||||
$l^= ($sb_0[$r >> 24 & 0xff] +
|
$l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^
|
||||||
$sb_1[$r >> 16 & 0xff] ^
|
|
||||||
$sb_2[$r >> 8 & 0xff]) +
|
$sb_2[$r >> 8 & 0xff]) +
|
||||||
$sb_3[$r & 0xff];
|
$sb_3[$r & 0xff]') . ';
|
||||||
';
|
';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1357,8 +1357,8 @@ class DES extends Base
|
||||||
$k[self::ENCRYPT][$i] = '$ke[' . $i . ']';
|
$k[self::ENCRYPT][$i] = '$ke[' . $i . ']';
|
||||||
$k[self::DECRYPT][$i] = '$kd[' . $i . ']';
|
$k[self::DECRYPT][$i] = '$kd[' . $i . ']';
|
||||||
}
|
}
|
||||||
$init_encrypt = '$ke = $self->keys[self::ENCRYPT];';
|
$init_encrypt = '$ke = $self->keys[$self::ENCRYPT];';
|
||||||
$init_decrypt = '$kd = $self->keys[self::DECRYPT];';
|
$init_decrypt = '$kd = $self->keys[$self::DECRYPT];';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,15 @@ class Hash
|
||||||
*/
|
*/
|
||||||
var $key = false;
|
var $key = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computed Key
|
||||||
|
*
|
||||||
|
* @see self::_computeKey()
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $computedKey = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Outer XOR (Internal HMAC)
|
* Outer XOR (Internal HMAC)
|
||||||
*
|
*
|
||||||
|
@ -130,6 +139,15 @@ class Hash
|
||||||
*/
|
*/
|
||||||
var $ipad;
|
var $ipad;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Engine
|
||||||
|
*
|
||||||
|
* @see self::setHash()
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $engine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Constructor.
|
* Default Constructor.
|
||||||
*
|
*
|
||||||
|
@ -166,6 +184,43 @@ class Hash
|
||||||
function setKey($key = false)
|
function setKey($key = false)
|
||||||
{
|
{
|
||||||
$this->key = $key;
|
$this->key = $key;
|
||||||
|
$this->_computeKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-compute the key used by the HMAC
|
||||||
|
*
|
||||||
|
* Quoting http://tools.ietf.org/html/rfc2104#section-2, "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."
|
||||||
|
*
|
||||||
|
* As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/
|
||||||
|
* when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during
|
||||||
|
* every call
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _computeKey()
|
||||||
|
{
|
||||||
|
if ($this->key === false) {
|
||||||
|
$this->computedKey = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen($this->key) <= $this->b) {
|
||||||
|
$this->computedKey = $this->key;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($this->engine) {
|
||||||
|
case self::MODE_MHASH:
|
||||||
|
$this->computedKey = mhash($this->hash, $this->key);
|
||||||
|
break;
|
||||||
|
case self::MODE_HASH:
|
||||||
|
$this->computedKey = hash($this->hash, $this->key, true);
|
||||||
|
break;
|
||||||
|
case self::MODE_INTERNAL:
|
||||||
|
$this->computedKey = call_user_func($this->hash, $this->key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -216,19 +271,38 @@ class Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($hash) {
|
switch ($hash) {
|
||||||
|
case 'md2-96':
|
||||||
case 'md2':
|
case 'md2':
|
||||||
$mode = CRYPT_HASH_MODE == self::MODE_HASH && in_array('md2', hash_algos()) ?
|
$this->b = 16;
|
||||||
|
case 'md5-96':
|
||||||
|
case 'sha1-96':
|
||||||
|
case 'sha224-96':
|
||||||
|
case 'sha256-96':
|
||||||
|
case 'md2':
|
||||||
|
case 'md5':
|
||||||
|
case 'sha1':
|
||||||
|
case 'sha224':
|
||||||
|
case 'sha256':
|
||||||
|
$this->b = 64;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$this->b = 128;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($hash) {
|
||||||
|
case 'md2':
|
||||||
|
$this->engine = CRYPT_HASH_MODE == self::MODE_HASH && in_array('md2', hash_algos()) ?
|
||||||
self::MODE_HASH : self::MODE_INTERNAL;
|
self::MODE_HASH : self::MODE_INTERNAL;
|
||||||
break;
|
break;
|
||||||
case 'sha384':
|
case 'sha384':
|
||||||
case 'sha512':
|
case 'sha512':
|
||||||
$mode = CRYPT_HASH_MODE == self::MODE_MHASH ? self::MODE_INTERNAL : CRYPT_HASH_MODE;
|
$this->engine = CRYPT_HASH_MODE == self::MODE_MHASH ? self::MODE_INTERNAL : CRYPT_HASH_MODE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$mode = CRYPT_HASH_MODE;
|
$this->engine = CRYPT_HASH_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($mode) {
|
switch ($this->engine) {
|
||||||
case self::MODE_MHASH:
|
case self::MODE_MHASH:
|
||||||
switch ($hash) {
|
switch ($hash) {
|
||||||
case 'md5':
|
case 'md5':
|
||||||
|
@ -241,6 +315,7 @@ class Hash
|
||||||
default:
|
default:
|
||||||
$this->hash = MHASH_SHA1;
|
$this->hash = MHASH_SHA1;
|
||||||
}
|
}
|
||||||
|
$this->_computeKey(self::MODE_MHASH);
|
||||||
return;
|
return;
|
||||||
case self::MODE_HASH:
|
case self::MODE_HASH:
|
||||||
switch ($hash) {
|
switch ($hash) {
|
||||||
|
@ -257,35 +332,33 @@ class Hash
|
||||||
default:
|
default:
|
||||||
$this->hash = 'sha1';
|
$this->hash = 'sha1';
|
||||||
}
|
}
|
||||||
|
$this->_computeKey(self::MODE_HASH);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($hash) {
|
switch ($hash) {
|
||||||
case 'md2':
|
case 'md2':
|
||||||
$this->b = 16;
|
|
||||||
$this->hash = array($this, '_md2');
|
$this->hash = array($this, '_md2');
|
||||||
break;
|
break;
|
||||||
case 'md5':
|
case 'md5':
|
||||||
$this->b = 64;
|
|
||||||
$this->hash = array($this, '_md5');
|
$this->hash = array($this, '_md5');
|
||||||
break;
|
break;
|
||||||
case 'sha256':
|
case 'sha256':
|
||||||
$this->b = 64;
|
|
||||||
$this->hash = array($this, '_sha256');
|
$this->hash = array($this, '_sha256');
|
||||||
break;
|
break;
|
||||||
case 'sha384':
|
case 'sha384':
|
||||||
case 'sha512':
|
case 'sha512':
|
||||||
$this->b = 128;
|
|
||||||
$this->hash = array($this, '_sha512');
|
$this->hash = array($this, '_sha512');
|
||||||
break;
|
break;
|
||||||
case 'sha1':
|
case 'sha1':
|
||||||
default:
|
default:
|
||||||
$this->b = 64;
|
|
||||||
$this->hash = array($this, '_sha1');
|
$this->hash = array($this, '_sha1');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->ipad = str_repeat(chr(0x36), $this->b);
|
$this->ipad = str_repeat(chr(0x36), $this->b);
|
||||||
$this->opad = str_repeat(chr(0x5C), $this->b);
|
$this->opad = str_repeat(chr(0x5C), $this->b);
|
||||||
|
|
||||||
|
$this->_computeKey(self::MODE_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -297,33 +370,25 @@ class Hash
|
||||||
*/
|
*/
|
||||||
function hash($text)
|
function hash($text)
|
||||||
{
|
{
|
||||||
$mode = is_array($this->hash) ? self::MODE_INTERNAL : CRYPT_HASH_MODE;
|
|
||||||
|
|
||||||
if (!empty($this->key) || is_string($this->key)) {
|
if (!empty($this->key) || is_string($this->key)) {
|
||||||
switch ($mode) {
|
switch ($this->engine) {
|
||||||
case self::MODE_MHASH:
|
case self::MODE_MHASH:
|
||||||
$output = mhash($this->hash, $text, $this->key);
|
$output = mhash($this->hash, $text, $this->computedKey);
|
||||||
break;
|
break;
|
||||||
case self::MODE_HASH:
|
case self::MODE_HASH:
|
||||||
$output = hash_hmac($this->hash, $text, $this->key, true);
|
$output = hash_hmac($this->hash, $text, $this->computedKey, true);
|
||||||
break;
|
break;
|
||||||
case self::MODE_INTERNAL:
|
case self::MODE_INTERNAL:
|
||||||
/* "Applications that use keys longer than B bytes will first hash the key using H and then use the
|
$key = str_pad($this->computedKey, $this->b, chr(0)); // step 1
|
||||||
resultant L byte string as the actual key to HMAC."
|
$temp = $this->ipad ^ $key; // step 2
|
||||||
|
$temp .= $text; // step 3
|
||||||
-- http://tools.ietf.org/html/rfc2104#section-2 */
|
$temp = call_user_func($this->hash, $temp); // step 4
|
||||||
$key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
|
$output = $this->opad ^ $key; // step 5
|
||||||
|
$output.= $temp; // step 6
|
||||||
$key = str_pad($key, $this->b, chr(0)); // step 1
|
$output = call_user_func($this->hash, $output); // step 7
|
||||||
$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 {
|
} else {
|
||||||
switch ($mode) {
|
switch ($this->engine) {
|
||||||
case self::MODE_MHASH:
|
case self::MODE_MHASH:
|
||||||
$output = mhash($this->hash, $text);
|
$output = mhash($this->hash, $text);
|
||||||
break;
|
break;
|
||||||
|
@ -802,7 +867,12 @@ class Hash
|
||||||
$result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
|
$result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmod($result, $mod);
|
if ((php_uname('m') & "\xDF\xDF\xDF") != 'ARM') {
|
||||||
|
return fmod($result, $mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (fmod($result, 0x80000000) & 0x7FFFFFFF) |
|
||||||
|
((fmod(floor($result / 0x80000000), 2) & 1) << 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -296,7 +296,7 @@ class RC2 extends Base
|
||||||
function setKeyLength($length)
|
function setKeyLength($length)
|
||||||
{
|
{
|
||||||
if ($length < 8) {
|
if ($length < 8) {
|
||||||
$this->default_key_length = 8;
|
$this->default_key_length = 1;
|
||||||
} elseif ($length > 1024) {
|
} elseif ($length > 1024) {
|
||||||
$this->default_key_length = 128;
|
$this->default_key_length = 128;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -107,7 +107,7 @@ class RC4 extends Base
|
||||||
* @var string
|
* @var string
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $key = "\0";
|
var $key;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Key Stream for decryption and encryption
|
* The Key Stream for decryption and encryption
|
||||||
|
|
|
@ -182,6 +182,10 @@ class RSA
|
||||||
* PKCS#8 formatted private key
|
* PKCS#8 formatted private key
|
||||||
*/
|
*/
|
||||||
const PRIVATE_FORMAT_PKCS8 = 8;
|
const PRIVATE_FORMAT_PKCS8 = 8;
|
||||||
|
/**
|
||||||
|
* OpenSSH formatted private key
|
||||||
|
*/
|
||||||
|
const PRIVATE_FORMAT_OPENSSH = 9;
|
||||||
/**#@-*/
|
/**#@-*/
|
||||||
|
|
||||||
/**#@+
|
/**#@+
|
||||||
|
@ -468,23 +472,27 @@ class RSA
|
||||||
break;
|
break;
|
||||||
case extension_loaded('openssl') && file_exists($this->configFile):
|
case extension_loaded('openssl') && file_exists($this->configFile):
|
||||||
// some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
|
// some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
|
||||||
ob_start();
|
|
||||||
@phpinfo();
|
|
||||||
$content = ob_get_contents();
|
|
||||||
ob_end_clean();
|
|
||||||
|
|
||||||
preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
|
|
||||||
|
|
||||||
$versions = array();
|
$versions = array();
|
||||||
if (!empty($matches[1])) {
|
|
||||||
for ($i = 0; $i < count($matches[1]); $i++) {
|
|
||||||
$fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
|
|
||||||
|
|
||||||
// Remove letter part in OpenSSL version
|
// avoid generating errors (even with suppression) when phpinfo() is disabled (common in production systems)
|
||||||
if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
|
if (strpos(ini_get('disable_functions'), 'phpinfo') === false) {
|
||||||
$versions[$matches[1][$i]] = $fullVersion;
|
ob_start();
|
||||||
} else {
|
@phpinfo();
|
||||||
$versions[$matches[1][$i]] = $m[0];
|
$content = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
|
||||||
|
|
||||||
|
if (!empty($matches[1])) {
|
||||||
|
for ($i = 0; $i < count($matches[1]); $i++) {
|
||||||
|
$fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
|
||||||
|
|
||||||
|
// Remove letter part in OpenSSL version
|
||||||
|
if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
|
||||||
|
$versions[$matches[1][$i]] = $fullVersion;
|
||||||
|
} else {
|
||||||
|
$versions[$matches[1][$i]] = $m[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -816,6 +824,58 @@ class RSA
|
||||||
$key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n";
|
$key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n";
|
||||||
|
|
||||||
return $key;
|
return $key;
|
||||||
|
case self::PRIVATE_FORMAT_OPENSSH:
|
||||||
|
if ($num_primes != 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$publicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']);
|
||||||
|
$privateKey = pack(
|
||||||
|
'Na*Na*Na*Na*Na*Na*Na*',
|
||||||
|
strlen('ssh-rsa'),
|
||||||
|
'ssh-rsa',
|
||||||
|
strlen($raw['modulus']),
|
||||||
|
$raw['modulus'],
|
||||||
|
strlen($raw['publicExponent']),
|
||||||
|
$raw['publicExponent'],
|
||||||
|
strlen($raw['privateExponent']),
|
||||||
|
$raw['privateExponent'],
|
||||||
|
strlen($raw['coefficient']),
|
||||||
|
$raw['coefficient'],
|
||||||
|
strlen($raw['prime1']),
|
||||||
|
$raw['prime1'],
|
||||||
|
strlen($raw['prime2']),
|
||||||
|
$raw['prime2']
|
||||||
|
);
|
||||||
|
$checkint = Random::string(4);
|
||||||
|
$paddedKey = pack(
|
||||||
|
'a*Na*',
|
||||||
|
$checkint . $checkint . $privateKey,
|
||||||
|
strlen($this->comment),
|
||||||
|
$this->comment
|
||||||
|
);
|
||||||
|
$paddingLength = (7 * strlen($paddedKey)) % 8;
|
||||||
|
for ($i = 1; $i <= $paddingLength; $i++) {
|
||||||
|
$paddedKey.= chr($i);
|
||||||
|
}
|
||||||
|
$key = pack(
|
||||||
|
'Na*Na*Na*NNa*Na*',
|
||||||
|
strlen('none'),
|
||||||
|
'none',
|
||||||
|
strlen('none'),
|
||||||
|
'none',
|
||||||
|
0,
|
||||||
|
'',
|
||||||
|
1,
|
||||||
|
strlen($publicKey),
|
||||||
|
$publicKey,
|
||||||
|
strlen($paddedKey),
|
||||||
|
$paddedKey
|
||||||
|
);
|
||||||
|
$key = "openssh-key-v1\0$key";
|
||||||
|
|
||||||
|
return "-----BEGIN OPENSSH PRIVATE KEY-----\r\n" .
|
||||||
|
chunk_split(base64_encode($key), 70) .
|
||||||
|
"-----END OPENSSH PRIVATE KEY-----";
|
||||||
default: // eg. self::PRIVATE_FORMAT_PKCS1
|
default: // eg. self::PRIVATE_FORMAT_PKCS1
|
||||||
$components = array();
|
$components = array();
|
||||||
foreach ($raw as $name => $value) {
|
foreach ($raw as $name => $value) {
|
||||||
|
@ -1016,9 +1076,9 @@ class RSA
|
||||||
* @access private
|
* @access private
|
||||||
* @see self::_convertPublicKey()
|
* @see self::_convertPublicKey()
|
||||||
* @see self::_convertPrivateKey()
|
* @see self::_convertPrivateKey()
|
||||||
* @param string $key
|
* @param string|array $key
|
||||||
* @param int $type
|
* @param int $type
|
||||||
* @return array
|
* @return array|bool
|
||||||
*/
|
*/
|
||||||
function _parseKey($key, $type)
|
function _parseKey($key, $type)
|
||||||
{
|
{
|
||||||
|
@ -1329,9 +1389,14 @@ class RSA
|
||||||
xml_set_character_data_handler($xml, '_data_handler');
|
xml_set_character_data_handler($xml, '_data_handler');
|
||||||
// add <xml></xml> to account for "dangling" tags like <BitStrength>...</BitStrength> that are sometimes added
|
// add <xml></xml> to account for "dangling" tags like <BitStrength>...</BitStrength> that are sometimes added
|
||||||
if (!xml_parse($xml, '<xml>' . $key . '</xml>')) {
|
if (!xml_parse($xml, '<xml>' . $key . '</xml>')) {
|
||||||
|
xml_parser_free($xml);
|
||||||
|
unset($xml);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xml_parser_free($xml);
|
||||||
|
unset($xml);
|
||||||
|
|
||||||
return isset($this->components['modulus']) && isset($this->components['publicExponent']) ? $this->components : false;
|
return isset($this->components['modulus']) && isset($this->components['publicExponent']) ? $this->components : false;
|
||||||
// from PuTTY's SSHPUBK.C
|
// from PuTTY's SSHPUBK.C
|
||||||
case self::PRIVATE_FORMAT_PUTTY:
|
case self::PRIVATE_FORMAT_PUTTY:
|
||||||
|
@ -1403,6 +1468,75 @@ class RSA
|
||||||
}
|
}
|
||||||
$components['coefficients'] = array(2 => new BigInteger($this->_string_shift($private, $length), -256));
|
$components['coefficients'] = array(2 => new BigInteger($this->_string_shift($private, $length), -256));
|
||||||
|
|
||||||
|
return $components;
|
||||||
|
case self::PRIVATE_FORMAT_OPENSSH:
|
||||||
|
$components = array();
|
||||||
|
$decoded = $this->_extractBER($key);
|
||||||
|
$magic = $this->_string_shift($decoded, 15);
|
||||||
|
if ($magic !== "openssh-key-v1\0") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$options = $this->_string_shift($decoded, 24);
|
||||||
|
// \0\0\0\4none = ciphername
|
||||||
|
// \0\0\0\4none = kdfname
|
||||||
|
// \0\0\0\0 = kdfoptions
|
||||||
|
// \0\0\0\1 = numkeys
|
||||||
|
if ($options != "\0\0\0\4none\0\0\0\4none\0\0\0\0\0\0\0\1") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
|
||||||
|
if (strlen($decoded) < $length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$publicKey = $this->_string_shift($decoded, $length);
|
||||||
|
extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
|
||||||
|
if (strlen($decoded) < $length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$paddedKey = $this->_string_shift($decoded, $length);
|
||||||
|
|
||||||
|
if ($this->_string_shift($publicKey, 11) !== "\0\0\0\7ssh-rsa") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$checkint1 = $this->_string_shift($paddedKey, 4);
|
||||||
|
$checkint2 = $this->_string_shift($paddedKey, 4);
|
||||||
|
if (strlen($checkint1) != 4 || $checkint1 !== $checkint2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->_string_shift($paddedKey, 11) !== "\0\0\0\7ssh-rsa") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$values = array(
|
||||||
|
&$components['modulus'],
|
||||||
|
&$components['publicExponent'],
|
||||||
|
&$components['privateExponent'],
|
||||||
|
&$components['coefficients'][2],
|
||||||
|
&$components['primes'][1],
|
||||||
|
&$components['primes'][2]
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($values as &$value) {
|
||||||
|
extract(unpack('Nlength', $this->_string_shift($paddedKey, 4)));
|
||||||
|
if (strlen($paddedKey) < $length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$value = new BigInteger($this->_string_shift($paddedKey, $length), -256);
|
||||||
|
}
|
||||||
|
|
||||||
|
extract(unpack('Nlength', $this->_string_shift($paddedKey, 4)));
|
||||||
|
if (strlen($paddedKey) < $length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$components['comment'] = $this->_string_shift($decoded, $length);
|
||||||
|
|
||||||
|
$temp = $components['primes'][1]->subtract($this->one);
|
||||||
|
$components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
|
||||||
|
$temp = $components['primes'][2]->subtract($this->one);
|
||||||
|
$components['exponents'][] = $components['publicExponent']->modInverse($temp);
|
||||||
|
|
||||||
return $components;
|
return $components;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1501,8 +1635,9 @@ class RSA
|
||||||
* Returns true on success and false on failure (ie. an incorrect password was provided or the key was malformed)
|
* Returns true on success and false on failure (ie. an incorrect password was provided or the key was malformed)
|
||||||
*
|
*
|
||||||
* @access public
|
* @access public
|
||||||
* @param string $key
|
* @param string|RSA|array $key
|
||||||
* @param int $type optional
|
* @param bool|int $type optional
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function loadKey($key, $type = false)
|
function loadKey($key, $type = false)
|
||||||
{
|
{
|
||||||
|
@ -1559,7 +1694,8 @@ class RSA
|
||||||
self::PRIVATE_FORMAT_PKCS1,
|
self::PRIVATE_FORMAT_PKCS1,
|
||||||
self::PRIVATE_FORMAT_XML,
|
self::PRIVATE_FORMAT_XML,
|
||||||
self::PRIVATE_FORMAT_PUTTY,
|
self::PRIVATE_FORMAT_PUTTY,
|
||||||
self::PUBLIC_FORMAT_OPENSSH
|
self::PUBLIC_FORMAT_OPENSSH,
|
||||||
|
self::PRIVATE_FORMAT_OPENSSH
|
||||||
);
|
);
|
||||||
foreach ($types as $type) {
|
foreach ($types as $type) {
|
||||||
$components = $this->_parseKey($key, $type);
|
$components = $this->_parseKey($key, $type);
|
||||||
|
@ -2207,16 +2343,21 @@ class RSA
|
||||||
*/
|
*/
|
||||||
function _equals($x, $y)
|
function _equals($x, $y)
|
||||||
{
|
{
|
||||||
|
if (function_exists('hash_equals')) {
|
||||||
|
return hash_equals($x, $y);
|
||||||
|
}
|
||||||
|
|
||||||
if (strlen($x) != strlen($y)) {
|
if (strlen($x) != strlen($y)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = 0;
|
$result = "\0";
|
||||||
|
$x^= $y;
|
||||||
for ($i = 0; $i < strlen($x); $i++) {
|
for ($i = 0; $i < strlen($x); $i++) {
|
||||||
$result |= ord($x[$i]) ^ ord($y[$i]);
|
$result|= $x[$i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result == 0;
|
return $result === "\0";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2423,19 +2564,26 @@ class RSA
|
||||||
$db = $maskedDB ^ $dbMask;
|
$db = $maskedDB ^ $dbMask;
|
||||||
$lHash2 = substr($db, 0, $this->hLen);
|
$lHash2 = substr($db, 0, $this->hLen);
|
||||||
$m = substr($db, $this->hLen);
|
$m = substr($db, $this->hLen);
|
||||||
if ($lHash != $lHash2) {
|
$hashesMatch = $this->_equals($lHash, $lHash2);
|
||||||
user_error('Decryption error');
|
$leadingZeros = 1;
|
||||||
return false;
|
$patternMatch = 0;
|
||||||
|
$offset = 0;
|
||||||
|
for ($i = 0; $i < strlen($m); $i++) {
|
||||||
|
$patternMatch|= $leadingZeros & ($m[$i] === "\1");
|
||||||
|
$leadingZeros&= $m[$i] === "\0";
|
||||||
|
$offset+= $patternMatch ? 0 : 1;
|
||||||
}
|
}
|
||||||
$m = ltrim($m, chr(0));
|
|
||||||
if (ord($m[0]) != 1) {
|
// we do & instead of && to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation
|
||||||
|
// to protect against timing attacks
|
||||||
|
if (!$hashesMatch & !$patternMatch) {
|
||||||
user_error('Decryption error');
|
user_error('Decryption error');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output the message M
|
// Output the message M
|
||||||
|
|
||||||
return substr($m, 1);
|
return substr($m, $offset + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -45,6 +45,10 @@ class Random
|
||||||
*/
|
*/
|
||||||
static function string($length)
|
static function string($length)
|
||||||
{
|
{
|
||||||
|
if (!$length) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
|
if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
|
||||||
try {
|
try {
|
||||||
return \random_bytes($length);
|
return \random_bytes($length);
|
||||||
|
|
|
@ -432,8 +432,10 @@ class Twofish extends Base
|
||||||
$m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^
|
$m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^
|
||||||
$m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]];
|
$m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]];
|
||||||
$B = ($B << 8) | ($B >> 24 & 0xff);
|
$B = ($B << 8) | ($B >> 24 & 0xff);
|
||||||
$K[] = $A+= $B;
|
$A = $this->safe_intval($A + $B);
|
||||||
$K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
|
$K[] = $A;
|
||||||
|
$A = $this->safe_intval($A + $B);
|
||||||
|
$K[] = ($A << 9 | $A >> 23 & 0x1ff);
|
||||||
}
|
}
|
||||||
for ($i = 0; $i < 256; ++$i) {
|
for ($i = 0; $i < 256; ++$i) {
|
||||||
$S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0];
|
$S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0];
|
||||||
|
@ -456,8 +458,10 @@ class Twofish extends Base
|
||||||
$m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
|
$m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
|
||||||
$m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]];
|
$m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]];
|
||||||
$B = ($B << 8) | ($B >> 24 & 0xff);
|
$B = ($B << 8) | ($B >> 24 & 0xff);
|
||||||
$K[] = $A+= $B;
|
$A = $this->safe_intval($A + $B);
|
||||||
$K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
|
$K[] = $A;
|
||||||
|
$A = $this->safe_intval($A + $B);
|
||||||
|
$K[] = ($A << 9 | $A >> 23 & 0x1ff);
|
||||||
}
|
}
|
||||||
for ($i = 0; $i < 256; ++$i) {
|
for ($i = 0; $i < 256; ++$i) {
|
||||||
$S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0];
|
$S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0];
|
||||||
|
@ -481,8 +485,10 @@ class Twofish extends Base
|
||||||
$m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
|
$m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
|
||||||
$m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]];
|
$m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]];
|
||||||
$B = ($B << 8) | ($B >> 24 & 0xff);
|
$B = ($B << 8) | ($B >> 24 & 0xff);
|
||||||
$K[] = $A+= $B;
|
$A = $this->safe_intval($A + $B);
|
||||||
$K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
|
$K[] = $A;
|
||||||
|
$A = $this->safe_intval($A + $B);
|
||||||
|
$K[] = ($A << 9 | $A >> 23 & 0x1ff);
|
||||||
}
|
}
|
||||||
for ($i = 0; $i < 256; ++$i) {
|
for ($i = 0; $i < 256; ++$i) {
|
||||||
$S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0];
|
$S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0];
|
||||||
|
@ -578,9 +584,9 @@ class Twofish extends Base
|
||||||
$S1[ $R1 & 0xff] ^
|
$S1[ $R1 & 0xff] ^
|
||||||
$S2[($R1 >> 8) & 0xff] ^
|
$S2[($R1 >> 8) & 0xff] ^
|
||||||
$S3[($R1 >> 16) & 0xff];
|
$S3[($R1 >> 16) & 0xff];
|
||||||
$R2^= $t0 + $t1 + $K[++$ki];
|
$R2^= $this->safe_intval($t0 + $t1 + $K[++$ki]);
|
||||||
$R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
|
$R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
|
||||||
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
|
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]);
|
||||||
|
|
||||||
$t0 = $S0[ $R2 & 0xff] ^
|
$t0 = $S0[ $R2 & 0xff] ^
|
||||||
$S1[($R2 >> 8) & 0xff] ^
|
$S1[($R2 >> 8) & 0xff] ^
|
||||||
|
@ -590,9 +596,9 @@ class Twofish extends Base
|
||||||
$S1[ $R3 & 0xff] ^
|
$S1[ $R3 & 0xff] ^
|
||||||
$S2[($R3 >> 8) & 0xff] ^
|
$S2[($R3 >> 8) & 0xff] ^
|
||||||
$S3[($R3 >> 16) & 0xff];
|
$S3[($R3 >> 16) & 0xff];
|
||||||
$R0^= ($t0 + $t1 + $K[++$ki]);
|
$R0^= $this->safe_intval($t0 + $t1 + $K[++$ki]);
|
||||||
$R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
|
$R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
|
||||||
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
|
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @codingStandardsIgnoreStart
|
// @codingStandardsIgnoreStart
|
||||||
|
@ -634,9 +640,9 @@ class Twofish extends Base
|
||||||
$S1[$R1 & 0xff] ^
|
$S1[$R1 & 0xff] ^
|
||||||
$S2[$R1 >> 8 & 0xff] ^
|
$S2[$R1 >> 8 & 0xff] ^
|
||||||
$S3[$R1 >> 16 & 0xff];
|
$S3[$R1 >> 16 & 0xff];
|
||||||
$R3^= $t0 + ($t1 << 1) + $K[--$ki];
|
$R3^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]);
|
||||||
$R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
|
$R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
|
||||||
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + $K[--$ki]);
|
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]);
|
||||||
|
|
||||||
$t0 = $S0[$R2 & 0xff] ^
|
$t0 = $S0[$R2 & 0xff] ^
|
||||||
$S1[$R2 >> 8 & 0xff] ^
|
$S1[$R2 >> 8 & 0xff] ^
|
||||||
|
@ -646,9 +652,9 @@ class Twofish extends Base
|
||||||
$S1[$R3 & 0xff] ^
|
$S1[$R3 & 0xff] ^
|
||||||
$S2[$R3 >> 8 & 0xff] ^
|
$S2[$R3 >> 8 & 0xff] ^
|
||||||
$S3[$R3 >> 16 & 0xff];
|
$S3[$R3 >> 16 & 0xff];
|
||||||
$R1^= $t0 + ($t1 << 1) + $K[--$ki];
|
$R1^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]);
|
||||||
$R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
|
$R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
|
||||||
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + $K[--$ki]);
|
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @codingStandardsIgnoreStart
|
// @codingStandardsIgnoreStart
|
||||||
|
@ -679,6 +685,8 @@ class Twofish extends Base
|
||||||
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
$code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$safeint = $this->safe_intval_inline();
|
||||||
|
|
||||||
if (!isset($lambda_functions[$code_hash])) {
|
if (!isset($lambda_functions[$code_hash])) {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case $gen_hi_opt_code:
|
case $gen_hi_opt_code:
|
||||||
|
@ -727,9 +735,9 @@ class Twofish extends Base
|
||||||
$S1[ $R1 & 0xff] ^
|
$S1[ $R1 & 0xff] ^
|
||||||
$S2[($R1 >> 8) & 0xff] ^
|
$S2[($R1 >> 8) & 0xff] ^
|
||||||
$S3[($R1 >> 16) & 0xff];
|
$S3[($R1 >> 16) & 0xff];
|
||||||
$R2^= ($t0 + $t1 + '.$K[++$ki].');
|
$R2^= ' . sprintf($safeint, '$t0 + $t1 + ' . $K[++$ki]) . ';
|
||||||
$R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
|
$R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
|
||||||
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
|
$R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . ';
|
||||||
|
|
||||||
$t0 = $S0[ $R2 & 0xff] ^
|
$t0 = $S0[ $R2 & 0xff] ^
|
||||||
$S1[($R2 >> 8) & 0xff] ^
|
$S1[($R2 >> 8) & 0xff] ^
|
||||||
|
@ -739,16 +747,16 @@ class Twofish extends Base
|
||||||
$S1[ $R3 & 0xff] ^
|
$S1[ $R3 & 0xff] ^
|
||||||
$S2[($R3 >> 8) & 0xff] ^
|
$S2[($R3 >> 8) & 0xff] ^
|
||||||
$S3[($R3 >> 16) & 0xff];
|
$S3[($R3 >> 16) & 0xff];
|
||||||
$R0^= ($t0 + $t1 + '.$K[++$ki].');
|
$R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . ';
|
||||||
$R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
|
$R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
|
||||||
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
|
$R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . ';
|
||||||
';
|
';
|
||||||
}
|
}
|
||||||
$encrypt_block.= '
|
$encrypt_block.= '
|
||||||
$in = pack("V4", '.$K[4].' ^ $R2,
|
$in = pack("V4", ' . $K[4] . ' ^ $R2,
|
||||||
'.$K[5].' ^ $R3,
|
' . $K[5] . ' ^ $R3,
|
||||||
'.$K[6].' ^ $R0,
|
' . $K[6] . ' ^ $R0,
|
||||||
'.$K[7].' ^ $R1);
|
' . $K[7] . ' ^ $R1);
|
||||||
';
|
';
|
||||||
|
|
||||||
// Generating decrypt code:
|
// Generating decrypt code:
|
||||||
|
@ -769,9 +777,9 @@ class Twofish extends Base
|
||||||
$S1[$R1 & 0xff] ^
|
$S1[$R1 & 0xff] ^
|
||||||
$S2[$R1 >> 8 & 0xff] ^
|
$S2[$R1 >> 8 & 0xff] ^
|
||||||
$S3[$R1 >> 16 & 0xff];
|
$S3[$R1 >> 16 & 0xff];
|
||||||
$R3^= $t0 + ($t1 << 1) + '.$K[--$ki].';
|
$R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . ';
|
||||||
$R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
|
$R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
|
||||||
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
|
$R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . ';
|
||||||
|
|
||||||
$t0 = $S0[$R2 & 0xff] ^
|
$t0 = $S0[$R2 & 0xff] ^
|
||||||
$S1[$R2 >> 8 & 0xff] ^
|
$S1[$R2 >> 8 & 0xff] ^
|
||||||
|
@ -781,16 +789,16 @@ class Twofish extends Base
|
||||||
$S1[$R3 & 0xff] ^
|
$S1[$R3 & 0xff] ^
|
||||||
$S2[$R3 >> 8 & 0xff] ^
|
$S2[$R3 >> 8 & 0xff] ^
|
||||||
$S3[$R3 >> 16 & 0xff];
|
$S3[$R3 >> 16 & 0xff];
|
||||||
$R1^= $t0 + ($t1 << 1) + '.$K[--$ki].';
|
$R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . ';
|
||||||
$R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
|
$R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
|
||||||
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
|
$R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . ';
|
||||||
';
|
';
|
||||||
}
|
}
|
||||||
$decrypt_block.= '
|
$decrypt_block.= '
|
||||||
$in = pack("V4", '.$K[0].' ^ $R2,
|
$in = pack("V4", ' . $K[0] . ' ^ $R2,
|
||||||
'.$K[1].' ^ $R3,
|
' . $K[1] . ' ^ $R3,
|
||||||
'.$K[2].' ^ $R0,
|
' . $K[2] . ' ^ $R0,
|
||||||
'.$K[3].' ^ $R1);
|
' . $K[3] . ' ^ $R1);
|
||||||
';
|
';
|
||||||
|
|
||||||
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
|
$lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
|
||||||
|
|
|
@ -305,6 +305,9 @@ class ANSI
|
||||||
case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines
|
case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines
|
||||||
$this->old_x = $this->x;
|
$this->old_x = $this->x;
|
||||||
$this->x-= $match[1];
|
$this->x-= $match[1];
|
||||||
|
if ($this->x < 0) {
|
||||||
|
$this->x = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
|
case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
|
||||||
break;
|
break;
|
||||||
|
@ -416,7 +419,7 @@ class ANSI
|
||||||
|
|
||||||
if ($this->x > $this->max_x) {
|
if ($this->x > $this->max_x) {
|
||||||
$this->x = 0;
|
$this->x = 0;
|
||||||
$this->y++;
|
$this->_newLine();
|
||||||
} else {
|
} else {
|
||||||
$this->x++;
|
$this->x++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ namespace phpseclib\File;
|
||||||
|
|
||||||
use phpseclib\File\ASN1\Element;
|
use phpseclib\File\ASN1\Element;
|
||||||
use phpseclib\Math\BigInteger;
|
use phpseclib\Math\BigInteger;
|
||||||
|
use DateTime;
|
||||||
|
use DateTimeZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pure-PHP ASN.1 Parser
|
* Pure-PHP ASN.1 Parser
|
||||||
|
@ -242,9 +244,10 @@ class ASN1
|
||||||
$tag = 0;
|
$tag = 0;
|
||||||
// process septets (since the eighth bit is ignored, it's not an octet)
|
// process septets (since the eighth bit is ignored, it's not an octet)
|
||||||
do {
|
do {
|
||||||
$loop = ord($encoded[0]) >> 7;
|
$temp = ord($encoded[$encoded_pos++]);
|
||||||
|
$loop = $temp >> 7;
|
||||||
$tag <<= 7;
|
$tag <<= 7;
|
||||||
$tag |= ord($encoded[$encoded_pos++]) & 0x7F;
|
$tag |= $temp & 0x7F;
|
||||||
$start++;
|
$start++;
|
||||||
} while ($loop);
|
} while ($loop);
|
||||||
}
|
}
|
||||||
|
@ -306,6 +309,9 @@ class ASN1
|
||||||
$remainingLength = $length;
|
$remainingLength = $length;
|
||||||
while ($remainingLength > 0) {
|
while ($remainingLength > 0) {
|
||||||
$temp = $this->_decode_ber($content, $start, $content_pos);
|
$temp = $this->_decode_ber($content, $start, $content_pos);
|
||||||
|
if ($temp === false) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
$length = $temp['length'];
|
$length = $temp['length'];
|
||||||
// end-of-content octets - see paragraph 8.1.5
|
// end-of-content octets - see paragraph 8.1.5
|
||||||
if (substr($content, $content_pos + $length, 2) == "\0\0") {
|
if (substr($content, $content_pos + $length, 2) == "\0\0") {
|
||||||
|
@ -357,6 +363,9 @@ class ASN1
|
||||||
$current['content'] = substr($content, $content_pos);
|
$current['content'] = substr($content, $content_pos);
|
||||||
} else {
|
} else {
|
||||||
$temp = $this->_decode_ber($content, $start, $content_pos);
|
$temp = $this->_decode_ber($content, $start, $content_pos);
|
||||||
|
if ($temp === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$length-= (strlen($content) - $content_pos);
|
$length-= (strlen($content) - $content_pos);
|
||||||
$last = count($temp) - 1;
|
$last = count($temp) - 1;
|
||||||
for ($i = 0; $i < $last; $i++) {
|
for ($i = 0; $i < $last; $i++) {
|
||||||
|
@ -381,6 +390,9 @@ class ASN1
|
||||||
$length = 0;
|
$length = 0;
|
||||||
while (substr($content, $content_pos, 2) != "\0\0") {
|
while (substr($content, $content_pos, 2) != "\0\0") {
|
||||||
$temp = $this->_decode_ber($content, $length + $start, $content_pos);
|
$temp = $this->_decode_ber($content, $length + $start, $content_pos);
|
||||||
|
if ($temp === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$content_pos += $temp['length'];
|
$content_pos += $temp['length'];
|
||||||
// all subtags should be octet strings
|
// all subtags should be octet strings
|
||||||
//if ($temp['type'] != self::TYPE_OCTET_STRING) {
|
//if ($temp['type'] != self::TYPE_OCTET_STRING) {
|
||||||
|
@ -413,30 +425,16 @@ class ASN1
|
||||||
break 2;
|
break 2;
|
||||||
}
|
}
|
||||||
$temp = $this->_decode_ber($content, $start + $offset, $content_pos);
|
$temp = $this->_decode_ber($content, $start + $offset, $content_pos);
|
||||||
|
if ($temp === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$content_pos += $temp['length'];
|
$content_pos += $temp['length'];
|
||||||
$current['content'][] = $temp;
|
$current['content'][] = $temp;
|
||||||
$offset+= $temp['length'];
|
$offset+= $temp['length'];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case self::TYPE_OBJECT_IDENTIFIER:
|
case self::TYPE_OBJECT_IDENTIFIER:
|
||||||
$temp = ord($content[$content_pos++]);
|
$current['content'] = $this->_decodeOID(substr($content, $content_pos));
|
||||||
$current['content'] = sprintf('%d.%d', floor($temp / 40), $temp % 40);
|
|
||||||
$valuen = 0;
|
|
||||||
// process septets
|
|
||||||
$content_len = strlen($content);
|
|
||||||
while ($content_pos < $content_len) {
|
|
||||||
$temp = ord($content[$content_pos++]);
|
|
||||||
$valuen <<= 7;
|
|
||||||
$valuen |= $temp & 0x7F;
|
|
||||||
if (~$temp & 0x80) {
|
|
||||||
$current['content'].= ".$valuen";
|
|
||||||
$valuen = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// the eighth bit of the last byte should not be 1
|
|
||||||
//if ($temp >> 7) {
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
break;
|
break;
|
||||||
/* Each character string type shall be encoded as if it had been declared:
|
/* Each character string type shall be encoded as if it had been declared:
|
||||||
[UNIVERSAL x] IMPLICIT OCTET STRING
|
[UNIVERSAL x] IMPLICIT OCTET STRING
|
||||||
|
@ -580,7 +578,7 @@ class ASN1
|
||||||
$childClass = $tempClass = self::CLASS_UNIVERSAL;
|
$childClass = $tempClass = self::CLASS_UNIVERSAL;
|
||||||
$constant = null;
|
$constant = null;
|
||||||
if (isset($temp['constant'])) {
|
if (isset($temp['constant'])) {
|
||||||
$tempClass = isset($temp['class']) ? $temp['class'] : self::CLASS_CONTEXT_SPECIFIC;
|
$tempClass = $temp['type'];
|
||||||
}
|
}
|
||||||
if (isset($child['class'])) {
|
if (isset($child['class'])) {
|
||||||
$childClass = $child['class'];
|
$childClass = $child['class'];
|
||||||
|
@ -643,7 +641,7 @@ class ASN1
|
||||||
$temp = $decoded['content'][$i];
|
$temp = $decoded['content'][$i];
|
||||||
$tempClass = self::CLASS_UNIVERSAL;
|
$tempClass = self::CLASS_UNIVERSAL;
|
||||||
if (isset($temp['constant'])) {
|
if (isset($temp['constant'])) {
|
||||||
$tempClass = isset($temp['class']) ? $temp['class'] : self::CLASS_CONTEXT_SPECIFIC;
|
$tempClass = $temp['type'];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($mapping['children'] as $key => $child) {
|
foreach ($mapping['children'] as $key => $child) {
|
||||||
|
@ -707,7 +705,7 @@ class ASN1
|
||||||
if (isset($mapping['implicit'])) {
|
if (isset($mapping['implicit'])) {
|
||||||
$decoded['content'] = $this->_decodeTime($decoded['content'], $decoded['type']);
|
$decoded['content'] = $this->_decodeTime($decoded['content'], $decoded['type']);
|
||||||
}
|
}
|
||||||
return @date($this->format, $decoded['content']);
|
return $decoded['content'] ? $decoded['content']->format($this->format) : false;
|
||||||
case self::TYPE_BIT_STRING:
|
case self::TYPE_BIT_STRING:
|
||||||
if (isset($mapping['mapping'])) {
|
if (isset($mapping['mapping'])) {
|
||||||
$offset = ord($decoded['content'][0]);
|
$offset = ord($decoded['content'][0]);
|
||||||
|
@ -956,7 +954,8 @@ class ASN1
|
||||||
case self::TYPE_GENERALIZED_TIME:
|
case self::TYPE_GENERALIZED_TIME:
|
||||||
$format = $mapping['type'] == self::TYPE_UTC_TIME ? 'y' : 'Y';
|
$format = $mapping['type'] == self::TYPE_UTC_TIME ? 'y' : 'Y';
|
||||||
$format.= 'mdHis';
|
$format.= 'mdHis';
|
||||||
$value = @gmdate($format, strtotime($source)) . 'Z';
|
$date = new DateTime($source, new DateTimeZone('GMT'));
|
||||||
|
$value = $date->format($format) . 'Z';
|
||||||
break;
|
break;
|
||||||
case self::TYPE_BIT_STRING:
|
case self::TYPE_BIT_STRING:
|
||||||
if (isset($mapping['mapping'])) {
|
if (isset($mapping['mapping'])) {
|
||||||
|
@ -998,27 +997,7 @@ class ASN1
|
||||||
$value = base64_decode($source);
|
$value = base64_decode($source);
|
||||||
break;
|
break;
|
||||||
case self::TYPE_OBJECT_IDENTIFIER:
|
case self::TYPE_OBJECT_IDENTIFIER:
|
||||||
$oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids);
|
$value = $this->_encodeOID($source);
|
||||||
if ($oid === false) {
|
|
||||||
user_error('Invalid OID');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$value = '';
|
|
||||||
$parts = explode('.', $oid);
|
|
||||||
$value = chr(40 * $parts[0] + $parts[1]);
|
|
||||||
for ($i = 2; $i < count($parts); $i++) {
|
|
||||||
$temp = '';
|
|
||||||
if (!$parts[$i]) {
|
|
||||||
$temp = "\0";
|
|
||||||
} else {
|
|
||||||
while ($parts[$i]) {
|
|
||||||
$temp = chr(0x80 | ($parts[$i] & 0x7F)) . $temp;
|
|
||||||
$parts[$i] >>= 7;
|
|
||||||
}
|
|
||||||
$temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F);
|
|
||||||
}
|
|
||||||
$value.= $temp;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case self::TYPE_ANY:
|
case self::TYPE_ANY:
|
||||||
$loc = $this->location;
|
$loc = $this->location;
|
||||||
|
@ -1117,6 +1096,108 @@ class ASN1
|
||||||
return pack('Ca*', 0x80 | strlen($temp), $temp);
|
return pack('Ca*', 0x80 | strlen($temp), $temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BER-decode the OID
|
||||||
|
*
|
||||||
|
* Called by _decode_ber()
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param string $content
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function _decodeOID($content)
|
||||||
|
{
|
||||||
|
static $eighty;
|
||||||
|
if (!$eighty) {
|
||||||
|
$eighty = new BigInteger(80);
|
||||||
|
}
|
||||||
|
|
||||||
|
$oid = array();
|
||||||
|
$pos = 0;
|
||||||
|
$len = strlen($content);
|
||||||
|
$n = new BigInteger();
|
||||||
|
while ($pos < $len) {
|
||||||
|
$temp = ord($content[$pos++]);
|
||||||
|
$n = $n->bitwise_leftShift(7);
|
||||||
|
$n = $n->bitwise_or(new BigInteger($temp & 0x7F));
|
||||||
|
if (~$temp & 0x80) {
|
||||||
|
$oid[] = $n;
|
||||||
|
$n = new BigInteger();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$part1 = array_shift($oid);
|
||||||
|
$first = floor(ord($content[0]) / 40);
|
||||||
|
/*
|
||||||
|
"This packing of the first two object identifier components recognizes that only three values are allocated from the root
|
||||||
|
node, and at most 39 subsequent values from nodes reached by X = 0 and X = 1."
|
||||||
|
|
||||||
|
-- https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=22
|
||||||
|
*/
|
||||||
|
if ($first <= 2) { // ie. 0 <= ord($content[0]) < 120 (0x78)
|
||||||
|
array_unshift($oid, ord($content[0]) % 40);
|
||||||
|
array_unshift($oid, $first);
|
||||||
|
} else {
|
||||||
|
array_unshift($oid, $part1->subtract($eighty));
|
||||||
|
array_unshift($oid, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode('.', $oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DER-encode the OID
|
||||||
|
*
|
||||||
|
* Called by _encode_der()
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @param string $content
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function _encodeOID($source)
|
||||||
|
{
|
||||||
|
static $mask, $zero, $forty;
|
||||||
|
if (!$mask) {
|
||||||
|
$mask = new BigInteger(0x7F);
|
||||||
|
$zero = new BigInteger();
|
||||||
|
$forty = new BigInteger(40);
|
||||||
|
}
|
||||||
|
|
||||||
|
$oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids);
|
||||||
|
if ($oid === false) {
|
||||||
|
user_error('Invalid OID');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$parts = explode('.', $oid);
|
||||||
|
$part1 = array_shift($parts);
|
||||||
|
$part2 = array_shift($parts);
|
||||||
|
|
||||||
|
$first = new BigInteger($part1);
|
||||||
|
$first = $first->multiply($forty);
|
||||||
|
$first = $first->add(new BigInteger($part2));
|
||||||
|
|
||||||
|
array_unshift($parts, $first->toString());
|
||||||
|
|
||||||
|
$value = '';
|
||||||
|
foreach ($parts as $part) {
|
||||||
|
if (!$part) {
|
||||||
|
$temp = "\0";
|
||||||
|
} else {
|
||||||
|
$temp = '';
|
||||||
|
$part = new BigInteger($part);
|
||||||
|
while (!$part->equals($zero)) {
|
||||||
|
$submask = $part->bitwise_and($mask);
|
||||||
|
$submask->setPrecision(8);
|
||||||
|
$temp = (chr(0x80) | $submask->toBytes()) . $temp;
|
||||||
|
$part = $part->bitwise_rightShift(7);
|
||||||
|
}
|
||||||
|
$temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F);
|
||||||
|
}
|
||||||
|
$value.= $temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BER-decode the time
|
* BER-decode the time
|
||||||
*
|
*
|
||||||
|
@ -1137,33 +1218,32 @@ class ASN1
|
||||||
http://tools.ietf.org/html/rfc5280#section-4.1.2.5.2
|
http://tools.ietf.org/html/rfc5280#section-4.1.2.5.2
|
||||||
http://www.obj-sys.com/asn1tutorial/node14.html */
|
http://www.obj-sys.com/asn1tutorial/node14.html */
|
||||||
|
|
||||||
$pattern = $tag == self::TYPE_UTC_TIME ?
|
$format = 'YmdHis';
|
||||||
'#^(..)(..)(..)(..)(..)(..)?(.*)$#' :
|
|
||||||
'#(....)(..)(..)(..)(..)(..).*([Z+-].*)$#';
|
|
||||||
|
|
||||||
preg_match($pattern, $content, $matches);
|
|
||||||
|
|
||||||
list(, $year, $month, $day, $hour, $minute, $second, $timezone) = $matches;
|
|
||||||
|
|
||||||
if ($tag == self::TYPE_UTC_TIME) {
|
if ($tag == self::TYPE_UTC_TIME) {
|
||||||
$year = $year >= 50 ? "19$year" : "20$year";
|
// https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=28 says "the seconds
|
||||||
}
|
// element shall always be present" but none-the-less I've seen X509 certs where it isn't and if the
|
||||||
|
// browsers parse it phpseclib ought to too
|
||||||
if ($timezone == 'Z') {
|
if (preg_match('#^(\d{10})(Z|[+-]\d{4})$#', $content, $matches)) {
|
||||||
$mktime = 'gmmktime';
|
$content = $matches[1] . '00' . $matches[2];
|
||||||
$timezone = 0;
|
|
||||||
} elseif (preg_match('#([+-])(\d\d)(\d\d)#', $timezone, $matches)) {
|
|
||||||
$mktime = 'gmmktime';
|
|
||||||
$timezone = 60 * $matches[3] + 3600 * $matches[2];
|
|
||||||
if ($matches[1] == '-') {
|
|
||||||
$timezone = -$timezone;
|
|
||||||
}
|
}
|
||||||
} else {
|
$prefix = substr($content, 0, 2) >= 50 ? '19' : '20';
|
||||||
$mktime = 'mktime';
|
$content = $prefix . $content;
|
||||||
$timezone = 0;
|
} elseif (strpos($content, '.') !== false) {
|
||||||
|
$format.= '.u';
|
||||||
}
|
}
|
||||||
|
|
||||||
return @$mktime((int)$hour, (int)$minute, (int)$second, (int)$month, (int)$day, (int)$year) + $timezone;
|
if ($content[strlen($content) - 1] == 'Z') {
|
||||||
|
$content = substr($content, 0, -1) . '+0000';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($content, '-') !== false || strpos($content, '+') !== false) {
|
||||||
|
$format.= 'O';
|
||||||
|
}
|
||||||
|
|
||||||
|
// error supression isn't necessary as of PHP 7.0:
|
||||||
|
// http://php.net/manual/en/migration70.other-changes.php
|
||||||
|
return @DateTime::createFromFormat($format, $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -31,6 +31,8 @@ use phpseclib\Crypt\Random;
|
||||||
use phpseclib\Crypt\RSA;
|
use phpseclib\Crypt\RSA;
|
||||||
use phpseclib\File\ASN1\Element;
|
use phpseclib\File\ASN1\Element;
|
||||||
use phpseclib\Math\BigInteger;
|
use phpseclib\Math\BigInteger;
|
||||||
|
use DateTime;
|
||||||
|
use DateTimeZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pure-PHP X.509 Parser
|
* Pure-PHP X.509 Parser
|
||||||
|
@ -303,6 +305,22 @@ class X509
|
||||||
*/
|
*/
|
||||||
var $challenge;
|
var $challenge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursion Limit
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
static $recur_limit = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL fetch flag
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
static $disable_url_fetch = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Constructor.
|
* Default Constructor.
|
||||||
*
|
*
|
||||||
|
@ -1910,6 +1928,9 @@ class X509
|
||||||
// "Certificate Transparency"
|
// "Certificate Transparency"
|
||||||
// https://tools.ietf.org/html/rfc6962
|
// https://tools.ietf.org/html/rfc6962
|
||||||
case '1.3.6.1.4.1.11129.2.4.2':
|
case '1.3.6.1.4.1.11129.2.4.2':
|
||||||
|
// "Qualified Certificate statements"
|
||||||
|
// https://tools.ietf.org/html/rfc3739#section-3.2.6
|
||||||
|
case '1.3.6.1.5.5.7.1.3':
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// CSR attributes
|
// CSR attributes
|
||||||
|
@ -2030,30 +2051,32 @@ class X509
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($names = $this->getExtension('id-ce-subjectAltName')) {
|
if ($names = $this->getExtension('id-ce-subjectAltName')) {
|
||||||
foreach ($names as $key => $value) {
|
foreach ($names as $name) {
|
||||||
$value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value);
|
foreach ($name as $key => $value) {
|
||||||
switch ($key) {
|
$value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value);
|
||||||
case 'dNSName':
|
switch ($key) {
|
||||||
/* From RFC2818 "HTTP over TLS":
|
case 'dNSName':
|
||||||
|
/* From RFC2818 "HTTP over TLS":
|
||||||
|
|
||||||
If a subjectAltName extension of type dNSName is present, that MUST
|
If a subjectAltName extension of type dNSName is present, that MUST
|
||||||
be used as the identity. Otherwise, the (most specific) Common Name
|
be used as the identity. Otherwise, the (most specific) Common Name
|
||||||
field in the Subject field of the certificate MUST be used. Although
|
field in the Subject field of the certificate MUST be used. Although
|
||||||
the use of the Common Name is existing practice, it is deprecated and
|
the use of the Common Name is existing practice, it is deprecated and
|
||||||
Certification Authorities are encouraged to use the dNSName instead. */
|
Certification Authorities are encouraged to use the dNSName instead. */
|
||||||
if (preg_match('#^' . $value . '$#', $components['host'])) {
|
if (preg_match('#^' . $value . '$#', $components['host'])) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'iPAddress':
|
case 'iPAddress':
|
||||||
/* From RFC2818 "HTTP over TLS":
|
/* From RFC2818 "HTTP over TLS":
|
||||||
|
|
||||||
In some cases, the URI is specified as an IP address rather than a
|
In some cases, the URI is specified as an IP address rather than a
|
||||||
hostname. In this case, the iPAddress subjectAltName must be present
|
hostname. In this case, the iPAddress subjectAltName must be present
|
||||||
in the certificate and must exactly match the IP in the URI. */
|
in the certificate and must exactly match the IP in the URI. */
|
||||||
if (preg_match('#(?:\d{1-3}\.){4}#', $components['host'] . '.') && preg_match('#^' . $value . '$#', $components['host'])) {
|
if (preg_match('#(?:\d{1-3}\.){4}#', $components['host'] . '.') && preg_match('#^' . $value . '$#', $components['host'])) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -2072,7 +2095,7 @@ class X509
|
||||||
*
|
*
|
||||||
* If $date isn't defined it is assumed to be the current date.
|
* If $date isn't defined it is assumed to be the current date.
|
||||||
*
|
*
|
||||||
* @param int $date optional
|
* @param \DateTime|string $date optional
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function validateDate($date = null)
|
function validateDate($date = null)
|
||||||
|
@ -2082,7 +2105,7 @@ class X509
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($date)) {
|
if (!isset($date)) {
|
||||||
$date = time();
|
$date = new DateTime(null, new DateTimeZone(@date_default_timezone_get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
$notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore'];
|
$notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore'];
|
||||||
|
@ -2091,15 +2114,133 @@ class X509
|
||||||
$notAfter = $this->currentCert['tbsCertificate']['validity']['notAfter'];
|
$notAfter = $this->currentCert['tbsCertificate']['validity']['notAfter'];
|
||||||
$notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
|
$notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
|
||||||
|
|
||||||
|
if (is_string($date)) {
|
||||||
|
$date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
$notBefore = new DateTime($notBefore, new DateTimeZone(@date_default_timezone_get()));
|
||||||
|
$notAfter = new DateTime($notAfter, new DateTimeZone(@date_default_timezone_get()));
|
||||||
|
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case $date < @strtotime($notBefore):
|
case $date < $notBefore:
|
||||||
case $date > @strtotime($notAfter):
|
case $date > $notAfter:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a URL
|
||||||
|
*
|
||||||
|
* @param string $url
|
||||||
|
* @access private
|
||||||
|
* @return bool|string
|
||||||
|
*/
|
||||||
|
static function _fetchURL($url)
|
||||||
|
{
|
||||||
|
if (self::$disable_url_fetch) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = parse_url($url);
|
||||||
|
$data = '';
|
||||||
|
switch ($parts['scheme']) {
|
||||||
|
case 'http':
|
||||||
|
$fsock = @fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80);
|
||||||
|
if (!$fsock) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fputs($fsock, "GET $parts[path] HTTP/1.0\r\n");
|
||||||
|
fputs($fsock, "Host: $parts[host]\r\n\r\n");
|
||||||
|
$line = fgets($fsock, 1024);
|
||||||
|
if (strlen($line) < 3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
preg_match('#HTTP/1.\d (\d{3})#', $line, $temp);
|
||||||
|
if ($temp[1] != '200') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip the rest of the headers in the http response
|
||||||
|
while (!feof($fsock) && fgets($fsock, 1024) != "\r\n") {
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!feof($fsock)) {
|
||||||
|
$data.= fread($fsock, 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
//case 'ftp':
|
||||||
|
//case 'ldap':
|
||||||
|
//default:
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates an intermediate cert as identified via authority info access extension
|
||||||
|
*
|
||||||
|
* See https://tools.ietf.org/html/rfc4325 for more info
|
||||||
|
*
|
||||||
|
* @param bool $caonly
|
||||||
|
* @param int $count
|
||||||
|
* @access private
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function _testForIntermediate($caonly, $count)
|
||||||
|
{
|
||||||
|
$opts = $this->getExtension('id-pe-authorityInfoAccess');
|
||||||
|
if (!is_array($opts)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
foreach ($opts as $opt) {
|
||||||
|
if ($opt['accessMethod'] == 'id-ad-caIssuers') {
|
||||||
|
// accessLocation is a GeneralName. GeneralName fields support stuff like email addresses, IP addresses, LDAP,
|
||||||
|
// etc, but we're only supporting URI's. URI's and LDAP are the only thing https://tools.ietf.org/html/rfc4325
|
||||||
|
// discusses
|
||||||
|
if (isset($opt['accessLocation']['uniformResourceIdentifier'])) {
|
||||||
|
$url = $opt['accessLocation']['uniformResourceIdentifier'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($url)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cert = static::_fetchURL($url);
|
||||||
|
if (!is_string($cert)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parent = new static();
|
||||||
|
$parent->CAs = $this->CAs;
|
||||||
|
/*
|
||||||
|
"Conforming applications that support HTTP or FTP for accessing
|
||||||
|
certificates MUST be able to accept .cer files and SHOULD be able
|
||||||
|
to accept .p7c files." -- https://tools.ietf.org/html/rfc4325
|
||||||
|
|
||||||
|
A .p7c file is 'a "certs-only" CMS message as specified in RFC 2797"
|
||||||
|
|
||||||
|
These are currently unsupported
|
||||||
|
*/
|
||||||
|
if (!is_array($parent->loadX509($cert))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$parent->_validateSignatureCountable($caonly, ++$count)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->CAs[] = $parent->currentCert;
|
||||||
|
//$this->loadCA($cert);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate a signature
|
* Validate a signature
|
||||||
*
|
*
|
||||||
|
@ -2116,11 +2257,30 @@ class X509
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
function validateSignature($caonly = true)
|
function validateSignature($caonly = true)
|
||||||
|
{
|
||||||
|
return $this->_validateSignatureCountable($caonly, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a signature
|
||||||
|
*
|
||||||
|
* Performs said validation whilst keeping track of how many times validation method is called
|
||||||
|
*
|
||||||
|
* @param bool $caonly
|
||||||
|
* @param int $count
|
||||||
|
* @access private
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function _validateSignatureCountable($caonly, $count)
|
||||||
{
|
{
|
||||||
if (!is_array($this->currentCert) || !isset($this->signatureSubject)) {
|
if (!is_array($this->currentCert) || !isset($this->signatureSubject)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($count == self::$recur_limit) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
"emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")."
|
"emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")."
|
||||||
-- http://tools.ietf.org/html/rfc5280#section-4.1.2.6
|
-- http://tools.ietf.org/html/rfc5280#section-4.1.2.6
|
||||||
|
@ -2137,7 +2297,8 @@ class X509
|
||||||
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier');
|
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier');
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case !is_array($authorityKey):
|
case !is_array($authorityKey):
|
||||||
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
case !$subjectKeyID:
|
||||||
|
case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||||
$signingCert = $this->currentCert; // working cert
|
$signingCert = $this->currentCert; // working cert
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2154,17 +2315,21 @@ class X509
|
||||||
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
|
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case !is_array($authorityKey):
|
case !is_array($authorityKey):
|
||||||
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
case !$subjectKeyID:
|
||||||
|
case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||||
|
if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) {
|
||||||
|
break 2; // serial mismatch - check other ca
|
||||||
|
}
|
||||||
$signingCert = $ca; // working cert
|
$signingCert = $ca; // working cert
|
||||||
break 3;
|
break 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count($this->CAs) == $i && $caonly) {
|
if (count($this->CAs) == $i && $caonly) {
|
||||||
return false;
|
return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly);
|
||||||
}
|
}
|
||||||
} elseif (!isset($signingCert) || $caonly) {
|
} elseif (!isset($signingCert) || $caonly) {
|
||||||
return false;
|
return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly);
|
||||||
}
|
}
|
||||||
return $this->_validateSignature(
|
return $this->_validateSignature(
|
||||||
$signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
|
$signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
|
||||||
|
@ -2200,7 +2365,11 @@ class X509
|
||||||
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
|
$subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case !is_array($authorityKey):
|
case !is_array($authorityKey):
|
||||||
case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
case !$subjectKeyID:
|
||||||
|
case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
|
||||||
|
if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) {
|
||||||
|
break 2; // serial mismatch - check other ca
|
||||||
|
}
|
||||||
$signingCert = $ca; // working cert
|
$signingCert = $ca; // working cert
|
||||||
break 3;
|
break 3;
|
||||||
}
|
}
|
||||||
|
@ -2267,6 +2436,41 @@ class X509
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the recursion limit
|
||||||
|
*
|
||||||
|
* When validating a signature it may be necessary to download intermediate certs from URI's.
|
||||||
|
* An intermediate cert that linked to itself would result in an infinite loop so to prevent
|
||||||
|
* that we set a recursion limit. A negative number means that there is no recursion limit.
|
||||||
|
*
|
||||||
|
* @param int $count
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
static function setRecurLimit($count)
|
||||||
|
{
|
||||||
|
self::$recur_limit = $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevents URIs from being automatically retrieved
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
static function disableURLFetch()
|
||||||
|
{
|
||||||
|
self::$disable_url_fetch = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows URIs to be automatically retrieved
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
static function enableURLFetch()
|
||||||
|
{
|
||||||
|
self::$disable_url_fetch = false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reformat public keys
|
* Reformat public keys
|
||||||
*
|
*
|
||||||
|
@ -2472,6 +2676,10 @@ class X509
|
||||||
}
|
}
|
||||||
|
|
||||||
$dn = array_values($dn);
|
$dn = array_values($dn);
|
||||||
|
// fix for https://bugs.php.net/75433 affecting PHP 7.2
|
||||||
|
if (!isset($dn[0])) {
|
||||||
|
$dn = array_splice($dn, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2715,12 +2923,14 @@ class X509
|
||||||
$value = array_pop($value); // Always strip data type.
|
$value = array_pop($value); // Always strip data type.
|
||||||
}
|
}
|
||||||
} elseif (is_object($value) && $value instanceof Element) {
|
} elseif (is_object($value) && $value instanceof Element) {
|
||||||
$callback = create_function('$x', 'return "\x" . bin2hex($x[0]);');
|
$callback = function ($x) {
|
||||||
|
return "\x" . bin2hex($x[0]);
|
||||||
|
};
|
||||||
$value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element));
|
$value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element));
|
||||||
}
|
}
|
||||||
$output.= $desc . '=' . $value;
|
$output.= $desc . '=' . $value;
|
||||||
$result[$desc] = isset($result[$desc]) ?
|
$result[$desc] = isset($result[$desc]) ?
|
||||||
array_merge((array) $dn[$prop], array($value)) :
|
array_merge((array) $result[$desc], array($value)) :
|
||||||
$value;
|
$value;
|
||||||
$start = false;
|
$start = false;
|
||||||
}
|
}
|
||||||
|
@ -3338,7 +3548,11 @@ class X509
|
||||||
*/
|
*/
|
||||||
function _timeField($date)
|
function _timeField($date)
|
||||||
{
|
{
|
||||||
$year = @gmdate("Y", @strtotime($date)); // the same way ASN1.php parses this
|
if ($date instanceof Element) {
|
||||||
|
return $date;
|
||||||
|
}
|
||||||
|
$dateObj = new DateTime($date, new DateTimeZone('GMT'));
|
||||||
|
$year = $dateObj->format('Y'); // the same way ASN1.php parses this
|
||||||
if ($year < 2050) {
|
if ($year < 2050) {
|
||||||
return array('utcTime' => $date);
|
return array('utcTime' => $date);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3403,8 +3617,12 @@ class X509
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$startDate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
|
$startDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
|
||||||
$endDate = !empty($this->endDate) ? $this->endDate : @date('D, d M Y H:i:s O', strtotime('+1 year'));
|
$startDate = !empty($this->startDate) ? $this->startDate : $startDate->format('D, d M Y H:i:s O');
|
||||||
|
|
||||||
|
$endDate = new DateTime('+1 year', new DateTimeZone(@date_default_timezone_get()));
|
||||||
|
$endDate = !empty($this->endDate) ? $this->endDate : $endDate->format('D, d M Y H:i:s O');
|
||||||
|
|
||||||
/* "The serial number MUST be a positive integer"
|
/* "The serial number MUST be a positive integer"
|
||||||
"Conforming CAs MUST NOT use serialNumber values longer than 20 octets."
|
"Conforming CAs MUST NOT use serialNumber values longer than 20 octets."
|
||||||
-- https://tools.ietf.org/html/rfc5280#section-4.1.2.2
|
-- https://tools.ietf.org/html/rfc5280#section-4.1.2.2
|
||||||
|
@ -3420,7 +3638,7 @@ class X509
|
||||||
'tbsCertificate' =>
|
'tbsCertificate' =>
|
||||||
array(
|
array(
|
||||||
'version' => 'v3',
|
'version' => 'v3',
|
||||||
'serialNumber' => $serialNumber, // $this->setserialNumber()
|
'serialNumber' => $serialNumber, // $this->setSerialNumber()
|
||||||
'signature' => array('algorithm' => $signatureAlgorithm),
|
'signature' => array('algorithm' => $signatureAlgorithm),
|
||||||
'issuer' => false, // this is going to be overwritten later
|
'issuer' => false, // this is going to be overwritten later
|
||||||
'validity' => array(
|
'validity' => array(
|
||||||
|
@ -3672,7 +3890,9 @@ class X509
|
||||||
|
|
||||||
$currentCert = isset($this->currentCert) ? $this->currentCert : null;
|
$currentCert = isset($this->currentCert) ? $this->currentCert : null;
|
||||||
$signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null;
|
$signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null;
|
||||||
$thisUpdate = !empty($this->startDate) ? $this->startDate : @date('D, d M Y H:i:s O');
|
|
||||||
|
$thisUpdate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
|
||||||
|
$thisUpdate = !empty($this->startDate) ? $this->startDate : $thisUpdate->format('D, d M Y H:i:s O');
|
||||||
|
|
||||||
if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) {
|
if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) {
|
||||||
$this->currentCert = $crl->currentCert;
|
$this->currentCert = $crl->currentCert;
|
||||||
|
@ -3823,7 +4043,11 @@ class X509
|
||||||
*/
|
*/
|
||||||
function setStartDate($date)
|
function setStartDate($date)
|
||||||
{
|
{
|
||||||
$this->startDate = @date('D, d M Y H:i:s O', @strtotime($date));
|
if (!is_object($date) || !is_a($date, 'DateTime')) {
|
||||||
|
$date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->startDate = $date->format('D, d M Y H:i:s O');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3847,7 +4071,11 @@ class X509
|
||||||
$temp = chr(ASN1::TYPE_GENERALIZED_TIME) . $asn1->_encodeLength(strlen($temp)) . $temp;
|
$temp = chr(ASN1::TYPE_GENERALIZED_TIME) . $asn1->_encodeLength(strlen($temp)) . $temp;
|
||||||
$this->endDate = new Element($temp);
|
$this->endDate = new Element($temp);
|
||||||
} else {
|
} else {
|
||||||
$this->endDate = @date('D, d M Y H:i:s O', @strtotime($date));
|
if (!is_object($date) || !is_a($date, 'DateTime')) {
|
||||||
|
$date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->endDate = $date->format('D, d M Y H:i:s O');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4057,6 +4285,10 @@ class X509
|
||||||
}
|
}
|
||||||
|
|
||||||
$extensions = array_values($extensions);
|
$extensions = array_values($extensions);
|
||||||
|
// fix for https://bugs.php.net/75433 affecting PHP 7.2
|
||||||
|
if (!isset($extensions[0])) {
|
||||||
|
$extensions = array_splice($extensions, 0, 0);
|
||||||
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4577,8 +4809,9 @@ class X509
|
||||||
}
|
}
|
||||||
|
|
||||||
$i = count($rclist);
|
$i = count($rclist);
|
||||||
|
$revocationDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
|
||||||
$rclist[] = array('userCertificate' => $serial,
|
$rclist[] = array('userCertificate' => $serial,
|
||||||
'revocationDate' => $this->_timeField(@date('D, d M Y H:i:s O')));
|
'revocationDate' => $this->_timeField($revocationDate->format('D, d M Y H:i:s O')));
|
||||||
return $i;
|
return $i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @copyright 2006 Jim Wigginton
|
* @copyright 2006 Jim Wigginton
|
||||||
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
* @link http://pear.php.net/package/Math_BigInteger
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace phpseclib\Math;
|
namespace phpseclib\Math;
|
||||||
|
@ -266,23 +265,27 @@ class BigInteger
|
||||||
|
|
||||||
if (extension_loaded('openssl') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
|
if (extension_loaded('openssl') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
|
||||||
// some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
|
// some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
|
||||||
ob_start();
|
|
||||||
@phpinfo();
|
|
||||||
$content = ob_get_contents();
|
|
||||||
ob_end_clean();
|
|
||||||
|
|
||||||
preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
|
|
||||||
|
|
||||||
$versions = array();
|
$versions = array();
|
||||||
if (!empty($matches[1])) {
|
|
||||||
for ($i = 0; $i < count($matches[1]); $i++) {
|
|
||||||
$fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
|
|
||||||
|
|
||||||
// Remove letter part in OpenSSL version
|
// avoid generating errors (even with suppression) when phpinfo() is disabled (common in production systems)
|
||||||
if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
|
if (strpos(ini_get('disable_functions'), 'phpinfo') === false) {
|
||||||
$versions[$matches[1][$i]] = $fullVersion;
|
ob_start();
|
||||||
} else {
|
@phpinfo();
|
||||||
$versions[$matches[1][$i]] = $m[0];
|
$content = ob_get_contents();
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
|
||||||
|
|
||||||
|
if (!empty($matches[1])) {
|
||||||
|
for ($i = 0; $i < count($matches[1]); $i++) {
|
||||||
|
$fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
|
||||||
|
|
||||||
|
// Remove letter part in OpenSSL version
|
||||||
|
if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
|
||||||
|
$versions[$matches[1][$i]] = $fullVersion;
|
||||||
|
} else {
|
||||||
|
$versions[$matches[1][$i]] = $m[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,8 +363,12 @@ class BigInteger
|
||||||
case 256:
|
case 256:
|
||||||
switch (MATH_BIGINTEGER_MODE) {
|
switch (MATH_BIGINTEGER_MODE) {
|
||||||
case self::MODE_GMP:
|
case self::MODE_GMP:
|
||||||
$sign = $this->is_negative ? '-' : '';
|
$this->value = function_exists('gmp_import') ?
|
||||||
$this->value = gmp_init($sign . '0x' . bin2hex($x));
|
gmp_import($x) :
|
||||||
|
gmp_init('0x' . bin2hex($x));
|
||||||
|
if ($this->is_negative) {
|
||||||
|
$this->value = gmp_neg($this->value);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case self::MODE_BCMATH:
|
case self::MODE_BCMATH:
|
||||||
// round $len to the nearest 4 (thanks, DavidMJ!)
|
// round $len to the nearest 4 (thanks, DavidMJ!)
|
||||||
|
@ -438,6 +445,9 @@ class BigInteger
|
||||||
// (?<=^|-)0*: find any 0's that are preceded by the start of the string or by a - (ie. octals)
|
// (?<=^|-)0*: find any 0's that are preceded by the start of the string or by a - (ie. octals)
|
||||||
// [^-0-9].*: find any non-numeric characters and then any characters that follow that
|
// [^-0-9].*: find any non-numeric characters and then any characters that follow that
|
||||||
$x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#', '', $x);
|
$x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#', '', $x);
|
||||||
|
if (!strlen($x) || $x == '-') {
|
||||||
|
$x = '0';
|
||||||
|
}
|
||||||
|
|
||||||
switch (MATH_BIGINTEGER_MODE) {
|
switch (MATH_BIGINTEGER_MODE) {
|
||||||
case self::MODE_GMP:
|
case self::MODE_GMP:
|
||||||
|
@ -531,7 +541,7 @@ class BigInteger
|
||||||
$temp = $comparison < 0 ? $this->add(new static(1)) : $this->copy();
|
$temp = $comparison < 0 ? $this->add(new static(1)) : $this->copy();
|
||||||
$bytes = $temp->toBytes();
|
$bytes = $temp->toBytes();
|
||||||
|
|
||||||
if (empty($bytes)) { // eg. if the number we're trying to convert is -1
|
if (!strlen($bytes)) { // eg. if the number we're trying to convert is -1
|
||||||
$bytes = chr(0);
|
$bytes = chr(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,9 +558,13 @@ class BigInteger
|
||||||
return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
|
return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$temp = gmp_strval(gmp_abs($this->value), 16);
|
if (function_exists('gmp_export')) {
|
||||||
$temp = (strlen($temp) & 1) ? '0' . $temp : $temp;
|
$temp = gmp_export($this->value);
|
||||||
$temp = pack('H*', $temp);
|
} else {
|
||||||
|
$temp = gmp_strval(gmp_abs($this->value), 16);
|
||||||
|
$temp = (strlen($temp) & 1) ? '0' . $temp : $temp;
|
||||||
|
$temp = pack('H*', $temp);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->precision > 0 ?
|
return $this->precision > 0 ?
|
||||||
substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
|
substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
|
||||||
|
@ -1547,7 +1561,9 @@ class BigInteger
|
||||||
$temp_value = array($quotient_value[$q_index]);
|
$temp_value = array($quotient_value[$q_index]);
|
||||||
$temp = $temp->multiply($y);
|
$temp = $temp->multiply($y);
|
||||||
$temp_value = &$temp->value;
|
$temp_value = &$temp->value;
|
||||||
$temp_value = array_merge($adjust, $temp_value);
|
if (count($temp_value)) {
|
||||||
|
$temp_value = array_merge($adjust, $temp_value);
|
||||||
|
}
|
||||||
|
|
||||||
$x = $x->subtract($temp);
|
$x = $x->subtract($temp);
|
||||||
|
|
||||||
|
@ -2680,7 +2696,14 @@ class BigInteger
|
||||||
{
|
{
|
||||||
switch (MATH_BIGINTEGER_MODE) {
|
switch (MATH_BIGINTEGER_MODE) {
|
||||||
case self::MODE_GMP:
|
case self::MODE_GMP:
|
||||||
return gmp_cmp($this->value, $y->value);
|
$r = gmp_cmp($this->value, $y->value);
|
||||||
|
if ($r < -1) {
|
||||||
|
$r = -1;
|
||||||
|
}
|
||||||
|
if ($r > 1) {
|
||||||
|
$r = 1;
|
||||||
|
}
|
||||||
|
return $r;
|
||||||
case self::MODE_BCMATH:
|
case self::MODE_BCMATH:
|
||||||
return bccomp($this->value, $y->value, 0);
|
return bccomp($this->value, $y->value, 0);
|
||||||
}
|
}
|
||||||
|
@ -2860,8 +2883,7 @@ class BigInteger
|
||||||
switch (MATH_BIGINTEGER_MODE) {
|
switch (MATH_BIGINTEGER_MODE) {
|
||||||
case self::MODE_GMP:
|
case self::MODE_GMP:
|
||||||
$temp = new static();
|
$temp = new static();
|
||||||
$temp->value = gmp_xor($this->value, $x->value);
|
$temp->value = gmp_xor(gmp_abs($this->value), gmp_abs($x->value));
|
||||||
|
|
||||||
return $this->_normalize($temp);
|
return $this->_normalize($temp);
|
||||||
case self::MODE_BCMATH:
|
case self::MODE_BCMATH:
|
||||||
$left = $this->toBytes();
|
$left = $this->toBytes();
|
||||||
|
@ -2877,6 +2899,7 @@ class BigInteger
|
||||||
|
|
||||||
$length = max(count($this->value), count($x->value));
|
$length = max(count($this->value), count($x->value));
|
||||||
$result = $this->copy();
|
$result = $this->copy();
|
||||||
|
$result->is_negative = false;
|
||||||
$result->value = array_pad($result->value, $length, 0);
|
$result->value = array_pad($result->value, $length, 0);
|
||||||
$x->value = array_pad($x->value, $length, 0);
|
$x->value = array_pad($x->value, $length, 0);
|
||||||
|
|
||||||
|
@ -2900,7 +2923,7 @@ class BigInteger
|
||||||
// (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0)
|
// (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0)
|
||||||
$temp = $this->toBytes();
|
$temp = $this->toBytes();
|
||||||
if ($temp == '') {
|
if ($temp == '') {
|
||||||
return '';
|
return $this->_normalize(new static());
|
||||||
}
|
}
|
||||||
$pre_msb = decbin(ord($temp[0]));
|
$pre_msb = decbin(ord($temp[0]));
|
||||||
$temp = ~$temp;
|
$temp = ~$temp;
|
||||||
|
@ -3435,7 +3458,7 @@ class BigInteger
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$s = 26 * $i + $j - 1;
|
$s = 26 * $i + $j;
|
||||||
$r->_rshift($s);
|
$r->_rshift($s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3561,6 +3584,7 @@ class BigInteger
|
||||||
$value = &$result->value;
|
$value = &$result->value;
|
||||||
|
|
||||||
if (!count($value)) {
|
if (!count($value)) {
|
||||||
|
$result->is_negative = false;
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,11 @@ class SCP
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (empty($remote_file)) {
|
||||||
|
user_error('remote_file cannot be blank', E_USER_NOTICE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!$this->ssh->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to
|
if (!$this->ssh->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,11 +109,11 @@ class SFTP extends SSH2
|
||||||
* The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support
|
* The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support
|
||||||
* concurrent actions, so it's somewhat academic, here.
|
* concurrent actions, so it's somewhat academic, here.
|
||||||
*
|
*
|
||||||
* @var int
|
* @var boolean
|
||||||
* @see self::_send_sftp_packet()
|
* @see self::_send_sftp_packet()
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $request_id = false;
|
var $use_request_id = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Packet Type
|
* The Packet Type
|
||||||
|
@ -158,7 +158,7 @@ class SFTP extends SSH2
|
||||||
* Current working directory
|
* Current working directory
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
* @see self::_realpath()
|
* @see self::realpath()
|
||||||
* @see self::chdir()
|
* @see self::chdir()
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
|
@ -187,7 +187,7 @@ class SFTP extends SSH2
|
||||||
*
|
*
|
||||||
* @see self::getSFTPErrors()
|
* @see self::getSFTPErrors()
|
||||||
* @see self::getLastSFTPError()
|
* @see self::getLastSFTPError()
|
||||||
* @var string
|
* @var array
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $sftp_errors = array();
|
var $sftp_errors = array();
|
||||||
|
@ -236,6 +236,29 @@ class SFTP extends SSH2
|
||||||
*/
|
*/
|
||||||
var $sortOptions = array();
|
var $sortOptions = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Canonicalization Flag
|
||||||
|
*
|
||||||
|
* Determines whether or not paths should be canonicalized before being
|
||||||
|
* passed on to the remote server.
|
||||||
|
*
|
||||||
|
* @see self::enablePathCanonicalization()
|
||||||
|
* @see self::disablePathCanonicalization()
|
||||||
|
* @see self::realpath()
|
||||||
|
* @var bool
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $canonicalize_paths = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request Buffers
|
||||||
|
*
|
||||||
|
* @see self::_get_sftp_packet()
|
||||||
|
* @var array
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $requestBuffer = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Constructor.
|
* Default Constructor.
|
||||||
*
|
*
|
||||||
|
@ -335,7 +358,7 @@ class SFTP extends SSH2
|
||||||
// yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in
|
// yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in
|
||||||
// two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000.
|
// two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000.
|
||||||
// that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored.
|
// that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored.
|
||||||
-1 << 31 => 'NET_SFTP_ATTR_EXTENDED'
|
(-1 << 31) & 0xFFFFFFFF => 'NET_SFTP_ATTR_EXTENDED'
|
||||||
);
|
);
|
||||||
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3
|
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3
|
||||||
// the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name
|
// the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name
|
||||||
|
@ -409,7 +432,7 @@ class SFTP extends SSH2
|
||||||
|
|
||||||
$this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN;
|
$this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN;
|
||||||
|
|
||||||
$response = $this->_get_channel_packet(self::CHANNEL);
|
$response = $this->_get_channel_packet(self::CHANNEL, true);
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -430,7 +453,7 @@ class SFTP extends SSH2
|
||||||
|
|
||||||
$this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
|
$this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
|
||||||
|
|
||||||
$response = $this->_get_channel_packet(self::CHANNEL);
|
$response = $this->_get_channel_packet(self::CHANNEL, true);
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
// from PuTTY's psftp.exe
|
// from PuTTY's psftp.exe
|
||||||
$command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" .
|
$command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" .
|
||||||
|
@ -454,7 +477,7 @@ class SFTP extends SSH2
|
||||||
|
|
||||||
$this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
|
$this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
|
||||||
|
|
||||||
$response = $this->_get_channel_packet(self::CHANNEL);
|
$response = $this->_get_channel_packet(self::CHANNEL, true);
|
||||||
if ($response === false) {
|
if ($response === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -505,7 +528,7 @@ class SFTP extends SSH2
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$this->request_id = 1;
|
$this->use_request_id = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A Note on SFTPv4/5/6 support:
|
A Note on SFTPv4/5/6 support:
|
||||||
|
@ -575,6 +598,26 @@ class SFTP extends SSH2
|
||||||
$this->stat_cache = array();
|
$this->stat_cache = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable path canonicalization
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function enablePathCanonicalization()
|
||||||
|
{
|
||||||
|
$this->canonicalize_paths = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable path canonicalization
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function disablePathCanonicalization()
|
||||||
|
{
|
||||||
|
$this->canonicalize_paths = false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current directory name
|
* Returns the current directory name
|
||||||
*
|
*
|
||||||
|
@ -633,13 +676,20 @@ class SFTP extends SSH2
|
||||||
* SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it. Returns
|
* SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it. Returns
|
||||||
* the absolute (canonicalized) path.
|
* the absolute (canonicalized) path.
|
||||||
*
|
*
|
||||||
|
* If canonicalize_paths has been disabled using disablePathCanonicalization(), $path is returned as-is.
|
||||||
|
*
|
||||||
* @see self::chdir()
|
* @see self::chdir()
|
||||||
|
* @see self::disablePathCanonicalization()
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _realpath($path)
|
function _realpath($path)
|
||||||
{
|
{
|
||||||
|
if (!$this->canonicalize_paths) {
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->pwd === false) {
|
if ($this->pwd === false) {
|
||||||
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9
|
// http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9
|
||||||
if (!$this->_send_sftp_packet(NET_SFTP_REALPATH, pack('Na*', strlen($path), $path))) {
|
if (!$this->_send_sftp_packet(NET_SFTP_REALPATH, pack('Na*', strlen($path), $path))) {
|
||||||
|
@ -792,6 +842,7 @@ class SFTP extends SSH2
|
||||||
}
|
}
|
||||||
if (is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $value)))) {
|
if (is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $value)))) {
|
||||||
$temp = $this->_nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/');
|
$temp = $this->_nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/');
|
||||||
|
$temp = is_array($temp) ? $temp : array();
|
||||||
$result = array_merge($result, $temp);
|
$result = array_merge($result, $temp);
|
||||||
} else {
|
} else {
|
||||||
$result[] = $relativeDir . $value;
|
$result[] = $relativeDir . $value;
|
||||||
|
@ -823,7 +874,17 @@ class SFTP extends SSH2
|
||||||
unset($files[$key]);
|
unset($files[$key]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($key != '.' && $key != '..' && is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $key)))) {
|
$is_directory = false;
|
||||||
|
if ($key != '.' && $key != '..') {
|
||||||
|
if ($this->use_stat_cache) {
|
||||||
|
$is_directory = is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $key)));
|
||||||
|
} else {
|
||||||
|
$stat = $this->lstat($dir . '/' . $key);
|
||||||
|
$is_directory = $stat && $stat['type'] === NET_SFTP_TYPE_DIRECTORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($is_directory) {
|
||||||
$depth++;
|
$depth++;
|
||||||
$files[$key] = $this->rawlist($dir . '/' . $key, true);
|
$files[$key] = $this->rawlist($dir . '/' . $key, true);
|
||||||
$depth--;
|
$depth--;
|
||||||
|
@ -1106,7 +1167,7 @@ class SFTP extends SSH2
|
||||||
$temp[$dir] = array();
|
$temp[$dir] = array();
|
||||||
}
|
}
|
||||||
if ($i === $max) {
|
if ($i === $max) {
|
||||||
if (is_object($temp[$dir])) {
|
if (is_object($temp[$dir]) && is_object($value)) {
|
||||||
if (!isset($value->stat) && isset($temp[$dir]->stat)) {
|
if (!isset($value->stat) && isset($temp[$dir]->stat)) {
|
||||||
$value->stat = $temp[$dir]->stat;
|
$value->stat = $temp[$dir]->stat;
|
||||||
}
|
}
|
||||||
|
@ -1294,7 +1355,7 @@ class SFTP extends SSH2
|
||||||
/**
|
/**
|
||||||
* Returns general information about a file or symbolic link
|
* Returns general information about a file or symbolic link
|
||||||
*
|
*
|
||||||
* Determines information without calling \phpseclib\Net\SFTP::_realpath().
|
* Determines information without calling \phpseclib\Net\SFTP::realpath().
|
||||||
* The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT.
|
* The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT.
|
||||||
*
|
*
|
||||||
* @param string $filename
|
* @param string $filename
|
||||||
|
@ -1455,7 +1516,7 @@ class SFTP extends SSH2
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$filename = $this->_realPath($filename);
|
$filename = $this->realpath($filename);
|
||||||
// rather than return what the permissions *should* be, we'll return what they actually are. this will also
|
// rather than return what the permissions *should* be, we'll return what they actually are. this will also
|
||||||
// tell us if the file actually exists.
|
// tell us if the file actually exists.
|
||||||
// incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
|
// incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
|
||||||
|
@ -1938,7 +1999,7 @@ class SFTP extends SSH2
|
||||||
|
|
||||||
if (isset($fp)) {
|
if (isset($fp)) {
|
||||||
$stat = fstat($fp);
|
$stat = fstat($fp);
|
||||||
$size = $stat['size'];
|
$size = !empty($stat) ? $stat['size'] : 0;
|
||||||
|
|
||||||
if ($local_start >= 0) {
|
if ($local_start >= 0) {
|
||||||
fseek($fp, $local_start);
|
fseek($fp, $local_start);
|
||||||
|
@ -2087,10 +2148,11 @@ class SFTP extends SSH2
|
||||||
* @param string $local_file
|
* @param string $local_file
|
||||||
* @param int $offset
|
* @param int $offset
|
||||||
* @param int $length
|
* @param int $length
|
||||||
|
* @param callable|null $progressCallback
|
||||||
* @return mixed
|
* @return mixed
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function get($remote_file, $local_file = false, $offset = 0, $length = -1)
|
function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null)
|
||||||
{
|
{
|
||||||
if (!($this->bitmap & SSH2::MASK_LOGIN)) {
|
if (!($this->bitmap & SSH2::MASK_LOGIN)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -2148,7 +2210,7 @@ class SFTP extends SSH2
|
||||||
$packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
|
$packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
|
||||||
|
|
||||||
$packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size);
|
$packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size);
|
||||||
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
|
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet, $i)) {
|
||||||
if ($fclose_check) {
|
if ($fclose_check) {
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
}
|
}
|
||||||
|
@ -2156,6 +2218,9 @@ class SFTP extends SSH2
|
||||||
}
|
}
|
||||||
$packet = null;
|
$packet = null;
|
||||||
$read+= $packet_size;
|
$read+= $packet_size;
|
||||||
|
if (is_callable($progressCallback)) {
|
||||||
|
call_user_func($progressCallback, $read);
|
||||||
|
}
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2163,15 +2228,17 @@ class SFTP extends SSH2
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$packets_sent = $i - 1;
|
||||||
|
|
||||||
$clear_responses = false;
|
$clear_responses = false;
|
||||||
while ($i > 0) {
|
while ($i > 0) {
|
||||||
$i--;
|
$i--;
|
||||||
|
|
||||||
if ($clear_responses) {
|
if ($clear_responses) {
|
||||||
$this->_get_sftp_packet();
|
$this->_get_sftp_packet($packets_sent - $i);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
$response = $this->_get_sftp_packet();
|
$response = $this->_get_sftp_packet($packets_sent - $i);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($this->packet_type) {
|
switch ($this->packet_type) {
|
||||||
|
@ -2880,10 +2947,10 @@ class SFTP extends SSH2
|
||||||
* @return bool
|
* @return bool
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _send_sftp_packet($type, $data)
|
function _send_sftp_packet($type, $data, $request_id = 1)
|
||||||
{
|
{
|
||||||
$packet = $this->request_id !== false ?
|
$packet = $this->use_request_id ?
|
||||||
pack('NCNa*', strlen($data) + 5, $type, $this->request_id, $data) :
|
pack('NCNa*', strlen($data) + 5, $type, $request_id, $data) :
|
||||||
pack('NCa*', strlen($data) + 1, $type, $data);
|
pack('NCa*', strlen($data) + 1, $type, $data);
|
||||||
|
|
||||||
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
||||||
|
@ -2921,15 +2988,24 @@ class SFTP extends SSH2
|
||||||
* @return string
|
* @return string
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
function _get_sftp_packet()
|
function _get_sftp_packet($request_id = null)
|
||||||
{
|
{
|
||||||
$this->curTimeout = false;
|
if (isset($request_id) && isset($this->requestBuffer[$request_id])) {
|
||||||
|
$this->packet_type = $this->requestBuffer[$request_id]['packet_type'];
|
||||||
|
$temp = $this->requestBuffer[$request_id]['packet'];
|
||||||
|
unset($this->requestBuffer[$request_id]);
|
||||||
|
return $temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// in SSH2.php the timeout is cumulative per function call. eg. exec() will
|
||||||
|
// timeout after 10s. but for SFTP.php it's cumulative per packet
|
||||||
|
$this->curTimeout = $this->timeout;
|
||||||
|
|
||||||
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
$start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
|
||||||
|
|
||||||
// SFTP packet length
|
// SFTP packet length
|
||||||
while (strlen($this->packet_buffer) < 4) {
|
while (strlen($this->packet_buffer) < 4) {
|
||||||
$temp = $this->_get_channel_packet(self::CHANNEL);
|
$temp = $this->_get_channel_packet(self::CHANNEL, true);
|
||||||
if (is_bool($temp)) {
|
if (is_bool($temp)) {
|
||||||
$this->packet_type = false;
|
$this->packet_type = false;
|
||||||
$this->packet_buffer = '';
|
$this->packet_buffer = '';
|
||||||
|
@ -2944,9 +3020,16 @@ class SFTP extends SSH2
|
||||||
$tempLength = $length;
|
$tempLength = $length;
|
||||||
$tempLength-= strlen($this->packet_buffer);
|
$tempLength-= strlen($this->packet_buffer);
|
||||||
|
|
||||||
|
|
||||||
|
// 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h
|
||||||
|
if ($tempLength > 256 * 1024) {
|
||||||
|
user_error('Invalid SFTP packet size');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// SFTP packet type and data payload
|
// SFTP packet type and data payload
|
||||||
while ($tempLength > 0) {
|
while ($tempLength > 0) {
|
||||||
$temp = $this->_get_channel_packet(self::CHANNEL);
|
$temp = $this->_get_channel_packet(self::CHANNEL, true);
|
||||||
if (is_bool($temp)) {
|
if (is_bool($temp)) {
|
||||||
$this->packet_type = false;
|
$this->packet_type = false;
|
||||||
$this->packet_buffer = '';
|
$this->packet_buffer = '';
|
||||||
|
@ -2960,8 +3043,8 @@ class SFTP extends SSH2
|
||||||
|
|
||||||
$this->packet_type = ord($this->_string_shift($this->packet_buffer));
|
$this->packet_type = ord($this->_string_shift($this->packet_buffer));
|
||||||
|
|
||||||
if ($this->request_id !== false) {
|
if ($this->use_request_id) {
|
||||||
$this->_string_shift($this->packet_buffer, 4); // remove the request id
|
extract(unpack('Npacket_id', $this->_string_shift($this->packet_buffer, 4))); // remove the request id
|
||||||
$length-= 5; // account for the request id and the packet type
|
$length-= 5; // account for the request id and the packet type
|
||||||
} else {
|
} else {
|
||||||
$length-= 1; // account for the packet type
|
$length-= 1; // account for the packet type
|
||||||
|
@ -2984,6 +3067,14 @@ class SFTP extends SSH2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($request_id) && $this->use_request_id && $packet_id != $request_id) {
|
||||||
|
$this->requestBuffer[$packet_id] = array(
|
||||||
|
'packet_type' => $this->packet_type,
|
||||||
|
'packet' => $packet
|
||||||
|
);
|
||||||
|
return $this->_get_sftp_packet($request_id);
|
||||||
|
}
|
||||||
|
|
||||||
return $packet;
|
return $packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3014,7 +3105,7 @@ class SFTP extends SSH2
|
||||||
/**
|
/**
|
||||||
* Returns all errors
|
* Returns all errors
|
||||||
*
|
*
|
||||||
* @return string
|
* @return array
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function getSFTPErrors()
|
function getSFTPErrors()
|
||||||
|
|
|
@ -179,7 +179,7 @@ class Stream
|
||||||
|
|
||||||
if ($host[0] == '$') {
|
if ($host[0] == '$') {
|
||||||
$host = substr($host, 1);
|
$host = substr($host, 1);
|
||||||
global $$host;
|
global ${$host};
|
||||||
if (($$host instanceof SFTP) === false) {
|
if (($$host instanceof SFTP) === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -916,7 +916,7 @@ class SSH1
|
||||||
/**
|
/**
|
||||||
* Returns the output of an interactive shell when there's a match for $expect
|
* Returns the output of an interactive shell when there's a match for $expect
|
||||||
*
|
*
|
||||||
* $expect can take the form of a string literal or, if $mode == self::READ__REGEX,
|
* $expect can take the form of a string literal or, if $mode == self::READ_REGEX,
|
||||||
* a regular expression.
|
* a regular expression.
|
||||||
*
|
*
|
||||||
* @see self::write()
|
* @see self::write()
|
||||||
|
@ -925,7 +925,7 @@ class SSH1
|
||||||
* @return bool
|
* @return bool
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function read($expect, $mode = self::READ__SIMPLE)
|
function read($expect, $mode = self::READ_SIMPLE)
|
||||||
{
|
{
|
||||||
if (!($this->bitmap & self::MASK_LOGIN)) {
|
if (!($this->bitmap & self::MASK_LOGIN)) {
|
||||||
user_error('Operation disallowed prior to login()');
|
user_error('Operation disallowed prior to login()');
|
||||||
|
@ -939,7 +939,7 @@ class SSH1
|
||||||
|
|
||||||
$match = $expect;
|
$match = $expect;
|
||||||
while (true) {
|
while (true) {
|
||||||
if ($mode == self::READ__REGEX) {
|
if ($mode == self::READ_REGEX) {
|
||||||
preg_match($expect, $this->interactiveBuffer, $matches);
|
preg_match($expect, $this->interactiveBuffer, $matches);
|
||||||
$match = isset($matches[0]) ? $matches[0] : '';
|
$match = isset($matches[0]) ? $matches[0] : '';
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -43,7 +43,7 @@ use phpseclib\System\SSH\Agent\Identity;
|
||||||
*
|
*
|
||||||
* @package SSH\Agent
|
* @package SSH\Agent
|
||||||
* @author Jim Wigginton <terrafrost@php.net>
|
* @author Jim Wigginton <terrafrost@php.net>
|
||||||
* @access internal
|
* @access public
|
||||||
*/
|
*/
|
||||||
class Agent
|
class Agent
|
||||||
{
|
{
|
||||||
|
@ -117,18 +117,20 @@ class Agent
|
||||||
* @return \phpseclib\System\SSH\Agent
|
* @return \phpseclib\System\SSH\Agent
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function __construct()
|
function __construct($address = null)
|
||||||
{
|
{
|
||||||
switch (true) {
|
if (!$address) {
|
||||||
case isset($_SERVER['SSH_AUTH_SOCK']):
|
switch (true) {
|
||||||
$address = $_SERVER['SSH_AUTH_SOCK'];
|
case isset($_SERVER['SSH_AUTH_SOCK']):
|
||||||
break;
|
$address = $_SERVER['SSH_AUTH_SOCK'];
|
||||||
case isset($_ENV['SSH_AUTH_SOCK']):
|
break;
|
||||||
$address = $_ENV['SSH_AUTH_SOCK'];
|
case isset($_ENV['SSH_AUTH_SOCK']):
|
||||||
break;
|
$address = $_ENV['SSH_AUTH_SOCK'];
|
||||||
default:
|
break;
|
||||||
user_error('SSH_AUTH_SOCK not found');
|
default:
|
||||||
return false;
|
user_error('SSH_AUTH_SOCK not found');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
|
$this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
|
||||||
|
@ -155,12 +157,14 @@ class Agent
|
||||||
$packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES);
|
$packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES);
|
||||||
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
||||||
user_error('Connection closed while requesting identities');
|
user_error('Connection closed while requesting identities');
|
||||||
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$length = current(unpack('N', fread($this->fsock, 4)));
|
$length = current(unpack('N', fread($this->fsock, 4)));
|
||||||
$type = ord(fread($this->fsock, 1));
|
$type = ord(fread($this->fsock, 1));
|
||||||
if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) {
|
if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) {
|
||||||
user_error('Unable to request identities');
|
user_error('Unable to request identities');
|
||||||
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$identities = array();
|
$identities = array();
|
||||||
|
|
|
@ -32,6 +32,17 @@ use phpseclib\System\SSH\Agent;
|
||||||
*/
|
*/
|
||||||
class Identity
|
class Identity
|
||||||
{
|
{
|
||||||
|
/**@+
|
||||||
|
* Signature Flags
|
||||||
|
*
|
||||||
|
* See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
const SSH_AGENT_RSA2_256 = 2;
|
||||||
|
const SSH_AGENT_RSA2_512 = 4;
|
||||||
|
/**#@-*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key Object
|
* Key Object
|
||||||
*
|
*
|
||||||
|
@ -59,6 +70,16 @@ class Identity
|
||||||
*/
|
*/
|
||||||
var $fsock;
|
var $fsock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signature flags
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
* @access private
|
||||||
|
* @see self::sign()
|
||||||
|
* @see self::setHash()
|
||||||
|
*/
|
||||||
|
var $flags = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Constructor.
|
* Default Constructor.
|
||||||
*
|
*
|
||||||
|
@ -126,6 +147,31 @@ class Identity
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Hash
|
||||||
|
*
|
||||||
|
* ssh-agent doesn't support using hashes for RSA other than SHA1
|
||||||
|
*
|
||||||
|
* @param string $hash
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function setHash($hash)
|
||||||
|
{
|
||||||
|
$this->flags = 0;
|
||||||
|
switch ($hash) {
|
||||||
|
case 'sha1':
|
||||||
|
break;
|
||||||
|
case 'sha256':
|
||||||
|
$this->flags = self::SSH_AGENT_RSA2_256;
|
||||||
|
break;
|
||||||
|
case 'sha512':
|
||||||
|
$this->flags = self::SSH_AGENT_RSA2_512;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
user_error('The only supported hashes for RSA are sha1, sha256 and sha512');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a signature
|
* Create a signature
|
||||||
*
|
*
|
||||||
|
@ -138,7 +184,7 @@ class Identity
|
||||||
function sign($message)
|
function sign($message)
|
||||||
{
|
{
|
||||||
// the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
|
// 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('CNa*Na*N', Agent::SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, $this->flags);
|
||||||
$packet = pack('Na*', strlen($packet), $packet);
|
$packet = pack('Na*', strlen($packet), $packet);
|
||||||
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
if (strlen($packet) != fputs($this->fsock, $packet)) {
|
||||||
user_error('Connection closed during signing');
|
user_error('Connection closed during signing');
|
||||||
|
@ -151,8 +197,34 @@ class Identity
|
||||||
}
|
}
|
||||||
|
|
||||||
$signature_blob = fread($this->fsock, $length - 1);
|
$signature_blob = fread($this->fsock, $length - 1);
|
||||||
// the only other signature format defined - ssh-dss - is the same length as ssh-rsa
|
$length = current(unpack('N', $this->_string_shift($signature_blob, 4)));
|
||||||
// the + 12 is for the other various SSH added length fields
|
if ($length != strlen($signature_blob)) {
|
||||||
return substr($signature_blob, strlen('ssh-rsa') + 12);
|
user_error('Malformed signature blob');
|
||||||
|
}
|
||||||
|
$length = current(unpack('N', $this->_string_shift($signature_blob, 4)));
|
||||||
|
if ($length > strlen($signature_blob) + 4) {
|
||||||
|
user_error('Malformed signature blob');
|
||||||
|
}
|
||||||
|
$type = $this->_string_shift($signature_blob, $length);
|
||||||
|
$this->_string_shift($signature_blob, 4);
|
||||||
|
|
||||||
|
return $signature_blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String Shift
|
||||||
|
*
|
||||||
|
* Inspired by array_shift
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
* @param int $index
|
||||||
|
* @return string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _string_shift(&$string, $index = 1)
|
||||||
|
{
|
||||||
|
$substr = substr($string, 0, $index);
|
||||||
|
$string = substr($string, $index);
|
||||||
|
return $substr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,21 +281,20 @@ class imapAccess extends baseModule {
|
||||||
* @return array HTML meta data
|
* @return array HTML meta data
|
||||||
*/
|
*/
|
||||||
function display_html_password() {
|
function display_html_password() {
|
||||||
$return = new htmlTable();
|
$return = new htmlResponsiveRow();
|
||||||
if($this->moduleSettings['ImapAccess_ImapAdminPasswordSelect'][0] == "lam_user_pass"){
|
if($this->moduleSettings['ImapAccess_ImapAdminPasswordSelect'][0] == "lam_user_pass"){
|
||||||
$message = $this->messages['managemailbox'][6];
|
$message = $this->messages['managemailbox'][6];
|
||||||
$messageElement = new htmlStatusMessage($message[0], $message[1]);
|
$messageElement = new htmlStatusMessage($message[0], $message[1]);
|
||||||
$messageElement->colspan = 3;
|
$return->add($messageElement, 12);
|
||||||
$return->addElement($messageElement);
|
$return->addVerticalSpacer('1rem');
|
||||||
$return->addElement(new htmlSpacer(null, '10px'), true);
|
|
||||||
}
|
}
|
||||||
$passwordInput = new htmlTableExtendedInputField(_("Password of IMAP admin user"), 'ImapAdminPassword', '', 'ImapAdminPassword_Sess');
|
$passwordInput = new htmlResponsiveInputField(_("Password of IMAP admin user"), 'ImapAdminPassword', '', 'ImapAdminPassword_Sess');
|
||||||
$passwordInput->setIsPassword(true);
|
$passwordInput->setIsPassword(true);
|
||||||
$passwordInput->setRequired(true);
|
$passwordInput->setRequired(true);
|
||||||
$passwordInput->setOnKeyPress('SubmitForm(\'enterPasswordButton\', event);');
|
$passwordInput->setOnKeyPress('SubmitForm(\'enterPasswordButton\', event);');
|
||||||
$return->addElement($passwordInput, true);
|
$return->add($passwordInput, 12);
|
||||||
$return->addElement(new htmlSpacer(null, '10px'), true);
|
$return->addVerticalSpacer('2rem');
|
||||||
$return->addElement(new htmlButton('enterPasswordButton', _('Ok')));
|
$return->add(new htmlButton('enterPasswordButton', _('Ok')), 12, 12, 12, 'text-center');
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue