aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2002-01-25 16:41:13 +0000
committerWerner Koch <[email protected]>2002-01-25 16:41:13 +0000
commit151deac0dfcc712a00844943445cbde7c6b0eb38 (patch)
treefa0b13b368613ba2ec69d7261377d4e4f54d84a9
parent* assuan-socket-connect.c (LOGERRORX): and removed typo. (diff)
downloadgnupg-151deac0dfcc712a00844943445cbde7c6b0eb38.tar.gz
gnupg-151deac0dfcc712a00844943445cbde7c6b0eb38.zip
* 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.
-rw-r--r--sm/ChangeLog14
-rw-r--r--sm/certchain.c61
-rw-r--r--sm/certpath.c61
-rw-r--r--sm/gpgsm.c28
-rw-r--r--sm/gpgsm.h11
-rw-r--r--sm/server.c14
-rw-r--r--sm/sign.c56
7 files changed, 235 insertions, 10 deletions
diff --git a/sm/ChangeLog b/sm/ChangeLog
index a893fdff9..561e3a573 100644
--- a/sm/ChangeLog
+++ b/sm/ChangeLog
@@ -1,3 +1,17 @@
+2002-01-25 Werner Koch <[email protected]>
+
+ * 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 <[email protected]>
* certpath.c (gpgsm_validate_path): Print the DN of a missing issuer.
diff --git a/sm/certchain.c b/sm/certchain.c
index 9ef862643..842481bfc 100644
--- a/sm/certchain.c
+++ b/sm/certchain.c
@@ -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;
+}
+
int
gpgsm_validate_path (KsbaCert cert)
{
diff --git a/sm/certpath.c b/sm/certpath.c
index 9ef862643..842481bfc 100644
--- a/sm/certpath.c
+++ b/sm/certpath.c
@@ -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;
+}
+
int
gpgsm_validate_path (KsbaCert cert)
{
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index d9b9e27b9..0203c5a2a 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -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
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index 4d7e55880..f8f5ed8b6 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -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);
diff --git a/sm/server.c b/sm/server.c
index e05f5da0b..616ae9bfe 100644
--- a/sm/server.c
+++ b/sm/server.c
@@ -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
diff --git a/sm/sign.c b/sm/sign.c
index 48ec24a4d..9b23e8536 100644
--- 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);
+}
+
+
+
/* 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*/);