]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - import.c
first pass
[PuTTY.git] / import.c
index 51b236a0517b29e92c0cb8c901ea18ab0386cc34..adf68777dcd96de71faef9e3de49f5a0aed0ddf1 100644 (file)
--- a/import.c
+++ b/import.c
@@ -195,14 +195,16 @@ static int ber_read_id_len(void *source, int sourcelen,
        return -1;
 
     if (*p & 0x80) {
+        unsigned len;
        int n = *p & 0x7F;
        p++, sourcelen--;
        if (sourcelen < n)
            return -1;
-       *length = 0;
+       len = 0;
        while (n--)
-           *length = (*length << 8) | (*p++);
+           len = (len << 8) | (*p++);
        sourcelen -= n;
+        *length = toint(len);
     } else {
        *length = *p;
        p++, sourcelen--;
@@ -383,8 +385,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 +423,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 */
@@ -657,7 +659,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename,
      * decrypt, if the key was encrypted. */
     ret = ber_read_id_len(p, key->keyblob_len, &id, &len, &flags);
     p += ret;
-    if (ret < 0 || id != 16) {
+    if (ret < 0 || id != 16 || len < 0 ||
+        key->keyblob+key->keyblob_len-p < len) {
         errmsg = "ASN.1 decoding failure";
         retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
         goto error;
@@ -683,8 +686,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename,
         ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
                               &id, &len, &flags);
         p += ret;
-        if (ret < 0 || id != 2 || key->keyblob+key->keyblob_len-p < len ||
-            len != 1 || p[0] != 1) {
+        if (ret < 0 || id != 2 || len != 1 ||
+            key->keyblob+key->keyblob_len-p < len || p[0] != 1) {
             errmsg = "ASN.1 decoding failure";
             retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
             goto error;
@@ -694,7 +697,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename,
         ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
                               &id, &len, &flags);
         p += ret;
-        if (ret < 0 || id != 4 || key->keyblob+key->keyblob_len-p < len) {
+        if (ret < 0 || id != 4 || len < 0 ||
+            key->keyblob+key->keyblob_len-p < len) {
             errmsg = "ASN.1 decoding failure";
             retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
             goto error;
@@ -706,7 +710,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename,
         ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
                               &id, &len, &flags);
         p += ret;
-        if (ret < 0 || id != 0 || key->keyblob+key->keyblob_len-p < len) {
+        if (ret < 0 || id != 0 || len < 0 ||
+            key->keyblob+key->keyblob_len-p < len) {
             errmsg = "ASN.1 decoding failure";
             retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
             goto error;
@@ -714,7 +719,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename,
         ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
                               &id, &len, &flags);
         p += ret;
-        if (ret < 0 || id != 6 || key->keyblob+key->keyblob_len-p < len) {
+        if (ret < 0 || id != 6 || len < 0 ||
+            key->keyblob+key->keyblob_len-p < len) {
             errmsg = "ASN.1 decoding failure";
             retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
             goto error;
@@ -730,7 +736,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename,
         ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
                               &id, &len, &flags);
         p += ret;
-        if (ret < 0 || id != 1 || key->keyblob+key->keyblob_len-p < len) {
+        if (ret < 0 || id != 1 || len < 0 ||
+            key->keyblob+key->keyblob_len-p < len) {
             errmsg = "ASN.1 decoding failure";
             retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
             goto error;
@@ -738,7 +745,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename,
         ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
                               &id, &len, &flags);
         p += ret;
-        if (ret < 0 || id != 3 || key->keyblob+key->keyblob_len-p < len ||
+        if (ret < 0 || id != 3 || len < 0 ||
+            key->keyblob+key->keyblob_len-p < len ||
             len != ((((curve->fieldBits + 7) / 8) * 2) + 2)) {
             errmsg = "ASN.1 decoding failure";
             retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
@@ -813,7 +821,7 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename,
             ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
                                   &id, &len, &flags);
             p += ret;
-            if (ret < 0 || id != 2 ||
+            if (ret < 0 || id != 2 || len < 0 ||
                 key->keyblob+key->keyblob_len-p < len) {
                 errmsg = "ASN.1 decoding failure";
                 retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
@@ -886,6 +894,8 @@ struct ssh2_userkey *openssh_pem_read(const Filename *filename,
 
     } else {
         assert(0 && "Bad key type from load_openssh_pem_key");
+       errmsg = "Bad key type from load_openssh_pem_key";
+       goto error;
     }
 
     /*
@@ -1533,18 +1543,14 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
                                       const char **errmsg_p)
 {
     struct openssh_new_key *key = load_openssh_new_key(filename, errmsg_p);
-    struct ssh2_userkey *retkey;
+    struct ssh2_userkey *retkey = NULL;
     int i;
     struct ssh2_userkey *retval = NULL;
     const char *errmsg;
-    unsigned char *blob;
-    int blobsize = 0;
     unsigned checkint0, checkint1;
     const void *priv, *string;
     int privlen, stringlen, key_index;
-    const struct ssh_signkey *alg;
-
-    blob = NULL;
+    const struct ssh_signkey *alg = NULL;
 
     if (!key)
        return NULL;
@@ -1668,10 +1674,10 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
                            (const unsigned char *)thiskey);
         if (key_index == key->key_wanted) {
             retkey = snew(struct ssh2_userkey);
+            retkey->comment = NULL;
             retkey->alg = alg;
             retkey->data = alg->openssh_createkey(alg, &thiskey, &thiskeylen);
             if (!retkey->data) {
-                sfree(retkey);
                 errmsg = "unable to create key data structure";
                 goto error;
             }
@@ -1708,11 +1714,16 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
 
     errmsg = NULL;                     /* no error */
     retval = retkey;
+    retkey = NULL;                     /* prevent the free */
 
     error:
-    if (blob) {
-        smemclr(blob, blobsize);
-        sfree(blob);
+    if (retkey) {
+        sfree(retkey->comment);
+        if (retkey->data) {
+            assert(alg);
+            alg->freekey(retkey->data);
+        }
+        sfree(retkey);
     }
     smemclr(key->keyblob, key->keyblob_size);
     sfree(key->keyblob);