Skip to content

Commit

Permalink
Made exact compression algorithm conifgurable
Browse files Browse the repository at this point in the history
  • Loading branch information
slusarz committed Apr 21, 2015
1 parent 7983c26 commit 9cd9273
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 100 deletions.
85 changes: 56 additions & 29 deletions framework/Pgp/lib/Horde/Pgp.php
Expand Up @@ -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
Expand All @@ -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.")
);
Expand All @@ -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
Expand All @@ -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.")
);
Expand All @@ -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.
Expand All @@ -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.")
);
Expand Down Expand Up @@ -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);
}


}
6 changes: 3 additions & 3 deletions framework/Pgp/lib/Horde/Pgp/Backend.php
Expand Up @@ -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.
*/
Expand All @@ -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.
*/
Expand All @@ -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.
Expand Down
56 changes: 23 additions & 33 deletions framework/Pgp/lib/Horde/Pgp/Backend/Openpgp.php
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}

/**
Expand All @@ -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);

Expand Down Expand Up @@ -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;
}
Expand All @@ -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))
);
Expand Down Expand Up @@ -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));
}

Expand Down Expand Up @@ -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'])
);
}
}

Expand Down
9 changes: 4 additions & 5 deletions framework/Pgp/lib/Horde/Pgp/Mime.php
Expand Up @@ -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
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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.
*
Expand All @@ -240,7 +239,7 @@ public function signAndEncryptPart(
$base = $this->_encryptPart(
$signed->message,
array_merge($opts, array(
'nocompress' => true
'compress' => 'NONE'
))
);
$base->setDescription(
Expand Down

0 comments on commit 9cd9273

Please sign in to comment.