Commit e5cdcf61 authored by Martin Kreichgauer's avatar Martin Kreichgauer Committed by Commit Bot

fido/win: plumb the credProtect extension through to the Windows API

Also updates third_party/microsoft_webauthn to a version that supports
credProtect.

Bug: 941120
Change-Id: I8e0fb6fd72bad6927ec7d1121c1a58888fb7ba3c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1599771
Commit-Queue: Martin Kreichgauer <martinkr@google.com>
Commit-Queue: Martin Kreichgauer <martinkr@chromium.org>
Reviewed-by: default avatarAdam Langley <agl@chromium.org>
Cr-Commit-Position: refs/heads/master@{#657484}
parent aa112d47
......@@ -45,6 +45,7 @@
#include "device/fido/features.h"
#include "device/fido/fido_authenticator.h"
#include "device/fido/fido_constants.h"
#include "device/fido/fido_test_data.h"
#include "device/fido/hid/fake_hid_impl_for_testing.h"
#include "device/fido/mock_fido_device.h"
#include "device/fido/scoped_virtual_fido_device.h"
......@@ -3712,4 +3713,45 @@ TEST_F(ResidentKeyAuthenticatorImplTest, ProtectedNonResidentCreds) {
EXPECT_TRUE(HasUV(callback_receiver));
}
#if defined(OS_WIN)
// Requests with a credProtect extension that have |enforce_protection_policy|
// set should be rejected if the Windows WebAuthn API doesn't support
// credProtect.
TEST_F(ResidentKeyAuthenticatorImplTest, WinCredProtectApiVersion) {
// The canned response returned by the Windows API fake is for acme.com.
NavigateAndCommit(GURL("https://acme.com"));
TestServiceManagerContext smc;
for (const bool supports_cred_protect : {false, true}) {
SCOPED_TRACE(testing::Message()
<< "supports_cred_protect: " << supports_cred_protect);
device::ScopedFakeWinWebAuthnApi fake_api;
fake_api.set_version(supports_cred_protect ? WEBAUTHN_API_VERSION_2
: WEBAUTHN_API_VERSION_1);
PublicKeyCredentialCreationOptionsPtr options = make_credential_options();
options->relying_party = PublicKeyCredentialRpEntity::New();
options->relying_party->id = device::test_data::kRelyingPartyId;
options->authenticator_selection->user_verification =
blink::mojom::UserVerificationRequirement::REQUIRED;
options->authenticator_selection->require_resident_key = true;
options->protection_policy =
blink::mojom::ProtectionPolicy::UV_OR_CRED_ID_REQUIRED;
options->enforce_protection_policy = true;
options->authenticator_selection->user_verification =
blink::mojom::UserVerificationRequirement::REQUIRED;
TestMakeCredentialCallback callback_receiver;
AuthenticatorPtr authenticator = ConnectToAuthenticator();
authenticator->MakeCredential(std::move(options),
callback_receiver.callback());
callback_receiver.WaitForCallback();
EXPECT_EQ(callback_receiver.status(),
supports_cred_protect ? AuthenticatorStatus::SUCCESS
: AuthenticatorStatus::NOT_ALLOWED_ERROR);
}
}
#endif // defined(OS_WIN)
} // namespace content
......@@ -1019,10 +1019,8 @@ IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest, WinMakeCredential) {
NavigateToURL(shell(), GetHttpsURL("www.acme.com", "/title1.html"));
device::ScopedFakeWinWebAuthnApi fake_api;
fake_api.set_available(true);
fake_api.set_is_uvpaa(true);
fake_api.set_hresult(S_OK);
fake_api.enable_fake_attestation();
base::Optional<std::string> result = ExecuteScriptAndExtractPrefixedString(
shell()->web_contents(),
......@@ -1036,10 +1034,8 @@ IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
NavigateToURL(shell(), GetHttpsURL("www.acme.com", "/title1.html"));
device::ScopedFakeWinWebAuthnApi fake_api;
fake_api.set_available(true);
fake_api.set_is_uvpaa(true);
fake_api.set_hresult(E_FAIL);
fake_api.enable_fake_attestation();
// The authenticator response was good but the return code indicated failure.
base::Optional<std::string> result = ExecuteScriptAndExtractPrefixedString(
......@@ -1053,10 +1049,8 @@ IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest, WinGetAssertion) {
NavigateToURL(shell(), GetHttpsURL("www.acme.com", "/title1.html"));
device::ScopedFakeWinWebAuthnApi fake_api;
fake_api.set_available(true);
fake_api.set_is_uvpaa(true);
fake_api.set_hresult(S_OK);
fake_api.enable_fake_assertion();
base::Optional<std::string> result = ExecuteScriptAndExtractPrefixedString(
shell()->web_contents(), BuildGetCallWithParameters(GetParameters()),
......@@ -1078,10 +1072,8 @@ IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
NavigateToURL(shell(), GetHttpsURL("www.acme.com", "/title1.html"));
device::ScopedFakeWinWebAuthnApi fake_api;
fake_api.set_available(true);
fake_api.set_is_uvpaa(true);
fake_api.set_hresult(E_FAIL);
fake_api.enable_fake_assertion();
// The authenticator response was good but the return code indicated failure.
base::Optional<std::string> result = ExecuteScriptAndExtractPrefixedString(
......
......@@ -67,16 +67,8 @@ CtapMakeCredentialRequest::EncodeAsCBOR(
}
if (request.cred_protect) {
int value;
switch (request.cred_protect->first) {
case CredProtect::kUVOrCredIDRequired:
value = 2;
break;
case CredProtect::kUVRequired:
value = 3;
break;
}
extensions.emplace(kExtensionCredProtect, value);
extensions.emplace(kExtensionCredProtect,
static_cast<uint8_t>(request.cred_protect->first));
}
if (!extensions.empty()) {
......
......@@ -412,8 +412,8 @@ enum class AttestationConveyancePreference : uint8_t {
// CredProtect enumerates the levels of credential protection specified by the
// `credProtect` CTAP2 extension.
enum class CredProtect : uint8_t {
kUVOrCredIDRequired = 1,
kUVRequired = 2,
kUVOrCredIDRequired = 2,
kUVRequired = 3,
};
} // namespace device
......
......@@ -12,6 +12,7 @@
#include "base/feature_list.h"
#include "base/metrics/histogram_functions.h"
#include "base/stl_util.h"
#include "build/build_config.h"
#include "components/device_event_log/device_event_log.h"
#include "device/fido/authenticator_make_credential_response.h"
#include "device/fido/features.h"
......@@ -22,6 +23,11 @@
#include "device/fido/pin.h"
#include "services/service_manager/public/cpp/connector.h"
#if defined(OS_WIN)
#include "device/fido/win/authenticator.h"
#include "third_party/microsoft_webauthn/webauthn.h"
#endif
namespace device {
using ClientPinAvailability =
......@@ -64,24 +70,32 @@ FidoReturnCode IsCandidateAuthenticatorPostTouch(
const AuthenticatorSelectionCriteria& authenticator_selection_criteria,
const FidoRequestHandlerBase::Observer* observer) {
const auto& opt_options = authenticator->Options();
if (!opt_options) {
#if defined(OS_WIN)
if (authenticator->IsWinNativeApiAuthenticator()) {
// This authenticator doesn't know its capabilities yet, so we need
// to assume it can handle the request. This is the case for Windows,
// where we proxy the request to the native API.
DCHECK(!opt_options);
if (request.cred_protect && request.cred_protect->second &&
!static_cast<WinWebAuthnApiAuthenticator*>(authenticator)
->SupportsCredProtectExtension()) {
return FidoReturnCode::kAuthenticatorMissingResidentKeys;
}
return FidoReturnCode::kSuccess;
}
#endif // defined(OS_WIN)
DCHECK(opt_options);
if (authenticator_selection_criteria.require_resident_key() &&
!opt_options->supports_resident_key) {
return FidoReturnCode::kAuthenticatorMissingResidentKeys;
}
// TODO(martinkr): the Windows integration needs to be able to pass the
// credProtect information to the DLL, and to fail if the DLL version is too
// low to support credProtect.
if (request.cred_protect && request.cred_protect->second &&
(!authenticator->Options() ||
!authenticator->Options()->supports_cred_protect)) {
!authenticator->Options()->supports_cred_protect) {
return FidoReturnCode::kAuthenticatorMissingResidentKeys;
}
......@@ -179,6 +193,16 @@ void MakeCredentialRequestHandler::DispatchRequest(
if (IsCandidateAuthenticatorPostTouch(
request_, authenticator, authenticator_selection_criteria_,
observer()) != FidoReturnCode::kSuccess) {
#if defined(OS_WIN)
// If the Windows API cannot handle a request, just reject the request
// outright. There are no other authenticators to attempt, so calling
// GetTouch() would not make sense.
if (authenticator->IsWinNativeApiAuthenticator()) {
HandleInapplicableAuthenticator(authenticator);
return;
}
#endif // defined(OS_WIN)
if (!base::FeatureList::IsEnabled(device::kWebAuthPINSupport)) {
// Don't flash authenticator without PIN support. This maintains previous
// behaviour and avoids adding UI unprotected by a feature flag without
......
......@@ -144,6 +144,10 @@ void WinWebAuthnApiAuthenticator::GetAssertionDone(
std::move(callback).Run(result.first, std::move(result.second));
}
void WinWebAuthnApiAuthenticator::GetTouch(base::OnceClosure callback) {
NOTREACHED();
}
void WinWebAuthnApiAuthenticator::Cancel() {
if (!is_pending_ || waiting_for_cancellation_)
return;
......@@ -194,4 +198,8 @@ base::WeakPtr<FidoAuthenticator> WinWebAuthnApiAuthenticator::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
bool WinWebAuthnApiAuthenticator::SupportsCredProtectExtension() {
return win_api_->Version() >= WEBAUTHN_API_VERSION_2;
}
} // namespace device
......@@ -47,6 +47,7 @@ class COMPONENT_EXPORT(DEVICE_FIDO) WinWebAuthnApiAuthenticator
MakeCredentialCallback callback) override;
void GetAssertion(CtapGetAssertionRequest request,
GetAssertionCallback callback) override;
void GetTouch(base::OnceClosure callback) override;
void Cancel() override;
std::string GetId() const override;
base::string16 GetDisplayName() const override;
......@@ -57,6 +58,8 @@ class COMPONENT_EXPORT(DEVICE_FIDO) WinWebAuthnApiAuthenticator
bool IsWinNativeApiAuthenticator() const override;
base::WeakPtr<FidoAuthenticator> GetWeakPtr() override;
bool SupportsCredProtectExtension();
private:
void MakeCredentialDone(
MakeCredentialCallback callback,
......
......@@ -11,7 +11,54 @@
namespace device {
FakeWinWebAuthnApi::FakeWinWebAuthnApi() = default;
namespace {
WEBAUTHN_CREDENTIAL_ATTESTATION FakeAttestation() {
WEBAUTHN_CREDENTIAL_ATTESTATION attestation = {};
attestation.dwVersion = WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_1;
attestation.cbAuthenticatorData =
sizeof(test_data::kCtap2MakeCredentialAuthData);
attestation.pbAuthenticatorData = reinterpret_cast<PBYTE>(
const_cast<uint8_t*>(device::test_data::kCtap2MakeCredentialAuthData));
attestation.cbAttestation =
sizeof(test_data::kPackedAttestationStatementCBOR);
attestation.pbAttestation = reinterpret_cast<PBYTE>(
const_cast<uint8_t*>(device::test_data::kPackedAttestationStatementCBOR));
attestation.cbAttestationObject = 0;
attestation.cbCredentialId = 0;
attestation.pwszFormatType = L"packed";
attestation.dwAttestationDecodeType = 0;
return attestation;
}
WEBAUTHN_ASSERTION FakeAssertion() {
WEBAUTHN_CREDENTIAL credential = {};
// No constant macro available because 1 is the current version
credential.dwVersion = 1;
credential.cbId = sizeof(test_data::kCredentialId);
credential.pbId =
reinterpret_cast<PBYTE>(const_cast<uint8_t*>(test_data::kCredentialId));
credential.pwszCredentialType = L"public-key";
WEBAUTHN_ASSERTION assertion = {};
// No constant macro available because 1 is the current version
assertion.dwVersion = 1;
assertion.cbAuthenticatorData = sizeof(test_data::kTestSignAuthenticatorData);
assertion.pbAuthenticatorData = reinterpret_cast<PBYTE>(
const_cast<uint8_t*>(test_data::kTestSignAuthenticatorData));
assertion.cbSignature = sizeof(test_data::kCtap2GetAssertionSignature);
assertion.pbSignature = reinterpret_cast<PBYTE>(
const_cast<uint8_t*>(test_data::kCtap2GetAssertionSignature));
assertion.Credential = credential;
assertion.pbUserId = NULL;
assertion.cbUserId = 0;
return assertion;
}
} // namespace
FakeWinWebAuthnApi::FakeWinWebAuthnApi()
: attestation_(FakeAttestation()), assertion_(FakeAssertion()) {}
FakeWinWebAuthnApi::~FakeWinWebAuthnApi() = default;
bool FakeWinWebAuthnApi::IsAvailable() const {
......@@ -64,46 +111,8 @@ void FakeWinWebAuthnApi::FreeCredentialAttestation(
void FakeWinWebAuthnApi::FreeAssertion(PWEBAUTHN_ASSERTION pWebAuthNAssertion) {
}
WEBAUTHN_CREDENTIAL_ATTESTATION FakeWinWebAuthnApi::MakePackedAttestation() {
WEBAUTHN_CREDENTIAL_ATTESTATION attestation = {};
attestation.dwVersion = WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_1;
attestation.cbAuthenticatorData =
sizeof(test_data::kCtap2MakeCredentialAuthData);
attestation.pbAuthenticatorData = reinterpret_cast<PBYTE>(
const_cast<uint8_t*>(device::test_data::kCtap2MakeCredentialAuthData));
attestation.cbAttestation =
sizeof(test_data::kPackedAttestationStatementCBOR);
attestation.pbAttestation = reinterpret_cast<PBYTE>(
const_cast<uint8_t*>(device::test_data::kPackedAttestationStatementCBOR));
attestation.cbAttestationObject = 0;
attestation.cbCredentialId = 0;
attestation.pwszFormatType = L"packed";
attestation.dwAttestationDecodeType = 0;
return attestation;
}
WEBAUTHN_ASSERTION FakeWinWebAuthnApi::MakeAssertion() {
WEBAUTHN_CREDENTIAL credential = {};
// No constant macro available because 1 is the current version
credential.dwVersion = 1;
credential.cbId = sizeof(test_data::kCredentialId);
credential.pbId =
reinterpret_cast<PBYTE>(const_cast<uint8_t*>(test_data::kCredentialId));
credential.pwszCredentialType = L"public-key";
WEBAUTHN_ASSERTION assertion = {};
// No constant macro available because 1 is the current version
assertion.dwVersion = 1;
assertion.cbAuthenticatorData = sizeof(test_data::kTestSignAuthenticatorData);
assertion.pbAuthenticatorData = reinterpret_cast<PBYTE>(
const_cast<uint8_t*>(test_data::kTestSignAuthenticatorData));
assertion.cbSignature = sizeof(test_data::kCtap2GetAssertionSignature);
assertion.pbSignature = reinterpret_cast<PBYTE>(
const_cast<uint8_t*>(test_data::kCtap2GetAssertionSignature));
assertion.Credential = credential;
assertion.pbUserId = NULL;
assertion.cbUserId = 0;
return assertion;
int FakeWinWebAuthnApi::Version() {
return version_;
}
ScopedFakeWinWebAuthnApi::ScopedFakeWinWebAuthnApi() : FakeWinWebAuthnApi() {
......
......@@ -21,16 +21,14 @@ class FakeWinWebAuthnApi : public WinWebAuthnApi {
// Inject the return value for WinWebAuthnApi::IsAvailable().
void set_available(bool available) { is_available_ = available; }
void enable_fake_attestation() { attestation_ = MakePackedAttestation(); }
void enable_fake_assertion() { assertion_ = MakeAssertion(); }
void set_hresult(HRESULT result) { result_ = result; }
// Inject the return value for
// WinWebAuthnApi::IsUserverifyingPlatformAuthenticatorAvailable().
void set_is_uvpaa(bool is_uvpaa) { is_uvpaa_ = is_uvpaa; }
void set_version(int version) { version_ = version; }
// WinWebAuthnApi:
bool IsAvailable() const override;
HRESULT IsUserVerifyingPlatformAuthenticatorAvailable(
......@@ -53,13 +51,12 @@ class FakeWinWebAuthnApi : public WinWebAuthnApi {
PCWSTR GetErrorName(HRESULT hr) override;
void FreeCredentialAttestation(PWEBAUTHN_CREDENTIAL_ATTESTATION) override;
void FreeAssertion(PWEBAUTHN_ASSERTION pWebAuthNAssertion) override;
int Version() override;
private:
WEBAUTHN_CREDENTIAL_ATTESTATION MakePackedAttestation();
WEBAUTHN_ASSERTION MakeAssertion();
bool is_available_ = true;
bool is_uvpaa_ = false;
int version_ = WEBAUTHN_API_VERSION_2;
WEBAUTHN_CREDENTIAL_ATTESTATION attestation_;
WEBAUTHN_ASSERTION assertion_;
HRESULT result_ = S_OK;
......
......@@ -13,6 +13,7 @@
#include "base/optional.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "components/device_event_log/device_event_log.h"
#include "device/fido/win/type_conversions.h"
namespace device {
......@@ -28,11 +29,6 @@ base::string16 OptionalGURLToUTF16(const base::Optional<GURL>& in) {
// to be larger than the largest internal request timeout.
constexpr uint32_t kWinWebAuthnTimeoutMilliseconds = 1000 * 60 * 5;
// We do not integrate with older API versions of webauthn.dll because they
// don't support BLE and direct device access to USB and BLE FIDO devices is
// not yet blocked on those platforms.
constexpr uint32_t kMinWinWebAuthnApiVersion = WEBAUTHN_API_VERSION_1;
class WinWebAuthnApiImpl : public WinWebAuthnApi {
public:
WinWebAuthnApiImpl() : WinWebAuthnApi(), is_bound_(false) {
......@@ -77,11 +73,15 @@ class WinWebAuthnApiImpl : public WinWebAuthnApi {
BIND_FN(get_api_version_number_, webauthn_dll_,
"WebAuthNGetApiVersionNumber");
api_version_ = get_api_version_number_ ? get_api_version_number_() : 0;
FIDO_LOG(DEBUG) << "webauthn.dll version " << api_version_;
}
~WinWebAuthnApiImpl() override {}
// WinWebAuthnApi:
bool IsAvailable() const override {
return is_bound_ && (api_version_ >= kMinWinWebAuthnApiVersion);
return is_bound_ && (api_version_ >= WEBAUTHN_API_VERSION_1);
}
HRESULT IsUserVerifyingPlatformAuthenticatorAvailable(
......@@ -130,12 +130,13 @@ class WinWebAuthnApiImpl : public WinWebAuthnApi {
DCHECK(is_bound_);
return free_credential_attestation_(attestation_ptr);
}
void FreeAssertion(PWEBAUTHN_ASSERTION assertion_ptr) override {
DCHECK(is_bound_);
return free_assertion_(assertion_ptr);
}
~WinWebAuthnApiImpl() override {}
int Version() override { return api_version_; }
private:
bool is_bound_ = false;
......@@ -246,6 +247,26 @@ AuthenticatorMakeCredentialBlocking(WinWebAuthnApi* webauthn_api,
sizeof(BOOL), static_cast<void*>(&kHMACSecretTrue)});
}
WEBAUTHN_CRED_PROTECT_EXTENSION_IN maybe_cred_protect_extension;
if (request.cred_protect) {
// MakeCredentialRequestHandler rejects a request with credProtect
// enforced=true if webauthn.dll does not support credProtect.
if (request.cred_protect->second &&
webauthn_api->Version() < WEBAUTHN_API_VERSION_2) {
NOTREACHED();
return {CtapDeviceResponseCode::kCtap2ErrNotAllowed, base::nullopt};
}
maybe_cred_protect_extension = WEBAUTHN_CRED_PROTECT_EXTENSION_IN{
/*dwCredProtect=*/static_cast<uint8_t>(request.cred_protect->first),
/*bRequireCredProtect=*/request.cred_protect->second,
};
extensions.emplace_back(WEBAUTHN_EXTENSION{
/*pwszExtensionIdentifier=*/WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT,
/*cbExtension=*/sizeof(WEBAUTHN_CRED_PROTECT_EXTENSION_IN),
/*pvExtension=*/&maybe_cred_protect_extension,
});
}
uint32_t authenticator_attachment;
if (request.is_u2f_only) {
authenticator_attachment =
......@@ -367,7 +388,7 @@ AuthenticatorGetAssertionBlocking(WinWebAuthnApi* webauthn_api,
// pCredentials data.
WEBAUTHN_CREDENTIALS{legacy_credentials.size(),
legacy_credentials.data()},
WEBAUTHN_EXTENSIONS{0, nullptr}, // None supported.
WEBAUTHN_EXTENSIONS{0, nullptr},
authenticator_attachment,
ToWinUserVerificationRequirement(request.user_verification),
/*dwFlags=*/0,
......@@ -394,4 +415,8 @@ AuthenticatorGetAssertionBlocking(WinWebAuthnApi* webauthn_api,
ToAuthenticatorGetAssertionResponse(*assertion)};
}
bool SupportsCredProtectExtension(WinWebAuthnApi* api) {
return api->IsAvailable() && api->Version() >= WEBAUTHN_API_VERSION_2;
}
} // namespace device
......@@ -61,9 +61,13 @@ class COMPONENT_EXPORT(DEVICE_FIDO) WinWebAuthnApi {
virtual HRESULT CancelCurrentOperation(GUID* cancellation_id) = 0;
virtual PCWSTR GetErrorName(HRESULT hr) = 0;
virtual void FreeCredentialAttestation(PWEBAUTHN_CREDENTIAL_ATTESTATION) = 0;
virtual void FreeAssertion(PWEBAUTHN_ASSERTION pWebAuthNAssertion) = 0;
virtual int Version() = 0;
protected:
WinWebAuthnApi();
......
......@@ -2,7 +2,7 @@ Name: Headers for the Windows 10 WebAuthn API (webauthn.dll)
Short Name: Windows webauthn.h
URL: https://github.com/Microsoft/webauthn/
Version: 0
Revision: 3a24bad67e717aed20c98c4ad7a82d32d4d9356d
Revision: 1687fc48a49f6d45aeed581822215b332a952eee
License: MIT
License File: LICENSE
Security Critical: no
......@@ -17,4 +17,3 @@ being.
Local Modifications:
- added BUILD.gn and README.chromium
- added an ifndef header include guard to webauthn.h
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#ifndef THIRD_PARTY_MICROSOFT_WEBAUTHN_WEBAUTHN_H_
#define THIRD_PARTY_MICROSOFT_WEBAUTHN_WEBAUTHN_H_
#ifndef __WEBAUTHN_H_
#define __WEBAUTHN_H_
#pragma once
......@@ -66,7 +66,13 @@ extern "C" {
// - WebAuthNGetErrorName
// - WebAuthNGetW3CExceptionDOMError
#define WEBAUTHN_API_CURRENT_VERSION WEBAUTHN_API_VERSION_1
#define WEBAUTHN_API_VERSION_2 2
// WEBAUTHN_API_VERSION_2 : Delta From WEBAUTHN_API_VERSION_1
// Added Extensions:
// - WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT
//
#define WEBAUTHN_API_CURRENT_VERSION WEBAUTHN_API_VERSION_2
//+------------------------------------------------------------------------------------------
// Information about an RP Entity
......@@ -270,6 +276,39 @@ typedef const WEBAUTHN_CREDENTIAL_LIST *PCWEBAUTHN_CREDENTIAL_LIST;
// GetAssertion Input Type: Not Supported
// GetAssertion Output Type: Not Supported
//+------------------------------------------------------------------------------------------
// credProtect extension
//-------------------------------------------------------------------------------------------
#define WEBAUTHN_USER_VERIFICATION_ANY 0
#define WEBAUTHN_USER_VERIFICATION_OPTIONAL 1
#define WEBAUTHN_USER_VERIFICATION_OPTIONAL_WITH_CREDENTIAL_ID_LIST 2
#define WEBAUTHN_USER_VERIFICATION_REQUIRED 3
typedef struct _WEBAUTHN_CRED_PROTECT_EXTENSION_IN {
// One of the above WEBAUTHN_USER_VERIFICATION_* values
DWORD dwCredProtect;
// Set the following to TRUE to require authenticator support for the
// credProtect extension
BOOL bRequireCredProtect;
} WEBAUTHN_CRED_PROTECT_EXTENSION_IN, *PWEBAUTHN_CRED_PROTECT_EXTENSION_IN;
typedef const WEBAUTHN_CRED_PROTECT_EXTENSION_IN*
PCWEBAUTHN_CRED_PROTECT_EXTENSION_IN;
#define WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT L"credProtect"
// Below type definitions is for WEBAUTHN_EXTENSIONS_IDENTIFIER_CRED_PROTECT
// MakeCredential Input Type: WEBAUTHN_CRED_PROTECT_EXTENSION_IN.
// - pvExtension must point to a WEBAUTHN_CRED_PROTECT_EXTENSION_IN struct
// - cbExtension will contain the
// sizeof(WEBAUTHN_CRED_PROTECT_EXTENSION_IN).
// MakeCredential Output Type: DWORD.
// - pvExtension will point to a DWORD with one of the above
// WEBAUTHN_USER_VERIFICATION_* values
// if credential was successfully created with CRED_PROTECT.
// - cbExtension will contain the sizeof(DWORD).
// GetAssertion Input Type: Not Supported
// GetAssertion Output Type: Not Supported
//+------------------------------------------------------------------------------------------
// Information about Extensions.
//-------------------------------------------------------------------------------------------
......@@ -667,4 +706,4 @@ WebAuthNGetW3CExceptionDOMError(
#endif // WINAPI_FAMILY_PARTITION
#pragma endregion
#endif // THIRD_PARTY_MICROSOFT_WEBAUTHN_WEBAUTHN_H_
#endif // __WEBAUTHN_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment