diff options
-rw-r--r-- | include/libssh/priv.h | 9 | ||||
-rw-r--r-- | libssh/client.c | 7 | ||||
-rw-r--r-- | libssh/dh.c | 89 | ||||
-rw-r--r-- | libssh/init.c | 1 | ||||
-rw-r--r-- | libssh/server.c | 4 |
5 files changed, 69 insertions, 41 deletions
diff --git a/include/libssh/priv.h b/include/libssh/priv.h index 50b82f63..4a4023bc 100644 --- a/include/libssh/priv.h +++ b/include/libssh/priv.h @@ -339,6 +339,10 @@ struct ssh_session { int dh_handshake_state; STRING *dh_server_signature; //information used by dh_handshake. + /* dh crypto */ + bignum dh_g; + bignum dh_p; + KEX server_kex; KEX client_kex; BUFFER *in_hashbuf; @@ -520,9 +524,8 @@ void dh_generate_x(SSH_SESSION *session); void dh_generate_y(SSH_SESSION *session); void dh_generate_f(SSH_SESSION *session); -/* FIXME: replace me with a thread safe function */ -void ssh_crypto_init(void); -void ssh_crypto_finalize(void); +int ssh_crypto_init(SSH_SESSION *session); +void ssh_crypto_finalize(SSH_SESSION *session); STRING *dh_get_e(SSH_SESSION *session); STRING *dh_get_f(SSH_SESSION *session); diff --git a/libssh/client.c b/libssh/client.c index 09f522ae..26277f03 100644 --- a/libssh/client.c +++ b/libssh/client.c @@ -449,7 +449,11 @@ int ssh_connect(SSH_SESSION *session) { session->alive = 0; session->client = 1; - ssh_crypto_init(); + if (ssh_crypto_init(session) < 0) { + ssh_set_error(session, SSH_FATAL, "Initializing crypto functions failed"); + leave_function(); + return SSH_ERROR; + } ssh_socket_init(); if (options->fd == -1 && options->host == NULL) { @@ -628,6 +632,7 @@ void ssh_disconnect(SSH_SESSION *session) { error: leave_function(); + ssh_crypto_finalize(session); ssh_cleanup(session); } diff --git a/libssh/dh.c b/libssh/dh.c index 1d825b2e..93bd090b 100644 --- a/libssh/dh.c +++ b/libssh/dh.c @@ -69,9 +69,6 @@ static unsigned char p_value[] = { #define P_LEN 128 /* Size in bytes of the p number */ static unsigned long g_int = 2 ; /* G is defined as 2 by the ssh2 standards */ -static bignum g; -static bignum p; -static int ssh_crypto_inited=0; int ssh_get_random(void *where, int len, int strong){ @@ -96,37 +93,51 @@ int ssh_get_random(void *where, int len, int strong){ /* it inits the values g and p which are used for DH key agreement */ -void ssh_crypto_init(void){ - if(ssh_crypto_inited == 0){ +int ssh_crypto_init(struct ssh_session *session) { #ifdef HAVE_LIBGCRYPT - gcry_check_version(NULL); - if (!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P,0)) - { - gcry_control(GCRYCTL_INIT_SECMEM, 4096); - gcry_control(GCRYCTL_INITIALIZATION_FINISHED,0); - } -#endif - g=bignum_new(); - bignum_set_word(g,g_int); + gcry_check_version(NULL); + + if (!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P,0)) { + gcry_control(GCRYCTL_INIT_SECMEM, 4096); + gcry_control(GCRYCTL_INITIALIZATION_FINISHED,0); + } +#endif + + session->dh_g = bignum_new(); + if (session->dh_g == NULL) { + return -1; + } + bignum_set_word(session->dh_g, g_int); + #ifdef HAVE_LIBGCRYPT - bignum_bin2bn(p_value,P_LEN,&p); + bignum_bin2bn(p_value, P_LEN, &session->dh_p); + if (session->dh_p == NULL) { + bignum_free(session->dh_g); + session->dh_g = NULL; + return -1; + } #elif defined HAVE_LIBCRYPTO - p=bignum_new(); - bignum_bin2bn(p_value,P_LEN,p); - OpenSSL_add_all_algorithms(); + session->dh_p = bignum_new(); + if (session->dh_p == NULL) { + bignum_free(session->dh_g); + session->dh_g = NULL; + return -1; + } + bignum_bin2bn(p_value, P_LEN, session->dh_p); + OpenSSL_add_all_algorithms(); #endif - ssh_crypto_inited++; - } + + return 0; } -void ssh_crypto_finalize(void){ - if(ssh_crypto_inited){ - bignum_free(g); - bignum_free(p); - ssh_crypto_inited=0; - } +void ssh_crypto_finalize(struct ssh_session *session) { + bignum_free(session->dh_g); + session->dh_g = NULL; + + bignum_free(session->dh_p); + session->dh_p = NULL; } - + /* prints the bignum on stderr */ void ssh_print_bignum(const char *which,bignum num){ #ifdef HAVE_LIBGCRYPT @@ -223,9 +234,11 @@ void dh_generate_e(SSH_SESSION *session){ #endif session->next_crypto->e=bignum_new(); #ifdef HAVE_LIBGCRYPT - bignum_mod_exp(session->next_crypto->e,g,session->next_crypto->x,p); + bignum_mod_exp(session->next_crypto->e, session->dh_g, + session->next_crypto->x, session->dh_p); #elif defined HAVE_LIBCRYPTO - bignum_mod_exp(session->next_crypto->e,g,session->next_crypto->x,p,ctx); + bignum_mod_exp(session->next_crypto->e, session->dh_g, + session->next_crypto->x, session->dh_p, ctx); #endif #ifdef DEBUG_CRYPTO ssh_print_bignum("e",session->next_crypto->e); @@ -241,9 +254,11 @@ void dh_generate_f(SSH_SESSION *session){ #endif session->next_crypto->f=bignum_new(); #ifdef HAVE_LIBGCRYPT - bignum_mod_exp(session->next_crypto->f,g,session->next_crypto->y,p); + bignum_mod_exp(session->next_crypto->f, session->dh_g, + session->next_crypto->y, session->dh_p); #elif defined HAVE_LIBCRYPTO - bignum_mod_exp(session->next_crypto->f,g,session->next_crypto->y,p,ctx); + bignum_mod_exp(session->next_crypto->f, session->dh_g, + session->next_crypto->y, session->dh_p, ctx); #endif #ifdef DEBUG_CRYPTO ssh_print_bignum("f",session->next_crypto->f); @@ -327,15 +342,19 @@ void dh_build_k(SSH_SESSION *session){ /* the server and clients don't use the same numbers */ #ifdef HAVE_LIBGCRYPT if(session->client){ - bignum_mod_exp(session->next_crypto->k,session->next_crypto->f,session->next_crypto->x,p); + bignum_mod_exp(session->next_crypto->k, session->next_crypto->f, + session->next_crypto->x, session->dh_p); } else { - bignum_mod_exp(session->next_crypto->k,session->next_crypto->e,session->next_crypto->y,p); + bignum_mod_exp(session->next_crypto->k, session->next_crypto->e, + session->next_crypto->y, session->dh_p); } #elif defined HAVE_LIBCRYPTO if(session->client){ - bignum_mod_exp(session->next_crypto->k,session->next_crypto->f,session->next_crypto->x,p,ctx); + bignum_mod_exp(session->next_crypto->k, session->next_crypto->f, + session->next_crypto->x, session->dh_p, ctx); } else { - bignum_mod_exp(session->next_crypto->k,session->next_crypto->e,session->next_crypto->y,p,ctx); + bignum_mod_exp(session->next_crypto->k, session->next_crypto->e, + session->next_crypto->y, session->dh_p, ctx); } #endif #ifdef DEBUG_CRYPTO diff --git a/libssh/init.c b/libssh/init.c index 6b10033b..e9c05393 100644 --- a/libssh/init.c +++ b/libssh/init.c @@ -38,7 +38,6 @@ */ int ssh_finalize(void) { - ssh_crypto_finalize(); #ifdef HAVE_LIBGCRYPT gcry_control(GCRYCTL_TERM_SECMEM); #elif defined HAVE_LIBCRYPTO diff --git a/libssh/server.c b/libssh/server.c index 358b13e7..7193a285 100644 --- a/libssh/server.c +++ b/libssh/server.c @@ -332,7 +332,9 @@ static int dh_handshake_server(SSH_SESSION *session){ /* do the banner and key exchange */ int ssh_accept(SSH_SESSION *session){ ssh_send_banner(session,1); - ssh_crypto_init(); + if (ssh_crypto_init(session) < 0) { + return -1; + } session->alive=1; session->clientbanner=ssh_get_banner(session); if (server_set_kex(session) < 0) { |