mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-11-29 01:03:57 +03:00
server: Support for extension negotiation
This includes intercepting the ext-info-c string from the client kex proposal, configuring the server to allow using this extension and sending the SSH_MSG_EXT_INFO packet back to the client after the new keys are in use. Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
committed by
Andreas Schneider
parent
60ad7ee15d
commit
6fa5e8adb0
@@ -90,6 +90,7 @@ enum ssh_pending_call_e {
|
|||||||
/* server-sig-algs extension */
|
/* server-sig-algs extension */
|
||||||
#define SSH_EXT_SIG_RSA_SHA256 0x01
|
#define SSH_EXT_SIG_RSA_SHA256 0x01
|
||||||
#define SSH_EXT_SIG_RSA_SHA512 0x02
|
#define SSH_EXT_SIG_RSA_SHA512 0x02
|
||||||
|
#define SSH_EXT_ALL SSH_EXT_SIG_RSA_SHA256 | SSH_EXT_SIG_RSA_SHA512
|
||||||
|
|
||||||
/* members that are common to ssh_session and ssh_bind */
|
/* members that are common to ssh_session and ssh_bind */
|
||||||
struct ssh_common_struct {
|
struct ssh_common_struct {
|
||||||
|
|||||||
18
src/kex.c
18
src/kex.c
@@ -415,7 +415,7 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_kexinit){
|
SSH_PACKET_CALLBACK(ssh_packet_kexinit){
|
||||||
int i;
|
int i, ok;
|
||||||
int server_kex=session->server;
|
int server_kex=session->server;
|
||||||
ssh_string str = NULL;
|
ssh_string str = NULL;
|
||||||
char *strings[KEX_METHODS_SIZE];
|
char *strings[KEX_METHODS_SIZE];
|
||||||
@@ -519,6 +519,22 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If client sent a ext-info-c message in the kex list, it supports
|
||||||
|
* RFC 8308 extension negotiation.
|
||||||
|
*/
|
||||||
|
ok = ssh_match_group(session->next_crypto->client_kex.methods[SSH_KEX],
|
||||||
|
KEX_EXTENSION_CLIENT);
|
||||||
|
if (ok) {
|
||||||
|
/*
|
||||||
|
* Enable all the supported extensions and when the time comes
|
||||||
|
* (after NEWKEYS) send them to the client.
|
||||||
|
*/
|
||||||
|
SSH_LOG(SSH_LOG_DEBUG, "The client supports extension "
|
||||||
|
"negotiation: enabling all extensions");
|
||||||
|
session->extensions = SSH_EXT_ALL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remember whether 'first_kex_packet_follows' was set and the client
|
* Remember whether 'first_kex_packet_follows' was set and the client
|
||||||
* guess was wrong: in this case the next SSH_MSG_KEXDH_INIT message
|
* guess was wrong: in this case the next SSH_MSG_KEXDH_INIT message
|
||||||
|
|||||||
41
src/server.c
41
src/server.c
@@ -67,7 +67,6 @@
|
|||||||
|
|
||||||
static int dh_handshake_server(ssh_session session);
|
static int dh_handshake_server(ssh_session session);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup libssh_server
|
* @addtogroup libssh_server
|
||||||
*
|
*
|
||||||
@@ -194,6 +193,37 @@ static int ssh_server_kexdh_init(ssh_session session, ssh_buffer packet){
|
|||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ssh_server_send_extensions(ssh_session session) {
|
||||||
|
int rc;
|
||||||
|
const char *hostkey_algorithms;
|
||||||
|
|
||||||
|
SSH_LOG(SSH_LOG_PACKET, "Sending SSH_MSG_EXT_INFO");
|
||||||
|
/*
|
||||||
|
* We can list here all the default hostkey methods, since
|
||||||
|
* they already contain the SHA2 extension algorithms
|
||||||
|
*/
|
||||||
|
hostkey_algorithms = ssh_kex_get_default_methods(SSH_HOSTKEYS);
|
||||||
|
rc = ssh_buffer_pack(session->out_buffer,
|
||||||
|
"bdss",
|
||||||
|
SSH2_MSG_EXT_INFO,
|
||||||
|
1, /* nr. of extensions */
|
||||||
|
"server-sig-algs",
|
||||||
|
hostkey_algorithms);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssh_packet_send(session) == SSH_ERROR) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
ssh_buffer_reinit(session->out_buffer);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
SSH_PACKET_CALLBACK(ssh_packet_kexdh_init){
|
SSH_PACKET_CALLBACK(ssh_packet_kexdh_init){
|
||||||
int rc = SSH_ERROR;
|
int rc = SSH_ERROR;
|
||||||
(void)type;
|
(void)type;
|
||||||
@@ -486,6 +516,15 @@ static void ssh_server_connection_callback(ssh_session session){
|
|||||||
session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
|
session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
|
||||||
if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED)
|
if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED)
|
||||||
session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
|
session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the client supports extension negotiation, we will send
|
||||||
|
* our supported extensions now. This is the first message after
|
||||||
|
* sending NEWKEYS message and after turning on crypto.
|
||||||
|
*/
|
||||||
|
if (session->extensions) {
|
||||||
|
ssh_server_send_extensions(session);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SSH_SESSION_STATE_AUTHENTICATING:
|
case SSH_SESSION_STATE_AUTHENTICATING:
|
||||||
|
|||||||
Reference in New Issue
Block a user