]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Separate key-type enum values for old and new OpenSSH keys.
authorSimon Tatham <anakin@pobox.com>
Tue, 28 Apr 2015 18:46:58 +0000 (19:46 +0100)
committerSimon Tatham <anakin@pobox.com>
Tue, 28 Apr 2015 18:48:43 +0000 (19:48 +0100)
It's all very well for these two different formats to share a type
code as long as we're only loading them and not saving, but as soon as
we need to save one or the other, we'll need different type codes
after all.

This commit introduces the openssh_new_write() function, but for the
moment, it always returns failure.

cmdgen.c
import.c
ssh.h
sshpubk.c
windows/winpgen.c

index e5a43c1fc28442d1bf67571c046dd90f8ccd2705..ea60c25f7dbdc82ad2defa6c4049c8ae05f71583 100644 (file)
--- a/cmdgen.c
+++ b/cmdgen.c
@@ -160,6 +160,10 @@ void help(void)
            "  -O    specify output type:\n"
            "           private             output PuTTY private key format\n"
            "           private-openssh     export OpenSSH private key\n"
+           "           private-openssh-pem export OpenSSH private key "
+                                             "(force old PEM format)\n"
+           "           private-openssh-new export OpenSSH private key "
+                                             "(force new format)\n"
            "           private-sshcom      export ssh.com private key\n"
            "           public              standard / ssh.com public key\n"
            "           public-openssh      OpenSSH public key\n"
@@ -267,7 +271,8 @@ int main(int argc, char **argv)
     Filename *infilename = NULL, *outfilename = NULL;
     enum { NOKEYGEN, RSA1, RSA2, DSA, ECDSA } keytype = NOKEYGEN;
     char *outfile = NULL, *outfiletmp = NULL;
-    enum { PRIVATE, PUBLIC, PUBLICO, FP, OPENSSH, SSHCOM } outtype = PRIVATE;
+    enum { PRIVATE, PUBLIC, PUBLICO, FP, OPENSSH_PEM,
+           OPENSSH_NEW, SSHCOM } outtype = PRIVATE;
     int bits = 2048;
     char *comment = NULL, *origcomment = NULL;
     int change_passphrase = FALSE;
@@ -460,8 +465,11 @@ int main(int argc, char **argv)
                            outtype = PRIVATE;
                        else if (!strcmp(p, "fingerprint"))
                            outtype = FP;
