Skip to content

Commit

Permalink
Enigma: Fix key selection for signing
Browse files Browse the repository at this point in the history
In some cases a public key of other user could be selected instead
of the sender's private key
  • Loading branch information
alecpl committed Apr 4, 2018
1 parent 77d447f commit ad628a9
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ CHANGELOG Roundcube Webmail
- Fix parsing date strings (e.g. from a Date: mail header) with comments (#6216)
- Fix PHP 7.2: count(): Parameter must be an array in enchant-based spellchecker (#6234)
- Fix possible IMAP command injection and type juggling vulnerabilities (#6229)
- Enigma: Fix key selection for signing

RELEASE 1.3.5
-------------
Expand Down
23 changes: 20 additions & 3 deletions plugins/enigma/lib/enigma_engine.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class enigma_engine
private $pgp_driver;
private $smime_driver;
private $password_time;
private $cache = array();

public $decryptions = array();
public $signatures = array();
Expand Down Expand Up @@ -348,7 +349,7 @@ function attach_public_key(&$message)
$from = $from[1];

// find my key
if ($from && ($key = $this->find_key($from))) {
if ($from && ($key = $this->find_key($from, true))) {
$pubkey_armor = $this->export_key($key->id);

if (!$pubkey_armor instanceof enigma_error) {
Expand Down Expand Up @@ -979,6 +980,10 @@ function list_keys($pattern = '')
*/
function find_key($email, $can_sign = false)
{
if ($can_sign && array_key_exists($email, $this->cache)) {
return $this->cache[$email];
}

$this->load_pgp_driver();
$result = $this->pgp_driver->list_keys($email);

Expand All @@ -988,13 +993,25 @@ function find_key($email, $can_sign = false)
}

$mode = $can_sign ? enigma_key::CAN_SIGN : enigma_key::CAN_ENCRYPT;
$ret = null;

// check key validity and type
foreach ($result as $key) {
if ($subkey = $key->find_subkey($email, $mode)) {
return $key;
if (($subkey = $key->find_subkey($email, $mode))
&& (!$can_sign || $key->get_type() == enigma_key::TYPE_KEYPAIR)
) {
$ret = $key;
break;
}
}

// cache private key info for better performance
// we can skip one list_keys() call when signing and attaching a key
if ($can_sign) {
$this->cache[$email] = $ret;
}

return $ret;
}

/**
Expand Down

0 comments on commit ad628a9

Please sign in to comment.