gecko-dev/dom/webauthn/WebAuthnManager.h

173 строки
5.5 KiB
C
Исходник Обычный вид История

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_WebAuthnManager_h
#define mozilla_dom_WebAuthnManager_h
#include "mozilla/MozPromise.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/PWebAuthnTransaction.h"
#include "nsIDOMEventListener.h"
/*
* Content process manager for the WebAuthn protocol. Created on calls to the
* WebAuthentication DOM object, this manager handles establishing IPC channels
* for WebAuthn transactions, as well as keeping track of JS Promise objects
* representing transactions in flight.
*
* The WebAuthn spec (https://www.w3.org/TR/webauthn/) allows for two different
* types of transactions: registration and signing. When either of these is
* requested via the DOM API, the following steps are executed in the
* WebAuthnManager:
*
* - Validation of the request. Return a failed promise to js if request does
* not have correct parameters.
*
* - If request is valid, open a new IPC channel for running the transaction. If
* another transaction is already running in this content process, cancel it.
* Return a pending promise to js.
*
* - Send transaction information to parent process (by running the Start*
* functions of WebAuthnManager). Assuming another transaction is currently in
* flight in another content process, parent will handle canceling it.
*
* - On return of successful transaction information from parent process, turn
* information into DOM object format required by spec, and resolve promise
* (by running the Finish* functions of WebAuthnManager). On cancellation
* request from parent, reject promise with corresponding error code. Either
* outcome will also close the IPC channel.
*
*/
// Forward decl because of nsHTMLDocument.h's complex dependency on /layout/style
class nsHTMLDocument {
public:
bool IsRegistrableDomainSuffixOfOrEqualTo(const nsAString& aHostSuffixString,
const nsACString& aOrigHost);
};
namespace mozilla {
namespace dom {
struct Account;
class ArrayBufferViewOrArrayBuffer;
struct AssertionOptions;
class OwningArrayBufferViewOrArrayBuffer;
struct MakePublicKeyCredentialOptions;
class Promise;
class WebAuthnTransactionChild;
Bug 1409434 - Rework WebAuthnManager state machine r=jcj Summary: This patch aims to clean up the WebAuthnManager's state machine, especially to make cancellation of transactions clearer. To fix bug 1403818, we'll have to later introduce a unique id that is forwarded to the U2FTokenManager. There are multiple stages of cancellation/cleanup after a transaction was started. All of the places where we previously called Cancel() or MaybeClearTransaction() are listed below: [stage 1] ClearTransaction This is the most basic stage, we only clean up what information we have about the current transaction. This means that the request was completed successfully. It is used at the end of FinishMakeCredential() and FinishGetAssertion(). [stage 2] RejectTransaction The second stage will reject the transaction promise we returned to the caller. Then it will call ClearTransaction, i.e. stage 1. It is used when one of the two Finish*() functions aborts before completion, or when the parent process sends a RequestAborted message. [stage 2b] MaybeRejectTransaction This is the same as stage 2, but will only run if there's an active transaction. It is used by ~WebAuthnManager() to reject and clean up when we the manager goes away. [stage 3] CancelTransaction The third stage sends a "Cancel" message to the parent process before rejecting the transaction promise (stage 2) and cleaning up (stage 1). It's used by HandleEvent(), i.e. the document becomes inactive. [stage 3b] MaybeCancelTransaction This is the same as stage 3, but will only run if there's an active transaction. it is used at the top of MakeCredential() and GetAssertion() so that any active transaction is cancelled before we handle a new request. Reviewers: jcj Reviewed By: jcj Bug #: 1409434 Differential Revision: https://phabricator.services.mozilla.com/D132
2017-10-18 16:04:56 +03:00
class WebAuthnTransaction
{
public:
WebAuthnTransaction(nsPIDOMWindowInner* aParent,
const RefPtr<Promise>& aPromise,
const nsTArray<uint8_t>& aRpIdHash,
const nsCString& aClientData,
AbortSignal* aSignal)
: mParent(aParent)
, mPromise(aPromise)
, mRpIdHash(aRpIdHash)
Bug 1409434 - Rework WebAuthnManager state machine r=jcj Summary: This patch aims to clean up the WebAuthnManager's state machine, especially to make cancellation of transactions clearer. To fix bug 1403818, we'll have to later introduce a unique id that is forwarded to the U2FTokenManager. There are multiple stages of cancellation/cleanup after a transaction was started. All of the places where we previously called Cancel() or MaybeClearTransaction() are listed below: [stage 1] ClearTransaction This is the most basic stage, we only clean up what information we have about the current transaction. This means that the request was completed successfully. It is used at the end of FinishMakeCredential() and FinishGetAssertion(). [stage 2] RejectTransaction The second stage will reject the transaction promise we returned to the caller. Then it will call ClearTransaction, i.e. stage 1. It is used when one of the two Finish*() functions aborts before completion, or when the parent process sends a RequestAborted message. [stage 2b] MaybeRejectTransaction This is the same as stage 2, but will only run if there's an active transaction. It is used by ~WebAuthnManager() to reject and clean up when we the manager goes away. [stage 3] CancelTransaction The third stage sends a "Cancel" message to the parent process before rejecting the transaction promise (stage 2) and cleaning up (stage 1). It's used by HandleEvent(), i.e. the document becomes inactive. [stage 3b] MaybeCancelTransaction This is the same as stage 3, but will only run if there's an active transaction. it is used at the top of MakeCredential() and GetAssertion() so that any active transaction is cancelled before we handle a new request. Reviewers: jcj Reviewed By: jcj Bug #: 1409434 Differential Revision: https://phabricator.services.mozilla.com/D132
2017-10-18 16:04:56 +03:00
, mClientData(aClientData)
, mSignal(aSignal)
, mId(NextId())
{
MOZ_ASSERT(mId > 0);
}
Bug 1409434 - Rework WebAuthnManager state machine r=jcj Summary: This patch aims to clean up the WebAuthnManager's state machine, especially to make cancellation of transactions clearer. To fix bug 1403818, we'll have to later introduce a unique id that is forwarded to the U2FTokenManager. There are multiple stages of cancellation/cleanup after a transaction was started. All of the places where we previously called Cancel() or MaybeClearTransaction() are listed below: [stage 1] ClearTransaction This is the most basic stage, we only clean up what information we have about the current transaction. This means that the request was completed successfully. It is used at the end of FinishMakeCredential() and FinishGetAssertion(). [stage 2] RejectTransaction The second stage will reject the transaction promise we returned to the caller. Then it will call ClearTransaction, i.e. stage 1. It is used when one of the two Finish*() functions aborts before completion, or when the parent process sends a RequestAborted message. [stage 2b] MaybeRejectTransaction This is the same as stage 2, but will only run if there's an active transaction. It is used by ~WebAuthnManager() to reject and clean up when we the manager goes away. [stage 3] CancelTransaction The third stage sends a "Cancel" message to the parent process before rejecting the transaction promise (stage 2) and cleaning up (stage 1). It's used by HandleEvent(), i.e. the document becomes inactive. [stage 3b] MaybeCancelTransaction This is the same as stage 3, but will only run if there's an active transaction. it is used at the top of MakeCredential() and GetAssertion() so that any active transaction is cancelled before we handle a new request. Reviewers: jcj Reviewed By: jcj Bug #: 1409434 Differential Revision: https://phabricator.services.mozilla.com/D132
2017-10-18 16:04:56 +03:00
// Parent of the context we're running the transaction in.
nsCOMPtr<nsPIDOMWindowInner> mParent;
Bug 1409434 - Rework WebAuthnManager state machine r=jcj Summary: This patch aims to clean up the WebAuthnManager's state machine, especially to make cancellation of transactions clearer. To fix bug 1403818, we'll have to later introduce a unique id that is forwarded to the U2FTokenManager. There are multiple stages of cancellation/cleanup after a transaction was started. All of the places where we previously called Cancel() or MaybeClearTransaction() are listed below: [stage 1] ClearTransaction This is the most basic stage, we only clean up what information we have about the current transaction. This means that the request was completed successfully. It is used at the end of FinishMakeCredential() and FinishGetAssertion(). [stage 2] RejectTransaction The second stage will reject the transaction promise we returned to the caller. Then it will call ClearTransaction, i.e. stage 1. It is used when one of the two Finish*() functions aborts before completion, or when the parent process sends a RequestAborted message. [stage 2b] MaybeRejectTransaction This is the same as stage 2, but will only run if there's an active transaction. It is used by ~WebAuthnManager() to reject and clean up when we the manager goes away. [stage 3] CancelTransaction The third stage sends a "Cancel" message to the parent process before rejecting the transaction promise (stage 2) and cleaning up (stage 1). It's used by HandleEvent(), i.e. the document becomes inactive. [stage 3b] MaybeCancelTransaction This is the same as stage 3, but will only run if there's an active transaction. it is used at the top of MakeCredential() and GetAssertion() so that any active transaction is cancelled before we handle a new request. Reviewers: jcj Reviewed By: jcj Bug #: 1409434 Differential Revision: https://phabricator.services.mozilla.com/D132
2017-10-18 16:04:56 +03:00
// JS Promise representing the transaction status.
RefPtr<Promise> mPromise;
// The RP ID hash.
nsTArray<uint8_t> mRpIdHash;
Bug 1409434 - Rework WebAuthnManager state machine r=jcj Summary: This patch aims to clean up the WebAuthnManager's state machine, especially to make cancellation of transactions clearer. To fix bug 1403818, we'll have to later introduce a unique id that is forwarded to the U2FTokenManager. There are multiple stages of cancellation/cleanup after a transaction was started. All of the places where we previously called Cancel() or MaybeClearTransaction() are listed below: [stage 1] ClearTransaction This is the most basic stage, we only clean up what information we have about the current transaction. This means that the request was completed successfully. It is used at the end of FinishMakeCredential() and FinishGetAssertion(). [stage 2] RejectTransaction The second stage will reject the transaction promise we returned to the caller. Then it will call ClearTransaction, i.e. stage 1. It is used when one of the two Finish*() functions aborts before completion, or when the parent process sends a RequestAborted message. [stage 2b] MaybeRejectTransaction This is the same as stage 2, but will only run if there's an active transaction. It is used by ~WebAuthnManager() to reject and clean up when we the manager goes away. [stage 3] CancelTransaction The third stage sends a "Cancel" message to the parent process before rejecting the transaction promise (stage 2) and cleaning up (stage 1). It's used by HandleEvent(), i.e. the document becomes inactive. [stage 3b] MaybeCancelTransaction This is the same as stage 3, but will only run if there's an active transaction. it is used at the top of MakeCredential() and GetAssertion() so that any active transaction is cancelled before we handle a new request. Reviewers: jcj Reviewed By: jcj Bug #: 1409434 Differential Revision: https://phabricator.services.mozilla.com/D132
2017-10-18 16:04:56 +03:00
// Client data used to assemble reply objects.
nsCString mClientData;
// An optional AbortSignal instance.
RefPtr<AbortSignal> mSignal;
// Unique transaction id.
uint64_t mId;
private:
// Generates a unique id for new transactions. This doesn't have to be unique
// forever, it's sufficient to differentiate between temporally close
// transactions, where messages can intersect. Can overflow.
static uint64_t NextId() {
static uint64_t id = 0;
return ++id;
}
Bug 1409434 - Rework WebAuthnManager state machine r=jcj Summary: This patch aims to clean up the WebAuthnManager's state machine, especially to make cancellation of transactions clearer. To fix bug 1403818, we'll have to later introduce a unique id that is forwarded to the U2FTokenManager. There are multiple stages of cancellation/cleanup after a transaction was started. All of the places where we previously called Cancel() or MaybeClearTransaction() are listed below: [stage 1] ClearTransaction This is the most basic stage, we only clean up what information we have about the current transaction. This means that the request was completed successfully. It is used at the end of FinishMakeCredential() and FinishGetAssertion(). [stage 2] RejectTransaction The second stage will reject the transaction promise we returned to the caller. Then it will call ClearTransaction, i.e. stage 1. It is used when one of the two Finish*() functions aborts before completion, or when the parent process sends a RequestAborted message. [stage 2b] MaybeRejectTransaction This is the same as stage 2, but will only run if there's an active transaction. It is used by ~WebAuthnManager() to reject and clean up when we the manager goes away. [stage 3] CancelTransaction The third stage sends a "Cancel" message to the parent process before rejecting the transaction promise (stage 2) and cleaning up (stage 1). It's used by HandleEvent(), i.e. the document becomes inactive. [stage 3b] MaybeCancelTransaction This is the same as stage 3, but will only run if there's an active transaction. it is used at the top of MakeCredential() and GetAssertion() so that any active transaction is cancelled before we handle a new request. Reviewers: jcj Reviewed By: jcj Bug #: 1409434 Differential Revision: https://phabricator.services.mozilla.com/D132
2017-10-18 16:04:56 +03:00
};
class WebAuthnManager final : public nsIDOMEventListener
, public AbortFollower
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMEVENTLISTENER
static WebAuthnManager* GetOrCreate();
static WebAuthnManager* Get();
already_AddRefed<Promise>
MakeCredential(nsPIDOMWindowInner* aParent,
const MakePublicKeyCredentialOptions& aOptions,
const Optional<OwningNonNull<AbortSignal>>& aSignal);
already_AddRefed<Promise>
GetAssertion(nsPIDOMWindowInner* aParent,
const PublicKeyCredentialRequestOptions& aOptions,
const Optional<OwningNonNull<AbortSignal>>& aSignal);
already_AddRefed<Promise>
Store(nsPIDOMWindowInner* aParent, const Credential& aCredential);
void
FinishMakeCredential(const uint64_t& aTransactionId,
nsTArray<uint8_t>& aRegBuffer);
void
FinishGetAssertion(const uint64_t& aTransactionId,
nsTArray<uint8_t>& aCredentialId,
nsTArray<uint8_t>& aSigBuffer);
void
RequestAborted(const uint64_t& aTransactionId, const nsresult& aError);
void Abort() override;
void ActorDestroyed();
private:
WebAuthnManager();
virtual ~WebAuthnManager();
Bug 1409434 - Rework WebAuthnManager state machine r=jcj Summary: This patch aims to clean up the WebAuthnManager's state machine, especially to make cancellation of transactions clearer. To fix bug 1403818, we'll have to later introduce a unique id that is forwarded to the U2FTokenManager. There are multiple stages of cancellation/cleanup after a transaction was started. All of the places where we previously called Cancel() or MaybeClearTransaction() are listed below: [stage 1] ClearTransaction This is the most basic stage, we only clean up what information we have about the current transaction. This means that the request was completed successfully. It is used at the end of FinishMakeCredential() and FinishGetAssertion(). [stage 2] RejectTransaction The second stage will reject the transaction promise we returned to the caller. Then it will call ClearTransaction, i.e. stage 1. It is used when one of the two Finish*() functions aborts before completion, or when the parent process sends a RequestAborted message. [stage 2b] MaybeRejectTransaction This is the same as stage 2, but will only run if there's an active transaction. It is used by ~WebAuthnManager() to reject and clean up when we the manager goes away. [stage 3] CancelTransaction The third stage sends a "Cancel" message to the parent process before rejecting the transaction promise (stage 2) and cleaning up (stage 1). It's used by HandleEvent(), i.e. the document becomes inactive. [stage 3b] MaybeCancelTransaction This is the same as stage 3, but will only run if there's an active transaction. it is used at the top of MakeCredential() and GetAssertion() so that any active transaction is cancelled before we handle a new request. Reviewers: jcj Reviewed By: jcj Bug #: 1409434 Differential Revision: https://phabricator.services.mozilla.com/D132
2017-10-18 16:04:56 +03:00
// Clears all information we have about the current transaction.
void ClearTransaction();
// Rejects the current transaction and calls ClearTransaction().
void RejectTransaction(const nsresult& aError);
// Cancels the current transaction (by sending a Cancel message to the
// parent) and rejects it by calling RejectTransaction().
void CancelTransaction(const nsresult& aError);
bool MaybeCreateBackgroundActor();
// IPC Channel to the parent process.
RefPtr<WebAuthnTransactionChild> mChild;
Bug 1409434 - Rework WebAuthnManager state machine r=jcj Summary: This patch aims to clean up the WebAuthnManager's state machine, especially to make cancellation of transactions clearer. To fix bug 1403818, we'll have to later introduce a unique id that is forwarded to the U2FTokenManager. There are multiple stages of cancellation/cleanup after a transaction was started. All of the places where we previously called Cancel() or MaybeClearTransaction() are listed below: [stage 1] ClearTransaction This is the most basic stage, we only clean up what information we have about the current transaction. This means that the request was completed successfully. It is used at the end of FinishMakeCredential() and FinishGetAssertion(). [stage 2] RejectTransaction The second stage will reject the transaction promise we returned to the caller. Then it will call ClearTransaction, i.e. stage 1. It is used when one of the two Finish*() functions aborts before completion, or when the parent process sends a RequestAborted message. [stage 2b] MaybeRejectTransaction This is the same as stage 2, but will only run if there's an active transaction. It is used by ~WebAuthnManager() to reject and clean up when we the manager goes away. [stage 3] CancelTransaction The third stage sends a "Cancel" message to the parent process before rejecting the transaction promise (stage 2) and cleaning up (stage 1). It's used by HandleEvent(), i.e. the document becomes inactive. [stage 3b] MaybeCancelTransaction This is the same as stage 3, but will only run if there's an active transaction. it is used at the top of MakeCredential() and GetAssertion() so that any active transaction is cancelled before we handle a new request. Reviewers: jcj Reviewed By: jcj Bug #: 1409434 Differential Revision: https://phabricator.services.mozilla.com/D132
2017-10-18 16:04:56 +03:00
// The current transaction, if any.
Maybe<WebAuthnTransaction> mTransaction;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_WebAuthnManager_h