forked from wolfSSL/wolfssl
S/MIME: Canonicalize multi-part messages before hashing. Improve error checking in wc_MIME_parse_headers.
This commit is contained in:
45
src/ssl.c
45
src/ssl.c
@@ -54354,11 +54354,14 @@ WOLFSSL_API PKCS7* wolfSSL_SMIME_read_PKCS7(WOLFSSL_BIO* in,
|
|||||||
int sectionLen = 0;
|
int sectionLen = 0;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
char* section = NULL;
|
char* section = NULL;
|
||||||
|
char* canonLine = NULL;
|
||||||
|
char* canonSection = NULL;
|
||||||
PKCS7* pkcs7 = NULL;
|
PKCS7* pkcs7 = NULL;
|
||||||
word32 outLen = 0;
|
word32 outLen = 0;
|
||||||
byte* out = NULL;
|
byte* out = NULL;
|
||||||
byte* outHead = NULL;
|
byte* outHead = NULL;
|
||||||
|
|
||||||
|
int canonPos = 0;
|
||||||
int lineLen = 0;
|
int lineLen = 0;
|
||||||
int remainLen = 0;
|
int remainLen = 0;
|
||||||
byte isEnd = 0;
|
byte isEnd = 0;
|
||||||
@@ -54461,38 +54464,60 @@ WOLFSSL_API PKCS7* wolfSSL_SMIME_read_PKCS7(WOLFSSL_BIO* in,
|
|||||||
|
|
||||||
section[0] = '\0';
|
section[0] = '\0';
|
||||||
sectionLen = 0;
|
sectionLen = 0;
|
||||||
|
canonSection = XMALLOC((remainLen+1)*sizeof(char), NULL,
|
||||||
|
DYNAMIC_TYPE_PKCS7);
|
||||||
|
if (canonSection == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
lineLen = wolfSSL_BIO_gets(in, section, remainLen);
|
lineLen = wolfSSL_BIO_gets(in, section, remainLen);
|
||||||
while(XSTRNCMP(§ion[sectionLen], boundary, boundLen) &&
|
while(XSTRNCMP(§ion[sectionLen], boundary, boundLen) &&
|
||||||
remainLen > 0) {
|
remainLen > 0) {
|
||||||
|
canonLine = wc_MIME_canonicalize(§ion[sectionLen]);
|
||||||
|
if (canonLine == NULL) {
|
||||||
|
XFREE(canonSection, NULL, DYNAMIC_TYPE_PKCS7);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
XMEMCPY(&canonSection[canonPos], canonLine,
|
||||||
|
(int)XSTRLEN(canonLine));
|
||||||
|
canonPos += XSTRLEN(canonLine);
|
||||||
|
XFREE(canonLine, NULL, DYNAMIC_TYPE_PKCS7);
|
||||||
|
|
||||||
sectionLen += lineLen;
|
sectionLen += lineLen;
|
||||||
remainLen -= lineLen;
|
remainLen -= lineLen;
|
||||||
|
|
||||||
lineLen = wolfSSL_BIO_gets(in, §ion[sectionLen],
|
lineLen = wolfSSL_BIO_gets(in, §ion[sectionLen],
|
||||||
remainLen);
|
remainLen);
|
||||||
if (lineLen <= 0) {
|
if (lineLen <= 0) {
|
||||||
|
XFREE(canonSection, NULL, DYNAMIC_TYPE_PKCS7);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sectionLen--;
|
|
||||||
|
canonPos--;
|
||||||
/* Strip the final trailing newline. Support \r, \n or \r\n. */
|
/* Strip the final trailing newline. Support \r, \n or \r\n. */
|
||||||
if (section[sectionLen] == '\n') {
|
if (canonSection[canonPos] == '\n') {
|
||||||
sectionLen--;
|
canonPos--;
|
||||||
if (section[sectionLen] == '\r') {
|
if (canonSection[canonPos] == '\r') {
|
||||||
sectionLen--;
|
canonPos--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (section[sectionLen] == '\r') {
|
else if (canonSection[canonPos] == '\r') {
|
||||||
sectionLen--;
|
canonPos--;
|
||||||
}
|
}
|
||||||
section[sectionLen+1] = '\0';
|
canonSection[canonPos+1] = '\0';
|
||||||
|
|
||||||
*bcont = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
|
*bcont = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
|
||||||
ret = wolfSSL_BIO_write(*bcont, section, (int)XSTRLEN(section));
|
ret = wolfSSL_BIO_write(*bcont, canonSection,
|
||||||
if (ret != (int)XSTRLEN(section)) {
|
(int)XSTRLEN(canonSection));
|
||||||
|
if (ret != (int)XSTRLEN(canonSection)) {
|
||||||
|
XFREE(canonSection, NULL, DYNAMIC_TYPE_PKCS7);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if ((bcontMemSz = wolfSSL_BIO_get_mem_data(*bcont, &bcontMem)) < 0) {
|
if ((bcontMemSz = wolfSSL_BIO_get_mem_data(*bcont, &bcontMem)) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
XFREE(canonSection, NULL, DYNAMIC_TYPE_PKCS7);
|
||||||
|
|
||||||
|
|
||||||
wc_MIME_free_hdrs(allHdrs);
|
wc_MIME_free_hdrs(allHdrs);
|
||||||
|
@@ -18547,13 +18547,17 @@ int wc_MIME_parse_headers(char* in, int inLen, MimeHdr** headers)
|
|||||||
}
|
}
|
||||||
start = end = 0;
|
start = end = 0;
|
||||||
lineLen = XSTRLEN(curLine);
|
lineLen = XSTRLEN(curLine);
|
||||||
|
if (lineLen == 0) {
|
||||||
|
ret = BAD_FUNC_ARG;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
for (pos = 0; pos < lineLen; pos++) {
|
for (pos = 0; pos < lineLen; pos++) {
|
||||||
char cur = curLine[pos];
|
char cur = curLine[pos];
|
||||||
|
|
||||||
if (mimeStatus == MIME_NAMEATTR && ((cur == ':' &&
|
if (mimeStatus == MIME_NAMEATTR && ((cur == ':' &&
|
||||||
mimeType == MIME_HDR) || (cur == '=' &&
|
mimeType == MIME_HDR) || (cur == '=' &&
|
||||||
mimeType == MIME_PARAM))) {
|
mimeType == MIME_PARAM)) && pos >= 1) {
|
||||||
mimeStatus = MIME_BODYVAL;
|
mimeStatus = MIME_BODYVAL;
|
||||||
end = pos-1;
|
end = pos-1;
|
||||||
ret = wc_MIME_header_strip(curLine, &nameAttr, start, end);
|
ret = wc_MIME_header_strip(curLine, &nameAttr, start, end);
|
||||||
@@ -18562,7 +18566,7 @@ int wc_MIME_parse_headers(char* in, int inLen, MimeHdr** headers)
|
|||||||
}
|
}
|
||||||
start = pos+1;
|
start = pos+1;
|
||||||
}
|
}
|
||||||
else if (mimeStatus == MIME_BODYVAL && cur == ';') {
|
else if (mimeStatus == MIME_BODYVAL && cur == ';' && pos >= 1) {
|
||||||
end = pos-1;
|
end = pos-1;
|
||||||
ret = wc_MIME_header_strip(curLine, &bodyVal, start, end);
|
ret = wc_MIME_header_strip(curLine, &bodyVal, start, end);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -18570,7 +18574,9 @@ int wc_MIME_parse_headers(char* in, int inLen, MimeHdr** headers)
|
|||||||
}
|
}
|
||||||
if (mimeType == MIME_HDR) {
|
if (mimeType == MIME_HDR) {
|
||||||
nextHdr->name = nameAttr;
|
nextHdr->name = nameAttr;
|
||||||
|
nameAttr = NULL;
|
||||||
nextHdr->body = bodyVal;
|
nextHdr->body = bodyVal;
|
||||||
|
bodyVal = NULL;
|
||||||
nextHdr->next = curHdr;
|
nextHdr->next = curHdr;
|
||||||
curHdr = nextHdr;
|
curHdr = nextHdr;
|
||||||
nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL,
|
nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL,
|
||||||
@@ -18583,7 +18589,9 @@ int wc_MIME_parse_headers(char* in, int inLen, MimeHdr** headers)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nextParam->attribute = nameAttr;
|
nextParam->attribute = nameAttr;
|
||||||
|
nameAttr = NULL;
|
||||||
nextParam->value = bodyVal;
|
nextParam->value = bodyVal;
|
||||||
|
bodyVal = NULL;
|
||||||
nextParam->next = curHdr->params;
|
nextParam->next = curHdr->params;
|
||||||
curHdr->params = nextParam;
|
curHdr->params = nextParam;
|
||||||
nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
|
nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
|
||||||
@@ -18612,7 +18620,9 @@ int wc_MIME_parse_headers(char* in, int inLen, MimeHdr** headers)
|
|||||||
}
|
}
|
||||||
if (mimeType == MIME_HDR) {
|
if (mimeType == MIME_HDR) {
|
||||||
nextHdr->name = nameAttr;
|
nextHdr->name = nameAttr;
|
||||||
|
nameAttr = NULL;
|
||||||
nextHdr->body = bodyVal;
|
nextHdr->body = bodyVal;
|
||||||
|
bodyVal = NULL;
|
||||||
nextHdr->next = curHdr;
|
nextHdr->next = curHdr;
|
||||||
curHdr = nextHdr;
|
curHdr = nextHdr;
|
||||||
nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL,
|
nextHdr = (MimeHdr*)XMALLOC(sizeof(MimeHdr), NULL,
|
||||||
@@ -18624,7 +18634,9 @@ int wc_MIME_parse_headers(char* in, int inLen, MimeHdr** headers)
|
|||||||
XMEMSET(nextHdr, 0, (word32)sizeof(MimeHdr));
|
XMEMSET(nextHdr, 0, (word32)sizeof(MimeHdr));
|
||||||
} else {
|
} else {
|
||||||
nextParam->attribute = nameAttr;
|
nextParam->attribute = nameAttr;
|
||||||
|
nameAttr = NULL;
|
||||||
nextParam->value = bodyVal;
|
nextParam->value = bodyVal;
|
||||||
|
bodyVal = NULL;
|
||||||
nextParam->next = curHdr->params;
|
nextParam->next = curHdr->params;
|
||||||
curHdr->params = nextParam;
|
curHdr->params = nextParam;
|
||||||
nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
|
nextParam = (MimeParam*)XMALLOC(sizeof(MimeParam), NULL,
|
||||||
@@ -18650,8 +18662,10 @@ int wc_MIME_parse_headers(char* in, int inLen, MimeHdr** headers)
|
|||||||
error:
|
error:
|
||||||
wc_MIME_free_hdrs(curHdr);
|
wc_MIME_free_hdrs(curHdr);
|
||||||
wc_MIME_free_hdrs(nextHdr);
|
wc_MIME_free_hdrs(nextHdr);
|
||||||
XFREE(nameAttr, NULL, DYNAMIC_TYPE_PKCS7);
|
if (nameAttr != NULL)
|
||||||
XFREE(bodyVal, NULL, DYNAMIC_TYPE_PKCS7);
|
XFREE(nameAttr, NULL, DYNAMIC_TYPE_PKCS7);
|
||||||
|
if (bodyVal != NULL)
|
||||||
|
XFREE(bodyVal, NULL, DYNAMIC_TYPE_PKCS7);
|
||||||
XFREE(nextParam, NULL, DYNAMIC_TYPE_PKCS7);
|
XFREE(nextParam, NULL, DYNAMIC_TYPE_PKCS7);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -18742,6 +18756,41 @@ MimeParam* wc_MIME_find_param_attr(const char* attribute,
|
|||||||
return param;
|
return param;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* wc_MIME_canonicalize - Canonicalize a line by converting all line endings
|
||||||
|
* to CRLF.
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
* returns a pointer to a canonicalized line on success, NULL on error.
|
||||||
|
*/
|
||||||
|
char* wc_MIME_canonicalize(const char* line)
|
||||||
|
{
|
||||||
|
size_t end = 0;
|
||||||
|
char* canonLine = NULL;
|
||||||
|
|
||||||
|
if (line == NULL || XSTRLEN(line) == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = XSTRLEN(line);
|
||||||
|
while (end >= 1 && ((line[end-1] == '\r') || (line[end-1] == '\n'))) {
|
||||||
|
end--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need 2 chars for \r\n and 1 for EOL */
|
||||||
|
canonLine = (char*)XMALLOC((end+3)*sizeof(char), NULL, DYNAMIC_TYPE_PKCS7);
|
||||||
|
if (canonLine == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
XSTRNCPY(canonLine, line, end);
|
||||||
|
canonLine[end] = '\r';
|
||||||
|
canonLine[end+1] = '\n';
|
||||||
|
canonLine[end+2] = '\0';
|
||||||
|
|
||||||
|
return canonLine;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* wc_MIME_free_hdrs - Frees all MIME headers, parameters and strings starting from
|
* wc_MIME_free_hdrs - Frees all MIME headers, parameters and strings starting from
|
||||||
* the provided header pointer.
|
* the provided header pointer.
|
||||||
|
@@ -1295,6 +1295,7 @@ WOLFSSL_LOCAL int wc_MIME_create_header(char* name, char* body, MimeHdr** hdr);
|
|||||||
WOLFSSL_LOCAL int wc_MIME_create_parameter(char* attribute, char* value, MimeParam** param);
|
WOLFSSL_LOCAL int wc_MIME_create_parameter(char* attribute, char* value, MimeParam** param);
|
||||||
WOLFSSL_LOCAL MimeHdr* wc_MIME_find_header_name(const char* name, MimeHdr* hdr);
|
WOLFSSL_LOCAL MimeHdr* wc_MIME_find_header_name(const char* name, MimeHdr* hdr);
|
||||||
WOLFSSL_LOCAL MimeParam* wc_MIME_find_param_attr(const char* attribute, MimeParam* param);
|
WOLFSSL_LOCAL MimeParam* wc_MIME_find_param_attr(const char* attribute, MimeParam* param);
|
||||||
|
WOLFSSL_LOCAL char* wc_MIME_canonicalize(const char* line);
|
||||||
WOLFSSL_LOCAL int wc_MIME_free_hdrs(MimeHdr* head);
|
WOLFSSL_LOCAL int wc_MIME_free_hdrs(MimeHdr* head);
|
||||||
#endif /* HAVE_SMIME */
|
#endif /* HAVE_SMIME */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user