Enigma: Fix redundant list-secret-keys/list-public-keys calls on signing/encryption

pull/5268/merge
Aleksander Machniak 8 years ago
parent f2eafda539
commit ac1cd3719c

@ -2,6 +2,7 @@ CHANGELOG Roundcube Webmail
===========================
- Update TinyMCE to version 4.3.13 (#5309)
- Enigma: Fix redundant list-secret-keys/list-public-keys calls on signing/encryption
- Enigma: Implement PGP encryption and signing in one go (#5302)
- Enigma: Display signature verification status for encrypted+signed messages (#5302)
- Display different attachment icon on encrypted messages

@ -34,20 +34,19 @@ abstract class enigma_driver
/**
* Encryption (and optional signing).
*
* @param string Message body
* @param array List of key-password mapping
* @param string Optional signing Key ID
* @param string Optional signing Key password
* @param string Message body
* @param array List of keys (enigma_key objects)
* @param enigma_key Optional signing Key ID
*
* @return mixed Encrypted message or enigma_error on failure
*/
abstract function encrypt($text, $keys, $sign_key = null, $sign_pass = null);
abstract function encrypt($text, $keys, $sign_key = null);
/**
* Decryption (and sig verification if sig exists).
*
* @param string Encrypted message
* @param array List of key-password mapping
* @param array List of key-password
* @param enigma_signature Signature information (if available)
*
* @return mixed Decrypted message or enigma_error on failure
@ -57,14 +56,13 @@ abstract class enigma_driver
/**
* Signing.
*
* @param string Message body
* @param string Key ID
* @param string Key password
* @param int Signing mode (enigma_engine::SIGN_*)
* @param string Message body
* @param enigma_key The signing key
* @param int Signing mode (enigma_engine::SIGN_*)
*
* @return mixed True on success or enigma_error on failure
*/
abstract function sign($text, $key, $passwd, $mode = null);
abstract function sign($text, $key, $mode = null);
/**
* Signature verification.

@ -97,22 +97,21 @@ class enigma_driver_gnupg extends enigma_driver
/**
* Encryption (and optional signing).
*
* @param string Message body
* @param array List of key-password mapping
* @param string Optional signing Key ID
* @param string Optional signing Key password
* @param string Message body
* @param array List of keys (enigma_key objects)
* @param enigma_key Optional signing Key ID
*
* @return mixed Encrypted message or enigma_error on failure
*/
function encrypt($text, $keys, $sign_key = null, $sign_pass = null)
function encrypt($text, $keys, $sign_key = null)
{
try {
foreach ($keys as $key) {
$this->gpg->addEncryptKey($key);
$this->gpg->addEncryptKey($key->reference);
}
if ($sign_key) {
$this->gpg->addSignKey($sign_key, $sign_pass);
$this->gpg->addSignKey($sign_key->reference, $sign_key->password);
return $this->gpg->encryptAndSign($text, true);
}
@ -155,17 +154,16 @@ class enigma_driver_gnupg extends enigma_driver
/**
* Signing.
*
* @param string Message body
* @param string Key ID
* @param string Key password
* @param int Signing mode (enigma_engine::SIGN_*)
* @param string Message body
* @param enigma_key The key
* @param int Signing mode (enigma_engine::SIGN_*)
*
* @return mixed True on success or enigma_error on failure
*/
function sign($text, $key, $passwd, $mode = null)
function sign($text, $key, $mode = null)
{
try {
$this->gpg->addSignKey($key, $passwd);
$this->gpg->addSignKey($key->reference, $key->password);
return $this->gpg->sign($text, $mode, CRYPT_GPG::ARMOR_ASCII, true);
}
catch (Exception $e) {
@ -450,6 +448,9 @@ class enigma_driver_gnupg extends enigma_driver
$ekey->name = trim($ekey->users[0]->name . ' <' . $ekey->users[0]->email . '>');
// keep reference to Crypt_GPG's key for performance reasons
$ekey->reference = $key;
foreach ($key->getSubKeys() as $idx => $subkey) {
$skey = new enigma_subkey();
$skey->id = $subkey->getId();

@ -67,7 +67,7 @@ class enigma_driver_phpssl extends enigma_driver
}
function encrypt($text, $keys, $sign_key = null, $sign_pass = null)
function encrypt($text, $keys, $sign_key = null)
{
}
@ -75,7 +75,7 @@ class enigma_driver_phpssl extends enigma_driver
{
}
function sign($text, $key, $passwd, $mode = null)
function sign($text, $key, $mode = null)
{
}

@ -208,7 +208,7 @@ class enigma_engine
}
// sign the body
$result = $this->pgp_sign($body, $key->id, $pass, $pgp_mode);
$result = $this->pgp_sign($body, $key, $pgp_mode);
if ($result !== true) {
if ($result->getCode() == enigma_error::BADPASS) {
@ -264,6 +264,8 @@ class enigma_engine
$error = array('missing' => array($sign_key->id => $sign_key->name));
return new enigma_error(enigma_error::BADPASS, '', $error);
}
$sign_key->password = $sign_pass;
}
$recipients = array($from);
@ -281,7 +283,12 @@ class enigma_engine
// find recipient public keys
foreach ((array) $recipients as $email) {
$key = $this->find_key($email);
if ($email == $from && $sign_key) {
$key = $sign_key;
}
else {
$key = $this->find_key($email);
}
if (empty($key)) {
return new enigma_error(enigma_error::KEYNOTFOUND, '', array(
@ -289,7 +296,7 @@ class enigma_engine
));
}
$keys[] = $key->id;
$keys[] = $key;
}
// select mode
@ -315,7 +322,7 @@ class enigma_engine
}
// sign the body
$result = $this->pgp_encrypt($body, $keys, $sign_key ? $sign_key->id : null, $sign_pass);
$result = $this->pgp_encrypt($body, $keys, $sign_key);
if ($result !== true) {
if ($result->getCode() == enigma_error::BADPASS) {
@ -854,7 +861,7 @@ class enigma_engine
*
* @return mixed enigma_signature or enigma_error
*/
private function pgp_verify(&$msg_body, $sig_body=null)
private function pgp_verify(&$msg_body, $sig_body = null)
{
// @TODO: Handle big bodies using (temp) files
$sig = $this->pgp_driver->verify($msg_body, $sig_body);
@ -902,17 +909,16 @@ class enigma_engine
/**
* PGP message signing
*
* @param mixed Message body
* @param string Key ID
* @param string Key passphrase
* @param int Signing mode
* @param mixed Message body
* @param enigma_key The key (with passphrase)
* @param int Signing mode
*
* @return mixed True or enigma_error
*/
private function pgp_sign(&$msg_body, $keyid, $password, $mode = null)
private function pgp_sign(&$msg_body, $key, $mode = null)
{
// @TODO: Handle big bodies using (temp) files
$result = $this->pgp_driver->sign($msg_body, $keyid, $password, $mode);
$result = $this->pgp_driver->sign($msg_body, $key, $mode);
if ($result instanceof enigma_error) {
$err_code = $result->getCode();
@ -934,7 +940,7 @@ class enigma_engine
* PGP message encrypting
*
* @param mixed Message body
* @param array Keys
* @param array Keys (array of enigma_key objects)
* @param string Optional signing Key ID
* @param string Optional signing Key password
*
@ -1012,7 +1018,7 @@ class enigma_engine
// check key validity and type
foreach ($result as $key) {
if ($keyid = $key->find_subkey($email, $mode)) {
if ($subkey = $key->find_subkey($email, $mode)) {
return $key;
}
}

@ -21,6 +21,8 @@ class enigma_key
public $name;
public $users = array();
public $subkeys = array();
public $reference;
public $password;
const TYPE_UNKNOWN = 0;
const TYPE_KEYPAIR = 1;

@ -27,6 +27,7 @@ class enigma_subkey
public $length;
public $usage;
/**
* Converts internal ID to short ID
* Crypt_GPG uses internal, but e.g. Thunderbird's Enigmail displays short ID

Loading…
Cancel
Save