From c64e52c3c08eb0ee79d439f8e095f5c1649f0b93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Wed, 1 Nov 2017 15:10:35 +0100 Subject: [PATCH] Test registration and authentication for FIDO U2F MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michal Čihař --- .../classes/Plugins/SecondFactor/Key.php | 2 +- test/classes/SecondFactorTest.php | 68 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/libraries/classes/Plugins/SecondFactor/Key.php b/libraries/classes/Plugins/SecondFactor/Key.php index 673e6df43b..3573824d57 100644 --- a/libraries/classes/Plugins/SecondFactor/Key.php +++ b/libraries/classes/Plugins/SecondFactor/Key.php @@ -167,7 +167,7 @@ class Key extends SecondFactorPlugin public function configure() { $this->_provided = false; - if (! isset($_POST['u2f_registration_response'])) { + if (! isset($_POST['u2f_registration_response']) || ! isset($_SESSION['registrationRequest'])) { return false; } $this->_provided = true; diff --git a/test/classes/SecondFactorTest.php b/test/classes/SecondFactorTest.php index 9edf4aa454..f2aa54ffef 100644 --- a/test/classes/SecondFactorTest.php +++ b/test/classes/SecondFactorTest.php @@ -8,6 +8,8 @@ namespace PhpMyAdmin\Tests; use PhpMyAdmin\SecondFactor; +use Samyoul\U2F\U2FServer\RegistrationRequest; +use Samyoul\U2F\U2FServer\SignRequest; /** * Tests behaviour of SecondFactor class @@ -122,6 +124,18 @@ class SecondFactorTest extends PmaTestCase $this->assertTrue($object->configure('application')); unset($_POST['2fa_code']); + /* Check code */ + unset($_POST['2fa_code']); + $this->assertFalse($object->check()); + $_POST['2fa_code'] = 'invalid'; + $this->assertFalse($object->check()); + $_POST['2fa_code'] = $google2fa->oathHotp( + $object->config['settings']['secret'], + $google2fa->getTimestamp() + ); + $this->assertTrue($object->check()); + unset($_POST['2fa_code']); + /* Test rendering */ $this->assertNotEquals('', $object->render()); $this->assertNotEquals('', $object->setup()); @@ -133,6 +147,7 @@ class SecondFactorTest extends PmaTestCase if (! in_array('key', $object->available)) { $this->markTestSkipped('u2f-php-server not available'); } + $_SESSION['registrationRequest'] = null; /* Without providing code this should fail */ unset($_POST['u2f_registration_response']); $this->assertFalse($object->configure('key')); @@ -141,11 +156,64 @@ class SecondFactorTest extends PmaTestCase $_POST['u2f_registration_response'] = 'invalid'; $this->assertFalse($object->configure('key')); + /* Invalid code */ + $_POST['u2f_registration_response'] = '[]'; + $this->assertFalse($object->configure('key')); + + /* Without providing code this should fail */ + unset($_POST['u2f_authentication_response']); + $this->assertFalse($object->check()); + + /* Invalid code */ + $_POST['u2f_authentication_response'] = 'invalid'; + $this->assertFalse($object->check()); + + /* Invalid code */ + $_POST['u2f_authentication_response'] = '[]'; + $this->assertFalse($object->check()); + /* Test rendering */ $this->assertNotEquals('', $object->render()); $this->assertNotEquals('', $object->setup()); } + /** + * Test based on upstream test data: + * https://github.com/Yubico/php-u2flib-server + */ + public function testKeyAuthentication() + { + $GLOBALS['PMA_Config']->set('PmaAbsoluteUri', 'http://demo.example.com'); + $object = new SecondFactor('user'); + if (! in_array('key', $object->available)) { + $this->markTestSkipped('u2f-php-server not available'); + } + $_SESSION['registrationRequest'] = new RegistrationRequest('yKA0x075tjJ-GE7fKTfnzTOSaNUOWQxRd9TWz5aFOg8', 'http://demo.example.com'); + unset($_POST['u2f_registration_response']); + $this->assertFalse($object->configure('key')); + + $_POST['u2f_registration_response'] = ''; + $this->assertFalse($object->configure('key')); + + $_POST['u2f_registration_response'] = '{ "registrationData": "BQQtEmhWVgvbh-8GpjsHbj_d5FB9iNoRL8mNEq34-ANufKWUpVdIj6BSB_m3eMoZ3GqnaDy3RA5eWP8mhTkT1Ht3QAk1GsmaPIQgXgvrBkCQoQtMFvmwYPfW5jpRgoMPFxquHS7MTt8lofZkWAK2caHD-YQQdaRBgd22yWIjPuWnHOcwggLiMIHLAgEBMA0GCSqGSIb3DQEBCwUAMB0xGzAZBgNVBAMTEll1YmljbyBVMkYgVGVzdCBDQTAeFw0xNDA1MTUxMjU4NTRaFw0xNDA2MTQxMjU4NTRaMB0xGzAZBgNVBAMTEll1YmljbyBVMkYgVGVzdCBFRTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNsK2_Uhx1zOY9ym4eglBg2U5idUGU-dJK8mGr6tmUQflaNxkQo6IOc-kV4T6L44BXrVeqN-dpCPr-KKlLYw650wDQYJKoZIhvcNAQELBQADggIBAJVAa1Bhfa2Eo7TriA_jMA8togoA2SUE7nL6Z99YUQ8LRwKcPkEpSpOsKYWJLaR6gTIoV3EB76hCiBaWN5HV3-CPyTyNsM2JcILsedPGeHMpMuWrbL1Wn9VFkc7B3Y1k3OmcH1480q9RpYIYr-A35zKedgV3AnvmJKAxVhv9GcVx0_CewHMFTryFuFOe78W8nFajutknarupekDXR4tVcmvj_ihJcST0j_Qggeo4_3wKT98CgjmBgjvKCd3Kqg8n9aSDVWyaOZsVOhZj3Fv5rFu895--D4qiPDETozJIyliH-HugoQpqYJaTX10mnmMdCa6aQeW9CEf-5QmbIP0S4uZAf7pKYTNmDQ5z27DVopqaFw00MIVqQkae_zSPX4dsNeeoTTXrwUGqitLaGap5ol81LKD9JdP3nSUYLfq0vLsHNDyNgb306TfbOenRRVsgQS8tJyLcknSKktWD_Qn7E5vjOXprXPrmdp7g5OPvrbz9QkWa1JTRfo2n2AXV02LPFc-UfR9bWCBEIJBxvmbpmqt0MnBTHWnth2b0CU_KJTDCY3kAPLGbOT8A4KiI73pRW-e9SWTaQXskw3Ei_dHRILM_l9OXsqoYHJ4Dd3tbfvmjoNYggSw4j50l3unI9d1qR5xlBFpW5sLr8gKX4bnY4SR2nyNiOQNLyPc0B0nW502aMEUCIQDTGOX-i_QrffJDY8XvKbPwMuBVrOSO-ayvTnWs_WSuDQIgZ7fMAvD_Ezyy5jg6fQeuOkoJi8V2naCtzV-HTly8Nww=", "clientData": "eyAiY2hhbGxlbmdlIjogInlLQTB4MDc1dGpKLUdFN2ZLVGZuelRPU2FOVU9XUXhSZDlUV3o1YUZPZzgiLCAib3JpZ2luIjogImh0dHA6XC9cL2RlbW8uZXhhbXBsZS5jb20iLCAidHlwIjogIm5hdmlnYXRvci5pZC5maW5pc2hFbnJvbGxtZW50IiB9", "errorCode": 0 }'; + $this->assertTrue($object->configure('key')); + + unset($_POST['u2f_authentication_response']); + $this->assertFalse($object->check(true)); + + $_POST['u2f_authentication_response'] = ''; + $this->assertFalse($object->check(true)); + + $_SESSION['authenticationRequest'] = [new SignRequest([ + 'challenge' => 'fEnc9oV79EaBgK5BoNERU5gPKM2XGYWrz4fUjgc0Q7g', + 'keyHandle' => 'CTUayZo8hCBeC-sGQJChC0wW-bBg99bmOlGCgw8XGq4dLsxO3yWh9mRYArZxocP5hBB1pEGB3bbJYiM-5acc5w', + 'appId' => 'http://demo.example.com' + ])]; + $this->assertFalse($object->check()); + $_POST['u2f_authentication_response'] = '{ "signatureData": "AQAAAAQwRQIhAI6FSrMD3KUUtkpiP0jpIEakql-HNhwWFngyw553pS1CAiAKLjACPOhxzZXuZsVO8im-HStEcYGC50PKhsGp_SUAng==", "clientData": "eyAiY2hhbGxlbmdlIjogImZFbmM5b1Y3OUVhQmdLNUJvTkVSVTVnUEtNMlhHWVdyejRmVWpnYzBRN2ciLCAib3JpZ2luIjogImh0dHA6XC9cL2RlbW8uZXhhbXBsZS5jb20iLCAidHlwIjogIm5hdmlnYXRvci5pZC5nZXRBc3NlcnRpb24iIH0=", "keyHandle": "CTUayZo8hCBeC-sGQJChC0wW-bBg99bmOlGCgw8XGq4dLsxO3yWh9mRYArZxocP5hBB1pEGB3bbJYiM-5acc5w", "errorCode": 0 }'; + $this->assertTrue($object->check()); + } + /** * Test listing of available backends. */