summaryrefslogtreecommitdiffstats
path: root/dom/webauthn/tests/test_webauthn_authenticator_selection.html
blob: 10ba6b643b64018073acb35b2664d586b020b90c (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
147
148
149
150
151
152
153
154
155
156
<!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;

    add_task(() => {
      // Enable the softtoken.
      return SpecialPowers.pushPrefEnv({"set": [
        ["security.webauth.webauthn", true],
        ["security.webauth.webauthn_enable_softtoken", true],
        ["security.webauth.webauthn_enable_usbtoken", false],
        ["security.webauth.webauthn_enable_android_fido2", false],
      ]});
    });

    // 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 () => {
      // 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 () => {
      // 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 () => {
      // 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 () => {
      // Require user verification.
      await requestGetAssertion("required")
        .then(arrivingHereIsBad)
        .catch(expectNotAllowedError);
    });
  </script>

</body>
</html>