crypt32: Partially implement CryptBinaryToStringW.
This commit is contained in:
parent
50bc161eb2
commit
2d5ac92d9a
|
@ -60,6 +60,8 @@ static const char b64[] =
|
|||
|
||||
typedef BOOL (*BinaryToStringAFunc)(const BYTE *pbBinary,
|
||||
DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString);
|
||||
typedef BOOL (*BinaryToStringWFunc)(const BYTE *pbBinary,
|
||||
DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString);
|
||||
|
||||
static BOOL EncodeBinaryToBinaryA(const BYTE *pbBinary,
|
||||
DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString)
|
||||
|
@ -280,6 +282,198 @@ BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary,
|
|||
return encoder(pbBinary, cbBinary, dwFlags, pszString, pcchString);
|
||||
}
|
||||
|
||||
static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep,
|
||||
WCHAR* out_buf, DWORD *out_len)
|
||||
{
|
||||
int div, i;
|
||||
const BYTE *d = in_buf;
|
||||
int bytes = (in_len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0;
|
||||
DWORD needed;
|
||||
LPWSTR ptr;
|
||||
|
||||
TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes);
|
||||
needed = bytes + pad_bytes + 1;
|
||||
needed += (needed / 64 + 1) * strlenW(sep);
|
||||
|
||||
if (needed > *out_len)
|
||||
{
|
||||
*out_len = needed;
|
||||
return ERROR_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
else
|
||||
*out_len = needed;
|
||||
|
||||
/* Three bytes of input give 4 chars of output */
|
||||
div = in_len / 3;
|
||||
|
||||
ptr = out_buf;
|
||||
i = 0;
|
||||
while (div > 0)
|
||||
{
|
||||
if (i && i % 64 == 0)
|
||||
{
|
||||
strcpyW(ptr, sep);
|
||||
ptr += strlenW(sep);
|
||||
}
|
||||
/* first char is the first 6 bits of the first byte*/
|
||||
*ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
|
||||
/* second char is the last 2 bits of the first byte and the first 4
|
||||
* bits of the second byte */
|
||||
*ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)];
|
||||
/* third char is the last 4 bits of the second byte and the first 2
|
||||
* bits of the third byte */
|
||||
*ptr++ = b64[ ((d[1] << 2) & 0x3c) | (d[2] >> 6 & 0x03)];
|
||||
/* fourth char is the remaining 6 bits of the third byte */
|
||||
*ptr++ = b64[ d[2] & 0x3f];
|
||||
i += 4;
|
||||
d += 3;
|
||||
div--;
|
||||
}
|
||||
|
||||
switch(pad_bytes)
|
||||
{
|
||||
case 1:
|
||||
/* first char is the first 6 bits of the first byte*/
|
||||
*ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
|
||||
/* second char is the last 2 bits of the first byte and the first 4
|
||||
* bits of the second byte */
|
||||
*ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)];
|
||||
/* third char is the last 4 bits of the second byte padded with
|
||||
* two zeroes */
|
||||
*ptr++ = b64[ ((d[1] << 2) & 0x3c) ];
|
||||
/* fourth char is a = to indicate one byte of padding */
|
||||
*ptr++ = '=';
|
||||
break;
|
||||
case 2:
|
||||
/* first char is the first 6 bits of the first byte*/
|
||||
*ptr++ = b64[ ( d[0] >> 2) & 0x3f ];
|
||||
/* second char is the last 2 bits of the first byte padded with
|
||||
* four zeroes*/
|
||||
*ptr++ = b64[ ((d[0] << 4) & 0x30)];
|
||||
/* third char is = to indicate padding */
|
||||
*ptr++ = '=';
|
||||
/* fourth char is = to indicate padding */
|
||||
*ptr++ = '=';
|
||||
break;
|
||||
}
|
||||
strcpyW(ptr, sep);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static BOOL BinaryToBase64W(const BYTE *pbBinary,
|
||||
DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString)
|
||||
{
|
||||
static const WCHAR crlf[] = { '\r','\n',0 }, lf[] = { '\n',0 };
|
||||
BOOL ret = TRUE;
|
||||
LPCWSTR header = NULL, trailer = NULL, sep = NULL;
|
||||
DWORD charsNeeded;
|
||||
|
||||
if (dwFlags & CRYPT_STRING_NOCR)
|
||||
sep = lf;
|
||||
else
|
||||
sep = crlf;
|
||||
switch (dwFlags & 0x7fffffff)
|
||||
{
|
||||
case CRYPT_STRING_BASE64:
|
||||
/* no header or footer */
|
||||
break;
|
||||
case CRYPT_STRING_BASE64HEADER:
|
||||
header = CERT_HEADER_W;
|
||||
trailer = CERT_TRAILER_W;
|
||||
break;
|
||||
case CRYPT_STRING_BASE64REQUESTHEADER:
|
||||
header = CERT_REQUEST_HEADER_W;
|
||||
trailer = CERT_REQUEST_TRAILER_W;
|
||||
break;
|
||||
case CRYPT_STRING_BASE64X509CRLHEADER:
|
||||
header = X509_HEADER_W;
|
||||
trailer = X509_TRAILER_W;
|
||||
break;
|
||||
}
|
||||
|
||||
charsNeeded = 0;
|
||||
encodeBase64W(pbBinary, cbBinary, sep, NULL, &charsNeeded);
|
||||
charsNeeded += strlenW(sep);
|
||||
if (header)
|
||||
charsNeeded += strlenW(header) + strlenW(sep);
|
||||
if (trailer)
|
||||
charsNeeded += strlenW(trailer) + strlenW(sep);
|
||||
if (charsNeeded <= *pcchString)
|
||||
{
|
||||
LPWSTR ptr = pszString;
|
||||
DWORD size = charsNeeded;
|
||||
|
||||
if (header)
|
||||
{
|
||||
strcpyW(ptr, header);
|
||||
ptr += strlenW(ptr);
|
||||
strcpyW(ptr, sep);
|
||||
ptr += strlenW(sep);
|
||||
}
|
||||
encodeBase64W(pbBinary, cbBinary, sep, ptr, &size);
|
||||
ptr += size - 1;
|
||||
if (trailer)
|
||||
{
|
||||
strcpyW(ptr, trailer);
|
||||
ptr += strlenW(ptr);
|
||||
strcpyW(ptr, sep);
|
||||
ptr += strlenW(sep);
|
||||
}
|
||||
*pcchString = charsNeeded - 1;
|
||||
}
|
||||
else if (pszString)
|
||||
{
|
||||
*pcchString = charsNeeded;
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
ret = FALSE;
|
||||
}
|
||||
else
|
||||
*pcchString = charsNeeded;
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI CryptBinaryToStringW(const BYTE *pbBinary,
|
||||
DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString)
|
||||
{
|
||||
BinaryToStringWFunc encoder = NULL;
|
||||
|
||||
TRACE("(%p, %d, %08x, %p, %p)\n", pbBinary, cbBinary, dwFlags, pszString,
|
||||
pcchString);
|
||||
|
||||
if (!pbBinary)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
if (!pcchString)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (dwFlags & 0x7fffffff)
|
||||
{
|
||||
case CRYPT_STRING_BASE64:
|
||||
case CRYPT_STRING_BASE64HEADER:
|
||||
case CRYPT_STRING_BASE64REQUESTHEADER:
|
||||
case CRYPT_STRING_BASE64X509CRLHEADER:
|
||||
encoder = BinaryToBase64W;
|
||||
break;
|
||||
case CRYPT_STRING_BINARY:
|
||||
case CRYPT_STRING_HEX:
|
||||
case CRYPT_STRING_HEXASCII:
|
||||
case CRYPT_STRING_HEXADDR:
|
||||
case CRYPT_STRING_HEXASCIIADDR:
|
||||
FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff);
|
||||
/* fall through */
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
return encoder(pbBinary, cbBinary, dwFlags, pszString, pcchString);
|
||||
}
|
||||
|
||||
static inline BYTE decodeBase64Byte(int c)
|
||||
{
|
||||
BYTE ret;
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
@ stdcall CertVerifyValidityNesting(ptr ptr)
|
||||
@ stdcall CreateFileU(wstr long long ptr long long ptr) kernel32.CreateFileW
|
||||
@ stdcall CryptBinaryToStringA(ptr long long ptr ptr)
|
||||
@ stub CryptBinaryToStringW # (ptr long long ptr ptr)
|
||||
@ stdcall CryptBinaryToStringW(ptr long long ptr ptr)
|
||||
@ stdcall CryptStringToBinaryA(str long long ptr ptr ptr ptr)
|
||||
@ stdcall CryptStringToBinaryW (wstr long long ptr ptr ptr ptr)
|
||||
@ stdcall CryptAcquireContextU(ptr wstr wstr long long) advapi32.CryptAcquireContextW
|
||||
|
|
Loading…
Reference in New Issue