mirror of https://github.com/wolfSSL/wolfssh.git
1. Starting to add in the Decryption and MAC Verification.
2. Fixed bug in getting the entire packet from the socket.pull/1/head
parent
1c902a641e
commit
71bcd94c5f
115
src/internal.c
115
src/internal.c
|
@ -34,9 +34,9 @@
|
|||
#include <wolfssh/ssh.h>
|
||||
#include <wolfssh/internal.h>
|
||||
#include <wolfssh/log.h>
|
||||
#include <cyassl/ctaocrypt/aes.h>
|
||||
#include <cyassl/ctaocrypt/asn.h>
|
||||
#include <cyassl/ctaocrypt/rsa.h>
|
||||
#include <cyassl/ctaocrypt/hmac.h>
|
||||
|
||||
|
||||
/* convert opaque to 32 bit integer */
|
||||
|
@ -124,6 +124,9 @@ const char* GetErrorString(int err)
|
|||
case WS_BAD_FILE_E:
|
||||
return "bad file";
|
||||
|
||||
case WS_DECRYPT_E:
|
||||
return "decrypt error";
|
||||
|
||||
default:
|
||||
return "Unknown error code";
|
||||
}
|
||||
|
@ -860,6 +863,21 @@ static int DoNewKeys(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx)
|
|||
ssh->peerEncryptId = ssh->handshake->encryptId;
|
||||
ssh->peerMacId = ssh->handshake->macId;
|
||||
|
||||
switch (ssh->peerEncryptId) {
|
||||
case ID_NONE:
|
||||
WLOG(WS_LOG_DEBUG, "DNK: peer using cipher none");
|
||||
break;
|
||||
|
||||
case ID_AES128_CBC:
|
||||
WLOG(WS_LOG_DEBUG, "DNK: peer using cipher aes128-cbc");
|
||||
AesSetKey(&ssh->decryptCipher.aes, ssh->encKeyClient, ssh->encKeyClientSz, ssh->ivClient, AES_DECRYPTION);
|
||||
break;
|
||||
|
||||
default:
|
||||
WLOG(WS_LOG_DEBUG, "DNK: peer using cipher invalid");
|
||||
break;
|
||||
}
|
||||
|
||||
ssh->clientState = CLIENT_USING_KEYS;
|
||||
|
||||
return WS_SUCCESS;
|
||||
|
@ -1122,6 +1140,8 @@ static int DoPacket(WOLFSSH* ssh)
|
|||
/* Problem: len is equal to the amount of data left in the input buffer.
|
||||
* The beginning part of that data is the packet we want to
|
||||
* decode. The remainder is the pad and the MAC. */
|
||||
/* Skip the packet_length field. */
|
||||
idx += LENGTH_SZ;
|
||||
padSz = buf[idx++];
|
||||
payloadSz = ssh->curSz - PAD_LENGTH_SZ - padSz;
|
||||
|
||||
|
@ -1181,7 +1201,8 @@ static int DoPacket(WOLFSSH* ssh)
|
|||
}
|
||||
|
||||
if (idx + padSz > len) {
|
||||
return -1;
|
||||
WLOG(WS_LOG_DEBUG, "Not enough data in buffer for pad.");
|
||||
return WS_BUFFER_E;
|
||||
}
|
||||
idx += padSz;
|
||||
|
||||
|
@ -1190,12 +1211,46 @@ static int DoPacket(WOLFSSH* ssh)
|
|||
}
|
||||
|
||||
|
||||
static INLINE int Decrypt(WOLFSSH* ssh, uint8_t* plain, const uint8_t* input,
|
||||
uint16_t sz)
|
||||
{
|
||||
int ret = WS_SUCCESS;
|
||||
|
||||
if (ssh == NULL || plain == NULL || input == NULL || sz == 0)
|
||||
return WS_BAD_ARGUMENT;
|
||||
|
||||
switch (ssh->peerEncryptId) {
|
||||
case ID_NONE:
|
||||
WLOG(WS_LOG_DEBUG, "Decrypt none");
|
||||
break;
|
||||
|
||||
case ID_AES128_CBC:
|
||||
WLOG(WS_LOG_DEBUG, "Decrypt aes128-cbc");
|
||||
if (AesCbcDecrypt(&ssh->decryptCipher.aes, plain, input, sz) < 0)
|
||||
ret = WS_DECRYPT_E;
|
||||
|
||||
default:
|
||||
WLOG(WS_LOG_DEBUG, "Decrypt invalid algo ID");
|
||||
ret = WS_INVALID_ALGO_ID;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static INLINE int VerifyMac(WOLFSSH* ssh)
|
||||
{
|
||||
(void)ssh;
|
||||
/* Verify the buffer is big enough for the data plus the mac. */
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int ProcessReply(WOLFSSH* ssh)
|
||||
{
|
||||
int ret = WS_FATAL_ERROR;
|
||||
int readSz;
|
||||
uint32_t readSz;
|
||||
|
||||
(void)readSz;
|
||||
for (;;) {
|
||||
switch (ssh->processReplyState) {
|
||||
case PROCESS_INIT:
|
||||
|
@ -1205,30 +1260,43 @@ int ProcessReply(WOLFSSH* ssh)
|
|||
return ret;
|
||||
}
|
||||
ssh->processReplyState = PROCESS_PACKET_LENGTH;
|
||||
WLOG(WS_LOG_DEBUG, "idx = %u, length = %u", ssh->inputBuffer.idx, ssh->inputBuffer.length);
|
||||
|
||||
/* Decrypt first block if encrypted */
|
||||
/* Decrypt first block if encrypted */
|
||||
ret = Decrypt(ssh,
|
||||
ssh->inputBuffer.buffer + ssh->inputBuffer.idx,
|
||||
ssh->inputBuffer.buffer + ssh->inputBuffer.idx,
|
||||
readSz);
|
||||
|
||||
case PROCESS_PACKET_LENGTH:
|
||||
/* Peek at the packet_length field. */
|
||||
ato32(ssh->inputBuffer.buffer + ssh->inputBuffer.idx, &ssh->curSz);
|
||||
ssh->inputBuffer.idx += LENGTH_SZ;
|
||||
ssh->processReplyState = PROCESS_PACKET_FINISH;
|
||||
|
||||
case PROCESS_PACKET_FINISH:
|
||||
WLOG(WS_LOG_DEBUG, "PR2: size = %d", ssh->curSz);
|
||||
if ((ret = GetInputData(ssh, ssh->curSz)) < 0) {
|
||||
readSz = ssh->curSz + LENGTH_SZ + ssh->macSz;
|
||||
WLOG(WS_LOG_DEBUG, "PR2: size = %d", readSz);
|
||||
if (readSz > 0) {
|
||||
if ((ret = GetInputData(ssh, readSz)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
ret = Decrypt(ssh,
|
||||
ssh->inputBuffer.buffer + ssh->inputBuffer.idx + ssh->blockSz - LENGTH_SZ,
|
||||
ssh->inputBuffer.buffer + ssh->inputBuffer.idx + ssh->blockSz - LENGTH_SZ,
|
||||
ssh->curSz - ssh->blockSz);
|
||||
|
||||
|
||||
ret = VerifyMac(ssh);
|
||||
}
|
||||
|
||||
ssh->processReplyState = PROCESS_PACKET;
|
||||
|
||||
/* Decrypt rest of packet here */
|
||||
|
||||
/* Check MAC here. */
|
||||
|
||||
case PROCESS_PACKET:
|
||||
if ( (ret = DoPacket(ssh)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
ssh->inputBuffer.idx += ssh->macSz;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1349,8 +1417,8 @@ static int BundlePacket(WOLFSSH* ssh)
|
|||
|
||||
HmacSetKey(&hmac, SHA, ssh->macKeyServer, ssh->macKeyServerSz);
|
||||
HmacUpdate(&hmac, flatSeq, sizeof(flatSeq));
|
||||
HmacUpdate(&sha,);
|
||||
HmacFinal(&sha, digest);
|
||||
HmacUpdate(&hmac,);
|
||||
HmacFinal(&hmac, digest);
|
||||
WMEMCPY(, digest, SHA1_96_SIZE);
|
||||
}
|
||||
break;
|
||||
|
@ -1371,8 +1439,6 @@ static int BundlePacket(WOLFSSH* ssh)
|
|||
return WS_FATAL_ERROR;
|
||||
}
|
||||
|
||||
ssh->seq++;
|
||||
|
||||
/* Encrypt the packet */
|
||||
switch (ssh->encryptId) {
|
||||
case ID_NONE:
|
||||
|
@ -1706,6 +1772,21 @@ int SendNewKeys(WOLFSSH* ssh)
|
|||
ssh->encryptId = ssh->handshake->encryptId;
|
||||
ssh->macId = ssh->handshake->macId;
|
||||
|
||||
switch (ssh->encryptId) {
|
||||
case ID_NONE:
|
||||
WLOG(WS_LOG_DEBUG, "SNK: using cipher none");
|
||||
break;
|
||||
|
||||
case ID_AES128_CBC:
|
||||
WLOG(WS_LOG_DEBUG, "SNK: using cipher aes128-cbc");
|
||||
AesSetKey(&ssh->encryptCipher.aes, ssh->encKeyServer, ssh->encKeyServerSz, ssh->ivServer, AES_ENCRYPTION);
|
||||
break;
|
||||
|
||||
default:
|
||||
WLOG(WS_LOG_DEBUG, "SNK: using cipher invalid");
|
||||
break;
|
||||
}
|
||||
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
18
src/ssh.c
18
src/ssh.c
|
@ -281,7 +281,7 @@ int wolfSSH_accept(WOLFSSH* ssh)
|
|||
case ACCEPT_BEGIN:
|
||||
while (ssh->clientState < CLIENT_VERSION_DONE) {
|
||||
if ( (ssh->error = ProcessClientVersion(ssh)) < 0) {
|
||||
WLOG(WS_LOG_DEBUG, "accept reply error: %d", ssh->error);
|
||||
WLOG(WS_LOG_DEBUG, "accept reply error 1: %d", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ int wolfSSH_accept(WOLFSSH* ssh)
|
|||
case SERVER_VERSION_SENT:
|
||||
while (ssh->clientState < CLIENT_ALGO_DONE) {
|
||||
if ( (ssh->error = ProcessReply(ssh)) < 0) {
|
||||
WLOG(WS_LOG_DEBUG, "accept reply error: %d", ssh->error);
|
||||
WLOG(WS_LOG_DEBUG, "accept reply error 2: %d", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -306,12 +306,22 @@ int wolfSSH_accept(WOLFSSH* ssh)
|
|||
case SERVER_ALGO_SENT:
|
||||
while (ssh->clientState < CLIENT_KEXDHINIT_DONE) {
|
||||
if ( (ssh->error = ProcessReply(ssh)) < 0) {
|
||||
WLOG(WS_LOG_DEBUG, "accept reply error: %d", ssh->error);
|
||||
WLOG(WS_LOG_DEBUG, "accept reply error 3: %d", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
SendKexDhReply(ssh);
|
||||
break;
|
||||
ssh->acceptState = SERVER_KEXDH_REPLY_SENT;
|
||||
|
||||
case SERVER_KEXDH_REPLY_SENT:
|
||||
while (ssh->clientState < CLIENT_USING_KEYS) {
|
||||
if ( (ssh->error = ProcessReply(ssh)) < 0) {
|
||||
WLOG(WS_LOG_DEBUG, "accept reply error 4: %d", ssh->error);
|
||||
return WS_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
SendNewKeys(ssh);
|
||||
ssh->acceptState = SERVER_USING_KEYS;
|
||||
}
|
||||
|
||||
return WS_FATAL_ERROR;
|
||||
|
|
|
@ -59,7 +59,8 @@ enum WS_ErrorCodes {
|
|||
WS_UNIMPLEMENTED_E = -17,
|
||||
WS_RSA_E = -18,
|
||||
WS_BAD_FILE_E = -19,
|
||||
WS_INVALID_ALGO_ID = -20
|
||||
WS_INVALID_ALGO_ID = -20,
|
||||
WS_DECRYPT_E = -21
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <cyassl/ctaocrypt/sha.h>
|
||||
#include <cyassl/ctaocrypt/random.h>
|
||||
#include <cyassl/ctaocrypt/dh.h>
|
||||
#include <cyassl/ctaocrypt/aes.h>
|
||||
|
||||
|
||||
#if !defined (ALIGN16)
|
||||
|
@ -135,6 +136,11 @@ struct WOLFSSH_CTX {
|
|||
};
|
||||
|
||||
|
||||
typedef struct Ciphers {
|
||||
Aes aes;
|
||||
} Ciphers;
|
||||
|
||||
|
||||
typedef struct HandshakeInfo {
|
||||
uint8_t kexId;
|
||||
uint8_t pubKeyId;
|
||||
|
@ -179,6 +185,9 @@ struct WOLFSSH {
|
|||
uint8_t peerEncryptId;
|
||||
uint8_t peerMacId;
|
||||
|
||||
Ciphers encryptCipher;
|
||||
Ciphers decryptCipher;
|
||||
|
||||
Buffer inputBuffer;
|
||||
Buffer outputBuffer;
|
||||
RNG* rng;
|
||||
|
@ -235,7 +244,9 @@ enum AcceptStates {
|
|||
ACCEPT_CLIENT_ALGO_DONE,
|
||||
SERVER_ALGO_SENT,
|
||||
ACCEPT_CLIENT_KEXDH_INIT_DONE,
|
||||
SERVER_KEXDH_ACCEPT_SENT
|
||||
SERVER_KEXDH_REPLY_SENT,
|
||||
SERVER_KEXDH_ACCEPT_SENT,
|
||||
SERVER_USING_KEYS
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue