Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/dom/webauthn/tests/browser/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 14 kB image not shown  

Quelle  browser_webauthn_prompts.js

  Sprache: JAVA
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


"use strict";

XPCOMUtils.defineLazyScriptGetter(
  this,
  ["FullScreen"],
  "chrome://browser/content/browser-fullScreenAndPointerLock.js"
);

const TEST_URL = "https://example.com/";
var gAuthenticatorId;

/**
 * Waits for the PopupNotifications button enable delay to expire so the
 * Notification can be interacted with using the buttons.
 */

async function waitForPopupNotificationSecurityDelay() {
  let notification = PopupNotifications.panel.firstChild.notification;
  let notificationEnableDelayMS = Services.prefs.getIntPref(
    "security.notification_enable_delay"
  );
  await TestUtils.waitForCondition(
    () => {
      let timeSinceShown = Cu.now() - notification.timeShown;
      return timeSinceShown > notificationEnableDelayMS;
    },
    "Wait for security delay to expire",
    500,
    50
  );
}

add_task(async function test_setup_usbtoken() {
  return SpecialPowers.pushPrefEnv({
    set: [
      ["security.webauth.webauthn_enable_softtoken"false],
      ["security.webauth.webauthn_enable_usbtoken"true],
    ],
  });
});
add_task(test_register);
add_task(test_register_escape);
add_task(test_sign);
add_task(test_sign_escape);
add_task(test_tab_switching);
add_task(test_window_switching);
add_task(async function test_setup_softtoken() {
  gAuthenticatorId = add_virtual_authenticator();
  return SpecialPowers.pushPrefEnv({
    set: [
      ["browser.fullscreen.autohide"true],
      ["full-screen-api.enabled"true],
      ["full-screen-api.allow-trusted-requests-only"false],
      ["security.webauth.webauthn_enable_softtoken"true],
      ["security.webauth.webauthn_enable_usbtoken"false],
    ],
  });
});
add_task(test_fullscreen_show_nav_toolbar);
add_task(test_no_fullscreen_dom);
add_task(test_register_direct_with_consent);
add_task(test_register_direct_without_consent);
add_task(test_select_sign_result);

function promiseNavToolboxStatus(aExpectedStatus) {
  let navToolboxStatus;
  return TestUtils.topicObserved("fullscreen-nav-toolbox", (subject, data) => {
    navToolboxStatus = data;
    return data == aExpectedStatus;
  }).then(() =>
    Assert.equal(
      navToolboxStatus,
      aExpectedStatus,
      "nav toolbox is " + aExpectedStatus
    )
  );
}

function promiseFullScreenPaint(aExpectedStatus) {
  return TestUtils.topicObserved("fullscreen-painted");
}

function triggerMainPopupCommand(popup) {
  info("triggering main command");
  let notifications = popup.childNodes;
  ok(notifications.length, "at least one notification displayed");
  let notification = notifications[0];
  info("triggering command: " + notification.getAttribute("buttonlabel"));

  return EventUtils.synthesizeMouseAtCenter(notification.button, {});
}

let expectNotAllowedError = expectError("NotAllowed");

function verifyAnonymizedCertificate(aResult) {
  return webAuthnDecodeCBORAttestation(aResult.attObj).then(
    ({ fmt, attStmt }) => {
      is(fmt, "none""Is a None Attestation");
      is(typeof attStmt, "object""attStmt is a map");
      is(Object.keys(attStmt).length, 0, "attStmt is empty");
    }
  );
}

async function verifyDirectCertificate(aResult) {
  let clientDataHash = await crypto.subtle
    .digest("SHA-256", aResult.clientDataJSON)
    .then(digest => new Uint8Array(digest));
  let { fmt, attStmt, authData, authDataObj } =
    await webAuthnDecodeCBORAttestation(aResult.attObj);
  is(fmt, "packed""Is a Packed Attestation");
  let signedData = new Uint8Array(authData.length + clientDataHash.length);
  signedData.set(authData);
  signedData.set(clientDataHash, authData.length);
  let valid = await verifySignature(
    authDataObj.publicKeyHandle,
    signedData,
    new Uint8Array(attStmt.sig)
  );
  ok(valid, "Signature is valid.");
}

async function test_register() {
  // Open a new tab.
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);

  // Request a new credential and wait for the prompt.
  let notificationPromise = promiseNotification("webauthn-prompt-presence");
  let active = true;
  let request = promiseWebAuthnMakeCredential(tab)
    .then(arrivingHereIsBad)
    .catch(expectNotAllowedError)
    .then(() => (active = false));
  await notificationPromise;

  // Cancel the request with the button.
  ok(active, "request should still be active");
  PopupNotifications.panel.firstElementChild.button.click();
  await request;

  // Close tab.
  await BrowserTestUtils.removeTab(tab);
}

