| 784 |
* 引数: |
* 引数: |
| 785 |
* data - ssh パケットの先頭を指すポインタ |
* data - ssh パケットの先頭を指すポインタ |
| 786 |
* len - パケット長 (先頭のパケット長領域(4バイト)を除いた値) |
* len - パケット長 (先頭のパケット長領域(4バイト)を除いた値) |
| 787 |
* etm - MAC 方式が EtM かどうかのフラグ |
* aadlen - 暗号化されていないが認証の対象となっているデータの長さ |
| 788 |
|
* authlen - 認証データ(AEAD tag)長 |
| 789 |
*/ |
*/ |
| 790 |
|
|
| 791 |
static int prep_packet_ssh2(PTInstVar pvar, char *data, unsigned int len, int etm) |
static int prep_packet_ssh2(PTInstVar pvar, char *data, unsigned int len, unsigned int aadlen, unsigned int authlen) |
| 792 |
{ |
{ |
| 793 |
unsigned int padding; |
unsigned int padding; |
| 794 |
|
|
| 795 |
if (etm) { |
if (authlen > 0) { |
| 796 |
|
if (!CRYPT_decrypt_aead(pvar, data, len, aadlen, authlen)) { |
| 797 |
|
UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, "Detected corrupted data; connection terminating."); |
| 798 |
|
notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE); |
| 799 |
|
return SSH_MSG_NONE; |
| 800 |
|
} |
| 801 |
|
} |
| 802 |
|
else if (aadlen > 0) { |
| 803 |
// EtM の場合は先に MAC の検証を行う |
// EtM の場合は先に MAC の検証を行う |
| 804 |
if (!CRYPT_verify_receiver_MAC(pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4, data + len + 4)) { |
if (!CRYPT_verify_receiver_MAC(pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4, data + len + 4)) { |
| 805 |
UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, "Detected corrupted data; connection terminating."); |
UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, "Detected corrupted data; connection terminating."); |
| 1033 |
unsigned int padding; |
unsigned int padding; |
| 1034 |
BOOL ret; |
BOOL ret; |
| 1035 |
struct Mac *mac = &pvar->ssh2_keys[MODE_OUT].mac; |
struct Mac *mac = &pvar->ssh2_keys[MODE_OUT].mac; |
| 1036 |
unsigned int aadlen = 0, maclen = 0; |
struct Enc *enc = &pvar->ssh2_keys[MODE_OUT].enc; |
| 1037 |
|
unsigned int aadlen = 0, maclen = 0, authlen = 0; |
| 1038 |
|
|
| 1039 |
/* |
/* |
| 1040 |
データ構造 |
データ構造 |
| 1087 |
block_size = 8; |
block_size = 8; |
| 1088 |
} |
} |
| 1089 |
|
|
| 1090 |
if (mac && mac->etm) { |
if (enc) { |
| 1091 |
|
authlen = enc->auth_len; |
| 1092 |
|
} |
| 1093 |
|
|
| 1094 |
|
if (mac && mac->etm || authlen > 0) { |
| 1095 |
// 暗号化対象では無いが、MAC の対象となる部分の長さ |
// 暗号化対象では無いが、MAC の対象となる部分の長さ |
| 1096 |
aadlen = 4; |
aadlen = 4; |
| 1097 |
} |
} |
| 1112 |
|
|
| 1113 |
CRYPT_set_random_data(pvar, data + 5 + len, padding); |
CRYPT_set_random_data(pvar, data + 5 + len, padding); |
| 1114 |
|
|
| 1115 |
if (aadlen == 0) { |
if (authlen > 0) { |
| 1116 |
// E&M では先に MAC を計算する |
CRYPT_encrypt_aead(pvar, data, encryption_size, aadlen, authlen); |
| 1117 |
|
maclen = authlen; |
| 1118 |
|
} |
| 1119 |
|
else if (aadlen) { |
| 1120 |
|
// パケット暗号化 |
| 1121 |
|
CRYPT_encrypt(pvar, data + aadlen, encryption_size); |
| 1122 |
|
|
| 1123 |
|
// EtM では暗号化後に MAC を計算する |
| 1124 |
ret = CRYPT_build_sender_MAC(pvar, pvar->ssh_state.sender_sequence_number, |
ret = CRYPT_build_sender_MAC(pvar, pvar->ssh_state.sender_sequence_number, |
| 1125 |
data, encryption_size, data + encryption_size); |
data, aadlen + encryption_size, data + aadlen + encryption_size); |
| 1126 |
if (ret) { |
if (ret) { |
| 1127 |
maclen = CRYPT_get_sender_MAC_size(pvar); |
maclen = CRYPT_get_sender_MAC_size(pvar); |
| 1128 |
} |
} |
| 1129 |
} |
} |
| 1130 |
|
else { |
| 1131 |
// パケットを暗号化する。MAC以降は暗号化対象外。 |
// E&M では先に MAC を計算する |
|
CRYPT_encrypt(pvar, data + aadlen, encryption_size); |
|
|
|
|
|
if (aadlen) { |
|
|
// EtM では暗号化後に MAC を計算する |
|
| 1132 |
ret = CRYPT_build_sender_MAC(pvar, pvar->ssh_state.sender_sequence_number, |
ret = CRYPT_build_sender_MAC(pvar, pvar->ssh_state.sender_sequence_number, |
| 1133 |
data, aadlen + encryption_size, data + aadlen + encryption_size); |
data, encryption_size, data + encryption_size); |
| 1134 |
if (ret) { |
if (ret) { |
| 1135 |
maclen = CRYPT_get_sender_MAC_size(pvar); |
maclen = CRYPT_get_sender_MAC_size(pvar); |
| 1136 |
} |
} |
| 1137 |
|
|
| 1138 |
|
// パケット暗号化 |
| 1139 |
|
CRYPT_encrypt(pvar, data, encryption_size); |
| 1140 |
} |
} |
| 1141 |
|
|
| 1142 |
data_length = encryption_size + aadlen + maclen; |
data_length = encryption_size + aadlen + maclen; |
| 2134 |
} |
} |
| 2135 |
} |
} |
| 2136 |
|
|
| 2137 |
void SSH2_handle_packet(PTInstVar pvar, char *data, unsigned int len, int etm) |
void SSH2_handle_packet(PTInstVar pvar, char *data, unsigned int len, unsigned int aadlen, unsigned int authlen) |
| 2138 |
{ |
{ |
| 2139 |
unsigned char message = prep_packet_ssh2(pvar, data, len, etm); |
unsigned char message = prep_packet_ssh2(pvar, data, len, aadlen, authlen); |
| 2140 |
|
|
| 2141 |
// SSHのメッセージタイプをチェック |
// SSHのメッセージタイプをチェック |
| 2142 |
if (message != SSH_MSG_NONE) { |
if (message != SSH_MSG_NONE) { |
| 2944 |
} |
} |
| 2945 |
} |
} |
| 2946 |
|
|
| 2947 |
|
unsigned int SSH_get_authdata_size(PTInstVar pvar, int direction) |
| 2948 |
|
{ |
| 2949 |
|
if (SSHv1(pvar)) { |
| 2950 |
|
return 0; |
| 2951 |
|
} |
| 2952 |
|
else { |
| 2953 |
|
struct Mac *mac = &pvar->ssh2_keys[direction].mac; |
| 2954 |
|
struct Enc *enc = &pvar->ssh2_keys[direction].enc; |
| 2955 |
|
|
| 2956 |
|
if (enc && enc->auth_len > 0) { |
| 2957 |
|
// AEAD |
| 2958 |
|
return enc->auth_len; |
| 2959 |
|
} |
| 2960 |
|
else if (mac && mac->enabled) { |
| 2961 |
|
return mac->mac_len; |
| 2962 |
|
} |
| 2963 |
|
else { |
| 2964 |
|
return 0; |
| 2965 |
|
} |
| 2966 |
|
} |
| 2967 |
|
} |
| 2968 |
|
|
| 2969 |
void SSH_notify_user_name(PTInstVar pvar) |
void SSH_notify_user_name(PTInstVar pvar) |
| 2970 |
{ |
{ |
| 2971 |
try_send_user_name(pvar); |
try_send_user_name(pvar); |
| 4136 |
return 0; |
return 0; |
| 4137 |
} |
} |
| 4138 |
|
|
| 4139 |
|
int get_cipher_iv_len(SSHCipher cipher) |
| 4140 |
|
{ |
| 4141 |
|
ssh2_cipher_t *ptr = ssh2_ciphers; |
| 4142 |
|
|
| 4143 |
|
while (ptr->name != NULL) { |
| 4144 |
|
if (cipher == ptr->cipher) { |
| 4145 |
|
if (ptr->iv_len != 0) { |
| 4146 |
|
return ptr->iv_len; |
| 4147 |
|
} |
| 4148 |
|
else { |
| 4149 |
|
return ptr->block_size; |
| 4150 |
|
} |
| 4151 |
|
} |
| 4152 |
|
ptr++; |
| 4153 |
|
} |
| 4154 |
|
|
| 4155 |
|
// not found. |
| 4156 |
|
return 8; // block_size |
| 4157 |
|
} |
| 4158 |
|
|
| 4159 |
|
int get_cipher_auth_len(SSHCipher cipher) |
| 4160 |
|
{ |
| 4161 |
|
ssh2_cipher_t *ptr = ssh2_ciphers; |
| 4162 |
|
|
| 4163 |
|
while (ptr->name != NULL) { |
| 4164 |
|
if (cipher == ptr->cipher) { |
| 4165 |
|
return ptr->auth_len; |
| 4166 |
|
} |
| 4167 |
|
ptr++; |
| 4168 |
|
} |
| 4169 |
|
|
| 4170 |
|
// not found. |
| 4171 |
|
return 0; |
| 4172 |
|
} |
| 4173 |
|
|
| 4174 |
// 暗号アルゴリズム名から検索する。 |
// 暗号アルゴリズム名から検索する。 |
| 4175 |
SSHCipher get_cipher_by_name(char *name) |
SSHCipher get_cipher_by_name(char *name) |
| 4176 |
{ |
{ |
| 4486 |
case SSH2_CIPHER_CAMELLIA256_CTR: |
case SSH2_CIPHER_CAMELLIA256_CTR: |
| 4487 |
c_str = "camellia256-ctr,"; |
c_str = "camellia256-ctr,"; |
| 4488 |
break; |
break; |
| 4489 |
|
case SSH2_CIPHER_AES128_GCM: |
| 4490 |
|
c_str = "aes128-gcm@openssh.com,"; |
| 4491 |
|
break; |
| 4492 |
|
case SSH2_CIPHER_AES256_GCM: |
| 4493 |
|
c_str = "aes256-gcm@openssh.com,"; |
| 4494 |
|
break; |
| 4495 |
default: |
default: |
| 4496 |
continue; |
continue; |
| 4497 |
} |
} |
| 4854 |
// キーサイズとブロックサイズもここで設定しておく (2004.11.7 yutaka) |
// キーサイズとブロックサイズもここで設定しておく (2004.11.7 yutaka) |
| 4855 |
current_keys[mode].enc.key_len = get_cipher_key_len(cipher); |
current_keys[mode].enc.key_len = get_cipher_key_len(cipher); |
| 4856 |
current_keys[mode].enc.block_size = get_cipher_block_size(cipher); |
current_keys[mode].enc.block_size = get_cipher_block_size(cipher); |
| 4857 |
|
current_keys[mode].enc.iv_len = get_cipher_iv_len(cipher); |
| 4858 |
|
current_keys[mode].enc.auth_len = get_cipher_auth_len(cipher); |
| 4859 |
|
|
| 4860 |
current_keys[mode].mac.enabled = 0; |
current_keys[mode].mac.enabled = 0; |
| 4861 |
current_keys[mode].comp.enabled = 0; // (2005.7.9 yutaka) |
current_keys[mode].comp.enabled = 0; // (2005.7.9 yutaka) |
| 4862 |
|
|
| 4868 |
for (mode = 0; mode < MODE_MAX; mode++) { |
for (mode = 0; mode < MODE_MAX; mode++) { |
| 4869 |
need = max(need, current_keys[mode].enc.key_len); |
need = max(need, current_keys[mode].enc.key_len); |
| 4870 |
need = max(need, current_keys[mode].enc.block_size); |
need = max(need, current_keys[mode].enc.block_size); |
| 4871 |
|
need = max(need, current_keys[mode].enc.iv_len); |
| 4872 |
need = max(need, current_keys[mode].mac.key_len); |
need = max(need, current_keys[mode].mac.key_len); |
| 4873 |
} |
} |
| 4874 |
pvar->we_need = need; |
pvar->we_need = need; |
| 5731 |
} else { |
} else { |
| 5732 |
// 初回接続の場合は実際に暗号ルーチンが設定されるのは、あとになってから |
// 初回接続の場合は実際に暗号ルーチンが設定されるのは、あとになってから |
| 5733 |
// なので(CRYPT_start_encryption関数)、ここで鍵の設定をしてしまってもよい。 |
// なので(CRYPT_start_encryption関数)、ここで鍵の設定をしてしまってもよい。 |
|
ssh2_set_newkeys(pvar, MODE_IN); |
|
| 5734 |
ssh2_set_newkeys(pvar, MODE_OUT); |
ssh2_set_newkeys(pvar, MODE_OUT); |
| 5735 |
|
|
| 5736 |
// SSH2_MSG_NEWKEYSを送信した時点で、MACを有効にする。(2006.10.30 yutaka) |
// SSH2_MSG_NEWKEYSを送信した時点で、MACを有効にする。(2006.10.30 yutaka) |
| 5965 |
} else { |
} else { |
| 5966 |
// 初回接続の場合は実際に暗号ルーチンが設定されるのは、あとになってから |
// 初回接続の場合は実際に暗号ルーチンが設定されるのは、あとになってから |
| 5967 |
// なので(CRYPT_start_encryption関数)、ここで鍵の設定をしてしまってもよい。 |
// なので(CRYPT_start_encryption関数)、ここで鍵の設定をしてしまってもよい。 |
|
ssh2_set_newkeys(pvar, MODE_IN); |
|
| 5968 |
ssh2_set_newkeys(pvar, MODE_OUT); |
ssh2_set_newkeys(pvar, MODE_OUT); |
| 5969 |
|
|
| 5970 |
// SSH2_MSG_NEWKEYSを送信した時点で、MACを有効にする。(2006.10.30 yutaka) |
// SSH2_MSG_NEWKEYSを送信した時点で、MACを有効にする。(2006.10.30 yutaka) |
| 6196 |
} else { |
} else { |
| 6197 |
// 初回接続の場合は実際に暗号ルーチンが設定されるのは、あとになってから |
// 初回接続の場合は実際に暗号ルーチンが設定されるのは、あとになってから |
| 6198 |
// なので(CRYPT_start_encryption関数)、ここで鍵の設定をしてしまってもよい。 |
// なので(CRYPT_start_encryption関数)、ここで鍵の設定をしてしまってもよい。 |
|
ssh2_set_newkeys(pvar, MODE_IN); |
|
| 6199 |
ssh2_set_newkeys(pvar, MODE_OUT); |
ssh2_set_newkeys(pvar, MODE_OUT); |
| 6200 |
|
|
| 6201 |
// SSH2_MSG_NEWKEYSを送信した時点で、MACを有効にする。(2006.10.30 yutaka) |
// SSH2_MSG_NEWKEYSを送信した時点で、MACを有効にする。(2006.10.30 yutaka) |
| 6321 |
| 1 << SSH2_CIPHER_CAMELLIA128_CTR |
| 1 << SSH2_CIPHER_CAMELLIA128_CTR |
| 6322 |
| 1 << SSH2_CIPHER_CAMELLIA192_CTR |
| 1 << SSH2_CIPHER_CAMELLIA192_CTR |
| 6323 |
| 1 << SSH2_CIPHER_CAMELLIA256_CTR |
| 1 << SSH2_CIPHER_CAMELLIA256_CTR |
| 6324 |
|
| 1 << SSH2_CIPHER_AES128_GCM |
| 6325 |
|
| 1 << SSH2_CIPHER_AES256_GCM |
| 6326 |
); |
); |
| 6327 |
int type = (1 << SSH_AUTH_PASSWORD) | (1 << SSH_AUTH_RSA) | |
int type = (1 << SSH_AUTH_PASSWORD) | (1 << SSH_AUTH_RSA) | |
| 6328 |
(1 << SSH_AUTH_TIS) | (1 << SSH_AUTH_PAGEANT); |
(1 << SSH_AUTH_TIS) | (1 << SSH_AUTH_PAGEANT); |
| 6353 |
|
|
| 6354 |
} else { |
} else { |
| 6355 |
// SSH2_MSG_NEWKEYSを受け取った時点で、MACを有効にする。(2006.10.30 yutaka) |
// SSH2_MSG_NEWKEYSを受け取った時点で、MACを有効にする。(2006.10.30 yutaka) |
| 6356 |
|
ssh2_set_newkeys(pvar, MODE_IN); |
| 6357 |
pvar->ssh2_keys[MODE_IN].mac.enabled = 1; |
pvar->ssh2_keys[MODE_IN].mac.enabled = 1; |
| 6358 |
pvar->ssh2_keys[MODE_IN].comp.enabled = 1; |
pvar->ssh2_keys[MODE_IN].comp.enabled = 1; |
| 6359 |
|
|