feat: add SSH2_MSG_KEXGSS_HOSTKEY support to client and server

Signed-off-by: Gauravsingh Sisodia <xaerru@gmail.com>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Gauravsingh Sisodia
2024-08-22 11:26:40 +00:00
committed by Jakub Jelen
parent 9044fcdb52
commit d730b40b91
3 changed files with 74 additions and 1 deletions

View File

@@ -30,6 +30,7 @@ int ssh_client_gss_dh_init(ssh_session session);
void ssh_server_gss_dh_init(ssh_session session);
int ssh_server_gss_dh_process_init(ssh_session session, ssh_buffer packet);
void ssh_client_gss_dh_remove_callbacks(ssh_session session);
void ssh_client_gss_dh_remove_callback_hostkey(ssh_session session);
#endif /* WITH_GSSAPI */
#endif /* DH_GSS_H_ */

View File

@@ -49,6 +49,19 @@ static struct ssh_packet_callbacks_struct ssh_gss_dh_client_callbacks = {
.user = NULL
};
static SSH_PACKET_CALLBACK(ssh_packet_client_gss_dh_hostkey);
static ssh_packet_callback gss_dh_client_callback_hostkey[]= {
ssh_packet_client_gss_dh_hostkey
};
static struct ssh_packet_callbacks_struct ssh_gss_dh_client_callback_hostkey = {
.start = SSH2_MSG_KEXGSS_HOSTKEY,
.n_callbacks = 1,
.callbacks = gss_dh_client_callback_hostkey,
.user = NULL
};
/** @internal
* @brief Starts gssapi key exchange
*/
@@ -131,6 +144,7 @@ int ssh_client_gss_dh_init(ssh_session session){
/* register the packet callbacks */
ssh_packet_set_callbacks(session, &ssh_gss_dh_client_callbacks);
ssh_packet_set_callbacks(session, &ssh_gss_dh_client_callback_hostkey);
session->dh_handshake_state = DH_STATE_INIT_SENT;
rc = ssh_packet_send(session);
@@ -148,6 +162,11 @@ void ssh_client_gss_dh_remove_callbacks(ssh_session session)
ssh_packet_remove_callbacks(session, &ssh_gss_dh_client_callbacks);
}
void ssh_client_gss_dh_remove_callback_hostkey(ssh_session session)
{
ssh_packet_remove_callbacks(session, &ssh_gss_dh_client_callback_hostkey);
}
SSH_PACKET_CALLBACK(ssh_packet_client_gss_dh_reply){
struct ssh_crypto_struct *crypto=session->next_crypto;
ssh_string pubkey_blob = NULL, mic = NULL, otoken = NULL;
@@ -211,6 +230,35 @@ error:
return SSH_PACKET_USED;
}
SSH_PACKET_CALLBACK(ssh_packet_client_gss_dh_hostkey) {
ssh_string pubkey_blob = NULL;
int rc;
(void)type;
(void)user;
ssh_client_gss_dh_remove_callback_hostkey(session);
rc = ssh_buffer_unpack(packet,
"S",
&pubkey_blob);
if (rc == SSH_ERROR) {
ssh_set_error(session, SSH_FATAL, "Invalid SSH2_MSG_KEXGSS_HOSTKEY packet");
goto error;
}
rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
SSH_STRING_FREE(pubkey_blob);
if (rc != 0) {
goto error;
}
return SSH_PACKET_USED;
error:
ssh_dh_cleanup(session->next_crypto);
session->session_state=SSH_SESSION_STATE_ERROR;
return SSH_PACKET_USED;
}
#ifdef WITH_SERVER
@@ -256,6 +304,7 @@ int ssh_server_gss_dh_process_init(ssh_session session, ssh_buffer packet)
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
ssh_string otoken = NULL;
ssh_string server_pubkey_blob = NULL;
OM_uint32 maj_stat, min_stat;
gss_name_t client_name = GSS_C_NO_NAME;
OM_uint32 ret_flags=0;
@@ -307,6 +356,28 @@ int ssh_server_gss_dh_process_init(ssh_session session, ssh_buffer packet)
ssh_set_error(session, SSH_FATAL, "Could not create a session id");
goto error;
}
rc = ssh_dh_get_next_server_publickey_blob(session, &server_pubkey_blob);
if (rc != SSH_OK) {
goto error;
}
rc = ssh_buffer_pack(session->out_buffer,
"bS",
SSH2_MSG_KEXGSS_HOSTKEY,
server_pubkey_blob);
if(rc != SSH_OK) {
ssh_set_error_oom(session);
ssh_buffer_reinit(session->out_buffer);
goto error;
}
rc = ssh_packet_send(session);
if (rc == SSH_ERROR) {
goto error;
}
SSH_LOG(SSH_LOG_DEBUG, "Sent SSH2_MSG_KEXGSS_HOSTKEY");
SSH_STRING_FREE(server_pubkey_blob);
rc = ssh_dh_keypair_get_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR,
NULL, &server_pubkey);
if (rc != SSH_OK){
@@ -414,6 +485,7 @@ int ssh_server_gss_dh_process_init(ssh_session session, ssh_buffer packet)
return SSH_OK;
error:
SSH_STRING_FREE(server_pubkey_blob);
#if defined(HAVE_LIBCRYPTO) && OPENSSL_VERSION_NUMBER >= 0x30000000L
bignum_safe_free(server_pubkey);
#endif

View File

@@ -1480,7 +1480,7 @@ int ssh_make_sessionid(ssh_session session)
}
if (session->server) {
if (ssh_kex_is_gss(session->next_crypto)) {
if (server_pubkey_blob == NULL && ssh_kex_is_gss(session->next_crypto)) {
ssh_string_free(server_pubkey_blob);
server_pubkey_blob = ssh_string_new(0);
}