[webauthn] FIDO2 C++ based application using WebAuthn.dll for "YUBIKEY 5 NFC" (External authenticator) gives "This Security Key doesn't look familiar. Please try a different one." (#1582)

Mahaboob-Aslam has just created a new issue for https://github.com/w3c/webauthn:

== FIDO2 C++ based application using WebAuthn.dll for "YUBIKEY 5 NFC" (External authenticator) gives "This Security Key doesn't look familiar. Please try a different one." ==
Hi

I am writing  `FIDO2 C++ based application using WebAuthn.dll for "YUBIKEY 5 NFC" (External authenticator) ` using the following `WebAutheN APIs of Microsoft` from the 
https://github.com/microsoft/webauthn/blob/master/webauthn.h


    HRESULT WINAPI WebAuthNAuthenticatorMakeCredential(
           _In_        HWND                                                hWnd,
            _In_        PCWEBAUTHN_RP_ENTITY_INFORMATION                    pRpInformation,
            _In_        PCWEBAUTHN_USER_ENTITY_INFORMATION                  pUserInformation,
            _In_        PCWEBAUTHN_COSE_CREDENTIAL_PARAMETERS               pPubKeyCredParams,
            _In_        PCWEBAUTHN_CLIENT_DATA                              pWebAuthNClientData,
            _In_opt_    PCWEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS    pWebAuthNMakeCredentialOptions,
            _Outptr_result_maybenull_ PWEBAUTHN_CREDENTIAL_ATTESTATION      *ppWebAuthNCredentialAttestation);

    HRESULT WINAPI WebAuthNAuthenticatorGetAssertion(
           _In_        HWND                                                hWnd,
           _In_        LPCWSTR                                             pwszRpId,
           _In_        PCWEBAUTHN_CLIENT_DATA                              pWebAuthNClientData,
           _In_opt_    PCWEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS      pWebAuthNGetAssertionOptions,
           _Outptr_result_maybenull_ PWEBAUTHN_ASSERTION                   *ppWebAuthNAssertion);



`I am able to get the  registration successfully with the IdP (Identity Provider) using  C++ API WebAuthNAuthenticatorMakeCredential() in my code`.

```
But when it comes to Authentication, I am facing problem with the api WebAuthNAuthenticatorGetAssertion() as follows:

"This Security Key doesn't look familiar.  Please try a different one."
```

![image](https://user-images.githubusercontent.com/80270354/110357889-caf26b80-8061-11eb-8643-32b40c64b102.png)

Below is my  code :
===================

    HWND  hWnd = GetForegroundWindow();
    LPCWSTR   pwszRpId = L"tenet.domain.com";
           
                                //My client data in json format is as below...
     sClientData64 = {"type":"webauthn.get","challenge":"MKB9ApSESppXbU-oVW_M","origin":"https://tenet.domain.com","crossOrigin":true};

    WEBAUTHN_CLIENT_DATA oClientData_in = { WEBAUTHN_CLIENT_DATA_CURRENT_VERSION,
         static_cast<DWORD>(sClientData64.length()),
         (PBYTE)(sClientData64.data()),
         WEBAUTHN_HASH_ALGORITHM_SHA_256 
                          };

    

I tried to manipulate the values as in the following link: https://github.com/Yubico/python-fido2/blob/master/fido2/win_api.py  to implement
the structure `"WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS` below:

My allow list code is as follows:
=================================

    std::vector<WEBAUTHN_CREDENTIAL_EX> allowCredentials;    
    WEBAUTHN_CREDENTIAL_EX* pAllowCredentials = nullptr;
    std::vector<WEBAUTHN_CREDENTIAL_EX*> allowCredentialsPtrs;
    
    WEBAUTHN_CREDENTIAL_LIST allowCredentialList = { 0 };
    WEBAUTHN_CREDENTIAL_LIST* pAllowCredentialList = nullptr;

    DWORD dwVersion = WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_4; // the value is 4

    if(dwversion is >= 4)
    {
     DWORD winTransports = 0;
       
     std::string sAuthenticatorType = "usb";
     int nTransport = 0;
     if(sAuthenticatorType == "usb")
     { 
      nTransport = 1;
     }
     
     if (nTransport & U2F_AUTHENTICATOR_TRANSPORT_USB)
     {
      winTransports |= WEBAUTHN_CTAP_TRANSPORT_USB;
     }     

     WEBAUTHN_CREDENTIAL_EX webCredEx = { WEBAUTHN_CREDENTIAL_EX_CURRENT_VERSION,
          static_cast<DWORD>(sCredentialId.length()),
          ((BYTE*)(sCredentialId.c_str())),
          WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY,
          winTransports
               };

     allowCredentials.push_back(webCredEx);    

     pAllowCredentials = allowCredentials.data();
     for (DWORD i = 0; i < allowCredentials.size(); i++)
     {
      allowCredentialsPtrs.push_back(&pAllowCredentials[i]);
     }
     allowCredentialList.cCredentials = allowCredentials.size();  // original
     allowCredentialList.ppCredentials = allowCredentialsPtrs.data(); // original
     pAllowCredentialList = &allowCredentialList;  // my AllowCredentialList value
    }

// Credentials is as follows:
=============================

    WEBAUTHN_CREDENTIALS webCredentials = {0,NULL};

    DWORD dwVersion = WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_3; // the value is 3

    if(dwversion is >= 3)
    {
     std::vector<WEBAUTHN_CREDENTIAL> vCredential;
     std::vector<WEBAUTHN_CREDENTIAL*> pCredential;
     WEBAUTHN_CREDENTIAL webAuthCredential = {WEBAUTHN_CREDENTIAL_CURRENT_VERSION,
           static_cast<DWORD>(sCredentialId.length()),
           ((BYTE*)(sCredentialId.c_str())),
          WEBAUTHN_CREDENTIAL_TYPE_PUBLIC_KEY
         };
     WEBAUTHN_CREDENTIAL *pwebCredential;
     vCredential.push_back(webAuthCredential);
     pwebCredential = vCredential.data();
     for (DWORD i = 0; i < vCredential.size(); i++)
     {
      pCredential.push_back(&pwebCredential[i]);
     }
     webCredentials.cCredentials = vCredential.size();
     webCredentials.pCredentials = pwebCredential;
    }

    WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS   oWebAuthNGetAssertionOptions = { 
         dwVersion,
         10000,
         webCredentials,  //WEBAUTHN_CREDENTIALS  // if (dwVersion >=3)  {webCredentials;} else {0,NULL}                                                                                                                            {webCredentials = NULL}
         {0, NULL},  //WEBAUTHN_EXTENSIONS
         dwAuthenticatorAttachement,  // option for Platform (Windows Hello) vs Cross platform authenticator (Yubikey)
           winUserVerificationReq,  // user Verification Required (preferred)
         0,  // dwFlags
         NULL, // as json data received it is null
                                                 pbU2fAppIdUsed, (FALSE) this is a pointer
         NULL,  // pCancellationId
         pAllowCredentialList  // allowList if (dwversion is >= 4) else allowlist is null
                       };

    WEBAUTHN_ASSERTION* pWebAuthNAssertion = nullptr;  // this is an output parameter, which will get data of signature, Authenticator etc...

     // on this call i get this message dialog popup saying  " This Security key doesn't look familiar. please try a different one."

    hResult = WebAuthNAuthenticatorGetAssertion(hWnd, pwszRpId &oClientData_in, &oWebAuthNAssertionOptions, &pWebAuthNAssertion);  
    

I took the  python code for reference from the  https://github.com/Yubico/python-fido2/blob/master/fido2/win_api.py

    if (dwVersion >= 3)
               self.pCancellationId = cancellationId  (NULL)

           if self.dwVersion >= 4:
               clist = WebAuthNCredentialList(credentials)
               self.pAllowCredentialList = ctypes.pointer(clist)
           else:
               self.CredentialList = WebAuthNCredentials(credentials)
========================================================================

I have posted the same issue in MSDN forums.
https://docs.microsoft.com/en-us/answers/questions/305670/fido2-c-based-application-using-webauthndll-for-34.html

Please let me know, if any thing has to added in my code.

Thankyou.

Please view or discuss this issue at https://github.com/w3c/webauthn/issues/1582 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Wednesday, 10 March 2021 14:28:34 UTC