Статус: Участник
Группы: Участники
Зарегистрирован: 22.07.2009(UTC) Сообщений: 18
|
В .Net всё просто. Там вряд ли. Вероятнее всего действительно в COM объекте, только вот непонятно, где в этом коде может неправильно выделяться память? Код:
DWORD cbContent;// Длина сообщения
BYTE* pbContent = NULL;
int icbContent = 0;
HCRYPTPROV hCryptProv = 0; // дескриптор CSP
HCERTSTORE hStoreHandle = 0; // дескриптор хранилища сертификатов
PCCERT_CONTEXT pRecipientCert = NULL;
CComBSTR tempCComBSTR;
CComBSTR RetBSTR;
int tempLen;
LPSTR tempByte = NULL;
LPSTR szDest = NULL;
int pnDestLen;
try
{
CRYPT_ALGORITHM_IDENTIFIER EncryptAlgorithm;
CRYPT_ENCRYPT_MESSAGE_PARA EncryptParams;
BYTE* pbEncryptedBlob = NULL;
DWORD cbEncryptedBlob;
tempCComBSTR = CComBSTR(ByteArray);
tempLen = tempCComBSTR.Length();
tempByte = (LPSTR)malloc(tempLen);
WideCharToMultiByte(
CP_ACP,
0,
(LPCWSTR)CStringW(ByteArray),
-1,
tempByte,
(int)tempLen,
NULL,
NULL);
Base64Decode(tempByte, tempLen, NULL, &icbContent);
pbContent = (BYTE*)malloc(icbContent);
cbContent = icbContent;
if (Base64Decode(tempByte, tempLen, pbContent, &icbContent) == FALSE)
{
SetErrorMessage(L"Неверно заданы входные параметры. Невозможно преобразовать входную строку из BASE64.(Код ошибки - 80004)");
SetErrorCode(80004);
goto done;
}
if (tempByte) free(tempByte);
if (tempCComBSTR)
{
tempCComBSTR.Empty();
delete tempCComBSTR;
}
// Получение дескриптора криптографического провайдера.
if(!CryptAcquireContext(
&hCryptProv, // Адрес возврашаемого дескриптора.
0, // Используется имя текущего зарегестрированного пользователя.
NULL, // Используется провайдер по умолчанию.
PROV_GOST_2001_DH, // Необходимо для зашифрования и подписи.
CRYPT_VERIFYCONTEXT)) // Никакие флаги не нужны.
{
SetErrorMessage(L"Невозможно инициализировать контекст криптопровайдера.(Код ошибки - 80005)");
SetErrorCode(80005);
return S_FALSE;
}
// Открытие системного хранилища сертификатов.
hStoreHandle = CertOpenSystemStore(hCryptProv, CW2A(p_StoreName));
if(!hStoreHandle)
{
SetErrorMessage(L"Невозможно открыть системное хранилище сертификатов.(Код ошибки - 80007)");
SetErrorCode(80007);
goto done;
}
// Получение указателя на сертификат получателя с помощью
// функции GetRecipientCert.
pRecipientCert = GetRecipientCert(hStoreHandle, p_Hash);
if(!pRecipientCert)
{
goto done;
}
// Инициализация структуры с нулем.
memset(&EncryptAlgorithm, 0, sizeof(CRYPT_ALGORITHM_IDENTIFIER));
EncryptAlgorithm.pszObjId = szOID_CP_GOST_28147;
// Инициализация структуры CRYPT_ENCRYPT_MESSAGE_PARA.
memset(&EncryptParams, 0, sizeof(CRYPT_ENCRYPT_MESSAGE_PARA));
EncryptParams.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);
EncryptParams.dwMsgEncodingType = MY_ENCODING_TYPE;
EncryptParams.hCryptProv = hCryptProv;
EncryptParams.ContentEncryptionAlgorithm = EncryptAlgorithm;
// Вызов функции CryptEncryptMessage.
if(!CryptEncryptMessage(
&EncryptParams,
1,
&pRecipientCert,
pbContent,
cbContent,
NULL,
&cbEncryptedBlob))
{
SetErrorMessage(L"Невозможно определить размер данных для шифрования.(Код ошибки - 80009)");
SetErrorCode(80009);
goto done;
}
// Распределение памяти под возвращаемый BLOB.
pbEncryptedBlob = (BYTE*)malloc(cbEncryptedBlob);
if(!pbEncryptedBlob)
{
SetErrorMessage(L"Невозможно выделить память для шифрования.(Код ошибки - 80011)");
SetErrorCode(80011);
goto done;
}
// Повторный вызов функции CryptEncryptMessage для зашифрования содержимого.
if(!CryptEncryptMessage(
&EncryptParams,
1,
&pRecipientCert,
pbContent,
cbContent,
pbEncryptedBlob,
&cbEncryptedBlob))
{
BSTR WindErr = SysAllocString(GetLastErrorWind());
AddToCallback(WindErr);
SetErrorMessage(L"Невозможно зашифровать данные.(Код ошибки - 80013)");
SetErrorCode(80013);
goto done;
}
pnDestLen = Base64EncodeGetRequiredLength(cbEncryptedBlob, ATL_BASE64_FLAG_NOCRLF );//| ATL_BASE64_FLAG_NOPAD
szDest = (LPSTR)malloc(pnDestLen);
if (Base64Encode(
pbEncryptedBlob,
cbEncryptedBlob,
szDest,
&pnDestLen,
ATL_BASE64_FLAG_NOCRLF) == FALSE)
{
SetErrorMessage(L"Невозможно возвратить зашифрованные данные.(Код ошибки - 80019)");
SetErrorCode(80019);
goto done;
}
RetBSTR = CComBSTR(pnDestLen,szDest);
*out_message = RetBSTR.Detach();
RetBSTR.Empty();
delete RetBSTR;
done:
if (pRecipientCert)
CertFreeCertificateContext(pRecipientCert);
if(hCryptProv)
{
BOOL Ret;
Ret = CryptReleaseContext(hCryptProv, 0);
}
if(hStoreHandle) {
CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG);
}
if (pbContent) free(pbContent);
if(szDest) free(szDest);
if (pbEncryptedBlob) free(pbEncryptedBlob);
}
catch(exception &e)
{
AddToCallback(A2BSTR(e.what()));
SetErrorMessage(L"Не удалось зашифровать данные.(Код ошибки - 80017)");
SetErrorCode(80017);
return S_FALSE;
}
return S_OK;
|