u2f_api.php 4.7 KB

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