* gpgsm.c (main): Disable core dumps.
authorWerner Koch <wk@gnupg.org>
Fri, 25 Jan 2002 16:41:13 +0000 (16:41 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 25 Jan 2002 16:41:13 +0000 (16:41 +0000)
* sign.c (add_certificate_list): New.
(gpgsm_sign): Add the certificates to the CMS object.
* certpath.c (gpgsm_walk_cert_chain): New.
* gpgsm.h (server_control_s): Add included_certs.
* gpgsm.c: Add option --include-certs.
(gpgsm_init_default_ctrl): New.
(main): Call it.
* server.c (gpgsm_server): Ditto.
(option_handler): Support --include-certs.

sm/ChangeLog
sm/certchain.c
sm/certpath.c
sm/gpgsm.c
sm/gpgsm.h
sm/server.c
sm/sign.c

index a893fdf..561e3a5 100644 (file)
@@ -1,3 +1,17 @@
+2002-01-25  Werner Koch  <wk@gnupg.org>
+
+       * gpgsm.c (main): Disable core dumps.
+
+       * sign.c (add_certificate_list): New.
+       (gpgsm_sign): Add the certificates to the CMS object.
+       * certpath.c (gpgsm_walk_cert_chain): New.
+       * gpgsm.h (server_control_s): Add included_certs.
+       * gpgsm.c: Add option --include-certs.
+       (gpgsm_init_default_ctrl): New.
+       (main): Call it.
+       * server.c (gpgsm_server): Ditto.
+       (option_handler): Support --include-certs.
+
 2002-01-23  Werner Koch  <wk@gnupg.org>
 
        * certpath.c (gpgsm_validate_path): Print the DN of a missing issuer.
index 9ef8626..842481b 100644 (file)
@@ -84,7 +84,68 @@ allowed_ca (KsbaCert cert, int *pathlen)
   return 0;
 }
 
+/* Return the next certificate up in the chain starting at START.
+   Returns -1 when there are no more certificates. */
+int
+gpgsm_walk_cert_chain (KsbaCert start, KsbaCert *r_next)
+{
+  int rc = 0; 
+  char *issuer = NULL;
+  char *subject = NULL;
+  KEYDB_HANDLE kh = keydb_new (0);
+
+  *r_next = NULL;
+  if (!kh)
+    {
+      log_error (_("failed to allocated keyDB handle\n"));
+      rc = GNUPG_General_Error;
+      goto leave;
+    }
+
+  issuer = ksba_cert_get_issuer (start, 0);
+  subject = ksba_cert_get_subject (start, 0);
+  if (!issuer)
+    {
+      log_error ("no issuer found in certificate\n");
+      rc = GNUPG_Bad_Certificate;
+      goto leave;
+    }
+  if (!subject)
+    {
+      log_error ("no subject found in certificate\n");
+      rc = GNUPG_Bad_Certificate;
+      goto leave;
+    }
+
+  if (!strcmp (issuer, subject))
+    {
+      rc = -1; /* we are at the root */
+      goto leave; 
+    }
+  rc = keydb_search_subject (kh, issuer);
+  if (rc)
+    {
+      log_error ("failed to find issuer's certificate: rc=%d\n", rc);
+      rc = GNUPG_Missing_Certificate;
+      goto leave;
+    }
+
+  rc = keydb_get_cert (kh, r_next);
+  if (rc)
+    {
+      log_error ("failed to get cert: rc=%d\n", rc);
+      rc = GNUPG_General_Error;
+    }
+
+ leave:
+  xfree (issuer);
+  xfree (subject);
+  keydb_release (kh); 
+  return rc;
+}
 
+\f
 int
 gpgsm_validate_path (KsbaCert cert)
 {
index 9ef8626..842481b 100644 (file)
@@ -84,7 +84,68 @@ allowed_ca (KsbaCert cert, int *pathlen)
   return 0;
 }
 
