ILIAS  release_5-0 Revision 5.0.0-1144-gc4397b1f870
ilBcryptPasswordEncoderTest.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2014 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once 'Services/Password/classes/encoders/class.ilBcryptPasswordEncoder.php';
5
12{
16 const VALID_COSTS = '08';
17
21 const PASSWORD = 'password';
22
26 const WRONG_PASSWORD = 'wrong_password';
27
31 const CLIENT_SALT = 'homer!12345_/';
32
36 const PASSWORD_SALT = 'salt';
37
41 protected $test_directory;
42
46 public function getTestDirectory()
47 {
49 }
50
55 {
56 $this->test_directory = $test_directory;
57 }
58
62 private function isVsfStreamInstalled()
63 {
64 return @include_once('vfsStream.php');
65 }
66
70 protected function setUp()
71 {
72 if($this->isVsfStreamInstalled())
73 {
74 vfsStream::setup();
75 $this->setTestDirectory(vfsStream::newDirectory('tests')->at(vfsStreamWrapper::getRoot()));
76 define('CLIENT_DATA_DIR', vfsStream::url('root/tests'));
77 }
78 parent::setUp();
79 }
80
84 public function testInstanceCanBeCreated()
85 {
86 $security_flaw_ignoring_encoder = new ilBcryptPasswordEncoder(array(
87 'ignore_security_flaw' => true
88 ));
89 $this->assertTrue($security_flaw_ignoring_encoder->isSecurityFlawIgnored());
90
91 $security_flaw_respecting_encoder = new ilBcryptPasswordEncoder(array(
92 'ignore_security_flaw' => false
93 ));
94 $this->assertFalse($security_flaw_respecting_encoder->isSecurityFlawIgnored());
95
96 $encoder = new ilBcryptPasswordEncoder(array(
97 'cost' => self::VALID_COSTS
98 ));
99 $this->assertInstanceOf('ilBcryptPasswordEncoder', $encoder);
100 $this->assertEquals(self::VALID_COSTS, $encoder->getCosts());
101 $this->assertFalse($encoder->isSecurityFlawIgnored());
102 $encoder->setClientSalt(self::CLIENT_SALT);
103 return $encoder;
104 }
105
110 {
111 $encoder->setCosts(4);
112 $this->assertEquals(4, $encoder->getCosts());
113 }
114
120 {
121 $encoder->setCosts(32);
122 }
123
129 {
130 $encoder->setCosts(3);
131 }
132
137 public function testCostsCanBeSetInRange($costs, ilBcryptPasswordEncoder $encoder)
138 {
139 $encoder->setCosts($costs);
140 }
141
145 public function costsProvider()
146 {
147 $data = array();
148 for($i = 4; $i <= 31; $i++)
149 {
150 $data[] = array($i);
151 }
152 return $data;
153 }
154
159 {
160 $encoder->setCosts(self::VALID_COSTS);
161 $encoded_password = $encoder->encodePassword(self::PASSWORD, self::PASSWORD_SALT);
162 $this->assertTrue($encoder->isPasswordValid($encoded_password, self::PASSWORD, self::PASSWORD_SALT));
163 $this->assertFalse($encoder->isPasswordValid($encoded_password, self::WRONG_PASSWORD, self::PASSWORD_SALT));
164 return $encoder;
165 }
166
172 {
173 $encoder->setCosts(self::VALID_COSTS);
174 $encoder->encodePassword(str_repeat('a', 5000), self::PASSWORD_SALT);
175 }
176
181 {
182 $encoder->setCosts(self::VALID_COSTS);
183 $this->assertFalse($encoder->isPasswordValid('encoded', str_repeat('a', 5000), self::PASSWORD_SALT));
184 }
185
190 {
191 $encoder = new ilBcryptPasswordEncoder();
192 $encoder->setClientSalt(null);
193 $encoder->setCosts(self::VALID_COSTS);
194 $encoder->encodePassword(self::PASSWORD, self::PASSWORD_SALT);
195 }
196
201 {
202 $encoder = new ilBcryptPasswordEncoder();
203 $encoder->setClientSalt(null);
204 $encoder->setCosts(self::VALID_COSTS);
205 $encoder->isPasswordValid('12121212', self::PASSWORD, self::PASSWORD_SALT);
206 }
207
212 {
214
215 $this->getTestDirectory()->chmod(0777);
216 vfsStream::newFile(ilBcryptPasswordEncoder::SALT_STORAGE_FILENAME)->withContent(self::CLIENT_SALT)->at($this->getTestDirectory());
217
218 $encoder = new ilBcryptPasswordEncoder();
219 $this->assertEquals(self::CLIENT_SALT, $encoder->getClientSalt());
220 }
221
226 {
227 $encoder = new ilBcryptPasswordEncoder();
228 $encoder->setBackwardCompatibility(true);
229 $this->assertTrue($encoder->isBackwardCompatibilityEnabled());
230 $encoder->setBackwardCompatibility(false);
231 $this->assertFalse($encoder->isBackwardCompatibilityEnabled());
232 }
233
238 {
240
241 $encoder = new ilBcryptPasswordEncoder();
242 $encoder->setClientSalt(self::CLIENT_SALT);
243 $encoder->setBackwardCompatibility(true);
244 $encoded_password = $encoder->encodePassword(self::PASSWORD, self::PASSWORD_SALT);
245 $this->assertTrue($encoder->isPasswordValid($encoded_password, self::PASSWORD, self::PASSWORD_SALT));
246 $this->assertEquals('$2a$', substr($encoded_password, 0, 4));
247
248 $another_encoder = new ilBcryptPasswordEncoder();
249 $another_encoder->setClientSalt(self::CLIENT_SALT);
250 $another_encoder->setBackwardCompatibility(false);
251 $another_encoded_password = $another_encoder->encodePassword(self::PASSWORD, self::PASSWORD_SALT);
252 $this->assertEquals('$2y$', substr($another_encoded_password, 0, 4));
253 $this->assertTrue($another_encoder->isPasswordValid($encoded_password, self::PASSWORD, self::PASSWORD_SALT));
254 }
255
260 {
261 if(version_compare(phpversion(), '5.3.7', '<'))
262 {
263 $this->markTestSkipped('Requires PHP >= 5.3.7');
264 }
265 }
266
271 {
272 if(!$this->isVsfStreamInstalled())
273 {
274 $this->markTestSkipped('Requires vfsStream (http://vfs.bovigo.org)');
275 }
276 }
277
282 {
283 $encoder = new ilBcryptPasswordEncoder();
284 $encoder->setClientSalt(self::CLIENT_SALT);
285 $encoder->setBackwardCompatibility(true);
286 $encoder->encodePassword(self::PASSWORD . chr(195), self::PASSWORD_SALT);
287 }
288
293 {
294 $encoder = new ilBcryptPasswordEncoder();
295 $encoder->setClientSalt(self::CLIENT_SALT);
296 $encoder->setBackwardCompatibility(true);
297 $encoder->setIsSecurityFlawIgnored(true);
298 $encoder->encodePassword(self::PASSWORD . chr(195), self::PASSWORD_SALT);
299 }
300
304 public function testNameShouldBeBcrypt()
305 {
306 $encoder = new ilBcryptPasswordEncoder();
307 $this->assertEquals('bcrypt', $encoder->getName());
308 }
309}
testPasswordVerificationShouldFailIfTheRawPasswordExceedsTheSupportedLength(ilBcryptPasswordEncoder $encoder)
@depends testInstanceCanBeCreated
testPasswordShouldBeCorrectlyEncodedAndVerified(ilBcryptPasswordEncoder $encoder)
@depends testInstanceCanBeCreated
testCostsCanBeRetrievedWhenCostsAreSet(ilBcryptPasswordEncoder $encoder)
@depends testInstanceCanBeCreated
testCostsCannotBeSetBelowRange(ilBcryptPasswordEncoder $encoder)
@depends testInstanceCanBeCreated @expectedException ilPasswordException
testCostsCanBeSetInRange($costs, ilBcryptPasswordEncoder $encoder)
@depends testInstanceCanBeCreated @dataProvider costsProvider
testExceptionIsRaisedIfSaltIsMissingIsOnEncoding()
@expectedException ilPasswordException
testExceptionIsRaisedIfTheRawPasswordContainsA8BitCharacterAndBackwardCompatibilityIsEnabled()
@expectedException ilPasswordException
testExceptionIsRaisedIfSaltIsMissingIsOnVerification()
@expectedException ilPasswordException
testExceptionIsNotRaisedIfTheRawPasswordContainsA8BitCharacterAndBackwardCompatibilityIsEnabledWithIgnoredSecurityFlaw()
testExceptionIsRaisedIfThePasswordExceedsTheSupportedLengthOnEncoding(ilBcryptPasswordEncoder $encoder)
@depends testInstanceCanBeCreated @expectedException ilPasswordException
testCostsCannotBeSetAboveRange(ilBcryptPasswordEncoder $encoder)
@depends testInstanceCanBeCreated @expectedException ilPasswordException
encodePassword($raw, $salt)
{Encodes the raw password.string The encoded password}
isPasswordValid($encoded, $raw, $salt)
{Checks a raw password against an encoded password.The raw password has to be injected into the encod...