[svn] gcry - r1359 - in trunk: cipher doc src tests

svn author wk cvs at cvs.gnupg.org
Tue Nov 25 12:05:15 CET 2008


Author: wk
Date: 2008-11-25 12:05:14 +0100 (Tue, 25 Nov 2008)
New Revision: 1359

Modified:
   trunk/cipher/ChangeLog
   trunk/cipher/dsa.c
   trunk/cipher/ecc.c
   trunk/cipher/elgamal.c
   trunk/cipher/pubkey.c
   trunk/cipher/rsa.c
   trunk/doc/gcrypt.texi
   trunk/src/ChangeLog
   trunk/src/cipher-proto.h
   trunk/src/gcrypt.h.in
   trunk/src/sexp.c
   trunk/tests/ChangeLog
   trunk/tests/pubkey.c
   trunk/tests/tsexp.c
Log:
Finished RSA X9.31 key generation.


Modified: trunk/cipher/ChangeLog
===================================================================
--- trunk/cipher/ChangeLog	2008-11-24 16:37:50 UTC (rev 1358)
+++ trunk/cipher/ChangeLog	2008-11-25 11:05:14 UTC (rev 1359)
@@ -1,5 +1,15 @@
 2008-11-24  Werner Koch  <wk at g10code.com>
 
+	* pubkey.c (gcry_pk_genkey): Insert code to output extrainfo.
+	(pubkey_generate): Add arg R_EXTRAINFO and pass it to the extended
+	key generation function.
+	* rsa.c (gen_x931_parm_xp, gen_x931_parm_xi): New.
+	(generate_x931): Generate params if not given.
+	(rsa_generate_ext): Parse use-x931 flag.  Return p-q-swapped
+	indicator.
+	* dsa.c (dsa_generate_ext): Put RETFACTORS into R_EXTRAINFO if
+	possible.
+
 	* pubkey.c (gcry_pk_genkey): Remove parsing of almost all
 	parameters and pass the parameter S-expression to pubkey_generate.
 	(pubkey_generate): Simplify by requitring modules to parse the

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2008-11-24 16:37:50 UTC (rev 1358)
+++ trunk/src/ChangeLog	2008-11-25 11:05:14 UTC (rev 1359)
@@ -1,5 +1,10 @@
 2008-11-24  Werner Koch  <wk at g10code.com>
 
+	* sexp.c (get_internal_buffer): New.
+	(sexp_sscan): Add format character S.
+	* cipher-proto.h (pk_ext_generate_t): Add field EXTRAINFO  changed
+	all implementors.
+
 	* cipher-proto.h (pk_ext_generate_t): Simplify. 
 	(pk_get_param): New.
 	(pk_extra_spec_t): Add field GET_PARAM.

Modified: trunk/tests/ChangeLog
===================================================================
--- trunk/tests/ChangeLog	2008-11-24 16:37:50 UTC (rev 1358)
+++ trunk/tests/ChangeLog	2008-11-25 11:05:14 UTC (rev 1359)
@@ -1,6 +1,14 @@
+2008-11-25  Werner Koch  <wk at g10code.com>
+
+	* pubkey.c (get_dsa_key_new): New.
+
 2008-11-24  Werner Koch  <wk at g10code.com>
 
+	* tsexp.c (basic): Add test for format character S.
+
 	* pubkey.c (check_x931_derived_key): New.
+	(get_keys_x931_new): New.
+	(check_run): Check X9.31 generated RSA key.
 
 2008-11-07  Werner Koch  <wk at g10code.com>
 

Modified: trunk/cipher/dsa.c
===================================================================
--- trunk/cipher/dsa.c	2008-11-24 16:37:50 UTC (rev 1358)
+++ trunk/cipher/dsa.c	2008-11-25 11:05:14 UTC (rev 1359)
@@ -461,7 +461,8 @@
 static gcry_err_code_t
 dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
                   const gcry_sexp_t genparms,