+/* Return the next certificate up in the chain starting at START.
+   Returns -1 when there are no more certificates. */
+int
+gpgsm_walk_cert_chain (KsbaCert start, KsbaCert *r_next)
+{
+  int rc = 0; 
+  char *issuer = NULL;
+  char *subject = NULL;
+  KEYDB_HANDLE kh = keydb_new (0);
+
+  *r_next = NULL;
+  if (!kh)
+    {
+      log_error (_("failed to allocated keyDB handle\n"));
+      rc = GNUPG_General_Error;
+      goto leave;
+    }
+
+  issuer = ksba_cert_get_issuer (start, 0);
+  subject = ksba_cert_get_subject (start, 0);
+  if (!issuer)
+    {
+      log_error ("no issuer found in certificate\n");
+      rc = GNUPG_Bad_Certificate;
+      goto leave;
+    }
+  if (!subject)
+    {
+      log_error ("no subject found in certificate\n");
+      rc = GNUPG_Bad_Certificate;
+      goto leave;
+    }
+
+  if (!strcmp (issuer, subject))
+    {
+      rc = -1; /* we are at the root */
+      goto leave; 
+    }
+  rc = keydb_search_subject (kh, issuer);
+  if (rc)
+    {
+      log_error ("failed to find issuer's certificate: rc=%d\n", rc);
+      rc = GNUPG_Missing_Certificate;
+      goto leave;
+    }
+
+  rc = keydb_get_cert (kh, r_next);
+  if (rc)
+    {
+      log_error ("failed to get cert: rc=%d\n", rc);
+      rc = GNUPG_General_Error;
+    }
+
+ leave:
+  xfree (issuer);
+  xfree (subject);
+  keydb_release (kh); 
+  return rc;
+}
 
