[Ttssh2-commit] [6120] SSH key fingerprint の 出力時に、使用しているハッシュアルゴリズム名を表示するようにした

Back to archive index

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);
 	}



Ttssh2-commit メーリングリストの案内
Back to archive index