diff options
Diffstat (limited to 'src/kex.c')
-rw-r--r-- | src/kex.c | 57 |
1 files changed, 41 insertions, 16 deletions
@@ -755,13 +755,29 @@ int ssh_set_client_kex(ssh_session session) return SSH_OK; } +static const char *ssh_find_aead_hmac(const char *cipher) +{ + if (cipher == NULL) { + return NULL; + } else if (strcmp(cipher, "chacha20-poly1305@openssh.com") == 0) { + return "aead-poly1305"; + } else if (strcmp(cipher, "aes256-gcm@openssh.com") == 0) { + return "aead-gcm"; + } else if (strcmp(cipher, "aes128-gcm@openssh.com") == 0) { + return "aead-gcm"; + } + return NULL; +} + /** @brief Select the different methods on basis of client's and * server's kex messages, and watches out if a match is possible. */ -int ssh_kex_select_methods (ssh_session session){ +int ssh_kex_select_methods (ssh_session session) +{ struct ssh_kex_struct *server = &session->next_crypto->server_kex; struct ssh_kex_struct *client = &session->next_crypto->client_kex; char *ext_start = NULL; + const char *aead_hmac = NULL; int i; /* Here we should drop the ext-info-c from the list so we avoid matching. @@ -773,7 +789,15 @@ int ssh_kex_select_methods (ssh_session session){ for (i = 0; i < SSH_KEX_METHODS; i++) { session->next_crypto->kex_methods[i]=ssh_find_matching(server->methods[i],client->methods[i]); - if(session->next_crypto->kex_methods[i] == NULL && i < SSH_LANG_C_S){ + + if (i == SSH_MAC_C_S || i == SSH_MAC_S_C) { + aead_hmac = ssh_find_aead_hmac(session->next_crypto->kex_methods[i-2]); + if (aead_hmac) { + free(session->next_crypto->kex_methods[i]); + session->next_crypto->kex_methods[i] = strdup(aead_hmac); + } + } + if (session->next_crypto->kex_methods[i] == NULL && i < SSH_LANG_C_S){ ssh_set_error(session,SSH_FATAL,"kex error : no match for method %s: server [%s], client [%s]", ssh_kex_descriptions[i],server->methods[i],client->methods[i]); return SSH_ERROR; @@ -782,31 +806,31 @@ int ssh_kex_select_methods (ssh_session session){ session->next_crypto->kex_methods[i] = strdup(""); } } - if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group1-sha1") == 0){ + if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group1-sha1") == 0){ session->next_crypto->kex_type=SSH_KEX_DH_GROUP1_SHA1; - } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha1") == 0){ + } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha1") == 0){ session->next_crypto->kex_type=SSH_KEX_DH_GROUP14_SHA1; - } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha256") == 0){ + } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha256") == 0){ session->next_crypto->kex_type=SSH_KEX_DH_GROUP14_SHA256; - } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group16-sha512") == 0){ + } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group16-sha512") == 0){ session->next_crypto->kex_type=SSH_KEX_DH_GROUP16_SHA512; - } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group18-sha512") == 0){ + } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group18-sha512") == 0){ session->next_crypto->kex_type=SSH_KEX_DH_GROUP18_SHA512; #ifdef WITH_GEX - } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha1") == 0){ + } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha1") == 0){ session->next_crypto->kex_type=SSH_KEX_DH_GEX_SHA1; - } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha256") == 0){ + } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha256") == 0){ session->next_crypto->kex_type=SSH_KEX_DH_GEX_SHA256; #endif /* WITH_GEX */ - } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp256") == 0){ + } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp256") == 0){ session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP256; - } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp384") == 0){ + } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp384") == 0){ session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP384; - } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp521") == 0){ + } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp521") == 0){ session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP521; - } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256@libssh.org") == 0){ + } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256@libssh.org") == 0){ session->next_crypto->kex_type=SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG; - } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256") == 0){ + } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256") == 0){ session->next_crypto->kex_type=SSH_KEX_CURVE25519_SHA256; } SSH_LOG(SSH_LOG_INFO, "Negotiated %s,%s,%s,%s,%s,%s,%s,%s,%s,%s", @@ -826,7 +850,8 @@ int ssh_kex_select_methods (ssh_session session){ /* this function only sends the predefined set of kex methods */ -int ssh_send_kex(ssh_session session, int server_kex) { +int ssh_send_kex(ssh_session session, int server_kex) +{ struct ssh_kex_struct *kex = (server_kex ? &session->next_crypto->server_kex : &session->next_crypto->client_kex); ssh_string str = NULL; @@ -1043,7 +1068,7 @@ int ssh_make_sessionid(ssh_session session) ssh_buffer_get(server_hash), server_pubkey_blob); SSH_STRING_FREE(server_pubkey_blob); - if(rc != SSH_OK){ + if (rc != SSH_OK){ goto error; } |