Я звоню AcquireCredentialsHandle в драйвере ядра, передавая в SCHANNEL_CRED с dwCredFormat
установлен в SCH_CRED_FORMAT_CERT_HASH
, Это не с SEC_E_NO_CREDENTIALS
, Вот мой код:
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 как для учетной записи пользователя, так и для локальной машины. Я знаю это, потому что он отлично работает в пользовательском режиме, а именно:
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);
Я считаю, что следовал инструкциям MSDN о том, как использовать SCH_CRED_FORMAT_CERT_HASH
точно — что не так?
Трудно узнать наверняка без отладки, однако я вижу некоторые моменты, которые могут быть проблемой:
— если цепочка сертификатов не может быть проверена; или это самоподписанный; или во время выполнения кода для проверки CRL аппарат не имеет доступа к Интернету, ваш вызов не будет выполнен. Если это так, используйте CRYPT_E_NO_REVOCATION_CHECK
— Если цели вашего сертификата правильны для подтверждения личности на удаленных серверах?
В последнее время в Windows наблюдается некоторое усиление безопасности, которое очень требовательно к сертификатам. Самозаверяющий сертификат иногда проще проверить, чем подписанный. Я видел все больше приложений, которые работали, перестали работать из-за того, что сертификат не подтвержден на 100%. Короче говоря, я не вижу, в чем проблема.
Других решений пока нет …