]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - sshpubk.c
first pass
[PuTTY.git] / sshpubk.c
index 053eeb6f233b66d0e13b0a9888404d1811bbb152..1a27c313974506ec4fd9e6051b47e3f414a87c97 100644 (file)
--- a/sshpubk.c
+++ b/sshpubk.c
@@ -309,6 +309,8 @@ int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen,
             *commentptr = commentp ? dupstr(commentp) : NULL;
         *blob = rsa_public_blob(&key, bloblen);
         freersakey(&key);
+        sfree(line);
+        fclose(fp);
         return 1;
 
       not_public_either:
@@ -853,7 +855,7 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename,
     ret = snew(struct ssh2_userkey);
     ret->alg = alg;
     ret->comment = comment;
-    ret->data = alg->createkey(public_blob, public_blob_len,
+    ret->data = alg->createkey(alg, public_blob, public_blob_len,
                               private_blob, private_blob_len);
     if (!ret->data) {
        sfree(ret);
@@ -944,6 +946,7 @@ unsigned char *rfc4716_loadpub(FILE *fp, char **algorithm,
             }
 
             *q = '\0';
+            sfree(comment);   /* *just* in case of multiple Comment headers */
             comment = dupstr(line);
         } else if (!strcmp(line, "Subject") ||
                    !strncmp(line, "x-", 2)) {
@@ -1089,6 +1092,7 @@ unsigned char *openssh_loadpub(FILE *fp, char **algorithm,
         *commentptr = comment;
     else
         sfree(comment);
+    sfree(line);
     return pubblob;
 
   error:
@@ -1191,7 +1195,7 @@ unsigned char *ssh2_userkey_loadpub(const Filename *filename, char **algorithm,
     if (pub_blob_len)
        *pub_blob_len = public_blob_len;
     if (algorithm)
-       *algorithm = alg->name;
+       *algorithm = dupstr(alg->name);
     return public_blob;
 
     /*
@@ -1308,7 +1312,7 @@ int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key,
     int passlen;
     int cipherblk;
     int i;
-    char *cipherstr;
+    const char *cipherstr;
     unsigned char priv_mac[20];
 
     /*
@@ -1568,6 +1572,62 @@ void ssh2_write_pubkey(FILE *fp, const char *comment,
     }
 }
 
+/* ----------------------------------------------------------------------
+ * Utility functions to compute SSH-2 fingerprints in a uniform way.
+ */
+char *ssh2_fingerprint_blob(const void *blob, int bloblen)
+{
+    unsigned char digest[16];
+    char fingerprint_str[16*3];
+    const char *algstr;
+    int alglen;
+    const struct ssh_signkey *alg;
+    int i;
+
+    /*
+     * The fingerprint hash itself is always just the MD5 of the blob.
+     */
+    MD5Simple(blob, bloblen, digest);
+    for (i = 0; i < 16; i++)
+        sprintf(fingerprint_str + i*3, "%02x%s", digest[i], i==15 ? "" : ":");
+
+    /*
+     * Identify the key algorithm, if possible.
+     */
+    alglen = toint(GET_32BIT((const unsigned char *)blob));
+    if (alglen > 0 && alglen < bloblen-4) {
+        algstr = (const char *)blob + 4;
+
+        /*
+         * If we can actually identify the algorithm as one we know
+         * about, get hold of the key's bit count too.
+         */
+        alg = find_pubkey_alg_len(alglen, algstr);
+        if (alg) {
+            int bits = alg->pubkey_bits(alg, blob, bloblen);
+            return dupprintf("%.*s %d %s", alglen, algstr,
+                             bits, fingerprint_str);
+        } else {
+            return dupprintf("%.*s %s", alglen, algstr, fingerprint_str);
+        }
+    } else {
+        /*
+         * No algorithm available (which means a seriously confused
+         * key blob, but there we go). Return only the hash.
+         */
+        return dupstr(fingerprint_str);
+    }
+}
+
+char *ssh2_fingerprint(const struct ssh_signkey *alg, void *data)
+{
+    int len;
+    unsigned char *blob = alg->public_blob(data, &len);
+    char *ret = ssh2_fingerprint_blob(blob, len);
+    sfree(blob);
+    return ret;
+}
+
 /* ----------------------------------------------------------------------
  * Determine the type of a private key file.
  */
@@ -1632,7 +1692,7 @@ int key_type(const Filename *filename)
  * Convert the type word to a string, for `wrong type' error
  * messages.
  */
-char *key_type_to_str(int type)
+const char *key_type_to_str(int type)
 {
     switch (type) {
       case SSH_KEYTYPE_UNOPENABLE: return "unable to open file"; break;