summaryrefslogtreecommitdiffstats
path: root/dom/webauthn/WebAuthnTransactionParent.cpp
blob: d73542d4788476e0d023dd711cba3fe025f9dc98 (plain)
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
/* -*- 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/. */

#include "mozilla/dom/WebAuthnTransactionParent.h"
#include "mozilla/dom/WebAuthnController.h"
#include "mozilla/dom/U2FTokenManager.h"
#include "mozilla/ipc/PBackgroundParent.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/StaticPrefs_security.h"

#include "nsThreadUtils.h"

#ifdef OS_WIN
#  include "WinWebAuthnManager.h"
#endif

namespace mozilla::dom {

mozilla::ipc::IPCResult WebAuthnTransactionParent::RecvRequestRegister(
    const uint64_t& aTransactionId,
    const WebAuthnMakeCredentialInfo& aTransactionInfo) {
  ::mozilla::ipc::AssertIsOnBackgroundThread();

#ifdef OS_WIN
  if (WinWebAuthnManager::AreWebAuthNApisAvailable()) {
    WinWebAuthnManager* mgr = WinWebAuthnManager::Get();
    mgr->Register(this, aTransactionId, aTransactionInfo);
    return IPC_OK();
  }
#endif

  bool androidFido2 =
      StaticPrefs::security_webauth_webauthn_enable_android_fido2();

  if (!androidFido2) {
    WebAuthnController* ctrl = WebAuthnController::Get();
    ctrl->Register(this, aTransactionId, aTransactionInfo);
  } else {
    U2FTokenManager* mgr = U2FTokenManager::Get();
    mgr->Register(this, aTransactionId, aTransactionInfo);
  }

  return IPC_OK();
}

mozilla::ipc::IPCResult WebAuthnTransactionParent::RecvRequestSign(
    const uint64_t& aTransactionId,
    const WebAuthnGetAssertionInfo& aTransactionInfo) {
  ::mozilla::ipc::AssertIsOnBackgroundThread();

#ifdef OS_WIN
  if (WinWebAuthnManager::AreWebAuthNApisAvailable()) {
    WinWebAuthnManager* mgr = WinWebAuthnManager::Get();
    mgr->Sign(this, aTransactionId, aTransactionInfo);
    return IPC_OK();
  }
#endif

  bool androidFido2 =
      StaticPrefs::security_webauth_webauthn_enable_android_fido2();

  if (!androidFido2) {
    WebAuthnController* ctrl = WebAuthnController::Get();
    ctrl->Sign(this, aTransactionId, aTransactionInfo);
  } else {
    U2FTokenManager* mgr = U2FTokenManager::Get();
    mgr->Sign(this, aTransactionId, aTransactionInfo);
  }

  return IPC_OK();
}

mozilla::ipc::IPCResult WebAuthnTransactionParent::RecvRequestCancel(
    const Tainted<uint64_t>& aTransactionId) {
  ::mozilla::ipc::AssertIsOnBackgroundThread();

#ifdef OS_WIN
  if (WinWebAuthnManager::AreWebAuthNApisAvailable()) {
    WinWebAuthnManager* mgr = WinWebAuthnManager::Get();
    mgr->Cancel(this, aTransactionId);
    return IPC_OK();
  }
#endif

  // We don't know whether WebAuthnController or U2FTokenManager was used, so
  // try cancelling both.
  WebAuthnController* ctrl = WebAuthnController::Get();
  if (ctrl) {
    ctrl->Cancel(this, aTransactionId);
  }

  U2FTokenManager* mgr = U2FTokenManager::Get();
  if (mgr) {
    mgr->Cancel(this, aTransactionId);
  }

  return IPC_OK();
}

mozilla::ipc::IPCResult WebAuthnTransactionParent::RecvDestroyMe() {
  ::mozilla::ipc::AssertIsOnBackgroundThread();

  // The child was disconnected from the WebAuthnManager instance and will send
  // no further messages. It is kept alive until we delete it explicitly.

  // The child should have cancelled any active transaction. This means
  // we expect no more messages to the child. We'll crash otherwise.

  // The IPC roundtrip is complete. No more messages, hopefully.
  IProtocol* mgr = Manager();
  if (!Send__delete__(this)) {
    return IPC_FAIL_NO_REASON(mgr);
  }

  return IPC_OK();
}

void WebAuthnTransactionParent::ActorDestroy(ActorDestroyReason aWhy) {
  ::mozilla::ipc::AssertIsOnBackgroundThread();

  // Called either by Send__delete__() in RecvDestroyMe() above, or when
  // the channel disconnects. Ensure the token manager forgets about us.

#ifdef OS_WIN
  if (WinWebAuthnManager::AreWebAuthNApisAvailable()) {
    WinWebAuthnManager* mgr = WinWebAuthnManager::Get();
    if (mgr) {
      mgr->MaybeClearTransaction(this);
    }
    return;
  }
#endif

  WebAuthnController* ctrl = WebAuthnController::Get();
  if (ctrl) {
    ctrl->MaybeClearTransaction(this);
  }

  U2FTokenManager* mgr = U2FTokenManager::Get();
  if (mgr) {
    mgr->MaybeClearTransaction(this);
  }
}

}  // namespace mozilla::dom