PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.20
VikAppointments Services Booking Calendar v1.2.20
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / libraries / adapter / cipher / sodium.php
vikappointments / libraries / adapter / cipher Last commit date
crypto.php 1 month ago key.php 1 month ago sodium.php 1 month ago
sodium.php
146 lines
1 <?php
2 /**
3 * @package VikWP - Libraries
4 * @subpackage adapter.html
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2023 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 require_once ABSPATH . WPINC . '/sodium_compat/autoload-php7.php';
15 JLoader::import('adapter.cipher.key');
16
17 /**
18 * JCrypt cipher for sodium algorithm encryption, decryption and key generation.
19 *
20 * @since 10.1.57
21 */
22 class JSodiumCipher
23 {
24 /**
25 * The message nonce to be used with encryption/decryption.
26 *
27 * @var string
28 */
29 private $nonce;
30
31 /**
32 * Method to decrypt a data string.
33 *
34 * @param string $data The encrypted string to decrypt.
35 * @param JCryptKey $key The key object to use for decryption.
36 *
37 * @return string The decrypted data string.
38 *
39 * @throws RuntimeException
40 */
41 public function decrypt($data, JCryptKey $key)
42 {
43 // validate key
44 if ($key->type !== 'sodium')
45 {
46 throw new InvalidArgumentException('Invalid key of type: ' . $key->type . '. Expected sodium.');
47 }
48
49 if (!$this->nonce)
50 {
51 throw new RuntimeException('Missing nonce to decrypt data');
52 }
53
54 $decrypted = ParagonIE_Sodium_Compat::crypto_box_open(
55 $data,
56 $this->nonce,
57 ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey($key->private, $key->public)
58 );
59
60 if ($decrypted === false)
61 {
62 throw new RuntimeException('Malformed message or invalid MAC');
63 }
64
65 return $decrypted;
66 }
67
68 /**
69 * Method to encrypt a data string.
70 *
71 * @param string $data The data string to encrypt.
72 * @param JCryptKey $key The key object to use for encryption.
73 *
74 * @return string The encrypted data string.
75 *
76 * @throws RuntimeException
77 */
78 public function encrypt($data, JCryptKey $key)
79 {
80 // validate key
81 if ($key->type !== 'sodium')
82 {
83 throw new InvalidArgumentException('Invalid key of type: ' . $key->type . '. Expected sodium.');
84 }
85
86 if (!$this->nonce)
87 {
88 throw new RuntimeException('Missing nonce to decrypt data');
89 }
90
91 return ParagonIE_Sodium_Compat::crypto_box(
92 $data,
93 $this->nonce,
94 ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey($key->private, $key->public)
95 );
96 }
97
98 /**
99 * Method to generate a new encryption key object.
100 *
101 * @param array $options Key generation options.
102 *
103 * @return JCryptKey
104 *
105 * @throws RuntimeException
106 */
107 public function generateKey(array $options = [])
108 {
109 // Generate the encryption key.
110 $pair = ParagonIE_Sodium_Compat::crypto_box_keypair();
111
112 return new JCryptKey(
113 'sodium',
114 ParagonIE_Sodium_Compat::crypto_box_secretkey($pair),
115 ParagonIE_Sodium_Compat::crypto_box_publickey($pair)
116 );
117 }
118
119 /**
120 * Check if the cipher is supported in this environment.
121 *
122 * @return bool
123 */
124 public static function isSupported(): bool
125 {
126 return class_exists(ParagonIE_Sodium_Compat::class);
127 }
128
129 /**
130 * Set the nonce to use for encrypting/decrypting messages
131 *
132 * @param string $nonce The message nonce
133 *
134 * @return void
135 */
136 public function setNonce($nonce)
137 {
138 if (strlen($nonce) < ParagonIE_Sodium_Compat::CRYPTO_BOX_NONCEBYTES)
139 {
140 $nonce = str_repeat($nonce, ceil(ParagonIE_Sodium_Compat::CRYPTO_BOX_NONCEBYTES / strlen($nonce)));
141 }
142
143 $this->nonce = substr($nonce, 0, ParagonIE_Sodium_Compat::CRYPTO_BOX_NONCEBYTES);
144 }
145 }
146