]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - sshpubk.c
Merge branch 'pre-0.64'
[PuTTY.git] / sshpubk.c
index f35febe31dc3c0d80b453e2a2a1dc04abd37d25b..cd35afd5ad2a15265324b03fa22bdedfeb4779f5 100644 (file)
--- a/sshpubk.c
+++ b/sshpubk.c
@@ -67,14 +67,15 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only,
     i += 4;
 
     /* Now the serious stuff. An ordinary SSH-1 public key. */
-    i += makekey(buf + i, len, key, NULL, 1);
-    if (i < 0)
+    = makekey(buf + i, len, key, NULL, 1);
+    if (j < 0)
        goto end;                      /* overran */
+    i += j;
 
     /* Next, the comment field. */
-    j = GET_32BIT(buf + i);
+    j = toint(GET_32BIT(buf + i));
     i += 4;
-    if (len - i < j)
+    if (j < 0 || len - i < j)
        goto end;
     comment = snewn(j + 1, char);
     if (comment) {
@@ -108,7 +109,7 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only,
        MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
        MD5Final(keybuf, &md5c);
        des3_decrypt_pubkey(keybuf, buf + i, (len - i + 7) & ~7);
-       memset(keybuf, 0, sizeof(keybuf));      /* burn the evidence */
+       smemclr(keybuf, sizeof(keybuf));        /* burn the evidence */
     }
 
     /*
@@ -150,7 +151,7 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only,
        ret = 1;
 
   end:
-    memset(buf, 0, sizeof(buf));       /* burn the evidence */
+    smemclr(buf, sizeof(buf));       /* burn the evidence */
     return ret;
 }
 
@@ -162,7 +163,7 @@ int loadrsakey(const Filename *filename, struct RSAKey *key, char *passphrase,
     int ret = 0;
     const char *error = NULL;
 
-    fp = f_open(*filename, "rb", FALSE);
+    fp = f_open(filename, "rb", FALSE);
     if (!fp) {
        error = "can't open file";
        goto end;
@@ -203,7 +204,7 @@ int rsakey_encrypted(const Filename *filename, char **comment)
     FILE *fp;
     char buf[64];
 
-    fp = f_open(*filename, "rb", FALSE);
+    fp = f_open(filename, "rb", FALSE);
     if (!fp)
        return 0;                      /* doesn't even exist */
 
@@ -241,7 +242,7 @@ int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen,
     *bloblen = 0;
     ret = 0;
 
-    fp = f_open(*filename, "rb", FALSE);
+    fp = f_open(filename, "rb", FALSE);
     if (!fp) {
        error = "can't open file";
        goto end;
@@ -257,8 +258,8 @@ int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen,
            *blob = rsa_public_blob(&key, bloblen);
            freersakey(&key);
            ret = 1;
-           fp = NULL;
        }
+       fp = NULL; /* loadrsakey_main unconditionally closes fp */
     } else {
        error = "not an SSH-1 RSA file";
     }
@@ -358,13 +359,13 @@ int saversakey(const Filename *filename, struct RSAKey *key, char *passphrase)
        MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
        MD5Final(keybuf, &md5c);
        des3_encrypt_pubkey(keybuf, estart, p - estart);
-       memset(keybuf, 0, sizeof(keybuf));      /* burn the evidence */
+       smemclr(keybuf, sizeof(keybuf));        /* burn the evidence */
     }
 
     /*
      * Done. Write the result to the file.
      */
