DXR will be turned off on Tuesday, December 29th. It will redirect to Searchfox.
See the announcement on Discourse.

DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (1aeaa33a64f9)

VCS Links

Line Code
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
/* -*- 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_U2F_h
#define mozilla_dom_U2F_h

#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/U2FBinding.h"
#include "mozilla/dom/WebAuthnManagerBase.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/MozPromise.h"
#include "nsProxyRelease.h"
#include "nsWrapperCache.h"
#include "U2FAuthenticator.h"

namespace mozilla {
namespace dom {

class WebAuthnMakeCredentialResult;
class WebAuthnGetAssertionResult;

class U2FRegisterCallback;
class U2FSignCallback;

// Defined in U2FBinding.h by the U2F.webidl; their use requires a JSContext.
struct RegisterRequest;
struct RegisteredKey;

class U2FTransaction {
  typedef Variant<nsMainThreadPtrHandle<U2FRegisterCallback>,
                  nsMainThreadPtrHandle<U2FSignCallback>>
      U2FCallback;

 public:
  explicit U2FTransaction(const nsCString& aClientData,
                          const U2FCallback&& aCallback)
      : mClientData(aClientData), mCallback(Move(aCallback)), mId(NextId()) {
    MOZ_ASSERT(mId > 0);
  }

  bool HasRegisterCallback() {
    return mCallback.is<nsMainThreadPtrHandle<U2FRegisterCallback>>();
  }

  auto& GetRegisterCallback() {
    return mCallback.as<nsMainThreadPtrHandle<U2FRegisterCallback>>();
  }

  bool HasSignCallback() {
    return mCallback.is<nsMainThreadPtrHandle<U2FSignCallback>>();
  }

  auto& GetSignCallback() {
    return mCallback.as<nsMainThreadPtrHandle<U2FSignCallback>>();
  }

  // Client data used to assemble reply objects.
  nsCString mClientData;

  // The callback passed to the API.
  U2FCallback mCallback;

  // 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;
  }
};

class U2F final : public WebAuthnManagerBase, public nsWrapperCache {
 public:
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(U2F)

  explicit U2F(nsPIDOMWindowInner* aParent) : WebAuthnManagerBase(aParent) {}

  nsPIDOMWindowInner* GetParentObject() const { return mParent; }

  void Init(ErrorResult& aRv);

  virtual JSObject* WrapObject(JSContext* aCx,
                               JS::Handle<JSObject*> aGivenProto) override;

  void Register(const nsAString& aAppId,
                const Sequence<RegisterRequest>& aRegisterRequests,
                const Sequence<RegisteredKey>& aRegisteredKeys,
                U2FRegisterCallback& aCallback,
                const Optional<Nullable<int32_t>>& opt_aTimeoutSeconds,
                ErrorResult& aRv);

  void Sign(const nsAString& aAppId, const nsAString& aChallenge,
            const Sequence<RegisteredKey>& aRegisteredKeys,
            U2FSignCallback& aCallback,
            const Optional<Nullable<int32_t>>& opt_aTimeoutSeconds,
            ErrorResult& aRv);

  // WebAuthnManagerBase

  void FinishMakeCredential(
      const uint64_t& aTransactionId,
      const WebAuthnMakeCredentialResult& aResult) override;

  void FinishGetAssertion(const uint64_t& aTransactionId,
                          const WebAuthnGetAssertionResult& aResult) override;

  void RequestAborted(const uint64_t& aTransactionId,
                      const nsresult& aError) override;

 protected:
  // Cancels the current transaction (by sending a Cancel message to the
  // parent) and rejects it by calling RejectTransaction().
  void CancelTransaction(const nsresult& aError) override;

 private:
  ~U2F();

  template <typename T, typename C>
  void ExecuteCallback(T& aResp, nsMainThreadPtrHandle<C>& aCb);

  // Clears all information we have about the current transaction.
  void ClearTransaction();
  // Rejects the current transaction and clears it.
  void RejectTransaction(const nsresult& aError);

  nsString mOrigin;

  // The current transaction, if any.
  Maybe<U2FTransaction> mTransaction;
};

}  // namespace dom
}  // namespace mozilla

#endif  // mozilla_dom_U2F_h