| 2584 |
} |
} |
| 2585 |
} |
} |
| 2586 |
else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) { |
else if (pvar->auth_state.cur_cred.method == SSH_AUTH_PAGEANT) { |
| 2587 |
int server_key_bits = BN_num_bits(pvar->crypt_state.server_key.RSA_key->n); |
int server_key_bits; |
| 2588 |
int host_key_bits = BN_num_bits(pvar->crypt_state.host_key.RSA_key->n); |
int host_key_bits; |
| 2589 |
int server_key_bytes = (server_key_bits + 7) / 8; |
int server_key_bytes; |
| 2590 |
int host_key_bytes = (host_key_bits + 7) / 8; |
int host_key_bytes; |
| 2591 |
int session_buf_len = server_key_bytes + host_key_bytes + 8; |
int session_buf_len; |
| 2592 |
char *session_buf = (char *) malloc(session_buf_len); |
char *session_buf; |
| 2593 |
unsigned char session_id[16]; |
unsigned char session_id[16]; |
| 2594 |
|
|
| 2595 |
unsigned char *hash; |
unsigned char *hash; |
| 2596 |
int pubkeylen, hashlen; |
int pubkeylen, hashlen; |
| 2597 |
|
BIGNUM *server_n, *host_n; |
| 2598 |
|
|
| 2599 |
|
RSA_get0_key(pvar->crypt_state.server_key.RSA_key, &server_n, NULL, NULL); |
| 2600 |
|
RSA_get0_key(pvar->crypt_state.host_key.RSA_key, &host_n, NULL, NULL); |
| 2601 |
|
server_key_bits = BN_num_bits(server_n); |
| 2602 |
|
host_key_bits = BN_num_bits(host_n); |
| 2603 |
|
server_key_bytes = (server_key_bits + 7) / 8; |
| 2604 |
|
host_key_bytes = (host_key_bits + 7) / 8; |
| 2605 |
|
session_buf_len = server_key_bytes + host_key_bytes + 8; |
| 2606 |
|
session_buf = (char FAR *) malloc(session_buf_len); |
| 2607 |
|
|
| 2608 |
/* Pageant にハッシュを計算してもらう */ |
/* Pageant にハッシュを計算してもらう */ |
| 2609 |
// 公開鍵の長さ |
// 公開鍵の長さ |
| 2610 |
pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey, pvar->pageant_keylistlen); |
pubkeylen = putty_get_ssh1_keylen(pvar->pageant_curkey, pvar->pageant_keylistlen); |
| 2611 |
// セッションIDを作成 |
// セッションIDを作成 |
| 2612 |
BN_bn2bin(pvar->crypt_state.host_key.RSA_key->n, session_buf); |
BN_bn2bin(host_n, session_buf); |
| 2613 |
BN_bn2bin(pvar->crypt_state.server_key.RSA_key->n, session_buf + host_key_bytes); |
BN_bn2bin(server_n, session_buf + host_key_bytes); |
| 2614 |
memcpy(session_buf + server_key_bytes + host_key_bytes, pvar->crypt_state.server_cookie, 8); |
memcpy(session_buf + server_key_bytes + host_key_bytes, pvar->crypt_state.server_cookie, 8); |
| 2615 |
MD5(session_buf, session_buf_len, session_id); |
MD5(session_buf, session_buf_len, session_id); |
| 2616 |
// ハッシュを受け取る |
// ハッシュを受け取る |
| 2636 |
|
|
| 2637 |
static void try_send_credentials(PTInstVar pvar) |
static void try_send_credentials(PTInstVar pvar) |
| 2638 |
{ |
{ |
| 2639 |
|
BIGNUM *e, *n; |
| 2640 |
|
|
| 2641 |
if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) { |
if ((pvar->ssh_state.status_flags & STATUS_DONT_SEND_CREDENTIALS) == 0) { |
| 2642 |
AUTHCred *cred = AUTH_get_cur_cred(pvar); |
AUTHCred *cred = AUTH_get_cur_cred(pvar); |
| 2643 |
static const int RSA_msgs[] = |
static const int RSA_msgs[] = |
| 2688 |
break; |
break; |
| 2689 |
} |
} |
| 2690 |
case SSH_AUTH_RSA:{ |
case SSH_AUTH_RSA:{ |
| 2691 |
int len = BN_num_bytes(cred->key_pair->rsa->n); |
int len; |
| 2692 |
unsigned char *outmsg = |
unsigned char *outmsg; |
| 2693 |
begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len); |
|
| 2694 |
|
RSA_get0_key(cred->key_pair->rsa, &n, NULL, NULL); |
| 2695 |
|
len = BN_num_bytes(n); |
| 2696 |
|
outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RSA, 2 + len); |
| 2697 |
|
|
| 2698 |
logputs(LOG_LEVEL_VERBOSE, "Trying RSA authentication..."); |
logputs(LOG_LEVEL_VERBOSE, "Trying RSA authentication..."); |
| 2699 |
|
|
| 2700 |
set_ushort16_MSBfirst(outmsg, len * 8); |
set_ushort16_MSBfirst(outmsg, len * 8); |
| 2701 |
BN_bn2bin(cred->key_pair->rsa->n, outmsg + 2); |
BN_bn2bin(n, outmsg + 2); |
| 2702 |
/* don't destroy the current credentials yet */ |
/* don't destroy the current credentials yet */ |
| 2703 |
enque_handlers(pvar, 2, RSA_msgs, RSA_handlers); |
enque_handlers(pvar, 2, RSA_msgs, RSA_handlers); |
| 2704 |
break; |
break; |
| 2705 |
} |
} |
| 2706 |
case SSH_AUTH_RHOSTS_RSA:{ |
case SSH_AUTH_RHOSTS_RSA:{ |
| 2707 |
int mod_len = BN_num_bytes(cred->key_pair->rsa->n); |
int mod_len; |
| 2708 |
int name_len = strlen(cred->rhosts_client_user); |
int name_len; |
| 2709 |
int exp_len = BN_num_bytes(cred->key_pair->rsa->e); |
int exp_len; |
| 2710 |
int index; |
int index; |
| 2711 |
unsigned char *outmsg = |
unsigned char *outmsg; |
| 2712 |
begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA, |
|
| 2713 |
12 + mod_len + name_len + exp_len); |
RSA_get0_key(cred->key_pair->rsa, &n, &e, NULL); |
| 2714 |
|
mod_len = BN_num_bytes(n); |
| 2715 |
|
name_len = strlen(cred->rhosts_client_user); |
| 2716 |
|
exp_len = BN_num_bytes(e); |
| 2717 |
|
outmsg = begin_send_packet(pvar, SSH_CMSG_AUTH_RHOSTS_RSA, |
| 2718 |
|
12 + mod_len + name_len + exp_len); |
| 2719 |
|
|
| 2720 |
logputs(LOG_LEVEL_VERBOSE, "Trying RHOSTS+RSA authentication..."); |
logputs(LOG_LEVEL_VERBOSE, "Trying RHOSTS+RSA authentication..."); |
| 2721 |
|
|
| 2725 |
|
|
| 2726 |
set_uint32(outmsg + index, 8 * mod_len); |
set_uint32(outmsg + index, 8 * mod_len); |
| 2727 |
set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len); |
set_ushort16_MSBfirst(outmsg + index + 4, 8 * exp_len); |
| 2728 |
BN_bn2bin(cred->key_pair->rsa->e, outmsg + index + 6); |
BN_bn2bin(e, outmsg + index + 6); |
| 2729 |
index += 6 + exp_len; |
index += 6 + exp_len; |
| 2730 |
|
|
| 2731 |
set_ushort16_MSBfirst(outmsg + index, 8 * mod_len); |
set_ushort16_MSBfirst(outmsg + index, 8 * mod_len); |
| 2732 |
BN_bn2bin(cred->key_pair->rsa->n, outmsg + index + 2); |
BN_bn2bin(n, outmsg + index + 2); |
| 2733 |
/* don't destroy the current credentials yet */ |
/* don't destroy the current credentials yet */ |
| 2734 |
enque_handlers(pvar, 2, RSA_msgs, RSA_handlers); |
enque_handlers(pvar, 2, RSA_msgs, RSA_handlers); |
| 2735 |
break; |
break; |
| 5427 |
buffer_t *msg = NULL; |
buffer_t *msg = NULL; |
| 5428 |
unsigned char *outmsg; |
unsigned char *outmsg; |
| 5429 |
int len; |
int len; |
| 5430 |
|
BIGNUM *pub_key; |
| 5431 |
|
|
| 5432 |
// Diffie-Hellman key agreement |
// Diffie-Hellman key agreement |
| 5433 |
switch (pvar->kex_type) { |
switch (pvar->kex_type) { |
| 5458 |
return; |
return; |
| 5459 |
} |
} |
| 5460 |
|
|
| 5461 |
buffer_put_bignum2(msg, dh->pub_key); |
DH_get0_key(dh, &pub_key, NULL); |
| 5462 |
|
buffer_put_bignum2(msg, pub_key); |
| 5463 |
|
|
| 5464 |
len = buffer_len(msg); |
len = buffer_len(msg); |
| 5465 |
outmsg = begin_send_packet(pvar, SSH2_MSG_KEXDH_INIT, len); |
outmsg = begin_send_packet(pvar, SSH2_MSG_KEXDH_INIT, len); |
| 5601 |
buffer_t *msg = NULL; |
buffer_t *msg = NULL; |
| 5602 |
unsigned char *outmsg; |
unsigned char *outmsg; |
| 5603 |
char tmpbuf[256]; |
char tmpbuf[256]; |
| 5604 |
|
BIGNUM *pub_key; |
| 5605 |
|
|
| 5606 |
logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_KEX_DH_GEX_GROUP was received."); |
logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_KEX_DH_GEX_GROUP was received."); |
| 5607 |
|
|
| 5676 |
dh = DH_new(); |
dh = DH_new(); |
| 5677 |
if (dh == NULL) |
if (dh == NULL) |
| 5678 |
goto error; |
goto error; |
| 5679 |
dh->p = p; |
DH_set0_pqg(dh, p, NULL, g); |
|
dh->g = g; |
|
| 5680 |
|
|
| 5681 |
// 秘密にすべき乱数(X)を生成 |
// 秘密にすべき乱数(X)を生成 |
| 5682 |
dh_gen_key(pvar, dh, pvar->we_need); |
dh_gen_key(pvar, dh, pvar->we_need); |
| 5686 |
if (msg == NULL) { |
if (msg == NULL) { |
| 5687 |
goto error; |
goto error; |
| 5688 |
} |
} |
| 5689 |
buffer_put_bignum2(msg, dh->pub_key); |
DH_get0_key(dh, &pub_key, NULL); |
| 5690 |
|
buffer_put_bignum2(msg, pub_key); |
| 5691 |
len = buffer_len(msg); |
len = buffer_len(msg); |
| 5692 |
outmsg = begin_send_packet(pvar, SSH2_MSG_KEX_DH_GEX_INIT, len); |
outmsg = begin_send_packet(pvar, SSH2_MSG_KEX_DH_GEX_INIT, len); |
| 5693 |
memcpy(outmsg, buffer_ptr(msg), len); |
memcpy(outmsg, buffer_ptr(msg), len); |
| 5702 |
pvar->kexdh = dh; |
pvar->kexdh = dh; |
| 5703 |
|
|
| 5704 |
{ |
{ |
| 5705 |
push_bignum_memdump("DH_GEX_GROUP", "p", dh->p); |
BIGNUM *p, *q, *pub_key; |
| 5706 |
push_bignum_memdump("DH_GEX_GROUP", "g", dh->g); |
|
| 5707 |
push_bignum_memdump("DH_GEX_GROUP", "pub_key", dh->pub_key); |
DH_get0_pqg(dh, &p, &q, NULL); |
| 5708 |
|
DH_get0_key(dh, &pub_key, NULL); |
| 5709 |
|
|
| 5710 |
|
push_bignum_memdump("DH_GEX_GROUP", "p", p); |
| 5711 |
|
push_bignum_memdump("DH_GEX_GROUP", "g", g); |
| 5712 |
|
push_bignum_memdump("DH_GEX_GROUP", "pub_key", pub_key); |
| 5713 |
} |
} |
| 5714 |
|
|
| 5715 |
SSH2_dispatch_init(2); |
SSH2_dispatch_init(2); |
| 5738 |
const EC_GROUP *group; |
const EC_GROUP *group; |
| 5739 |
buffer_t *msg = NULL; |
buffer_t *msg = NULL; |
| 5740 |
unsigned char *outmsg; |
unsigned char *outmsg; |
| 5741 |
int len; |
int len, ret; |
| 5742 |
|
char buf[128]; |
| 5743 |
|
|
| 5744 |
client_key = EC_KEY_new(); |
client_key = EC_KEY_new(); |
| 5745 |
if (client_key == NULL) { |
if (client_key == NULL) { |
| 5746 |
|
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s: EC_KEY_new was failed", __FUNCTION__); |
| 5747 |
goto error; |
goto error; |
| 5748 |
} |
} |
| 5749 |
client_key = EC_KEY_new_by_curve_name(kextype_to_cipher_nid(pvar->kex_type)); |
client_key = EC_KEY_new_by_curve_name(kextype_to_cipher_nid(pvar->kex_type)); |
| 5750 |
if (client_key == NULL) { |
if (client_key == NULL) { |
| 5751 |
|
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s: EC_KEY_new_by_curve_name was failed", __FUNCTION__); |
| 5752 |
goto error; |
goto error; |
| 5753 |
} |
} |
| 5754 |
if (EC_KEY_generate_key(client_key) != 1) { |
ret = EC_KEY_generate_key(client_key); |
| 5755 |
|
if (ret != 1) { |
| 5756 |
|
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s: EC_KEY_generate_key was failed(ret %d)", __FUNCTION__, ret); |
| 5757 |
goto error; |
goto error; |
| 5758 |
} |
} |
| 5759 |
group = EC_KEY_get0_group(client_key); |
group = EC_KEY_get0_group(client_key); |
| 5761 |
|
|
| 5762 |
msg = buffer_init(); |
msg = buffer_init(); |
| 5763 |
if (msg == NULL) { |
if (msg == NULL) { |
|
// TODO: error check |
|
| 5764 |
logprintf(LOG_LEVEL_ERROR, "%s: buffer_init returns NULL.", __FUNCTION__); |
logprintf(LOG_LEVEL_ERROR, "%s: buffer_init returns NULL.", __FUNCTION__); |
| 5765 |
return; |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s: buffer_init was failed", __FUNCTION__); |
| 5766 |
|
goto error; |
| 5767 |
} |
} |
| 5768 |
|
|
| 5769 |
buffer_put_ecpoint(msg, group, EC_KEY_get0_public_key(client_key)); |
buffer_put_ecpoint(msg, group, EC_KEY_get0_public_key(client_key)); |
| 5792 |
EC_KEY_free(client_key); |
EC_KEY_free(client_key); |
| 5793 |
buffer_free(msg); |
buffer_free(msg); |
| 5794 |
|
|
| 5795 |
notify_fatal_error(pvar, "error occurred @ SSH2_ecdh_kex_init()", TRUE); |
notify_fatal_error(pvar, buf, TRUE); |
| 5796 |
} |
} |
| 5797 |
|
|
| 5798 |
|
|
| 5838 |
if ((ret = key_verify(hostkey, signature, siglen, hash, hashlen)) != 1) { |
if ((ret = key_verify(hostkey, signature, siglen, hash, hashlen)) != 1) { |
| 5839 |
if (ret == -3 && hostkey->type == KEY_RSA) { |
if (ret == -3 && hostkey->type == KEY_RSA) { |
| 5840 |
if (!pvar->settings.EnableRsaShortKeyServer) { |
if (!pvar->settings.EnableRsaShortKeyServer) { |
| 5841 |
|
BIGNUM *n; |
| 5842 |
|
RSA_get0_key(hostkey->rsa, &n, NULL, NULL); |
| 5843 |
_snprintf_s(emsg, sizeof(emsg), _TRUNCATE, |
_snprintf_s(emsg, sizeof(emsg), _TRUNCATE, |
| 5844 |
"%s: key verify error. remote rsa key length is too short (%d-bit)", __FUNCTION__, |
"%s: key verify error. remote rsa key length is too short (%d-bit)", __FUNCTION__, |
| 5845 |
BN_num_bits(hostkey->rsa->n)); |
BN_num_bits(n)); |
| 5846 |
} |
} |
| 5847 |
else { |
else { |
| 5848 |
goto cont; |
goto cont; |
| 6060 |
int hashlen; |
int hashlen; |
| 6061 |
Key *hostkey = NULL; // hostkey |
Key *hostkey = NULL; // hostkey |
| 6062 |
BOOL result = FALSE; |
BOOL result = FALSE; |
| 6063 |
|
BIGNUM *pub_key; |
| 6064 |
|
|
| 6065 |
logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_KEXDH_REPLY is continued after known_hosts."); |
logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_KEXDH_REPLY is continued after known_hosts."); |
| 6066 |
|
|
| 6139 |
|
|
| 6140 |
// ハッシュの計算 |
// ハッシュの計算 |
| 6141 |
/* calc and verify H */ |
/* calc and verify H */ |
| 6142 |
|
DH_get0_key(pvar->kexdh, &pub_key, NULL); |
| 6143 |
hash = kex_dh_hash( |
hash = kex_dh_hash( |
| 6144 |
get_kex_algorithm_EVP_MD(pvar->kex_type), |
get_kex_algorithm_EVP_MD(pvar->kex_type), |
| 6145 |
pvar->client_version_string, |
pvar->client_version_string, |
| 6147 |
buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex), |
buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex), |
| 6148 |
buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex), |
buffer_ptr(pvar->peer_kex), buffer_len(pvar->peer_kex), |
| 6149 |
server_host_key_blob, bloblen, |
server_host_key_blob, bloblen, |
| 6150 |
pvar->kexdh->pub_key, |
pub_key, |
| 6151 |
server_public, |
server_public, |
| 6152 |
share_key, |
share_key, |
| 6153 |
&hashlen); |
&hashlen); |
| 6163 |
} |
} |
| 6164 |
|
|
| 6165 |
// TTSSHバージョン情報に表示するキービット数を求めておく |
// TTSSHバージョン情報に表示するキービット数を求めておく |
| 6166 |
pvar->client_key_bits = BN_num_bits(pvar->kexdh->pub_key); |
DH_get0_key(pvar->kexdh, &pub_key, NULL); |
| 6167 |
|
pvar->client_key_bits = BN_num_bits(pub_key); |
| 6168 |
pvar->server_key_bits = BN_num_bits(server_public); |
pvar->server_key_bits = BN_num_bits(server_public); |
| 6169 |
|
|
| 6170 |
result = ssh2_kex_finish(pvar, hash, hashlen, share_key, hostkey, signature, siglen); |
result = ssh2_kex_finish(pvar, hash, hashlen, share_key, hostkey, signature, siglen); |
| 6218 |
Key *hostkey = NULL; // hostkey |
Key *hostkey = NULL; // hostkey |
| 6219 |
BOOL result = FALSE; |
BOOL result = FALSE; |
| 6220 |
int ret; |
int ret; |
| 6221 |
|
|
| 6222 |
logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_KEX_DH_GEX_REPLY was received."); |
logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_KEX_DH_GEX_REPLY was received."); |
| 6223 |
|
|
| 6224 |
memset(&hostkey, 0, sizeof(hostkey)); |
memset(&hostkey, 0, sizeof(hostkey)); |
| 6325 |
int hashlen; |
int hashlen; |
| 6326 |
Key *hostkey = NULL; // hostkey |
Key *hostkey = NULL; // hostkey |
| 6327 |
BOOL result = FALSE; |
BOOL result = FALSE; |
| 6328 |
|
BIGNUM *p, *g; |
| 6329 |
|
BIGNUM *pub_key; |
| 6330 |
|
|
| 6331 |
logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_KEX_DH_GEX_REPLY is continued after known_hosts."); |
logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_KEX_DH_GEX_REPLY is continued after known_hosts."); |
| 6332 |
|
|
| 6411 |
|
|
| 6412 |
// ハッシュの計算 |
// ハッシュの計算 |
| 6413 |
/* calc and verify H */ |
/* calc and verify H */ |
| 6414 |
|
DH_get0_pqg(pvar->kexdh, &p, NULL, &g); |
| 6415 |
|
DH_get0_key(pvar->kexdh, &pub_key, NULL); |
| 6416 |
hash = kex_dh_gex_hash( |
hash = kex_dh_gex_hash( |
| 6417 |
get_kex_algorithm_EVP_MD(pvar->kex_type), |
get_kex_algorithm_EVP_MD(pvar->kex_type), |
| 6418 |
pvar->client_version_string, |
pvar->client_version_string, |
| 6423 |
pvar->kexgex_min, |
pvar->kexgex_min, |
| 6424 |
pvar->kexgex_bits, |
pvar->kexgex_bits, |
| 6425 |
pvar->kexgex_max, |
pvar->kexgex_max, |
| 6426 |
pvar->kexdh->p, |
p, |
| 6427 |
pvar->kexdh->g, |
g, |
| 6428 |
pvar->kexdh->pub_key, |
pub_key, |
| 6429 |
server_public, |
server_public, |
| 6430 |
share_key, |
share_key, |
| 6431 |
&hashlen); |
&hashlen); |
| 6441 |
} |
} |
| 6442 |
|
|
| 6443 |
// TTSSHバージョン情報に表示するキービット数を求めておく |
// TTSSHバージョン情報に表示するキービット数を求めておく |
| 6444 |
pvar->client_key_bits = BN_num_bits(pvar->kexdh->pub_key); |
DH_get0_key(pvar->kexdh, &pub_key, NULL); |
| 6445 |
|
pvar->client_key_bits = BN_num_bits(pub_key); |
| 6446 |
pvar->server_key_bits = BN_num_bits(server_public); |
pvar->server_key_bits = BN_num_bits(server_public); |
| 6447 |
|
|
| 6448 |
result = ssh2_kex_finish(pvar, hash, hashlen, share_key, hostkey, signature, siglen); |
result = ssh2_kex_finish(pvar, hash, hashlen, share_key, hostkey, signature, siglen); |