u2f_api.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <?php
  2. require_once('inc/prerequisites.inc.php');
  3. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  4. $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
  5. $scheme = isset($_SERVER['HTTPS']) ? "https://" : "http://";
  6. $u2f = new u2flib_server\U2F($scheme . $_SERVER['HTTP_HOST']);
  7. function getRegs($username) {
  8. global $pdo;
  9. $sel = $pdo->prepare("select * from tfa where username = ?");
  10. $sel->execute(array($username));
  11. return $sel->fetchAll();
  12. }
  13. function addReg($username, $reg) {
  14. global $pdo;
  15. $ins = $pdo->prepare("INSERT INTO `tfa` (`username`, `keyHandle`, `publicKey`, `certificate`, `counter`) values (?, ?, ?, ?, ?)");
  16. $ins->execute(array($username, $reg->keyHandle, $reg->publicKey, $reg->certificate, $reg->counter));
  17. }
  18. function updateReg($reg) {
  19. global $pdo;
  20. $upd = $pdo->prepare("update tfa set counter = ? where id = ?");
  21. $upd->execute(array($reg->counter, $reg->id));
  22. }
  23. ?>
  24. <html>
  25. <head>
  26. <script src="js/u2f-api.js"></script>
  27. <?php
  28. if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  29. if ((empty($_POST['u2f_username'])) || (!isset($_POST['action']) && !isset($_POST['u2f_register_data']) && !isset($_POST['u2f_auth_data']))) {
  30. print_r($_POST);
  31. exit();
  32. }
  33. else {
  34. $username = $_POST['u2f_username'];
  35. if (isset($_POST['action'])) {
  36. switch($_POST['action']) {
  37. case 'register':
  38. try {
  39. $data = $u2f->getRegisterData(getRegs($username));
  40. list($req, $sigs) = $data;
  41. $_SESSION['regReq'] = json_encode($req);
  42. ?>
  43. <script>
  44. var req = <?=json_encode($req);?>;
  45. var sigs = <?=json_encode($sigs);?>;
  46. var username = "<?=$username;?>";
  47. setTimeout(function() {
  48. console.log("Register: ", req);
  49. u2f.register([req], sigs, function(data) {
  50. var form = document.getElementById('u2f_form');
  51. var reg = document.getElementById('u2f_register_data');
  52. var user = document.getElementById('u2f_username');
  53. var status = document.getElementById('u2f_status');
  54. console.log("Register callback", data);
  55. if (data.errorCode && data.errorCode != 0) {
  56. var div = document.getElementById('u2f_return_code');
  57. div.innerHTML = 'Error code: ' + data.errorCode;
  58. return;
  59. }
  60. reg.value = JSON.stringify(data);
  61. user.value = username;
  62. status.value = "1";
  63. form.submit();
  64. });
  65. }, 1000);
  66. </script>
  67. <?php
  68. }
  69. catch( Exception $e ) {
  70. echo "U2F error: " . $e->getMessage();
  71. }
  72. break;
  73. case 'authenticate':
  74. try {
  75. $reqs = json_encode($u2f->getAuthenticateData(getRegs($username)));
  76. $_SESSION['authReq'] = $reqs;
  77. ?>
  78. <script>
  79. var req = <?=$reqs;?>;
  80. var username = "<?=$username;?>";
  81. setTimeout(function() {
  82. console.log("sign: ", req);
  83. u2f.sign(req, function(data) {
  84. var form = document.getElementById('u2f_form');
  85. var auth = document.getElementById('u2f_auth_data');
  86. var user = document.getElementById('u2f_username');
  87. console.log("Authenticate callback", data);
  88. auth.value = JSON.stringify(data);
  89. user.value = username;
  90. form.submit();
  91. });
  92. }, 1000);
  93. </script>
  94. <?php
  95. }
  96. catch (Exception $e) {
  97. echo "U2F error: " . $e->getMessage();
  98. }
  99. break;
  100. }
  101. }
  102. if (!empty($_POST['u2f_register_data'])) {
  103. try {
  104. $reg = $u2f->doRegister(json_decode($_SESSION['regReq']), json_decode($_POST['u2f_register_data']));
  105. addReg($username, $reg);
  106. }
  107. catch (Exception $e) {
  108. echo "U2F error: " . $e->getMessage();
  109. }
  110. finally {
  111. echo "Success";
  112. $_SESSION['regReq'] = null;
  113. }
  114. }
  115. if (!empty($_POST['u2f_auth_data'])) {
  116. try {
  117. $reg = $u2f->doAuthenticate(json_decode($_SESSION['authReq']), getRegs($username), json_decode($_POST['u2f_auth_data']));
  118. updateReg($reg);
  119. }
  120. catch (Exception $e) {
  121. echo "U2F error: " . $e->getMessage();
  122. }
  123. finally {
  124. echo "Success";
  125. $_SESSION['authReq'] = null;
  126. }
  127. }
  128. }
  129. ?>
  130. </head>
  131. <body>
  132. <div id="u2f_return_code"></div>
  133. <form method="POST" id="u2f_form">
  134. <input type="hidden" name="u2f_register_data" id="u2f_register_data"/>
  135. <input type="hidden" name="u2f_auth_data" id="u2f_auth_data"/>
  136. <input type="hidden" name="u2f_username" id="u2f_username"/><br/>
  137. <input type="hidden" name="u2f_status" id="u2f_status"/><br/>
  138. </form>
  139. <?php
  140. }
  141. else {
  142. ?>
  143. <form method="POST" id="post_form">
  144. Username: <input name="u2f_username" id="u2f_username"/><br/><hr>
  145. Action: <br />
  146. <input value="register" name="action" type="radio"/> Register<br/>
  147. <input value="authenticate" name="action" type="radio"/> Authenticate<br/>
  148. <button type="submit">Submit!</button>
  149. </form>
  150. <?php
  151. }
  152. ?>
  153. </body>
  154. </html>