Skip to content

Commit

Permalink
non-block size strings weren't correctly handled in streams
Browse files Browse the repository at this point in the history
  • Loading branch information
terrafrost committed Jul 10, 2018
1 parent 9646c46 commit 2ea74ed
Showing 1 changed file with 57 additions and 5 deletions.
62 changes: 57 additions & 5 deletions lib/mcrypt.php
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,23 @@ class phpseclib_mcrypt_filter extends php_user_filter
* @var int
* @access private
*/
private $block_length = '';
private $block_length;

/**
* Cipher block mode
*
* @var bool
* @access private
*/
private $block_mode;

/**
* Buffer handle
*
* @var resource
* @access private
*/
private $bh;

/**
* Called when applying the filter
Expand All @@ -1090,15 +1106,17 @@ class phpseclib_mcrypt_filter extends php_user_filter
public function filter($in, $out, &$consumed, $closing)
{
$newlen = 0;
$block_mode = phpseclib_mcrypt_module_is_block_mode($this->cipher->mcrypt_mode);
while ($bucket = stream_bucket_make_writeable($in)) {
if ($block_mode) {
if ($this->block_mode) {
$bucket->data = $this->buffer . $bucket->data;
$extra = strlen($bucket->data) % $this->block_length;
if ($extra) {
$this->buffer = substr($bucket->data, -$extra);
$bucket->data = substr($bucket->data, 0, -$extra);
}
if (!strlen($bucket->data)) {
continue;
}
}

$bucket->data = $this->op ?
Expand All @@ -1110,7 +1128,19 @@ public function filter($in, $out, &$consumed, $closing)
stream_bucket_append($out, $bucket);
}

return $block_mode && $newlen < $this->block_length ? PSFS_FEED_ME : PSFS_PASS_ON;
if ($closing && strlen($this->buffer)) {
$temp = $this->buffer . str_repeat("\0", $this->block_length - strlen($this->buffer));
$data = $this->op ?
$this->cipher->encrypt($temp) :
$this->cipher->decrypt($temp);
$newlen+= strlen($data);
$bucket = stream_bucket_new($this->bh, $data);
$this->buffer = '';
$newlen = 0;
stream_bucket_append($out, $bucket);
}

return $this->block_mode && $newlen && $newlen < $this->block_length ? PSFS_FEED_ME : PSFS_PASS_ON;
}

/**
Expand Down Expand Up @@ -1168,9 +1198,31 @@ public function onCreate()
$this->op = $parts[0] == 'mcrypt';
$this->cipher = $cipher;
$this->block_length = phpseclib_mcrypt_enc_get_iv_size($cipher);
$this->block_mode = phpseclib_mcrypt_module_is_block_mode($mode);

if ($this->block_mode) {
$this->bh = fopen('php://memory', 'w+');
}

return true;
}

/**
* Called when closing the filter
*
* This method is called upon filter shutdown (typically, this is also during stream shutdown), and is
* executed after the flush method is called. If any resources were allocated or initialized during
* onCreate() this would be the time to destroy or dispose of them.
*
* @link http://php.net/manual/en/php-user-filter.onclose.php
* @access public
*/
public function onClose()
{
if ($this->bh) {
fclose($this->bh);
}
}
}

stream_filter_register('phpseclib.mcrypt.*', 'phpseclib_mcrypt_filter');
Expand Down Expand Up @@ -1338,4 +1390,4 @@ function mcrypt_decrypt($cipher, $key, $data, $mode, $iv = null)
stream_filter_register('mcrypt.*', 'phpseclib_mcrypt_filter');
stream_filter_register('mdecrypt.*', 'phpseclib_mcrypt_filter');
//}
}
}

0 comments on commit 2ea74ed

Please sign in to comment.