From 67bb1cdbdc955601cd30f1fcfbad817f5362747d Mon Sep 17 00:00:00 2001 From: John Safranek Date: Sat, 23 Aug 2014 23:07:12 -0700 Subject: [PATCH] 1. Adding the packet building and send functions. 2. Fix RNG initializer. --- src/internal.c | 161 ++++++++++++++++++++++++++++++++++++++++++++- src/ssh.c | 2 + wolfssh/internal.h | 8 ++- 3 files changed, 166 insertions(+), 5 deletions(-) diff --git a/src/internal.c b/src/internal.c index 711bc91..712ea88 100644 --- a/src/internal.c +++ b/src/internal.c @@ -38,12 +38,22 @@ /* convert opaque to 32 bit integer */ -static /*INLINE*/ void ato32(const uint8_t* c, uint32_t* u32) +static INLINE void ato32(const uint8_t* c, uint32_t* u32) { *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; } +/* convert 32 bit integer to opaque */ +static INLINE void c32toa(uint32_t u32, uint8_t* c) +{ + c[0] = (u32 >> 24) & 0xff; + c[1] = (u32 >> 16) & 0xff; + c[2] = (u32 >> 8) & 0xff; + c[3] = u32 & 0xff; +} + + const char* GetErrorString(int err) { #ifdef NO_WOLFSSH_STRINGS @@ -740,8 +750,8 @@ static int DoPacket(WOLFSSH* ssh) msg = buf[idx++]; switch (msg) { - case SSH_MSG_KEXINIT: - WLOG(WS_LOG_DEBUG, "Decoding SSH_MSG_KEXINIT (len = %d)", len); + case MSGID_KEXINIT: + WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXINIT (len = %d)", len); DoKexInit(ssh, buf, len, &idx); break; @@ -853,3 +863,148 @@ int SendServerVersion(WOLFSSH* ssh) } +static int PreparePacket(WOLFSSH* ssh, uint32_t payloadSz) +{ + int ret; + uint8_t* output; + uint32_t outputSz; + uint32_t packetSz; + uint8_t paddingSz; + + /* Minimum value for paddingSz is 4. */ + paddingSz = (LENGTH_SZ + PAD_LENGTH_SZ + payloadSz) % ssh->blockSz; + if (paddingSz < 4) + paddingSz += ssh->blockSz; + ssh->paddingSz = paddingSz; + packetSz = PAD_LENGTH_SZ + payloadSz + paddingSz; + outputSz = LENGTH_SZ + packetSz + ssh->macSz; + + if ( (ret = GrowBuffer(&ssh->outputBuffer, outputSz, 0)) != WS_SUCCESS) + return ret; + + output = ssh->outputBuffer.buffer + ssh->outputBuffer.length; + + /* fill in the packetSz, paddingSz */ + c32toa(packetSz, output); + output[LENGTH_SZ] = paddingSz; + + ssh->outputBuffer.length += LENGTH_SZ + PAD_LENGTH_SZ; + + return ret; +} + + +static int BundlePacket(WOLFSSH* ssh) +{ + uint8_t* output; + uint32_t outputSz, i; + uint8_t paddingSz; + + outputSz = ssh->outputBuffer.length; + output = ssh->outputBuffer.buffer + outputSz; + paddingSz = ssh->paddingSz; + + for (i = 0; i < ssh->paddingSz; i++) + output[i] = i + 1; + outputSz += paddingSz; + + switch (ssh->integrityId) { + case ID_NONE: + break; + + case ID_HMAC_SHA1_96: + break; + + case ID_HMAC_SHA1: + break; + + default: + break; + } + + return WS_SUCCESS; +} + + +static int SendPacket(WOLFSSH* ssh) +{ + (void)ssh; + return WS_SUCCESS; +} + + +/* + * MAX_MSG_EXTRA = 4 (packet_length) + * + 1 (padding_length) + * + ssh->blockSz (worst case padding size) + * + ssh->macSz + */ + + +static const char cannedEncAlgoNames[] = "aes128-cbc"; +static const char cannedMacAlgoNames[] = "hmac-sha1-96,hmac-sha1"; +static const char cannedKeyAlgoNames[] = "ssh-rsa"; +static const char cannedKexAlgoNames[] = "diffie-hellman-group14-sha1," + "diffie-hellman-group1-sha1"; +static const char cannedNoneNames[] = "none"; + +static const uint32_t cannedEncAlgoNamesSz = sizeof(cannedEncAlgoNames) - 1; +static const uint32_t cannedMacAlgoNamesSz = sizeof(cannedMacAlgoNames) - 1; +static const uint32_t cannedKeyAlgoNamesSz = sizeof(cannedKeyAlgoNames) - 1; +static const uint32_t cannedKexAlgoNamesSz = sizeof(cannedKexAlgoNames) - 1; +static const uint32_t cannedNoneNamesSz = sizeof(cannedNoneNames) - 1; + + + /* + * byte[16] cookie + * name-list kex_algorithms (2) + * name-list server_host_key_algorithms (1) + * name-list encryption_algorithms_client_to_server (3) + * name-list encryption_algorithms_server_to_client (3) + * name-list mac_algorithms_client_to_server (2) + * name-list mac_algorithms_server_to_client (2) + * name-list compression_algorithms_client_to_server (1) + * name-list compression_algorithms_server_to_client (1) + * name-list languages_client_to_server (0, skip) + * name-list languages_server_to_client (0, skip) + * boolean first_kex_packet_follows + * uint32 0 (reserved for future extension) + */ + +int SendKexInit(WOLFSSH* ssh) +{ + uint8_t* output; + uint32_t length, idx = 0; + uint32_t payloadSz; + int ret = WS_SUCCESS; + + (void)length; + (void)idx; + (void)cannedEncAlgoNames; + (void)cannedMacAlgoNames; + (void)cannedKeyAlgoNames; + (void)cannedKexAlgoNames; + (void)cannedNoneNames; + + payloadSz = MSG_ID_SZ + COOKIE_SZ + (LENGTH_SZ * 11) + BOOLEAN_SZ + + cannedKexAlgoNamesSz + cannedKeyAlgoNamesSz + + (cannedEncAlgoNamesSz * 2) + + (cannedMacAlgoNamesSz * 2) + + (cannedNoneNamesSz * 2); + PreparePacket(ssh, payloadSz); + + output = ssh->outputBuffer.buffer + ssh->outputBuffer.length; + idx = ssh->outputBuffer.length; + + output[idx++] = MSGID_KEXINIT; + + RNG_GenerateBlock(ssh->rng, output + idx, COOKIE_SZ); + idx += COOKIE_SZ; + + BundlePacket(ssh); + SendPacket(ssh); + + return ret; +} + + diff --git a/src/ssh.c b/src/ssh.c index 75b4392..5a11c5c 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -153,6 +153,7 @@ static WOLFSSH* SshInit(WOLFSSH* ssh, WOLFSSH_CTX* ctx) ssh->publicKeyId = ID_NONE; ssh->encryptionId = ID_NONE; ssh->integrityId = ID_NONE; + ssh->rng = rng; ssh->handshake = handshake; handshake->keyExchangeId = ID_NONE; handshake->publicKeyId = ID_NONE; @@ -297,6 +298,7 @@ int wolfSSH_accept(WOLFSSH* ssh) WLOG(WS_LOG_DEBUG, "accept reply error: %d", ssh->error); return WS_FATAL_ERROR; } + SendKexInit(ssh); } break; } diff --git a/wolfssh/internal.h b/wolfssh/internal.h index 999f8ec..adcff49 100644 --- a/wolfssh/internal.h +++ b/wolfssh/internal.h @@ -86,6 +86,8 @@ enum { #define COOKIE_SZ 16 #define LENGTH_SZ 4 #define PAD_LENGTH_SZ 1 +#define BOOLEAN_SZ 1 +#define MSG_ID_SZ 1 WOLFSSH_LOCAL uint8_t NameToId(const char*, uint32_t); @@ -159,6 +161,7 @@ struct WOLFSSH { uint32_t peerSeq; uint8_t blockSz; uint8_t macSz; + uint8_t paddingSz; uint8_t acceptState; uint8_t clientState; uint8_t processReplyState; @@ -193,6 +196,7 @@ WOLFSSH_LOCAL int wsEmbedSend(WOLFSSH*, void*, uint32_t, void*); WOLFSSH_LOCAL int ProcessReply(WOLFSSH*); WOLFSSH_LOCAL int ProcessClientVersion(WOLFSSH*); WOLFSSH_LOCAL int SendServerVersion(WOLFSSH*); +WOLFSSH_LOCAL int SendKexInit(WOLFSSH*); enum AcceptStates { @@ -220,8 +224,8 @@ enum ProcessReplyStates { enum SshMessageIds { - SSH_MSG_KEXINIT = 20, - SSH_MSG_NEWKEYS = 21 + MSGID_KEXINIT = 20, + MSGID_NEWKEYS = 21 };