TYPO3 CMS  TYPO3_7-6
BlowfishSaltTest.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\BlowfishSalt::class, ['dummy']);
37  }
38 
44  protected function skipTestIfBlowfishIsNotAvailable()
45  {
46  if (!CRYPT_BLOWFISH) {
47  $this->markTestSkipped('Blowfish is not supported on your platform.');
48  }
49  }
50 
54  public function hasCorrectBaseClass()
55  {
56  $hasCorrectBaseClass = get_class($this->objectInstance) === \TYPO3\CMS\Saltedpasswords\Salt\BlowfishSalt::class;
57  // XCLASS ?
58  if (!$hasCorrectBaseClass && false != get_parent_class($this->objectInstance)) {
59  $hasCorrectBaseClass = is_subclass_of($this->objectInstance, \TYPO3\CMS\Saltedpasswords\Salt\BlowfishSalt::class);
60  }
61  $this->assertTrue($hasCorrectBaseClass);
62  }
63 
67  public function nonZeroSaltLength()
68  {
69  $this->assertTrue($this->objectInstance->getSaltLength() > 0);
70  }
71 
76  {
77  $password = '';
78  $this->assertNull($this->objectInstance->getHashedPassword($password));
79  }
80 
85  {
87  $password = 'a';
88  $this->assertNotNull($this->objectInstance->getHashedPassword($password));
89  }
90 
95  {
97  $password = 'password';
98  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
99  $this->assertTrue($this->objectInstance->isValidSaltedPW($saltedHashPassword));
100  }
101 
106  {
108  $password = 'password';
109  // custom salt without setting
110  $randomBytes = \TYPO3\CMS\Core\Utility\GeneralUtility::generateRandomBytes($this->objectInstance->getSaltLength());
111  $salt = $this->objectInstance->base64Encode($randomBytes, $this->objectInstance->getSaltLength());
112  $this->assertTrue($this->objectInstance->isValidSalt($salt));
113  $saltedHashPassword = $this->objectInstance->getHashedPassword($password, $salt);
114  $this->assertTrue($this->objectInstance->isValidSaltedPW($saltedHashPassword));
115  }
116 
121  {
123  $password = 'password';
124  $minHashCount = $this->objectInstance->getMinHashCount();
125  $this->objectInstance->setHashCount($minHashCount);
126  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
127  $this->assertTrue($this->objectInstance->isValidSaltedPW($saltedHashPassword));
128  // reset hashcount
129  $this->objectInstance->setHashCount(null);
130  }
131 
141  {
143  $password = 'aEjOtY';
144  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
145  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
146  }
147 
157  {
159  $password = '01369';
160  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
161  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
162  }
163 
173  {
175  $password = ' !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~';
176  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
177  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
178  }
179 
189  {
191  $password = '';
192  for ($i = 160; $i <= 191; $i++) {
193  $password .= chr($i);
194  }
195  $password .= chr(215) . chr(247);
196  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
197  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
198  }
199 
209  {
211  $password = '';
212  for ($i = 192; $i <= 214; $i++) {
213  $password .= chr($i);
214  }
215  for ($i = 216; $i <= 246; $i++) {
216  $password .= chr($i);
217  }
218  for ($i = 248; $i <= 255; $i++) {
219  $password .= chr($i);
220  }
221  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
222  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword));
223  }
224 
229  {
231  $password = 'password';
232  $password1 = $password . 'INVALID';
233  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
234  $this->assertFalse($this->objectInstance->checkPassword($password1, $saltedHashPassword));
235  }
236 
241  {
243  $pad = 'a';
244  $password = '';
245  $criticalPwLength = 0;
246  // We're using a constant salt.
247  $saltedHashPasswordCurrent = $salt = $this->objectInstance->getHashedPassword($pad);
248  for ($i = 0; $i <= 128; $i += 8) {
249  $password = str_repeat($pad, max($i, 1));
250  $saltedHashPasswordPrevious = $saltedHashPasswordCurrent;
251  $saltedHashPasswordCurrent = $this->objectInstance->getHashedPassword($password, $salt);
252  if ($i > 0 && $saltedHashPasswordPrevious === $saltedHashPasswordCurrent) {
253  $criticalPwLength = $i;
254  break;
255  }
256  }
257  $this->assertTrue($criticalPwLength == 0 || $criticalPwLength > 32, 'Duplicates of hashed passwords with plaintext password of length ' . $criticalPwLength . '+.');
258  }
259 
263  public function modifiedMinHashCount()
264  {
265  $minHashCount = $this->objectInstance->getMinHashCount();
266  $this->objectInstance->setMinHashCount($minHashCount - 1);
267  $this->assertTrue($this->objectInstance->getMinHashCount() < $minHashCount);
268  $this->objectInstance->setMinHashCount($minHashCount + 1);
269  $this->assertTrue($this->objectInstance->getMinHashCount() > $minHashCount);
270  }
271 
275  public function modifiedMaxHashCount()
276  {
277  $maxHashCount = $this->objectInstance->getMaxHashCount();
278  $this->objectInstance->setMaxHashCount($maxHashCount + 1);
279  $this->assertTrue($this->objectInstance->getMaxHashCount() > $maxHashCount);
280  $this->objectInstance->setMaxHashCount($maxHashCount - 1);
281  $this->assertTrue($this->objectInstance->getMaxHashCount() < $maxHashCount);
282  }
283 
287  public function modifiedHashCount()
288  {
289  $hashCount = $this->objectInstance->getHashCount();
290  $this->objectInstance->setMaxHashCount($hashCount + 1);
291  $this->objectInstance->setHashCount($hashCount + 1);
292  $this->assertTrue($this->objectInstance->getHashCount() > $hashCount);
293  $this->objectInstance->setMinHashCount($hashCount - 1);
294  $this->objectInstance->setHashCount($hashCount - 1);
295  $this->assertTrue($this->objectInstance->getHashCount() < $hashCount);
296  // reset hashcount
297  $this->objectInstance->setHashCount(null);
298  }
299 
304  {
306  $password = 'password';
307  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
308  $this->assertFalse($this->objectInstance->isHashUpdateNeeded($saltedHashPassword));
309  }
310 
315  {
316  $password = 'password';
317  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
318  $increasedHashCount = $this->objectInstance->getHashCount() + 1;
319  $this->objectInstance->setMaxHashCount($increasedHashCount);
320  $this->objectInstance->setHashCount($increasedHashCount);
321  $this->assertTrue($this->objectInstance->isHashUpdateNeeded($saltedHashPassword));
322  // reset hashcount
323  $this->objectInstance->setHashCount(null);
324  }
325 
330  {
332  $password = 'password';
333  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
334  $decreasedHashCount = $this->objectInstance->getHashCount() - 1;
335  $this->objectInstance->setMinHashCount($decreasedHashCount);
336  $this->objectInstance->setHashCount($decreasedHashCount);
337  $this->assertFalse($this->objectInstance->isHashUpdateNeeded($saltedHashPassword));
338  // reset hashcount
339  $this->objectInstance->setHashCount(null);
340  }
341 }
static generateRandomBytes($bytesToReturn)