-    fp = f_open(*filename, "wb", TRUE);
+    fp = f_open(filename, "wb", TRUE);
     if (fp) {
        int ret = (fwrite(buf, 1, p - buf, fp) == (size_t) (p - buf));
         if (fclose(fp))
@@ -462,7 +463,7 @@ static int read_header(FILE * fp, char *header)
     int len = 39;
     int c;
 
-    while (len > 0) {
+    while (1) {
        c = fgetc(fp);
        if (c == '\n' || c == '\r' || c == EOF)
            return 0;                  /* failure */
@@ -495,16 +496,14 @@ static char *read_body(FILE * fp)
 
     while (1) {
        c = fgetc(fp);
-       if (c == '\r' || c == '\n') {
-           c = fgetc(fp);
-           if (c != '\r' && c != '\n' && c != EOF)
-               ungetc(c, fp);
+       if (c == '\r' || c == '\n' || c == EOF) {
+           if (c != EOF) {
+               c = fgetc(fp);
+               if (c != '\r' && c != '\n')
+                   ungetc(c, fp);
+           }
            return text;
        }
-       if (c == EOF) {
-           sfree(text);
-           return NULL;
-       }
        if (len + 1 >= size) {
            size += 128;
            text = sresize(text, size, char);
@@ -514,54 +513,6 @@ static char *read_body(FILE * fp)
     }
 }
 
-int base64_decode_atom(char *atom, unsigned char *out)
-{
-    int vals[4];
-    int i, v, len;
-    unsigned word;
-    char c;
-
-    for (i = 0; i < 4; i++) {
-       c = atom[i];
-       if (c >= 'A' && c <= 'Z')
-           v = c - 'A';
-       else if (c >= 'a' && c <= 'z')
-           v = c - 'a' + 26;
-       else if (c >= '0' && c <= '9')
-           v = c - '0' + 52;
-       else if (c == '+')
-           v = 62;
-       else if (c == '/')
-           v = 63;
-       else if (c == '=')
-           v = -1;
-       else
-           return 0;                  /* invalid atom */
-       vals[i] = v;
-    }
-
-    if (vals[0] == -1 || vals[1] == -1)
-       return 0;
-    if (vals[2] == -1 && vals[3] != -1)
-       return 0;
-
-    if (vals[3] != -1)
-       len = 3;
-    else if (vals[2] != -1)
-       len = 2;
-    else
-       len = 1;
-
-    word = ((vals[0] << 18) |
-           (vals[1] << 12) | ((vals[2] & 0x3F) << 6) | (vals[3] & 0x3F));
-    out[0] = (word >> 16) & 0xFF;
-    if (len > 1)
-       out[1] = (word >> 8) & 0xFF;
-    if (len > 2)
-       out[2] = word & 0xFF;
-    return len;
-}
-
 static unsigned char *read_blob(FILE * fp, int nlines, int *bloblen)
 {
     unsigned char *blob;
@@ -612,6 +563,12 @@ const struct ssh_signkey *find_pubkey_alg(const char *name)
        return &ssh_rsa;
     else if (!strcmp(name, "ssh-dss"))
        return &ssh_dss;
+    else if (!strcmp(name, "ecdsa-sha2-nistp256"))
+        return &ssh_ecdsa_nistp256;
+    else if (!strcmp(name, "ecdsa-sha2-nistp384"))
+        return &ssh_ecdsa_nistp384;
+    else if (!strcmp(name, "ecdsa-sha2-nistp521"))
+        return &ssh_ecdsa_nistp521;
     else
        return NULL;
 }
@@ -634,7 +591,7 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename,
     encryption = comment = mac = NULL;
     public_blob = private_blob = NULL;
 
-    fp = f_open(*filename, "rb", FALSE);
+    fp = f_open(filename, "rb", FALSE);
     if (!fp) {
        error = "can't open file";
        goto error;
@@ -649,6 +606,11 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename,
        /* this is an old key file; warn and then continue */
        old_keyfile_warning();
        old_fmt = 1;
+    } else if (0 == strncmp(header, "PuTTY-User-Key-File-", 20)) {
+       /* this is a key file FROM THE FUTURE; refuse it, but with a
+         * more specific error message than the generic one below */
+       error = "PuTTY key format too new";
+       goto error;
     } else {
        error = "not a PuTTY SSH-2 private key";
        goto error;
@@ -676,7 +638,6 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename,
        cipher = 0;
        cipherblk = 1;
     } else {
-       sfree(encryption);
        goto error;
     }
 
@@ -796,14 +757,14 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename,
 
            hmac_sha1_simple(mackey, 20, macdata, maclen, binary);
 
-           memset(mackey, 0, sizeof(mackey));
-           memset(&s, 0, sizeof(s));
+           smemclr(mackey, sizeof(mackey));
+           smemclr(&s, sizeof(s));
        } else {
            SHA_Simple(macdata, maclen, binary);
        }
 
        if (free_macdata) {
-           memset(macdata, 0, maclen);
+           smemclr(macdata, maclen);
            sfree(macdata);
        }
 
@@ -824,6 +785,7 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename,
        }
     }
     sfree(mac);
+    mac = NULL;
 
     /*
      * Create and return the key.
@@ -834,7 +796,6 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename,
     ret->data = alg->createkey(public_blob, public_blob_len,
                               private_blob, private_blob_len);
     if (!ret->data) {
-       sfree(ret->comment);
        sfree(ret);
        ret = NULL;
        error = "createkey failed";
@@ -883,7 +844,7 @@ unsigned char *ssh2_userkey_loadpub(const Filename *filename, char **algorithm,
 
     public_blob = NULL;
 
-    fp = f_open(*filename, "rb", FALSE);
+    fp = f_open(filename, "rb", FALSE);
     if (!fp) {
        error = "can't open file";
        goto error;
@@ -893,7 +854,10 @@ unsigned char *ssh2_userkey_loadpub(const Filename *filename, char **algorithm,
     if (!read_header(fp, header)
        || (0 != strcmp(header, "PuTTY-User-Key-File-2") &&
            0 != strcmp(header, "PuTTY-User-Key-File-1"))) {
-       error = "not a PuTTY SSH-2 private key";
+        if (0 == strncmp(header, "PuTTY-User-Key-File-", 20))
+            error = "PuTTY key format too new";
+        else
+            error = "not a PuTTY SSH-2 private key";
        goto error;
     }
     error = "file format error";
@@ -964,7 +928,7 @@ int ssh2_userkey_encrypted(const Filename *filename, char **commentptr)
     if (commentptr)
        *commentptr = NULL;
 
-    fp = f_open(*filename, "rb", FALSE);
+    fp = f_open(filename, "rb", FALSE);
     if (!fp)
        return 0;
     if (!read_header(fp, header)
@@ -1002,6 +966,8 @@ int ssh2_userkey_encrypted(const Filename *filename, char **commentptr)
 
     if (commentptr)
        *commentptr = comment;
+    else
+        sfree(comment);
 
     fclose(fp);
     if (!strcmp(b, "aes256-cbc"))
@@ -1118,10 +1084,10 @@ int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key,
            SHA_Bytes(&s, passphrase, strlen(passphrase));
        SHA_Final(&s, mackey);
        hmac_sha1_simple(mackey, 20, macdata, maclen, priv_mac);
-       memset(macdata, 0, maclen);
+       smemclr(macdata, maclen);
        sfree(macdata);
-       memset(mackey, 0, sizeof(mackey));
-       memset(&s, 0, sizeof(s));
+       smemclr(mackey, sizeof(mackey));
+       smemclr(&s, sizeof(s));
     }
 
     if (passphrase) {
@@ -1141,11 +1107,11 @@ int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key,
        aes256_encrypt_pubkey(key, priv_blob_encrypted,
                              priv_encrypted_len);
 
-       memset(key, 0, sizeof(key));
-       memset(&s, 0, sizeof(s));
+       smemclr(key, sizeof(key));
+       smemclr(&s, sizeof(s));
     }
 
-    fp = f_open(*filename, "w", TRUE);
+    fp = f_open(filename, "w", TRUE);
     if (!fp)
        return 0;
     fprintf(fp, "PuTTY-User-Key-File-2: %s\n", key->alg->name);
@@ -1162,7 +1128,7 @@ int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key,
     fclose(fp);
 
     sfree(pub_blob);
-    memset(priv_blob, 0, priv_blob_len);
+    smemclr(priv_blob, priv_blob_len);
     sfree(priv_blob);
     sfree(priv_blob_encrypted);
     return 1;
@@ -1181,7 +1147,7 @@ int key_type(const Filename *filename)
     const char openssh_sig[] = "-----BEGIN ";
     int i;
 
-    fp = f_open(*filename, "r", FALSE);
+    fp = f_open(filename, "r", FALSE);
     if (!fp)
        return SSH_KEYTYPE_UNOPENABLE;
     i = fread(buf, 1, sizeof(buf), fp);