Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Openssl.php
Go to the documentation of this file.
1 <?php
25 #require_once 'Zend/Filter/Encrypt/Interface.php';
26 
36 {
45  protected $_keys = array(
46  'public' => array(),
47  'private' => array(),
48  'envelope' => array()
49  );
50 
56  protected $_passphrase;
57 
63  protected $_compression;
64 
70  protected $_package = false;
71 
84  public function __construct($options = array())
85  {
86  if (!extension_loaded('openssl')) {
87  #require_once 'Zend/Filter/Exception.php';
88  throw new Zend_Filter_Exception('This filter needs the openssl extension');
89  }
90 
91  if ($options instanceof Zend_Config) {
92  $options = $options->toArray();
93  }
94 
95  if (!is_array($options)) {
96  $options = array('public' => $options);
97  }
98 
99  if (array_key_exists('passphrase', $options)) {
100  $this->setPassphrase($options['passphrase']);
101  unset($options['passphrase']);
102  }
103 
104  if (array_key_exists('compression', $options)) {
105  $this->setCompression($options['compression']);
106  unset($options['compress']);
107  }
108 
109  if (array_key_exists('package', $options)) {
110  $this->setPackage($options['package']);
111  unset($options['package']);
112  }
113 
114  $this->_setKeys($options);
115  }
116 
123  protected function _setKeys($keys)
124  {
125  if (!is_array($keys)) {
126  #require_once 'Zend/Filter/Exception.php';
127  throw new Zend_Filter_Exception('Invalid options argument provided to filter');
128  }
129 
130  foreach ($keys as $type => $key) {
131  if (ctype_print($key) && is_file(realpath($key)) && is_readable($key)) {
132  $file = fopen($key, 'r');
133  $cert = fread($file, 8192);
134  fclose($file);
135  } else {
136  $cert = $key;
137  $key = count($this->_keys[$type]);
138  }
139 
140  switch ($type) {
141  case 'public':
142  $test = openssl_pkey_get_public($cert);
143  if ($test === false) {
144  #require_once 'Zend/Filter/Exception.php';
145  throw new Zend_Filter_Exception("Public key '{$cert}' not valid");
146  }
147 
148  openssl_free_key($test);
149  $this->_keys['public'][$key] = $cert;
150  break;
151  case 'private':
152  $test = openssl_pkey_get_private($cert, $this->_passphrase);
153  if ($test === false) {
154  #require_once 'Zend/Filter/Exception.php';
155  throw new Zend_Filter_Exception("Private key '{$cert}' not valid");
156  }
157 
158  openssl_free_key($test);
159  $this->_keys['private'][$key] = $cert;
160  break;
161  case 'envelope':
162  $this->_keys['envelope'][$key] = $cert;
163  break;
164  default:
165  break;
166  }
167  }
168 
169  return $this;
170  }
171 
177  public function getPublicKey()
178  {
179  $key = $this->_keys['public'];
180  return $key;
181  }
182 
189  public function setPublicKey($key)
190  {
191  if (is_array($key)) {
192  foreach($key as $type => $option) {
193  if ($type !== 'public') {
194  $key['public'] = $option;
195  unset($key[$type]);
196  }
197  }
198  } else {
199  $key = array('public' => $key);
200  }
201 
202  return $this->_setKeys($key);
203  }
204 
210  public function getPrivateKey()
211  {
212  $key = $this->_keys['private'];
213  return $key;
214  }
215 
223  public function setPrivateKey($key, $passphrase = null)
224  {
225  if (is_array($key)) {
226  foreach($key as $type => $option) {
227  if ($type !== 'private') {
228  $key['private'] = $option;
229  unset($key[$type]);
230  }
231  }
232  } else {
233  $key = array('private' => $key);
234  }
235 
236  if ($passphrase !== null) {
237  $this->setPassphrase($passphrase);
238  }
239 
240  return $this->_setKeys($key);
241  }
242 
248  public function getEnvelopeKey()
249  {
250  $key = $this->_keys['envelope'];
251  return $key;
252  }
253 
260  public function setEnvelopeKey($key)
261  {
262  if (is_array($key)) {
263  foreach($key as $type => $option) {
264  if ($type !== 'envelope') {
265  $key['envelope'] = $option;
266  unset($key[$type]);
267  }
268  }
269  } else {
270  $key = array('envelope' => $key);
271  }
272 
273  return $this->_setKeys($key);
274  }
275 
281  public function getPassphrase()
282  {
283  return $this->_passphrase;
284  }
285 
292  public function setPassphrase($passphrase)
293  {
294  $this->_passphrase = $passphrase;
295  return $this;
296  }
297 
303  public function getCompression()
304  {
305  return $this->_compression;
306  }
307 
314  public function setCompression($compression)
315  {
316  if (is_string($this->_compression)) {
317  $compression = array('adapter' => $compression);
318  }
319 
320  $this->_compression = $compression;
321  return $this;
322  }
323 
329  public function getPackage()
330  {
331  return $this->_package;
332  }
333 
340  public function setPackage($package)
341  {
342  $this->_package = (boolean) $package;
343  return $this;
344  }
345 
354  public function encrypt($value)
355  {
356  $encrypted = array();
357  $encryptedkeys = array();
358 
359  if (count($this->_keys['public']) == 0) {
360  #require_once 'Zend/Filter/Exception.php';
361  throw new Zend_Filter_Exception('Openssl can not encrypt without public keys');
362  }
363 
364  $keys = array();
365  $fingerprints = array();
366  $count = -1;
367  foreach($this->_keys['public'] as $key => $cert) {
368  $keys[$key] = openssl_pkey_get_public($cert);
369  if ($this->_package) {
370  $details = openssl_pkey_get_details($keys[$key]);
371  if ($details === false) {
372  $details = array('key' => 'ZendFramework');
373  }
374 
375  ++$count;
376  $fingerprints[$count] = md5($details['key']);
377  }
378  }
379 
380  // compress prior to encryption
381  if (!empty($this->_compression)) {
382  #require_once 'Zend/Filter/Compress.php';
383  $compress = new Zend_Filter_Compress($this->_compression);
384  $value = $compress->filter($value);
385  }
386 
387  $crypt = openssl_seal($value, $encrypted, $encryptedkeys, $keys);
388  foreach ($keys as $key) {
389  openssl_free_key($key);
390  }
391 
392  if ($crypt === false) {
393  #require_once 'Zend/Filter/Exception.php';
394  throw new Zend_Filter_Exception('Openssl was not able to encrypt your content with the given options');
395  }
396 
397  $this->_keys['envelope'] = $encryptedkeys;
398 
399  // Pack data and envelope keys into single string
400  if ($this->_package) {
401  $header = pack('n', count($this->_keys['envelope']));
402  foreach($this->_keys['envelope'] as $key => $envKey) {
403  $header .= pack('H32n', $fingerprints[$key], strlen($envKey)) . $envKey;
404  }
405 
406  $encrypted = $header . $encrypted;
407  }
408 
409  return $encrypted;
410  }
411 
421  public function decrypt($value)
422  {
423  $decrypted = "";
424  $envelope = current($this->getEnvelopeKey());
425 
426  if (count($this->_keys['private']) !== 1) {
427  #require_once 'Zend/Filter/Exception.php';
428  throw new Zend_Filter_Exception('Please give a private key for decryption with Openssl');
429  }
430 
431  if (!$this->_package && empty($envelope)) {
432  #require_once 'Zend/Filter/Exception.php';
433  throw new Zend_Filter_Exception('Please give a envelope key for decryption with Openssl');
434  }
435 
436  foreach($this->_keys['private'] as $key => $cert) {
437  $keys = openssl_pkey_get_private($cert, $this->getPassphrase());
438  }
439 
440  if ($this->_package) {
441  $details = openssl_pkey_get_details($keys);
442  if ($details !== false) {
443  $fingerprint = md5($details['key']);
444  } else {
445  $fingerprint = md5("ZendFramework");
446  }
447 
448  $count = unpack('ncount', $value);
449  $count = $count['count'];
450  $length = 2;
451  for($i = $count; $i > 0; --$i) {
452  $header = unpack('H32print/nsize', substr($value, $length, 18));
453  $length += 18;
454  if ($header['print'] == $fingerprint) {
455  $envelope = substr($value, $length, $header['size']);
456  }
457 
458  $length += $header['size'];
459  }
460 
461  // remainder of string is the value to decrypt
462  $value = substr($value, $length);
463  }
464 
465  $crypt = openssl_open($value, $decrypted, $envelope, $keys);
466  openssl_free_key($keys);
467 
468  if ($crypt === false) {
469  #require_once 'Zend/Filter/Exception.php';
470  throw new Zend_Filter_Exception('Openssl was not able to decrypt you content with the given options');
471  }
472 
473  // decompress after decryption
474  if (!empty($this->_compression)) {
475  #require_once 'Zend/Filter/Decompress.php';
476  $decompress = new Zend_Filter_Decompress($this->_compression);
477  $decrypted = $decompress->filter($decrypted);
478  }
479 
480  return $decrypted;
481  }
482 
488  public function toString()
489  {
490  return 'Openssl';
491  }
492 }
setCompression($compression)
Definition: Openssl.php:314
setPrivateKey($key, $passphrase=null)
Definition: Openssl.php:223
$details
Definition: vault.phtml:10
$count
Definition: recent.phtml:13
$type
Definition: item.phtml:13
setPassphrase($passphrase)
Definition: Openssl.php:292
$value
Definition: gender.phtml:16
__construct($options=array())
Definition: Openssl.php:84
$i
Definition: gallery.phtml:31