mirror of
https://github.com/RobThree/TwoFactorAuth.git
synced 2026-08-18 03:31:49 +00:00
* Tabs -> Spaces. Yep.
This commit is contained in:
@@ -6,20 +6,20 @@ abstract class BaseHTTPQRCodeProvider implements IQRCodeProvider
|
||||
{
|
||||
protected $verifyssl;
|
||||
|
||||
protected function getContent($url)
|
||||
protected function getContent($url)
|
||||
{
|
||||
$ch = curl_init();
|
||||
|
||||
curl_setopt_array($ch, array(
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_MAXREDIRS => 3,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_CONNECTTIMEOUT => 10,
|
||||
CURLOPT_DNS_CACHE_TIMEOUT => 10,
|
||||
CURLOPT_TIMEOUT => 10,
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_MAXREDIRS => 3,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_CONNECTTIMEOUT => 10,
|
||||
CURLOPT_DNS_CACHE_TIMEOUT => 10,
|
||||
CURLOPT_TIMEOUT => 10,
|
||||
CURLOPT_SSL_VERIFYPEER => $this->verifyssl,
|
||||
CURLOPT_USERAGENT => 'TwoFactorAuth'
|
||||
CURLOPT_USERAGENT => 'TwoFactorAuth'
|
||||
));
|
||||
$data = curl_exec($ch);
|
||||
|
||||
|
||||
@@ -4,6 +4,6 @@ namespace RobThree\Auth\Providers\Qr;
|
||||
|
||||
interface IQRCodeProvider
|
||||
{
|
||||
public function getQRCodeImage($qrtext, $size);
|
||||
public function getQRCodeImage($qrtext, $size);
|
||||
public function getMimeType();
|
||||
}
|
||||
@@ -160,10 +160,10 @@ class TwoFactorAuth
|
||||
$l = strlen($s);
|
||||
$r = trim(chunk_split(substr($s, 0, $l - ($l % 8)), 8, ' '));
|
||||
|
||||
$o = '';
|
||||
foreach (explode(' ', $r) as $b)
|
||||
$o = '';
|
||||
foreach (explode(' ', $r) as $b)
|
||||
$o .= chr(bindec(str_pad($b, 8, 0, STR_PAD_RIGHT)));
|
||||
|
||||
return $o;
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
||||
+92
-92
@@ -14,117 +14,117 @@ require_once 'lib/Providers/Rng/HashRNGProvider.php';
|
||||
|
||||
class TwoFactorAuthTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
/**
|
||||
* @expectedException \RobThree\Auth\TwoFactorAuthException
|
||||
*/
|
||||
public function testConstructorThrowsOnInvalidDigits() {
|
||||
public function testConstructorThrowsOnInvalidDigits() {
|
||||
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 0);
|
||||
}
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 0);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @expectedException \RobThree\Auth\TwoFactorAuthException
|
||||
*/
|
||||
public function testConstructorThrowsOnInvalidPeriod() {
|
||||
public function testConstructorThrowsOnInvalidPeriod() {
|
||||
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 0);
|
||||
}
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @expectedException \RobThree\Auth\TwoFactorAuthException
|
||||
*/
|
||||
public function testConstructorThrowsOnInvalidAlgorithm() {
|
||||
public function testConstructorThrowsOnInvalidAlgorithm() {
|
||||
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 30, 'xxx');
|
||||
}
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 30, 'xxx');
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @expectedException \RobThree\Auth\TwoFactorAuthException
|
||||
*/
|
||||
public function testConstructorThrowsOnQrProviderNotImplementingInterface() {
|
||||
public function testConstructorThrowsOnQrProviderNotImplementingInterface() {
|
||||
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 30, 'sha1', new stdClass());
|
||||
}
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 30, 'sha1', new stdClass());
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @expectedException \RobThree\Auth\TwoFactorAuthException
|
||||
*/
|
||||
public function testConstructorThrowsOnRngProviderNotImplementingInterface() {
|
||||
public function testConstructorThrowsOnRngProviderNotImplementingInterface() {
|
||||
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 30, 'sha1', null, new stdClass());
|
||||
}
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 30, 'sha1', null, new stdClass());
|
||||
}
|
||||
|
||||
public function testGetCodeReturnsCorrectResults() {
|
||||
public function testGetCodeReturnsCorrectResults() {
|
||||
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test');
|
||||
$this->assertEquals('543160', $tfa->getCode('VMR466AB62ZBOKHE', 1426847216));
|
||||
$this->assertEquals('538532', $tfa->getCode('VMR466AB62ZBOKHE', 0));
|
||||
}
|
||||
$tfa = new \RobThree\Auth\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();
|
||||
public function testCreateSecretThrowsOnInsecureRNGProvider() {
|
||||
$rng = new TestRNGProvider();
|
||||
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng);
|
||||
$tfa->createSecret();
|
||||
}
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng);
|
||||
$tfa->createSecret();
|
||||
}
|
||||
|
||||
public function testCreateSecretOverrideSecureDoesNotThrowOnInsecureRNG() {
|
||||
$rng = new TestRNGProvider();
|
||||
public function testCreateSecretOverrideSecureDoesNotThrowOnInsecureRNG() {
|
||||
$rng = new TestRNGProvider();
|
||||
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng);
|
||||
$this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret(80, false));
|
||||
}
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng);
|
||||
$this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret(80, false));
|
||||
}
|
||||
|
||||
public function testCreateSecretDoesNotThrowOnSecureRNGProvider() {
|
||||
$rng = new TestRNGProvider(true);
|
||||
public function testCreateSecretDoesNotThrowOnSecureRNGProvider() {
|
||||
$rng = new TestRNGProvider(true);
|
||||
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng);
|
||||
$this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret());
|
||||
}
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 30, 'sha1', null, $rng);
|
||||
$this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret());
|
||||
}
|
||||
|
||||
public function testCreateSecretGeneratesDesiredAmountOfEntropy() {
|
||||
$rng = new TestRNGProvider(true);
|
||||
public function testCreateSecretGeneratesDesiredAmountOfEntropy() {
|
||||
$rng = new TestRNGProvider(true);
|
||||
|
||||
$tfa = new \RobThree\Auth\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));
|
||||
}
|
||||
$tfa = new \RobThree\Auth\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 testVerifyCodeWorksCorrectly() {
|
||||
public function testVerifyCodeWorksCorrectly() {
|
||||
|
||||
$tfa = new \RobThree\Auth\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
|
||||
$tfa = new \RobThree\Auth\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->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->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->assertEquals(false, $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 1, 1426847205 + 65)); //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->assertEquals(false, $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->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 + 65)); //Test discrepancy
|
||||
$this->assertEquals(true , $tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 - 65)); //Test discrepancy
|
||||
}
|
||||
|
||||
public function testTotpUriIsCorrect() {
|
||||
$qr = new TestQrProvider();
|
||||
|
||||
$tfa = new \RobThree\Auth\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']);
|
||||
$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']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,19 +134,19 @@ class TwoFactorAuthTest extends PHPUnit_Framework_TestCase
|
||||
$qr = new TestQrProvider();
|
||||
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 6, 30, 'sha1', $qr);
|
||||
$tfa->getQRCodeImageAsDataUri('Test', 'VMR466AB62ZBOKHE', 0);
|
||||
$tfa->getQRCodeImageAsDataUri('Test', 'VMR466AB62ZBOKHE', 0);
|
||||
}
|
||||
|
||||
public function testKnownTestVectors_sha1() {
|
||||
//Known test vectors for SHA1: https://tools.ietf.org/html/rfc6238#page-15
|
||||
$secret = 'GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ'; //== base32encode('12345678901234567890')
|
||||
$tfa = new \RobThree\Auth\TwoFactorAuth('Test', 8, 30, 'sha1');
|
||||
$this->assertEquals('94287082', $tfa->getCode($secret, 59));
|
||||
$this->assertEquals('07081804', $tfa->getCode($secret, 1111111109));
|
||||
$this->assertEquals('14050471', $tfa->getCode($secret, 1111111111));
|
||||
$this->assertEquals('89005924', $tfa->getCode($secret, 1234567890));
|
||||
$this->assertEquals('69279037', $tfa->getCode($secret, 2000000000));
|
||||
$this->assertEquals('65353130', $tfa->getCode($secret, 20000000000));
|
||||
$this->assertEquals('94287082', $tfa->getCode($secret, 59));
|
||||
$this->assertEquals('07081804', $tfa->getCode($secret, 1111111109));
|
||||
$this->assertEquals('14050471', $tfa->getCode($secret, 1111111111));
|
||||
$this->assertEquals('89005924', $tfa->getCode($secret, 1234567890));
|
||||
$this->assertEquals('69279037', $tfa->getCode($secret, 2000000000));
|
||||
$this->assertEquals('65353130', $tfa->getCode($secret, 20000000000));
|
||||
}
|
||||
|
||||
public function testKnownTestVectors_sha256() {
|
||||
@@ -174,16 +174,16 @@ class TwoFactorAuthTest extends PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
|
||||
private function DecodeDataUri($datauri) {
|
||||
if (preg_match('/data:(?P<mimetype>[\w\.\-\/]+);(?P<encoding>\w+),(?P<data>.*)/', $datauri, $m) === 1) {
|
||||
return array(
|
||||
'mimetype' => $m['mimetype'],
|
||||
'encoding' => $m['encoding'],
|
||||
'data' => base64_decode($m['data'])
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private function DecodeDataUri($datauri) {
|
||||
if (preg_match('/data:(?P<mimetype>[\w\.\-\/]+);(?P<encoding>\w+),(?P<data>.*)/', $datauri, $m) === 1) {
|
||||
return array(
|
||||
'mimetype' => $m['mimetype'],
|
||||
'encoding' => $m['encoding'],
|
||||
'data' => base64_decode($m['data'])
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class TestRNGProvider implements \RobThree\Auth\Providers\Rng\IRNGProvider {
|
||||
@@ -207,11 +207,11 @@ class TestRNGProvider implements \RobThree\Auth\Providers\Rng\IRNGProvider {
|
||||
}
|
||||
|
||||
class TestQrProvider implements \RobThree\Auth\Providers\Qr\IQRCodeProvider {
|
||||
public function getQRCodeImage($qrtext, $size) {
|
||||
return $qrtext . '@' . $size;
|
||||
}
|
||||
public function getQRCodeImage($qrtext, $size) {
|
||||
return $qrtext . '@' . $size;
|
||||
}
|
||||
|
||||
public function getMimeType() {
|
||||
return 'test/test';
|
||||
}
|
||||
public function getMimeType() {
|
||||
return 'test/test';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user