dee22afd94588ded04d1257fe40667f6b6df0af0
Bernd Wurst merge passkeys feature

Bernd Wurst authored 11 months ago

1) <?php
2) /*
3) This file belongs to the Webinterface of schokokeks.org Hosting
4) 
5) Written by schokokeks.org Hosting, namely
6)   Bernd Wurst <bernd@schokokeks.org>
7)   Hanno Böck <hanno@schokokeks.org>
8) 
9) This code is published under a 0BSD license.
10) 
11) Nevertheless, in case you use a significant part of this code, we ask (but not require, see the license) that you keep the authors' names in place and return your changes to the public. We would be especially happy if you tell us what you're going to do with this code.
12) */
13) 
14) require_once('passkey.php');
15) require_once('inc/base.php');
16) 
17) require_once('vendor/autoload.php');
18) 
19) $req = filter_input(INPUT_POST, 'req');
20) 
21) // Relying Party == Hostname
22) $rpId = $_SERVER['HTTP_HOST'];
23) 
Hanno Böck Fix codingstyle

Hanno Böck authored 11 months ago

24) $WebAuthn = new lbuchs\WebAuthn\WebAuthn(config('company_name') . ' Webinterface', $rpId, ["none"]);
Bernd Wurst merge passkeys feature

Bernd Wurst authored 11 months ago

25) 
26) if ($req == 'getCreateArgs') {
27)     require_role(ROLE_SYSTEMUSER);
28)     $userId = dechex($_SESSION['userinfo']['uid']); // Hex-formatted internal ID not displayed to the user
29)     if (strlen($userId) % 2 == 1) {
Hanno Böck Fix codingstyle

Hanno Böck authored 11 months ago

30)         $userId = "0" . $userId;
Bernd Wurst merge passkeys feature

Bernd Wurst authored 11 months ago

31)     }
32)     $userName = $_SESSION['userinfo']['username'];
33)     $_SESSION['passkey_handle'] = filter_input(INPUT_POST, "handle");
34)     $userDisplayName = $_SESSION['userinfo']['name'];
35)     if ($_SESSION['passkey_handle']) {
36)         $userDisplayName = $userDisplayName . " ({$_SESSION['passkey_handle']})";
37)     }
38) 
39)     $requireResidentKey = 'required';
40)     $userVerification = 'preferred';
Hanno Böck Fix codingstyle

Hanno Böck authored 11 months ago

41) 
42)     $timeout = 3 * 60;
Bernd Wurst merge passkeys feature

Bernd Wurst authored 11 months ago

43) 
44)     $createArgs = $WebAuthn->getCreateArgs(\hex2bin($userId), $userName, $userDisplayName, $timeout, $requireResidentKey, $userVerification);
45) 
46)     // save challange to session. you have to deliver it to processGet later.
47)     $_SESSION['challenge'] = ($WebAuthn->getChallenge())->getBinaryString();
48) 
49)     header('Content-Type: application/json');
50)     print(json_encode($createArgs));
51) } elseif ($req == 'processCreate') {
52)     require_role(ROLE_SYSTEMUSER);
53)     $client = $_POST['client'];
54)     $attest = $_POST['attest'];
55) 
56)     try {
Hanno Böck Fix codingstyle

Hanno Böck authored 11 months ago

57)         $data = $WebAuthn->processCreate(
58)             base64_decode($_POST["client"]),
59)             base64_decode($_POST["attest"]),
60)             $_SESSION["challenge"],
61)             true,
62)             true,
63)             false,
64)             false
65)         );
66)     } catch (Exception $ex) {
Bernd Wurst merge passkeys feature

Bernd Wurst authored 11 months ago

67)         logger(LOG_ERR, "modules/loginsecurity/passkey_ajax", "loginsecurity", "processCreate failed with {$ex}");
68)         print("Error");
69)         die();
70)     }
71) 
72)     save_passkey($data, $_SESSION['passkey_handle']);
73)     unset($_SESSION['passkey_handle']);
74)     print("OK");
75)     success_msg("Der Passkey wurde gespeichert!");
76)     die();
77) } elseif ($req == 'getGetArgs') {
78)     $args = $WebAuthn->getGetArgs([], 30);
79)     $_SESSION["challenge"] = ($WebAuthn->getChallenge())->getBinaryString();
80)     header('Content-Type: application/json');
81)     print(json_encode($args));
82)     die();
83) } elseif ($req == 'processGet') {
84)     $id = base64_decode($_POST["id"]);
85)     $savedData = get_passkey($id);
Hanno Böck Fix codingstyle

Hanno Böck authored 11 months ago

86)     if (!$savedData) {
87)         print("Invalid credentials");
Bernd Wurst merge passkeys feature

Bernd Wurst authored 11 months ago

88)         die();
89)     }
90)     try {
Hanno Böck Fix codingstyle

Hanno Böck authored 11 months ago

91)         $WebAuthn->processGet(
92)             base64_decode($_POST["client"]),
93)             base64_decode($_POST["auth"]),
94)             base64_decode($_POST["sig"]),
95)             $savedData['credentialPublicKey'],
96)             $_SESSION["challenge"]
97)         );
98)         // DO WHATEVER IS REQUIRED AFTER VALIDATION
99)         echo "OK";
100)         $login = ($_POST['login'] == "true");
101)         if ($login) {
102)             $uid = $savedData['uid'];
103)             require_once("session/start.php");
104)             $role = find_role($uid, '', true);
105)             setup_session($role, $uid);
106)             die();
107)         } else {
108)             success_msg("Die Identifikation mit dem Passkey »{$savedData['handle']}« hat funktioniert!");
109)         }
110)     } catch (Exception $ex) {