@@ -612,8 +612,8 @@ INLINE static int IsMessageAllowedKeying(WOLFSSH *ssh, byte msg)
612612 return 0;
613613 }
614614
615- /* case of resending SSH_MSG_KEXINIT */
616- if (msg == MSGID_KEXINIT) {
615+ /* case of peer resending SSH_MSG_KEXINIT */
616+ if ((ssh->isKeying & WOLFSSH_PEER_IS_KEYING) && msg == MSGID_KEXINIT) {
617617 WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by during rekeying", msg);
618618 ssh->error = WS_REKEYING;
619619 return 0;
@@ -632,34 +632,50 @@ INLINE static int IsMessageAllowedKeying(WOLFSSH *ssh, byte msg)
632632#ifndef NO_WOLFSSH_SERVER
633633INLINE static int IsMessageAllowedServer(WOLFSSH *ssh, byte msg)
634634{
635+ /* Only the server should send these messages, never receive. */
636+ if (msg == MSGID_SERVICE_ACCEPT) {
637+ WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by %s %s",
638+ msg, "client", "ever");
639+ return 0;
640+ }
641+
642+ /* Transport Layer Generic messages are always allowed. */
643+ if (MSGIDLIMIT_TRANS_GEN(msg)) {
644+ return 1;
645+ }
646+
635647 /* Has client userauth started? */
648+ /* Allows the server to receive up to KEXDH GEX Request during KEX. */
636649 if (ssh->acceptState < ACCEPT_KEYED) {
637- if (msg > MSGID_KEXDH_LIMIT ) {
650+ if (msg > MSGID_KEXDH_GEX_REQUEST ) {
638651 return 0;
639652 }
640653 }
641654 /* Is server userauth complete? */
642655 if (ssh->acceptState < ACCEPT_SERVER_USERAUTH_SENT) {
656+ /* The server should only receive the user auth request message,
657+ * it should not accept the other user auth messages, it sends
658+ * them. (>50) */
643659 /* Explicitly check for messages not allowed before user
644660 * authentication has comleted. */
645- if (msg >= MSGID_USERAUTH_LIMIT ) {
646- WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by server "
647- " before user authentication is complete", msg );
661+ if (MSGIDLIMIT_POST_USERAUTH( msg) ) {
662+ WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by %s %s",
663+ msg, "server", " before user authentication is complete");
648664 return 0;
649665 }
650666 /* Explicitly check for the user authentication messages that
651667 * only the server sends, it shouldn't receive them. */
652- if ((msg > MSGID_USERAUTH_RESTRICT ) &&
668+ if ((msg > MSGID_USERAUTH_REQUEST ) &&
653669 (msg != MSGID_USERAUTH_INFO_RESPONSE)) {
654- WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by server "
655- " during user authentication", msg );
670+ WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by %s %s",
671+ msg, "server", " during user authentication");
656672 return 0;
657673 }
658674 }
659675 else {
660- if (msg >= MSGID_USERAUTH_RESTRICT && msg < MSGID_USERAUTH_LIMIT ) {
661- WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by server "
662- " after user authentication", msg );
676+ if (msg >= MSGID_USERAUTH_REQUEST && msg < MSGID_GLOBAL_REQUEST ) {
677+ WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by %s %s",
678+ msg, "server", " after user authentication");
663679 return 0;
664680 }
665681 }
@@ -672,37 +688,95 @@ INLINE static int IsMessageAllowedServer(WOLFSSH *ssh, byte msg)
672688#ifndef NO_WOLFSSH_CLIENT
673689INLINE static int IsMessageAllowedClient(WOLFSSH *ssh, byte msg)
674690{
675- /* Has client userauth started? */
676- if (ssh->connectState < CONNECT_CLIENT_KEXDH_INIT_SENT) {
677- if (msg >= MSGID_KEXDH_LIMIT) {
691+ /* Only the client should send these messages, never receive. */
692+ if (msg == MSGID_SERVICE_REQUEST || msg == MSGID_USERAUTH_REQUEST) {
693+ WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by %s %s",
694+ msg, "client", "ever");
695+ return 0;
696+ }
697+
698+ if (msg == MSGID_SERVICE_ACCEPT) {
699+ if (ssh->connectState == CONNECT_CLIENT_USERAUTH_REQUEST_SENT) {
700+ return 1;
701+ }
702+ else {
703+ WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by %s %s",
704+ msg, "client", "after starting user auth");
678705 return 0;
679706 }
680707 }
681- /* Is client userauth complete? */
682- if (ssh->connectState < CONNECT_SERVER_USERAUTH_ACCEPT_DONE) {
683- /* Explicitly check for messages not allowed before user
684- * authentication has comleted. */
685- if (msg >= MSGID_USERAUTH_LIMIT) {
686- WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by client "
687- "before user authentication is complete", msg);
708+
709+ /* Transport Layer Generic messages are always allowed. */
710+ if (MSGIDLIMIT_TRANS_GEN(msg)) {
711+ return 1;
712+ }
713+
714+ /* Is KEX complete? */
715+ if (MSGIDLIMIT_TRANS(msg)) {
716+ if (ssh->isKeying & WOLFSSH_PEER_IS_KEYING) {
717+ /* MSGID_KEXINIT not allowed when keying. */
718+ if (msg == MSGID_KEXINIT) {
719+ WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by %s %s",
720+ msg, "client", "when keying");
721+ return 0;
722+ }
723+
724+ /* Error if expecting a specific message and didn't receive. */
725+ if (ssh->handshake && ssh->handshake->expectMsgId != MSGID_NONE) {
726+ if (msg != ssh->handshake->expectMsgId) {
727+ WLOG(WS_LOG_DEBUG,
728+ "Message ID %u not the expected message %u",
729+ msg, ssh->handshake->expectMsgId);
730+ return 0;
731+ }
732+ else {
733+ /* Got the expected message, clear expectation. */
734+ ssh->handshake->expectMsgId = MSGID_NONE;
735+ return 1;
736+ }
737+ }
738+ }
739+ else {
740+ /* MSGID_KEXINIT only allowed when not keying. */
741+ if (msg == MSGID_KEXINIT) {
742+ return 1;
743+ }
744+
745+ /* All other transport KEX and ALGO messages are not allowed
746+ * when not keying. */
747+ WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by %s %s",
748+ msg, "client", "when not keying");
688749 return 0;
689750 }
690- /* Explicitly check for the user authentication message that
691- * only the client sends, it shouldn't receive it. */
692- if (msg == MSGID_USERAUTH_RESTRICT) {
693- WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by client "
694- "during user authentication", msg);
751+ }
752+
753+ /* Is client userauth complete? */
754+ if (ssh->connectState >= CONNECT_KEYED
755+ && ssh->connectState < CONNECT_SERVER_USERAUTH_ACCEPT_DONE) {
756+ /* The endpoints should not allow message IDs greater than or
757+ * equal to msgid 80 before user authentication is complete.
758+ * Per RFC 4252 section 6. */
759+ if (MSGIDLIMIT_POST_USERAUTH(msg)) {
760+ WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by %s %s",
761+ msg, "client", "before user authentication is complete");
695762 return 0;
696763 }
764+ else if (MSGIDLIMIT_AUTH(msg)) {
765+ return 1;
766+ }
697767 }
698768 else {
699- if (msg >= MSGID_USERAUTH_RESTRICT && msg < MSGID_USERAUTH_LIMIT) {
700- WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by client "
701- "after user authentication", msg);
769+ if (MSGIDLIMIT_POST_USERAUTH(msg)) {
770+ return 1;
771+ }
772+ else if (MSGIDLIMIT_AUTH(msg)) {
773+ WLOG(WS_LOG_DEBUG, "Message ID %u not allowed by %s %s",
774+ msg, "client", "after user authentication");
702775 return 0;
703776 }
704777 }
705- return 1;
778+
779+ return 0;
706780}
707781#endif /* NO_WOLFSSH_CLIENT */
708782
@@ -711,7 +785,7 @@ INLINE static int IsMessageAllowedClient(WOLFSSH *ssh, byte msg)
711785 * Returns 1 if allowed 0 if not allowed. */
712786INLINE static int IsMessageAllowed(WOLFSSH *ssh, byte msg, byte state)
713787{
714- if (state == WS_MSG_SEND && !IsMessageAllowedKeying(ssh, msg)) {
788+ if (!IsMessageAllowedKeying(ssh, msg)) {
715789 return 0;
716790 }
717791
@@ -725,6 +799,7 @@ INLINE static int IsMessageAllowed(WOLFSSH *ssh, byte msg, byte state)
725799 return IsMessageAllowedClient(ssh, msg);
726800 }
727801#endif /* NO_WOLFSSH_CLIENT */
802+ (void)state;
728803 return 0;
729804}
730805
@@ -5872,8 +5947,10 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
58725947 ret = GenerateKeys(ssh, hashId, !ssh->handshake->useEccMlKem);
58735948 }
58745949
5875- if (ret == WS_SUCCESS)
5950+ if (ret == WS_SUCCESS) {
58765951 ret = SendNewKeys(ssh);
5952+ ssh->handshake->expectMsgId = MSGID_NEWKEYS;
5953+ }
58775954
58785955 if (sigKeyBlock_ptr)
58795956 WFREE(sigKeyBlock_ptr, ssh->ctx->heap, DYNTYPE_PRIVKEY);
@@ -10648,8 +10725,9 @@ int SendKexInit(WOLFSSH* ssh)
1064810725 ret = BundlePacket(ssh);
1064910726 }
1065010727
10651- if (ret == WS_SUCCESS)
10728+ if (ret == WS_SUCCESS) {
1065210729 ret = wolfSSH_SendPacket(ssh);
10730+ }
1065310731
1065410732 if (ret != WS_WANT_WRITE && ret != WS_SUCCESS)
1065510733 PurgePacket(ssh);
@@ -12612,6 +12690,11 @@ int SendKexDhGexRequest(WOLFSSH* ssh)
1261212690 if (ret == WS_SUCCESS)
1261312691 ret = wolfSSH_SendPacket(ssh);
1261412692
12693+ if (ret == WS_SUCCESS) {
12694+ WLOG_EXPECT_MSGID(MSGID_KEXDH_GEX_GROUP);
12695+ ssh->handshake->expectMsgId = MSGID_KEXDH_GEX_GROUP;
12696+ }
12697+
1261512698 WLOG(WS_LOG_DEBUG, "Leaving SendKexDhGexRequest(), ret = %d", ret);
1261612699 return ret;
1261712700}
@@ -12700,6 +12783,7 @@ int SendKexDhInit(WOLFSSH* ssh)
1270012783#endif
1270112784 int ret = WS_SUCCESS;
1270212785 byte msgId = MSGID_KEXDH_INIT;
12786+ byte expectMsgId = MSGID_KEXDH_REPLY;
1270312787 byte e[MAX_KEX_KEY_SZ+1]; /* plus 1 in case of padding. */
1270412788 word32 eSz = (word32)sizeof(e);
1270512789 byte ePad = 0;
@@ -12751,6 +12835,7 @@ int SendKexDhInit(WOLFSSH* ssh)
1275112835 generator = ssh->handshake->generator;
1275212836 generatorSz = ssh->handshake->generatorSz;
1275312837 msgId = MSGID_KEXDH_GEX_INIT;
12838+ expectMsgId = MSGID_KEXDH_GEX_REPLY;
1275412839 break;
1275512840#endif
1275612841#ifndef WOLFSSH_NO_ECDH_SHA2_NISTP256
@@ -12962,6 +13047,11 @@ int SendKexDhInit(WOLFSSH* ssh)
1296213047 if (ret == WS_SUCCESS)
1296313048 ret = wolfSSH_SendPacket(ssh);
1296413049
13050+ if (ret == WS_SUCCESS) {
13051+ WLOG_EXPECT_MSGID(expectMsgId);
13052+ ssh->handshake->expectMsgId = expectMsgId;
13053+ }
13054+
1296513055 WLOG(WS_LOG_DEBUG, "Leaving SendKexDhInit(), ret = %d", ret);
1296613056 return ret;
1296713057}
0 commit comments