Статус: Новичок
Группы: Участники
Зарегистрирован: 04.10.2018(UTC) Сообщений: 4 Откуда: Москва Сказал(а) «Спасибо»: 6 раз
|
Добрый день. Нужно установить сертификат из файла в контейнер с приватной частью. Если это делать вручную через CryptoPro, то все работает. Пытаюсь автоматизировать процесс (С++). Код приведен ниже. Отрабатывает до шага 7 - Map key and certificate. Вызов CryptSetKeyParam возвращает ошибку 'Неправильный параметр набора ключей'. Подскажите, корректен ли мой алгоритм? Последовательность шагов такая: 0.) Open cert. store. 1.) Construct PCCERT_CONTEXT from dataCert. 2.) Create new certificate from the encoded part of an available certificate. 3.) Fill provider info 4.) Associate the container with certificate 5.) Get access to container 6.) Get key 7.) Map key and certificate. <- Вы 8.) Add certificate to store. Не нужно ли сначала добавлять сертификат в контейнер, и уже потом его модифицировать? Сам сертификат по идее валидный - у меня получалось его через CertAddCertificateContextToStore добавлять в CryptoPro (правда, не в конкретно нужный мне контейнер). На форуме нашел вот этот пост: https://www.cryptopro.ru....aspx?g=posts&t=6125Код очень похож на мой, но до проблем с использованием установленного сертификата я не дошел. Код:
//! dataCert - содержимое сертификата.
PCCERT_CONTEXT installCert(const std::string &containerName, const std::string &dataCert, int providerType)
{
// ----------------------------------------------------------------
// 0.) Open cert. store.
HCERTSTORE hCertStore = CertOpenSystemStore(0, _T("MY"));
if (!hCertStore)
{
const auto message = logLastErrorMesage("CertOpenSystemStore");
throw std::runtime_error("can't install cert: " + message);
}
// ----------------------------------------------------------------
// 1.) Construct PCCERT_CONTEXT from dataCert.
CERT_BLOB certBlob;
certBlob.pbData = (BYTE*)dataCert.data();
certBlob.cbData = dataCert.size();
PCCERT_CONTEXT pCertContext = NULL;
PCCERT_CONTEXT pExtCertCtx = 0;
if (!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &certBlob, CERT_QUERY_CONTENT_FLAG_CERT,
CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL, NULL, NULL, NULL, (const void **)&pExtCertCtx))
{
const auto message = logLastErrorMesage("CryptQueryObject");
throw std::runtime_error("can't install cert: " + message);
}
// ------------------------------------------------------------------
// 2.) Create a new certificate from the encoded part of an available certificate.
pCertContext = CertCreateCertificateContext(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, // The encoding type
pExtCertCtx->pbCertEncoded, // The encoded data from the certificate retrieved
pExtCertCtx->cbCertEncoded); // The length of the encoded data
if (!pCertContext)
{
const auto message = logLastErrorMesage("CertCreateCertificateContext");
throw std::runtime_error("can't install cert: " + message);
}
// ------------------------------------------------------------------
// 3.) Fill provider info
CRYPT_KEY_PROV_INFO providerInfo;
memset(&providerInfo, 0, sizeof(providerInfo));
providerInfo.pwszContainerName = (wchar_t*)std::wstring(toWString(containerName)).c_str();
providerInfo.dwProvType = providerType;
providerInfo.dwKeySpec = AT_KEYEXCHANGE;
// ------------------------------------------------------------------
// 4.) Associate the container with our certificate
if (!CertSetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, 0, &providerInfo))
{
const auto message = logLastErrorMesage("CertSetCertificateContextProperty");
throw std::runtime_error("can't install cert: " + message);
}
// ------------------------------------------------------------------
// 5.) Get access to container
HCRYPTPROV hCryptProv = NULL;
if (!CryptAcquireContext(
&hCryptProv, // handle to the CSP
utils::utf8_decode(containerName).c_str(), // container name
NULL, // use the default provider
providerType, // provider type
0) // flag values
)
{
const auto message = logLastErrorMesage("CryptAcquireContext");
throw std::runtime_error("can't access cypto provider/container: " + message);
}
// ------------------------------------------------------------------
// 6.) Get key
HCRYPTKEY hKey = NULL;
if (!CryptGetUserKey(hCryptProv, AT_KEYEXCHANGE, &hKey))
{
const auto message = logLastErrorMesage("CryptGetUserKey");
throw std::runtime_error("can't get key for certificate: " + message);
}
// ------------------------------------------------------------------
// 7.) Map key and certificate.
if (!CryptSetKeyParam(
hKey,
KP_CERTIFICATE,
certBlob.pbData,
0))
{
const auto message = logLastErrorMesage("CryptSetKeyParam");
throw std::runtime_error("can't set key cert param: " + message);
}
// ------------------------------------------------------------------
// 8.) Add certificate to store.
if (!CertAddCertificateContextToStore(hCertStore, pCertContext, CERT_STORE_ADD_ALWAYS, 0))
{
const auto message = logLastErrorMesage("CertAddCertificateContextToStore");
throw std::runtime_error("can't install cert: " + message);
}
// ------------------------------------------------------------------
// ------------------------------------------------------------------
displayCertInStore(L"MY");
/* Free resources, catch exceptions.
...
*/
return pCertContext;
}
Отредактировано пользователем 4 октября 2018 г. 17:50:10(UTC)
| Причина: Не указана
|