]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Fix a segfault in parsing OpenSSH private key files.
authorSimon Tatham <anakin@pobox.com>
Tue, 10 Nov 2015 18:47:55 +0000 (18:47 +0000)
committerSimon Tatham <anakin@pobox.com>
Tue, 10 Nov 2015 19:05:49 +0000 (19:05 +0000)
The initial test for a line ending with "PRIVATE KEY-----" failed to
take into account the possibility that the line might be shorter than
that. Fixed by introducing a new library function strendswith(), and
strstartswith() for good measure, and using that.

Thanks to Hanno Böck for spotting this, with the aid of AFL.

import.c
misc.c
misc.h

index 508ef782a03b2f62541ac1cb51213d7a7baa4185..49846a6e3fc13b53180081bf93cf686b46a1f3d7 100644 (file)
--- a/import.c
+++ b/import.c
@@ -383,8 +383,8 @@ static struct openssh_pem_key *load_openssh_pem_key(const Filename *filename,
        goto error;
     }
     strip_crlf(line);
-    if (0 != strncmp(line, "-----BEGIN ", 11) ||
-       0 != strcmp(line+strlen(line)-16, "PRIVATE KEY-----")) {
+    if (!strstartswith(line, "-----BEGIN ") ||
+        !strendswith(line, "PRIVATE KEY-----")) {
        errmsg = "file does not begin with OpenSSH key header";
        goto error;
     }
@@ -421,8 +421,8 @@ static struct openssh_pem_key *load_openssh_pem_key(const Filename *filename,
            goto error;
        }
        strip_crlf(line);
-       if (0 == strncmp(line, "-----END ", 9) &&
-           0 == strcmp(line+strlen(line)-16, "PRIVATE KEY-----")) {
+       if (strstartswith(line, "-----END ") &&
+           strendswith(line, "PRIVATE KEY-----")) {
             sfree(line);
             line = NULL;
            break;                     /* done */
diff --git a/misc.c b/misc.c
index 6af441c301129df44f30009c4ae4829c71d29242..618ca2971d0646fc7a889e4a65bd97edbad0b27f 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -1087,3 +1087,14 @@ int get_ssh_uint32(int *datalen, const void **data, unsigned *ret)
     *data = (const char *)*data + 4;
     return TRUE;
 }
+
+int strstartswith(const char *s, const char *t)
+{
+    return !memcmp(s, t, strlen(t));
+}
+
+int strendswith(const char *s, const char *t)
+{
+    size_t slen = strlen(s), tlen = strlen(t);
+    return slen >= tlen && !strcmp(s + (slen - tlen), t);
+}
diff --git a/misc.h b/misc.h
index 8c8377f9e823007a4118af6848571baf4675678d..ae33e96e3fff7cb8dfd8d3d6cfc26a5bd5d2370c 100644 (file)
--- a/misc.h
+++ b/misc.h
@@ -52,6 +52,8 @@ int toint(unsigned);
 
 char *fgetline(FILE *fp);
 char *chomp(char *str);
+int strstartswith(const char *s, const char *t);
+int strendswith(const char *s, const char *t);
 
 void base64_encode_atom(const unsigned char *data, int n, char *out);
 int base64_decode_atom(const char *atom, unsigned char *out);