1
1
Этот коммит содержится в:
Aris Adamantiadis 2012-12-23 23:09:50 +01:00
родитель e934ab0816
Коммит 63c3f0e736
8 изменённых файлов: 48 добавлений и 14 удалений

Просмотреть файл

@ -65,6 +65,7 @@ struct ssh_crypto_struct {
ssh_string dh_server_signature; /* information used by dh_handshake. */
size_t digest_len; /* len of all the fields below */
unsigned char *session_id;
unsigned char *secret_hash; /* Secret hash is same as session id until re-kex */
unsigned char *encryptIV;
unsigned char *decryptIV;
unsigned char *decryptkey;

Просмотреть файл

@ -66,6 +66,9 @@ enum ssh_pending_call_e {
/* libssh calls may block an undefined amount of time */
#define SSH_SESSION_FLAG_BLOCKING 1
/* Client successfully authenticated */
#define SSH_SESSION_FLAG_AUTHENTICATED 2
/* codes to use with ssh_handle_packets*() */
#define SSH_TIMEOUT_INFINITE -1
#define SSH_TIMEOUT_USER -2

Просмотреть файл

@ -252,6 +252,8 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_success){
session->auth_state=SSH_AUTH_STATE_SUCCESS;
session->session_state=SSH_SESSION_STATE_AUTHENTICATED;
session->flags |= SSH_SESSION_FLAG_AUTHENTICATED;
if(session->current_crypto && session->current_crypto->delayed_compress_out){
SSH_LOG(session, SSH_LOG_DEBUG, "Enabling delayed compression OUT");
session->current_crypto->do_compress_out=1;

Просмотреть файл

@ -409,7 +409,10 @@ static void ssh_client_connection_callback(ssh_session session){
if(session->dh_handshake_state==DH_STATE_FINISHED){
set_status(session,1.0f);
session->connected = 1;
session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED)
session->session_state = SSH_SESSION_STATE_AUTHENTICATED;
else
session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
}
break;
case SSH_SESSION_STATE_AUTHENTICATING:

Просмотреть файл

@ -788,31 +788,43 @@ int make_sessionid(ssh_session session) {
case SSH_KEX_DH_GROUP14_SHA1:
session->next_crypto->digest_len = SHA_DIGEST_LENGTH;
session->next_crypto->mac_type = SSH_MAC_SHA1;
session->next_crypto->session_id = malloc(session->next_crypto->digest_len);
if(session->next_crypto->session_id == NULL){
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
if(session->next_crypto->secret_hash == NULL){
ssh_set_error_oom(session);
goto error;
}
sha1(buffer_get_rest(buf), buffer_get_rest_len(buf),
session->next_crypto->session_id);
session->next_crypto->secret_hash);
break;
case SSH_KEX_ECDH_SHA2_NISTP256:
session->next_crypto->digest_len = SHA256_DIGEST_LENGTH;
session->next_crypto->mac_type = SSH_MAC_SHA256;
session->next_crypto->session_id = malloc(session->next_crypto->digest_len);
if(session->next_crypto->session_id == NULL){
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
if(session->next_crypto->secret_hash == NULL){
ssh_set_error_oom(session);
goto error;
}
sha256(buffer_get_rest(buf), buffer_get_rest_len(buf),
session->next_crypto->session_id);
session->next_crypto->secret_hash);
break;
}
/* During the first kex, secret hash and session ID are equal. However, after
* a key re-exchange, a new secret hash is calculated. This hash will not replace
* but complement existing session id.
*/
if (!session->next_crypto->session_id){
session->next_crypto->session_id = malloc(session->next_crypto->digest_len);
if (session->next_crypto->session_id == NULL){
ssh_set_error_oom(session);
goto error;
}
memcpy(session->next_crypto->session_id, session->next_crypto->secret_hash,
session->next_crypto->digest_len);
}
#ifdef DEBUG_CRYPTO
printf("Session hash: ");
ssh_print_hexa("session id", session->next_crypto->session_id, SHA_DIGEST_LEN);
ssh_print_hexa("secret hash", session->next_crypto->secret_hash, session->next_crypto->digest_len);
ssh_print_hexa("session id", session->next_crypto->session_id, session->next_crypto->digest_len);
#endif
rc = SSH_OK;
@ -888,7 +900,7 @@ static int generate_one_key(ssh_string k,
}
ssh_mac_update(ctx, k, ssh_string_len(k) + 4);
ssh_mac_update(ctx, crypto->session_id, crypto->digest_len);
ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len);
ssh_mac_update(ctx, &letter, 1);
ssh_mac_update(ctx, crypto->session_id, crypto->digest_len);
ssh_mac_final(output, ctx);

Просмотреть файл

@ -276,7 +276,9 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
(void)type;
(void)user;
memset(strings, 0, sizeof(strings));
if(session->session_state != SSH_SESSION_STATE_INITIAL_KEX){
if (session->session_state == SSH_SESSION_STATE_AUTHENTICATED){
ssh_log(session,SSH_LOG_WARNING, "Other side initiating key re-exchange");
} else if(session->session_state != SSH_SESSION_STATE_INITIAL_KEX){
ssh_set_error(session,SSH_FATAL,"SSH_KEXINIT received in wrong state");
goto error;
}
@ -335,6 +337,7 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
leave_function();
session->session_state=SSH_SESSION_STATE_KEXINIT_RECEIVED;
session->dh_handshake_state=DH_STATE_INIT;
session->ssh_connection_callback(session);
return SSH_PACKET_USED;
error:

Просмотреть файл

@ -179,7 +179,7 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
rc = ssh_pki_signature_verify_blob(session,
sig_blob,
key,
session->next_crypto->session_id,
session->next_crypto->secret_hash,
session->next_crypto->digest_len);
/* Set the server public key type for known host checking */
session->next_crypto->server_pubkey_type = key->type_c;
@ -210,6 +210,13 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
ssh_set_error_oom(session);
goto error;
}
session->next_crypto->session_id = malloc(session->current_crypto->digest_len);
if (session->next_crypto->session_id == NULL) {
ssh_set_error_oom(session);
goto error;
}
memcpy(session->next_crypto->session_id, session->current_crypto->session_id,
session->current_crypto->digest_len);
}
session->dh_handshake_state = DH_STATE_FINISHED;
session->ssh_connection_callback(session);

Просмотреть файл

@ -121,7 +121,10 @@ void crypto_free(struct ssh_crypto_struct *crypto){
memset(crypto->session_id, '\0', crypto->digest_len);
SAFE_FREE(crypto->session_id);
}
if(crypto->secret_hash != NULL){
memset(crypto->secret_hash, '\0', crypto->digest_len);
SAFE_FREE(crypto->secret_hash);
}
#ifdef WITH_ZLIB
if (crypto->compress_out_ctx &&
(deflateEnd(crypto->compress_out_ctx) != 0)) {