summaryrefslogtreecommitdiffstats
path: root/dom/webauthn/tests/test_webauthn_authenticator_selection.html
blob: 6ddde1e91f1aaa6f37dcfacf2f896825f5a65af8 (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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<!DOCTYPE html>
<meta charset=utf-8>
<head>
  <title>W3C Web Authentication - Authenticator Selection Criteria</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <script type="text/javascript" src="u2futil.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>

  <h1>W3C Web Authentication - Authenticator Selection Criteria</h1>
  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1406462">Mozilla Bug 1406462</a>
  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1406467">Mozilla Bug 1406467</a>

  <script class="testbody" type="text/javascript">
    "use strict";

    function arrivingHereIsGood(aResult) {
      ok(true, "Good result! Received a: " + aResult);
    }

    function arrivingHereIsBad(aResult) {
      ok(false, "Bad result! Received a: " + aResult);
    }

    function expectNotAllowedError(aResult) {
      ok(aResult.toString().startsWith("NotAllowedError"), "Expecting a NotAllowedError, got " + aResult);
    }

    // We store the credential of the first successful make credential
    // operation so we can use it for get assertion tests later.
    let gCredential;

    // Start a new MakeCredential() request.
    function requestMakeCredential(authenticatorSelection) {
      let publicKey = {
        rp: {id: document.domain, name: "none", icon: "none"},
        user: {id: new Uint8Array(), name: "none", icon: "none", displayName: "none"},
        challenge: crypto.getRandomValues(new Uint8Array(16)),
        timeout: 5000, // the minimum timeout is actually 15 seconds
        pubKeyCredParams: [{type: "public-key", alg: cose_alg_ECDSA_w_SHA256}],
        authenticatorSelection,
      };

      return navigator.credentials.create({publicKey});
    }

    // Start a new GetAssertion() request.
    function requestGetAssertion(userVerification) {
      let newCredential = {
        type: "public-key",
        id: gCredential,
        transports: ["usb"],
      };

      let publicKey = {
        challenge: crypto.getRandomValues(new Uint8Array(16)),
        timeout: 5000, // the minimum timeout is actually 15 seconds
        rpId: document.domain,
        allowCredentials: [newCredential]
      };

      if (userVerification) {
        publicKey.userVerification = userVerification;
      }

      return navigator.credentials.get({publicKey});
    }

    // Test success cases for make credential.
    add_task(async function test_make_credential_successes() {
      // No selection criteria.
      await requestMakeCredential({})
         // Save the credential so we can use it for sign success tests.
        .then(res => gCredential = res.rawId)
        .then(arrivingHereIsGood)
        .catch(arrivingHereIsBad);

      // Request a cross-platform authenticator.
      await requestMakeCredential({authenticatorAttachment: "cross-platform"})
        .then(arrivingHereIsGood)
        .catch(arrivingHereIsBad);

      // Don't require a resident key.
      await requestMakeCredential({requireResidentKey: false})
        .then(arrivingHereIsGood)
        .catch(arrivingHereIsBad);

      // Prefer user verification.
      await requestMakeCredential({userVerification: "preferred"})
        .then(arrivingHereIsGood)
        .catch(arrivingHereIsBad);

      // Discourage user verification.
      await requestMakeCredential({userVerification: "discouraged"})
        .then(arrivingHereIsGood)
        .catch(arrivingHereIsBad);
    });

    // Test success cases for get assertion.
    add_task(async function test_get_assertion_successes() {
      // No selection criteria.
      await requestGetAssertion()
        .then(arrivingHereIsGood)
        .catch(arrivingHereIsBad);

      // Prefer user verification.
      await requestGetAssertion("preferred")
        .then(arrivingHereIsGood)
        .catch(arrivingHereIsBad);

      // Discourage user verification.
      await requestGetAssertion("discouraged")
        .then(arrivingHereIsGood)
        .catch(arrivingHereIsBad);
    });

    // Test failure cases for make credential.
    add_task(async function test_make_credential_failures() {
      // Request a platform authenticator.
      await requestMakeCredential({authenticatorAttachment: "platform"})
        .then(arrivingHereIsBad)
        .catch(expectNotAllowedError);

      // Require a resident key.
      await requestMakeCredential({requireResidentKey: true})
        .then(arrivingHereIsBad)
        .catch(expectNotAllowedError);

      // Require user verification.
      await requestMakeCredential({userVerification: "required"})
        .then(arrivingHereIsBad)
        .catch(expectNotAllowedError);
    });

    // Test failure cases for get assertion.
    add_task(async function test_get_assertion_failures() {
      // Require user verification.
      await requestGetAssertion("required")
        .then(arrivingHereIsBad)
        .catch(expectNotAllowedError);
    });
  </script>

</body>
</html>