-                       else if (!strcmp(p, "private-openssh"))
-                           outtype = OPENSSH, sshver = 2;
+                       else if (!strcmp(p, "private-openssh") ||
+                                 !strcmp(p, "private-openssh-pem"))
+                           outtype = OPENSSH_PEM, sshver = 2;
+                       else if (!strcmp(p, "private-openssh-new"))
+                           outtype = OPENSSH_NEW, sshver = 2;
                        else if (!strcmp(p, "private-sshcom"))
                            outtype = SSHCOM, sshver = 2;
                        else {
@@ -536,7 +544,8 @@ int main(int argc, char **argv)
      * We must save the private part when generating a new key.
      */
     if (keytype != NOKEYGEN &&
-       (outtype != PRIVATE && outtype != OPENSSH && outtype != SSHCOM)) {
+       (outtype != PRIVATE && outtype != OPENSSH_PEM &&
+         outtype != OPENSSH_NEW && outtype != SSHCOM)) {
        fprintf(stderr, "puttygen: this would generate a new key but "
                "discard the private part\n");
        return 1;
@@ -590,7 +599,8 @@ int main(int argc, char **argv)
            break;
 
          case SSH_KEYTYPE_SSH2:
-         case SSH_KEYTYPE_OPENSSH:
+         case SSH_KEYTYPE_OPENSSH_PEM:
+         case SSH_KEYTYPE_OPENSSH_NEW:
          case SSH_KEYTYPE_SSHCOM:
            if (sshver == 1) {
                fprintf(stderr, "puttygen: conversion from SSH-2 to SSH-1 keys"
@@ -614,7 +624,8 @@ int main(int argc, char **argv)
      */
     if ((intype == SSH_KEYTYPE_SSH1 && outtype == PRIVATE) ||
        (intype == SSH_KEYTYPE_SSH2 && outtype == PRIVATE) ||
-       (intype == SSH_KEYTYPE_OPENSSH && outtype == OPENSSH) ||
+       (intype == SSH_KEYTYPE_OPENSSH_PEM && outtype == OPENSSH_PEM) ||
+       (intype == SSH_KEYTYPE_OPENSSH_NEW && outtype == OPENSSH_NEW) ||
        (intype == SSH_KEYTYPE_SSHCOM && outtype == SSHCOM)) {
        if (!outfile) {
            outfile = infile;
@@ -632,7 +643,8 @@ int main(int argc, char **argv)
             * Bomb out rather than automatically choosing to write
             * a private key file to stdout.
             */
-           if (outtype==PRIVATE || outtype==OPENSSH || outtype==SSHCOM) {
+           if (outtype == PRIVATE || outtype == OPENSSH_PEM ||
+                outtype == OPENSSH_NEW || outtype == SSHCOM) {
                fprintf(stderr, "puttygen: need to specify an output file\n");
                return 1;
            }
@@ -645,8 +657,11 @@ int main(int argc, char **argv)
      * out a private key format, or (b) the entire input key file
      * is encrypted.
      */
-    if (outtype == PRIVATE || outtype == OPENSSH || outtype == SSHCOM ||
-       intype == SSH_KEYTYPE_OPENSSH || intype == SSH_KEYTYPE_SSHCOM)
+    if (outtype == PRIVATE || outtype == OPENSSH_PEM ||
+        outtype == OPENSSH_NEW || outtype == SSHCOM ||
+       intype == SSH_KEYTYPE_OPENSSH_PEM ||
+       intype == SSH_KEYTYPE_OPENSSH_NEW ||
+        intype == SSH_KEYTYPE_SSHCOM)
        load_encrypted = TRUE;
     else
        load_encrypted = FALSE;
@@ -831,7 +846,8 @@ int main(int argc, char **argv)
            }
            break;
 
-         case SSH_KEYTYPE_OPENSSH:
+         case SSH_KEYTYPE_OPENSSH_PEM:
+         case SSH_KEYTYPE_OPENSSH_NEW:
          case SSH_KEYTYPE_SSHCOM:
            ssh2key = import_ssh2(infilename, intype, passphrase, &error);
            if (ssh2key) {
@@ -1052,19 +1068,25 @@ int main(int argc, char **argv)
        }
        break;
        
-      case OPENSSH:
+      case OPENSSH_PEM:
+      case OPENSSH_NEW:
       case SSHCOM:
        assert(sshver == 2);
        assert(ssh2key);
        random_ref(); /* both foreign key types require randomness,
                        * for IV or padding */
         switch (outtype) {
-          case OPENSSH:
-            real_outtype = SSH_KEYTYPE_OPENSSH;
+          case OPENSSH_PEM:
+            real_outtype = SSH_KEYTYPE_OPENSSH_PEM;
+            break;
+          case OPENSSH_NEW:
+            real_outtype = SSH_KEYTYPE_OPENSSH_NEW;
             break;
           case SSHCOM:
             real_outtype = SSH_KEYTYPE_SSHCOM;
             break;
+          default:
+            assert(0 && "control flow goof");
         }
        ret = export_ssh2(outfilename, real_outtype, ssh2key, passphrase);
        if (!ret) {
index 2c0157d5a7c71f0f0ecacbdefe613145528cb829..ce3887df1813b5dbc8a29a1e7850eb65156d6c54 100644 (file)
--- a/import.c
+++ b/import.c
 int openssh_encrypted(const Filename *filename);
 struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase,
                                  const char **errmsg_p);
-int openssh_write(const Filename *filename, struct ssh2_userkey *key,
-                 char *passphrase);
+int openssh_pem_write(const Filename *filename, struct ssh2_userkey *key,
+                      char *passphrase);
+int openssh_new_write(const Filename *filename, struct ssh2_userkey *key,
+                      char *passphrase);
 
 int sshcom_encrypted(const Filename *filename, char **comment);
 struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
@@ -29,7 +31,9 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
  */
 int import_possible(int type)
 {
-    if (type == SSH_KEYTYPE_OPENSSH)
+    if (type == SSH_KEYTYPE_OPENSSH_PEM)
+       return 1;
+    if (type == SSH_KEYTYPE_OPENSSH_NEW)
        return 1;
     if (type == SSH_KEYTYPE_SSHCOM)
        return 1;
@@ -54,7 +58,7 @@ int import_target_type(int type)
  */
 int import_encrypted(const Filename *filename, int type, char **comment)
 {
-    if (type == SSH_KEYTYPE_OPENSSH) {
+    if (type == SSH_KEYTYPE_OPENSSH_PEM || type == SSH_KEYTYPE_OPENSSH_NEW) {
        /* OpenSSH doesn't do key comments */
        *comment = dupstr(filename_to_str(filename));
        return openssh_encrypted(filename);
@@ -80,7 +84,7 @@ int import_ssh1(const Filename *filename, int type,
 struct ssh2_userkey *import_ssh2(const Filename *filename, int type,
                                 char *passphrase, const char **errmsg_p)
 {
-    if (type == SSH_KEYTYPE_OPENSSH)
+    if (type == SSH_KEYTYPE_OPENSSH_PEM || type == SSH_KEYTYPE_OPENSSH_NEW)
        return openssh_read(filename, passphrase, errmsg_p);
     if (type == SSH_KEYTYPE_SSHCOM)
        return sshcom_read(filename, passphrase, errmsg_p);
@@ -102,8 +106,10 @@ int export_ssh1(const Filename *filename, int type, struct RSAKey *key,
 int export_ssh2(const Filename *filename, int type,
                 struct ssh2_userkey *key, char *passphrase)
 {
-    if (type == SSH_KEYTYPE_OPENSSH)
-       return openssh_write(filename, key, passphrase);
+    if (type == SSH_KEYTYPE_OPENSSH_PEM)
+       return openssh_pem_write(filename, key, passphrase);
+    if (type == SSH_KEYTYPE_OPENSSH_NEW)
+       return openssh_new_write(filename, key, passphrase);
     if (type == SSH_KEYTYPE_SSHCOM)
        return sshcom_write(filename, key, passphrase);
     return 0;
@@ -305,6 +311,11 @@ static int ssh2_read_mpint(void *data, int len, struct mpint_pos *ret)
 
 /* ----------------------------------------------------------------------
  * Code to read and write OpenSSH private keys.
+ *
+ * These come in two more or less entirely different formats, except
+ * that the base64 wrapper is similar enough to handle with the same
+ * code. Accordingly, there's just one function to load OpenSSH keys
+ * in both formats, but separate functions to write the two formats.
  */
 
 typedef enum {
@@ -1263,8 +1274,8 @@ struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase,
     return retval;
 }
 
-int openssh_write(const Filename *filename, struct ssh2_userkey *key,
-                 char *passphrase)
+int openssh_pem_write(const Filename *filename, struct ssh2_userkey *key,
+                      char *passphrase)
 {
     unsigned char *pubblob, *privblob, *spareblob;
     int publen, privlen, sparelen = 0;
@@ -1626,6 +1637,12 @@ int openssh_write(const Filename *filename, struct ssh2_userkey *key,
     return ret;
 }
 
+int openssh_new_write(const Filename *filename, struct ssh2_userkey *key,
+                      char *passphrase)
+{
+    return FALSE;
+}
+
 /* ----------------------------------------------------------------------
  * Code to read ssh.com private keys.
  */
diff --git a/ssh.h b/ssh.h
index c958ddd1623d67ae2093eafffec75b72df7ca764..f81d95c530f65adb7c030732edf9873ef89975e5 100644 (file)
--- a/ssh.h
+++ b/ssh.h
@@ -630,7 +630,9 @@ enum {
     SSH_KEYTYPE_UNOPENABLE,
     SSH_KEYTYPE_UNKNOWN,
     SSH_KEYTYPE_SSH1, SSH_KEYTYPE_SSH2,
-    SSH_KEYTYPE_OPENSSH, SSH_KEYTYPE_SSHCOM
+    SSH_KEYTYPE_OPENSSH_PEM,
+    SSH_KEYTYPE_OPENSSH_NEW,
+    SSH_KEYTYPE_SSHCOM
 };
 int key_type(const Filename *filename);
 char *key_type_to_str(int type);
index 8b80f389959c25de251bcde25e6dd4837cfbaa3a..6af08c75c8312be166fbd051056c74ca4c736cb0 100644 (file)
--- a/sshpubk.c
+++ b/sshpubk.c
@@ -1157,6 +1157,7 @@ int key_type(const Filename *filename)
     char buf[32];
     const char putty2_sig[] = "PuTTY-User-Key-File-";
     const char sshcom_sig[] = "---- BEGIN SSH2 ENCRYPTED PRIVAT";
+    const char openssh_new_sig[] = "-----BEGIN OPENSSH PRIVATE KEY";
     const char openssh_sig[] = "-----BEGIN ";
     int i;
 
@@ -1173,8 +1174,10 @@ int key_type(const Filename *filename)
        return SSH_KEYTYPE_SSH1;
     if (!memcmp(buf, putty2_sig, sizeof(putty2_sig)-1))
        return SSH_KEYTYPE_SSH2;
+    if (!memcmp(buf, openssh_new_sig, sizeof(openssh_new_sig)-1))
+       return SSH_KEYTYPE_OPENSSH_NEW;
     if (!memcmp(buf, openssh_sig, sizeof(openssh_sig)-1))
-       return SSH_KEYTYPE_OPENSSH;
+       return SSH_KEYTYPE_OPENSSH_PEM;
     if (!memcmp(buf, sshcom_sig, sizeof(sshcom_sig)-1))
        return SSH_KEYTYPE_SSHCOM;
     return SSH_KEYTYPE_UNKNOWN;               /* unrecognised or EOF */
@@ -1191,7 +1194,8 @@ char *key_type_to_str(int type)
       case SSH_KEYTYPE_UNKNOWN: return "not a private key"; break;
       case SSH_KEYTYPE_SSH1: return "SSH-1 private key"; break;
       case SSH_KEYTYPE_SSH2: return "PuTTY SSH-2 private key"; break;
-      case SSH_KEYTYPE_OPENSSH: return "OpenSSH SSH-2 private key"; break;
+      case SSH_KEYTYPE_OPENSSH_PEM: return "OpenSSH SSH-2 private key (old PEM format)"; break;
+      case SSH_KEYTYPE_OPENSSH_NEW: return "OpenSSH SSH-2 private key (new format)"; break;
       case SSH_KEYTYPE_SSHCOM: return "ssh.com SSH-2 private key"; break;
       default: return "INTERNAL ERROR"; break;
     }
index 8f263efcbe3b421de14e1be74b492511a24dbd2e..e7f240a57aa436f740a7a18bae494b45f27431fc 100644 (file)
@@ -534,7 +534,9 @@ enum {
     IDC_BITSSTATIC, IDC_BITS,
     IDC_ABOUT,
     IDC_GIVEHELP,
-    IDC_IMPORT, IDC_EXPORT_OPENSSH, IDC_EXPORT_SSHCOM
+    IDC_IMPORT,
+    IDC_EXPORT_OPENSSH_PEM, IDC_EXPORT_OPENSSH_NEW,
+    IDC_EXPORT_SSHCOM
 };
 
 static const int nokey_ids[] = { IDC_NOKEY, 0 };
@@ -579,7 +581,9 @@ void ui_set_state(HWND hwnd, struct MainDlgState *state, int status)
         EnableMenuItem(state->keymenu, IDC_KEYSSH2ECDSA,
                        MF_ENABLED|MF_BYCOMMAND);
        EnableMenuItem(state->cvtmenu, IDC_IMPORT, MF_ENABLED|MF_BYCOMMAND);
-       EnableMenuItem(state->cvtmenu, IDC_EXPORT_OPENSSH,
+       EnableMenuItem(state->cvtmenu, IDC_EXPORT_OPENSSH_PEM,
+                      MF_GRAYED|MF_BYCOMMAND);
+       EnableMenuItem(state->cvtmenu, IDC_EXPORT_OPENSSH_NEW,
                       MF_GRAYED|MF_BYCOMMAND);
        EnableMenuItem(state->cvtmenu, IDC_EXPORT_SSHCOM,
                       MF_GRAYED|MF_BYCOMMAND);
@@ -607,7 +611,9 @@ void ui_set_state(HWND hwnd, struct MainDlgState *state, int status)
         EnableMenuItem(state->keymenu, IDC_KEYSSH2ECDSA,
                        MF_GRAYED|MF_BYCOMMAND);
        EnableMenuItem(state->cvtmenu, IDC_IMPORT, MF_GRAYED|MF_BYCOMMAND);
-       EnableMenuItem(state->cvtmenu, IDC_EXPORT_OPENSSH,
+       EnableMenuItem(state->cvtmenu, IDC_EXPORT_OPENSSH_PEM,
+                      MF_GRAYED|MF_BYCOMMAND);
+       EnableMenuItem(state->cvtmenu, IDC_EXPORT_OPENSSH_NEW,
                       MF_GRAYED|MF_BYCOMMAND);
        EnableMenuItem(state->cvtmenu, IDC_EXPORT_SSHCOM,
                       MF_GRAYED|MF_BYCOMMAND);
@@ -643,7 +649,8 @@ void ui_set_state(HWND hwnd, struct MainDlgState *state, int status)
 #define do_export_menuitem(x,y) \
     EnableMenuItem(state->cvtmenu, x, MF_BYCOMMAND | \
                       (import_target_type(y)==type?MF_ENABLED:MF_GRAYED))
-       do_export_menuitem(IDC_EXPORT_OPENSSH, SSH_KEYTYPE_OPENSSH);
+       do_export_menuitem(IDC_EXPORT_OPENSSH_PEM, SSH_KEYTYPE_OPENSSH_PEM);
+       do_export_menuitem(IDC_EXPORT_OPENSSH_NEW, SSH_KEYTYPE_OPENSSH_NEW);
        do_export_menuitem(IDC_EXPORT_SSHCOM, SSH_KEYTYPE_SSHCOM);
 #undef do_export_menuitem
        break;
@@ -883,8 +890,10 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
            menu1 = CreateMenu();
            AppendMenu(menu1, MF_ENABLED, IDC_IMPORT, "&Import key");
            AppendMenu(menu1, MF_SEPARATOR, 0, 0);
-           AppendMenu(menu1, MF_ENABLED, IDC_EXPORT_OPENSSH,
-                      "Export &OpenSSH key");
+           AppendMenu(menu1, MF_ENABLED, IDC_EXPORT_OPENSSH_PEM,
+                      "Export &OpenSSH key (old PEM format)");
+           AppendMenu(menu1, MF_ENABLED, IDC_EXPORT_OPENSSH_NEW,
+                      "Export &OpenSSH key (new format)");
            AppendMenu(menu1, MF_ENABLED, IDC_EXPORT_SSHCOM,
                       "Export &ssh.com key");
            AppendMenu(menu, MF_POPUP | MF_ENABLED, (UINT) menu1,
@@ -1161,7 +1170,8 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
            }
            break;
          case IDC_SAVE:
-          case IDC_EXPORT_OPENSSH:
+          case IDC_EXPORT_OPENSSH_PEM:
+          case IDC_EXPORT_OPENSSH_NEW:
           case IDC_EXPORT_SSHCOM:
            if (HIWORD(wParam) != BN_CLICKED)
                break;
@@ -1177,8 +1187,10 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
                 else
                     realtype = SSH_KEYTYPE_SSH1;
 
-                if (LOWORD(wParam) == IDC_EXPORT_OPENSSH)
-                    type = SSH_KEYTYPE_OPENSSH;
+                if (LOWORD(wParam) == IDC_EXPORT_OPENSSH_PEM)
+                    type = SSH_KEYTYPE_OPENSSH_PEM;
+                else if (LOWORD(wParam) == IDC_EXPORT_OPENSSH_NEW)
+                    type = SSH_KEYTYPE_OPENSSH_NEW;
                 else if (LOWORD(wParam) == IDC_EXPORT_SSHCOM)
                     type = SSH_KEYTYPE_SSHCOM;
                 else
@@ -1453,7 +1465,8 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
               case IDC_BITS:
                 topic = WINHELP_CTX_puttygen_bits; break;
               case IDC_IMPORT:
-              case IDC_EXPORT_OPENSSH:
+              case IDC_EXPORT_OPENSSH_PEM:
+              case IDC_EXPORT_OPENSSH_NEW:
               case IDC_EXPORT_SSHCOM:
                 topic = WINHELP_CTX_puttygen_conversions; break;
             }