-                  gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+                  gcry_sexp_t *r_extrainfo)
 {
   gpg_err_code_t ec;
   DSA_secret_key sk;
@@ -502,6 +503,77 @@
       skey[2] = sk.g;
       skey[3] = sk.y;
       skey[4] = sk.x;
+
+      if (!r_extrainfo)
+        {
+          /* Old style interface - return the factors - if any - at
+             retfactors.  */
+        }
+      else if (r_extrainfo && !*retfactors)
+        {
+          /* No factors, thus there is nothing to return.  */
+          *r_extrainfo = NULL;
+        }
+      else
+        {
+          /* Put the factors into extrainfo and set retfactors to NULL
+             to make use of the new interface.  Note that the factors
+             are not confidential thus we can store them in standard
+             memory.  */
+          int nfactors, i;
+          char *p;
+          char *format = NULL;
+          void **arg_list = NULL;
+
+          for (nfactors=0; (*retfactors)[nfactors]; nfactors++)
+            ;
+          /* Allocate space for the format string:
+               "(misc-key-info(pm1-factors%m))"
+             with one "%m" for each factor and build the string  */
+          format = gcry_malloc (40 + 2*nfactors);
+          if (!format)
+            ec = gpg_err_code_from_syserror ();
+          else
+            {
+              p = stpcpy (format, "(misc-key-info(pm1-factors");
+              for (i=0; i < nfactors; i++)
+                p = stpcpy (p, "%m");
+              p = stpcpy (p, "))");
+              
+              /* Allocate space for the argument list plus an extra
+                 NULL entry for safety and fill it with the
+                 factors.  */
+              arg_list = gcry_calloc (nfactors+1, sizeof *arg_list);
+              if (!arg_list)
+                ec = gpg_err_code_from_syserror ();
+              else
+                {
+                  for (i=0; i < nfactors; i++)
+                    arg_list[i] = (*retfactors) + i;
+                  arg_list[i] = NULL;
+                  
+                  ec = gpg_err_code (gcry_sexp_build_array 
+                                     (r_extrainfo, NULL, format, arg_list));
+                }
+            }
+
+          gcry_free (arg_list);
+          gcry_free (format);
+          for (i=0; i < nfactors; i++)
+            {
+              gcry_mpi_release ((*retfactors)[i]);
+              (*retfactors)[i] = NULL;
+            }
+          *retfactors = NULL;
+          if (ec)
+            {
+              for (i=0; i < 5; i++)
+                {
+                  gcry_mpi_release (skey[i]);
+                  skey[i] = NULL;
+                }
+            }
+        }
     }
 
   return ec;
@@ -513,7 +585,7 @@
               gcry_mpi_t *skey, gcry_mpi_t **retfactors)
 {
   (void)evalue;
-  return dsa_generate_ext (algo, nbits, 0, NULL, skey, retfactors);
+  return dsa_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
 }
 
 

Modified: trunk/cipher/ecc.c
===================================================================
--- trunk/cipher/ecc.c	2008-11-24 16:37:50 UTC (rev 1358)
+++ trunk/cipher/ecc.c	2008-11-25 11:05:14 UTC (rev 1359)
@@ -954,7 +954,8 @@
 static gcry_err_code_t
 ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
                   const gcry_sexp_t genparms,
