diff --git a/framework/Pgp/lib/Horde/Pgp.php b/framework/Pgp/lib/Horde/Pgp.php index 4fad84e73af..922d88da189 100644 --- a/framework/Pgp/lib/Horde/Pgp.php +++ b/framework/Pgp/lib/Horde/Pgp.php @@ -94,7 +94,8 @@ public function generateKey($name, $email, array $opts = array()) * @param array $opts Additional options: * - cipher: (string) Default symmetric cipher algorithm to use. One of: * 3DES, CAST5, AES128, AES192, AES256, Twofish. - * - nocompress: (boolean) If true, don't compress encrypted data. + * - compress: (string) Default compression to use. One of: + * NONE, ZIP, ZLIB * * @return Horde_Pgp_Element_Message The encrypted data. * @throws Horde_Pgp_Exception @@ -109,9 +110,11 @@ public function encrypt($text, $keys, array $opts = array()) array('Horde_Pgp_Element_PublicKey', 'create'), is_array($keys) ? $keys : array($keys) ), - array_merge(array( - 'nocompress' => false - ), $this->_getCipher($opts, 'AES128')) + array_merge( + $opts, + $this->_getCompression($opts, 'ZIP'), + $this->_getCipher($opts, 'AES128') + ) ), Horde_Pgp_Translation::t("Could not PGP encrypt data.") ); @@ -125,7 +128,8 @@ public function encrypt($text, $keys, array $opts = array()) * @param array $opts Additional options: * - cipher: (string) Default symmetric cipher algorithm to use. One of: * 3DES, CAST5, AES128, AES192, AES256, Twofish. - * - nocompress: (boolean) If true, don't compress encrypted data. + * - compress: (string) Default compression to use. One of: + * NONE, ZIP, ZLIB * * @return Horde_Pgp_Element_Message The encrypted data. * @throws Horde_Pgp_Exception @@ -141,9 +145,11 @@ public function encryptSymmetric($text, $passphrase, array $opts = array()) array( $text, is_array($passphrase) ? $passphrase : array($passphrase), - array_merge(array( - 'nocompress' => false - ), $this->_getCipher($opts, '3DES')) + array_merge( + $opts, + $this->_getCompression($opts, 'ZIP'), + $this->_getCipher($opts, '3DES') + ) ), Horde_Pgp_Translation::t("Could not PGP encrypt data.") ); @@ -159,7 +165,8 @@ public function encryptSymmetric($text, $passphrase, array $opts = array()) * @param mixed $key The private key to use for signing (must be * decrypted). * @param array $opts Additional options: - * - nocompress: (boolean) If true, don't compress signed data. + * - compress: (string) Default compression to use. One of: + * NONE, ZIP, ZLIB * - sign_hash: (string) The hash method to use. * * @return Horde_Pgp_Element_Message The signed data. @@ -173,10 +180,11 @@ public function sign($text, $key, array $opts = array()) $text, $this->_getPrivateKey($key), 'message', - array_merge(array( - 'nocompress' => false, - 'sign_hash' => null - ), $opts) + array_merge( + array('sign_hash' => null), + $opts, + $this->_getCompression($opts, 'ZIP') + ) ), Horde_Pgp_Translation::t("Could not PGP sign data.") ); @@ -400,26 +408,45 @@ protected function _getPrivateKey($key) */ protected function _getCipher($opts, $default) { - $cipher = isset($opts['cipher']) - ? $opts['cipher'] + /* RFC 4880 [9.2] */ + return $this->_getOption($opts, $default, 'cipher', array( + '3DES' => 2, + 'CAST5' => 3, + 'AES128' => 7, + 'AES192' => 8, + 'AES256' => 9, + 'Twofish' => 10 + )); + } + + /** + * TODO + */ + protected function _getCompression($opts, $default) + { + /* RFC 4880 [9.3] */ + return $this->_getOption($opts, $default, 'compress', array( + 'NONE' => 0, + 'ZIP' => 1, + 'ZLIB' => 2 + )); + } + + /** + * TODO + */ + protected function _getOption($opts, $default, $name, $map) + { + $val = isset($opts[$name]) + ? $opts[$name] : $default; - if (is_string($cipher)) { - /* RFC 4880 [9.2] */ - $cipher_map = array( - '3DES' => 2, - 'CAST5' => 3, - 'AES128' => 7, - 'AES192' => 8, - 'AES256' => 9, - 'Twofish' => 10 - ); - $cipher = $cipher_map[$cipher]; + if (is_string($val)) { + $val = $map[$val]; } - $opts['cipher'] = $cipher; - - return $opts; + return array($name => $val); } + } diff --git a/framework/Pgp/lib/Horde/Pgp/Backend.php b/framework/Pgp/lib/Horde/Pgp/Backend.php index 76d17e05f36..a3d9fb383a7 100644 --- a/framework/Pgp/lib/Horde/Pgp/Backend.php +++ b/framework/Pgp/lib/Horde/Pgp/Backend.php @@ -64,7 +64,7 @@ public function generateKey($opts) * (Horde_Pgp_Element_PublicKey objects). * @param array $opts Additional options: * - cipher: (integer) Symmetric cipher algorithm. - * - nocompress: (boolean) If true, don't compress encrypted data. + * - compress: (boolean) Compression algorithm. * * @return Horde_Pgp_Element_Message The encrypted message. */ @@ -80,7 +80,7 @@ public function encrypt($text, $keys, $opts) * @param array $passphrase The symmetric passphrase(s). * @param array $opts Additional options: * - cipher: (integer) Symmetric cipher algorithm. - * - nocompress: (boolean) If true, don't compress encrypted data. + * - compress: (boolean) Compression algorithm. * * @return Horde_Pgp_Element_Message The encrypted message. */ @@ -99,7 +99,7 @@ public function encryptSymmetric($text, $passphrase, $opts) * 'clear', 'detach', or * 'message'. * @param array $opts Additional options: - * - nocompress: (boolean) If true, don't compress signed data. + * - compress: (boolean) Compression algorithm. * - sign_hash: (string) The hash method to use. * * @return mixed The signed message. diff --git a/framework/Pgp/lib/Horde/Pgp/Backend/Openpgp.php b/framework/Pgp/lib/Horde/Pgp/Backend/Openpgp.php index 44a6b585e23..864566d12c6 100644 --- a/framework/Pgp/lib/Horde/Pgp/Backend/Openpgp.php +++ b/framework/Pgp/lib/Horde/Pgp/Backend/Openpgp.php @@ -234,7 +234,6 @@ protected function _encryptPrivateKey($p, $cipher, $s2k, $iv) */ public function encrypt($text, $keys, $opts) { - $cipher_algo = null; $p = array(); foreach ($keys as $val) { @@ -274,29 +273,19 @@ public function encrypt($text, $keys, $opts) /* Use 3DES with ElGamal; 3DES is a MUST implement, so assume that * someone requiring ElGamal encryption will more likely have * support for 3DES than AES. */ - if (!$cipher_algo && ($current->algorithm === 16)) { - $cipher_algo = 2; + if ($current->algorithm === 16) { + $opts['cipher'] = 2; } } - return $this->_encrypt( - $p, - $text, - empty($opts['nocompress']), - is_null($cipher_algo) ? $opts['cipher'] : $cipher_algo - ); + return $this->_encrypt($p, $text, $opts); } /** */ public function encryptSymmetric($text, $passphrase, $opts) { - return $this->_encrypt( - $passphrase, - $text, - empty($opts['nocompress']), - $opts['cipher'] - ); + return $this->_encrypt($passphrase, $text, $opts); } /** @@ -305,22 +294,23 @@ public function encryptSymmetric($text, $passphrase, $opts) * @param mixed $key The list of public keys used to encrypt or a * list of passphrases. * @param mixed $data The data to be PGP encrypted. - * @param boolean $compress If true, compress data. - * @param interer $c_algo The cipher algorithm to use. + * @param array $opts Additional options: + * - cipher: (integer) Cipher algorithm. + * - compress: (integer) Compression algorithm. * * @param Horde_Pgp_Element_Message Encrypted message. */ - protected function _encrypt($key, $data, $compress, $c_algo) + protected function _encrypt($key, $data, $opts) { - $msg = $this->_getMessageOb($data); - if ($compress) { - $msg = $this->_compressMessageOb($msg); - } + $msg = $this->_compressMessageOb( + $this->_getMessageOb($data), + $opts['compress'] + ); /* Following code adapted from OpenPGP_Crypt_Symmetric::encrypt(). */ list($cipher, $key_bytes, $block_bytes) = - OpenPGP_Crypt_Symmetric::getCipher($c_algo); + OpenPGP_Crypt_Symmetric::getCipher($opts['cipher']); $prefix = crypt_random_string($block_bytes); $prefix .= substr($prefix, -2); @@ -351,8 +341,8 @@ protected function _encrypt($key, $data, $compress, $c_algo) $encrypted[] = new OpenPGP_SymmetricSessionKeyPacket( $s2k, - $cipher->encrypt(chr($c_algo) . $ckey), - $c_algo + $cipher->encrypt(chr($opts['cipher']) . $ckey), + $opts['cipher'] ); continue; } @@ -373,7 +363,7 @@ protected function _encrypt($key, $data, $compress, $c_algo) } $pk_encrypt = $pk->encrypt( - chr($c_algo) . + chr($opts['cipher']) . $ckey . pack('n', OpenPGP_Crypt_Symmetric::checksum($ckey)) ); @@ -422,14 +412,15 @@ protected function _getMessageOb($data) * Compress PGP data, if compression is available. * * @param OpenPGP_Message $msg PGP message. + * @param integer $algo Compression algorithm. * * @return OpenPGP_Message (Possibly compressed) message. */ - protected function _compressMessageOb($msg) + protected function _compressMessageOb($msg, $algo) { - if (Horde_Util::extensionExists('zlib')) { + if ($algo && Horde_Util::extensionExists('zlib')) { $zip = new OpenPGP_CompressedDataPacket($msg); - $zip->algorithm = 1; // ZIP (DEFLATE) Compression + $zip->algorithm = $algo; $msg = new OpenPGP_Message(array($zip)); } @@ -496,10 +487,9 @@ public function sign($text, $key, $mode, $opts = array()) break; case 'message': - if (empty($opts['nocompress'])) { - $result = $this->_compressMessageOb($result); - } - return new Horde_Pgp_Element_Message($result); + return new Horde_Pgp_Element_Message( + $this->_compressMessageOb($result, $opts['compress']) + ); } } diff --git a/framework/Pgp/lib/Horde/Pgp/Mime.php b/framework/Pgp/lib/Horde/Pgp/Mime.php index c345e1637e4..6cbfc2fe3f4 100644 --- a/framework/Pgp/lib/Horde/Pgp/Mime.php +++ b/framework/Pgp/lib/Horde/Pgp/Mime.php @@ -33,7 +33,7 @@ class Horde_Pgp_Mime * @param mixed $key The private key to use for signing (must * be decrypted). * @param array $opts Additional options: - * - nocompress: (boolean) If true, don't compress signed data. + * - compress: (string) Default compression algorithm. * * @return Horde_Mime_Part A signed object. * @throws Horde_Pgp_Exception @@ -118,7 +118,7 @@ protected function _signPart($part, $detach_sig) * @param Horde_Mime_Part $part The object to encrypt. * @param array $opts Additional options: * - cipher: (string) Default symmetric cipher algorithm to use. - * - nocompress: (boolean) If true, don't compress encrypted data. + * - compress: (string) Default compression algorithm. * - pubkeys: (mixed) The public key(s) to use for encryption. * - symmetric: (string) If set, use as symmetric key. * @@ -214,8 +214,7 @@ protected function _encryptBase($encrypted) * be decrypted). * @param array $opts Additional options: * - cipher: (string) Default symmetric cipher algorithm to use. - * - nocompress: (boolean) If true, don't compress signed/encrypted - * data. + * - compress: (string) Default compression algorithm. * - pubkeys: (mixed) The public key(s) to use for encryption. * - symmetric: (string) If set, use as symmetric key. * @@ -240,7 +239,7 @@ public function signAndEncryptPart( $base = $this->_encryptPart( $signed->message, array_merge($opts, array( - 'nocompress' => true + 'compress' => 'NONE' )) ); $base->setDescription( diff --git a/framework/Pgp/test/Horde/Pgp/Backend/TestBase.php b/framework/Pgp/test/Horde/Pgp/Backend/TestBase.php index 2ea4de4c92a..5416d8669ca 100644 --- a/framework/Pgp/test/Horde/Pgp/Backend/TestBase.php +++ b/framework/Pgp/test/Horde/Pgp/Backend/TestBase.php @@ -249,32 +249,20 @@ public function testEncrypt($pubkey, $privkeys) { $cleartext = $this->_getFixture('clear.txt'); - foreach (array(true, false) as $val) { - $result = $this->_pgp->encrypt( - $cleartext, - $pubkey, - array( - 'nocompress' => $val - ) - ); + $result = $this->_pgp->encrypt($cleartext, $pubkey); - $this->assertInstanceOf( - 'Horde_Pgp_Element_Message', - $result - ); + $this->assertInstanceOf( + 'Horde_Pgp_Element_Message', + $result + ); - $this->assertEquals( - 1 + count($privkeys), - count($result->message->packets) - ); + $this->assertEquals( + 1 + count($privkeys), + count($result->message->packets) + ); - foreach ($privkeys as $val2) { - $this->testDecrypt( - strval($result), - $val2, - $cleartext - ); - } + foreach ($privkeys as $val) { + $this->testDecrypt(strval($result), $val, $cleartext); } } @@ -315,15 +303,18 @@ public function testEncryptSymmetric($data, $pass) $ciphers = array( '3DES', 'CAST5', 'AES128', 'AES192', 'AES256', 'Twofish' ); + $compress = array( + 'NONE', 'ZIP', 'ZLIB' + ); - foreach (array(true, false) as $val) { - foreach ($ciphers as $c) { + foreach ($compress as $c1) { + foreach ($ciphers as $c2) { $result = $this->_pgp->encryptSymmetric( $data, $pass, array( - 'cipher' => $c, - 'nocompress' => $val + 'cipher' => $c2, + 'compress' => $c1 ) ); @@ -378,12 +369,16 @@ public function encryptSymmetricProvider() */ public function testSign($text, $privkey) { - foreach (array(true, false) as $val) { + $compress = array( + 'NONE', 'ZIP', 'ZLIB' + ); + + foreach ($compress as $c) { $result = $this->_pgp->sign( $text, $privkey, array( - 'nocompress' => $val + 'compress' => $c ) ); @@ -393,7 +388,7 @@ public function testSign($text, $privkey) ); $this->assertInstanceOf( - ($val) + ($c === 'NONE') ? 'OpenPGP_SignaturePacket' : 'OpenPGP_CompressedDataPacket', $result->message[0]