Commit d16bed15 authored by Andrew Bogott's avatar Andrew Bogott Committed by Alexandre Julliard

crypt32: Rework Base64WithHeaderAndTrailerToBinaryA and…

crypt32: Rework Base64WithHeaderAndTrailerToBinaryA and Base64WithHeaderAndTrailerToBinaryW so that they accept a wider variety of headers and trailers.
parent 812d6477
......@@ -30,7 +30,10 @@
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
#define CERT_HEADER "-----BEGIN CERTIFICATE-----"
#define CERT_HEADER_START "-----BEGIN"
#define CERT_DELIMITER "-----"
#define CERT_TRAILER "-----END CERTIFICATE-----"
#define CERT_TRAILER_START "-----END"
#define CERT_REQUEST_HEADER "-----BEGIN NEW CERTIFICATE REQUEST-----"
#define CERT_REQUEST_TRAILER "-----END NEW CERTIFICATE REQUEST-----"
#define X509_HEADER "-----BEGIN X509 CRL-----"
......@@ -39,7 +42,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(crypt);
static const WCHAR CERT_HEADER_W[] = {
'-','-','-','-','-','B','E','G','I','N',' ','C','E','R','T','I','F','I','C',
'A','T','E','-','-','-','-','-',0 };
static const WCHAR CERT_HEADER_START_W[] = {
'-','-','-','-','-','B','E','G','I','N',0 };
static const WCHAR CERT_DELIMITER_W[] = {
'-','-','-','-','-',0 };
static const WCHAR CERT_TRAILER_W[] = {
'-','-','-','-','-','E','N','D',0 };
static const WCHAR CERT_TRAILER_START_W[] = {
'-','-','-','-','-','E','N','D',' ','C','E','R','T','I','F','I','C','A','T',
'E','-','-','-','-','-',0 };
static const WCHAR CERT_REQUEST_HEADER_W[] = {
......@@ -605,42 +614,73 @@ static LONG Base64ToBinaryA(LPCSTR pszString, DWORD cchString,
static LONG Base64WithHeaderAndTrailerToBinaryA(LPCSTR pszString,
DWORD cchString, LPCSTR header, LPCSTR trailer, BYTE *pbBinary,
DWORD *pcbBinary, DWORD *pdwSkip)
DWORD *pcbBinary, DWORD *pdwSkip, BOOL exactHeaderAndTrailerMatch)
{
LONG ret;
LPCSTR ptr;
if (cchString > strlen(header) + strlen(trailer)
&& (ptr = strstr(pszString, header)) != NULL)
{
LPCSTR trailerSpot = pszString + cchString - strlen(trailer);
LPCSTR headerBegins;
LPCSTR dataBegins;
LPCSTR trailerBegins;
size_t dataLength;
if (pszString[cchString - 1] == '\n')
if ((strlen(header) + strlen(trailer)) > cchString)
{
cchString--;
trailerSpot--;
return ERROR_INVALID_DATA;
}
if (pszString[cchString - 1] == '\r')
if (!(headerBegins = strstr(pszString, header)))
{
cchString--;
trailerSpot--;
TRACE("Can't find %s in %s.\n", header, pszString);
return ERROR_INVALID_DATA;
}
if (!strncmp(trailerSpot, trailer, strlen(trailer)))
dataBegins = headerBegins + strlen(header);
if (!exactHeaderAndTrailerMatch)
{
if (pdwSkip)
*pdwSkip = ptr - pszString;
ptr += strlen(header);
if (*ptr == '\r') ptr++;
if (*ptr == '\n') ptr++;
cchString -= ptr - pszString + strlen(trailer);
ret = Base64ToBinaryA(ptr, cchString, pbBinary, pcbBinary, NULL,
NULL);
if ((dataBegins = strstr(dataBegins, CERT_DELIMITER)))
{
dataBegins += strlen(CERT_DELIMITER);
}
else
ret = ERROR_INVALID_DATA;
{
return ERROR_INVALID_DATA;
}
}
if (*dataBegins == '\r') dataBegins++;
if (*dataBegins == '\n') dataBegins++;
if (exactHeaderAndTrailerMatch)
{
trailerBegins = pszString + cchString - strlen(trailer);
if (pszString[cchString - 1] == '\n') trailerBegins--;
if (pszString[cchString - 2] == '\r') trailerBegins--;
if (*(trailerBegins-1) == '\n') trailerBegins--;
if (*(trailerBegins-1) == '\r') trailerBegins--;
if (!strncmp(trailerBegins, trailer, strlen(trailer)))
{
return ERROR_INVALID_DATA;
}
}
else
ret = ERROR_INVALID_DATA;
{
if (!(trailerBegins = strstr(dataBegins, trailer)))
{
return ERROR_INVALID_DATA;
}
if (*(trailerBegins-1) == '\n') trailerBegins--;
if (*(trailerBegins-1) == '\r') trailerBegins--;
}
if (pdwSkip)
*pdwSkip = headerBegins - pszString;
dataLength = trailerBegins - dataBegins;
ret = Base64ToBinaryA(dataBegins, dataLength, pbBinary, pcbBinary, NULL,
NULL);
return ret;
}
......@@ -648,7 +688,7 @@ static LONG Base64HeaderToBinaryA(LPCSTR pszString, DWORD cchString,
BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
{
LONG ret = Base64WithHeaderAndTrailerToBinaryA(pszString, cchString,
CERT_HEADER, CERT_TRAILER, pbBinary, pcbBinary, pdwSkip);
CERT_HEADER_START, CERT_TRAILER_START, pbBinary, pcbBinary, pdwSkip, FALSE);
if (!ret && pdwFlags)
*pdwFlags = CRYPT_STRING_BASE64HEADER;
......@@ -659,7 +699,7 @@ static LONG Base64RequestHeaderToBinaryA(LPCSTR pszString, DWORD cchString,
BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
{
LONG ret = Base64WithHeaderAndTrailerToBinaryA(pszString, cchString,
CERT_REQUEST_HEADER, CERT_REQUEST_TRAILER, pbBinary, pcbBinary, pdwSkip);
CERT_REQUEST_HEADER, CERT_REQUEST_TRAILER, pbBinary, pcbBinary, pdwSkip, TRUE);
if (!ret && pdwFlags)
*pdwFlags = CRYPT_STRING_BASE64REQUESTHEADER;
......@@ -670,7 +710,7 @@ static LONG Base64X509HeaderToBinaryA(LPCSTR pszString, DWORD cchString,
BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
{
LONG ret = Base64WithHeaderAndTrailerToBinaryA(pszString, cchString,
X509_HEADER, X509_TRAILER, pbBinary, pcbBinary, pdwSkip);
X509_HEADER, X509_TRAILER, pbBinary, pcbBinary, pdwSkip, TRUE);
if (!ret && pdwFlags)
*pdwFlags = CRYPT_STRING_BASE64X509CRLHEADER;
......@@ -904,42 +944,73 @@ static LONG Base64ToBinaryW(LPCWSTR pszString, DWORD cchString,
static LONG Base64WithHeaderAndTrailerToBinaryW(LPCWSTR pszString,
DWORD cchString, LPCWSTR header, LPCWSTR trailer, BYTE *pbBinary,
DWORD *pcbBinary, DWORD *pdwSkip)
DWORD *pcbBinary, DWORD *pdwSkip, BOOL exactHeaderAndTrailerMatch)
{
LONG ret;
LPCWSTR ptr;
if (cchString > strlenW(header) + strlenW(trailer)
&& (ptr = strstrW(pszString, header)) != NULL)
{
LPCWSTR trailerSpot = pszString + cchString - strlenW(trailer);
LPCWSTR headerBegins;
LPCWSTR dataBegins;
LPCWSTR trailerBegins;
size_t dataLength;
if (pszString[cchString - 1] == '\n')
if ((strlenW(header) + strlenW(trailer)) > cchString)
{
cchString--;
trailerSpot--;
return ERROR_INVALID_DATA;
}
if (pszString[cchString - 1] == '\r')
if (!(headerBegins = strstrW(pszString, header)))
{
cchString--;
trailerSpot--;
TRACE("Can't find %s in %s.\n", debugstr_w(header), debugstr_w(pszString));
return ERROR_INVALID_DATA;
}
if (!strncmpW(trailerSpot, trailer, strlenW(trailer)))
dataBegins = headerBegins + strlenW(header);
if (!exactHeaderAndTrailerMatch)
{
if (pdwSkip)
*pdwSkip = ptr - pszString;
ptr += strlenW(header);
if (*ptr == '\r') ptr++;
if (*ptr == '\n') ptr++;
cchString -= ptr - pszString + strlenW(trailer);
ret = Base64ToBinaryW(ptr, cchString, pbBinary, pcbBinary, NULL,
NULL);
if ((dataBegins = strstrW(dataBegins, CERT_DELIMITER_W)))
{
dataBegins += strlenW(CERT_DELIMITER_W);
}
else
ret = ERROR_INVALID_DATA;
{
return ERROR_INVALID_DATA;
}
}
if (*dataBegins == '\r') dataBegins++;
if (*dataBegins == '\n') dataBegins++;
if (exactHeaderAndTrailerMatch)
{
trailerBegins = pszString + cchString - strlenW(trailer);
if (pszString[cchString - 1] == '\n') trailerBegins--;
if (pszString[cchString - 2] == '\r') trailerBegins--;
if (*(trailerBegins-1) == '\n') trailerBegins--;
if (*(trailerBegins-1) == '\r') trailerBegins--;
if (!strncmpW(trailerBegins, trailer, strlenW(trailer)))
{
return ERROR_INVALID_DATA;
}
}
else
ret = ERROR_INVALID_DATA;
{
if (!(trailerBegins = strstrW(dataBegins, trailer)))
{
return ERROR_INVALID_DATA;
}
if (*(trailerBegins-1) == '\n') trailerBegins--;
if (*(trailerBegins-1) == '\r') trailerBegins--;
}
if (pdwSkip)
*pdwSkip = headerBegins - pszString;
dataLength = trailerBegins - dataBegins;
ret = Base64ToBinaryW(dataBegins, dataLength, pbBinary, pcbBinary, NULL,
NULL);
return ret;
}
......@@ -947,7 +1018,8 @@ static LONG Base64HeaderToBinaryW(LPCWSTR pszString, DWORD cchString,
BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
{
LONG ret = Base64WithHeaderAndTrailerToBinaryW(pszString, cchString,
CERT_HEADER_W, CERT_TRAILER_W, pbBinary, pcbBinary, pdwSkip);
CERT_HEADER_START_W, CERT_TRAILER_START_W, pbBinary, pcbBinary,
pdwSkip, FALSE);
if (!ret && pdwFlags)
*pdwFlags = CRYPT_STRING_BASE64HEADER;
......@@ -959,7 +1031,7 @@ static LONG Base64RequestHeaderToBinaryW(LPCWSTR pszString, DWORD cchString,
{
LONG ret = Base64WithHeaderAndTrailerToBinaryW(pszString, cchString,
CERT_REQUEST_HEADER_W, CERT_REQUEST_TRAILER_W, pbBinary, pcbBinary,
pdwSkip);
pdwSkip, TRUE);
if (!ret && pdwFlags)
*pdwFlags = CRYPT_STRING_BASE64REQUESTHEADER;
......@@ -970,7 +1042,7 @@ static LONG Base64X509HeaderToBinaryW(LPCWSTR pszString, DWORD cchString,
BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags)
{
LONG ret = Base64WithHeaderAndTrailerToBinaryW(pszString, cchString,
X509_HEADER_W, X509_TRAILER_W, pbBinary, pcbBinary, pdwSkip);
X509_HEADER_W, X509_TRAILER_W, pbBinary, pcbBinary, pdwSkip, TRUE);
if (!ret && pdwFlags)
*pdwFlags = CRYPT_STRING_BASE64X509CRLHEADER;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment