PageRenderTime 24ms CodeModel.GetById 40ms RepoModel.GetById 0ms app.codeStats 0ms

/framework/Secret/Secret.php

https://github.com/wrobel/horde-fw3
PHP | 196 lines | 106 code | 22 blank | 68 comment | 16 complexity | f8a22a08cda7d23c727e91584c2e5a33 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, LGPL-2.1, BSD-2-Clause
  1. <?php
  2. /**
  3. * The Secret:: class provides an API for encrypting and decrypting
  4. * small pieces of data with the use of a shared key.
  5. *
  6. * The Secret:: functions use the Horde Cipher:: class if mcrypt is not
  7. * available.
  8. *
  9. * $Horde: framework/Secret/Secret.php,v 1.45.10.14 2009-01-06 15:23:34 jan Exp $
  10. *
  11. * Copyright 1999-2009 The Horde Project (http://www.horde.org/)
  12. *
  13. * See the enclosed file COPYING for license information (LGPL). If you
  14. * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  15. *
  16. * @author Chuck Hagenbuch <chuck@horde.org>
  17. * @since Horde 1.3
  18. * @package Horde_Secret
  19. */
  20. class Secret {
  21. /**
  22. * Take a small piece of data and encrypt it with a key.
  23. *
  24. * @param string $key The key to use for encryption.
  25. * @param string $message The plaintext message.
  26. *
  27. * @return string The ciphertext message.
  28. */
  29. function write($key, $message)
  30. {
  31. if (!strlen($key)) {
  32. return false;
  33. }
  34. $ret = Secret::_getMcryptData($key, $message, 'encrypt');
  35. if ($ret !== false) {
  36. return $ret;
  37. }
  38. $ptr = Secret::_getCipherOb($key);
  39. return $ptr->encrypt($message);
  40. }
  41. /**
  42. * Decrypt a message encrypted with Secret::write().
  43. *
  44. * @param string $key The key to use for decryption.
  45. * @param string $message The ciphertext message.
  46. *
  47. * @return string The plaintext message.
  48. */
  49. function read($key, $ciphertext)
  50. {
  51. $ret = Secret::_getMcryptData($key, $ciphertext, 'decrypt');
  52. if ($ret !== false) {
  53. return rtrim($ret, "\0");
  54. }
  55. $ptr = Secret::_getCipherOb($key);
  56. return $ptr->decrypt($ciphertext);
  57. }
  58. /**
  59. * @access private
  60. */
  61. function _getMcryptData($key, $text, $type)
  62. {
  63. $ret = false;
  64. require_once 'Horde/Util.php';
  65. if (Util::extensionExists('mcrypt')) {
  66. $old_error = error_reporting(0);
  67. $td = mcrypt_module_open(MCRYPT_GOST, '', MCRYPT_MODE_ECB, '');
  68. if ($td) {
  69. $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
  70. mcrypt_generic_init($td, $key, $iv);
  71. $ret = ($type == 'encrypt') ? mcrypt_generic($td, $text) : mdecrypt_generic($td, $text);
  72. mcrypt_generic_deinit($td);
  73. }
  74. error_reporting($old_error);
  75. }
  76. return $ret;
  77. }
  78. /**
  79. * @access private
  80. */
  81. function _getCipherOb($key)
  82. {
  83. static $cache = array();
  84. $cacheIdx = md5($key);
  85. if (!isset($cache[$cacheIdx])) {
  86. require_once 'Horde/Cipher.php';
  87. $cache[$cacheIdx] = &Horde_Cipher::factory('blowfish');
  88. $cache[$cacheIdx]->setBlockMode('ofb64');
  89. $cache[$cacheIdx]->setKey($key);
  90. }
  91. return $cache[$cacheIdx];
  92. }
  93. /**
  94. * Generate a secret key (for encryption), either using a random
  95. * md5 string and storing it in a cookie if the user has cookies
  96. * enabled, or munging some known values if they don't.
  97. *
  98. * @param string $keyname The name of the key to set.
  99. *
  100. * @return string The secret key that has been generated.
  101. */
  102. function setKey($keyname = 'generic')
  103. {
  104. global $conf;
  105. if (isset($_COOKIE[$conf['session']['name']])) {
  106. if (isset($_COOKIE[$keyname . '_key'])) {
  107. $key = $_COOKIE[$keyname . '_key'];
  108. } else {
  109. $key = md5(mt_rand());
  110. $_COOKIE[$keyname . '_key'] = $key;
  111. Secret::_setCookie($keyname, $key);
  112. }
  113. } else {
  114. $key = session_id();
  115. Secret::_setCookie($keyname, $key);
  116. }
  117. return $key;
  118. }
  119. /**
  120. * Return a secret key, either from a cookie, or if the cookie
  121. * isn't there, assume we are using a munged version of a known
  122. * base value.
  123. *
  124. * @param string $keyname The name of the key to get.
  125. *
  126. * @return string The secret key.
  127. */
  128. function getKey($keyname = 'generic')
  129. {
  130. static $keycache = array();
  131. if (!isset($keycache[$keyname])) {
  132. if (isset($_COOKIE[$keyname . '_key'])) {
  133. $keycache[$keyname] = $_COOKIE[$keyname . '_key'];
  134. } else {
  135. $keycache[$keyname] = session_id();
  136. Secret::_setCookie($keyname, $keycache[$keyname]);
  137. }
  138. }
  139. return $keycache[$keyname];
  140. }
  141. /**
  142. * @access private
  143. */
  144. function _setCookie($keyname, $key)
  145. {
  146. global $conf;
  147. $old_error = error_reporting(0);
  148. setcookie(
  149. $keyname . '_key',
  150. $key,
  151. $conf['session']['timeout'] ? time() + $conf['session']['timeout'] : 0,
  152. $conf['cookie']['path'],
  153. $conf['cookie']['domain'],
  154. $conf['use_ssl'] == 1 ? 1 : 0
  155. );
  156. error_reporting($old_error);
  157. }
  158. /**
  159. * Clears a secret key entry from the current cookie.
  160. *
  161. * @param string $keyname The name of the key to clear.
  162. *
  163. * @return boolean True if key existed, false if not.
  164. */
  165. function clearKey($keyname = 'generic')
  166. {
  167. if (isset($_COOKIE[$GLOBALS['conf']['session']['name']]) &&
  168. isset($_COOKIE[$keyname . '_key'])) {
  169. unset($_COOKIE[$keyname . '_key']);
  170. return true;
  171. }
  172. return false;
  173. }
  174. }