diff --git a/src/ssh.c b/src/ssh.c index 09bf297fe..4d281f575 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -50,6 +50,7 @@ #include #endif +#include #include #include #include @@ -2154,7 +2155,8 @@ int wolfSSH_SetUsernameRaw(WOLFSSH* ssh, if (ssh == NULL) ret = WS_BAD_ARGUMENT; - if (username == NULL || usernameSz == 0) + /* usernameSz + 1 below must not wrap. */ + if (username == NULL || usernameSz == 0 || usernameSz == UINT32_MAX) ret = WS_BAD_ARGUMENT; if (ret == WS_SUCCESS) { @@ -2251,6 +2253,10 @@ static int DoSshPubKey(const byte* in, word32 inSz, byte** out, allocate a copy to tokenize, add a null terminator. */ + /* inSz + 1 must not wrap. */ + if (inSz == UINT32_MAX) + return WS_BAD_ARGUMENT; + c = (char*)WMALLOC(inSz + 1, heap, DYNTYPE_STRING); if (c != NULL) { WMEMCPY(c, in, inSz); diff --git a/tests/api.c b/tests/api.c index 8a7fe35e0..cb195cbd1 100644 --- a/tests/api.c +++ b/tests/api.c @@ -32,6 +32,7 @@ #include #include +#include #if ((defined(WOLFSSH_SFTP) && !defined(NO_WOLFSSH_CLIENT)) || \ (defined(WOLFSSH_SCP) && defined(WOLFSSH_HAVE_SYMLINK) && \ !defined(WOLFSSH_SCP_USER_CALLBACKS))) && \ @@ -282,6 +283,9 @@ static void test_wolfSSH_SetUsername(void) (const byte*)empty, 0)); AssertIntNE(WS_SUCCESS, wolfSSH_SetUsernameRaw(ssh, (const byte*)username, 0)); + /* usernameSz + 1 would wrap to a zero-byte allocation. */ + AssertIntEQ(WS_BAD_ARGUMENT, wolfSSH_SetUsernameRaw(ssh, + (const byte*)username, UINT32_MAX)); wolfSSH_free(ssh); AssertNotNull(ssh = wolfSSH_new(ctx)); AssertIntEQ(WS_SUCCESS, wolfSSH_SetUsername(ssh, username)); @@ -2887,6 +2891,25 @@ static void test_wolfSSH_ReadKey_sshNoComment(void) } +static void test_wolfSSH_ReadKey_sshMaxSize(void) +{ + /* An SSH format key of size UINT32_MAX must be refused before + * DoSshPubKey() allocates inSz + 1, which wraps to zero. The buffer is + * never read past its end, the size is refused first. */ + static const char in[] = "ssh-ed25519 AAAA\n"; + byte* key = NULL; + word32 keySz = 0; + const byte* keyType = NULL; + word32 keyTypeSz = 0; + int ret; + + ret = wolfSSH_ReadKey_buffer((const byte*)in, UINT32_MAX, + WOLFSSH_FORMAT_SSH, &key, &keySz, &keyType, &keyTypeSz, NULL); + AssertIntEQ(ret, WS_BAD_ARGUMENT); + AssertNull(key); +} + + #ifdef WOLFSSH_SCP static int my_ScpRecv(WOLFSSH* ssh, int state, const char* basePath, @@ -9355,6 +9378,7 @@ int wolfSSH_ApiTest(int argc, char** argv) test_wolfSSH_ReadKey_shortBuffer(); test_wolfSSH_ReadKey_noTrailingNewline(); test_wolfSSH_ReadKey_sshNoComment(); + test_wolfSSH_ReadKey_sshMaxSize(); test_wolfSSH_QueryAlgoList(); test_wolfSSH_SetMaxAuthAttempts(); test_wolfSSH_StrictKex();