[Ttssh2-commit] [5056] PuTTY 形式 , SECSH 形式の SSH2 秘密鍵を読み込めるようにした

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2012年 11月 2日 (金) 22:24:07 JST


Revision: 5056
          http://sourceforge.jp/projects/ttssh2/scm/svn/commits/5056
Author:   maya
Date:     2012-11-02 22:24:06 +0900 (Fri, 02 Nov 2012)
Log Message:
-----------
PuTTY 形式, SECSH 形式の SSH2 秘密鍵を読み込めるようにした

Modified Paths:
--------------
    trunk/doc/en/html/about/history.html
    trunk/doc/en/html/menu/setup-sshauth.html
    trunk/doc/en/html/usage/ssh.html
    trunk/doc/ja/html/about/history.html
    trunk/doc/ja/html/menu/setup-sshauth.html
    trunk/doc/ja/html/usage/ssh.html
    trunk/installer/release/lang/English.lng
    trunk/installer/release/lang/French.lng
    trunk/installer/release/lang/German.lng
    trunk/installer/release/lang/Japanese.lng
    trunk/ttssh2/ttxssh/auth.c
    trunk/ttssh2/ttxssh/buffer.c
    trunk/ttssh2/ttxssh/buffer.h
    trunk/ttssh2/ttxssh/keyfiles.c
    trunk/ttssh2/ttxssh/keyfiles.h

-------------- next part --------------
Modified: trunk/doc/en/html/about/history.html
===================================================================
--- trunk/doc/en/html/about/history.html	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/doc/en/html/about/history.html	2012-11-02 13:24:06 UTC (rev 5056)
@@ -1955,6 +1955,7 @@
       <li>Removed the hmac-sha2-256-96 and hmac-sha2-512-96 of SSH2 HMAC algorithm because these protols are obsolete. Refer to the RFC6668(OpenSSH 6.1).</li>
       <li>added some service names of the port number at the SSH Fowarding dialog.</li>
       <li>The length of the DSA key on the <a href="../menu/setup-sshkeygenerator.html">SSH Keygenerator</a> is fixed at 1024 bit because the SSH protocol will support only the 1024 bit officially.</li>
+      <!--li>PuTTY \x8C`\x8E\xAE\x82\xA8\x82\xE6\x82\xD1 SECSH(ssh.com) \x8C`\x8E\xAE\x82\xCC SSH2 \x94閧\x8C\xAE\x82ɑΉ\x9E\x82\xB5\x82\xBD\x81B</li-->
     </ul>
   </li>
 

Modified: trunk/doc/en/html/menu/setup-sshauth.html
===================================================================
--- trunk/doc/en/html/menu/setup-sshauth.html	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/doc/en/html/menu/setup-sshauth.html	2012-11-02 13:24:06 UTC (rev 5056)
@@ -23,9 +23,10 @@
         Specify Password if a password authentication is used.
       </dd>
 
-      <dt>Use RSA/DSA key to login</dt>
+      <dt>Use RSA/DSA/ECDSA key to login</dt>
       <dd>
-        Choose an authentication method using RSA/DSA key which are previosuly generated.
+        Choose an authentication method using RSA/DSA/ECDSA key which are previosuly generated.<br />
+        <!-- OpenSSH \x8C`\x8E\xAE\x82̂ق\xA9\x81ATTSSH 2.63(Tera Term 4.76) \x88ȍ~\x82ł\xCD PuTTY \x8C`\x8E\xAE\x81ESECSH(ssh.com) \x8C`\x8E\xAE\x82\xCC SSH2 \x94閧\x8C\xAE\x82ɑΉ\x9E\x82\xB5\x82Ă\xA2\x82܂\xB7\x81B -->
       </dd>
 
       <dt>Use rhost to login (SSH1)</dt>

Modified: trunk/doc/en/html/usage/ssh.html
===================================================================
--- trunk/doc/en/html/usage/ssh.html	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/doc/en/html/usage/ssh.html	2012-11-02 13:24:06 UTC (rev 5056)
@@ -58,7 +58,8 @@
     <ul>
       <li>If you want to use Password authentication, then make sure that [Use plain password to log in] is chcked and type in username and password. If they are correct, you can login.</li>
       <li>When using public key authentication, check [RSA/DSA/ECDSA key to log in] (second from the top line) and click [Private key file:] to specify Private key file. Then type in username and Private key pass phrase.<br>
-          Note: The passphrase can include the control character(0x01 - 0x1F).</li>
+          Note: The passphrase can include the control character(0x01 - 0x1F).<br />
+          Note: <!-- OpenSSH \x8C`\x8E\xAE\x82̂ق\xA9\x81ATTSSH 2.63(Tera Term 4.76) \x88ȍ~\x82ł\xCD PuTTY \x8C`\x8E\xAE\x81ESECSH(ssh.com) \x8C`\x8E\xAE\x82\xCC SSH2 \x94閧\x8C\xAE\x82ɑΉ\x9E\x82\xB5\x82Ă\xA2\x82܂\xB7\x81B--></li>
       <li>When the keyboard-interactive authentication is used, check the [Use challange/response to log in(keyboard-interactive)] and input your user name.<br>
           Next, the dialog with the server prompt and string is shown and input your password.</li>
       <li>When the Pageant is used, check the [Use Pageant] and input your user name.</li>
@@ -120,9 +121,5 @@
       <em>Note: </em>Since Private key should not be disclosed to other party, please be careful to make it secret. Please makre that it is NOT sent to server by accident.
     </p>
 
-    <p>
-      <em>Note: </em>Tera Term can support the OpenSSH-style key format. That is, Tera Term can load the key file generated by OpenSSH(ssh-keygen) command. However, Tera Term can not support the SECSH(ssh.com) and PuTTY original format.
-    </p>
-
   </body>
 </html>

