1 <?php
2 /**
3 * @package Joomla.Platform
4 * @subpackage Crypt
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 */
9
10 defined('JPATH_PLATFORM') or die;
11
12 /**
13 * JCrypt cipher for encryption, decryption and key generation via the php-encryption library.
14 *
15 * @since 3.5
16 */
17 class JCryptCipherCrypto implements JCryptCipher
18 {
19 /**
20 * Method to decrypt a data string.
21 *
22 * @param string $data The encrypted string to decrypt.
23 * @param JCryptKey $key The key object to use for decryption.
24 *
25 * @return string The decrypted data string.
26 *
27 * @since 3.5
28 * @throws RuntimeException
29 */
30 public function decrypt($data, JCryptKey $key)
31 {
32 // Validate key.
33 if ($key->type != 'crypto')
34 {
35 throw new InvalidArgumentException('Invalid key of type: ' . $key->type . '. Expected crypto.');
36 }
37
38 // Decrypt the data.
39 try
40 {
41 return Crypto::Decrypt($data, $key->public);
42 }
43 catch (InvalidCiphertextException $ex)
44 {
45 throw new RuntimeException('DANGER! DANGER! The ciphertext has been tampered with!', $ex->getCode(), $ex);
46 }
47 catch (CryptoTestFailedException $ex)
48 {
49 throw new RuntimeException('Cannot safely perform decryption', $ex->getCode(), $ex);
50 }
51 catch (CannotPerformOperationException $ex)
52 {
53 throw new RuntimeException('Cannot safely perform decryption', $ex->getCode(), $ex);
54 }
55 }
56
57 /**
58 * Method to encrypt a data string.
59 *
60 * @param string $data The data string to encrypt.
61 * @param JCryptKey $key The key object to use for encryption.
62 *
63 * @return string The encrypted data string.
64 *
65 * @since 3.5
66 * @throws RuntimeException
67 */
68 public function encrypt($data, JCryptKey $key)
69 {
70 // Validate key.
71 if ($key->type != 'crypto')
72 {
73 throw new InvalidArgumentException('Invalid key of type: ' . $key->type . '. Expected crypto.');
74 }
75
76 // Encrypt the data.
77 try
78 {
79 return Crypto::Encrypt($data, $key->public);
80 }
81 catch (CryptoTestFailedException $ex)
82 {
83 throw new RuntimeException('Cannot safely perform encryption', $ex->getCode(), $ex);
84 }
85 catch (CannotPerformOperationException $ex)
86 {
87 throw new RuntimeException('Cannot safely perform encryption', $ex->getCode(), $ex);
88 }
89 }
90
91 /**
92 * Method to generate a new encryption key object.
93 *
94 * @param array $options Key generation options.
95 *
96 * @return JCryptKey
97 *
98 * @since 3.5
99 * @throws RuntimeException
100 */
101 public function generateKey(array $options = array())
102 {
103 // Create the new encryption key object.
104 $key = new JCryptKey('crypto');
105
106 // Generate the encryption key.
107 try
108 {
109 $key->public = Crypto::CreateNewRandomKey();
110 }
111 catch (CryptoTestFailedException $ex)
112 {
113 throw new RuntimeException('Cannot safely create a key', $ex->getCode(), $ex);
114 }
115 catch (CannotPerformOperationException $ex)
116 {
117 throw new RuntimeException('Cannot safely create a key', $ex->getCode(), $ex);
118 }
119
120 // Explicitly flag the private as unused in this cipher.
121 $key->private = 'unused';
122
123 return $key;
124 }
125 }
126