06.10.2006 17:22:57Список контейнеров Ответов: 2
Андрей Горячев
Есть вот следующий код, который получает список контейнеров доступных. И вот интересно, что на одной машине оно работает и возвращает нормально список контейнеров и т.д. А на остальных не работает, даже в цикл не попадает! В чём может быть проблема? Что сделано не так?

DWORD size;
BYTE result[100];
DWORD fParam = CRYPT_FIRST;
CString resultString;
HCRYPTPROV hCryptProv;
int i = 0;

if (!CryptAcquireContextA(&hCryptProv, NULL, NULL, CRYPT_PROV_TYPE, CRYPT_VERIFYCONTEXT))
{
setLastError();
return false;
}

while(CryptGetProvParam(hCryptProv, PP_ENUMCONTAINERS, result, &size, fParam))
{
fParam = 0;

HCRYPTPROV tmpProv = NULL;
LPCSTR containerName = (LPCSTR)result;
CryptAcquireContextA(&tmpProv, containerName, "", CRYPT_PROV_TYPE, CRYPT_MACHINE_KEYSET);

HCRYPTKEY hKey = NULL;
if (!CryptGetUserKey(tmpProv, AT_KEYEXCHANGE, &hKey))
{
CryptGetUserKey(tmpProv, AT_SIGNATURE, &hKey);
}

BYTE* pbCert = NULL;
DWORD pcbCert = 0;
PCCERT_CONTEXT certContext;

CryptGetKeyParam(hKey, KP_CERTIFICATE, NULL, &pcbCert, 0);
pbCert = (BYTE*)malloc(pcbCert);
CryptGetKeyParam(hKey, KP_CERTIFICATE, pbCert, &pcbCert, 0);

certContext = CertCreateCertificateContext(MY_ENCODING_TYPE, pbCert, pcbCert);

if (i > 0)
resultString.Append("~");

resultString.Append(containerName);
resultString.Append("|");

DWORD dataSize;
BYTE* data;
char* tmpString;
DWORD tmpStringSize;

// Добавляем хэш

CertGetCertificateContextProperty(certContext, CERT_HASH_PROP_ID, NULL, &dataSize);
data = (BYTE*)malloc(dataSize);
tmpString = (char*)malloc((dataSize * 2) + 1);
CertGetCertificateContextProperty(certContext, CERT_HASH_PROP_ID, data, &dataSize);

CryptBinaryToString(data, dataSize, CRYPT_STRING_HEX, NULL, &tmpStringSize);
tmpString = (char*)malloc(tmpStringSize);
CryptBinaryToString(data, dataSize, CRYPT_STRING_HEX, tmpString, &tmpStringSize);

resultString.Append(tmpString);
resultString.Append("|");

//Имя Получателя
CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, dataSize);
tmpString = (char*)malloc(dataSize);
CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, tmpString, dataSize);

resultString.Append(tmpString);
resultString.Append("|");

//Имя УЦ
CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, NULL, dataSize);
tmpString = (char*)malloc(dataSize);
CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, tmpString, dataSize);

resultString.Append(tmpString);

i++;

free(pbCert);
free(data);
free(tmpString);
}

free(result);

return resultString.GetBuffer();
 
Ответы:
09.10.2006 12:18:59Василий
А чему равно CRYPT_PROV_TYPE ?
Если это значение отсутствует (не зарегистрировано) на каком-то компьютере, естественно, работать не будет.
Пример. "КриптоПро CSP" 3.0 регистрирует два значения типа: 71 и 75 (десятичные). Для 2.0 есть ещё тип 2.
09.10.2006 12:20:10Андрей Горячев
75