Author: bh
Date: 2007-10-26 21:13:55 +0200 (Fri, 26 Oct 2007)
New Revision: 463

Modified:
   trunk/openvas-libnasl/ChangeLog
   trunk/openvas-libnasl/nasl/nasl_crypto2.c
   trunk/openvas-libnasl/test/test_rsa.nasl
Log:
* nasl/nasl_crypto2.c (nasl_rsa_public_decrypt): Pass the
signature as MPI to libgcrypt to avoid problems with numbers whose
most significant bit is set.  Also strip pkcs#1 padding from the
decrypted string if present.  The original openssl based
implementation also stripped the padding and the code in
ssh_func.inc expects that behavior.
(strip_pkcs1_padding): New internal function to strip pkcs#1
padding.

* test/test_rsa.nasl (signature2, plain_text2): New
plaintext/signature combination where the signature has the most
significant bit set.
(test_rsa_public_decrypt): New parameter variant so that multiple
calls can be distinguished in the output.  The function is called
twice now with different signatures.  Also, omit the padding from
the expected result because it's automatically stripped now.


Modified: trunk/openvas-libnasl/ChangeLog
===================================================================
--- trunk/openvas-libnasl/ChangeLog     2007-10-26 08:42:44 UTC (rev 462)
+++ trunk/openvas-libnasl/ChangeLog     2007-10-26 19:13:55 UTC (rev 463)
@@ -1,3 +1,22 @@
+2007-10-26  Bernhard Herzog  <[EMAIL PROTECTED]>
+
+       * nasl/nasl_crypto2.c (nasl_rsa_public_decrypt): Pass the
+       signature as MPI to libgcrypt to avoid problems with numbers whose
+       most significant bit is set.  Also strip pkcs#1 padding from the
+       decrypted string if present.  The original openssl based
+       implementation also stripped the padding and the code in
+       ssh_func.inc expects that behavior.
+       (strip_pkcs1_padding): New internal function to strip pkcs#1
+       padding.
+
+       * test/test_rsa.nasl (signature2, plain_text2): New
+       plaintext/signature combination where the signature has the most
+       significant bit set.
+       (test_rsa_public_decrypt): New parameter variant so that multiple
+       calls can be distinguished in the output.  The function is called
+       twice now with different signatures.  Also, omit the padding from
+       the expected result because it's automatically stripped now.
+
 2007-10-17  Jan-Oliver Wagner <[EMAIL PROTECTED]>
 
        * nasl/Makefile: Don't remove strutils.h anymore, it is now

Modified: trunk/openvas-libnasl/nasl/nasl_crypto2.c
===================================================================
--- trunk/openvas-libnasl/nasl/nasl_crypto2.c   2007-10-26 08:42:44 UTC (rev 
462)
+++ trunk/openvas-libnasl/nasl/nasl_crypto2.c   2007-10-26 19:13:55 UTC (rev 
463)
@@ -575,7 +575,8 @@
 /*
  * Sets the return value in retc from an sexpression.  The function uses
  * extract_mpi_from_sexp to extract an MPI from the sexpression sexp and
- * the subexpression given by token.  The function return 1 on success
+ * the subexpression given by token.
+ * The function return 1 on success
  * and 0 on failure.
  */
 static int
@@ -593,6 +594,51 @@
   return ret;
 }
 
+/*
+ * Strips PKCS#1 padding from the string in retc.
+ */
+static int
+strip_pkcs1_padding(tree_cell *retc)
+{
+  char *p;
+
+  if (retc->x.str_val== NULL || retc->size < 1)
+    return -1;
+
+  /* Find type of padding. PKCS#1 padding normally starts with a 0 byte.
+   * However, due to the way the value in retc has been created, any
+   * leading zeros have already been stripped.  So the byte that
+   * describes the type of padding is the first byte in str_val.  Also,
+   * the only padding types we can actually find are 1 and 2.  padding
+   * type 0 means that the padding is done with zeros and those will
+   * have been already stripped too. */
+  p = retc->x.str_val;
+  if (p[0] == 1 || p[0] == 2)
+    {
+      /* for padding type 1 and 2 we simply have to strip all non-zero
+       * bytes at the beginning of the value */
+      int i = 0;
+      char * temp;
+      while (i < retc->size && p[i])
+       i++;
+      /* skipt the zero byte */
+      i++;
+      if (i <= retc->size)
+       {
+         int rest = retc->size - i;
+         temp = emalloc(rest);
+         memcpy(temp, p + i, rest);
+         efree(&(retc->x.str_val));
+         retc->x.str_val = temp;
+         retc->size = rest;
+       }
+      else
+       return -1;
+    }
+
+  return 0;
+}
+
 /* nasl function
  *
  *   rsa_public_decrypt(sig:signature, e:mpi_e, n:mpi_n)
@@ -604,20 +650,16 @@
 tree_cell *
 nasl_rsa_public_decrypt(lex_ctxt* lexic)
 {
-  char *s1 = NULL;
   tree_cell *retc = NULL;
-  long sz1;
-  gcry_mpi_t e = NULL, n = NULL;
+  gcry_mpi_t e = NULL, n = NULL, s = NULL;
   gcry_sexp_t key = NULL, sig = NULL, decrypted = NULL;
   gcry_error_t err;
 
   retc = alloc_tree_cell(0, NULL);
   retc->type = CONST_DATA;
 
-  /* encrypted data */
-  s1 = get_str_local_var_by_name(lexic, "sig");
-  sz1 = get_var_size_by_name(lexic, "sig");
-
+  if (mpi_from_named_parameter(lexic, &s, "sig", "nasl_rsa_public_decrypt") < 
0)
+    goto fail;
   if (mpi_from_named_parameter(lexic, &e, "e", "nasl_rsa_public_decrypt") < 0)
     goto fail;
   if (mpi_from_named_parameter(lexic, &n, "n", "nasl_rsa_public_decrypt") < 0)
