|
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 Rsa |
|
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 * @version $Id: Rsa.php 23439 2010-11-23 21:10:14Z alexander $ |
|
21 */ |
|
22 |
|
23 /** |
|
24 * @see Zend_Crypt_Rsa_Key_Private |
|
25 */ |
|
26 require_once 'Zend/Crypt/Rsa/Key/Private.php'; |
|
27 |
|
28 /** |
|
29 * @see Zend_Crypt_Rsa_Key_Public |
|
30 */ |
|
31 require_once 'Zend/Crypt/Rsa/Key/Public.php'; |
|
32 |
|
33 /** |
|
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_Rsa |
|
40 { |
|
41 |
|
42 const BINARY = 'binary'; |
|
43 const BASE64 = 'base64'; |
|
44 |
|
45 protected $_privateKey; |
|
46 |
|
47 protected $_publicKey; |
|
48 |
|
49 /** |
|
50 * @var string |
|
51 */ |
|
52 protected $_pemString; |
|
53 |
|
54 protected $_pemPath; |
|
55 |
|
56 protected $_certificateString; |
|
57 |
|
58 protected $_certificatePath; |
|
59 |
|
60 protected $_hashAlgorithm; |
|
61 |
|
62 protected $_passPhrase; |
|
63 |
|
64 /** |
|
65 * Class constructor |
|
66 * |
|
67 * @param array $options |
|
68 * @throws Zend_Crypt_Rsa_Exception |
|
69 */ |
|
70 public function __construct(array $options = null) |
|
71 { |
|
72 if (!extension_loaded('openssl')) { |
|
73 require_once 'Zend/Crypt/Rsa/Exception.php'; |
|
74 throw new Zend_Crypt_Rsa_Exception('Zend_Crypt_Rsa requires openssl extention to be loaded.'); |
|
75 } |
|
76 |
|
77 // Set _hashAlgorithm property when we are sure, that openssl extension is loaded |
|
78 // and OPENSSL_ALGO_SHA1 constant is available |
|
79 $this->_hashAlgorithm = OPENSSL_ALGO_SHA1; |
|
80 |
|
81 if (isset($options)) { |
|
82 $this->setOptions($options); |
|
83 } |
|
84 } |
|
85 |
|
86 public function setOptions(array $options) |
|
87 { |
|
88 if (isset($options['passPhrase'])) { |
|
89 $this->_passPhrase = $options['passPhrase']; |
|
90 } |
|
91 foreach ($options as $option=>$value) { |
|
92 switch ($option) { |
|
93 case 'pemString': |
|
94 $this->setPemString($value); |
|
95 break; |
|
96 case 'pemPath': |
|
97 $this->setPemPath($value); |
|
98 break; |
|
99 case 'certificateString': |
|
100 $this->setCertificateString($value); |
|
101 break; |
|
102 case 'certificatePath': |
|
103 $this->setCertificatePath($value); |
|
104 break; |
|
105 case 'hashAlgorithm': |
|
106 $this->setHashAlgorithm($value); |
|
107 break; |
|
108 } |
|
109 } |
|
110 } |
|
111 |
|
112 public function getPrivateKey() |
|
113 { |
|
114 return $this->_privateKey; |
|
115 } |
|
116 |
|
117 public function getPublicKey() |
|
118 { |
|
119 return $this->_publicKey; |
|
120 } |
|
121 |
|
122 /** |
|
123 * @param string $data |
|
124 * @param Zend_Crypt_Rsa_Key_Private $privateKey |
|
125 * @param string $format |
|
126 * @return string |
|
127 */ |
|
128 public function sign($data, Zend_Crypt_Rsa_Key_Private $privateKey = null, $format = null) |
|
129 { |
|
130 $signature = ''; |
|
131 if (isset($privateKey)) { |
|
132 $opensslKeyResource = $privateKey->getOpensslKeyResource(); |
|
133 } else { |
|
134 $opensslKeyResource = $this->_privateKey->getOpensslKeyResource(); |
|
135 } |
|
136 $result = openssl_sign( |
|
137 $data, $signature, |
|
138 $opensslKeyResource, |
|
139 $this->getHashAlgorithm() |
|
140 ); |
|
141 if ($format == self::BASE64) { |
|
142 return base64_encode($signature); |
|
143 } |
|
144 return $signature; |
|
145 } |
|
146 |
|
147 /** |
|
148 * @param string $data |
|
149 * @param string $signature |
|
150 * @param string $format |
|
151 * @return string |
|
152 */ |
|
153 public function verifySignature($data, $signature, $format = null) |
|
154 { |
|
155 if ($format == self::BASE64) { |
|
156 $signature = base64_decode($signature); |
|
157 } |
|
158 $result = openssl_verify($data, $signature, |
|
159 $this->getPublicKey()->getOpensslKeyResource(), |
|
160 $this->getHashAlgorithm()); |
|
161 return $result; |
|
162 } |
|
163 |
|
164 /** |
|
165 * @param string $data |
|
166 * @param Zend_Crypt_Rsa_Key $key |
|
167 * @param string $format |
|
168 * @return string |
|
169 */ |
|
170 public function encrypt($data, Zend_Crypt_Rsa_Key $key, $format = null) |
|
171 { |
|
172 $encrypted = ''; |
|
173 $function = 'openssl_public_encrypt'; |
|
174 if ($key instanceof Zend_Crypt_Rsa_Key_Private) { |
|
175 $function = 'openssl_private_encrypt'; |
|
176 } |
|
177 $function($data, $encrypted, $key->getOpensslKeyResource()); |
|
178 if ($format == self::BASE64) { |
|
179 return base64_encode($encrypted); |
|
180 } |
|
181 return $encrypted; |
|
182 } |
|
183 |
|
184 /** |
|
185 * @param string $data |
|
186 * @param Zend_Crypt_Rsa_Key $key |
|
187 * @param string $format |
|
188 * @return string |
|
189 */ |
|
190 public function decrypt($data, Zend_Crypt_Rsa_Key $key, $format = null) |
|
191 { |
|
192 $decrypted = ''; |
|
193 if ($format == self::BASE64) { |
|
194 $data = base64_decode($data); |
|
195 } |
|
196 $function = 'openssl_private_decrypt'; |
|
197 if ($key instanceof Zend_Crypt_Rsa_Key_Public) { |
|
198 $function = 'openssl_public_decrypt'; |
|
199 } |
|
200 $function($data, $decrypted, $key->getOpensslKeyResource()); |
|
201 return $decrypted; |
|
202 } |
|
203 |
|
204 public function generateKeys(array $configargs = null) |
|
205 { |
|
206 $config = null; |
|
207 $passPhrase = null; |
|
208 if ($configargs !== null) { |
|
209 if (isset($configargs['passPhrase'])) { |
|
210 $passPhrase = $configargs['passPhrase']; |
|
211 unset($configargs['passPhrase']); |
|
212 } |
|
213 $config = $this->_parseConfigArgs($configargs); |
|
214 } |
|
215 $privateKey = null; |
|
216 $publicKey = null; |
|
217 $resource = openssl_pkey_new($config); |
|
218 // above fails on PHP 5.3 |
|
219 openssl_pkey_export($resource, $private, $passPhrase); |
|
220 $privateKey = new Zend_Crypt_Rsa_Key_Private($private, $passPhrase); |
|
221 $details = openssl_pkey_get_details($resource); |
|
222 $publicKey = new Zend_Crypt_Rsa_Key_Public($details['key']); |
|
223 $return = new ArrayObject(array( |
|
224 'privateKey'=>$privateKey, |
|
225 'publicKey'=>$publicKey |
|
226 ), ArrayObject::ARRAY_AS_PROPS); |
|
227 return $return; |
|
228 } |
|
229 |
|
230 /** |
|
231 * @param string $value |
|
232 */ |
|
233 public function setPemString($value) |
|
234 { |
|
235 $this->_pemString = $value; |
|
236 try { |
|
237 $this->_privateKey = new Zend_Crypt_Rsa_Key_Private($this->_pemString, $this->_passPhrase); |
|
238 $this->_publicKey = $this->_privateKey->getPublicKey(); |
|
239 } catch (Zend_Crypt_Exception $e) { |
|
240 $this->_privateKey = null; |
|
241 $this->_publicKey = new Zend_Crypt_Rsa_Key_Public($this->_pemString); |
|
242 } |
|
243 } |
|
244 |
|
245 public function setPemPath($value) |
|
246 { |
|
247 $this->_pemPath = $value; |
|
248 $this->setPemString(file_get_contents($this->_pemPath)); |
|
249 } |
|
250 |
|
251 public function setCertificateString($value) |
|
252 { |
|
253 $this->_certificateString = $value; |
|
254 $this->_publicKey = new Zend_Crypt_Rsa_Key_Public($this->_certificateString, $this->_passPhrase); |
|
255 } |
|
256 |
|
257 public function setCertificatePath($value) |
|
258 { |
|
259 $this->_certificatePath = $value; |
|
260 $this->setCertificateString(file_get_contents($this->_certificatePath)); |
|
261 } |
|
262 |
|
263 public function setHashAlgorithm($name) |
|
264 { |
|
265 switch (strtolower($name)) { |
|
266 case 'md2': |
|
267 $this->_hashAlgorithm = OPENSSL_ALGO_MD2; |
|
268 break; |
|
269 case 'md4': |
|
270 $this->_hashAlgorithm = OPENSSL_ALGO_MD4; |
|
271 break; |
|
272 case 'md5': |
|
273 $this->_hashAlgorithm = OPENSSL_ALGO_MD5; |
|
274 break; |
|
275 case 'sha1': |
|
276 $this->_hashAlgorithm = OPENSSL_ALGO_SHA1; |
|
277 break; |
|
278 case 'dss1': |
|
279 $this->_hashAlgorithm = OPENSSL_ALGO_DSS1; |
|
280 break; |
|
281 } |
|
282 } |
|
283 |
|
284 /** |
|
285 * @return string |
|
286 */ |
|
287 public function getPemString() |
|
288 { |
|
289 return $this->_pemString; |
|
290 } |
|
291 |
|
292 public function getPemPath() |
|
293 { |
|
294 return $this->_pemPath; |
|
295 } |
|
296 |
|
297 public function getCertificateString() |
|
298 { |
|
299 return $this->_certificateString; |
|
300 } |
|
301 |
|
302 public function getCertificatePath() |
|
303 { |
|
304 return $this->_certificatePath; |
|
305 } |
|
306 |
|
307 public function getHashAlgorithm() |
|
308 { |
|
309 return $this->_hashAlgorithm; |
|
310 } |
|
311 |
|
312 protected function _parseConfigArgs(array $config = null) |
|
313 { |
|
314 $configs = array(); |
|
315 if (isset($config['privateKeyBits'])) { |
|
316 $configs['private_key_bits'] = $config['privateKeyBits']; |
|
317 } |
|
318 if (!empty($configs)) { |
|
319 return $configs; |
|
320 } |
|
321 return null; |
|
322 } |
|
323 |
|
324 } |