@@ -1337,6 +1337,7 @@ WOLFSSH_CTX* CtxInit(WOLFSSH_CTX* ctx, byte side, void* heap)
13371337 ctx->maxPacketSz = DEFAULT_MAX_PACKET_SZ;
13381338 ctx->maxAuthAttempts = DEFAULT_MAX_AUTH_ATTEMPTS;
13391339 ctx->sshProtoIdStr = sshProtoIdStr;
1340+ ctx->sshProtoIdStrSz = (word32)(sizeof(sshProtoIdStr) - 1);
13401341 ctx->algoListKex = cannedKexAlgoNames;
13411342 if (side == WOLFSSH_ENDPOINT_CLIENT) {
13421343 ctx->algoListKey = cannedKeyAlgoNamesHostKey;
@@ -6533,9 +6534,8 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
65336534 }
65346535
65356536 if (ret == WS_SUCCESS) {
6536- byte SSH_PROTO_EOL_SZ = 2;
6537-
6538- strSz = (word32)WSTRLEN(ssh->ctx->sshProtoIdStr) - SSH_PROTO_EOL_SZ;
6537+ /* The ID is hashed without its terminator. */
6538+ strSz = ssh->ctx->sshProtoIdStrSz - SSH_PROTO_EOL_SZ;
65396539 c32toa(strSz, scratchLen);
65406540 ret = HashUpdate(hash, hashId, scratchLen, LENGTH_SZ);
65416541 }
@@ -14185,21 +14185,38 @@ int DoProtoId(WOLFSSH* ssh)
1418514185/* Validates a locally configured proto ID string */
1418614186int ValidateProtoId(const char* protoIdStr, word32 len)
1418714187{
14188- /* Length is checked first: the prefix, terminator, and body checks below
14189- * index and subtract from len. The minimum is the "SSH-2.0-" prefix plus
14190- * one body byte plus CRLF. */
14191- if (protoIdStr == NULL || len < SSH_PROTO_SZ + 3 ||
14192- protoIdStr[len-1] != '\n' || protoIdStr[len-2] != '\r' ||
14193- len > WOLFSSH_PROTOID_LIMIT ||
14194- WSTRNCMP(protoIdStr, sshProtoIdPrefix, SSH_PROTO_SZ) != 0 ||
14195- WSTRNSTR(protoIdStr, "\n", len - 2) != NULL ||
14196- WSTRNSTR(protoIdStr, "\r", len - 2) != NULL) {
14188+ word32 i;
14189+
14190+ if (protoIdStr == NULL ||
14191+ len < SSH_PROTO_SZ + 1 + SSH_PROTO_EOL_SZ ||
14192+ len > WOLFSSH_PROTOID_LIMIT) {
14193+ WLOG(WS_LOG_ERROR, "Proto Id was invalid: it must be between %d and "
14194+ "%d bytes, counting the prefix and the terminator",
14195+ SSH_PROTO_SZ + 1 + SSH_PROTO_EOL_SZ, WOLFSSH_PROTOID_LIMIT);
14196+ return WS_BAD_ARGUMENT;
14197+ }
14198+
14199+ if (WSTRNCMP(protoIdStr, sshProtoIdPrefix, SSH_PROTO_SZ) != 0) {
1419714200 WLOG(WS_LOG_ERROR, "Proto Id was invalid: it must start with "
14198- "\"SSH-2.0-\", end in \\r\\n, be no longer than %d bytes, "
14199- "and must not contain \\r or \\n in the body of the line",
14200- WOLFSSH_PROTOID_LIMIT);
14201+ "\"SSH-2.0-\"");
1420114202 return WS_BAD_ARGUMENT;
1420214203 }
14204+
14205+ if (protoIdStr[len - 1] != '\n' || protoIdStr[len - 2] != '\r') {
14206+ WLOG(WS_LOG_ERROR, "Proto Id was invalid: it must end in \\r\\n");
14207+ return WS_BAD_ARGUMENT;
14208+ }
14209+
14210+ for (i = 0; i < len - SSH_PROTO_EOL_SZ; i++) {
14211+ byte c = (byte)protoIdStr[i];
14212+
14213+ if (c < 0x20 || c > 0x7e) {
14214+ WLOG(WS_LOG_ERROR, "Proto Id was invalid: byte %u is "
14215+ "not printable US-ASCII", i);
14216+ return WS_BAD_ARGUMENT;
14217+ }
14218+ }
14219+
1420314220 return WS_SUCCESS;
1420414221}
1420514222
@@ -14214,7 +14231,7 @@ int SendProtoId(WOLFSSH* ssh)
1421414231
1421514232 if (ret == WS_SUCCESS) {
1421614233 WLOG(WS_LOG_DEBUG, "%s", ssh->ctx->sshProtoIdStr);
14217- sshProtoIdStrSz = (word32)WSTRLEN( ssh->ctx->sshProtoIdStr) ;
14234+ sshProtoIdStrSz = ssh->ctx->sshProtoIdStrSz ;
1421814235 ret = GrowBuffer(&ssh->outputBuffer, sshProtoIdStrSz);
1421914236 }
1422014237
0 commit comments