diff --git a/include/libssh/priv.h b/include/libssh/priv.h index 31f66069..98f5e6e1 100644 --- a/include/libssh/priv.h +++ b/include/libssh/priv.h @@ -530,7 +530,7 @@ void dh_import_f(SSH_SESSION *session,STRING *f_string); void dh_import_e(SSH_SESSION *session, STRING *e_string); void dh_import_pubkey(SSH_SESSION *session,STRING *pubkey_string); void dh_build_k(SSH_SESSION *session); -void make_sessionid(SSH_SESSION *session); +int make_sessionid(SSH_SESSION *session); /* add data for the final cookie */ void hashbufin_add_cookie(SSH_SESSION *session,unsigned char *cookie); void hashbufout_add_cookie(SSH_SESSION *session); diff --git a/libssh/client.c b/libssh/client.c index e64ae021..63c5de6d 100644 --- a/libssh/client.c +++ b/libssh/client.c @@ -212,7 +212,11 @@ static int dh_handshake(SSH_SESSION *session){ return ret; } ssh_log(session, SSH_LOG_RARE, "Got SSH_MSG_NEWKEYS\n"); - make_sessionid(session); + ret = make_sessionid(session); + if (ret != SSH_OK) { + leave_function(); + return SSH_ERROR; + } /* set the cryptographic functions for the next crypto */ /* (it is needed for generate_session_keys for key lenghts) */ if(crypt_set_algorithms(session)){ diff --git a/libssh/dh.c b/libssh/dh.c index 24e7257e..48a7da8d 100644 --- a/libssh/dh.c +++ b/libssh/dh.c @@ -356,88 +356,150 @@ static void sha_add(STRING *str,SHACTX ctx){ } */ -/* TODO FIXME add memory checking and a return value */ -void make_sessionid(SSH_SESSION *session){ - SHACTX ctx; - STRING *num,*str; - BUFFER *server_hash, *client_hash; - BUFFER *buf=buffer_new(); - u32 len; - enter_function(); +int make_sessionid(SSH_SESSION *session) { + SHACTX ctx; + STRING *num = NULL; + STRING *str = NULL; + BUFFER *server_hash = NULL; + BUFFER *client_hash = NULL; + BUFFER *buf = NULL; + u32 len; + int rc = SSH_ERROR; - ctx = sha1_init(); - if (ctx == NULL) { - return; - } + enter_function(); - str=string_from_char(session->clientbanner); - buffer_add_ssh_string(buf,str); - //sha_add(str,ctx); - free(str); + ctx = sha1_init(); + if (ctx == NULL) { + return rc; + } - str=string_from_char(session->serverbanner); - buffer_add_ssh_string(buf,str); - //sha_add(str,ctx); - free(str); - if(session->client){ - server_hash=session->in_hashbuf; - client_hash=session->out_hashbuf; - } else{ - server_hash=session->out_hashbuf; - client_hash=session->in_hashbuf; - } - buffer_add_u32(server_hash,0); - buffer_add_u8(server_hash,0); - buffer_add_u32(client_hash,0); - buffer_add_u8(client_hash,0); + buf = buffer_new(); + if (buf == NULL) { + return rc; + } - len=ntohl(buffer_get_len(client_hash)); - //sha1_update(ctx,&len,4); - buffer_add_u32(buf,len); - buffer_add_data(buf,buffer_get(client_hash),buffer_get_len(client_hash)); - //sha1_update(ctx,buffer_get(client_hash),buffer_get_len(client_hash)); - buffer_free(client_hash); + str = string_from_char(session->clientbanner); + if (str == NULL) { + goto error; + } - len=ntohl(buffer_get_len(server_hash)); - buffer_add_u32(buf,len); - //sha1_update(ctx,&len,4); + if (buffer_add_ssh_string(buf, str) < 0) { + goto error; + } + string_free(str); + + str = string_from_char(session->serverbanner); + if (str == NULL) { + goto error; + } + + if (buffer_add_ssh_string(buf, str) < 0) { + goto error; + } + + if (session->client) { + server_hash = session->in_hashbuf; + client_hash = session->out_hashbuf; + } else { + server_hash = session->out_hashbuf; + client_hash = session->in_hashbuf; + } + + if (buffer_add_u32(server_hash, 0) < 0) { + goto error; + } + if (buffer_add_u8(server_hash, 0) < 0) { + goto error; + } + if (buffer_add_u32(client_hash, 0) < 0) { + goto error; + } + if (buffer_add_u8(client_hash, 0) < 0) { + goto error; + } + + len = ntohl(buffer_get_len(client_hash)); + if (buffer_add_u32(buf,len) < 0) { + goto error; + } + if (buffer_add_data(buf, buffer_get(client_hash), + buffer_get_len(client_hash)) < 0) { + goto error; + } + + len = ntohl(buffer_get_len(server_hash)); + if (buffer_add_u32(buf, len) < 0) { + goto error; + } + if (buffer_add_data(buf, buffer_get(server_hash), + buffer_get_len(server_hash)) < 0) { + goto error; + } + + len = string_len(session->next_crypto->server_pubkey) + 4; + if (buffer_add_data(buf, session->next_crypto->server_pubkey, len) < 0) { + goto error; + } + + num = make_bignum_string(session->next_crypto->e); + if (num == NULL) { + goto error; + } + + len = string_len(num) + 4; + if (buffer_add_data(buf, num, len) < 0) { + goto error; + } + + string_free(num); + num = make_bignum_string(session->next_crypto->f); + if (num == NULL) { + goto error; + } + + len = string_len(num) + 4; + if (buffer_add_data(buf, num, len) < 0) { + goto error; + } + + string_free(num); + num = make_bignum_string(session->next_crypto->k); + if (num == NULL) { + goto error; + } + + len = string_len(num) + 4; + if (buffer_add_data(buf, num, len) < 0) { + goto error; + } - buffer_add_data(buf,buffer_get(server_hash),buffer_get_len(server_hash)); -// ssh_print_hexa("server_hash",buffer_get(server_hash),buffer_get_len(server_hash)); - //sha1_update(ctx,buffer_get(server_hash),buffer_get_len(server_hash)); - buffer_free(server_hash); - - session->in_hashbuf=NULL; - session->out_hashbuf=NULL; - len=string_len(session->next_crypto->server_pubkey)+4; - buffer_add_data(buf,session->next_crypto->server_pubkey,len); -// sha1_update(ctx,session->next_crypto->server_pubkey,len); - num=make_bignum_string(session->next_crypto->e); - len=string_len(num)+4; - buffer_add_data(buf,num,len); - //sha1_update(ctx,num,len); - free(num); - num=make_bignum_string(session->next_crypto->f); - len=string_len(num)+4; - buffer_add_data(buf,num,len); -// sha1_update(ctx,num,len=(string_len(num)+4)); - free(num); - num=make_bignum_string(session->next_crypto->k); - len=string_len(num)+4; - buffer_add_data(buf,num,len); -// sha1_update(ctx,num,len); - free(num); #ifdef DEBUG_CRYPTO - ssh_print_hexa("hash buffer",buffer_get(buf),buffer_get_len(buf)); + ssh_print_hexa("hash buffer", buffer_get(buf), buffer_get_len(buf)); #endif - sha1_update(ctx,buffer_get(buf),buffer_get_len(buf)); - sha1_final(session->next_crypto->session_id,ctx); - buffer_free(buf); + + sha1_update(ctx, buffer_get(buf), buffer_get_len(buf)); + sha1_final(session->next_crypto->session_id, ctx); + #ifdef DEBUG_CRYPTO - printf("Session hash : "); - ssh_print_hexa("session id",session->next_crypto->session_id,SHA_DIGEST_LEN); + printf("Session hash: "); + ssh_print_hexa("session id", session->next_crypto->session_id, SHA_DIGEST_LEN); #endif - leave_function(); + + rc = SSH_OK; +error: + buffer_free(buf); + buffer_free(client_hash); + buffer_free(server_hash); + + session->in_hashbuf = NULL; + session->out_hashbuf = NULL; + + string_free(str); + string_free(num); + + leave_function(); + + return rc; } void hashbufout_add_cookie(SSH_SESSION *session){ diff --git a/libssh/server.c b/libssh/server.c index cd2db3e0..6aebf673 100644 --- a/libssh/server.c +++ b/libssh/server.c @@ -290,7 +290,9 @@ static int dh_handshake_server(SSH_SESSION *session){ publickey_free(pub); dh_import_pubkey(session,pubkey); dh_build_k(session); - make_sessionid(session); + if (make_sessionid(session) != SSH_OK) { + return -1; + } sign=ssh_sign_session_id(session,prv); buffer_free(buf); /* free private keys as they should not be readable past this point */