| 4263 |
} |
} |
| 4264 |
} |
} |
| 4265 |
|
|
| 4266 |
|
static enum kex_algorithm choose_SSH2_kex_algorithm(char *server_proposal, char *my_proposal) |
| 4267 |
|
{ |
| 4268 |
|
enum kex_algorithm type = KEX_DH_UNKNOWN; |
| 4269 |
|
char str_kextype[40]; |
| 4270 |
|
ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms; |
| 4271 |
|
|
| 4272 |
|
choose_SSH2_proposal(server_proposal, my_proposal, str_kextype, sizeof(str_kextype)); |
| 4273 |
|
|
| 4274 |
|
while (ptr->name != NULL) { |
| 4275 |
|
if (strcmp(ptr->name, str_kextype) == 0) { |
| 4276 |
|
type = ptr->kextype; |
| 4277 |
|
break; |
| 4278 |
|
} |
| 4279 |
|
ptr++; |
| 4280 |
|
} |
| 4281 |
|
|
| 4282 |
|
return (type); |
| 4283 |
|
} |
| 4284 |
|
|
| 4285 |
static SSHCipher choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal) |
static SSHCipher choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal) |
| 4286 |
{ |
{ |
| 4287 |
SSHCipher cipher = SSH_CIPHER_NONE; |
SSHCipher cipher = SSH_CIPHER_NONE; |
| 4288 |
char str_cipher[16]; |
char str_cipher[16]; |
| 4289 |
|
ssh2_cipher_t *ptr = ssh2_ciphers; |
| 4290 |
|
|
| 4291 |
choose_SSH2_proposal(server_proposal, my_proposal, str_cipher, sizeof(str_cipher)); |
choose_SSH2_proposal(server_proposal, my_proposal, str_cipher, sizeof(str_cipher)); |
| 4292 |
|
|
| 4293 |
if (strcmp(str_cipher, "3des-cbc") == 0) { |
while (ptr->name != NULL) { |
| 4294 |
cipher = SSH2_CIPHER_3DES_CBC; |
if (strcmp(ptr->name, str_cipher) == 0) { |
| 4295 |
} else if (strcmp(str_cipher, "aes128-cbc") == 0) { |
cipher = ptr->cipher; |
| 4296 |
cipher = SSH2_CIPHER_AES128_CBC; |
break; |
| 4297 |
} else if (strcmp(str_cipher, "aes192-cbc") == 0) { |
} |
| 4298 |
cipher = SSH2_CIPHER_AES192_CBC; |
ptr++; |
|
} else if (strcmp(str_cipher, "aes256-cbc") == 0) { |
|
|
cipher = SSH2_CIPHER_AES256_CBC; |
|
|
} else if (strcmp(str_cipher, "blowfish-cbc") == 0) { |
|
|
cipher = SSH2_CIPHER_BLOWFISH_CBC; |
|
|
} else if (strcmp(str_cipher, "aes128-ctr") == 0) { |
|
|
cipher = SSH2_CIPHER_AES128_CTR; |
|
|
} else if (strcmp(str_cipher, "aes192-ctr") == 0) { |
|
|
cipher = SSH2_CIPHER_AES192_CTR; |
|
|
} else if (strcmp(str_cipher, "aes256-ctr") == 0) { |
|
|
cipher = SSH2_CIPHER_AES256_CTR; |
|
|
} else if (strcmp(str_cipher, "arcfour128") == 0) { |
|
|
cipher = SSH2_CIPHER_ARCFOUR128; |
|
|
} else if (strcmp(str_cipher, "arcfour256") == 0) { |
|
|
cipher = SSH2_CIPHER_ARCFOUR256; |
|
|
} else if (strcmp(str_cipher, "arcfour") == 0) { |
|
|
cipher = SSH2_CIPHER_ARCFOUR; |
|
|
} else if (strcmp(str_cipher, "cast128-cbc") == 0) { |
|
|
cipher = SSH2_CIPHER_CAST128_CBC; |
|
|
} else if (strcmp(str_cipher, "3des-ctr") == 0) { |
|
|
cipher = SSH2_CIPHER_3DES_CTR; |
|
|
} else if (strcmp(str_cipher, "blowfish-ctr") == 0) { |
|
|
cipher = SSH2_CIPHER_BLOWFISH_CTR; |
|
|
} else if (strcmp(str_cipher, "cast128-ctr") == 0) { |
|
|
cipher = SSH2_CIPHER_CAST128_CTR; |
|
| 4299 |
} |
} |
| 4300 |
|
|
| 4301 |
return (cipher); |
return (cipher); |
| 4306 |
{ |
{ |
| 4307 |
enum hmac_type type = HMAC_UNKNOWN; |
enum hmac_type type = HMAC_UNKNOWN; |
| 4308 |
char str_hmac[16]; |
char str_hmac[16]; |
| 4309 |
|
ssh2_mac_t *ptr = ssh2_macs; |
| 4310 |
|
|
| 4311 |
choose_SSH2_proposal(server_proposal, my_proposal, str_hmac, sizeof(str_hmac)); |
choose_SSH2_proposal(server_proposal, my_proposal, str_hmac, sizeof(str_hmac)); |
| 4312 |
|
|
| 4313 |
if (strcmp(str_hmac, "hmac-sha1") == 0) { |
while (ptr->name != NULL) { |
| 4314 |
type = HMAC_SHA1; |
if (strcmp(ptr->name, str_hmac) == 0) { |
| 4315 |
} else if (strcmp(str_hmac, "hmac-md5") == 0) { |
type = ptr->type; |
| 4316 |
type = HMAC_MD5; |
break; |
| 4317 |
|
} |
| 4318 |
|
ptr++; |
| 4319 |
} |
} |
| 4320 |
|
|
| 4321 |
return (type); |
return (type); |
| 4326 |
{ |
{ |
| 4327 |
enum compression_type type = COMP_UNKNOWN; |
enum compression_type type = COMP_UNKNOWN; |
| 4328 |
char str_comp[20]; |
char str_comp[20]; |
| 4329 |
|
ssh_comp_t *ptr = ssh_comps; |
| 4330 |
|
|
| 4331 |
// OpenSSH 4.3では遅延パケット圧縮("zlib@openssh.com")が新規追加されているため、 |
// OpenSSH 4.3では遅延パケット圧縮("zlib@openssh.com")が新規追加されているため、 |
| 4332 |
// マッチしないように修正した。 |
// マッチしないように修正した。 |
| 4337 |
|
|
| 4338 |
choose_SSH2_proposal(server_proposal, my_proposal, str_comp, sizeof(str_comp)); |
choose_SSH2_proposal(server_proposal, my_proposal, str_comp, sizeof(str_comp)); |
| 4339 |
|
|
| 4340 |
// support of "Compression delayed" (2006.6.23 maya) |
while (ptr->name != NULL) { |
| 4341 |
if (strcmp(str_comp, "zlib@openssh.com") == 0) { |
if (strcmp(ptr->name, str_comp) == 0) { |
| 4342 |
type = COMP_DELAYED; |
type = ptr->type; |
| 4343 |
} else if (strcmp(str_comp, "zlib") == 0) { |
break; |
| 4344 |
type = COMP_ZLIB; // packet compression enabled |
} |
| 4345 |
} else if (strcmp(str_comp, "none") == 0) { |
ptr++; |
|
type = COMP_NONE; // packet compression disabled |
|
| 4346 |
} |
} |
| 4347 |
|
|
| 4348 |
return (type); |
return (type); |
| 4423 |
int offset = 0; |
int offset = 0; |
| 4424 |
char *msg = NULL; |
char *msg = NULL; |
| 4425 |
char tmp[1024+512]; |
char tmp[1024+512]; |
|
char str_kextype[40]; |
|
| 4426 |
char str_keytype[10]; |
char str_keytype[10]; |
| 4427 |
|
|
| 4428 |
notify_verbose_message(pvar, "SSH2_MSG_KEXINIT was received.", LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, "SSH2_MSG_KEXINIT was received.", LOG_LEVEL_VERBOSE); |
| 4488 |
// サーバは、クライアントから送られてきた myproposal[PROPOSAL_KEX_ALGS] のカンマ文字列のうち、 |
// サーバは、クライアントから送られてきた myproposal[PROPOSAL_KEX_ALGS] のカンマ文字列のうち、 |
| 4489 |
// 先頭から自分の myproposal[] と比較を行い、最初にマッチしたものがKEXアルゴリズムとして |
// 先頭から自分の myproposal[] と比較を行い、最初にマッチしたものがKEXアルゴリズムとして |
| 4490 |
// 選択される。(2004.10.30 yutaka) |
// 選択される。(2004.10.30 yutaka) |
| 4491 |
pvar->kex_type = -1; |
pvar->kex_type = choose_SSH2_kex_algorithm(buf, myproposal[PROPOSAL_KEX_ALGS]); |
| 4492 |
choose_SSH2_proposal(buf, myproposal[PROPOSAL_KEX_ALGS],str_kextype, sizeof(str_kextype)); |
if (pvar->kex_type == KEX_DH_UNKNOWN) { // not match |
|
if (strlen(str_kextype) == 0) { // not match |
|
| 4493 |
strncpy_s(tmp, sizeof(tmp), "unknown KEX algorithm: ", _TRUNCATE); |
strncpy_s(tmp, sizeof(tmp), "unknown KEX algorithm: ", _TRUNCATE); |
| 4494 |
strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE); |
strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE); |
| 4495 |
msg = tmp; |
msg = tmp; |
| 4496 |
goto error; |
goto error; |
| 4497 |
} |
} |
|
if (strcmp(str_kextype, KEX_DH14) == 0) { |
|
|
pvar->kex_type = KEX_DH_GRP14_SHA1; |
|
|
} else if (strcmp(str_kextype, KEX_DH1) == 0) { |
|
|
pvar->kex_type = KEX_DH_GRP1_SHA1; |
|
|
} else if (strcmp(str_kextype, KEX_DHGEX_SHA1) == 0) { |
|
|
pvar->kex_type = KEX_DH_GEX_SHA1; |
|
|
} else if (strcmp(str_kextype, KEX_DHGEX_SHA256) == 0) { |
|
|
pvar->kex_type = KEX_DH_GEX_SHA256; |
|
|
} |
|
| 4498 |
|
|
| 4499 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "KEX algorithm: %s", str_kextype); |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "KEX algorithm: %s", ssh2_kex_algorithms[pvar->kex_type].name); |
| 4500 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 4501 |
|
|
| 4502 |
// ホストキーアルゴリズムチェック |
// ホストキーアルゴリズムチェック |
| 4643 |
|
|
| 4644 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 4645 |
"compression algorithm client to server: %s", |
"compression algorithm client to server: %s", |
| 4646 |
ssh_comp[pvar->ctos_compression]); |
ssh_comps[pvar->ctos_compression].name); |
| 4647 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 4648 |
|
|
| 4649 |
size = get_payload_uint32(pvar, offset); |
size = get_payload_uint32(pvar, offset); |
| 4663 |
|
|
| 4664 |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
_snprintf_s(buf, sizeof(buf), _TRUNCATE, |
| 4665 |
"compression algorithm server to client: %s", |
"compression algorithm server to client: %s", |
| 4666 |
ssh_comp[pvar->stoc_compression]); |
ssh_comps[pvar->stoc_compression].name); |
| 4667 |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, buf, LOG_LEVEL_VERBOSE); |
| 4668 |
|
|
| 4669 |
// we_needの決定 (2004.11.6 yutaka) |
// we_needの決定 (2004.11.6 yutaka) |
| 5070 |
|
|
| 5071 |
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, |
| 5072 |
char *session_id, int session_id_len, |
char *session_id, int session_id_len, |
| 5073 |
enum kex_exchange kex_type) |
enum kex_algorithm kex_type) |
| 5074 |
{ |
{ |
| 5075 |
buffer_t *b; |
buffer_t *b; |
| 5076 |
const EVP_MD *evp_md; |
const EVP_MD *evp_md = ssh2_kex_algorithms[kex_type].evp_md(); |
| 5077 |
EVP_MD_CTX md; |
EVP_MD_CTX md; |
| 5078 |
char c = id; |
char c = id; |
| 5079 |
int have; |
int have; |
| 5080 |
int mdsz; |
int mdsz = EVP_MD_size(evp_md); |
| 5081 |
u_char *digest; |
u_char *digest = malloc(roundup(need, mdsz)); |
|
|
|
|
if (kex_type == KEX_DH_GEX_SHA256) { |
|
|
evp_md = EVP_sha256(); |
|
|
} |
|
|
else { |
|
|
evp_md = EVP_sha1(); |
|
|
} |
|
|
mdsz = EVP_MD_size(evp_md); |
|
|
digest = malloc(roundup(need, mdsz)); |
|
| 5082 |
|
|
| 5083 |
if (digest == NULL) |
if (digest == NULL) |
| 5084 |
goto skip; |
goto skip; |
| 5939 |
BIGNUM *share_key = NULL; |
BIGNUM *share_key = NULL; |
| 5940 |
char *hash; |
char *hash; |
| 5941 |
char *emsg, emsg_tmp[1024]; // error message |
char *emsg, emsg_tmp[1024]; // error message |
| 5942 |
int ret; |
int ret, hashlen; |
| 5943 |
Key hostkey; // hostkey |
Key hostkey; // hostkey |
| 5944 |
|
|
| 5945 |
notify_verbose_message(pvar, "SSH2_MSG_KEXDH_REPLY was received.", LOG_LEVEL_VERBOSE); |
notify_verbose_message(pvar, "SSH2_MSG_KEXDH_REPLY was received.", LOG_LEVEL_VERBOSE); |
| 6087 |
pvar->kexdh->pub_key, |
pvar->kexdh->pub_key, |
| 6088 |
dh_server_pub, |
dh_server_pub, |
| 6089 |
share_key); |
share_key); |
| 6090 |
//debug_print(30, hash, 20); |
|
| 6091 |
|
hashlen = EVP_MD_size(ssh2_kex_algorithms[pvar->kex_type].evp_md()); |
| 6092 |
|
//debug_print(30, hash, hashlen); |
| 6093 |
//debug_print(31, pvar->client_version_string, strlen(pvar->client_version_string)); |
//debug_print(31, pvar->client_version_string, strlen(pvar->client_version_string)); |
| 6094 |
//debug_print(32, pvar->server_version_string, strlen(pvar->server_version_string)); |
//debug_print(32, pvar->server_version_string, strlen(pvar->server_version_string)); |
| 6095 |
//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)); |
| 6098 |
|
|
| 6099 |
// session idの保存(初回接続時のみ) |
// session idの保存(初回接続時のみ) |
| 6100 |
if (pvar->session_id == NULL) { |
if (pvar->session_id == NULL) { |
| 6101 |
pvar->session_id_len = 20; |
pvar->session_id_len = hashlen; |
| 6102 |
pvar->session_id = malloc(pvar->session_id_len); |
pvar->session_id = malloc(pvar->session_id_len); |
| 6103 |
if (pvar->session_id != NULL) { |
if (pvar->session_id != NULL) { |
| 6104 |
memcpy(pvar->session_id, hash, pvar->session_id_len); |
memcpy(pvar->session_id, hash, pvar->session_id_len); |
| 6208 |
BIGNUM *kexgex_p, |
BIGNUM *kexgex_p, |
| 6209 |
BIGNUM *kexgex_g, |
BIGNUM *kexgex_g, |
| 6210 |
BIGNUM *client_dh_pub, |
BIGNUM *client_dh_pub, |
| 6211 |
enum kex_exchange kex_type, |
enum kex_algorithm kex_type, |
| 6212 |
BIGNUM *server_dh_pub, |
BIGNUM *server_dh_pub, |
| 6213 |
BIGNUM *shared_secret) |
BIGNUM *shared_secret) |
| 6214 |
{ |
{ |
| 6215 |
buffer_t *b; |
buffer_t *b; |
| 6216 |
static unsigned char digest[EVP_MAX_MD_SIZE]; |
static unsigned char digest[EVP_MAX_MD_SIZE]; |
| 6217 |
const EVP_MD *evp_md; |
const EVP_MD *evp_md = ssh2_kex_algorithms[kex_type].evp_md(); |
| 6218 |
EVP_MD_CTX md; |
EVP_MD_CTX md; |
| 6219 |
|
|
| 6220 |
b = buffer_init(); |
b = buffer_init(); |
| 6247 |
// yutaka |
// yutaka |
| 6248 |
//debug_print(38, buffer_ptr(b), buffer_len(b)); |
//debug_print(38, buffer_ptr(b), buffer_len(b)); |
| 6249 |
|
|
|
if (kex_type == KEX_DH_GEX_SHA256) { |
|
|
evp_md = EVP_sha256(); |
|
|
} |
|
|
else { |
|
|
evp_md = EVP_sha1(); |
|
|
} |
|
| 6250 |
EVP_DigestInit(&md, evp_md); |
EVP_DigestInit(&md, evp_md); |
| 6251 |
EVP_DigestUpdate(&md, buffer_ptr(b), buffer_len(b)); |
EVP_DigestUpdate(&md, buffer_ptr(b), buffer_len(b)); |
| 6252 |
EVP_DigestFinal(&md, digest, NULL); |
EVP_DigestFinal(&md, digest, NULL); |
| 6444 |
dh_server_pub, |
dh_server_pub, |
| 6445 |
share_key); |
share_key); |
| 6446 |
|
|
| 6447 |
if (pvar->kex_type == KEX_DH_GEX_SHA256) { |
hashlen = EVP_MD_size(ssh2_kex_algorithms[pvar->kex_type].evp_md()); |
|
hashlen = 32; |
|
|
} |
|
|
else{ |
|
|
hashlen = 20; |
|
|
} |
|
| 6448 |
{ |
{ |
| 6449 |
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)); |
| 6450 |
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)); |