TYPO3 CMS  TYPO3_7-6
PhpassSaltTest.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
21 {
27  protected $objectInstance = null;
28 
34  protected function setUp()
35  {
36  $this->objectInstance = $this->getMock(\TYPO3\CMS\Saltedpasswords\Salt\PhpassSalt::class, ['dummy']);
37  }
38 
42  public function hasCorrectBaseClass()
43  {
44  $hasCorrectBaseClass = get_class($this->objectInstance) === \TYPO3\CMS\Saltedpasswords\Salt\PhpassSalt::class;
45  // XCLASS ?
46  if (!$hasCorrectBaseClass && false != get_parent_class($this->objectInstance)) {
47  $hasCorrectBaseClass = is_subclass_of($this->objectInstance, \TYPO3\CMS\Saltedpasswords\Salt\PhpassSalt::class);
48  }
49  $this->assertTrue($hasCorrectBaseClass);
50  }
51 
55  public function nonZeroSaltLength()
56  {
57  $this->assertTrue($this->objectInstance->getSaltLength() > 0);
58  }
59 
64  {
65  $password = '';
66  $this->assertNull($this->objectInstance->getHashedPassword($password));
67  }
68 
73  {
74  $password = 'a';
75  $this->assertNotNull($this->objectInstance->getHashedPassword($password));
76  }
77 
82  {
83  $password = 'password';
84  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
85  $this->assertTrue($this->objectInstance->isValidSaltedPW($saltedHashPassword));
86  }
87 
92  {
93  $password = 'password';
94  // custom salt without setting
95  $randomBytes = \TYPO3\CMS\Core\Utility\GeneralUtility::generateRandomBytes($this->objectInstance->getSaltLength());
96  $salt = $this->objectInstance->base64Encode($randomBytes, $this->objectInstance->getSaltLength());
97  $this->assertTrue($this->objectInstance->isValidSalt($salt));
98  $saltedHashPassword = $this->objectInstance->getHashedPassword($password, $salt);
99  $this->assertTrue($this->objectInstance->isValidSaltedPW($saltedHashPassword));
100  }
101 
106  {
107  $password = 'password';
108  $minHashCount = $this->objectInstance->getMinHashCount();
109  $this->objectInstance->setHashCount($minHashCount);
110  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
111  $this->assertTrue($this->objectInstance->isValidSaltedPW($saltedHashPassword));
112  // reset hashcount
113  $this->objectInstance->setHashCount(null);
114  }
115 
125  {
126  $password = 'aEjOtY';
127  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
128  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
129  }
130 
140  {
141  $password = '01369';
142  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
143  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
144  }
145 
155  {
156  $password = ' !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~';
157  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
158  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
159  }
160 
170  {
171  $password = '';
172  for ($i = 160; $i <= 191; $i++) {
173  $password .= chr($i);
174  }
175  $password .= chr(215) . chr(247);
176  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
177  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
178  }
179 
189  {
190  $password = '';
191  for ($i = 192; $i <= 214; $i++) {
192  $password .= chr($i);
193  }
194  for ($i = 216; $i <= 246; $i++) {
195  $password .= chr($i);
196  }
197  for ($i = 248; $i <= 255; $i++) {
198  $password .= chr($i);
199  }
200  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
201  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
202  }
203 
208  {
209  $password = 'password';
210  $password1 = $password . 'INVALID';
211  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
212  $this->assertFalse($this->objectInstance->checkPassword($password1, $saltedHashPassword));
213  }
214 
219  {
220  $pad = 'a';
221  $criticalPwLength = 0;
222  // We're using a constant salt.
223  $saltedHashPasswordCurrent = $salt = $this->objectInstance->getHashedPassword($pad);
224  for ($i = 0; $i <= 128; $i += 8) {
225  $password = str_repeat($pad, max($i, 1));
226  $saltedHashPasswordPrevious = $saltedHashPasswordCurrent;
227  $saltedHashPasswordCurrent = $this->objectInstance->getHashedPassword($password, $salt);
228  if ($i > 0 && $saltedHashPasswordPrevious === $saltedHashPasswordCurrent) {
229  $criticalPwLength = $i;
230  break;
231  }
232  }
233  $this->assertTrue($criticalPwLength == 0 || $criticalPwLength > 32, 'Duplicates of hashed passwords with plaintext password of length ' . $criticalPwLength . '+.');
234  }
235 
239  public function modifiedMinHashCount()
240  {
241  $minHashCount = $this->objectInstance->getMinHashCount();
242  $this->objectInstance->setMinHashCount($minHashCount - 1);
243  $this->assertTrue($this->objectInstance->getMinHashCount() < $minHashCount);
244  $this->objectInstance->setMinHashCount($minHashCount + 1);
245  $this->assertTrue($this->objectInstance->getMinHashCount() > $minHashCount);
246  }
247 
251  public function modifiedMaxHashCount()
252  {
253  $maxHashCount = $this->objectInstance->getMaxHashCount();
254  $this->objectInstance->setMaxHashCount($maxHashCount + 1);
255  $this->assertTrue($this->objectInstance->getMaxHashCount() > $maxHashCount);
256  $this->objectInstance->setMaxHashCount($maxHashCount - 1);
257  $this->assertTrue($this->objectInstance->getMaxHashCount() < $maxHashCount);
258  }
259 
263  public function modifiedHashCount()
264  {
265  $hashCount = $this->objectInstance->getHashCount();
266  $this->objectInstance->setMaxHashCount($hashCount + 1);
267  $this->objectInstance->setHashCount($hashCount + 1);
268  $this->assertTrue($this->objectInstance->getHashCount() > $hashCount);
269  $this->objectInstance->setMinHashCount($hashCount - 1);
270  $this->objectInstance->setHashCount($hashCount - 1);
271  $this->assertTrue($this->objectInstance->getHashCount() < $hashCount);
272  // reset hashcount
273  $this->objectInstance->setHashCount(null);
274  }
275 
280  {
281  $password = 'password';
282  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
283  $this->assertFalse($this->objectInstance->isHashUpdateNeeded($saltedHashPassword));
284  }
285 
290  {
291  $password = 'password';
292  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
293  $increasedHashCount = $this->objectInstance->getHashCount() + 1;
294  $this->objectInstance->setMaxHashCount($increasedHashCount);
295  $this->objectInstance->setHashCount($increasedHashCount);
296  $this->assertTrue($this->objectInstance->isHashUpdateNeeded($saltedHashPassword));
297  // reset hashcount
298  $this->objectInstance->setHashCount(null);
299  }
300 
305  {
306  $password = 'password';
307  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
308  $decreasedHashCount = $this->objectInstance->getHashCount() - 1;
309  $this->objectInstance->setMinHashCount($decreasedHashCount);
310  $this->objectInstance->setHashCount($decreasedHashCount);
311  $this->assertFalse($this->objectInstance->isHashUpdateNeeded($saltedHashPassword));
312  // reset hashcount
313  $this->objectInstance->setHashCount(null);
314  }
315 }
static generateRandomBytes($bytesToReturn)