1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/PWebAuthnTransactionParent.h"
8 #include "mozilla/ipc/BackgroundParent.h"
9 #include "mozilla/Assertions.h"
10 #include "mozilla/MozPromise.h"
11 #include "mozilla/Preferences.h"
12 #include "mozilla/ScopeExit.h"
13 #include "mozilla/StaticMutex.h"
14 #include "mozilla/Unused.h"
16 #include "nsTextFormatter.h"
17 #include "nsWindowsHelpers.h"
18 #include "WebAuthnAutoFillEntry.h"
19 #include "WebAuthnEnumStrings.h"
20 #include "WebAuthnResult.h"
21 #include "WebAuthnTransportIdentifiers.h"
22 #include "winwebauthn/webauthn.h"
23 #include "WinWebAuthnService.h"
25 namespace mozilla::dom
{
28 StaticRWLock gWinWebAuthnModuleLock
;
30 static bool gWinWebAuthnModuleUnusable
= false;
31 static HMODULE gWinWebAuthnModule
= 0;
33 static decltype(WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable
)*
34 gWinWebauthnIsUVPAA
= nullptr;
35 static decltype(WebAuthNAuthenticatorMakeCredential
)*
36 gWinWebauthnMakeCredential
= nullptr;
37 static decltype(WebAuthNFreeCredentialAttestation
)*
38 gWinWebauthnFreeCredentialAttestation
= nullptr;
39 static decltype(WebAuthNAuthenticatorGetAssertion
)* gWinWebauthnGetAssertion
=
41 static decltype(WebAuthNFreeAssertion
)* gWinWebauthnFreeAssertion
= nullptr;
42 static decltype(WebAuthNGetCancellationId
)* gWinWebauthnGetCancellationId
=
44 static decltype(WebAuthNCancelCurrentOperation
)*
45 gWinWebauthnCancelCurrentOperation
= nullptr;
46 static decltype(WebAuthNGetErrorName
)* gWinWebauthnGetErrorName
= nullptr;
47 static decltype(WebAuthNGetApiVersionNumber
)* gWinWebauthnGetApiVersionNumber
=
49 static decltype(WebAuthNGetPlatformCredentialList
)*
50 gWinWebauthnGetPlatformCredentialList
= nullptr;
51 static decltype(WebAuthNFreePlatformCredentialList
)*
52 gWinWebauthnFreePlatformCredentialList
= nullptr;
56 /***********************************************************************
57 * WinWebAuthnService Implementation
58 **********************************************************************/
60 constexpr uint32_t kMinWinWebAuthNApiVersion
= WEBAUTHN_API_VERSION_1
;
62 NS_IMPL_ISUPPORTS(WinWebAuthnService
, nsIWebAuthnService
)
65 nsresult
WinWebAuthnService::EnsureWinWebAuthnModuleLoaded() {
67 StaticAutoReadLock
moduleLock(gWinWebAuthnModuleLock
);
68 if (gWinWebAuthnModule
) {
69 // The module is already loaded.
72 if (gWinWebAuthnModuleUnusable
) {
73 // A previous attempt to load the module failed.
74 return NS_ERROR_NOT_AVAILABLE
;
78 StaticAutoWriteLock
lock(gWinWebAuthnModuleLock
);
79 if (gWinWebAuthnModule
) {
80 // Another thread successfully loaded the module while we were waiting.
83 if (gWinWebAuthnModuleUnusable
) {
84 // Another thread failed to load the module while we were waiting.
85 return NS_ERROR_NOT_AVAILABLE
;
88 gWinWebAuthnModule
= LoadLibrarySystem32(L
"webauthn.dll");
89 auto markModuleUnusable
= MakeScopeExit([]() {
90 if (gWinWebAuthnModule
) {
91 FreeLibrary(gWinWebAuthnModule
);
92 gWinWebAuthnModule
= 0;
94 gWinWebAuthnModuleUnusable
= true;
97 if (!gWinWebAuthnModule
) {
98 return NS_ERROR_NOT_AVAILABLE
;
101 gWinWebauthnIsUVPAA
= reinterpret_cast<
102 decltype(WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable
)*>(
103 GetProcAddress(gWinWebAuthnModule
,
104 "WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable"));
105 gWinWebauthnMakeCredential
=
106 reinterpret_cast<decltype(WebAuthNAuthenticatorMakeCredential
)*>(
107 GetProcAddress(gWinWebAuthnModule
,
108 "WebAuthNAuthenticatorMakeCredential"));
109 gWinWebauthnFreeCredentialAttestation
=
110 reinterpret_cast<decltype(WebAuthNFreeCredentialAttestation
)*>(
111 GetProcAddress(gWinWebAuthnModule
,
112 "WebAuthNFreeCredentialAttestation"));
113 gWinWebauthnGetAssertion
=
114 reinterpret_cast<decltype(WebAuthNAuthenticatorGetAssertion
)*>(
115 GetProcAddress(gWinWebAuthnModule
,
116 "WebAuthNAuthenticatorGetAssertion"));
117 gWinWebauthnFreeAssertion
=
118 reinterpret_cast<decltype(WebAuthNFreeAssertion
)*>(
119 GetProcAddress(gWinWebAuthnModule
, "WebAuthNFreeAssertion"));
120 gWinWebauthnGetCancellationId
=
121 reinterpret_cast<decltype(WebAuthNGetCancellationId
)*>(
122 GetProcAddress(gWinWebAuthnModule
, "WebAuthNGetCancellationId"));
123 gWinWebauthnCancelCurrentOperation
=
124 reinterpret_cast<decltype(WebAuthNCancelCurrentOperation
)*>(
125 GetProcAddress(gWinWebAuthnModule
, "WebAuthNCancelCurrentOperation"));
126 gWinWebauthnGetErrorName
= reinterpret_cast<decltype(WebAuthNGetErrorName
)*>(
127 GetProcAddress(gWinWebAuthnModule
, "WebAuthNGetErrorName"));
128 gWinWebauthnGetApiVersionNumber
=
129 reinterpret_cast<decltype(WebAuthNGetApiVersionNumber
)*>(
130 GetProcAddress(gWinWebAuthnModule
, "WebAuthNGetApiVersionNumber"));
132 if (!(gWinWebauthnIsUVPAA
&& gWinWebauthnMakeCredential
&&
133 gWinWebauthnFreeCredentialAttestation
&& gWinWebauthnGetAssertion
&&
134 gWinWebauthnFreeAssertion
&& gWinWebauthnGetCancellationId
&&
135 gWinWebauthnCancelCurrentOperation
&& gWinWebauthnGetErrorName
&&
136 gWinWebauthnGetApiVersionNumber
)) {
137 return NS_ERROR_NOT_AVAILABLE
;
140 DWORD version
= gWinWebauthnGetApiVersionNumber();
142 if (version
>= WEBAUTHN_API_VERSION_4
) {
143 gWinWebauthnGetPlatformCredentialList
=
144 reinterpret_cast<decltype(WebAuthNGetPlatformCredentialList
)*>(
145 GetProcAddress(gWinWebAuthnModule
,
146 "WebAuthNGetPlatformCredentialList"));
147 gWinWebauthnFreePlatformCredentialList
=
148 reinterpret_cast<decltype(WebAuthNFreePlatformCredentialList
)*>(
149 GetProcAddress(gWinWebAuthnModule
,
150 "WebAuthNFreePlatformCredentialList"));
151 if (!(gWinWebauthnGetPlatformCredentialList
&&
152 gWinWebauthnFreePlatformCredentialList
)) {
153 return NS_ERROR_NOT_AVAILABLE
;
157 // Bug 1869584: In some of our tests, a content process can end up here due to
158 // a call to WinWebAuthnService::AreWebAuthNApisAvailable. This causes us to
159 // fail an assertion in Preferences::SetBool, which is parent-process only.
160 if (XRE_IsParentProcess()) {
161 NS_DispatchToMainThread(NS_NewRunnableFunction(__func__
, [version
]() {
162 Preferences::SetBool("security.webauthn.show_ms_settings_link",
163 version
>= WEBAUTHN_API_VERSION_7
);
167 markModuleUnusable
.release();
171 WinWebAuthnService::~WinWebAuthnService() {
172 StaticAutoWriteLock
lock(gWinWebAuthnModuleLock
);
173 if (gWinWebAuthnModule
) {
174 FreeLibrary(gWinWebAuthnModule
);
176 gWinWebAuthnModule
= 0;
180 bool WinWebAuthnService::AreWebAuthNApisAvailable() {
181 nsresult rv
= EnsureWinWebAuthnModuleLoaded();
182 NS_ENSURE_SUCCESS(rv
, false);
184 StaticAutoReadLock
moduleLock(gWinWebAuthnModuleLock
);
185 return gWinWebAuthnModule
&&
186 gWinWebauthnGetApiVersionNumber() >= kMinWinWebAuthNApiVersion
;
190 WinWebAuthnService::GetIsUVPAA(bool* aAvailable
) {
191 nsresult rv
= EnsureWinWebAuthnModuleLoaded();
192 NS_ENSURE_SUCCESS(rv
, rv
);
194 if (WinWebAuthnService::AreWebAuthNApisAvailable()) {
195 BOOL isUVPAA
= FALSE
;
196 StaticAutoReadLock
moduleLock(gWinWebAuthnModuleLock
);
197 *aAvailable
= gWinWebAuthnModule
&& gWinWebauthnIsUVPAA(&isUVPAA
) == S_OK
&&
206 WinWebAuthnService::Cancel(uint64_t aTransactionId
) {
207 return NS_ERROR_NOT_IMPLEMENTED
;
211 WinWebAuthnService::Reset() {
212 // Reset will never be the first function to use gWinWebAuthnModule, so
213 // we shouldn't try to initialize it here.
214 auto guard
= mTransactionState
.Lock();
215 if (guard
->isSome()) {
216 StaticAutoReadLock
moduleLock(gWinWebAuthnModuleLock
);
217 if (gWinWebAuthnModule
) {
218 const GUID cancellationId
= guard
->ref().cancellationId
;
219 gWinWebauthnCancelCurrentOperation(&cancellationId
);
221 if (guard
->ref().pendingSignPromise
.isSome()) {
222 // This request was never dispatched to the platform API, so
223 // we need to reject the promise ourselves.
224 guard
->ref().pendingSignPromise
.ref()->Reject(
225 NS_ERROR_DOM_NOT_ALLOWED_ERR
);
234 WinWebAuthnService::MakeCredential(uint64_t aTransactionId
,
235 uint64_t aBrowsingContextId
,
236 nsIWebAuthnRegisterArgs
* aArgs
,
237 nsIWebAuthnRegisterPromise
* aPromise
) {
238 nsresult rv
= EnsureWinWebAuthnModuleLoaded();
239 NS_ENSURE_SUCCESS(rv
, rv
);
242 auto guard
= mTransactionState
.Lock();
243 StaticAutoReadLock
moduleLock(gWinWebAuthnModuleLock
);
245 if (gWinWebauthnGetCancellationId(&cancellationId
) != S_OK
) {
246 // caller will reject promise
247 return NS_ERROR_DOM_UNKNOWN_ERR
;
249 *guard
= Some(TransactionState
{
257 nsCOMPtr
<nsIRunnable
> runnable(NS_NewRunnableFunction(
258 "WinWebAuthnService::MakeCredential",
259 [self
= RefPtr
{this}, aArgs
= RefPtr
{aArgs
}, aPromise
= RefPtr
{aPromise
},
260 cancellationId
]() mutable {
261 // Take a read lock on gWinWebAuthnModuleLock to prevent the module from
262 // being unloaded while the operation is in progress. This does not
263 // prevent the operation from being cancelled, so it does not block a
265 StaticAutoReadLock
moduleLock(gWinWebAuthnModuleLock
);
266 if (!gWinWebAuthnModule
) {
267 aPromise
->Reject(NS_ERROR_DOM_UNKNOWN_ERR
);
271 BOOL HmacCreateSecret
= FALSE
;
272 BOOL MinPinLength
= FALSE
;
276 Unused
<< aArgs
->GetRpId(rpId
);
277 WEBAUTHN_RP_ENTITY_INFORMATION rpInfo
= {
278 WEBAUTHN_RP_ENTITY_INFORMATION_CURRENT_VERSION
, rpId
.get(), nullptr,
282 WEBAUTHN_USER_ENTITY_INFORMATION userInfo
= {
283 WEBAUTHN_USER_ENTITY_INFORMATION_CURRENT_VERSION
,
291 nsCString clientDataJSON
;
292 Unused
<< aArgs
->GetClientDataJSON(clientDataJSON
);
293 WEBAUTHN_CLIENT_DATA WebAuthNClientData
= {
294 WEBAUTHN_CLIENT_DATA_CURRENT_VERSION
,
295 (DWORD
)clientDataJSON
.Length(), (BYTE
*)(clientDataJSON
.get()),
296 WEBAUTHN_HASH_ALGORITHM_SHA_256
};
298 // User Verification Requirement
299 DWORD winUserVerificationReq
=
300 WEBAUTHN_USER_VERIFICATION_REQUIREMENT_ANY
;
302 // Resident Key Requirement.
303 BOOL winRequireResidentKey
= FALSE
; // Will be set to TRUE if and only
304 // if residentKey = "required"
305 BOOL winPreferResidentKey
= FALSE
; // Will be set to TRUE if and only
306 // if residentKey = "preferred"
308 // AttestationConveyance
309 DWORD winAttestation
= WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_ANY
;
312 BOOL winEnablePrf
= FALSE
;
315 Unused
<< aArgs
->GetRpName(rpName
);
316 rpInfo
.pwszName
= rpName
.get();
317 rpInfo
.pwszIcon
= nullptr;
319 nsTArray
<uint8_t> userId
;
320 Unused
<< aArgs
->GetUserId(userId
);
321 userInfo
.cbId
= static_cast<DWORD
>(userId
.Length());
322 userInfo
.pbId
= const_cast<unsigned char*>(userId
.Elements());
325 Unused
<< aArgs
->GetUserName(userName
);
326 userInfo
.pwszName
= userName
.get();
328 userInfo
.pwszIcon
= nullptr;
330 nsString userDisplayName
;
331 Unused
<< aArgs
->GetUserDisplayName(userDisplayName
);
332 userInfo
.pwszDisplayName
= userDisplayName
.get();
335 nsTArray
<WEBAUTHN_COSE_CREDENTIAL_PARAMETER
> coseParams
;
336 nsTArray
<int32_t> coseAlgs
;
337 Unused
<< aArgs
->GetCoseAlgs(coseAlgs
);
338 for (const int32_t& coseAlg
: coseAlgs
) {
339 WEBAUTHN_COSE_CREDENTIAL_PARAMETER coseAlgorithm
= {
340 WEBAUTHN_COSE_CREDENTIAL_PARAMETER_CURRENT_VERSION
,
341 WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY
, coseAlg
};
342 coseParams
.AppendElement(coseAlgorithm
);
345 nsString userVerificationReq
;
346 Unused
<< aArgs
->GetUserVerification(userVerificationReq
);
347 // This mapping needs to be reviewed if values are added to the
348 // UserVerificationRequirement enum.
349 static_assert(MOZ_WEBAUTHN_ENUM_STRINGS_VERSION
== 3);
350 if (userVerificationReq
.EqualsLiteral(
351 MOZ_WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED
)) {
352 winUserVerificationReq
=
353 WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED
;
354 } else if (userVerificationReq
.EqualsLiteral(
355 MOZ_WEBAUTHN_USER_VERIFICATION_REQUIREMENT_PREFERRED
)) {
356 winUserVerificationReq
=
357 WEBAUTHN_USER_VERIFICATION_REQUIREMENT_PREFERRED
;
358 } else if (userVerificationReq
.EqualsLiteral(
359 MOZ_WEBAUTHN_RESIDENT_KEY_REQUIREMENT_DISCOURAGED
)) {
360 winUserVerificationReq
=
361 WEBAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED
;
363 winUserVerificationReq
= WEBAUTHN_USER_VERIFICATION_REQUIREMENT_ANY
;
367 DWORD winAttachment
= WEBAUTHN_AUTHENTICATOR_ATTACHMENT_ANY
;
368 nsString authenticatorAttachment
;
370 aArgs
->GetAuthenticatorAttachment(authenticatorAttachment
);
371 if (rv
!= NS_ERROR_NOT_AVAILABLE
) {
373 aPromise
->Reject(rv
);
376 // This mapping needs to be reviewed if values are added to the
377 // AuthenticatorAttachement enum.
378 static_assert(MOZ_WEBAUTHN_ENUM_STRINGS_VERSION
== 3);
379 if (authenticatorAttachment
.EqualsLiteral(
380 MOZ_WEBAUTHN_AUTHENTICATOR_ATTACHMENT_PLATFORM
)) {
381 winAttachment
= WEBAUTHN_AUTHENTICATOR_ATTACHMENT_PLATFORM
;
383 authenticatorAttachment
.EqualsLiteral(
384 MOZ_WEBAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM
)) {
385 winAttachment
= WEBAUTHN_AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM
;
387 winAttachment
= WEBAUTHN_AUTHENTICATOR_ATTACHMENT_ANY
;
391 nsString residentKey
;
392 Unused
<< aArgs
->GetResidentKey(residentKey
);
393 // This mapping needs to be reviewed if values are added to the
394 // ResidentKeyRequirement enum.
395 static_assert(MOZ_WEBAUTHN_ENUM_STRINGS_VERSION
== 3);
396 if (residentKey
.EqualsLiteral(
397 MOZ_WEBAUTHN_RESIDENT_KEY_REQUIREMENT_REQUIRED
)) {
398 winRequireResidentKey
= TRUE
;
399 winPreferResidentKey
= FALSE
;
400 } else if (residentKey
.EqualsLiteral(
401 MOZ_WEBAUTHN_RESIDENT_KEY_REQUIREMENT_PREFERRED
)) {
402 winRequireResidentKey
= FALSE
;
403 winPreferResidentKey
= TRUE
;
404 } else if (residentKey
.EqualsLiteral(
405 MOZ_WEBAUTHN_RESIDENT_KEY_REQUIREMENT_DISCOURAGED
)) {
406 winRequireResidentKey
= FALSE
;
407 winPreferResidentKey
= FALSE
;
409 // WebAuthnManager::MakeCredential is supposed to assign one of the
410 // above values, so this shouldn't happen.
411 MOZ_ASSERT_UNREACHABLE();
412 aPromise
->Reject(NS_ERROR_DOM_UNKNOWN_ERR
);
416 // AttestationConveyance
417 nsString attestation
;
418 Unused
<< aArgs
->GetAttestationConveyancePreference(attestation
);
419 // This mapping needs to be reviewed if values are added to the
420 // AttestationConveyancePreference enum.
421 static_assert(MOZ_WEBAUTHN_ENUM_STRINGS_VERSION
== 3);
422 if (attestation
.EqualsLiteral(
423 MOZ_WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_NONE
)) {
424 winAttestation
= WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_NONE
;
426 attestation
.EqualsLiteral(
427 MOZ_WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_INDIRECT
)) {
428 winAttestation
= WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_INDIRECT
;
429 } else if (attestation
.EqualsLiteral(
430 MOZ_WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_DIRECT
)) {
431 winAttestation
= WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_DIRECT
;
433 winAttestation
= WEBAUTHN_ATTESTATION_CONVEYANCE_PREFERENCE_ANY
;
437 Unused
<< aArgs
->GetPrf(&requestedPrf
);
442 bool requestedCredProps
;
443 Unused
<< aArgs
->GetCredProps(&requestedCredProps
);
445 bool requestedMinPinLength
;
446 Unused
<< aArgs
->GetMinPinLength(&requestedMinPinLength
);
448 bool requestedHmacCreateSecret
;
449 Unused
<< aArgs
->GetHmacCreateSecret(&requestedHmacCreateSecret
);
451 // Extensions that might require an entry: hmac-secret, minPinLength.
452 WEBAUTHN_EXTENSION rgExtension
[2] = {};
453 DWORD cExtensions
= 0;
454 if (requestedPrf
|| requestedHmacCreateSecret
) {
455 HmacCreateSecret
= TRUE
;
456 rgExtension
[cExtensions
].pwszExtensionIdentifier
=
457 WEBAUTHN_EXTENSIONS_IDENTIFIER_HMAC_SECRET
;
458 rgExtension
[cExtensions
].cbExtension
= sizeof(BOOL
);
459 rgExtension
[cExtensions
].pvExtension
= &HmacCreateSecret
;
462 if (requestedMinPinLength
) {
464 rgExtension
[cExtensions
].pwszExtensionIdentifier
=
465 WEBAUTHN_EXTENSIONS_IDENTIFIER_MIN_PIN_LENGTH
;
466 rgExtension
[cExtensions
].cbExtension
= sizeof(BOOL
);
467 rgExtension
[cExtensions
].pvExtension
= &MinPinLength
;
471 WEBAUTHN_COSE_CREDENTIAL_PARAMETERS WebAuthNCredentialParameters
= {
472 static_cast<DWORD
>(coseParams
.Length()), coseParams
.Elements()};
474 // Exclude Credentials
475 nsTArray
<nsTArray
<uint8_t>> excludeList
;
476 Unused
<< aArgs
->GetExcludeList(excludeList
);
478 nsTArray
<uint8_t> excludeListTransports
;
479 Unused
<< aArgs
->GetExcludeListTransports(excludeListTransports
);
481 if (excludeList
.Length() != excludeListTransports
.Length()) {
482 aPromise
->Reject(NS_ERROR_DOM_UNKNOWN_ERR
);
486 nsTArray
<WEBAUTHN_CREDENTIAL_EX
> excludeCredentials
;
487 WEBAUTHN_CREDENTIAL_EX
* pExcludeCredentials
= nullptr;
488 nsTArray
<WEBAUTHN_CREDENTIAL_EX
*> excludeCredentialsPtrs
;
489 WEBAUTHN_CREDENTIAL_LIST excludeCredentialList
= {0};
490 WEBAUTHN_CREDENTIAL_LIST
* pExcludeCredentialList
= nullptr;
492 for (size_t i
= 0; i
< excludeList
.Length(); i
++) {
493 nsTArray
<uint8_t>& cred
= excludeList
[i
];
494 uint8_t& transports
= excludeListTransports
[i
];
495 DWORD winTransports
= 0;
496 if (transports
& MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_USB
) {
497 winTransports
|= WEBAUTHN_CTAP_TRANSPORT_USB
;
499 if (transports
& MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_NFC
) {
500 winTransports
|= WEBAUTHN_CTAP_TRANSPORT_NFC
;
502 if (transports
& MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_BLE
) {
503 winTransports
|= WEBAUTHN_CTAP_TRANSPORT_BLE
;
505 if (transports
& MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_INTERNAL
) {
506 winTransports
|= WEBAUTHN_CTAP_TRANSPORT_INTERNAL
;
508 if (transports
& MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_HYBRID
) {
509 winTransports
|= WEBAUTHN_CTAP_TRANSPORT_HYBRID
;
512 WEBAUTHN_CREDENTIAL_EX credential
= {
513 WEBAUTHN_CREDENTIAL_EX_CURRENT_VERSION
,
514 static_cast<DWORD
>(cred
.Length()), (PBYTE
)(cred
.Elements()),
515 WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY
, winTransports
};
516 excludeCredentials
.AppendElement(credential
);
519 if (!excludeCredentials
.IsEmpty()) {
520 pExcludeCredentials
= excludeCredentials
.Elements();
521 for (DWORD i
= 0; i
< excludeCredentials
.Length(); i
++) {
522 excludeCredentialsPtrs
.AppendElement(&pExcludeCredentials
[i
]);
524 excludeCredentialList
.cCredentials
= excludeCredentials
.Length();
525 excludeCredentialList
.ppCredentials
=
526 excludeCredentialsPtrs
.Elements();
527 pExcludeCredentialList
= &excludeCredentialList
;
530 uint32_t timeout_u32
;
531 Unused
<< aArgs
->GetTimeoutMS(&timeout_u32
);
532 DWORD timeout
= timeout_u32
;
534 // MakeCredentialOptions
535 WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS
536 WebAuthNCredentialOptions
= {
537 WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_7
,
542 winRequireResidentKey
,
543 winUserVerificationReq
,
546 &cancellationId
, // CancellationId
547 pExcludeCredentialList
,
548 WEBAUTHN_ENTERPRISE_ATTESTATION_NONE
,
549 WEBAUTHN_LARGE_BLOB_SUPPORT_NONE
,
550 winPreferResidentKey
, // PreferResidentKey
551 FALSE
, // BrowserInPrivateMode
552 winEnablePrf
, // EnablePrf
553 NULL
, // LinkedDevice
554 0, // size of JsonExt
558 if (cExtensions
!= 0) {
559 WebAuthNCredentialOptions
.Extensions
.cExtensions
= cExtensions
;
560 WebAuthNCredentialOptions
.Extensions
.pExtensions
= rgExtension
;
563 PWEBAUTHN_CREDENTIAL_ATTESTATION pWebAuthNCredentialAttestation
=
566 // Bug 1518876: Get Window Handle from Content process for Windows
568 HWND hWnd
= GetForegroundWindow();
570 HRESULT hr
= gWinWebauthnMakeCredential(
571 hWnd
, &rpInfo
, &userInfo
, &WebAuthNCredentialParameters
,
572 &WebAuthNClientData
, &WebAuthNCredentialOptions
,
573 &pWebAuthNCredentialAttestation
);
576 RefPtr
<WebAuthnRegisterResult
> result
= new WebAuthnRegisterResult(
577 clientDataJSON
, pWebAuthNCredentialAttestation
);
579 // WEBAUTHN_CREDENTIAL_ATTESTATION structs of version >= 4 always
580 // include a flag to indicate whether a resident key was created. We
581 // copy that flag to the credProps extension output only if the RP
582 // requested the credProps extension.
583 if (requestedCredProps
&&
584 pWebAuthNCredentialAttestation
->dwVersion
>=
585 WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_4
) {
586 BOOL rk
= pWebAuthNCredentialAttestation
->bResidentKey
;
587 Unused
<< result
->SetCredPropsRk(rk
== TRUE
);
589 gWinWebauthnFreeCredentialAttestation(pWebAuthNCredentialAttestation
);
591 aPromise
->Resolve(result
);
593 PCWSTR errorName
= gWinWebauthnGetErrorName(hr
);
594 nsresult aError
= NS_ERROR_DOM_ABORT_ERR
;
596 if (_wcsicmp(errorName
, L
"InvalidStateError") == 0) {
597 aError
= NS_ERROR_DOM_INVALID_STATE_ERR
;
598 } else if (_wcsicmp(errorName
, L
"ConstraintError") == 0 ||
599 _wcsicmp(errorName
, L
"UnknownError") == 0) {
600 aError
= NS_ERROR_DOM_UNKNOWN_ERR
;
601 } else if (_wcsicmp(errorName
, L
"NotSupportedError") == 0) {
602 aError
= NS_ERROR_DOM_INVALID_STATE_ERR
;
603 } else if (_wcsicmp(errorName
, L
"NotAllowedError") == 0) {
604 aError
= NS_ERROR_DOM_NOT_ALLOWED_ERR
;
607 aPromise
->Reject(aError
);
611 NS_DispatchBackgroundTask(runnable
, NS_DISPATCH_EVENT_MAY_BLOCK
);
616 WinWebAuthnService::GetAssertion(uint64_t aTransactionId
,
617 uint64_t aBrowsingContextId
,
618 nsIWebAuthnSignArgs
* aArgs
,
619 nsIWebAuthnSignPromise
* aPromise
) {
620 nsresult rv
= EnsureWinWebAuthnModuleLoaded();
621 NS_ENSURE_SUCCESS(rv
, rv
);
625 auto guard
= mTransactionState
.Lock();
629 StaticAutoReadLock
moduleLock(gWinWebAuthnModuleLock
);
630 if (gWinWebauthnGetCancellationId(&cancellationId
) != S_OK
) {
631 // caller will reject promise
632 return NS_ERROR_DOM_UNKNOWN_ERR
;
636 *guard
= Some(TransactionState
{
640 Some(RefPtr
{aPromise
}),
644 bool conditionallyMediated
;
645 Unused
<< aArgs
->GetConditionallyMediated(&conditionallyMediated
);
646 if (!conditionallyMediated
) {
647 DoGetAssertion(Nothing(), guard
);
652 void WinWebAuthnService::DoGetAssertion(
653 Maybe
<nsTArray
<uint8_t>>&& aSelectedCredentialId
,
654 const TransactionStateMutex::AutoLock
& aGuard
) {
655 if (aGuard
->isNothing() || aGuard
->ref().pendingSignArgs
.isNothing() ||
656 aGuard
->ref().pendingSignPromise
.isNothing()) {
660 // Take the pending Args and Promise to prevent repeated calls to
661 // DoGetAssertion for this transaction.
662 RefPtr
<nsIWebAuthnSignArgs
> aArgs
= aGuard
->ref().pendingSignArgs
.extract();
663 RefPtr
<nsIWebAuthnSignPromise
> aPromise
=
664 aGuard
->ref().pendingSignPromise
.extract();
666 nsCOMPtr
<nsIRunnable
> runnable(NS_NewRunnableFunction(
667 "WinWebAuthnService::MakeCredential",
668 [self
= RefPtr
{this}, aArgs
, aPromise
,
669 aSelectedCredentialId
= std::move(aSelectedCredentialId
),
670 aCancellationId
= aGuard
->ref().cancellationId
]() mutable {
671 // Take a read lock on gWinWebAuthnModuleLock to prevent the module from
672 // being unloaded while the operation is in progress. This does not
673 // prevent the operation from being cancelled, so it does not block a
675 StaticAutoReadLock
moduleLock(gWinWebAuthnModuleLock
);
676 if (!gWinWebAuthnModule
) {
677 aPromise
->Reject(NS_ERROR_DOM_UNKNOWN_ERR
);
682 DWORD winAttachment
= WEBAUTHN_AUTHENTICATOR_ATTACHMENT_ANY
;
685 BOOL bAppIdUsed
= FALSE
;
686 BOOL
* pbAppIdUsed
= nullptr;
687 PCWSTR winAppIdentifier
= nullptr;
690 nsCString clientDataJSON
;
691 Unused
<< aArgs
->GetClientDataJSON(clientDataJSON
);
692 WEBAUTHN_CLIENT_DATA WebAuthNClientData
= {
693 WEBAUTHN_CLIENT_DATA_CURRENT_VERSION
,
694 (DWORD
)clientDataJSON
.Length(), (BYTE
*)(clientDataJSON
.get()),
695 WEBAUTHN_HASH_ALGORITHM_SHA_256
};
698 nsresult rv
= aArgs
->GetAppId(appId
);
699 if (rv
!= NS_ERROR_NOT_AVAILABLE
) {
701 aPromise
->Reject(rv
);
704 winAppIdentifier
= appId
.get();
705 pbAppIdUsed
= &bAppIdUsed
;
710 Unused
<< aArgs
->GetRpId(rpId
);
712 // User Verification Requirement
713 nsString userVerificationReq
;
714 Unused
<< aArgs
->GetUserVerification(userVerificationReq
);
715 DWORD winUserVerificationReq
;
716 // This mapping needs to be reviewed if values are added to the
717 // UserVerificationRequirement enum.
718 static_assert(MOZ_WEBAUTHN_ENUM_STRINGS_VERSION
== 3);
719 if (userVerificationReq
.EqualsLiteral(
720 MOZ_WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED
)) {
721 winUserVerificationReq
=
722 WEBAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED
;
723 } else if (userVerificationReq
.EqualsLiteral(
724 MOZ_WEBAUTHN_USER_VERIFICATION_REQUIREMENT_PREFERRED
)) {
725 winUserVerificationReq
=
726 WEBAUTHN_USER_VERIFICATION_REQUIREMENT_PREFERRED
;
727 } else if (userVerificationReq
.EqualsLiteral(
728 MOZ_WEBAUTHN_RESIDENT_KEY_REQUIREMENT_DISCOURAGED
)) {
729 winUserVerificationReq
=
730 WEBAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED
;
732 winUserVerificationReq
= WEBAUTHN_USER_VERIFICATION_REQUIREMENT_ANY
;
736 WEBAUTHN_HMAC_SECRET_SALT_VALUES
* pPrfInputs
= nullptr;
737 WEBAUTHN_HMAC_SECRET_SALT_VALUES prfInputs
= {0};
738 WEBAUTHN_HMAC_SECRET_SALT globalHmacSalt
= {0};
739 nsTArray
<uint8_t> prfEvalFirst
;
740 nsTArray
<uint8_t> prfEvalSecond
;
741 nsTArray
<nsTArray
<uint8_t>> prfEvalByCredIds
;
742 nsTArray
<nsTArray
<uint8_t>> prfEvalByCredFirsts
;
743 nsTArray
<bool> prfEvalByCredSecondMaybes
;
744 nsTArray
<nsTArray
<uint8_t>> prfEvalByCredSeconds
;
745 nsTArray
<WEBAUTHN_HMAC_SECRET_SALT
> hmacSecretSalts
;
746 nsTArray
<WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT
>
747 credWithHmacSecretSaltList
;
750 Unused
<< aArgs
->GetPrf(&requestedPrf
);
752 rv
= aArgs
->GetPrfEvalFirst(prfEvalFirst
);
754 globalHmacSalt
.cbFirst
= prfEvalFirst
.Length();
755 globalHmacSalt
.pbFirst
= prfEvalFirst
.Elements();
756 prfInputs
.pGlobalHmacSalt
= &globalHmacSalt
;
758 rv
= aArgs
->GetPrfEvalSecond(prfEvalSecond
);
760 globalHmacSalt
.cbSecond
= prfEvalSecond
.Length();
761 globalHmacSalt
.pbSecond
= prfEvalSecond
.Elements();
764 aArgs
->GetPrfEvalByCredentialCredentialId(prfEvalByCredIds
) &&
766 aArgs
->GetPrfEvalByCredentialEvalFirst(prfEvalByCredFirsts
) &&
767 NS_OK
== aArgs
->GetPrfEvalByCredentialEvalSecondMaybe(
768 prfEvalByCredSecondMaybes
) &&
769 NS_OK
== aArgs
->GetPrfEvalByCredentialEvalSecond(
770 prfEvalByCredSeconds
) &&
771 prfEvalByCredIds
.Length() == prfEvalByCredFirsts
.Length() &&
772 prfEvalByCredIds
.Length() == prfEvalByCredSecondMaybes
.Length() &&
773 prfEvalByCredIds
.Length() == prfEvalByCredSeconds
.Length()) {
774 for (size_t i
= 0; i
< prfEvalByCredIds
.Length(); i
++) {
775 WEBAUTHN_HMAC_SECRET_SALT salt
= {0};
776 salt
.cbFirst
= prfEvalByCredFirsts
[i
].Length();
777 salt
.pbFirst
= prfEvalByCredFirsts
[i
].Elements();
778 if (prfEvalByCredSecondMaybes
[i
]) {
779 salt
.cbSecond
= prfEvalByCredSeconds
[i
].Length();
780 salt
.pbSecond
= prfEvalByCredSeconds
[i
].Elements();
782 hmacSecretSalts
.AppendElement(salt
);
784 // The credWithHmacSecretSaltList array will contain raw pointers to
785 // elements of the hmacSecretSalts array, so we must not cause
786 // any re-allocations of hmacSecretSalts from this point.
787 for (size_t i
= 0; i
< prfEvalByCredIds
.Length(); i
++) {
788 WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT value
= {0};
789 value
.cbCredID
= prfEvalByCredIds
[i
].Length();
790 value
.pbCredID
= prfEvalByCredIds
[i
].Elements();
791 value
.pHmacSecretSalt
= &hmacSecretSalts
[i
];
792 credWithHmacSecretSaltList
.AppendElement(value
);
794 prfInputs
.cCredWithHmacSecretSaltList
=
795 credWithHmacSecretSaltList
.Length();
796 prfInputs
.pCredWithHmacSecretSaltList
=
797 credWithHmacSecretSaltList
.Elements();
800 pPrfInputs
= &prfInputs
;
803 // https://w3c.github.io/webauthn/#prf-extension
804 // "The hmac-secret extension provides two PRFs per credential: one
805 // which is used for requests where user verification is performed and
806 // another for all other requests. This extension [PRF] only exposes a
807 // single PRF per credential and, when implementing on top of
808 // hmac-secret, that PRF MUST be the one used for when user verification
809 // is performed. This overrides the UserVerificationRequirement if
812 winUserVerificationReq
==
813 WEBAUTHN_USER_VERIFICATION_REQUIREMENT_DISCOURAGED
) {
814 winUserVerificationReq
=
815 WEBAUTHN_USER_VERIFICATION_REQUIREMENT_PREFERRED
;
819 nsTArray
<nsTArray
<uint8_t>> allowList
;
820 nsTArray
<uint8_t> allowListTransports
;
821 if (aSelectedCredentialId
.isSome()) {
822 allowList
.AppendElement(aSelectedCredentialId
.extract());
823 allowListTransports
.AppendElement(
824 MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_INTERNAL
);
826 Unused
<< aArgs
->GetAllowList(allowList
);
827 Unused
<< aArgs
->GetAllowListTransports(allowListTransports
);
830 if (allowList
.Length() != allowListTransports
.Length()) {
831 aPromise
->Reject(NS_ERROR_DOM_UNKNOWN_ERR
);
835 nsTArray
<WEBAUTHN_CREDENTIAL_EX
> allowCredentials
;
836 WEBAUTHN_CREDENTIAL_EX
* pAllowCredentials
= nullptr;
837 nsTArray
<WEBAUTHN_CREDENTIAL_EX
*> allowCredentialsPtrs
;
838 WEBAUTHN_CREDENTIAL_LIST allowCredentialList
= {0};
839 WEBAUTHN_CREDENTIAL_LIST
* pAllowCredentialList
= nullptr;
841 for (size_t i
= 0; i
< allowList
.Length(); i
++) {
842 nsTArray
<uint8_t>& cred
= allowList
[i
];
843 uint8_t& transports
= allowListTransports
[i
];
844 DWORD winTransports
= 0;
845 if (transports
& MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_USB
) {
846 winTransports
|= WEBAUTHN_CTAP_TRANSPORT_USB
;
848 if (transports
& MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_NFC
) {
849 winTransports
|= WEBAUTHN_CTAP_TRANSPORT_NFC
;
851 if (transports
& MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_BLE
) {
852 winTransports
|= WEBAUTHN_CTAP_TRANSPORT_BLE
;
854 if (transports
& MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_INTERNAL
) {
855 winTransports
|= WEBAUTHN_CTAP_TRANSPORT_INTERNAL
;
857 if (transports
& MOZ_WEBAUTHN_AUTHENTICATOR_TRANSPORT_ID_HYBRID
) {
858 winTransports
|= WEBAUTHN_CTAP_TRANSPORT_HYBRID
;
861 WEBAUTHN_CREDENTIAL_EX credential
= {
862 WEBAUTHN_CREDENTIAL_EX_CURRENT_VERSION
,
863 static_cast<DWORD
>(cred
.Length()), (PBYTE
)(cred
.Elements()),
864 WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY
, winTransports
};
865 allowCredentials
.AppendElement(credential
);
868 if (allowCredentials
.Length()) {
869 pAllowCredentials
= allowCredentials
.Elements();
870 for (DWORD i
= 0; i
< allowCredentials
.Length(); i
++) {
871 allowCredentialsPtrs
.AppendElement(&pAllowCredentials
[i
]);
873 allowCredentialList
.cCredentials
= allowCredentials
.Length();
874 allowCredentialList
.ppCredentials
= allowCredentialsPtrs
.Elements();
875 pAllowCredentialList
= &allowCredentialList
;
878 uint32_t timeout_u32
;
879 Unused
<< aArgs
->GetTimeoutMS(&timeout_u32
);
880 DWORD timeout
= timeout_u32
;
882 WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS WebAuthNAssertionOptions
=
884 WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_7
,
889 winUserVerificationReq
,
893 &aCancellationId
, // CancellationId
894 pAllowCredentialList
,
895 WEBAUTHN_CRED_LARGE_BLOB_OPERATION_NONE
,
896 0, // Size of CredLargeBlob
897 NULL
, // CredLargeBlob
898 pPrfInputs
, // HmacSecretSaltValues
899 FALSE
, // BrowserInPrivateMode
900 NULL
, // LinkedDevice
902 0, // Size of JsonExt
906 PWEBAUTHN_ASSERTION pWebAuthNAssertion
= nullptr;
908 // Bug 1518876: Get Window Handle from Content process for Windows
910 HWND hWnd
= GetForegroundWindow();
912 HRESULT hr
= gWinWebauthnGetAssertion(
913 hWnd
, rpId
.get(), &WebAuthNClientData
, &WebAuthNAssertionOptions
,
914 &pWebAuthNAssertion
);
917 RefPtr
<WebAuthnSignResult
> result
=
918 new WebAuthnSignResult(clientDataJSON
, pWebAuthNAssertion
);
919 gWinWebauthnFreeAssertion(pWebAuthNAssertion
);
920 if (winAppIdentifier
!= nullptr) {
921 // The gWinWebauthnGetAssertion call modified bAppIdUsed through
922 // a pointer provided in WebAuthNAssertionOptions.
923 Unused
<< result
->SetUsedAppId(bAppIdUsed
== TRUE
);
925 aPromise
->Resolve(result
);
927 PCWSTR errorName
= gWinWebauthnGetErrorName(hr
);
928 nsresult aError
= NS_ERROR_DOM_ABORT_ERR
;
930 if (_wcsicmp(errorName
, L
"InvalidStateError") == 0) {
931 aError
= NS_ERROR_DOM_INVALID_STATE_ERR
;
932 } else if (_wcsicmp(errorName
, L
"ConstraintError") == 0 ||
933 _wcsicmp(errorName
, L
"UnknownError") == 0) {
934 aError
= NS_ERROR_DOM_UNKNOWN_ERR
;
935 } else if (_wcsicmp(errorName
, L
"NotSupportedError") == 0) {
936 aError
= NS_ERROR_DOM_INVALID_STATE_ERR
;
937 } else if (_wcsicmp(errorName
, L
"NotAllowedError") == 0) {
938 aError
= NS_ERROR_DOM_NOT_ALLOWED_ERR
;
941 aPromise
->Reject(aError
);
945 NS_DispatchBackgroundTask(runnable
, NS_DISPATCH_EVENT_MAY_BLOCK
);
949 WinWebAuthnService::HasPendingConditionalGet(uint64_t aBrowsingContextId
,
950 const nsAString
& aOrigin
,
952 auto guard
= mTransactionState
.Lock();
953 if (guard
->isNothing() ||
954 guard
->ref().browsingContextId
!= aBrowsingContextId
||
955 guard
->ref().pendingSignArgs
.isNothing()) {
961 Unused
<< guard
->ref().pendingSignArgs
.ref()->GetOrigin(origin
);
962 if (origin
!= aOrigin
) {
967 *aRv
= guard
->ref().transactionId
;
972 WinWebAuthnService::GetAutoFillEntries(
973 uint64_t aTransactionId
, nsTArray
<RefPtr
<nsIWebAuthnAutoFillEntry
>>& aRv
) {
978 auto guard
= mTransactionState
.Lock();
979 if (guard
->isNothing() || guard
->ref().transactionId
!= aTransactionId
||
980 guard
->ref().pendingSignArgs
.isNothing()) {
981 return NS_ERROR_NOT_AVAILABLE
;
983 Unused
<< guard
->ref().pendingSignArgs
.ref()->GetRpId(rpId
);
986 StaticAutoReadLock
moduleLock(gWinWebAuthnModuleLock
);
987 if (!gWinWebAuthnModule
) {
988 return NS_ERROR_NOT_AVAILABLE
;
991 if (gWinWebauthnGetApiVersionNumber() < WEBAUTHN_API_VERSION_4
) {
992 // GetPlatformCredentialList was added in version 4. Earlier versions
993 // can still present a generic "Use a Passkey" autofill entry, so
994 // this isn't an error.
998 WEBAUTHN_GET_CREDENTIALS_OPTIONS getCredentialsOptions
{
999 WEBAUTHN_GET_CREDENTIALS_OPTIONS_VERSION_1
,
1000 rpId
.get(), // pwszRpId
1001 FALSE
, // bBrowserInPrivateMode
1003 PWEBAUTHN_CREDENTIAL_DETAILS_LIST pCredentialList
= nullptr;
1004 HRESULT hr
= gWinWebauthnGetPlatformCredentialList(&getCredentialsOptions
,
1006 // WebAuthNGetPlatformCredentialList has an _Outptr_result_maybenull_
1007 // annotation and a comment "Returns NTE_NOT_FOUND when credentials are
1009 if (pCredentialList
== nullptr) {
1010 if (hr
!= NTE_NOT_FOUND
) {
1011 return NS_ERROR_FAILURE
;
1015 MOZ_ASSERT(hr
== S_OK
);
1016 for (size_t i
= 0; i
< pCredentialList
->cCredentialDetails
; i
++) {
1017 RefPtr
<nsIWebAuthnAutoFillEntry
> entry(
1018 new WebAuthnAutoFillEntry(pCredentialList
->ppCredentialDetails
[i
]));
1019 aRv
.AppendElement(entry
);
1021 gWinWebauthnFreePlatformCredentialList(pCredentialList
);
1026 WinWebAuthnService::SelectAutoFillEntry(
1027 uint64_t aTransactionId
, const nsTArray
<uint8_t>& aCredentialId
) {
1028 auto guard
= mTransactionState
.Lock();
1029 if (guard
->isNothing() || guard
->ref().transactionId
!= aTransactionId
||
1030 guard
->ref().pendingSignArgs
.isNothing()) {
1031 return NS_ERROR_NOT_AVAILABLE
;
1034 nsTArray
<nsTArray
<uint8_t>> allowList
;
1035 Unused
<< guard
->ref().pendingSignArgs
.ref()->GetAllowList(allowList
);
1036 if (!allowList
.IsEmpty() && !allowList
.Contains(aCredentialId
)) {
1037 return NS_ERROR_FAILURE
;
1040 Maybe
<nsTArray
<uint8_t>> id
;
1042 id
.ref().Assign(aCredentialId
);
1043 DoGetAssertion(std::move(id
), guard
);
1049 WinWebAuthnService::ResumeConditionalGet(uint64_t aTransactionId
) {
1050 auto guard
= mTransactionState
.Lock();
1051 if (guard
->isNothing() || guard
->ref().transactionId
!= aTransactionId
||
1052 guard
->ref().pendingSignArgs
.isNothing()) {
1053 return NS_ERROR_NOT_AVAILABLE
;
1055 DoGetAssertion(Nothing(), guard
);
1060 WinWebAuthnService::PinCallback(uint64_t aTransactionId
,
1061 const nsACString
& aPin
) {
1062 return NS_ERROR_NOT_IMPLEMENTED
;
1066 WinWebAuthnService::SetHasAttestationConsent(uint64_t aTransactionId
,
1068 return NS_ERROR_NOT_IMPLEMENTED
;
1072 WinWebAuthnService::SelectionCallback(uint64_t aTransactionId
,
1074 return NS_ERROR_NOT_IMPLEMENTED
;
1078 WinWebAuthnService::AddVirtualAuthenticator(
1079 const nsACString
& protocol
, const nsACString
& transport
,
1080 bool hasResidentKey
, bool hasUserVerification
, bool isUserConsenting
,
1081 bool isUserVerified
, uint64_t* _retval
) {
1082 return NS_ERROR_NOT_IMPLEMENTED
;
1086 WinWebAuthnService::RemoveVirtualAuthenticator(uint64_t authenticatorId
) {
1087 return NS_ERROR_NOT_IMPLEMENTED
;
1091 WinWebAuthnService::AddCredential(uint64_t authenticatorId
,
1092 const nsACString
& credentialId
,
1093 bool isResidentCredential
,
1094 const nsACString
& rpId
,
1095 const nsACString
& privateKey
,
1096 const nsACString
& userHandle
,
1097 uint32_t signCount
) {
1098 return NS_ERROR_NOT_IMPLEMENTED
;
1102 WinWebAuthnService::GetCredentials(
1103 uint64_t authenticatorId
,
1104 nsTArray
<RefPtr
<nsICredentialParameters
>>& _retval
) {
1105 return NS_ERROR_NOT_IMPLEMENTED
;
1109 WinWebAuthnService::RemoveCredential(uint64_t authenticatorId
,
1110 const nsACString
& credentialId
) {
1111 return NS_ERROR_NOT_IMPLEMENTED
;
1115 WinWebAuthnService::RemoveAllCredentials(uint64_t authenticatorId
) {
1116 return NS_ERROR_NOT_IMPLEMENTED
;
1120 WinWebAuthnService::SetUserVerified(uint64_t authenticatorId
,
1121 bool isUserVerified
) {
1122 return NS_ERROR_NOT_IMPLEMENTED
;
1126 WinWebAuthnService::Listen() { return NS_ERROR_NOT_IMPLEMENTED
; }
1129 WinWebAuthnService::RunCommand(const nsACString
& cmd
) {
1130 return NS_ERROR_NOT_IMPLEMENTED
;
1133 } // namespace mozilla::dom