none
SmartCard Custom Credential Provider RRS feed

  • Question

  • I use the CredMarshalCredential  to return the username and pass it to the CredPackAuthenticationBuffer as follow:


      
    var username = GetSmartCardUser();
    var password = "12345678";
    
    var inCredSize = 0;
    var inCredBuffer = Marshal.AllocCoTaskMem(0);
    
    if (!PInvoke.CredPackAuthenticationBuffer(0, username, password, inCredBuffer, ref inCredSize))
    {                   
    	Marshal.FreeCoTaskMem(inCredBuffer);
    	inCredBuffer = Marshal.AllocCoTaskMem(inCredSize);
    
    	if (PInvoke.CredPackAuthenticationBuffer(0, username, password, inCredBuffer, ref inCredSize))
    	{
    		ppszOptionalStatusText = string.Empty;
    		pcpsiOptionalStatusIcon = _CREDENTIAL_PROVIDER_STATUS_ICON.CPSI_SUCCESS;
    
    		pcpcs.clsidCredentialProvider = Guid.Parse(Constants.CredentialProviderUID);
    		pcpcs.rgbSerialization = inCredBuffer;
    		pcpcs.cbSerialization = (uint)inCredSize;
    
    		RetrieveNegotiateAuthPackage(out var authPackage);
    		pcpcs.ulAuthenticationPackage = authPackage;
    
    		return HResultValues.S_OK;
    	}
    }



    And GetSmartCardUser:

    var certCredential = FindCert();         
    
    NativeMethods.CERT_CREDENTIAL_INFO certInfo = new NativeMethods.CERT_CREDENTIAL_INFO();
    certInfo.cbSize = (uint)Marshal.SizeOf(typeof(NativeMethods.CERT_CREDENTIAL_INFO));
    
    
    certInfo.rgbHashOfCert = certCredential.GetCertHash();
    int size = Marshal.SizeOf(certInfo);
    IntPtr pCertInfo = Marshal.AllocHGlobal(size);
    Marshal.StructureToPtr(certInfo, pCertInfo, false);
    IntPtr marshaledCredential = IntPtr.Zero;
    bool result = NativeMethods.CredMarshalCredential(NativeMethods.CRED_MARSHAL_TYPE.CertCredential, pCertInfo,
    	out marshaledCredential);
    
    var user = "";
    if (result)
    {
    	user = Marshal.PtrToStringUni(marshaledCredential);
    	var psCreds = new PSCredential(user, new SecureString());
    }
    
    Marshal.FreeHGlobal(pCertInfo);
    if (marshaledCredential != IntPtr.Zero)
    {
    	NativeMethods.CredFree(marshaledCredential);
    }
    
    return user;


    When I run it in debug mode  with Visual Studio everything is fine and first call CredPackAuthenticationBuffer return the correct size and second call return true, but when I lock the windows and run it through the logon screen first call return iCredSize =0 and second call return false. any idea or help?

                    
    • Edited by Peymanmi Friday, October 11, 2019 4:35 AM
    Friday, October 11, 2019 4:33 AM

All replies

  • Hi,

    Try to use Marshal.GetLastWin32Error in first call return iCredSize =0 to get the error code.

    Best Regards,

    Drake


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, October 14, 2019 2:20 AM
    Moderator
  • Did you use a local user? CredPackAuthenticationBuffer may not be available for local user. Since it cannot split the domain and user name.

    See the comments in the samples that provide by microsoft.

    https://github.com/microsoft/Windows-classic-samples/blob/master/Samples/CredentialProvider/cpp/CSampleCredential.cpp#L514

    You can refer to the way the local user is handled in the link.

    (if(_fIsLocalUser){...})

    Best Regards,

    Drake


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Monday, October 14, 2019 3:12 AM
    Moderator
  • I use this code for Domain certificate, but already I didn't send Domain name with Certificate User, but after add domain,  CredPackAuthenticationBuffer return true and see Welcome on screen, but cannot unlock the screen, any Idea?

    Thanks

    Monday, October 14, 2019 4:24 AM
  • No I use for domain user, as I already mentioned I missed the domain name, after added the domain name see the Welcome screen but couldn't Unlock the screen and call all function again, however with Domain User everything works fine and unlock the screen quickly. This is what I found in System Log

    

    • Edited by Peymanmi Monday, October 14, 2019 6:07 AM
    Monday, October 14, 2019 4:49 AM
  • CredPackAuthenticationBuffer return true. But cannot unlock the screen, Did you check the other calls return value? Did any call failed and with which error code? 

    Best Regards,

    Drake


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, October 14, 2019 7:36 AM
    Moderator
  • CredPackAuthenticationBuffer return true but Marshal.GetLastWin32Error() return Error Code: 87 ERROR_INVALID_PARAMETER
    • Edited by Peymanmi Monday, October 14, 2019 12:08 PM
    Monday, October 14, 2019 8:43 AM
  • Thanks for provide the details.

    If the function executes successfully, the error code may be meaningless. Find out the function that actually failed, then call Marshal.GetLastWin32Error().

    ERROR_INVALID_PARAMETER: This is related to the first parameter of CredPackAuthenticationBuffer, you need to specify how the credential should be packed according to the documentation instead of setting to zero. such as "CRED_PACK_GENERIC_CREDENTIALS | CRED_PACK_ID_PROVIDER_CREDENTIALS" 

    Best Regards,

    Drake


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, October 15, 2019 3:04 AM
    Moderator