aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelen <jjelen@redhat.com>2018-08-06 11:51:26 +0200
committerAndreas Schneider <asn@cryptomilk.org>2018-08-31 14:18:34 +0200
commit761225712a28d70adea7a2b872c265bc98a83511 (patch)
treee3b64f27742c357a1625e30407d12b7888c2e9cc
parentdf13d8c61f4fe0cc7d07260d59740eaf7f939d65 (diff)
downloadlibssh-761225712a28d70adea7a2b872c265bc98a83511.tar.gz
libssh-761225712a28d70adea7a2b872c265bc98a83511.tar.xz
libssh-761225712a28d70adea7a2b872c265bc98a83511.zip
client: Handle the MSG_EXT_INFO packet signalling supported extensions
RFC 8308: The extension negotiation in Secure Shell (SSH) Protocol RFC 8332: Use of RSA Keys with SHA-256 and SHA-512 in the Secure Shell (SSH) Protocol Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
-rw-r--r--include/libssh/packet.h1
-rw-r--r--include/libssh/session.h8
-rw-r--r--include/libssh/ssh2.h1
-rw-r--r--src/packet.c5
-rw-r--r--src/packet_cb.c52
5 files changed, 65 insertions, 2 deletions
diff --git a/include/libssh/packet.h b/include/libssh/packet.h
index 1a9283d8..a3bcb9a8 100644
--- a/include/libssh/packet.h
+++ b/include/libssh/packet.h
@@ -51,6 +51,7 @@ SSH_PACKET_CALLBACK(ssh_packet_ignore_callback);
SSH_PACKET_CALLBACK(ssh_packet_dh_reply);
SSH_PACKET_CALLBACK(ssh_packet_newkeys);
SSH_PACKET_CALLBACK(ssh_packet_service_accept);
+SSH_PACKET_CALLBACK(ssh_packet_ext_info);
#ifdef WITH_SERVER
SSH_PACKET_CALLBACK(ssh_packet_kexdh_init);
diff --git a/include/libssh/session.h b/include/libssh/session.h
index 6cb79628..00717652 100644
--- a/include/libssh/session.h
+++ b/include/libssh/session.h
@@ -86,6 +86,11 @@ enum ssh_pending_call_e {
#define SSH_OPT_FLAG_KBDINT_AUTH 0x4
#define SSH_OPT_FLAG_GSSAPI_AUTH 0x8
+/* extensions flags */
+/* server-sig-algs extension */
+#define SSH_EXT_SIG_RSA_SHA256 0x01
+#define SSH_EXT_SIG_RSA_SHA512 0x02
+
/* members that are common to ssh_session and ssh_bind */
struct ssh_common_struct {
struct error_struct error;
@@ -114,6 +119,9 @@ struct ssh_session_struct {
/* session flags (SSH_SESSION_FLAG_*) */
int flags;
+ /* Extensions negotiated using RFC 8308 */
+ uint32_t extensions;
+
ssh_string banner; /* that's the issue banner from
the server */
char *discon_msg; /* disconnect message from
diff --git a/include/libssh/ssh2.h b/include/libssh/ssh2.h
index 8b39b9a6..35214330 100644
--- a/include/libssh/ssh2.h
+++ b/include/libssh/ssh2.h
@@ -7,6 +7,7 @@
#define SSH2_MSG_DEBUG 4
#define SSH2_MSG_SERVICE_REQUEST 5
#define SSH2_MSG_SERVICE_ACCEPT 6
+#define SSH2_MSG_EXT_INFO 7
#define SSH2_MSG_KEXINIT 20
#define SSH2_MSG_NEWKEYS 21
diff --git a/src/packet.c b/src/packet.c
index 16f96149..5b9252f5 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -59,8 +59,9 @@ static ssh_packet_callback default_packet_handlers[]= {
NULL,
#endif
ssh_packet_service_accept, // SSH2_MSG_SERVICE_ACCEPT 6
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, // 7-19
+ ssh_packet_ext_info, // SSH2_MSG_EXT_INFO 7
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, // 8-19
ssh_packet_kexinit, // SSH2_MSG_KEXINIT 20
ssh_packet_newkeys, // SSH2_MSG_NEWKEYS 21
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
diff --git a/src/packet_cb.c b/src/packet_cb.c
index ecf327ef..c3a1997f 100644
--- a/src/packet_cb.c
+++ b/src/packet_cb.c
@@ -270,3 +270,55 @@ SSH_PACKET_CALLBACK(ssh_packet_service_accept){
return SSH_PACKET_USED;
}
+
+/**
+ * @internal
+ * @brief handles a SSH2_MSG_EXT_INFO packet defined in RFC 8308
+ *
+ */
+SSH_PACKET_CALLBACK(ssh_packet_ext_info)
+{
+ int rc;
+ uint32_t nr_extensions = 0;
+ uint32_t i;
+ (void)type;
+ (void)user;
+
+ SSH_LOG(SSH_LOG_PACKET, "Received SSH_MSG_EXT_INFO");
+
+ rc = ssh_buffer_get_u32(packet, &nr_extensions);
+ if (rc == 0) {
+ SSH_LOG(SSH_LOG_PACKET, "Failed to read number of extensions");
+ return SSH_PACKET_USED;
+ }
+ nr_extensions = ntohl(nr_extensions);
+ SSH_LOG(SSH_LOG_PACKET, "Follows %u extensions", nr_extensions);
+
+ for (i = 0; i < nr_extensions; i++) {
+ char *name = NULL;
+ char *value = NULL;
+ int cmp;
+
+ rc = ssh_buffer_unpack(packet, "ss", &name, &value);
+ if (rc != SSH_OK) {
+ SSH_LOG(SSH_LOG_PACKET, "Error reading extension name-value pair");
+ return SSH_PACKET_USED;
+ }
+
+ cmp = strcmp(name, "server-sig-algs");
+ if (cmp == 0) {
+ /* TODO check for NULL bytes */
+ SSH_LOG(SSH_LOG_PACKET, "Extension: %s=<%s>", name, value);
+ if (ssh_match_group(value, "rsa-sha2-512")) {
+ session->extensions |= SSH_EXT_SIG_RSA_SHA512;
+ }
+ if (ssh_match_group(value, "rsa-sha2-256")) {
+ session->extensions |= SSH_EXT_SIG_RSA_SHA256;
+ }
+ }
+ free(name);
+ free(value);
+ }
+
+ return SSH_PACKET_USED;
+}