tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_webauthn_get_assertion.html (10309B)


      1 <!DOCTYPE html>
      2 <meta charset=utf-8>
      3 <head>
      4  <title>Tests for GetAssertion for W3C Web Authentication</title>
      5  <script src="/tests/SimpleTest/SimpleTest.js"></script>
      6  <script type="text/javascript" src="u2futil.js"></script>
      7  <script type="text/javascript" src="pkijs/common.js"></script>
      8  <script type="text/javascript" src="pkijs/asn1.js"></script>
      9  <script type="text/javascript" src="pkijs/x509_schema.js"></script>
     10  <script type="text/javascript" src="pkijs/x509_simpl.js"></script>
     11  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
     12 </head>
     13 <body>
     14 
     15  <h1>Tests for GetAssertion for W3C Web Authentication</h1>
     16  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1309284">Mozilla Bug 1309284</a>
     17 
     18  <script class="testbody" type="text/javascript">
     19    "use strict";
     20 
     21    let authenticatorId = null;
     22    add_task(async () => {
     23      authenticatorId = await addVirtualAuthenticator();
     24    });
     25 
     26    is(navigator.authentication, undefined, "navigator.authentication does not exist any longer");
     27    isnot(navigator.credentials, undefined, "Credential Management API endpoint must exist");
     28    isnot(navigator.credentials.create, undefined, "CredentialManagement create API endpoint must exist");
     29    isnot(navigator.credentials.get, undefined, "CredentialManagement get API endpoint must exist");
     30 
     31    let gAssertionChallenge = new Uint8Array(16);
     32    window.crypto.getRandomValues(gAssertionChallenge);
     33 
     34    let unknownCredType = {type: "Magic", id: base64ToBytes("AAA=")};
     35    let unknownCred = {type: "public-key", id: base64ToBytes("AAA=")};
     36    let validCred = null;
     37 
     38    add_task(test_setup_valid_credential);
     39    add_task(test_with_credential);
     40    add_task(test_unexpected_option);
     41    add_task(test_unexpected_option_with_credential);
     42    add_task(test_unexpected_transport);
     43    add_task(test_unknown_credential_type);
     44    add_task(test_unknown_credential);
     45    add_task(test_too_many_credentials);
     46    add_task(test_unexpected_option_unknown_credential_type);
     47    add_task(test_empty_credential_list);
     48    add_task(test_credential_protection_policy_uv_optional_with_list);
     49    add_task(test_credential_protection_policy_uv_required);
     50 
     51    function requestGetAssertion(params) {
     52      return navigator.credentials.get(params);
     53    }
     54 
     55    function arrivingHereIsGood(aResult) {
     56      ok(true, "Good result! Received a: " + aResult);
     57    }
     58 
     59    function arrivingHereIsBad(aResult) {
     60      ok(false, "Bad result! Received a: " + aResult);
     61    }
     62 
     63    function expectNotAllowedError(aResult) {
     64      ok(aResult.toString().startsWith("NotAllowedError"), "Expecting a NotAllowedError, got " + aResult);
     65    }
     66 
     67    function expectInvalidStateError(aResult) {
     68      ok(aResult.toString().startsWith("InvalidStateError"), "Expecting a InvalidStateError, got " + aResult);
     69    }
     70 
     71    function expectTypeError(aResult) {
     72      ok(aResult.toString().startsWith("TypeError"), "Expecting a TypeError, got " + aResult);
     73    }
     74 
     75    function expectSecurityError(aResult) {
     76      ok(aResult.toString().startsWith("SecurityError"), "Expecting a SecurityError, got " + aResult);
     77    }
     78 
     79    function expectAbortError(aResult) {
     80      is(aResult.code, DOMException.ABORT_ERR, "Expecting an AbortError");
     81    }
     82 
     83    // Set up a valid credential
     84    async function test_setup_valid_credential() {
     85      let publicKey = {
     86        rp: {id: document.domain, name: "none"},
     87        user: {id: new Uint8Array(), name: "none", displayName: "none"},
     88        challenge: crypto.getRandomValues(new Uint8Array(16)),
     89        pubKeyCredParams: [{type: "public-key", alg: cose_alg_ECDSA_w_SHA256}],
     90      };
     91 
     92      return navigator.credentials.create({publicKey})
     93      .then(res => validCred = {type: "public-key", id: res.rawId} );
     94    }
     95 
     96    // Test with a valid credential
     97    async function test_with_credential() {
     98      let publicKey = {
     99        challenge: gAssertionChallenge,
    100        allowCredentials: [validCred]
    101      };
    102 
    103      await requestGetAssertion({publicKey})
    104        .then(arrivingHereIsGood)
    105        .catch(arrivingHereIsBad);
    106    }
    107 
    108    // Test with an unexpected option. That won't stop anything, and we'll
    109    // fail with NotAllowed just as if we had no valid credentials -- which
    110    // we don't.
    111    async function test_unexpected_option() {
    112      let publicKey = {
    113        challenge: gAssertionChallenge,
    114        unknownValue: "hi"
    115      };
    116 
    117      await requestGetAssertion({publicKey})
    118        .then(arrivingHereIsBad)
    119        .catch(expectNotAllowedError);
    120    }
    121 
    122    // Test with an unexpected option but a valid credential
    123    async function test_unexpected_option_with_credential() {
    124      let publicKey = {
    125        challenge: gAssertionChallenge,
    126        unknownValue: "hi",
    127        allowCredentials: [validCred]
    128      };
    129 
    130      await requestGetAssertion({publicKey})
    131        .then(arrivingHereIsGood)
    132        .catch(arrivingHereIsBad);
    133    }
    134 
    135    // Test with an unexpected transport on a valid credential
    136    async function test_unexpected_transport() {
    137      let cred = validCred;
    138      cred.transports = ["unknown", "usb"];
    139 
    140      let publicKey = {
    141        challenge: gAssertionChallenge,
    142        unknownValue: "hi",
    143        allowCredentials: [cred]
    144      };
    145 
    146      await requestGetAssertion({publicKey})
    147        .then(arrivingHereIsGood)
    148        .catch(arrivingHereIsBad);
    149    }
    150 
    151    // Test with an unknown credential type
    152    async function test_unknown_credential_type() {
    153      let publicKey = {
    154        challenge: gAssertionChallenge,
    155        allowCredentials: [unknownCredType]
    156      };
    157 
    158      await requestGetAssertion({publicKey})
    159        .then(arrivingHereIsBad)
    160        .catch(expectNotAllowedError);
    161    }
    162 
    163    // Test with an unknown credential
    164    async function test_unknown_credential() {
    165      let publicKey = {
    166        challenge: gAssertionChallenge,
    167        allowCredentials: [unknownCred]
    168      };
    169 
    170      await requestGetAssertion({publicKey})
    171        .then(arrivingHereIsBad)
    172        .catch(expectNotAllowedError);
    173    }
    174 
    175    // Test with too many credentials
    176    async function test_too_many_credentials() {
    177      let tooManyCredentials = Array(21).fill(validCred);
    178      let publicKey = {
    179        challenge: gAssertionChallenge,
    180        allowCredentials: tooManyCredentials,
    181      };
    182 
    183      await requestGetAssertion({publicKey})
    184        .then(arrivingHereIsBad)
    185        .catch(expectSecurityError);
    186    }
    187 
    188    // Test with an unexpected option and an unknown credential type
    189    async function test_unexpected_option_unknown_credential_type() {
    190      let publicKey = {
    191        challenge: gAssertionChallenge,
    192        unknownValue: "hi",
    193        allowCredentials: [unknownCredType]
    194      };
    195 
    196      await requestGetAssertion({publicKey})
    197        .then(arrivingHereIsBad)
    198        .catch(expectNotAllowedError);
    199    }
    200 
    201    // Test with an empty credential list
    202    async function test_empty_credential_list() {
    203      let publicKey = {
    204        challenge: gAssertionChallenge,
    205        allowCredentials: []
    206      };
    207 
    208      await requestGetAssertion({publicKey})
    209        .then(arrivingHereIsBad)
    210        .catch(expectNotAllowedError);
    211    }
    212 
    213    async function test_credential_protection_policy_uv_optional_with_list() {
    214      let publicKey = {
    215        rp: {id: document.domain, name: "none"},
    216        user: {id: new Uint8Array(), name: "none", displayName: "none"},
    217        challenge: crypto.getRandomValues(new Uint8Array(16)),
    218        authenticatorSelection: { residentKey: "required"},
    219        pubKeyCredParams: [{type: "public-key", alg: cose_alg_ECDSA_w_SHA256}],
    220        extensions: { credentialProtectionPolicy: "userVerificationOptionalWithCredentialIDList" },
    221      };
    222 
    223      let protectedCred = null;
    224      await navigator.credentials.create({publicKey})
    225      .then(res => protectedCred = {type: "public-key", id: res.rawId} );
    226 
    227      publicKey = {
    228        challenge: gAssertionChallenge,
    229        allowCredentials: [protectedCred],
    230        userVerification: "discouraged"
    231      };
    232 
    233      // User verification is optional for this request. So it should succeed
    234      // both with and without user verification as long as the credential ID
    235      // is provided in allowCredentials.
    236      setUserVerified(authenticatorId, true)
    237      await requestGetAssertion({publicKey})
    238        .then(arrivingHereIsGood)
    239        .catch(arrivingHereIsBad);
    240 
    241      setUserVerified(authenticatorId, false)
    242      await requestGetAssertion({publicKey})
    243        .then(arrivingHereIsGood)
    244        .catch(arrivingHereIsBad);
    245 
    246      // User verification is required if the credential ID is not provided in
    247      // allowCredentials.
    248      publicKey = {
    249        challenge: gAssertionChallenge,
    250        allowCredentials: [],
    251        userVerification: "discouraged"
    252      };
    253      await requestGetAssertion({publicKey})
    254        .then(arrivingHereIsBad)
    255        .catch(arrivingHereIsGood);
    256 
    257      setUserVerified(authenticatorId, true)
    258      await requestGetAssertion({publicKey})
    259        .then(arrivingHereIsGood)
    260        .catch(arrivingHereIsBad);
    261    }
    262 
    263    async function test_credential_protection_policy_uv_required() {
    264      let publicKey = {
    265        rp: {id: document.domain, name: "none"},
    266        user: {id: new Uint8Array(), name: "none", displayName: "none"},
    267        challenge: crypto.getRandomValues(new Uint8Array(16)),
    268        pubKeyCredParams: [{type: "public-key", alg: cose_alg_ECDSA_w_SHA256}],
    269        extensions: { credentialProtectionPolicy: "userVerificationRequired" },
    270      };
    271 
    272      let protectedCred = null;
    273      await navigator.credentials.create({publicKey})
    274      .then(res => protectedCred = {type: "public-key", id: res.rawId} );
    275 
    276      publicKey = {
    277        challenge: gAssertionChallenge,
    278        allowCredentials: [protectedCred],
    279        userVerification: "discouraged"
    280      };
    281 
    282      // User verification is required; this should succeed.
    283      setUserVerified(authenticatorId, true)
    284      await requestGetAssertion({publicKey})
    285        .then(arrivingHereIsGood)
    286        .catch(arrivingHereIsBad);
    287 
    288      // The same request should fail without user verification.
    289      setUserVerified(authenticatorId, false)
    290      await requestGetAssertion({publicKey})
    291        .then(arrivingHereIsBad)
    292        .catch(arrivingHereIsGood);
    293 
    294      setUserVerified(authenticatorId, true)
    295    }
    296  </script>
    297 
    298 </body>
    299 </html>