Bug 1880216 - Migrate Fenix docs into Sphinx. r=owlish,geckoview-reviewers,android...
[gecko.git] / dom / webauthn / WebAuthnService.cpp
blob3e1557edbc32cf6d7c7d74ad6b2afd8b440197b8
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "mozilla/Services.h"
6 #include "mozilla/StaticPrefs_security.h"
7 #include "nsIObserverService.h"
8 #include "nsThreadUtils.h"
9 #include "WebAuthnService.h"
10 #include "WebAuthnTransportIdentifiers.h"
12 namespace mozilla::dom {
14 already_AddRefed<nsIWebAuthnService> NewWebAuthnService() {
15 nsCOMPtr<nsIWebAuthnService> webauthnService(new WebAuthnService());
16 return webauthnService.forget();
19 NS_IMPL_ISUPPORTS(WebAuthnService, nsIWebAuthnService)
21 NS_IMETHODIMP
22 WebAuthnService::MakeCredential(uint64_t aTransactionId,
23 uint64_t browsingContextId,
24 nsIWebAuthnRegisterArgs* aArgs,
25 nsIWebAuthnRegisterPromise* aPromise) {
26 auto guard = mTransactionState.Lock();
27 if (guard->isSome()) {
28 guard->ref().service->Reset();
29 *guard = Nothing();
31 *guard = Some(TransactionState{DefaultService()});
32 return guard->ref().service->MakeCredential(aTransactionId, browsingContextId,
33 aArgs, aPromise);
36 NS_IMETHODIMP
37 WebAuthnService::GetAssertion(uint64_t aTransactionId,
38 uint64_t browsingContextId,
39 nsIWebAuthnSignArgs* aArgs,
40 nsIWebAuthnSignPromise* aPromise) {
41 auto guard = mTransactionState.Lock();
42 if (guard->isSome()) {
43 guard->ref().service->Reset();
44 *guard = Nothing();
46 *guard = Some(TransactionState{DefaultService()});
47 nsresult rv;
49 #if defined(XP_MACOSX)
50 // The macOS security key API doesn't handle the AppID extension. So we'll
51 // use authenticator-rs if it's likely that the request requires AppID. We
52 // consider it likely if 1) the AppID extension is present, 2) the allow list
53 // is non-empty, and 3) none of the allowed credentials use the
54 // "internal" or "hybrid" transport.
55 nsString appId;
56 rv = aArgs->GetAppId(appId);
57 if (rv == NS_OK) { // AppID is set
58 uint8_t transportSet = 0;
59 nsTArray<uint8_t> allowListTransports;
60 Unused << aArgs->GetAllowListTransports(allowListTransports);
61 for (const uint8_t& transport : allowListTransports) {
62 transportSet |= transport;
64 uint8_t passkeyTransportMask =
65 MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_INTERNAL |
66 MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_HYBRID;
67 if (allowListTransports.Length() > 0 &&
68 (transportSet & passkeyTransportMask) == 0) {
69 guard->ref().service = AuthrsService();
72 #endif
74 rv = guard->ref().service->GetAssertion(aTransactionId, browsingContextId,
75 aArgs, aPromise);
76 if (NS_FAILED(rv)) {
77 return rv;
80 // If this is a conditionally mediated request, notify observers that there
81 // is a pending transaction. This is mainly useful in tests.
82 bool conditionallyMediated;
83 Unused << aArgs->GetConditionallyMediated(&conditionallyMediated);
84 if (conditionallyMediated) {
85 nsCOMPtr<nsIRunnable> runnable(NS_NewRunnableFunction(__func__, []() {
86 nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
87 if (os) {
88 os->NotifyObservers(nullptr, "webauthn:conditional-get-pending",
89 nullptr);
91 }));
92 NS_DispatchToMainThread(runnable.forget());
95 return NS_OK;
98 NS_IMETHODIMP
99 WebAuthnService::GetIsUVPAA(bool* aAvailable) {
100 return DefaultService()->GetIsUVPAA(aAvailable);
103 NS_IMETHODIMP
104 WebAuthnService::HasPendingConditionalGet(uint64_t aBrowsingContextId,
105 const nsAString& aOrigin,
106 uint64_t* aRv) {
107 return SelectedService()->HasPendingConditionalGet(aBrowsingContextId,
108 aOrigin, aRv);
111 NS_IMETHODIMP
112 WebAuthnService::GetAutoFillEntries(
113 uint64_t aTransactionId, nsTArray<RefPtr<nsIWebAuthnAutoFillEntry>>& aRv) {
114 return SelectedService()->GetAutoFillEntries(aTransactionId, aRv);
117 NS_IMETHODIMP
118 WebAuthnService::SelectAutoFillEntry(uint64_t aTransactionId,
119 const nsTArray<uint8_t>& aCredentialId) {
120 return SelectedService()->SelectAutoFillEntry(aTransactionId, aCredentialId);
123 NS_IMETHODIMP
124 WebAuthnService::ResumeConditionalGet(uint64_t aTransactionId) {
125 return SelectedService()->ResumeConditionalGet(aTransactionId);
128 NS_IMETHODIMP
129 WebAuthnService::Reset() {
130 auto guard = mTransactionState.Lock();
131 if (guard->isSome()) {
132 guard->ref().service->Reset();
134 *guard = Nothing();
135 return NS_OK;
138 NS_IMETHODIMP
139 WebAuthnService::Cancel(uint64_t aTransactionId) {
140 return SelectedService()->Cancel(aTransactionId);
143 NS_IMETHODIMP
144 WebAuthnService::PinCallback(uint64_t aTransactionId, const nsACString& aPin) {
145 return SelectedService()->PinCallback(aTransactionId, aPin);
148 NS_IMETHODIMP
149 WebAuthnService::ResumeMakeCredential(uint64_t aTransactionId,
150 bool aForceNoneAttestation) {
151 return SelectedService()->ResumeMakeCredential(aTransactionId,
152 aForceNoneAttestation);
155 NS_IMETHODIMP
156 WebAuthnService::SelectionCallback(uint64_t aTransactionId, uint64_t aIndex) {
157 return SelectedService()->SelectionCallback(aTransactionId, aIndex);
160 NS_IMETHODIMP
161 WebAuthnService::AddVirtualAuthenticator(
162 const nsACString& protocol, const nsACString& transport,
163 bool hasResidentKey, bool hasUserVerification, bool isUserConsenting,
164 bool isUserVerified, uint64_t* retval) {
165 return SelectedService()->AddVirtualAuthenticator(
166 protocol, transport, hasResidentKey, hasUserVerification,
167 isUserConsenting, isUserVerified, retval);
170 NS_IMETHODIMP
171 WebAuthnService::RemoveVirtualAuthenticator(uint64_t authenticatorId) {
172 return SelectedService()->RemoveVirtualAuthenticator(authenticatorId);
175 NS_IMETHODIMP
176 WebAuthnService::AddCredential(uint64_t authenticatorId,
177 const nsACString& credentialId,
178 bool isResidentCredential,
179 const nsACString& rpId,
180 const nsACString& privateKey,
181 const nsACString& userHandle,
182 uint32_t signCount) {
183 return SelectedService()->AddCredential(authenticatorId, credentialId,
184 isResidentCredential, rpId,
185 privateKey, userHandle, signCount);
188 NS_IMETHODIMP
189 WebAuthnService::GetCredentials(
190 uint64_t authenticatorId,
191 nsTArray<RefPtr<nsICredentialParameters>>& retval) {
192 return SelectedService()->GetCredentials(authenticatorId, retval);
195 NS_IMETHODIMP
196 WebAuthnService::RemoveCredential(uint64_t authenticatorId,
197 const nsACString& credentialId) {
198 return SelectedService()->RemoveCredential(authenticatorId, credentialId);
201 NS_IMETHODIMP
202 WebAuthnService::RemoveAllCredentials(uint64_t authenticatorId) {
203 return SelectedService()->RemoveAllCredentials(authenticatorId);
206 NS_IMETHODIMP
207 WebAuthnService::SetUserVerified(uint64_t authenticatorId,
208 bool isUserVerified) {
209 return SelectedService()->SetUserVerified(authenticatorId, isUserVerified);
212 NS_IMETHODIMP
213 WebAuthnService::Listen() { return SelectedService()->Listen(); }
215 NS_IMETHODIMP
216 WebAuthnService::RunCommand(const nsACString& cmd) {
217 return SelectedService()->RunCommand(cmd);
220 } // namespace mozilla::dom