CryptEncrypt() fixed to support zero-length reserved buffers

This commit is contained in:
Simon Rozman 2016-06-20 14:51:14 +02:00
parent 7510410b56
commit 5d47a19972

View File

@ -230,19 +230,29 @@ template<class _Ty, class _Ax>
inline BOOL CryptEncrypt(_In_ HCRYPTKEY hKey, _In_opt_ HCRYPTHASH hHash, _In_ BOOL Final, _In_ DWORD dwFlags, _Inout_ std::vector<_Ty, _Ax> &aData) inline BOOL CryptEncrypt(_In_ HCRYPTKEY hKey, _In_opt_ HCRYPTHASH hHash, _In_ BOOL Final, _In_ DWORD dwFlags, _Inout_ std::vector<_Ty, _Ax> &aData)
{ {
DWORD DWORD
dwDataLen = (DWORD)(aData.size() * sizeof(_Ty)), dwDataLen = (DWORD)(aData.size() * sizeof(_Ty)),
dwBufLen = (DWORD)(aData.capacity() * sizeof(_Ty)), dwBufLen = (DWORD)(aData.capacity() * sizeof(_Ty)),
dwEncLen; dwEncLen = dwDataLen,
dwResult;
aData.resize(dwBufLen); if (dwBufLen) {
dwEncLen = dwDataLen; aData.resize(dwBufLen);
if (CryptEncrypt(hKey, hHash, Final, dwFlags, (BYTE*)aData.data(), &dwEncLen, dwBufLen)) { if (CryptEncrypt(hKey, hHash, Final, dwFlags, (BYTE*)aData.data(), &dwEncLen, dwBufLen)) {
// Encryption succeeded. // Encryption succeeded.
assert(dwEncLen <= dwBufLen); assert(dwEncLen <= dwBufLen);
if (dwEncLen < dwBufLen) if (dwEncLen < dwBufLen)
aData.resize((dwEncLen + sizeof(_Ty) - 1) / sizeof(_Ty)); aData.resize((dwEncLen + sizeof(_Ty) - 1) / sizeof(_Ty));
return TRUE; return TRUE;
} else if (GetLastError() == ERROR_MORE_DATA) { } else
dwResult = GetLastError();
} else if (CryptEncrypt(hKey, NULL, Final, dwFlags, NULL, &dwEncLen, 0)) {
// CryptEncrypt() always succeeds for output data size queries.
// dwEncLen contains required output data size. Continue as if the buffer was to small. Actually, the output buffer _was_ too small!
dwResult = ERROR_MORE_DATA;
} else
dwResult = GetLastError();
if (dwResult == ERROR_MORE_DATA) {
// Encrypted data will be longer. Reserve more space and retry. // Encrypted data will be longer. Reserve more space and retry.
aData.resize(((dwBufLen = dwEncLen) + sizeof(_Ty) - 1) / sizeof(_Ty)); aData.resize(((dwBufLen = dwEncLen) + sizeof(_Ty) - 1) / sizeof(_Ty));
dwEncLen = dwDataLen; dwEncLen = dwDataLen;