Modified: trunk/doc/ja/html/about/history.html
===================================================================
--- trunk/doc/ja/html/about/history.html	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/doc/ja/html/about/history.html	2012-11-02 13:24:06 UTC (rev 5056)
@@ -1956,6 +1956,7 @@
       <li>RFC6668(OpenSSH 6.1)\x82ō폜\x82\xB3\x82ꂽ\x82\xBD\x82߁ASSH2 \x82\xCC MAC \x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82\xC5 hmac-sha2-256-96, hmac-sha2-512-96 \x82̃T\x83|\x81[\x83g\x82\xF0\x94p\x8E~\x82\xB5\x82\xBD\x81B</li>
       <li>SSH Forwarding\x83_\x83C\x83A\x83\x8D\x83O\x82̃|\x81[\x83g\x94ԍ\x86\x82̃T\x81[\x83r\x83X\x96\xBC\x82\xF0\x92lj\xC1\x82\xB5\x82\xBD\x81B</li>
       <li>SSH\x83v\x83\x8D\x83g\x83R\x83\x8B\x82ł͐\xB3\x8E\xAE\x82ɃT\x83|\x81[\x83g\x82\xB5\x82Ă\xA2\x82\xE9\x82̂\xCD1024\x83r\x83b\x83g\x82ł\xA0\x82邽\x82߁A<a href="../menu/setup-sshkeygenerator.html">SSH \x8C\xAE\x90\xB6\x90\xAC</a>\x82ŁADSA \x8C\xAE\x82̌\xAE\x92\xB7\x82\xF0 1024 \x83r\x83b\x83g\x8CŒ\xE8\x82ɕύX\x82\xB5\x82\xBD\x81B</li>
+      <li>PuTTY \x8C`\x8E\xAE\x82\xA8\x82\xE6\x82\xD1 SECSH(ssh.com) \x8C`\x8E\xAE\x82\xCC SSH2 \x94閧\x8C\xAE\x82ɑΉ\x9E\x82\xB5\x82\xBD\x81B</li>
     </ul>
   </li>
 

Modified: trunk/doc/ja/html/menu/setup-sshauth.html
===================================================================
--- trunk/doc/ja/html/menu/setup-sshauth.html	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/doc/ja/html/menu/setup-sshauth.html	2012-11-02 13:24:06 UTC (rev 5056)
@@ -23,9 +23,10 @@
         \x83p\x83X\x83\x8F\x81[\x83h\x94F\x8F؂\xF0\x97p\x82\xA2\x82\xE9\x8Fꍇ\x82Ɏw\x92肵\x82܂\xB7\x81B
       </dd>
 
-      <dt>Use RSA/DSA key to login</dt>
+      <dt>Use RSA/DSA/ECDSA key to login</dt>
       <dd>
-        \x82\xA0\x82炩\x82\xB6\x82ߍ쐬\x82\xB5\x82\xBD RSA/DSA \x8C\xAE\x82\xF0\x97p\x82\xA2\x82\xBD\x94F\x8Fؕ\xFB\x96@\x82\xF0\x91I\x91\xF0\x82\xB5\x82܂\xB7\x81B
+        \x82\xA0\x82炩\x82\xB6\x82ߍ쐬\x82\xB5\x82\xBD RSA/DSA/ECDSA \x8C\xAE\x82\xF0\x97p\x82\xA2\x82\xBD\x94F\x8Fؕ\xFB\x96@\x82\xF0\x91I\x91\xF0\x82\xB5\x82܂\xB7\x81B<br />
+        OpenSSH \x8C`\x8E\xAE\x82̂ق\xA9\x81ATTSSH 2.63(Tera Term 4.76) \x88ȍ~\x82ł\xCD PuTTY \x8C`\x8E\xAE\x81ESECSH(ssh.com) \x8C`\x8E\xAE\x82\xCC SSH2 \x94閧\x8C\xAE\x82ɑΉ\x9E\x82\xB5\x82Ă\xA2\x82܂\xB7\x81B
       </dd>
 
       <dt>Use rhost to login (SSH1)</dt>

Modified: trunk/doc/ja/html/usage/ssh.html
===================================================================
--- trunk/doc/ja/html/usage/ssh.html	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/doc/ja/html/usage/ssh.html	2012-11-02 13:24:06 UTC (rev 5056)
@@ -57,7 +57,8 @@
     <ul>
       <li>\x83p\x83X\x83\x8F\x81[\x83h\x94F\x8F؂\xF0\x8Eg\x97p\x82\xB7\x82\xE9\x8Fꍇ\x82́uUse plain password to log in\x81v\x82Ƀ`\x83F\x83b\x83N\x82\xAA\x82‚\xA2\x82Ă\xA2\x82邱\x82Ƃ\xF0\x8Am\x94F\x82\xB5\x81A\x83\x86\x81[\x83U\x96\xBC\x82ƃp\x83X\x83\x8F\x81[\x83h\x82\xF0\x93\xFC\x97͂\xB5\x82܂\xB7\x81B\x82\xB1\x82\xEA\x82炪\x90\xB3\x82\xB5\x82\xAF\x82\xEA\x82Ζ\xB3\x8E\x96\x83\x8D\x83O\x83C\x83\x93\x82ł\xAB\x82܂\xB7\x81B</li>
       <li>\x8C\xF6\x8AJ\x8C\xAE\x94F\x8F؂\xF0\x97p\x82\xA2\x82\xE9\x8Fꍇ\x82́A\x8Fォ\x82\xE72\x94Ԗڂ́uUse RSA/DSA/ECDSA key to log in\x81v\x82Ƀ`\x83F\x83b\x83N\x82\xF0\x82‚\xAF\x81A\x81uPrivate key file:\x81v\x83{\x83^\x83\x93\x82\xF0\x89\x9F\x82\xB5\x82Ĕ閧\x83L\x81[\x82̃t\x83@\x83C\x83\x8B\x82\xF0\x8Ew\x92肵\x82܂\xB7\x81B\x82\xBB\x82̌テ\x81[\x83U\x96\xBC\x82Ɣ閧\x83L\x81[\x82̃p\x83X\x83t\x83\x8C\x81[\x83Y\x82\xF0\x93\xFC\x97͂\xB5\x82ă\x8D\x83O\x83C\x83\x93\x82\xB5\x82܂\xB7\x81B<br>
-          \x81\xA6\x83p\x83X\x83t\x83\x8C\x81[\x83Y\x82ɂ͐\xA7\x8C䕶\x8E\x9A(0x01 - 0x1F)\x82\xF0\x93\xFC\x97͂\xB7\x82邱\x82Ƃ\xAA\x82ł\xAB\x82܂\xB7\x81B</li>
+          \x81\xA6\x83p\x83X\x83t\x83\x8C\x81[\x83Y\x82ɂ͐\xA7\x8C䕶\x8E\x9A(0x01 - 0x1F)\x82\xF0\x93\xFC\x97͂\xB7\x82邱\x82Ƃ\xAA\x82ł\xAB\x82܂\xB7\x81B<br />
+          \x81\xA6OpenSSH \x8C`\x8E\xAE\x82̂ق\xA9\x81ATTSSH 2.63(Tera Term 4.76) \x88ȍ~\x82ł\xCD PuTTY \x8C`\x8E\xAE\x81ESECSH(ssh.com) \x8C`\x8E\xAE\x82\xCC SSH2 \x94閧\x8C\xAE\x82ɑΉ\x9E\x82\xB5\x82Ă\xA2\x82܂\xB7\x81B</li>
       <li>keyboard-interactive\x94F\x8F؂\xF0\x8Eg\x97p\x82\xB7\x82\xE9\x8Fꍇ\x82́uUse challange/response to log in(keyboard-interactive)\x81v\x82Ƀ`\x83F\x83b\x83N\x82\xF0\x82‚\xAF\x81A\x83\x86\x81[\x83U\x96\xBC\x82\xF0\x93\xFC\x97͂\xB5\x82܂\xB7\x81B<br>
           \x83T\x81[\x83o\x82\xA9\x82\xE7\x82̃v\x83\x8D\x83\x93\x83v\x83g\x82ƕ\xB6\x8E\x9A\x97\xF1\x82\xF0\x93\xFC\x97͂\xB7\x82\xE9\x83_\x83C\x83A\x83\x8D\x83O\x82\xAA\x95\\x8E\xA6\x82\xB3\x82\xEA\x82\xE9\x82̂ŁA\x83p\x83X\x83\x8F\x81[\x83h\x82\xF0\x93\xFC\x97͂\xB5\x82܂\xB7\x81B</li>
       <li>Pageant \x82\xF0\x97p\x82\xA2\x82ĔF\x8F؂\xB7\x82\xE9\x8Fꍇ\x82́uUse Pageant\x81v\x82Ƀ`\x83F\x83b\x83N\x82\xF0\x82‚\xAF\x81A\x83\x86\x81[\x83U\x96\xBC\x82\xF0\x93\xFC\x97͂\xB5\x82܂\xB7\x81B</li>
@@ -115,10 +116,6 @@
     <p>
       <em>\x92\x8D\x88\xD3</em>\x81F\x94閧\x8C\xAE\x81iprivate key\x81j\x82͑\xE6\x8EO\x8E҂ɐ\xE2\x91΂ɒm\x82\xE7\x82\xEA\x82Ă͂\xA2\x82\xAF\x82Ȃ\xA2\x82\xBD\x82߁A\x8AǗ\x9D\x82\xF0\x8C\xB5\x8Fd\x82ɍs\x82\xA4\x82悤\x82ɂ\xB5\x82Ă\xAD\x82\xBE\x82\xB3\x82\xA2\x81B\x82܂\xBD\x81A\x8C\xEB\x82\xC1\x82ăT\x81[\x83o\x82֓]\x91\x97\x82\xB5\x82Ă\xB5\x82܂\xED\x82Ȃ\xA2\x82悤\x82ɂ\xB5\x82Ă\xAD\x82\xBE\x82\xB3\x82\xA2\x81B<br>
     </p>
-    
-    <p>
-      <em>\x92\x8D\x88\xD3</em>\x81FTera Term\x82\xAA\x83T\x83|\x81[\x83g\x82\xB7\x82錮\x8C`\x8E\xAE\x82́uOpenSSH\x8C`\x8E\xAE\x81v\x82ł\xB7\x81B\x82\xB7\x82Ȃ킿\x81AOpenSSH(ssh-keygen)\x82ō쐬\x82\xB5\x82\xBD\x8C\xAE\x82\xE0\x93ǂݍ\x9E\x82ނ\xB1\x82Ƃ\xAA\x82ł\xAB\x82܂\xB7\x81BSECSH(ssh.com)\x8C`\x8E\xAE\x82\xE2PuTTY\x93Ǝ\xA9\x8C`\x8E\xAE\x82ɂ͖\xA2\x91Ή\x9E\x82ł\xB7\x81B
-    </p>
 
   </body>
 </html>

Modified: trunk/installer/release/lang/English.lng
===================================================================
--- trunk/installer/release/lang/English.lng	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/installer/release/lang/English.lng	2012-11-02 13:24:06 UTC (rev 5056)
@@ -532,7 +532,7 @@
 DLG_AUTHSETUP_CHECKAUTH=&Check the enabled authentication methods before login (SSH2)
 
 FILEDLG_OPEN_PRIVATEKEY_TITLE=Choose a file with the RSA/DSA/ECDSA private key
-FILEDLG_OPEN_PRIVATEKEY_FILTER=identity files\0identity;id_rsa;id_dsa;id_ecdsa\0identity(RSA1)\0identity\0id_rsa(SSH2)\0id_rsa\0id_dsa(SSH2)\0id_dsa\0id_ecdsa(SSH2)\0id_ecdsa\0all(*.*)\0*.*\0\0
+FILEDLG_OPEN_PRIVATEKEY_FILTER=identity files\0identity;id_rsa;id_dsa;id_ecdsa;*.ppk\0identity(RSA1)\0identity\0id_rsa(SSH2)\0id_rsa\0id_dsa(SSH2)\0id_dsa\0id_ecdsa(SSH2)\0id_ecdsa\0PuTTY(*.ppk)\0*.ppk\0all(*.*)\0*.*\0\0
 MSG_KEYSPECIFY_ERROR=You must specify a file containing the RSA/DSA/ECDSA private key.
 MSG_READKEY_ERROR=read error SSH2 private key file\n%s
 MSG_RHOSTS_NOTDEFAULT_ERROR=Rhosts authentication will probably fail because it was not the default authentication method.\nTo use Rhosts authentication in TTSSH, you need to set it to be the default by restarting\nTTSSH and selecting "SSH Authentication..." from the Setup menubefore connecting.

Modified: trunk/installer/release/lang/French.lng
===================================================================
--- trunk/installer/release/lang/French.lng	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/installer/release/lang/French.lng	2012-11-02 13:24:06 UTC (rev 5056)
@@ -531,7 +531,7 @@
 DLG_AUTHSETUP_CHECKAUTH=V\xE9rifier la m\xE9thode d'authentification autoris\xE9e avant la connexion (SSH2)
 
 FILEDLG_OPEN_PRIVATEKEY_TITLE=Choisir le fichier contenant la cl\xE9 priv\xE9e RSA/DSA/ECDSA
-FILEDLG_OPEN_PRIVATEKEY_FILTER=identity files\0identity;id_rsa;id_dsa;id_ecdsa\0identity(RSA1)\0identity\0id_rsa(SSH2)\0id_rsa\0id_dsa(SSH2)\0id_dsa\0id_ecdsa(SSH2)\0id_ecdsa\0all(*.*)\0*.*\0\0
+FILEDLG_OPEN_PRIVATEKEY_FILTER=identity files\0identity;id_rsa;id_dsa;id_ecdsa;*.ppk\0identity(RSA1)\0identity\0id_rsa(SSH2)\0id_rsa\0id_dsa(SSH2)\0id_dsa\0id_ecdsa(SSH2)\0id_ecdsa\0PuTTY(*.ppk)\0*.ppk\0all(*.*)\0*.*\0\0
 MSG_KEYSPECIFY_ERROR=Vous devez sp\xE9cifier un fichier contenant la cl\xE9 priv\xE9e RSA/DSA/ECDSA.
 MSG_READKEY_ERROR=Erreur de lecture du fichier de cl\xE9 priv\xE9e SSH2\n%s
 MSG_RHOSTS_NOTDEFAULT_ERROR=L'authentification Rhosts va probablement \xE9chouer car ce n'est pas la m\xE9thode d'authentification par d\xE9faut.\nPour utiliser l'authentification Rhosts avec TTSSH, il faut la param\xE9trer par d\xE9faut en red\xE9marrant\nTTSSH et en s\xE9lectionnant "Authentification SSH..." dans le menu de configuration avant de vous connecter.

Modified: trunk/installer/release/lang/German.lng
===================================================================
--- trunk/installer/release/lang/German.lng	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/installer/release/lang/German.lng	2012-11-02 13:24:06 UTC (rev 5056)
@@ -529,7 +529,7 @@
 DLG_AUTHSETUP_CHECKAUTH=Pr\xFCfe die Authentifizierungsmethoden vor dem Logins (SSH2)
 
 FILEDLG_OPEN_PRIVATEKEY_TITLE=DSA/RSA/ECDSA-Schl\xFCssel ausw\xE4hlen
-FILEDLG_OPEN_PRIVATEKEY_FILTER=identity files\0identity;*.*;id_rsa;id_dsa;id_ecdsa\0identity(RSA1)\0identity\0id_rsa(SSH2)\0id_rsa\0id_dsa(SSH2)\0id_dsa\0id_ecdsa(SSH2)\0id_ecdsa\0all(*.*)\0*.*\0\0
+FILEDLG_OPEN_PRIVATEKEY_FILTER=identity files\0identity;*.*;id_rsa;id_dsa;id_ecdsa;*.ppk\0identity(RSA1)\0identity\0id_rsa(SSH2)\0id_rsa\0id_dsa(SSH2)\0id_dsa\0id_ecdsa(SSH2)\0id_ecdsa\0PuTTY(*.ppk)\0*.ppk\0all(*.*)\0*.*\0\0
 MSG_KEYSPECIFY_ERROR=Bitte einen DSA/RSA/ECDSA-Schl\xFCssel ausw\xE4hlen.
 MSG_READKEY_ERROR=Lesefehler des DSA/RSA/ECDSA-Schl\xFCssels\n%s
 MSG_RHOSTS_NOTDEFAULT_ERROR=Rhosts authentication will probably fail because it was not the default authentication method.\nTo use Rhosts authentication in TTSSH, you need to set it to be the default by restarting\nTTSSH and selecting "SSH Authentication..." from the Setup menubefore connecting.

Modified: trunk/installer/release/lang/Japanese.lng
===================================================================
--- trunk/installer/release/lang/Japanese.lng	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/installer/release/lang/Japanese.lng	2012-11-02 13:24:06 UTC (rev 5056)
@@ -532,7 +532,7 @@
 DLG_AUTHSETUP_CHECKAUTH=\x83\x8D\x83O\x83C\x83\x93\x91O\x82ɃT\x81[\x83o\x82ŗL\x8C\xF8\x82ȔF\x8Fؕ\xFB\x8E\xAE\x82\xF0\x8Am\x94F\x82\xB7\x82\xE9 (SSH2)(&C)
 
 FILEDLG_OPEN_PRIVATEKEY_TITLE=RSA/DSA/ECDSA\x94閧\x8C\xAE\x83t\x83@\x83C\x83\x8B\x82̑I\x91\xF0
-FILEDLG_OPEN_PRIVATEKEY_FILTER=\x94閧\x8C\xAE\x83t\x83@\x83C\x83\x8B\0identity;id_rsa;id_dsa;id_ecdsa\0identity(RSA1)\0identity\0id_rsa(SSH2)\0id_rsa\0id_dsa(SSH2)\0id_dsa\0id_ecdsa(SSH2)\0id_ecdsa\0\x82\xB7\x82ׂẴt\x83@\x83C\x83\x8B(*.*)\0*.*\0\0
+FILEDLG_OPEN_PRIVATEKEY_FILTER=\x94閧\x8C\xAE\x83t\x83@\x83C\x83\x8B\0identity;id_rsa;id_dsa;id_ecdsa;*.ppk\0identity(RSA1)\0identity\0id_rsa(SSH2)\0id_rsa\0id_dsa(SSH2)\0id_dsa\0id_ecdsa(SSH2)\0id_ecdsa\0PuTTY(*.ppk)\0*.ppk\0\x82\xB7\x82ׂẴt\x83@\x83C\x83\x8B(*.*)\0*.*\0\0
 MSG_KEYSPECIFY_ERROR=RSA/DSA/ECDSA\x94閧\x8C\xAE\x82̊܂܂\xEA\x82\xE9\x83t\x83@\x83C\x83\x8B\x82\xF0\x8Ew\x92肵\x82Ă\xAD\x82\xBE\x82\xB3\x82\xA2
 MSG_READKEY_ERROR=SSH2\x94閧\x8C\xAE\x82̓ǂݍ\x9E\x82݂Ɏ\xB8\x94s\x82\xB5\x82܂\xB5\x82\xBD\n%s
 MSG_RHOSTS_NOTDEFAULT_ERROR=Rhosts \x94F\x8F؂͕W\x8F\x80\x82̔F\x8Fؕ\xFB\x8E\xAE\x82ł͂Ȃ\xA2\x82\xBD\x82\xDF, \x94F\x8F؂Ɏ\xB8\x94s\x82\xB7\x82邩\x82\xE0\x82\xB5\x82\xEA\x82܂\xB9\x82\xF1.\nRhosts \x94F\x8F؂\xF0TTSSH \x82Ŏg\x97p\x82\xB7\x82\xE9\x82ɂ\xCD, Rhosts \x94F\x8F؂\xF0\x95W\x8F\x80\x82ɐݒ\xE8\x8C\xE3TTSSH \x82\xF0\x8DċN\x93\xAE\x82\xB5, \x90ڑ\xB1\x91O\x82ɐݒ胁\x83j\x83\x85\x81[\x82\xA9\x82\xE7"SSH \x94F\x8F\xD8..." \x82\xF0\x91I\x91\xF0\x82\xB5\x82ĉ\xBA\x82\xB3\x82\xA2.

Modified: trunk/ttssh2/ttxssh/auth.c
===================================================================
--- trunk/ttssh2/ttxssh/auth.c	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/ttssh2/ttxssh/auth.c	2012-11-02 13:24:06 UTC (rev 5056)
@@ -377,8 +377,7 @@
 	// \x83t\x83B\x83\x8B\x83^\x82̒lj\xC1 (2004.12.19 yutaka)
 	// 3\x83t\x83@\x83C\x83\x8B\x83t\x83B\x83\x8B\x83^\x82̒lj\xC1 (2005.4.26 yutaka)
 	UTIL_get_lang_msg("FILEDLG_OPEN_PRIVATEKEY_FILTER", pvar,
-	                  "identity files\\0identity;id_rsa;id_dsa;id_ecdsa\\0identity(RSA1)\\0identity\\0id_rsa(SSH2)\\0id_rsa\\0id_dsa(SSH2)\\0id_dsa\\0id_ecdsa(SSH2)\\0id_ecdsa\\0all(*.*)\\0*.*\\0\\0");
-//	                  "identity files\\0identity;id_rsa;id_dsa;id_ecdsa\\0identity(RSA1)\\0identity\\0id_rsa(SSH2)\\0id_rsa\\0id_dsa(SSH2)\\0id_dsa\\0id_ecdsa(SSH2)\\0id_ecdsa\\0PuTTY(*.ppk)\\0*.ppk\\0all(*.*)\\0*.*\\0\\0");
+	                  "identity files\\0identity;id_rsa;id_dsa;id_ecdsa;*.ppk\\0identity(RSA1)\\0identity\\0id_rsa(SSH2)\\0id_rsa\\0id_dsa(SSH2)\\0id_dsa\\0id_ecdsa(SSH2)\\0id_ecdsa\\0PuTTY(*.ppk)\\0*.ppk\\0all(*.*)\\0*.*\\0\\0");
 	memcpy(filter, pvar->ts->UIMsg, sizeof(filter));
 	params.lpstrFilter = filter;
 	params.lpstrCustomFilter = NULL;
@@ -481,16 +480,57 @@
 		} else { // SSH2(yutaka)
 			BOOL invalid_passphrase = FALSE;
 			char errmsg[256];
+			FILE *fp = NULL;
+			ssh2_keyfile_type keyfile_type;
 
 			memset(errmsg, 0, sizeof(errmsg));
-			//GetCurrentDirectory(sizeof(errmsg), errmsg);
 
-			key_pair = read_SSH2_private_key(pvar, buf, password,
-			                                 &invalid_passphrase,
-			                                 FALSE,
-			                                 errmsg,
-			                                 sizeof(errmsg)
-			                                );
+			keyfile_type = get_ssh2_keytype(buf, &fp, errmsg, sizeof(errmsg));
+			switch (keyfile_type) {
+				case SSH2_KEYFILE_TYPE_OPENSSH:
+				{
+					key_pair = read_SSH2_private_key(pvar, fp, password,
+					                                 &invalid_passphrase,
+					                                 FALSE,
+					                                 errmsg,
+					                                 sizeof(errmsg)
+					                                );
+					break;
+				}
+				case SSH2_KEYFILE_TYPE_PUTTY:
+				{
+					key_pair = read_SSH2_PuTTY_private_key(pvar, fp, password,
+					                                       &invalid_passphrase,
+					                                       FALSE,
+					                                       errmsg,
+					                                       sizeof(errmsg)
+					                                      );
+					break;
+				}
+				case SSH2_KEYFILE_TYPE_SECSH:
+				{
+					key_pair = read_SSH2_SECSH_private_key(pvar, fp, password,
+					                                       &invalid_passphrase,
+					                                       FALSE,
+					                                       errmsg,
+					                                       sizeof(errmsg)
+					                                      );
+					break;
+				}
+				default:
+				{
+					char buf[1024];
+					UTIL_get_lang_msg("MSG_READKEY_ERROR", pvar,
+					                  "read error SSH2 private key file\r\n%s");
+					_snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, errmsg);
+					notify_nonfatal_error(pvar, buf);
+					// \x82\xB1\x82\xB1\x82ɗ\x88\x82\xBD\x82Ƃ\xA2\x82\xA4\x82\xB1\x82Ƃ\xCD SSH2 \x94閧\x8C\xAE\x82\xAA\x8AJ\x82\xAF\x82Ȃ\xA2\x81A\x82\xA0\x82邢\x82̓t\x83@\x83C\x83\x8B\x8C`\x8E\xAE\x82\xAA\x82\xA8\x82\xA9\x82\xB5\x82\xA2\x82̂\xC5
+					// \x8C\xAE\x83t\x83@\x83C\x83\x8B\x82̑I\x91\xF0\x83{\x83^\x83\x93\x82Ƀt\x83H\x81[\x83J\x83X\x82\xF0\x88ڂ\xB7
+					SetFocus(GetDlgItem(dlg, IDC_CHOOSERSAFILE));
+					destroy_malloced_string(&password);
+					return FALSE;
+				}
+			}
 
 			if (key_pair == NULL) { // read error
 				char buf[1024];

Modified: trunk/ttssh2/ttxssh/buffer.c
===================================================================
--- trunk/ttssh2/ttxssh/buffer.c	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/ttssh2/ttxssh/buffer.c	2012-11-02 13:24:06 UTC (rev 5056)
@@ -397,6 +397,32 @@
 	*data = buf;
 }
 
+void buffer_get_bignum_SECSH(buffer_t *buffer, BIGNUM *value)
+{
+	char *buf;
+	int bits, bytes;
+
+	bits = buffer_get_int(buffer);
+	bytes = (bits + 7) / 8;
+
+	if ((buffer->len - buffer->offset) < bytes) {
+		return;
+	}
+	buf = buffer->buf + buffer->offset;
+	if ((*buf & 0x80) != 0) {
+		char *tmp = (char *)malloc(bytes + 1);
+		tmp[0] = '\0';
+		memcpy(tmp + 1, buf, bytes);
+		BN_bin2bn(tmp, bytes + 1, value);
+		free(tmp);
+	}
+	else {
+		BN_bin2bn(buf, bytes, value);
+	}
+
+	buffer->offset += bytes;
+}
+
 void buffer_put_ecpoint(buffer_t *msg, const EC_GROUP *curve, const EC_POINT *point)
 {
 	unsigned char *buf = NULL;

Modified: trunk/ttssh2/ttxssh/buffer.h
===================================================================
--- trunk/ttssh2/ttxssh/buffer.h	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/ttssh2/ttxssh/buffer.h	2012-11-02 13:24:06 UTC (rev 5056)
@@ -29,6 +29,7 @@
 void buffer_put_bignum(buffer_t *buffer, BIGNUM *value);
 void buffer_put_bignum2(buffer_t *msg, BIGNUM *value);
 void buffer_get_bignum2(char **data, BIGNUM *value);
+void buffer_get_bignum_SECSH(buffer_t *buffer, BIGNUM *value);
 void buffer_put_ecpoint(buffer_t *msg, const EC_GROUP *curve, const EC_POINT *point);
 void buffer_get_ecpoint(char **data, const EC_GROUP *curve, EC_POINT *point);
 char *buffer_tail_ptr(buffer_t *msg);

Modified: trunk/ttssh2/ttxssh/keyfiles.c
===================================================================
--- trunk/ttssh2/ttxssh/keyfiles.c	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/ttssh2/ttxssh/keyfiles.c	2012-11-02 13:24:06 UTC (rev 5056)
@@ -44,8 +44,11 @@
 #include <openssl/dsa.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
+#include <openssl/md5.h>
 #include <openssl/err.h>
 
+#include "cipher.h"
+
 static char ID_string[] = "SSH PRIVATE KEY FILE FORMAT 1.1\n";
 
 static BIGNUM FAR *get_bignum(unsigned char FAR * bytes)
@@ -339,16 +342,15 @@
 // SSH2
 //
 
+// OpenSSL format
 Key *read_SSH2_private_key(PTInstVar pvar,
-                           char * relative_name,
+                           FILE * fp,
                            char * passphrase,
                            BOOL * invalid_passphrase,
                            BOOL is_auto_login,
                            char *errmsg,
                            int errmsg_len)
 {
-	char filename[2048];
-	FILE *fp = NULL;
 	Key *result = NULL;
 	EVP_PKEY *pk = NULL;
 	unsigned long err = 0;
@@ -357,17 +359,6 @@
 	ERR_load_crypto_strings();
 	//seed_prng();
 
-	// \x91\x8A\x91΃p\x83X\x82\xF0\x90\xE2\x91΃p\x83X\x82֕ϊ\xB7\x82\xB7\x82\xE9\x81B\x82\xB1\x82\xA4\x82\xB7\x82邱\x82Ƃɂ\xE6\x82\xE8\x81A\x81u\x83h\x83b\x83g\x82Ŏn\x82܂\xE9\x81v\x83f\x83B\x83\x8C\x83N\x83g\x83\x8A\x82\xC9
-	// \x82\xA0\x82\xE9\x83t\x83@\x83C\x83\x8B\x82\xF0\x93ǂݍ\x9E\x82ނ\xB1\x82Ƃ\xAA\x82ł\xAB\x82\xE9\x81B(2005.2.7 yutaka)
-	get_teraterm_dir_relative_name(filename, sizeof(filename),
-	                               relative_name);
-
-	fp = fopen(filename, "r");
-	if (fp == NULL) {
-		strncpy_s(errmsg, errmsg_len, strerror(errno), _TRUNCATE);
-		goto error;
-	}
-
 	result = (Key *)malloc(sizeof(Key));
 	ZeroMemory(result, sizeof(Key)); 
 
@@ -438,3 +429,801 @@
 
 	return (NULL);
 }
+
+// PuTTY format
+/*
+ * PuTTY-User-Key-File-2: ssh-dss
+ * Encryption: aes256-cbc
+ * Comment: imported-openssh-key
+ * Public-Lines: 10
+ * Base64...
+ * Private-Lines: 1
+ * Base64...
+ * Private-MAC: Base16...
+ * Private-Hash: Base16... (PuTTY-User-Key-File-1) ???
+ * 
+ * for "ssh-rsa", it will be composed of
+ *
+ * "Public-Lines: " plus a number N.
+ *
+ *    string "ssh-rsa"
+ *    mpint  exponent
+ *    mpint  modulus
+ *
+ * "Private-Lines: " plus a number N,
+ *
+ *    mpint  private_exponent
+ *    mpint  p                  (the larger of the two primes)
+ *    mpint  q                  (the smaller prime)
+ *    mpint  iqmp               (the inverse of q modulo p)
+ *    data   padding            (to reach a multiple of the cipher block size)
+ *
+ * for "ssh-dss", it will be composed of
+ *
+ * "Public-Lines: " plus a number N.
+ *
+ *    string "ssh-rsa"
+ *    mpint p
+ *    mpint q
+ *    mpint g
+ *    mpint y
+ *
+ * "Private-Lines: " plus a number N,
+ *
+ *    mpint  x                  (the private key parameter)
+ *
+ * "Private-MAC: " plus a hex, HMAC-SHA-1 of:
+ *
+ *    string name of algorithm ("ssh-dss", "ssh-rsa")
+ *    string encryption type
+ *    string comment
+ *    string public-blob
+ *    string private-plaintext
+ */
+Key *read_SSH2_PuTTY_private_key(PTInstVar pvar,
+                                 FILE * fp,
+                                 char * passphrase,
+                                 BOOL * invalid_passphrase,
+                                 BOOL is_auto_login,
+                                 char *errmsg,
+                                 int errmsg_len)
+{
+	Key *result = NULL;
+	EVP_PKEY *pk = NULL;
+	unsigned long err = 0;
+	int i, len, len2;
+	char *encname = NULL, *comment = NULL, *private_mac = NULL;
+	buffer_t *pubkey = NULL, *prikey = NULL;
+
+	result = (Key *)malloc(sizeof(Key));
+	ZeroMemory(result, sizeof(Key)); 
+	result->type = KEY_NONE;
+	result->rsa = NULL;
+	result->dsa = NULL;
+	result->ecdsa = NULL;
+
+	pubkey = buffer_init();
+	prikey = buffer_init();
+
+	// parse keyfile & decode blob
+	{
+	char line[200], buf[100];
+	BIO *bmem, *b64, *chain;
+	while (fgets(line, sizeof(line), fp) != NULL) {
+		if (strncmp(line, "PuTTY-User-Key-File-2: ", strlen("PuTTY-User-Key-File-2: ")) == 0) {
+			if (strncmp(line + strlen("PuTTY-User-Key-File-2: "), "ssh-dss", strlen("ssh-dss")) == 0) {
+				result->type = KEY_DSA;
+			}
+			else if (strncmp(line + strlen("PuTTY-User-Key-File-2: "), "ssh-rsa", strlen("ssh-rsa")) == 0) {
+				result->type = KEY_RSA;
+			}
+			else {
+				strncpy_s(errmsg, errmsg_len, "not a PuTTY SSH-2 private key", _TRUNCATE);
+				goto error;
+			}
+		}
+		else if (strncmp(line, "Encryption: ", strlen("Encryption: ")) == 0) {
+			len = strlen(line + strlen("Encryption: "));
+			encname = (char *)malloc(len); // trim \n
+			strncpy_s(encname, len, line + strlen("Encryption: "), _TRUNCATE);
+			if (strcmp(encname, "aes256-cbc") == 0) {
+				// NOP
+			}
+			else if (strcmp(encname, "none") == 0) {
+				// NOP
+			}
+			else {
+				strncpy_s(errmsg, errmsg_len, "unknown encryption type", _TRUNCATE);
+				goto error;
+			}
+		}
+		else if (strncmp(line, "Comment: ", strlen("Comment: ")) == 0) {
+			len = strlen(line + strlen("Comment: "));
+			comment = (char *)malloc(len); // trim \n
+			strncpy_s(comment, len, line + strlen("Comment: "), _TRUNCATE);
+		}
+		else if (strncmp(line, "Private-MAC: ", strlen("Private-MAC: ")) == 0) {
+			len = strlen(line + strlen("Private-MAC: "));
+			private_mac = (char *)malloc(len); // trim \n
+			strncpy_s(private_mac, len, line + strlen("Private-MAC: "), _TRUNCATE);
+		}
+		else if (strncmp(line, "Private-HASH: ", strlen("Private-HASH: ")) == 0) {
+			strncpy_s(errmsg, errmsg_len, "not a PuTTY SSH-2 private key", _TRUNCATE);
+			goto error;
+		}
+		else if (strncmp(line, "Public-Lines: ", strlen("Public-Lines: ")) == 0) {
+			len = atoi(line + strlen("Public-Lines: "));
+			b64 = BIO_new(BIO_f_base64());
+			bmem = BIO_new(BIO_s_mem());
+			for (i=0; i<len && fgets(line, sizeof(line), fp)!=NULL; i++) {
+				BIO_write(bmem, line, strlen(line));
+			}
+			BIO_flush(bmem);
+			chain = BIO_push(b64, bmem);
+			BIO_set_mem_eof_return(chain, 0);
+			while ((len2 = BIO_read(chain, buf, sizeof(buf))) > 0) {
+				buffer_append(pubkey, buf, len2);
+			}
+			BIO_free_all(chain);
+		}
+		else if (strncmp(line, "Private-Lines: ", strlen("Private-Lines: ")) == 0) {
+			len = atoi(line + strlen("Private-Lines: "));
+			b64 = BIO_new(BIO_f_base64());
+			bmem = BIO_new(BIO_s_mem());
+			for (i=0; i<len && fgets(line, sizeof(line), fp)!=NULL; i++) {
+				BIO_write(bmem, line, strlen(line));
+			}
+			BIO_flush(bmem);
+			chain = BIO_push(b64, bmem);
+			BIO_set_mem_eof_return(chain, 0);
+			while ((len2 = BIO_read(chain, buf, sizeof(buf))) > 0) {
+				buffer_append(prikey, buf, len2);
+			}
+			BIO_free_all(chain);
+		}
+		else {
+			strncpy_s(errmsg, errmsg_len, "not a PuTTY SSH-2 private key", _TRUNCATE);
+			goto error;
+		}
+	}
+	}
+
+	if (result->type == KEY_NONE || strlen(encname) == 0 || buffer_len(pubkey) == 0 || buffer_len(prikey) == 0) {
+		strncpy_s(errmsg, errmsg_len, "key file format error", _TRUNCATE);
+		goto error;
+	}
+
+	// decrypt prikey with aes256-cbc
+	if (strcmp(encname, "aes256-cbc") == 0) {
+		const EVP_MD *md = EVP_sha1();
+		EVP_MD_CTX ctx;
+		unsigned char key[40], iv[32];
+		EVP_CIPHER_CTX cipher_ctx;
+		char *decrypted = NULL;
+
+		EVP_DigestInit(&ctx, md);
+		EVP_DigestUpdate(&ctx, "\0\0\0\0", 4);
+		EVP_DigestUpdate(&ctx, passphrase, strlen(passphrase));
+		EVP_DigestFinal(&ctx, key, &len);
+
+		EVP_DigestInit(&ctx, md);
+		EVP_DigestUpdate(&ctx, "\0\0\0\1", 4);
+		EVP_DigestUpdate(&ctx, passphrase, strlen(passphrase));
+		EVP_DigestFinal(&ctx, key + 20, &len);
+
+		memset(iv, 0, sizeof(iv));
+
+		// decrypt
+		cipher_init_SSH2(&cipher_ctx, key, 32, iv, 16, CIPHER_DECRYPT, EVP_aes_256_cbc(), 0, pvar);
+		len = buffer_len(prikey);
+		decrypted = (char *)malloc(len);
+		if (EVP_Cipher(&cipher_ctx, decrypted, prikey->buf, len) == 0) {
+			strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE);
+			free(decrypted);
+			goto error;
+		}
+		buffer_clear(prikey);
+		buffer_append(prikey, decrypted, len);
+		free(decrypted);
+	}
+
+	// verity MAC
+	{
+	char realmac[41];
+	unsigned char binary[20];
+	buffer_t *macdata;
+
+	macdata = buffer_init();
+
+	len = strlen(get_ssh_keytype_name(result->type));
+	buffer_put_int(macdata, len);
+	buffer_append(macdata, get_ssh_keytype_name(result->type), len);
+	len = strlen(encname);
+	buffer_put_int(macdata, len);
+	buffer_append(macdata, encname, len);
+	len = strlen(comment);
+	buffer_put_int(macdata, len);
+	buffer_append(macdata, comment, len);
+	buffer_put_int(macdata, pubkey->len);
+	buffer_append(macdata, pubkey->buf, pubkey->len);
+	buffer_put_int(macdata, prikey->len);
+	buffer_append(macdata, prikey->buf, prikey->len);
+	
+	if (private_mac != NULL) {
+		unsigned char mackey[20];
+		char header[] = "putty-private-key-file-mac-key";
+		const EVP_MD *md = EVP_sha1();
+		EVP_MD_CTX ctx;
+
+		EVP_DigestInit(&ctx, md);
+		EVP_DigestUpdate(&ctx, header, sizeof(header)-1);
+		len = strlen(passphrase);
+		if (strcmp(encname, "aes256-cbc") == 0 && len > 0) {
+			EVP_DigestUpdate(&ctx, passphrase, len);
+		}
+		EVP_DigestFinal(&ctx, mackey, &len);
+
+		//hmac_sha1_simple(mackey, sizeof(mackey), macdata->buf, macdata->len, binary);
+		{
+		EVP_MD_CTX ctx[2];
+		unsigned char intermediate[20];
+		unsigned char foo[64];
+		int i;
+
+		memset(foo, 0x36, sizeof(foo));
+		for (i = 0; i < sizeof(mackey) && i < sizeof(foo); i++) {
+			foo[i] ^= mackey[i];
+		}
+		EVP_DigestInit(&ctx[0], md);
+		EVP_DigestUpdate(&ctx[0], foo, sizeof(foo));
+
+		memset(foo, 0x5C, sizeof(foo));
+		for (i = 0; i < sizeof(mackey) && i < sizeof(foo); i++) {
+			foo[i] ^= mackey[i];
+		}
+		EVP_DigestInit(&ctx[1], md);
+		EVP_DigestUpdate(&ctx[1], foo, sizeof(foo));
+
+		memset(foo, 0, sizeof(foo));
+
+		EVP_DigestUpdate(&ctx[0], macdata->buf, macdata->len);
+		EVP_DigestFinal(&ctx[0], intermediate, &len);
+
+		EVP_DigestUpdate(&ctx[1], intermediate, sizeof(intermediate));
+		EVP_DigestFinal(&ctx[1], binary, &len);
+		}
+
+		memset(mackey, 0, sizeof(mackey));
+		
+	}
+	else {
+		strncpy_s(errmsg, errmsg_len, "key file format error", _TRUNCATE);
+		buffer_free(macdata);
+		goto error;
+	}
+
+	buffer_free(macdata);
+
+	for (i=0; i<20; i++) {
+		sprintf(realmac + 2*i, "%02x", binary[i]);
+	}
+
+	if (strcmp(private_mac, realmac) != 0) {
+		if (strcmp(encname, "aes256-cbc") == 0) {
+			strncpy_s(errmsg, errmsg_len, "wrong passphrase", _TRUNCATE);
+			*invalid_passphrase = TRUE;
+			goto error;
+		}
+		else {
+			strncpy_s(errmsg, errmsg_len, "MAC verify failed", _TRUNCATE);
+			goto error;
+		}
+	}
+	}
+
+	switch (result->type) {
+	case KEY_RSA:
+	{
+		char *pubkey_type, *pub, *pri;
+		pub = pubkey->buf;
+		pri = prikey->buf;
+		pubkey_type = buffer_get_string(&pub, NULL);
+		if (strcmp(pubkey_type, "ssh-rsa") != 0) {
+			strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
+			free(pubkey_type);
+			goto error;
+		}
+		free(pubkey_type);
+
+		result->rsa = RSA_new();
+		if (result->rsa == NULL) {
+			strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
+			goto error;
+		}
+		result->rsa->e = BN_new();
+		result->rsa->n = BN_new();
+		result->rsa->d = BN_new();
+		result->rsa->p = BN_new();
+		result->rsa->q = BN_new();
+		result->rsa->iqmp = BN_new();
+		if (result->rsa->e == NULL ||
+		    result->rsa->n == NULL ||
+		    result->rsa->d == NULL ||
+		    result->rsa->p == NULL ||
+		    result->rsa->q == NULL ||
+		    result->rsa->iqmp == NULL) {
+			strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
+			goto error;
+		}
+
+		buffer_get_bignum2(&pub, result->rsa->e);
+		buffer_get_bignum2(&pub, result->rsa->n);
+
+		buffer_get_bignum2(&pri, result->rsa->d);
+		buffer_get_bignum2(&pri, result->rsa->p);
+		buffer_get_bignum2(&pri, result->rsa->q);
+		buffer_get_bignum2(&pri, result->rsa->iqmp);
+
+		break;
+	}
+	case KEY_DSA:
+	{
+		char *pubkey_type, *pub, *pri;
+		pub = pubkey->buf;
+		pri = prikey->buf;
+		pubkey_type = buffer_get_string(&pub, NULL);
+		if (strcmp(pubkey_type, "ssh-dss") != 0) {
+			strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
+			free(pubkey_type);
+			goto error;
+		}
+		free(pubkey_type);
+
+		result->dsa = DSA_new();
+		if (result->dsa == NULL) {
+			strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
+			goto error;
+		}
+		result->dsa->p = BN_new();
+		result->dsa->q = BN_new();
+		result->dsa->g = BN_new();
+		result->dsa->pub_key = BN_new();
+		result->dsa->priv_key = BN_new();
+		if (result->dsa->p == NULL ||
+		    result->dsa->q == NULL ||
+		    result->dsa->g == NULL ||
+		    result->dsa->pub_key == NULL ||
+		    result->dsa->priv_key == NULL) {
+			strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
+			goto error;
+		}
+
+		buffer_get_bignum2(&pub, result->dsa->p);
+		buffer_get_bignum2(&pub, result->dsa->q);
+		buffer_get_bignum2(&pub, result->dsa->g);
+		buffer_get_bignum2(&pub, result->dsa->pub_key);
+
+		buffer_get_bignum2(&pri, result->dsa->priv_key);
+
+		break;
+	}
+	default:
+		strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
+		goto error;
+		break;
+	}
+
+	fclose(fp);
+
+	if (encname != NULL)
+		free(encname);
+
+	if (comment != NULL)
+		free(comment);
+
+	if (pubkey != NULL)
+		buffer_free(pubkey);
+
+	if (prikey != NULL)
+		buffer_free(prikey);
+
+	if (private_mac != NULL)
+		free(private_mac);
+
+	return (result);
+
+error:
+	if (result != NULL)
+		key_free(result);
+
+	if (fp != NULL)
+		fclose(fp);
+
+	if (encname != NULL)
+		free(encname);
+
+	if (comment != NULL)
+		free(comment);
+
+	if (pubkey != NULL)
+		buffer_free(pubkey);
+
+	if (prikey != NULL)
+		buffer_free(prikey);
+
+	if (private_mac != NULL)
+		free(private_mac);
+
+	return (NULL);
+}
+
+// SECSH(ssh.com) format
+/*
+ * Code to read ssh.com private keys.
+ *
+ *  "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
+ *  "Comment:..."
+ *  "Base64..."
+ *  "---- END SSH2 ENCRYPTED PRIVATE KEY ----"
+ *
+ * Body of key data
+ *
+ *  - uint32 0x3f6ff9eb       (magic number)
+ *  - uint32 size             (total blob size)
+ *  - string key-type         (see below)
+ *  - string cipher-type      (tells you if key is encrypted)
+ *  - string encrypted-blob
+ *
+ * The key type strings are ghastly. The RSA key I looked at had a type string of
+ * 
+ *   `if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}'
+ *   `dl-modp{sign{dsa-nist-sha1},dh{plain}}'
+ *
+ * The encryption. The cipher-type string appears to be either
+ *
+ *    `none'
+ *    `3des-cbc'
+ *
+ * The payload blob, for an RSA key, contains:
+ *  - mpint e
+ *  - mpint d
+ *  - mpint n  (yes, the public and private stuff is intermixed)
+ *  - mpint u  (presumably inverse of p mod q)
+ *  - mpint p  (p is the smaller prime)
+ *  - mpint q  (q is the larger)
+ * 
+ * For a DSA key, the payload blob contains:
+ *  - uint32 0
+ *  - mpint p
+ *  - mpint g
+ *  - mpint q
+ *  - mpint y
+ *  - mpint x
+ */
+Key *read_SSH2_SECSH_private_key(PTInstVar pvar,
+                                 FILE * fp,
+                                 char * passphrase,
+                                 BOOL * invalid_passphrase,
+                                 BOOL is_auto_login,
+                                 char *errmsg,
+                                 int errmsg_len)
+{
+	Key *result = NULL;
+	unsigned long err = 0;
+	int i, len, len2;
+	int encflag;
+	char *encname = NULL;
+	buffer_t *blob = NULL, *blob2 = NULL;
+
+	result = (Key *)malloc(sizeof(Key));
+	ZeroMemory(result, sizeof(Key)); 
+	result->type = KEY_NONE;
+	result->rsa = NULL;
+	result->dsa = NULL;
+	result->ecdsa = NULL;
+
+	blob = buffer_init();
+	blob2 = buffer_init();
+
+	// parse keyfile & decode blob
+	{
+	char line[200], buf[100];
+	BIO *bmem, *b64, *chain;
+	int st = 0;
+
+	b64 = BIO_new(BIO_f_base64());
+	bmem = BIO_new(BIO_s_mem());
+
+	while (fgets(line, sizeof(line), fp) != NULL) {
+		if (strncmp(line, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----", strlen("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----")) == 0) {
+			if (st == 0) {
+				st = 1;
+				continue;
+			}
+			else {
+				break;
+			}
+		}
+		else if (strncmp(line, "---- END SSH2 ENCRYPTED PRIVATE KEY ----", strlen("---- END SSH2 ENCRYPTED PRIVATE KEY ----")) == 0) {
+			break;
+		}
+
+		if (st == 0) {
+			continue;
+		}
+
+		if (strchr(line, ':') != NULL) {
+			if (st == 1) {
+				continue;
+			}
+			strncpy_s(errmsg, errmsg_len, "header found in body of key data", _TRUNCATE);
+			BIO_free_all(bmem);
+			goto error;
+		}
+		else if (st == 1) {
+			st = 2;
+		}
+
+		BIO_write(bmem, line, strlen(line));
+	}
+
+	BIO_flush(bmem);
+	chain = BIO_push(b64, bmem);
+	BIO_set_mem_eof_return(chain, 0);
+	while ((len2 = BIO_read(chain, buf, sizeof(buf))) > 0) {
+		buffer_append(blob, buf, len2);
+	}
+	BIO_free_all(chain);
+	buffer_rewind(blob);
+	}
+
+	if (blob->len < 8) {
+		strncpy_s(errmsg, errmsg_len, "key body not present", _TRUNCATE);
+		goto error;
+	}
+	i = buffer_get_int(blob);
+	if (i != 0x3f6ff9eb) {
+		strncpy_s(errmsg, errmsg_len, "magic number error", _TRUNCATE);
+		goto error;
+	}
+	len = buffer_get_int(blob);
+	if (len <= 0 || len > blob->len) {
+		strncpy_s(errmsg, errmsg_len, "body size error", _TRUNCATE);
+		goto error;
+	}
+
+	len = buffer_get_int(blob);
+	if (strncmp(blob->buf + blob->offset, "if-modn{sign{rsa", strlen("if-modn{sign{rsa") - 1) == 0) {
+		result->type = KEY_RSA;
+	}
+	else if (strncmp(blob->buf + blob->offset, "dl-modp{sign{dsa", strlen("dl-modp{sign{dsa") - 1) == 0) {
+		result->type = KEY_DSA;
+	}
+	else {
+		strncpy_s(errmsg, errmsg_len, "unknown key type", _TRUNCATE);
+		goto error;
+	}
+	buffer_consume(blob, len);
+
+	len = buffer_get_int(blob);
+	encname = (char *)malloc(len + 1);
+	strncpy_s(encname, len + 1, blob->buf + blob->offset, _TRUNCATE);
+	if (strcmp(encname, "3des-cbc") == 0) {
+		encflag = 1;
+	}
+	else if (strcmp(encname, "none") == 0) {
+		encflag = 0;
+	}
+	else {
+		strncpy_s(errmsg, errmsg_len, "unknown encryption type", _TRUNCATE);
+		goto error;
+	}
+	buffer_consume(blob, len);
+
+	len = buffer_get_int(blob);
+	if (len > (blob->len - blob->offset)) {
+		strncpy_s(errmsg, errmsg_len, "body size error", _TRUNCATE);
+		goto error;
+	}
+
+	// decrypt privkey with 3des-cbc
+	if (strcmp(encname, "3des-cbc") == 0) {
+		MD5_CTX md;
+		unsigned char key[32], iv[16];
+		EVP_CIPHER_CTX cipher_ctx;
+		char *decrypted = NULL;
+
+		MD5_Init(&md);
+		MD5_Update(&md, passphrase, strlen(passphrase));
+		MD5_Final(key, &md);
+
+		MD5_Init(&md);
+		MD5_Update(&md, passphrase, strlen(passphrase));
+		MD5_Update(&md, key, 16);
+		MD5_Final(key + 16, &md);
+
+		memset(iv, 0, sizeof(iv));
+
+		// decrypt
+		cipher_init_SSH2(&cipher_ctx, key, 24, iv, 8, CIPHER_DECRYPT, EVP_des_ede3_cbc(), 0, pvar);
+		decrypted = (char *)malloc(len);
+		if (EVP_Cipher(&cipher_ctx, decrypted, blob->buf + blob->offset, len) == 0) {
+			strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE);
+			goto error;
+		}
+		buffer_append(blob2, decrypted, len);
+		free(decrypted);
+
+		*invalid_passphrase = TRUE;
+	}
+	else { // none
+		buffer_append(blob2, blob->buf + blob->offset, len);
+	}
+	buffer_rewind(blob2);
+
+	len = buffer_get_int(blob2);
+	if (len <= 0 || len > (blob2->len - blob2->offset)) {
+		strncpy_s(errmsg, errmsg_len, "blob size error", _TRUNCATE);
+		goto error;
+	}
+
+	switch (result->type) {
+	case KEY_RSA:
+	{
+		result->rsa = RSA_new();
+		if (result->rsa == NULL) {
+			strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
+			goto error;
+		}
+		result->rsa->e = BN_new();
+		result->rsa->n = BN_new();
+		result->rsa->d = BN_new();
+		result->rsa->p = BN_new();
+		result->rsa->q = BN_new();
+		result->rsa->iqmp = BN_new();
+		if (result->rsa->e == NULL ||
+		    result->rsa->n == NULL ||
+		    result->rsa->d == NULL ||
+		    result->rsa->p == NULL ||
+		    result->rsa->q == NULL ||
+		    result->rsa->iqmp == NULL) {
+			strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
+			goto error;
+		}
+
+		buffer_get_bignum_SECSH(blob2, result->rsa->e);
+		buffer_get_bignum_SECSH(blob2, result->rsa->d);
+		buffer_get_bignum_SECSH(blob2, result->rsa->n);
+		buffer_get_bignum_SECSH(blob2, result->rsa->iqmp);
+		buffer_get_bignum_SECSH(blob2, result->rsa->p);
+		buffer_get_bignum_SECSH(blob2, result->rsa->q);
+
+		break;
+	}
+	case KEY_DSA:
+	{
+		int param;
+
+		result->dsa = DSA_new();
+		if (result->dsa == NULL) {
+			strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
+			goto error;
+		}
+		result->dsa->p = BN_new();
+		result->dsa->q = BN_new();
+		result->dsa->g = BN_new();
+		result->dsa->pub_key = BN_new();
+		result->dsa->priv_key = BN_new();
+		if (result->dsa->p == NULL ||
+		    result->dsa->q == NULL ||
+		    result->dsa->g == NULL ||
+		    result->dsa->pub_key == NULL ||
+		    result->dsa->priv_key == NULL) {
+			strncpy_s(errmsg, errmsg_len, "key init error", _TRUNCATE);
+			goto error;
+		}
+
+		param = buffer_get_int(blob2);
+		if (param != 0) {
+			strncpy_s(errmsg, errmsg_len, "predefined DSA parameters not supported", _TRUNCATE);
+			goto error;
+		}
+		buffer_get_bignum_SECSH(blob2, result->dsa->p);
+		buffer_get_bignum_SECSH(blob2, result->dsa->g);
+		buffer_get_bignum_SECSH(blob2, result->dsa->q);
+		buffer_get_bignum_SECSH(blob2, result->dsa->pub_key);
+		buffer_get_bignum_SECSH(blob2, result->dsa->priv_key);
+
+		break;
+	}
+	default:
+		strncpy_s(errmsg, errmsg_len, "key type error", _TRUNCATE);
+		goto error;
+		break;
+	}
+
+	*invalid_passphrase = FALSE;
+
+	fclose(fp);
+
+	if (encname != NULL)
+		free(encname);
+
+	if (blob != NULL)
+		buffer_free(blob);
+
+	if (blob2 != NULL)
+		buffer_free(blob2);
+
+	return (result);
+
+error:
+	if (result != NULL)
+		key_free(result);
+
+	if (fp != NULL)
+		fclose(fp);
+
+	if (encname != NULL)
+		free(encname);
+
+	if (blob != NULL)
+		buffer_free(blob);
+
+	if (blob2 != NULL)
+		buffer_free(blob2);
+
+	return (NULL);
+}
+
+ssh2_keyfile_type get_ssh2_keytype(char *relative_name,
+                                   FILE **fp,
+                                   char *errmsg,
+                                   int errmsg_len) {
+	ssh2_keyfile_type ret = SSH2_KEYFILE_TYPE_NONE;
+	char filename[2048];
+	char line[200];
+
+	// \x91\x8A\x91΃p\x83X\x82\xF0\x90\xE2\x91΃p\x83X\x82֕ϊ\xB7\x82\xB7\x82\xE9\x81B\x82\xB1\x82\xA4\x82\xB7\x82邱\x82Ƃɂ\xE6\x82\xE8\x81A\x81u\x83h\x83b\x83g\x82Ŏn\x82܂\xE9\x81v\x83f\x83B\x83\x8C\x83N\x83g\x83\x8A\x82\xC9
+	// \x82\xA0\x82\xE9\x83t\x83@\x83C\x83\x8B\x82\xF0\x93ǂݍ\x9E\x82ނ\xB1\x82Ƃ\xAA\x82ł\xAB\x82\xE9\x81B(2005.2.7 yutaka)
+	get_teraterm_dir_relative_name(filename, sizeof(filename),
+	                               relative_name);
+
+	*fp = fopen(filename, "r");
+	if (*fp == NULL) {
+		strncpy_s(errmsg, errmsg_len, strerror(errno), _TRUNCATE);
+		return ret;
+	}
+
+	while (fgets(line, sizeof(line), *fp) != NULL) {
+		if (strncmp(line, "-----BEGIN RSA PRIVATE KEY-----", strlen("-----BEGIN RSA PRIVATE KEY-----")) == 0) {
+			ret = SSH2_KEYFILE_TYPE_OPENSSH;
+			break;
+		}
+		else if (strncmp(line, "-----BEGIN DSA PRIVATE KEY-----", strlen("-----BEGIN DSA PRIVATE KEY-----")) == 0) {
+			ret = SSH2_KEYFILE_TYPE_OPENSSH;
+			break;
+		}
+		else if (strncmp(line, "-----BEGIN EC PRIVATE KEY-----", strlen("-----BEGIN EC PRIVATE KEY-----")) == 0) {
+			ret = SSH2_KEYFILE_TYPE_OPENSSH;
+			break;
+		}
+		else if (strncmp(line, "PuTTY-User-Key-File-2", strlen("PuTTY-User-Key-File-2")) == 0) {
+			ret = SSH2_KEYFILE_TYPE_PUTTY;
+			break;
+		}
+		else if (strncmp(line, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----", strlen("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----")) == 0) {
+			ret = SSH2_KEYFILE_TYPE_SECSH;
+			break;
+		}
+	}
+	
+	if (ret == SSH2_KEYFILE_TYPE_NONE) {
+		fclose(*fp);
+		strncpy_s(errmsg, errmsg_len, "Unknown key file type.", _TRUNCATE);
+		return ret;
+	}
+	
+	fseek(*fp, 0, SEEK_SET);
+	return ret;
+}

Modified: trunk/ttssh2/ttxssh/keyfiles.h
===================================================================
--- trunk/ttssh2/ttxssh/keyfiles.h	2012-11-02 09:21:04 UTC (rev 5055)
+++ trunk/ttssh2/ttxssh/keyfiles.h	2012-11-02 13:24:06 UTC (rev 5056)
@@ -34,6 +34,13 @@
 #ifndef __KEYFILES_H
 #define __KEYFILES_H
 
+typedef enum {
+	SSH2_KEYFILE_TYPE_NONE,
+	SSH2_KEYFILE_TYPE_OPENSSH,
+	SSH2_KEYFILE_TYPE_PUTTY,
+	SSH2_KEYFILE_TYPE_SECSH
+} ssh2_keyfile_type;
+
 Key * KEYFILES_read_private_key(PTInstVar pvar,
                                 char * relative_name,
                                 char * passphrase,
@@ -41,11 +48,32 @@
                                 BOOL is_auto_login);
 
 Key *read_SSH2_private_key(PTInstVar pvar,
-                           char * relative_name,
+                           FILE * fp,
                            char * passphrase,
                            BOOL * invalid_passphrase,
                            BOOL is_auto_login,
                            char *errmsg,
                            int errmsg_len);
 
+Key *read_SSH2_PuTTY_private_key(PTInstVar pvar,
+                                 FILE * fp,
+                                 char * passphrase,
+                                 BOOL * invalid_passphrase,
+                                 BOOL is_auto_login,
+                                 char *errmsg,
+                                 int errmsg_len);
+
+Key *read_SSH2_SECSH_private_key(PTInstVar pvar,
+                                 FILE * fp,
+                                 char * passphrase,
+                                 BOOL * invalid_passphrase,
+                                 BOOL is_auto_login,
+                                 char *errmsg,
+                                 int errmsg_len);
+
+ssh2_keyfile_type get_ssh2_keytype(char *relative_name,
+                                   FILE **fp,
+                                   char *errmsg,
+                                   int errmsg_len);
+
 #endif



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