summaryrefslogtreecommitdiffstats
path: root/src/kex.c
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2014-04-15 09:49:25 +0200
committerAndreas Schneider <asn@cryptomilk.org>2014-04-15 09:49:25 +0200
commite2805abbf7b4976a7eeeee3a215d00bd23aa14ef (patch)
tree17ea4e189f998f257918a2651cf6e51e0ca78879 /src/kex.c
parent79d51099ac3273aa73c3bd3bd047b3fa996fef18 (diff)
downloadlibssh-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.c213
1 files changed, 64 insertions, 149 deletions
diff --git a/src/kex.c b/src/kex.c
index c5dd2130..4eb45d22 100644
--- a/src/kex.c
+++ b/src/kex.c
@@ -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) {