| 4091 |
// general |
// general |
| 4092 |
// |
// |
| 4093 |
|
|
| 4094 |
int get_cipher_block_size(SSHCipher cipher) |
int get_cipher_block_size(ssh2_cipher_t *cipher) |
| 4095 |
{ |
{ |
| 4096 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
int blocksize = 0; |
| 4097 |
|
|
| 4098 |
while (ptr->name != NULL) { |
if (cipher) { |
| 4099 |
if (cipher == ptr->cipher) { |
blocksize = cipher->block_size; |
|
return ptr->block_size; |
|
|
} |
|
|
ptr++; |
|
| 4100 |
} |
} |
| 4101 |
|
|
| 4102 |
// not found. |
return max(blocksize, 8); |
|
return 8; |
|
| 4103 |
} |
} |
| 4104 |
|
|
| 4105 |
int get_cipher_key_len(SSHCipher cipher) |
int get_cipher_key_len(ssh2_cipher_t *cipher) |
| 4106 |
{ |
{ |
| 4107 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
if (cipher) { |
| 4108 |
|
return cipher->key_len; |
| 4109 |
while (ptr->name != NULL) { |
} |
| 4110 |
if (cipher == ptr->cipher) { |
else { |
| 4111 |
return ptr->key_len; |
return 0; |
|
} |
|
|
ptr++; |
|
| 4112 |
} |
} |
|
|
|
|
// not found. |
|
|
return 0; |
|
| 4113 |
} |
} |
| 4114 |
|
|
| 4115 |
int get_cipher_discard_len(SSHCipher cipher) |
int get_cipher_discard_len(ssh2_cipher_t *cipher) |
| 4116 |
{ |
{ |
| 4117 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
if (cipher) { |
| 4118 |
|
return cipher->discard_len; |
| 4119 |
while (ptr->name != NULL) { |
} |
| 4120 |
if (cipher == ptr->cipher) { |
else { |
| 4121 |
return ptr->discard_len; |
return 0; |
|
} |
|
|
ptr++; |
|
| 4122 |
} |
} |
|
|
|
|
// not found. |
|
|
return 0; |
|
| 4123 |
} |
} |
| 4124 |
|
|
| 4125 |
int get_cipher_iv_len(SSHCipher cipher) |
int get_cipher_iv_len(ssh2_cipher_t *cipher) |
| 4126 |
{ |
{ |
| 4127 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
if (cipher) { |
| 4128 |
|
if (cipher->iv_len != 0) { |
| 4129 |
while (ptr->name != NULL) { |
return cipher->iv_len; |
| 4130 |
if (cipher == ptr->cipher) { |
} |
| 4131 |
if (ptr->iv_len != 0) { |
else { |
| 4132 |
return ptr->iv_len; |
return cipher->block_size; |
|
} |
|
|
else { |
|
|
return ptr->block_size; |
|
|
} |
|
| 4133 |
} |
} |
|
ptr++; |
|
| 4134 |
} |
} |
| 4135 |
|
else { |
| 4136 |
// not found. |
return 8; // block_size |
| 4137 |
return 8; // block_size |
} |
| 4138 |
} |
} |
| 4139 |
|
|
| 4140 |
int get_cipher_auth_len(SSHCipher cipher) |
int get_cipher_auth_len(ssh2_cipher_t *cipher) |
| 4141 |
{ |
{ |
| 4142 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
if (cipher) { |
| 4143 |
|
return cipher->auth_len; |
| 4144 |
while (ptr->name != NULL) { |
} |
| 4145 |
if (cipher == ptr->cipher) { |
else { |
| 4146 |
return ptr->auth_len; |
return 0; |
|
} |
|
|
ptr++; |
|
| 4147 |
} |
} |
|
|
|
|
// not found. |
|
|
return 0; |
|
| 4148 |
} |
} |
| 4149 |
|
|
| 4150 |
// 暗号アルゴリズム名から検索する。 |
// 暗号アルゴリズム名から検索する。 |
| 4151 |
SSHCipher get_cipher_by_name(char *name) |
ssh2_cipher_t *get_cipher_by_name(char *name) |
| 4152 |
{ |
{ |
| 4153 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
ssh2_cipher_t *ptr = ssh2_ciphers; |
| 4154 |
|
|
|
if (name == NULL) |
|
|
goto error; |
|
|
|
|
| 4155 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4156 |
if (strcmp(ptr->name, name) == 0) { |
if (name != NULL && strcmp(ptr->name, name) == 0) { |
| 4157 |
return ptr->cipher; |
return ptr; |
| 4158 |
} |
} |
| 4159 |
ptr++; |
ptr++; |
| 4160 |
} |
} |
| 4161 |
|
|
| 4162 |
// not found. |
// not found. |
| 4163 |
error: |
return ptr; |
|
return SSH_CIPHER_NONE; |
|
| 4164 |
} |
} |
| 4165 |
|
|
| 4166 |
static char * get_cipher_string(SSHCipher cipher) |
static char * get_cipher_string(ssh2_cipher_t *cipher) |
| 4167 |
{ |
{ |
| 4168 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
if (cipher) { |
| 4169 |
|
return cipher->name; |
| 4170 |
while (ptr->name != NULL) { |
} |
| 4171 |
if (cipher == ptr->cipher) { |
else { |
| 4172 |
return ptr->name; |
return "unknown"; |
|
} |
|
|
ptr++; |
|
| 4173 |
} |
} |
|
|
|
|
// not found. |
|
|
return "unknown"; |
|
| 4174 |
} |
} |
| 4175 |
|
|
| 4176 |
const EVP_CIPHER* get_cipher_EVP_CIPHER(SSHCipher cipher) |
const EVP_CIPHER* get_cipher_EVP_CIPHER(ssh2_cipher_t *cipher) |
| 4177 |
{ |
{ |
| 4178 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
if (cipher) { |
| 4179 |
|
return cipher->func(); |
| 4180 |
while (ptr->name != NULL) { |
} |
| 4181 |
if (cipher == ptr->cipher) { |
else { |
| 4182 |
return ptr->func(); |
return EVP_enc_null(); |
|
} |
|
|
ptr++; |
|
| 4183 |
} |
} |
|
|
|
|
// not found. |
|
|
return EVP_enc_null(); |
|
| 4184 |
} |
} |
| 4185 |
|
|
| 4186 |
char* get_kex_algorithm_name(kex_algorithm kextype) |
char* get_kex_algorithm_name(kex_algorithm kextype) |
| 4673 |
{ |
{ |
| 4674 |
char tmp_cli[1024], *ptr_cli, *ctc_cli; |
char tmp_cli[1024], *ptr_cli, *ctc_cli; |
| 4675 |
char tmp_svr[1024], *ptr_svr, *ctc_svr; |
char tmp_svr[1024], *ptr_svr, *ctc_svr; |
|
SSHCipher cipher = SSH_CIPHER_NONE; |
|
| 4676 |
|
|
| 4677 |
strncpy_s(tmp_cli, sizeof(tmp_cli), my_proposal, _TRUNCATE); |
strncpy_s(tmp_cli, sizeof(tmp_cli), my_proposal, _TRUNCATE); |
| 4678 |
ptr_cli = strtok_s(tmp_cli, ",", &ctc_cli); |
ptr_cli = strtok_s(tmp_cli, ",", &ctc_cli); |
| 4717 |
return (type); |
return (type); |
| 4718 |
} |
} |
| 4719 |
|
|
| 4720 |
static SSHCipher choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal) |
static ssh2_cipher_t *choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal) |
| 4721 |
{ |
{ |
|
SSHCipher cipher = SSH_CIPHER_NONE; |
|
| 4722 |
char str_cipher[32]; |
char str_cipher[32]; |
| 4723 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
ssh2_cipher_t *ptr = ssh2_ciphers; |
| 4724 |
|
|
| 4725 |
choose_SSH2_proposal(server_proposal, my_proposal, str_cipher, sizeof(str_cipher)); |
choose_SSH2_proposal(server_proposal, my_proposal, str_cipher, sizeof(str_cipher)); |
| 4726 |
|
return get_cipher_by_name(str_cipher); |
|
while (ptr->name != NULL) { |
|
|
if (strcmp(ptr->name, str_cipher) == 0) { |
|
|
cipher = ptr->cipher; |
|
|
break; |
|
|
} |
|
|
ptr++; |
|
|
} |
|
|
|
|
|
return (cipher); |
|
| 4727 |
} |
} |
| 4728 |
|
|
| 4729 |
|
|
| 4779 |
int mode, val; |
int mode, val; |
| 4780 |
unsigned int need = 0; |
unsigned int need = 0; |
| 4781 |
const EVP_MD *md; |
const EVP_MD *md; |
| 4782 |
SSHCipher cipher; |
ssh2_cipher_t *cipher; |
| 4783 |
hmac_type mac; |
hmac_type mac; |
| 4784 |
|
|
| 4785 |
for (mode = 0; mode < MODE_MAX; mode++) { |
for (mode = 0; mode < MODE_MAX; mode++) { |
| 4786 |
if (mode == MODE_OUT) { |
if (mode == MODE_OUT) { |
| 4787 |
mac = pvar->ctos_hmac; |
mac = pvar->ctos_hmac; |
|
cipher = pvar->ctos_cipher; |
|
| 4788 |
} |
} |
| 4789 |
else { |
else { |
| 4790 |
mac = pvar->stoc_hmac; |
mac = pvar->stoc_hmac; |
|
cipher = pvar->stoc_cipher; |
|
| 4791 |
} |
} |
| 4792 |
|
|
| 4793 |
|
cipher = pvar->ciphers[mode]; |
| 4794 |
|
|
| 4795 |
// current_keys[]に設定しておいて、あとで pvar->ssh2_keys[] へコピーする。 |
// current_keys[]に設定しておいて、あとで pvar->ssh2_keys[] へコピーする。 |
| 4796 |
md = get_ssh2_mac_EVP_MD(mac); |
md = get_ssh2_mac_EVP_MD(mac); |
| 4797 |
current_keys[mode].mac.md = md; |
current_keys[mode].mac.md = md; |
| 4948 |
|
|
| 4949 |
logprintf(LOG_LEVEL_VERBOSE, "server proposal: encryption algorithm client to server: %s", buf); |
logprintf(LOG_LEVEL_VERBOSE, "server proposal: encryption algorithm client to server: %s", buf); |
| 4950 |
|
|
| 4951 |
pvar->ctos_cipher = choose_SSH2_cipher_algorithm(buf, myproposal[PROPOSAL_ENC_ALGS_CTOS]); |
pvar->ciphers[MODE_OUT] = choose_SSH2_cipher_algorithm(buf, myproposal[PROPOSAL_ENC_ALGS_CTOS]); |
| 4952 |
if (pvar->ctos_cipher == SSH_CIPHER_NONE) { |
if (pvar->ciphers[MODE_OUT]->id == SSH_CIPHER_NONE) { |
| 4953 |
strncpy_s(tmp, sizeof(tmp), "unknown Encrypt algorithm(ctos): ", _TRUNCATE); |
strncpy_s(tmp, sizeof(tmp), "unknown Encrypt algorithm(ctos): ", _TRUNCATE); |
| 4954 |
strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE); |
strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE); |
| 4955 |
msg = tmp; |
msg = tmp; |
| 4968 |
|
|
| 4969 |
logprintf(LOG_LEVEL_VERBOSE, "server proposal: encryption algorithm server to client: %s", buf); |
logprintf(LOG_LEVEL_VERBOSE, "server proposal: encryption algorithm server to client: %s", buf); |
| 4970 |
|
|
| 4971 |
pvar->stoc_cipher = choose_SSH2_cipher_algorithm(buf, myproposal[PROPOSAL_ENC_ALGS_STOC]); |
pvar->ciphers[MODE_IN] = choose_SSH2_cipher_algorithm(buf, myproposal[PROPOSAL_ENC_ALGS_STOC]); |
| 4972 |
if (pvar->stoc_cipher == SSH_CIPHER_NONE) { |
if (pvar->ciphers[MODE_IN]->id == SSH_CIPHER_NONE) { |
| 4973 |
strncpy_s(tmp, sizeof(tmp), "unknown Encrypt algorithm(stoc): ", _TRUNCATE); |
strncpy_s(tmp, sizeof(tmp), "unknown Encrypt algorithm(stoc): ", _TRUNCATE); |
| 4974 |
strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE); |
strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE); |
| 4975 |
msg = tmp; |
msg = tmp; |
| 5067 |
|
|
| 5068 |
logprintf(LOG_LEVEL_VERBOSE, |
logprintf(LOG_LEVEL_VERBOSE, |
| 5069 |
"encryption algorithm client to server: %s", |
"encryption algorithm client to server: %s", |
| 5070 |
get_cipher_string(pvar->ctos_cipher)); |
get_cipher_string(pvar->ciphers[MODE_OUT])); |
| 5071 |
|
|
| 5072 |
logprintf(LOG_LEVEL_VERBOSE, |
logprintf(LOG_LEVEL_VERBOSE, |
| 5073 |
"encryption algorithm server to client: %s", |
"encryption algorithm server to client: %s", |
| 5074 |
get_cipher_string(pvar->stoc_cipher)); |
get_cipher_string(pvar->ciphers[MODE_IN])); |
| 5075 |
|
|
| 5076 |
logprintf(LOG_LEVEL_VERBOSE, |
logprintf(LOG_LEVEL_VERBOSE, |
| 5077 |
"MAC algorithm client to server: %s", |
"MAC algorithm client to server: %s", |