| 4053 |
int get_cipher_block_size(SSHCipher cipher) |
int get_cipher_block_size(SSHCipher cipher) |
| 4054 |
{ |
{ |
| 4055 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
ssh2_cipher_t *ptr = ssh2_ciphers; |
|
int val = 8; |
|
| 4056 |
|
|
| 4057 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4058 |
if (cipher == ptr->cipher) { |
if (cipher == ptr->cipher) { |
| 4059 |
val = ptr->block_size; |
return ptr->block_size; |
|
break; |
|
| 4060 |
} |
} |
| 4061 |
ptr++; |
ptr++; |
| 4062 |
} |
} |
| 4063 |
return (val); |
|
| 4064 |
|
// not found. |
| 4065 |
|
return 8; |
| 4066 |
} |
} |
| 4067 |
|
|
| 4068 |
int get_cipher_key_len(SSHCipher cipher) |
int get_cipher_key_len(SSHCipher cipher) |
| 4069 |
{ |
{ |
| 4070 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
ssh2_cipher_t *ptr = ssh2_ciphers; |
|
int val = 0; |
|
| 4071 |
|
|
| 4072 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4073 |
if (cipher == ptr->cipher) { |
if (cipher == ptr->cipher) { |
| 4074 |
val = ptr->key_len; |
return ptr->key_len; |
|
break; |
|
| 4075 |
} |
} |
| 4076 |
ptr++; |
ptr++; |
| 4077 |
} |
} |
| 4078 |
return (val); |
|
| 4079 |
|
// not found. |
| 4080 |
|
return 0; |
| 4081 |
} |
} |
| 4082 |
|
|
| 4083 |
int get_cipher_discard_len(SSHCipher cipher) |
int get_cipher_discard_len(SSHCipher cipher) |
| 4084 |
{ |
{ |
| 4085 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
ssh2_cipher_t *ptr = ssh2_ciphers; |
|
int val = 0; |
|
| 4086 |
|
|
| 4087 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4088 |
if (cipher == ptr->cipher) { |
if (cipher == ptr->cipher) { |
| 4089 |
val = ptr->discard_len; |
return ptr->discard_len; |
|
break; |
|
| 4090 |
} |
} |
| 4091 |
ptr++; |
ptr++; |
| 4092 |
} |
} |
| 4093 |
return (val); |
|
| 4094 |
|
// not found. |
| 4095 |
|
return 0; |
| 4096 |
} |
} |
| 4097 |
|
|
| 4098 |
// 暗号アルゴリズム名から検索する。 |
// 暗号アルゴリズム名から検索する。 |
| 4099 |
SSHCipher get_cipher_by_name(char *name) |
SSHCipher get_cipher_by_name(char *name) |
| 4100 |
{ |
{ |
| 4101 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
ssh2_cipher_t *ptr = ssh2_ciphers; |
|
SSHCipher ret = SSH_CIPHER_NONE; |
|
| 4102 |
|
|
| 4103 |
if (name == NULL) |
if (name == NULL) |
| 4104 |
goto error; |
goto error; |
| 4105 |
|
|
| 4106 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4107 |
if (strcmp(ptr->name, name) == 0) { |
if (strcmp(ptr->name, name) == 0) { |
| 4108 |
ret = ptr->cipher; |
return ptr->cipher; |
|
break; |
|
| 4109 |
} |
} |
| 4110 |
ptr++; |
ptr++; |
| 4111 |
} |
} |
| 4112 |
|
|
| 4113 |
|
// not found. |
| 4114 |
error: |
error: |
| 4115 |
return (ret); |
return SSH_CIPHER_NONE; |
| 4116 |
} |
} |
| 4117 |
|
|
| 4118 |
static char * get_cipher_string(SSHCipher cipher) |
static char * get_cipher_string(SSHCipher cipher) |
| 4119 |
{ |
{ |
| 4120 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
ssh2_cipher_t *ptr = ssh2_ciphers; |
|
char *p = "unknown"; |
|
| 4121 |
|
|
| 4122 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4123 |
if (cipher == ptr->cipher) { |
if (cipher == ptr->cipher) { |
| 4124 |
p = ptr->name; |
return ptr->name; |
|
break; |
|
| 4125 |
} |
} |
| 4126 |
ptr++; |
ptr++; |
| 4127 |
} |
} |
| 4128 |
return p; |
|
| 4129 |
|
// not found. |
| 4130 |
|
return "unknown"; |
| 4131 |
} |
} |
| 4132 |
|
|
| 4133 |
const EVP_CIPHER* get_cipher_EVP_CIPHER(SSHCipher cipher) |
const EVP_CIPHER* get_cipher_EVP_CIPHER(SSHCipher cipher) |
| 4134 |
{ |
{ |
| 4135 |
ssh2_cipher_t *ptr = ssh2_ciphers; |
ssh2_cipher_t *ptr = ssh2_ciphers; |
|
const EVP_CIPHER *type; |
|
|
|
|
|
type = EVP_enc_null(); |
|
| 4136 |
|
|
| 4137 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4138 |
if (cipher == ptr->cipher) { |
if (cipher == ptr->cipher) { |
| 4139 |
type = ptr->func(); |
return ptr->func(); |
|
break; |
|
| 4140 |
} |
} |
| 4141 |
ptr++; |
ptr++; |
| 4142 |
} |
} |
| 4143 |
return type; |
|
| 4144 |
|
// not found. |
| 4145 |
|
return EVP_enc_null(); |
| 4146 |
} |
} |
| 4147 |
|
|
| 4148 |
char* get_kex_algorithm_name(kex_algorithm kextype) |
char* get_kex_algorithm_name(kex_algorithm kextype) |
| 4149 |
{ |
{ |
| 4150 |
ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms; |
ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms; |
|
char *p = "unknown"; |
|
| 4151 |
|
|
| 4152 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4153 |
if (kextype == ptr->kextype) { |
if (kextype == ptr->kextype) { |
| 4154 |
p = ptr->name; |
return ptr->name; |
|
break; |
|
| 4155 |
} |
} |
| 4156 |
ptr++; |
ptr++; |
| 4157 |
} |
} |
| 4158 |
return p; |
|
| 4159 |
|
// not found. |
| 4160 |
|
return "unknown"; |
| 4161 |
} |
} |
| 4162 |
|
|
| 4163 |
const EVP_MD* get_kex_algorithm_EVP_MD(kex_algorithm kextype) |
const EVP_MD* get_kex_algorithm_EVP_MD(kex_algorithm kextype) |
| 4164 |
{ |
{ |
| 4165 |
ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms; |
ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms; |
|
const EVP_MD *evp_md; |
|
| 4166 |
|
|
| 4167 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4168 |
if (kextype == ptr->kextype) { |
if (kextype == ptr->kextype) { |
| 4169 |
evp_md = ptr->evp_md(); |
return ptr->evp_md(); |
|
break; |
|
| 4170 |
} |
} |
| 4171 |
ptr++; |
ptr++; |
| 4172 |
} |
} |
| 4173 |
return evp_md; |
|
| 4174 |
|
// not found. |
| 4175 |
|
return EVP_md_null(); |
| 4176 |
} |
} |
| 4177 |
|
|
| 4178 |
char* get_ssh2_mac_name(hmac_type type) |
char* get_ssh2_mac_name(hmac_type type) |
| 4179 |
{ |
{ |
| 4180 |
ssh2_mac_t *ptr = ssh2_macs; |
ssh2_mac_t *ptr = ssh2_macs; |
|
char *p = "unknown"; |
|
| 4181 |
|
|
| 4182 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4183 |
if (type == ptr->type) { |
if (type == ptr->type) { |
| 4184 |
p = ptr->name; |
return ptr->name; |
|
break; |
|
| 4185 |
} |
} |
| 4186 |
ptr++; |
ptr++; |
| 4187 |
} |
} |
| 4188 |
return p; |
|
| 4189 |
|
// not found. |
| 4190 |
|
return "unknown"; |
| 4191 |
} |
} |
| 4192 |
|
|
| 4193 |
const EVP_MD* get_ssh2_mac_EVP_MD(hmac_type type) |
const EVP_MD* get_ssh2_mac_EVP_MD(hmac_type type) |
| 4194 |
{ |
{ |
| 4195 |
ssh2_mac_t *ptr = ssh2_macs; |
ssh2_mac_t *ptr = ssh2_macs; |
|
const EVP_MD *evp_md; |
|
| 4196 |
|
|
| 4197 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4198 |
if (type == ptr->type) { |
if (type == ptr->type) { |
| 4199 |
evp_md = ptr->evp_md(); |
return ptr->evp_md(); |
|
break; |
|
| 4200 |
} |
} |
| 4201 |
ptr++; |
ptr++; |
| 4202 |
} |
} |
| 4203 |
return evp_md; |
|
| 4204 |
|
// not found. |
| 4205 |
|
return EVP_md_null(); |
| 4206 |
} |
} |
| 4207 |
|
|
| 4208 |
int get_ssh2_mac_truncatebits(hmac_type type) |
int get_ssh2_mac_truncatebits(hmac_type type) |
| 4209 |
{ |
{ |
| 4210 |
ssh2_mac_t *ptr = ssh2_macs; |
ssh2_mac_t *ptr = ssh2_macs; |
|
int bits; |
|
| 4211 |
|
|
| 4212 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4213 |
if (type == ptr->type) { |
if (type == ptr->type) { |
| 4214 |
bits = ptr->truncatebits; |
return ptr->truncatebits; |
|
break; |
|
| 4215 |
} |
} |
| 4216 |
ptr++; |
ptr++; |
| 4217 |
} |
} |
| 4218 |
return bits; |
|
| 4219 |
|
// not found. |
| 4220 |
|
return 0; |
| 4221 |
} |
} |
| 4222 |
|
|
| 4223 |
int get_ssh2_mac_etm(hmac_type type) |
int get_ssh2_mac_etm(hmac_type type) |
| 4224 |
{ |
{ |
| 4225 |
ssh2_mac_t *ptr = ssh2_macs; |
ssh2_mac_t *ptr = ssh2_macs; |
|
int etm; |
|
| 4226 |
|
|
| 4227 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4228 |
if (type == ptr->type) { |
if (type == ptr->type) { |
| 4229 |
etm = ptr->etm; |
return ptr->etm; |
|
break; |
|
| 4230 |
} |
} |
| 4231 |
ptr++; |
ptr++; |
| 4232 |
} |
} |
| 4233 |
return etm; |
|
| 4234 |
|
// not found |
| 4235 |
|
return 0; |
| 4236 |
} |
} |
| 4237 |
|
|
| 4238 |
char* get_ssh2_comp_name(compression_type type) |
char* get_ssh2_comp_name(compression_type type) |
| 4239 |
{ |
{ |
| 4240 |
ssh2_comp_t *ptr = ssh2_comps; |
ssh2_comp_t *ptr = ssh2_comps; |
|
char *p = "unknown"; |
|
| 4241 |
|
|
| 4242 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4243 |
if (type == ptr->type) { |
if (type == ptr->type) { |
| 4244 |
p = ptr->name; |
return ptr->name; |
|
break; |
|
| 4245 |
} |
} |
| 4246 |
ptr++; |
ptr++; |
| 4247 |
} |
} |
| 4248 |
return p; |
|
| 4249 |
|
// not found. |
| 4250 |
|
return "unknown"; |
| 4251 |
} |
} |
| 4252 |
|
|
| 4253 |
char* get_ssh_keytype_name(ssh_keytype type) |
char* get_ssh_keytype_name(ssh_keytype type) |
| 4254 |
{ |
{ |
| 4255 |
ssh2_host_key_t *ptr = ssh2_host_key; |
ssh2_host_key_t *ptr = ssh2_host_key; |
|
char *p = "ssh-unknown"; |
|
| 4256 |
|
|
| 4257 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4258 |
if (type == ptr->type) { |
if (type == ptr->type) { |
| 4259 |
// ssh2_host_key[]はグローバル変数なので、そのまま返り値にできる。 |
return ptr->name; |
|
p = ptr->name; |
|
|
break; |
|
| 4260 |
} |
} |
| 4261 |
ptr++; |
ptr++; |
| 4262 |
} |
} |
| 4263 |
return p; |
|
| 4264 |
|
// not found. |
| 4265 |
|
return "ssh-unknown"; |
| 4266 |
} |
} |
| 4267 |
|
|
| 4268 |
char* get_digest_algorithm_name(digest_algorithm id) |
char* get_digest_algorithm_name(digest_algorithm id) |
| 4269 |
{ |
{ |
| 4270 |
ssh_digest_t *ptr = ssh_digests; |
ssh_digest_t *ptr = ssh_digests; |
|
char *p = "unknown"; |
|
| 4271 |
|
|
| 4272 |
while (ptr->name != NULL) { |
while (ptr->name != NULL) { |
| 4273 |
if (id == ptr->id) { |
if (id == ptr->id) { |
| 4274 |
p = ptr->name; |
return ptr->name; |
|
break; |
|
| 4275 |
} |
} |
| 4276 |
ptr++; |
ptr++; |
| 4277 |
} |
} |
| 4278 |
return p; |
|
| 4279 |
|
// not found. |
| 4280 |
|
return "unknown"; |
| 4281 |
} |
} |
| 4282 |
|
|
| 4283 |
static void do_write_buffer_file(void *buf, int len, char *file, int lineno) |
static void do_write_buffer_file(void *buf, int len, char *file, int lineno) |
| 4296 |
fclose(fp); |
fclose(fp); |
| 4297 |
} |
} |
| 4298 |
|
|
|
|
|
| 4299 |
void SSH2_packet_start(buffer_t *msg, unsigned char type) |
void SSH2_packet_start(buffer_t *msg, unsigned char type) |
| 4300 |
{ |
{ |
| 4301 |
unsigned char buf[9]; |
unsigned char buf[9]; |
| 4307 |
buffer_append(msg, buf, len); |
buffer_append(msg, buf, len); |
| 4308 |
} |
} |
| 4309 |
|
|
|
|
|
| 4310 |
// the caller is normalize_cipher_order() |
// the caller is normalize_cipher_order() |
| 4311 |
void SSH2_update_cipher_myproposal(PTInstVar pvar) |
void SSH2_update_cipher_myproposal(PTInstVar pvar) |
| 4312 |
{ |
{ |
| 4743 |
// 暗号アルゴリズムのキーサイズ、ブロックサイズ、MACサイズのうち最大値(we_need)を決定する。 |
// 暗号アルゴリズムのキーサイズ、ブロックサイズ、MACサイズのうち最大値(we_need)を決定する。 |
| 4744 |
static void choose_SSH2_key_maxlength(PTInstVar pvar) |
static void choose_SSH2_key_maxlength(PTInstVar pvar) |
| 4745 |
{ |
{ |
| 4746 |
int mode, need, val, ctos; |
int mode, val; |
| 4747 |
|
unsigned int need = 0; |
| 4748 |
const EVP_MD *md; |
const EVP_MD *md; |
| 4749 |
|
SSHCipher cipher; |
| 4750 |
|
hmac_type mac; |
| 4751 |
|
|
| 4752 |
for (mode = 0; mode < MODE_MAX; mode++) { |
for (mode = 0; mode < MODE_MAX; mode++) { |
| 4753 |
if (mode == MODE_OUT) |
if (mode == MODE_OUT) { |
| 4754 |
ctos = 1; |
mac = pvar->ctos_hmac; |
| 4755 |
else |
cipher = pvar->ctos_cipher; |
| 4756 |
ctos = 0; |
} |
| 4757 |
|
else { |
| 4758 |
if (ctos == 1) { |
mac = pvar->stoc_hmac; |
| 4759 |
val = pvar->ctos_hmac; |
cipher = pvar->stoc_cipher; |
|
} else { |
|
|
val = pvar->stoc_hmac; |
|
| 4760 |
} |
} |
| 4761 |
|
|
| 4762 |
// current_keys[]に設定しておいて、あとで pvar->ssh2_keys[] へコピーする。 |
// current_keys[]に設定しておいて、あとで pvar->ssh2_keys[] へコピーする。 |
| 4763 |
md = get_ssh2_mac_EVP_MD(val); |
md = get_ssh2_mac_EVP_MD(mac); |
| 4764 |
current_keys[mode].mac.md = md; |
current_keys[mode].mac.md = md; |
| 4765 |
current_keys[mode].mac.key_len = current_keys[mode].mac.mac_len = EVP_MD_size(md); |
current_keys[mode].mac.key_len = current_keys[mode].mac.mac_len = EVP_MD_size(md); |
| 4766 |
if (get_ssh2_mac_truncatebits(val) != 0) { |
val = get_ssh2_mac_truncatebits(mac); |
| 4767 |
current_keys[mode].mac.mac_len = get_ssh2_mac_truncatebits(val) / 8; |
if (val != 0) { |
| 4768 |
|
current_keys[mode].mac.mac_len = val / 8; |
| 4769 |
} |
} |
| 4770 |
current_keys[mode].mac.etm = get_ssh2_mac_etm(val); |
current_keys[mode].mac.etm = get_ssh2_mac_etm(mac); |
| 4771 |
|
|
| 4772 |
// キーサイズとブロックサイズもここで設定しておく (2004.11.7 yutaka) |
// キーサイズとブロックサイズもここで設定しておく (2004.11.7 yutaka) |
| 4773 |
if (ctos == 1) { |
current_keys[mode].enc.key_len = get_cipher_key_len(cipher); |
| 4774 |
current_keys[mode].enc.key_len = get_cipher_key_len(pvar->ctos_cipher); |
current_keys[mode].enc.block_size = get_cipher_block_size(cipher); |
|
current_keys[mode].enc.block_size = get_cipher_block_size(pvar->ctos_cipher); |
|
|
} else { |
|
|
current_keys[mode].enc.key_len = get_cipher_key_len(pvar->stoc_cipher); |
|
|
current_keys[mode].enc.block_size = get_cipher_block_size(pvar->stoc_cipher); |
|
|
} |
|
| 4775 |
current_keys[mode].mac.enabled = 0; |
current_keys[mode].mac.enabled = 0; |
| 4776 |
current_keys[mode].comp.enabled = 0; // (2005.7.9 yutaka) |
current_keys[mode].comp.enabled = 0; // (2005.7.9 yutaka) |
| 4777 |
|
|
| 4779 |
pvar->ssh2_keys[mode].mac.enabled = 0; |
pvar->ssh2_keys[mode].mac.enabled = 0; |
| 4780 |
pvar->ssh2_keys[mode].comp.enabled = 0; // (2005.7.9 yutaka) |
pvar->ssh2_keys[mode].comp.enabled = 0; // (2005.7.9 yutaka) |
| 4781 |
} |
} |
| 4782 |
need = 0; |
|
| 4783 |
for (mode = 0; mode < MODE_MAX; mode++) { |
for (mode = 0; mode < MODE_MAX; mode++) { |
| 4784 |
if (mode == MODE_OUT) |
need = max(need, current_keys[mode].enc.key_len); |
| 4785 |
ctos = 1; |
need = max(need, current_keys[mode].enc.block_size); |
| 4786 |
else |
need = max(need, current_keys[mode].mac.key_len); |
|
ctos = 0; |
|
|
|
|
|
val = current_keys[mode].enc.key_len; |
|
|
if (need < val) |
|
|
need = val; |
|
|
|
|
|
val = current_keys[mode].enc.block_size; |
|
|
if (need < val) |
|
|
need = val; |
|
|
|
|
|
val = current_keys[mode].mac.key_len; |
|
|
if (need < val) |
|
|
need = val; |
|
| 4787 |
} |
} |
| 4788 |
pvar->we_need = need; |
pvar->we_need = need; |
|
|
|
| 4789 |
} |
} |
| 4790 |
|
|
| 4791 |
|
|