1

https://social.msdn.microsoft.com/Forums/vstudio/en-US/86f77b01-6da7-4321-8c57-563d9441de76/smartcard-custom-credential-provider?forum=windowssecurity

I want to implement Custom WindowsCredentialProvider which unlock windows session by SmartCard. With //username & password works fine but have problem with SmartCard. I use this sample https://github.com/phaetto/windows-credentials-provider and did the changes according to this topic https://learn.microsoft.com/en-gb/windows/win32/api/wincred/nf-wincred-credpackauthenticationbuffera and call CredMarshalCredential as follow:

    NativeMethods.CERT_CREDENTIAL_INFO certInfo = new NativeMethods.CERT_CREDENTIAL_INFO();
    certInfo.cbSize = (uint)Marshal.SizeOf(typeof(NativeMethods.CERT_CREDENTIAL_INFO));

    X509Certificate2 certCredential = new X509Certificate2();
    var userMyStore = new X509Store();
    userMyStore.Open(OpenFlags.ReadOnly);
    X509Certificate2Collection certsReturned = userMyStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
    userMyStore.Close();

    if (certsReturned.Count == 0)
    {
            Console.WriteLine("Could not find the cert you want, aborting");
            return null;
    }

    certCredential = certsReturned[0];
    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.CertCredentia, pCertInfo, out marshaledCredential);

    var user = "";
    if (result)
    {
           user = Marshal.PtrToStringUni(marshaledCredential);
           var psCreds = new PSCredential(user, new SecureString());
    }

Then pass the Username and SmartCard PIN to the CredPackAuthenticationBuffer function and return True, but cannot unlock the screen. I also log the credential method call, it looks like as folow:

TestWindowsCredentialProvider::Advise
TestWindowsCredentialProvider::GetCredentialCount
TestWindowsCredentialProvider::GetCredentialAt
TestWindowsCredentialProvider::GetFieldDescriptorCount
TestWindowsCredentialProvider::GetFieldDescriptorAt
TestWindowsCredentialProvider::GetFieldDescriptorAt 
TestWindowsCredentialProviderTile::GetStringValue
TestWindowsCredentialProviderTile::GetFieldState
TestWindowsCredentialProviderTile::GetFieldState
TestWindowsCredentialProviderTile::GetSubmitButtonValue
TestWindowsCredentialProviderTile::Advise
TestWindowsCredentialProviderTile::SetSelected  
TestWindowsCredentialProviderTile::SetSelected
TestWindowsCredentialProviderTile::GetSerialization
TestWindowsCredentialProviderTile::SetDeselected
TestWindowsCredentialProviderTile::UnAdvise
TestWindowsCredentialProvider::UnAdvise

Update: When I use domain\username & password logs is same except call ReportResult after SetDeselected

TestWindowsCredentialProviderTile::ReportResult
Peyman
  • 3,068
  • 1
  • 18
  • 32
  • Can you unlock the card using a windows explorer? First you have to get windows to recognize the card then get your app to work same as windows. – jdweng Oct 10 '19 at 13:22
  • Yes card works fine, already configure it and working properly. If card didn't configured then should get error in finding certification. – Peyman Oct 10 '19 at 23:17
  • Normally the last step I do is unlock card in code. I first make sure I can do all read/write card in code after unlocking from windows explorer. Then once I get the read writes working I then unlock card from code. It is much harder to unlock the card when you don't know the read/writes are working properly. – jdweng Oct 11 '19 at 09:00
  • Actually when I run the code while logged in to windows everything works fine, but when I lock or sign out then can't login/unblock by smartcard certificate. I just log the code and CredPackAuthenticationBuffer return false however in debug mode return true with exactly same data – Peyman Oct 11 '19 at 12:32
  • Read the notes on the 2nd link you provided (ending with provider). With encryption that are lots of options (32 bit, 64 bit). I've been seeing a lot of issues recently with different version of SHA (32 bit and 64 bit). See : https://en.wikipedia.org/wiki/SHA-2 – jdweng Oct 11 '19 at 12:52
  • Recently I answer two postings were people were having issues with SOAP using 509 certificates. In one case an OPs upgraded from Net 4.0 to Net 4.8 end the de-encryption stopped working. – jdweng Oct 11 '19 at 13:08
  • thanks for answer @jdweng, but what I think the problem could be related to Windows session, as I already said code working fine while running in SignedIn windows. As long as lock the user get the error. So I guess windowss session locked and can't open it by certificate or something like that – Peyman Oct 11 '19 at 13:39
  • You missing the point. Is the library you are using defaulting to 32 bit mode or 64 bit mode? You are probably in Win 10 and the library you are using is defaulting to 32 bit mode. The notes in the 2nd link says what to do for Win 10. – jdweng Oct 11 '19 at 13:46
  • Yes I use Windows 10 and use x64. – Peyman Oct 11 '19 at 14:09
  • did you run the TestConsoleApp like notes said? Is certificate 32 or 64 bits? the version of certificate should be in the certificate and then refer to Wiki page to check the parameters. Windows is checking the parameters in the certificate to determine options and your code is probably hard coding the options. – jdweng Oct 11 '19 at 14:21
  • In x86 doesn't work, must be in 64 bit mode – Peyman Oct 11 '19 at 14:30
  • So you found the answer? – jdweng Oct 11 '19 at 14:39
  • no still same issue, already it was in 64 bit as well. Only TestConsoleApp working, still cannot unlock windows – Peyman Oct 11 '19 at 14:44
  • Did you check options on TestConsoleApp like link said? – jdweng Oct 11 '19 at 15:44
  • Sorry I didn't get your mean, which option I should check? You mean in Wiki link? – Peyman Oct 11 '19 at 21:51
  • The GUI should have pull-down/menu with settings. – jdweng Oct 11 '19 at 22:14
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/200738/discussion-between-peyman-and-jdweng). – Peyman Oct 11 '19 at 22:19
  • The options in the programs and the type of certificate are not the same. You need to determine the type of certificate and then set the application to match the certificate. The certificate is XML so you can open with notepad and check the type. Just because you are using Window 10 that you are using a 64 bit certificate. – jdweng Oct 12 '19 at 10:07
  • @jdweng thanks, it's not related to the certificate type, I found I must pass the domain name as well. After userdomain\\CertficateUser, CredPackAuthenticationBuffer return true and can see the Welcome message but cannot unlock the screen. I tried with Lock and Signed Out user – Peyman Oct 14 '19 at 04:52
  • So you have two issues 1) Not using the domain name 2) Unlocking the card. What make you think the unlocking of the card is not related to the type of certificate? – jdweng Oct 14 '19 at 09:01
  • I use domain, CredPackAuthenticationBuffer doesn't work without domain. IF the certificate type is wrong then CredPackAuthenticationBuffer should return false not true. – Peyman Oct 14 '19 at 13:13
  • No. As I said there are a lot of different options and Windows reads the options and then opens the card using the appropriate options. You are hard coding the options and the current options are not the same that the card is using. – jdweng Oct 14 '19 at 13:41
  • you mean this line? certInfo.cbSize = (uint)Marshal.SizeOf(typeof(NativeMethods.CERT_CREDENTIAL_INFO)) – Peyman Oct 14 '19 at 13:58
  • Where did I say size? See my Wiki link from Oct 11. – jdweng Oct 14 '19 at 14:21

0 Answers0