AcquireCredentialsHandle fails in kernel mode, when using SCH_CRED_FORMAT_CERT_HASH
Asked Answered
S

1

10

I call AcquireCredentialsHandle in a kernel driver, passing in SCHANNEL_CRED with the dwCredFormat set to SCH_CRED_FORMAT_CERT_HASH. It fails with SEC_E_NO_CREDENTIALS. Here is my code:

BYTE certHashBytes[20] = { 0x6d,0x64,0xed,0x56,0xd2,0x94,0x15,0xf4,0x49,0x08,0xaf,0x18,0xf1,0xca,0xf5,0xa2,0xc8,0x01,0x20,0x96 };
CredHandle credHandle;
RtlZeroMemory(&credHandle, sizeof(CredHandle));

SCHANNEL_CRED schannelCred;
RtlZeroMemory(&schannelCred, sizeof(SCHANNEL_CRED));
schannelCred.dwVersion = 4;
schannelCred.cCreds = 1;
schannelCred.paCred = certHashBytes;
schannelCred.dwCredFormat = 1;

UNICODE_STRING unispName;
RtlUnicodeStringInit(&unispName, L"Microsoft Unified Security Protocol Provider");
TimeStamp ts;

SECURITY_STATUS res = AcquireCredentialsHandle(NULL, &unispName, SECPKG_CRED_INBOUND, NULL, &schannelCred, NULL, NULL, &credHandle, &ts);
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, "AcquireCredentialsHandle %x\n", res);

My certificate hash is definitely correct, and installed properly in the MY store, for both User Account and Local Machine. I know this because it works fine in user mode, as follows:

HCERTSTORE certStore = CertOpenSystemStore(NULL, L"MY");
BYTE certHashBytes[20] = { 0x6d,0x64,0xed,0x56,0xd2,0x94,0x15,0xf4,0x49,0x08,0xaf,0x18,0xf1,0xca,0xf5,0xa2,0xc8,0x01,0x20,0x96 };
CERT_NAME_BLOB certHash { 20, certHashBytes };
PCCERT_CONTEXT cert = CertFindCertificateInStore(certStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SHA1_HASH, &certHash, NULL);

CredHandle credHandle;
ZeroMemory(&credHandle, sizeof(CredHandle));

SCHANNEL_CRED cred;
ZeroMemory(&cred, sizeof(SCHANNEL_CRED));
cred.dwVersion = SCHANNEL_CRED_VERSION;
cred.cCreds = 1;
cred.paCred = &cert;

SECURITY_STATUS res = AcquireCredentialsHandle(NULL, const_cast<LPWSTR>(UNISP_NAME), SECPKG_CRED_INBOUND, NULL, &cred, NULL, NULL, &credHandle, NULL);

I believe I followed the MSDN instructions on how to use SCH_CRED_FORMAT_CERT_HASH exactly - what's wrong?

Schrecklichkeit answered 3/8, 2018 at 9:18 Comment(5)
Did you enable Schannel event logging? that can help a lot for debug purposes.Thickening
@Thickening Yes, but there's nothing there from my driver.Schrecklichkeit
My guess is that something is wrong with the private key. Is your private key corretly stored/loaded in the PROV_RSA_SCHANNEL CSP? "...it works fine in user mode..." -> Does not mean it will work in the server side. Could you fill us if you see any events (like 36867, 36868 ,36871 ) in your system log?Communicable
@Communicable If it works in user mode, then why shouldn't it work in kernel mode? Both of them are acting as server-side, by the SECPKG_CRED_INBOUND parameter. Besides, mmc shows that the private key is fine, for both User Account, & Local Computer. There's nothing in 'System' in 'eventvwr'.Schrecklichkeit
If I quote John Banes: "Well, just because the private key works for client-side operations doesn't mean that it will work on the server side. The server-side operations are different and so are the requirements for the privatekey.". If there is nothing in event viewer then I'll gladly pass this to somebody else.Communicable
O
0

It is difficult to know for sure without debugging, however I see some points that could be the problem: - If the certificate chain cannot be verified; or it is self-signed; or the machine does not have access to the internet at the time your code execute to check CRL, your call will fail. If this is the case, use CRYPT_E_NO_REVOCATION_CHECK - If the purposes of your certificate are correct for proving an identity to remote servers?

There are some recent security hardenings in Windows to be very picky when it comes to certificates. A self-signed certificate sometimes is easier to test than a signed one. I have seen an increasing number of applications that were working stopped working for having a certificate not 100% proved. Short of it, I do not see what the problem is.

Ochoa answered 10/8, 2018 at 22:55 Comment(6)
It is a certificate bought from Comodo, and I have Internet access. I also already tried with CRYPT_E_NO_REVOCATION_CHECK. Besides, if any of these are the case, it wouldn't work in user mode either.Schrecklichkeit
I recommend you open a case with Microsoft so we can analyze the situation via kernel dump file or if you can provide the driver, do a kernel dump with source and symbols of Kernel. There're some captures that are useful but I believe you did most (if you write Kernel drivers you're an advanced developer). As it works in user mode, I suggest you test your user mode version with system account running as a service or via psexec -i -s if you have not done so already. I will keep your question in mind and I will talk to some friends during the week to see if someone come up with some anyr idea.Ochoa
Thanks. I did ask Microsoft (social.msdn.microsoft.com/Forums/windowsdesktop/en-US/…) but no one helped. Is there a better way of opening a case?Schrecklichkeit
Let me see if I can get some traction to your request tomorrow, but I think a deeper analysis is necessary for your case. Search ‘open a Microsoft support case’ and you will see the options. If you are a partner you can open cases using your partner account without any extra cost.Ochoa
I search for ‘open a Microsoft support case’, but could only see pricey options.Schrecklichkeit
lol. If you are a free-lancer, yes. I will create a mock driver and see if I can reproduce your issue. Give me some time.Ochoa

© 2022 - 2024 — McMap. All rights reserved.