diff --git a/composer.json b/composer.json index 6911dc2..20bcd21 100644 --- a/composer.json +++ b/composer.json @@ -24,8 +24,8 @@ "phpunit/phpunit": "@stable" }, "suggest": { - "bacon/bacon-qr-code": "Needed for BaconQrCodeProvider provider", - "endroid/qr-code": "Needed for EndroidQrCodeProvider" + "bacon/bacon-qr-code": "Needed for BaconQrCodeProvider provider", + "endroid/qr-code": "Needed for EndroidQrCodeProvider" }, "autoload": { "psr-4": { @@ -34,7 +34,7 @@ }, "autoload-dev": { "psr-4": { - "RobThree\\Auth\\Test\\": "tests" + "Tests\\": "tests/" } } } diff --git a/tests/MightNotMakeAssertions.php b/tests/MightNotMakeAssertions.php new file mode 100644 index 0000000..17e1076 --- /dev/null +++ b/tests/MightNotMakeAssertions.php @@ -0,0 +1,23 @@ +assertTrue(true); + } +} diff --git a/tests/Providers/Qr/IQRCodeProviderTest.php b/tests/Providers/Qr/IQRCodeProviderTest.php new file mode 100644 index 0000000..4ba9f14 --- /dev/null +++ b/tests/Providers/Qr/IQRCodeProviderTest.php @@ -0,0 +1,45 @@ +[\w\.\-\/]+);(?P\w+),(?P.*)/', $datauri, $m) === 1) { + return array( + 'mimetype' => $m['mimetype'], + 'encoding' => $m['encoding'], + 'data' => base64_decode($m['data']) + ); + } + + return null; + } + + public function testTotpUriIsCorrect() + { + $qr = new TestQrProvider(); + + $tfa = new TwoFactorAuth('Test&Issuer', 6, 30, 'sha1', $qr); + $data = $this->DecodeDataUri($tfa->getQRCodeImageAsDataUri('Test&Label', 'VMR466AB62ZBOKHE')); + $this->assertEquals('test/test', $data['mimetype']); + $this->assertEquals('base64', $data['encoding']); + $this->assertEquals('otpauth://totp/Test%26Label?secret=VMR466AB62ZBOKHE&issuer=Test%26Issuer&period=30&algorithm=SHA1&digits=6@200', $data['data']); + } + + public function testGetQRCodeImageAsDataUriThrowsOnInvalidSize() + { + $qr = new TestQrProvider(); + + $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', $qr); + + $this->expectException(TwoFactorAuthException::class); + + $tfa->getQRCodeImageAsDataUri('Test', 'VMR466AB62ZBOKHE', 0); + } +} diff --git a/tests/Providers/Qr/TestQrProvider.php b/tests/Providers/Qr/TestQrProvider.php new file mode 100644 index 0000000..e8d80d0 --- /dev/null +++ b/tests/Providers/Qr/TestQrProvider.php @@ -0,0 +1,18 @@ +rngTestLengths as $l) { + $this->assertEquals($l, strlen($rng->getRandomBytes($l))); + } + $this->assertTrue($rng->isCryptographicallySecure()); + } else { + $this->noAssertionsMade(); + } + } +} diff --git a/tests/Providers/Rng/HashRNGProviderTest.php b/tests/Providers/Rng/HashRNGProviderTest.php new file mode 100644 index 0000000..e96def0 --- /dev/null +++ b/tests/Providers/Rng/HashRNGProviderTest.php @@ -0,0 +1,21 @@ +rngTestLengths as $l) { + $this->assertEquals($l, strlen($rng->getRandomBytes($l))); + } + + $this->assertFalse($rng->isCryptographicallySecure()); + } +} diff --git a/tests/Providers/Rng/IRNGProviderTest.php b/tests/Providers/Rng/IRNGProviderTest.php new file mode 100644 index 0000000..697d137 --- /dev/null +++ b/tests/Providers/Rng/IRNGProviderTest.php @@ -0,0 +1,49 @@ +expectException(TwoFactorAuthException::class); + $tfa->createSecret(); + } + + public function testCreateSecretOverrideSecureDoesNotThrowOnInsecureRNG() + { + $rng = new TestRNGProvider(); + + $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng); + $this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret(80, false)); + } + + public function testCreateSecretDoesNotThrowOnSecureRNGProvider() + { + $rng = new TestRNGProvider(true); + + $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng); + $this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret()); + } + + public function testCreateSecretGeneratesDesiredAmountOfEntropy() + { + $rng = new TestRNGProvider(true); + + $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng); + $this->assertEquals('A', $tfa->createSecret(5)); + $this->assertEquals('AB', $tfa->createSecret(6)); + $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ', $tfa->createSecret(128)); + $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', $tfa->createSecret(160)); + $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', $tfa->createSecret(320)); + $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567ABCDEFGHIJKLMNOPQRSTUVWXYZ234567A', $tfa->createSecret(321)); + } +} diff --git a/tests/Providers/Rng/MCryptRNGProviderTest.php b/tests/Providers/Rng/MCryptRNGProviderTest.php new file mode 100644 index 0000000..7d63f95 --- /dev/null +++ b/tests/Providers/Rng/MCryptRNGProviderTest.php @@ -0,0 +1,30 @@ +rngTestLengths as $l) { + $this->assertEquals($l, strlen($rng->getRandomBytes($l))); + } + + $this->assertTrue($rng->isCryptographicallySecure()); + } else { + $this->noAssertionsMade(); + } + } +} diff --git a/tests/Providers/Rng/NeedsRngLengths.php b/tests/Providers/Rng/NeedsRngLengths.php new file mode 100644 index 0000000..9a6360b --- /dev/null +++ b/tests/Providers/Rng/NeedsRngLengths.php @@ -0,0 +1,8 @@ +rngTestLengths as $l) { + $this->assertEquals($l, strlen($rng->getRandomBytes($l))); + } + + $this->assertTrue($rng->isCryptographicallySecure()); + } + + public function testNonStrongOpenSSLRNGProvidersReturnExpectedNumberOfBytes() + { + $rng = new OpenSSLRNGProvider(false); + foreach ($this->rngTestLengths as $l) { + $this->assertEquals($l, strlen($rng->getRandomBytes($l))); + } + + $this->assertFalse($rng->isCryptographicallySecure()); + } +} diff --git a/tests/Providers/Rng/TestRNGProvider.php b/tests/Providers/Rng/TestRNGProvider.php new file mode 100644 index 0000000..1882c5b --- /dev/null +++ b/tests/Providers/Rng/TestRNGProvider.php @@ -0,0 +1,31 @@ +isSecure = $isSecure; + } + + public function getRandomBytes($bytecount) + { + $result = ''; + + for ($i = 0; $i < $bytecount; $i++) { + $result .= chr($i); + } + + return $result; + } + + public function isCryptographicallySecure() + { + return $this->isSecure; + } +} diff --git a/tests/Providers/Time/ITimeProviderTest.php b/tests/Providers/Time/ITimeProviderTest.php new file mode 100644 index 0000000..313de3c --- /dev/null +++ b/tests/Providers/Time/ITimeProviderTest.php @@ -0,0 +1,44 @@ +ensureCorrectTime(array($tpr2)); // 128 - 123 = 5 => within default leniency + + $this->noAssertionsMade(); + } + + public function testEnsureCorrectTimeThrowsOnIncorrectTime() + { + $tpr1 = new TestTimeProvider(123); + $tpr2 = new TestTimeProvider(124); + + $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, null, $tpr1); + + $this->expectException(TwoFactorAuthException::class); + + $tfa->ensureCorrectTime(array($tpr2), 0); // We force a leniency of 0, 124-123 = 1 so this should throw + } + + public function testEnsureDefaultTimeProviderReturnsCorrectTime() + { + $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1'); + $tfa->ensureCorrectTime(array(new TestTimeProvider(time())), 1); // Use a leniency of 1, should the time change between both time() calls + + $this->noAssertionsMade(); + } +} diff --git a/tests/Providers/Time/TestTimeProvider.php b/tests/Providers/Time/TestTimeProvider.php new file mode 100644 index 0000000..6c95532 --- /dev/null +++ b/tests/Providers/Time/TestTimeProvider.php @@ -0,0 +1,20 @@ +time = $time; + } + + public function getTime() + { + return $this->time; + } +} diff --git a/tests/TwoFactorAuthTest.php b/tests/TwoFactorAuthTest.php index e011fc4..0beb74c 100644 --- a/tests/TwoFactorAuthTest.php +++ b/tests/TwoFactorAuthTest.php @@ -1,221 +1,121 @@ expectException(TwoFactorAuthException::class); new TwoFactorAuth('Test', 0); } - /** - * @expectedException \RobThree\Auth\TwoFactorAuthException - */ - public function testConstructorThrowsOnInvalidPeriod() { + public function testConstructorThrowsOnInvalidPeriod() + { + $this->expectException(TwoFactorAuthException::class); new TwoFactorAuth('Test', 6, 0); } - /** - * @expectedException \RobThree\Auth\TwoFactorAuthException - */ - public function testConstructorThrowsOnInvalidAlgorithm() { + public function testConstructorThrowsOnInvalidAlgorithm() + { + $this->expectException(TwoFactorAuthException::class); new TwoFactorAuth('Test', 6, 30, 'xxx'); } - public function testGetCodeReturnsCorrectResults() { - + public function testGetCodeReturnsCorrectResults() + { $tfa = new TwoFactorAuth('Test'); $this->assertEquals('543160', $tfa->getCode('VMR466AB62ZBOKHE', 1426847216)); $this->assertEquals('538532', $tfa->getCode('VMR466AB62ZBOKHE', 0)); } - /** - * @expectedException \RobThree\Auth\TwoFactorAuthException - */ - public function testCreateSecretThrowsOnInsecureRNGProvider() { - $rng = new TestRNGProvider(); - - $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng); - $tfa->createSecret(); - } - - public function testCreateSecretOverrideSecureDoesNotThrowOnInsecureRNG() { - $rng = new TestRNGProvider(); - - $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng); - $this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret(80, false)); - } - - public function testCreateSecretDoesNotThrowOnSecureRNGProvider() { - $rng = new TestRNGProvider(true); - - $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng); - $this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret()); - } - - public function testCreateSecretGeneratesDesiredAmountOfEntropy() { - $rng = new TestRNGProvider(true); - - $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng); - $this->assertEquals('A', $tfa->createSecret(5)); - $this->assertEquals('AB', $tfa->createSecret(6)); - $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ', $tfa->createSecret(128)); - $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', $tfa->createSecret(160)); - $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', $tfa->createSecret(320)); - $this->assertEquals('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567ABCDEFGHIJKLMNOPQRSTUVWXYZ234567A', $tfa->createSecret(321)); - } - - public function testEnsureCorrectTimeDoesNotThrowForCorrectTime() { - $tpr1 = new TestTimeProvider(123); - $tpr2 = new TestTimeProvider(128); - - $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, null, $tpr1); - $tfa->ensureCorrectTime(array($tpr2)); // 128 - 123 = 5 => within default leniency - $this->assertTrue(true); - } - - /** - * @expectedException \RobThree\Auth\TwoFactorAuthException - */ - public function testEnsureCorrectTimeThrowsOnIncorrectTime() { - $tpr1 = new TestTimeProvider(123); - $tpr2 = new TestTimeProvider(124); - - $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', null, null, $tpr1); - $tfa->ensureCorrectTime(array($tpr2), 0); // We force a leniency of 0, 124-123 = 1 so this should throw - } - - - public function testEnsureDefaultTimeProviderReturnsCorrectTime() { - $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1'); - $tfa->ensureCorrectTime(array(new TestTimeProvider(time())), 1); // Use a leniency of 1, should the time change between both time() calls - $this->assertTrue(true); - } - - public function testEnsureAllTimeProvidersReturnCorrectTime() { + public function testEnsureAllTimeProvidersReturnCorrectTime() + { $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1'); $tfa->ensureCorrectTime(array( - new RobThree\Auth\Providers\Time\NTPTimeProvider(), // Uses pool.ntp.org by default - //new RobThree\Auth\Providers\Time\NTPTimeProvider('time.google.com'), // Somehow time.google.com and time.windows.com make travis timeout?? - new RobThree\Auth\Providers\Time\HttpTimeProvider(), // Uses google.com by default - new RobThree\Auth\Providers\Time\HttpTimeProvider('https://github.com'), - new RobThree\Auth\Providers\Time\HttpTimeProvider('https://yahoo.com'), + new \RobThree\Auth\Providers\Time\NTPTimeProvider(), // Uses pool.ntp.org by default + //new \RobThree\Auth\Providers\Time\NTPTimeProvider('time.google.com'), // Somehow time.google.com and time.windows.com make travis timeout?? + new \RobThree\Auth\Providers\Time\HttpTimeProvider(), // Uses google.com by default + new \RobThree\Auth\Providers\Time\HttpTimeProvider('https://github.com'), + new \RobThree\Auth\Providers\Time\HttpTimeProvider('https://yahoo.com'), )); - $this->assertTrue(true); + $this->noAssertionsMade(); } - public function testVerifyCodeWorksCorrectly() { - + public function testVerifyCodeWorksCorrectly() + { $tfa = new TwoFactorAuth('Test', 6, 30); - $this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847190)); - $this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 + 29)); //Test discrepancy - $this->assertEquals(false, $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 + 30)); //Test discrepancy - $this->assertEquals(false, $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 - 1)); //Test discrepancy + $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847190)); + $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 + 29)); //Test discrepancy + $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 + 30)); //Test discrepancy + $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 0, 1426847190 - 1)); //Test discrepancy - $this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 0)); //Test discrepancy - $this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 35)); //Test discrepancy - $this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 - 35)); //Test discrepancy + $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 0)); //Test discrepancy + $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 35)); //Test discrepancy + $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 - 35)); //Test discrepancy - $this->assertEquals(false, $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 65)); //Test discrepancy - $this->assertEquals(false, $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 - 65)); //Test discrepancy + $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 65)); //Test discrepancy + $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 - 65)); //Test discrepancy - $this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 + 65)); //Test discrepancy - $this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 - 65)); //Test discrepancy + $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 + 65)); //Test discrepancy + $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 - 65)); //Test discrepancy } - public function testVerifyCorrectTimeSliceIsReturned() { + public function testVerifyCorrectTimeSliceIsReturned() + { $tfa = new TwoFactorAuth('Test', 6, 30); // We test with discrepancy 3 (so total of 7 codes: c-3, c-2, c-1, c, c+1, c+2, c+3 // Ensure each corresponding timeslice is returned correctly - $this->assertEquals(true, $tfa->verifyCode('VMR466AB62ZBOKHE', '534113', 3, 1426847190, $timeslice1)); + $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '534113', 3, 1426847190, $timeslice1)); $this->assertEquals(47561570, $timeslice1); - $this->assertEquals(true, $tfa->verifyCode('VMR466AB62ZBOKHE', '819652', 3, 1426847190, $timeslice2)); + $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '819652', 3, 1426847190, $timeslice2)); $this->assertEquals(47561571, $timeslice2); - $this->assertEquals(true, $tfa->verifyCode('VMR466AB62ZBOKHE', '915954', 3, 1426847190, $timeslice3)); + $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '915954', 3, 1426847190, $timeslice3)); $this->assertEquals(47561572, $timeslice3); - $this->assertEquals(true, $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 3, 1426847190, $timeslice4)); + $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 3, 1426847190, $timeslice4)); $this->assertEquals(47561573, $timeslice4); - $this->assertEquals(true, $tfa->verifyCode('VMR466AB62ZBOKHE', '348401', 3, 1426847190, $timeslice5)); + $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '348401', 3, 1426847190, $timeslice5)); $this->assertEquals(47561574, $timeslice5); - $this->assertEquals(true, $tfa->verifyCode('VMR466AB62ZBOKHE', '648525', 3, 1426847190, $timeslice6)); + $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '648525', 3, 1426847190, $timeslice6)); $this->assertEquals(47561575, $timeslice6); - $this->assertEquals(true, $tfa->verifyCode('VMR466AB62ZBOKHE', '170645', 3, 1426847190, $timeslice7)); + $this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '170645', 3, 1426847190, $timeslice7)); $this->assertEquals(47561576, $timeslice7); // Incorrect code should return false and a 0 timeslice - $this->assertEquals(false, $tfa->verifyCode('VMR466AB62ZBOKHE', '111111', 3, 1426847190, $timeslice8)); + $this->assertFalse($tfa->verifyCode('VMR466AB62ZBOKHE', '111111', 3, 1426847190, $timeslice8)); $this->assertEquals(0, $timeslice8); } - public function testTotpUriIsCorrect() { - $qr = new TestQrProvider(); - - $tfa = new TwoFactorAuth('Test&Issuer', 6, 30, 'sha1', $qr); - $data = $this->DecodeDataUri($tfa->getQRCodeImageAsDataUri('Test&Label', 'VMR466AB62ZBOKHE')); - $this->assertEquals('test/test', $data['mimetype']); - $this->assertEquals('base64', $data['encoding']); - $this->assertEquals('otpauth://totp/Test%26Label?secret=VMR466AB62ZBOKHE&issuer=Test%26Issuer&period=30&algorithm=SHA1&digits=6@200', $data['data']); - } - - /** - * @expectedException \RobThree\Auth\TwoFactorAuthException - */ - public function testGetQRCodeImageAsDataUriThrowsOnInvalidSize() { - $qr = new TestQrProvider(); - - $tfa = new TwoFactorAuth('Test', 6, 30, 'sha1', $qr); - $tfa->getQRCodeImageAsDataUri('Test', 'VMR466AB62ZBOKHE', 0); - } - - /** - * @expectedException \RobThree\Auth\TwoFactorAuthException - */ - public function testGetCodeThrowsOnInvalidBase32String1() { + public function testGetCodeThrowsOnInvalidBase32String1() + { $tfa = new TwoFactorAuth('Test'); + + $this->expectException(TwoFactorAuthException::class); + $tfa->getCode('FOO1BAR8BAZ9'); //1, 8 & 9 are invalid chars } - /** - * @expectedException \RobThree\Auth\TwoFactorAuthException - */ - public function testGetCodeThrowsOnInvalidBase32String2() { + public function testGetCodeThrowsOnInvalidBase32String2() + { $tfa = new TwoFactorAuth('Test'); + + $this->expectException(TwoFactorAuthException::class); + $tfa->getCode('mzxw6==='); //Lowercase } - public function testKnownBase32DecodeTestVectors() { + public function testKnownBase32DecodeTestVectors() + { // We usually don't test internals (e.g. privates) but since we rely heavily on base32 decoding and don't want // to expose this method nor do we want to give people the possibility of implementing / providing their own base32 // decoding/decoder (as we do with Rng/QR providers for example) we simply test the private base32Decode() method @@ -229,7 +129,7 @@ class TwoFactorAuthTest extends PHPUnit\Framework\TestCase // Dave Thomas and Andy Hunt -- "Pragmatic Unit Testing $tfa = new TwoFactorAuth('Test'); - $method = new ReflectionMethod('RobThree\Auth\TwoFactorAuth', 'base32Decode'); + $method = new \ReflectionMethod(TwoFactorAuth::class, 'base32Decode'); $method->setAccessible(true); // Test vectors from: https://tools.ietf.org/html/rfc4648#page-12 @@ -242,14 +142,15 @@ class TwoFactorAuthTest extends PHPUnit\Framework\TestCase $this->assertEquals('foobar', $method->invoke($tfa, 'MZXW6YTBOI======')); } - public function testKnownBase32DecodeUnpaddedTestVectors() { + public function testKnownBase32DecodeUnpaddedTestVectors() + { // See testKnownBase32DecodeTestVectors() for the rationale behind testing the private base32Decode() method. // This test ensures that strings without the padding-char ('=') are also decoded correctly. // https://tools.ietf.org/html/rfc4648#page-4: // "In some circumstances, the use of padding ("=") in base-encoded data is not required or used." $tfa = new TwoFactorAuth('Test'); - $method = new ReflectionMethod('RobThree\Auth\TwoFactorAuth', 'base32Decode'); + $method = new \ReflectionMethod(TwoFactorAuth::class, 'base32Decode'); $method->setAccessible(true); // Test vectors from: https://tools.ietf.org/html/rfc4648#page-12 @@ -262,8 +163,8 @@ class TwoFactorAuthTest extends PHPUnit\Framework\TestCase $this->assertEquals('foobar', $method->invoke($tfa, 'MZXW6YTBOI')); } - - public function testKnownTestVectors_sha1() { + public function testKnownTestVectors_sha1() + { //Known test vectors for SHA1: https://tools.ietf.org/html/rfc6238#page-15 $secret = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ'; //== base32encode('12345678901234567890') $tfa = new TwoFactorAuth('Test', 8, 30, 'sha1'); @@ -275,7 +176,8 @@ class TwoFactorAuthTest extends PHPUnit\Framework\TestCase $this->assertEquals('65353130', $tfa->getCode($secret, 20000000000)); } - public function testKnownTestVectors_sha256() { + public function testKnownTestVectors_sha256() + { //Known test vectors for SHA256: https://tools.ietf.org/html/rfc6238#page-15 $secret = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZA'; //== base32encode('12345678901234567890123456789012') $tfa = new TwoFactorAuth('Test', 8, 30, 'sha256'); @@ -287,7 +189,8 @@ class TwoFactorAuthTest extends PHPUnit\Framework\TestCase $this->assertEquals('77737706', $tfa->getCode($secret, 20000000000)); } - public function testKnownTestVectors_sha512() { + public function testKnownTestVectors_sha512() + { //Known test vectors for SHA512: https://tools.ietf.org/html/rfc6238#page-15 $secret = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNA'; //== base32encode('1234567890123456789012345678901234567890123456789012345678901234') $tfa = new TwoFactorAuth('Test', 8, 30, 'sha512'); @@ -298,116 +201,4 @@ class TwoFactorAuthTest extends PHPUnit\Framework\TestCase $this->assertEquals('38618901', $tfa->getCode($secret, 2000000000)); $this->assertEquals('47863826', $tfa->getCode($secret, 20000000000)); } - - /** - * @requires function random_bytes - */ - public function testCSRNGProvidersReturnExpectedNumberOfBytes() { - $rng = new \RobThree\Auth\Providers\Rng\CSRNGProvider(); - foreach ($this->getRngTestLengths() as $l) - $this->assertEquals($l, strlen($rng->getRandomBytes($l))); - $this->assertEquals(true, $rng->isCryptographicallySecure()); - } - - /** - * @requires function hash_algos - * @requires function hash - */ - public function testHashRNGProvidersReturnExpectedNumberOfBytes() { - $rng = new \RobThree\Auth\Providers\Rng\HashRNGProvider(); - foreach ($this->getRngTestLengths() as $l) - $this->assertEquals($l, strlen($rng->getRandomBytes($l))); - $this->assertEquals(false, $rng->isCryptographicallySecure()); - } - - /** - * @requires function mcrypt_create_iv - */ - public function testMCryptRNGProvidersReturnExpectedNumberOfBytes() { - if (function_exists('mcrypt_create_iv')) { - $rng = new \RobThree\Auth\Providers\Rng\MCryptRNGProvider(); - foreach ($this->getRngTestLengths() as $l) - $this->assertEquals($l, strlen($rng->getRandomBytes($l))); - $this->assertEquals(true, $rng->isCryptographicallySecure()); - } - $this->assertTrue(true); - } - - /** - * @requires function openssl_random_pseudo_bytes - */ - public function testStrongOpenSSLRNGProvidersReturnExpectedNumberOfBytes() { - $rng = new \RobThree\Auth\Providers\Rng\OpenSSLRNGProvider(true); - foreach ($this->getRngTestLengths() as $l) - $this->assertEquals($l, strlen($rng->getRandomBytes($l))); - $this->assertEquals(true, $rng->isCryptographicallySecure()); - } - - /** - * @requires function openssl_random_pseudo_bytes - */ - public function testNonStrongOpenSSLRNGProvidersReturnExpectedNumberOfBytes() { - $rng = new \RobThree\Auth\Providers\Rng\OpenSSLRNGProvider(false); - foreach ($this->getRngTestLengths() as $l) - $this->assertEquals($l, strlen($rng->getRandomBytes($l))); - $this->assertEquals(false, $rng->isCryptographicallySecure()); - } - - - private function getRngTestLengths() { - return array(1, 16, 32, 256); - } - - private function DecodeDataUri($datauri) { - if (preg_match('/data:(?P[\w\.\-\/]+);(?P\w+),(?P.*)/', $datauri, $m) === 1) { - return array( - 'mimetype' => $m['mimetype'], - 'encoding' => $m['encoding'], - 'data' => base64_decode($m['data']) - ); - } - return null; - } } - -class TestRNGProvider implements IRNGProvider { - private $isSecure; - - function __construct($isSecure = false) { - $this->isSecure = $isSecure; - } - - public function getRandomBytes($bytecount) { - $result = ''; - for ($i=0; $i<$bytecount; $i++) - $result.=chr($i); - return $result; - - } - - public function isCryptographicallySecure() { - return $this->isSecure; - } -} - -class TestQrProvider implements IQRCodeProvider { - public function getQRCodeImage($qrtext, $size) { - return $qrtext . '@' . $size; - } - - public function getMimeType() { - return 'test/test'; - } -} - -class TestTimeProvider implements ITimeProvider { - private $time; - - function __construct($time) { - $this->time = $time; - } - - public function getTime() { - return $this->time; - } -} \ No newline at end of file