More changes to resolve issues brought up during the security

review of the code.
This commit is contained in:
Juan Carlos Luciani
2007-02-06 22:09:00 +00:00
parent 8719ce2410
commit 51ffdf0702
16 changed files with 550 additions and 427 deletions

View File

@@ -60,7 +60,7 @@ AuthTokenIf_GetAuthToken(
IN const char *pHostName,
IN void *pCredStoreScope,
INOUT char *pTokenBuf,
INOUT int *pTokenBufLen);
INOUT size_t *pTokenBufLen);
extern
int
@@ -74,17 +74,17 @@ extern
CasaStatus
EncodeData(
IN const void *pData,
IN const int32_t dataLen,
IN const uint32_t dataLen,
INOUT char **ppEncodedData,
INOUT int32_t *pEncodedDataLen);
INOUT uint32_t *pEncodedDataLen);
extern
CasaStatus
DecodeData(
IN const char *pEncodedData,
IN const int32_t encodedDataLen, // Does not include NULL terminator
IN const uint32_t encodedDataLen, // Does not include NULL terminator
INOUT void **ppData,
INOUT int32_t *pDataLen);
INOUT uint32_t *pDataLen);
extern
int

View File

@@ -129,7 +129,7 @@ AuthTokenIf_GetAuthToken(
IN const char *pHostName,
IN void *pCredStoreScope,
INOUT char *pTokenBuf,
INOUT int *pTokenBufLen)
INOUT uint32_t *pTokenBufLen)
//
// Arguments:
// pIfInstance -
@@ -186,7 +186,7 @@ AuthTokenIf_GetAuthToken(
//=======================================================================--
{
CasaStatus retStatus;
char const *pKrbServiceName = pMechInfo;
char *pKrbServiceName = (char*) pMechInfo;
OM_uint32 gssMajStat;
OM_uint32 gssMinStat;
gss_buffer_desc gssBuffer;
@@ -272,45 +272,56 @@ AuthTokenIf_GetAuthToken(
if (gssMajStat == GSS_S_COMPLETE
&& gssSendToken.length != 0)
{
char *pEncodedToken;
int encodedTokenLen;
// The security context was initialized, now return the token to the
// caller after base64 encoding it.
retStatus = EncodeData(gssSendToken.value,
gssSendToken.length,
&pEncodedToken,
&encodedTokenLen);
if (CASA_SUCCESS(retStatus))
// Make sure that the token is not too large
if (gssSendToken.length <= UINT32_MAX)
{
// Verify that the caller provided a buffer that is big enough
if (encodedTokenLen > *pTokenBufLen)
{
// At least one of the supplied buffers is not big enough
DbgTrace(1, "-AuthTokenIf_GetAuthToken- Insufficient buffer space provided\n", 0);
char *pEncodedToken;
uint32_t encodedTokenLen;
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_KRB5TOKEN,
CASA_STATUS_BUFFER_OVERFLOW);
// The security context was initialized, now return the token to the
// caller after base64 encoding it.
retStatus = EncodeData(gssSendToken.value,
gssSendToken.length,
&pEncodedToken,
&encodedTokenLen);
if (CASA_SUCCESS(retStatus))
{
// Verify that the caller provided a buffer that is big enough
if (encodedTokenLen > *pTokenBufLen)
{
// At least one of the supplied buffers is not big enough
DbgTrace(1, "-AuthTokenIf_GetAuthToken- Insufficient buffer space provided\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_KRB5TOKEN,
CASA_STATUS_BUFFER_OVERFLOW);
}
else
{
// The buffer provided is large enough, copy the data and return the actual size.
memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen);
// Success
retStatus = CASA_STATUS_SUCCESS;
}
// Return the actual size or the size required
*pTokenBufLen = encodedTokenLen;
// Free the buffer containing the encoded token
free(pEncodedToken);
}
else
{
// The buffer provided is large enough, copy the data and return the actual size.
memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen);
// Success
retStatus = CASA_STATUS_SUCCESS;
DbgTrace(1, "-AuthTokenIf_GetAuthToken- Encoding failed\n", 0);
}
// Return the actual size or the size required
*pTokenBufLen = encodedTokenLen;
// Free the buffer containing the encoded token
free(pEncodedToken);
}
else
{
DbgTrace(1, "-AuthTokenIf_GetAuthToken- Encoding failed\n", 0);
DbgTrace(0, "-AuthTokenIf_GetAuthToken- GSS Token too large\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_KRB5TOKEN,
CASA_STATUS_UNSUCCESSFUL);
}
}
else

View File

@@ -65,9 +65,9 @@ static const uint8_t g_Expand64[256] =
CasaStatus
EncodeData(
IN const void *pData,
IN const int32_t dataLen,
IN const uint32_t dataLen,
INOUT char **ppEncodedData,
INOUT int32_t *pEncodedDataLen)
INOUT uint32_t *pEncodedDataLen)
//
// Arguments:
//
@@ -150,9 +150,9 @@ EncodeData(
CasaStatus
DecodeData(
IN const char *pEncodedData,
IN const int32_t encodedDataLen, // Does not include NULL terminator
IN const uint32_t encodedDataLen, // Does not include NULL terminator
INOUT void **ppData,
INOUT int32_t *pDataLen)
INOUT uint32_t *pDataLen)
//
// Arguments:
//
@@ -164,8 +164,8 @@ DecodeData(
//=======================================================================--
{
CasaStatus retStatus;
int i, j;
int decodedSize;
uint32_t i, j;
size_t decodedSize;
DbgTrace(3, "-DecodeData- Start\n", 0);
@@ -175,98 +175,110 @@ DecodeData(
j++;
decodedSize = (j * 3 + 3) / 4;
// Allocate buffer to hold the decoded data
*ppData = malloc(decodedSize);
if (*ppData)
// Verify that we are not going to overflow the uint32
if (decodedSize <= UINT32_MAX)
{
bool endReached = false;
uint8_t c0, c1, c2, c3;
uint8_t *p, *q;
// Initialize parameters that will be used during the decode operation
c0 = c1 = c2 = c3 = 0;
p = (uint8_t*) pEncodedData;
q = (uint8_t*) *ppData;
// Decode the data
//
// Loop through the data, piecing back information. Any newlines, and/or
// carriage returns need to be skipped.
while (j > 4)
// Allocate buffer to hold the decoded data
*ppData = malloc(decodedSize);
if (*ppData)
{
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
endReached = true;
break;
}
c0 = *(p++);
bool endReached = false;
uint8_t c0, c1, c2, c3;
uint8_t *p, *q;
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
*(q++) = (uint8_t)(g_Expand64[c0] << 2);
j--;
endReached = true;
break;
}
c1 = *(p++);
// Initialize parameters that will be used during the decode operation
c0 = c1 = c2 = c3 = 0;
p = (uint8_t*) pEncodedData;
q = (uint8_t*) *ppData;
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
*(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
*(q++) = (uint8_t)(g_Expand64[c1] << 4);
j -= 2;
endReached = true;
break;
}
c2 = *(p++);
// Decode the data
//
// Loop through the data, piecing back information. Any newlines, and/or
// carriage returns need to be skipped.
while (j > 4)
{
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
endReached = true;
break;
}
c0 = *(p++);
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
*(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
*(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
*(q++) = (uint8_t)(g_Expand64[c2] << 6);
j -= 3;
endReached = true;
break;
}
c3 = *(p++);
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
*(q++) = (uint8_t)(g_Expand64[c0] << 2);
j--;
endReached = true;
break;
}
c1 = *(p++);
*(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
*(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
*(q++) = (uint8_t)(g_Expand64[c2] << 6 | g_Expand64[c3]);
j -= 4;
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
*(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
*(q++) = (uint8_t)(g_Expand64[c1] << 4);
j -= 2;
endReached = true;
break;
}
c2 = *(p++);
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
*(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
*(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
*(q++) = (uint8_t)(g_Expand64[c2] << 6);
j -= 3;
endReached = true;
break;
}
c3 = *(p++);
*(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
*(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
*(q++) = (uint8_t)(g_Expand64[c2] << 6 | g_Expand64[c3]);
j -= 4;
}
if (!endReached)
{
if (j > 1)
*(q++) = (uint8_t)(g_Expand64[*p] << 2 | g_Expand64[p[1]] >> 4);
if (j > 2)
*(q++) = (uint8_t)(g_Expand64[p[1]] << 4 | g_Expand64[p[2]] >> 2);
if (j > 3)
*(q++) = (uint8_t)(g_Expand64[p[2]] << 6 | g_Expand64[p[3]]);
}
// Return the length of the decoded data
*pDataLen = (int32_t)(q - (uint8_t*)*ppData);
// Success
retStatus = CASA_STATUS_SUCCESS;
}
if (!endReached)
else
{
if (j > 1)
*(q++) = (uint8_t)(g_Expand64[*p] << 2 | g_Expand64[p[1]] >> 4);
if (j > 2)
*(q++) = (uint8_t)(g_Expand64[p[1]] << 4 | g_Expand64[p[2]] >> 2);
if (j > 3)
*(q++) = (uint8_t)(g_Expand64[p[2]] << 6 | g_Expand64[p[3]]);
DbgTrace(0, "-DecodeData- Buffer allocation failure\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
// Return the length of the decoded data
*pDataLen = (int32_t)(q - (uint8_t*)*ppData);
// Success
retStatus = CASA_STATUS_SUCCESS;
}
else
{
DbgTrace(0, "-DecodeData- Buffer allocation failure\n", 0);
DbgTrace(0, "-DecodeData- Prevented uint32 overflow\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_PWTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
}
DbgTrace(3, "-DecodeData- End, retStatus = %0X\n", retStatus);

View File

@@ -43,7 +43,7 @@ AuthTokenIf_GetAuthToken(
IN const char *pHostName,
IN void *pCredStoreScope,
INOUT char *pTokenBuf,
INOUT int *pTokenBufLen)
INOUT uint32_t *pTokenBufLen)
//
// Arguments:
// pIfInstance -
@@ -131,6 +131,9 @@ AuthTokenIf_GetAuthToken(
else
{
DbgTrace(0, "-AuthTokenIf_GetAuthToken- Memory allocation failure\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_KRB5TOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
goto exit;
}
}
@@ -180,40 +183,55 @@ AuthTokenIf_GetAuthToken(
&expiry);
if (secStatus == SEC_E_OK)
{
char *pEncodedToken;
int encodedTokenLen;
// The security context was initialized, now return it to the caller after base64 encoding it.
retStatus = EncodeData(sendTok.pvBuffer,
(const int) sendTok.cbBuffer,
&pEncodedToken,
&encodedTokenLen);
if (CASA_SUCCESS(retStatus))
// Make sure that the token is not too large
if (sendTok.cbBuffer <= UINT32_MAX)
{
// Verify that the caller provided a buffer that is big enough
if (encodedTokenLen > *pTokenBufLen)
uint32_t encodedTokenLen;
char *pEncodedToken;
// The security context was initialized, now return it to the caller after base64 encoding it.
retStatus = EncodeData(sendTok.pvBuffer,
(const uint32_t) sendTok.cbBuffer,
&pEncodedToken,
&encodedTokenLen);
if (CASA_SUCCESS(retStatus))
{
// The buffer is not big enough
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_KRB5TOKEN,
CASA_STATUS_BUFFER_OVERFLOW);
// Verify that the caller provided a buffer that is big enough
if (encodedTokenLen > *pTokenBufLen)
{
// The buffer is not big enough
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_KRB5TOKEN,
CASA_STATUS_BUFFER_OVERFLOW);
}
else
{
// The buffer provided is large enough, copy the data.
memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen);
// Success
retStatus = CASA_STATUS_SUCCESS;
}
// Return the actual size or the size required
*pTokenBufLen = encodedTokenLen;
// Free the buffer containing the encoded token after clearing
// its memory to avoid leaking sensitive information.
memset(pEncodedToken, 0, strlen(pEncodedToken));
free(pEncodedToken);
}
else
{
// The buffer provided is large enough, copy the data.
memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen);
// Success
retStatus = CASA_STATUS_SUCCESS;
DbgTrace(1, "-AuthTokenIf_GetAuthToken- Encoding failed\n", 0);
}
// Return the actual size or the size required
*pTokenBufLen = encodedTokenLen;
// Free the buffer containing the encoded token after clearing
// its memory to avoid leaking sensitive information.
memset(pEncodedToken, 0, strlen(pEncodedToken));
free(pEncodedToken);
}
else
{
DbgTrace(0, "-AuthTokenIf_GetAuthToken- GSS Token too large\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_KRB5TOKEN,
CASA_STATUS_UNSUCCESSFUL);
}
// Delete the security context

View File

@@ -87,7 +87,7 @@ GetUserCredentials(
// Get the length of the realm string into the secret id structure
// and verify thatr it is not too long.
secretIdLen = sscs_Utf8Strlen(pRealm) + 1;
if (secretIdLen <= U32_MAX)
if (secretIdLen <= UINT32_MAX)
{
secretId.len = secretIdLen;
if (secretId.len <= NSSCS_MAX_SECRET_ID_LEN)
@@ -219,7 +219,7 @@ AuthTokenIf_GetAuthToken(
IN const char *pHostName,
IN void *pCredStoreScope,
INOUT char *pTokenBuf,
INOUT int *pTokenBufLen)
INOUT size_t *pTokenBufLen)
//
// Arguments:
// pIfInstance -
@@ -300,63 +300,80 @@ AuthTokenIf_GetAuthToken(
&pPassword);
if (CASA_SUCCESS(retStatus))
{
// Now construct the PW token with the following format:
// "username\r\n" + "password\r\n"
//
// First allocate a buffer large enough to hold the token
pToken = (char*) malloc(strlen(pUsername) + 2 + strlen(pPassword) + 2 + 1);
if (pToken)
size_t tokenLen = strlen(pUsername) + 2 + strlen(pPassword) + 2 + 1;
// Make sure that the token is not too large
if (tokenLen <= UINT32_MAX)
{
char *pEncodedToken;
int encodedTokenLen;
// Now assemble the token
sprintf(pToken, "%s\r\n%s\r\n", pUsername, pPassword);
// The token has been assembled, now encode it.
retStatus = EncodeData(pToken,
(const int) strlen(pToken),
&pEncodedToken,
&encodedTokenLen);
if (CASA_SUCCESS(retStatus))
// Now construct the PW token with the following format:
// "username\r\n" + "password\r\n"
//
// First allocate a buffer large enough to hold the token
pToken = (char*) malloc(strlen(pUsername) + 2 + strlen(pPassword) + 2 + 1);
if (pToken)
{
// Verify that the caller provided a buffer that is big enough
if (encodedTokenLen > *pTokenBufLen)
char *pEncodedToken;
uint32_t encodedTokenLen;
// Now assemble the token
sprintf(pToken, "%s\r\n%s\r\n", pUsername, pPassword);
// The token has been assembled, now encode it.
retStatus = EncodeData(pToken,
(const uint32_t) tokenLen,
&pEncodedToken,
&encodedTokenLen);
if (CASA_SUCCESS(retStatus))
{
// The buffer is not big enough
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_PWTOKEN,
CASA_STATUS_BUFFER_OVERFLOW);
// Verify that the caller provided a buffer that is big enough
if (encodedTokenLen > *pTokenBufLen)
{
// The buffer is not big enough
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_PWTOKEN,
CASA_STATUS_BUFFER_OVERFLOW);
}
else
{
// The buffer provided is large enough, copy the data.
memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen);
// Success
retStatus = CASA_STATUS_SUCCESS;
}
// Return the actual size or the size required
*pTokenBufLen = encodedTokenLen;
// Free the buffer containing the encoded token after clearing
// it to avoid leaking sensitive information.
memset(pEncodedToken, 0, strlen(pEncodedToken));
free(pEncodedToken);
}
else
{
// The buffer provided is large enough, copy the data.
memcpy((void*) pTokenBuf, pEncodedToken, encodedTokenLen);
// Success
retStatus = CASA_STATUS_SUCCESS;
DbgTrace(1, "-AuthTokenIf_GetAuthToken- Encoding failed\n", 0);
}
// Return the actual size or the size required
*pTokenBufLen = encodedTokenLen;
// Free the buffer containing the encoded token after clearing
// it to avoid leaking sensitive information.
memset(pEncodedToken, 0, strlen(pEncodedToken));
free(pEncodedToken);
// Free the buffer allocated for the token after clearing it
// to avoid leaving sensitive information behind.
memset(pToken, 0, strlen(pToken));
free(pToken);
}
else
{
DbgTrace(0, "-AuthTokenIf_GetAuthToken- Buffer allocation error\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_PWTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
// Free the buffer allocated for the token after clearing it
// to avoid leaving sensitive information behind.
memset(pToken, 0, strlen(pToken));
free(pToken);
}
else
{
DbgTrace(0, "-AuthTokenIf_GetAuthToken- Buffer allocation error\n", 0);
DbgTrace(0, "-AuthTokenIf_GetAuthToken- Token too large\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_PWTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
CASA_FACILITY_KRB5TOKEN,
CASA_STATUS_UNSUCCESSFUL);
}
// Free allocated buffers after clearing memory holding the password

View File

@@ -37,10 +37,6 @@
//===[ Type definitions ]==================================================
#ifndef U32_MAX
#define U32_MAX (~(uint32_t)0)
#endif
//===[ Inlines functions ]===============================================
//===[ Function prototypes ]===============================================
@@ -66,7 +62,7 @@ AuthTokenIf_GetAuthToken(
IN const char *pHostName,
IN void *pCredStoreScope,
INOUT char *pTokenBuf,
INOUT int *pTokenBufLen);
INOUT size_t *pTokenBufLen);
//
// Defined in utils.c
@@ -76,17 +72,17 @@ extern
CasaStatus
EncodeData(
IN const void *pData,
IN const int32_t dataLen,
IN const uint32_t dataLen,
INOUT char **ppEncodedData,
INOUT int32_t *pEncodedDataLen);
INOUT uint32_t *pEncodedDataLen);
extern
CasaStatus
DecodeData(
IN const char *pEncodedData,
IN const int32_t encodedDataLen, // Does not include NULL terminator
IN const uint32_t encodedDataLen, // Does not include NULL terminator
INOUT void **ppData,
INOUT int32_t *pDataLen);
INOUT uint32_t *pDataLen);
extern
int

View File

@@ -65,9 +65,9 @@ static const uint8_t g_Expand64[256] =
CasaStatus
EncodeData(
IN const void *pData,
IN const int32_t dataLen,
IN const uint32_t dataLen,
INOUT char **ppEncodedData,
INOUT int32_t *pEncodedDataLen)
INOUT uint32_t *pEncodedDataLen)
//
// Arguments:
//
@@ -150,9 +150,9 @@ EncodeData(
CasaStatus
DecodeData(
IN const char *pEncodedData,
IN const int32_t encodedDataLen, // Does not include NULL terminator
IN const uint32_t encodedDataLen, // Does not include NULL terminator
INOUT void **ppData,
INOUT int32_t *pDataLen)
INOUT uint32_t *pDataLen)
//
// Arguments:
//
@@ -164,8 +164,8 @@ DecodeData(
//=======================================================================--
{
CasaStatus retStatus;
int i, j;
int decodedSize;
uint32_t i, j;
size_t decodedSize;
DbgTrace(3, "-DecodeData- Start\n", 0);
@@ -175,98 +175,110 @@ DecodeData(
j++;
decodedSize = (j * 3 + 3) / 4;
// Allocate buffer to hold the decoded data
*ppData = malloc(decodedSize);
if (*ppData)
// Verify that we are not going to overflow the uint32
if (decodedSize <= UINT32_MAX)
{
bool endReached = false;
uint8_t c0, c1, c2, c3;
uint8_t *p, *q;
// Initialize parameters that will be used during the decode operation
c0 = c1 = c2 = c3 = 0;
p = (uint8_t*) pEncodedData;
q = (uint8_t*) *ppData;
// Decode the data
//
// Loop through the data, piecing back information. Any newlines, and/or
// carriage returns need to be skipped.
while (j > 4)
// Allocate buffer to hold the decoded data
*ppData = malloc(decodedSize);
if (*ppData)
{
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
endReached = true;
break;
}
c0 = *(p++);
bool endReached = false;
uint8_t c0, c1, c2, c3;
uint8_t *p, *q;
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
*(q++) = (uint8_t)(g_Expand64[c0] << 2);
j--;
endReached = true;
break;
}
c1 = *(p++);
// Initialize parameters that will be used during the decode operation
c0 = c1 = c2 = c3 = 0;
p = (uint8_t*) pEncodedData;
q = (uint8_t*) *ppData;
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
*(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
*(q++) = (uint8_t)(g_Expand64[c1] << 4);
j -= 2;
endReached = true;
break;
}
c2 = *(p++);
// Decode the data
//
// Loop through the data, piecing back information. Any newlines, and/or
// carriage returns need to be skipped.
while (j > 4)
{
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
endReached = true;
break;
}
c0 = *(p++);
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
*(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
*(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
*(q++) = (uint8_t)(g_Expand64[c2] << 6);
j -= 3;
endReached = true;
break;
}
c3 = *(p++);
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
*(q++) = (uint8_t)(g_Expand64[c0] << 2);
j--;
endReached = true;
break;
}
c1 = *(p++);
*(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
*(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
*(q++) = (uint8_t)(g_Expand64[c2] << 6 | g_Expand64[c3]);
j -= 4;
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
*(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
*(q++) = (uint8_t)(g_Expand64[c1] << 4);
j -= 2;
endReached = true;
break;
}
c2 = *(p++);
while ((64 == g_Expand64[*p]) && (('\n' == *p) || ('\r' == *p)))
p++;
if (64 == g_Expand64[*p])
{
*(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
*(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
*(q++) = (uint8_t)(g_Expand64[c2] << 6);
j -= 3;
endReached = true;
break;
}
c3 = *(p++);
*(q++) = (uint8_t)(g_Expand64[c0] << 2 | g_Expand64[c1] >> 4);
*(q++) = (uint8_t)(g_Expand64[c1] << 4 | g_Expand64[c2] >> 2);
*(q++) = (uint8_t)(g_Expand64[c2] << 6 | g_Expand64[c3]);
j -= 4;
}
if (!endReached)
{
if (j > 1)
*(q++) = (uint8_t)(g_Expand64[*p] << 2 | g_Expand64[p[1]] >> 4);
if (j > 2)
*(q++) = (uint8_t)(g_Expand64[p[1]] << 4 | g_Expand64[p[2]] >> 2);
if (j > 3)
*(q++) = (uint8_t)(g_Expand64[p[2]] << 6 | g_Expand64[p[3]]);
}
// Return the length of the decoded data
*pDataLen = (int32_t)(q - (uint8_t*)*ppData);
// Success
retStatus = CASA_STATUS_SUCCESS;
}
if (!endReached)
else
{
if (j > 1)
*(q++) = (uint8_t)(g_Expand64[*p] << 2 | g_Expand64[p[1]] >> 4);
if (j > 2)
*(q++) = (uint8_t)(g_Expand64[p[1]] << 4 | g_Expand64[p[2]] >> 2);
if (j > 3)
*(q++) = (uint8_t)(g_Expand64[p[2]] << 6 | g_Expand64[p[3]]);
DbgTrace(0, "-DecodeData- Buffer allocation failure\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
}
// Return the length of the decoded data
*pDataLen = (int32_t)(q - (uint8_t*)*ppData);
// Success
retStatus = CASA_STATUS_SUCCESS;
}
else
{
DbgTrace(0, "-DecodeData- Buffer allocation failure\n", 0);
DbgTrace(0, "-DecodeData- Prevented uint32 overflow\n", 0);
retStatus = CasaStatusBuild(CASA_SEVERITY_ERROR,
CASA_FACILITY_PWTOKEN,
CASA_STATUS_INSUFFICIENT_RESOURCES);
CASA_FACILITY_AUTHTOKEN,
CASA_STATUS_UNSUCCESSFUL);
}
DbgTrace(3, "-DecodeData- End, retStatus = %0X\n", retStatus);