From: Michael M Slusarz Date: Thu, 11 Dec 2008 22:13:33 +0000 (-0700) Subject: Initial Horde 4 import of Horde_Secret. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=92ee419f0d497f4f137dceb950466a62706ff99a;p=horde.git Initial Horde 4 import of Horde_Secret. --- diff --git a/framework/Secret/lib/Horde/Secret.php b/framework/Secret/lib/Horde/Secret.php new file mode 100644 index 000000000..ebcb6740e --- /dev/null +++ b/framework/Secret/lib/Horde/Secret.php @@ -0,0 +1,203 @@ + + * @package Horde_Secret + */ +class Horde_Secret +{ + /** + * Cipher cache. + * + * @var array + */ + static protected $_cipherCache = array(); + + /** + * Key cache. + * + * @var array + */ + static protected $_keyCache = array(); + + /** + * Take a small piece of data and encrypt it with a key. + * + * @param string $key The key to use for encryption. + * @param string $message The plaintext message. + * + * @return string The ciphertext message. + */ + static public function write($key, $message) + { + if (!strlen($key)) { + return false; + } + + $ret = Secret::_getMcryptData($key, $message, 'encrypt'); + if ($ret !== false) { + return $ret; + } + + $ptr = Secret::_getCipherOb($key); + return $ptr->encrypt($message); + } + + /** + * Decrypt a message encrypted with Secret::write(). + * + * @param string $key The key to use for decryption. + * @param string $message The ciphertext message. + * + * @return string The plaintext message. + */ + static public function read($key, $ciphertext) + { + $ret = Secret::_getMcryptData($key, $ciphertext, 'decrypt'); + if ($ret !== false) { + return rtrim($ret, "\0"); + } + + $ptr = Secret::_getCipherOb($key); + return $ptr->decrypt($ciphertext); + } + + /** + * TODO + */ + static protected function _getMcryptData($key, $text, $type) + { + $ret = false; + + require_once 'Horde/Util.php'; + if (Util::extensionExists('mcrypt')) { + $old_error = error_reporting(0); + $td = mcrypt_module_open(MCRYPT_GOST, '', MCRYPT_MODE_ECB, ''); + if ($td) { + $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND); + mcrypt_generic_init($td, $key, $iv); + $ret = ($type == 'encrypt') ? mcrypt_generic($td, $text) : mdecrypt_generic($td, $text); + mcrypt_generic_deinit($td); + } + error_reporting($old_error); + } + + return $ret; + } + + /** + * TODO + */ + static protected function _getCipherOb($key) + { + $idx = md5($key); + + if (!isset(self::$_cipherCache[$idx])) { + self::$_cipherCache[$idx] = &Horde_Cipher::factory('blowfish'); + self::$_cipherCache[$idx]->setBlockMode('ofb64'); + self::$_cipherCache[$idx]->setKey($key); + } + + return self::$_cipherCache[$idx]; + } + + /** + * Generate a secret key (for encryption), either using a random + * md5 string and storing it in a cookie if the user has cookies + * enabled, or munging some known values if they don't. + * + * @param string $keyname The name of the key to set. + * + * @return string The secret key that has been generated. + */ + static public function setKey($keyname = 'generic') + { + if (isset($_COOKIE[$GLOBALS['conf']['session']['name']])) { + if (isset($_COOKIE[$keyname . '_key'])) { + $key = $_COOKIE[$keyname . '_key']; + } else { + $key = md5(mt_rand()); + $_COOKIE[$keyname . '_key'] = $key; + Secret::_setCookie($keyname, $key); + } + } else { + $key = session_id(); + Secret::_setCookie($keyname, $key); + } + + return $key; + } + + /** + * Return a secret key, either from a cookie, or if the cookie + * isn't there, assume we are using a munged version of a known + * base value. + * + * @param string $keyname The name of the key to get. + * + * @return string The secret key. + */ + static public function getKey($keyname = 'generic') + { + if (!isset(self::$_keyCache[$keyname])) { + if (isset($_COOKIE[$keyname . '_key'])) { + self::$_keyCache[$keyname] = $_COOKIE[$keyname . '_key']; + } else { + self::$_keyCache[$keyname] = session_id(); + Secret::_setCookie($keyname, self::$_keyCache[$keyname]); + } + } + + return self::$_keyCache[$keyname]; + } + + /** + * TODO + */ + static protected function _setCookie($keyname, $key) + { + global $conf; + + $old_error = error_reporting(0); + setcookie( + $keyname . '_key', + $key, + $conf['session']['timeout'] ? time() + $conf['session']['timeout'] : 0, + $conf['cookie']['path'], + $conf['cookie']['domain'], + $conf['use_ssl'] == 1 ? 1 : 0 + ); + error_reporting($old_error); + } + + /** + * Clears a secret key entry from the current cookie. + * + * @param string $keyname The name of the key to clear. + * + * @return boolean True if key existed, false if not. + */ + static public function clearKey($keyname = 'generic') + { + if (isset($_COOKIE[$GLOBALS['conf']['session']['name']]) && + isset($_COOKIE[$keyname . '_key'])) { + unset($_COOKIE[$keyname . '_key']); + return true; + } + return false; + } + +} + +// TODO - Remove once apps are transitioned to Horde 4 +class Secret extends Horde_Secret {} diff --git a/framework/Secret/package.xml b/framework/Secret/package.xml new file mode 100644 index 000000000..04fe3ef61 --- /dev/null +++ b/framework/Secret/package.xml @@ -0,0 +1,97 @@ + + + Horde_Secret + pear.horde.org + Secret Encryption API + The Horde_Secret:: class provides an API for encrypting and decrypting small pieces of data with the use of a shared key. + + + Chuck Hagenbuch + chuck + chuck@horde.org + yes + + 2008-12-11 + + 0.0.3 + 0.0.2 + + + alpha + alpha + + LGPL + * Initial Horde 4 package. + + + + + + + + + + + + + 5.2.0 + + + 1.5.0 + + + Horde_Cipher + pear.horde.org + + + Util + pear.horde.org + + + + + mcrypt + + + + + + + + + + + 2006-05-08 + + + 0.0.2 + 0.0.2 + + + alpha + alpha + + LGPL + - Converted to package.xml 2.0 for pear.horde.org +- Return false instead of generating encryption errors if $key is empty (Bug #5925). + + + + + 0.0.1 + 0.0.1 + + + alpha + alpha + + 2003-07-05 + LGPL + Initial release as a PEAR package + + + +