]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - import.c
Unix Pageant: support -d, to delete a key from the agent.
[PuTTY.git] / import.c
index 6206fdb110ac38f32bb7929add785d70c5f071a8..34f29acf3600007a9a2149645e78ac1c8c041796 100644 (file)
--- a/import.c
+++ b/import.c
@@ -20,6 +20,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename,
 struct ssh2_userkey *openssh_new_read(const Filename *filename,
                                       char *passphrase,
                                       const char **errmsg_p);
+int openssh_auto_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,
@@ -117,8 +119,8 @@ 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_PEM)
-       return openssh_pem_write(filename, key, passphrase);
+    if (type == SSH_KEYTYPE_OPENSSH_AUTO)
+       return openssh_auto_write(filename, key, passphrase);
     if (type == SSH_KEYTYPE_OPENSSH_NEW)
        return openssh_new_write(filename, key, passphrase);
     if (type == SSH_KEYTYPE_SSHCOM)
@@ -1628,8 +1630,8 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
 
     retkey = NULL;
     for (key_index = 0; key_index < key->nkeys; key_index++) {
-        unsigned char *thiskey;
-        int thiskeylen, npieces;
+        const unsigned char *thiskey;
+        int thiskeylen;
 
         /*
          * Read the key type, which will tell us how to scan over
@@ -1647,35 +1649,25 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
          * of strings, so we just need to know how many of them to
          * skip over. (The numbers below exclude the key comment.)
          */
-        if (match_ssh_id(stringlen, string, "ssh-rsa")) {
-            alg = &ssh_rsa;
-            npieces = 6;           /* n,e,d,iqmp,q,p */
-        } else if (match_ssh_id(stringlen, string, "ssh-dss")) {
-            alg = &ssh_dss;
-            npieces = 5;           /* p,q,g,y,x */
-        } else if (match_ssh_id(stringlen, string,
-                                "ecdsa-sha2-nistp256")) {
-            alg = &ssh_ecdsa_nistp256;
-            npieces = 3;      /* curve name, point, private exponent */
-        } else if (match_ssh_id(stringlen, string,
-                                "ecdsa-sha2-nistp384")) {
-            alg = &ssh_ecdsa_nistp384;
-            npieces = 3;      /* curve name, point, private exponent */
-        } else if (match_ssh_id(stringlen, string,
-                                "ecdsa-sha2-nistp521")) {
-            alg = &ssh_ecdsa_nistp521;
-            npieces = 3;      /* curve name, point, private exponent */
-        } else {
-            errmsg = "private key did not start with type string\n";
+        {
+            /* find_pubkey_alg needs a zero-terminated copy of the
+             * algorithm name */
+            char *name_zt = dupprintf("%.*s", stringlen, (char *)string);
+            alg = find_pubkey_alg(name_zt);
+            sfree(name_zt);
+        }
+
+        if (!alg) {
+            errmsg = "private key type not recognised\n";
             goto error;
         }
 
-        thiskey = (unsigned char *)priv;
+        thiskey = priv;
 
         /*
          * Skip over the pieces of key.
          */
-        for (i = 0; i < npieces; i++) {
+        for (i = 0; i < alg->openssh_private_npieces; i++) {
             if (!(string = get_ssh_string(&privlen, &priv, &stringlen))) {
                 errmsg = "ran out of data in mid-private-key";
                 goto error;
@@ -1898,6 +1890,28 @@ int openssh_new_write(const Filename *filename, struct ssh2_userkey *key,
     return ret;
 }
 
+/* ----------------------------------------------------------------------
+ * The switch function openssh_auto_write(), which chooses one of the
+ * concrete OpenSSH output formats based on the key type.
+ */
+int openssh_auto_write(const Filename *filename, struct ssh2_userkey *key,
+                       char *passphrase)
+{
+    /*
+     * The old OpenSSH format supports a fixed list of key types. We
+     * assume that anything not in that fixed list is newer, and hence
+     * will use the new format.
+     */
+    if (key->alg == &ssh_dss ||
+        key->alg == &ssh_rsa ||
+        key->alg == &ssh_ecdsa_nistp256 ||
+        key->alg == &ssh_ecdsa_nistp384 ||
+        key->alg == &ssh_ecdsa_nistp521)
+        return openssh_pem_write(filename, key, passphrase);
+    else
+        return openssh_new_write(filename, key, passphrase);
+}
+
 /* ----------------------------------------------------------------------
  * Code to read ssh.com private keys.
  */