]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - Zend/Crypt/Hmac.php
Release 6.5.0
[Github/sugarcrm.git] / Zend / Crypt / Hmac.php
1 <?php
2 /**
3  * Zend Framework
4  *
5  * LICENSE
6  *
7  * This source file is subject to the new BSD license that is bundled
8  * with this package in the file LICENSE.txt.
9  * It is also available through the world-wide-web at this URL:
10  * http://framework.zend.com/license/new-bsd
11  * If you did not receive a copy of the license and are unable to
12  * obtain it through the world-wide-web, please send an email
13  * to license@zend.com so we can send you a copy immediately.
14  *
15  * @category   Zend
16  * @package    Zend_Crypt
17  * @subpackage Hmac
18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
20
21  */
22
23 /**
24  * @see Zend_Crypt
25  */
26 require_once 'Zend/Crypt.php';
27
28 /**
29  * PHP implementation of the RFC 2104 Hash based Message Authentication Code
30  * algorithm.
31  *
32  * @todo  Patch for refactoring failed tests (key block sizes >80 using internal algo)
33  * @todo       Check if mhash() is a required alternative (will be PECL-only soon)
34  * @category   Zend
35  * @package    Zend_Crypt
36  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
37  * @license    http://framework.zend.com/license/new-bsd     New BSD License
38  */
39 class Zend_Crypt_Hmac extends Zend_Crypt
40 {
41
42     /**
43      * The key to use for the hash
44      *
45      * @var string
46      */
47     protected static $_key = null;
48
49     /**
50      * pack() format to be used for current hashing method
51      *
52      * @var string
53      */
54     protected static $_packFormat = null;
55
56     /**
57      * Hashing algorithm; can be the md5/sha1 functions or any algorithm name
58      * listed in the output of PHP 5.1.2+ hash_algos().
59      *
60      * @var string
61      */
62     protected static $_hashAlgorithm = 'md5';
63
64     /**
65      * List of algorithms supported my mhash()
66      *
67      * @var array
68      */
69     protected static $_supportedMhashAlgorithms = array('adler32',' crc32', 'crc32b', 'gost',
70             'haval128', 'haval160', 'haval192', 'haval256', 'md4', 'md5', 'ripemd160',
71             'sha1', 'sha256', 'tiger', 'tiger128', 'tiger160');
72
73     /**
74      * Constants representing the output mode of the hash algorithm
75      */
76     const STRING = 'string';
77     const BINARY = 'binary';
78
79     /**
80      * Performs a HMAC computation given relevant details such as Key, Hashing
81      * algorithm, the data to compute MAC of, and an output format of String,
82      * Binary notation or BTWOC.
83      *
84      * @param string $key
85      * @param string $hash
86      * @param string $data
87      * @param string $output
88      * @param boolean $internal
89      * @return string
90      */
91     public static function compute($key, $hash, $data, $output = self::STRING)
92     {
93         // set the key
94         if (!isset($key) || empty($key)) {
95             require_once 'Zend/Crypt/Hmac/Exception.php';
96             throw new Zend_Crypt_Hmac_Exception('provided key is null or empty');
97         }
98         self::$_key = $key;
99
100         // set the hash
101         self::_setHashAlgorithm($hash);
102
103         // perform hashing and return
104         return self::_hash($data, $output);
105     }
106
107     /**
108      * Setter for the hash method.
109      *
110      * @param string $hash
111      * @return Zend_Crypt_Hmac
112      */
113     protected static function _setHashAlgorithm($hash)
114     {
115         if (!isset($hash) || empty($hash)) {
116             require_once 'Zend/Crypt/Hmac/Exception.php';
117             throw new Zend_Crypt_Hmac_Exception('provided hash string is null or empty');
118         }
119
120         $hash = strtolower($hash);
121         $hashSupported = false;
122
123         if (function_exists('hash_algos') && in_array($hash, hash_algos())) {
124             $hashSupported = true;
125         }
126
127         if ($hashSupported === false && function_exists('mhash') && in_array($hash, self::$_supportedAlgosMhash)) {
128             $hashSupported = true;
129         }
130
131         if ($hashSupported === false) {
132             require_once 'Zend/Crypt/Hmac/Exception.php';
133             throw new Zend_Crypt_Hmac_Exception('hash algorithm provided is not supported on this PHP installation; please enable the hash or mhash extensions');
134         }
135         self::$_hashAlgorithm = $hash;
136     }
137
138     /**
139      * Perform HMAC and return the keyed data
140      *
141      * @param string $data
142      * @param string $output
143      * @param bool $internal Option to not use hash() functions for testing
144      * @return string
145      */
146     protected static function _hash($data, $output = self::STRING, $internal = false)
147     {
148         if (function_exists('hash_hmac')) {
149             if ($output == self::BINARY) {
150                 return hash_hmac(self::$_hashAlgorithm, $data, self::$_key, 1);
151             }
152             return hash_hmac(self::$_hashAlgorithm, $data, self::$_key);
153         }
154
155         if (function_exists('mhash')) {
156             if ($output == self::BINARY) {
157                 return mhash(self::_getMhashDefinition(self::$_hashAlgorithm), $data, self::$_key);
158             }
159             $bin = mhash(self::_getMhashDefinition(self::$_hashAlgorithm), $data, self::$_key);
160             return bin2hex($bin);
161         }
162     }
163
164     /**
165      * Since MHASH accepts an integer constant representing the hash algorithm
166      * we need to make a small detour to get the correct integer matching our
167      * algorithm's name.
168      *
169      * @param string $hashAlgorithm
170      * @return integer
171      */
172     protected static function _getMhashDefinition($hashAlgorithm)
173     {
174         for ($i = 0; $i <= mhash_count(); $i++)
175         {
176             $types[mhash_get_hash_name($i)] = $i;
177         }
178         return $types[strtoupper($hashAlgorithm)];
179     }
180
181 }