feat: add gssapi key exchange

feat: add generic functions for importing name and initializing ctx

feat: add suffix to gsskex algs dynamically

feat: move gssapi key exchange to another file

feat: add gssapi key exchange for server

refactor: remove unnecessary fields in gssapi struct

refactor: add some documentation and improve logging

fix: remove gss_dh callbacks

feat: add a check to see if GSSAPI is configured correctly

fix: memory leaks

feat: add client side "gssapi-keyex" auth

feat: add gssapi_key_exchange_algs for server

fix: some memory issues

feat: add gssapi kex options to config

feat: add check to see if GSSAPI key exchange was performed

feat: add more tests for gssapi key exchange

fix: add valgrind supp

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-07-17 05:49:24 +00:00
committed by Jakub Jelen
parent 701a2155a7
commit bc5211d055
39 changed files with 2100 additions and 154 deletions

View File

@@ -52,6 +52,7 @@ typedef struct ssh_kbdint_struct* ssh_kbdint;
ssh_kbdint ssh_kbdint_new(void);
void ssh_kbdint_clean(ssh_kbdint kbd);
void ssh_kbdint_free(ssh_kbdint kbd);
int ssh_userauth_gssapi_keyex(ssh_session session);
/** @internal
* States of authentication in the client-side. They describe
@@ -88,6 +89,8 @@ enum ssh_auth_state_e {
SSH_AUTH_STATE_PASSWORD_AUTH_SENT,
/** We have sent a request without auth information (method 'none') */
SSH_AUTH_STATE_AUTH_NONE_SENT,
/** We have sent the MIC and expecting to be authenticated */
SSH_AUTH_STATE_GSSAPI_KEYEX_MIC_SENT,
};
/** @internal

View File

@@ -54,6 +54,8 @@ struct ssh_bind_struct {
char *pubkey_accepted_key_types;
char* moduli_file;
int rsa_min_size;
bool gssapi_key_exchange;
char *gssapi_key_exchange_algs;
};
struct ssh_poll_handle_struct *ssh_bind_get_poll(struct ssh_bind_struct

View File

@@ -69,6 +69,8 @@ enum ssh_config_opcode_e {
SOC_CERTIFICATE,
SOC_REQUIRED_RSA_SIZE,
SOC_ADDRESSFAMILY,
SOC_GSSAPIKEYEXCHANGE,
SOC_GSSAPIKEXALGORITHMS,
SOC_MAX /* Keep this one last in the list */
};

View File

@@ -95,6 +95,10 @@ enum ssh_key_exchange_e {
/* mlkem1024nistp384-sha384 */
SSH_KEX_MLKEM1024NISTP384_SHA384,
#endif /* HAVE_MLKEM */
/* gss-group14-sha256-* */
SSH_GSS_KEX_DH_GROUP14_SHA256,
/* gss-group16-sha512-* */
SSH_GSS_KEX_DH_GROUP16_SHA512,
};
enum ssh_cipher_e {

35
include/libssh/dh-gss.h Normal file
View File

@@ -0,0 +1,35 @@
/*
* dh-gss.h - diffie-hellman GSSAPI key exchange
*
* This file is part of the SSH Library
*
* Copyright (c) 2024 by Gauravsingh Sisodia <xaerru@gmail.com>
*
* The SSH 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.
*
* The SSH 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 the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#ifndef DH_GSS_H_
#define DH_GSS_H_
#include "config.h"
#ifdef WITH_GSSAPI
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);
#endif /* WITH_GSSAPI */
#endif /* DH_GSS_H_ */

View File

@@ -29,6 +29,9 @@
/* all OID begin with the tag identifier + length */
#define SSH_OID_TAG 06
#define GSSAPI_KEY_EXCHANGE_SUPPORTED \
"gss-group14-sha256-,gss-group16-sha512-,"
typedef struct ssh_gssapi_struct *ssh_gssapi;
#ifdef __cplusplus
@@ -44,14 +47,12 @@ enum ssh_gssapi_state_e {
struct ssh_gssapi_struct{
enum ssh_gssapi_state_e state; /* current state */
struct gss_OID_desc_struct mech; /* mechanism being elected for auth */
gss_cred_id_t server_creds; /* credentials of server */
gss_cred_id_t client_creds; /* creds delegated by the client */
gss_ctx_id_t ctx; /* the authentication context */
gss_name_t client_name; /* Identity of the client */
char *user; /* username of client */
char *canonic_user; /* canonic form of the client's username */
char *service; /* name of the service */
struct {
gss_name_t server_name; /* identity of server */
OM_uint32 flags; /* flags used for init context */
@@ -65,6 +66,7 @@ struct ssh_gssapi_struct{
int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n_oid, ssh_string *oids);
SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server);
SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic);
int ssh_gssapi_server_oids(gss_OID_set *selected);
#endif /* WITH_SERVER */
SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token);
@@ -76,7 +78,17 @@ int ssh_gssapi_init(ssh_session session);
void ssh_gssapi_log_error(int verb, const char *msg_a, int maj_stat, int min_stat);
int ssh_gssapi_auth_mic(ssh_session session);
void ssh_gssapi_free(ssh_session session);
int ssh_gssapi_client_identity(ssh_session session, gss_OID_set *valid_oids);
char *ssh_gssapi_name_to_char(gss_name_t name);
int ssh_gssapi_import_name(struct ssh_gssapi_struct *gssapi, const char *host);
OM_uint32 ssh_gssapi_init_ctx(struct ssh_gssapi_struct *gssapi,
gss_buffer_desc *input_token,
gss_buffer_desc *output_token,
OM_uint32 *ret_flags);
char *ssh_gssapi_oid_hash(ssh_string oid);
char *ssh_gssapi_kex_mechs(ssh_session session, const char *gss_algs);
int ssh_gssapi_check_client_config(ssh_session session);
#ifdef __cplusplus
}

