diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index 985189645..2fad2307e 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -379,22 +379,18 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) break; } #endif - if ( strncmp(command, "GET", 3) == 0) { - char type[] = "HTTP/1.0 200 ok\r\nContent-type:" - " text/html\r\n\r\n"; - char header[] = "
\n\n"; - char body[] = "greetings from wolfSSL\n"; - char footer[] = "\r\n\r\n"; + if (strncmp(command, "GET", 3) == 0) { + const char resp[] = + "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n" + "\r\n" + "greetings from wolfSSL\r\n\r\n\r\n"; - strncpy(command, type, sizeof(type)); - echoSz = sizeof(type) - 1; - - strncpy(&command[echoSz], header, sizeof(header)); - echoSz += (int)sizeof(header) - 1; - strncpy(&command[echoSz], body, sizeof(body)); - echoSz += (int)sizeof(body) - 1; - strncpy(&command[echoSz], footer, sizeof(footer)); - echoSz += (int)sizeof(footer); + echoSz = (int)strlen(resp) + 1; + if (echoSz > (int)sizeof(command)) { + /* Internal error. */ + err_sys("HTTP response greater than buffer."); + } + strncpy(command, resp, sizeof(command)); do { err = 0; /* reset error */ diff --git a/src/crl.c b/src/crl.c index 59b2bcb63..93a77eec5 100644 --- a/src/crl.c +++ b/src/crl.c @@ -1045,8 +1045,7 @@ int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor) pathLen = (word32)XSTRLEN(path); pathBuf = (char*)XMALLOC(pathLen+1, crl->heap,DYNAMIC_TYPE_CRL_MONITOR); if (pathBuf) { - XSTRNCPY(pathBuf, path, pathLen); - pathBuf[pathLen] = '\0'; /* Null Terminate */ + XSTRNCPY(pathBuf, path, pathLen+1); if (type == WOLFSSL_FILETYPE_PEM) { /* free old path before setting a new one */ diff --git a/src/sniffer.c b/src/sniffer.c index 9f27ee97f..2feec52f9 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -252,7 +252,8 @@ static const char* const msgTable[] = /* *nix version uses table above */ static void GetError(int idx, char* str) { - XSTRNCPY(str, msgTable[idx - 1], MAX_ERROR_LEN); + XSTRNCPY(str, msgTable[idx - 1], MAX_ERROR_LEN-1); + str[MAX_ERROR_LEN-1] = '\0'; } diff --git a/src/ssl.c b/src/ssl.c index 5a5383765..ed1336b52 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -692,30 +692,25 @@ char* wolfSSL_get_cipher_list_ex(WOLFSSL* ssl, int priority) int wolfSSL_get_ciphers(char* buf, int len) { const CipherSuiteInfo* ciphers = GetCipherNames(); - int totalInc = 0; - int step = 0; - char delim = ':'; - int size = GetCipherNamesSize(); - int i; + int ciphersSz = GetCipherNamesSize(); + int i; + int cipherNameSz; if (buf == NULL || len <= 0) return BAD_FUNC_ARG; /* Add each member to the buffer delimited by a : */ - for (i = 0; i < size; i++) { - step = (int)(XSTRLEN(ciphers[i].name) + 1); /* delimiter */ - totalInc += step; + for (i = 0; i < ciphersSz; i++) { + cipherNameSz = (int)XSTRLEN(ciphers[i].name); + if (cipherNameSz + 1 < len) { + XSTRNCPY(buf, ciphers[i].name, len); + buf += cipherNameSz; - /* Check to make sure buf is large enough and will not overflow */ - if (totalInc < len) { - size_t cipherLen = XSTRLEN(ciphers[i].name); - XSTRNCPY(buf, ciphers[i].name, cipherLen); - buf += cipherLen; + if (i < ciphersSz - 1) + *buf++ = ':'; + *buf = 0; - if (i < size - 1) - *buf++ = delim; - else - *buf++ = '\0'; + len -= cipherNameSz + 1; } else return BUFFER_E; @@ -10738,8 +10733,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ssl->arrays->server_hint[0] = 0; else { XSTRNCPY(ssl->arrays->server_hint, hint, - sizeof(ssl->arrays->server_hint)); - ssl->arrays->server_hint[MAX_PSK_ID_LEN] = '\0'; /* null term */ + sizeof(ssl->arrays->server_hint)-1); + ssl->arrays->server_hint[sizeof(ssl->arrays->server_hint)-1] = '\0'; } return WOLFSSL_SUCCESS; } @@ -16518,7 +16513,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509) tmp[sizeof(tmp) - 1] = '\0'; if (mp_leading_bit(&rsa.n)) { lbit = 1; - XSTRNCAT(tmp, "00", sizeof("00")); + XSTRNCAT(tmp, "00", 3); } rawLen = mp_unsigned_bin_size(&rsa.n); @@ -25719,7 +25714,7 @@ static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher, return WOLFSSL_FAILURE; } XSTRNCPY((char*)*cipherInfo, info->name, cipherInfoSz); - XSTRNCAT((char*)*cipherInfo, ",", 1); + XSTRNCAT((char*)*cipherInfo, ",", 2); idx = (word32)XSTRLEN((char*)*cipherInfo); cipherInfoSz -= idx; diff --git a/src/wolfio.c b/src/wolfio.c index 72d86fa87..344b12f8b 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -1185,33 +1185,33 @@ int wolfIO_HttpBuildRequest(const char* reqType, const char* domainName, if (maxLen > (word32)bufSize) return 0; - XSTRNCPY((char*)buf, reqType, reqTypeLen); - buf += reqTypeLen; - XSTRNCPY((char*)buf, blankStr, blankStrLen+1); - buf += blankStrLen; - XSTRNCPY((char*)buf, path, pathLen); - buf += pathLen; - XSTRNCPY((char*)buf, http11Str, http11StrLen+1); - buf += http11StrLen; + XSTRNCPY((char*)buf, reqType, bufSize); + buf += reqTypeLen; bufSize -= reqTypeLen; + XSTRNCPY((char*)buf, blankStr, bufSize); + buf += blankStrLen; bufSize -= blankStrLen; + XSTRNCPY((char*)buf, path, bufSize); + buf += pathLen; bufSize -= pathLen; + XSTRNCPY((char*)buf, http11Str, bufSize); + buf += http11StrLen; bufSize -= http11StrLen; if (domainNameLen > 0) { - XSTRNCPY((char*)buf, hostStr, hostStrLen+1); - buf += hostStrLen; - XSTRNCPY((char*)buf, domainName, domainNameLen); - buf += domainNameLen; + XSTRNCPY((char*)buf, hostStr, bufSize); + buf += hostStrLen; bufSize -= hostStrLen; + XSTRNCPY((char*)buf, domainName, bufSize); + buf += domainNameLen; bufSize -= domainNameLen; } if (reqSz > 0 && reqSzStrLen > 0) { - XSTRNCPY((char*)buf, contentLenStr, contentLenStrLen+1); - buf += contentLenStrLen; - XSTRNCPY((char*)buf, reqSzStr, reqSzStrLen); - buf += reqSzStrLen; + XSTRNCPY((char*)buf, contentLenStr, bufSize); + buf += contentLenStrLen; bufSize -= contentLenStrLen; + XSTRNCPY((char*)buf, reqSzStr, bufSize); + buf += reqSzStrLen; bufSize -= reqSzStrLen; } if (contentTypeLen > 0) { - XSTRNCPY((char*)buf, contentTypeStr, contentTypeStrLen+1); - buf += contentTypeStrLen; - XSTRNCPY((char*)buf, contentType, contentTypeLen); - buf += contentTypeLen; + XSTRNCPY((char*)buf, contentTypeStr, bufSize); + buf += contentTypeStrLen; bufSize -= contentTypeStrLen; + XSTRNCPY((char*)buf, contentType, bufSize); + buf += contentTypeLen; bufSize -= contentTypeLen; } - XSTRNCPY((char*)buf, doubleCrLfStr, doubleCrLfStrLen+1); + XSTRNCPY((char*)buf, doubleCrLfStr, bufSize); buf += doubleCrLfStrLen; #ifdef WOLFIO_DEBUG diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 8b7282caf..a06492227 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -4564,24 +4564,23 @@ int GetTimeString(byte* date, int format, char* buf, int len) /* place month in buffer */ buf[0] = '\0'; switch(t.tm_mon) { - case 0: XSTRNCAT(buf, "Jan ", 4); break; - case 1: XSTRNCAT(buf, "Feb ", 4); break; - case 2: XSTRNCAT(buf, "Mar ", 4); break; - case 3: XSTRNCAT(buf, "Apr ", 4); break; - case 4: XSTRNCAT(buf, "May ", 4); break; - case 5: XSTRNCAT(buf, "Jun ", 4); break; - case 6: XSTRNCAT(buf, "Jul ", 4); break; - case 7: XSTRNCAT(buf, "Aug ", 4); break; - case 8: XSTRNCAT(buf, "Sep ", 4); break; - case 9: XSTRNCAT(buf, "Oct ", 4); break; - case 10: XSTRNCAT(buf, "Nov ", 4); break; - case 11: XSTRNCAT(buf, "Dec ", 4); break; + case 0: XSTRNCAT(buf, "Jan ", 5); break; + case 1: XSTRNCAT(buf, "Feb ", 5); break; + case 2: XSTRNCAT(buf, "Mar ", 5); break; + case 3: XSTRNCAT(buf, "Apr ", 5); break; + case 4: XSTRNCAT(buf, "May ", 5); break; + case 5: XSTRNCAT(buf, "Jun ", 5); break; + case 6: XSTRNCAT(buf, "Jul ", 5); break; + case 7: XSTRNCAT(buf, "Aug ", 5); break; + case 8: XSTRNCAT(buf, "Sep ", 5); break; + case 9: XSTRNCAT(buf, "Oct ", 5); break; + case 10: XSTRNCAT(buf, "Nov ", 5); break; + case 11: XSTRNCAT(buf, "Dec ", 5); break; default: return 0; } idx = 4; /* use idx now for char buffer */ - buf[idx] = ' '; XSNPRINTF(buf + idx, len - idx, "%2d %02d:%02d:%02d %d GMT", t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, t.tm_year + 1900); @@ -7725,19 +7724,23 @@ static int wc_EncryptedInfoParse(EncryptedInfo* info, #endif /* WOLFSSL_PEM_TO_DER */ #ifdef WOLFSSL_DER_TO_PEM -static int wc_EncryptedInfoAppend(char* dest, char* cipherInfo) +static int wc_EncryptedInfoAppend(char* dest, int destSz, char* cipherInfo) { if (cipherInfo != NULL) { - size_t cipherInfoStrLen = XSTRLEN(cipherInfo); + int cipherInfoStrLen = (int)XSTRLEN((char*)cipherInfo); + if (cipherInfoStrLen > HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3)) cipherInfoStrLen = HEADER_ENCRYPTED_KEY_SIZE - (9+14+10+3); - XSTRNCAT(dest, kProcTypeHeader, 9); - XSTRNCAT(dest, ": 4,ENCRYPTED\n", 14); - XSTRNCAT(dest, kDecInfoHeader, 8); - XSTRNCAT(dest, ": ", 2); - XSTRNCAT(dest, cipherInfo, cipherInfoStrLen); - XSTRNCAT(dest, "\n\n", 3); + if (destSz - (int)XSTRLEN(dest) >= cipherInfoStrLen + (9+14+8+2+2+1)) { + /* strncat's src length needs to include the NULL */ + XSTRNCAT(dest, kProcTypeHeader, 10); + XSTRNCAT(dest, ": 4,ENCRYPTED\n", 15); + XSTRNCAT(dest, kDecInfoHeader, 9); + XSTRNCAT(dest, ": ", 3); + XSTRNCAT(dest, cipherInfo, destSz - (int)XSTRLEN(dest) - 1); + XSTRNCAT(dest, "\n\n", 4); + } } return 0; } @@ -7794,20 +7797,18 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, } #endif - /* null term and leave room for newline */ - header[--headerLen] = '\0'; header[--headerLen] = '\0'; - footer[--footerLen] = '\0'; footer[--footerLen] = '\0'; - /* build header and footer based on type */ - XSTRNCPY(header, headerStr, headerLen); - XSTRNCPY(footer, footerStr, footerLen); + XSTRNCPY(header, headerStr, headerLen - 1); + header[headerLen - 1] = 0; + XSTRNCPY(footer, footerStr, footerLen - 1); + footer[footerLen - 1] = 0; /* add new line to end */ XSTRNCAT(header, "\n", 2); XSTRNCAT(footer, "\n", 2); #ifdef WOLFSSL_ENCRYPTED_KEYS - err = wc_EncryptedInfoAppend(header, (char*)cipher_info); + err = wc_EncryptedInfoAppend(header, headerLen, (char*)cipher_info); if (err != 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -9667,8 +9668,7 @@ static int EncodePolicyOID(byte *out, word32 *outSz, const char *in, void* heap) if (str == NULL) return MEMORY_E; - XSTRNCPY(str, in, len); - str[len] = '\0'; + XSTRNCPY(str, in, len+1); nb_val = 0; @@ -11439,8 +11439,7 @@ int wc_SetKeyUsage(Cert *cert, const char *value) if (str == NULL) return MEMORY_E; - XSTRNCPY(str, value, len); - str[len] = '\0'; + XSTRNCPY(str, value, len+1); /* parse value, and set corresponding Key Usage value */ if ((token = XSTRTOK(str, ",", &ptr)) == NULL) { @@ -11499,8 +11498,7 @@ int wc_SetExtKeyUsage(Cert *cert, const char *value) if (str == NULL) return MEMORY_E; - XSTRNCPY(str, value, len); - str[len] = '\0'; + XSTRNCPY(str, value, len+1); /* parse value, and set corresponding Key Usage value */ if ((token = XSTRTOK(str, ",", &ptr)) == NULL) { diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index a9290dcd7..b1e81f846 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -247,6 +247,8 @@ int wolfCrypt_Cleanup(void) int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name) { int ret = -1; /* default to no files found */ + int pathLen = 0; + int dnameLen = 0; if (name) *name = NULL; @@ -256,10 +258,14 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name) } XMEMSET(ctx->name, 0, MAX_FILENAME_SZ); + pathLen = (int)XSTRLEN(path); #ifdef USE_WINDOWS_API - XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ - 4); - XSTRNCAT(ctx->name, "\\*", 3); + if (pathLen > MAX_FILENAME_SZ - 3) + return BAD_PATH_ERROR; + + XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ - 3); + XSTRNCPY(ctx->name + pathLen, "\\*", MAX_FILENAME_SZ - pathLen); ctx->hFind = FindFirstFileA(ctx->name, &ctx->FindFileData); if (ctx->hFind == INVALID_HANDLE_VALUE) { @@ -269,9 +275,16 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name) do { if (ctx->FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) { - XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 3); - XSTRNCAT(ctx->name, "\\", 2); - XSTRNCAT(ctx->name, ctx->FindFileData.cFileName, MAX_FILENAME_SZ/2); + dnameLen = (int)XSTRLEN(ctx->FindFileData.cFileName); + + if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) { + return BAD_PATH_ERROR; + } + XSTRNCPY(ctx->name, path, pathLen + 1); + ctx->name[pathLen] = '\\'; + XSTRNCPY(ctx->name + pathLen + 1, + ctx->FindFileData.cFileName, + MAX_FILENAME_SZ - pathLen - 1); if (name) *name = ctx->name; return 0; @@ -285,9 +298,16 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name) } while ((ctx->entry = readdir(ctx->dir)) != NULL) { - XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 2); - XSTRNCAT(ctx->name, "/", 1); - XSTRNCAT(ctx->name, ctx->entry->d_name, MAX_FILENAME_SZ/2); + dnameLen = (int)XSTRLEN(ctx->entry->d_name); + + if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) { + ret = BAD_PATH_ERROR; + break; + } + XSTRNCPY(ctx->name, path, pathLen + 1); + ctx->name[pathLen] = '/'; + XSTRNCPY(ctx->name + pathLen + 1, + ctx->entry->d_name, MAX_FILENAME_SZ - pathLen - 1); if (stat(ctx->name, &ctx->s) != 0) { WOLFSSL_MSG("stat on name failed"); @@ -309,6 +329,8 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name) int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name) { int ret = -1; /* default to no file found */ + int pathLen = 0; + int dnameLen = 0; if (name) *name = NULL; @@ -318,13 +340,21 @@ int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name) } XMEMSET(ctx->name, 0, MAX_FILENAME_SZ); + pathLen = (int)XSTRLEN(path); #ifdef USE_WINDOWS_API while (FindNextFileA(ctx->hFind, &ctx->FindFileData)) { if (ctx->FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) { - XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 3); - XSTRNCAT(ctx->name, "\\", 2); - XSTRNCAT(ctx->name, ctx->FindFileData.cFileName, MAX_FILENAME_SZ/2); + dnameLen = (int)XSTRLEN(ctx->FindFileData.cFileName); + + if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) { + return BAD_PATH_ERROR; + } + XSTRNCPY(ctx->name, path, pathLen + 1); + ctx->name[pathLen] = '\\'; + XSTRNCPY(ctx->name + pathLen + 1, + ctx->FindFileData.cFileName, + MAX_FILENAME_SZ - pathLen - 1); if (name) *name = ctx->name; return 0; @@ -332,9 +362,16 @@ int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name) } #else while ((ctx->entry = readdir(ctx->dir)) != NULL) { - XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 2); - XSTRNCAT(ctx->name, "/", 1); - XSTRNCAT(ctx->name, ctx->entry->d_name, MAX_FILENAME_SZ/2); + dnameLen = (int)XSTRLEN(ctx->entry->d_name); + + if (pathLen + dnameLen + 2 > MAX_FILENAME_SZ) { + ret = BAD_PATH_ERROR; + break; + } + XSTRNCPY(ctx->name, path, pathLen + 1); + ctx->name[pathLen] = '/'; + XSTRNCPY(ctx->name + pathLen + 1, + ctx->entry->d_name, MAX_FILENAME_SZ - pathLen - 1); if (stat(ctx->name, &ctx->s) != 0) { WOLFSSL_MSG("stat on name failed");