/** @internal * @brief launches the DH handshake state machine * @param session session handle * @returns SSH_OK or SSH_ERROR * @warning this function returning is no proof that DH handshake is * completed */ static int dh_handshake(ssh_session session) { int rc = SSH_AGAIN; enum ssh_dh_state_e next_state = DH_STATE_INIT_SENT; switch (session->dh_handshake_state) { case DH_STATE_INIT: switch(session->next_crypto->kex_type){ case SSH_KEX_DH_GROUP1_SHA1: case SSH_KEX_DH_GROUP14_SHA1: rc = ssh_client_dh_init(session); break; case SSH_KEX_DH_GROUPEX_SHA1: case SSH_KEX_DH_GROUPEX_SHA256: next_state = DH_STATE_GEX_REQUEST_SENT; rc = ssh_client_dh_gex_init(session); break; #ifdef HAVE_ECDH case SSH_KEX_ECDH_SHA2_NISTP256: rc = ssh_client_ecdh_init(session); break; #endif #ifdef HAVE_CURVE25519 case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG: rc = ssh_client_curve25519_init(session); break; #endif default: rc = SSH_ERROR; } if (rc == SSH_ERROR) { return SSH_ERROR; } session->dh_handshake_state = next_state; break; case DH_STATE_INIT_SENT: /* wait until ssh_packet_dh_reply is called */ break; case DH_STATE_GEX_REQUEST_SENT: /* wait until ssh_packet_dh_reply is called */ break; case DH_STATE_NEWKEYS_SENT: /* wait until ssh_packet_newkeys is called */ break; case DH_STATE_FINISHED: return SSH_OK; default: ssh_set_error(session, SSH_FATAL, "Invalid state in dh_handshake(): %d", session->dh_handshake_state); return SSH_ERROR; } return rc; }
/** @internal * @brief launches the DH handshake state machine * @param session session handle * @returns SSH_OK or SSH_ERROR * @warning this function returning is no proof that DH handshake is * completed */ static int dh_handshake(ssh_session session) { int rc = SSH_AGAIN; enter_function(); switch (session->dh_handshake_state) { case DH_STATE_INIT: switch(session->next_crypto->kex_type){ case SSH_KEX_DH_GROUP1_SHA1: case SSH_KEX_DH_GROUP14_SHA1: rc = ssh_client_dh_init(session); break; #ifdef HAVE_ECDH case SSH_KEX_ECDH_SHA2_NISTP256: rc = ssh_client_ecdh_init(session); break; #endif default: rc=SSH_ERROR; goto error; } if (rc == SSH_ERROR) { goto error; } session->dh_handshake_state = DH_STATE_INIT_SENT; case DH_STATE_INIT_SENT: /* wait until ssh_packet_dh_reply is called */ break; case DH_STATE_NEWKEYS_SENT: /* wait until ssh_packet_newkeys is called */ break; case DH_STATE_FINISHED: leave_function(); return SSH_OK; default: ssh_set_error(session, SSH_FATAL, "Invalid state in dh_handshake(): %d", session->dh_handshake_state); leave_function(); return SSH_ERROR; } error: leave_function(); return rc; }