scmno****@osdn*****
scmno****@osdn*****
2017年 12月 18日 (月) 19:41:06 JST
Revision: 7002 http://sourceforge.jp/projects/ttssh2/scm/svn/commits/7002 Author: doda Date: 2017-12-18 19:41:06 +0900 (Mon, 18 Dec 2017) Log Message: ----------- 暗号方式の管理を、暗号方式を表す値(SSHCipher)から ssh2_ciphers 内のエントリへのポインタを使うように変更。 これにより、暗号方式のパラメータ(ブロックサイズ等)が容易に参照できるようになる。 SSHCipher の値が欲しい時は cipher->id を使う。 Modified Paths: -------------- trunk/ttssh2/ttxssh/crypt.c trunk/ttssh2/ttxssh/keyfiles.c trunk/ttssh2/ttxssh/ssh.c trunk/ttssh2/ttxssh/ssh.h trunk/ttssh2/ttxssh/ttxssh.c trunk/ttssh2/ttxssh/ttxssh.h -------------- next part -------------- Modified: trunk/ttssh2/ttxssh/crypt.c =================================================================== --- trunk/ttssh2/ttxssh/crypt.c 2017-12-18 10:41:02 UTC (rev 7001) +++ trunk/ttssh2/ttxssh/crypt.c 2017-12-18 10:41:06 UTC (rev 7002) @@ -765,9 +765,18 @@ choose_cipher(pvar, pvar->crypt_state.supported_receiver_ciphers); } else { // SSH2(yutaka) - pvar->crypt_state.sender_cipher = pvar->ctos_cipher; - pvar->crypt_state.receiver_cipher =pvar->stoc_cipher; - + if (pvar->ciphers[MODE_OUT] == NULL) { + pvar->crypt_state.sender_cipher = SSH_CIPHER_NONE; + } + else { + pvar->crypt_state.sender_cipher = pvar->ciphers[MODE_OUT]->id; + } + if (pvar->ciphers[MODE_IN] == NULL) { + pvar->crypt_state.receiver_cipher = SSH_CIPHER_NONE; + } + else { + pvar->crypt_state.receiver_cipher = pvar->ciphers[MODE_IN]->id; + } } if (pvar->crypt_state.sender_cipher == SSH_CIPHER_NONE @@ -1060,36 +1069,39 @@ struct Enc *enc; char *encryption_key = pvar->crypt_state.sender_cipher_key; char *decryption_key = pvar->crypt_state.receiver_cipher_key; - int cipher; + ssh2_cipher_t *cipher; BOOL isOK = TRUE; if (sender_flag) { - cipher = pvar->crypt_state.sender_cipher; - switch (cipher) { - case SSH_CIPHER_3DES: - c3DES_init(encryption_key, &pvar->crypt_state.enc.c3DES); - pvar->crypt_state.encrypt = c3DES_encrypt; - break; + if (SSHv1(pvar)) { + switch (pvar->crypt_state.sender_cipher) { + case SSH_CIPHER_3DES: + c3DES_init(encryption_key, &pvar->crypt_state.enc.c3DES); + pvar->crypt_state.encrypt = c3DES_encrypt; + break; - case SSH_CIPHER_DES: - cDES_init(encryption_key, &pvar->crypt_state.enc.cDES); - pvar->crypt_state.encrypt = cDES_encrypt; - break; + case SSH_CIPHER_DES: + cDES_init(encryption_key, &pvar->crypt_state.enc.cDES); + pvar->crypt_state.encrypt = cDES_encrypt; + break; - case SSH_CIPHER_BLOWFISH: - cBlowfish_init(encryption_key, &pvar->crypt_state.enc.cBlowfish); - pvar->crypt_state.encrypt = cBlowfish_encrypt; - break; + case SSH_CIPHER_BLOWFISH: + cBlowfish_init(encryption_key, &pvar->crypt_state.enc.cBlowfish); + pvar->crypt_state.encrypt = cBlowfish_encrypt; + break; - case SSH_CIPHER_NONE: - case SSH_CIPHER_IDEA: - case SSH_CIPHER_TSS: - case SSH_CIPHER_RC4: - isOK = FALSE; - break; - - default: // SSH2 - if (cipher <= SSH_CIPHER_MAX) { + case SSH_CIPHER_NONE: + case SSH_CIPHER_IDEA: + case SSH_CIPHER_TSS: + case SSH_CIPHER_RC4: + isOK = FALSE; + break; + } + } + else { + // SSH2 + cipher = pvar->ciphers[MODE_OUT]; + if (cipher) { enc = &pvar->ssh2_keys[MODE_OUT].enc; cipher_init_SSH2(&pvar->evpcip[MODE_OUT], enc->key, get_cipher_key_len(cipher), @@ -1105,37 +1117,39 @@ else { isOK = FALSE; } - break; } } if (receiver_flag) { - cipher = pvar->crypt_state.receiver_cipher; - switch (cipher) { - case SSH_CIPHER_3DES: - c3DES_init(decryption_key, &pvar->crypt_state.dec.c3DES); - pvar->crypt_state.decrypt = c3DES_decrypt; - break; + if (SSHv1(pvar)) { + switch (pvar->crypt_state.receiver_cipher) { + case SSH_CIPHER_3DES: + c3DES_init(decryption_key, &pvar->crypt_state.dec.c3DES); + pvar->crypt_state.decrypt = c3DES_decrypt; + break; - case SSH_CIPHER_DES: - cDES_init(decryption_key, &pvar->crypt_state.dec.cDES); - pvar->crypt_state.decrypt = cDES_decrypt; - break; + case SSH_CIPHER_DES: + cDES_init(decryption_key, &pvar->crypt_state.dec.cDES); + pvar->crypt_state.decrypt = cDES_decrypt; + break; - case SSH_CIPHER_BLOWFISH: - cBlowfish_init(decryption_key, &pvar->crypt_state.dec.cBlowfish); - pvar->crypt_state.decrypt = cBlowfish_decrypt; - break; + case SSH_CIPHER_BLOWFISH: + cBlowfish_init(decryption_key, &pvar->crypt_state.dec.cBlowfish); + pvar->crypt_state.decrypt = cBlowfish_decrypt; + break; - case SSH_CIPHER_NONE: - case SSH_CIPHER_IDEA: - case SSH_CIPHER_TSS: - case SSH_CIPHER_RC4: - isOK = FALSE; - break; - - default: // SSH2 - if (cipher <= SSH_CIPHER_MAX) { + case SSH_CIPHER_NONE: + case SSH_CIPHER_IDEA: + case SSH_CIPHER_TSS: + case SSH_CIPHER_RC4: + isOK = FALSE; + break; + } + } + else { + // SSH2 + cipher = pvar->ciphers[MODE_IN]; + if (cipher) { enc = &pvar->ssh2_keys[MODE_IN].enc; cipher_init_SSH2(&pvar->evpcip[MODE_IN], enc->key, get_cipher_key_len(cipher), @@ -1151,7 +1165,6 @@ else { isOK = FALSE; } - break; } } Modified: trunk/ttssh2/ttxssh/keyfiles.c =================================================================== --- trunk/ttssh2/ttxssh/keyfiles.c 2017-12-18 10:41:02 UTC (rev 7001) +++ trunk/ttssh2/ttxssh/keyfiles.c 2017-12-18 10:41:06 UTC (rev 7002) @@ -371,7 +371,7 @@ unsigned int len, klen, nkeys, blocksize, keylen, ivlen, slen, rounds; unsigned int check1, check2, m1len, m2len; int dlen, i; - SSHCipher ciphernameval; + ssh2_cipher_t *cipher; size_t authlen; EVP_CIPHER_CTX cipher_ctx; @@ -452,8 +452,8 @@ */ // \x88Í\x86\x89\xBB\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82̖\xBC\x91O ciphername = buffer_get_string_msg(copy_consumed, NULL); - ciphernameval = get_cipher_by_name(ciphername); - if (ciphernameval == SSH_CIPHER_NONE && strcmp(ciphername, "none") != 0) { + cipher = get_cipher_by_name(ciphername); + if (cipher->id == SSH_CIPHER_NONE && strcmp(ciphername, "none") != 0) { logprintf(LOG_LEVEL_ERROR, "%s: unknown cipher name", __FUNCTION__); goto error; } @@ -509,7 +509,7 @@ /* size of encrypted key blob */ len = buffer_get_int(copy_consumed); - blocksize = get_cipher_block_size(ciphernameval); + blocksize = get_cipher_block_size(cipher); authlen = 0; // TODO: \x82Ƃ肠\x82\xA6\x82\xB8\x8CŒ艻 if (len < blocksize) { logprintf(LOG_LEVEL_ERROR, __FUNCTION__ ": encrypted data too small"); @@ -521,7 +521,7 @@ } /* setup key */ - keylen = get_cipher_key_len(ciphernameval); + keylen = get_cipher_key_len(cipher); ivlen = blocksize; key = calloc(1, keylen + ivlen); if (!strcmp(kdfname, KDFNAME)) { @@ -542,7 +542,7 @@ // \x95\x9C\x8D\x86\x89\xBB cp = buffer_append_space(b, len); cipher_init_SSH2(&cipher_ctx, key, keylen, key + keylen, ivlen, CIPHER_DECRYPT, - get_cipher_EVP_CIPHER(ciphernameval), 0, 0, pvar); + get_cipher_EVP_CIPHER(cipher), 0, 0, pvar); if (EVP_Cipher(&cipher_ctx, cp, buffer_tail_ptr(copy_consumed), len) == 0) { cipher_cleanup_SSH2(&cipher_ctx); goto error; Modified: trunk/ttssh2/ttxssh/ssh.c =================================================================== --- trunk/ttssh2/ttxssh/ssh.c 2017-12-18 10:41:02 UTC (rev 7001) +++ trunk/ttssh2/ttxssh/ssh.c 2017-12-18 10:41:06 UTC (rev 7002) @@ -4091,134 +4091,96 @@ // general // -int get_cipher_block_size(SSHCipher cipher) +int get_cipher_block_size(ssh2_cipher_t *cipher) { - ssh2_cipher_t *ptr = ssh2_ciphers; - - while (ptr->name != NULL) { - if (cipher == ptr->cipher) { - return ptr->block_size; - } - ptr++; + int blocksize = 0; + + if (cipher) { + blocksize = cipher->block_size; } - // not found. - return 8; + return max(blocksize, 8); } -int get_cipher_key_len(SSHCipher cipher) +int get_cipher_key_len(ssh2_cipher_t *cipher) { - ssh2_cipher_t *ptr = ssh2_ciphers; - - while (ptr->name != NULL) { - if (cipher == ptr->cipher) { - return ptr->key_len; - } - ptr++; + if (cipher) { + return cipher->key_len; } - - // not found. - return 0; + else { + return 0; + } } -int get_cipher_discard_len(SSHCipher cipher) +int get_cipher_discard_len(ssh2_cipher_t *cipher) { - ssh2_cipher_t *ptr = ssh2_ciphers; - - while (ptr->name != NULL) { - if (cipher == ptr->cipher) { - return ptr->discard_len; - } - ptr++; + if (cipher) { + return cipher->discard_len; } - - // not found. - return 0; + else { + return 0; + } } -int get_cipher_iv_len(SSHCipher cipher) +int get_cipher_iv_len(ssh2_cipher_t *cipher) { - ssh2_cipher_t *ptr = ssh2_ciphers; - - while (ptr->name != NULL) { - if (cipher == ptr->cipher) { - if (ptr->iv_len != 0) { - return ptr->iv_len; - } - else { - return ptr->block_size; - } + if (cipher) { + if (cipher->iv_len != 0) { + return cipher->iv_len; } - ptr++; + else { + return cipher->block_size; + } } - - // not found. - return 8; // block_size + else { + return 8; // block_size + } } -int get_cipher_auth_len(SSHCipher cipher) +int get_cipher_auth_len(ssh2_cipher_t *cipher) { - ssh2_cipher_t *ptr = ssh2_ciphers; - - while (ptr->name != NULL) { - if (cipher == ptr->cipher) { - return ptr->auth_len; - } - ptr++; + if (cipher) { + return cipher->auth_len; } - - // not found. - return 0; + else { + return 0; + } } // \x88Í\x86\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x96\xBC\x82\xA9\x82猟\x8D\x{142DC2}\xE9\x81B -SSHCipher get_cipher_by_name(char *name) +ssh2_cipher_t *get_cipher_by_name(char *name) { ssh2_cipher_t *ptr = ssh2_ciphers; - if (name == NULL) - goto error; - while (ptr->name != NULL) { - if (strcmp(ptr->name, name) == 0) { - return ptr->cipher; + if (name != NULL && strcmp(ptr->name, name) == 0) { + return ptr; } ptr++; } // not found. -error: - return SSH_CIPHER_NONE; + return ptr; } -static char * get_cipher_string(SSHCipher cipher) +static char * get_cipher_string(ssh2_cipher_t *cipher) { - ssh2_cipher_t *ptr = ssh2_ciphers; - - while (ptr->name != NULL) { - if (cipher == ptr->cipher) { - return ptr->name; - } - ptr++; + if (cipher) { + return cipher->name; } - - // not found. - return "unknown"; + else { + return "unknown"; + } } -const EVP_CIPHER* get_cipher_EVP_CIPHER(SSHCipher cipher) +const EVP_CIPHER* get_cipher_EVP_CIPHER(ssh2_cipher_t *cipher) { - ssh2_cipher_t *ptr = ssh2_ciphers; - - while (ptr->name != NULL) { - if (cipher == ptr->cipher) { - return ptr->func(); - } - ptr++; + if (cipher) { + return cipher->func(); } - - // not found. - return EVP_enc_null(); + else { + return EVP_enc_null(); + } } char* get_kex_algorithm_name(kex_algorithm kextype) @@ -4711,7 +4673,6 @@ { char tmp_cli[1024], *ptr_cli, *ctc_cli; char tmp_svr[1024], *ptr_svr, *ctc_svr; - SSHCipher cipher = SSH_CIPHER_NONE; strncpy_s(tmp_cli, sizeof(tmp_cli), my_proposal, _TRUNCATE); ptr_cli = strtok_s(tmp_cli, ",", &ctc_cli); @@ -4756,23 +4717,13 @@ return (type); } -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) { - SSHCipher cipher = SSH_CIPHER_NONE; char str_cipher[32]; ssh2_cipher_t *ptr = ssh2_ciphers; choose_SSH2_proposal(server_proposal, my_proposal, str_cipher, sizeof(str_cipher)); - - while (ptr->name != NULL) { - if (strcmp(ptr->name, str_cipher) == 0) { - cipher = ptr->cipher; - break; - } - ptr++; - } - - return (cipher); + return get_cipher_by_name(str_cipher); } @@ -4828,19 +4779,19 @@ int mode, val; unsigned int need = 0; const EVP_MD *md; - SSHCipher cipher; + ssh2_cipher_t *cipher; hmac_type mac; for (mode = 0; mode < MODE_MAX; mode++) { if (mode == MODE_OUT) { mac = pvar->ctos_hmac; - cipher = pvar->ctos_cipher; } else { mac = pvar->stoc_hmac; - cipher = pvar->stoc_cipher; } + cipher = pvar->ciphers[mode]; + // current_keys[]\x82ɐݒ肵\x82Ă\xA8\x82\xA2\x82āA\x82\xA0\x82Ƃ\xC5 pvar->ssh2_keys[] \x82փR\x83s\x81[\x82\xB7\x82\xE9\x81B md = get_ssh2_mac_EVP_MD(mac); current_keys[mode].mac.md = md; @@ -4997,8 +4948,8 @@ logprintf(LOG_LEVEL_VERBOSE, "server proposal: encryption algorithm client to server: %s", buf); - pvar->ctos_cipher = choose_SSH2_cipher_algorithm(buf, myproposal[PROPOSAL_ENC_ALGS_CTOS]); - if (pvar->ctos_cipher == SSH_CIPHER_NONE) { + pvar->ciphers[MODE_OUT] = choose_SSH2_cipher_algorithm(buf, myproposal[PROPOSAL_ENC_ALGS_CTOS]); + if (pvar->ciphers[MODE_OUT]->id == SSH_CIPHER_NONE) { strncpy_s(tmp, sizeof(tmp), "unknown Encrypt algorithm(ctos): ", _TRUNCATE); strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE); msg = tmp; @@ -5017,8 +4968,8 @@ logprintf(LOG_LEVEL_VERBOSE, "server proposal: encryption algorithm server to client: %s", buf); - pvar->stoc_cipher = choose_SSH2_cipher_algorithm(buf, myproposal[PROPOSAL_ENC_ALGS_STOC]); - if (pvar->stoc_cipher == SSH_CIPHER_NONE) { + pvar->ciphers[MODE_IN] = choose_SSH2_cipher_algorithm(buf, myproposal[PROPOSAL_ENC_ALGS_STOC]); + if (pvar->ciphers[MODE_IN]->id == SSH_CIPHER_NONE) { strncpy_s(tmp, sizeof(tmp), "unknown Encrypt algorithm(stoc): ", _TRUNCATE); strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE); msg = tmp; @@ -5116,11 +5067,11 @@ logprintf(LOG_LEVEL_VERBOSE, "encryption algorithm client to server: %s", - get_cipher_string(pvar->ctos_cipher)); + get_cipher_string(pvar->ciphers[MODE_OUT])); logprintf(LOG_LEVEL_VERBOSE, "encryption algorithm server to client: %s", - get_cipher_string(pvar->stoc_cipher)); + get_cipher_string(pvar->ciphers[MODE_IN])); logprintf(LOG_LEVEL_VERBOSE, "MAC algorithm client to server: %s", Modified: trunk/ttssh2/ttxssh/ssh.h =================================================================== --- trunk/ttssh2/ttxssh/ssh.h 2017-12-18 10:41:02 UTC (rev 7001) +++ trunk/ttssh2/ttxssh/ssh.h 2017-12-18 10:41:06 UTC (rev 7002) @@ -376,7 +376,7 @@ typedef struct ssh2_cipher { - SSHCipher cipher; + SSHCipher id; char *name; int block_size; int key_len; @@ -773,13 +773,13 @@ BOOL do_SSH2_userauth(PTInstVar pvar); BOOL do_SSH2_authrequest(PTInstVar pvar); void debug_print(int no, char *msg, int len); -int get_cipher_block_size(SSHCipher cipher); -int get_cipher_key_len(SSHCipher cipher); -int get_cipher_iv_len(SSHCipher cipher); -int get_cipher_auth_len(SSHCipher cipher); -SSHCipher get_cipher_by_name(char *name); +int get_cipher_block_size(ssh2_cipher_t *cipher); +int get_cipher_key_len(ssh2_cipher_t *cipher); +int get_cipher_iv_len(ssh2_cipher_t *cipher); +int get_cipher_auth_len(ssh2_cipher_t *cipher); +ssh2_cipher_t *get_cipher_by_name(char *name); char* get_kex_algorithm_name(kex_algorithm kextype); -const EVP_CIPHER* get_cipher_EVP_CIPHER(SSHCipher cipher); +const EVP_CIPHER* get_cipher_EVP_CIPHER(ssh2_cipher_t *cipher); const EVP_MD* get_kex_algorithm_EVP_MD(kex_algorithm kextype); char* get_ssh2_mac_name(hmac_type type); const EVP_MD* get_ssh2_mac_EVP_MD(hmac_type type); @@ -787,7 +787,7 @@ char* get_ssh2_comp_name(compression_type type); char* get_ssh_keytype_name(ssh_keytype type); char* get_digest_algorithm_name(digest_algorithm id); -int get_cipher_discard_len(SSHCipher cipher); +int get_cipher_discard_len(ssh2_cipher_t *cipher); void ssh_heartbeat_lock_initialize(void); void ssh_heartbeat_lock_finalize(void); void ssh_heartbeat_lock(void); Modified: trunk/ttssh2/ttxssh/ttxssh.c =================================================================== --- trunk/ttssh2/ttxssh/ttxssh.c 2017-12-18 10:41:02 UTC (rev 7001) +++ trunk/ttssh2/ttxssh/ttxssh.c 2017-12-18 10:41:06 UTC (rev 7002) @@ -4128,7 +4128,7 @@ // based on OpenSSH 6.5:key_save_private(), key_private_to_blob2() static void save_bcrypt_private_key(char *passphrase, char *filename, char *comment, HWND dlg, PTInstVar pvar, int rounds) { - SSHCipher ciphernameval = SSH_CIPHER_NONE; + ssh2_cipher_t *cipher = NULL; char *ciphername = DEFAULT_CIPHERNAME; buffer_t *b = NULL; buffer_t *kdf = NULL; @@ -4156,9 +4156,9 @@ kdfname = "none"; } - ciphernameval = get_cipher_by_name(ciphername); - blocksize = get_cipher_block_size(ciphernameval); - keylen = get_cipher_key_len(ciphernameval); + cipher = get_cipher_by_name(ciphername); + blocksize = get_cipher_block_size(cipher); + keylen = get_cipher_key_len(cipher); ivlen = blocksize; authlen = 0; // TODO: \x82Ƃ肠\x82\xA6\x82\xB8\x8CŒ艻 key = calloc(1, keylen + ivlen); @@ -4176,7 +4176,7 @@ // TODO: OpenSSH 6.5\x82ł\xCD -Z \x83I\x83v\x83V\x83\x87\x83\x93\x82ŁA\x88Í\x86\x89\xBB\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82\xF0\x8Ew\x92\xE8\x89\\x82\xBE\x82\xAA\x81A // \x82\xB1\x82\xB1\x82ł\xCD"AES256-CBC"\x82ɌŒ\xE8\x82Ƃ\xB7\x82\xE9\x81B cipher_init_SSH2(&cipher_ctx, key, keylen, key + keylen, ivlen, CIPHER_ENCRYPT, - get_cipher_EVP_CIPHER(ciphernameval), 0, 0, pvar); + get_cipher_EVP_CIPHER(cipher), 0, 0, pvar); SecureZeroMemory(key, keylen + ivlen); free(key); Modified: trunk/ttssh2/ttxssh/ttxssh.h =================================================================== --- trunk/ttssh2/ttxssh/ttxssh.h 2017-12-18 10:41:02 UTC (rev 7001) +++ trunk/ttssh2/ttxssh/ttxssh.h 2017-12-18 10:41:06 UTC (rev 7002) @@ -257,8 +257,7 @@ buffer_t *peer_kex; kex_algorithm kex_type; // KEX algorithm ssh_keytype hostkey_type; - SSHCipher ctos_cipher; - SSHCipher stoc_cipher; + ssh2_cipher_t *ciphers[MODE_MAX]; hmac_type ctos_hmac; hmac_type stoc_hmac; compression_type ctos_compression;