TYPO3 CMS  TYPO3_7-6
Md5SaltTest.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\Md5Salt::class, ['dummy']);
37  }
38 
44  protected function getWarningWhenMethodUnavailable()
45  {
46  $warningMsg = '';
47  if (!CRYPT_MD5) {
48  $warningMsg = 'MD5 is not supported on your platform. ' . 'Then, some of the md5 tests will fail.';
49  }
50  return $warningMsg;
51  }
52 
56  public function hasCorrectBaseClass()
57  {
58  $hasCorrectBaseClass = get_class($this->objectInstance) === \TYPO3\CMS\Saltedpasswords\Salt\Md5Salt::class;
59  // XCLASS ?
60  if (!$hasCorrectBaseClass && false != get_parent_class($this->objectInstance)) {
61  $hasCorrectBaseClass = is_subclass_of($this->objectInstance, \TYPO3\CMS\Saltedpasswords\Salt\Md5Salt::class);
62  }
63  $this->assertTrue($hasCorrectBaseClass);
64  }
65 
69  public function nonZeroSaltLength()
70  {
71  $this->assertTrue($this->objectInstance->getSaltLength() > 0);
72  }
73 
78  {
79  $password = '';
80  $this->assertNull($this->objectInstance->getHashedPassword($password));
81  }
82 
87  {
88  $password = 'a';
89  $this->assertNotNull($this->objectInstance->getHashedPassword($password), $this->getWarningWhenMethodUnavailable());
90  }
91 
96  {
97  $password = 'password';
98  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
99  $this->assertTrue($this->objectInstance->isValidSaltedPW($saltedHashPassword), $this->getWarningWhenMethodUnavailable());
100  }
101 
106  {
107  $password = 'password';
108  // custom salt without setting
109  $randomBytes = \TYPO3\CMS\Core\Utility\GeneralUtility::generateRandomBytes($this->objectInstance->getSaltLength());
110  $salt = $this->objectInstance->base64Encode($randomBytes, $this->objectInstance->getSaltLength());
111  $this->assertTrue($this->objectInstance->isValidSalt($salt), $this->getWarningWhenMethodUnavailable());
112  $saltedHashPassword = $this->objectInstance->getHashedPassword($password, $salt);
113  $this->assertTrue($this->objectInstance->isValidSaltedPW($saltedHashPassword), $this->getWarningWhenMethodUnavailable());
114  }
115 
125  {
126  $password = 'aEjOtY';
127  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
128  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword), $this->getWarningWhenMethodUnavailable());
129  }
130 
140  {
141  $password = '01369';
142  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
143  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword), $this->getWarningWhenMethodUnavailable());
144  }
145 
155  {
156  $password = ' !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~';
157  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
158  $this->assertTrue($this->objectInstance->checkPassword($password, $saltedHashPassword), $this->getWarningWhenMethodUnavailable());
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), $this->getWarningWhenMethodUnavailable());
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), $this->getWarningWhenMethodUnavailable());
202  }
203 
208  {
209  $password = 'password';
210  $password1 = $password . 'INVALID';
211  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
212  $this->assertFalse($this->objectInstance->checkPassword($password1, $saltedHashPassword), $this->getWarningWhenMethodUnavailable());
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, $this->getWarningWhenMethodUnavailable() . 'Duplicates of hashed passwords with plaintext password of length ' . $criticalPwLength . '+.');
234  }
235 
239  public function noUpdateNecessityForMd5()
240  {
241  $password = 'password';
242  $saltedHashPassword = $this->objectInstance->getHashedPassword($password);
243  $this->assertFalse($this->objectInstance->isHashUpdateNeeded($saltedHashPassword));
244  }
245 }
static generateRandomBytes($bytesToReturn)