aboutsummaryrefslogtreecommitdiff
path: root/libssh
diff options
context:
space:
mode:
authorAndreas Schneider <mail@cynapses.org>2009-04-16 12:08:11 +0000
committerAndreas Schneider <mail@cynapses.org>2009-04-16 12:08:11 +0000
commit24fc1b2028ed03ac7355c05ad2c93d81f0d5497a (patch)
tree7668ab141dc294d13d1ed43d300bbb3a219ab667 /libssh
parentc608883205b986e8c5192919e7c1f44715b5bb31 (diff)
downloadlibssh-24fc1b2028ed03ac7355c05ad2c93d81f0d5497a.tar.gz
libssh-24fc1b2028ed03ac7355c05ad2c93d81f0d5497a.tar.xz
libssh-24fc1b2028ed03ac7355c05ad2c93d81f0d5497a.zip
Make dh crypto functions thread safe.
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@491 7dcaeef0-15fb-0310-b436-a5af3365683c
Diffstat (limited to 'libssh')
-rw-r--r--libssh/client.c7
-rw-r--r--libssh/dh.c89
-rw-r--r--libssh/init.c1
-rw-r--r--libssh/server.c4
4 files changed, 63 insertions, 38 deletions
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) {