diff options
| author | Andreas Schneider <asn@cryptomilk.org> | 2014-04-15 09:49:25 +0200 |
|---|---|---|
| committer | Andreas Schneider <asn@cryptomilk.org> | 2014-04-15 09:49:25 +0200 |
| commit | e2805abbf7b4976a7eeeee3a215d00bd23aa14ef (patch) | |
| tree | 17ea4e189f998f257918a2651cf6e51e0ca78879 /src/kex.c | |
| parent | 79d51099ac3273aa73c3bd3bd047b3fa996fef18 (diff) | |
| download | libssh-e2805abbf7b4976a7eeeee3a215d00bd23aa14ef.tar.gz libssh-e2805abbf7b4976a7eeeee3a215d00bd23aa14ef.tar.xz libssh-e2805abbf7b4976a7eeeee3a215d00bd23aa14ef.zip | |
Revert "kex: server fix for first_kex_packet_follows"
The patch breaks the client with ECDSA.
This reverts commit 5865b9436fda96ac9fc7c18e4dffe5fb12dcc515.
Diffstat (limited to 'src/kex.c')
| -rw-r--r-- | src/kex.c | 213 |
1 files changed, 64 insertions, 149 deletions
@@ -275,172 +275,87 @@ 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; - - (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"); - } else if(session->session_state != SSH_SESSION_STATE_INITIAL_KEX){ - 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) { - 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) { - 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) { - 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) { - ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed"); - goto error; - } - } + int server_kex=session->server; + ssh_string str = NULL; + char *strings[KEX_METHODS_SIZE]; + int i; - for (i = 0; i < KEX_METHODS_SIZE; i++) { - str = buffer_get_ssh_string(packet); - if (str == NULL) { - break; - } + (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"); + } else if(session->session_state != SSH_SESSION_STATE_INITIAL_KEX){ + ssh_set_error(session,SSH_FATAL,"SSH_KEXINIT received in wrong state"); + goto error; + } + if (server_kex) { + 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 = buffer_add_ssh_string(session->in_hashbuf, str); - if (rc < 0) { - ssh_set_error(session, SSH_FATAL, "Error adding string in hash buffer"); - goto error; - } + 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 { + 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; + } - strings[i] = ssh_string_to_char(str); - if (strings[i] == NULL) { - ssh_set_error_oom(session); - goto error; - } - ssh_string_free(str); - str = NULL; - } + 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; + } + } - /* copy the server kex info into an array of strings */ - if (server_kex) { - for (i = 0; i < SSH_KEX_METHODS; i++) { - session->next_crypto->client_kex.methods[i] = strings[i]; - } - } else { /* client */ - for (i = 0; i < SSH_KEX_METHODS; i++) { - session->next_crypto->server_kex.methods[i] = strings[i]; - } + for (i = 0; i < KEX_METHODS_SIZE; i++) { + str = buffer_get_ssh_string(packet); + if (str == NULL) { + break; } - /* - * 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; + if (buffer_add_ssh_string(session->in_hashbuf, str) < 0) { + ssh_set_error(session, SSH_FATAL, "Error adding string in hash buffer"); + goto error; } - rc = buffer_add_u8(session->in_hashbuf, first_kex_packet_follows); - if (rc < 0) { - goto error; + strings[i] = ssh_string_to_char(str); + if (strings[i] == NULL) { + ssh_set_error_oom(session); + goto error; } + ssh_string_free(str); + str = NULL; + } - rc = buffer_add_u32(session->in_hashbuf, kexinit_reserved); - if (rc < 0) { - goto error; + /* copy the server kex info into an array of strings */ + if (server_kex) { + for (i = 0; i < SSH_KEX_METHODS; i++) { + session->next_crypto->client_kex.methods[i] = strings[i]; } - - /* - * 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]); + } else { /* client */ + for (i = 0; i < SSH_KEX_METHODS; i++) { + session->next_crypto->server_kex.methods[i] = strings[i]; } + } - session->session_state = SSH_SESSION_STATE_KEXINIT_RECEIVED; - session->dh_handshake_state = DH_STATE_INIT; - session->ssh_connection_callback(session); - return SSH_PACKET_USED; - + 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++) { - SAFE_FREE(strings[i]); - } + ssh_string_free(str); + for (i = 0; i < SSH_KEX_METHODS; i++) { + SAFE_FREE(strings[i]); + } - session->session_state = SSH_SESSION_STATE_ERROR; + session->session_state = SSH_SESSION_STATE_ERROR; - return SSH_PACKET_USED; + return SSH_PACKET_USED; } void ssh_list_kex(struct ssh_kex_struct *kex) { |
