Added the zend framework 2 library, the path is specified in line no.26 in zend_modul...
[openemr.git] / interface / modules / zend_modules / library / Zend / Crypt / PublicKey / Rsa.php
blob03b1f177514611ffbe206de89996b8323db56e87
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\Crypt\PublicKey;
12 use Traversable;
13 use Zend\Crypt\PublicKey\Rsa\Exception;
14 use Zend\Crypt\PublicKey\RsaOptions;
15 use Zend\Stdlib\ArrayUtils;
17 /**
18 * Implementation of the RSA public key encryption algorithm.
20 class Rsa
22 const MODE_AUTO = 1;
23 const MODE_BASE64 = 2;
24 const MODE_RAW = 3;
26 /**
27 * @var RsaOptions
29 protected $options = null;
31 /**
32 * RSA instance factory
34 * @param array|Traversable $options
35 * @return Rsa
36 * @throws Rsa\Exception\RuntimeException
37 * @throws Rsa\Exception\InvalidArgumentException
39 public static function factory($options)
41 if (!extension_loaded('openssl')) {
42 throw new Exception\RuntimeException(
43 'Can not create Zend\Crypt\PublicKey\Rsa; openssl extension to be loaded'
47 if ($options instanceof Traversable) {
48 $options = ArrayUtils::iteratorToArray($options);
49 } elseif (!is_array($options)) {
50 throw new Exception\InvalidArgumentException(
51 'The options parameter must be an array or a Traversable'
55 $privateKey = null;
56 $passPhrase = isset($options['pass_phrase']) ? $options['pass_phrase'] : null;
57 if (isset($options['private_key'])) {
58 if (is_file($options['private_key'])) {
59 $privateKey = Rsa\PrivateKey::fromFile($options['private_key'], $passPhrase);
60 } elseif (is_string($options['private_key'])) {
61 $privateKey = new Rsa\PrivateKey($options['private_key'], $passPhrase);
62 } else {
63 throw new Exception\InvalidArgumentException(
64 'Parameter "private_key" must be PEM formatted string or path to key file'
67 unset($options['private_key']);
70 $publicKey = null;
71 if (isset($options['public_key'])) {
72 if (is_file($options['public_key'])) {
73 $publicKey = Rsa\PublicKey::fromFile($options['public_key']);
74 } elseif (is_string($options['public_key'])) {
75 $publicKey = new Rsa\PublicKey($options['public_key']);
76 } else {
77 throw new Exception\InvalidArgumentException(
78 'Parameter "public_key" must be PEM/certificate string or path to key/certificate file'
81 unset($options['public_key']);
84 $options = new RsaOptions($options);
85 if ($privateKey instanceof Rsa\PrivateKey) {
86 $options->setPrivateKey($privateKey);
88 if ($publicKey instanceof Rsa\PublicKey) {
89 $options->setPublicKey($publicKey);
92 return new Rsa($options);
95 /**
96 * Class constructor
98 * @param RsaOptions $options
99 * @throws Rsa\Exception\RuntimeException
101 public function __construct(RsaOptions $options = null)
103 if (!extension_loaded('openssl')) {
104 throw new Exception\RuntimeException(
105 'Zend\Crypt\PublicKey\Rsa requires openssl extension to be loaded'
109 if ($options === null) {
110 $this->options = new RsaOptions();
111 } else {
112 $this->options = $options;
117 * Set options
119 * @param RsaOptions $options
120 * @return Rsa
122 public function setOptions(RsaOptions $options)
124 $this->options = $options;
125 return $this;
129 * Get options
131 * @return RsaOptions
133 public function getOptions()
135 return $this->options;
139 * Return last openssl error(s)
141 * @return string
143 public function getOpensslErrorString()
145 $message = '';
146 while (false !== ($error = openssl_error_string())) {
147 $message .= $error . "\n";
149 return trim($message);
153 * Sign with private key
155 * @param string $data
156 * @param Rsa\PrivateKey $privateKey
157 * @return string
158 * @throws Rsa\Exception\RuntimeException
160 public function sign($data, Rsa\PrivateKey $privateKey = null)
162 $signature = '';
163 if (null === $privateKey) {
164 $privateKey = $this->options->getPrivateKey();
167 $result = openssl_sign(
168 $data,
169 $signature,
170 $privateKey->getOpensslKeyResource(),
171 $this->options->getOpensslSignatureAlgorithm()
173 if (false === $result) {
174 throw new Exception\RuntimeException(
175 'Can not generate signature; openssl ' . $this->getOpensslErrorString()
179 if ($this->options->getBinaryOutput()) {
180 return $signature;
183 return base64_encode($signature);
187 * Verify signature with public key
189 * $signature can be encoded in base64 or not. $mode sets how the input must be processed:
190 * - MODE_AUTO: Check if the $signature is encoded in base64. Not recommended for performance.
191 * - MODE_BASE64: Decode $signature using base64 algorithm.
192 * - MODE_RAW: $signature is not encoded.
194 * @param string $data
195 * @param string $signature
196 * @param null|Rsa\PublicKey $publicKey
197 * @param int $mode Input encoding
198 * @return bool
199 * @throws Rsa\Exception\RuntimeException
200 * @see Rsa::MODE_AUTO
201 * @see Rsa::MODE_BASE64
202 * @see Rsa::MODE_RAW
204 public function verify(
205 $data,
206 $signature,
207 Rsa\PublicKey $publicKey = null,
208 $mode = self::MODE_AUTO
210 if (null === $publicKey) {
211 $publicKey = $this->options->getPublicKey();
214 switch ($mode) {
215 case self::MODE_AUTO:
216 // check if data is encoded in Base64
217 $output = base64_decode($signature, true);
218 if ((false !== $output) && ($signature === base64_encode($output))) {
219 $signature = $output;
221 break;
222 case self::MODE_BASE64:
223 $signature = base64_decode($signature);
224 break;
225 case self::MODE_RAW:
226 default:
227 break;
230 $result = openssl_verify(
231 $data,
232 $signature,
233 $publicKey->getOpensslKeyResource(),
234 $this->options->getOpensslSignatureAlgorithm()
236 if (-1 === $result) {
237 throw new Exception\RuntimeException(
238 'Can not verify signature; openssl ' . $this->getOpensslErrorString()
242 return ($result === 1);
246 * Encrypt with private/public key
248 * @param string $data
249 * @param Rsa\AbstractKey $key
250 * @return string
251 * @throws Rsa\Exception\InvalidArgumentException
253 public function encrypt($data, Rsa\AbstractKey $key = null)
255 if (null === $key) {
256 $key = $this->options->getPublicKey();
259 if (null === $key) {
260 throw new Exception\InvalidArgumentException('No key specified for the decryption');
263 $encrypted = $key->encrypt($data);
265 if ($this->options->getBinaryOutput()) {
266 return $encrypted;
269 return base64_encode($encrypted);
273 * Decrypt with private/public key
275 * $data can be encoded in base64 or not. $mode sets how the input must be processed:
276 * - MODE_AUTO: Check if the $signature is encoded in base64. Not recommended for performance.
277 * - MODE_BASE64: Decode $data using base64 algorithm.
278 * - MODE_RAW: $data is not encoded.
280 * @param string $data
281 * @param Rsa\AbstractKey $key
282 * @param int $mode Input encoding
283 * @return string
284 * @throws Rsa\Exception\InvalidArgumentException
285 * @see Rsa::MODE_AUTO
286 * @see Rsa::MODE_BASE64
287 * @see Rsa::MODE_RAW
289 public function decrypt(
290 $data,
291 Rsa\AbstractKey $key = null,
292 $mode = self::MODE_AUTO
294 if (null === $key) {
295 $key = $this->options->getPrivateKey();
298 if (null === $key) {
299 throw new Exception\InvalidArgumentException('No key specified for the decryption');
302 switch ($mode) {
303 case self::MODE_AUTO:
304 // check if data is encoded in Base64
305 $output = base64_decode($data, true);
306 if ((false !== $output) && ($data === base64_encode($output))) {
307 $data = $output;
309 break;
310 case self::MODE_BASE64:
311 $data = base64_decode($data);
312 break;
313 case self::MODE_RAW:
314 default:
315 break;
318 return $key->decrypt($data);
322 * Generate new private/public key pair
323 * @see RsaOptions::generateKeys()
325 * @param array $opensslConfig
326 * @return Rsa
327 * @throws Rsa\Exception\RuntimeException
329 public function generateKeys(array $opensslConfig = array())
331 $this->options->generateKeys($opensslConfig);
332 return $this;