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
)
22 WebAuthnService::MakeCredential(uint64_t aTransactionId
,
23 uint64_t browsingContextId
,
24 nsIWebAuthnRegisterArgs
* aArgs
,
25 nsIWebAuthnRegisterPromise
* aPromise
) {
26 return DefaultService()->MakeCredential(aTransactionId
, browsingContextId
,
31 WebAuthnService::GetAssertion(uint64_t aTransactionId
,
32 uint64_t browsingContextId
,
33 nsIWebAuthnSignArgs
* aArgs
,
34 nsIWebAuthnSignPromise
* aPromise
) {
35 nsIWebAuthnService
* service
= DefaultService();
38 #if defined(XP_MACOSX)
39 // The macOS security key API doesn't handle the AppID extension. So we'll
40 // use authenticator-rs if it's likely that the request requires AppID. We
41 // consider it likely if 1) the AppID extension is present, 2) the allow list
42 // is non-empty, and 3) none of the allowed credentials use the
43 // "internal" or "hybrid" transport.
45 rv
= aArgs
->GetAppId(appId
);
46 if (rv
== NS_OK
) { // AppID is set
47 uint8_t transportSet
= 0;
48 nsTArray
<uint8_t> allowListTransports
;
49 Unused
<< aArgs
->GetAllowListTransports(allowListTransports
);
50 for (const uint8_t& transport
: allowListTransports
) {
51 transportSet
|= transport
;
53 uint8_t passkeyTransportMask
=
54 MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_INTERNAL
|
55 MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_HYBRID
;
56 if (allowListTransports
.Length() > 0 &&
57 (transportSet
& passkeyTransportMask
) == 0) {
58 service
= AuthrsService();
64 service
->GetAssertion(aTransactionId
, browsingContextId
, aArgs
, aPromise
);
69 // If this is a conditionally mediated request, notify observers that there
70 // is a pending transaction. This is mainly useful in tests.
71 bool conditionallyMediated
;
72 Unused
<< aArgs
->GetConditionallyMediated(&conditionallyMediated
);
73 if (conditionallyMediated
) {
74 nsCOMPtr
<nsIRunnable
> runnable(NS_NewRunnableFunction(__func__
, []() {
75 nsCOMPtr
<nsIObserverService
> os
= mozilla::services::GetObserverService();
77 os
->NotifyObservers(nullptr, "webauthn:conditional-get-pending",
81 NS_DispatchToMainThread(runnable
.forget());
88 WebAuthnService::GetIsUVPAA(bool* aAvailable
) {
89 return DefaultService()->GetIsUVPAA(aAvailable
);
93 WebAuthnService::HasPendingConditionalGet(uint64_t aBrowsingContextId
,
94 const nsAString
& aOrigin
,
96 return DefaultService()->HasPendingConditionalGet(aBrowsingContextId
, aOrigin
,
101 WebAuthnService::GetAutoFillEntries(
102 uint64_t aTransactionId
, nsTArray
<RefPtr
<nsIWebAuthnAutoFillEntry
>>& aRv
) {
103 return DefaultService()->GetAutoFillEntries(aTransactionId
, aRv
);
107 WebAuthnService::SelectAutoFillEntry(uint64_t aTransactionId
,
108 const nsTArray
<uint8_t>& aCredentialId
) {
109 return DefaultService()->SelectAutoFillEntry(aTransactionId
, aCredentialId
);
113 WebAuthnService::ResumeConditionalGet(uint64_t aTransactionId
) {
114 return DefaultService()->ResumeConditionalGet(aTransactionId
);
118 WebAuthnService::Reset() { return DefaultService()->Reset(); }
121 WebAuthnService::Cancel(uint64_t aTransactionId
) {
122 return DefaultService()->Cancel(aTransactionId
);
126 WebAuthnService::PinCallback(uint64_t aTransactionId
, const nsACString
& aPin
) {
127 return DefaultService()->PinCallback(aTransactionId
, aPin
);
131 WebAuthnService::ResumeMakeCredential(uint64_t aTransactionId
,
132 bool aForceNoneAttestation
) {
133 return DefaultService()->ResumeMakeCredential(aTransactionId
,
134 aForceNoneAttestation
);
138 WebAuthnService::SelectionCallback(uint64_t aTransactionId
, uint64_t aIndex
) {
139 return DefaultService()->SelectionCallback(aTransactionId
, aIndex
);
143 WebAuthnService::AddVirtualAuthenticator(
144 const nsACString
& protocol
, const nsACString
& transport
,
145 bool hasResidentKey
, bool hasUserVerification
, bool isUserConsenting
,
146 bool isUserVerified
, uint64_t* retval
) {
147 return DefaultService()->AddVirtualAuthenticator(
148 protocol
, transport
, hasResidentKey
, hasUserVerification
,
149 isUserConsenting
, isUserVerified
, retval
);
153 WebAuthnService::RemoveVirtualAuthenticator(uint64_t authenticatorId
) {
154 return DefaultService()->RemoveVirtualAuthenticator(authenticatorId
);
158 WebAuthnService::AddCredential(uint64_t authenticatorId
,
159 const nsACString
& credentialId
,
160 bool isResidentCredential
,
161 const nsACString
& rpId
,
162 const nsACString
& privateKey
,
163 const nsACString
& userHandle
,
164 uint32_t signCount
) {
165 return DefaultService()->AddCredential(authenticatorId
, credentialId
,
166 isResidentCredential
, rpId
, privateKey
,
167 userHandle
, signCount
);
171 WebAuthnService::GetCredentials(
172 uint64_t authenticatorId
,
173 nsTArray
<RefPtr
<nsICredentialParameters
>>& retval
) {
174 return DefaultService()->GetCredentials(authenticatorId
, retval
);
178 WebAuthnService::RemoveCredential(uint64_t authenticatorId
,
179 const nsACString
& credentialId
) {
180 return DefaultService()->RemoveCredential(authenticatorId
, credentialId
);
184 WebAuthnService::RemoveAllCredentials(uint64_t authenticatorId
) {
185 return DefaultService()->RemoveAllCredentials(authenticatorId
);
189 WebAuthnService::SetUserVerified(uint64_t authenticatorId
,
190 bool isUserVerified
) {
191 return DefaultService()->SetUserVerified(authenticatorId
, isUserVerified
);
195 WebAuthnService::Listen() { return DefaultService()->Listen(); }
198 WebAuthnService::RunCommand(const nsACString
& cmd
) {
199 return DefaultService()->RunCommand(cmd
);
202 } // namespace mozilla::dom