+\f
 int
 gpgsm_validate_path (KsbaCert cert)
 {
index d9b9e27..0203c5a 100644 (file)
@@ -33,6 +33,7 @@
 #include "../kbx/keybox.h" /* malloc hooks */
 #include "i18n.h"
 #include "keydb.h"
+#include "sysutils.h"
 
 enum cmd_and_opt_values {
   aNull = 0,
@@ -98,6 +99,14 @@ enum cmd_and_opt_values {
   oDisableCRLChecks,
   oEnableCRLChecks,
 
+  oIncludeCerts,
+
+
+
+
+
+
+
   oTextmode,
   oFingerprint,
   oWithFingerprint,
@@ -229,6 +238,9 @@ static ARGPARSE_OPTS opts[] = {
     { oDisableCRLChecks, "disable-crl-checks", 0, N_("never consult a CRL")},
     { oEnableCRLChecks, "enable-crl-checks", 0, "@"},
 
+    { oIncludeCerts, "include-certs", 1,
+                                 N_("|N|number of certificates to include") },
+
 
 #if 0
     { oDefRecipient, "default-recipient" ,2,
@@ -577,7 +589,7 @@ main ( int argc, char **argv)
 
   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
 
-  may_coredump = 0/* FIXME: disable_core_dumps()*/;
+  may_coredump = disable_core_dumps ();
   
   /* FIXME: init_signals();*/
   
@@ -631,8 +643,9 @@ main ( int argc, char **argv)
   assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
   keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
 
-  /* Setup a default control structure */
+  /* Setup a default control structure for command line mode */
   memset (&ctrl, 0, sizeof ctrl);
+  gpgsm_init_default_ctrl (&ctrl);
   ctrl.no_server = 1;
   ctrl.status_fd = -1; /* not status output */
   ctrl.autodetect_encoding = 1;
@@ -741,7 +754,8 @@ main ( int argc, char **argv)
         case oEnableCRLChecks:
           opt.no_crl_check = 0;
           break;
-          
+
+        case oIncludeCerts: ctrl.include_certs = pargs.r.ret_int; break;
 
         case oOutput: opt.outfile = pargs.r.ret_str; break;
 
@@ -1198,6 +1212,14 @@ gpgsm_exit (int rc)
 }
 
 
+void
+gpgsm_init_default_ctrl (struct server_control_s *ctrl)
+{
+  ctrl->include_certs = 1;
+}
+
+
+
 /* Check whether the filename has the form "-&nnnn", where n is a
    non-zero number.  Returns this number or -1 if it is not the case.  */
 static int
index 4d7e558..f8f5ed8 100644 (file)
@@ -89,6 +89,8 @@ struct {
 
 struct server_local_s;
 
+/* Note that the default values for this are set by
+   gpgsm_init_default_ctrl() */
 struct server_control_s {
   int no_server;     /* we are not running under server control */
   int  status_fd;    /* only for non-server mode */
@@ -102,6 +104,11 @@ struct server_control_s {
   int create_base64;  /* Create base64 encoded output */
   int create_pem;     /* create PEM output */
   const char *pem_name; /* PEM name to use */
+
+  int include_certs;  /* -1 to send all certificates in the chain
+                         along with a signature or the number of
+                         certificates up the chain (0 = none, 1 = only
+                         signer) */
  
 };
 typedef struct server_control_s *CTRL;
@@ -118,6 +125,7 @@ typedef struct certlist_s *CERTLIST;
 
 /*-- gpgsm.c --*/
 void gpgsm_exit (int rc);
+void gpgsm_init_default_ctrl (struct server_control_s *ctrl);
 
 /*-- server.c --*/
 void gpgsm_server (void);
@@ -158,10 +166,11 @@ int gpgsm_create_cms_signature (KsbaCert cert, GCRY_MD_HD md, int mdalgo,
 
 
 /*-- certpath.c --*/
+int gpgsm_walk_cert_chain (KsbaCert start, KsbaCert *r_next);
 int gpgsm_validate_path (KsbaCert cert);
 int gpgsm_basic_cert_check (KsbaCert cert);
 
-/*-- cetlist.c --*/
+/*-- cetrlist.c --*/
 int gpgsm_add_to_certlist (const char *name, CERTLIST *listaddr);
 void gpgsm_release_certlist (CERTLIST list);
 int gpgsm_find_cert (const char *name, KsbaCert *r_cert);
index e05f5da..616ae9b 100644 (file)
@@ -57,7 +57,18 @@ close_message_fd (CTRL ctrl)
 static int
 option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value)
 {
-  log_debug ("got option key=`%s' value=`%s'\n", key, value);
+  CTRL ctrl = assuan_get_pointer (ctx);
+
+  if (!strcmp (key, "include-certs"))
+    {
+      int i = *value? atoi (value) : -1;
+      if (ctrl->include_certs < -1)
+        return ASSUAN_Parameter_Error;
+      ctrl->include_certs = i;
+    }
+  else
+    return ASSUAN_Invalid_Option;
+
   return 0;
 }
 
@@ -458,6 +469,7 @@ gpgsm_server (void)
   struct server_control_s ctrl;
 
   memset (&ctrl, 0, sizeof ctrl);
+  gpgsm_init_default_ctrl (&ctrl);
 
   /* For now we use a simple pipe based server so that we can work
      from scripts.  We will later add options to run as a daemon and
index 48ec24a..9b23e85 100644 (file)
--- a/sm/sign.c
+++ b/sm/sign.c
@@ -103,6 +103,49 @@ get_default_signer (void)
 }
 
 
+/* Depending on the options in CTRL add the certifcate CERT as well as
+   other certificate up in the chain to the Root-CA to the CMS
+   object. */
+static int 
+add_certificate_list (CTRL ctrl, KsbaCMS cms, KsbaCert cert)
+{
+  KsbaError err;
+  int rc = 0;
+  KsbaCert next = NULL;
+  int n;
+
+  ksba_cert_ref (cert);
+
+  n = ctrl->include_certs;
+  if (n < 0 || n > 50)
+    n = 50; /* We better apply an upper bound */
+
+  if (n)
+    {
+      err = ksba_cms_add_cert (cms, cert);
+      if (err)
+        goto ksba_failure;
+    }
+  while ( n-- && !(rc = gpgsm_walk_cert_chain (cert, &next)) )
+    {
+      err = ksba_cms_add_cert (cms, next);
+      ksba_cert_release (cert);
+      cert = next; next = NULL;
+      if (err)
+        goto ksba_failure;
+    }
+  ksba_cert_release (cert);
+
+  return rc == -1? 0: rc;
+
+ ksba_failure:
+  ksba_cert_release (cert);
+  log_error ("ksba_cms_add_cert failed: %s\n", ksba_strerror (err));
+  return map_ksba_err (err);
+}
+
+
+
 \f
 /* Perform a sign operation.  
 
@@ -192,16 +235,19 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
   err = ksba_cms_add_signer (cms, cert);
   if (err)
     {
-      log_debug ("ksba_cms_add_signer failed: %s\n",  ksba_strerror (err));
+      log_error ("ksba_cms_add_signer failed: %s\n",  ksba_strerror (err));
       rc = map_ksba_err (err);
       goto leave;
     }
+  rc = add_certificate_list (ctrl, cms, cert);
+  if (rc)
+    {
+      log_error ("failed to store list of certificates: %s\n",
+                 gnupg_strerror(rc));
+      goto leave;
+    }
   ksba_cert_release (cert); cert = NULL;
 
-  /* fixme: We might want to include a list of certificate which are
-     put as info into the signed data object - maybe we should add a
-     flag to ksba_cms_add_signer to decider whether this cert should
-     be send along with the signature */
   
   /* Set the hash algorithm we are going to use */
   err = ksba_cms_add_digest_algo (cms, "1.3.14.3.2.26" /*SHA-1*/);