Статус: Участник
Группы: Участники
Зарегистрирован: 19.09.2019(UTC) Сообщений: 17  Откуда: Москва Сказал(а) «Спасибо»: 4 раз
|
Коллеги, добрый день. Столкнулись с зависаниями при попытке получить доступ к приватной части ключа через контекст сертификата. Код: CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_SILENT_FLAG, 0, &hProv, &keySpec, &keyFree) {
На некоторых машинах воспроизводится, на некоторых нет. Основные версии Windows на которых стокнулись с этим: - Windows Server 2019 Standard (10.0.17763), КриптоПро 13000 - Windows Server 2022 Standard (10.0.20348), КриптоПро 12800 При этом, Windows Server 2016 Standard (10.0.14393), КриптоПро 13000 все хорошо. Зависания происходят на контейнерах ключа как в реестре, так и на рутокене. Пин ключа хранится в системе. Криптопровайдер: Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider Кэширование ключей КриптоПро выключено. Зависание происходит при запуске приложения в режиме Windows сервиса. При запуске в режиме приложения все хорошо. Машина после ребута, все хорошо работает. Спустя несколько дней - зависание в момент: Код: CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_SILENT_FLAG, 0, &hProv, &keySpec, &keyFree) {
pCertContext получаем стандартно: Код:
PCCERT_CONTEXT GetCertContextFromStore(const upg::crypto::CommonContext &context)
{
const auto StrStore = upg::utils::utf8_decode(context.store_name);
const auto StrSerial = upg::utils::filterCntrlSymbols(context.serial);
std::wstring StrFindField = upg::utils::utf8_decode(context.subject);
DWORD CertFindOPT = CERT_FIND_SUBJECT_STR_W;
if (context.subject.empty()) {
StrFindField = upg::utils::utf8_decode(context.issuer);
CertFindOPT = CERT_FIND_ISSUER_STR_W;
}
HCERTSTORE hCertStore = CertOpenSystemStoreW(0, StrStore.c_str());
if (!hCertStore) {
THROW_AND_ELOG_LAST_ERROR(std::runtime_error, "Can't open system certificate store");
}
BOOST_SCOPE_EXIT(&hCertStore)
{
if (hCertStore) { //!< close store, but leave active PCCERT_CONTEXT valid and not persistent.
CertCloseStore(hCertStore, CERT_CLOSE_STORE_CHECK_FLAG);
}
}
BOOST_SCOPE_EXIT_END;
DWORD encoding = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
for (PCCERT_CONTEXT pCert = CertFindCertificateInStore(hCertStore, encoding,
0, CertFindOPT, StrFindField.c_str(), NULL);
pCert; )
{
if (!(pCert->pCertInfo)) {
THROW_AND_ELOG<std::runtime_error>( "GetCertContext: not valid pCertInfo");
}
CRYPT_INTEGER_BLOB serial_blob = pCert->pCertInfo->SerialNumber;
auto serial = to_string_CRYPT_INTEGER_BLOB(serial_blob);
L_DEBUG << "FindCertContext: cert serial [ " << serial << " ]";
if (boost::iequals(serial, StrSerial)) {
L_DEBUG << "FindCertContext: have got a good serial [ " << context.serial << " ]";
return pCert;
}
// be aware, this function frees previous cert context, so no additional hustle needed.
pCert = CertFindCertificateInStore(hCertStore, encoding,
0, CertFindOPT, StrFindField.c_str(), pCert);
}
THROW_AND_ELOG_LAST_ERROR(std::runtime_error, "Can't find requested certificate in system store");
}
Кто-то сталкивался с таким? Как это можно залогировать? Попробовали включить лог так: HKLM\SOFTWARE\Crypto Pro\CSP\Log\Enabled = 1 (DWORD) HKLM\SOFTWARE\Crypto Pro\CSP\Log\Level = 7 (DWORD) Однако в логе ничего не пишется в момент зависания. Никаких странных записей об ошибках не заметили. По документации CryptAcquireCertificatePrivateKey не должен "зависать". Насколько я понимаю, если что-то не так, он должен вернуть 0 и записать ошибку, однако такого в случаях зависаний не проиходит. Возможно ли как-то задать таймаут ожидания?
|