AcquireCredentialsHandle fails in kernel mode, when using SCH_CRED_FORMAT_CERT_HASH

598 Views Asked by At

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?

1

There are 1 best solutions below

6
On

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.