File: WebAuthnHandler.h

package info (click to toggle)
firefox 143.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,617,328 kB
  • sloc: cpp: 7,478,492; javascript: 6,417,157; ansic: 3,720,058; python: 1,396,372; xml: 627,523; asm: 438,677; java: 186,156; sh: 63,477; makefile: 19,171; objc: 13,059; perl: 12,983; yacc: 4,583; cs: 3,846; pascal: 3,405; lex: 1,720; ruby: 1,003; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 53; csh: 10
file content (159 lines) | stat: -rw-r--r-- 5,659 bytes parent folder | download | duplicates (4)
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
147
148
149
150
151
152
153
154
155
156
157
158
159
/* -*- 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_WebAuthnHandler_h
#define mozilla_dom_WebAuthnHandler_h

#include "mozilla/Maybe.h"
#include "mozilla/MozPromise.h"
#include "mozilla/RandomNum.h"
#include "mozilla/dom/AbortSignal.h"
#include "mozilla/dom/PWebAuthnTransaction.h"
#include "mozilla/dom/PWebAuthnTransactionChild.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/WebAuthnTransactionChild.h"

/*
 * Content process handler for the WebAuthn protocol. Created on calls to the
 * WebAuthentication DOM object, this is responsible for 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
 * WebAuthnHandler:
 *
 * - 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.
 *
 * - 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 WebAuthnHandler). On cancellation
 *   request from parent, reject promise with corresponding error code.
 *
 */

namespace mozilla::dom {

class Credential;
class PublicKeyCredential;
struct PublicKeyCredentialCreationOptions;
struct PublicKeyCredentialRequestOptions;

enum class WebAuthnTransactionType { Create, Get };

class WebAuthnTransaction {
 public:
  explicit WebAuthnTransaction(const RefPtr<Promise>& aPromise,
                               WebAuthnTransactionType aType)
      : mPromise(aPromise), mType(aType) {}

  // JS Promise representing the transaction status.
  RefPtr<Promise> mPromise;

  WebAuthnTransactionType mType;

  // These holders are used to track the transaction once it has been dispatched
  // to the parent process. Once ->Track()'d, they must either be disconnected
  // (through a call to WebAuthnHandler::CancelTransaction) or completed
  // (through a response on the IPC channel) before this WebAuthnTransaction is
  // destroyed.
  MozPromiseRequestHolder<PWebAuthnTransactionChild::RequestRegisterPromise>
      mRegisterHolder;
  MozPromiseRequestHolder<PWebAuthnTransactionChild::RequestSignPromise>
      mSignHolder;
};

class WebAuthnHandler final : public AbortFollower {
 public:
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  NS_DECL_CYCLE_COLLECTION_CLASS(WebAuthnHandler)

  explicit WebAuthnHandler(nsPIDOMWindowInner* aWindow) : mWindow(aWindow) {
    MOZ_ASSERT(NS_IsMainThread());
    MOZ_ASSERT(aWindow);
  }

  already_AddRefed<Promise> MakeCredential(
      const PublicKeyCredentialCreationOptions& aOptions,
      const Optional<OwningNonNull<AbortSignal>>& aSignal, ErrorResult& aError);

  already_AddRefed<Promise> GetAssertion(
      const PublicKeyCredentialRequestOptions& aOptions,
      const bool aConditionallyMediated,
      const Optional<OwningNonNull<AbortSignal>>& aSignal, ErrorResult& aError);

  already_AddRefed<Promise> Store(const Credential& aCredential,
                                  ErrorResult& aError);

  already_AddRefed<Promise> IsUVPAA(GlobalObject& aGlobal, ErrorResult& aError);

  void ActorDestroyed();

  // AbortFollower
  void RunAbortAlgorithm() override;

 private:
  virtual ~WebAuthnHandler();

  bool MaybeCreateActor();

  void FinishMakeCredential(const WebAuthnMakeCredentialResult& aResult);

  void FinishGetAssertion(const WebAuthnGetAssertionResult& aResult);

  // Send a Cancel message to the parent, reject the promise with the given
  // reason (an nsresult or JS::Handle<JS::Value>), and clear the transaction.
  template <typename T>
  void CancelTransaction(const T& aReason) {
    MOZ_ASSERT(mActor);
    MOZ_ASSERT(mTransaction.isSome());

    mTransaction.ref().mRegisterHolder.DisconnectIfExists();
    mTransaction.ref().mSignHolder.DisconnectIfExists();

    mActor->SendRequestCancel();
    RejectTransaction(aReason);
  }

  // Resolve the promise with the given credential.
  void ResolveTransaction(const RefPtr<PublicKeyCredential>& aCredential);

  // Reject the promise with the given reason (an nsresult or JS::Value), and
  // clear the transaction.
  template <typename T>
  void RejectTransaction(const T& aReason);

  // The parent window.
  nsCOMPtr<nsPIDOMWindowInner> mWindow;

  // IPC Channel to the parent process.
  RefPtr<WebAuthnTransactionChild> mActor;

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

inline void ImplCycleCollectionTraverse(
    nsCycleCollectionTraversalCallback& aCallback,
    WebAuthnTransaction& aTransaction, const char* aName, uint32_t aFlags = 0) {
  ImplCycleCollectionTraverse(aCallback, aTransaction.mPromise, aName, aFlags);
}

inline void ImplCycleCollectionUnlink(WebAuthnTransaction& aTransaction) {
  ImplCycleCollectionUnlink(aTransaction.mPromise);
}

}  // namespace mozilla::dom

#endif  // mozilla_dom_WebAuthnHandler_h