mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-12 11:10:28 +09:00
Make dh crypto functions thread safe.
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@491 7dcaeef0-15fb-0310-b436-a5af3365683c
This commit is contained in:
@@ -339,6 +339,10 @@ struct ssh_session {
|
|||||||
int dh_handshake_state;
|
int dh_handshake_state;
|
||||||
STRING *dh_server_signature; //information used by dh_handshake.
|
STRING *dh_server_signature; //information used by dh_handshake.
|
||||||
|
|
||||||
|
/* dh crypto */
|
||||||
|
bignum dh_g;
|
||||||
|
bignum dh_p;
|
||||||
|
|
||||||
KEX server_kex;
|
KEX server_kex;
|
||||||
KEX client_kex;
|
KEX client_kex;
|
||||||
BUFFER *in_hashbuf;
|
BUFFER *in_hashbuf;
|
||||||
@@ -520,9 +524,8 @@ void dh_generate_x(SSH_SESSION *session);
|
|||||||
void dh_generate_y(SSH_SESSION *session);
|
void dh_generate_y(SSH_SESSION *session);
|
||||||
void dh_generate_f(SSH_SESSION *session);
|
void dh_generate_f(SSH_SESSION *session);
|
||||||
|
|
||||||
/* FIXME: replace me with a thread safe function */
|
int ssh_crypto_init(SSH_SESSION *session);
|
||||||
void ssh_crypto_init(void);
|
void ssh_crypto_finalize(SSH_SESSION *session);
|
||||||
void ssh_crypto_finalize(void);
|
|
||||||
|
|
||||||
STRING *dh_get_e(SSH_SESSION *session);
|
STRING *dh_get_e(SSH_SESSION *session);
|
||||||
STRING *dh_get_f(SSH_SESSION *session);
|
STRING *dh_get_f(SSH_SESSION *session);
|
||||||
|
|||||||
@@ -449,7 +449,11 @@ int ssh_connect(SSH_SESSION *session) {
|
|||||||
session->alive = 0;
|
session->alive = 0;
|
||||||
session->client = 1;
|
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();
|
ssh_socket_init();
|
||||||
|
|
||||||
if (options->fd == -1 && options->host == NULL) {
|
if (options->fd == -1 && options->host == NULL) {
|
||||||
@@ -628,6 +632,7 @@ void ssh_disconnect(SSH_SESSION *session) {
|
|||||||
|
|
||||||
error:
|
error:
|
||||||
leave_function();
|
leave_function();
|
||||||
|
ssh_crypto_finalize(session);
|
||||||
ssh_cleanup(session);
|
ssh_cleanup(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
85
libssh/dh.c
85
libssh/dh.c
@@ -69,9 +69,6 @@ static unsigned char p_value[] = {
|
|||||||
#define P_LEN 128 /* Size in bytes of the p number */
|
#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 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){
|
int ssh_get_random(void *where, int len, int strong){
|
||||||
|
|
||||||
@@ -96,35 +93,49 @@ int ssh_get_random(void *where, int len, int strong){
|
|||||||
|
|
||||||
|
|
||||||
/* it inits the values g and p which are used for DH key agreement */
|
/* it inits the values g and p which are used for DH key agreement */
|
||||||
void ssh_crypto_init(void){
|
int ssh_crypto_init(struct ssh_session *session) {
|
||||||
if(ssh_crypto_inited == 0){
|
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#ifdef HAVE_LIBGCRYPT
|
||||||
gcry_check_version(NULL);
|
gcry_check_version(NULL);
|
||||||
if (!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P,0))
|
|
||||||
{
|
if (!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P,0)) {
|
||||||
gcry_control(GCRYCTL_INIT_SECMEM, 4096);
|
gcry_control(GCRYCTL_INIT_SECMEM, 4096);
|
||||||
gcry_control(GCRYCTL_INITIALIZATION_FINISHED,0);
|
gcry_control(GCRYCTL_INITIALIZATION_FINISHED,0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
g=bignum_new();
|
|
||||||
bignum_set_word(g,g_int);
|
session->dh_g = bignum_new();
|
||||||
|
if (session->dh_g == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
bignum_set_word(session->dh_g, g_int);
|
||||||
|
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#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
|
#elif defined HAVE_LIBCRYPTO
|
||||||
p=bignum_new();
|
session->dh_p = bignum_new();
|
||||||
bignum_bin2bn(p_value,P_LEN,p);
|
if (session->dh_p == NULL) {
|
||||||
OpenSSL_add_all_algorithms();
|
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
|
#endif
|
||||||
ssh_crypto_inited++;
|
|
||||||
}
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ssh_crypto_finalize(void){
|
void ssh_crypto_finalize(struct ssh_session *session) {
|
||||||
if(ssh_crypto_inited){
|
bignum_free(session->dh_g);
|
||||||
bignum_free(g);
|
session->dh_g = NULL;
|
||||||
bignum_free(p);
|
|
||||||
ssh_crypto_inited=0;
|
bignum_free(session->dh_p);
|
||||||
}
|
session->dh_p = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prints the bignum on stderr */
|
/* prints the bignum on stderr */
|
||||||
@@ -223,9 +234,11 @@ void dh_generate_e(SSH_SESSION *session){
|
|||||||
#endif
|
#endif
|
||||||
session->next_crypto->e=bignum_new();
|
session->next_crypto->e=bignum_new();
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#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
|
#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
|
#endif
|
||||||
#ifdef DEBUG_CRYPTO
|
#ifdef DEBUG_CRYPTO
|
||||||
ssh_print_bignum("e",session->next_crypto->e);
|
ssh_print_bignum("e",session->next_crypto->e);
|
||||||
@@ -241,9 +254,11 @@ void dh_generate_f(SSH_SESSION *session){
|
|||||||
#endif
|
#endif
|
||||||
session->next_crypto->f=bignum_new();
|
session->next_crypto->f=bignum_new();
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#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
|
#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
|
#endif
|
||||||
#ifdef DEBUG_CRYPTO
|
#ifdef DEBUG_CRYPTO
|
||||||
ssh_print_bignum("f",session->next_crypto->f);
|
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 */
|
/* the server and clients don't use the same numbers */
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#ifdef HAVE_LIBGCRYPT
|
||||||
if(session->client){
|
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 {
|
} 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
|
#elif defined HAVE_LIBCRYPTO
|
||||||
if(session->client){
|
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 {
|
} 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
|
#endif
|
||||||
#ifdef DEBUG_CRYPTO
|
#ifdef DEBUG_CRYPTO
|
||||||
|
|||||||
@@ -38,7 +38,6 @@
|
|||||||
*/
|
*/
|
||||||
int ssh_finalize(void)
|
int ssh_finalize(void)
|
||||||
{
|
{
|
||||||
ssh_crypto_finalize();
|
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#ifdef HAVE_LIBGCRYPT
|
||||||
gcry_control(GCRYCTL_TERM_SECMEM);
|
gcry_control(GCRYCTL_TERM_SECMEM);
|
||||||
#elif defined HAVE_LIBCRYPTO
|
#elif defined HAVE_LIBCRYPTO
|
||||||
|
|||||||
@@ -332,7 +332,9 @@ static int dh_handshake_server(SSH_SESSION *session){
|
|||||||
/* do the banner and key exchange */
|
/* do the banner and key exchange */
|
||||||
int ssh_accept(SSH_SESSION *session){
|
int ssh_accept(SSH_SESSION *session){
|
||||||
ssh_send_banner(session,1);
|
ssh_send_banner(session,1);
|
||||||
ssh_crypto_init();
|
if (ssh_crypto_init(session) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
session->alive=1;
|
session->alive=1;
|
||||||
session->clientbanner=ssh_get_banner(session);
|
session->clientbanner=ssh_get_banner(session);
|
||||||
if (server_set_kex(session) < 0) {
|
if (server_set_kex(session) < 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user