tor-browser

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

WebAuthnHandler.h (5628B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_WebAuthnHandler_h
      8 #define mozilla_dom_WebAuthnHandler_h
      9 
     10 #include "mozilla/Maybe.h"
     11 #include "mozilla/MozPromise.h"
     12 #include "mozilla/dom/AbortSignal.h"
     13 #include "mozilla/dom/PWebAuthnTransaction.h"
     14 #include "mozilla/dom/PWebAuthnTransactionChild.h"
     15 #include "mozilla/dom/Promise.h"
     16 #include "mozilla/dom/WebAuthnTransactionChild.h"
     17 
     18 /*
     19 * Content process handler for the WebAuthn protocol. Created on calls to the
     20 * WebAuthentication DOM object, this is responsible for establishing IPC
     21 * channels for WebAuthn transactions as well as keeping track of JS Promise
     22 * objects representing transactions in flight.
     23 *
     24 * The WebAuthn spec (https://www.w3.org/TR/webauthn/) allows for two different
     25 * types of transactions: registration and signing. When either of these is
     26 * requested via the DOM API, the following steps are executed in the
     27 * WebAuthnHandler:
     28 *
     29 * - Validation of the request. Return a failed promise to js if request does
     30 *   not have correct parameters.
     31 *
     32 * - If request is valid, open a new IPC channel for running the transaction. If
     33 *   another transaction is already running in this content process, cancel it.
     34 *   Return a pending promise to js.
     35 *
     36 * - Send transaction information to parent process.
     37 *
     38 * - On return of successful transaction information from parent process, turn
     39 *   information into DOM object format required by spec, and resolve promise
     40 *   (by running the Finish* functions of WebAuthnHandler). On cancellation
     41 *   request from parent, reject promise with corresponding error code.
     42 *
     43 */
     44 
     45 namespace mozilla::dom {
     46 
     47 class Credential;
     48 class PublicKeyCredential;
     49 struct PublicKeyCredentialCreationOptions;
     50 struct PublicKeyCredentialRequestOptions;
     51 
     52 enum class WebAuthnTransactionType { Create, Get };
     53 
     54 class WebAuthnTransaction {
     55 public:
     56  explicit WebAuthnTransaction(const RefPtr<Promise>& aPromise,
     57                               WebAuthnTransactionType aType)
     58      : mPromise(aPromise), mType(aType) {}
     59 
     60  // JS Promise representing the transaction status.
     61  RefPtr<Promise> mPromise;
     62 
     63  WebAuthnTransactionType mType;
     64 
     65  // These holders are used to track the transaction once it has been dispatched
     66  // to the parent process. Once ->Track()'d, they must either be disconnected
     67  // (through a call to WebAuthnHandler::CancelTransaction) or completed
     68  // (through a response on the IPC channel) before this WebAuthnTransaction is
     69  // destroyed.
     70  MozPromiseRequestHolder<PWebAuthnTransactionChild::RequestRegisterPromise>
     71      mRegisterHolder;
     72  MozPromiseRequestHolder<PWebAuthnTransactionChild::RequestSignPromise>
     73      mSignHolder;
     74 };
     75 
     76 class WebAuthnHandler final : public AbortFollower {
     77 public:
     78  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     79  NS_DECL_CYCLE_COLLECTION_CLASS(WebAuthnHandler)
     80 
     81  explicit WebAuthnHandler(nsPIDOMWindowInner* aWindow) : mWindow(aWindow) {
     82    MOZ_ASSERT(NS_IsMainThread());
     83    MOZ_ASSERT(aWindow);
     84  }
     85 
     86  already_AddRefed<Promise> MakeCredential(
     87      const PublicKeyCredentialCreationOptions& aOptions,
     88      const Optional<OwningNonNull<AbortSignal>>& aSignal, ErrorResult& aError);
     89 
     90  already_AddRefed<Promise> GetAssertion(
     91      const PublicKeyCredentialRequestOptions& aOptions,
     92      const bool aConditionallyMediated,
     93      const Optional<OwningNonNull<AbortSignal>>& aSignal, ErrorResult& aError);
     94 
     95  already_AddRefed<Promise> Store(const Credential& aCredential,
     96                                  ErrorResult& aError);
     97 
     98  already_AddRefed<Promise> IsUVPAA(GlobalObject& aGlobal, ErrorResult& aError);
     99 
    100  void ActorDestroyed();
    101 
    102  // AbortFollower
    103  void RunAbortAlgorithm() override;
    104 
    105 private:
    106  virtual ~WebAuthnHandler();
    107 
    108  bool MaybeCreateActor();
    109 
    110  void FinishMakeCredential(const WebAuthnMakeCredentialResult& aResult);
    111 
    112  void FinishGetAssertion(const WebAuthnGetAssertionResult& aResult);
    113 
    114  // Send a Cancel message to the parent, reject the promise with the given
    115  // reason (an nsresult or JS::Handle<JS::Value>), and clear the transaction.
    116  template <typename T>
    117  void CancelTransaction(const T& aReason) {
    118    MOZ_ASSERT(mActor);
    119    MOZ_ASSERT(mTransaction.isSome());
    120 
    121    mTransaction.ref().mRegisterHolder.DisconnectIfExists();
    122    mTransaction.ref().mSignHolder.DisconnectIfExists();
    123 
    124    mActor->SendRequestCancel();
    125    RejectTransaction(aReason);
    126  }
    127 
    128  // Resolve the promise with the given credential.
    129  void ResolveTransaction(const RefPtr<PublicKeyCredential>& aCredential);
    130 
    131  // Reject the promise with the given reason (an nsresult or JS::Value), and
    132  // clear the transaction.
    133  template <typename T>
    134  void RejectTransaction(const T& aReason);
    135 
    136  // The parent window.
    137  nsCOMPtr<nsPIDOMWindowInner> mWindow;
    138 
    139  // IPC Channel to the parent process.
    140  RefPtr<WebAuthnTransactionChild> mActor;
    141 
    142  // The current transaction, if any.
    143  Maybe<WebAuthnTransaction> mTransaction;
    144 };
    145 
    146 inline void ImplCycleCollectionTraverse(
    147    nsCycleCollectionTraversalCallback& aCallback,
    148    WebAuthnTransaction& aTransaction, const char* aName, uint32_t aFlags = 0) {
    149  ImplCycleCollectionTraverse(aCallback, aTransaction.mPromise, aName, aFlags);
    150 }
    151 
    152 inline void ImplCycleCollectionUnlink(WebAuthnTransaction& aTransaction) {
    153  ImplCycleCollectionUnlink(aTransaction.mPromise);
    154 }
    155 
    156 }  // namespace mozilla::dom
    157 
    158 #endif  // mozilla_dom_WebAuthnHandler_h