Updated copyright year.
[mailer.git] / inc / encryption-functions.php
1 <?php
2 /************************************************************************
3  * Mailer v0.2.1-FINAL                                Start: 04/04/2015 *
4  * ===================                          Last change: 04/04/2015 *
5  *                                                                      *
6  * -------------------------------------------------------------------- *
7  * File              : encryption-functions.php                         *
8  * -------------------------------------------------------------------- *
9  * Short description : Functions for encryption                         *
10  * -------------------------------------------------------------------- *
11  * Kurzbeschreibung  : Funktionen fuer Verschluesselung                 *
12  * -------------------------------------------------------------------- *
13  * Copyright (c) 2003 - 2009 by Roland Haeder                           *
14  * Copyright (c) 2009 - 2016 by Mailer Developer Team                   *
15  * For more information visit: http://mxchange.org                      *
16  *                                                                      *
17  * This program is free software; you can redistribute it and/or modify *
18  * it under the terms of the GNU General Public License as published by *
19  * the Free Software Foundation; either version 2 of the License, or    *
20  * (at your option) any later version.                                  *
21  *                                                                      *
22  * This program is distributed in the hope that it will be useful,      *
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
25  * GNU General Public License for more details.                         *
26  *                                                                      *
27  * You should have received a copy of the GNU General Public License    *
28  * along with this program; if not, write to the Free Software          *
29  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,               *
30  * MA  02110-1301  USA                                                  *
31  ************************************************************************/
32
33 if (!defined('__SECURITY')) {
34         exit();
35 } // END - if
36
37 // Generate salt if not set
38 function generateSalt ($salt = '', $hashLength = 48) {
39         // The length should not be shorter than 48 to have 8 byte as salt
40         assert(($hashLength >= 48) && ($hashLength <= 80));
41
42         // Is the salt set?
43         if (empty($salt)) {
44                 // Then generate it from various data
45                 $salt = hashSha256($hashLength . ':' . mt_rand(100000, 999999) . ':' . getSiteKey());
46         } // END - if
47
48         // Shorten salt ...
49         $salt = substr($salt, 0, $hashLength - 64);
50
51         // Return salt
52         return $salt;
53 }
54
55 // Hashes a string with SHA256, salts it and returns it hexdecimal-encoded
56 function hashString ($str, $salt = '') {
57         // Generate salt
58         $salt = generateSalt($salt, 64);
59
60         // Generate salt
61         $hash = hashSha256($salt . $str);
62
63         // Return it
64         return $salt . $hash;
65 }
66
67 // Hash string with SHA256 and encode it to hex
68 function hashSha256 ($str) {
69         /// Hash string
70         $hash = mhash(MHASH_SHA256, $str);
71
72         // Encode it to hexadecimal
73         $hex = '';
74         for ($i = 0; $i < strlen($hash); $i++) {
75                 // Encode char to decimal, pad it with zero, add it
76                 $hex .= padLeftZero(dechex(ord(substr($hash, $i, 1))), 2);
77         } // END - if
78
79         // Make sure 'length modulo 2' = 0
80         assert((strlen($hex) % 2) == 0);
81
82         // Return it
83         return $hex;
84 }
85
86 // "Calculates" password strength
87 function calculatePasswordStrength ($password, $configEntry = 'min_password_length') {
88         // Default score
89         $score = 1;
90
91         if ((strlen($password) < 1) || (strlen($password) < getConfig($configEntry))) {
92                 // Is to weak
93                 return 0;
94         } // END - if
95
96         // At least 8 chars long?
97         if (strlen($password) >= 8) {
98                 // Add score
99                 $score++;
100         } // END - if
101
102         // At least 10 chars long?
103         if (strlen($password) >= 10) {
104                 // Add score
105                 $score++;
106         } // END - if
107
108         // Lower and upper cases?
109         if ((preg_match('/[a-z]/', $password)) && (preg_match('/[A-Z]/', $password))) {
110                 // Add score
111                 $score++;
112         } // END - if
113
114         // Also numbers?
115         if (preg_match('/[0-9]/', $password))  {
116                 // Add score
117                 $score++;
118         } // END - if
119
120         // Special characters?
121         if (preg_match('/.[!,@,#,$,%,^,&,*,?,\/,_,~,+,-,(,)]/', $password)) {
122                 // Add score
123                 $score++;
124         } // END - if
125
126         // Return password score
127         return $score;
128 }
129
130 // "Translates" password strength/score
131 function translatePasswordStrength ($strength) {
132         // Return it translated
133         return '{--PASSWORD_SCORE_' . bigintval($strength) . '--}';
134 }
135
136 // Checks whether given password is strong enough
137 function isStrongPassword ($password) {
138         // Determine it
139         return (calculatePasswordStrength($password) >= getConfig('min_password_score'));
140 }
141
142 // "Translates" encryption algorithm
143 function translateEncryptionAlgorithm ($algo) {
144         // Default is 'NONE'
145         $translated = '{--SELECT_NONE--}';
146
147         // Is a valid number? Also '0' is valid.
148         if ((isValidNumber($algo)) || ($algo === '0')) {
149                 // Get array
150                 $algos = getSupportedEncryptionAlgorithms();
151
152                 // Is it there?
153                 if (isset($algos[$algo])) {
154                         // "Translate" it
155                         $translated = strtoupper($algos[$algo]);
156                 } else {
157                         // Unknown/unsupported
158                         $translated = '{--UNSUPPORTED_ENCRYPTION_ALGO--}';
159                 }
160         } // END - if
161
162         // Return it
163         return $translated;
164 }
165
166 // "Translates" encryption mode
167 function translateEncryptionMode ($mode) {
168         // Default is 'NONE'
169         $translated = '{--SELECT_NONE--}';
170
171         // Is a valid number?
172         if ((isValidNumber($mode)) || (is_numeric($mode))) {
173                 // Get array
174                 $modes = getSupportedEncryptionModes();
175
176                 // Is it there?
177                 if (isset($modes[$mode])) {
178                         // "Translate" it
179                         $translated = strtoupper($modes[$mode]);
180                 } else {
181                         // Unknown/unsupported
182                         $translated = '{--UNSUPPORTED_ENCRYPTION_MODE--}';
183                 }
184         } // END - if
185
186         // Return it
187         return $translated;
188 }
189
190 // "Getter" for an array of supported ("safe") encryption algorithms
191 function getSupportedEncryptionAlgorithms () {
192         // Get full list
193         $algos = mcrypt_list_algorithms();
194
195         // Remove any unsecure (e.g. DES/3DES)
196         foreach (array('des', 'tripledes') as $unsecure) {
197                 // Search for it
198                 $id = array_search($unsecure, $algos, TRUE);
199
200                 // Is it found?
201                 if (isValidNumber($id)) {
202                         // Remove it
203                         unset($algos[$id]);
204                 } // END - if
205         } // END - foreach
206
207         // Return it
208         return $algos;
209 }
210
211 // "Getter" for an array of supported encryption modes
212 function getSupportedEncryptionModes () {
213         // Get full list
214         $modes = mcrypt_list_modes();
215
216         // Return it
217         return $modes;
218 }
219
220 // Determines whether given encryption algorithm number is valid
221 function isValidEncryptionAlgorithm ($algo) {
222         // Default is not valid
223         $isValid = FALSE;
224
225         // Is valid number?
226         if (isValidNumber($algo)) {
227                 // Get supported algorithms
228                 $algos = getSupportedEncryptionAlgorithms();
229
230                 // Is it there?
231                 $isValid = (isset($algos[$algo]));
232         } // END - if
233
234         // Return status
235         return $isValid;
236 }
237
238 // Determines whether given encryption mode number is valid
239 function isValidEncryptionMode ($mode) {
240         // Default is not valid
241         $isValid = FALSE;
242
243         // Is valid number?
244         if ((isValidNumber($mode)) || (is_numeric($mode))) {
245                 // Get supported algorithms
246                 $modes = getSupportedEncryptionModes();
247
248                 // Is it there?
249                 $isValid = (isset($modes[$mode]));
250         } // END - if
251
252         // Return status
253         return $isValid;
254 }
255
256 // Encrypts a string by given algorithm and key
257 function encrytStringByCipher ($str, $algo, $mode, $key) {
258         // Init encryption
259         $cipher = initEncryption($algo, $mode, $key);
260
261         // Encrypt it
262         $encrypted = mcrypt_generic($cipher, $str);
263
264         // Deinit/close cipher
265         deinitEncryption($cipher);
266
267         // Return encrypted
268         return $encrypted;
269 }
270
271 // Decrypts a string by given algorithm and key
272 function decrytStringByCipher ($str, $algo, $mode, $key, $iv) {
273         // Init encryption
274         $cipher = initEncryption($algo, $mode, $key, $iv);
275
276         // Decrypt it
277         $encrypted = mdecrypt_generic($cipher, $str);
278
279         // Deinit/close cipher
280         deinitEncryption($cipher);
281
282         // Return encrypted
283         return $encrypted;
284 }
285
286 // Initializes encryption/decryption
287 function initEncryption ($algo, $mode, $key, $iv = NULL) {
288         // Must be valid algo/mode
289         assert((isValidEncryptionAlgorithm($algo)) && (isValidEncryptionMode($mode)));
290
291         // Get algorithms/modes
292         $algos = getSupportedEncryptionAlgorithms();
293         $modes = getSupportedEncryptionModes();
294
295         // Open encryption module
296         $cipher = mcrypt_module_open($algos[$algo], '', $modes[$mode], '');
297
298         // Ist not a resource?
299         assert(is_resource($cipher));
300
301         // Is iv set?
302         if (is_null($iv)) {
303                 // Create IV
304                 $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($cipher), MCRYPT_DEV_RANDOM);
305         } // END - if
306
307         // Generate key size
308         $keySize = mcrypt_enc_get_key_size($cipher);
309
310         // Key size must be smaller/equal key's size
311         assert($keySize <= strlen($key));
312
313         // Initialize encryption
314         mcrypt_generic_init($cipher, substr($key, 0, $keySize), $iv);
315
316         // Return prepared cipher
317         return $cipher;
318 }
319
320 // Deinitializes encryption cipher
321 function deinitEncryption ($cipher) {
322         // Ist not a resource?
323         assert(is_resource($cipher));
324
325         // Deinit/close cipher
326         mcrypt_generic_deinit($cipher);
327         mcrypt_module_close($cipher);
328 }
329
330 // [EOF]
331 ?>