-                  gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+                  gcry_sexp_t *r_extrainfo)
 {
   gpg_err_code_t ec;
   ECC_secret_key sk;
@@ -964,6 +965,7 @@
 
   (void)algo;
   (void)evalue;
+  (void)r_extrainfo;
 
   if (genparms)
     {
@@ -1018,7 +1020,7 @@
               gcry_mpi_t *skey, gcry_mpi_t **retfactors)
 {
   (void)evalue;
-  return ecc_generate_ext (algo, nbits, 0, NULL, skey, retfactors);
+  return ecc_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
 }
 
 

Modified: trunk/cipher/elgamal.c
===================================================================
--- trunk/cipher/elgamal.c	2008-11-24 16:37:50 UTC (rev 1358)
+++ trunk/cipher/elgamal.c	2008-11-25 11:05:14 UTC (rev 1359)
@@ -615,7 +615,8 @@
 static gpg_err_code_t
 elg_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
                   const gcry_sexp_t genparms,
-                  gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+                  gcry_sexp_t *r_extrainfo)
 {
   gpg_err_code_t ec;
   ELG_secret_key sk;
@@ -624,6 +625,7 @@
 
   (void)algo;
   (void)evalue;
+  (void)r_extrainfo;
 
   if (genparms)
     {

Modified: trunk/cipher/pubkey.c
===================================================================
--- trunk/cipher/pubkey.c	2008-11-24 16:37:50 UTC (rev 1358)
+++ trunk/cipher/pubkey.c	2008-11-25 11:05:14 UTC (rev 1359)
@@ -542,7 +542,8 @@
                  unsigned int nbits,
                  unsigned long use_e,
                  gcry_sexp_t genparms,
-                 gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+                 gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+                 gcry_sexp_t *r_extrainfo)
 {
   gcry_err_code_t ec = GPG_ERR_PUBKEY_ALGO;
   gcry_module_t pubkey;
@@ -559,7 +560,7 @@
         {
           /* Use the extended generate function.  */
           ec = extraspec->ext_generate 
-            (algorithm, nbits, use_e, genparms, skey, retfactors);
+            (algorithm, nbits, use_e, genparms, skey, retfactors, r_extrainfo);
         }
       else
         {
@@ -2076,7 +2077,9 @@
   const char *algo_name = NULL;
   int algo;
   const char *sec_elems = NULL, *pub_elems = NULL;
-  gcry_mpi_t skey[12], *factors = NULL;
+  gcry_mpi_t skey[12];
+  gcry_mpi_t *factors = NULL;
+  gcry_sexp_t extrainfo = NULL;
   unsigned int nbits = 0;
   unsigned long use_e = 0;
 
@@ -2132,7 +2135,7 @@
 
   /* Handle the optional rsa-use-e element.  Actually this belong into
      the algorithm module but we have this parameter in the public
-     moudle API, so we need to parse it right here.  */
+     module API, so we need to parse it right here.  */
   l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
   if (l2)
     {
@@ -2177,7 +2180,8 @@
     nbits = 0;
 
   /* Pass control to the algorithm module. */
-  rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey, &factors);
+  rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey, 
+                        &factors, &extrainfo);
   gcry_sexp_release (list); list = NULL;
   if (rc)
     goto leave;
@@ -2188,13 +2192,18 @@
     size_t nelem=0, nelem_cp = 0, needed=0;
     gcry_mpi_t mpis[30];
     
+    /* Estimate size of format string.  */
     nelem = strlen (pub_elems) + strlen (sec_elems);
-    for (i = 0; factors[i]; i++)
-      nelem++;
+    if (factors)
+      {
+        for (i = 0; factors[i]; i++)
+          nelem++;
+      }
     nelem_cp = nelem;
 
     needed += nelem * 10;
-    needed += 2 * strlen (algo_name) + 300;
+    /* (+5 is for EXTRAINFO ("%S")).  */
+    needed += 2 * strlen (algo_name) + 300 + 5;
     if (nelem > DIM (mpis))
       BUG ();
 
@@ -2231,8 +2240,13 @@
     /* Hack to make release_mpi_array() work.  */
     skey[i] = NULL;
 
-    if (factors[0])
+    if (extrainfo)
       {
+        /* If we have extrainfo we should not have any factors.  */
+        p = stpcpy (p, "%S");
+      }
+    else if (factors && factors[0])
+      {
         p = stpcpy (p, "(misc-key-info(pm1-factors");
         for(i = 0; factors[i]; i++)
           {
@@ -2251,7 +2265,8 @@
       int elem_n = strlen (pub_elems) + strlen (sec_elems);
       void **arg_list;
 
-      arg_list = malloc (nelem_cp * sizeof *arg_list);
+      /* Allocate one extra for EXTRAINFO ("%S").  */
+      arg_list = gcry_calloc (nelem_cp+1, sizeof *arg_list);
       if (!arg_list)
         {
           rc = gpg_err_code_from_errno (errno);
@@ -2259,11 +2274,16 @@
         }
       for (i = 0; i < elem_n; i++)
         arg_list[i] = mpis + i;
-      for (; i < nelem_cp; i++)
-        arg_list[i] = factors + i - elem_n;
+      if (extrainfo)
+        arg_list[i] = &extrainfo;
+      else if (factors && factors[0])
+        {
+          for (; i < nelem_cp; i++)
+            arg_list[i] = factors + i - elem_n;
+        }
       
       rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
-      free (arg_list);
+      gcry_free (arg_list);
       if (rc)
 	BUG ();
       gcry_assert (DIM (mpis) == 30); /* Reminder to make sure that
@@ -2275,6 +2295,7 @@
 
  leave:
   gcry_free (name);
+  gcry_sexp_release (extrainfo);
   release_mpi_array (skey);
   /* Don't free SKEY itself, it is an stack allocated array. */
 

Modified: trunk/cipher/rsa.c
===================================================================
--- trunk/cipher/rsa.c	2008-11-24 16:37:50 UTC (rev 1358)
+++ trunk/cipher/rsa.c	2008-11-25 11:05:14 UTC (rev 1359)
@@ -328,6 +328,46 @@
 }
 
 
+/* Helper for generate_x931.  */
+static gcry_mpi_t 
+gen_x931_parm_xp (unsigned int nbits)
+{
+  gcry_mpi_t xp;
+
+  xp = gcry_mpi_snew (nbits);
+  gcry_mpi_randomize (xp, nbits, GCRY_VERY_STRONG_RANDOM);
+      
+  /* The requirement for Xp is:
+
+       sqrt{2}*2^{nbits-1} <= xp <= 2^{nbits} - 1
+
+     We set the two high order bits to 1 to satisfy the lower bound.
+     By using mpi_set_highbit we make sure that the upper bound is
+     satisfied as well.  */
+  mpi_set_highbit (xp, nbits-1);
+  mpi_set_bit (xp, nbits-2);
+  gcry_assert ( mpi_get_nbits (xp) == nbits );
+  
+  return xp;
+}     
+
+
+/* Helper for generate_x931.  */
+static gcry_mpi_t 
+gen_x931_parm_xi (void)
+{
+  gcry_mpi_t xi;
+
+  xi = gcry_mpi_snew (101);
+  gcry_mpi_randomize (xi, 101, GCRY_VERY_STRONG_RANDOM);
+  mpi_set_highbit (xi, 100);
+  gcry_assert ( mpi_get_nbits (xi) == 101 );
+  
+  return xi;
+}     
+
+
+
 /* Variant of the standard key generation code using the algorithm
    from X9.31.  Using this algorithm has the advantage that the
    generation can be made deterministic which is required for CAVS
@@ -378,14 +418,32 @@
     gcry_mpi_t xq1 = NULL;
     gcry_mpi_t xq2 = NULL;
     gcry_mpi_t xq  = NULL;
+    gcry_mpi_t tmpval;
 
     if (!deriveparms)
       {
-        /* Fixme: Create them.  */
-        return GPG_ERR_INV_VALUE;
+        /* Not given: Generate them.  */
+        xp = gen_x931_parm_xp (nbits/2);
+        /* Make sure that |xp - xq| > 2^{nbits - 100} holds.  */
+        tmpval = gcry_mpi_snew (nbits/2);
+        do
+          {
+            gcry_mpi_release (xq);
+            xq = gen_x931_parm_xp (nbits/2);
+            mpi_sub (tmpval, xp, xq);
+          }
+        while (mpi_get_nbits (tmpval) <= (nbits/2 - 100));
+        gcry_mpi_release (tmpval);
+
+        xp1 = gen_x931_parm_xi ();
+        xp2 = gen_x931_parm_xi ();
+        xq1 = gen_x931_parm_xi ();
+        xq2 = gen_x931_parm_xi ();
+
       }
     else
       {
+        /* Parameters to derive the key are given.  */
         struct { const char *name; gcry_mpi_t *value; } tbl[] = {
           { "Xp1", &xp1 },
           { "Xp2", &xp2 },
@@ -478,7 +536,7 @@
 
   if( DBG_CIPHER )
     {
-      if (swapped)
+      if (*swapped)
         log_debug ("p and q are swapped\n");
       log_mpidump("  p", p );
       log_mpidump("  q", q );
@@ -717,25 +775,52 @@
 static gcry_err_code_t
 rsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
                   const gcry_sexp_t genparms,
-                  gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+                  gcry_sexp_t *r_extrainfo)
 {
   RSA_secret_key sk;
   gpg_err_code_t ec;
   gcry_sexp_t deriveparms;
   int transient_key = 0;
+  int use_x931 = 0;
   gcry_sexp_t l1;
-  int swapped;
-  int i;
 
   (void)algo;
+  
+  *retfactors = NULL; /* We don't return them.  */
 
   deriveparms = (genparms?
                  gcry_sexp_find_token (genparms, "derive-parms", 0) : NULL);
+  if (!deriveparms)
+    {
+      /* Parse the optional "rsa-use-x931" flag. */
+      l1 = gcry_sexp_find_token (genparms, "use-x931", 0);
+      if (l1)
+        {
+          use_x931 = 1;
+          gcry_sexp_release (l1);
+        }
+    }
 
-  if (deriveparms || fips_mode ())
+  if (deriveparms || use_x931 || fips_mode ())
     {
+      int swapped;
       ec = generate_x931 (&sk, nbits, evalue, deriveparms, &swapped);
       gcry_sexp_release (deriveparms);
+      if (!ec && r_extrainfo && swapped)
+        {
+          ec = gcry_sexp_new (r_extrainfo, 
+                              "(misc-key-info(p-q-swapped))", 0, 1);
+          if (ec)
+            {
+              gcry_mpi_release (sk.n); sk.n = NULL;
+              gcry_mpi_release (sk.e); sk.e = NULL;
+              gcry_mpi_release (sk.p); sk.p = NULL;
+              gcry_mpi_release (sk.q); sk.q = NULL;
+              gcry_mpi_release (sk.d); sk.d = NULL;
+              gcry_mpi_release (sk.u); sk.u = NULL;
+            }
+        }
     }
   else
     {
@@ -745,7 +830,6 @@
         {
           transient_key = 1;
           gcry_sexp_release (l1);
-          l1 = NULL;
         }
       /* Generate.  */
       ec = generate_std (&sk, nbits, evalue, transient_key);
@@ -759,20 +843,6 @@
       skey[3] = sk.p;
       skey[4] = sk.q;
       skey[5] = sk.u;
-  
-      /* Make an empty list of factors.  */
-      *retfactors = gcry_calloc ( 1, sizeof **retfactors );
-      if (!*retfactors)
-        {
-          ec = gpg_err_code_from_syserror ();
-          for (i=0; i <= 5; i++)
-            {
-              gcry_mpi_release (skey[i]);
-              skey[i] = NULL;
-            }
-        }
-      else
-        ec = 0;
     }
   
   return ec;
@@ -783,7 +853,7 @@
 rsa_generate (int algo, unsigned int nbits, unsigned long evalue,
               gcry_mpi_t *skey, gcry_mpi_t **retfactors)
 {
-  return rsa_generate_ext (algo, nbits, evalue, NULL, skey, retfactors);
+  return rsa_generate_ext (algo, nbits, evalue, NULL, skey, retfactors, NULL);
 }
 
 

Modified: trunk/doc/gcrypt.texi
===================================================================
--- trunk/doc/gcrypt.texi	2008-11-24 16:37:50 UTC (rev 1358)
+++ trunk/doc/gcrypt.texi	2008-11-25 11:05:14 UTC (rev 1359)
@@ -2752,6 +2752,13 @@
             321DE34A#))))
 @end example
 
+ at item use-x931
+Force the use of the ANSI X9.31 key generation algorithm instead of
+the default algorithm. This flag is only meaningful for RSA and
+usullat not required.  Note that this algorithm is implicitly used if
+either @code{derive-parms} are given or Libgcrypt is in FIPS mode.
+
+
 @end table
 @c end table of parameters
 

Modified: trunk/src/cipher-proto.h
===================================================================
--- trunk/src/cipher-proto.h	2008-11-24 16:37:50 UTC (rev 1358)
+++ trunk/src/cipher-proto.h	2008-11-25 11:05:14 UTC (rev 1359)
@@ -46,7 +46,8 @@
       unsigned long evalue,
       gcry_sexp_t genparms,
       gcry_mpi_t *skey,
-      gcry_mpi_t **retfactors);
+      gcry_mpi_t **retfactors,
+      gcry_sexp_t *extrainfo);
 
 /* The type used to compute the keygrip.  */
 typedef gpg_err_code_t (*pk_comp_keygrip_t)

Modified: trunk/src/gcrypt.h.in
===================================================================
--- trunk/src/gcrypt.h.in	2008-11-24 16:37:50 UTC (rev 1358)
+++ trunk/src/gcrypt.h.in	2008-11-25 11:05:14 UTC (rev 1359)
@@ -1654,8 +1654,8 @@
 
 
 /* Set the big integer W to a random value of NBITS using a random
-   generator with quality LEVEL.  Note that using a level of
-   GCRY_WEAK_RANDOM here, uses gcry_create_nonce internally. */
+   generator with quality LEVEL.  Note that by using a level of
+   GCRY_WEAK_RANDOM gcry_create_nonce is used internally. */
 void gcry_mpi_randomize (gcry_mpi_t w,
                          unsigned int nbits, enum gcry_random_level level);
 

Modified: trunk/src/sexp.c
===================================================================
--- trunk/src/sexp.c	2008-11-24 16:37:50 UTC (rev 1358)
+++ trunk/src/sexp.c	2008-11-25 11:05:14 UTC (rev 1359)
@@ -1,6 +1,6 @@
 /* sexp.c  -  S-Expression handling
  * Copyright (C) 1999, 2000, 2001, 2002, 2003,
- *               2004, 2006, 2007 Free Software Foundation, Inc.
+ *               2004, 2006, 2007, 2008  Free Software Foundation, Inc.
  *
  * This file is part of Libgcrypt.
  *
@@ -191,7 +191,7 @@
 }
 
 /* Create a new S-expression object by reading LENGTH bytes from
-   BUFFER, assuming it is canonilized encoded or autodetected encoding
+   BUFFER, assuming it is canonical encoded or autodetected encoding
    when AUTODETECT is set to 1.  With FREEFNC not NULL, ownership of
    the buffer is transferred to the newly created object.  FREEFNC
    should be the freefnc used to release BUFFER; there is no guarantee
@@ -492,7 +492,48 @@
 }
 
 
+/* Return the internal lengths offset of LIST.  That is the size of
+   the buffer from the first ST_OPEN, which is retruned at R_OFF, to
+   the corresponding ST_CLOSE inclusive.  */
+static size_t
+get_internal_buffer (const gcry_sexp_t list, size_t *r_off)
+{
+  const unsigned char *p;
+  DATALEN n;
+  int type;
+  int level = 0;
+  
+  *r_off = 0;
+  if (list)
+    {
+      p = list->d;
+      while ( (type=*p) != ST_STOP ) 
+        {
+          p++;
+          if (type == ST_DATA) 
+            {
+              memcpy (&n, p, sizeof n);
+              p += sizeof n + n;
+            }
+          else if (type == ST_OPEN)
+            {
+              if (!level)
+                *r_off = (p-1) - list->d;
+              level++;
+            }
+          else if ( type == ST_CLOSE )
+            {
+              level--;
+              if (!level)
+                return p - list->d;
+            }
+        }
+    }
+  return 0; /* Not a proper list.  */
+}
 
+
+
 /* Extract the CAR of the given list.  May return NULL for bad lists
    or memory failure.  */
 gcry_sexp_t
@@ -920,6 +961,9 @@
  *	%d - integer stored as string (no autoswitch to secure allocation)
  *      %b - memory buffer; this takes _two_ arguments: an integer with the 
  *           length of the buffer and a pointer to the buffer.
+ *      %S - Copy an gcry_sexp_t here.  The S-expression needs to be a
+ *           regular one, starting with a parenthesis. 
+ *           (no autoswitch to secure allocation)
  *  all other format elements are currently not defined and return an error.
  *  this includes the "%%" sequence becauce the percent sign is not an
  *  allowed character.
@@ -966,7 +1010,7 @@
 #define ARG_NEXT(storage, type)                          \
   do                                                     \
     {                                                    \
-      if (!arg_list)                                    \
+      if (!arg_list)                                     \
 	storage = va_arg (arg_ptr, type);                \
       else                                               \
 	storage = *((type *) (arg_list[arg_counter++])); \
@@ -1310,6 +1354,21 @@
 	      memcpy (c.pos, buf, alen);
 	      c.pos += alen;
 	    }
+	  else if (*p == 'S')
+	    {
+	      /* Insert a gcry_sexp_t.  */
+	      gcry_sexp_t asexp;
+	      size_t alen, aoff;
+
+	      ARG_NEXT (asexp, gcry_sexp_t);
+              alen = get_internal_buffer (asexp, &aoff);
+              if (alen)
+                {
+                  MAKE_SPACE (alen);
+                  memcpy (c.pos, asexp->d + aoff, alen);
+                  c.pos += alen;
+                }
+	    }
 	  else
 	    {
 	      *erroff = p - buffer;

Modified: trunk/tests/pubkey.c
===================================================================
--- trunk/tests/pubkey.c	2008-11-24 16:37:50 UTC (rev 1358)
+++ trunk/tests/pubkey.c	2008-11-25 11:05:14 UTC (rev 1359)
@@ -266,6 +266,9 @@
   if (rc)
     die ("error generating RSA key: %s\n", gcry_strerror (rc));
     
+  if (verbose > 1)
+    show_sexp ("generated RSA key:\n", key);
+
   pub_key = gcry_sexp_find_token (key, "public-key", 0);
   if (! pub_key)
     die ("public part missing in key\n");
@@ -281,6 +284,38 @@
 
 
 static void
+get_keys_x931_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+  gcry_sexp_t key_spec, key, pub_key, sec_key;
+  int rc;
+  
+  rc = gcry_sexp_new (&key_spec,
+		      "(genkey (rsa (nbits 4:1024)(use-x931)))", 0, 1);
+  if (rc)
+    die ("error creating S-expression: %s\n", gcry_strerror (rc));
+  rc = gcry_pk_genkey (&key, key_spec);
+  gcry_sexp_release (key_spec);
+  if (rc)
+    die ("error generating RSA key: %s\n", gcry_strerror (rc));
+    
+  if (verbose > 1)
+    show_sexp ("generated RSA (X9.31) key:\n", key);
+
+  pub_key = gcry_sexp_find_token (key, "public-key", 0);
+  if (!pub_key)
+    die ("public part missing in key\n");
+
+  sec_key = gcry_sexp_find_token (key, "private-key", 0);
+  if (!sec_key)
+    die ("private part missing in key\n");
+
+  gcry_sexp_release (key);
+  *pkey = pub_key;
+  *skey = sec_key;
+}
+
+
+static void
 get_elg_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int fixed_x)
 {
   gcry_sexp_t key_spec, key, pub_key, sec_key;
@@ -300,6 +335,9 @@
   if (rc)
     die ("error generating Elgamal key: %s\n", gcry_strerror (rc));
     
+  if (verbose > 1)
+    show_sexp ("generated ELG key:\n", key);
+
   pub_key = gcry_sexp_find_token (key, "public-key", 0);
   if (!pub_key)
     die ("public part missing in key\n");
@@ -313,7 +351,38 @@
   *skey = sec_key;
 }
 
+static void
+get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+  gcry_sexp_t key_spec, key, pub_key, sec_key;
+  int rc;
 
+  rc = gcry_sexp_new 
+    (&key_spec, "(genkey (dsa (nbits 4:1024)))",  0, 1);
+  if (rc)
+    die ("error creating S-expression: %s\n", gcry_strerror (rc));
+  rc = gcry_pk_genkey (&key, key_spec);
+  gcry_sexp_release (key_spec);
+  if (rc)
+    die ("error generating Elgamal key: %s\n", gcry_strerror (rc));
+    
+  if (verbose > 1)
+    show_sexp ("generated DSA key:\n", key);
+
+  pub_key = gcry_sexp_find_token (key, "public-key", 0);
+  if (!pub_key)
+    die ("public part missing in key\n");
+
+  sec_key = gcry_sexp_find_token (key, "private-key", 0);
+  if (!sec_key)
+    die ("private part missing in key\n");
+
+  gcry_sexp_release (key);
+  *pkey = pub_key;
+  *skey = sec_key;
+}
+
+
 static void
 check_run (void)
 {
@@ -345,6 +414,13 @@
   gcry_sexp_release (skey);
 
   if (verbose)
+    fprintf (stderr, "Checking generated RSA key (X9.31).\n");
+  get_keys_x931_new (&pkey, &skey);
+  check_keys (pkey, skey, 800, 0);
+  gcry_sexp_release (pkey);
+  gcry_sexp_release (skey);
+
+  if (verbose)
     fprintf (stderr, "Checking generated Elgamal key.\n");
   get_elg_key_new (&pkey, &skey, 0);
   check_keys (pkey, skey, 400, 0);
@@ -357,6 +433,13 @@
   check_keys (pkey, skey, 800, 0);
   gcry_sexp_release (pkey);
   gcry_sexp_release (skey);
+
+  if (verbose)
+    fprintf (stderr, "Generating DSA key.\n");
+  get_dsa_key_new (&pkey, &skey);
+  /* Fixme:  Add a check function for DSA keys.  */
+  gcry_sexp_release (pkey);
+  gcry_sexp_release (skey);
 }
 
 
@@ -377,6 +460,7 @@
       gcry_sexp_release (l1);
       return NULL;
     }
