コード例 #1
0
/* Handle a diffie-hellman key exchange reply. */
void recv_msg_kexdh_reply() {

	DEF_MP_INT(dh_f);
	sign_key *hostkey = NULL;
	unsigned int type, keybloblen;
	unsigned char* keyblob = NULL;


	TRACE(("enter recv_msg_kexdh_reply"))

	if (cli_ses.kex_state != KEXDH_INIT_SENT) {
		dropbear_exit("Received out-of-order kexdhreply");
	}
	m_mp_init(&dh_f);
	type = ses.newkeys->algo_hostkey;
	TRACE(("type is %d", type))

	hostkey = new_sign_key();
	keybloblen = buf_getint(ses.payload);

	keyblob = buf_getptr(ses.payload, keybloblen);
	if (!ses.kexstate.donefirstkex) {
		/* Only makes sense the first time */
		checkhostkey(keyblob, keybloblen);
	}

	if (buf_get_pub_key(ses.payload, hostkey, &type) != DROPBEAR_SUCCESS) {
		TRACE(("failed getting pubkey"))
		dropbear_exit("Bad KEX packet");
	}

	if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) {
		TRACE(("failed getting mpint"))
		dropbear_exit("Bad KEX packet");
	}

	kexdh_comb_key(cli_ses.dh_e, cli_ses.dh_x, &dh_f, hostkey);
	mp_clear(&dh_f);
	mp_clear_multi(cli_ses.dh_e, cli_ses.dh_x, NULL);
	m_free(cli_ses.dh_e);
	m_free(cli_ses.dh_x);

	if (buf_verify(ses.payload, hostkey, ses.hash, SHA1_HASH_SIZE) 
			!= DROPBEAR_SUCCESS) {
		dropbear_exit("Bad hostkey signature");
	}

	sign_key_free(hostkey);
	hostkey = NULL;

	send_msg_newkeys();
	ses.requirenext = SSH_MSG_NEWKEYS;
	TRACE(("leave recv_msg_kexdh_init"))
}
コード例 #2
0
ファイル: cli-kex.c プロジェクト: AllardJ/Tomato
/* Handle a diffie-hellman key exchange reply. */
void recv_msg_kexdh_reply() {

	sign_key *hostkey = NULL;
	unsigned int type, keybloblen;
	unsigned char* keyblob = NULL;

	TRACE(("enter recv_msg_kexdh_reply"))

	if (cli_ses.kex_state != KEXDH_INIT_SENT) {
		dropbear_exit("Received out-of-order kexdhreply");
	}
	type = ses.newkeys->algo_hostkey;
	TRACE(("type is %d", type))

	hostkey = new_sign_key();
	keybloblen = buf_getint(ses.payload);

	keyblob = buf_getptr(ses.payload, keybloblen);
	if (!ses.kexstate.donefirstkex) {
		/* Only makes sense the first time */
		checkhostkey(keyblob, keybloblen);
	}

	if (buf_get_pub_key(ses.payload, hostkey, &type) != DROPBEAR_SUCCESS) {
		TRACE(("failed getting pubkey"))
		dropbear_exit("Bad KEX packet");
	}

	switch (ses.newkeys->algo_kex->mode) {
		case DROPBEAR_KEX_NORMAL_DH:
			{
			DEF_MP_INT(dh_f);
			m_mp_init(&dh_f);
			if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) {
				TRACE(("failed getting mpint"))
				dropbear_exit("Bad KEX packet");
			}

			kexdh_comb_key(cli_ses.dh_param, &dh_f, hostkey);
			mp_clear(&dh_f);
			}
			break;
		case DROPBEAR_KEX_ECDH:
#ifdef DROPBEAR_ECDH
			{
			buffer *ecdh_qs = buf_getstringbuf(ses.payload);
			kexecdh_comb_key(cli_ses.ecdh_param, ecdh_qs, hostkey);
			buf_free(ecdh_qs);
			}
#endif
			break;
#ifdef DROPBEAR_CURVE25519
		case DROPBEAR_KEX_CURVE25519:
			{
			buffer *ecdh_qs = buf_getstringbuf(ses.payload);
			kexcurve25519_comb_key(cli_ses.curve25519_param, ecdh_qs, hostkey);
			buf_free(ecdh_qs);
			}
#endif
			break;
	}

	if (cli_ses.dh_param) {
		free_kexdh_param(cli_ses.dh_param);
		cli_ses.dh_param = NULL;
	}
#ifdef DROPBEAR_ECDH
	if (cli_ses.ecdh_param) {
		free_kexecdh_param(cli_ses.ecdh_param);
		cli_ses.ecdh_param = NULL;
	}
#endif
#ifdef DROPBEAR_CURVE25519
	if (cli_ses.curve25519_param) {
		free_kexcurve25519_param(cli_ses.curve25519_param);
		cli_ses.curve25519_param = NULL;
	}
#endif

	cli_ses.param_kex_algo = NULL;
	if (buf_verify(ses.payload, hostkey, ses.hash) != DROPBEAR_SUCCESS) {
		dropbear_exit("Bad hostkey signature");
	}

	sign_key_free(hostkey);
	hostkey = NULL;

	send_msg_newkeys();
	ses.requirenext[0] = SSH_MSG_NEWKEYS;
	ses.requirenext[1] = 0;
	TRACE(("leave recv_msg_kexdh_init"))
}