]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - sshpubk.c
Sort out the mess with OpenSSH key file formats.
[PuTTY.git] / sshpubk.c
index 8b80f389959c25de251bcde25e6dd4837cfbaa3a..6aba82fc80630d19f2cac5bbfbf296c7d8d6752d 100644 (file)
--- a/sshpubk.c
+++ b/sshpubk.c
@@ -557,22 +557,29 @@ struct ssh2_userkey ssh2_wrong_passphrase = {
     NULL, NULL, NULL
 };
 
-const struct ssh_signkey *find_pubkey_alg(const char *name)
+const struct ssh_signkey *find_pubkey_alg_len(int namelen, const char *name)
 {
-    if (!strcmp(name, "ssh-rsa"))
+    if (match_ssh_id(namelen, name, "ssh-rsa"))
        return &ssh_rsa;
-    else if (!strcmp(name, "ssh-dss"))
+    else if (match_ssh_id(namelen, name, "ssh-dss"))
        return &ssh_dss;
-    else if (!strcmp(name, "ecdsa-sha2-nistp256"))
+    else if (match_ssh_id(namelen, name, "ecdsa-sha2-nistp256"))
         return &ssh_ecdsa_nistp256;
-    else if (!strcmp(name, "ecdsa-sha2-nistp384"))
+    else if (match_ssh_id(namelen, name, "ecdsa-sha2-nistp384"))
         return &ssh_ecdsa_nistp384;
-    else if (!strcmp(name, "ecdsa-sha2-nistp521"))
+    else if (match_ssh_id(namelen, name, "ecdsa-sha2-nistp521"))
         return &ssh_ecdsa_nistp521;
+    else if (match_ssh_id(namelen, name, "ssh-ed25519"))
+        return &ssh_ecdsa_ed25519;
     else
        return NULL;
 }
 
+const struct ssh_signkey *find_pubkey_alg(const char *name)
+{
+    return find_pubkey_alg_len(strlen(name), name);
+}
+
 struct ssh2_userkey *ssh2_load_userkey(const Filename *filename,
                                       char *passphrase, const char **errorstr)
 {
@@ -1157,6 +1164,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 +1181,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,8 +1201,16 @@ 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;
+        /*
+         * This function is called with a key type derived from
+         * looking at an actual key file, so the output-only type
+         * OPENSSH_AUTO should never get here, and is much an INTERNAL
+         * ERROR as a code we don't even understand.
+         */
+      case SSH_KEYTYPE_OPENSSH_AUTO: return "INTERNAL ERROR (OPENSSH_AUTO)"; break;
       default: return "INTERNAL ERROR"; break;
     }
 }