[Ttssh2-commit] [5530] ED25519 秘密鍵のファイル読み込み処理の追加。

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2014年 3月 11日 (火) 21:49:21 JST


Revision: 5530
          http://sourceforge.jp/projects/ttssh2/scm/svn/commits/5530
Author:   yutakapon
Date:     2014-03-11 21:49:21 +0900 (Tue, 11 Mar 2014)
Log Message:
-----------
ED25519 秘密鍵のファイル読み込み処理の追加。
まだ、途中です。

Modified Paths:
--------------
    branches/ssh_ed25519/ttssh2/ttxssh/keyfiles.c
    branches/ssh_ed25519/ttssh2/ttxssh/keyfiles.h

-------------- next part --------------
Modified: branches/ssh_ed25519/ttssh2/ttxssh/keyfiles.c
===================================================================
--- branches/ssh_ed25519/ttssh2/ttxssh/keyfiles.c	2014-03-11 12:48:54 UTC (rev 5529)
+++ branches/ssh_ed25519/ttssh2/ttxssh/keyfiles.c	2014-03-11 12:49:21 UTC (rev 5530)
@@ -342,6 +342,218 @@
 // SSH2
 //
 
+// ED25519 \x8C`\x8E\xAE\x82œǂ\xDE
+// based on key_parse_private2() @ OpenSSH 6.5
+static Key *read_SSH2_private2_key(PTInstVar pvar,
+                           FILE * fp,
+                           char * passphrase,
+                           BOOL * invalid_passphrase,
+                           BOOL is_auto_login,
+                           char *errmsg,
+                           int errmsg_len)
+{
+	buffer_t *blob = NULL;
+	buffer_t *b = NULL;
+	buffer_t *kdf = NULL;
+	buffer_t *encoded = NULL;
+	buffer_t *copy = NULL;
+	Key *key = NULL;
+	unsigned char buf[1024];
+	unsigned char *cp, last;
+	char *ciphername = NULL, *kdfname = NULL, *kdfp = NULL;
+	unsigned int len, klen, nkeys, blocksize;
+	unsigned int check1, check2, m1len, m2len; 
+	int dlen;
+	SSHCipher ciphernameval;
+	size_t authlen;
+
+	blob = buffer_init();
+	b = buffer_init();
+	kdf = buffer_init();
+	encoded = buffer_init();
+	copy = buffer_init();
+	if (blob == NULL || b == NULL || kdf == NULL || encoded == NULL || copy == NULL)
+		goto error;
+
+	// \x83t\x83@\x83C\x83\x8B\x82\xF0\x82\xB7\x82ׂēǂݍ\x9E\x82\xDE
+	for (;;) {
+		len = fread(buf, 1, sizeof(buf), fp);
+		buffer_append(blob, buf, len);
+		if (buffer_len(blob) > MAX_KEY_FILE_SIZE) {
+			goto error;
+		}
+		if (len < sizeof(buf))
+			break;
+	}
+
+	/* uudecode */
+	m1len = sizeof(MARK_BEGIN) - 1;
+	m2len = sizeof(MARK_END) - 1;
+	cp = buffer_ptr(blob);
+	len = buffer_len(blob);
+	if (len < m1len || memcmp(cp, MARK_BEGIN, m1len)) {
+		//debug("%s: missing begin marker", __func__);
+		goto error;
+	}
+	cp += m1len;
+	len -= m1len;
+	while (len) {
+		if (*cp != '\n' && *cp != '\r')
+			buffer_put_char(encoded, *cp);
+		last = *cp;
+		len--;
+		cp++;
+		if (last == '\n') {
+			if (len >= m2len && !memcmp(cp, MARK_END, m2len)) {
+				buffer_put_char(encoded, '\0');
+				break;
+			}
+		}
+	}
+	if (!len) {
+		//debug("%s: no end marker", __func__);
+		goto error;
+	}
+
+	// \x83t\x83@\x83C\x83\x8B\x82̃X\x83L\x83\x83\x83\x93\x82\xAA\x8FI\x82\xED\x82\xC1\x82\xBD\x82̂ŁAuudecode\x82\xB7\x82\xE9\x81B
+	len = buffer_len(encoded);
+	if ((cp = buffer_append_space(copy, len)) == NULL) {
+		//error("%s: buffer_append_space", __func__);
+		goto error;
+	}
+	if ((dlen = uudecode(buffer_ptr(encoded), buffer_len(encoded), cp, len)) < 0) {
+		//error("%s: uudecode failed", __func__);
+		goto error;
+	}
+	if ((unsigned int)dlen > len) {
+		//error("%s: crazy uudecode length %d > %u", __func__, dlen, len);
+		goto error;
+	}
+
+	buffer_consume_end(copy, len - dlen);
+	if (buffer_len(copy) < sizeof(AUTH_MAGIC) ||
+	    memcmp(buffer_ptr(copy), AUTH_MAGIC, sizeof(AUTH_MAGIC))) {
+		//error("%s: bad magic", __func__);
+		goto error;
+	}
+	buffer_consume(copy, sizeof(AUTH_MAGIC));
+
+	/*
+	 * \x83f\x83R\x81[\x83h\x82\xB5\x82\xBD\x83f\x81[\x83^\x82\xF0\x89\xF0\x90͂\xB7\x82\xE9\x81B
+	 */
+	// \x88Í\x86\x89\xBB\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82̖\xBC\x91O
+	ciphername = buffer_get_string_msg(copy, NULL);
+	ciphernameval = get_cipher_by_name(ciphername);
+	if (ciphernameval == SSH_CIPHER_NONE) {
+		//error("%s: unknown cipher name", __func__);
+		goto error;
+	}
+	// \x83p\x83X\x83t\x83\x8C\x81[\x83Y\x82̃`\x83F\x83b\x83N\x81B\x8B\xF3\x82̃p\x83X\x83\x8F\x81[\x83h\x82͔F\x82߂Ȃ\xA2\x81B
+	if (passphrase == NULL || strlen(passphrase) == 0) {
+		/* passphrase required */
+		goto error;
+	}
+
+	kdfname = buffer_get_string_msg(copy, NULL);
+	if (kdfname == NULL || strcmp(kdfname, KDFNAME) != 0) {
+		//error("%s: unknown kdf name", __func__);
+		goto error;
+	}
+
+	/* kdf options */
+	kdfp = buffer_get_string_msg(copy, &klen);
+	if (kdfp == NULL) {
+		//error("%s: kdf options not set", __func__);
+		goto error;
+	}
+	if (klen > 0) {
+		if ((cp = buffer_append_space(kdf, klen)) == NULL) {
+			//error("%s: kdf alloc failed", __func__);
+			goto error;
+		}
+		memcpy(cp, kdfp, klen);
+	}
+
+	/* number of keys */
+	if (buffer_get_int_ret(&nkeys, copy) < 0) {
+		//error("%s: key counter missing", __func__);
+		goto error;
+	}
+	if (nkeys != 1) {
+		//error("%s: only one key supported", __func__);
+		goto error;
+	}
+
+	/* pubkey */
+	cp = buffer_get_string_msg(copy, &len);
+	if (cp == NULL) {
+		//error("%s: pubkey not found", __func__);
+		goto error;
+	}
+	free(cp); /* XXX check pubkey against decrypted private key */
+
+	/* size of encrypted key blob */
+	len = buffer_get_int(copy);
+	blocksize = get_cipher_block_size(ciphernameval);
+	authlen = 0;  // TODO: \x82Ƃ肠\x82\xA6\x82\xB8\x8CŒ艻
+	if (len < blocksize) {
+		//error("%s: encrypted data too small", __func__);
+		goto error;
+	}
+	if (len % blocksize) {
+		//error("%s: length not multiple of blocksize", __func__);
+		goto error;
+	}
+
+#if 0
+	/* setup key */
+	keylen = cipher_keylen(c);
+	ivlen = cipher_ivlen(c);
+	key = xcalloc(1, keylen + ivlen);
+	if (!strcmp(kdfname, "bcrypt")) {
+		if ((salt = buffer_get_string_ret(&kdf, &slen)) == NULL) {
+			error("%s: salt not set", __func__);
+			goto out;
+		}
+		if (buffer_get_int_ret(&rounds, &kdf) < 0) {
+			error("%s: rounds not set", __func__);
+			goto out;
+		}
+		if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen,
+		    key, keylen + ivlen, rounds) < 0) {
+			error("%s: bcrypt_pbkdf failed", __func__);
+			goto out;
+		}
+	}
+#endif
+
+
+	/* success */
+
+error:
+	buffer_free(blob);
+	buffer_free(b);
+	buffer_free(kdf);
+	buffer_free(encoded);
+	buffer_free(copy);
+
+	free(ciphername);
+	free(kdfname);
+	free(kdfp);
+
+	// ED25519 \x82ł͂Ȃ\xA9\x82\xC1\x82\xBD
+	if (key == NULL) {
+		fseek(fp, 0, SEEK_SET);
+
+	} else {
+		fclose(fp);
+
+	}
+
+	return (key);
+}
+
+
 // OpenSSL format
 Key *read_SSH2_private_key(PTInstVar pvar,
                            FILE * fp,
@@ -359,6 +571,10 @@
 	ERR_load_crypto_strings();
 	//seed_prng();
 
+	result = read_SSH2_private2_key(pvar, fp, passphrase, invalid_passphrase, is_auto_login, errmsg, errmsg_len);
+	if (result)
+		return (result);
+
 	result = (Key *)malloc(sizeof(Key));
 	ZeroMemory(result, sizeof(Key)); 
 

Modified: branches/ssh_ed25519/ttssh2/ttxssh/keyfiles.h
===================================================================
--- branches/ssh_ed25519/ttssh2/ttxssh/keyfiles.h	2014-03-11 12:48:54 UTC (rev 5529)
+++ branches/ssh_ed25519/ttssh2/ttxssh/keyfiles.h	2014-03-11 12:49:21 UTC (rev 5530)
@@ -86,9 +86,22 @@
 	{SSH2_KEYFILE_TYPE_OPENSSH, "-----BEGIN DSA PRIVATE KEY-----"},
 	{SSH2_KEYFILE_TYPE_OPENSSH, "-----BEGIN EC PRIVATE KEY-----"},
 	{SSH2_KEYFILE_TYPE_OPENSSH, "-----BEGIN ENCRYPTED PRIVATE KEY-----"},
+	{SSH2_KEYFILE_TYPE_OPENSSH, "-----BEGIN OPENSSH PRIVATE KEY-----"},
 	{SSH2_KEYFILE_TYPE_PUTTY,   "PuTTY-User-Key-File-2"},
 	{SSH2_KEYFILE_TYPE_SECSH,   "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"},
 	{SSH2_KEYFILE_TYPE_NONE,    NULL},
 
 };
+
+/* openssh private key file format */
+#define MARK_BEGIN		"-----BEGIN OPENSSH PRIVATE KEY-----\n"
+#define MARK_END		"-----END OPENSSH PRIVATE KEY-----\n"
+#define KDFNAME			"bcrypt"
+#define AUTH_MAGIC		"openssh-key-v1"
+#define SALT_LEN		16
+#define DEFAULT_CIPHERNAME	"aes256-cbc"
+#define	DEFAULT_ROUNDS		16
+
+#define MAX_KEY_FILE_SIZE	(1024 * 1024)
+
 #endif



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