svnno****@sourc*****
svnno****@sourc*****
2015年 11月 13日 (金) 14:06:34 JST
Revision: 6120 http://sourceforge.jp/projects/ttssh2/scm/svn/commits/6120 Author: maya Date: 2015-11-13 14:06:34 +0900 (Fri, 13 Nov 2015) Log Message: ----------- SSH key fingerprint の 出力時に、使用しているハッシュアルゴリズム名を表示するようにした Modified Paths: -------------- trunk/ttssh2/ttxssh/dns.c trunk/ttssh2/ttxssh/hosts.c trunk/ttssh2/ttxssh/key.c trunk/ttssh2/ttxssh/key.h trunk/ttssh2/ttxssh/ssh.c trunk/ttssh2/ttxssh/ssh.h trunk/ttssh2/ttxssh/ttxssh.c -------------- next part -------------- Modified: trunk/ttssh2/ttxssh/dns.c =================================================================== --- trunk/ttssh2/ttxssh/dns.c 2015-11-12 15:04:55 UTC (rev 6119) +++ trunk/ttssh2/ttxssh/dns.c 2015-11-13 05:06:34 UTC (rev 6120) @@ -56,7 +56,8 @@ DNS_STATUS status; PDNS_RECORD rec, p; PDNS_SSHFP_DATA t; - int hostkey_alg, hostkey_dtype, hostkey_dlen, fp_type; + int hostkey_alg, hostkey_dtype, hostkey_dlen; + digest_algorithm dgst_alg; BYTE *hostkey_digest = NULL; int found = DNS_VERIFY_NOTFOUND; OSVERSIONINFO osvi; @@ -112,25 +113,25 @@ "Algorithm = %d, Digest type = %d", t->Algorithm, t->DigestType); - fp_type = -1; + dgst_alg = -1; } else { - fp_type = SSH_FP_SHA1; + dgst_alg = SSH_DIGEST_SHA1; } break; case SSHFP_HASH_SHA256: - fp_type = SSH_FP_SHA256; + dgst_alg = SSH_DIGEST_SHA256; break; default: - fp_type = -1; + dgst_alg = -1; } - if (fp_type == -1) + if (dgst_alg == -1) continue; // skip invalid/un-supported hash type. hostkey_dtype = t->DigestType; free(hostkey_digest); - hostkey_digest = key_fingerprint_raw(key, fp_type, &hostkey_dlen); + hostkey_digest = key_fingerprint_raw(key, dgst_alg, &hostkey_dlen); if (!hostkey_digest) continue; } Modified: trunk/ttssh2/ttxssh/hosts.c =================================================================== --- trunk/ttssh2/ttxssh/hosts.c 2015-11-12 15:04:55 UTC (rev 6119) +++ trunk/ttssh2/ttxssh/hosts.c 2015-11-13 05:06:34 UTC (rev 6120) @@ -1097,12 +1097,12 @@ SetDlgItemText(dlg, IDC_HOSTWARNING, buf2); // fingerprint\x82\xF0\x90ݒ肷\x82\xE9 - fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX, SSH_FP_MD5); + fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX, SSH_DIGEST_MD5); SendMessage(GetDlgItem(dlg, IDC_FINGER_PRINT), WM_SETTEXT, 0, (LPARAM)fp); free(fp); // \x83r\x83W\x83\x85\x83A\x83\x8B\x89\xBBfingerprint\x82\xF0\x95\\x8E\xA6\x82\xB7\x82\xE9 - fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART, SSH_FP_MD5); + fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART, SSH_DIGEST_MD5); SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETTEXT, 0, (LPARAM)fp); SendMessage(GetDlgItem(dlg, IDC_FP_RANDOMART), WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), TRUE); free(fp); Modified: trunk/ttssh2/ttxssh/key.c =================================================================== --- trunk/ttssh2/ttxssh/key.c 2015-11-12 15:04:55 UTC (rev 6119) +++ trunk/ttssh2/ttxssh/key.c 2015-11-13 05:06:34 UTC (rev 6120) @@ -548,7 +548,7 @@ } -char* key_fingerprint_raw(Key *k, enum fp_type dgst_type, int *dgst_raw_length) +char* key_fingerprint_raw(Key *k, enum digest_algorithm dgst_alg, int *dgst_raw_length) { const EVP_MD *md = NULL; EVP_MD_CTX ctx; @@ -560,14 +560,14 @@ *dgst_raw_length = 0; - switch (dgst_type) { - case SSH_FP_MD5: + switch (dgst_alg) { + case SSH_DIGEST_MD5: md = EVP_md5(); break; - case SSH_FP_SHA1: + case SSH_DIGEST_SHA1: md = EVP_sha1(); break; - case SSH_FP_SHA256: + case SSH_DIGEST_SHA256: md = EVP_sha256(); break; default: @@ -603,7 +603,7 @@ break; default: - //fatal("key_fingerprint_raw: bad key type %d", k->type); + //fatal("key_fingerprint_raw: bad key type %d", dgst_alg); break; } @@ -667,18 +667,22 @@ return 0; } +// based on OpenSSH 7.1 static char * -key_fingerprint_b64(u_char *dgst_raw, u_int dgst_raw_len) +key_fingerprint_b64(const char *alg, u_char *dgst_raw, u_int dgst_raw_len) { char *retval; unsigned int i, retval_len; BIO *bio, *b64; BUF_MEM *bufferPtr; - retval_len = ((dgst_raw_len + 2) / 3) * 4 + 1; + retval_len = strlen(alg) + 1 + ((dgst_raw_len + 2) / 3) * 4 + 1; retval = malloc(retval_len); retval[0] = '\0'; + strncat_s(retval, retval_len, alg, _TRUNCATE); + strncat_s(retval, retval_len, ":", _TRUNCATE); + b64 = BIO_new(BIO_f_base64()); bio = BIO_new(BIO_s_mem()); bio = BIO_push(b64, bio); @@ -700,14 +704,18 @@ } static char * -key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len) +key_fingerprint_hex(const char *alg, u_char *dgst_raw, u_int dgst_raw_len) { char *retval; unsigned int i, retval_len; - retval_len = dgst_raw_len * 3 + 1; + retval_len = strlen(alg) + 1 + dgst_raw_len * 3 + 1; retval = malloc(retval_len); retval[0] = '\0'; + + strncat_s(retval, retval_len, alg, _TRUNCATE); + strncat_s(retval, retval_len, ":", _TRUNCATE); + for (i = 0; i < dgst_raw_len; i++) { char hex[4]; _snprintf_s(hex, sizeof(hex), _TRUNCATE, "%02x:", dgst_raw[i]); @@ -720,25 +728,25 @@ return (retval); } -// based on OpenSSH 5.1 #define FLDBASE 8 #define FLDSIZE_Y (FLDBASE + 1) #define FLDSIZE_X (FLDBASE * 2 + 1) static char * -key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k) +key_fingerprint_randomart(const char *alg, u_char *dgst_raw, u_int dgst_raw_len, const Key *k) { /* - * Chars to be used after each other every time the worm - * intersects with itself. Matter of taste. - */ + * Chars to be used after each other every time the worm + * intersects with itself. Matter of taste. + */ char *augmentation_string = " .o+=*BOX@%&#/^SE"; - char *retval, *p; + char *retval, *p, title[FLDSIZE_X], hash[FLDSIZE_X]; unsigned char field[FLDSIZE_X][FLDSIZE_Y]; - unsigned int i, b; - int x, y; + size_t i, tlen, hlen; + unsigned int b; + int x, y, r; size_t len = strlen(augmentation_string) - 1; - retval = calloc(1, (FLDSIZE_X + 3 + 1) * (FLDSIZE_Y + 2)); + retval = calloc((FLDSIZE_X + 3 + 1), (FLDSIZE_Y + 2)); /* initialize field */ memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char)); @@ -762,7 +770,8 @@ y = min(y, FLDSIZE_Y - 1); /* augment the field */ - field[x][y]++; + if (field[x][y] < len - 2) + field[x][y]++; input = input >> 2; } } @@ -771,13 +780,28 @@ field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1; field[x][y] = len; - /* fill in retval */ - _snprintf_s(retval, FLDSIZE_X, _TRUNCATE, "+--[%4s %4u]", ssh_key_type(k->type), key_size(k)); - p = strchr(retval, '\0'); + /* assemble title */ + r = _snprintf_s(title, sizeof(title), _TRUNCATE, "[%s %u]", + ssh_key_type(k->type), key_size(k)); + /* If [type size] won't fit, then try [type]; fits "[ED25519-CERT]" */ + if (r < 0 || r >(int)sizeof(title)) + r = _snprintf_s(title, sizeof(title), _TRUNCATE, "[%s]", + ssh_key_type(k->type)); + tlen = (r <= 0) ? 0 : strlen(title); + /* assemble hash ID. */ + r = _snprintf_s(hash, sizeof(hash), _TRUNCATE, "[%s]", alg); + hlen = (r <= 0) ? 0 : strlen(hash); + /* output upper border */ - for (i = p - retval - 1; i < FLDSIZE_X; i++) + p = retval; + *p++ = '+'; + for (i = 0; i < (FLDSIZE_X - tlen) / 2; i++) *p++ = '-'; + memcpy(p, title, tlen); + p += tlen; + for (i += tlen; i < FLDSIZE_X; i++) + *p++ = '-'; *p++ = '+'; *p++ = '\r'; *p++ = '\n'; @@ -794,8 +818,12 @@ /* output lower border */ *p++ = '+'; - for (i = 0; i < FLDSIZE_X; i++) + for (i = 0; i < (FLDSIZE_X - hlen) / 2; i++) *p++ = '-'; + memcpy(p, hash, hlen); + p += hlen; + for (i += hlen; i < FLDSIZE_X; i++) + *p++ = '-'; *p++ = '+'; return retval; @@ -807,26 +835,28 @@ // // fingerprint\x81i\x8Ew\x96\xE4\x81F\x83z\x83X\x83g\x8C\xF6\x8AJ\x8C\xAE\x82̃n\x83b\x83V\x83\x85\x81j\x82\xAC\x82\xB7\x82\xE9 // -char *key_fingerprint(Key *key, enum fp_rep dgst_rep, enum fp_type dgst_type) +char *key_fingerprint(Key *key, enum fp_rep dgst_rep, enum digest_algorithm dgst_alg) { - char *retval = NULL; + char *retval = NULL, *alg; unsigned char *dgst_raw; int dgst_raw_len; // fingerprint\x82̃n\x83b\x83V\x83\x85\x92l\x81i\x83o\x83C\x83i\x83\x8A\x81j\x82\xF0\x8B\x81\x82߂\xE9 - dgst_raw = key_fingerprint_raw(key, dgst_type, &dgst_raw_len); + dgst_raw = key_fingerprint_raw(key, dgst_alg, &dgst_raw_len); if (dgst_raw == NULL) return NULL; + alg = get_digest_algorithm_name(dgst_alg); + switch (dgst_rep) { case SSH_FP_HEX: - retval = key_fingerprint_hex(dgst_raw, dgst_raw_len); + retval = key_fingerprint_hex(alg, dgst_raw, dgst_raw_len); break; case SSH_FP_BASE64: - retval = key_fingerprint_b64(dgst_raw, dgst_raw_len); + retval = key_fingerprint_b64(alg, dgst_raw, dgst_raw_len); break; case SSH_FP_RANDOMART: - retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, key); + retval = key_fingerprint_randomart(alg, dgst_raw, dgst_raw_len, key); break; } @@ -1998,7 +2028,7 @@ for (i = 0; i < ctx->nkeys; i++) { if (ctx->keys_seen[i]) continue; - fp = key_fingerprint(ctx->keys[i], SSH_FP_HEX, SSH_FP_MD5); + fp = key_fingerprint(ctx->keys[i], SSH_FP_HEX, SSH_DIGEST_MD5); buf[0] = 0; strcat_s(buf, sizeof(buf), get_sshname_from_key(ctx->keys[i])); strcat_s(buf, sizeof(buf), " "); @@ -2013,7 +2043,7 @@ _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, ctx->nold); SetDlgItemText(dlg, IDC_REMOVEKEY_TEXT, buf); for (i = 0; i < ctx->nold; i++) { - fp = key_fingerprint(ctx->old_keys[i], SSH_FP_HEX, SSH_FP_MD5); + fp = key_fingerprint(ctx->old_keys[i], SSH_FP_HEX, SSH_DIGEST_MD5); buf[0] = 0; strcat_s(buf, sizeof(buf), get_sshname_from_key(ctx->old_keys[i])); strcat_s(buf, sizeof(buf), " "); @@ -2271,7 +2301,7 @@ free(blob); blob = NULL; - fp = key_fingerprint(key, SSH_FP_HEX, SSH_FP_MD5); + fp = key_fingerprint(key, SSH_FP_HEX, SSH_DIGEST_MD5); _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Received %s host key %s", get_sshname_from_key(key), fp); notify_verbose_message(pvar, msg, LOG_LEVEL_VERBOSE); Modified: trunk/ttssh2/ttxssh/key.h =================================================================== --- trunk/ttssh2/ttxssh/key.h 2015-11-12 15:04:55 UTC (rev 6119) +++ trunk/ttssh2/ttxssh/key.h 2015-11-13 05:06:34 UTC (rev 6120) @@ -42,7 +42,7 @@ DSA *duplicate_DSA(DSA *src); unsigned char *duplicate_ED25519_PK(unsigned char *src); -char *key_fingerprint_raw(Key *k, enum fp_type dgst_type, int *dgst_raw_length); +char *key_fingerprint_raw(Key *k, enum digest_algorithm dgst_alg, int *dgst_raw_length); char *key_fingerprint(Key *key, enum fp_rep dgst_rep, enum fp_type dgst_type); const char *ssh_key_type(ssh_keytype type); Modified: trunk/ttssh2/ttxssh/ssh.c =================================================================== --- trunk/ttssh2/ttxssh/ssh.c 2015-11-12 15:04:55 UTC (rev 6119) +++ trunk/ttssh2/ttxssh/ssh.c 2015-11-13 05:06:34 UTC (rev 6120) @@ -4271,7 +4271,21 @@ return p; } +char* get_digest_algorithm_name(digest_algorithm id) +{ + ssh_digest_t *ptr = ssh_digests; + static char buf[16]; + while (ptr->name != NULL) { + if (id == ptr->id) { + strncpy_s(buf, sizeof(buf), ptr->name, _TRUNCATE); + break; + } + ptr++; + } + return buf; +} + static void do_write_buffer_file(void *buf, int len, char *file, int lineno) { FILE *fp; Modified: trunk/ttssh2/ttxssh/ssh.h =================================================================== --- trunk/ttssh2/ttxssh/ssh.h 2015-11-12 15:04:55 UTC (rev 6119) +++ trunk/ttssh2/ttxssh/ssh.h 2015-11-13 05:06:34 UTC (rev 6120) @@ -535,13 +535,39 @@ SSH_FP_BUBBLEBABBLE, SSH_FP_RANDOMART }; - +/* enum fp_type { SSH_FP_MD5, SSH_FP_SHA1, SSH_FP_SHA256 }; +*/ +typedef enum { + SSH_DIGEST_MD5, + SSH_DIGEST_RIPEMD160, + SSH_DIGEST_SHA1, + SSH_DIGEST_SHA256, + SSH_DIGEST_SHA384, + SSH_DIGEST_SHA512, + SSH_DIGEST_MAX, +} digest_algorithm; +typedef struct ssh_digest { + digest_algorithm id; + const char *name; +} ssh_digest_t; + +/* NB. Indexed directly by algorithm number */ +static ssh_digest_t ssh_digests[] = { + { SSH_DIGEST_MD5, "MD5" }, + { SSH_DIGEST_RIPEMD160, "RIPEMD160" }, + { SSH_DIGEST_SHA1, "SHA1" }, + { SSH_DIGEST_SHA256, "SHA256" }, + { SSH_DIGEST_SHA384, "SHA384" }, + { SSH_DIGEST_SHA512, "SHA512" }, + { SSH_DIGEST_MAX, NULL }, +}; + enum scp_dir { TOREMOTE, FROMREMOTE, }; @@ -690,6 +716,7 @@ int get_ssh2_mac_truncatebits(hmac_type type); 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); void ssh_heartbeat_lock_initialize(void); void ssh_heartbeat_lock_finalize(void); Modified: trunk/ttssh2/ttxssh/ttxssh.c =================================================================== --- trunk/ttssh2/ttxssh/ttxssh.c 2015-11-12 15:04:55 UTC (rev 6119) +++ trunk/ttssh2/ttxssh/ttxssh.c 2015-11-13 05:06:34 UTC (rev 6120) @@ -2747,12 +2747,12 @@ // \x83z\x83X\x83g\x8C\xF6\x8AJ\x8C\xAE\x82\xCCfingerprint\x82\xF0\x95\\x8E\xA6\x82\xB7\x82\xE9\x81B // Random art\x82̕\\x8E\xA6\x82\xAA\x95\xF6\x82\xEA\x82Ă\xB5\x82܂\xA4\x82̂\xAA\x89ۑ\xE8\x81B // (2014.5.1 yutaka) - fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX, SSH_FP_MD5); + fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_HEX, SSH_DIGEST_MD5); UTIL_get_lang_msg("DLG_ABOUT_FINGERPRINT", pvar, "Host key's fingerprint:"); append_about_text(dlg, pvar->ts->UIMsg, fp); free(fp); - fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART, SSH_FP_MD5); + fp = key_fingerprint(&pvar->hosts_state.hostkey, SSH_FP_RANDOMART, SSH_DIGEST_MD5); append_about_text(dlg, "", fp); free(fp); }