From 292fe64e7883e74a63293f28806725411eedb3be Mon Sep 17 00:00:00 2001 From: phpipam <miha.petkovsek@telemach.si> Date: Thu, 14 Dec 2023 14:26:09 +0100 Subject: [PATCH] Updated passkeys --- app/login/passkey_login_check.php | 8 +- app/tools/user-menu/passkey_save.php | 86 +++++++++++-------- app/tools/user-menu/passkeys.php | 16 ++-- functions/composer.json | 3 +- functions/composer.lock | 10 +-- functions/vendor/autoload.php | 2 +- functions/vendor/composer/autoload_real.php | 8 +- functions/vendor/composer/autoload_static.php | 8 +- functions/vendor/composer/installed.json | 8 +- functions/vendor/composer/installed.php | 6 +- functions/vendor/firehed/webauthn | 2 +- 11 files changed, 82 insertions(+), 75 deletions(-) diff --git a/app/login/passkey_login_check.php b/app/login/passkey_login_check.php index c955cfbb..58cdadec 100644 --- a/app/login/passkey_login_check.php +++ b/app/login/passkey_login_check.php @@ -29,6 +29,7 @@ use Firehed\WebAuthn\{ SessionChallengeManager, SingleOriginRelyingParty, ResponseParser, + ArrayBufferResponseParser, BinaryString }; @@ -37,14 +38,9 @@ $json = file_get_contents('php://input'); $data = json_decode($json, true); // parser -$parser = new ResponseParser(); +$parser = new ArrayBufferResponseParser(); $getResponse = $parser->parseGetResponse($data); -// header('HTTP/1.1 201 Created'); -// header('Content-Type: text/html; charset=utf-8'); -// echo(implode('', array_map('chr', $data['keyId']))); -// die(); - // Set relaying party $rp = new \Firehed\WebAuthn\SingleOriginRelyingParty($User->createURL ()); // challange manager diff --git a/app/tools/user-menu/passkey_save.php b/app/tools/user-menu/passkey_save.php index 0be8bbc6..a37d70cf 100644 --- a/app/tools/user-menu/passkey_save.php +++ b/app/tools/user-menu/passkey_save.php @@ -27,45 +27,59 @@ use Firehed\WebAuthn\{ RelyingParty, SessionChallengeManager, SingleOriginRelyingParty, - JsonResponseParser + JsonResponseParser, + ArrayBufferResponseParser }; # process request $json = file_get_contents('php://input'); $data = json_decode($json, true); -// parser -$parser = new JsonResponseParser(); -$createResponse = $parser->parseCreateResponse($data); - -// escape keyId -$data['keyId'] = $User->strip_input_tags ($data['keyId']); - -// Relaying party -$rp = new \Firehed\WebAuthn\SingleOriginRelyingParty($User->createURL ()); -// challange manager -$challengeManager = new \Firehed\WebAuthn\SessionChallengeManager(); - -// Verify credentials, if it fails exit -try { - $credential = $createResponse->verify($challengeManager, $rp); -} catch (Throwable) { - header('HTTP/1.1 403 Unauthorized'); - return; -} - -// encode credentials to store to database -$codec = new Codecs\Credential(); -$encodedCredential = $codec->encode($credential); - - -// save passkey -$User->save_passkey ($encodedCredential, $credential->getStorageId(), $data['keyId']); - -// print result -header('HTTP/1.1 200 OK'); -header('Content-type: application/json'); -echo json_encode([ - 'success' => true, - 'credentialId' => $credential->getStorageId() -]); \ No newline at end of file +// +// we dont try to catch exceptions, as messages are unclear, check webserver/php-fpm error_logs +// + +// try { + // parser + $parser = new ArrayBufferResponseParser(); + $createResponse = $parser->parseCreateResponse($data); + + // escape keyId + $data['keyId'] = $User->strip_input_tags ($data['keyId']); + + // Relaying party + $rp = new \Firehed\WebAuthn\SingleOriginRelyingParty($User->createURL ()); + // challange manager + $challengeManager = new \Firehed\WebAuthn\SessionChallengeManager(); + + // Verify credentials, if it fails exit + try { + $credential = $createResponse->verify($challengeManager, $rp); + } catch (Throwable) { + header('HTTP/1.1 403 Unauthorized'); + return; + } + + // encode credentials to store to database + $codec = new Codecs\Credential(); + $encodedCredential = $codec->encode($credential); + + + // save passkey + $User->save_passkey ($encodedCredential, $credential->getStorageId(), $data['keyId']); + + // print result + header('HTTP/1.1 200 OK'); + header('Content-type: application/json'); + echo json_encode([ + 'success' => true, + 'credentialId' => $credential->getStorageId() + ]); +// } catch (exception $e) { +// header('HTTP/1.1 500 '.$e->getMessage()); +// } +// catch (Throwable) { +// // Verification failed. Send an error to the user? +// header('HTTP/1.1 403 Unauthorized'); +// return; +// } \ No newline at end of file diff --git a/app/tools/user-menu/passkeys.php b/app/tools/user-menu/passkeys.php index 240fd5cf..ed3c91b5 100644 --- a/app/tools/user-menu/passkeys.php +++ b/app/tools/user-menu/passkeys.php @@ -112,8 +112,7 @@ const startRegister = async (e) => { try { // get and parse challenge const challengeReq = await fetch('app/tools/user-menu/passkey_challenge.php') - const challengeB64 = await challengeReq.json() - const challenge = atob(challengeB64) // base64-decode + const challenge = await challengeReq.json() // create const createOptions = { @@ -127,16 +126,13 @@ const startRegister = async (e) => { id: Uint8Array.from("<?php print $User->user->id; ?>", c => c.charCodeAt(0)), }, // This base64-decodes the response and translates it into the Webauthn-required format. - challenge: Uint8Array.from(challenge, c => c.charCodeAt(0)), + // challenge: Uint8Array.from(atob(challenge), c => c.charCodeAt(0)), + challenge: Uint8Array.from(atob(challenge), c => c.charCodeAt(0)), pubKeyCredParams: [ { alg: -7, // ES256 type: "public-key", - }, - { - alg: -257, // Value registered by this specification for "RS256" - type: "public-key", - } + } ] }, attestation: 'direct', @@ -145,12 +141,12 @@ const startRegister = async (e) => { // Call the WebAuthn browser API and get the response. This may throw, which you // should handle. Example: user cancels or never interacts with the device. const credential = await navigator.credentials.create(createOptions) - console.log(Array.from(new Uint8Array(credential.rawId))) // Format the credential to send to the server. This must match the format // handed by the ResponseParser class. The formatting code below can be used // without modification. const dataForResponseParser = { + // rawId: Array.from(new Uint8Array(credential.rawId)), rawId: Array.from(new Uint8Array(credential.rawId)), keyId: credential.id, type: credential.type, @@ -197,7 +193,7 @@ const startRegister = async (e) => { }); } else { - $('#loginCheckPasskeys').html("<div class='alert alert-danger'>Failed to register new passkey.</div>"); + $('#loginCheckPasskeys').html("<div class='alert alert-danger'>Failed to register new passkey. <strong>Error : </strong>"+result.statusText+"</div>"); console.log(result) $('div.loading').hide(); } diff --git a/functions/composer.json b/functions/composer.json index 74c9d4e0..98208ceb 100644 --- a/functions/composer.json +++ b/functions/composer.json @@ -1,5 +1,6 @@ { "require": { - "firehed/webauthn": "dev-main" + "firehed/webauthn": "dev-main", + "firehed/cbor": "^0.1.0" } } diff --git a/functions/composer.lock b/functions/composer.lock index ebb1323a..df24dd56 100644 --- a/functions/composer.lock +++ b/functions/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7bf730768732814406175c12775f3390", + "content-hash": "b0a7a5cc1994c275013de9975a5f2675", "packages": [ { "name": "firehed/cbor", @@ -59,12 +59,12 @@ "source": { "type": "git", "url": "https://github.com/Firehed/webauthn-php.git", - "reference": "267d04a6d2926d9ab6d7630fb86a92410eb6b36c" + "reference": "e263a3553360d63131af707f3e563b151f4661b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Firehed/webauthn-php/zipball/267d04a6d2926d9ab6d7630fb86a92410eb6b36c", - "reference": "267d04a6d2926d9ab6d7630fb86a92410eb6b36c", + "url": "https://api.github.com/repos/Firehed/webauthn-php/zipball/e263a3553360d63131af707f3e563b151f4661b9", + "reference": "e263a3553360d63131af707f3e563b151f4661b9", "shasum": "" }, "require": { @@ -105,7 +105,7 @@ "issues": "https://github.com/Firehed/webauthn-php/issues", "source": "https://github.com/Firehed/webauthn-php/tree/main" }, - "time": "2023-11-16T23:07:44+00:00" + "time": "2023-12-10T19:00:08+00:00" } ], "packages-dev": [], diff --git a/functions/vendor/autoload.php b/functions/vendor/autoload.php index 29e50e81..1cca443d 100644 --- a/functions/vendor/autoload.php +++ b/functions/vendor/autoload.php @@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) { require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit7bf730768732814406175c12775f3390::getLoader(); +return ComposerAutoloaderInitb0a7a5cc1994c275013de9975a5f2675::getLoader(); diff --git a/functions/vendor/composer/autoload_real.php b/functions/vendor/composer/autoload_real.php index 53cd7ae3..2aa2feed 100644 --- a/functions/vendor/composer/autoload_real.php +++ b/functions/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit7bf730768732814406175c12775f3390 +class ComposerAutoloaderInitb0a7a5cc1994c275013de9975a5f2675 { private static $loader; @@ -24,12 +24,12 @@ class ComposerAutoloaderInit7bf730768732814406175c12775f3390 require __DIR__ . '/platform_check.php'; - spl_autoload_register(array('ComposerAutoloaderInit7bf730768732814406175c12775f3390', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInitb0a7a5cc1994c275013de9975a5f2675', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInit7bf730768732814406175c12775f3390', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInitb0a7a5cc1994c275013de9975a5f2675', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit7bf730768732814406175c12775f3390::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInitb0a7a5cc1994c275013de9975a5f2675::getInitializer($loader)); $loader->register(true); diff --git a/functions/vendor/composer/autoload_static.php b/functions/vendor/composer/autoload_static.php index 2d75bd05..da8883f2 100644 --- a/functions/vendor/composer/autoload_static.php +++ b/functions/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit7bf730768732814406175c12775f3390 +class ComposerStaticInitb0a7a5cc1994c275013de9975a5f2675 { public static $prefixLengthsPsr4 = array ( 'F' => @@ -32,9 +32,9 @@ class ComposerStaticInit7bf730768732814406175c12775f3390 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit7bf730768732814406175c12775f3390::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit7bf730768732814406175c12775f3390::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit7bf730768732814406175c12775f3390::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInitb0a7a5cc1994c275013de9975a5f2675::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitb0a7a5cc1994c275013de9975a5f2675::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInitb0a7a5cc1994c275013de9975a5f2675::$classMap; }, null, ClassLoader::class); } diff --git a/functions/vendor/composer/installed.json b/functions/vendor/composer/installed.json index 4c86530b..0c7c9064 100644 --- a/functions/vendor/composer/installed.json +++ b/functions/vendor/composer/installed.json @@ -57,12 +57,12 @@ "source": { "type": "git", "url": "https://github.com/Firehed/webauthn-php.git", - "reference": "267d04a6d2926d9ab6d7630fb86a92410eb6b36c" + "reference": "e263a3553360d63131af707f3e563b151f4661b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Firehed/webauthn-php/zipball/267d04a6d2926d9ab6d7630fb86a92410eb6b36c", - "reference": "267d04a6d2926d9ab6d7630fb86a92410eb6b36c", + "url": "https://api.github.com/repos/Firehed/webauthn-php/zipball/e263a3553360d63131af707f3e563b151f4661b9", + "reference": "e263a3553360d63131af707f3e563b151f4661b9", "shasum": "" }, "require": { @@ -81,7 +81,7 @@ "phpunit/phpunit": "^9.3", "squizlabs/php_codesniffer": "^3.5" }, - "time": "2023-11-16T23:07:44+00:00", + "time": "2023-12-10T19:00:08+00:00", "default-branch": true, "type": "library", "installation-source": "source", diff --git a/functions/vendor/composer/installed.php b/functions/vendor/composer/installed.php index 384a408b..a4c65c37 100644 --- a/functions/vendor/composer/installed.php +++ b/functions/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => '__root__', 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => 'e75387138147905ffd3b12cafffdc10f5388d948', + 'reference' => '7673d1b4aea9adf767af36a2cf418b7ad9091382', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -13,7 +13,7 @@ '__root__' => array( 'pretty_version' => 'dev-master', 'version' => 'dev-master', - 'reference' => 'e75387138147905ffd3b12cafffdc10f5388d948', + 'reference' => '7673d1b4aea9adf767af36a2cf418b7ad9091382', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -31,7 +31,7 @@ 'firehed/webauthn' => array( 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => '267d04a6d2926d9ab6d7630fb86a92410eb6b36c', + 'reference' => 'e263a3553360d63131af707f3e563b151f4661b9', 'type' => 'library', 'install_path' => __DIR__ . '/../firehed/webauthn', 'aliases' => array( diff --git a/functions/vendor/firehed/webauthn b/functions/vendor/firehed/webauthn index 267d04a6..e263a355 160000 --- a/functions/vendor/firehed/webauthn +++ b/functions/vendor/firehed/webauthn @@ -1 +1 @@ -Subproject commit 267d04a6d2926d9ab6d7630fb86a92410eb6b36c +Subproject commit e263a3553360d63131af707f3e563b151f4661b9 -- GitLab