| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- <?php
- /**
- * Copyright (c) 2014 Yubico AB
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- /**
- * This is a simple example using PDO and a sqlite database for storing
- * registrations. It supports multiple registrations associated with each user.
- */
- require_once('../../src/u2flib_server/U2F.php');
- $dbfile = '/var/tmp/u2f-pdo.sqlite';
- $pdo = new PDO("sqlite:$dbfile");
- $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
- $pdo->exec("create table if not exists users (id integer primary key, name varchar(255))");
- $pdo->exec("create table if not exists registrations (id integer primary key, user_id integer, keyHandle varchar(255), publicKey varchar(255), certificate text, counter integer)");
- $scheme = isset($_SERVER['HTTPS']) ? "https://" : "http://";
- $u2f = new u2flib_server\U2F($scheme . $_SERVER['HTTP_HOST']);
- session_start();
- function createAndGetUser($name) {
- global $pdo;
- $sel = $pdo->prepare("select * from users where name = ?");
- $sel->execute(array($name));
- $user = $sel->fetch();
- if(!$user) {
- $ins = $pdo->prepare("insert into users (name) values(?)");
- $ins->execute(array($name));
- $sel->execute(array($name));
- $user = $sel->fetch();
- }
- return $user;
- }
- function getRegs($user_id) {
- global $pdo;
- $sel = $pdo->prepare("select * from registrations where user_id = ?");
- $sel->execute(array($user_id));
- return $sel->fetchAll();
- }
- function addReg($user_id, $reg) {
- global $pdo;
- $ins = $pdo->prepare("insert into registrations (user_id, keyHandle, publicKey, certificate, counter) values (?, ?, ?, ?, ?)");
- $ins->execute(array($user_id, $reg->keyHandle, $reg->publicKey, $reg->certificate, $reg->counter));
- }
- function updateReg($reg) {
- global $pdo;
- $upd = $pdo->prepare("update registrations set counter = ? where id = ?");
- $upd->execute(array($reg->counter, $reg->id));
- }
- ?>
- <html>
- <head>
- <title>PHP U2F example</title>
- <script src="../assets/u2f-api.js"></script>
- <script>
- <?php
- if($_SERVER['REQUEST_METHOD'] === 'POST') {
- if(!$_POST['username']) {
- echo "alert('no username provided!');";
- } else if(!isset($_POST['action']) && !isset($_POST['register2']) && !isset($_POST['authenticate2'])) {
- echo "alert('no action provided!');";
- } else {
- $user = createAndGetUser($_POST['username']);
- if(isset($_POST['action'])) {
- switch($_POST['action']):
- case 'register':
- try {
- $data = $u2f->getRegisterData(getRegs($user->id));
- list($req,$sigs) = $data;
- $_SESSION['regReq'] = json_encode($req);
- echo "var req = " . json_encode($req) . ";";
- echo "var sigs = " . json_encode($sigs) . ";";
- echo "var username = '" . $user->name . "';";
- ?>
- setTimeout(function() {
- console.log("Register: ", req);
- u2f.register([req], sigs, function(data) {
- var form = document.getElementById('form');
- var reg = document.getElementById('register2');
- var user = document.getElementById('username');
- console.log("Register callback", data);
- if(data.errorCode && errorCode != 0) {
- alert("registration failed with errror: " + data.errorCode);
- return;
- }
- reg.value = JSON.stringify(data);
- user.value = username;
- form.submit();
- });
- }, 1000);
- <?php
- } catch( Exception $e ) {
- echo "alert('error: " . $e->getMessage() . "');";
- }
- break;
- case 'authenticate':
- try {
- $reqs = json_encode($u2f->getAuthenticateData(getRegs($user->id)));
- $_SESSION['authReq'] = $reqs;
- echo "var req = $reqs;";
- echo "var username = '" . $user->name . "';";
- ?>
- setTimeout(function() {
- console.log("sign: ", req);
- u2f.sign(req, function(data) {
- var form = document.getElementById('form');
- var auth = document.getElementById('authenticate2');
- var user = document.getElementById('username');
- console.log("Authenticate callback", data);
- auth.value=JSON.stringify(data);
- user.value = username;
- form.submit();
- });
- }, 1000);
- <?php
- } catch( Exception $e ) {
- echo "alert('error: " . $e->getMessage() . "');";
- }
- break;
- endswitch;
- } else if($_POST['register2']) {
- try {
- $reg = $u2f->doRegister(json_decode($_SESSION['regReq']), json_decode($_POST['register2']));
- addReg($user->id, $reg);
- } catch( Exception $e ) {
- echo "alert('error: " . $e->getMessage() . "');";
- } finally {
- $_SESSION['regReq'] = null;
- }
- } else if($_POST['authenticate2']) {
- try {
- $reg = $u2f->doAuthenticate(json_decode($_SESSION['authReq']), getRegs($user->id), json_decode($_POST['authenticate2']));
- updateReg($reg);
- echo "alert('success: " . $reg->counter . "');";
- } catch( Exception $e ) {
- echo "alert('error: " . $e->getMessage() . "');";
- } finally {
- $_SESSION['authReq'] = null;
- }
- }
- }
- }
- ?>
- </script>
- </head>
- <body>
- <form method="POST" id="form">
- username: <input name="username" id="username"/><br/>
- register: <input value="register" name="action" type="radio"/><br/>
- authenticate: <input value="authenticate" name="action" type="radio"/><br/>
- <input type="hidden" name="register2" id="register2"/>
- <input type="hidden" name="authenticate2" id="authenticate2"/>
- <button type="submit">Submit!</button>
- </form>
- </body>
- </html>
|