| 4502 |
pvar->kex_type = KEX_DH_GRP14_SHA1; |
pvar->kex_type = KEX_DH_GRP14_SHA1; |
| 4503 |
} else if (strcmp(str_kextype, KEX_DH1) == 0) { |
} else if (strcmp(str_kextype, KEX_DH1) == 0) { |
| 4504 |
pvar->kex_type = KEX_DH_GRP1_SHA1; |
pvar->kex_type = KEX_DH_GRP1_SHA1; |
| 4505 |
} else if (strcmp(str_kextype, KEX_DHGEX) == 0) { |
} else if (strcmp(str_kextype, KEX_DHGEX_SHA1) == 0) { |
| 4506 |
pvar->kex_type = KEX_DH_GEX_SHA1; |
pvar->kex_type = KEX_DH_GEX_SHA1; |
| 4507 |
|
} else if (strcmp(str_kextype, KEX_DHGEX_SHA256) == 0) { |
| 4508 |
|
pvar->kex_type = KEX_DH_GEX_SHA256; |
| 4509 |
} |
} |
| 4510 |
|
|
| 4511 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "KEX algorithm: %s", str_kextype); |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "KEX algorithm: %s", str_kextype); |
| 4685 |
} |
} |
| 4686 |
|
|
| 4687 |
// send DH kex init |
// send DH kex init |
| 4688 |
if (pvar->kex_type == KEX_DH_GRP1_SHA1) { |
switch (pvar->kex_type) { |
| 4689 |
SSH2_dh_kex_init(pvar); |
case KEX_DH_GRP1_SHA1: |
| 4690 |
|
case KEX_DH_GRP14_SHA1: |
| 4691 |
} else if (pvar->kex_type == KEX_DH_GRP14_SHA1) { |
SSH2_dh_kex_init(pvar); |
| 4692 |
SSH2_dh_kex_init(pvar); |
break; |
| 4693 |
|
case KEX_DH_GEX_SHA1: |
| 4694 |
} else if (pvar->kex_type == KEX_DH_GEX_SHA1) { |
case KEX_DH_GEX_SHA256: |
| 4695 |
SSH2_dh_gex_kex_init(pvar); |
SSH2_dh_gex_kex_init(pvar); |
| 4696 |
|
break; |
| 4697 |
|
default: |
| 4698 |
|
// TODO |
| 4699 |
|
break; |
| 4700 |
} |
} |
| 4701 |
|
|
| 4702 |
return TRUE; |
return TRUE; |
| 5081 |
|
|
| 5082 |
|
|
| 5083 |
static u_char *derive_key(int id, int need, u_char *hash, BIGNUM *shared_secret, |
static u_char *derive_key(int id, int need, u_char *hash, BIGNUM *shared_secret, |
| 5084 |
char *session_id, int session_id_len) |
char *session_id, int session_id_len, |
| 5085 |
|
enum kex_exchange kex_type) |
| 5086 |
{ |
{ |
| 5087 |
buffer_t *b; |
buffer_t *b; |
| 5088 |
const EVP_MD *evp_md = EVP_sha1(); |
const EVP_MD *evp_md; |
| 5089 |
EVP_MD_CTX md; |
EVP_MD_CTX md; |
| 5090 |
char c = id; |
char c = id; |
| 5091 |
int have; |
int have; |
| 5092 |
int mdsz = EVP_MD_size(evp_md); // 20bytes(160bit) |
int mdsz; |
| 5093 |
u_char *digest = malloc(roundup(need, mdsz)); |
u_char *digest; |
| 5094 |
|
|
| 5095 |
|
if (kex_type == KEX_DH_GEX_SHA256) { |
| 5096 |
|
evp_md = EVP_sha256(); |
| 5097 |
|
} |
| 5098 |
|
else { |
| 5099 |
|
evp_md = EVP_sha1(); |
| 5100 |
|
} |
| 5101 |
|
mdsz = EVP_MD_size(evp_md); |
| 5102 |
|
digest = malloc(roundup(need, mdsz)); |
| 5103 |
|
|
| 5104 |
if (digest == NULL) |
if (digest == NULL) |
| 5105 |
goto skip; |
goto skip; |
| 5164 |
int i, mode, ctos; |
int i, mode, ctos; |
| 5165 |
|
|
| 5166 |
for (i = 0; i < NKEYS; i++) { |
for (i = 0; i < NKEYS; i++) { |
| 5167 |
keys[i] = derive_key('A'+i, need, hash, shared_secret, session_id, session_id_len); |
keys[i] = derive_key('A'+i, need, hash, shared_secret, session_id, session_id_len, pvar->kex_type); |
| 5168 |
//debug_print(i, keys[i], need); |
//debug_print(i, keys[i], need); |
| 5169 |
} |
} |
| 5170 |
|
|
| 5427 |
memset(sigblob, 0, diff); |
memset(sigblob, 0, diff); |
| 5428 |
len = modlen; |
len = modlen; |
| 5429 |
} |
} |
| 5430 |
|
|
| 5431 |
|
/* sha1 the data */ |
| 5432 |
// nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; |
// nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1; |
| 5433 |
nid = NID_sha1; |
nid = NID_sha1; |
| 5434 |
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { |
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) { |
| 6215 |
|
|
| 6216 |
|
|
| 6217 |
|
|
| 6218 |
// SHA-1(160bit)を求める |
// SHA-1(160bit)/SHA-256(256bit)を求める |
| 6219 |
static unsigned char *kex_dh_gex_hash(char *client_version_string, |
static unsigned char *kex_dh_gex_hash(char *client_version_string, |
| 6220 |
char *server_version_string, |
char *server_version_string, |
| 6221 |
char *ckexinit, int ckexinitlen, |
char *ckexinit, int ckexinitlen, |
| 6227 |
BIGNUM *kexgex_p, |
BIGNUM *kexgex_p, |
| 6228 |
BIGNUM *kexgex_g, |
BIGNUM *kexgex_g, |
| 6229 |
BIGNUM *client_dh_pub, |
BIGNUM *client_dh_pub, |
| 6230 |
|
enum kex_exchange kex_type, |
| 6231 |
BIGNUM *server_dh_pub, |
BIGNUM *server_dh_pub, |
| 6232 |
BIGNUM *shared_secret) |
BIGNUM *shared_secret) |
| 6233 |
{ |
{ |
| 6234 |
buffer_t *b; |
buffer_t *b; |
| 6235 |
static unsigned char digest[EVP_MAX_MD_SIZE]; |
static unsigned char digest[EVP_MAX_MD_SIZE]; |
| 6236 |
const EVP_MD *evp_md = EVP_sha1(); |
const EVP_MD *evp_md; |
| 6237 |
EVP_MD_CTX md; |
EVP_MD_CTX md; |
| 6238 |
|
|
| 6239 |
b = buffer_init(); |
b = buffer_init(); |
| 6266 |
// yutaka |
// yutaka |
| 6267 |
//debug_print(38, buffer_ptr(b), buffer_len(b)); |
//debug_print(38, buffer_ptr(b), buffer_len(b)); |
| 6268 |
|
|
| 6269 |
|
if (kex_type == KEX_DH_GEX_SHA256) { |
| 6270 |
|
evp_md = EVP_sha256(); |
| 6271 |
|
} |
| 6272 |
|
else { |
| 6273 |
|
evp_md = EVP_sha1(); |
| 6274 |
|
} |
| 6275 |
EVP_DigestInit(&md, evp_md); |
EVP_DigestInit(&md, evp_md); |
| 6276 |
EVP_DigestUpdate(&md, buffer_ptr(b), buffer_len(b)); |
EVP_DigestUpdate(&md, buffer_ptr(b), buffer_len(b)); |
| 6277 |
EVP_DigestFinal(&md, digest, NULL); |
EVP_DigestFinal(&md, digest, NULL); |
| 6305 |
BIGNUM *share_key = NULL; |
BIGNUM *share_key = NULL; |
| 6306 |
char *hash; |
char *hash; |
| 6307 |
char *emsg, emsg_tmp[1024]; // error message |
char *emsg, emsg_tmp[1024]; // error message |
| 6308 |
int ret; |
int ret, hashlen; |
| 6309 |
Key hostkey; // hostkey |
Key hostkey; // hostkey |
| 6310 |
|
|
| 6311 |
notify_verbose_message(pvar, "SSH2_MSG_KEX_DH_GEX_REPLY was received.", LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, "SSH2_MSG_KEX_DH_GEX_REPLY was received.", LOG_LEVEL_VERBOSE); |
| 6464 |
pvar->kexdh->p, |
pvar->kexdh->p, |
| 6465 |
pvar->kexdh->g, |
pvar->kexdh->g, |
| 6466 |
pvar->kexdh->pub_key, |
pvar->kexdh->pub_key, |
| 6467 |
|
pvar->kex_type, |
| 6468 |
/////// KEXGEX |
/////// KEXGEX |
| 6469 |
dh_server_pub, |
dh_server_pub, |
| 6470 |
share_key); |
share_key); |
| 6471 |
|
|
| 6472 |
|
if (pvar->kex_type == KEX_DH_GEX_SHA256) { |
| 6473 |
|
hashlen = 32; |
| 6474 |
|
} |
| 6475 |
|
else{ |
| 6476 |
|
hashlen = 20; |
| 6477 |
|
} |
| 6478 |
{ |
{ |
| 6479 |
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)); |
| 6480 |
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)); |
| 6482 |
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", "dh_server_pub", dh_server_pub); |
| 6483 |
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); |
| 6484 |
|
|
| 6485 |
push_memdump("DH_GEX_REPLY kex_dh_gex_hash", "hash", hash, 20); |
push_memdump("DH_GEX_REPLY kex_dh_gex_hash", "hash", hash, hashlen); |
| 6486 |
} |
} |
| 6487 |
|
|
| 6488 |
//debug_print(30, hash, 20); |
//debug_print(30, hash, hashlen); |
| 6489 |
//debug_print(31, pvar->client_version_string, strlen(pvar->client_version_string)); |
//debug_print(31, pvar->client_version_string, strlen(pvar->client_version_string)); |
| 6490 |
//debug_print(32, pvar->server_version_string, strlen(pvar->server_version_string)); |
//debug_print(32, pvar->server_version_string, strlen(pvar->server_version_string)); |
| 6491 |
//debug_print(33, buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex)); |
//debug_print(33, buffer_ptr(pvar->my_kex), buffer_len(pvar->my_kex)); |
| 6494 |
|
|
| 6495 |
// session idの保存(初回接続時のみ) |
// session idの保存(初回接続時のみ) |
| 6496 |
if (pvar->session_id == NULL) { |
if (pvar->session_id == NULL) { |
| 6497 |
pvar->session_id_len = 20; |
pvar->session_id_len = hashlen; |
| 6498 |
pvar->session_id = malloc(pvar->session_id_len); |
pvar->session_id = malloc(pvar->session_id_len); |
| 6499 |
if (pvar->session_id != NULL) { |
if (pvar->session_id != NULL) { |
| 6500 |
memcpy(pvar->session_id, hash, pvar->session_id_len); |
memcpy(pvar->session_id, hash, pvar->session_id_len); |
| 6503 |
} |
} |
| 6504 |
} |
} |
| 6505 |
|
|
| 6506 |
if ((ret = key_verify(rsa, dsa, signature, siglen, hash, 20)) != 1) { |
if ((ret = key_verify(rsa, dsa, signature, siglen, hash, hashlen)) != 1) { |
| 6507 |
if (ret == -3 && rsa != NULL) { |
if (ret == -3 && rsa != NULL) { |
| 6508 |
if (!pvar->settings.EnableRsaShortKeyServer) { |
if (!pvar->settings.EnableRsaShortKeyServer) { |
| 6509 |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, |
| 6593 |
// KEXにおいてサーバから返ってくる 31 番メッセージに対するハンドラ |
// KEXにおいてサーバから返ってくる 31 番メッセージに対するハンドラ |
| 6594 |
static BOOL handle_SSH2_dh_common_reply(PTInstVar pvar) |
static BOOL handle_SSH2_dh_common_reply(PTInstVar pvar) |
| 6595 |
{ |
{ |
| 6596 |
|
switch (pvar->kex_type) { |
| 6597 |
if (pvar->kex_type == KEX_DH_GRP1_SHA1 || pvar->kex_type == KEX_DH_GRP14_SHA1) { |
case KEX_DH_GRP1_SHA1: |
| 6598 |
handle_SSH2_dh_kex_reply(pvar); |
case KEX_DH_GRP14_SHA1: |
| 6599 |
|
handle_SSH2_dh_kex_reply(pvar); |
| 6600 |
} else if (pvar->kex_type == KEX_DH_GEX_SHA1) { |
break; |
| 6601 |
handle_SSH2_dh_gex_group(pvar); |
case KEX_DH_GEX_SHA1: |
| 6602 |
|
case KEX_DH_GEX_SHA256: |
| 6603 |
} else { |
handle_SSH2_dh_gex_group(pvar); |
| 6604 |
// TODO: |
break; |
| 6605 |
|
default: |
| 6606 |
|
// TODO |
| 6607 |
|
break; |
| 6608 |
} |
} |
| 6609 |
|
|
| 6610 |
return TRUE; |
return TRUE; |