dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20);
if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1) fatal("dsa_verify failed for server_host_key");
ssh_kex2(char *host, struct sockaddr *hostaddr){	Kex *kex;	char *cprop[PROPOSAL_MAX];	char *sprop[PROPOSAL_MAX];	Buffer *client_kexinit;	Buffer *server_kexinit;	int payload_len, dlen;	unsigned int klen, kout;	char *ptr;	char *signature = NULL;	unsigned int slen;	char *server_host_key_blob = NULL;	Key *server_host_key;	unsigned int sbloblen;	DH *dh;	BIGNUM *dh_server_pub = 0;	BIGNUM *shared_secret = 0;	int i;	unsigned char *kbuf;	unsigned char *hash;/* KEXINIT */	debug("Sending KEX init.");	if (options.ciphers != NULL) {		myproposal[PROPOSAL_ENC_ALGS_CTOS] =		myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;	} else if (	    options.cipher == SSH_CIPHER_ARCFOUR ||	    options.cipher == SSH_CIPHER_3DES_CBC ||	    options.cipher == SSH_CIPHER_CAST128_CBC ||	    options.cipher == SSH_CIPHER_BLOWFISH_CBC) {		myproposal[PROPOSAL_ENC_ALGS_CTOS] =		myproposal[PROPOSAL_ENC_ALGS_STOC] = cipher_name(options.cipher);	}	if (options.compression) {		myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib";		myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib";	} else {		myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none";		myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";	}	for (i = 0; i < PROPOSAL_MAX; i++)		cprop[i] = xstrdup(myproposal[i]);	client_kexinit = kex_init(cprop);	packet_start(SSH2_MSG_KEXINIT);	packet_put_raw(buffer_ptr(client_kexinit), buffer_len(client_kexinit));		packet_send();	packet_write_wait();	debug("done");	packet_read_expect(&payload_len, SSH2_MSG_KEXINIT);	/* save payload for session_id */	server_kexinit = xmalloc(sizeof(*server_kexinit));	buffer_init(server_kexinit);	ptr = packet_get_raw(&payload_len);	buffer_append(server_kexinit, ptr, payload_len);	/* skip cookie */	for (i = 0; i < 16; i++)		(void) packet_get_char();	/* kex init proposal strings */	for (i = 0; i < PROPOSAL_MAX; i++) {		sprop[i] = packet_get_string(NULL);		debug("got kexinit string: %s", sprop[i]);	}	i = (int) packet_get_char();	debug("first kex follow == %d", i);	i = packet_get_int();	debug("reserved == %d", i);	packet_done();	debug("done read kexinit");	kex = kex_choose_conf(cprop, sprop, 0);/* KEXDH */	debug("Sending SSH2_MSG_KEXDH_INIT.");	/* generate and send 'e', client DH public key */	dh = dh_new_group1();	packet_start(SSH2_MSG_KEXDH_INIT);	packet_put_bignum2(dh->pub_key);	packet_send();	packet_write_wait();#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");	DHparams_print_fp(stderr, dh);#endif	debug("Wait SSH2_MSG_KEXDH_REPLY.");	packet_read_expect(&payload_len, SSH2_MSG_KEXDH_REPLY);	debug("Got SSH2_MSG_KEXDH_REPLY.");	/* key, cert */	server_host_key_blob = packet_get_string(&sbloblen);	server_host_key = dsa_serverkey_from_blob(server_host_key_blob, sbloblen);	if (server_host_key == NULL)		fatal("cannot decode server_host_key_blob");	check_host_key(host, hostaddr, server_host_key);	/* DH paramter f, server public DH key */	dh_server_pub = BN_new();	if (dh_server_pub == NULL)		fatal("dh_server_pub == NULL");	packet_get_bignum2(dh_server_pub, &dlen);#ifdef DEBUG_KEXDH	fprintf(stderr, "\ndh_server_pub= ");	bignum_print(dh_server_pub);	fprintf(stderr, "\n");	debug("bits %d", BN_num_bits(dh_server_pub));#endif	/* signed H */	signature = packet_get_string(&slen);	packet_done();	if (!dh_pub_is_valid(dh, dh_server_pub))		packet_disconnect("bad server public DH value");	klen = DH_size(dh);	kbuf = xmalloc(klen);	kout = DH_compute_key(kbuf, dh_server_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);	/* calc and verify H */	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),	    server_host_key_blob, sbloblen,	    dh->pub_key,	    dh_server_pub,	    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	dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20);	key_free(server_host_key);	kex_derive_keys(kex, hash, shared_secret);	packet_set_kex(kex);	/* have keys, free DH */	DH_free(dh);	debug("Wait SSH2_MSG_NEWKEYS.");	packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);	packet_done();	debug("GOT SSH2_MSG_NEWKEYS.");	debug("send SSH2_MSG_NEWKEYS.");	packet_start(SSH2_MSG_NEWKEYS);	packet_send();	packet_write_wait();	debug("done: send 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.");}