async function test_register_escape() {
  // Open a new tab.
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);

  // Request a new credential and wait for the prompt.
  let notificationPromise = promiseNotification("webauthn-prompt-presence");
  let active = true;
  let request = promiseWebAuthnMakeCredential(tab)
    .then(arrivingHereIsBad)
    .catch(expectNotAllowedError)
    .then(() => (active = false));
  await notificationPromise;

  // Cancel the request by hitting escape.
  ok(active, "request should still be active");
  EventUtils.synthesizeKey("KEY_Escape");
  await request;

  // Close tab.
  await BrowserTestUtils.removeTab(tab);
}

async function test_sign() {
  // Open a new tab.
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);

  // Request a new assertion and wait for the prompt.
  let notificationPromise = promiseNotification("webauthn-prompt-presence");
  let active = true;
  let request = promiseWebAuthnGetAssertion(tab)
    .then(arrivingHereIsBad)
    .catch(expectNotAllowedError)
    .then(() => (active = false));
  await notificationPromise;

  // Cancel the request with the button.
  ok(active, "request should still be active");
  PopupNotifications.panel.firstElementChild.button.click();
  await request;

  // Close tab.
  await BrowserTestUtils.removeTab(tab);
}

async function test_sign_escape() {
  // Open a new tab.
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);

  // Request a new assertion and wait for the prompt.
  let notificationPromise = promiseNotification("webauthn-prompt-presence");
  let active = true;
  let request = promiseWebAuthnGetAssertion(tab)
    .then(arrivingHereIsBad)
    .catch(expectNotAllowedError)
    .then(() => (active = false));
  await notificationPromise;

  // Cancel the request by hitting escape.
  ok(active, "request should still be active");
  EventUtils.synthesizeKey("KEY_Escape");
  await request;

  // Close tab.
  await BrowserTestUtils.removeTab(tab);
}

// Add two tabs, open WebAuthn in the first, switch, assert the prompt is
// not visible, switch back, assert the prompt is there and cancel it.
async function test_tab_switching() {
  // Open a new tab.
  let tab_one = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);

  // Request a new credential and wait for the prompt.
  let notificationPromise = promiseNotification("webauthn-prompt-presence");
  let active = true;
  let request = promiseWebAuthnMakeCredential(tab_one)
    .then(arrivingHereIsBad)
    .catch(expectNotAllowedError)
    .then(() => (active = false));
  await notificationPromise;
  is(PopupNotifications.panel.state, "open""Doorhanger is visible");

  // Open and switch to a second tab.
  let tab_two = await BrowserTestUtils.openNewForegroundTab(
    gBrowser,
    "https://example.org/"
  );

  await TestUtils.waitForCondition(
    () => PopupNotifications.panel.state == "closed"
  );
  is(PopupNotifications.panel.state, "closed""Doorhanger is hidden");

  let notificationPromise2 = promiseNotification("webauthn-prompt-presence");

  // Go back to the first tab
  await BrowserTestUtils.removeTab(tab_two);

  await notificationPromise2;

  await TestUtils.waitForCondition(
    () => PopupNotifications.panel.state == "open"
  );
  is(PopupNotifications.panel.state, "open""Doorhanger is visible");

  // Cancel the request.
  ok(active, "request should still be active");
  await triggerMainPopupCommand(PopupNotifications.panel);
  await request;
  ok(!active, "request should be stopped");

  // Close tab.
  await BrowserTestUtils.removeTab(tab_one);
}

// Add two tabs, open WebAuthn in the first, switch, assert the prompt is
// not visible, switch back, assert the prompt is there and cancel it.
async function test_window_switching() {
  // Open a new tab.
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);

  // Request a new credential and wait for the prompt.
  let notificationPromise = promiseNotification("webauthn-prompt-presence");
  let active = true;
  let request = promiseWebAuthnMakeCredential(tab)
    .then(arrivingHereIsBad)
    .catch(expectNotAllowedError)
    .then(() => (active = false));
  await notificationPromise;

  await TestUtils.waitForCondition(
    () => PopupNotifications.panel.state == "open"
  );
  is(PopupNotifications.panel.state, "open""Doorhanger is visible");

  // Open and switch to a second window
  let new_window = await BrowserTestUtils.openNewBrowserWindow();
  await SimpleTest.promiseFocus(new_window);

  await TestUtils.waitForCondition(
    () => new_window.PopupNotifications.panel.state == "closed"
  );
  is(
    new_window.PopupNotifications.panel.state,
    "closed",
    "Doorhanger is hidden"
  );

  // Go back to the first tab
  await BrowserTestUtils.closeWindow(new_window);
  await SimpleTest.promiseFocus(window);

  await TestUtils.waitForCondition(
    () => PopupNotifications.panel.state == "open"
  );
  is(PopupNotifications.panel.state, "open""Doorhanger is still visible");

  // Cancel the request.
  ok(active, "request should still be active");
  await triggerMainPopupCommand(PopupNotifications.panel);
  await request;
  ok(!active, "request should be stopped");

  // Close tab.
  await BrowserTestUtils.removeTab(tab);
}

