- server_kexinit = kex_init(myproposal);
- client_kexinit = xmalloc(sizeof(*client_kexinit));
- buffer_init(client_kexinit);
-
- /* algorithm negotiation */
- kex_exchange_kexinit(server_kexinit, client_kexinit, cprop);
- kex = kex_choose_conf(cprop, myproposal, 1);
- for (i = 0; i < PROPOSAL_MAX; i++)
- xfree(cprop[i]);
-
-/* 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);
-
- /* XXX precompute? */
- dsa_make_key_blob(sensitive_data.dsa_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
- /* save session id := H */
- /* XXX hashlen depends on KEX */
- session_id2_len = 20;
- session_id2 = xmalloc(session_id2_len);
- memcpy(session_id2, hash, session_id2_len);
-
- /* sign H */
- /* XXX hashlen depends on KEX */
- dsa_sign(sensitive_data.dsa_host_key, &signature, &slen, hash, 20);
-
- destroy_sensitive_data();
-
- /* 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);
- xfree(server_host_key_blob);
- packet_write_wait();