@@ -629,7 +671,7 @@
       print_gcrypt_error(lexic, "gcry_sexp_build pubkey", err);
       goto fail;
     }
-  err = gcry_sexp_build(&sig, NULL, "(data (value %b))", sz1, s1);
+  err = gcry_sexp_build(&sig, NULL, "(data (flags raw) (value %m))", s);
   if (err)
     {
       print_gcrypt_error(lexic, "gcry_sexp_build sig", err);
@@ -645,7 +687,8 @@
       goto fail;
     }
 
-  if (set_retc_from_sexp(retc, decrypted, "a") >= 0)
+  if (set_retc_from_sexp(retc, decrypted, "a") >= 0
+      && strip_pkcs1_padding(retc) >= 0)
     goto ret;
 
 fail:
@@ -655,6 +698,7 @@
   gcry_sexp_release(decrypted);
   gcry_sexp_release(key);
   gcry_sexp_release(sig);
+  gcry_mpi_release(s);
   gcry_mpi_release(e);
   gcry_mpi_release(n);
   return retc;

Modified: trunk/openvas-libnasl/test/test_rsa.nasl
===================================================================
--- trunk/openvas-libnasl/test/test_rsa.nasl    2007-10-26 08:42:44 UTC (rev 
462)
+++ trunk/openvas-libnasl/test/test_rsa.nasl    2007-10-26 19:13:55 UTC (rev 
463)
@@ -54,6 +54,25 @@
                       0x6d, 0x75, 0x31, 0x60, 0xcb, 0x03, 0xe2, 0x4d,
                       0x67, 0x5e, 0xd7, 0xf9, 0x40, 0xaa, 0xe0, 0xd9);
 
+# another signature where the signature value has the most significant
+# bit set.
+plain_text2 = "XXXXXX";
+signature2 = raw_string(0x91, 0x3c, 0x12, 0x5d, 0x76, 0x6c, 0x29, 0x43,
+                       0x32, 0x95, 0x04, 0xdb, 0xe3, 0x20, 0xd2, 0x98,
+                       0xf3, 0xe6, 0xd2, 0x0f, 0x08, 0x53, 0xbb, 0xc7,
+                       0xde, 0x5f, 0xf3, 0x55, 0xb5, 0x0b, 0x15, 0x84,
+                       0xf9, 0x28, 0xe9, 0x3e, 0x36, 0x1b, 0xfd, 0x17,
+                       0x96, 0x5b, 0x30, 0xdb, 0x39, 0x36, 0x2c, 0xe8,
+                       0xb3, 0xb6, 0xdb, 0x61, 0x96, 0x14, 0x98, 0xd1,
+                       0xa9, 0x58, 0x99, 0x07, 0x4f, 0x05, 0x5f, 0x7d,
+                       0x24, 0xe4, 0xac, 0xf2, 0x12, 0xb5, 0x50, 0x3f,
+                       0x91, 0x87, 0xc8, 0x81, 0x96, 0x47, 0x1d, 0x48,
+                       0x7a, 0x3b, 0x20, 0xc6, 0x3c, 0x30, 0x12, 0x36,
+                       0x68, 0xbd, 0x35, 0x03, 0x95, 0x7a, 0x83, 0xb0,
+                       0xc2, 0x3d, 0x85, 0x24, 0xfe, 0x45, 0xe2, 0x24,
+                       0x63, 0x89, 0xa2, 0x99, 0x1c, 0x82, 0x9a, 0x54,
+                       0xfc, 0xf9, 0x62, 0x18, 0x7d, 0x95, 0x8c, 0xa6,
+                       0x1b, 0x7b, 0xf5, 0x1f, 0xd8, 0x28, 0x31, 0x3b);
 
 function test_rsa_sign(priv, e, n, hash, expected)
 {
@@ -74,22 +93,16 @@
     }
 }
 
-function test_rsa_public_decrypt(e, n, sig, plaintext)
+function test_rsa_public_decrypt(e, n, sig, plaintext, variant)
 {
   local_var decrypted, prefix, expected;
 
-  testcase_start("test_rsa_public_decrypt");
+  testcase_start("test_rsa_public_decrypt " + variant);
 
   decrypted = rsa_public_decrypt(sig:sig, e:e, n:n);
 
-  # prefix is pkcs1 block type 1 + padding and SHA oid.
-  prefix=string("01ffffffffffffffffffffffffffffff",
-               "ffffffffffffffffffffffffffffffff",
-               "ffffffffffffffffffffffffffffffff",
-               "ffffffffffffffffffffffffffffffff",
-               "ffffffffffffffffffffffffffffffff",
-               "ffffffffffffffffffffff00",
-               "3021300906052b0e03021a05000414");
+  # prefix is the SHA oid.
+  prefix="3021300906052b0e03021a05000414";
   expected = strcat(prefix, hexstr(SHA1(plaintext)));
   if (hexstr(decrypted) == expected)
     testcase_ok();
@@ -104,4 +117,7 @@
 
 test_rsa_sign(priv:rsa_key_plain, e:e, n:n, hash:SHA1(plain_text),
              expected=signature);
-test_rsa_public_decrypt(e:e, n:n, sig:signature, plaintext:plain_text);
+test_rsa_public_decrypt(e:e, n:n, sig:signature, plaintext:plain_text,
+                       variant:"(msb not set)");
+test_rsa_public_decrypt(e:e, n:n, sig:signature2, plaintext:plain_text2,
+                       variant:"(msb set)");

_______________________________________________
Openvas-commits mailing list
[email protected]
http://lists.wald.intevation.org/mailman/listinfo/openvas-commits

Reply via email to