From f3e6f3891805f57c709f92704b6fcb0b1a870e27 Mon Sep 17 00:00:00 2001 From: Savely Krasovsky Date: Sun, 5 Oct 2025 00:57:58 +0200 Subject: [PATCH 1/8] feat: version 8-9 support is added --- consts.go | 179 ++++++++++++++--- types_webauthn.go | 3 + versions.go | 9 +- webauthn.h | 4 +- winhello.go | 64 +++--- ztypes_webauthn.go | 477 +++++++++++++++++++++++---------------------- 6 files changed, 453 insertions(+), 283 deletions(-) diff --git a/consts.go b/consts.go index 986917a..f5cbb5d 100644 --- a/consts.go +++ b/consts.go @@ -46,7 +46,8 @@ const ( WinHelloCTAPTransportTest WinHelloCTAPTransportInternal WinHelloCTAPTransportHybrid - WinHelloCTAPTransportFlagsMask WinHelloCOSEAlgorithm = 0x0000003F + WinHelloCTAPTransportSmartCard + WinHelloCTAPTransportFlagsMask WinHelloCOSEAlgorithm = 0x0000007F ) type WinHelloUserVerification uint32 @@ -135,25 +136,30 @@ const ( ) type AuthenticatorGetAssertionOptions struct { - Timeout time.Duration - AuthenticatorAttachment WinHelloAuthenticatorAttachment - UserVerificationRequirement WinHelloUserVerificationRequirement - U2FAppID string - CancellationID *windows.GUID - CredentialLargeBlobOperation WinHelloCredentialLargeBlobOperation - CredentialLargeBlob []byte - BrowserInPrivateMode bool - AutoFill bool - JsonExt []byte - CredentialHints []webauthntypes.PublicKeyCredentialHint + Timeout time.Duration + AuthenticatorAttachment WinHelloAuthenticatorAttachment + UserVerificationRequirement WinHelloUserVerificationRequirement + U2FAppID string + CancellationID *windows.GUID + CredentialLargeBlobOperation WinHelloCredentialLargeBlobOperation + CredentialLargeBlob []byte + BrowserInPrivateMode bool + AutoFill bool + JsonExt []byte + CredentialHints []webauthntypes.PublicKeyCredentialHint + RemoteWebOrigin string + PublicKeyCredentialRequestOptionsJSON []byte + AuthenticatorID []byte } type WinHelloGetAssertionResponse struct { *ctaptypes.AuthenticatorGetAssertionResponse - CredLargeBlob []byte - CredLargeBlobStatus WinHelloCredentialLargeBlobStatus - UsedTransport []webauthntypes.AuthenticatorTransport - hmacSecret *webauthntypes.AuthenticationExtensionsPRFValues + CredLargeBlob []byte + CredLargeBlobStatus WinHelloCredentialLargeBlobStatus + UsedTransport []webauthntypes.AuthenticatorTransport + ClientDataJSON []byte + AuthenticationResponseJSON []byte + hmacSecret *webauthntypes.AuthenticationExtensionsPRFValues } func (a *_WEBAUTHN_ASSERTION) ToGetAssertionResponse() ( @@ -185,25 +191,150 @@ func (a *_WEBAUTHN_ASSERTION) ToGetAssertionResponse() ( winHelloResp := &WinHelloGetAssertionResponse{ AuthenticatorGetAssertionResponse: resp, - CredLargeBlob: bytes.Clone(unsafe.Slice(a.PbCredLargeBlob, a.CbCredLargeBlob)), - CredLargeBlobStatus: WinHelloCredentialLargeBlobStatus(a.DwCredLargeBlobStatus), - UsedTransport: flagsToTransports(a.DwUsedTransport), } - if a.PHmacSecret != nil { + if a.DwVersion >= 2 { + winHelloResp.CredLargeBlob = bytes.Clone(unsafe.Slice(a.PbCredLargeBlob, a.CbCredLargeBlob)) + winHelloResp.CredLargeBlobStatus = WinHelloCredentialLargeBlobStatus(a.DwCredLargeBlobStatus) + } + + if a.DwVersion >= 3 && a.PHmacSecret != nil { winHelloResp.hmacSecret = &webauthntypes.AuthenticationExtensionsPRFValues{ First: bytes.Clone(unsafe.Slice(a.PHmacSecret.PbFirst, a.PHmacSecret.CbFirst)), Second: bytes.Clone(unsafe.Slice(a.PHmacSecret.PbSecond, a.PHmacSecret.CbSecond)), } } - unsignedExtensionOutputsRaw := bytes.Clone(unsafe.Slice(a.PbUnsignedExtensionOutputs, a.CbUnsignedExtensionOutputs)) - if unsignedExtensionOutputsRaw != nil && len(unsignedExtensionOutputsRaw) > 0 { - if err := cbor.Unmarshal(unsignedExtensionOutputsRaw, &resp.UnsignedExtensionOutputs); err != nil { + if a.DwVersion >= 4 { + winHelloResp.UsedTransport = flagsToTransports(a.DwUsedTransport) + } + + if a.DwVersion >= 5 { + unsignedExtensionOutputsRaw := bytes.Clone(unsafe.Slice(a.PbUnsignedExtensionOutputs, a.CbUnsignedExtensionOutputs)) + if unsignedExtensionOutputsRaw != nil && len(unsignedExtensionOutputsRaw) > 0 { + if err := cbor.Unmarshal(unsignedExtensionOutputsRaw, &resp.UnsignedExtensionOutputs); err != nil { + return nil, err + } + } + } + + if a.DwVersion >= 6 { + clientDataJSONRaw := bytes.Clone(unsafe.Slice(a.PbClientDataJSON, a.CbClientDataJSON)) + if clientDataJSONRaw != nil && len(clientDataJSONRaw) > 0 { + winHelloResp.ClientDataJSON = clientDataJSONRaw + } + authenticationResponseJSONRaw := bytes.Clone(unsafe.Slice(a.PbAuthenticationResponseJSON, a.CbAuthenticationResponseJSON)) + if authenticationResponseJSONRaw != nil && len(authenticationResponseJSONRaw) > 0 { + winHelloResp.AuthenticationResponseJSON = authenticationResponseJSONRaw + } + } + + return winHelloResp, nil +} + +type AuthenticatorMakeCredentialOptions struct { + Timeout time.Duration + AuthenticatorAttachment WinHelloAuthenticatorAttachment + RequireResidentKey bool + UserVerificationRequirement WinHelloUserVerificationRequirement + AttestationConveyancePreference WinHelloAttestationConveyancePreference + CancellationID *windows.GUID + EnterpriseAttestation WinHelloEnterpriseAttestation + LargeBlobSupport WinHelloLargeBlobSupport + PreferResidentKey bool + BrowserInPrivateMode bool + JsonExt []byte + CredentialHints []webauthntypes.PublicKeyCredentialHint + ThirdPartyPayment bool + RemoteWebOrigin string + PublicKeyCredentialCreationOptionsJSON []byte + AuthenticatorID []byte +} + +type WinHelloMakeCredentialResponse struct { + *ctaptypes.AuthenticatorMakeCredentialResponse + CredentialID []byte + UsedTransport []webauthntypes.AuthenticatorTransport + LargeBlobSupported bool + ResidentKey bool + PRFEnabled bool + HMACSecret *webauthntypes.AuthenticationExtensionsPRFValues + ThirdPartyPayment bool + Transports []webauthntypes.AuthenticatorTransport + ClientDataJSON []byte + RegistrationResponseJSON []byte +} + +func (a *_WEBAUTHN_CREDENTIAL_ATTESTATION) ToMakeCredentialResponse() (*WinHelloMakeCredentialResponse, error) { + authDataRaw := bytes.Clone(unsafe.Slice(a.PbAuthenticatorData, a.CbAuthenticatorData)) + authData, err := ctaptypes.ParseMakeCredentialAuthData(authDataRaw) + if err != nil { + return nil, err + } + + resp := &ctaptypes.AuthenticatorMakeCredentialResponse{ + Format: webauthntypes.AttestationStatementFormatIdentifier(windows.UTF16PtrToString(a.PwszFormatType)), + AuthData: authData, + AuthDataRaw: authDataRaw, + } + + attestationRaw := bytes.Clone(unsafe.Slice(a.PbAttestation, a.CbAttestation)) + if resp.Format != webauthntypes.AttestationStatementFormatIdentifierNone && + attestationRaw != nil && + len(attestationRaw) > 0 { + if err := cbor.Unmarshal(attestationRaw, &resp.AttestationStatement); err != nil { return nil, err } } + winHelloResp := &WinHelloMakeCredentialResponse{ + AuthenticatorMakeCredentialResponse: resp, + CredentialID: bytes.Clone(unsafe.Slice(a.PbCredentialId, a.CbCredentialId)), + } + + if a.DwVersion >= 3 { + winHelloResp.UsedTransport = flagsToTransports(a.DwUsedTransport) + } + + if a.DwVersion >= 4 { + winHelloResp.EnterpriseAttestation = int32ToBool(a.BEpAtt) + winHelloResp.LargeBlobSupported = int32ToBool(a.BLargeBlobSupported) + winHelloResp.ResidentKey = int32ToBool(a.BResidentKey) + } + + if a.DwVersion >= 5 { + winHelloResp.PRFEnabled = int32ToBool(a.BPrfEnabled) + } + + if a.DwVersion >= 6 { + unsignedExtensionOutputsRaw := bytes.Clone(unsafe.Slice(a.PbUnsignedExtensionOutputs, a.CbUnsignedExtensionOutputs)) + if unsignedExtensionOutputsRaw != nil && len(unsignedExtensionOutputsRaw) > 0 { + if err := cbor.Unmarshal(unsignedExtensionOutputsRaw, &resp.UnsignedExtensionOutputs); err != nil { + return nil, err + } + } + } + + if a.DwVersion >= 7 && a.PHmacSecret != nil { + winHelloResp.HMACSecret = &webauthntypes.AuthenticationExtensionsPRFValues{ + First: bytes.Clone(unsafe.Slice(a.PHmacSecret.PbFirst, a.PHmacSecret.CbFirst)), + Second: bytes.Clone(unsafe.Slice(a.PHmacSecret.PbSecond, a.PHmacSecret.CbSecond)), + } + winHelloResp.ThirdPartyPayment = int32ToBool(a.BThirdPartyPayment) + } + + if a.DwVersion >= 8 { + winHelloResp.Transports = flagsToTransports(a.DwTransports) + clientDataJSONRaw := bytes.Clone(unsafe.Slice(a.PbClientDataJSON, a.CbClientDataJSON)) + if clientDataJSONRaw != nil && len(clientDataJSONRaw) > 0 { + winHelloResp.ClientDataJSON = clientDataJSONRaw + } + registrationResponseJSONRaw := bytes.Clone(unsafe.Slice(a.PbRegistrationResponseJSON, a.CbRegistrationResponseJSON)) + if registrationResponseJSONRaw != nil && len(registrationResponseJSONRaw) > 0 { + winHelloResp.RegistrationResponseJSON = registrationResponseJSONRaw + } + } + return winHelloResp, nil } @@ -220,6 +351,8 @@ func flagsToTransports(flags uint32) []webauthntypes.AuthenticatorTransport { case flags&uint32(WinHelloCTAPTransportInternal) != 0: tr = append(tr, webauthntypes.AuthenticatorTransportInternal) case flags&uint32(WinHelloCTAPTransportHybrid) != 0: + case flags&uint32(WinHelloCTAPTransportSmartCard) != 0: + tr = append(tr, webauthntypes.AuthenticatorTransportSmartCard) tr = append(tr, webauthntypes.AuthenticatorTransportHybrid) } diff --git a/types_webauthn.go b/types_webauthn.go index f014862..2050631 100644 --- a/types_webauthn.go +++ b/types_webauthn.go @@ -38,6 +38,9 @@ type ( _WEBAUTHN_USER_ENTITY_INFORMATION C.WEBAUTHN_USER_ENTITY_INFORMATION _WEBAUTHN_X5C C.WEBAUTHN_X5C _CTAPCBOR_HYBRID_STORAGE_LINKED_DATA C.CTAPCBOR_HYBRID_STORAGE_LINKED_DATA + _WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS C.WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS + _WEBAUTHN_AUTHENTICATOR_DETAILS C.WEBAUTHN_AUTHENTICATOR_DETAILS + _WEBAUTHN_AUTHENTICATOR_DETAILS_LIST C.WEBAUTHN_AUTHENTICATOR_DETAILS_LIST ) func int32ToBool(i int32) bool { diff --git a/versions.go b/versions.go index b89b6c7..4d04c97 100644 --- a/versions.go +++ b/versions.go @@ -14,6 +14,7 @@ type currentVersion struct { commonAttestation uint32 credentialAttestation uint32 assertion uint32 + authenticatorDetails uint32 } func availableVersions(ver uint32) *currentVersion { @@ -24,7 +25,6 @@ func availableVersions(ver uint32) *currentVersion { coseCredentialParameter: 1, credential: 1, credentialEx: 1, - getCredentialsOptions: 1, commonAttestation: 1, authenticatorMakeCredentialOptions: 3, @@ -45,6 +45,7 @@ func availableVersions(ver uint32) *currentVersion { v.authenticatorMakeCredentialOptions++ v.authenticatorGetAssertionOptions++ v.assertion++ + v.getCredentialsOptions++ v.credentialDetails++ }, // 4 func(v *currentVersion) { @@ -69,10 +70,12 @@ func availableVersions(ver uint32) *currentVersion { }, // 8 func(v *currentVersion) { v.authenticatorMakeCredentialOptions++ + v.authenticatorGetAssertionOptions++ + v.assertion++ v.credentialDetails++ v.credentialAttestation++ - v.authenticatorGetAssertionOptions++ - }, // 9 + v.authenticatorDetails++ + }, } for i, d := range diff { diff --git a/webauthn.h b/webauthn.h index 989b324..6b4a94e 100644 --- a/webauthn.h +++ b/webauthn.h @@ -1159,6 +1159,7 @@ typedef struct _WEBAUTHN_CREDENTIAL_ATTESTATION { typedef const WEBAUTHN_CREDENTIAL_ATTESTATION *PCWEBAUTHN_CREDENTIAL_ATTESTATION; + //+------------------------------------------------------------------------------------------ // authenticatorGetAssertion output. //------------------------------------------------------------------------------------------- @@ -1285,6 +1286,7 @@ WebAuthNAuthenticatorMakeCredential( _Outptr_result_maybenull_ PWEBAUTHN_CREDENTIAL_ATTESTATION *ppWebAuthNCredentialAttestation); + HRESULT WINAPI WebAuthNAuthenticatorGetAssertion( @@ -1378,4 +1380,4 @@ WebAuthNGetW3CExceptionDOMError( #endif // WINAPI_FAMILY_PARTITION #pragma endregion -#endif // __WEBAUTHN_H_ \ No newline at end of file +#endif // __WEBAUTHN_H_ diff --git a/winhello.go b/winhello.go index 7f1ae0f..132ce4b 100644 --- a/winhello.go +++ b/winhello.go @@ -15,21 +15,25 @@ import ( ) var ( - modWebAuthn = windows.NewLazyDLL("webauthn.dll") - procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") - procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") - procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") - currVer = availableVersions(APIVersionNumber()) + modWebAuthn = windows.NewLazyDLL("webauthn.dll") + procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") + procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable = modWebAuthn.NewProc("WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable") + procWebAuthNAuthenticatorMakeCredential = modWebAuthn.NewProc("WebAuthNAuthenticatorMakeCredential") + procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") + procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") + procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") + procWebAuthNGetCancellationId = modWebAuthn.NewProc("WebAuthNGetCancellationId") + procWebAuthNCancelCurrentOperation = modWebAuthn.NewProc("WebAuthNCancelCurrentOperation") + procWebAuthNGetPlatformCredentialList = modWebAuthn.NewProc("WebAuthNGetPlatformCredentialList") + procWebAuthNFreePlatformCredentialList = modWebAuthn.NewProc("WebAuthNFreePlatformCredentialList") + procWebAuthNDeletePlatformCredential = modWebAuthn.NewProc("WebAuthNDeletePlatformCredential") + procWebAuthNGetAuthenticatorList = modWebAuthn.NewProc("WebAuthNGetAuthenticatorList") + procWebAuthNFreeAuthenticatorList = modWebAuthn.NewProc("WebAuthNFreeAuthenticatorList") + procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") + procWebAuthNGetW3CExceptionDOMError = modWebAuthn.NewProc("WebAuthNGetW3CExceptionDOMError") + currVer = availableVersions(APIVersionNumber()) ) -type WebAuthnCredentialDetails struct { - CredentialID []byte - RP webauthntypes.PublicKeyCredentialRpEntity - User webauthntypes.PublicKeyCredentialUserEntity - Removable bool - BackedUp bool -} - func GetAssertion( hWnd windows.HWND, rpID string, @@ -43,19 +47,23 @@ func GetAssertion( } opts := &_WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS{ - DwVersion: currVer.authenticatorGetAssertionOptions, - DwTimeoutMilliseconds: uint32(winHelloOpts.Timeout.Milliseconds()), - CredentialList: _WEBAUTHN_CREDENTIALS{}, // basically deprecated, baseline supports pAllowCredentialList - DwAuthenticatorAttachment: uint32(winHelloOpts.AuthenticatorAttachment), - DwUserVerificationRequirement: uint32(winHelloOpts.UserVerificationRequirement), - DwFlags: 0, // user only in version 8 for PRF Global Eval - DwCredLargeBlobOperation: uint32(winHelloOpts.CredentialLargeBlobOperation), - CbCredLargeBlob: uint32(len(winHelloOpts.CredentialLargeBlob)), - PbCredLargeBlob: unsafe.SliceData(winHelloOpts.CredentialLargeBlob), - BBrowserInPrivateMode: boolToInt32(winHelloOpts.BrowserInPrivateMode), - BAutoFill: boolToInt32(winHelloOpts.AutoFill), - CbJsonExt: uint32(len(winHelloOpts.JsonExt)), - PbJsonExt: unsafe.SliceData(winHelloOpts.JsonExt), + DwVersion: currVer.authenticatorGetAssertionOptions, + DwTimeoutMilliseconds: uint32(winHelloOpts.Timeout.Milliseconds()), + CredentialList: _WEBAUTHN_CREDENTIALS{}, // basically deprecated, baseline supports pAllowCredentialList + DwAuthenticatorAttachment: uint32(winHelloOpts.AuthenticatorAttachment), + DwUserVerificationRequirement: uint32(winHelloOpts.UserVerificationRequirement), + DwFlags: 0, // user only in version 8 for PRF Global Eval + DwCredLargeBlobOperation: uint32(winHelloOpts.CredentialLargeBlobOperation), + CbCredLargeBlob: uint32(len(winHelloOpts.CredentialLargeBlob)), + PbCredLargeBlob: unsafe.SliceData(winHelloOpts.CredentialLargeBlob), + BBrowserInPrivateMode: boolToInt32(winHelloOpts.BrowserInPrivateMode), + BAutoFill: boolToInt32(winHelloOpts.AutoFill), + CbJsonExt: uint32(len(winHelloOpts.JsonExt)), + PbJsonExt: unsafe.SliceData(winHelloOpts.JsonExt), + CbPublicKeyCredentialRequestOptionsJSON: uint32(len(winHelloOpts.PublicKeyCredentialRequestOptionsJSON)), + PbPublicKeyCredentialRequestOptionsJSON: unsafe.SliceData(winHelloOpts.PublicKeyCredentialRequestOptionsJSON), + CbAuthenticatorId: uint32(len(winHelloOpts.AuthenticatorID)), + PbAuthenticatorId: unsafe.SliceData(winHelloOpts.AuthenticatorID), } credExList := make([]*_WEBAUTHN_CREDENTIAL_EX, len(allowList)) @@ -117,6 +125,10 @@ func GetAssertion( opts.PpwszCredentialHints = unsafe.SliceData(credHints) } + if winHelloOpts.RemoteWebOrigin != "" { + opts.PwszRemoteWebOrigin = windows.StringToUTF16Ptr(winHelloOpts.RemoteWebOrigin) + } + if extInputs != nil { exts := make([]_WEBAUTHN_EXTENSION, 0) diff --git a/ztypes_webauthn.go b/ztypes_webauthn.go index 4d7203c..22cf96d 100644 --- a/ztypes_webauthn.go +++ b/ztypes_webauthn.go @@ -4,262 +4,279 @@ package winhello type ( - _GUID struct { - Data1 uint32 - Data2 uint16 - Data3 uint16 - Data4 [8]uint8 + _GUID struct { + Data1 uint32 + Data2 uint16 + Data3 uint16 + Data4 [8]uint8 } - _WEBAUTHN_ASSERTION struct { - DwVersion uint32 - CbAuthenticatorData uint32 - PbAuthenticatorData *uint8 - CbSignature uint32 - PbSignature *uint8 - Credential _WEBAUTHN_CREDENTIAL - CbUserId uint32 - PbUserId *uint8 - Extensions _WEBAUTHN_EXTENSIONS - CbCredLargeBlob uint32 - PbCredLargeBlob *uint8 - DwCredLargeBlobStatus uint32 - PHmacSecret *_WEBAUTHN_HMAC_SECRET_SALT - DwUsedTransport uint32 - CbUnsignedExtensionOutputs uint32 - PbUnsignedExtensionOutputs *uint8 - CbClientDataJSON uint32 - PbClientDataJSON *uint8 - CbAuthenticationResponseJSON uint32 - PbAuthenticationResponseJSON *uint8 + _WEBAUTHN_ASSERTION struct { + DwVersion uint32 + CbAuthenticatorData uint32 + PbAuthenticatorData *uint8 + CbSignature uint32 + PbSignature *uint8 + Credential _WEBAUTHN_CREDENTIAL + CbUserId uint32 + PbUserId *uint8 + Extensions _WEBAUTHN_EXTENSIONS + CbCredLargeBlob uint32 + PbCredLargeBlob *uint8 + DwCredLargeBlobStatus uint32 + PHmacSecret *_WEBAUTHN_HMAC_SECRET_SALT + DwUsedTransport uint32 + CbUnsignedExtensionOutputs uint32 + PbUnsignedExtensionOutputs *uint8 + CbClientDataJSON uint32 + PbClientDataJSON *uint8 + CbAuthenticationResponseJSON uint32 + PbAuthenticationResponseJSON *uint8 } - _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS struct { - DwVersion uint32 - DwTimeoutMilliseconds uint32 - CredentialList _WEBAUTHN_CREDENTIALS - Extensions _WEBAUTHN_EXTENSIONS - DwAuthenticatorAttachment uint32 - DwUserVerificationRequirement uint32 - DwFlags uint32 - PwszU2fAppId *uint16 - PbU2fAppId *int32 - PCancellationId *_GUID - PAllowCredentialList *_WEBAUTHN_CREDENTIAL_LIST - DwCredLargeBlobOperation uint32 - CbCredLargeBlob uint32 - PbCredLargeBlob *uint8 - PHmacSecretSaltValues *_WEBAUTHN_HMAC_SECRET_SALT_VALUES - BBrowserInPrivateMode int32 - PLinkedDevice *_CTAPCBOR_HYBRID_STORAGE_LINKED_DATA - BAutoFill int32 - CbJsonExt uint32 - PbJsonExt *uint8 - CCredentialHints uint32 - PpwszCredentialHints **uint16 - PwszRemoteWebOrigin *uint16 - CbPublicKeyCredentialRequestOptionsJSON uint32 - PbPublicKeyCredentialRequestOptionsJSON *uint8 - CbAuthenticatorId uint32 - PbAuthenticatorId *uint8 + _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS struct { + DwVersion uint32 + DwTimeoutMilliseconds uint32 + CredentialList _WEBAUTHN_CREDENTIALS + Extensions _WEBAUTHN_EXTENSIONS + DwAuthenticatorAttachment uint32 + DwUserVerificationRequirement uint32 + DwFlags uint32 + PwszU2fAppId *uint16 + PbU2fAppId *int32 + PCancellationId *_GUID + PAllowCredentialList *_WEBAUTHN_CREDENTIAL_LIST + DwCredLargeBlobOperation uint32 + CbCredLargeBlob uint32 + PbCredLargeBlob *uint8 + PHmacSecretSaltValues *_WEBAUTHN_HMAC_SECRET_SALT_VALUES + BBrowserInPrivateMode int32 + PLinkedDevice *_CTAPCBOR_HYBRID_STORAGE_LINKED_DATA + BAutoFill int32 + CbJsonExt uint32 + PbJsonExt *uint8 + CCredentialHints uint32 + PpwszCredentialHints **uint16 + PwszRemoteWebOrigin *uint16 + CbPublicKeyCredentialRequestOptionsJSON uint32 + PbPublicKeyCredentialRequestOptionsJSON *uint8 + CbAuthenticatorId uint32 + PbAuthenticatorId *uint8 } - _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS struct { - DwVersion uint32 - DwTimeoutMilliseconds uint32 - CredentialList _WEBAUTHN_CREDENTIALS - Extensions _WEBAUTHN_EXTENSIONS - DwAuthenticatorAttachment uint32 - BRequireResidentKey int32 - DwUserVerificationRequirement uint32 - DwAttestationConveyancePreference uint32 - DwFlags uint32 - PCancellationId *_GUID - PExcludeCredentialList *_WEBAUTHN_CREDENTIAL_LIST - DwEnterpriseAttestation uint32 - DwLargeBlobSupport uint32 - BPreferResidentKey int32 - BBrowserInPrivateMode int32 - BEnablePrf int32 - PLinkedDevice *_CTAPCBOR_HYBRID_STORAGE_LINKED_DATA - CbJsonExt uint32 - PbJsonExt *uint8 - PPRFGlobalEval *_WEBAUTHN_HMAC_SECRET_SALT - CCredentialHints uint32 - PpwszCredentialHints **uint16 - BThirdPartyPayment int32 - PwszRemoteWebOrigin *uint16 - CbPublicKeyCredentialCreationOptionsJSON uint32 - PbPublicKeyCredentialCreationOptionsJSON *uint8 - CbAuthenticatorId uint32 - PbAuthenticatorId *uint8 + _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS struct { + DwVersion uint32 + DwTimeoutMilliseconds uint32 + CredentialList _WEBAUTHN_CREDENTIALS + Extensions _WEBAUTHN_EXTENSIONS + DwAuthenticatorAttachment uint32 + BRequireResidentKey int32 + DwUserVerificationRequirement uint32 + DwAttestationConveyancePreference uint32 + DwFlags uint32 + PCancellationId *_GUID + PExcludeCredentialList *_WEBAUTHN_CREDENTIAL_LIST + DwEnterpriseAttestation uint32 + DwLargeBlobSupport uint32 + BPreferResidentKey int32 + BBrowserInPrivateMode int32 + BEnablePrf int32 + PLinkedDevice *_CTAPCBOR_HYBRID_STORAGE_LINKED_DATA + CbJsonExt uint32 + PbJsonExt *uint8 + PPRFGlobalEval *_WEBAUTHN_HMAC_SECRET_SALT + CCredentialHints uint32 + PpwszCredentialHints **uint16 + BThirdPartyPayment int32 + PwszRemoteWebOrigin *uint16 + CbPublicKeyCredentialCreationOptionsJSON uint32 + PbPublicKeyCredentialCreationOptionsJSON *uint8 + CbAuthenticatorId uint32 + PbAuthenticatorId *uint8 } - _WEBAUTHN_CLIENT_DATA struct { - DwVersion uint32 - CbClientDataJSON uint32 - PbClientDataJSON *uint8 - PwszHashAlgId *uint16 + _WEBAUTHN_CLIENT_DATA struct { + DwVersion uint32 + CbClientDataJSON uint32 + PbClientDataJSON *uint8 + PwszHashAlgId *uint16 } - _WEBAUTHN_COMMON_ATTESTATION struct { - DwVersion uint32 - PwszAlg *uint16 - LAlg int32 - CbSignature uint32 - PbSignature *uint8 - CX5c uint32 - PX5c *_WEBAUTHN_X5C - PwszVer *uint16 - CbCertInfo uint32 - PbCertInfo *uint8 - CbPubArea uint32 - PbPubArea *uint8 + _WEBAUTHN_COMMON_ATTESTATION struct { + DwVersion uint32 + PwszAlg *uint16 + LAlg int32 + CbSignature uint32 + PbSignature *uint8 + CX5c uint32 + PX5c *_WEBAUTHN_X5C + PwszVer *uint16 + CbCertInfo uint32 + PbCertInfo *uint8 + CbPubArea uint32 + PbPubArea *uint8 } - _WEBAUTHN_COSE_CREDENTIAL_PARAMETER struct { - DwVersion uint32 - PwszCredentialType *uint16 - LAlg int32 - Pad_cgo_0 [4]byte + _WEBAUTHN_COSE_CREDENTIAL_PARAMETER struct { + DwVersion uint32 + PwszCredentialType *uint16 + LAlg int32 + Pad_cgo_0 [4]byte } - _WEBAUTHN_COSE_CREDENTIAL_PARAMETERS struct { - CCredentialParameters uint32 - PCredentialParameters *_WEBAUTHN_COSE_CREDENTIAL_PARAMETER + _WEBAUTHN_COSE_CREDENTIAL_PARAMETERS struct { + CCredentialParameters uint32 + PCredentialParameters *_WEBAUTHN_COSE_CREDENTIAL_PARAMETER } - _WEBAUTHN_CRED_BLOB_EXTENSION struct { - CbCredBlob uint32 - PbCredBlob *uint8 + _WEBAUTHN_CRED_BLOB_EXTENSION struct { + CbCredBlob uint32 + PbCredBlob *uint8 } - _WEBAUTHN_CRED_PROTECT_EXTENSION_IN struct { - DwCredProtect uint32 - BRequireCredProtect int32 + _WEBAUTHN_CRED_PROTECT_EXTENSION_IN struct { + DwCredProtect uint32 + BRequireCredProtect int32 } - _WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT struct { - CbCredID uint32 - PbCredID *uint8 - PHmacSecretSalt *_WEBAUTHN_HMAC_SECRET_SALT + _WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT struct { + CbCredID uint32 + PbCredID *uint8 + PHmacSecretSalt *_WEBAUTHN_HMAC_SECRET_SALT } - _WEBAUTHN_CREDENTIAL struct { - DwVersion uint32 - CbId uint32 - PbId *uint8 - PwszCredentialType *uint16 + _WEBAUTHN_CREDENTIAL struct { + DwVersion uint32 + CbId uint32 + PbId *uint8 + PwszCredentialType *uint16 } - _WEBAUTHN_CREDENTIAL_ATTESTATION struct { - DwVersion uint32 - PwszFormatType *uint16 - CbAuthenticatorData uint32 - PbAuthenticatorData *uint8 - CbAttestation uint32 - PbAttestation *uint8 - DwAttestationDecodeType uint32 - PvAttestationDecode *byte - CbAttestationObject uint32 - PbAttestationObject *uint8 - CbCredentialId uint32 - PbCredentialId *uint8 - Extensions _WEBAUTHN_EXTENSIONS - DwUsedTransport uint32 - BEpAtt int32 - BLargeBlobSupported int32 - BResidentKey int32 - BPrfEnabled int32 - CbUnsignedExtensionOutputs uint32 - PbUnsignedExtensionOutputs *uint8 - PHmacSecret *_WEBAUTHN_HMAC_SECRET_SALT - BThirdPartyPayment int32 - DwTransports uint32 - CbClientDataJSON uint32 - PbClientDataJSON *uint8 - CbRegistrationResponseJSON uint32 - PbRegistrationResponseJSON *uint8 + _WEBAUTHN_CREDENTIAL_ATTESTATION struct { + DwVersion uint32 + PwszFormatType *uint16 + CbAuthenticatorData uint32 + PbAuthenticatorData *uint8 + CbAttestation uint32 + PbAttestation *uint8 + DwAttestationDecodeType uint32 + PvAttestationDecode *byte + CbAttestationObject uint32 + PbAttestationObject *uint8 + CbCredentialId uint32 + PbCredentialId *uint8 + Extensions _WEBAUTHN_EXTENSIONS + DwUsedTransport uint32 + BEpAtt int32 + BLargeBlobSupported int32 + BResidentKey int32 + BPrfEnabled int32 + CbUnsignedExtensionOutputs uint32 + PbUnsignedExtensionOutputs *uint8 + PHmacSecret *_WEBAUTHN_HMAC_SECRET_SALT + BThirdPartyPayment int32 + DwTransports uint32 + CbClientDataJSON uint32 + PbClientDataJSON *uint8 + CbRegistrationResponseJSON uint32 + PbRegistrationResponseJSON *uint8 } - _WEBAUTHN_CREDENTIAL_DETAILS struct { - DwVersion uint32 - CbCredentialID uint32 - PbCredentialID *uint8 - PRpInformation *_WEBAUTHN_RP_ENTITY_INFORMATION - PUserInformation *_WEBAUTHN_USER_ENTITY_INFORMATION - BRemovable int32 - BBackedUp int32 - PwszAuthenticatorName *uint16 - CbAuthenticatorLogo uint32 - PbAuthenticatorLogo *uint8 - BThirdPartyPayment int32 - DwTransports uint32 + _WEBAUTHN_CREDENTIAL_DETAILS struct { + DwVersion uint32 + CbCredentialID uint32 + PbCredentialID *uint8 + PRpInformation *_WEBAUTHN_RP_ENTITY_INFORMATION + PUserInformation *_WEBAUTHN_USER_ENTITY_INFORMATION + BRemovable int32 + BBackedUp int32 + PwszAuthenticatorName *uint16 + CbAuthenticatorLogo uint32 + PbAuthenticatorLogo *uint8 + BThirdPartyPayment int32 + DwTransports uint32 } - _WEBAUTHN_CREDENTIAL_DETAILS_LIST struct { - CCredentialDetails uint32 - PpCredentialDetails **_WEBAUTHN_CREDENTIAL_DETAILS + _WEBAUTHN_CREDENTIAL_DETAILS_LIST struct { + CCredentialDetails uint32 + PpCredentialDetails **_WEBAUTHN_CREDENTIAL_DETAILS } - _WEBAUTHN_CREDENTIAL_EX struct { - DwVersion uint32 - CbId uint32 - PbId *uint8 - PwszCredentialType *uint16 - DwTransports uint32 - Pad_cgo_0 [4]byte + _WEBAUTHN_CREDENTIAL_EX struct { + DwVersion uint32 + CbId uint32 + PbId *uint8 + PwszCredentialType *uint16 + DwTransports uint32 + Pad_cgo_0 [4]byte } - _WEBAUTHN_CREDENTIAL_LIST struct { - CCredentials uint32 - PpCredentials **_WEBAUTHN_CREDENTIAL_EX + _WEBAUTHN_CREDENTIAL_LIST struct { + CCredentials uint32 + PpCredentials **_WEBAUTHN_CREDENTIAL_EX } - _WEBAUTHN_CREDENTIALS struct { - CCredentials uint32 - PCredentials *_WEBAUTHN_CREDENTIAL + _WEBAUTHN_CREDENTIALS struct { + CCredentials uint32 + PCredentials *_WEBAUTHN_CREDENTIAL } - _WEBAUTHN_EXTENSION struct { - PwszExtensionIdentifier *uint16 - CbExtension uint32 - PvExtension *byte + _WEBAUTHN_EXTENSION struct { + PwszExtensionIdentifier *uint16 + CbExtension uint32 + PvExtension *byte } - _WEBAUTHN_EXTENSIONS struct { - CExtensions uint32 - PExtensions *_WEBAUTHN_EXTENSION + _WEBAUTHN_EXTENSIONS struct { + CExtensions uint32 + PExtensions *_WEBAUTHN_EXTENSION } - _WEBAUTHN_GET_CREDENTIALS_OPTIONS struct { - DwVersion uint32 - PwszRpId *uint16 - BBrowserInPrivateMode int32 - Pad_cgo_0 [4]byte + _WEBAUTHN_GET_CREDENTIALS_OPTIONS struct { + DwVersion uint32 + PwszRpId *uint16 + BBrowserInPrivateMode int32 + Pad_cgo_0 [4]byte } - _WEBAUTHN_HMAC_SECRET_SALT struct { - CbFirst uint32 - PbFirst *uint8 - CbSecond uint32 - PbSecond *uint8 + _WEBAUTHN_HMAC_SECRET_SALT struct { + CbFirst uint32 + PbFirst *uint8 + CbSecond uint32 + PbSecond *uint8 } - _WEBAUTHN_HMAC_SECRET_SALT_VALUES struct { - PGlobalHmacSalt *_WEBAUTHN_HMAC_SECRET_SALT - CCredWithHmacSecretSaltList uint32 - PCredWithHmacSecretSaltList *_WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT + _WEBAUTHN_HMAC_SECRET_SALT_VALUES struct { + PGlobalHmacSalt *_WEBAUTHN_HMAC_SECRET_SALT + CCredWithHmacSecretSaltList uint32 + PCredWithHmacSecretSaltList *_WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT } - _WEBAUTHN_RP_ENTITY_INFORMATION struct { - DwVersion uint32 - PwszId *uint16 - PwszName *uint16 - PwszIcon *uint16 + _WEBAUTHN_RP_ENTITY_INFORMATION struct { + DwVersion uint32 + PwszId *uint16 + PwszName *uint16 + PwszIcon *uint16 } - _WEBAUTHN_USER_ENTITY_INFORMATION struct { - DwVersion uint32 - CbId uint32 - PbId *uint8 - PwszName *uint16 - PwszIcon *uint16 - PwszDisplayName *uint16 + _WEBAUTHN_USER_ENTITY_INFORMATION struct { + DwVersion uint32 + CbId uint32 + PbId *uint8 + PwszName *uint16 + PwszIcon *uint16 + PwszDisplayName *uint16 } - _WEBAUTHN_X5C struct { - CbData uint32 - PbData *uint8 + _WEBAUTHN_X5C struct { + CbData uint32 + PbData *uint8 } - _CTAPCBOR_HYBRID_STORAGE_LINKED_DATA struct { - DwVersion uint32 - CbContactId uint32 - PbContactId *uint8 - CbLinkId uint32 - PbLinkId *uint8 - CbLinkSecret uint32 - PbLinkSecret *uint8 - CbPublicKey uint32 - PbPublicKey *uint8 - PwszAuthenticatorName *uint16 - WEncodedTunnelServerDomain uint16 - Pad_cgo_0 [6]byte + _CTAPCBOR_HYBRID_STORAGE_LINKED_DATA struct { + DwVersion uint32 + CbContactId uint32 + PbContactId *uint8 + CbLinkId uint32 + PbLinkId *uint8 + CbLinkSecret uint32 + PbLinkSecret *uint8 + CbPublicKey uint32 + PbPublicKey *uint8 + PwszAuthenticatorName *uint16 + WEncodedTunnelServerDomain uint16 + Pad_cgo_0 [6]byte + } + _WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS struct { + DwVersion uint32 + } + _WEBAUTHN_AUTHENTICATOR_DETAILS struct { + DwVersion uint32 + CbAuthenticatorId uint32 + PbAuthenticatorId *uint8 + PwszAuthenticatorName *uint16 + CbAuthenticatorLogo uint32 + PbAuthenticatorLogo *uint8 + BLocked int32 + Pad_cgo_0 [4]byte + } + _WEBAUTHN_AUTHENTICATOR_DETAILS_LIST struct { + CAuthenticatorDetails uint32 + PpAuthenticatorDetails **_WEBAUTHN_AUTHENTICATOR_DETAILS } ) From 99a97aa0fdf203bb8c5a65afedca10efcd7b5846 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Sep 2025 01:32:03 +0000 Subject: [PATCH 2/8] build(deps): bump actions/setup-go from 5 to 6 Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index cbf10cb..cb3fbf1 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v5 - name: Set up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: '1.24' check-latest: true From 702a4c0ffc860e9d69f205e7e8c8103f3deece36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 01:37:53 +0000 Subject: [PATCH 3/8] build(deps): bump golang.org/x/sys from 0.35.0 to 0.38.0 Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.35.0 to 0.38.0. - [Commits](https://github.com/golang/sys/compare/v0.35.0...v0.38.0) --- updated-dependencies: - dependency-name: golang.org/x/sys dependency-version: 0.38.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 84fe92d..a3ef595 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/goforj/godump v1.6.0 github.com/ldclabs/cose v1.3.2 github.com/stretchr/testify v1.11.1 - golang.org/x/sys v0.35.0 + golang.org/x/sys v0.38.0 ) require ( diff --git a/go.sum b/go.sum index b05428a..3c00305 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,8 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= From 81183e347dbbc503298a036da106bd22b2fc406f Mon Sep 17 00:00:00 2001 From: Atanas Janeshliev Date: Thu, 18 Sep 2025 16:21:55 +0200 Subject: [PATCH 4/8] chore: minor tweaks --- versions.go | 7 +- webauthn.h | 989 ++++++++++++++++++++++++++++++++++++--------- winhello.go | 64 ++- ztypes_webauthn.go | 460 ++++++++++----------- 4 files changed, 1038 insertions(+), 482 deletions(-) diff --git a/versions.go b/versions.go index 4d04c97..7b3cf3b 100644 --- a/versions.go +++ b/versions.go @@ -14,7 +14,6 @@ type currentVersion struct { commonAttestation uint32 credentialAttestation uint32 assertion uint32 - authenticatorDetails uint32 } func availableVersions(ver uint32) *currentVersion { @@ -25,6 +24,7 @@ func availableVersions(ver uint32) *currentVersion { coseCredentialParameter: 1, credential: 1, credentialEx: 1, + getCredentialsOptions: 1, commonAttestation: 1, authenticatorMakeCredentialOptions: 3, @@ -45,7 +45,6 @@ func availableVersions(ver uint32) *currentVersion { v.authenticatorMakeCredentialOptions++ v.authenticatorGetAssertionOptions++ v.assertion++ - v.getCredentialsOptions++ v.credentialDetails++ }, // 4 func(v *currentVersion) { @@ -70,11 +69,9 @@ func availableVersions(ver uint32) *currentVersion { }, // 8 func(v *currentVersion) { v.authenticatorMakeCredentialOptions++ - v.authenticatorGetAssertionOptions++ - v.assertion++ v.credentialDetails++ v.credentialAttestation++ - v.authenticatorDetails++ + v.authenticatorGetAssertionOptions++ }, } diff --git a/webauthn.h b/webauthn.h index 6b4a94e..a5ff363 100644 --- a/webauthn.h +++ b/webauthn.h @@ -1,8 +1,29 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. +/* + +MIT License + +Copyright (c) Microsoft Corporation. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE + +*/ -#ifndef __WEBAUTHN_H_ -#define __WEBAUTHN_H_ #pragma once @@ -95,7 +116,6 @@ extern "C" { // - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 5 // - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 6 // - WEBAUTHN_ASSERTION : 3 -// - WEBAUTHN_GET_CREDENTIALS_OPTIONS : 1 // - WEBAUTHN_CREDENTIAL_DETAILS : 1 // APIs: // - WebAuthNGetPlatformCredentialList @@ -137,21 +157,7 @@ extern "C" { // - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 8 // -#define WEBAUTHN_API_VERSION_9 9 -// WEBAUTHN_API_VERSION_9 : Delta From WEBAUTHN_API_VERSION_8 -// Data Structures and their sub versions: -// - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 9 -// - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 9 -// - WEBAUTHN_ASSERTION : 6 -// - WEBAUTHN_CREDENTIAL_DETAILS : 4 -// - WEBAUTHN_CREDENTIAL_ATTESTATION : 8 -// - WEBAUTHN_AUTHENTICATOR_DETAILS : 1 -// - WEBAUTHN_AUTHENTICATOR_DETAILS_LIST : Not Applicable -// APIs: -// - WebAuthNGetAuthenticatorList -// - WebAuthNFreeAuthenticatorList - -#define WEBAUTHN_API_CURRENT_VERSION WEBAUTHN_API_VERSION_9 +#define WEBAUTHN_API_CURRENT_VERSION WEBAUTHN_API_VERSION_8 //+------------------------------------------------------------------------------------------ // Information about an RP Entity @@ -159,6 +165,12 @@ extern "C" { #define WEBAUTHN_RP_ENTITY_INFORMATION_CURRENT_VERSION 1 +#ifdef __midl +typedef [string] wchar_t* PWSTR; +typedef [string] wchar_t* const PCWSTR; +typedef unsigned char* PBYTE; +#endif + typedef struct _WEBAUTHN_RP_ENTITY_INFORMATION { // Version of this structure, to allow for modifications in the future. // This field is required and should be set to CURRENT_VERSION above. @@ -190,7 +202,12 @@ typedef struct _WEBAUTHN_USER_ENTITY_INFORMATION { // Identifier for the User. This field is required. DWORD cbId; + + #ifdef __midl + [size_is(cbId)] + #else _Field_size_bytes_(cbId) + #endif PBYTE pbId; // Contains a detailed name for this account, such as "john.p.smith@example.com". @@ -205,6 +222,8 @@ typedef struct _WEBAUTHN_USER_ENTITY_INFORMATION { } WEBAUTHN_USER_ENTITY_INFORMATION, *PWEBAUTHN_USER_ENTITY_INFORMATION; typedef const WEBAUTHN_USER_ENTITY_INFORMATION *PCWEBAUTHN_USER_ENTITY_INFORMATION; +#ifndef __midl + //+------------------------------------------------------------------------------------------ // Information about client data. //------------------------------------------------------------------------------------------- @@ -231,6 +250,8 @@ typedef struct _WEBAUTHN_CLIENT_DATA { } WEBAUTHN_CLIENT_DATA, *PWEBAUTHN_CLIENT_DATA; typedef const WEBAUTHN_CLIENT_DATA *PCWEBAUTHN_CLIENT_DATA; +#endif //__midl + //+------------------------------------------------------------------------------------------ // Information about credential parameters. //------------------------------------------------------------------------------------------- @@ -256,7 +277,11 @@ typedef struct _WEBAUTHN_COSE_CREDENTIAL_PARAMETER { DWORD dwVersion; // Well-known credential type specifying a credential to create. + #ifdef __midl + PCWSTR pwszCredentialType; + #else LPCWSTR pwszCredentialType; + #endif // Well-known COSE algorithm specifying the algorithm to use for the credential. LONG lAlg; @@ -265,7 +290,11 @@ typedef const WEBAUTHN_COSE_CREDENTIAL_PARAMETER *PCWEBAUTHN_COSE_CREDENTIAL_PAR typedef struct _WEBAUTHN_COSE_CREDENTIAL_PARAMETERS { DWORD cCredentialParameters; + #ifdef __midl + [size_is(cCredentialParameters)] + #else _Field_size_(cCredentialParameters) + #endif PWEBAUTHN_COSE_CREDENTIAL_PARAMETER pCredentialParameters; } WEBAUTHN_COSE_CREDENTIAL_PARAMETERS, *PWEBAUTHN_COSE_CREDENTIAL_PARAMETERS; typedef const WEBAUTHN_COSE_CREDENTIAL_PARAMETERS *PCWEBAUTHN_COSE_CREDENTIAL_PARAMETERS; @@ -279,20 +308,32 @@ typedef struct _WEBAUTHN_CREDENTIAL { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; - // Size of pbID. - DWORD cbId; // Unique ID for this particular credential. + DWORD cbId; + #ifdef __midl + [size_is(cbId)] + #else _Field_size_bytes_(cbId) PBYTE pbId; + #endif // Well-known credential type specifying what this particular credential is. - LPCWSTR pwszCredentialType; + #ifdef __midl + PWSTR pwszCredentialType; + #else + PCWSTR pwszCredentialType; + #endif + } WEBAUTHN_CREDENTIAL, *PWEBAUTHN_CREDENTIAL; typedef const WEBAUTHN_CREDENTIAL *PCWEBAUTHN_CREDENTIAL; typedef struct _WEBAUTHN_CREDENTIALS { DWORD cCredentials; + #ifdef __midl + [size_is(cCredentials)] + #else _Field_size_(cCredentials) + #endif PWEBAUTHN_CREDENTIAL pCredentials; } WEBAUTHN_CREDENTIALS, *PWEBAUTHN_CREDENTIALS; typedef const WEBAUTHN_CREDENTIALS *PCWEBAUTHN_CREDENTIALS; @@ -307,15 +348,7 @@ typedef const WEBAUTHN_CREDENTIALS *PCWEBAUTHN_CREDENTIALS; #define WEBAUTHN_CTAP_TRANSPORT_TEST 0x00000008 #define WEBAUTHN_CTAP_TRANSPORT_INTERNAL 0x00000010 #define WEBAUTHN_CTAP_TRANSPORT_HYBRID 0x00000020 -#define WEBAUTHN_CTAP_TRANSPORT_SMART_CARD 0x00000040 -#define WEBAUTHN_CTAP_TRANSPORT_FLAGS_MASK 0x0000007F - -#define WEBAUTHN_CTAP_TRANSPORT_USB_STRING "usb" -#define WEBAUTHN_CTAP_TRANSPORT_NFC_STRING "nfc" -#define WEBAUTHN_CTAP_TRANSPORT_BLE_STRING "ble" -#define WEBAUTHN_CTAP_TRANSPORT_SMART_CARD_STRING "smart-card" -#define WEBAUTHN_CTAP_TRANSPORT_HYBRID_STRING "hybrid" -#define WEBAUTHN_CTAP_TRANSPORT_INTERNAL_STRING "internal" +#define WEBAUTHN_CTAP_TRANSPORT_FLAGS_MASK 0x0000003F #define WEBAUTHN_CREDENTIAL_EX_CURRENT_VERSION 1 @@ -325,12 +358,19 @@ typedef struct _WEBAUTHN_CREDENTIAL_EX { // Size of pbID. DWORD cbId; - // Unique ID for this particular credential. + #ifdef __midl + [size_is(cbId)] + #else _Field_size_bytes_(cbId) + #endif PBYTE pbId; // Well-known credential type specifying what this particular credential is. + #ifdef __midl + PCWSTR pwszCredentialType; + #else LPCWSTR pwszCredentialType; + #endif // Transports. 0 implies no transport restrictions. DWORD dwTransports; @@ -343,16 +383,24 @@ typedef const WEBAUTHN_CREDENTIAL_EX *PCWEBAUTHN_CREDENTIAL_EX; typedef struct _WEBAUTHN_CREDENTIAL_LIST { DWORD cCredentials; + #ifdef __midl + [size_is(cCredentials)] + #else _Field_size_(cCredentials) + #endif PWEBAUTHN_CREDENTIAL_EX *ppCredentials; } WEBAUTHN_CREDENTIAL_LIST, *PWEBAUTHN_CREDENTIAL_LIST; typedef const WEBAUTHN_CREDENTIAL_LIST *PCWEBAUTHN_CREDENTIAL_LIST; +#ifndef __midl + //+------------------------------------------------------------------------------------------ // Information about linked devices //------------------------------------------------------------------------------------------- +// Deprecated #define CTAPCBOR_HYBRID_STORAGE_LINKED_DATA_VERSION_1 1 +// Deprecated #define CTAPCBOR_HYBRID_STORAGE_LINKED_DATA_CURRENT_VERSION CTAPCBOR_HYBRID_STORAGE_LINKED_DATA_VERSION_1 // Deprecated @@ -389,56 +437,7 @@ typedef struct _CTAPCBOR_HYBRID_STORAGE_LINKED_DATA } CTAPCBOR_HYBRID_STORAGE_LINKED_DATA, *PCTAPCBOR_HYBRID_STORAGE_LINKED_DATA; typedef const CTAPCBOR_HYBRID_STORAGE_LINKED_DATA *PCCTAPCBOR_HYBRID_STORAGE_LINKED_DATA; -//+------------------------------------------------------------------------------------------ -// Authenticator Information for WebAuthNGetAuthenticatorList API -//------------------------------------------------------------------------------------------- - -#define WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS_VERSION_1 1 -#define WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS_VERSION_1 - -typedef struct _WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS { - // Version of this structure, to allow for modifications in the future. - DWORD dwVersion; - -} WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS, *PWEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS; -typedef const WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS *PCWEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS; - -#define WEBAUTHN_AUTHENTICATOR_DETAILS_VERSION_1 1 -#define WEBAUTHN_AUTHENTICATOR_DETAILS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_DETAILS_VERSION_1 - -typedef struct _WEBAUTHN_AUTHENTICATOR_DETAILS { - // Version of this structure, to allow for modifications in the future. - DWORD dwVersion; - - // Authenticator ID - DWORD cbAuthenticatorId; - _Field_size_bytes_(cbAuthenticatorId) - PBYTE pbAuthenticatorId; - - // Authenticator Name - PCWSTR pwszAuthenticatorName; - - // Authenticator logo (expected to be in SVG format) - DWORD cbAuthenticatorLogo; - _Field_size_bytes_(cbAuthenticatorLogo) - PBYTE pbAuthenticatorLogo; - - // Is the authenticator currently locked? When locked, this authenticator's credentials - // might not be present or updated in WebAuthNGetPlatformCredentialList. - BOOL bLocked; - -} WEBAUTHN_AUTHENTICATOR_DETAILS, *PWEBAUTHN_AUTHENTICATOR_DETAILS; -typedef const WEBAUTHN_AUTHENTICATOR_DETAILS *PCWEBAUTHN_AUTHENTICATOR_DETAILS; - -typedef struct _WEBAUTHN_AUTHENTICATOR_DETAILS_LIST { - // Authenticator Details - DWORD cAuthenticatorDetails; - _Field_size_(cAuthenticatorDetails) - PWEBAUTHN_AUTHENTICATOR_DETAILS *ppAuthenticatorDetails; - -} WEBAUTHN_AUTHENTICATOR_DETAILS_LIST, *PWEBAUTHN_AUTHENTICATOR_DETAILS_LIST; -typedef const WEBAUTHN_AUTHENTICATOR_DETAILS_LIST *PCWEBAUTHN_AUTHENTICATOR_DETAILS_LIST; - +#endif //__midl //+------------------------------------------------------------------------------------------ // Credential Information for WebAuthNGetPlatformCredentialList API //------------------------------------------------------------------------------------------- @@ -446,8 +445,7 @@ typedef const WEBAUTHN_AUTHENTICATOR_DETAILS_LIST *PCWEBAUTHN_AUTHENTICATOR_DETA #define WEBAUTHN_CREDENTIAL_DETAILS_VERSION_1 1 #define WEBAUTHN_CREDENTIAL_DETAILS_VERSION_2 2 #define WEBAUTHN_CREDENTIAL_DETAILS_VERSION_3 3 -#define WEBAUTHN_CREDENTIAL_DETAILS_VERSION_4 4 -#define WEBAUTHN_CREDENTIAL_DETAILS_CURRENT_VERSION WEBAUTHN_CREDENTIAL_DETAILS_VERSION_4 +#define WEBAUTHN_CREDENTIAL_DETAILS_CURRENT_VERSION WEBAUTHN_CREDENTIAL_DETAILS_VERSION_3 typedef struct _WEBAUTHN_CREDENTIAL_DETAILS { // Version of this structure, to allow for modifications in the future. @@ -455,13 +453,24 @@ typedef struct _WEBAUTHN_CREDENTIAL_DETAILS { // Size of pbCredentialID. DWORD cbCredentialID; + + #ifdef __midl + [size_is(cbCredentialID)] + #else _Field_size_bytes_(cbCredentialID) + #endif PBYTE pbCredentialID; // RP Info + #ifdef __midl + [unique] + #endif PWEBAUTHN_RP_ENTITY_INFORMATION pRpInformation; // User Info + #ifdef __midl + [unique] + #endif PWEBAUTHN_USER_ENTITY_INFORMATION pUserInformation; // Removable or not. @@ -481,25 +490,27 @@ typedef struct _WEBAUTHN_CREDENTIAL_DETAILS { // The logo is expected to be in the svg format DWORD cbAuthenticatorLogo; + + #ifdef __midl + [size_is(cbAuthenticatorLogo)] + #else _Field_size_bytes_(cbAuthenticatorLogo) + #endif PBYTE pbAuthenticatorLogo; // ThirdPartyPayment Credential or not. BOOL bThirdPartyPayment; - // - // The following fields have been added in WEBAUTHN_CREDENTIAL_DETAILS_VERSION_4 - // - - // Applicable Transports - DWORD dwTransports; - } WEBAUTHN_CREDENTIAL_DETAILS, *PWEBAUTHN_CREDENTIAL_DETAILS; typedef const WEBAUTHN_CREDENTIAL_DETAILS *PCWEBAUTHN_CREDENTIAL_DETAILS; typedef struct _WEBAUTHN_CREDENTIAL_DETAILS_LIST { DWORD cCredentialDetails; + #ifdef __midl + [size_is(cCredentialDetails)] + #else _Field_size_(cCredentialDetails) + #endif PWEBAUTHN_CREDENTIAL_DETAILS *ppCredentialDetails; } WEBAUTHN_CREDENTIAL_DETAILS_LIST, *PWEBAUTHN_CREDENTIAL_DETAILS_LIST; typedef const WEBAUTHN_CREDENTIAL_DETAILS_LIST *PCWEBAUTHN_CREDENTIAL_DETAILS_LIST; @@ -528,23 +539,33 @@ typedef const WEBAUTHN_GET_CREDENTIALS_OPTIONS *PCWEBAUTHN_GET_CREDENTIALS_OPTIO // SALT values below by default are converted into RAW Hmac-Secret values as per PRF extension. // - SHA-256(UTF8Encode("WebAuthn PRF") || 0x00 || Value) // -// Set WEBAUTHN_AUTHENTICATOR_HMAC_SECRET_VALUES_FLAG in dwFlags in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS, +// Set WEBAUTHN_CTAP_HMAC_SECRET_VALUES_FLAG in dwFlags in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS, // if caller wants to provide RAW Hmac-Secret SALT values directly. In that case, // values if provided MUST be of WEBAUTHN_CTAP_ONE_HMAC_SECRET_LENGTH size. typedef struct _WEBAUTHN_HMAC_SECRET_SALT { // Size of pbFirst. DWORD cbFirst; + #ifdef __midl + [size_is(cbFirst)] + #else _Field_size_bytes_(cbFirst) + #endif PBYTE pbFirst; // Required // Size of pbSecond. DWORD cbSecond; + #ifdef __midl + [size_is(cbSecond)] + #else _Field_size_bytes_(cbSecond) + #endif PBYTE pbSecond; } WEBAUTHN_HMAC_SECRET_SALT, *PWEBAUTHN_HMAC_SECRET_SALT; typedef const WEBAUTHN_HMAC_SECRET_SALT *PCWEBAUTHN_HMAC_SECRET_SALT; +#ifndef __midl + typedef struct _WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT { // Size of pbCredID. DWORD cbCredID; @@ -655,23 +676,41 @@ typedef const WEBAUTHN_CRED_BLOB_EXTENSION *PCWEBAUTHN_CRED_BLOB_EXTENSION; // GetAssertion Input Type: Not Supported // GetAssertion Output Type: Not Supported +#endif //__midl + //+------------------------------------------------------------------------------------------ // Information about Extensions. //------------------------------------------------------------------------------------------- typedef struct _WEBAUTHN_EXTENSION { + #ifdef __midl + PWSTR pwszExtensionIdentifier; + #else LPCWSTR pwszExtensionIdentifier; + #endif + DWORD cbExtension; + #ifdef __midl + [size_is(cbExtension)] + PBYTE pvExtension; + #else PVOID pvExtension; + #endif } WEBAUTHN_EXTENSION, *PWEBAUTHN_EXTENSION; typedef const WEBAUTHN_EXTENSION *PCWEBAUTHN_EXTENSION; typedef struct _WEBAUTHN_EXTENSIONS { DWORD cExtensions; + #ifdef __midl + [size_is(cExtensions)] + #else _Field_size_(cExtensions) + #endif PWEBAUTHN_EXTENSION pExtensions; } WEBAUTHN_EXTENSIONS, *PWEBAUTHN_EXTENSIONS; typedef const WEBAUTHN_EXTENSIONS *PCWEBAUTHN_EXTENSIONS; +#ifndef __midl + //+------------------------------------------------------------------------------------------ // Options. //------------------------------------------------------------------------------------------- @@ -711,8 +750,7 @@ typedef const WEBAUTHN_EXTENSIONS *PCWEBAUTHN_EXTENSIONS; #define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_6 6 #define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_7 7 #define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_8 8 -#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_9 9 -#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_9 +#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_8 typedef struct _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS { // Version of this structure, to allow for modifications in the future. @@ -806,35 +844,24 @@ typedef struct _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS { // // PRF extension "eval" values which will be converted into HMAC-SECRET values according to WebAuthn Spec. - // Set WEBAUTHN_AUTHENTICATOR_HMAC_SECRET_VALUES_FLAG in dwFlags above, if caller wants to provide RAW Hmac-Secret SALT values directly. + // Set WEBAUTHN_CTAP_HMAC_SECRET_VALUES_FLAG in dwFlags above, if caller wants to provide RAW Hmac-Secret SALT values directly. // In that case, values provided MUST be of WEBAUTHN_CTAP_ONE_HMAC_SECRET_LENGTH size. PWEBAUTHN_HMAC_SECRET_SALT pPRFGlobalEval; // PublicKeyCredentialHints (https://w3c.github.io/webauthn/#enum-hints) DWORD cCredentialHints; + + #ifdef __midl + [size_is(cCredentialHints)] + PCWSTR *ppwszCredentialHints; + #else _Field_size_(cCredentialHints) LPCWSTR *ppwszCredentialHints; + #endif // Enable ThirdPartyPayment BOOL bThirdPartyPayment; - // - // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_9 - // - - // Web Origin. For Remote Web App scenario. - PCWSTR pwszRemoteWebOrigin; - - // UTF-8 encoded JSON serialization of the PublicKeyCredentialCreationOptions. - DWORD cbPublicKeyCredentialCreationOptionsJSON; - _Field_size_bytes_(cbPublicKeyCredentialCreationOptionsJSON) - PBYTE pbPublicKeyCredentialCreationOptionsJSON; - - // Authenticator ID got from WebAuthNGetAuthenticatorList API. - DWORD cbAuthenticatorId; - _Field_size_bytes_(cbAuthenticatorId) - PBYTE pbAuthenticatorId; - } WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS, *PWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS; typedef const WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS; @@ -851,8 +878,7 @@ typedef const WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *PCWEBAUTHN_AUTHENT #define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_6 6 #define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_7 7 #define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_8 8 -#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_9 9 -#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_9 +#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_8 /* Information about flags. @@ -951,25 +977,14 @@ typedef struct _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS { // PublicKeyCredentialHints (https://w3c.github.io/webauthn/#enum-hints) DWORD cCredentialHints; + + #ifdef __midl + [size_is(cCredentialHints)] + PCWSTR *ppwszCredentialHints; + #else _Field_size_(cCredentialHints) LPCWSTR *ppwszCredentialHints; - - // - // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_9 - // - - // Web Origin. For Remote Web App scenario. - PCWSTR pwszRemoteWebOrigin; - - // UTF-8 encoded JSON serialization of the PublicKeyCredentialRequestOptions. - DWORD cbPublicKeyCredentialRequestOptionsJSON; - _Field_size_bytes_(cbPublicKeyCredentialRequestOptionsJSON) - PBYTE pbPublicKeyCredentialRequestOptionsJSON; - - // Authenticator ID got from WebAuthNGetAuthenticatorList API. - DWORD cbAuthenticatorId; - _Field_size_bytes_(cbAuthenticatorId) - PBYTE pbAuthenticatorId; + #endif } WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS, *PWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS; typedef const WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS; @@ -1038,6 +1053,8 @@ typedef struct _WEBAUTHN_COMMON_ATTESTATION { } WEBAUTHN_COMMON_ATTESTATION, *PWEBAUTHN_COMMON_ATTESTATION; typedef const WEBAUTHN_COMMON_ATTESTATION *PCWEBAUTHN_COMMON_ATTESTATION; +#endif //__midl + #define WEBAUTHN_ATTESTATION_TYPE_PACKED L"packed" #define WEBAUTHN_ATTESTATION_TYPE_U2F L"fido-u2f" #define WEBAUTHN_ATTESTATION_TYPE_TPM L"tpm" @@ -1050,27 +1067,38 @@ typedef const WEBAUTHN_COMMON_ATTESTATION *PCWEBAUTHN_COMMON_ATTESTATION; #define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_5 5 #define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_6 6 #define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_7 7 -#define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_8 8 -#define WEBAUTHN_CREDENTIAL_ATTESTATION_CURRENT_VERSION WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_8 +#define WEBAUTHN_CREDENTIAL_ATTESTATION_CURRENT_VERSION WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_7 typedef struct _WEBAUTHN_CREDENTIAL_ATTESTATION { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; // Attestation format type + #ifdef __midl + PWSTR pwszFormatType; + #else PCWSTR pwszFormatType; + #endif // Size of cbAuthenticatorData. DWORD cbAuthenticatorData; // Authenticator data that was created for this credential. + #ifdef __midl + [size_is(cbAuthenticatorData)] + #else _Field_size_bytes_(cbAuthenticatorData) + #endif PBYTE pbAuthenticatorData; // Size of CBOR encoded attestation information //0 => encoded as CBOR null value. DWORD cbAttestation; //Encoded CBOR attestation information + #ifdef __midl + [size_is(cbAttestation)] + #else _Field_size_bytes_(cbAttestation) + #endif PBYTE pbAttestation; DWORD dwAttestationDecodeType; @@ -1079,17 +1107,29 @@ typedef struct _WEBAUTHN_CREDENTIAL_ATTESTATION { // NULL - not able to decode the CBOR attestation information // WEBAUTHN_ATTESTATION_DECODE_COMMON // PWEBAUTHN_COMMON_ATTESTATION; + #ifdef __midl + PBYTE pvAttestationDecode; + #else PVOID pvAttestationDecode; + #endif // The CBOR encoded Attestation Object to be returned to the RP. DWORD cbAttestationObject; + #ifdef __midl + [size_is(cbAttestationObject)] + #else _Field_size_bytes_(cbAttestationObject) + #endif PBYTE pbAttestationObject; // The CredentialId bytes extracted from the Authenticator Data. // Used by Edge to return to the RP. DWORD cbCredentialId; + #ifdef __midl + [size_is(cbCredentialId)] + #else _Field_size_bytes_(cbCredentialId) + #endif PBYTE pbCredentialId; // @@ -1125,7 +1165,11 @@ typedef struct _WEBAUTHN_CREDENTIAL_ATTESTATION { // DWORD cbUnsignedExtensionOutputs; + #ifdef __midl + [size_is(cbUnsignedExtensionOutputs)] + #else _Field_size_bytes_(cbUnsignedExtensionOutputs) + #endif PBYTE pbUnsignedExtensionOutputs; // @@ -1137,29 +1181,9 @@ typedef struct _WEBAUTHN_CREDENTIAL_ATTESTATION { // ThirdPartyPayment Credential or not. BOOL bThirdPartyPayment; - // - // Following fields have been added in WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_8 - // - - // Multiple WEBAUTHN_CTAP_TRANSPORT_* bits will be set corresponding to - // the transports that are supported. - DWORD dwTransports; - - // UTF-8 encoded JSON serialization of the client data. - DWORD cbClientDataJSON; - _Field_size_bytes_(cbClientDataJSON) - PBYTE pbClientDataJSON; - - // UTF-8 encoded JSON serialization of the RegistrationResponse. - DWORD cbRegistrationResponseJSON; - _Field_size_bytes_(cbRegistrationResponseJSON) - PBYTE pbRegistrationResponseJSON; - } WEBAUTHN_CREDENTIAL_ATTESTATION, *PWEBAUTHN_CREDENTIAL_ATTESTATION; typedef const WEBAUTHN_CREDENTIAL_ATTESTATION *PCWEBAUTHN_CREDENTIAL_ATTESTATION; - - //+------------------------------------------------------------------------------------------ // authenticatorGetAssertion output. //------------------------------------------------------------------------------------------- @@ -1180,32 +1204,40 @@ typedef const WEBAUTHN_CREDENTIAL_ATTESTATION *PCWEBAUTHN_CREDENTIAL_ATTESTATION #define WEBAUTHN_ASSERTION_VERSION_3 3 #define WEBAUTHN_ASSERTION_VERSION_4 4 #define WEBAUTHN_ASSERTION_VERSION_5 5 -#define WEBAUTHN_ASSERTION_VERSION_6 6 -#define WEBAUTHN_ASSERTION_CURRENT_VERSION WEBAUTHN_ASSERTION_VERSION_6 +#define WEBAUTHN_ASSERTION_CURRENT_VERSION WEBAUTHN_ASSERTION_VERSION_5 typedef struct _WEBAUTHN_ASSERTION { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; - // Size of cbAuthenticatorData. - DWORD cbAuthenticatorData; // Authenticator data that was created for this assertion. + DWORD cbAuthenticatorData; + #ifdef __midl + [size_is(cbAuthenticatorData)] + #else _Field_size_bytes_(cbAuthenticatorData) + #endif PBYTE pbAuthenticatorData; - // Size of pbSignature. - DWORD cbSignature; // Signature that was generated for this assertion. + DWORD cbSignature; + #ifdef __midl + [size_is(cbSignature)] + #else _Field_size_bytes_(cbSignature) + #endif PBYTE pbSignature; // Credential that was used for this assertion. WEBAUTHN_CREDENTIAL Credential; - // Size of User Id - DWORD cbUserId; // UserId + DWORD cbUserId; + #ifdef __midl + [size_is(cbUserId)] + #else _Field_size_bytes_(cbUserId) + #endif PBYTE pbUserId; // @@ -1216,7 +1248,11 @@ typedef struct _WEBAUTHN_ASSERTION { // Size of pbCredLargeBlob DWORD cbCredLargeBlob; + #ifdef __midl + [size_is(cbCredLargeBlob)] + #else _Field_size_bytes_(cbCredLargeBlob) + #endif PBYTE pbCredLargeBlob; DWORD dwCredLargeBlobStatus; @@ -1225,6 +1261,9 @@ typedef struct _WEBAUTHN_ASSERTION { // Following fields have been added in WEBAUTHN_ASSERTION_VERSION_3 // + #ifdef __midl + [unique] + #endif PWEBAUTHN_HMAC_SECRET_SALT pHmacSecret; // @@ -1240,26 +1279,18 @@ typedef struct _WEBAUTHN_ASSERTION { // DWORD cbUnsignedExtensionOutputs; + #ifdef __midl + [size_is(cbUnsignedExtensionOutputs)] + #else _Field_size_bytes_(cbUnsignedExtensionOutputs) + #endif PBYTE pbUnsignedExtensionOutputs; - // - // Following fields have been added in WEBAUTHN_ASSERTION_VERSION_6 - // - - // UTF-8 encoded JSON serialization of the client data. - DWORD cbClientDataJSON; - _Field_size_bytes_(cbClientDataJSON) - PBYTE pbClientDataJSON; - - // UTF-8 encoded JSON serialization of the AuthenticationResponse. - DWORD cbAuthenticationResponseJSON; - _Field_size_bytes_(cbAuthenticationResponseJSON) - PBYTE pbAuthenticationResponseJSON; - } WEBAUTHN_ASSERTION, *PWEBAUTHN_ASSERTION; typedef const WEBAUTHN_ASSERTION *PCWEBAUTHN_ASSERTION; +#ifndef __midl + //+------------------------------------------------------------------------------------------ // APIs. //------------------------------------------------------------------------------------------- @@ -1273,6 +1304,10 @@ WINAPI WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable( _Out_ BOOL *pbIsUserVerifyingPlatformAuthenticatorAvailable); +HRESULT +WINAPI +EXPERIMENTAL_WebAuthNIsUserVerifyingNativePlatformAuthenticatorAvailable( + _Out_ BOOL *pbIsUserVerifyingNativePlatformAuthenticatorAvailable); HRESULT WINAPI @@ -1285,8 +1320,6 @@ WebAuthNAuthenticatorMakeCredential( _In_opt_ PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS pWebAuthNMakeCredentialOptions, _Outptr_result_maybenull_ PWEBAUTHN_CREDENTIAL_ATTESTATION *ppWebAuthNCredentialAttestation); - - HRESULT WINAPI WebAuthNAuthenticatorGetAssertion( @@ -1335,18 +1368,6 @@ WebAuthNDeletePlatformCredential( _In_reads_bytes_(cbCredentialId) const BYTE *pbCredentialId ); -// Returns NTE_NOT_FOUND when authenticator details are not found. -HRESULT -WINAPI -WebAuthNGetAuthenticatorList( - _In_opt_ PCWEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS pWebAuthNGetAuthenticatorListOptions, - _Outptr_result_maybenull_ PWEBAUTHN_AUTHENTICATOR_DETAILS_LIST* ppAuthenticatorDetailsList); - -void -WINAPI -WebAuthNFreeAuthenticatorList( - _In_ PWEBAUTHN_AUTHENTICATOR_DETAILS_LIST pAuthenticatorDetailsList); - // // Returns the following Error Names: // L"Success" - S_OK @@ -1372,6 +1393,592 @@ WINAPI WebAuthNGetW3CExceptionDOMError( _In_ HRESULT hr); +typedef enum _EXPERIMENTAL_PLUGIN_AUTHENTICATOR_STATE +{ + PluginAuthenticatorState_Unknown = 0, + PluginAuthenticatorState_Disabled, + PluginAuthenticatorState_Enabled +} EXPERIMENTAL_PLUGIN_AUTHENTICATOR_STATE; + +// +// Plugin Authenticator API: WebAuthNPluginGetAuthenticatorState: Get Plugin Authenticator State +// +HRESULT +WINAPI +EXPERIMENTAL_WebAuthNPluginGetAuthenticatorState( + _In_ LPCWSTR pwszPluginClsId, + _Out_ EXPERIMENTAL_PLUGIN_AUTHENTICATOR_STATE* pluginAuthenticatorState +); + +// +// Plugin Authenticator API: WebAuthNAddPluginAuthenticator: Add Plugin Authenticator +// + +typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS { + // Authenticator Name + LPCWSTR pwszAuthenticatorName; + + // Plugin COM ClsId + LPCWSTR pwszPluginClsId; + + // Plugin RPID (Optional. Required for a nested WebAuthN call originating from a plugin) + LPCWSTR pwszPluginRpId; + + // Plugin Authenticator Logo for the Light themes. base64 svg (Optional) + LPCWSTR pwszLightThemeLogo; + + // Plugin Authenticator Logo for the Dark themes. base64 svg (Optional) + LPCWSTR pwszDarkThemeLogo; + + // CTAP CBOR encoded authenticatorGetInfo + DWORD cbAuthenticatorInfo; + _Field_size_bytes_(cbAuthenticatorInfo) + PBYTE pbAuthenticatorInfo; + +} EXPERIMENTAL_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS, *EXPERIMENTAL_PWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS; +typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS; + +typedef struct _EXPERIMENTAL2_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS { + // Authenticator Name + LPCWSTR pwszAuthenticatorName; + + // Plugin COM ClsId + LPCWSTR pwszPluginClsId; + + // Plugin RPID (Optional. Required for a nested WebAuthN call originating from a plugin) + LPCWSTR pwszPluginRpId; + + // Plugin Authenticator Logo for the Light themes. base64 svg (Optional) + LPCWSTR pwszLightThemeLogo; + + // Plugin Authenticator Logo for the Dark themes. base64 svg (Optional) + LPCWSTR pwszDarkThemeLogo; + + // CTAP CBOR encoded authenticatorGetInfo + DWORD cbAuthenticatorInfo; + _Field_size_bytes_(cbAuthenticatorInfo) + PBYTE pbAuthenticatorInfo; + + // List of supported RPs. Should be 0/nullptr if all RPs are supported. + DWORD cSupportedRpIds; + LPCWSTR *ppwszSupportedRpIds; + +} EXPERIMENTAL2_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS, *EXPERIMENTAL2_PWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS; +typedef const EXPERIMENTAL2_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS *EXPERIMENTAL2_PCWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS; + +typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE { + // Plugin operation signing Public Key - Used to sign the request in the EXPERIMENTAL_PluginPerformOperation. Refer pluginauthenticator.h. + DWORD cbOpSignPubKey; + _Field_size_bytes_(cbOpSignPubKey) + PBYTE pbOpSignPubKey; + +} EXPERIMENTAL_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE, *EXPERIMENTAL_PWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE; +typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE; + +HRESULT +WINAPI +EXPERIMENTAL_WebAuthNPluginAddAuthenticator( + _In_ EXPERIMENTAL_PCWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS pPluginAddAuthenticatorOptions, + _Outptr_result_maybenull_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE *ppPluginAddAuthenticatorResponse); + +HRESULT +WINAPI +EXPERIMENTAL2_WebAuthNPluginAddAuthenticator( + _In_ EXPERIMENTAL2_PCWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS pPluginAddAuthenticatorOptions, + _Outptr_result_maybenull_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE *ppPluginAddAuthenticatorResponse); + +void +WINAPI +EXPERIMENTAL_WebAuthNPluginFreeAddAuthenticatorResponse( + _In_opt_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE pPluginAddAuthenticatorResponse); + +// +// Plugin Authenticator API: WebAuthNRemovePluginAuthenticator: Remove Plugin Authenticator +// + +HRESULT +WINAPI +EXPERIMENTAL_WebAuthNPluginRemoveAuthenticator( + _In_ LPCWSTR pwszPluginClsId); + +// +// Plugin Authenticator API: WebAuthNPluginAuthenticatorUpdateDetails: Update Credential Metadata for Browser AutoFill Scenarios +// + +typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS { + // Authenticator Name (Optional) + LPCWSTR pwszAuthenticatorName; + + // Plugin COM ClsId + LPCWSTR pwszPluginClsId; + + // Plugin COM New ClsId (Optional) + LPCWSTR pwszNewPluginClsId; + + // Plugin Authenticator Logo for the Light themes. base64 svg (Optional) + LPCWSTR pwszLightThemeLogo; + + // Plugin Authenticator Logo for the Dark themes. base64 svg (Optional) + LPCWSTR pwszDarkThemeLogo; + + // CTAP CBOR encoded authenticatorGetInfo (Optional) + DWORD cbAuthenticatorInfo; + _Field_size_bytes_(cbAuthenticatorInfo) + PBYTE pbAuthenticatorInfo; + +} EXPERIMENTAL_WEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS, *EXPERIMENTAL_PWEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS; +typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS; + +typedef struct _EXPERIMENTAL2_WEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS { + // Authenticator Name (Optional) + LPCWSTR pwszAuthenticatorName; + + // Plugin COM ClsId + LPCWSTR pwszPluginClsId; + + // Plugin COM New ClsId (Optional) + LPCWSTR pwszNewPluginClsId; + + // Plugin Authenticator Logo for the Light themes. base64 svg (Optional) + LPCWSTR pwszLightThemeLogo; + + // Plugin Authenticator Logo for the Dark themes. base64 svg (Optional) + LPCWSTR pwszDarkThemeLogo; + + // CTAP CBOR encoded authenticatorGetInfo (Optional) + DWORD cbAuthenticatorInfo; + _Field_size_bytes_(cbAuthenticatorInfo) + PBYTE pbAuthenticatorInfo; + + // List of supported RPs. Should be 0/nullptr if all RPs are supported. + DWORD cSupportedRpIds; + LPCWSTR *ppwszSupportedRpIds; + +} EXPERIMENTAL2_WEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS, *EXPERIMENTAL2_PWEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS; +typedef const EXPERIMENTAL2_WEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS *EXPERIMENTAL2_PCWEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS; + +HRESULT +WINAPI +EXPERIMENTAL_WebAuthNPluginUpdateAuthenticatorDetails( + _In_ EXPERIMENTAL_PCWEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS pPluginUpdateAuthenticatorDetails); + +HRESULT +WINAPI +EXPERIMENTAL2_WebAuthNPluginUpdateAuthenticatorDetails( + _In_ EXPERIMENTAL2_PCWEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS pPluginUpdateAuthenticatorDetails); + +#endif //__midl + +// +// Plugin Authenticator API: WebAuthNPluginAuthenticatorAddCredentials: Add Credential Metadata for Browser AutoFill Scenarios +// + + +typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS { + // Size of pbCredentialId. + DWORD cbCredentialId; + + // Credential Identifier bytes. This field is required. + #ifdef __midl + [size_is(cbCredentialId)] + #else + _Field_size_bytes_(cbCredentialId) + #endif + PBYTE pbCredentialId; + + // Identifier for the RP. This field is required. + PWSTR pwszRpId; + + // Contains the friendly name of the Relying Party, such as "Acme Corporation", "Widgets Inc" or "Awesome Site". + // This field is required. + PWSTR pwszRpName; + + // Identifier for the User. This field is required. + DWORD cbUserId; + + // User Identifier bytes. This field is required. + #ifdef __midl + [size_is(cbUserId)] + #else + _Field_size_bytes_(cbUserId) + #endif + PBYTE pbUserId; + + // Contains a detailed name for this account, such as "john.p.smith@example.com". + PWSTR pwszUserName; + + // For User: Contains the friendly name associated with the user account such as "John P. Smith". + PWSTR pwszUserDisplayName; + +} EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS, *EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS; +typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS; + +typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST { + // Plugin COM ClsId + PWSTR pwszPluginClsId; + + // count of credentials + DWORD cCredentialDetails; + + #ifdef __midl + [size_is(cCredentialDetails)] + #else + _Field_size_(cCredentialDetails) + #endif + EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS *pCredentialDetails; + +} EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST, *EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST; +typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST; + +#ifndef __midl + +HRESULT +WINAPI +EXPERIMENTAL_WebAuthNPluginAuthenticatorAddCredentials( + _In_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST pCredentialDetailsList); + +// +// Plugin Authenticator API: WebAuthNPluginAuthenticatorRemoveCredentials: Remove Credential Metadata for Browser AutoFill Scenarios +// + +HRESULT +WINAPI +EXPERIMENTAL_WebAuthNPluginAuthenticatorRemoveCredentials( + _In_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST pCredentialDetailsList); + +// +// Plugin Authenticator API: WebAuthNPluginAuthenticatorRemoveCredentials: Remove All Credential Metadata for Browser AutoFill Scenarios +// + +HRESULT +WINAPI +EXPERIMENTAL_WebAuthNPluginAuthenticatorRemoveAllCredentials( + _In_ LPCWSTR pwszPluginClsId); + +// +// Plugin Authenticator API: WebAuthNPluginAuthenticatorGetAllCredentials: Get All Credential Metadata cached for Browser AutoFill Scenarios +// +HRESULT +WINAPI +EXPERIMENTAL_WebAuthNPluginAuthenticatorGetAllCredentials( + _In_ LPCWSTR pwszPluginClsId, + _Outptr_result_maybenull_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST *ppCredentialDetailsList); + +// +// Hello UV API for Plugin: WebAuthNPluginPerformUv: Perform Hello UV related operations +// + +typedef enum _EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV_OPERATION_TYPE +{ + PerformUv = 1, + GetUvCount, + GetPubKey +} EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV_OPERATION_TYPE; + +typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV { + HWND hwnd; + GUID* transactionId; + EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV_OPERATION_TYPE type; + PCWSTR pwszUsername; + PCWSTR pwszContext; +} EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV, *EXPERIMENTAL_PWEBAUTHN_PLUGIN_PERFROM_UV; +typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_PERFORM_UV; + +typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV_RESPONSE { + DWORD cbResponse; + PBYTE pbResponse; +} EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV_RESPONSE, *EXPERIMENTAL_PWEBAUTHN_PLUGIN_PERFORM_UV_RESPONSE; +typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV_RESPONSE *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_PERFORM_UV_RESPONSE; + +HRESULT +WINAPI +EXPERIMENTAL_WebAuthNPluginPerformUv( + _In_ EXPERIMENTAL_PCWEBAUTHN_PLUGIN_PERFORM_UV pPluginPerformUv, + _Outptr_result_maybenull_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_PERFORM_UV_RESPONSE *ppPluginPerformUvRespose); + +void +WINAPI +EXPERIMENTAL_WebAuthNPluginFreePerformUvResponse( + _In_opt_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_PERFORM_UV_RESPONSE ppPluginPerformUvResponse); + +#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS_VERSION_1 1 +#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS_CURRENT_VERSION EXPERIMENTAL_WEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS_VERSION_1 +typedef struct _EXPERIMENTAL_WEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS { + //Version of this structure, to allow for modifications in the future. + DWORD dwVersion; + + // Following have following values: + // +1 - TRUE + // 0 - Not defined + // -1 - FALSE + //up: "true" | "false" + LONG lUp; + //uv: "true" | "false" + LONG lUv; + //rk: "true" | "false" + LONG lRequireResidentKey; +} EXPERIMENTAL_WEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS, *EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS; +typedef const EXPERIMENTAL_WEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS *EXPERIMENTAL_PCWEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS; + +#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY_VERSION_1 1 +#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY_CURRENT_VERSION EXPERIMENTAL_WEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY_VERSION_1 +typedef struct _EXPERIMENTAL_WEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY { + //Version of this structure, to allow for modifications in the future. + DWORD dwVersion; + + // Key type + LONG lKty; + + // Hash Algorithm: ES256, ES384, ES512 + LONG lAlg; + + // Curve + LONG lCrv; + + //Size of "x" (X Coordinate) + DWORD cbX; + + //"x" (X Coordinate) data. Big Endian. + PBYTE pbX; + + //Size of "y" (Y Coordinate) + DWORD cbY; + + //"y" (Y Coordinate) data. Big Endian. + PBYTE pbY; +} EXPERIMENTAL_WEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY, *EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY; +typedef const EXPERIMENTAL_WEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY *EXPERIMENTAL_PCWEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY; + +#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION_VERSION_1 1 +#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION_CURRENT_VERSION EXPERIMENTAL_WEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION_VERSION_1 +typedef struct _EXPERIMENTAL_WEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION { + //Version of this structure, to allow for modifications in the future. + DWORD dwVersion; + + // Platform's key agreement public key + EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY pKeyAgreement; + + DWORD cbEncryptedSalt; + PBYTE pbEncryptedSalt; + + DWORD cbSaltAuth; + PBYTE pbSaltAuth; +} EXPERIMENTAL_WEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION, *EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION; +typedef const EXPERIMENTAL_WEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION *EXPERIMENTAL_PCWEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION; + +#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST_VERSION_1 1 +#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST_CURRENT_VERSION EXPERIMENTAL_WEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST_VERSION_1 +typedef struct _EXPERIMENTAL_WEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST { + //Version of this structure, to allow for modifications in the future. + DWORD dwVersion; + + //Input RP ID. Raw UTF8 bytes before conversion. + //These are the bytes to be hashed in the Authenticator Data. + DWORD cbRpId; + PBYTE pbRpId; + + //Client Data Hash + DWORD cbClientDataHash; + PBYTE pbClientDataHash; + + //RP Information + PCWEBAUTHN_RP_ENTITY_INFORMATION pRpInformation; + + //User Information + PCWEBAUTHN_USER_ENTITY_INFORMATION pUserInformation; + + // Crypto Parameters + WEBAUTHN_COSE_CREDENTIAL_PARAMETERS WebAuthNCredentialParameters; + + //Credentials used for exclusion + WEBAUTHN_CREDENTIAL_LIST CredentialList; + + //Optional extensions to parse when performing the operation. + DWORD cbCborExtensionsMap; + PBYTE pbCborExtensionsMap; + + // Authenticator Options (Optional) + EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS pAuthenticatorOptions; + + // Pin Auth (Optional) + BOOL fEmptyPinAuth; // Zero length PinAuth is included in the request + DWORD cbPinAuth; + PBYTE pbPinAuth; + + //"hmac-secret": true extension + LONG lHmacSecretExt; + + // "hmac-secret-mc" extension + EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION pHmacSecretMcExtension; + + //"prf" extension + LONG lPrfExt; + DWORD cbHmacSecretSaltValues; + PBYTE pbHmacSecretSaltValues; + + //"credProtect" extension. Nonzero if present + DWORD dwCredProtect; + + // Nonzero if present + DWORD dwPinProtocol; + + // Nonzero if present + DWORD dwEnterpriseAttestation; + + //"credBlob" extension. Nonzero if present + DWORD cbCredBlobExt; + PBYTE pbCredBlobExt; + + //"largeBlobKey": true extension + LONG lLargeBlobKeyExt; + + //"largeBlob": extension + DWORD dwLargeBlobSupport; + + //"minPinLength": true extension + LONG lMinPinLengthExt; + + // "json" extension. Nonzero if present + DWORD cbJsonExt; + PBYTE pbJsonExt; +} EXPERIMENTAL_WEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST, *EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST; +typedef const EXPERIMENTAL_WEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST *EXPERIMENTAL_PCWEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST; + +_Success_(return == S_OK) +HRESULT +WINAPI +EXPERIMENTAL_WebAuthNEncodeMakeCredentialResponse( + _In_ PCWEBAUTHN_CREDENTIAL_ATTESTATION pCredentialAttestation, + _Out_ DWORD *pcbResp, + _Outptr_result_buffer_maybenull_(*pcbResp) BYTE **ppbResp + ); + +_Success_(return == S_OK) +HRESULT +WINAPI +EXPERIMENTAL_WebAuthNDecodeMakeCredentialRequest( + _In_ DWORD cbEncoded, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _Outptr_ EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST *ppMakeCredentialRequest + ); + +void +WINAPI +EXPERIMENTAL_WebAuthNFreeDecodedMakeCredentialRequest( + _In_opt_ EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST pMakeCredentialRequest + ); + +#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST_VERSION_1 1 +#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST_CURRENT_VERSION EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST_VERSION_1 +typedef struct _EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST { + //Version of this structure, to allow for modifications in the future. + DWORD dwVersion; + + //RP ID. After UTF8 to Unicode conversion, + PCWSTR pwszRpId; + + //Input RP ID. Raw UTF8 bytes before conversion. + //These are the bytes to be hashed in the Authenticator Data. + DWORD cbRpId; + PBYTE pbRpId; + + //Client Data Hash + DWORD cbClientDataHash; + PBYTE pbClientDataHash; + + //Credentials used for inclusion + WEBAUTHN_CREDENTIAL_LIST CredentialList; + + //Optional extensions to parse when performing the operation. + DWORD cbCborExtensionsMap; + PBYTE pbCborExtensionsMap; + + // Authenticator Options (Optional) + EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS pAuthenticatorOptions; + + // Pin Auth (Optional) + BOOL fEmptyPinAuth; // Zero length PinAuth is included in the request + DWORD cbPinAuth; + PBYTE pbPinAuth; + + // HMAC Salt Extension (Optional) + EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION pHmacSaltExtension; + + // PRF Extension + DWORD cbHmacSecretSaltValues; + PBYTE pbHmacSecretSaltValues; + + DWORD dwPinProtocol; + + //"credBlob": true extension + LONG lCredBlobExt; + + //"largeBlobKey": true extension + LONG lLargeBlobKeyExt; + + //"largeBlob" extension + DWORD dwCredLargeBlobOperation; + DWORD cbCredLargeBlobCompressed; + PBYTE pbCredLargeBlobCompressed; + DWORD dwCredLargeBlobOriginalSize; + + // "json" extension. Nonzero if present + DWORD cbJsonExt; + PBYTE pbJsonExt; +} EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST, *EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST; +typedef const EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST *EXPERIMENTAL_PCWEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST; + +_Success_(return == S_OK) +HRESULT +WINAPI +EXPERIMENTAL_WebAuthNDecodeGetAssertionRequest( + _In_ DWORD cbEncoded, + _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, + _Outptr_ EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST *ppGetAssertionRequest + ); + +void +WINAPI +EXPERIMENTAL_WebAuthNFreeDecodedGetAssertionRequest( + _In_opt_ EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST pGetAssertionRequest + ); + +typedef struct _EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_RESPONSE { + // [1] credential (optional) + // [2] authenticatorData + // [3] signature + WEBAUTHN_ASSERTION WebAuthNAssertion; + + // [4] user (optional) + PCWEBAUTHN_USER_ENTITY_INFORMATION pUserInformation; + + // [5] numberOfCredentials (optional) + DWORD dwNumberOfCredentials; + + // [6] userSelected (optional) + LONG lUserSelected; + + // [7] largeBlobKey (optional) + DWORD cbLargeBlobKey; + PBYTE pbLargeBlobKey; + + // [8] unsignedExtensionOutputs + DWORD cbUnsignedExtensionOutputs; + PBYTE pbUnsignedExtensionOutputs; +} EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_RESPONSE, *EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_GET_ASSERTION_RESPONSE; +typedef const EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_GET_ASSERTION_RESPONSE *EXPERIMENTAL_PCWEBAUTHN_CTAPCBOR_GET_ASSERTION_RESPONSE; + +_Success_(return == S_OK) +HRESULT +WINAPI +EXPERIMENTAL_WebAuthNEncodeGetAssertionResponse( + _In_ EXPERIMENTAL_PCWEBAUTHN_CTAPCBOR_GET_ASSERTION_RESPONSE pGetAssertionResponse, + _Out_ DWORD *pcbResp, + _Outptr_result_buffer_maybenull_(*pcbResp) BYTE **ppbResp + ); + +#endif //__midl + #ifdef __cplusplus } // Balance extern "C" above @@ -1379,5 +1986,3 @@ WebAuthNGetW3CExceptionDOMError( #endif // WINAPI_FAMILY_PARTITION #pragma endregion - -#endif // __WEBAUTHN_H_ diff --git a/winhello.go b/winhello.go index 132ce4b..7f1ae0f 100644 --- a/winhello.go +++ b/winhello.go @@ -15,25 +15,21 @@ import ( ) var ( - modWebAuthn = windows.NewLazyDLL("webauthn.dll") - procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") - procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable = modWebAuthn.NewProc("WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable") - procWebAuthNAuthenticatorMakeCredential = modWebAuthn.NewProc("WebAuthNAuthenticatorMakeCredential") - procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") - procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") - procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") - procWebAuthNGetCancellationId = modWebAuthn.NewProc("WebAuthNGetCancellationId") - procWebAuthNCancelCurrentOperation = modWebAuthn.NewProc("WebAuthNCancelCurrentOperation") - procWebAuthNGetPlatformCredentialList = modWebAuthn.NewProc("WebAuthNGetPlatformCredentialList") - procWebAuthNFreePlatformCredentialList = modWebAuthn.NewProc("WebAuthNFreePlatformCredentialList") - procWebAuthNDeletePlatformCredential = modWebAuthn.NewProc("WebAuthNDeletePlatformCredential") - procWebAuthNGetAuthenticatorList = modWebAuthn.NewProc("WebAuthNGetAuthenticatorList") - procWebAuthNFreeAuthenticatorList = modWebAuthn.NewProc("WebAuthNFreeAuthenticatorList") - procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") - procWebAuthNGetW3CExceptionDOMError = modWebAuthn.NewProc("WebAuthNGetW3CExceptionDOMError") - currVer = availableVersions(APIVersionNumber()) + modWebAuthn = windows.NewLazyDLL("webauthn.dll") + procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") + procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") + procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") + currVer = availableVersions(APIVersionNumber()) ) +type WebAuthnCredentialDetails struct { + CredentialID []byte + RP webauthntypes.PublicKeyCredentialRpEntity + User webauthntypes.PublicKeyCredentialUserEntity + Removable bool + BackedUp bool +} + func GetAssertion( hWnd windows.HWND, rpID string, @@ -47,23 +43,19 @@ func GetAssertion( } opts := &_WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS{ - DwVersion: currVer.authenticatorGetAssertionOptions, - DwTimeoutMilliseconds: uint32(winHelloOpts.Timeout.Milliseconds()), - CredentialList: _WEBAUTHN_CREDENTIALS{}, // basically deprecated, baseline supports pAllowCredentialList - DwAuthenticatorAttachment: uint32(winHelloOpts.AuthenticatorAttachment), - DwUserVerificationRequirement: uint32(winHelloOpts.UserVerificationRequirement), - DwFlags: 0, // user only in version 8 for PRF Global Eval - DwCredLargeBlobOperation: uint32(winHelloOpts.CredentialLargeBlobOperation), - CbCredLargeBlob: uint32(len(winHelloOpts.CredentialLargeBlob)), - PbCredLargeBlob: unsafe.SliceData(winHelloOpts.CredentialLargeBlob), - BBrowserInPrivateMode: boolToInt32(winHelloOpts.BrowserInPrivateMode), - BAutoFill: boolToInt32(winHelloOpts.AutoFill), - CbJsonExt: uint32(len(winHelloOpts.JsonExt)), - PbJsonExt: unsafe.SliceData(winHelloOpts.JsonExt), - CbPublicKeyCredentialRequestOptionsJSON: uint32(len(winHelloOpts.PublicKeyCredentialRequestOptionsJSON)), - PbPublicKeyCredentialRequestOptionsJSON: unsafe.SliceData(winHelloOpts.PublicKeyCredentialRequestOptionsJSON), - CbAuthenticatorId: uint32(len(winHelloOpts.AuthenticatorID)), - PbAuthenticatorId: unsafe.SliceData(winHelloOpts.AuthenticatorID), + DwVersion: currVer.authenticatorGetAssertionOptions, + DwTimeoutMilliseconds: uint32(winHelloOpts.Timeout.Milliseconds()), + CredentialList: _WEBAUTHN_CREDENTIALS{}, // basically deprecated, baseline supports pAllowCredentialList + DwAuthenticatorAttachment: uint32(winHelloOpts.AuthenticatorAttachment), + DwUserVerificationRequirement: uint32(winHelloOpts.UserVerificationRequirement), + DwFlags: 0, // user only in version 8 for PRF Global Eval + DwCredLargeBlobOperation: uint32(winHelloOpts.CredentialLargeBlobOperation), + CbCredLargeBlob: uint32(len(winHelloOpts.CredentialLargeBlob)), + PbCredLargeBlob: unsafe.SliceData(winHelloOpts.CredentialLargeBlob), + BBrowserInPrivateMode: boolToInt32(winHelloOpts.BrowserInPrivateMode), + BAutoFill: boolToInt32(winHelloOpts.AutoFill), + CbJsonExt: uint32(len(winHelloOpts.JsonExt)), + PbJsonExt: unsafe.SliceData(winHelloOpts.JsonExt), } credExList := make([]*_WEBAUTHN_CREDENTIAL_EX, len(allowList)) @@ -125,10 +117,6 @@ func GetAssertion( opts.PpwszCredentialHints = unsafe.SliceData(credHints) } - if winHelloOpts.RemoteWebOrigin != "" { - opts.PwszRemoteWebOrigin = windows.StringToUTF16Ptr(winHelloOpts.RemoteWebOrigin) - } - if extInputs != nil { exts := make([]_WEBAUTHN_EXTENSION, 0) diff --git a/ztypes_webauthn.go b/ztypes_webauthn.go index 22cf96d..5fd0523 100644 --- a/ztypes_webauthn.go +++ b/ztypes_webauthn.go @@ -4,279 +4,245 @@ package winhello type ( - _GUID struct { - Data1 uint32 - Data2 uint16 - Data3 uint16 - Data4 [8]uint8 + _GUID struct { + Data1 uint32 + Data2 uint16 + Data3 uint16 + Data4 [8]uint8 } - _WEBAUTHN_ASSERTION struct { - DwVersion uint32 - CbAuthenticatorData uint32 - PbAuthenticatorData *uint8 - CbSignature uint32 - PbSignature *uint8 - Credential _WEBAUTHN_CREDENTIAL - CbUserId uint32 - PbUserId *uint8 - Extensions _WEBAUTHN_EXTENSIONS - CbCredLargeBlob uint32 - PbCredLargeBlob *uint8 - DwCredLargeBlobStatus uint32 - PHmacSecret *_WEBAUTHN_HMAC_SECRET_SALT - DwUsedTransport uint32 - CbUnsignedExtensionOutputs uint32 - PbUnsignedExtensionOutputs *uint8 - CbClientDataJSON uint32 - PbClientDataJSON *uint8 - CbAuthenticationResponseJSON uint32 - PbAuthenticationResponseJSON *uint8 + _WEBAUTHN_ASSERTION struct { + DwVersion uint32 + CbAuthenticatorData uint32 + PbAuthenticatorData *uint8 + CbSignature uint32 + PbSignature *uint8 + Credential _WEBAUTHN_CREDENTIAL + CbUserId uint32 + PbUserId *uint8 + Extensions _WEBAUTHN_EXTENSIONS + CbCredLargeBlob uint32 + PbCredLargeBlob *uint8 + DwCredLargeBlobStatus uint32 + PHmacSecret *_WEBAUTHN_HMAC_SECRET_SALT + DwUsedTransport uint32 + CbUnsignedExtensionOutputs uint32 + PbUnsignedExtensionOutputs *uint8 } - _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS struct { - DwVersion uint32 - DwTimeoutMilliseconds uint32 - CredentialList _WEBAUTHN_CREDENTIALS - Extensions _WEBAUTHN_EXTENSIONS - DwAuthenticatorAttachment uint32 - DwUserVerificationRequirement uint32 - DwFlags uint32 - PwszU2fAppId *uint16 - PbU2fAppId *int32 - PCancellationId *_GUID - PAllowCredentialList *_WEBAUTHN_CREDENTIAL_LIST - DwCredLargeBlobOperation uint32 - CbCredLargeBlob uint32 - PbCredLargeBlob *uint8 - PHmacSecretSaltValues *_WEBAUTHN_HMAC_SECRET_SALT_VALUES - BBrowserInPrivateMode int32 - PLinkedDevice *_CTAPCBOR_HYBRID_STORAGE_LINKED_DATA - BAutoFill int32 - CbJsonExt uint32 - PbJsonExt *uint8 - CCredentialHints uint32 - PpwszCredentialHints **uint16 - PwszRemoteWebOrigin *uint16 - CbPublicKeyCredentialRequestOptionsJSON uint32 - PbPublicKeyCredentialRequestOptionsJSON *uint8 - CbAuthenticatorId uint32 - PbAuthenticatorId *uint8 + _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS struct { + DwVersion uint32 + DwTimeoutMilliseconds uint32 + CredentialList _WEBAUTHN_CREDENTIALS + Extensions _WEBAUTHN_EXTENSIONS + DwAuthenticatorAttachment uint32 + DwUserVerificationRequirement uint32 + DwFlags uint32 + PwszU2fAppId *uint16 + PbU2fAppId *int32 + PCancellationId *_GUID + PAllowCredentialList *_WEBAUTHN_CREDENTIAL_LIST + DwCredLargeBlobOperation uint32 + CbCredLargeBlob uint32 + PbCredLargeBlob *uint8 + PHmacSecretSaltValues *_WEBAUTHN_HMAC_SECRET_SALT_VALUES + BBrowserInPrivateMode int32 + PLinkedDevice *_CTAPCBOR_HYBRID_STORAGE_LINKED_DATA + BAutoFill int32 + CbJsonExt uint32 + PbJsonExt *uint8 + CCredentialHints uint32 + PpwszCredentialHints **uint16 } - _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS struct { - DwVersion uint32 - DwTimeoutMilliseconds uint32 - CredentialList _WEBAUTHN_CREDENTIALS - Extensions _WEBAUTHN_EXTENSIONS - DwAuthenticatorAttachment uint32 - BRequireResidentKey int32 - DwUserVerificationRequirement uint32 - DwAttestationConveyancePreference uint32 - DwFlags uint32 - PCancellationId *_GUID - PExcludeCredentialList *_WEBAUTHN_CREDENTIAL_LIST - DwEnterpriseAttestation uint32 - DwLargeBlobSupport uint32 - BPreferResidentKey int32 - BBrowserInPrivateMode int32 - BEnablePrf int32 - PLinkedDevice *_CTAPCBOR_HYBRID_STORAGE_LINKED_DATA - CbJsonExt uint32 - PbJsonExt *uint8 - PPRFGlobalEval *_WEBAUTHN_HMAC_SECRET_SALT - CCredentialHints uint32 - PpwszCredentialHints **uint16 - BThirdPartyPayment int32 - PwszRemoteWebOrigin *uint16 - CbPublicKeyCredentialCreationOptionsJSON uint32 - PbPublicKeyCredentialCreationOptionsJSON *uint8 - CbAuthenticatorId uint32 - PbAuthenticatorId *uint8 + _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS struct { + DwVersion uint32 + DwTimeoutMilliseconds uint32 + CredentialList _WEBAUTHN_CREDENTIALS + Extensions _WEBAUTHN_EXTENSIONS + DwAuthenticatorAttachment uint32 + BRequireResidentKey int32 + DwUserVerificationRequirement uint32 + DwAttestationConveyancePreference uint32 + DwFlags uint32 + PCancellationId *_GUID + PExcludeCredentialList *_WEBAUTHN_CREDENTIAL_LIST + DwEnterpriseAttestation uint32 + DwLargeBlobSupport uint32 + BPreferResidentKey int32 + BBrowserInPrivateMode int32 + BEnablePrf int32 + PLinkedDevice *_CTAPCBOR_HYBRID_STORAGE_LINKED_DATA + CbJsonExt uint32 + PbJsonExt *uint8 + PPRFGlobalEval *_WEBAUTHN_HMAC_SECRET_SALT + CCredentialHints uint32 + PpwszCredentialHints **uint16 + BThirdPartyPayment int32 + Pad_cgo_0 [4]byte } - _WEBAUTHN_CLIENT_DATA struct { - DwVersion uint32 - CbClientDataJSON uint32 - PbClientDataJSON *uint8 - PwszHashAlgId *uint16 + _WEBAUTHN_CLIENT_DATA struct { + DwVersion uint32 + CbClientDataJSON uint32 + PbClientDataJSON *uint8 + PwszHashAlgId *uint16 } - _WEBAUTHN_COMMON_ATTESTATION struct { - DwVersion uint32 - PwszAlg *uint16 - LAlg int32 - CbSignature uint32 - PbSignature *uint8 - CX5c uint32 - PX5c *_WEBAUTHN_X5C - PwszVer *uint16 - CbCertInfo uint32 - PbCertInfo *uint8 - CbPubArea uint32 - PbPubArea *uint8 + _WEBAUTHN_COMMON_ATTESTATION struct { + DwVersion uint32 + PwszAlg *uint16 + LAlg int32 + CbSignature uint32 + PbSignature *uint8 + CX5c uint32 + PX5c *_WEBAUTHN_X5C + PwszVer *uint16 + CbCertInfo uint32 + PbCertInfo *uint8 + CbPubArea uint32 + PbPubArea *uint8 } - _WEBAUTHN_COSE_CREDENTIAL_PARAMETER struct { - DwVersion uint32 - PwszCredentialType *uint16 - LAlg int32 - Pad_cgo_0 [4]byte + _WEBAUTHN_COSE_CREDENTIAL_PARAMETER struct { + DwVersion uint32 + PwszCredentialType *uint16 + LAlg int32 + Pad_cgo_0 [4]byte } - _WEBAUTHN_COSE_CREDENTIAL_PARAMETERS struct { - CCredentialParameters uint32 - PCredentialParameters *_WEBAUTHN_COSE_CREDENTIAL_PARAMETER + _WEBAUTHN_COSE_CREDENTIAL_PARAMETERS struct { + CCredentialParameters uint32 + PCredentialParameters *_WEBAUTHN_COSE_CREDENTIAL_PARAMETER } - _WEBAUTHN_CRED_BLOB_EXTENSION struct { - CbCredBlob uint32 - PbCredBlob *uint8 + _WEBAUTHN_CRED_BLOB_EXTENSION struct { + CbCredBlob uint32 + PbCredBlob *uint8 } - _WEBAUTHN_CRED_PROTECT_EXTENSION_IN struct { - DwCredProtect uint32 - BRequireCredProtect int32 + _WEBAUTHN_CRED_PROTECT_EXTENSION_IN struct { + DwCredProtect uint32 + BRequireCredProtect int32 } - _WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT struct { - CbCredID uint32 - PbCredID *uint8 - PHmacSecretSalt *_WEBAUTHN_HMAC_SECRET_SALT + _WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT struct { + CbCredID uint32 + PbCredID *uint8 + PHmacSecretSalt *_WEBAUTHN_HMAC_SECRET_SALT } - _WEBAUTHN_CREDENTIAL struct { - DwVersion uint32 - CbId uint32 - PbId *uint8 - PwszCredentialType *uint16 + _WEBAUTHN_CREDENTIAL struct { + DwVersion uint32 + CbId uint32 + PbId *uint8 + PwszCredentialType *uint16 } - _WEBAUTHN_CREDENTIAL_ATTESTATION struct { - DwVersion uint32 - PwszFormatType *uint16 - CbAuthenticatorData uint32 - PbAuthenticatorData *uint8 - CbAttestation uint32 - PbAttestation *uint8 - DwAttestationDecodeType uint32 - PvAttestationDecode *byte - CbAttestationObject uint32 - PbAttestationObject *uint8 - CbCredentialId uint32 - PbCredentialId *uint8 - Extensions _WEBAUTHN_EXTENSIONS - DwUsedTransport uint32 - BEpAtt int32 - BLargeBlobSupported int32 - BResidentKey int32 - BPrfEnabled int32 - CbUnsignedExtensionOutputs uint32 - PbUnsignedExtensionOutputs *uint8 - PHmacSecret *_WEBAUTHN_HMAC_SECRET_SALT - BThirdPartyPayment int32 - DwTransports uint32 - CbClientDataJSON uint32 - PbClientDataJSON *uint8 - CbRegistrationResponseJSON uint32 - PbRegistrationResponseJSON *uint8 + _WEBAUTHN_CREDENTIAL_ATTESTATION struct { + DwVersion uint32 + PwszFormatType *uint16 + CbAuthenticatorData uint32 + PbAuthenticatorData *uint8 + CbAttestation uint32 + PbAttestation *uint8 + DwAttestationDecodeType uint32 + PvAttestationDecode *byte + CbAttestationObject uint32 + PbAttestationObject *uint8 + CbCredentialId uint32 + PbCredentialId *uint8 + Extensions _WEBAUTHN_EXTENSIONS + DwUsedTransport uint32 + BEpAtt int32 + BLargeBlobSupported int32 + BResidentKey int32 + BPrfEnabled int32 + CbUnsignedExtensionOutputs uint32 + PbUnsignedExtensionOutputs *uint8 + PHmacSecret *_WEBAUTHN_HMAC_SECRET_SALT + BThirdPartyPayment int32 + Pad_cgo_0 [4]byte } - _WEBAUTHN_CREDENTIAL_DETAILS struct { - DwVersion uint32 - CbCredentialID uint32 - PbCredentialID *uint8 - PRpInformation *_WEBAUTHN_RP_ENTITY_INFORMATION - PUserInformation *_WEBAUTHN_USER_ENTITY_INFORMATION - BRemovable int32 - BBackedUp int32 - PwszAuthenticatorName *uint16 - CbAuthenticatorLogo uint32 - PbAuthenticatorLogo *uint8 - BThirdPartyPayment int32 - DwTransports uint32 + _WEBAUTHN_CREDENTIAL_DETAILS struct { + DwVersion uint32 + CbCredentialID uint32 + PbCredentialID *uint8 + PRpInformation *_WEBAUTHN_RP_ENTITY_INFORMATION + PUserInformation *_WEBAUTHN_USER_ENTITY_INFORMATION + BRemovable int32 + BBackedUp int32 + PwszAuthenticatorName *uint16 + CbAuthenticatorLogo uint32 + PbAuthenticatorLogo *uint8 + BThirdPartyPayment int32 + Pad_cgo_0 [4]byte } - _WEBAUTHN_CREDENTIAL_DETAILS_LIST struct { - CCredentialDetails uint32 - PpCredentialDetails **_WEBAUTHN_CREDENTIAL_DETAILS + _WEBAUTHN_CREDENTIAL_DETAILS_LIST struct { + CCredentialDetails uint32 + PpCredentialDetails **_WEBAUTHN_CREDENTIAL_DETAILS } - _WEBAUTHN_CREDENTIAL_EX struct { - DwVersion uint32 - CbId uint32 - PbId *uint8 - PwszCredentialType *uint16 - DwTransports uint32 - Pad_cgo_0 [4]byte + _WEBAUTHN_CREDENTIAL_EX struct { + DwVersion uint32 + CbId uint32 + PbId *uint8 + PwszCredentialType *uint16 + DwTransports uint32 + Pad_cgo_0 [4]byte } - _WEBAUTHN_CREDENTIAL_LIST struct { - CCredentials uint32 - PpCredentials **_WEBAUTHN_CREDENTIAL_EX + _WEBAUTHN_CREDENTIAL_LIST struct { + CCredentials uint32 + PpCredentials **_WEBAUTHN_CREDENTIAL_EX } - _WEBAUTHN_CREDENTIALS struct { - CCredentials uint32 - PCredentials *_WEBAUTHN_CREDENTIAL + _WEBAUTHN_CREDENTIALS struct { + CCredentials uint32 + PCredentials *_WEBAUTHN_CREDENTIAL } - _WEBAUTHN_EXTENSION struct { - PwszExtensionIdentifier *uint16 - CbExtension uint32 - PvExtension *byte + _WEBAUTHN_EXTENSION struct { + PwszExtensionIdentifier *uint16 + CbExtension uint32 + PvExtension *byte } - _WEBAUTHN_EXTENSIONS struct { - CExtensions uint32 - PExtensions *_WEBAUTHN_EXTENSION + _WEBAUTHN_EXTENSIONS struct { + CExtensions uint32 + PExtensions *_WEBAUTHN_EXTENSION } - _WEBAUTHN_GET_CREDENTIALS_OPTIONS struct { - DwVersion uint32 - PwszRpId *uint16 - BBrowserInPrivateMode int32 - Pad_cgo_0 [4]byte + _WEBAUTHN_GET_CREDENTIALS_OPTIONS struct { + DwVersion uint32 + PwszRpId *uint16 + BBrowserInPrivateMode int32 + Pad_cgo_0 [4]byte } - _WEBAUTHN_HMAC_SECRET_SALT struct { - CbFirst uint32 - PbFirst *uint8 - CbSecond uint32 - PbSecond *uint8 + _WEBAUTHN_HMAC_SECRET_SALT struct { + CbFirst uint32 + PbFirst *uint8 + CbSecond uint32 + PbSecond *uint8 } - _WEBAUTHN_HMAC_SECRET_SALT_VALUES struct { - PGlobalHmacSalt *_WEBAUTHN_HMAC_SECRET_SALT - CCredWithHmacSecretSaltList uint32 - PCredWithHmacSecretSaltList *_WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT + _WEBAUTHN_HMAC_SECRET_SALT_VALUES struct { + PGlobalHmacSalt *_WEBAUTHN_HMAC_SECRET_SALT + CCredWithHmacSecretSaltList uint32 + PCredWithHmacSecretSaltList *_WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT } - _WEBAUTHN_RP_ENTITY_INFORMATION struct { - DwVersion uint32 - PwszId *uint16 - PwszName *uint16 - PwszIcon *uint16 + _WEBAUTHN_RP_ENTITY_INFORMATION struct { + DwVersion uint32 + PwszId *uint16 + PwszName *uint16 + PwszIcon *uint16 } - _WEBAUTHN_USER_ENTITY_INFORMATION struct { - DwVersion uint32 - CbId uint32 - PbId *uint8 - PwszName *uint16 - PwszIcon *uint16 - PwszDisplayName *uint16 + _WEBAUTHN_USER_ENTITY_INFORMATION struct { + DwVersion uint32 + CbId uint32 + PbId *uint8 + PwszName *uint16 + PwszIcon *uint16 + PwszDisplayName *uint16 } - _WEBAUTHN_X5C struct { - CbData uint32 - PbData *uint8 + _WEBAUTHN_X5C struct { + CbData uint32 + PbData *uint8 } - _CTAPCBOR_HYBRID_STORAGE_LINKED_DATA struct { - DwVersion uint32 - CbContactId uint32 - PbContactId *uint8 - CbLinkId uint32 - PbLinkId *uint8 - CbLinkSecret uint32 - PbLinkSecret *uint8 - CbPublicKey uint32 - PbPublicKey *uint8 - PwszAuthenticatorName *uint16 - WEncodedTunnelServerDomain uint16 - Pad_cgo_0 [6]byte - } - _WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS struct { - DwVersion uint32 - } - _WEBAUTHN_AUTHENTICATOR_DETAILS struct { - DwVersion uint32 - CbAuthenticatorId uint32 - PbAuthenticatorId *uint8 - PwszAuthenticatorName *uint16 - CbAuthenticatorLogo uint32 - PbAuthenticatorLogo *uint8 - BLocked int32 - Pad_cgo_0 [4]byte - } - _WEBAUTHN_AUTHENTICATOR_DETAILS_LIST struct { - CAuthenticatorDetails uint32 - PpAuthenticatorDetails **_WEBAUTHN_AUTHENTICATOR_DETAILS + _CTAPCBOR_HYBRID_STORAGE_LINKED_DATA struct { + DwVersion uint32 + CbContactId uint32 + PbContactId *uint8 + CbLinkId uint32 + PbLinkId *uint8 + CbLinkSecret uint32 + PbLinkSecret *uint8 + CbPublicKey uint32 + PbPublicKey *uint8 + PwszAuthenticatorName *uint16 + WEncodedTunnelServerDomain uint16 + Pad_cgo_0 [6]byte } ) From f86730439ccebdd7ae5afc196cce2203c1082c17 Mon Sep 17 00:00:00 2001 From: Atanas Janeshliev Date: Thu, 18 Sep 2025 16:55:18 +0200 Subject: [PATCH 5/8] chore: update types --- consts.go | 179 ++------ versions.go | 2 +- webauthn.h | 987 +++++++++------------------------------------ ztypes_webauthn.go | 89 ++-- 4 files changed, 267 insertions(+), 990 deletions(-) diff --git a/consts.go b/consts.go index f5cbb5d..986917a 100644 --- a/consts.go +++ b/consts.go @@ -46,8 +46,7 @@ const ( WinHelloCTAPTransportTest WinHelloCTAPTransportInternal WinHelloCTAPTransportHybrid - WinHelloCTAPTransportSmartCard - WinHelloCTAPTransportFlagsMask WinHelloCOSEAlgorithm = 0x0000007F + WinHelloCTAPTransportFlagsMask WinHelloCOSEAlgorithm = 0x0000003F ) type WinHelloUserVerification uint32 @@ -136,30 +135,25 @@ const ( ) type AuthenticatorGetAssertionOptions struct { - Timeout time.Duration - AuthenticatorAttachment WinHelloAuthenticatorAttachment - UserVerificationRequirement WinHelloUserVerificationRequirement - U2FAppID string - CancellationID *windows.GUID - CredentialLargeBlobOperation WinHelloCredentialLargeBlobOperation - CredentialLargeBlob []byte - BrowserInPrivateMode bool - AutoFill bool - JsonExt []byte - CredentialHints []webauthntypes.PublicKeyCredentialHint - RemoteWebOrigin string - PublicKeyCredentialRequestOptionsJSON []byte - AuthenticatorID []byte + Timeout time.Duration + AuthenticatorAttachment WinHelloAuthenticatorAttachment + UserVerificationRequirement WinHelloUserVerificationRequirement + U2FAppID string + CancellationID *windows.GUID + CredentialLargeBlobOperation WinHelloCredentialLargeBlobOperation + CredentialLargeBlob []byte + BrowserInPrivateMode bool + AutoFill bool + JsonExt []byte + CredentialHints []webauthntypes.PublicKeyCredentialHint } type WinHelloGetAssertionResponse struct { *ctaptypes.AuthenticatorGetAssertionResponse - CredLargeBlob []byte - CredLargeBlobStatus WinHelloCredentialLargeBlobStatus - UsedTransport []webauthntypes.AuthenticatorTransport - ClientDataJSON []byte - AuthenticationResponseJSON []byte - hmacSecret *webauthntypes.AuthenticationExtensionsPRFValues + CredLargeBlob []byte + CredLargeBlobStatus WinHelloCredentialLargeBlobStatus + UsedTransport []webauthntypes.AuthenticatorTransport + hmacSecret *webauthntypes.AuthenticationExtensionsPRFValues } func (a *_WEBAUTHN_ASSERTION) ToGetAssertionResponse() ( @@ -191,150 +185,25 @@ func (a *_WEBAUTHN_ASSERTION) ToGetAssertionResponse() ( winHelloResp := &WinHelloGetAssertionResponse{ AuthenticatorGetAssertionResponse: resp, + CredLargeBlob: bytes.Clone(unsafe.Slice(a.PbCredLargeBlob, a.CbCredLargeBlob)), + CredLargeBlobStatus: WinHelloCredentialLargeBlobStatus(a.DwCredLargeBlobStatus), + UsedTransport: flagsToTransports(a.DwUsedTransport), } - if a.DwVersion >= 2 { - winHelloResp.CredLargeBlob = bytes.Clone(unsafe.Slice(a.PbCredLargeBlob, a.CbCredLargeBlob)) - winHelloResp.CredLargeBlobStatus = WinHelloCredentialLargeBlobStatus(a.DwCredLargeBlobStatus) - } - - if a.DwVersion >= 3 && a.PHmacSecret != nil { + if a.PHmacSecret != nil { winHelloResp.hmacSecret = &webauthntypes.AuthenticationExtensionsPRFValues{ First: bytes.Clone(unsafe.Slice(a.PHmacSecret.PbFirst, a.PHmacSecret.CbFirst)), Second: bytes.Clone(unsafe.Slice(a.PHmacSecret.PbSecond, a.PHmacSecret.CbSecond)), } } - if a.DwVersion >= 4 { - winHelloResp.UsedTransport = flagsToTransports(a.DwUsedTransport) - } - - if a.DwVersion >= 5 { - unsignedExtensionOutputsRaw := bytes.Clone(unsafe.Slice(a.PbUnsignedExtensionOutputs, a.CbUnsignedExtensionOutputs)) - if unsignedExtensionOutputsRaw != nil && len(unsignedExtensionOutputsRaw) > 0 { - if err := cbor.Unmarshal(unsignedExtensionOutputsRaw, &resp.UnsignedExtensionOutputs); err != nil { - return nil, err - } - } - } - - if a.DwVersion >= 6 { - clientDataJSONRaw := bytes.Clone(unsafe.Slice(a.PbClientDataJSON, a.CbClientDataJSON)) - if clientDataJSONRaw != nil && len(clientDataJSONRaw) > 0 { - winHelloResp.ClientDataJSON = clientDataJSONRaw - } - authenticationResponseJSONRaw := bytes.Clone(unsafe.Slice(a.PbAuthenticationResponseJSON, a.CbAuthenticationResponseJSON)) - if authenticationResponseJSONRaw != nil && len(authenticationResponseJSONRaw) > 0 { - winHelloResp.AuthenticationResponseJSON = authenticationResponseJSONRaw - } - } - - return winHelloResp, nil -} - -type AuthenticatorMakeCredentialOptions struct { - Timeout time.Duration - AuthenticatorAttachment WinHelloAuthenticatorAttachment - RequireResidentKey bool - UserVerificationRequirement WinHelloUserVerificationRequirement - AttestationConveyancePreference WinHelloAttestationConveyancePreference - CancellationID *windows.GUID - EnterpriseAttestation WinHelloEnterpriseAttestation - LargeBlobSupport WinHelloLargeBlobSupport - PreferResidentKey bool - BrowserInPrivateMode bool - JsonExt []byte - CredentialHints []webauthntypes.PublicKeyCredentialHint - ThirdPartyPayment bool - RemoteWebOrigin string - PublicKeyCredentialCreationOptionsJSON []byte - AuthenticatorID []byte -} - -type WinHelloMakeCredentialResponse struct { - *ctaptypes.AuthenticatorMakeCredentialResponse - CredentialID []byte - UsedTransport []webauthntypes.AuthenticatorTransport - LargeBlobSupported bool - ResidentKey bool - PRFEnabled bool - HMACSecret *webauthntypes.AuthenticationExtensionsPRFValues - ThirdPartyPayment bool - Transports []webauthntypes.AuthenticatorTransport - ClientDataJSON []byte - RegistrationResponseJSON []byte -} - -func (a *_WEBAUTHN_CREDENTIAL_ATTESTATION) ToMakeCredentialResponse() (*WinHelloMakeCredentialResponse, error) { - authDataRaw := bytes.Clone(unsafe.Slice(a.PbAuthenticatorData, a.CbAuthenticatorData)) - authData, err := ctaptypes.ParseMakeCredentialAuthData(authDataRaw) - if err != nil { - return nil, err - } - - resp := &ctaptypes.AuthenticatorMakeCredentialResponse{ - Format: webauthntypes.AttestationStatementFormatIdentifier(windows.UTF16PtrToString(a.PwszFormatType)), - AuthData: authData, - AuthDataRaw: authDataRaw, - } - - attestationRaw := bytes.Clone(unsafe.Slice(a.PbAttestation, a.CbAttestation)) - if resp.Format != webauthntypes.AttestationStatementFormatIdentifierNone && - attestationRaw != nil && - len(attestationRaw) > 0 { - if err := cbor.Unmarshal(attestationRaw, &resp.AttestationStatement); err != nil { + unsignedExtensionOutputsRaw := bytes.Clone(unsafe.Slice(a.PbUnsignedExtensionOutputs, a.CbUnsignedExtensionOutputs)) + if unsignedExtensionOutputsRaw != nil && len(unsignedExtensionOutputsRaw) > 0 { + if err := cbor.Unmarshal(unsignedExtensionOutputsRaw, &resp.UnsignedExtensionOutputs); err != nil { return nil, err } } - winHelloResp := &WinHelloMakeCredentialResponse{ - AuthenticatorMakeCredentialResponse: resp, - CredentialID: bytes.Clone(unsafe.Slice(a.PbCredentialId, a.CbCredentialId)), - } - - if a.DwVersion >= 3 { - winHelloResp.UsedTransport = flagsToTransports(a.DwUsedTransport) - } - - if a.DwVersion >= 4 { - winHelloResp.EnterpriseAttestation = int32ToBool(a.BEpAtt) - winHelloResp.LargeBlobSupported = int32ToBool(a.BLargeBlobSupported) - winHelloResp.ResidentKey = int32ToBool(a.BResidentKey) - } - - if a.DwVersion >= 5 { - winHelloResp.PRFEnabled = int32ToBool(a.BPrfEnabled) - } - - if a.DwVersion >= 6 { - unsignedExtensionOutputsRaw := bytes.Clone(unsafe.Slice(a.PbUnsignedExtensionOutputs, a.CbUnsignedExtensionOutputs)) - if unsignedExtensionOutputsRaw != nil && len(unsignedExtensionOutputsRaw) > 0 { - if err := cbor.Unmarshal(unsignedExtensionOutputsRaw, &resp.UnsignedExtensionOutputs); err != nil { - return nil, err - } - } - } - - if a.DwVersion >= 7 && a.PHmacSecret != nil { - winHelloResp.HMACSecret = &webauthntypes.AuthenticationExtensionsPRFValues{ - First: bytes.Clone(unsafe.Slice(a.PHmacSecret.PbFirst, a.PHmacSecret.CbFirst)), - Second: bytes.Clone(unsafe.Slice(a.PHmacSecret.PbSecond, a.PHmacSecret.CbSecond)), - } - winHelloResp.ThirdPartyPayment = int32ToBool(a.BThirdPartyPayment) - } - - if a.DwVersion >= 8 { - winHelloResp.Transports = flagsToTransports(a.DwTransports) - clientDataJSONRaw := bytes.Clone(unsafe.Slice(a.PbClientDataJSON, a.CbClientDataJSON)) - if clientDataJSONRaw != nil && len(clientDataJSONRaw) > 0 { - winHelloResp.ClientDataJSON = clientDataJSONRaw - } - registrationResponseJSONRaw := bytes.Clone(unsafe.Slice(a.PbRegistrationResponseJSON, a.CbRegistrationResponseJSON)) - if registrationResponseJSONRaw != nil && len(registrationResponseJSONRaw) > 0 { - winHelloResp.RegistrationResponseJSON = registrationResponseJSONRaw - } - } - return winHelloResp, nil } @@ -351,8 +220,6 @@ func flagsToTransports(flags uint32) []webauthntypes.AuthenticatorTransport { case flags&uint32(WinHelloCTAPTransportInternal) != 0: tr = append(tr, webauthntypes.AuthenticatorTransportInternal) case flags&uint32(WinHelloCTAPTransportHybrid) != 0: - case flags&uint32(WinHelloCTAPTransportSmartCard) != 0: - tr = append(tr, webauthntypes.AuthenticatorTransportSmartCard) tr = append(tr, webauthntypes.AuthenticatorTransportHybrid) } diff --git a/versions.go b/versions.go index 7b3cf3b..b89b6c7 100644 --- a/versions.go +++ b/versions.go @@ -72,7 +72,7 @@ func availableVersions(ver uint32) *currentVersion { v.credentialDetails++ v.credentialAttestation++ v.authenticatorGetAssertionOptions++ - }, + }, // 9 } for i, d := range diff { diff --git a/webauthn.h b/webauthn.h index a5ff363..989b324 100644 --- a/webauthn.h +++ b/webauthn.h @@ -1,29 +1,8 @@ -/* - -MIT License - -Copyright (c) Microsoft Corporation. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE - -*/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +#ifndef __WEBAUTHN_H_ +#define __WEBAUTHN_H_ #pragma once @@ -116,6 +95,7 @@ extern "C" { // - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 5 // - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 6 // - WEBAUTHN_ASSERTION : 3 +// - WEBAUTHN_GET_CREDENTIALS_OPTIONS : 1 // - WEBAUTHN_CREDENTIAL_DETAILS : 1 // APIs: // - WebAuthNGetPlatformCredentialList @@ -157,7 +137,21 @@ extern "C" { // - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 8 // -#define WEBAUTHN_API_CURRENT_VERSION WEBAUTHN_API_VERSION_8 +#define WEBAUTHN_API_VERSION_9 9 +// WEBAUTHN_API_VERSION_9 : Delta From WEBAUTHN_API_VERSION_8 +// Data Structures and their sub versions: +// - WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS : 9 +// - WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS : 9 +// - WEBAUTHN_ASSERTION : 6 +// - WEBAUTHN_CREDENTIAL_DETAILS : 4 +// - WEBAUTHN_CREDENTIAL_ATTESTATION : 8 +// - WEBAUTHN_AUTHENTICATOR_DETAILS : 1 +// - WEBAUTHN_AUTHENTICATOR_DETAILS_LIST : Not Applicable +// APIs: +// - WebAuthNGetAuthenticatorList +// - WebAuthNFreeAuthenticatorList + +#define WEBAUTHN_API_CURRENT_VERSION WEBAUTHN_API_VERSION_9 //+------------------------------------------------------------------------------------------ // Information about an RP Entity @@ -165,12 +159,6 @@ extern "C" { #define WEBAUTHN_RP_ENTITY_INFORMATION_CURRENT_VERSION 1 -#ifdef __midl -typedef [string] wchar_t* PWSTR; -typedef [string] wchar_t* const PCWSTR; -typedef unsigned char* PBYTE; -#endif - typedef struct _WEBAUTHN_RP_ENTITY_INFORMATION { // Version of this structure, to allow for modifications in the future. // This field is required and should be set to CURRENT_VERSION above. @@ -202,12 +190,7 @@ typedef struct _WEBAUTHN_USER_ENTITY_INFORMATION { // Identifier for the User. This field is required. DWORD cbId; - - #ifdef __midl - [size_is(cbId)] - #else _Field_size_bytes_(cbId) - #endif PBYTE pbId; // Contains a detailed name for this account, such as "john.p.smith@example.com". @@ -222,8 +205,6 @@ typedef struct _WEBAUTHN_USER_ENTITY_INFORMATION { } WEBAUTHN_USER_ENTITY_INFORMATION, *PWEBAUTHN_USER_ENTITY_INFORMATION; typedef const WEBAUTHN_USER_ENTITY_INFORMATION *PCWEBAUTHN_USER_ENTITY_INFORMATION; -#ifndef __midl - //+------------------------------------------------------------------------------------------ // Information about client data. //------------------------------------------------------------------------------------------- @@ -250,8 +231,6 @@ typedef struct _WEBAUTHN_CLIENT_DATA { } WEBAUTHN_CLIENT_DATA, *PWEBAUTHN_CLIENT_DATA; typedef const WEBAUTHN_CLIENT_DATA *PCWEBAUTHN_CLIENT_DATA; -#endif //__midl - //+------------------------------------------------------------------------------------------ // Information about credential parameters. //------------------------------------------------------------------------------------------- @@ -277,11 +256,7 @@ typedef struct _WEBAUTHN_COSE_CREDENTIAL_PARAMETER { DWORD dwVersion; // Well-known credential type specifying a credential to create. - #ifdef __midl - PCWSTR pwszCredentialType; - #else LPCWSTR pwszCredentialType; - #endif // Well-known COSE algorithm specifying the algorithm to use for the credential. LONG lAlg; @@ -290,11 +265,7 @@ typedef const WEBAUTHN_COSE_CREDENTIAL_PARAMETER *PCWEBAUTHN_COSE_CREDENTIAL_PAR typedef struct _WEBAUTHN_COSE_CREDENTIAL_PARAMETERS { DWORD cCredentialParameters; - #ifdef __midl - [size_is(cCredentialParameters)] - #else _Field_size_(cCredentialParameters) - #endif PWEBAUTHN_COSE_CREDENTIAL_PARAMETER pCredentialParameters; } WEBAUTHN_COSE_CREDENTIAL_PARAMETERS, *PWEBAUTHN_COSE_CREDENTIAL_PARAMETERS; typedef const WEBAUTHN_COSE_CREDENTIAL_PARAMETERS *PCWEBAUTHN_COSE_CREDENTIAL_PARAMETERS; @@ -308,32 +279,20 @@ typedef struct _WEBAUTHN_CREDENTIAL { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; - // Unique ID for this particular credential. + // Size of pbID. DWORD cbId; - #ifdef __midl - [size_is(cbId)] - #else + // Unique ID for this particular credential. _Field_size_bytes_(cbId) PBYTE pbId; - #endif // Well-known credential type specifying what this particular credential is. - #ifdef __midl - PWSTR pwszCredentialType; - #else - PCWSTR pwszCredentialType; - #endif - + LPCWSTR pwszCredentialType; } WEBAUTHN_CREDENTIAL, *PWEBAUTHN_CREDENTIAL; typedef const WEBAUTHN_CREDENTIAL *PCWEBAUTHN_CREDENTIAL; typedef struct _WEBAUTHN_CREDENTIALS { DWORD cCredentials; - #ifdef __midl - [size_is(cCredentials)] - #else _Field_size_(cCredentials) - #endif PWEBAUTHN_CREDENTIAL pCredentials; } WEBAUTHN_CREDENTIALS, *PWEBAUTHN_CREDENTIALS; typedef const WEBAUTHN_CREDENTIALS *PCWEBAUTHN_CREDENTIALS; @@ -348,7 +307,15 @@ typedef const WEBAUTHN_CREDENTIALS *PCWEBAUTHN_CREDENTIALS; #define WEBAUTHN_CTAP_TRANSPORT_TEST 0x00000008 #define WEBAUTHN_CTAP_TRANSPORT_INTERNAL 0x00000010 #define WEBAUTHN_CTAP_TRANSPORT_HYBRID 0x00000020 -#define WEBAUTHN_CTAP_TRANSPORT_FLAGS_MASK 0x0000003F +#define WEBAUTHN_CTAP_TRANSPORT_SMART_CARD 0x00000040 +#define WEBAUTHN_CTAP_TRANSPORT_FLAGS_MASK 0x0000007F + +#define WEBAUTHN_CTAP_TRANSPORT_USB_STRING "usb" +#define WEBAUTHN_CTAP_TRANSPORT_NFC_STRING "nfc" +#define WEBAUTHN_CTAP_TRANSPORT_BLE_STRING "ble" +#define WEBAUTHN_CTAP_TRANSPORT_SMART_CARD_STRING "smart-card" +#define WEBAUTHN_CTAP_TRANSPORT_HYBRID_STRING "hybrid" +#define WEBAUTHN_CTAP_TRANSPORT_INTERNAL_STRING "internal" #define WEBAUTHN_CREDENTIAL_EX_CURRENT_VERSION 1 @@ -358,19 +325,12 @@ typedef struct _WEBAUTHN_CREDENTIAL_EX { // Size of pbID. DWORD cbId; - #ifdef __midl - [size_is(cbId)] - #else + // Unique ID for this particular credential. _Field_size_bytes_(cbId) - #endif PBYTE pbId; // Well-known credential type specifying what this particular credential is. - #ifdef __midl - PCWSTR pwszCredentialType; - #else LPCWSTR pwszCredentialType; - #endif // Transports. 0 implies no transport restrictions. DWORD dwTransports; @@ -383,24 +343,16 @@ typedef const WEBAUTHN_CREDENTIAL_EX *PCWEBAUTHN_CREDENTIAL_EX; typedef struct _WEBAUTHN_CREDENTIAL_LIST { DWORD cCredentials; - #ifdef __midl - [size_is(cCredentials)] - #else _Field_size_(cCredentials) - #endif PWEBAUTHN_CREDENTIAL_EX *ppCredentials; } WEBAUTHN_CREDENTIAL_LIST, *PWEBAUTHN_CREDENTIAL_LIST; typedef const WEBAUTHN_CREDENTIAL_LIST *PCWEBAUTHN_CREDENTIAL_LIST; -#ifndef __midl - //+------------------------------------------------------------------------------------------ // Information about linked devices //------------------------------------------------------------------------------------------- -// Deprecated #define CTAPCBOR_HYBRID_STORAGE_LINKED_DATA_VERSION_1 1 -// Deprecated #define CTAPCBOR_HYBRID_STORAGE_LINKED_DATA_CURRENT_VERSION CTAPCBOR_HYBRID_STORAGE_LINKED_DATA_VERSION_1 // Deprecated @@ -437,7 +389,56 @@ typedef struct _CTAPCBOR_HYBRID_STORAGE_LINKED_DATA } CTAPCBOR_HYBRID_STORAGE_LINKED_DATA, *PCTAPCBOR_HYBRID_STORAGE_LINKED_DATA; typedef const CTAPCBOR_HYBRID_STORAGE_LINKED_DATA *PCCTAPCBOR_HYBRID_STORAGE_LINKED_DATA; -#endif //__midl +//+------------------------------------------------------------------------------------------ +// Authenticator Information for WebAuthNGetAuthenticatorList API +//------------------------------------------------------------------------------------------- + +#define WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS_VERSION_1 1 +#define WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS_VERSION_1 + +typedef struct _WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS { + // Version of this structure, to allow for modifications in the future. + DWORD dwVersion; + +} WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS, *PWEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS; +typedef const WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS *PCWEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS; + +#define WEBAUTHN_AUTHENTICATOR_DETAILS_VERSION_1 1 +#define WEBAUTHN_AUTHENTICATOR_DETAILS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_DETAILS_VERSION_1 + +typedef struct _WEBAUTHN_AUTHENTICATOR_DETAILS { + // Version of this structure, to allow for modifications in the future. + DWORD dwVersion; + + // Authenticator ID + DWORD cbAuthenticatorId; + _Field_size_bytes_(cbAuthenticatorId) + PBYTE pbAuthenticatorId; + + // Authenticator Name + PCWSTR pwszAuthenticatorName; + + // Authenticator logo (expected to be in SVG format) + DWORD cbAuthenticatorLogo; + _Field_size_bytes_(cbAuthenticatorLogo) + PBYTE pbAuthenticatorLogo; + + // Is the authenticator currently locked? When locked, this authenticator's credentials + // might not be present or updated in WebAuthNGetPlatformCredentialList. + BOOL bLocked; + +} WEBAUTHN_AUTHENTICATOR_DETAILS, *PWEBAUTHN_AUTHENTICATOR_DETAILS; +typedef const WEBAUTHN_AUTHENTICATOR_DETAILS *PCWEBAUTHN_AUTHENTICATOR_DETAILS; + +typedef struct _WEBAUTHN_AUTHENTICATOR_DETAILS_LIST { + // Authenticator Details + DWORD cAuthenticatorDetails; + _Field_size_(cAuthenticatorDetails) + PWEBAUTHN_AUTHENTICATOR_DETAILS *ppAuthenticatorDetails; + +} WEBAUTHN_AUTHENTICATOR_DETAILS_LIST, *PWEBAUTHN_AUTHENTICATOR_DETAILS_LIST; +typedef const WEBAUTHN_AUTHENTICATOR_DETAILS_LIST *PCWEBAUTHN_AUTHENTICATOR_DETAILS_LIST; + //+------------------------------------------------------------------------------------------ // Credential Information for WebAuthNGetPlatformCredentialList API //------------------------------------------------------------------------------------------- @@ -445,7 +446,8 @@ typedef const CTAPCBOR_HYBRID_STORAGE_LINKED_DATA *PCCTAPCBOR_HYBRID_STORAGE_LIN #define WEBAUTHN_CREDENTIAL_DETAILS_VERSION_1 1 #define WEBAUTHN_CREDENTIAL_DETAILS_VERSION_2 2 #define WEBAUTHN_CREDENTIAL_DETAILS_VERSION_3 3 -#define WEBAUTHN_CREDENTIAL_DETAILS_CURRENT_VERSION WEBAUTHN_CREDENTIAL_DETAILS_VERSION_3 +#define WEBAUTHN_CREDENTIAL_DETAILS_VERSION_4 4 +#define WEBAUTHN_CREDENTIAL_DETAILS_CURRENT_VERSION WEBAUTHN_CREDENTIAL_DETAILS_VERSION_4 typedef struct _WEBAUTHN_CREDENTIAL_DETAILS { // Version of this structure, to allow for modifications in the future. @@ -453,24 +455,13 @@ typedef struct _WEBAUTHN_CREDENTIAL_DETAILS { // Size of pbCredentialID. DWORD cbCredentialID; - - #ifdef __midl - [size_is(cbCredentialID)] - #else _Field_size_bytes_(cbCredentialID) - #endif PBYTE pbCredentialID; // RP Info - #ifdef __midl - [unique] - #endif PWEBAUTHN_RP_ENTITY_INFORMATION pRpInformation; // User Info - #ifdef __midl - [unique] - #endif PWEBAUTHN_USER_ENTITY_INFORMATION pUserInformation; // Removable or not. @@ -490,27 +481,25 @@ typedef struct _WEBAUTHN_CREDENTIAL_DETAILS { // The logo is expected to be in the svg format DWORD cbAuthenticatorLogo; - - #ifdef __midl - [size_is(cbAuthenticatorLogo)] - #else _Field_size_bytes_(cbAuthenticatorLogo) - #endif PBYTE pbAuthenticatorLogo; // ThirdPartyPayment Credential or not. BOOL bThirdPartyPayment; + // + // The following fields have been added in WEBAUTHN_CREDENTIAL_DETAILS_VERSION_4 + // + + // Applicable Transports + DWORD dwTransports; + } WEBAUTHN_CREDENTIAL_DETAILS, *PWEBAUTHN_CREDENTIAL_DETAILS; typedef const WEBAUTHN_CREDENTIAL_DETAILS *PCWEBAUTHN_CREDENTIAL_DETAILS; typedef struct _WEBAUTHN_CREDENTIAL_DETAILS_LIST { DWORD cCredentialDetails; - #ifdef __midl - [size_is(cCredentialDetails)] - #else _Field_size_(cCredentialDetails) - #endif PWEBAUTHN_CREDENTIAL_DETAILS *ppCredentialDetails; } WEBAUTHN_CREDENTIAL_DETAILS_LIST, *PWEBAUTHN_CREDENTIAL_DETAILS_LIST; typedef const WEBAUTHN_CREDENTIAL_DETAILS_LIST *PCWEBAUTHN_CREDENTIAL_DETAILS_LIST; @@ -539,33 +528,23 @@ typedef const WEBAUTHN_GET_CREDENTIALS_OPTIONS *PCWEBAUTHN_GET_CREDENTIALS_OPTIO // SALT values below by default are converted into RAW Hmac-Secret values as per PRF extension. // - SHA-256(UTF8Encode("WebAuthn PRF") || 0x00 || Value) // -// Set WEBAUTHN_CTAP_HMAC_SECRET_VALUES_FLAG in dwFlags in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS, +// Set WEBAUTHN_AUTHENTICATOR_HMAC_SECRET_VALUES_FLAG in dwFlags in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS, // if caller wants to provide RAW Hmac-Secret SALT values directly. In that case, // values if provided MUST be of WEBAUTHN_CTAP_ONE_HMAC_SECRET_LENGTH size. typedef struct _WEBAUTHN_HMAC_SECRET_SALT { // Size of pbFirst. DWORD cbFirst; - #ifdef __midl - [size_is(cbFirst)] - #else _Field_size_bytes_(cbFirst) - #endif PBYTE pbFirst; // Required // Size of pbSecond. DWORD cbSecond; - #ifdef __midl - [size_is(cbSecond)] - #else _Field_size_bytes_(cbSecond) - #endif PBYTE pbSecond; } WEBAUTHN_HMAC_SECRET_SALT, *PWEBAUTHN_HMAC_SECRET_SALT; typedef const WEBAUTHN_HMAC_SECRET_SALT *PCWEBAUTHN_HMAC_SECRET_SALT; -#ifndef __midl - typedef struct _WEBAUTHN_CRED_WITH_HMAC_SECRET_SALT { // Size of pbCredID. DWORD cbCredID; @@ -676,41 +655,23 @@ typedef const WEBAUTHN_CRED_BLOB_EXTENSION *PCWEBAUTHN_CRED_BLOB_EXTENSION; // GetAssertion Input Type: Not Supported // GetAssertion Output Type: Not Supported -#endif //__midl - //+------------------------------------------------------------------------------------------ // Information about Extensions. //------------------------------------------------------------------------------------------- typedef struct _WEBAUTHN_EXTENSION { - #ifdef __midl - PWSTR pwszExtensionIdentifier; - #else LPCWSTR pwszExtensionIdentifier; - #endif - DWORD cbExtension; - #ifdef __midl - [size_is(cbExtension)] - PBYTE pvExtension; - #else PVOID pvExtension; - #endif } WEBAUTHN_EXTENSION, *PWEBAUTHN_EXTENSION; typedef const WEBAUTHN_EXTENSION *PCWEBAUTHN_EXTENSION; typedef struct _WEBAUTHN_EXTENSIONS { DWORD cExtensions; - #ifdef __midl - [size_is(cExtensions)] - #else _Field_size_(cExtensions) - #endif PWEBAUTHN_EXTENSION pExtensions; } WEBAUTHN_EXTENSIONS, *PWEBAUTHN_EXTENSIONS; typedef const WEBAUTHN_EXTENSIONS *PCWEBAUTHN_EXTENSIONS; -#ifndef __midl - //+------------------------------------------------------------------------------------------ // Options. //------------------------------------------------------------------------------------------- @@ -750,7 +711,8 @@ typedef const WEBAUTHN_EXTENSIONS *PCWEBAUTHN_EXTENSIONS; #define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_6 6 #define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_7 7 #define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_8 8 -#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_8 +#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_9 9 +#define WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_9 typedef struct _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS { // Version of this structure, to allow for modifications in the future. @@ -844,24 +806,35 @@ typedef struct _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS { // // PRF extension "eval" values which will be converted into HMAC-SECRET values according to WebAuthn Spec. - // Set WEBAUTHN_CTAP_HMAC_SECRET_VALUES_FLAG in dwFlags above, if caller wants to provide RAW Hmac-Secret SALT values directly. + // Set WEBAUTHN_AUTHENTICATOR_HMAC_SECRET_VALUES_FLAG in dwFlags above, if caller wants to provide RAW Hmac-Secret SALT values directly. // In that case, values provided MUST be of WEBAUTHN_CTAP_ONE_HMAC_SECRET_LENGTH size. PWEBAUTHN_HMAC_SECRET_SALT pPRFGlobalEval; // PublicKeyCredentialHints (https://w3c.github.io/webauthn/#enum-hints) DWORD cCredentialHints; - - #ifdef __midl - [size_is(cCredentialHints)] - PCWSTR *ppwszCredentialHints; - #else _Field_size_(cCredentialHints) LPCWSTR *ppwszCredentialHints; - #endif // Enable ThirdPartyPayment BOOL bThirdPartyPayment; + // + // The following fields have been added in WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_9 + // + + // Web Origin. For Remote Web App scenario. + PCWSTR pwszRemoteWebOrigin; + + // UTF-8 encoded JSON serialization of the PublicKeyCredentialCreationOptions. + DWORD cbPublicKeyCredentialCreationOptionsJSON; + _Field_size_bytes_(cbPublicKeyCredentialCreationOptionsJSON) + PBYTE pbPublicKeyCredentialCreationOptionsJSON; + + // Authenticator ID got from WebAuthNGetAuthenticatorList API. + DWORD cbAuthenticatorId; + _Field_size_bytes_(cbAuthenticatorId) + PBYTE pbAuthenticatorId; + } WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS, *PWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS; typedef const WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS; @@ -878,7 +851,8 @@ typedef const WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS *PCWEBAUTHN_AUTHENT #define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_6 6 #define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_7 7 #define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_8 8 -#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_8 +#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_9 9 +#define WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_CURRENT_VERSION WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_9 /* Information about flags. @@ -977,14 +951,25 @@ typedef struct _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS { // PublicKeyCredentialHints (https://w3c.github.io/webauthn/#enum-hints) DWORD cCredentialHints; - - #ifdef __midl - [size_is(cCredentialHints)] - PCWSTR *ppwszCredentialHints; - #else _Field_size_(cCredentialHints) LPCWSTR *ppwszCredentialHints; - #endif + + // + // The following fields have been added in WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_9 + // + + // Web Origin. For Remote Web App scenario. + PCWSTR pwszRemoteWebOrigin; + + // UTF-8 encoded JSON serialization of the PublicKeyCredentialRequestOptions. + DWORD cbPublicKeyCredentialRequestOptionsJSON; + _Field_size_bytes_(cbPublicKeyCredentialRequestOptionsJSON) + PBYTE pbPublicKeyCredentialRequestOptionsJSON; + + // Authenticator ID got from WebAuthNGetAuthenticatorList API. + DWORD cbAuthenticatorId; + _Field_size_bytes_(cbAuthenticatorId) + PBYTE pbAuthenticatorId; } WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS, *PWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS; typedef const WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS *PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS; @@ -1053,8 +1038,6 @@ typedef struct _WEBAUTHN_COMMON_ATTESTATION { } WEBAUTHN_COMMON_ATTESTATION, *PWEBAUTHN_COMMON_ATTESTATION; typedef const WEBAUTHN_COMMON_ATTESTATION *PCWEBAUTHN_COMMON_ATTESTATION; -#endif //__midl - #define WEBAUTHN_ATTESTATION_TYPE_PACKED L"packed" #define WEBAUTHN_ATTESTATION_TYPE_U2F L"fido-u2f" #define WEBAUTHN_ATTESTATION_TYPE_TPM L"tpm" @@ -1067,38 +1050,27 @@ typedef const WEBAUTHN_COMMON_ATTESTATION *PCWEBAUTHN_COMMON_ATTESTATION; #define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_5 5 #define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_6 6 #define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_7 7 -#define WEBAUTHN_CREDENTIAL_ATTESTATION_CURRENT_VERSION WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_7 +#define WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_8 8 +#define WEBAUTHN_CREDENTIAL_ATTESTATION_CURRENT_VERSION WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_8 typedef struct _WEBAUTHN_CREDENTIAL_ATTESTATION { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; // Attestation format type - #ifdef __midl - PWSTR pwszFormatType; - #else PCWSTR pwszFormatType; - #endif // Size of cbAuthenticatorData. DWORD cbAuthenticatorData; // Authenticator data that was created for this credential. - #ifdef __midl - [size_is(cbAuthenticatorData)] - #else _Field_size_bytes_(cbAuthenticatorData) - #endif PBYTE pbAuthenticatorData; // Size of CBOR encoded attestation information //0 => encoded as CBOR null value. DWORD cbAttestation; //Encoded CBOR attestation information - #ifdef __midl - [size_is(cbAttestation)] - #else _Field_size_bytes_(cbAttestation) - #endif PBYTE pbAttestation; DWORD dwAttestationDecodeType; @@ -1107,29 +1079,17 @@ typedef struct _WEBAUTHN_CREDENTIAL_ATTESTATION { // NULL - not able to decode the CBOR attestation information // WEBAUTHN_ATTESTATION_DECODE_COMMON // PWEBAUTHN_COMMON_ATTESTATION; - #ifdef __midl - PBYTE pvAttestationDecode; - #else PVOID pvAttestationDecode; - #endif // The CBOR encoded Attestation Object to be returned to the RP. DWORD cbAttestationObject; - #ifdef __midl - [size_is(cbAttestationObject)] - #else _Field_size_bytes_(cbAttestationObject) - #endif PBYTE pbAttestationObject; // The CredentialId bytes extracted from the Authenticator Data. // Used by Edge to return to the RP. DWORD cbCredentialId; - #ifdef __midl - [size_is(cbCredentialId)] - #else _Field_size_bytes_(cbCredentialId) - #endif PBYTE pbCredentialId; // @@ -1165,11 +1125,7 @@ typedef struct _WEBAUTHN_CREDENTIAL_ATTESTATION { // DWORD cbUnsignedExtensionOutputs; - #ifdef __midl - [size_is(cbUnsignedExtensionOutputs)] - #else _Field_size_bytes_(cbUnsignedExtensionOutputs) - #endif PBYTE pbUnsignedExtensionOutputs; // @@ -1181,9 +1137,28 @@ typedef struct _WEBAUTHN_CREDENTIAL_ATTESTATION { // ThirdPartyPayment Credential or not. BOOL bThirdPartyPayment; + // + // Following fields have been added in WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_8 + // + + // Multiple WEBAUTHN_CTAP_TRANSPORT_* bits will be set corresponding to + // the transports that are supported. + DWORD dwTransports; + + // UTF-8 encoded JSON serialization of the client data. + DWORD cbClientDataJSON; + _Field_size_bytes_(cbClientDataJSON) + PBYTE pbClientDataJSON; + + // UTF-8 encoded JSON serialization of the RegistrationResponse. + DWORD cbRegistrationResponseJSON; + _Field_size_bytes_(cbRegistrationResponseJSON) + PBYTE pbRegistrationResponseJSON; + } WEBAUTHN_CREDENTIAL_ATTESTATION, *PWEBAUTHN_CREDENTIAL_ATTESTATION; typedef const WEBAUTHN_CREDENTIAL_ATTESTATION *PCWEBAUTHN_CREDENTIAL_ATTESTATION; + //+------------------------------------------------------------------------------------------ // authenticatorGetAssertion output. //------------------------------------------------------------------------------------------- @@ -1204,40 +1179,32 @@ typedef const WEBAUTHN_CREDENTIAL_ATTESTATION *PCWEBAUTHN_CREDENTIAL_ATTESTATION #define WEBAUTHN_ASSERTION_VERSION_3 3 #define WEBAUTHN_ASSERTION_VERSION_4 4 #define WEBAUTHN_ASSERTION_VERSION_5 5 -#define WEBAUTHN_ASSERTION_CURRENT_VERSION WEBAUTHN_ASSERTION_VERSION_5 +#define WEBAUTHN_ASSERTION_VERSION_6 6 +#define WEBAUTHN_ASSERTION_CURRENT_VERSION WEBAUTHN_ASSERTION_VERSION_6 typedef struct _WEBAUTHN_ASSERTION { // Version of this structure, to allow for modifications in the future. DWORD dwVersion; - // Authenticator data that was created for this assertion. + // Size of cbAuthenticatorData. DWORD cbAuthenticatorData; - #ifdef __midl - [size_is(cbAuthenticatorData)] - #else + // Authenticator data that was created for this assertion. _Field_size_bytes_(cbAuthenticatorData) - #endif PBYTE pbAuthenticatorData; - // Signature that was generated for this assertion. + // Size of pbSignature. DWORD cbSignature; - #ifdef __midl - [size_is(cbSignature)] - #else + // Signature that was generated for this assertion. _Field_size_bytes_(cbSignature) - #endif PBYTE pbSignature; // Credential that was used for this assertion. WEBAUTHN_CREDENTIAL Credential; - // UserId + // Size of User Id DWORD cbUserId; - #ifdef __midl - [size_is(cbUserId)] - #else + // UserId _Field_size_bytes_(cbUserId) - #endif PBYTE pbUserId; // @@ -1248,11 +1215,7 @@ typedef struct _WEBAUTHN_ASSERTION { // Size of pbCredLargeBlob DWORD cbCredLargeBlob; - #ifdef __midl - [size_is(cbCredLargeBlob)] - #else _Field_size_bytes_(cbCredLargeBlob) - #endif PBYTE pbCredLargeBlob; DWORD dwCredLargeBlobStatus; @@ -1261,9 +1224,6 @@ typedef struct _WEBAUTHN_ASSERTION { // Following fields have been added in WEBAUTHN_ASSERTION_VERSION_3 // - #ifdef __midl - [unique] - #endif PWEBAUTHN_HMAC_SECRET_SALT pHmacSecret; // @@ -1279,18 +1239,26 @@ typedef struct _WEBAUTHN_ASSERTION { // DWORD cbUnsignedExtensionOutputs; - #ifdef __midl - [size_is(cbUnsignedExtensionOutputs)] - #else _Field_size_bytes_(cbUnsignedExtensionOutputs) - #endif PBYTE pbUnsignedExtensionOutputs; + // + // Following fields have been added in WEBAUTHN_ASSERTION_VERSION_6 + // + + // UTF-8 encoded JSON serialization of the client data. + DWORD cbClientDataJSON; + _Field_size_bytes_(cbClientDataJSON) + PBYTE pbClientDataJSON; + + // UTF-8 encoded JSON serialization of the AuthenticationResponse. + DWORD cbAuthenticationResponseJSON; + _Field_size_bytes_(cbAuthenticationResponseJSON) + PBYTE pbAuthenticationResponseJSON; + } WEBAUTHN_ASSERTION, *PWEBAUTHN_ASSERTION; typedef const WEBAUTHN_ASSERTION *PCWEBAUTHN_ASSERTION; -#ifndef __midl - //+------------------------------------------------------------------------------------------ // APIs. //------------------------------------------------------------------------------------------- @@ -1304,10 +1272,6 @@ WINAPI WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable( _Out_ BOOL *pbIsUserVerifyingPlatformAuthenticatorAvailable); -HRESULT -WINAPI -EXPERIMENTAL_WebAuthNIsUserVerifyingNativePlatformAuthenticatorAvailable( - _Out_ BOOL *pbIsUserVerifyingNativePlatformAuthenticatorAvailable); HRESULT WINAPI @@ -1320,6 +1284,7 @@ WebAuthNAuthenticatorMakeCredential( _In_opt_ PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS pWebAuthNMakeCredentialOptions, _Outptr_result_maybenull_ PWEBAUTHN_CREDENTIAL_ATTESTATION *ppWebAuthNCredentialAttestation); + HRESULT WINAPI WebAuthNAuthenticatorGetAssertion( @@ -1368,6 +1333,18 @@ WebAuthNDeletePlatformCredential( _In_reads_bytes_(cbCredentialId) const BYTE *pbCredentialId ); +// Returns NTE_NOT_FOUND when authenticator details are not found. +HRESULT +WINAPI +WebAuthNGetAuthenticatorList( + _In_opt_ PCWEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS pWebAuthNGetAuthenticatorListOptions, + _Outptr_result_maybenull_ PWEBAUTHN_AUTHENTICATOR_DETAILS_LIST* ppAuthenticatorDetailsList); + +void +WINAPI +WebAuthNFreeAuthenticatorList( + _In_ PWEBAUTHN_AUTHENTICATOR_DETAILS_LIST pAuthenticatorDetailsList); + // // Returns the following Error Names: // L"Success" - S_OK @@ -1393,592 +1370,6 @@ WINAPI WebAuthNGetW3CExceptionDOMError( _In_ HRESULT hr); -typedef enum _EXPERIMENTAL_PLUGIN_AUTHENTICATOR_STATE -{ - PluginAuthenticatorState_Unknown = 0, - PluginAuthenticatorState_Disabled, - PluginAuthenticatorState_Enabled -} EXPERIMENTAL_PLUGIN_AUTHENTICATOR_STATE; - -// -// Plugin Authenticator API: WebAuthNPluginGetAuthenticatorState: Get Plugin Authenticator State -// -HRESULT -WINAPI -EXPERIMENTAL_WebAuthNPluginGetAuthenticatorState( - _In_ LPCWSTR pwszPluginClsId, - _Out_ EXPERIMENTAL_PLUGIN_AUTHENTICATOR_STATE* pluginAuthenticatorState -); - -// -// Plugin Authenticator API: WebAuthNAddPluginAuthenticator: Add Plugin Authenticator -// - -typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS { - // Authenticator Name - LPCWSTR pwszAuthenticatorName; - - // Plugin COM ClsId - LPCWSTR pwszPluginClsId; - - // Plugin RPID (Optional. Required for a nested WebAuthN call originating from a plugin) - LPCWSTR pwszPluginRpId; - - // Plugin Authenticator Logo for the Light themes. base64 svg (Optional) - LPCWSTR pwszLightThemeLogo; - - // Plugin Authenticator Logo for the Dark themes. base64 svg (Optional) - LPCWSTR pwszDarkThemeLogo; - - // CTAP CBOR encoded authenticatorGetInfo - DWORD cbAuthenticatorInfo; - _Field_size_bytes_(cbAuthenticatorInfo) - PBYTE pbAuthenticatorInfo; - -} EXPERIMENTAL_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS, *EXPERIMENTAL_PWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS; -typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS; - -typedef struct _EXPERIMENTAL2_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS { - // Authenticator Name - LPCWSTR pwszAuthenticatorName; - - // Plugin COM ClsId - LPCWSTR pwszPluginClsId; - - // Plugin RPID (Optional. Required for a nested WebAuthN call originating from a plugin) - LPCWSTR pwszPluginRpId; - - // Plugin Authenticator Logo for the Light themes. base64 svg (Optional) - LPCWSTR pwszLightThemeLogo; - - // Plugin Authenticator Logo for the Dark themes. base64 svg (Optional) - LPCWSTR pwszDarkThemeLogo; - - // CTAP CBOR encoded authenticatorGetInfo - DWORD cbAuthenticatorInfo; - _Field_size_bytes_(cbAuthenticatorInfo) - PBYTE pbAuthenticatorInfo; - - // List of supported RPs. Should be 0/nullptr if all RPs are supported. - DWORD cSupportedRpIds; - LPCWSTR *ppwszSupportedRpIds; - -} EXPERIMENTAL2_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS, *EXPERIMENTAL2_PWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS; -typedef const EXPERIMENTAL2_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS *EXPERIMENTAL2_PCWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS; - -typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE { - // Plugin operation signing Public Key - Used to sign the request in the EXPERIMENTAL_PluginPerformOperation. Refer pluginauthenticator.h. - DWORD cbOpSignPubKey; - _Field_size_bytes_(cbOpSignPubKey) - PBYTE pbOpSignPubKey; - -} EXPERIMENTAL_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE, *EXPERIMENTAL_PWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE; -typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE; - -HRESULT -WINAPI -EXPERIMENTAL_WebAuthNPluginAddAuthenticator( - _In_ EXPERIMENTAL_PCWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS pPluginAddAuthenticatorOptions, - _Outptr_result_maybenull_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE *ppPluginAddAuthenticatorResponse); - -HRESULT -WINAPI -EXPERIMENTAL2_WebAuthNPluginAddAuthenticator( - _In_ EXPERIMENTAL2_PCWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_OPTIONS pPluginAddAuthenticatorOptions, - _Outptr_result_maybenull_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE *ppPluginAddAuthenticatorResponse); - -void -WINAPI -EXPERIMENTAL_WebAuthNPluginFreeAddAuthenticatorResponse( - _In_opt_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_ADD_AUTHENTICATOR_RESPONSE pPluginAddAuthenticatorResponse); - -// -// Plugin Authenticator API: WebAuthNRemovePluginAuthenticator: Remove Plugin Authenticator -// - -HRESULT -WINAPI -EXPERIMENTAL_WebAuthNPluginRemoveAuthenticator( - _In_ LPCWSTR pwszPluginClsId); - -// -// Plugin Authenticator API: WebAuthNPluginAuthenticatorUpdateDetails: Update Credential Metadata for Browser AutoFill Scenarios -// - -typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS { - // Authenticator Name (Optional) - LPCWSTR pwszAuthenticatorName; - - // Plugin COM ClsId - LPCWSTR pwszPluginClsId; - - // Plugin COM New ClsId (Optional) - LPCWSTR pwszNewPluginClsId; - - // Plugin Authenticator Logo for the Light themes. base64 svg (Optional) - LPCWSTR pwszLightThemeLogo; - - // Plugin Authenticator Logo for the Dark themes. base64 svg (Optional) - LPCWSTR pwszDarkThemeLogo; - - // CTAP CBOR encoded authenticatorGetInfo (Optional) - DWORD cbAuthenticatorInfo; - _Field_size_bytes_(cbAuthenticatorInfo) - PBYTE pbAuthenticatorInfo; - -} EXPERIMENTAL_WEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS, *EXPERIMENTAL_PWEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS; -typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS; - -typedef struct _EXPERIMENTAL2_WEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS { - // Authenticator Name (Optional) - LPCWSTR pwszAuthenticatorName; - - // Plugin COM ClsId - LPCWSTR pwszPluginClsId; - - // Plugin COM New ClsId (Optional) - LPCWSTR pwszNewPluginClsId; - - // Plugin Authenticator Logo for the Light themes. base64 svg (Optional) - LPCWSTR pwszLightThemeLogo; - - // Plugin Authenticator Logo for the Dark themes. base64 svg (Optional) - LPCWSTR pwszDarkThemeLogo; - - // CTAP CBOR encoded authenticatorGetInfo (Optional) - DWORD cbAuthenticatorInfo; - _Field_size_bytes_(cbAuthenticatorInfo) - PBYTE pbAuthenticatorInfo; - - // List of supported RPs. Should be 0/nullptr if all RPs are supported. - DWORD cSupportedRpIds; - LPCWSTR *ppwszSupportedRpIds; - -} EXPERIMENTAL2_WEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS, *EXPERIMENTAL2_PWEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS; -typedef const EXPERIMENTAL2_WEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS *EXPERIMENTAL2_PCWEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS; - -HRESULT -WINAPI -EXPERIMENTAL_WebAuthNPluginUpdateAuthenticatorDetails( - _In_ EXPERIMENTAL_PCWEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS pPluginUpdateAuthenticatorDetails); - -HRESULT -WINAPI -EXPERIMENTAL2_WebAuthNPluginUpdateAuthenticatorDetails( - _In_ EXPERIMENTAL2_PCWEBAUTHN_PLUGIN_UPDATE_AUTHENTICATOR_DETAILS pPluginUpdateAuthenticatorDetails); - -#endif //__midl - -// -// Plugin Authenticator API: WebAuthNPluginAuthenticatorAddCredentials: Add Credential Metadata for Browser AutoFill Scenarios -// - - -typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS { - // Size of pbCredentialId. - DWORD cbCredentialId; - - // Credential Identifier bytes. This field is required. - #ifdef __midl - [size_is(cbCredentialId)] - #else - _Field_size_bytes_(cbCredentialId) - #endif - PBYTE pbCredentialId; - - // Identifier for the RP. This field is required. - PWSTR pwszRpId; - - // Contains the friendly name of the Relying Party, such as "Acme Corporation", "Widgets Inc" or "Awesome Site". - // This field is required. - PWSTR pwszRpName; - - // Identifier for the User. This field is required. - DWORD cbUserId; - - // User Identifier bytes. This field is required. - #ifdef __midl - [size_is(cbUserId)] - #else - _Field_size_bytes_(cbUserId) - #endif - PBYTE pbUserId; - - // Contains a detailed name for this account, such as "john.p.smith@example.com". - PWSTR pwszUserName; - - // For User: Contains the friendly name associated with the user account such as "John P. Smith". - PWSTR pwszUserDisplayName; - -} EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS, *EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS; -typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS; - -typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST { - // Plugin COM ClsId - PWSTR pwszPluginClsId; - - // count of credentials - DWORD cCredentialDetails; - - #ifdef __midl - [size_is(cCredentialDetails)] - #else - _Field_size_(cCredentialDetails) - #endif - EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS *pCredentialDetails; - -} EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST, *EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST; -typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST; - -#ifndef __midl - -HRESULT -WINAPI -EXPERIMENTAL_WebAuthNPluginAuthenticatorAddCredentials( - _In_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST pCredentialDetailsList); - -// -// Plugin Authenticator API: WebAuthNPluginAuthenticatorRemoveCredentials: Remove Credential Metadata for Browser AutoFill Scenarios -// - -HRESULT -WINAPI -EXPERIMENTAL_WebAuthNPluginAuthenticatorRemoveCredentials( - _In_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST pCredentialDetailsList); - -// -// Plugin Authenticator API: WebAuthNPluginAuthenticatorRemoveCredentials: Remove All Credential Metadata for Browser AutoFill Scenarios -// - -HRESULT -WINAPI -EXPERIMENTAL_WebAuthNPluginAuthenticatorRemoveAllCredentials( - _In_ LPCWSTR pwszPluginClsId); - -// -// Plugin Authenticator API: WebAuthNPluginAuthenticatorGetAllCredentials: Get All Credential Metadata cached for Browser AutoFill Scenarios -// -HRESULT -WINAPI -EXPERIMENTAL_WebAuthNPluginAuthenticatorGetAllCredentials( - _In_ LPCWSTR pwszPluginClsId, - _Outptr_result_maybenull_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST *ppCredentialDetailsList); - -// -// Hello UV API for Plugin: WebAuthNPluginPerformUv: Perform Hello UV related operations -// - -typedef enum _EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV_OPERATION_TYPE -{ - PerformUv = 1, - GetUvCount, - GetPubKey -} EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV_OPERATION_TYPE; - -typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV { - HWND hwnd; - GUID* transactionId; - EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV_OPERATION_TYPE type; - PCWSTR pwszUsername; - PCWSTR pwszContext; -} EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV, *EXPERIMENTAL_PWEBAUTHN_PLUGIN_PERFROM_UV; -typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_PERFORM_UV; - -typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV_RESPONSE { - DWORD cbResponse; - PBYTE pbResponse; -} EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV_RESPONSE, *EXPERIMENTAL_PWEBAUTHN_PLUGIN_PERFORM_UV_RESPONSE; -typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_PERFORM_UV_RESPONSE *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_PERFORM_UV_RESPONSE; - -HRESULT -WINAPI -EXPERIMENTAL_WebAuthNPluginPerformUv( - _In_ EXPERIMENTAL_PCWEBAUTHN_PLUGIN_PERFORM_UV pPluginPerformUv, - _Outptr_result_maybenull_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_PERFORM_UV_RESPONSE *ppPluginPerformUvRespose); - -void -WINAPI -EXPERIMENTAL_WebAuthNPluginFreePerformUvResponse( - _In_opt_ EXPERIMENTAL_PWEBAUTHN_PLUGIN_PERFORM_UV_RESPONSE ppPluginPerformUvResponse); - -#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS_VERSION_1 1 -#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS_CURRENT_VERSION EXPERIMENTAL_WEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS_VERSION_1 -typedef struct _EXPERIMENTAL_WEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS { - //Version of this structure, to allow for modifications in the future. - DWORD dwVersion; - - // Following have following values: - // +1 - TRUE - // 0 - Not defined - // -1 - FALSE - //up: "true" | "false" - LONG lUp; - //uv: "true" | "false" - LONG lUv; - //rk: "true" | "false" - LONG lRequireResidentKey; -} EXPERIMENTAL_WEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS, *EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS; -typedef const EXPERIMENTAL_WEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS *EXPERIMENTAL_PCWEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS; - -#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY_VERSION_1 1 -#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY_CURRENT_VERSION EXPERIMENTAL_WEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY_VERSION_1 -typedef struct _EXPERIMENTAL_WEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY { - //Version of this structure, to allow for modifications in the future. - DWORD dwVersion; - - // Key type - LONG lKty; - - // Hash Algorithm: ES256, ES384, ES512 - LONG lAlg; - - // Curve - LONG lCrv; - - //Size of "x" (X Coordinate) - DWORD cbX; - - //"x" (X Coordinate) data. Big Endian. - PBYTE pbX; - - //Size of "y" (Y Coordinate) - DWORD cbY; - - //"y" (Y Coordinate) data. Big Endian. - PBYTE pbY; -} EXPERIMENTAL_WEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY, *EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY; -typedef const EXPERIMENTAL_WEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY *EXPERIMENTAL_PCWEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY; - -#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION_VERSION_1 1 -#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION_CURRENT_VERSION EXPERIMENTAL_WEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION_VERSION_1 -typedef struct _EXPERIMENTAL_WEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION { - //Version of this structure, to allow for modifications in the future. - DWORD dwVersion; - - // Platform's key agreement public key - EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_ECC_PUBLIC_KEY pKeyAgreement; - - DWORD cbEncryptedSalt; - PBYTE pbEncryptedSalt; - - DWORD cbSaltAuth; - PBYTE pbSaltAuth; -} EXPERIMENTAL_WEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION, *EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION; -typedef const EXPERIMENTAL_WEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION *EXPERIMENTAL_PCWEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION; - -#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST_VERSION_1 1 -#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST_CURRENT_VERSION EXPERIMENTAL_WEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST_VERSION_1 -typedef struct _EXPERIMENTAL_WEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST { - //Version of this structure, to allow for modifications in the future. - DWORD dwVersion; - - //Input RP ID. Raw UTF8 bytes before conversion. - //These are the bytes to be hashed in the Authenticator Data. - DWORD cbRpId; - PBYTE pbRpId; - - //Client Data Hash - DWORD cbClientDataHash; - PBYTE pbClientDataHash; - - //RP Information - PCWEBAUTHN_RP_ENTITY_INFORMATION pRpInformation; - - //User Information - PCWEBAUTHN_USER_ENTITY_INFORMATION pUserInformation; - - // Crypto Parameters - WEBAUTHN_COSE_CREDENTIAL_PARAMETERS WebAuthNCredentialParameters; - - //Credentials used for exclusion - WEBAUTHN_CREDENTIAL_LIST CredentialList; - - //Optional extensions to parse when performing the operation. - DWORD cbCborExtensionsMap; - PBYTE pbCborExtensionsMap; - - // Authenticator Options (Optional) - EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS pAuthenticatorOptions; - - // Pin Auth (Optional) - BOOL fEmptyPinAuth; // Zero length PinAuth is included in the request - DWORD cbPinAuth; - PBYTE pbPinAuth; - - //"hmac-secret": true extension - LONG lHmacSecretExt; - - // "hmac-secret-mc" extension - EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION pHmacSecretMcExtension; - - //"prf" extension - LONG lPrfExt; - DWORD cbHmacSecretSaltValues; - PBYTE pbHmacSecretSaltValues; - - //"credProtect" extension. Nonzero if present - DWORD dwCredProtect; - - // Nonzero if present - DWORD dwPinProtocol; - - // Nonzero if present - DWORD dwEnterpriseAttestation; - - //"credBlob" extension. Nonzero if present - DWORD cbCredBlobExt; - PBYTE pbCredBlobExt; - - //"largeBlobKey": true extension - LONG lLargeBlobKeyExt; - - //"largeBlob": extension - DWORD dwLargeBlobSupport; - - //"minPinLength": true extension - LONG lMinPinLengthExt; - - // "json" extension. Nonzero if present - DWORD cbJsonExt; - PBYTE pbJsonExt; -} EXPERIMENTAL_WEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST, *EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST; -typedef const EXPERIMENTAL_WEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST *EXPERIMENTAL_PCWEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST; - -_Success_(return == S_OK) -HRESULT -WINAPI -EXPERIMENTAL_WebAuthNEncodeMakeCredentialResponse( - _In_ PCWEBAUTHN_CREDENTIAL_ATTESTATION pCredentialAttestation, - _Out_ DWORD *pcbResp, - _Outptr_result_buffer_maybenull_(*pcbResp) BYTE **ppbResp - ); - -_Success_(return == S_OK) -HRESULT -WINAPI -EXPERIMENTAL_WebAuthNDecodeMakeCredentialRequest( - _In_ DWORD cbEncoded, - _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, - _Outptr_ EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST *ppMakeCredentialRequest - ); - -void -WINAPI -EXPERIMENTAL_WebAuthNFreeDecodedMakeCredentialRequest( - _In_opt_ EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_MAKE_CREDENTIAL_REQUEST pMakeCredentialRequest - ); - -#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST_VERSION_1 1 -#define EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST_CURRENT_VERSION EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST_VERSION_1 -typedef struct _EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST { - //Version of this structure, to allow for modifications in the future. - DWORD dwVersion; - - //RP ID. After UTF8 to Unicode conversion, - PCWSTR pwszRpId; - - //Input RP ID. Raw UTF8 bytes before conversion. - //These are the bytes to be hashed in the Authenticator Data. - DWORD cbRpId; - PBYTE pbRpId; - - //Client Data Hash - DWORD cbClientDataHash; - PBYTE pbClientDataHash; - - //Credentials used for inclusion - WEBAUTHN_CREDENTIAL_LIST CredentialList; - - //Optional extensions to parse when performing the operation. - DWORD cbCborExtensionsMap; - PBYTE pbCborExtensionsMap; - - // Authenticator Options (Optional) - EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_AUTHENTICATOR_OPTIONS pAuthenticatorOptions; - - // Pin Auth (Optional) - BOOL fEmptyPinAuth; // Zero length PinAuth is included in the request - DWORD cbPinAuth; - PBYTE pbPinAuth; - - // HMAC Salt Extension (Optional) - EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_HMAC_SALT_EXTENSION pHmacSaltExtension; - - // PRF Extension - DWORD cbHmacSecretSaltValues; - PBYTE pbHmacSecretSaltValues; - - DWORD dwPinProtocol; - - //"credBlob": true extension - LONG lCredBlobExt; - - //"largeBlobKey": true extension - LONG lLargeBlobKeyExt; - - //"largeBlob" extension - DWORD dwCredLargeBlobOperation; - DWORD cbCredLargeBlobCompressed; - PBYTE pbCredLargeBlobCompressed; - DWORD dwCredLargeBlobOriginalSize; - - // "json" extension. Nonzero if present - DWORD cbJsonExt; - PBYTE pbJsonExt; -} EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST, *EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST; -typedef const EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST *EXPERIMENTAL_PCWEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST; - -_Success_(return == S_OK) -HRESULT -WINAPI -EXPERIMENTAL_WebAuthNDecodeGetAssertionRequest( - _In_ DWORD cbEncoded, - _In_reads_bytes_(cbEncoded) const BYTE *pbEncoded, - _Outptr_ EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST *ppGetAssertionRequest - ); - -void -WINAPI -EXPERIMENTAL_WebAuthNFreeDecodedGetAssertionRequest( - _In_opt_ EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_GET_ASSERTION_REQUEST pGetAssertionRequest - ); - -typedef struct _EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_RESPONSE { - // [1] credential (optional) - // [2] authenticatorData - // [3] signature - WEBAUTHN_ASSERTION WebAuthNAssertion; - - // [4] user (optional) - PCWEBAUTHN_USER_ENTITY_INFORMATION pUserInformation; - - // [5] numberOfCredentials (optional) - DWORD dwNumberOfCredentials; - - // [6] userSelected (optional) - LONG lUserSelected; - - // [7] largeBlobKey (optional) - DWORD cbLargeBlobKey; - PBYTE pbLargeBlobKey; - - // [8] unsignedExtensionOutputs - DWORD cbUnsignedExtensionOutputs; - PBYTE pbUnsignedExtensionOutputs; -} EXPERIMENTAL_WEBAUTHN_CTAPCBOR_GET_ASSERTION_RESPONSE, *EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_GET_ASSERTION_RESPONSE; -typedef const EXPERIMENTAL_PWEBAUTHN_CTAPCBOR_GET_ASSERTION_RESPONSE *EXPERIMENTAL_PCWEBAUTHN_CTAPCBOR_GET_ASSERTION_RESPONSE; - -_Success_(return == S_OK) -HRESULT -WINAPI -EXPERIMENTAL_WebAuthNEncodeGetAssertionResponse( - _In_ EXPERIMENTAL_PCWEBAUTHN_CTAPCBOR_GET_ASSERTION_RESPONSE pGetAssertionResponse, - _Out_ DWORD *pcbResp, - _Outptr_result_buffer_maybenull_(*pcbResp) BYTE **ppbResp - ); - -#endif //__midl - #ifdef __cplusplus } // Balance extern "C" above @@ -1986,3 +1377,5 @@ EXPERIMENTAL_WebAuthNEncodeGetAssertionResponse( #endif // WINAPI_FAMILY_PARTITION #pragma endregion + +#endif // __WEBAUTHN_H_ \ No newline at end of file diff --git a/ztypes_webauthn.go b/ztypes_webauthn.go index 5fd0523..4d7203c 100644 --- a/ztypes_webauthn.go +++ b/ztypes_webauthn.go @@ -27,56 +27,69 @@ type ( DwUsedTransport uint32 CbUnsignedExtensionOutputs uint32 PbUnsignedExtensionOutputs *uint8 + CbClientDataJSON uint32 + PbClientDataJSON *uint8 + CbAuthenticationResponseJSON uint32 + PbAuthenticationResponseJSON *uint8 } _WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS struct { - DwVersion uint32 - DwTimeoutMilliseconds uint32 - CredentialList _WEBAUTHN_CREDENTIALS - Extensions _WEBAUTHN_EXTENSIONS - DwAuthenticatorAttachment uint32 - DwUserVerificationRequirement uint32 - DwFlags uint32 - PwszU2fAppId *uint16 - PbU2fAppId *int32 - PCancellationId *_GUID - PAllowCredentialList *_WEBAUTHN_CREDENTIAL_LIST - DwCredLargeBlobOperation uint32 - CbCredLargeBlob uint32 - PbCredLargeBlob *uint8 - PHmacSecretSaltValues *_WEBAUTHN_HMAC_SECRET_SALT_VALUES - BBrowserInPrivateMode int32 - PLinkedDevice *_CTAPCBOR_HYBRID_STORAGE_LINKED_DATA - BAutoFill int32 - CbJsonExt uint32 - PbJsonExt *uint8 - CCredentialHints uint32 - PpwszCredentialHints **uint16 - } - _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS struct { DwVersion uint32 DwTimeoutMilliseconds uint32 CredentialList _WEBAUTHN_CREDENTIALS Extensions _WEBAUTHN_EXTENSIONS DwAuthenticatorAttachment uint32 - BRequireResidentKey int32 DwUserVerificationRequirement uint32 - DwAttestationConveyancePreference uint32 DwFlags uint32 + PwszU2fAppId *uint16 + PbU2fAppId *int32 PCancellationId *_GUID - PExcludeCredentialList *_WEBAUTHN_CREDENTIAL_LIST - DwEnterpriseAttestation uint32 - DwLargeBlobSupport uint32 - BPreferResidentKey int32 + PAllowCredentialList *_WEBAUTHN_CREDENTIAL_LIST + DwCredLargeBlobOperation uint32 + CbCredLargeBlob uint32 + PbCredLargeBlob *uint8 + PHmacSecretSaltValues *_WEBAUTHN_HMAC_SECRET_SALT_VALUES BBrowserInPrivateMode int32 - BEnablePrf int32 PLinkedDevice *_CTAPCBOR_HYBRID_STORAGE_LINKED_DATA + BAutoFill int32 CbJsonExt uint32 PbJsonExt *uint8 - PPRFGlobalEval *_WEBAUTHN_HMAC_SECRET_SALT CCredentialHints uint32 PpwszCredentialHints **uint16 - BThirdPartyPayment int32 - Pad_cgo_0 [4]byte + PwszRemoteWebOrigin *uint16 + CbPublicKeyCredentialRequestOptionsJSON uint32 + PbPublicKeyCredentialRequestOptionsJSON *uint8 + CbAuthenticatorId uint32 + PbAuthenticatorId *uint8 + } + _WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS struct { + DwVersion uint32 + DwTimeoutMilliseconds uint32 + CredentialList _WEBAUTHN_CREDENTIALS + Extensions _WEBAUTHN_EXTENSIONS + DwAuthenticatorAttachment uint32 + BRequireResidentKey int32 + DwUserVerificationRequirement uint32 + DwAttestationConveyancePreference uint32 + DwFlags uint32 + PCancellationId *_GUID + PExcludeCredentialList *_WEBAUTHN_CREDENTIAL_LIST + DwEnterpriseAttestation uint32 + DwLargeBlobSupport uint32 + BPreferResidentKey int32 + BBrowserInPrivateMode int32 + BEnablePrf int32 + PLinkedDevice *_CTAPCBOR_HYBRID_STORAGE_LINKED_DATA + CbJsonExt uint32 + PbJsonExt *uint8 + PPRFGlobalEval *_WEBAUTHN_HMAC_SECRET_SALT + CCredentialHints uint32 + PpwszCredentialHints **uint16 + BThirdPartyPayment int32 + PwszRemoteWebOrigin *uint16 + CbPublicKeyCredentialCreationOptionsJSON uint32 + PbPublicKeyCredentialCreationOptionsJSON *uint8 + CbAuthenticatorId uint32 + PbAuthenticatorId *uint8 } _WEBAUTHN_CLIENT_DATA struct { DwVersion uint32 @@ -150,7 +163,11 @@ type ( PbUnsignedExtensionOutputs *uint8 PHmacSecret *_WEBAUTHN_HMAC_SECRET_SALT BThirdPartyPayment int32 - Pad_cgo_0 [4]byte + DwTransports uint32 + CbClientDataJSON uint32 + PbClientDataJSON *uint8 + CbRegistrationResponseJSON uint32 + PbRegistrationResponseJSON *uint8 } _WEBAUTHN_CREDENTIAL_DETAILS struct { DwVersion uint32 @@ -164,7 +181,7 @@ type ( CbAuthenticatorLogo uint32 PbAuthenticatorLogo *uint8 BThirdPartyPayment int32 - Pad_cgo_0 [4]byte + DwTransports uint32 } _WEBAUTHN_CREDENTIAL_DETAILS_LIST struct { CCredentialDetails uint32 From f8369078d9bdf004160885f1d0e46e4aaed09071 Mon Sep 17 00:00:00 2001 From: Sebastijan Zindl Date: Fri, 20 Feb 2026 11:56:39 +0100 Subject: [PATCH 6/8] fix(BRIDGE-475): Windows 10 22H2 fix --- consts.go | 75 ++++++++++----- versions.go | 1 + winhello.go | 227 ++++++++++++++++++++++++++++++++++++++++----- ztypes_webauthn.go | 17 ++++ 4 files changed, 273 insertions(+), 47 deletions(-) diff --git a/consts.go b/consts.go index 986917a..23cda91 100644 --- a/consts.go +++ b/consts.go @@ -46,7 +46,8 @@ const ( WinHelloCTAPTransportTest WinHelloCTAPTransportInternal WinHelloCTAPTransportHybrid - WinHelloCTAPTransportFlagsMask WinHelloCOSEAlgorithm = 0x0000003F + WinHelloCTAPTransportSmartCard + WinHelloCTAPTransportFlagsMask WinHelloCOSEAlgorithm = 0x0000007F ) type WinHelloUserVerification uint32 @@ -135,25 +136,30 @@ const ( ) type AuthenticatorGetAssertionOptions struct { - Timeout time.Duration - AuthenticatorAttachment WinHelloAuthenticatorAttachment - UserVerificationRequirement WinHelloUserVerificationRequirement - U2FAppID string - CancellationID *windows.GUID - CredentialLargeBlobOperation WinHelloCredentialLargeBlobOperation - CredentialLargeBlob []byte - BrowserInPrivateMode bool - AutoFill bool - JsonExt []byte - CredentialHints []webauthntypes.PublicKeyCredentialHint + Timeout time.Duration + AuthenticatorAttachment WinHelloAuthenticatorAttachment + UserVerificationRequirement WinHelloUserVerificationRequirement + U2FAppID string + CancellationID *windows.GUID + CredentialLargeBlobOperation WinHelloCredentialLargeBlobOperation + CredentialLargeBlob []byte + BrowserInPrivateMode bool + AutoFill bool + JsonExt []byte + CredentialHints []webauthntypes.PublicKeyCredentialHint + RemoteWebOrigin string + PublicKeyCredentialRequestOptionsJSON []byte + AuthenticatorID []byte } type WinHelloGetAssertionResponse struct { *ctaptypes.AuthenticatorGetAssertionResponse - CredLargeBlob []byte - CredLargeBlobStatus WinHelloCredentialLargeBlobStatus - UsedTransport []webauthntypes.AuthenticatorTransport - hmacSecret *webauthntypes.AuthenticationExtensionsPRFValues + CredLargeBlob []byte + CredLargeBlobStatus WinHelloCredentialLargeBlobStatus + UsedTransport []webauthntypes.AuthenticatorTransport + ClientDataJSON []byte + AuthenticationResponseJSON []byte + hmacSecret *webauthntypes.AuthenticationExtensionsPRFValues } func (a *_WEBAUTHN_ASSERTION) ToGetAssertionResponse() ( @@ -185,22 +191,41 @@ func (a *_WEBAUTHN_ASSERTION) ToGetAssertionResponse() ( winHelloResp := &WinHelloGetAssertionResponse{ AuthenticatorGetAssertionResponse: resp, - CredLargeBlob: bytes.Clone(unsafe.Slice(a.PbCredLargeBlob, a.CbCredLargeBlob)), - CredLargeBlobStatus: WinHelloCredentialLargeBlobStatus(a.DwCredLargeBlobStatus), - UsedTransport: flagsToTransports(a.DwUsedTransport), } - if a.PHmacSecret != nil { + if a.DwVersion >= 2 { + winHelloResp.CredLargeBlob = bytes.Clone(unsafe.Slice(a.PbCredLargeBlob, a.CbCredLargeBlob)) + winHelloResp.CredLargeBlobStatus = WinHelloCredentialLargeBlobStatus(a.DwCredLargeBlobStatus) + } + + if a.DwVersion >= 3 && a.PHmacSecret != nil { winHelloResp.hmacSecret = &webauthntypes.AuthenticationExtensionsPRFValues{ First: bytes.Clone(unsafe.Slice(a.PHmacSecret.PbFirst, a.PHmacSecret.CbFirst)), Second: bytes.Clone(unsafe.Slice(a.PHmacSecret.PbSecond, a.PHmacSecret.CbSecond)), } } - unsignedExtensionOutputsRaw := bytes.Clone(unsafe.Slice(a.PbUnsignedExtensionOutputs, a.CbUnsignedExtensionOutputs)) - if unsignedExtensionOutputsRaw != nil && len(unsignedExtensionOutputsRaw) > 0 { - if err := cbor.Unmarshal(unsignedExtensionOutputsRaw, &resp.UnsignedExtensionOutputs); err != nil { - return nil, err + if a.DwVersion >= 4 { + winHelloResp.UsedTransport = flagsToTransports(a.DwUsedTransport) + } + + if a.DwVersion >= 5 { + unsignedExtensionOutputsRaw := bytes.Clone(unsafe.Slice(a.PbUnsignedExtensionOutputs, a.CbUnsignedExtensionOutputs)) + if unsignedExtensionOutputsRaw != nil && len(unsignedExtensionOutputsRaw) > 0 { + if err := cbor.Unmarshal(unsignedExtensionOutputsRaw, &resp.UnsignedExtensionOutputs); err != nil { + return nil, err + } + } + } + + if a.DwVersion >= 6 { + clientDataJSONRaw := bytes.Clone(unsafe.Slice(a.PbClientDataJSON, a.CbClientDataJSON)) + if clientDataJSONRaw != nil && len(clientDataJSONRaw) > 0 { + winHelloResp.ClientDataJSON = clientDataJSONRaw + } + authenticationResponseJSONRaw := bytes.Clone(unsafe.Slice(a.PbAuthenticationResponseJSON, a.CbAuthenticationResponseJSON)) + if authenticationResponseJSONRaw != nil && len(authenticationResponseJSONRaw) > 0 { + winHelloResp.AuthenticationResponseJSON = authenticationResponseJSONRaw } } @@ -220,6 +245,8 @@ func flagsToTransports(flags uint32) []webauthntypes.AuthenticatorTransport { case flags&uint32(WinHelloCTAPTransportInternal) != 0: tr = append(tr, webauthntypes.AuthenticatorTransportInternal) case flags&uint32(WinHelloCTAPTransportHybrid) != 0: + case flags&uint32(WinHelloCTAPTransportSmartCard) != 0: + tr = append(tr, webauthntypes.AuthenticatorTransportSmartCard) tr = append(tr, webauthntypes.AuthenticatorTransportHybrid) } diff --git a/versions.go b/versions.go index b89b6c7..775af1c 100644 --- a/versions.go +++ b/versions.go @@ -14,6 +14,7 @@ type currentVersion struct { commonAttestation uint32 credentialAttestation uint32 assertion uint32 + authenticatorDetails uint32 } func availableVersions(ver uint32) *currentVersion { diff --git a/winhello.go b/winhello.go index 7f1ae0f..680aed4 100644 --- a/winhello.go +++ b/winhello.go @@ -4,10 +4,12 @@ package winhello import ( + "bytes" "encoding/base64" "errors" "fmt" "log/slog" + "slices" "unsafe" "github.com/go-ctap/ctaphid/pkg/webauthntypes" @@ -15,19 +17,35 @@ import ( ) var ( - modWebAuthn = windows.NewLazyDLL("webauthn.dll") - procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") - procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") - procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") - currVer = availableVersions(APIVersionNumber()) + modWebAuthn = windows.NewLazyDLL("webauthn.dll") + procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") + procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable = modWebAuthn.NewProc("WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable") + procWebAuthNAuthenticatorMakeCredential = modWebAuthn.NewProc("WebAuthNAuthenticatorMakeCredential") + procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") + procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") + procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") + procWebAuthNGetCancellationId = modWebAuthn.NewProc("WebAuthNGetCancellationId") + procWebAuthNCancelCurrentOperation = modWebAuthn.NewProc("WebAuthNCancelCurrentOperation") + procWebAuthNGetPlatformCredentialList = modWebAuthn.NewProc("WebAuthNGetPlatformCredentialList") + procWebAuthNFreePlatformCredentialList = modWebAuthn.NewProc("WebAuthNFreePlatformCredentialList") + procWebAuthNDeletePlatformCredential = modWebAuthn.NewProc("WebAuthNDeletePlatformCredential") + procWebAuthNGetAuthenticatorList = modWebAuthn.NewProc("WebAuthNGetAuthenticatorList") + procWebAuthNFreeAuthenticatorList = modWebAuthn.NewProc("WebAuthNFreeAuthenticatorList") + procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") + procWebAuthNGetW3CExceptionDOMError = modWebAuthn.NewProc("WebAuthNGetW3CExceptionDOMError") + currVer = availableVersions(APIVersionNumber()) ) type WebAuthnCredentialDetails struct { - CredentialID []byte - RP webauthntypes.PublicKeyCredentialRpEntity - User webauthntypes.PublicKeyCredentialUserEntity - Removable bool - BackedUp bool + CredentialID []byte + RP webauthntypes.PublicKeyCredentialRpEntity + User webauthntypes.PublicKeyCredentialUserEntity + Removable bool + BackedUp bool + AuthenticatorName string + AuthenticatorLogo []byte + ThirdPartyPayment bool + Transports []webauthntypes.AuthenticatorTransport } func GetAssertion( @@ -43,19 +61,23 @@ func GetAssertion( } opts := &_WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS{ - DwVersion: currVer.authenticatorGetAssertionOptions, - DwTimeoutMilliseconds: uint32(winHelloOpts.Timeout.Milliseconds()), - CredentialList: _WEBAUTHN_CREDENTIALS{}, // basically deprecated, baseline supports pAllowCredentialList - DwAuthenticatorAttachment: uint32(winHelloOpts.AuthenticatorAttachment), - DwUserVerificationRequirement: uint32(winHelloOpts.UserVerificationRequirement), - DwFlags: 0, // user only in version 8 for PRF Global Eval - DwCredLargeBlobOperation: uint32(winHelloOpts.CredentialLargeBlobOperation), - CbCredLargeBlob: uint32(len(winHelloOpts.CredentialLargeBlob)), - PbCredLargeBlob: unsafe.SliceData(winHelloOpts.CredentialLargeBlob), - BBrowserInPrivateMode: boolToInt32(winHelloOpts.BrowserInPrivateMode), - BAutoFill: boolToInt32(winHelloOpts.AutoFill), - CbJsonExt: uint32(len(winHelloOpts.JsonExt)), - PbJsonExt: unsafe.SliceData(winHelloOpts.JsonExt), + DwVersion: currVer.authenticatorGetAssertionOptions, + DwTimeoutMilliseconds: uint32(winHelloOpts.Timeout.Milliseconds()), + CredentialList: _WEBAUTHN_CREDENTIALS{}, // basically deprecated, baseline supports pAllowCredentialList + DwAuthenticatorAttachment: uint32(winHelloOpts.AuthenticatorAttachment), + DwUserVerificationRequirement: uint32(winHelloOpts.UserVerificationRequirement), + DwFlags: 0, // user only in version 8 for PRF Global Eval + DwCredLargeBlobOperation: uint32(winHelloOpts.CredentialLargeBlobOperation), + CbCredLargeBlob: uint32(len(winHelloOpts.CredentialLargeBlob)), + PbCredLargeBlob: unsafe.SliceData(winHelloOpts.CredentialLargeBlob), + BBrowserInPrivateMode: boolToInt32(winHelloOpts.BrowserInPrivateMode), + BAutoFill: boolToInt32(winHelloOpts.AutoFill), + CbJsonExt: uint32(len(winHelloOpts.JsonExt)), + PbJsonExt: unsafe.SliceData(winHelloOpts.JsonExt), + CbPublicKeyCredentialRequestOptionsJSON: uint32(len(winHelloOpts.PublicKeyCredentialRequestOptionsJSON)), + PbPublicKeyCredentialRequestOptionsJSON: unsafe.SliceData(winHelloOpts.PublicKeyCredentialRequestOptionsJSON), + CbAuthenticatorId: uint32(len(winHelloOpts.AuthenticatorID)), + PbAuthenticatorId: unsafe.SliceData(winHelloOpts.AuthenticatorID), } credExList := make([]*_WEBAUTHN_CREDENTIAL_EX, len(allowList)) @@ -117,6 +139,10 @@ func GetAssertion( opts.PpwszCredentialHints = unsafe.SliceData(credHints) } + if winHelloOpts.RemoteWebOrigin != "" { + opts.PwszRemoteWebOrigin = windows.StringToUTF16Ptr(winHelloOpts.RemoteWebOrigin) + } + if extInputs != nil { exts := make([]_WEBAUTHN_EXTENSION, 0) @@ -261,3 +287,158 @@ func APIVersionNumber() uint32 { r1, _, _ := procWebAuthNGetApiVersionNumber.Call() return uint32(r1) } + +func CancellationID() (*windows.GUID, error) { + var cancellationIDPtr windows.GUID + + r1, _, _ := procWebAuthNGetCancellationId.Call( + uintptr(unsafe.Pointer(&cancellationIDPtr)), + ) + if hr := windows.Handle(r1); hr != windows.S_OK { + return nil, windows.Errno(hr) + } + + return &cancellationIDPtr, nil +} + +func ErrorName(hr windows.Handle) string { + r1, _, _ := procWebAuthNGetErrorName.Call(uintptr(hr)) + return windows.UTF16PtrToString((*uint16)(unsafe.Pointer(r1))) +} + +func PlatformCredentialList(rpID string, browserInPrivateMode bool) ([]*WebAuthnCredentialDetails, error) { + var rpIDPtr *uint16 + if rpID != "" { + rpIDPtr = windows.StringToUTF16Ptr(rpID) + } + + credDetailsListPtr := new(_WEBAUTHN_CREDENTIAL_DETAILS_LIST) + + r1, _, _ := procWebAuthNGetPlatformCredentialList.Call( + uintptr(unsafe.Pointer(&_WEBAUTHN_GET_CREDENTIALS_OPTIONS{ + DwVersion: currVer.getCredentialsOptions, + PwszRpId: rpIDPtr, + BBrowserInPrivateMode: boolToInt32(browserInPrivateMode), + })), + uintptr(unsafe.Pointer(&credDetailsListPtr)), + ) + if hr := windows.Handle(r1); hr != windows.S_OK { + return nil, windows.Errno(hr) + } + + credListDetails := slices.Clone(unsafe.Slice(credDetailsListPtr.PpCredentialDetails, credDetailsListPtr.CCredentialDetails)) + + list := make([]*WebAuthnCredentialDetails, len(credListDetails)) + for i, cred := range credListDetails { + credID := bytes.Clone(unsafe.Slice(cred.PbCredentialID, cred.CbCredentialID)) + + list[i] = &WebAuthnCredentialDetails{ + CredentialID: credID, + RP: webauthntypes.PublicKeyCredentialRpEntity{ + ID: windows.UTF16PtrToString(cred.PRpInformation.PwszId), + Name: windows.UTF16PtrToString(cred.PRpInformation.PwszName), + }, + User: webauthntypes.PublicKeyCredentialUserEntity{ + ID: bytes.Clone(unsafe.Slice(cred.PUserInformation.PbId, cred.PUserInformation.CbId)), + DisplayName: windows.UTF16PtrToString(cred.PUserInformation.PwszDisplayName), + Name: windows.UTF16PtrToString(cred.PUserInformation.PwszName), + }, + Removable: int32ToBool(cred.BRemovable), + } + + if cred.DwVersion >= 2 { + list[i].BackedUp = int32ToBool(cred.BBackedUp) + } + + if cred.DwVersion >= 3 { + list[i].AuthenticatorName = windows.UTF16PtrToString(cred.PwszAuthenticatorName) + list[i].AuthenticatorLogo = bytes.Clone(unsafe.Slice(cred.PbAuthenticatorLogo, cred.CbAuthenticatorLogo)) + list[i].ThirdPartyPayment = int32ToBool(cred.BThirdPartyPayment) + } + + if cred.DwVersion >= 4 { + list[i].Transports = flagsToTransports(cred.DwTransports) + } + } + + if _, _, err := procWebAuthNFreePlatformCredentialList.Call( + uintptr(unsafe.Pointer(credDetailsListPtr)), + ); !errors.Is(err, windows.NTE_OP_OK) { + return nil, err + } + + return list, nil +} + +type WebAuthnAuthenticatorDetails struct { + ID []byte + Name string + Logo []byte + Locked bool +} + +func AuthenticatorList() ([]*WebAuthnAuthenticatorDetails, error) { + authenticatorListPtr := new(_WEBAUTHN_AUTHENTICATOR_DETAILS_LIST) + + r1, _, _ := procWebAuthNGetAuthenticatorList.Call( + uintptr(unsafe.Pointer(&_WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS{ + DwVersion: currVer.authenticatorDetails, + })), + uintptr(unsafe.Pointer(&authenticatorListPtr)), + ) + if hr := windows.Handle(r1); hr != windows.S_OK { + return nil, windows.Errno(hr) + } + + authenticatorListDetails := slices.Clone(unsafe.Slice( + authenticatorListPtr.PpAuthenticatorDetails, + authenticatorListPtr.CAuthenticatorDetails, + )) + + list := make([]*WebAuthnAuthenticatorDetails, len(authenticatorListDetails)) + for i, cred := range authenticatorListDetails { + authenticatorID := bytes.Clone(unsafe.Slice(cred.PbAuthenticatorId, cred.CbAuthenticatorId)) + authenticatorLogo := bytes.Clone(unsafe.Slice(cred.PbAuthenticatorLogo, cred.CbAuthenticatorLogo)) + + list[i] = &WebAuthnAuthenticatorDetails{ + ID: authenticatorID, + Name: windows.UTF16PtrToString(cred.PwszAuthenticatorName), + Logo: authenticatorLogo, + Locked: int32ToBool(cred.BLocked), + } + } + + if _, _, err := procWebAuthNFreeAuthenticatorList.Call( + uintptr(unsafe.Pointer(authenticatorListPtr)), + ); !errors.Is(err, windows.NTE_OP_OK) { + return nil, err + } + + return list, nil +} + +func W3CExceptionDOMError() (windows.Handle, error) { + var ret windows.Handle + + r1, _, _ := procWebAuthNGetW3CExceptionDOMError.Call( + uintptr(unsafe.Pointer(&ret)), + ) + if hr := windows.Handle(r1); hr != windows.S_OK { + return 0, windows.Errno(hr) + } + + return ret, nil +} + +func IsUserVerifyingPlatformAuthenticatorAvailable() (bool, error) { + var isAvailable bool + + r1, _, _ := procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable.Call( + uintptr(unsafe.Pointer(&isAvailable)), + ) + if hr := windows.Handle(r1); hr != windows.S_OK { + return false, windows.Errno(hr) + } + + return isAvailable, nil +} diff --git a/ztypes_webauthn.go b/ztypes_webauthn.go index 4d7203c..77cd436 100644 --- a/ztypes_webauthn.go +++ b/ztypes_webauthn.go @@ -261,6 +261,23 @@ type ( WEncodedTunnelServerDomain uint16 Pad_cgo_0 [6]byte } + _WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS struct { + DwVersion uint32 + } + _WEBAUTHN_AUTHENTICATOR_DETAILS struct { + DwVersion uint32 + CbAuthenticatorId uint32 + PbAuthenticatorId *uint8 + PwszAuthenticatorName *uint16 + CbAuthenticatorLogo uint32 + PbAuthenticatorLogo *uint8 + BLocked int32 + Pad_cgo_0 [4]byte + } + _WEBAUTHN_AUTHENTICATOR_DETAILS_LIST struct { + CAuthenticatorDetails uint32 + PpAuthenticatorDetails **_WEBAUTHN_AUTHENTICATOR_DETAILS + } ) func int32ToBool(i int32) bool { From d85bf4aca9b8216d0f8f27d2d5fb15a54206b8e1 Mon Sep 17 00:00:00 2001 From: Sebastijan Zindl Date: Fri, 20 Feb 2026 13:39:13 +0100 Subject: [PATCH 7/8] fix(BRIDGE-474): return an erorr instead of panic when dealing with unsuported version of windows --- winhello.go | 76 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 17 deletions(-) diff --git a/winhello.go b/winhello.go index 680aed4..bf74d7b 100644 --- a/winhello.go +++ b/winhello.go @@ -17,25 +17,63 @@ import ( ) var ( - modWebAuthn = windows.NewLazyDLL("webauthn.dll") - procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") - procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable = modWebAuthn.NewProc("WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable") - procWebAuthNAuthenticatorMakeCredential = modWebAuthn.NewProc("WebAuthNAuthenticatorMakeCredential") - procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") - procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") - procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") - procWebAuthNGetCancellationId = modWebAuthn.NewProc("WebAuthNGetCancellationId") - procWebAuthNCancelCurrentOperation = modWebAuthn.NewProc("WebAuthNCancelCurrentOperation") - procWebAuthNGetPlatformCredentialList = modWebAuthn.NewProc("WebAuthNGetPlatformCredentialList") - procWebAuthNFreePlatformCredentialList = modWebAuthn.NewProc("WebAuthNFreePlatformCredentialList") - procWebAuthNDeletePlatformCredential = modWebAuthn.NewProc("WebAuthNDeletePlatformCredential") - procWebAuthNGetAuthenticatorList = modWebAuthn.NewProc("WebAuthNGetAuthenticatorList") - procWebAuthNFreeAuthenticatorList = modWebAuthn.NewProc("WebAuthNFreeAuthenticatorList") - procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") - procWebAuthNGetW3CExceptionDOMError = modWebAuthn.NewProc("WebAuthNGetW3CExceptionDOMError") - currVer = availableVersions(APIVersionNumber()) + ErrWindowsVersionNotSupported = errors.New("windows version not supported, requires Windows 10 1903 or later") +) + +var ( + modWebAuthn *windows.LazyDLL + procWebAuthNGetApiVersionNumber *windows.LazyProc + procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable *windows.LazyProc + procWebAuthNAuthenticatorMakeCredential *windows.LazyProc + procWebAuthNAuthenticatorGetAssertion *windows.LazyProc + procWebAuthNFreeCredentialAttestation *windows.LazyProc + procWebAuthNFreeAssertion *windows.LazyProc + procWebAuthNGetCancellationId *windows.LazyProc + procWebAuthNCancelCurrentOperation *windows.LazyProc + procWebAuthNGetPlatformCredentialList *windows.LazyProc + procWebAuthNFreePlatformCredentialList *windows.LazyProc + procWebAuthNDeletePlatformCredential *windows.LazyProc + procWebAuthNGetAuthenticatorList *windows.LazyProc + procWebAuthNFreeAuthenticatorList *windows.LazyProc + procWebAuthNGetErrorName *windows.LazyProc + procWebAuthNGetW3CExceptionDOMError *windows.LazyProc + currVer *currentVersion + InitError error ) +func init() { + modWebAuthn = windows.NewLazyDLL("webauthn.dll") + + if err := modWebAuthn.Load(); err != nil { + InitError = ErrWindowsVersionNotSupported + return + } + + procWebAuthNGetApiVersionNumber = modWebAuthn.NewProc("WebAuthNGetApiVersionNumber") + procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable = modWebAuthn.NewProc("WebAuthNIsUserVerifyingPlatformAuthenticatorAvailable") + procWebAuthNAuthenticatorMakeCredential = modWebAuthn.NewProc("WebAuthNAuthenticatorMakeCredential") + procWebAuthNAuthenticatorGetAssertion = modWebAuthn.NewProc("WebAuthNAuthenticatorGetAssertion") + procWebAuthNFreeCredentialAttestation = modWebAuthn.NewProc("WebAuthNFreeCredentialAttestation") + procWebAuthNFreeAssertion = modWebAuthn.NewProc("WebAuthNFreeAssertion") + procWebAuthNGetCancellationId = modWebAuthn.NewProc("WebAuthNGetCancellationId") + procWebAuthNCancelCurrentOperation = modWebAuthn.NewProc("WebAuthNCancelCurrentOperation") + procWebAuthNGetPlatformCredentialList = modWebAuthn.NewProc("WebAuthNGetPlatformCredentialList") + procWebAuthNFreePlatformCredentialList = modWebAuthn.NewProc("WebAuthNFreePlatformCredentialList") + procWebAuthNDeletePlatformCredential = modWebAuthn.NewProc("WebAuthNDeletePlatformCredential") + procWebAuthNGetAuthenticatorList = modWebAuthn.NewProc("WebAuthNGetAuthenticatorList") + procWebAuthNFreeAuthenticatorList = modWebAuthn.NewProc("WebAuthNFreeAuthenticatorList") + procWebAuthNGetErrorName = modWebAuthn.NewProc("WebAuthNGetErrorName") + procWebAuthNGetW3CExceptionDOMError = modWebAuthn.NewProc("WebAuthNGetW3CExceptionDOMError") + + apiVersion := APIVersionNumber() + if apiVersion == 0 { + InitError = ErrWindowsVersionNotSupported + return + } + + currVer = availableVersions(apiVersion) +} + type WebAuthnCredentialDetails struct { CredentialID []byte RP webauthntypes.PublicKeyCredentialRpEntity @@ -284,6 +322,10 @@ func GetAssertion( } func APIVersionNumber() uint32 { + if procWebAuthNGetApiVersionNumber.Find() != nil { + return 0 + } + r1, _, _ := procWebAuthNGetApiVersionNumber.Call() return uint32(r1) } From ada4857b83fd1704368a260e527cec987f38e465 Mon Sep 17 00:00:00 2001 From: Sebastijan Zindl Date: Fri, 20 Feb 2026 16:56:47 +0100 Subject: [PATCH 8/8] chore: remove unused wrapper functions --- winhello.go | 157 ---------------------------------------------------- 1 file changed, 157 deletions(-) diff --git a/winhello.go b/winhello.go index bf74d7b..3c7bd04 100644 --- a/winhello.go +++ b/winhello.go @@ -4,12 +4,10 @@ package winhello import ( - "bytes" "encoding/base64" "errors" "fmt" "log/slog" - "slices" "unsafe" "github.com/go-ctap/ctaphid/pkg/webauthntypes" @@ -329,158 +327,3 @@ func APIVersionNumber() uint32 { r1, _, _ := procWebAuthNGetApiVersionNumber.Call() return uint32(r1) } - -func CancellationID() (*windows.GUID, error) { - var cancellationIDPtr windows.GUID - - r1, _, _ := procWebAuthNGetCancellationId.Call( - uintptr(unsafe.Pointer(&cancellationIDPtr)), - ) - if hr := windows.Handle(r1); hr != windows.S_OK { - return nil, windows.Errno(hr) - } - - return &cancellationIDPtr, nil -} - -func ErrorName(hr windows.Handle) string { - r1, _, _ := procWebAuthNGetErrorName.Call(uintptr(hr)) - return windows.UTF16PtrToString((*uint16)(unsafe.Pointer(r1))) -} - -func PlatformCredentialList(rpID string, browserInPrivateMode bool) ([]*WebAuthnCredentialDetails, error) { - var rpIDPtr *uint16 - if rpID != "" { - rpIDPtr = windows.StringToUTF16Ptr(rpID) - } - - credDetailsListPtr := new(_WEBAUTHN_CREDENTIAL_DETAILS_LIST) - - r1, _, _ := procWebAuthNGetPlatformCredentialList.Call( - uintptr(unsafe.Pointer(&_WEBAUTHN_GET_CREDENTIALS_OPTIONS{ - DwVersion: currVer.getCredentialsOptions, - PwszRpId: rpIDPtr, - BBrowserInPrivateMode: boolToInt32(browserInPrivateMode), - })), - uintptr(unsafe.Pointer(&credDetailsListPtr)), - ) - if hr := windows.Handle(r1); hr != windows.S_OK { - return nil, windows.Errno(hr) - } - - credListDetails := slices.Clone(unsafe.Slice(credDetailsListPtr.PpCredentialDetails, credDetailsListPtr.CCredentialDetails)) - - list := make([]*WebAuthnCredentialDetails, len(credListDetails)) - for i, cred := range credListDetails { - credID := bytes.Clone(unsafe.Slice(cred.PbCredentialID, cred.CbCredentialID)) - - list[i] = &WebAuthnCredentialDetails{ - CredentialID: credID, - RP: webauthntypes.PublicKeyCredentialRpEntity{ - ID: windows.UTF16PtrToString(cred.PRpInformation.PwszId), - Name: windows.UTF16PtrToString(cred.PRpInformation.PwszName), - }, - User: webauthntypes.PublicKeyCredentialUserEntity{ - ID: bytes.Clone(unsafe.Slice(cred.PUserInformation.PbId, cred.PUserInformation.CbId)), - DisplayName: windows.UTF16PtrToString(cred.PUserInformation.PwszDisplayName), - Name: windows.UTF16PtrToString(cred.PUserInformation.PwszName), - }, - Removable: int32ToBool(cred.BRemovable), - } - - if cred.DwVersion >= 2 { - list[i].BackedUp = int32ToBool(cred.BBackedUp) - } - - if cred.DwVersion >= 3 { - list[i].AuthenticatorName = windows.UTF16PtrToString(cred.PwszAuthenticatorName) - list[i].AuthenticatorLogo = bytes.Clone(unsafe.Slice(cred.PbAuthenticatorLogo, cred.CbAuthenticatorLogo)) - list[i].ThirdPartyPayment = int32ToBool(cred.BThirdPartyPayment) - } - - if cred.DwVersion >= 4 { - list[i].Transports = flagsToTransports(cred.DwTransports) - } - } - - if _, _, err := procWebAuthNFreePlatformCredentialList.Call( - uintptr(unsafe.Pointer(credDetailsListPtr)), - ); !errors.Is(err, windows.NTE_OP_OK) { - return nil, err - } - - return list, nil -} - -type WebAuthnAuthenticatorDetails struct { - ID []byte - Name string - Logo []byte - Locked bool -} - -func AuthenticatorList() ([]*WebAuthnAuthenticatorDetails, error) { - authenticatorListPtr := new(_WEBAUTHN_AUTHENTICATOR_DETAILS_LIST) - - r1, _, _ := procWebAuthNGetAuthenticatorList.Call( - uintptr(unsafe.Pointer(&_WEBAUTHN_AUTHENTICATOR_DETAILS_OPTIONS{ - DwVersion: currVer.authenticatorDetails, - })), - uintptr(unsafe.Pointer(&authenticatorListPtr)), - ) - if hr := windows.Handle(r1); hr != windows.S_OK { - return nil, windows.Errno(hr) - } - - authenticatorListDetails := slices.Clone(unsafe.Slice( - authenticatorListPtr.PpAuthenticatorDetails, - authenticatorListPtr.CAuthenticatorDetails, - )) - - list := make([]*WebAuthnAuthenticatorDetails, len(authenticatorListDetails)) - for i, cred := range authenticatorListDetails { - authenticatorID := bytes.Clone(unsafe.Slice(cred.PbAuthenticatorId, cred.CbAuthenticatorId)) - authenticatorLogo := bytes.Clone(unsafe.Slice(cred.PbAuthenticatorLogo, cred.CbAuthenticatorLogo)) - - list[i] = &WebAuthnAuthenticatorDetails{ - ID: authenticatorID, - Name: windows.UTF16PtrToString(cred.PwszAuthenticatorName), - Logo: authenticatorLogo, - Locked: int32ToBool(cred.BLocked), - } - } - - if _, _, err := procWebAuthNFreeAuthenticatorList.Call( - uintptr(unsafe.Pointer(authenticatorListPtr)), - ); !errors.Is(err, windows.NTE_OP_OK) { - return nil, err - } - - return list, nil -} - -func W3CExceptionDOMError() (windows.Handle, error) { - var ret windows.Handle - - r1, _, _ := procWebAuthNGetW3CExceptionDOMError.Call( - uintptr(unsafe.Pointer(&ret)), - ) - if hr := windows.Handle(r1); hr != windows.S_OK { - return 0, windows.Errno(hr) - } - - return ret, nil -} - -func IsUserVerifyingPlatformAuthenticatorAvailable() (bool, error) { - var isAvailable bool - - r1, _, _ := procWebAuthNIsUserVerifyingPlatformAuthenticatorAvailable.Call( - uintptr(unsafe.Pointer(&isAvailable)), - ) - if hr := windows.Handle(r1); hr != windows.S_OK { - return false, windows.Errno(hr) - } - - return isAvailable, nil -}