......
std::string CertName = "RegistratorCert";
std::wstring wCertName;
bool is_forSign = true;
std::string PIN = "12345678";
//---------------------------------------
//открытие хранилища сертификатов
HCERTSTORE hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
0,
CERT_SYSTEM_STORE_CURRENT_USER,
STORE_NAME);
if(!hCertStore)
{
printf("cert storerror");
return -1;
}
std::cout << "certificate store was opened successfully" << std::endl;
std::wstring Certificate(CertName.begin(), CertName.end() );
wCertName = Certificate;
//поиск нужного сертификата
pSignerCert = CertFindCertificateInStore(
hCertStore,
CERT_TYPE,
0,
CERT_FIND_SUBJECT_STR,
wCertName.c_str(),
NULL);
if(!pSignerCert)
{
printf ("signer cert error");
CertCloseStore(hCertStore, 0);
return -1;
}
std::cout << "needed certificate was found successfully" << std::endl;
if(is_forSign) //если нужен закрытый ключ
{
CRYPT_KEY_PROV_INFO *pKeyInfo = NULL;
DWORD dwKeyInfo;
//полчение длины информации о ключе
if(!CertGetCertificateContextProperty(pSignerCert,CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwKeyInfo))
{
DWORD dError = GetLastError();
switch (dError)
{
case CRYPT_E_NOT_FOUND :
{
printf("The certificate does not have the specified property. Underlying error is: %d\n", dError);
break;
}
default:
{
printf("Unexpected error CertGetCertificateContextProperty. Underlying error is: %d\n", dError);
break;
}
}
CertCloseStore(hCertStore, 0);
CertFreeCertificateContext(pSignerCert);
return -1;
}
if(pKeyInfo)
free(pKeyInfo);
if(!(pKeyInfo = (CRYPT_KEY_PROV_INFO*)malloc(dwKeyInfo)))
{
printf("Error in allocation of memory.");
CertCloseStore(hCertStore, 0);
CertFreeCertificateContext(pSignerCert);
return -1;
}
//полчение информации о ключе
if(!CertGetCertificateContextProperty(pSignerCert,CERT_KEY_PROV_INFO_PROP_ID, pKeyInfo, &dwKeyInfo))
{
DWORD dError = GetLastError();
switch (dError)
{
case ERROR_MORE_DATA :
{
printf("The buffer is not large enough to hold the returned data about certificate. Underlying error is: %d\n", dError);
break;
}
default:
{
printf("Unexpected error CertGetCertificateContextProperty. Underlying error is: %d\n", dError);
break;
}
}
CertCloseStore(hCertStore, 0);
CertFreeCertificateContext(pSignerCert);
return -1;
}
//в CSP_WinCrypt.h фукция CryptAcquireContext получает имя контейнера в виде char*
#if defined(__WIN32__) || defined(_WIN32)
wchar_t* wcContainerName = pKeyInfo->pwszContainerName;
#else
char *wcContainerName = static_cast<char*>(malloc(wcslen(pKeyInfo->pwszContainerName) + 1));
ZeroMemory(wcContainerName, wcslen(pKeyInfo->pwszContainerName) + 1);
wcstombs(wcContainerName, pKeyInfo->pwszContainerName, wcslen(pKeyInfo->pwszContainerName));
#endif
//подключение к криптопровайдеру с нужным контейнером
if(!CryptAcquireContext(&hProv, wcContainerName, 0, pKeyInfo->dwProvType, /*CRYPT_SILENT*/0))
{
DWORD dError = GetLastError();
switch (dError)
{
case ERROR_INVALID_PARAMETER :
{
printf("While connect CSP one of the parameters contains a value that is not valid. Underlying error is: %d\n", dError);
break;
}
case NTE_KEYSET_NOT_DEF :
{
printf("The key container does not exist. Underlying error is: %d\n", dError);
break;
}
default:
{
printf("Unexpected error CryptAcquireContext. Underlying error is: %d\n", dError);
break;
}
}
CertCloseStore(hCertStore, 0);
CertFreeCertificateContext(pSignerCert);
return -1;
}
//ввод ПИН кода контейнера
if(!CryptSetProvParam(hProv, PP_KEYEXCHANGE_PIN, reinterpret_cast<const BYTE*>(PIN.c_str()), 0))
{
DWORD dError = GetLastError();
switch (dError)
{
case ERROR_BUSY:
{
printf("The CSP context is currently being used by another process. Underlying error is: %d\n", dError);
break;
}
default:
{
printf("Unexpected error CryptAcquireContext. Underlying error is: %d\n", dError);
break;
}
}
CertCloseStore(hCertStore, 0);
CertFreeCertificateContext(pSignerCert);
return -1;
}
//CertCloseStore(hCertStore, 0);
//CertFreeCertificateContext(pSignerCert);
delete wcContainerName;
вот начало работы
собственно отличается у нас и параметр функции подписи...в CryptSignHash(.., AT_KEYEXCHANGE, ......) работает только с таким параметром(у вас стоит 0, но у меня не работает и с AT_SIGNATURE), иначе не получается подписать, размер возвращает равный 0... Я так понимаю это несущественно??!! В чем может заключаться ошибка, что может влиять негативно на процесс проверки подписи на стороне получателя???