From 1e10407658e86b56b41e7e32cd808160c9d7a733 Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Fri, 17 Nov 2023 20:29:26 -0300 Subject: [PATCH 01/10] Move WebAuthNGetApiVersionNumber to mkwinsyscall --- lib/auth/webauthnwin/syscall_gen.go | 20 +++++++++ lib/auth/webauthnwin/syscall_windows.go | 53 ++++++++++++++++++++++++ lib/auth/webauthnwin/webauthn_windows.go | 18 +------- 3 files changed, 74 insertions(+), 17 deletions(-) create mode 100644 lib/auth/webauthnwin/syscall_gen.go create mode 100644 lib/auth/webauthnwin/syscall_windows.go diff --git a/lib/auth/webauthnwin/syscall_gen.go b/lib/auth/webauthnwin/syscall_gen.go new file mode 100644 index 0000000000000..495fbf749f4ce --- /dev/null +++ b/lib/auth/webauthnwin/syscall_gen.go @@ -0,0 +1,20 @@ +// Copyright 2023 Gravitational, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output syscall_windows.go syscall_gen.go + +//sys webAuthNGetApiVersionNumber() (ret int, err error) [failretval==0] = WebAuthn.WebAuthNGetApiVersionNumber +// https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L895-L897 + +package webauthnwin diff --git a/lib/auth/webauthnwin/syscall_windows.go b/lib/auth/webauthnwin/syscall_windows.go new file mode 100644 index 0000000000000..6ae351143a937 --- /dev/null +++ b/lib/auth/webauthnwin/syscall_windows.go @@ -0,0 +1,53 @@ +// Code generated by 'go generate'; DO NOT EDIT. + +package webauthnwin + +import ( + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +var _ unsafe.Pointer + +// Do the interface allocations only once for common +// Errno values. +const ( + errnoERROR_IO_PENDING = 997 +) + +var ( + errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL +) + +// errnoErr returns common boxed Errno values, to prevent +// allocations at runtime. +func errnoErr(e syscall.Errno) error { + switch e { + case 0: + return errERROR_EINVAL + case errnoERROR_IO_PENDING: + return errERROR_IO_PENDING + } + // TODO: add more here, after collecting data on the common + // error values see on Windows. (perhaps when running + // all.bat?) + return e +} + +var ( + modWebAuthn = windows.NewLazySystemDLL("WebAuthn.dll") + + procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") +) + +func webAuthNGetApiVersionNumber() (ret int, err error) { + r0, _, e1 := syscall.Syscall(procWebAuthNGetApiVersionNumber.Addr(), 0, 0, 0, 0) + ret = int(r0) + if ret == 0 { + err = errnoErr(e1) + } + return +} diff --git a/lib/auth/webauthnwin/webauthn_windows.go b/lib/auth/webauthnwin/webauthn_windows.go index 49d08e4773b0f..0b9e89fe9cbf0 100644 --- a/lib/auth/webauthnwin/webauthn_windows.go +++ b/lib/auth/webauthnwin/webauthn_windows.go @@ -30,11 +30,8 @@ import ( ) var ( - modWebAuthn = windows.NewLazySystemDLL("WebAuthn.dll") - // For reference, see // https://learn.microsoft.com/en-us/windows/win32/api/webauthn/. - procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable = modWebAuthn.NewProc("WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable") procWebAuthNAuthenticatorMakeCredential = modWebAuthn.NewProc("WebAuthNAuthenticatorMakeCredential") procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") @@ -228,20 +225,7 @@ func freeAssertion(in *webauthnAssertion) error { // it's version via API call. This function makes sure to not panic if dll is // missing. func checkIfDLLExistsAndGetAPIVersionNumber() (int, error) { - if err := modWebAuthn.Load(); err != nil { - return 0, err - } - if err := procWebAuthNGetApiVersionNumber.Find(); err != nil { - return 0, err - } - // This is the only API call of Windows Webauthn API that returns non-zero - // value when everything went fine. - // https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L895-L897 - ret, _, err := procWebAuthNGetApiVersionNumber.Call() - if ret == 0 && err != syscall.Errno(0) { - return 0, err - } - return int(ret), nil + return webAuthNGetApiVersionNumber() } func getErrorNameOrLastErr(in uintptr, lastError error) error { From bd11115711d40e74b9952a2aa91207adcb41107a Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Fri, 17 Nov 2023 20:42:03 -0300 Subject: [PATCH 02/10] Move WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable --- lib/auth/webauthnwin/syscall_gen.go | 3 +++ lib/auth/webauthnwin/syscall_windows.go | 17 ++++++++++++++++- lib/auth/webauthnwin/webauthn_windows.go | 21 +++++++++------------ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/lib/auth/webauthnwin/syscall_gen.go b/lib/auth/webauthnwin/syscall_gen.go index 495fbf749f4ce..0363cedb576ed 100644 --- a/lib/auth/webauthnwin/syscall_gen.go +++ b/lib/auth/webauthnwin/syscall_gen.go @@ -17,4 +17,7 @@ //sys webAuthNGetApiVersionNumber() (ret int, err error) [failretval==0] = WebAuthn.WebAuthNGetApiVersionNumber // https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L895-L897 +//sys webAuthNIsUserVerifyingPlatformAuthenticatorAvailable(out *bool) (ret uintptr, err error) [failretval!=0] = WebAuthn.WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable +// https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L901 + package webauthnwin diff --git a/lib/auth/webauthnwin/syscall_windows.go b/lib/auth/webauthnwin/syscall_windows.go index 6ae351143a937..b92159624b4fd 100644 --- a/lib/auth/webauthnwin/syscall_windows.go +++ b/lib/auth/webauthnwin/syscall_windows.go @@ -40,7 +40,8 @@ func errnoErr(e syscall.Errno) error { var ( modWebAuthn = windows.NewLazySystemDLL("WebAuthn.dll") - procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") + procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") + procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable = modWebAuthn.NewProc("WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable") ) func webAuthNGetApiVersionNumber() (ret int, err error) { @@ -51,3 +52,17 @@ func webAuthNGetApiVersionNumber() (ret int, err error) { } return } + +func webAuthNIsUserVerifyingPlatformAuthenticatorAvailable(out *bool) (ret uintptr, err error) { + var _p0 uint32 + if *out { + _p0 = 1 + } + r0, _, e1 := syscall.Syscall(procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable.Addr(), 1, uintptr(unsafe.Pointer(&_p0)), 0, 0) + *out = _p0 != 0 + ret = uintptr(r0) + if ret != 0 { + err = errnoErr(e1) + } + return +} diff --git a/lib/auth/webauthnwin/webauthn_windows.go b/lib/auth/webauthnwin/webauthn_windows.go index 0b9e89fe9cbf0..6920cc458e949 100644 --- a/lib/auth/webauthnwin/webauthn_windows.go +++ b/lib/auth/webauthnwin/webauthn_windows.go @@ -32,12 +32,11 @@ import ( var ( // For reference, see // https://learn.microsoft.com/en-us/windows/win32/api/webauthn/. - procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable = modWebAuthn.NewProc("WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable") - procWebAuthNAuthenticatorMakeCredential = modWebAuthn.NewProc("WebAuthNAuthenticatorMakeCredential") - procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") - procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") - procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") - procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") + procWebAuthNAuthenticatorMakeCredential = modWebAuthn.NewProc("WebAuthNAuthenticatorMakeCredential") + procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") + procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") + procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") + procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") modUser32 = windows.NewLazySystemDLL("user32.dll") procGetForegroundWindow = modUser32.NewProc("GetForegroundWindow") @@ -243,14 +242,12 @@ func getErrorNameOrLastErr(in uintptr, lastError error) error { } func isUVPlatformAuthenticatorAvailable() (bool, error) { - var out uint32 - ret, _, err := procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable.Call( - uintptr(unsafe.Pointer(&out)), - ) - if ret != 0 { + var out bool + ret, err := webAuthNIsUserVerifyingPlatformAuthenticatorAvailable(&out) + if err != nil { return false, getErrorNameOrLastErr(ret, err) } - return out == 1, nil + return out, nil } // bytesFromCBytes gets slice of bytes from C type and copies it to new slice From c6cc734dd8a5f36820774425356c9bc9f20c4fe0 Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Fri, 17 Nov 2023 20:55:37 -0300 Subject: [PATCH 03/10] Move WebAuthNAuthenticatorMakeCredential --- lib/auth/webauthnwin/syscall_gen.go | 3 +++ lib/auth/webauthnwin/syscall_windows.go | 10 ++++++++++ lib/auth/webauthnwin/webauthn_windows.go | 20 ++++++-------------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/lib/auth/webauthnwin/syscall_gen.go b/lib/auth/webauthnwin/syscall_gen.go index 0363cedb576ed..681d98e569cd6 100644 --- a/lib/auth/webauthnwin/syscall_gen.go +++ b/lib/auth/webauthnwin/syscall_gen.go @@ -20,4 +20,7 @@ //sys webAuthNIsUserVerifyingPlatformAuthenticatorAvailable(out *bool) (ret uintptr, err error) [failretval!=0] = WebAuthn.WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable // https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L901 +//sys webAuthNAuthenticatorMakeCredential(hwnd syscall.Handle, rp *webauthnRPEntityInformation, user *webauthnUserEntityInformation, pubKeyCredParams *webauthnCoseCredentialParameters, clientData *webauthnClientData, opts *webauthnAuthenticatorMakeCredentialOptions, out **webauthnCredentialAttestation) (ret uintptr, err error) [failretval!=0] = WebAuthn.WebAuthNAuthenticatorMakeCredential +// https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L907 + package webauthnwin diff --git a/lib/auth/webauthnwin/syscall_windows.go b/lib/auth/webauthnwin/syscall_windows.go index b92159624b4fd..35e6166c32749 100644 --- a/lib/auth/webauthnwin/syscall_windows.go +++ b/lib/auth/webauthnwin/syscall_windows.go @@ -40,10 +40,20 @@ func errnoErr(e syscall.Errno) error { var ( modWebAuthn = windows.NewLazySystemDLL("WebAuthn.dll") + procWebAuthNAuthenticatorMakeCredential = modWebAuthn.NewProc("WebAuthNAuthenticatorMakeCredential") procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable = modWebAuthn.NewProc("WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable") ) +func webAuthNAuthenticatorMakeCredential(hwnd syscall.Handle, rp *webauthnRPEntityInformation, user *webauthnUserEntityInformation, pubKeyCredParams *webauthnCoseCredentialParameters, clientData *webauthnClientData, opts *webauthnAuthenticatorMakeCredentialOptions, out **webauthnCredentialAttestation) (ret uintptr, err error) { + r0, _, e1 := syscall.Syscall9(procWebAuthNAuthenticatorMakeCredential.Addr(), 7, uintptr(hwnd), uintptr(unsafe.Pointer(rp)), uintptr(unsafe.Pointer(user)), uintptr(unsafe.Pointer(pubKeyCredParams)), uintptr(unsafe.Pointer(clientData)), uintptr(unsafe.Pointer(opts)), uintptr(unsafe.Pointer(out)), 0, 0) + ret = uintptr(r0) + if ret != 0 { + err = errnoErr(e1) + } + return +} + func webAuthNGetApiVersionNumber() (ret int, err error) { r0, _, e1 := syscall.Syscall(procWebAuthNGetApiVersionNumber.Addr(), 0, 0, 0, 0) ret = int(r0) diff --git a/lib/auth/webauthnwin/webauthn_windows.go b/lib/auth/webauthnwin/webauthn_windows.go index 6920cc458e949..839741037fe94 100644 --- a/lib/auth/webauthnwin/webauthn_windows.go +++ b/lib/auth/webauthnwin/webauthn_windows.go @@ -32,11 +32,10 @@ import ( var ( // For reference, see // https://learn.microsoft.com/en-us/windows/win32/api/webauthn/. - procWebAuthNAuthenticatorMakeCredential = modWebAuthn.NewProc("WebAuthNAuthenticatorMakeCredential") - procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") - procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") - procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") - procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") + procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") + procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") + procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") + procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") modUser32 = windows.NewLazySystemDLL("user32.dll") procGetForegroundWindow = modUser32.NewProc("GetForegroundWindow") @@ -160,15 +159,8 @@ func (n *nativeImpl) MakeCredential(origin string, in *makeCredentialRequest) (* } var out *webauthnCredentialAttestation - ret, _, err := procWebAuthNAuthenticatorMakeCredential.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(in.rp)), - uintptr(unsafe.Pointer(in.user)), - uintptr(unsafe.Pointer(in.credParameters)), - uintptr(unsafe.Pointer(in.clientData)), - uintptr(unsafe.Pointer(in.opts)), - uintptr(unsafe.Pointer(&out)), - ) + ret, err := webAuthNAuthenticatorMakeCredential( + hwnd, in.rp, in.user, in.credParameters, in.clientData, in.opts, &out) if ret != 0 { return nil, trace.Wrap(getErrorNameOrLastErr(ret, err)) } From 8d7c2c2a82eefe30f790573e90d688044d6425aa Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Fri, 17 Nov 2023 21:02:17 -0300 Subject: [PATCH 04/10] Move WebAuthNFreeCredentialAttestation --- lib/auth/webauthnwin/syscall_gen.go | 3 +++ lib/auth/webauthnwin/syscall_windows.go | 6 ++++++ lib/auth/webauthnwin/webauthn_windows.go | 8 +------- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/auth/webauthnwin/syscall_gen.go b/lib/auth/webauthnwin/syscall_gen.go index 681d98e569cd6..29491fc85e994 100644 --- a/lib/auth/webauthnwin/syscall_gen.go +++ b/lib/auth/webauthnwin/syscall_gen.go @@ -23,4 +23,7 @@ //sys webAuthNAuthenticatorMakeCredential(hwnd syscall.Handle, rp *webauthnRPEntityInformation, user *webauthnUserEntityInformation, pubKeyCredParams *webauthnCoseCredentialParameters, clientData *webauthnClientData, opts *webauthnAuthenticatorMakeCredentialOptions, out **webauthnCredentialAttestation) (ret uintptr, err error) [failretval!=0] = WebAuthn.WebAuthNAuthenticatorMakeCredential // https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L907 +//sys webAuthNFreeCredentialAttestation(in *webauthnCredentialAttestation) = WebAuthn.WebAuthNFreeCredentialAttestation +// https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L928 + package webauthnwin diff --git a/lib/auth/webauthnwin/syscall_windows.go b/lib/auth/webauthnwin/syscall_windows.go index 35e6166c32749..5437c74a697f9 100644 --- a/lib/auth/webauthnwin/syscall_windows.go +++ b/lib/auth/webauthnwin/syscall_windows.go @@ -41,6 +41,7 @@ var ( modWebAuthn = windows.NewLazySystemDLL("WebAuthn.dll") procWebAuthNAuthenticatorMakeCredential = modWebAuthn.NewProc("WebAuthNAuthenticatorMakeCredential") + procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable = modWebAuthn.NewProc("WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable") ) @@ -54,6 +55,11 @@ func webAuthNAuthenticatorMakeCredential(hwnd syscall.Handle, rp *webauthnRPEnti return } +func webAuthNFreeCredentialAttestation(in *webauthnCredentialAttestation) { + syscall.Syscall(procWebAuthNFreeCredentialAttestation.Addr(), 1, uintptr(unsafe.Pointer(in)), 0, 0) + return +} + func webAuthNGetApiVersionNumber() (ret int, err error) { r0, _, e1 := syscall.Syscall(procWebAuthNGetApiVersionNumber.Addr(), 0, 0, 0, 0) ret = int(r0) diff --git a/lib/auth/webauthnwin/webauthn_windows.go b/lib/auth/webauthnwin/webauthn_windows.go index 839741037fe94..1fdb5ba51f33e 100644 --- a/lib/auth/webauthnwin/webauthn_windows.go +++ b/lib/auth/webauthnwin/webauthn_windows.go @@ -32,7 +32,6 @@ import ( var ( // For reference, see // https://learn.microsoft.com/en-us/windows/win32/api/webauthn/. - procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") @@ -193,12 +192,7 @@ func (n *nativeImpl) MakeCredential(origin string, in *makeCredentialRequest) (* } func freeCredentialAttestation(in *webauthnCredentialAttestation) error { - _, _, err := procWebAuthNFreeCredentialAttestation.Call( - uintptr(unsafe.Pointer(in)), - ) - if err != syscall.Errno(0) { - return err - } + webAuthNFreeCredentialAttestation(in) return nil } From c9f54249a04bcf5e87c8ffeb9ce41df376120f9a Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Fri, 17 Nov 2023 21:11:48 -0300 Subject: [PATCH 05/10] Move WebAuthNAuthenticatorGetAssertion --- lib/auth/webauthnwin/syscall_gen.go | 3 +++ lib/auth/webauthnwin/syscall_windows.go | 10 ++++++++++ lib/auth/webauthnwin/webauthn_windows.go | 13 +++---------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/auth/webauthnwin/syscall_gen.go b/lib/auth/webauthnwin/syscall_gen.go index 29491fc85e994..b77c78ec234ae 100644 --- a/lib/auth/webauthnwin/syscall_gen.go +++ b/lib/auth/webauthnwin/syscall_gen.go @@ -26,4 +26,7 @@ //sys webAuthNFreeCredentialAttestation(in *webauthnCredentialAttestation) = WebAuthn.WebAuthNFreeCredentialAttestation // https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L928 +//sys webAuthNAuthenticatorGetAssertion(hwnd syscall.Handle, rpID *uint16, clientData *webauthnClientData, opts *webauthnAuthenticatorGetAssertionOptions, out **webauthnAssertion) (ret uintptr, err error) [failretval!=0] = WebAuthn.WebAuthNAuthenticatorGetAssertion +// https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L919 + package webauthnwin diff --git a/lib/auth/webauthnwin/syscall_windows.go b/lib/auth/webauthnwin/syscall_windows.go index 5437c74a697f9..2a53e5f5aaa59 100644 --- a/lib/auth/webauthnwin/syscall_windows.go +++ b/lib/auth/webauthnwin/syscall_windows.go @@ -40,12 +40,22 @@ func errnoErr(e syscall.Errno) error { var ( modWebAuthn = windows.NewLazySystemDLL("WebAuthn.dll") + procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") procWebAuthNAuthenticatorMakeCredential = modWebAuthn.NewProc("WebAuthNAuthenticatorMakeCredential") procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable = modWebAuthn.NewProc("WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable") ) +func webAuthNAuthenticatorGetAssertion(hwnd syscall.Handle, rpID *uint16, clientData *webauthnClientData, opts *webauthnAuthenticatorGetAssertionOptions, out **webauthnAssertion) (ret uintptr, err error) { + r0, _, e1 := syscall.Syscall6(procWebAuthNAuthenticatorGetAssertion.Addr(), 5, uintptr(hwnd), uintptr(unsafe.Pointer(rpID)), uintptr(unsafe.Pointer(clientData)), uintptr(unsafe.Pointer(opts)), uintptr(unsafe.Pointer(out)), 0) + ret = uintptr(r0) + if ret != 0 { + err = errnoErr(e1) + } + return +} + func webAuthNAuthenticatorMakeCredential(hwnd syscall.Handle, rp *webauthnRPEntityInformation, user *webauthnUserEntityInformation, pubKeyCredParams *webauthnCoseCredentialParameters, clientData *webauthnClientData, opts *webauthnAuthenticatorMakeCredentialOptions, out **webauthnCredentialAttestation) (ret uintptr, err error) { r0, _, e1 := syscall.Syscall9(procWebAuthNAuthenticatorMakeCredential.Addr(), 7, uintptr(hwnd), uintptr(unsafe.Pointer(rp)), uintptr(unsafe.Pointer(user)), uintptr(unsafe.Pointer(pubKeyCredParams)), uintptr(unsafe.Pointer(clientData)), uintptr(unsafe.Pointer(opts)), uintptr(unsafe.Pointer(out)), 0, 0) ret = uintptr(r0) diff --git a/lib/auth/webauthnwin/webauthn_windows.go b/lib/auth/webauthnwin/webauthn_windows.go index 1fdb5ba51f33e..12596898f4e85 100644 --- a/lib/auth/webauthnwin/webauthn_windows.go +++ b/lib/auth/webauthnwin/webauthn_windows.go @@ -32,9 +32,8 @@ import ( var ( // For reference, see // https://learn.microsoft.com/en-us/windows/win32/api/webauthn/. - procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") - procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") - procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") + procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") + procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") modUser32 = windows.NewLazySystemDLL("user32.dll") procGetForegroundWindow = modUser32.NewProc("GetForegroundWindow") @@ -101,13 +100,7 @@ func (n *nativeImpl) GetAssertion(origin string, in *getAssertionRequest) (*want } var out *webauthnAssertion - ret, _, err := procWebAuthNAuthenticatorGetAssertion.Call( - uintptr(hwnd), - uintptr(unsafe.Pointer(in.rpID)), - uintptr(unsafe.Pointer(in.clientData)), - uintptr(unsafe.Pointer(in.opts)), - uintptr(unsafe.Pointer(&out)), - ) + ret, err := webAuthNAuthenticatorGetAssertion(hwnd, in.rpID, in.clientData, in.opts, &out) if ret != 0 { return nil, trace.Wrap(getErrorNameOrLastErr(ret, err)) } From f8edf4ca5f5e8645a5d8de9c2a65109296223d8a Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Fri, 17 Nov 2023 21:13:59 -0300 Subject: [PATCH 06/10] Move WebAuthNFreeAssertion --- lib/auth/webauthnwin/syscall_gen.go | 3 +++ lib/auth/webauthnwin/syscall_windows.go | 6 ++++++ lib/auth/webauthnwin/webauthn_windows.go | 10 ++-------- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/auth/webauthnwin/syscall_gen.go b/lib/auth/webauthnwin/syscall_gen.go index b77c78ec234ae..7844b7572de21 100644 --- a/lib/auth/webauthnwin/syscall_gen.go +++ b/lib/auth/webauthnwin/syscall_gen.go @@ -29,4 +29,7 @@ //sys webAuthNAuthenticatorGetAssertion(hwnd syscall.Handle, rpID *uint16, clientData *webauthnClientData, opts *webauthnAuthenticatorGetAssertionOptions, out **webauthnAssertion) (ret uintptr, err error) [failretval!=0] = WebAuthn.WebAuthNAuthenticatorGetAssertion // https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L919 +//sys webAuthNFreeAssertion(in *webauthnAssertion) = WebAuthn.WebAuthNFreeAssertion +// https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L933 + package webauthnwin diff --git a/lib/auth/webauthnwin/syscall_windows.go b/lib/auth/webauthnwin/syscall_windows.go index 2a53e5f5aaa59..c7bf82259e201 100644 --- a/lib/auth/webauthnwin/syscall_windows.go +++ b/lib/auth/webauthnwin/syscall_windows.go @@ -42,6 +42,7 @@ var ( procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") procWebAuthNAuthenticatorMakeCredential = modWebAuthn.NewProc("WebAuthNAuthenticatorMakeCredential") + procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable = modWebAuthn.NewProc("WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable") @@ -65,6 +66,11 @@ func webAuthNAuthenticatorMakeCredential(hwnd syscall.Handle, rp *webauthnRPEnti return } +func webAuthNFreeAssertion(in *webauthnAssertion) { + syscall.Syscall(procWebAuthNFreeAssertion.Addr(), 1, uintptr(unsafe.Pointer(in)), 0, 0) + return +} + func webAuthNFreeCredentialAttestation(in *webauthnCredentialAttestation) { syscall.Syscall(procWebAuthNFreeCredentialAttestation.Addr(), 1, uintptr(unsafe.Pointer(in)), 0, 0) return diff --git a/lib/auth/webauthnwin/webauthn_windows.go b/lib/auth/webauthnwin/webauthn_windows.go index 12596898f4e85..72d3f1f2e354f 100644 --- a/lib/auth/webauthnwin/webauthn_windows.go +++ b/lib/auth/webauthnwin/webauthn_windows.go @@ -32,8 +32,7 @@ import ( var ( // For reference, see // https://learn.microsoft.com/en-us/windows/win32/api/webauthn/. - procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") - procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") + procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") modUser32 = windows.NewLazySystemDLL("user32.dll") procGetForegroundWindow = modUser32.NewProc("GetForegroundWindow") @@ -190,12 +189,7 @@ func freeCredentialAttestation(in *webauthnCredentialAttestation) error { } func freeAssertion(in *webauthnAssertion) error { - _, _, err := procWebAuthNFreeAssertion.Call( - uintptr(unsafe.Pointer(in)), - ) - if err != syscall.Errno(0) { - return err - } + webAuthNFreeAssertion(in) return nil } From d791918744c0ffaabc0a1486f8549df6256fc524 Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Fri, 17 Nov 2023 21:27:08 -0300 Subject: [PATCH 07/10] Move WebAuthNGetErrorName --- lib/auth/webauthnwin/syscall_gen.go | 5 +++++ lib/auth/webauthnwin/syscall_windows.go | 7 +++++++ lib/auth/webauthnwin/webauthn_windows.go | 8 +------- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/auth/webauthnwin/syscall_gen.go b/lib/auth/webauthnwin/syscall_gen.go index 7844b7572de21..d15a0f2bf3b21 100644 --- a/lib/auth/webauthnwin/syscall_gen.go +++ b/lib/auth/webauthnwin/syscall_gen.go @@ -14,6 +14,8 @@ //go:generate go run golang.org/x/sys/windows/mkwinsyscall -output syscall_windows.go syscall_gen.go +// See https://learn.microsoft.com/en-us/windows/win32/api/webauthn/. + //sys webAuthNGetApiVersionNumber() (ret int, err error) [failretval==0] = WebAuthn.WebAuthNGetApiVersionNumber // https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L895-L897 @@ -32,4 +34,7 @@ //sys webAuthNFreeAssertion(in *webauthnAssertion) = WebAuthn.WebAuthNFreeAssertion // https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L933 +//sys webAuthNGetErrorName(in uintptr) (ret uintptr) = WebAuthn.WebAuthNGetErrorName +// https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L982 + package webauthnwin diff --git a/lib/auth/webauthnwin/syscall_windows.go b/lib/auth/webauthnwin/syscall_windows.go index c7bf82259e201..9535acd089849 100644 --- a/lib/auth/webauthnwin/syscall_windows.go +++ b/lib/auth/webauthnwin/syscall_windows.go @@ -45,6 +45,7 @@ var ( procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") + procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable = modWebAuthn.NewProc("WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable") ) @@ -85,6 +86,12 @@ func webAuthNGetApiVersionNumber() (ret int, err error) { return } +func webAuthNGetErrorName(in uintptr) (ret uintptr) { + r0, _, _ := syscall.Syscall(procWebAuthNGetErrorName.Addr(), 1, uintptr(in), 0, 0) + ret = uintptr(r0) + return +} + func webAuthNIsUserVerifyingPlatformAuthenticatorAvailable(out *bool) (ret uintptr, err error) { var _p0 uint32 if *out { diff --git a/lib/auth/webauthnwin/webauthn_windows.go b/lib/auth/webauthnwin/webauthn_windows.go index 72d3f1f2e354f..ce6c38fdd816d 100644 --- a/lib/auth/webauthnwin/webauthn_windows.go +++ b/lib/auth/webauthnwin/webauthn_windows.go @@ -30,10 +30,6 @@ import ( ) var ( - // For reference, see - // https://learn.microsoft.com/en-us/windows/win32/api/webauthn/. - procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") - modUser32 = windows.NewLazySystemDLL("user32.dll") procGetForegroundWindow = modUser32.NewProc("GetForegroundWindow") ) @@ -201,9 +197,7 @@ func checkIfDLLExistsAndGetAPIVersionNumber() (int, error) { } func getErrorNameOrLastErr(in uintptr, lastError error) error { - ret, _, _ := procWebAuthNGetErrorName.Call( - uintptr(int32(in)), - ) + ret := webAuthNGetErrorName(in) if ret == 0 { if lastError != syscall.Errno(0) { return fmt.Errorf("webauthn error code %v and syscall err: %v", in, lastError) From 51556641ebc932408e371c071dfeb61084c2bbf3 Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Fri, 17 Nov 2023 21:29:23 -0300 Subject: [PATCH 08/10] Move GetForegroundWindow --- lib/auth/webauthnwin/syscall_gen.go | 3 +++ lib/auth/webauthnwin/syscall_windows.go | 11 +++++++++++ lib/auth/webauthnwin/webauthn_windows.go | 13 ------------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/auth/webauthnwin/syscall_gen.go b/lib/auth/webauthnwin/syscall_gen.go index d15a0f2bf3b21..b81e3b92d44a5 100644 --- a/lib/auth/webauthnwin/syscall_gen.go +++ b/lib/auth/webauthnwin/syscall_gen.go @@ -37,4 +37,7 @@ //sys webAuthNGetErrorName(in uintptr) (ret uintptr) = WebAuthn.WebAuthNGetErrorName // https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L982 +//sys getForegroundWindow() (hwnd syscall.Handle, err error) [failretval==0] = user32.GetForegroundWindow +// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getforegroundwindow + package webauthnwin diff --git a/lib/auth/webauthnwin/syscall_windows.go b/lib/auth/webauthnwin/syscall_windows.go index 9535acd089849..35e7f31a3624a 100644 --- a/lib/auth/webauthnwin/syscall_windows.go +++ b/lib/auth/webauthnwin/syscall_windows.go @@ -39,6 +39,7 @@ func errnoErr(e syscall.Errno) error { var ( modWebAuthn = windows.NewLazySystemDLL("WebAuthn.dll") + moduser32 = windows.NewLazySystemDLL("user32.dll") procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") procWebAuthNAuthenticatorMakeCredential = modWebAuthn.NewProc("WebAuthNAuthenticatorMakeCredential") @@ -47,6 +48,7 @@ var ( procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable = modWebAuthn.NewProc("WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable") + procGetForegroundWindow = moduser32.NewProc("GetForegroundWindow") ) func webAuthNAuthenticatorGetAssertion(hwnd syscall.Handle, rpID *uint16, clientData *webauthnClientData, opts *webauthnAuthenticatorGetAssertionOptions, out **webauthnAssertion) (ret uintptr, err error) { @@ -105,3 +107,12 @@ func webAuthNIsUserVerifyingPlatformAuthenticatorAvailable(out *bool) (ret uintp } return } + +func getForegroundWindow() (hwnd syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall(procGetForegroundWindow.Addr(), 0, 0, 0, 0) + hwnd = syscall.Handle(r0) + if hwnd == 0 { + err = errnoErr(e1) + } + return +} diff --git a/lib/auth/webauthnwin/webauthn_windows.go b/lib/auth/webauthnwin/webauthn_windows.go index ce6c38fdd816d..0616d59b4073d 100644 --- a/lib/auth/webauthnwin/webauthn_windows.go +++ b/lib/auth/webauthnwin/webauthn_windows.go @@ -29,11 +29,6 @@ import ( wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes" ) -var ( - modUser32 = windows.NewLazySystemDLL("user32.dll") - procGetForegroundWindow = modUser32.NewProc("GetForegroundWindow") -) - var native nativeWebauthn = newNativeImpl() // nativeImpl keeps diagnostic informations about windows webauthn support. @@ -231,11 +226,3 @@ func bytesFromCBytes(size uint32, p *byte) []byte { copy(out, tmp) return out } - -func getForegroundWindow() (hwnd syscall.Handle, err error) { - r0, _, err := procGetForegroundWindow.Call() - if err != syscall.Errno(0) { - return syscall.InvalidHandle, err - } - return syscall.Handle(r0), nil -} From 03ae7a077e393ee3a7bbd08e2aab03125befddc6 Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Fri, 17 Nov 2023 21:35:31 -0300 Subject: [PATCH 09/10] Fully replace free functions --- lib/auth/webauthnwin/syscall_gen.go | 4 ++-- lib/auth/webauthnwin/syscall_windows.go | 4 ++-- lib/auth/webauthnwin/webauthn_windows.go | 16 ++-------------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/lib/auth/webauthnwin/syscall_gen.go b/lib/auth/webauthnwin/syscall_gen.go index b81e3b92d44a5..21c5a00e9295d 100644 --- a/lib/auth/webauthnwin/syscall_gen.go +++ b/lib/auth/webauthnwin/syscall_gen.go @@ -25,13 +25,13 @@ //sys webAuthNAuthenticatorMakeCredential(hwnd syscall.Handle, rp *webauthnRPEntityInformation, user *webauthnUserEntityInformation, pubKeyCredParams *webauthnCoseCredentialParameters, clientData *webauthnClientData, opts *webauthnAuthenticatorMakeCredentialOptions, out **webauthnCredentialAttestation) (ret uintptr, err error) [failretval!=0] = WebAuthn.WebAuthNAuthenticatorMakeCredential // https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L907 -//sys webAuthNFreeCredentialAttestation(in *webauthnCredentialAttestation) = WebAuthn.WebAuthNFreeCredentialAttestation +//sys freeCredentialAttestation(in *webauthnCredentialAttestation) = WebAuthn.WebAuthNFreeCredentialAttestation // https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L928 //sys webAuthNAuthenticatorGetAssertion(hwnd syscall.Handle, rpID *uint16, clientData *webauthnClientData, opts *webauthnAuthenticatorGetAssertionOptions, out **webauthnAssertion) (ret uintptr, err error) [failretval!=0] = WebAuthn.WebAuthNAuthenticatorGetAssertion // https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L919 -//sys webAuthNFreeAssertion(in *webauthnAssertion) = WebAuthn.WebAuthNFreeAssertion +//sys freeAssertion(in *webauthnAssertion) = WebAuthn.WebAuthNFreeAssertion // https://github.com/microsoft/webauthn/blob/7ab979cc833bfab9a682ed51761309db57f56c8c/webauthn.h#L933 //sys webAuthNGetErrorName(in uintptr) (ret uintptr) = WebAuthn.WebAuthNGetErrorName diff --git a/lib/auth/webauthnwin/syscall_windows.go b/lib/auth/webauthnwin/syscall_windows.go index 35e7f31a3624a..c27df503f6ea5 100644 --- a/lib/auth/webauthnwin/syscall_windows.go +++ b/lib/auth/webauthnwin/syscall_windows.go @@ -69,12 +69,12 @@ func webAuthNAuthenticatorMakeCredential(hwnd syscall.Handle, rp *webauthnRPEnti return } -func webAuthNFreeAssertion(in *webauthnAssertion) { +func freeAssertion(in *webauthnAssertion) { syscall.Syscall(procWebAuthNFreeAssertion.Addr(), 1, uintptr(unsafe.Pointer(in)), 0, 0) return } -func webAuthNFreeCredentialAttestation(in *webauthnCredentialAttestation) { +func freeCredentialAttestation(in *webauthnCredentialAttestation) { syscall.Syscall(procWebAuthNFreeCredentialAttestation.Addr(), 1, uintptr(unsafe.Pointer(in)), 0, 0) return } diff --git a/lib/auth/webauthnwin/webauthn_windows.go b/lib/auth/webauthnwin/webauthn_windows.go index 0616d59b4073d..9db32a0562893 100644 --- a/lib/auth/webauthnwin/webauthn_windows.go +++ b/lib/auth/webauthnwin/webauthn_windows.go @@ -100,8 +100,7 @@ func (n *nativeImpl) GetAssertion(origin string, in *getAssertionRequest) (*want // Note that we need to copy bytes out of `out` if we want to free object. // That's why bytesFromCBytes is used. - // We don't care about free error so ignore it explicitly. - defer func() { _ = freeAssertion(out) }() + defer freeAssertion(out) authData := bytesFromCBytes(out.cbAuthenticatorData, out.pbAuthenticatorData) signature := bytesFromCBytes(out.cbSignature, out.pbSignature) @@ -152,8 +151,7 @@ func (n *nativeImpl) MakeCredential(origin string, in *makeCredentialRequest) (* // Note that we need to copy bytes out of `out` if we want to free object. // That's why bytesFromCBytes is used. - // We don't care about free error so ignore it explicitly. - defer func() { _ = freeCredentialAttestation(out) }() + defer freeCredentialAttestation(out) credential := bytesFromCBytes(out.cbCredentialID, out.pbCredentialID) @@ -174,16 +172,6 @@ func (n *nativeImpl) MakeCredential(origin string, in *makeCredentialRequest) (* }, nil } -func freeCredentialAttestation(in *webauthnCredentialAttestation) error { - webAuthNFreeCredentialAttestation(in) - return nil -} - -func freeAssertion(in *webauthnAssertion) error { - webAuthNFreeAssertion(in) - return nil -} - // checkIfDLLExistsAndGetAPIVersionNumber checks if dll exists and tries to load // it's version via API call. This function makes sure to not panic if dll is // missing. From 9316e6420e29c0bfa9ce62195f64227efa2d5fce Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Tue, 21 Nov 2023 10:17:13 -0300 Subject: [PATCH 10/10] Rename syscall_windows.go to zsyscall_windows.go --- lib/auth/webauthnwin/syscall_gen.go | 2 +- .../webauthnwin/{syscall_windows.go => zsyscall_windows.go} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/auth/webauthnwin/{syscall_windows.go => zsyscall_windows.go} (100%) diff --git a/lib/auth/webauthnwin/syscall_gen.go b/lib/auth/webauthnwin/syscall_gen.go index 21c5a00e9295d..0c5cec50503d0 100644 --- a/lib/auth/webauthnwin/syscall_gen.go +++ b/lib/auth/webauthnwin/syscall_gen.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output syscall_windows.go syscall_gen.go +//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go syscall_gen.go // See https://learn.microsoft.com/en-us/windows/win32/api/webauthn/. diff --git a/lib/auth/webauthnwin/syscall_windows.go b/lib/auth/webauthnwin/zsyscall_windows.go similarity index 100% rename from lib/auth/webauthnwin/syscall_windows.go rename to lib/auth/webauthnwin/zsyscall_windows.go