From 9028e772904da6dcf3122cee72868008d8d1bd57 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Mon, 6 Mar 2017 10:57:20 +0100 Subject: [PATCH] Enigma: Set micalg parameter to real hash algorithm used for signing --- plugins/enigma/lib/enigma_driver.php | 8 ++++++ plugins/enigma/lib/enigma_driver_gnupg.php | 28 ++++++++++++++++++-- plugins/enigma/lib/enigma_driver_phpssl.php | 10 +++++++ plugins/enigma/lib/enigma_engine.php | 2 +- plugins/enigma/lib/enigma_mime_message.php | 17 +++++++++--- program/lib/Roundcube/rcube_imap_generic.php | 3 +-- 6 files changed, 60 insertions(+), 8 deletions(-) diff --git a/plugins/enigma/lib/enigma_driver.php b/plugins/enigma/lib/enigma_driver.php index fa03c2274..bab3e9fc1 100644 --- a/plugins/enigma/lib/enigma_driver.php +++ b/plugins/enigma/lib/enigma_driver.php @@ -131,4 +131,12 @@ abstract class enigma_driver * @return mixed True on success or enigma_error */ abstract function delete_key($keyid); + + /** + * Returns a name of the hash algorithm used for the last + * signing operation. + * + * @return string Hash algorithm name e.g. sha1 + */ + abstract function signature_algorithm(); } diff --git a/plugins/enigma/lib/enigma_driver_gnupg.php b/plugins/enigma/lib/enigma_driver_gnupg.php index 8632fd43a..0c72137ec 100644 --- a/plugins/enigma/lib/enigma_driver_gnupg.php +++ b/plugins/enigma/lib/enigma_driver_gnupg.php @@ -23,6 +23,7 @@ class enigma_driver_gnupg extends enigma_driver protected $gpg; protected $homedir; protected $user; + protected $last_sig_algorithm; function __construct($user) @@ -120,7 +121,13 @@ class enigma_driver_gnupg extends enigma_driver if ($sign_key) { $this->gpg->addSignKey($sign_key->reference, $sign_key->password); - return $this->gpg->encryptAndSign($text, true); + + $res = $this->gpg->encryptAndSign($text, true); + $sigInfo = $this->gpg->getLastSignatureInfo(); + + $this->last_sig_algorithm = $sigInfo->getHashAlgorithmName(); + + return $res; } return $this->gpg->encrypt($text, true); @@ -172,7 +179,13 @@ class enigma_driver_gnupg extends enigma_driver { try { $this->gpg->addSignKey($key->reference, $key->password); - return $this->gpg->sign($text, $mode, CRYPT_GPG::ARMOR_ASCII, true); + + $res = $this->gpg->sign($text, $mode, CRYPT_GPG::ARMOR_ASCII, true); + $sigInfo = $this->gpg->getLastSignatureInfo(); + + $this->last_sig_algorithm = $sigInfo->getHashAlgorithmName(); + + return $res; } catch (Exception $e) { return $this->get_error_from_exception($e); @@ -365,6 +378,17 @@ class enigma_driver_gnupg extends enigma_driver return $result; } + /** + * Returns a name of the hash algorithm used for the last + * signing operation. + * + * @return string Hash algorithm name e.g. sha1 + */ + public function signature_algorithm() + { + return $this->last_sig_algorithm; + } + /** * Private key deletion. */ diff --git a/plugins/enigma/lib/enigma_driver_phpssl.php b/plugins/enigma/lib/enigma_driver_phpssl.php index a2b16fa93..e4056c8c0 100644 --- a/plugins/enigma/lib/enigma_driver_phpssl.php +++ b/plugins/enigma/lib/enigma_driver_phpssl.php @@ -146,6 +146,16 @@ class enigma_driver_phpssl extends enigma_driver { } + /** + * Returns a name of the hash algorithm used for the last + * signing operation. + * + * @return string Hash algorithm name e.g. sha1 + */ + public function signature_algorithm() + { + } + /** * Converts Crypt_GPG_Key object into Enigma's key object * diff --git a/plugins/enigma/lib/enigma_engine.php b/plugins/enigma/lib/enigma_engine.php index 49ec7bd1a..68908450f 100644 --- a/plugins/enigma/lib/enigma_engine.php +++ b/plugins/enigma/lib/enigma_engine.php @@ -216,7 +216,7 @@ class enigma_engine $message->setParam('text_charset', $text_charset); } else { - $mime->addPGPSignature($body); + $mime->addPGPSignature($body, $this->pgp_driver->signature_algorithm()); $message = $mime; } } diff --git a/plugins/enigma/lib/enigma_mime_message.php b/plugins/enigma/lib/enigma_mime_message.php index 734377f75..a81f3cfc6 100644 --- a/plugins/enigma/lib/enigma_mime_message.php +++ b/plugins/enigma/lib/enigma_mime_message.php @@ -25,6 +25,7 @@ class enigma_mime_message extends Mail_mime protected $body; protected $signature; protected $encrypted; + protected $micalg; /** @@ -119,10 +120,12 @@ class enigma_mime_message extends Mail_mime * Register signature attachment * * @param string Signature body + * @param string Hash algorithm name */ - public function addPGPSignature($body) + public function addPGPSignature($body, $algorithm = null) { $this->signature = $body; + $this->micalg = $algorithm; // Reset Content-Type to be overwritten with valid boundary unset($this->headers['Content-Type']); @@ -168,10 +171,14 @@ class enigma_mime_message extends Mail_mime if ($this->type == self::PGP_SIGNED) { $params = array( 'preamble' => "This is an OpenPGP/MIME signed message (RFC 4880 and 3156)", - 'content_type' => "multipart/signed; micalg=pgp-sha1; protocol=\"application/pgp-signature\"", + 'content_type' => "multipart/signed; protocol=\"application/pgp-signature\"", 'eol' => $this->build_params['eol'], ); + if ($this->micalg) { + $params['content_type'] .= "; micalg=pgp-" . $this->micalg; + } + $message = new Mail_mimePart('', $params); if (!empty($this->body)) { @@ -279,9 +286,13 @@ class enigma_mime_message extends Mail_mime $this->build_params['boundary'] = $boundary; if ($this->type == self::PGP_SIGNED) { - $headers['Content-Type'] = "multipart/signed; micalg=pgp-sha1;$eol" + $headers['Content-Type'] = "multipart/signed;$eol" ." protocol=\"application/pgp-signature\";$eol" ." boundary=\"$boundary\""; + + if ($this->micalg) { + $headers['Content-Type'] .= ";{$eol} micalg=pgp-" . $this->micalg; + } } else if ($this->type == self::PGP_ENCRYPTED) { $headers['Content-Type'] = "multipart/encrypted;$eol" diff --git a/program/lib/Roundcube/rcube_imap_generic.php b/program/lib/Roundcube/rcube_imap_generic.php index db9d743b1..d7245c2bb 100644 --- a/program/lib/Roundcube/rcube_imap_generic.php +++ b/program/lib/Roundcube/rcube_imap_generic.php @@ -114,8 +114,7 @@ class rcube_imap_generic $res = fwrite($this->fp, $string); if ($res === false) { - @fclose($this->fp); - $this->fp = null; + $this->closeSocket(); } return $res;