+
   result = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
   gcry_sexp_release (l2);
   gcry_sexp_release (l1);
@@ -552,8 +636,9 @@
   if (err)
     die ("error converting string [%d]\n", what);
 
-  if (verbose)
-    show_sexp ("generated private key:\n", sec_key);
+  if (verbose > 1)
+    show_sexp ("generated key:\n", key);
+
   d_have = key_param_from_sexp (sec_key, "rsa", "d");
   if (!d_have)
     die ("parameter d not found in RSA secret key [%d]\n", what);
@@ -582,7 +667,10 @@
   if (argc > 1 && !strcmp (argv[1], "--verbose"))
     verbose = 1;
   else if (argc > 1 && !strcmp (argv[1], "--debug"))
-    verbose = debug = 1;
+    {
+      verbose = 2;
+      debug = 1;
+    }
 
   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
   if (!gcry_check_version (GCRYPT_VERSION))

Modified: trunk/tests/tsexp.c
===================================================================
--- trunk/tests/tsexp.c	2008-11-24 16:37:50 UTC (rev 1358)
+++ trunk/tests/tsexp.c	2008-11-25 11:05:14 UTC (rev 1359)
@@ -130,7 +130,32 @@
           if (!gcry_is_secure (sexp))
             fail ("gcry_sexp_build did not switch to secure memory\n");
           break;
+
+        case 3:
+          {
+            gcry_sexp_t help_sexp;
+
+            if (gcry_sexp_new (&help_sexp,
+                               "(foobar-parms (xp #1234#)(xq #03#))", 0, 1))
+              {
+                fail (" scanning fixed string failed\n");
+                return;
+              }
+
+            string = ("(public-key (dsa (p #41424344#) (parm %S) "
+                      "(y dummy)(q %b) (g %m)))");
+            if ( gcry_sexp_build (&sexp, NULL, string, help_sexp,
+                                  secure_buffer_len, secure_buffer,
+                                  gcry_mpi_set_ui (NULL, 17)) )
+              {
+                fail (" scanning `%s' failed\n", string);
+                return;
+              }
+            gcry_sexp_release (help_sexp);
+          }
+          break;
           
+          
         default:
           return; /* Ready. */
         }
@@ -416,7 +441,7 @@
 int
 main (int argc, char **argv)
 {
-  if (argc > 1 && !strcmp (argv[1], "-v"))
+  if (argc > 1 && !strcmp (argv[1], "--verbose"))
     verbose = 1;
 
   gcry_control (GCRYCTL_DISABLE_SECMEM_WARN);




More information about the Gnupg-commits mailing list