async function test_register_direct_with_consent() {
  // Open a new tab.
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);

  // Request a new credential with direct attestation and wait for the prompt.
  let notificationPromise = promiseNotification(
    "webauthn-prompt-register-direct"
  );
  let request = promiseWebAuthnMakeCredential(tab, "direct");
  await notificationPromise;

  // Click "Allow".
  PopupNotifications.panel.firstElementChild.button.click();

  // Ensure we got "direct" attestation.
  await request.then(verifyDirectCertificate);

  // Close tab.
  await BrowserTestUtils.removeTab(tab);
}

async function test_register_direct_without_consent() {
  // Open a new tab.
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);

  // Request a new credential with direct attestation and wait for the prompt.
  let notificationPromise = promiseNotification(
    "webauthn-prompt-register-direct"
  );
  let request = promiseWebAuthnMakeCredential(tab, "direct");
  await notificationPromise;

  // Click "Block".
  PopupNotifications.panel.firstElementChild.secondaryButton.click();

  // Ensure we got "none" attestation.
  await request.then(verifyAnonymizedCertificate);

  // Close tab.
  await BrowserTestUtils.removeTab(tab);
}

async function test_select_sign_result() {
  // Open a new tab.
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);

  // Make two discoverable credentials for the same RP ID so that
  // the user has to select one to return.
  let cred1 = await addCredential(gAuthenticatorId, "example.com");
  let cred2 = await addCredential(gAuthenticatorId, "example.com");

  let notificationPromise = promiseNotification(
    "webauthn-prompt-select-sign-result"
  );
  let active = true;
  let request = promiseWebAuthnGetAssertionDiscoverable(tab)
    .then(arrivingHereIsBad)
    .catch(expectNotAllowedError)
    .then(() => (active = false));

  // Ensure the selection prompt is shown
  await notificationPromise;

  ok(active, "request is active");

  // Cancel the request
  PopupNotifications.panel.firstElementChild.button.click();
  await request;

  await removeCredential(gAuthenticatorId, cred1);
  await removeCredential(gAuthenticatorId, cred2);
  await BrowserTestUtils.removeTab(tab);
}

async function test_fullscreen_show_nav_toolbar() {
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);

  // Start with the window fullscreen and the nav toolbox hidden
  let fullscreenState = window.fullScreen;

  let navToolboxHiddenPromise = promiseNavToolboxStatus("hidden");

  window.fullScreen = true;
  FullScreen.hideNavToolbox(false);

  await navToolboxHiddenPromise;

  // Request a new credential with direct attestation. The consent prompt will
  // keep the request active until we can verify that the nav toolbar is shown.
  let promptPromise = promiseNotification("webauthn-prompt-register-direct");
  let navToolboxShownPromise = promiseNavToolboxStatus("shown");

  let active = true;
  let requestPromise = promiseWebAuthnMakeCredential(tab, "direct").then(
    () => (active = false)
  );

  await Promise.all([promptPromise, navToolboxShownPromise]);

  ok(active, "request is active");
  ok(window.fullScreen, "window is fullscreen");

  // Proceed through the consent prompt.
  PopupNotifications.panel.firstElementChild.secondaryButton.click();
  await requestPromise;

  window.fullScreen = fullscreenState;

  // Close tab.
  await BrowserTestUtils.removeTab(tab);
}

async function test_no_fullscreen_dom() {
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);

  let fullScreenPaintPromise = promiseFullScreenPaint();
  // Make a DOM element fullscreen
  await ContentTask.spawn(tab.linkedBrowser, [], () => {
    return content.document.body.requestFullscreen();
  });
  await fullScreenPaintPromise;
  ok(!!document.fullscreenElement, "a DOM element is fullscreen");

  // Request a new credential with direct attestation. The consent prompt will
  // keep the request active until we can verify that we've left fullscreen.
  let promptPromise = promiseNotification("webauthn-prompt-register-direct");
  fullScreenPaintPromise = promiseFullScreenPaint();

  let active = true;
  let requestPromise = promiseWebAuthnMakeCredential(tab, "direct").then(
    () => (active = false)
  );

  await Promise.all([promptPromise, fullScreenPaintPromise]);

  ok(active, "request is active");
  ok(!document.fullscreenElement, "no DOM element is fullscreen");

  // Proceed through the consent prompt.
  await waitForPopupNotificationSecurityDelay();
  PopupNotifications.panel.firstElementChild.secondaryButton.click();
  await requestPromise;

  // Close tab.
  await BrowserTestUtils.removeTab(tab);
}

Messung V0.5 in Prozent
C=94 H=98 G=95

¤ Dauer der Verarbeitung: 0.23 Sekunden  (vorverarbeitet am  2026-04-26) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.