summaryrefslogtreecommitdiffstats
path: root/dom/u2f/tests/frame_multiple_keys.html
blob: d9e9705496b0ee564a61fb0d44c9e81375657112 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<!DOCTYPE html>
<meta charset=utf-8>
<head>
  <script type="text/javascript" src="frame_utils.js"></script>
  <script type="text/javascript" src="u2futil.js"></script>
</head>
<body>
<p>Test for multiple simultaneous key</p>
<script class="testbody" type="text/javascript">
"use strict";

function keyHandleFromRegResponse(aRegResponse) {
  // Parse the response data from the U2F token
  let registrationData = base64ToBytesUrlSafe(aRegResponse.registrationData);
  local_is(registrationData[0], 0x05, "Reserved byte is correct")

  let keyHandleLength = registrationData[66];
  let keyHandleBytes = registrationData.slice(67, 67 + keyHandleLength);

  return {
    version: "U2F_V2",
    keyHandle: bytesToBase64UrlSafe(keyHandleBytes),
  };
}

let challenge = new Uint8Array(16);
window.crypto.getRandomValues(challenge);

let regRequest = {
  version: "U2F_V2",
  challenge: bytesToBase64UrlSafe(challenge),
};

let testState = {
  key1: null,
  key2: null,
}

// Just a key that came from a random profile; syntactically valid but not
// unwrappable.
let invalidKey = {
  "version": "U2F_V2",
  "keyHandle": "rQdreHgHrmKfsnGPAElEP9yfTx6eq2eU3_Y8n0RRsGKML0DY2d1_a8_-sOtxDr3"
};

async function doTests() {
  // Ensure the SpecialPowers push worked properly
  local_isnot(window.u2f, undefined, "U2F API endpoint must exist");

  // Get two valid keys and present them
  await promiseU2FRegister(window.location.origin, [regRequest], [], function(aRegResponse) {
    testState.key1 = keyHandleFromRegResponse(aRegResponse);
  });

  // Get the second key...
  // It's OK to repeat the regRequest; not material for this test
  await promiseU2FRegister(window.location.origin, [regRequest], [], function(aRegResponse) {
    testState.key2 = keyHandleFromRegResponse(aRegResponse);
  });

  await promiseU2FRegister(window.location.origin, [regRequest],
                           [invalidKey], function(aRegResponse) {
    // The invalid key shouldn't match anything, so we should register OK here, too
    local_is(aRegResponse.errorCode, 0, "The register should have gone through with the invalid key");
  });


  await promiseU2FRegister(window.location.origin, [regRequest],
                           [invalidKey, testState.key1], function(aRegResponse) {
    // Expect a failure response since key1 is already registered
    local_is(aRegResponse.errorCode, 4, "The register should have skipped since there was a valid key");
  });

  await promiseU2FSign(window.location.origin, bytesToBase64UrlSafe(challenge),
                  [testState.key1], function(aSignResponse) {
    local_is(aSignResponse.errorCode, 0, "The signing did not error with one key");
    local_isnot(aSignResponse.clientData, undefined, "The signing provided clientData with one key");
  });

  // It's OK to sign with either one
  await promiseU2FSign(window.location.origin, bytesToBase64UrlSafe(challenge),
                  [testState.key1, testState.key2], function(aSignResponse) {
    local_is(aSignResponse.errorCode, 0, "The signing did not error with two keys");
    local_isnot(aSignResponse.clientData, undefined, "The signing provided clientData with two keys");
  });

  await promiseU2FSign(window.location.origin, bytesToBase64UrlSafe(challenge),
                    [invalidKey, testState.key2], function(aSignResponse) {
    local_is(aSignResponse.errorCode, 0, "The signing did not error when given an invalid key");
    local_isnot(aSignResponse.clientData, undefined, "The signing provided clientData even when given an invalid key");
  });

  await promiseU2FSign(window.location.origin, bytesToBase64UrlSafe(challenge),
                    [testState.key2, invalidKey], function(aSignResponse) {
    local_is(aSignResponse.errorCode, 0, "The signing did not error when given an invalid key");
    local_isnot(aSignResponse.clientData, undefined, "The signing provided clientData even when given an invalid key");
  });

  await promiseU2FSign(window.location.origin, bytesToBase64UrlSafe(challenge),
                    [invalidKey], function(aSignResponse) {
    local_is(aSignResponse.errorCode, 4, "The signing couldn't complete with this invalid key");
    local_is(aSignResponse.clientData, undefined, "The signing shouldn't provide clientData when there's no valid key");
  });

  local_finished();
};

doTests();
</script>
</body>
</html>