summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2018-05-17 12:29:57 +0800
committerIru Cai <mytbk920423@gmail.com>2018-05-21 09:18:16 +0800
commit593b92e5be8805e32ef43d9208ed0e7a4acf83df (patch)
tree75260bb96524f6f1d3df9d83cc373df9b853e843
parent535fc2e838277de6132ea1b3f5a3726c315e6d5e (diff)
downloadfqterm-593b92e5be8805e32ef43d9208ed0e7a4acf83df.tar.xz
move packet making code to C code
-rw-r--r--src/protocol/CMakeLists.txt4
-rw-r--r--src/protocol/internal/crc32.c (renamed from src/protocol/internal/crc32.cpp)21
-rw-r--r--src/protocol/internal/crc32.h13
-rw-r--r--src/protocol/internal/fqterm_ssh1_packet.cpp37
-rw-r--r--src/protocol/internal/fqterm_ssh2_packet.cpp84
-rw-r--r--src/protocol/internal/ssh_packet.c142
-rw-r--r--src/protocol/internal/ssh_packet.h39
7 files changed, 207 insertions, 133 deletions
diff --git a/src/protocol/CMakeLists.txt b/src/protocol/CMakeLists.txt
index 5c35577..e6db775 100644
--- a/src/protocol/CMakeLists.txt
+++ b/src/protocol/CMakeLists.txt
@@ -27,7 +27,8 @@ set(internal_SRCS
internal/ssh_pubkey_crypto.c
internal/ssh_diffie-hellman.h
internal/ssh_diffie-hellman.c
- internal/crc32.h
+ internal/crc32.c
+ internal/ssh_packet.c
internal/fqterm_serialization.h
internal/fqterm_ssh_auth.h
internal/fqterm_ssh_const.h
@@ -38,7 +39,6 @@ set(internal_SRCS
internal/fqterm_ssh2_packet.h
internal/fqterm_ssh_channel.h
internal/fqterm_ssh_types.h
- internal/crc32.cpp
internal/fqterm_ssh_auth.cpp
internal/fqterm_ssh_kex.cpp
internal/fqterm_ssh2_kex.cpp
diff --git a/src/protocol/internal/crc32.cpp b/src/protocol/internal/crc32.c
index 2039ac8..2365730 100644
--- a/src/protocol/internal/crc32.cpp
+++ b/src/protocol/internal/crc32.c
@@ -25,8 +25,7 @@
*/
#include "crc32.h"
-namespace FQTerm {
-static const u_int32_t crc32tab[] = {
+static const uint32_t crc32tab[] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL,
0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L,
@@ -72,13 +71,13 @@ static const u_int32_t crc32tab[] = {
0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
};
-u_int32_t ssh_crc32(const u_char *buf, u_int32_t size) {
- u_int32_t i, crc;
-
- crc = 0;
- for (i = 0; i < size; i++) {
- crc = crc32tab[(crc ^ buf[i]) &0xff] ^ (crc >> 8);
- } return crc;
-}
+uint32_t ssh_crc32(const uint8_t *buf, uint32_t size)
+{
+ uint32_t i, crc;
+
+ crc = 0;
+ for (i = 0; i < size; i++)
+ crc = crc32tab[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
-} // namespace FQTerm
+ return crc;
+}
diff --git a/src/protocol/internal/crc32.h b/src/protocol/internal/crc32.h
index ca95b89..56e3b7b 100644
--- a/src/protocol/internal/crc32.h
+++ b/src/protocol/internal/crc32.h
@@ -26,12 +26,17 @@
#ifndef SSH_CRC32_H
#define SSH_CRC32_H
-#include "fqterm_ssh_types.h"
-namespace FQTerm {
+#include <stdint.h>
-u_int32_t ssh_crc32(const u_char *, u_int32_t);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint32_t ssh_crc32(const uint8_t *, uint32_t);
-} // namespace FQTerm
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/src/protocol/internal/fqterm_ssh1_packet.cpp b/src/protocol/internal/fqterm_ssh1_packet.cpp
index b1f873b..5e64d45 100644
--- a/src/protocol/internal/fqterm_ssh1_packet.cpp
+++ b/src/protocol/internal/fqterm_ssh1_packet.cpp
@@ -23,23 +23,12 @@
#include "fqterm_serialization.h"
#include "crc32.h"
+#include "ssh_packet.h"
namespace FQTerm {
//==============================================================================
//FQTermSSH1PacketSender
//==============================================================================
-//==============================================================================
-//
-// SSH1 Packet Structure:
-// --------------------------------------------------------------------------
-// | length | padding | type | data | crc32 |
-// --------------------------------------------------------------------------
-// | uint32 | 1-7bytes | uchar | | 4bytes|
-// --------------------------------------------------------------------------
-// encrypt = padding + type + data + crc32
-// length = type + data + crc32
-//
-//==============================================================================
FQTermSSH1PacketSender::FQTermSSH1PacketSender()
{
@@ -48,29 +37,7 @@ namespace FQTerm {
void FQTermSSH1PacketSender::makePacket()
{
- int len, padding_len;
- uint32_t padding[2];
- uint8_t *data = buffer_data(&orig_data);
- size_t data_len = buffer_len(&orig_data);
-
- len = data_len + 4; //CRC32
- padding_len = 8 - (len % 8);
- padding[0] = rand();
- padding[1] = rand();
-
- buffer_clear(&data_to_send);
- buffer_append_be32(&data_to_send, len);
- buffer_append(&data_to_send, (const uint8_t*)padding, padding_len);
- buffer_append(&data_to_send, data, data_len);
- buffer_append_be32(&data_to_send, ssh_crc32(
- buffer_data(&data_to_send) + 4,
- buffer_len(&data_to_send) - 4));
-
- if (cipher->started) {
- cipher->crypt(cipher, buffer_data(&data_to_send) + 4,
- buffer_data(&data_to_send) + 4,
- buffer_len(&data_to_send) - 4);
- }
+ make_ssh1_packet(&orig_data, &data_to_send, cipher);
}
//==============================================================================
diff --git a/src/protocol/internal/fqterm_ssh2_packet.cpp b/src/protocol/internal/fqterm_ssh2_packet.cpp
index 9f8fd70..e13cab7 100644
--- a/src/protocol/internal/fqterm_ssh2_packet.cpp
+++ b/src/protocol/internal/fqterm_ssh2_packet.cpp
@@ -23,19 +23,12 @@
#include "fqterm_serialization.h"
#include "buffer.h"
+#include "ssh_packet.h"
namespace FQTerm {
//==============================================================================
//FQTermSSH2PacketSender
//==============================================================================
-// SSH2 Packet Structure:
-// uint32 packet_length
-// byte padding_length
-// byte[n1] payload; n1 = packet_length - padding_length - 1
-// byte[n2] random padding; n2 = padding_length
-// byte[m] mac (Message Authentication Code - MAC); m = mac_length
-//==============================================================================
-
void FQTermSSH2PacketSender::makePacket()
{
FQ_TRACE("ssh2packet", 9) << "----------------------------Send "
@@ -46,79 +39,8 @@ void FQTermSSH2PacketSender::makePacket()
if (is_compressed_)
FQ_VERIFY(false);
- // 1. compute the padding length for padding.
- int non_padding_len = 4 + 1 + buffer_len(&orig_data);
-
- int padding_block_len = 8;
- if (cipher->started && cipher->blkSize > padding_block_len)
- padding_block_len = cipher->blkSize;
-
- int padding_len = padding_block_len - (non_padding_len % padding_block_len);
- if (padding_len < 4)
- padding_len += padding_block_len;
-
- // 2. renew the output buffer.
- int total_len = non_padding_len + padding_len;
- if (is_mac_)
- total_len += mac->dgstSize;
-
- buffer_clear(&data_to_send);
-
- // 3. Fill the output buffer.
- int packet_len = 1 + buffer_len(&orig_data) + padding_len;
-
- buffer_append_be32(&data_to_send, packet_len);
- buffer_append_byte(&data_to_send, padding_len);
- buffer_append(&data_to_send, buffer_data(&orig_data), buffer_len(&orig_data));
-
- uint32_t padding[8]; /* padding at most 256 bits */
- for (int i = 0; i < 8; i++)
- padding[i] = rand();
- buffer_append(&data_to_send, (const uint8_t*)padding, padding_len);
-
- // 4. Add MAC on the entire unencrypted packet,
- // including two length fields, 'payload' and 'random padding'.
- if (is_mac_) {
- const unsigned char *packet = buffer_data(&data_to_send);
- int len = buffer_len(&data_to_send);
-
- uint8_t digest[MAX_DGSTLEN];
-
- buffer mbuffer;
- buffer_init(&mbuffer);
- buffer_append_be32(&mbuffer, sequence_no_);
- buffer_append(&mbuffer, packet, len);
- mac->getmac(mac, buffer_data(&mbuffer), buffer_len(&mbuffer), digest);
- buffer_deinit(&mbuffer);
-
- buffer_append(&data_to_send, digest, mac->dgstSize);
- }
-
- if (is_compressed_) {
- FQ_VERIFY(false);
- }
-
- if (cipher->started) {
- // as RFC 4253:
- // When encryption is in effect, the packet length, padding
- // length, payload, and padding fields of each packet MUST be encrypted
- // with the given algorithm.
-
- uint8_t *data = buffer_data(&data_to_send);
- int len = buffer_len(&data_to_send) - mac->dgstSize;
-
- FQ_TRACE("ssh2packet", 9) << "An packet (without MAC) to be encrypted:"
- << len << " bytes:\n"
- << dumpHexString << std::string((const char *)data, len);
-
- FQ_VERIFY(cipher->crypt(cipher, data, data, len)==1);
-
- FQ_TRACE("ssh2packet", 9) << "An encrypted packet (without MAC) made:"
- << len << " bytes:\n"
- << dumpHexString << std::string((const char *)data, len);
- }
-
- ++sequence_no_;
+ make_ssh2_packet(&orig_data, &data_to_send, cipher,
+ mac, is_mac_, &sequence_no_);
}
//==============================================================================
diff --git a/src/protocol/internal/ssh_packet.c b/src/protocol/internal/ssh_packet.c
new file mode 100644
index 0000000..6aad6d9
--- /dev/null
+++ b/src/protocol/internal/ssh_packet.c
@@ -0,0 +1,142 @@
+/*
+ * ssh_packet.c: SSH packet maker
+ * Copyright (C) 2018 Iru Cai <mytbk920423@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "ssh_packet.h"
+#include "crc32.h"
+#include "ssh_error.h"
+
+//==============================================================================
+//
+// SSH1 Packet Structure:
+// --------------------------------------------------------------------------
+// | length | padding | type | data | crc32 |
+// --------------------------------------------------------------------------
+// | uint32 | 1-7bytes | uchar | | 4bytes|
+// --------------------------------------------------------------------------
+// encrypt = padding + type + data + crc32
+// length = type + data + crc32
+//
+//==============================================================================
+void make_ssh1_packet(buffer *orig_data, buffer *data_to_send,
+ SSH_CIPHER *cipher)
+{
+ int len, padding_len;
+ uint32_t padding[2];
+ uint8_t *data = buffer_data(orig_data);
+ size_t data_len = buffer_len(orig_data);
+
+ len = data_len + 4; //CRC32
+ padding_len = 8 - (len % 8);
+ padding[0] = rand();
+ padding[1] = rand();
+
+ buffer_clear(data_to_send);
+ buffer_append_be32(data_to_send, len);
+ buffer_append(data_to_send, (const uint8_t *)padding, padding_len);
+ buffer_append(data_to_send, data, data_len);
+ buffer_append_be32(data_to_send,
+ ssh_crc32(buffer_data(data_to_send) + 4,
+ buffer_len(data_to_send) - 4));
+
+ if (cipher->started) {
+ cipher->crypt(cipher, buffer_data(data_to_send) + 4,
+ buffer_data(data_to_send) + 4,
+ buffer_len(data_to_send) - 4);
+ }
+}
+
+//==============================================================================
+// SSH2 Packet Structure:
+// uint32 packet_length
+// byte padding_length
+// byte[n1] payload; n1 = packet_length - padding_length - 1
+// byte[n2] random padding; n2 = padding_length
+// byte[m] mac (Message Authentication Code - MAC); m = mac_length
+//==============================================================================
+int make_ssh2_packet(buffer *orig_data, buffer *data_to_send,
+ SSH_CIPHER *cipher, SSH_MAC *mac, bool is_mac_,
+ uint32_t *seq)
+{
+ // 1. compute the padding length for padding.
+ int non_padding_len = 4 + 1 + buffer_len(orig_data);
+
+ int padding_block_len = 8;
+ if (cipher->started && cipher->blkSize > padding_block_len)
+ padding_block_len = cipher->blkSize;
+
+ int padding_len =
+ padding_block_len - (non_padding_len % padding_block_len);
+ if (padding_len < 4)
+ padding_len += padding_block_len;
+
+ // 2. renew the output buffer.
+ int total_len = non_padding_len + padding_len;
+ if (is_mac_)
+ total_len += mac->dgstSize;
+
+ buffer_clear(data_to_send);
+
+ // 3. Fill the output buffer.
+ int packet_len = 1 + buffer_len(orig_data) + padding_len;
+
+ buffer_append_be32(data_to_send, packet_len);
+ buffer_append_byte(data_to_send, padding_len);
+ buffer_append(data_to_send, buffer_data(orig_data),
+ buffer_len(orig_data));
+
+ uint32_t padding[8]; /* padding at most 256 bits */
+ for (int i = 0; i < 8; i++)
+ padding[i] = rand();
+ buffer_append(data_to_send, (const uint8_t *)padding, padding_len);
+
+ // 4. Add MAC on the entire unencrypted packet,
+ // including two length fields, 'payload' and 'random padding'.
+ if (is_mac_) {
+ const unsigned char *packet = buffer_data(data_to_send);
+ int len = buffer_len(data_to_send);
+
+ uint8_t digest[MAX_DGSTLEN];
+
+ buffer mbuffer;
+ buffer_init(&mbuffer);
+ buffer_append_be32(&mbuffer, *seq);
+ buffer_append(&mbuffer, packet, len);
+ mac->getmac(mac, buffer_data(&mbuffer), buffer_len(&mbuffer),
+ digest);
+ buffer_deinit(&mbuffer);
+
+ buffer_append(data_to_send, digest, mac->dgstSize);
+ }
+
+ if (cipher->started) {
+ // as RFC 4253:
+ // When encryption is in effect, the packet length, padding
+ // length, payload, and padding fields of each packet MUST be encrypted
+ // with the given algorithm.
+
+ uint8_t *data = buffer_data(data_to_send);
+ int len = buffer_len(data_to_send) - mac->dgstSize;
+
+ if (cipher->crypt(cipher, data, data, len) != 1)
+ return -ECRYPT;
+ }
+
+ *seq = *seq + 1;
+ return 0;
+}
diff --git a/src/protocol/internal/ssh_packet.h b/src/protocol/internal/ssh_packet.h
new file mode 100644
index 0000000..d8cdaf2
--- /dev/null
+++ b/src/protocol/internal/ssh_packet.h
@@ -0,0 +1,39 @@
+/*
+ * ssh_packet.h: SSH packet maker
+ * Copyright (C) 2018 Iru Cai <mytbk920423@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef SSH_PACKET_H
+#define SSH_PACKET_H
+
+#include "buffer.h"
+#include "ssh_cipher.h"
+#include "ssh_mac.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* } */
+
+void make_ssh1_packet(buffer *src, buffer *dest, SSH_CIPHER *);
+int make_ssh2_packet(buffer *src, buffer *dest, SSH_CIPHER *,
+ SSH_MAC *, bool is_mac_, uint32_t *seq);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif