1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-08-10 06:23:01 +03:00

Revert "kex: server fix for first_kex_packet_follows"

The patch breaks the client with ECDSA.

This reverts commit 5865b9436f.
This commit is contained in:
Andreas Schneider
2014-04-15 09:49:25 +02:00
parent 79d51099ac
commit e2805abbf7
4 changed files with 242 additions and 361 deletions

View File

@@ -127,15 +127,6 @@ struct ssh_session_struct {
struct ssh_agent_state_struct *agent_state;
struct ssh_auth_auto_state_struct *auth_auto_state;
/*
* RFC 4253, 7.1: if the first_kex_packet_follows flag was set in
* the received SSH_MSG_KEXINIT, but the guess was wrong, this
* field will be set such that the following guessed packet will
* be ignored. Once that packet has been received and ignored,
* this field is cleared.
*/
int first_kex_follows_guess_wrong;
ssh_buffer in_hashbuf;
ssh_buffer out_hashbuf;
struct ssh_crypto_struct *current_crypto;

View File

@@ -587,6 +587,16 @@ error:
return SSH_ERROR;
}
/*
static void sha_add(ssh_string str,SHACTX ctx){
sha1_update(ctx,str,string_len(str)+4);
#ifdef DEBUG_CRYPTO
ssh_print_hexa("partial hashed sessionid",str,string_len(str)+4);
#endif
}
*/
int make_sessionid(ssh_session session) {
ssh_string num = NULL;
ssh_string str = NULL;
@@ -606,8 +616,7 @@ int make_sessionid(ssh_session session) {
goto error;
}
rc = buffer_add_ssh_string(buf, str);
if (rc < 0) {
if (buffer_add_ssh_string(buf, str) < 0) {
goto error;
}
ssh_string_free(str);
@@ -617,8 +626,7 @@ int make_sessionid(ssh_session session) {
goto error;
}
rc = buffer_add_ssh_string(buf, str);
if (rc < 0) {
if (buffer_add_ssh_string(buf, str) < 0) {
goto error;
}
@@ -630,61 +638,41 @@ int make_sessionid(ssh_session session) {
client_hash = session->in_hashbuf;
}
/*
* Handle the two final fields for the KEXINIT message (RFC 4253 7.1):
*
* boolean first_kex_packet_follows
* uint32 0 (reserved for future extension)
*/
rc = buffer_add_u8(server_hash, 0);
if (rc < 0) {
if (buffer_add_u32(server_hash, 0) < 0) {
goto error;
}
rc = buffer_add_u32(server_hash, 0);
if (rc < 0) {
if (buffer_add_u8(server_hash, 0) < 0) {
goto error;
}
/* These fields are handled for the server case in ssh_packet_kexinit. */
if (session->client) {
rc = buffer_add_u8(client_hash, 0);
if (rc < 0) {
if (buffer_add_u32(client_hash, 0) < 0) {
goto error;
}
rc = buffer_add_u32(client_hash, 0);
if (rc < 0) {
if (buffer_add_u8(client_hash, 0) < 0) {
goto error;
}
}
len = ntohl(buffer_get_rest_len(client_hash));
rc = buffer_add_u32(buf,len);
if (rc < 0) {
if (buffer_add_u32(buf,len) < 0) {
goto error;
}
rc = ssh_buffer_add_data(buf, buffer_get_rest(client_hash),
buffer_get_rest_len(client_hash));
if (rc < 0) {
if (ssh_buffer_add_data(buf, buffer_get_rest(client_hash),
buffer_get_rest_len(client_hash)) < 0) {
goto error;
}
len = ntohl(buffer_get_rest_len(server_hash));
rc = buffer_add_u32(buf, len);
if (rc < 0) {
if (buffer_add_u32(buf, len) < 0) {
goto error;
}
rc = ssh_buffer_add_data(buf, buffer_get_rest(server_hash),
buffer_get_rest_len(server_hash));
if (rc < 0) {
if (ssh_buffer_add_data(buf, buffer_get_rest(server_hash),
buffer_get_rest_len(server_hash)) < 0) {
goto error;
}
len = ssh_string_len(session->next_crypto->server_pubkey) + 4;
rc = ssh_buffer_add_data(buf, session->next_crypto->server_pubkey, len);
if (rc < 0) {
if (ssh_buffer_add_data(buf, session->next_crypto->server_pubkey, len) < 0) {
goto error;
}
if(session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1 ||
session->next_crypto->kex_type == SSH_KEX_DH_GROUP14_SHA1) {
@@ -694,8 +682,7 @@ int make_sessionid(ssh_session session) {
}
len = ssh_string_len(num) + 4;
rc = ssh_buffer_add_data(buf, num, len);
if (rc < 0) {
if (ssh_buffer_add_data(buf, num, len) < 0) {
goto error;
}
@@ -706,8 +693,7 @@ int make_sessionid(ssh_session session) {
}
len = ssh_string_len(num) + 4;
rc = ssh_buffer_add_data(buf, num, len);
if (rc < 0) {
if (ssh_buffer_add_data(buf, num, len) < 0) {
goto error;
}
@@ -741,15 +727,13 @@ int make_sessionid(ssh_session session) {
}
#endif
}
num = make_bignum_string(session->next_crypto->k);
if (num == NULL) {
goto error;
}
len = ssh_string_len(num) + 4;
rc = ssh_buffer_add_data(buf, num, len);
if (rc < 0) {
if (ssh_buffer_add_data(buf, num, len) < 0) {
goto error;
}

View File

@@ -275,56 +275,14 @@ char *ssh_find_matching(const char *available_d, const char *preferred_d){
return NULL;
}
/**
* @internal
* @brief returns whether the first client key exchange algorithm matches
* the first server key exchange algorithm
* @returns whether the first client key exchange algorithm matches
* the first server key exchange algorithm
*/
static int is_first_kex_packet_follows_guess_wrong(const char *client_kex,
const char *server_kex) {
int is_wrong = 1;
char **server_kex_tokens = NULL;
char **client_kex_tokens = tokenize(client_kex);
if (client_kex_tokens == NULL) {
goto out;
}
if (client_kex_tokens[0] == NULL) {
goto freeout;
}
server_kex_tokens = tokenize(server_kex);
if (server_kex_tokens == NULL) {
goto freeout;
}
is_wrong = (strcmp(client_kex_tokens[0], server_kex_tokens[0]) != 0);
SAFE_FREE(server_kex_tokens[0]);
SAFE_FREE(server_kex_tokens);
freeout:
SAFE_FREE(client_kex_tokens[0]);
SAFE_FREE(client_kex_tokens);
out:
return is_wrong;
}
SSH_PACKET_CALLBACK(ssh_packet_kexinit){
int i;
int server_kex=session->server;
ssh_string str = NULL;
char *strings[KEX_METHODS_SIZE];
int rc = SSH_ERROR;
uint8_t first_kex_packet_follows = 0;
uint32_t kexinit_reserved = 0;
int i;
(void)type;
(void)user;
memset(strings, 0, sizeof(strings));
if (session->session_state == SSH_SESSION_STATE_AUTHENTICATED){
SSH_LOG(SSH_LOG_WARNING, "Other side initiating key re-exchange");
@@ -332,28 +290,23 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
ssh_set_error(session,SSH_FATAL,"SSH_KEXINIT received in wrong state");
goto error;
}
if (server_kex) {
rc = buffer_get_data(packet,session->next_crypto->client_kex.cookie, 16);
if (rc != 16) {
if (buffer_get_data(packet,session->next_crypto->client_kex.cookie,16) != 16) {
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet");
goto error;
}
rc = hashbufin_add_cookie(session, session->next_crypto->client_kex.cookie);
if (rc < 0) {
if (hashbufin_add_cookie(session, session->next_crypto->client_kex.cookie) < 0) {
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed");
goto error;
}
} else {
rc = buffer_get_data(packet,session->next_crypto->server_kex.cookie, 16);
if (rc != 16) {
if (buffer_get_data(packet,session->next_crypto->server_kex.cookie,16) != 16) {
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet");
goto error;
}
rc = hashbufin_add_cookie(session, session->next_crypto->server_kex.cookie);
if (rc < 0) {
if (hashbufin_add_cookie(session, session->next_crypto->server_kex.cookie) < 0) {
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed");
goto error;
}
@@ -365,8 +318,7 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
break;
}
rc = buffer_add_ssh_string(session->in_hashbuf, str);
if (rc < 0) {
if (buffer_add_ssh_string(session->in_hashbuf, str) < 0) {
ssh_set_error(session, SSH_FATAL, "Error adding string in hash buffer");
goto error;
}
@@ -391,47 +343,10 @@ SSH_PACKET_CALLBACK(ssh_packet_kexinit){
}
}
/*
* Handle the two final fields for the KEXINIT message (RFC 4253 7.1):
*
* boolean first_kex_packet_follows
* uint32 0 (reserved for future extension)
*
* Notably if clients set 'first_kex_packet_follows', it is expected
* that its value is included when computing the session ID (see
* 'make_sessionid').
*/
rc = buffer_get_u8(packet, &first_kex_packet_follows);
if (rc != 1) {
goto error;
}
rc = buffer_add_u8(session->in_hashbuf, first_kex_packet_follows);
if (rc < 0) {
goto error;
}
rc = buffer_add_u32(session->in_hashbuf, kexinit_reserved);
if (rc < 0) {
goto error;
}
/*
* Remember whether 'first_kex_packet_follows' was set and the client
* guess was wrong: in this case the next SSH_MSG_KEXDH_INIT message
* must be ignored.
*/
if (server_kex && first_kex_packet_follows) {
session->first_kex_follows_guess_wrong =
is_first_kex_packet_follows_guess_wrong(session->next_crypto->client_kex.methods[SSH_KEX],
session->next_crypto->server_kex.methods[SSH_KEX]);
}
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:
ssh_string_free(str);
for (i = 0; i < SSH_KEX_METHODS; i++) {

View File

@@ -174,15 +174,6 @@ SSH_PACKET_CALLBACK(ssh_packet_kexdh_init){
SSH_LOG(SSH_LOG_RARE,"Invalid state for SSH_MSG_KEXDH_INIT");
goto error;
}
/* If first_kex_packet_follows guess was wrong, ignore this message. */
if (session->first_kex_follows_guess_wrong != 0) {
SSH_LOG(SSH_LOG_RARE, "first_kex_packet_follows guess was wrong, "
"ignoring first SSH_MSG_KEXDH_INIT message");
session->first_kex_follows_guess_wrong = 0;
goto error;
}
switch(session->next_crypto->kex_type){
case SSH_KEX_DH_GROUP1_SHA1:
case SSH_KEX_DH_GROUP14_SHA1: