Fix double-free when un-padding invalid data.
authorDaiki Ueno <ueno@unixuser.org>
Fri, 27 May 2011 01:18:39 +0000 (10:18 +0900)
committerDaiki Ueno <ueno@unixuser.org>
Fri, 27 May 2011 01:18:39 +0000 (10:18 +0900)
Also add invalid padding cases to the basic test.

cipher/ChangeLog
cipher/pubkey.c
tests/ChangeLog
tests/basic.c

index c547758..18e895e 100644 (file)
@@ -1,3 +1,8 @@
+2011-05-27  Daiki Ueno  <ueno@unixuser.org>
+
+       * pubkey.c (gcry_pk_decrypt): Fix double-free when un-padding
+       invalid data.  Thanks to Tom Ritter.
+
 2011-05-23  Daiki Ueno  <ueno@unixuser.org>
 
        * pubkey.c (pkcs1_decode_for_encryption, oaep_decode): Fix memleak
index ba888f3..9d257ab 100644 (file)
@@ -2257,17 +2257,17 @@ gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
     case PUBKEY_ENC_PKCS1:
       rc = pkcs1_decode_for_encryption (&unpad, gcry_pk_get_nbits (s_skey),
                                        plain);
-      mpi_free (plain);
       if (rc)
        goto leave;
+      mpi_free (plain);
       plain = unpad;
       break;
     case PUBKEY_ENC_OAEP:
       rc = oaep_decode (&unpad, gcry_pk_get_nbits (s_skey), ctx.hash_algo,
                        plain, ctx.label, ctx.labellen);
-      mpi_free (plain);
       if (rc)
        goto leave;
+      mpi_free (plain);
       plain = unpad;
       break;
     default:
index c12892d..3b2fb09 100644 (file)
@@ -1,3 +1,7 @@
+2011-05-27  Daiki Ueno  <ueno@unixuser.org>
+
+       * basic.c (check_pubkey_crypt): Add test data with invalid padding.
+
 2011-05-18  Daiki Ueno  <ueno@unixuser.org>
 
        * basic.c (check_pubkey_crypt): Remove unused "unpad" flag.
index 8bfe5c4..5f56c1d 100644 (file)
@@ -2368,56 +2368,79 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey)
     const char *data;
     const char *hint;
     int unpadded;
-    int expected_rc;
+    int encrypt_expected_rc;
+    int decrypt_expected_rc;
   } datas[] =
     {
       {        "(data\n (flags pkcs1)\n"
        " (value #11223344556677889900AA#))\n",
        NULL,
        0,
+       0,
        0 },
       {        "(data\n (flags pkcs1)\n"
        " (value #11223344556677889900AA#))\n",
        "(flags pkcs1)",
        1,
+       0,
        0 },
       { "(data\n (flags oaep)\n"
        " (value #11223344556677889900AA#))\n",
        "(flags oaep)",
        1,
+       0,
        0 },
       { "(data\n (flags oaep)\n (hash-algo sha1)\n"
        " (value #11223344556677889900AA#))\n",
        "(flags oaep)(hash-algo sha1)",
        1,
+       0,
        0 },
       { "(data\n (flags oaep)\n (hash-algo sha1)\n (label \"test\")\n"
        " (value #11223344556677889900AA#))\n",
        "(flags oaep)(hash-algo sha1)(label \"test\")",
        1,
+       0,
        0 },
       {        "(data\n (flags )\n" " (value #11223344556677889900AA#))\n",
        NULL,
        1,
+       0,
        0 },
       {        "(data\n (flags )\n" " (value #0090223344556677889900AA#))\n",
        NULL,
        1,
+       0,
        0 },
       { "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n",
        NULL,
        1,
+       0,
        0 },
       { "(data\n (flags pkcs1)\n"
        " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
        NULL,
        0,
-       GPG_ERR_CONFLICT },
+       GPG_ERR_CONFLICT,
+       0},
       { "(data\n (flags raw foo)\n"
        " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
        NULL,
        0,
-       GPG_ERR_INV_FLAG },
+       GPG_ERR_INV_FLAG,
+       0},
+      { "(data\n (flags raw)\n"
+       " (value #11223344556677889900AA#))\n",
+       "(flags oaep)",
+       1,
+       0,
+       GPG_ERR_ENCODING_PROBLEM },
+      { "(data\n (flags oaep)\n"
+       " (value #11223344556677889900AA#))\n",
+       "(flags pkcs1)",
+       1,
+       0,
+       GPG_ERR_ENCODING_PROBLEM },
       { NULL }
     };
 
@@ -2434,7 +2457,7 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey)
        die ("converting data failed: %s\n", gpg_strerror (rc));
 
       rc = gcry_pk_encrypt (&ciph, data, pkey);
-      if (gcry_err_code (rc) != datas[dataidx].expected_rc)
+      if (gcry_err_code (rc) != datas[dataidx].encrypt_expected_rc)
        fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (rc));
 
       if (!rc)
@@ -2475,9 +2498,10 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey)
              ciph = list;
            }
          rc = gcry_pk_decrypt (&plain, ciph, skey);
-         if (rc)
+         if (gcry_err_code (rc) != datas[dataidx].decrypt_expected_rc)
            fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (rc));
-         else if (datas[dataidx].unpadded)
+
+         if (!rc && datas[dataidx].unpadded)
            {
              gcry_sexp_t p1, p2;