dsa_sign(server_host_key, &signature, &slen, hash, 20);  key_free(server_host_key);
dsa_sign(sensitive_data.dsa_host_key, &signature, &slen, hash, 20);  destroy_sensitive_data();
do_ssh2_kex(){	Buffer *server_kexinit;	Buffer *client_kexinit;	int payload_len, dlen;	int slen;	unsigned int klen, kout;	char *ptr;	unsigned char *signature = NULL;	unsigned char *server_host_key_blob = NULL;	unsigned int sbloblen;	DH *dh;	BIGNUM *dh_client_pub = 0;	BIGNUM *shared_secret = 0;	int i;	unsigned char *kbuf;	unsigned char *hash;	Kex *kex;	Key *server_host_key;	char *cprop[PROPOSAL_MAX];	char *sprop[PROPOSAL_MAX];/* KEXINIT */	if (options.ciphers != NULL) {		myproposal[PROPOSAL_ENC_ALGS_CTOS] =		myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;	}	debug("Sending KEX init.");	for (i = 0; i < PROPOSAL_MAX; i++)		sprop[i] = xstrdup(myproposal[i]);	server_kexinit = kex_init(sprop);	packet_start(SSH2_MSG_KEXINIT);	packet_put_raw(buffer_ptr(server_kexinit), buffer_len(server_kexinit));		packet_send();	packet_write_wait();	debug("done");	packet_read_expect(&payload_len, SSH2_MSG_KEXINIT);	/*	 * save raw KEXINIT payload in buffer. this is used during	 * computation of the session_id and the session keys.	 */	client_kexinit = xmalloc(sizeof(*client_kexinit));	buffer_init(client_kexinit);	ptr = packet_get_raw(&payload_len);	buffer_append(client_kexinit, ptr, payload_len);	/* skip cookie */	for (i = 0; i < 16; i++)		(void) packet_get_char();	/* save kex init proposal strings */	for (i = 0; i < PROPOSAL_MAX; i++) {		cprop[i] = packet_get_string(NULL);		debug("got kexinit string: %s", cprop[i]);	}	i = (int) packet_get_char();	debug("first kex follow == %d", i);	i = packet_get_int();	debug("reserved == %d", i);	debug("done read kexinit");	kex = kex_choose_conf(cprop, sprop, 1);/* KEXDH */	debug("Wait SSH2_MSG_KEXDH_INIT.");	packet_read_expect(&payload_len, SSH2_MSG_KEXDH_INIT);	/* key, cert */	dh_client_pub = BN_new();	if (dh_client_pub == NULL)		fatal("dh_client_pub == NULL");	packet_get_bignum2(dh_client_pub, &dlen);#ifdef DEBUG_KEXDH	fprintf(stderr, "\ndh_client_pub= ");	bignum_print(dh_client_pub);	fprintf(stderr, "\n");	debug("bits %d", BN_num_bits(dh_client_pub));#endif	/* generate DH key */	dh = dh_new_group1();			/* XXX depends on 'kex' */#ifdef DEBUG_KEXDH	fprintf(stderr, "\np= ");	bignum_print(dh->p);	fprintf(stderr, "\ng= ");	bignum_print(dh->g);	fprintf(stderr, "\npub= ");	bignum_print(dh->pub_key);	fprintf(stderr, "\n");#endif	if (!dh_pub_is_valid(dh, dh_client_pub))		packet_disconnect("bad client public DH value");	klen = DH_size(dh);	kbuf = xmalloc(klen);	kout = DH_compute_key(kbuf, dh_client_pub, dh);#ifdef DEBUG_KEXDH	debug("shared secret: len %d/%d", klen, kout);	fprintf(stderr, "shared secret == ");	for (i = 0; i< kout; i++)		fprintf(stderr, "%02x", (kbuf[i])&0xff);	fprintf(stderr, "\n");#endif	shared_secret = BN_new();	BN_bin2bn(kbuf, kout, shared_secret);	memset(kbuf, 0, klen);	xfree(kbuf);	server_host_key = dsa_get_serverkey(options.dsa_key_file);	dsa_make_serverkey_blob(server_host_key, &server_host_key_blob, &sbloblen);	/* calc H */			/* XXX depends on 'kex' */	hash = kex_hash(	    client_version_string,	    server_version_string,	    buffer_ptr(client_kexinit), buffer_len(client_kexinit),	    buffer_ptr(server_kexinit), buffer_len(server_kexinit),	    (char *)server_host_key_blob, sbloblen,	    dh_client_pub,	    dh->pub_key,	    shared_secret	);	buffer_free(client_kexinit);	buffer_free(server_kexinit);	xfree(client_kexinit);	xfree(server_kexinit);#ifdef DEBUG_KEXDH	fprintf(stderr, "hash == ");	for (i = 0; i< 20; i++)		fprintf(stderr, "%02x", (hash[i])&0xff);	fprintf(stderr, "\n");#endif	/* sign H */	dsa_sign(server_host_key, &signature, &slen, hash, 20);		/* hashlen depends on KEX */	key_free(server_host_key);	/* send server hostkey, DH pubkey 'f' and singed H */	packet_start(SSH2_MSG_KEXDH_REPLY);	packet_put_string((char *)server_host_key_blob, sbloblen);	packet_put_bignum2(dh->pub_key);	// f	packet_put_string((char *)signature, slen);	packet_send();	xfree(signature);	packet_write_wait();	kex_derive_keys(kex, hash, shared_secret);	packet_set_kex(kex);	/* have keys, free DH */	DH_free(dh);	debug("send SSH2_MSG_NEWKEYS.");	packet_start(SSH2_MSG_NEWKEYS);	packet_send();	packet_write_wait();	debug("done: send SSH2_MSG_NEWKEYS.");	debug("Wait SSH2_MSG_NEWKEYS.");	packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);	debug("GOT SSH2_MSG_NEWKEYS.");#ifdef DEBUG_KEXDH	/* send 1st encrypted/maced/compressed message */	packet_start(SSH2_MSG_IGNORE);	packet_put_cstring("markus");	packet_send();	packet_write_wait();#endif	debug("done: KEX2.");}