PluginProbe ʕ •ᴥ•ʔ
WP Mail SMTP by WPForms – The Most Popular SMTP and Email Log Plugin / 4.9.0
WP Mail SMTP by WPForms – The Most Popular SMTP and Email Log Plugin v4.9.0
4.9.0 0.9.6 1.0.0 1.0.1 1.0.2 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.6.0 1.6.2 1.7.0 1.7.1 1.8.0 1.8.1 1.9.0 2.0.0 2.0.1 2.1.1 2.2.1 2.3.1 2.4.0 2.5.0 2.5.1 2.6.0 2.7.0 2.8.0 2.9.0 3.0.1 3.0.2 3.0.3 3.1.0 3.10.0 3.11.0 3.11.1 3.2.0 3.2.1 3.3.0 3.4.0 3.5.0 3.5.1 3.5.2 3.6.1 3.7.0 3.8.0 3.8.2 3.9.0 4.0.1 4.1.0 4.1.1 4.2.0 4.3.0 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.8.0 trunk 0.10.0 0.10.1 0.11.1 0.11.2 0.3.1 0.3.2 0.4 0.4.1 0.4.2 0.5.0 0.5.1 0.5.2 0.6 0.7 0.8 0.8.2 0.8.3 0.8.4 0.8.5 0.8.6 0.8.7 0.9.0 0.9.1 0.9.2 0.9.3 0.9.4 0.9.5
wp-mail-smtp / src / Helpers / Crypto.php
wp-mail-smtp / src / Helpers Last commit date
Crypto.php 5 days ago DB.php 5 days ago Data.php 5 days ago Helpers.php 5 days ago PluginImportDataRetriever.php 5 days ago UI.php 5 days ago
Crypto.php
164 lines
1 <?php
2
3 namespace WPMailSMTP\Helpers;
4
5 /**
6 * Class for encryption functionality.
7 *
8 * @since 2.5.0
9 *
10 * @link https://www.php.net/manual/en/intro.sodium.php
11 */
12 class Crypto {
13
14 /**
15 * Get a secret key for encrypt/decrypt.
16 *
17 * @since 2.5.0
18 *
19 * @param bool $create Should the key be created, if it does not exist yet.
20 *
21 * @return string|bool
22 */
23 public static function get_secret_key( $create = false ) {
24
25 if ( defined( 'WPMS_CRYPTO_KEY' ) ) {
26 return WPMS_CRYPTO_KEY;
27 }
28
29 $secret_key = apply_filters( 'wp_mail_smtp_helpers_crypto_get_secret_key', get_option( 'wp_mail_smtp_mail_key' ) );
30
31 // If we already have the secret, send it back.
32 if ( false !== $secret_key ) {
33 return base64_decode( $secret_key ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
34 }
35
36 if ( $create ) {
37 // We don't have a secret, so let's generate one.
38 try {
39 $secret_key = sodium_crypto_secretbox_keygen(); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.sodium_crypto_secretbox_keygenFound
40 } catch ( \Exception $e ) {
41 $secret_key = wp_generate_password( SODIUM_CRYPTO_SECRETBOX_KEYBYTES ); // phpcs:ignore PHPCompatibility.Constants.NewConstants.sodium_crypto_secretbox_keybytesFound
42 }
43
44 add_option( 'wp_mail_smtp_mail_key', base64_encode( $secret_key ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
45
46 return $secret_key;
47 }
48
49 return false;
50 }
51
52 /**
53 * Encrypt a message.
54 *
55 * @since 2.5.0
56 *
57 * @param string $message Message to encrypt.
58 * @param string $key Encryption key.
59 *
60 * @return string
61 * @throws \Exception The exception object.
62 */
63 public static function encrypt( $message, $key = '' ) {
64
65 if ( apply_filters( 'wp_mail_smtp_helpers_crypto_stop', false ) ) {
66 return $message;
67 }
68
69 // Create a nonce for this operation. It will be stored and recovered in the message itself.
70 // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.random_bytesFound, PHPCompatibility.Constants.NewConstants.sodium_crypto_secretbox_noncebytesFound
71 $nonce = random_bytes( SODIUM_CRYPTO_SECRETBOX_NONCEBYTES );
72
73 if ( empty( $key ) ) {
74 $key = self::get_secret_key( true );
75 }
76
77 // Encrypt message and combine with nonce.
78 $cipher = base64_encode( // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
79 $nonce .
80 sodium_crypto_secretbox( // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.sodium_crypto_secretboxFound
81 $message,
82 $nonce,
83 $key
84 )
85 );
86
87 try {
88 sodium_memzero( $message ); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.sodium_memzeroFound
89 sodium_memzero( $key ); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.sodium_memzeroFound
90 } catch ( \Exception $e ) {
91 return $cipher;
92 }
93
94 return $cipher;
95 }
96
97 /**
98 * Decrypt a message.
99 * Returns encrypted message on any failure and the decrypted message on success.
100 *
101 * @since 2.5.0
102 *
103 * @param string $encrypted Encrypted message.
104 * @param string $key Encryption key.
105 *
106 * @return string
107 * @throws \Exception The exception object.
108 */
109 public static function decrypt( $encrypted, $key = '' ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
110
111 if ( apply_filters( 'wp_mail_smtp_helpers_crypto_stop', false ) ) {
112 return $encrypted;
113 }
114
115 // Unpack base64 message.
116 $decoded = base64_decode( $encrypted ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
117
118 if ( false === $decoded ) {
119 return $encrypted;
120 }
121
122 // Include polyfill if mbstring PHP extension is not enabled.
123 if ( ! function_exists( 'mb_strlen' ) || ! function_exists( 'mb_substr' ) ) {
124 Helpers::include_mbstring_polyfill();
125 }
126
127 // phpcs:ignore PHPCompatibility.Constants.NewConstants.sodium_crypto_secretbox_noncebytesFound, PHPCompatibility.Constants.NewConstants.sodium_crypto_secretbox_macbytesFound
128 if ( mb_strlen( $decoded, '8bit' ) < ( SODIUM_CRYPTO_SECRETBOX_NONCEBYTES + SODIUM_CRYPTO_SECRETBOX_MACBYTES ) ) {
129 return $encrypted;
130 }
131
132 // Pull nonce and ciphertext out of unpacked message.
133 $nonce = mb_substr( $decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit' ); // phpcs:ignore PHPCompatibility.Constants.NewConstants.sodium_crypto_secretbox_noncebytesFound
134 $ciphertext = mb_substr( $decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit' ); // phpcs:ignore PHPCompatibility.Constants.NewConstants.sodium_crypto_secretbox_noncebytesFound
135
136 $key = empty( $key ) ? self::get_secret_key() : $key;
137
138 if ( empty( $key ) ) {
139 return $encrypted;
140 }
141
142 // Decrypt it.
143 $message = sodium_crypto_secretbox_open( // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.sodium_crypto_secretbox_openFound
144 $ciphertext,
145 $nonce,
146 $key
147 );
148
149 // Check for decryption failures.
150 if ( false === $message ) {
151 return $encrypted;
152 }
153
154 try {
155 sodium_memzero( $ciphertext ); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.sodium_memzeroFound
156 sodium_memzero( $key ); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.sodium_memzeroFound
157 } catch ( \Exception $e ) {
158 return $message;
159 }
160
161 return $message;
162 }
163 }
164