TYPO3 CMS  TYPO3_8-7
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 
18 
22 class PhpassSaltTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
23 {
29  protected $objectInstance = null;
30 
34  protected function setUp()
35  {
36  $this->objectInstance = $this->getMockBuilder(\TYPO3\CMS\Saltedpasswords\Salt\PhpassSalt::class)
37  ->setMethods(['dummy'])
38  ->getMock();
39  }
40 
44  public function hasCorrectBaseClass()
45  {
46  $hasCorrectBaseClass = get_class($this->objectInstance) === \TYPO3\CMS\Saltedpasswords\Salt\PhpassSalt::class;
47  // XCLASS ?
48  if (!$hasCorrectBaseClass && false != get_parent_class($this->objectInstance)) {
49  $hasCorrectBaseClass = is_subclass_of($this->objectInstance, \TYPO3\CMS\Saltedpasswords\Salt\PhpassSalt::class);
50  }
51  $this->assertTrue($hasCorrectBaseClass);
52  }
53 
57  public function nonZeroSaltLength()
58  {
59  $this->assertTrue($this->objectInstance->getSaltLength() > 0);
60  }
61 
66  {
67  $password = '';
68  $this->assertNull($this->objectInstance->getHashedPassword($password));
69  }
70 
75  {
76  $password = 'a';
77  $this->assertNotNull($this->objectInstance->getHashedPassword($password));
78  }
79 
84  {
85  $password = 'password';
86  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
87  $this->assertTrue($this->objectInstance->isValidSaltedPW($saltedHashPassword));
88  }
89 
94  {
95  $password = 'password';
96  // custom salt without setting
97  $randomBytes = (new Random())->generateRandomBytes($this->objectInstance->getSaltLength());
98  $salt = $this->objectInstance->base64Encode($randomBytes, $this->objectInstance->getSaltLength());
99  $this->assertTrue($this->objectInstance->isValidSalt($salt));
100  $saltedHashPassword = $this->objectInstance->getHashedPassword($password, $salt);
101  $this->assertTrue($this->objectInstance->isValidSaltedPW($saltedHashPassword));
102  }
103 
108  {
109  $password = 'password';
110  $minHashCount = $this->objectInstance->getMinHashCount();
111  $this->objectInstance->setHashCount($minHashCount);
112  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
113  $this->assertTrue($this->objectInstance->isValidSaltedPW($saltedHashPassword));
114  // reset hashcount
115  $this->objectInstance->setHashCount(null);
116  }
117 
127  {
128  $password = 'password';
129  $saltedHashPassword = '$P$C7u7E10SBEie/Jbdz0jDtUcWhzgOPF.';
130  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
131  }
132 
139  {
140  $password = 'password';
141  $saltedHashPassword = '$P$C7u7E10SBEie/Jbdz0jDtUcWhzgOPF';
142  $this->assertFalse($this->objectInstance->checkPassword($password, $saltedHashPassword));
143  }
144 
154  {
155  $password = 'aEjOtY';
156  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
157  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
158  }
159 
169  {
170  $password = '01369';
171  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
172  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
173  }
174 
184  {
185  $password = ' !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~';
186  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
187  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
188  }
189 
199  {
200  $password = '';
201  for ($i = 160; $i <= 191; $i++) {
202  $password .= chr($i);
203  }
204  $password .= chr(215) . chr(247);
205  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
206  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
207  }
208 
218  {
219  $password = '';
220  for ($i = 192; $i <= 214; $i++) {
221  $password .= chr($i);
222  }
223  for ($i = 216; $i <= 246; $i++) {
224  $password .= chr($i);
225  }
226  for ($i = 248; $i <= 255; $i++) {
227  $password .= chr($i);
228  }
229  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
230  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
231  }
232 
237  {
238  $password = 'password';
239  $password1 = $password . 'INVALID';
240  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
241  $this->assertFalse($this->objectInstance->checkPassword($password1, $saltedHashPassword));
242  }
243 
248  {
249  $pad = 'a';
250  $criticalPwLength = 0;
251  // We're using a constant salt.
252  $saltedHashPasswordCurrent = $salt = $this->objectInstance->getHashedPassword($pad);
253  for ($i = 0; $i <= 128; $i += 8) {
254  $password = str_repeat($pad, max($i, 1));
255  $saltedHashPasswordPrevious = $saltedHashPasswordCurrent;
256  $saltedHashPasswordCurrent = $this->objectInstance->getHashedPassword($password, $salt);
257  if ($i > 0 && $saltedHashPasswordPrevious === $saltedHashPasswordCurrent) {
258  $criticalPwLength = $i;
259  break;
260  }
261  }
262  $this->assertTrue($criticalPwLength == 0 || $criticalPwLength > 32, 'Duplicates of hashed passwords with plaintext password of length ' . $criticalPwLength . '+.');
263  }
264 
268  public function modifiedMinHashCount()
269  {
270  $minHashCount = $this->objectInstance->getMinHashCount();
271  $this->objectInstance->setMinHashCount($minHashCount - 1);
272  $this->assertTrue($this->objectInstance->getMinHashCount() < $minHashCount);
273  $this->objectInstance->setMinHashCount($minHashCount + 1);
274  $this->assertTrue($this->objectInstance->getMinHashCount() > $minHashCount);
275  }
276 
280  public function modifiedMaxHashCount()
281  {
282  $maxHashCount = $this->objectInstance->getMaxHashCount();
283  $this->objectInstance->setMaxHashCount($maxHashCount + 1);
284  $this->assertTrue($this->objectInstance->getMaxHashCount() > $maxHashCount);
285  $this->objectInstance->setMaxHashCount($maxHashCount - 1);
286  $this->assertTrue($this->objectInstance->getMaxHashCount() < $maxHashCount);
287  }
288 
292  public function modifiedHashCount()
293  {
294  $hashCount = $this->objectInstance->getHashCount();
295  $this->objectInstance->setMaxHashCount($hashCount + 1);
296  $this->objectInstance->setHashCount($hashCount + 1);
297  $this->assertTrue($this->objectInstance->getHashCount() > $hashCount);
298  $this->objectInstance->setMinHashCount($hashCount - 1);
299  $this->objectInstance->setHashCount($hashCount - 1);
300  $this->assertTrue($this->objectInstance->getHashCount() < $hashCount);
301  // reset hashcount
302  $this->objectInstance->setHashCount(null);
303  }
304 
309  {
310  $password = 'password';
311  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
312  $this->assertFalse($this->objectInstance->isHashUpdateNeeded($saltedHashPassword));
313  }
314 
319  {
320  $password = 'password';
321  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
322  $increasedHashCount = $this->objectInstance->getHashCount() + 1;
323  $this->objectInstance->setMaxHashCount($increasedHashCount);
324  $this->objectInstance->setHashCount($increasedHashCount);
325  $this->assertTrue($this->objectInstance->isHashUpdateNeeded($saltedHashPassword));
326  // reset hashcount
327  $this->objectInstance->setHashCount(null);
328  }
329 
334  {
335  $password = 'password';
336  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
337  $decreasedHashCount = $this->objectInstance->getHashCount() - 1;
338  $this->objectInstance->setMinHashCount($decreasedHashCount);
339  $this->objectInstance->setHashCount($decreasedHashCount);
340  $this->assertFalse($this->objectInstance->isHashUpdateNeeded($saltedHashPassword));
341  // reset hashcount
342  $this->objectInstance->setHashCount(null);
343  }
344 }