| 5545 |
begin_send_packet(pvar, SSH2_MSG_NEWKEYS, 0); |
begin_send_packet(pvar, SSH2_MSG_NEWKEYS, 0); |
| 5546 |
finish_send_packet(pvar); |
finish_send_packet(pvar); |
| 5547 |
|
|
| 5548 |
logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_NEWKEYS was sent at handle_SSH2_dh_kex_reply()."); |
logputs(LOG_LEVEL_VERBOSE, __FUNCTION__ ": SSH2_MSG_NEWKEYS was sent."); |
| 5549 |
|
|
| 5550 |
// SSH2_MSG_NEWKEYSを送り終わったあとにキーの設定および再設定を行う |
// SSH2_MSG_NEWKEYSを送り終わったあとにキーの設定および再設定を行う |
| 5551 |
// 送信用の暗号鍵は SSH2_MSG_NEWKEYS の送信後に、受信用のは SSH2_MSG_NEWKEYS の |
// 送信用の暗号鍵は SSH2_MSG_NEWKEYS の送信後に、受信用のは SSH2_MSG_NEWKEYS の |
| 5591 |
int offset = 0; |
int offset = 0; |
| 5592 |
char *server_host_key_blob; |
char *server_host_key_blob; |
| 5593 |
int bloblen, siglen; |
int bloblen, siglen; |
| 5594 |
BIGNUM *dh_server_pub = NULL; |
BIGNUM *server_public = NULL; |
| 5595 |
char *signature; |
char *signature; |
| 5596 |
int dh_len, share_len; |
int dh_len, share_len; |
| 5597 |
char *dh_buf = NULL; |
char *dh_buf = NULL; |
| 5599 |
char *hash; |
char *hash; |
| 5600 |
char *emsg = NULL, emsg_tmp[1024]; // error message |
char *emsg = NULL, emsg_tmp[1024]; // error message |
| 5601 |
int hashlen; |
int hashlen; |
| 5602 |
Key *hostkey; // hostkey |
Key *hostkey = NULL; // hostkey |
| 5603 |
BOOL result = FALSE; |
BOOL result = FALSE; |
| 5604 |
|
|
| 5605 |
logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_KEXDH_REPLY was received."); |
logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_KEXDH_REPLY was received."); |
| 5624 |
|
|
| 5625 |
hostkey = key_from_blob(data, bloblen); |
hostkey = key_from_blob(data, bloblen); |
| 5626 |
if (hostkey == NULL) { |
if (hostkey == NULL) { |
| 5627 |
emsg = "key_from_blob error @ handle_SSH2_dh_kex_reply()"; |
emsg = __FUNCTION__ ": key_from_blob error"; |
| 5628 |
goto error; |
goto error; |
| 5629 |
} |
} |
| 5630 |
data += bloblen; |
data += bloblen; |
| 5632 |
// known_hosts対応 (2006.3.20 yutaka) |
// known_hosts対応 (2006.3.20 yutaka) |
| 5633 |
if (hostkey->type != pvar->hostkey_type) { // ホストキーの種別比較 |
if (hostkey->type != pvar->hostkey_type) { // ホストキーの種別比較 |
| 5634 |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
| 5635 |
"type mismatch for decoded server_host_key_blob (kex:%s blob:%s) @ %s", |
"%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", __FUNCTION__, |
| 5636 |
get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type), __FUNCTION__); |
get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type)); |
| 5637 |
emsg = emsg_tmp; |
emsg = emsg_tmp; |
| 5638 |
goto error; |
goto error; |
| 5639 |
} |
} |
| 5640 |
HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, hostkey); |
HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, hostkey); |
| 5641 |
if (pvar->socket == INVALID_SOCKET) { |
if (pvar->socket == INVALID_SOCKET) { |
| 5642 |
emsg = "Server disconnected @ handle_SSH2_dh_kex_reply()"; |
emsg = __FUNCTION__ ": Server disconnected"; |
| 5643 |
goto error; |
goto error; |
| 5644 |
} |
} |
| 5645 |
|
|
| 5646 |
dh_server_pub = BN_new(); |
server_public = BN_new(); |
| 5647 |
if (dh_server_pub == NULL) { |
if (server_public == NULL) { |
| 5648 |
emsg = "Out of memory1 @ handle_SSH2_dh_kex_reply()"; |
emsg = __FUNCTION__ ": Out of memory (1)"; |
| 5649 |
goto error; |
goto error; |
| 5650 |
} |
} |
| 5651 |
|
|
| 5652 |
buffer_get_bignum2(&data, dh_server_pub); |
buffer_get_bignum2(&data, server_public); |
| 5653 |
|
|
| 5654 |
siglen = get_uint32_MSBfirst(data); |
siglen = get_uint32_MSBfirst(data); |
| 5655 |
data += 4; |
data += 4; |
| 5656 |
signature = data; |
signature = data; |
| 5657 |
data += siglen; |
data += siglen; |
| 5658 |
|
|
| 5659 |
|
push_memdump("KEXDH_REPLY", "signature", signature, siglen); |
| 5660 |
|
|
| 5661 |
// check DH public value |
// check public key |
| 5662 |
if (!dh_pub_is_valid(pvar->kexdh, dh_server_pub)) { |
if (!dh_pub_is_valid(pvar->kexdh, server_public)) { |
| 5663 |
emsg = "DH public value invalid @ handle_SSH2_dh_kex_reply()"; |
emsg = __FUNCTION__ ": invalid server public key"; |
| 5664 |
goto error; |
goto error; |
| 5665 |
} |
} |
| 5666 |
// 共通鍵の生成 |
// 共通鍵の生成 |
| 5667 |
dh_len = DH_size(pvar->kexdh); |
dh_len = DH_size(pvar->kexdh); |
| 5668 |
dh_buf = malloc(dh_len); |
dh_buf = malloc(dh_len); |
| 5669 |
if (dh_buf == NULL) { |
if (dh_buf == NULL) { |
| 5670 |
emsg = "Out of memory2 @ handle_SSH2_dh_kex_reply()"; |
emsg = __FUNCTION__ ": Out of memory (2)"; |
| 5671 |
goto error; |
goto error; |
| 5672 |
} |
} |
| 5673 |
share_len = DH_compute_key(dh_buf, dh_server_pub, pvar->kexdh); |
share_len = DH_compute_key(dh_buf, server_public, pvar->kexdh); |
| 5674 |
share_key = BN_new(); |
share_key = BN_new(); |
| 5675 |
if (share_key == NULL) { |
if (share_key == NULL) { |
| 5676 |
emsg = "Out of memory3 @ handle_SSH2_dh_kex_reply()"; |
emsg = __FUNCTION__ ": Out of memory (3)"; |
| 5677 |
goto error; |
goto error; |
| 5678 |
} |
} |
| 5679 |
// 'share_key'がサーバとクライアントで共有する鍵(G^A×B mod P)となる。 |
// 'share_key'がサーバとクライアントで共有する鍵(G^A×B mod P)となる。 |
| 5682 |
|
|
| 5683 |
// ハッシュの計算 |
// ハッシュの計算 |
| 5684 |
/* calc and verify H */ |
/* calc and verify H */ |
| 5685 |
hash = kex_dh_hash(get_kex_algorithm_EVP_MD(pvar->kex_type), |
hash = kex_dh_hash( |
| 5686 |
pvar->client_version_string, |
get_kex_algorithm_EVP_MD(pvar->kex_type), |
| 5687 |
pvar->server_version_string, |
pvar->client_version_string, |
| 5688 |
buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex), |
pvar->server_version_string, |
| 5689 |
buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex), |
buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex), |
| 5690 |
server_host_key_blob, bloblen, |
buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex), |
| 5691 |
pvar->kexdh->pub_key, |
server_host_key_blob, bloblen, |
| 5692 |
dh_server_pub, |
pvar->kexdh->pub_key, |
| 5693 |
share_key, |
server_public, |
| 5694 |
&hashlen); |
share_key, |
| 5695 |
|
&hashlen); |
| 5696 |
|
|
| 5697 |
{ |
{ |
| 5698 |
push_memdump("KEXDH_REPLY kex_dh_kex_hash", "my_kex", buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex)); |
push_memdump("KEXDH_REPLY kex_dh_kex_hash", "my_kex", buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex)); |
| 5699 |
push_memdump("KEXDH_REPLY kex_dh_kex_hash", "peer_kex", buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex)); |
push_memdump("KEXDH_REPLY kex_dh_kex_hash", "peer_kex", buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex)); |
| 5700 |
|
|
| 5701 |
push_bignum_memdump("KEXDH_REPLY kex_dh_kex_hash", "dh_server_pub", dh_server_pub); |
push_bignum_memdump("KEXDH_REPLY kex_dh_kex_hash", "server_public", server_public); |
| 5702 |
push_bignum_memdump("KEXDH_REPLY kex_dh_kex_hash", "share_key", share_key); |
push_bignum_memdump("KEXDH_REPLY kex_dh_kex_hash", "share_key", share_key); |
| 5703 |
|
|
| 5704 |
push_memdump("KEXDH_REPLY kex_dh_kex_hash", "hash", hash, hashlen); |
push_memdump("KEXDH_REPLY kex_dh_kex_hash", "hash", hash, hashlen); |
| 5705 |
} |
} |
| 5706 |
|
|
| 5707 |
// TTSSHバージョン情報に表示するキービット数を求めておく (2004.10.30 yutaka) |
// TTSSHバージョン情報に表示するキービット数を求めておく |
| 5708 |
pvar->client_key_bits = BN_num_bits(pvar->kexdh->pub_key); |
pvar->client_key_bits = BN_num_bits(pvar->kexdh->pub_key); |
| 5709 |
pvar->server_key_bits = BN_num_bits(dh_server_pub); |
pvar->server_key_bits = BN_num_bits(server_public); |
| 5710 |
|
|
| 5711 |
result = ssh2_kex_finish(pvar, hash, hashlen, share_key, hostkey, signature, siglen); |
result = ssh2_kex_finish(pvar, hash, hashlen, share_key, hostkey, signature, siglen); |
| 5712 |
|
|
| 5713 |
error: |
error: |
| 5714 |
BN_free(dh_server_pub); |
BN_free(server_public); |
| 5715 |
DH_free(pvar->kexdh); pvar->kexdh = NULL; |
DH_free(pvar->kexdh); pvar->kexdh = NULL; |
| 5716 |
key_free(hostkey); |
key_free(hostkey); |
| 5717 |
free(dh_buf); |
free(dh_buf); |
| 5724 |
} |
} |
| 5725 |
|
|
| 5726 |
|
|
|
// Diffie-Hellman Key Exchange Reply(SSH2_MSG_KEX_DH_GEX_REPLY:33) |
|
| 5727 |
// |
// |
| 5728 |
// C then computes K = f^x mod p, H = hash(V_C || |
// Diffie-Hellman Group and Key Exchange Reply(SSH2_MSG_KEX_DH_GEX_REPLY:33) |
| 5729 |
// V_S || I_C || I_S || K_S || min || n || max || p || g || e || |
// |
|
// f || K), and verifies the signature s on H. |
|
| 5730 |
static BOOL handle_SSH2_dh_gex_reply(PTInstVar pvar) |
static BOOL handle_SSH2_dh_gex_reply(PTInstVar pvar) |
| 5731 |
{ |
{ |
| 5732 |
char *data; |
char *data; |
| 5734 |
int offset = 0; |
int offset = 0; |
| 5735 |
char *server_host_key_blob; |
char *server_host_key_blob; |
| 5736 |
int bloblen, siglen; |
int bloblen, siglen; |
| 5737 |
BIGNUM *dh_server_pub = NULL; |
BIGNUM *server_public = NULL; |
| 5738 |
char *signature; |
char *signature; |
| 5739 |
int dh_len, share_len; |
int dh_len, share_len; |
| 5740 |
char *dh_buf = NULL; |
char *dh_buf = NULL; |
| 5767 |
|
|
| 5768 |
hostkey = key_from_blob(data, bloblen); |
hostkey = key_from_blob(data, bloblen); |
| 5769 |
if (hostkey == NULL) { |
if (hostkey == NULL) { |
| 5770 |
emsg = "key_from_blob error @ handle_SSH2_dh_gex_reply()"; |
emsg = __FUNCTION__ ": key_from_blob error"; |
| 5771 |
goto error; |
goto error; |
| 5772 |
} |
} |
| 5773 |
data += bloblen; |
data += bloblen; |
| 5775 |
// known_hosts対応 (2006.3.20 yutaka) |
// known_hosts対応 (2006.3.20 yutaka) |
| 5776 |
if (hostkey->type != pvar->hostkey_type) { // ホストキーの種別比較 |
if (hostkey->type != pvar->hostkey_type) { // ホストキーの種別比較 |
| 5777 |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
| 5778 |
"type mismatch for decoded server_host_key_blob (kex:%s blob:%s) @ %s", |
"%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", __FUNCTION__, |
| 5779 |
get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type), __FUNCTION__); |
get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type)); |
| 5780 |
emsg = emsg_tmp; |
emsg = emsg_tmp; |
| 5781 |
goto error; |
goto error; |
| 5782 |
} |
} |
| 5783 |
HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, hostkey); |
HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, hostkey); |
| 5784 |
if (pvar->socket == INVALID_SOCKET) { |
if (pvar->socket == INVALID_SOCKET) { |
| 5785 |
emsg = "Server disconnected @ handle_SSH2_dh_gex_reply()"; |
emsg = __FUNCTION__ ": Server disconnected"; |
| 5786 |
goto error; |
goto error; |
| 5787 |
} |
} |
| 5788 |
|
|
| 5789 |
dh_server_pub = BN_new(); |
server_public = BN_new(); |
| 5790 |
if (dh_server_pub == NULL) { |
if (server_public == NULL) { |
| 5791 |
emsg = "Out of memory1 @ handle_SSH2_dh_gex_reply()"; |
emsg = __FUNCTION__ ": Out of memory (1)"; |
| 5792 |
goto error; |
goto error; |
| 5793 |
} |
} |
| 5794 |
|
|
| 5795 |
buffer_get_bignum2(&data, dh_server_pub); |
buffer_get_bignum2(&data, server_public); |
| 5796 |
|
|
| 5797 |
siglen = get_uint32_MSBfirst(data); |
siglen = get_uint32_MSBfirst(data); |
| 5798 |
data += 4; |
data += 4; |
| 5801 |
|
|
| 5802 |
push_memdump("DH_GEX_REPLY", "signature", signature, siglen); |
push_memdump("DH_GEX_REPLY", "signature", signature, siglen); |
| 5803 |
|
|
| 5804 |
// check DH public value |
// check public key |
| 5805 |
if (!dh_pub_is_valid(pvar->kexdh, dh_server_pub)) { |
if (!dh_pub_is_valid(pvar->kexdh, server_public)) { |
| 5806 |
emsg = "DH public value invalid @ handle_SSH2_dh_gex_reply()"; |
emsg = __FUNCTION__ ": invalid server public key"; |
| 5807 |
goto error; |
goto error; |
| 5808 |
} |
} |
| 5809 |
// 共通鍵の生成 |
// 共通鍵の生成 |
| 5810 |
dh_len = DH_size(pvar->kexdh); |
dh_len = DH_size(pvar->kexdh); |
| 5811 |
dh_buf = malloc(dh_len); |
dh_buf = malloc(dh_len); |
| 5812 |
if (dh_buf == NULL) { |
if (dh_buf == NULL) { |
| 5813 |
emsg = "Out of memory2 @ handle_SSH2_dh_gex_reply()"; |
emsg = __FUNCTION__ ": Out of memory (2)"; |
| 5814 |
goto error; |
goto error; |
| 5815 |
} |
} |
| 5816 |
share_len = DH_compute_key(dh_buf, dh_server_pub, pvar->kexdh); |
share_len = DH_compute_key(dh_buf, server_public, pvar->kexdh); |
| 5817 |
share_key = BN_new(); |
share_key = BN_new(); |
| 5818 |
if (share_key == NULL) { |
if (share_key == NULL) { |
| 5819 |
emsg = "Out of memory3 @ handle_SSH2_dh_gex_reply()"; |
emsg = __FUNCTION__ ": Out of memory (3)"; |
| 5820 |
goto error; |
goto error; |
| 5821 |
} |
} |
| 5822 |
// 'share_key'がサーバとクライアントで共有する鍵(G^A×B mod P)となる。 |
// 'share_key'がサーバとクライアントで共有する鍵(G^A×B mod P)となる。 |
| 5829 |
get_kex_algorithm_EVP_MD(pvar->kex_type), |
get_kex_algorithm_EVP_MD(pvar->kex_type), |
| 5830 |
pvar->client_version_string, |
pvar->client_version_string, |
| 5831 |
pvar->server_version_string, |
pvar->server_version_string, |
| 5832 |
buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex), |
buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex), |
| 5833 |
buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex), |
buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex), |
| 5834 |
server_host_key_blob, bloblen, |
server_host_key_blob, bloblen, |
|
/////// KEXGEX |
|
| 5835 |
pvar->kexgex_min, |
pvar->kexgex_min, |
| 5836 |
pvar->kexgex_bits, |
pvar->kexgex_bits, |
| 5837 |
pvar->kexgex_max, |
pvar->kexgex_max, |
| 5838 |
pvar->kexdh->p, |
pvar->kexdh->p, |
| 5839 |
pvar->kexdh->g, |
pvar->kexdh->g, |
| 5840 |
pvar->kexdh->pub_key, |
pvar->kexdh->pub_key, |
| 5841 |
/////// KEXGEX |
server_public, |
|
dh_server_pub, |
|
| 5842 |
share_key, |
share_key, |
| 5843 |
&hashlen); |
&hashlen); |
| 5844 |
|
|
| 5846 |
push_memdump("DH_GEX_REPLY kex_dh_gex_hash", "my_kex", buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex)); |
push_memdump("DH_GEX_REPLY kex_dh_gex_hash", "my_kex", buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex)); |
| 5847 |
push_memdump("DH_GEX_REPLY kex_dh_gex_hash", "peer_kex", buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex)); |
push_memdump("DH_GEX_REPLY kex_dh_gex_hash", "peer_kex", buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex)); |
| 5848 |
|
|
| 5849 |
push_bignum_memdump("DH_GEX_REPLY kex_dh_gex_hash", "dh_server_pub", dh_server_pub); |
push_bignum_memdump("DH_GEX_REPLY kex_dh_gex_hash", "server_public", server_public); |
| 5850 |
push_bignum_memdump("DH_GEX_REPLY kex_dh_gex_hash", "share_key", share_key); |
push_bignum_memdump("DH_GEX_REPLY kex_dh_gex_hash", "share_key", share_key); |
| 5851 |
|
|
| 5852 |
push_memdump("DH_GEX_REPLY kex_dh_gex_hash", "hash", hash, hashlen); |
push_memdump("DH_GEX_REPLY kex_dh_gex_hash", "hash", hash, hashlen); |
| 5853 |
} |
} |
| 5854 |
|
|
| 5855 |
// TTSSHバージョン情報に表示するキービット数を求めておく (2004.10.30 yutaka) |
// TTSSHバージョン情報に表示するキービット数を求めておく |
| 5856 |
pvar->client_key_bits = BN_num_bits(pvar->kexdh->pub_key); |
pvar->client_key_bits = BN_num_bits(pvar->kexdh->pub_key); |
| 5857 |
pvar->server_key_bits = BN_num_bits(dh_server_pub); |
pvar->server_key_bits = BN_num_bits(server_public); |
| 5858 |
|
|
| 5859 |
result = ssh2_kex_finish(pvar, hash, hashlen, share_key, hostkey, signature, siglen); |
result = ssh2_kex_finish(pvar, hash, hashlen, share_key, hostkey, signature, siglen); |
| 5860 |
|
|
| 5861 |
error: |
error: |
| 5862 |
BN_free(dh_server_pub); |
BN_free(server_public); |
| 5863 |
DH_free(pvar->kexdh); pvar->kexdh = NULL; |
DH_free(pvar->kexdh); pvar->kexdh = NULL; |
| 5864 |
key_free(hostkey); |
key_free(hostkey); |
| 5865 |
free(dh_buf); |
free(dh_buf); |
| 5916 |
|
|
| 5917 |
hostkey = key_from_blob(data, bloblen); |
hostkey = key_from_blob(data, bloblen); |
| 5918 |
if (hostkey == NULL) { |
if (hostkey == NULL) { |
| 5919 |
emsg = "key_from_blob error @ handle_SSH2_ecdh_kex_reply()"; |
emsg = __FUNCTION__ ": key_from_blob error"; |
| 5920 |
goto error; |
goto error; |
| 5921 |
} |
} |
| 5922 |
data += bloblen; |
data += bloblen; |
| 5924 |
// known_hosts対応 (2006.3.20 yutaka) |
// known_hosts対応 (2006.3.20 yutaka) |
| 5925 |
if (hostkey->type != pvar->hostkey_type) { // ホストキーの種別比較 |
if (hostkey->type != pvar->hostkey_type) { // ホストキーの種別比較 |
| 5926 |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
| 5927 |
"type mismatch for decoded server_host_key_blob (kex:%s blob:%s) @ %s", |
"%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", __FUNCTION__, |
| 5928 |
get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type), __FUNCTION__); |
get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type)); |
| 5929 |
emsg = emsg_tmp; |
emsg = emsg_tmp; |
| 5930 |
goto error; |
goto error; |
| 5931 |
} |
} |
| 5932 |
HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, hostkey); |
HOSTS_check_host_key(pvar, pvar->ssh_state.hostname, pvar->ssh_state.tcpport, hostkey); |
| 5933 |
if (pvar->socket == INVALID_SOCKET) { |
if (pvar->socket == INVALID_SOCKET) { |
| 5934 |
emsg = "Server disconnected @ handle_SSH2_ecdh_kex_reply()"; |
emsg = __FUNCTION__ ": Server disconnected"; |
| 5935 |
goto error; |
goto error; |
| 5936 |
} |
} |
| 5937 |
|
|
| 5939 |
group = EC_KEY_get0_group(pvar->ecdh_client_key); |
group = EC_KEY_get0_group(pvar->ecdh_client_key); |
| 5940 |
server_public = EC_POINT_new(group); |
server_public = EC_POINT_new(group); |
| 5941 |
if (server_public == NULL) { |
if (server_public == NULL) { |
| 5942 |
emsg = "Out of memory1 @ handle_SSH2_ecdh_kex_reply()"; |
emsg = __FUNCTION__ ": Out of memory (1)"; |
| 5943 |
goto error; |
goto error; |
| 5944 |
} |
} |
| 5945 |
|
|
| 5954 |
|
|
| 5955 |
// check public key |
// check public key |
| 5956 |
if (key_ec_validate_public(group, server_public) != 0) { |
if (key_ec_validate_public(group, server_public) != 0) { |
| 5957 |
emsg = "ECDH invalid server public key @ handle_SSH2_ecdh_kex_reply()"; |
emsg = __FUNCTION__ ": invalid server public key"; |
| 5958 |
goto error; |
goto error; |
| 5959 |
} |
} |
| 5960 |
// 共通鍵の生成 |
// 共通鍵の生成 |
| 5961 |
ecdh_len = (EC_GROUP_get_degree(group) + 7) / 8; |
ecdh_len = (EC_GROUP_get_degree(group) + 7) / 8; |
| 5962 |
ecdh_buf = malloc(ecdh_len); |
ecdh_buf = malloc(ecdh_len); |
| 5963 |
if (ecdh_buf == NULL) { |
if (ecdh_buf == NULL) { |
| 5964 |
emsg = "Out of memory2 @ handle_SSH2_ecdh_kex_reply()"; |
emsg = __FUNCTION__ ": Out of memory (2)"; |
| 5965 |
goto error; |
goto error; |
| 5966 |
} |
} |
| 5967 |
if (ECDH_compute_key(ecdh_buf, ecdh_len, server_public, |
if (ECDH_compute_key(ecdh_buf, ecdh_len, server_public, |
| 5968 |
pvar->ecdh_client_key, NULL) != (int)ecdh_len) { |
pvar->ecdh_client_key, NULL) != (int)ecdh_len) { |
| 5969 |
emsg = "Out of memory3 @ handle_SSH2_ecdh_kex_reply()"; |
emsg = __FUNCTION__ ": Out of memory (3)"; |
| 5970 |
goto error; |
goto error; |
| 5971 |
} |
} |
| 5972 |
share_key = BN_new(); |
share_key = BN_new(); |
| 5973 |
if (share_key == NULL) { |
if (share_key == NULL) { |
| 5974 |
emsg = "Out of memory4 @ handle_SSH2_ecdh_kex_reply()"; |
emsg = __FUNCTION__ ": Out of memory (4)"; |
| 5975 |
goto error; |
goto error; |
| 5976 |
} |
} |
| 5977 |
// 'share_key'がサーバとクライアントで共有する鍵(G^A×B mod P)となる。 |
// 'share_key'がサーバとクライアントで共有する鍵(G^A×B mod P)となる。 |
| 5980 |
|
|
| 5981 |
// ハッシュの計算 |
// ハッシュの計算 |
| 5982 |
/* calc and verify H */ |
/* calc and verify H */ |
| 5983 |
hash = kex_ecdh_hash(get_kex_algorithm_EVP_MD(pvar->kex_type), |
hash = kex_ecdh_hash( |
| 5984 |
group, |
get_kex_algorithm_EVP_MD(pvar->kex_type), |
| 5985 |
pvar->client_version_string, |
group, |
| 5986 |
pvar->server_version_string, |
pvar->client_version_string, |
| 5987 |
buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex), |
pvar->server_version_string, |
| 5988 |
buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex), |
buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex), |
| 5989 |
server_host_key_blob, bloblen, |
buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex), |
| 5990 |
EC_KEY_get0_public_key(pvar->ecdh_client_key), |
server_host_key_blob, bloblen, |
| 5991 |
server_public, |
EC_KEY_get0_public_key(pvar->ecdh_client_key), |
| 5992 |
share_key, |
server_public, |
| 5993 |
&hashlen); |
share_key, |
| 5994 |
|
&hashlen); |
| 5995 |
|
|
| 5996 |
{ |
{ |
| 5997 |
push_memdump("KEX_ECDH_REPLY ecdh_kex_reply", "my_kex", buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex)); |
push_memdump("KEX_ECDH_REPLY ecdh_kex_reply", "my_kex", buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex)); |