View File

@@ -152,13 +152,14 @@ enum ssh_auth_e {
};
/* auth flags */
#define SSH_AUTH_METHOD_UNKNOWN 0x0000u
#define SSH_AUTH_METHOD_NONE 0x0001u
#define SSH_AUTH_METHOD_PASSWORD 0x0002u
#define SSH_AUTH_METHOD_PUBLICKEY 0x0004u
#define SSH_AUTH_METHOD_HOSTBASED 0x0008u
#define SSH_AUTH_METHOD_INTERACTIVE 0x0010u
#define SSH_AUTH_METHOD_GSSAPI_MIC 0x0020u
#define SSH_AUTH_METHOD_UNKNOWN 0x0000u
#define SSH_AUTH_METHOD_NONE 0x0001u
#define SSH_AUTH_METHOD_PASSWORD 0x0002u
#define SSH_AUTH_METHOD_PUBLICKEY 0x0004u
#define SSH_AUTH_METHOD_HOSTBASED 0x0008u
#define SSH_AUTH_METHOD_INTERACTIVE 0x0010u
#define SSH_AUTH_METHOD_GSSAPI_MIC 0x0020u
#define SSH_AUTH_METHOD_GSSAPI_KEYEX 0x0040u
/* messages */
enum ssh_requests_e {
@@ -429,6 +430,8 @@ enum ssh_options_e {
SSH_OPTIONS_PROXYJUMP_CB_LIST_APPEND,
SSH_OPTIONS_PKI_CONTEXT,
SSH_OPTIONS_ADDRESS_FAMILY,
SSH_OPTIONS_GSSAPI_KEY_EXCHANGE,
SSH_OPTIONS_GSSAPI_KEY_EXCHANGE_ALGS,
};
enum {

View File

@@ -59,6 +59,8 @@ enum ssh_bind_options_e {
SSH_BIND_OPTIONS_MODULI,
SSH_BIND_OPTIONS_RSA_MIN_SIZE,
SSH_BIND_OPTIONS_IMPORT_KEY_STR,
SSH_BIND_OPTIONS_GSSAPI_KEY_EXCHANGE,
SSH_BIND_OPTIONS_GSSAPI_KEY_EXCHANGE_ALGS,
};
typedef struct ssh_bind_struct* ssh_bind;

View File

@@ -67,7 +67,8 @@ enum ssh_pending_call_e {
SSH_PENDING_CALL_AUTH_AGENT,
SSH_PENDING_CALL_AUTH_KBDINT_INIT,
SSH_PENDING_CALL_AUTH_KBDINT_SEND,
SSH_PENDING_CALL_AUTH_GSSAPI_MIC
SSH_PENDING_CALL_AUTH_GSSAPI_MIC,
SSH_PENDING_CALL_AUTH_GSSAPI_KEYEX
};
/* libssh calls may block an undefined amount of time */
@@ -201,6 +202,8 @@ struct ssh_session_struct {
*/
bool first_kex_follows_guess_wrong;
ssh_string gssapi_key_exchange_mic;
ssh_buffer in_hashbuf;
ssh_buffer out_hashbuf;
struct ssh_crypto_struct *current_crypto;
@@ -265,6 +268,8 @@ struct ssh_session_struct {
char compressionlevel;
char *gss_server_identity;
char *gss_client_identity;
bool gssapi_key_exchange;
char *gssapi_key_exchange_algs;
int gss_delegate_creds;
int flags;
int exp_flags;

View File

@@ -39,6 +39,14 @@
#define SSH2_MSG_USERAUTH_GSSAPI_ERRTOK 65
#define SSH2_MSG_USERAUTH_GSSAPI_MIC 66
#define SSH2_MSG_KEXGSS_INIT 30
#define SSH2_MSG_KEXGSS_CONTINUE 31
#define SSH2_MSG_KEXGSS_COMPLETE 32
#define SSH2_MSG_KEXGSS_HOSTKEY 33
#define SSH2_MSG_KEXGSS_ERROR 34
#define SSH2_MSG_KEXGSS_GROUPREQ 40
#define SSH2_MSG_KEXGSS_GROUP 41
#define SSH2_MSG_GLOBAL_REQUEST 80
#define SSH2_MSG_REQUEST_SUCCESS 81
#define SSH2_MSG_REQUEST_FAILURE 82