more return code checking

pull/13/head
John Safranek 2016-07-21 20:07:29 -07:00
parent f865ad2487
commit 2e1744265b
1 changed files with 202 additions and 128 deletions

View File

@ -411,16 +411,16 @@ int GrowBuffer(Buffer* buf, uint32_t sz, uint32_t usedSz)
void ShrinkBuffer(Buffer* buf, int forcedFree) void ShrinkBuffer(Buffer* buf, int forcedFree)
{ {
WLOG(WS_LOG_DEBUG, "Entering %s", __func__); WLOG(WS_LOG_DEBUG, "Entering ShrinkBuffer()");
if (buf != NULL) { if (buf != NULL) {
uint32_t usedSz = buf->length - buf->idx; uint32_t usedSz = buf->length - buf->idx;
WLOG(WS_LOG_DEBUG, "SB: usedSz = %u, forcedFree = %u", usedSz, forcedFree); WLOG(WS_LOG_DEBUG, "SB: usedSz = %u, forcedFree = %u",
if (!forcedFree && usedSz > STATIC_BUFFER_LEN) { usedSz, forcedFree);
WLOG(WS_LOG_DEBUG, "SB: shifting down");
if (!forcedFree && usedSz > STATIC_BUFFER_LEN)
return; return;
}
if (!forcedFree && usedSz) { if (!forcedFree && usedSz) {
WLOG(WS_LOG_DEBUG, "SB: shifting down"); WLOG(WS_LOG_DEBUG, "SB: shifting down");
@ -437,7 +437,8 @@ void ShrinkBuffer(Buffer* buf, int forcedFree)
buf->length = forcedFree ? 0 : usedSz; buf->length = forcedFree ? 0 : usedSz;
buf->idx = 0; buf->idx = 0;
} }
WLOG(WS_LOG_DEBUG, "Leaving %s", __func__);
WLOG(WS_LOG_DEBUG, "Leaving ShrinkBuffer()");
} }
@ -667,6 +668,7 @@ static int GetBoolean(uint8_t* v, uint8_t* buf, uint32_t len, uint32_t* idx)
*idx += BOOLEAN_SZ; *idx += BOOLEAN_SZ;
result = WS_SUCCESS; result = WS_SUCCESS;
} }
return result; return result;
} }
@ -711,26 +713,37 @@ static int DoNameList(uint8_t* idList, uint32_t* idListSz,
{ {
uint8_t idListIdx; uint8_t idListIdx;
uint32_t nameListSz, nameListIdx; uint32_t nameListSz, nameListIdx;
uint32_t begin = *idx; uint32_t begin;
uint8_t* name; uint8_t* name;
uint32_t nameSz; uint32_t nameSz;
int ret = WS_SUCCESS;
WLOG(WS_LOG_DEBUG, "Entering DoNameList()");
if (idList == NULL || idListSz == NULL ||
buf == NULL || len == 0 || idx == NULL) {
ret = WS_BAD_ARGUMENT;
}
/* /*
* This iterates across a name list and finds names that end in either the * This iterates across a name list and finds names that end in either the
* comma delimeter or with the end of the list. * comma delimeter or with the end of the list.
*/ */
if (ret == WS_SUCCESS) {
begin = *idx;
if (begin >= len || begin + 4 >= len) if (begin >= len || begin + 4 >= len)
return WS_FATAL_ERROR; ret = WS_BUFFER_E;
}
ato32(buf + begin, &nameListSz); if (ret == WS_SUCCESS)
begin += 4; ret = GetUint32(&nameListSz, buf, len, &begin);
if (begin + nameListSz > len)
return WS_FATAL_ERROR;
/* The strings we want are now in the bounds of the message, and the /* The strings we want are now in the bounds of the message, and the
* length of the list. Find the commas, or end of list, and then decode * length of the list. Find the commas, or end of list, and then decode
* the values. */ * the values. */
if (ret == WS_SUCCESS) {
name = buf + begin; name = buf + begin;
nameSz = 0; nameSz = 0;
nameListIdx = 0; nameListIdx = 0;
@ -749,7 +762,8 @@ static int DoNameList(uint8_t* idList, uint32_t* idListSz,
{ {
const char* displayName = IdToName(id); const char* displayName = IdToName(id);
if (displayName) { if (displayName) {
/*WLOG(WS_LOG_DEBUG, "DNL: name ID = %s", displayName);*/ /*WLOG(WS_LOG_DEBUG,
"DNL: name ID = %s", displayName);*/
} }
} }
if (id != ID_UNKNOWN) if (id != ID_UNKNOWN)
@ -765,8 +779,10 @@ static int DoNameList(uint8_t* idList, uint32_t* idListSz,
begin += nameListSz; begin += nameListSz;
*idListSz = idListIdx; *idListSz = idListIdx;
*idx = begin; *idx = begin;
}
return WS_SUCCESS; WLOG(WS_LOG_DEBUG, "Leaving DoNameList(), ret = %d", ret);
return ret;
} }
@ -855,7 +871,9 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
uint8_t list[3]; uint8_t list[3];
uint32_t listSz; uint32_t listSz;
uint32_t skipSz; uint32_t skipSz;
uint32_t begin = *idx; uint32_t begin;
WLOG(WS_LOG_DEBUG, "Entering DoKexInit()");
if (ssh == NULL || buf == NULL || len == 0 || idx == NULL) if (ssh == NULL || buf == NULL || len == 0 || idx == NULL)
ret = WS_BAD_ARGUMENT; ret = WS_BAD_ARGUMENT;
@ -867,126 +885,182 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
* is save the actual values. * is save the actual values.
*/ */
if (ret == WS_SUCCESS) {
begin = *idx;
/* Check that the cookie exists inside the message */ /* Check that the cookie exists inside the message */
if (begin + COOKIE_SZ > len) { if (begin + COOKIE_SZ > len) {
/* error, out of bounds */ /* error, out of bounds */
return WS_FATAL_ERROR; ret = WS_PARSE_E;
} }
else {
/* Move past the cookie. */ /* Move past the cookie. */
begin += COOKIE_SZ; begin += COOKIE_SZ;
}
}
/* KEX Algorithms */ /* KEX Algorithms */
if (ret == WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "DKI: KEX Algorithms"); WLOG(WS_LOG_DEBUG, "DKI: KEX Algorithms");
listSz = 2; listSz = 2;
DoNameList(list, &listSz, buf, len, &begin); ret = DoNameList(list, &listSz, buf, len, &begin);
if (ret == WS_SUCCESS) {
algoId = MatchIdLists(list, listSz, cannedKexAlgo, cannedKexAlgoSz); algoId = MatchIdLists(list, listSz, cannedKexAlgo, cannedKexAlgoSz);
if (algoId == ID_UNKNOWN) { if (algoId == ID_UNKNOWN) {
WLOG(WS_LOG_DEBUG, "Unable to negotiate KEX Algo"); WLOG(WS_LOG_DEBUG, "Unable to negotiate KEX Algo");
return WS_INVALID_ALGO_ID; ret = WS_INVALID_ALGO_ID;
}
else
ssh->handshake->kexId = algoId;
}
} }
ssh->handshake->kexId = algoId;
/* Server Host Key Algorithms */ /* Server Host Key Algorithms */
if (ret == WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "DKI: Server Host Key Algorithms"); WLOG(WS_LOG_DEBUG, "DKI: Server Host Key Algorithms");
listSz = 1; listSz = 1;
DoNameList(list, &listSz, buf, len, &begin); ret = DoNameList(list, &listSz, buf, len, &begin);
if (ret == WS_SUCCESS) {
algoId = MatchIdLists(list, listSz, cannedKeyAlgo, cannedKeyAlgoSz); algoId = MatchIdLists(list, listSz, cannedKeyAlgo, cannedKeyAlgoSz);
if (algoId == ID_UNKNOWN) { if (algoId == ID_UNKNOWN) {
WLOG(WS_LOG_DEBUG, "Unable to negotiate Server Host Key Algo"); WLOG(WS_LOG_DEBUG, "Unable to negotiate Server Host Key Algo");
return WS_INVALID_ALGO_ID; return WS_INVALID_ALGO_ID;
} }
else
ssh->handshake->pubKeyId = algoId; ssh->handshake->pubKeyId = algoId;
}
}
/* Enc Algorithms - Client to Server */ /* Enc Algorithms - Client to Server */
if (ret == WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "DKI: Enc Algorithms - Client to Server"); WLOG(WS_LOG_DEBUG, "DKI: Enc Algorithms - Client to Server");
listSz = 3; listSz = 3;
DoNameList(list, &listSz, buf, len, &begin); ret = DoNameList(list, &listSz, buf, len, &begin);
if (ret == WS_SUCCESS) {
algoId = MatchIdLists(list, listSz, cannedEncAlgo, cannedEncAlgoSz); algoId = MatchIdLists(list, listSz, cannedEncAlgo, cannedEncAlgoSz);
if (algoId == ID_UNKNOWN) { if (algoId == ID_UNKNOWN) {
WLOG(WS_LOG_DEBUG, "Unable to negotiate Encryption Algo C2S"); WLOG(WS_LOG_DEBUG, "Unable to negotiate Encryption Algo C2S");
return WS_INVALID_ALGO_ID; ret = WS_INVALID_ALGO_ID;
}
}
} }
/* Enc Algorithms - Server to Client */ /* Enc Algorithms - Server to Client */
if (ret == WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "DKI: Enc Algorithms - Server to Client"); WLOG(WS_LOG_DEBUG, "DKI: Enc Algorithms - Server to Client");
listSz = 3; listSz = 3;
DoNameList(list, &listSz, buf, len, &begin); ret = DoNameList(list, &listSz, buf, len, &begin);
if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) { if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) {
WLOG(WS_LOG_DEBUG, "Unable to negotiate Encryption Algo S2C"); WLOG(WS_LOG_DEBUG, "Unable to negotiate Encryption Algo S2C");
return WS_INVALID_ALGO_ID; ret = WS_INVALID_ALGO_ID;
} }
else {
ssh->handshake->encryptId = algoId; ssh->handshake->encryptId = algoId;
ssh->handshake->blockSz = ssh->ivClientSz = ssh->ivServerSz ssh->handshake->blockSz = ssh->ivClientSz = ssh->ivServerSz
= BlockSzForId(algoId); = BlockSzForId(algoId);
ssh->encKeyClientSz = ssh->encKeyServerSz = KeySzForId(algoId); ssh->encKeyClientSz = ssh->encKeyServerSz = KeySzForId(algoId);
}
}
/* MAC Algorithms - Client to Server */ /* MAC Algorithms - Client to Server */
if (ret == WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "DKI: MAC Algorithms - Client to Server"); WLOG(WS_LOG_DEBUG, "DKI: MAC Algorithms - Client to Server");
listSz = 2; listSz = 2;
DoNameList(list, &listSz, buf, len, &begin); ret = DoNameList(list, &listSz, buf, len, &begin);
if (ret == WS_SUCCESS) {
algoId = MatchIdLists(list, listSz, cannedMacAlgo, cannedMacAlgoSz); algoId = MatchIdLists(list, listSz, cannedMacAlgo, cannedMacAlgoSz);
if (algoId == ID_UNKNOWN) { if (algoId == ID_UNKNOWN) {
WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo C2S"); WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo C2S");
return WS_INVALID_ALGO_ID; ret = WS_INVALID_ALGO_ID;
}
}
} }
/* MAC Algorithms - Server to Client */ /* MAC Algorithms - Server to Client */
if (ret == WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "DKI: MAC Algorithms - Server to Client"); WLOG(WS_LOG_DEBUG, "DKI: MAC Algorithms - Server to Client");
listSz = 2; listSz = 2;
DoNameList(list, &listSz, buf, len, &begin); ret = DoNameList(list, &listSz, buf, len, &begin);
if (ret == WS_SUCCESS) {
if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) { if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) {
WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo S2C"); WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo S2C");
return WS_INVALID_ALGO_ID; ret = WS_INVALID_ALGO_ID;
} }
else {
ssh->handshake->macId = algoId; ssh->handshake->macId = algoId;
ssh->handshake->macSz = MacSzForId(algoId); ssh->handshake->macSz = MacSzForId(algoId);
ssh->macKeyClientSz = ssh->macKeyServerSz = KeySzForId(algoId); ssh->macKeyClientSz = ssh->macKeyServerSz = KeySzForId(algoId);
}
}
}
/* Compression Algorithms - Client to Server */
if (ret == WS_SUCCESS) {
/* The compression algorithm lists should have none as a value. */ /* The compression algorithm lists should have none as a value. */
algoId = ID_NONE; algoId = ID_NONE;
/* Compression Algorithms - Client to Server */
WLOG(WS_LOG_DEBUG, "DKI: Compression Algorithms - Client to Server"); WLOG(WS_LOG_DEBUG, "DKI: Compression Algorithms - Client to Server");
listSz = 1; listSz = 1;
DoNameList(list, &listSz, buf, len, &begin); ret = DoNameList(list, &listSz, buf, len, &begin);
if (ret == WS_SUCCESS) {
if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) { if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) {
WLOG(WS_LOG_DEBUG, "Unable to negotiate Compression Algo C2S"); WLOG(WS_LOG_DEBUG, "Unable to negotiate Compression Algo C2S");
return WS_INVALID_ALGO_ID; ret = WS_INVALID_ALGO_ID;
}
}
} }
/* Compression Algorithms - Server to Client */ /* Compression Algorithms - Server to Client */
if (ret == WS_SUCCESS) {
WLOG(WS_LOG_DEBUG, "DKI: Compression Algorithms - Server to Client"); WLOG(WS_LOG_DEBUG, "DKI: Compression Algorithms - Server to Client");
listSz = 1; listSz = 1;
DoNameList(list, &listSz, buf, len, &begin); ret = DoNameList(list, &listSz, buf, len, &begin);
if (ret == WS_SUCCESS) {
if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) { if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) {
WLOG(WS_LOG_DEBUG, "Unable to negotiate Compression Algo S2C"); WLOG(WS_LOG_DEBUG, "Unable to negotiate Compression Algo S2C");
return WS_INVALID_ALGO_ID; ret = WS_INVALID_ALGO_ID;
}
}
} }
/* Languages - Client to Server, skip */ /* Languages - Client to Server, skip */
ato32(buf + begin, &skipSz); if (ret == WS_SUCCESS) {
begin += 4 + skipSz; WLOG(WS_LOG_DEBUG, "DKI: Languages - Client to Server");
ret = GetUint32(&skipSz, buf, len, &begin);
if (ret == WS_SUCCESS)
begin += skipSz;
}
/* Languages - Server to Client, skip */ /* Languages - Server to Client, skip */
ato32(buf + begin, &skipSz); if (ret == WS_SUCCESS) {
begin += 4 + skipSz; WLOG(WS_LOG_DEBUG, "DKI: Languages - Server to Client");
ret = GetUint32(&skipSz, buf, len, &begin);
if (ret == WS_SUCCESS)
begin += skipSz;
}
/* First KEX Packet Follows */ /* First KEX Packet Follows */
ssh->handshake->kexPacketFollows = buf[begin]; if (ret == WS_SUCCESS) {
begin += 1; WLOG(WS_LOG_DEBUG, "DKI: KEX Packet Follows");
ret = GetBoolean(&ssh->handshake->kexPacketFollows, buf, len, &begin);
}
/* Skip the "for future use" length. */ /* Skip the "for future use" length. */
ato32(buf + begin, &skipSz); if (ret == WS_SUCCESS) {
begin += 4 + skipSz; WLOG(WS_LOG_DEBUG, "DKI: For Future Use");
ret = GetUint32(&skipSz, buf, len, &begin);
if (ret == WS_SUCCESS)
begin += skipSz;
}
if (ret == WS_SUCCESS) {
*idx = begin; *idx = begin;
ssh->clientState = CLIENT_KEXINIT_DONE; ssh->clientState = CLIENT_KEXINIT_DONE;
return WS_SUCCESS; }
WLOG(WS_LOG_DEBUG, "Leaving DoKexInit(), ret = %d", ret);
return ret;
} }
@ -2080,11 +2154,11 @@ static int DoPacket(WOLFSSH* ssh)
case MSGID_KEXINIT: case MSGID_KEXINIT:
{ {
uint8_t scratchLen[LENGTH_SZ]; uint8_t szFlat[LENGTH_SZ];
WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXINIT"); WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXINIT");
c32toa(payloadSz + sizeof(msg), scratchLen); c32toa(payloadSz + sizeof(msg), szFlat);
wc_ShaUpdate(&ssh->handshake->hash, scratchLen, LENGTH_SZ); wc_ShaUpdate(&ssh->handshake->hash, szFlat, LENGTH_SZ);
wc_ShaUpdate(&ssh->handshake->hash, &msg, sizeof(msg)); wc_ShaUpdate(&ssh->handshake->hash, &msg, sizeof(msg));
wc_ShaUpdate(&ssh->handshake->hash, buf + idx, payloadSz); wc_ShaUpdate(&ssh->handshake->hash, buf + idx, payloadSz);
ret = DoKexInit(ssh, buf + idx, payloadSz, &payloadIdx); ret = DoKexInit(ssh, buf + idx, payloadSz, &payloadIdx);