Skip to content

Commit f218c5c

Browse files
authored
Merge pull request #840 from JacobBarthelmeh/rekey
improvements to keying and track side
2 parents 50aa10d + 024b141 commit f218c5c

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

src/internal.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,7 +1096,7 @@ WOLFSSH* SshInit(WOLFSSH* ssh, WOLFSSH_CTX* ctx)
10961096
ssh->fs = NULL;
10971097
ssh->acceptState = ACCEPT_BEGIN;
10981098
ssh->clientState = CLIENT_BEGIN;
1099-
ssh->isKeying = 1;
1099+
ssh->isKeying = 0; /* initial state of not keying yet */
11001100
ssh->authId = ID_USERAUTH_PUBLICKEY;
11011101
ssh->supportedAuth[0] = ID_USERAUTH_PUBLICKEY;
11021102
ssh->supportedAuth[1] = ID_USERAUTH_PASSWORD;
@@ -4058,6 +4058,15 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
40584058
ret = WS_BAD_ARGUMENT;
40594059
}
40604060

4061+
if (ret == WS_SUCCESS) {
4062+
/* Check if already in process of keying and error out if so. */
4063+
if (ssh->isKeying & WOLFSSH_PEER_IS_KEYING) {
4064+
WLOG(WS_LOG_ERROR,
4065+
"Already in keying process and got KEX init");
4066+
ret = WS_INVALID_STATE_E;
4067+
}
4068+
}
4069+
40614070
/*
40624071
* I don't need to save what the client sends here. I should decode
40634072
* each list into a local array of IDs, and pick the one the peer is
@@ -4067,6 +4076,8 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
40674076
*/
40684077

40694078
if (ret == WS_SUCCESS) {
4079+
/* Set peer is keying flag after receiving SSH_MSG_KEX_INIT */
4080+
ssh->isKeying |= WOLFSSH_PEER_IS_KEYING;
40704081
if (ssh->handshake == NULL) {
40714082
ssh->handshake = HandshakeInfoNew(ssh->ctx->heap);
40724083
if (ssh->handshake == NULL) {
@@ -4327,7 +4338,8 @@ static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
43274338
byte scratchLen[LENGTH_SZ];
43284339
word32 strSz = 0;
43294340

4330-
if (!ssh->isKeying) {
4341+
/* respond with KEX Init message if not having initiated the keying */
4342+
if ((ssh->isKeying & WOLFSSH_SELF_IS_KEYING) == 0) {
43314343
WLOG(WS_LOG_DEBUG, "Keying initiated");
43324344
ret = SendKexInit(ssh);
43334345
}
@@ -5881,6 +5893,13 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
58815893
if (ssh == NULL || ssh->handshake == NULL)
58825894
ret = WS_BAD_ARGUMENT;
58835895

5896+
if (ret == WS_SUCCESS) {
5897+
if (ssh->isKeying & WOLFSSH_SELF_IS_KEYING) {
5898+
WLOG(WS_LOG_ERROR, "Keying failed");
5899+
ret = WS_INVALID_STATE_E;
5900+
}
5901+
}
5902+
58845903
if (ret == WS_SUCCESS) {
58855904
ssh->peerEncryptId = ssh->handshake->encryptId;
58865905
ssh->peerMacId = ssh->handshake->macId;
@@ -5941,7 +5960,9 @@ static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
59415960
if (ret == WS_SUCCESS) {
59425961
ssh->rxCount = 0;
59435962
ssh->highwaterFlag = 0;
5944-
ssh->isKeying = 0;
5963+
5964+
/* Clear peer is keying flag */
5965+
ssh->isKeying &= ~WOLFSSH_PEER_IS_KEYING;
59455966
HandshakeInfoFree(ssh->handshake, ssh->ctx->heap);
59465967
ssh->handshake = NULL;
59475968
WLOG(WS_LOG_DEBUG, "Keying completed");
@@ -9405,7 +9426,7 @@ static int DoPacket(WOLFSSH* ssh, byte* bufferConsumed)
94059426
case MSGID_KEXINIT:
94069427
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXINIT");
94079428
ret = DoKexInit(ssh, buf + idx, payloadSz, &payloadIdx);
9408-
if (ssh->isKeying == 1 &&
9429+
if (ssh->isKeying &&
94099430
ssh->connectState == CONNECT_SERVER_CHANNEL_REQUEST_DONE) {
94109431
if (ssh->handshake->kexId == ID_DH_GEX_SHA256) {
94119432
#if !defined(WOLFSSH_NO_DH) && !defined(WOLFSSH_NO_DH_GEX_SHA256)
@@ -10501,7 +10522,8 @@ int SendKexInit(WOLFSSH* ssh)
1050110522
}
1050210523

1050310524
if (ret == WS_SUCCESS) {
10504-
ssh->isKeying = 1;
10525+
/* Set self is keying flag since we started sending the KEX init msg */
10526+
ssh->isKeying |= WOLFSSH_SELF_IS_KEYING;
1050510527
if (ssh->handshake == NULL) {
1050610528
ssh->handshake = HandshakeInfoNew(ssh->ctx->heap);
1050710529
if (ssh->handshake == NULL) {
@@ -12534,9 +12556,13 @@ int SendNewKeys(WOLFSSH* ssh)
1253412556
ssh->txCount = 0;
1253512557
}
1253612558

12537-
if (ret == WS_SUCCESS)
12559+
if (ret == WS_SUCCESS) {
1253812560
ret = wolfSSH_SendPacket(ssh);
1253912561

12562+
/* Clear self is keying flag */
12563+
ssh->isKeying &= ~WOLFSSH_SELF_IS_KEYING;
12564+
}
12565+
1254012566
WLOG(WS_LOG_DEBUG, "Leaving SendNewKeys(), ret = %d", ret);
1254112567
return ret;
1254212568
}

wolfssh/internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,11 @@ enum NameIdType {
473473
#define WOLFSSH_KEY_QUANTITY_REQ 1
474474
#endif
475475

476+
/* Keep track of keying state for both sides of the connection.
477+
* WOLFSSH_SELF_IS_KEYING gets set on sending KEX init and
478+
* WOLFSSH_PEER_IS_KEYING gets set on receiving KEX init */
479+
#define WOLFSSH_PEER_IS_KEYING 0x01
480+
#define WOLFSSH_SELF_IS_KEYING 0x02
476481

477482
WOLFSSH_LOCAL byte NameToId(const char* name, word32 nameSz);
478483
WOLFSSH_LOCAL const char* IdToName(byte id);

0 commit comments

Comments
 (0)