dirmngr (12 files)

cvs user wk cvs at cvs.gnupg.org
Fri Dec 3 15:34:58 CET 2004


    Date: Friday, December 3, 2004 @ 15:42:36
  Author: wk
    Path: /cvs/dirmngr/dirmngr

Modified: ChangeLog configure.ac src/ChangeLog src/certcache.c
          src/certcache.h src/crlcache.c src/dirmngr-client.c
          src/dirmngr.c src/misc.c src/misc.h src/ocsp.c src/server.c

* configure.ac (canonicalize_file_name): Check for it.

* crlcache.c (crl_cache_load): Re-implement it.

* dirmngr-client.c: New command --load-crl
(do_loadcrl): New.

* dirmngr.c (parse_rereadable_options, main): Make --allow-ocsp,
--ocsp-responder, --ocsp-signer and --max-replies re-readable.

* ocsp.c (check_signature): try to get the cert from the cache
first.
(ocsp_isvalid): Print the next and this update times on time
conflict.

* certcache.c (load_certs_from_dir): Print the fingerprint for
trusted certificates.
(get_cert_byhexfpr): New.
* misc.c (get_fingerprint_hexstring_colon): New.


----------------------+
 ChangeLog            |    4 ++
 configure.ac         |    2 +
 src/ChangeLog        |   20 +++++++++++
 src/certcache.c      |   51 +++++++++++++++++++++++++++++-
 src/certcache.h      |    7 ++++
 src/crlcache.c       |   20 ++++++++---
 src/dirmngr-client.c |   82 ++++++++++++++++++++++++++++++++++++++++++++++---
 src/dirmngr.c        |   17 +++++-----
 src/misc.c           |   35 ++++++++++++++++++++
 src/misc.h           |    3 +
 src/ocsp.c           |    8 ++++
 src/server.c         |    2 -
 12 files changed, 232 insertions(+), 19 deletions(-)


Index: dirmngr/ChangeLog
diff -u dirmngr/ChangeLog:1.78 dirmngr/ChangeLog:1.79
--- dirmngr/ChangeLog:1.78	Thu Nov 25 14:19:07 2004
+++ dirmngr/ChangeLog	Fri Dec  3 15:42:36 2004
@@ -1,3 +1,7 @@
+2004-12-03  Werner Koch  <wk at g10code.com>
+
+	* configure.ac (canonicalize_file_name): Check for it.
+
 2004-11-25  Werner Koch  <wk at g10code.com>
 
 	* configure.ac: Reverted to require autoconf/make 2.57/1.7.6 as
Index: dirmngr/configure.ac
diff -u dirmngr/configure.ac:1.63 dirmngr/configure.ac:1.64
--- dirmngr/configure.ac:1.63	Thu Nov 25 14:19:07 2004
+++ dirmngr/configure.ac	Fri Dec  3 15:42:36 2004
@@ -363,6 +363,8 @@
   AC_MSG_ERROR([[Sorry, the current implemenation requires mmap.]])
 fi
 
+AC_CHECK_FUNCS([canonicalize_file_name])
+
 # Check for funopen
 AC_CHECK_FUNCS(funopen fopencookie)
 if test $ac_cv_func_funopen != yes; then
Index: dirmngr/src/ChangeLog
diff -u dirmngr/src/ChangeLog:1.31 dirmngr/src/ChangeLog:1.32
--- dirmngr/src/ChangeLog:1.31	Wed Dec  1 17:11:14 2004
+++ dirmngr/src/ChangeLog	Fri Dec  3 15:42:36 2004
@@ -1,3 +1,23 @@
+2004-12-03  Werner Koch  <wk at g10code.com>
+
+	* crlcache.c (crl_cache_load): Re-implement it.
+
+	* dirmngr-client.c: New command --load-crl
+	(do_loadcrl): New.
+
+	* dirmngr.c (parse_rereadable_options, main): Make --allow-ocsp,
+	--ocsp-responder, --ocsp-signer and --max-replies re-readable.
+
+	* ocsp.c (check_signature): try to get the cert from the cache
+	first.
+	(ocsp_isvalid): Print the next and this update times on time
+	conflict.
+
+	* certcache.c (load_certs_from_dir): Print the fingerprint for
+	trusted certificates.
+	(get_cert_byhexfpr): New.
+	* misc.c (get_fingerprint_hexstring_colon): New.
+
 2004-12-01  Werner Koch  <wk at g10code.com>
 
 	* Makefile.am (dirmngr_LDADD): Don't use LDAP_LIBS.
Index: dirmngr/src/certcache.c
diff -u dirmngr/src/certcache.c:1.7 dirmngr/src/certcache.c:1.8
--- dirmngr/src/certcache.c:1.7	Wed Nov 24 13:25:53 2004
+++ dirmngr/src/certcache.c	Fri Dec  3 15:42:36 2004
@@ -353,7 +353,15 @@
       if (gpg_err_code (err) == GPG_ERR_DUP_VALUE)
         log_info (_("certificate `%s' already cached\n"), fname);
       else if (!err)
-        log_info (_("certificate `%s' loaded\n"), fname);
+        {
+          log_info (_("certificate `%s' loaded\n"), fname);
+          if (are_trusted || opt.verbose)
+            {
+              p = get_fingerprint_hexstring_colon (cert);
+              log_info (_("SHA1 fingerprint = %s\n"), p);
+              xfree (p);
+            }
+        }
       else
         log_error (_("error loading certificate `%s': %s\n"),
                      fname, gpg_strerror (err));
@@ -482,6 +490,47 @@
   return NULL;
 }
 
+/* Return a certificate object for the given fingerprint.  STRING is
+   expected to be a SHA-1 fingerprint in standard hex notation with or
+   without colons.  If no matching certificate is available in the
+   cache NULL is returned.  The caller must release a returned
+   certificate.  Note that although we are using reference counting
+   the caller should not just compare the pointers to check for
+   identical certificates. */
+ksba_cert_t
+get_cert_byhexfpr (const char *string)
+{
+  unsigned char fpr[20];
+  const char *s;
+  int i;
+
+  if (strchr (string, ':'))
+    {
+      for (s=string,i=0; i < 20 && hexdigitp (s) && hexdigitp(s+1);)
+        {
+          if (s[2] && s[2] != ':')
+            break; /* Invalid string. */
+          fpr[i++] = xtoi_2 (s);
+          s += 2;
+          if (i!= 20 && *s == ':')
+            s++;
+        }
+    }
+  else
+    {
+      for (s=string,i=0; i < 20 && hexdigitp (s) && hexdigitp(s+1); s+=2 )
+        fpr[i++] = xtoi_2 (s);
+    }
+  if (i!=20 || *s)
+    {
+      log_error (_("invalid SHA1 fingerprint string `%s'\n"), string);
+      return NULL;
+    }
+
+  return get_cert_byfpr (fpr);
+}
+
+
 
 /* Return the certificate matching ISSUER_DN and SERIALNO.  */
 ksba_cert_t
Index: dirmngr/src/certcache.h
diff -u dirmngr/src/certcache.h:1.4 dirmngr/src/certcache.h:1.5
--- dirmngr/src/certcache.h:1.4	Mon Nov 22 22:30:50 2004
+++ dirmngr/src/certcache.h	Fri Dec  3 15:42:36 2004
@@ -49,6 +49,13 @@
    must release a returned certificate.  */
 ksba_cert_t get_cert_byfpr (const unsigned char *fpr);
 
+/* Return a certificate object for the given fingerprint.  STRING is
+   expected to be a SHA-1 fingerprint in standard hex notation with or
+   without colons.  If no matching certificate is available in the
+   cache NULL is returned.  The caller must release a returned
+   certificate.  */
+ksba_cert_t get_cert_byhexfpr (const char *string);
+
 
 /* Return the certificate matching ISSUER_DN.  SEQ should initially be
    set to 0 and bumped up to get the next issuer with that DN. */
Index: dirmngr/src/crlcache.c
diff -u dirmngr/src/crlcache.c:1.50 dirmngr/src/crlcache.c:1.51
--- dirmngr/src/crlcache.c:1.50	Wed Nov 24 13:25:53 2004
+++ dirmngr/src/crlcache.c	Fri Dec  3 15:42:36 2004
@@ -2127,13 +2127,13 @@
 }
 
 
-/* Load the CRL contain the the file named FILENAME into our cache
-   CACHE */
+/* Load the CRL containing the file named FILENAME into our CRL cache. */
 gpg_error_t
 crl_cache_load (ctrl_t ctrl, const char *filename)
 {
   gpg_error_t err;
-  FILE* fp;
+  FILE *fp;
+  ksba_reader_t reader;
 
   fp = fopen (filename, "r");
   if (!fp)
@@ -2143,8 +2143,18 @@
       return err;
     }
 
-  err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
-       /*crl_cache_insert (ctrl, filename, fo);*/
+  err = ksba_reader_new (&reader);
+  if (!err)
+    err = ksba_reader_set_file (reader, fp);
+  if (err)
+    {
+      log_error (_("error initializing reader object: %s\n"),
+                 gpg_strerror (err));
+      ksba_reader_release (reader);
+      return err;
+    }
+  err = crl_cache_insert (ctrl, filename, reader);
+  ksba_reader_release (reader);
   fclose (fp);
   return err;
 }
Index: dirmngr/src/dirmngr-client.c
diff -u dirmngr/src/dirmngr-client.c:1.5 dirmngr/src/dirmngr-client.c:1.6
--- dirmngr/src/dirmngr-client.c:1.5	Wed Nov 24 13:25:53 2004
+++ dirmngr/src/dirmngr-client.c	Fri Dec  3 15:42:36 2004
@@ -55,7 +55,7 @@
     oCacheCert,
     oValidate,
     oLookup,
-    oDummy
+    oLoadCRL
   };
 
 
@@ -68,6 +68,7 @@
   { oCacheCert,"cache-cert",0, N_("add a certificate to the cache")},
   { oValidate, "validate",  0, N_("validate a certificate")},
   { oLookup,   "lookup",    0, N_("lookup a certificate")},
+  { oLoadCRL,  "load-crl",  0, N_("load a CRL into the dirmngr")},
   {0}
 };
  
@@ -105,6 +106,7 @@
                              const unsigned char *cert, size_t certlen);
 static gpg_error_t do_validate (assuan_context_t ctx,
                                 const unsigned char *cert, size_t certlen);
+static gpg_error_t do_loadcrl (assuan_context_t ctx, const char *filename);
 static gpg_error_t do_lookup (assuan_context_t ctx, const char *pattern);
 
 
@@ -170,6 +172,7 @@
   int cmd_cache_cert = 0;
   int cmd_validate = 0;
   int cmd_lookup = 0;
+  int cmd_loadcrl = 0;
 
   set_strusage (my_strusage);
   log_set_prefix ("dirmngr-client",
@@ -198,6 +201,7 @@
         case oCacheCert: cmd_cache_cert = 1; break;
         case oValidate: cmd_validate = 1; break;
         case oLookup: cmd_lookup = 1; break;
+        case oLoadCRL: cmd_loadcrl = 1; break;
 
         default : pargs.err = 2; break;
 	}
@@ -207,7 +211,7 @@
 
   if (cmd_ping)
     err = 0;
-  else if (cmd_lookup)
+  else if (cmd_lookup || cmd_loadcrl)
     {
       if (!argc)
         usage (1);
@@ -263,6 +267,22 @@
         }
       err = last_err;
     }
+  else if (cmd_loadcrl)
+    {
+      int last_err = 0;
+
+      for (; argc; argc--, argv++)
+        {
+          err = do_loadcrl (ctx, *argv);
+          if (err)
+            {
+              log_error (_("loading CRL `%s' failed: %s\n"),
+                         *argv, gpg_strerror (err));
+              last_err = err;
+            }
+        }
+      err = last_err;
+    }
   else if (cmd_cache_cert)
     {
       err = do_cache (ctx, certbuf, certbuflen);
@@ -287,7 +307,7 @@
         log_info (_("a dirmngr daemon is up and running\n"));
       return 0;
     }
-  else if (cmd_lookup)
+  else if (cmd_lookup||cmd_loadcrl)
     return err? 1:0;
   else if (cmd_cache_cert)
     {
@@ -468,7 +488,7 @@
 }
 
 
-/* Red a binary certificate from the file FNAME.  If fname is NULL the
+/* Read a binary certificate from the file FNAME.  If fname is NULL the
    file is read from stdin.  The certificate is returned in an alloced
    buffer whos address will be returned in RBUF and its length in
    RBUFLEN.  */
@@ -613,6 +633,60 @@
   return map_assuan_err (ae);
 }
 
+/* Load a CRL into the dirmngr.  */
+static gpg_error_t
+do_loadcrl (assuan_context_t ctx, const char *filename)
+{
+  assuan_error_t ae;
+  const char *s;
+  char *fname, *line, *p;
+
+#ifdef HAVE_CANONICALIZE_FILE_NAME
+  fname = canonicalize_file_name (filename);
+  if (!fname)
+    {
+      log_error ("error canonicalizing `%s': %s\n",
+                 filename, strerror (errno));
+      return gpg_error (GPG_ERR_GENERAL);
+    }      
+#else
+  fname = xstrdup (filename);
+#endif
+  if (*fname != '/')
+    {
+      log_error (_("absolute file name expected\n"));
+      return gpg_error (GPG_ERR_GENERAL);
+    }
+
+  line = xmalloc (8+ strlen (fname) * 3 + 1);
+  p = stpcpy (line, "LOADCRL ");
+  for (s = fname; *s; s++)
+    {
+      if (*s < ' ' || *s == '+')
+        {
+          sprintf (p, "%%%02X", *s);
+          p += 3;
+        }
+      else if (*s == ' ')
+        *p++ = '+';
+      else
+        *p++ = *s;
+    }
+  *p = 0;
+
+  ae = assuan_transact (ctx, line, NULL, NULL,
+                        NULL, NULL,
+                        status_cb, NULL);
+  if (opt.verbose > 1)
+    log_info ("response of dirmngr: %s\n", ae? assuan_strerror (ae): "okay");
+  xfree (line);
+  xfree (fname);
+  return map_assuan_err (ae);
+}
+
+
+/* Do a LDAP lookup using PATTERN and print the result in a base-64
+   encoded format.  */
 static gpg_error_t
 do_lookup (assuan_context_t ctx, const char *pattern)
 {
Index: dirmngr/src/dirmngr.c
diff -u dirmngr/src/dirmngr.c:1.49 dirmngr/src/dirmngr.c:1.50
--- dirmngr/src/dirmngr.c:1.49	Wed Dec  1 17:11:14 2004
+++ dirmngr/src/dirmngr.c	Fri Dec  3 15:42:36 2004
@@ -384,6 +384,10 @@
       opt.ignore_http_dp = 0;
       opt.ignore_ldap_dp = 0;
       opt.ignore_ocsp_service_url = 0;
+      opt.allow_ocsp = 0;
+      opt.ocsp_responder = NULL;
+      opt.ocsp_signer = NULL; 
+      opt.max_replies = DEFAULT_MAX_REPLIES;
       return 1;
     }
 
@@ -424,6 +428,12 @@
     case oIgnoreLDAPDP: opt.ignore_ldap_dp = 1; break;
     case oIgnoreOCSPSvcUrl: opt.ignore_ocsp_service_url = 1; break;
 
+    case oAllowOCSP: opt.allow_ocsp = 1; break;
+    case oOCSPResponder: opt.ocsp_responder = pargs->r.ret_str; break;
+    case oOCSPSigner:    opt.ocsp_signer = pargs->r.ret_str; break;
+
+    case oMaxReplies: opt.max_replies = pargs->r.ret_int; break;
+
     default:
       return 0; /* Not handled. */
     }
@@ -522,8 +532,6 @@
   opt.ldaptimeout.tv_sec = DEFAULT_LDAP_TIMEOUT;
   opt.ldaptimeout.tv_usec = 0;
 
-  /* Default max replies */
-  opt.max_replies = DEFAULT_MAX_REPLIES;
 
   /* Other defaults.  */
   socket_name = DEFAULT_SOCKET_NAME;
@@ -650,11 +658,6 @@
 	  opt.ldaptimeout.tv_sec = pargs.r.ret_int; 
 	  opt.ldaptimeout.tv_usec = 0;
 	  break;
-	case oMaxReplies: opt.max_replies = pargs.r.ret_int; break;
-
-        case oAllowOCSP: opt.allow_ocsp = 1; break;
-        case oOCSPResponder: opt.ocsp_responder = pargs.r.ret_str; break;
-        case oOCSPSigner:    opt.ocsp_signer = pargs.r.ret_str; break;
 
         case oFakedSystemTime:
           set_time ( (time_t)pargs.r.ret_ulong, 0);
Index: dirmngr/src/misc.c
diff -u dirmngr/src/misc.c:1.9 dirmngr/src/misc.c:1.10
--- dirmngr/src/misc.c:1.9	Tue Nov 23 14:20:44 2004
+++ dirmngr/src/misc.c	Fri Dec  3 15:42:36 2004
@@ -470,6 +470,41 @@
   return buf;
 }
 
+/* Return an allocated buffer with the formatted fingerprint as one
+   large hexnumber.  This version inserts the usual colons. */
+char *
+get_fingerprint_hexstring_colon (ksba_cert_t cert)
+{
+  unsigned char digest[20];
+  gcry_md_hd_t md;
+  int rc;
+  char *buf;
+  int i;
+
+  rc = gcry_md_open (&md, GCRY_MD_SHA1, 0);
+  if (rc)
+    log_fatal (_("gcry_md_open failed: %s\n"), gpg_strerror (rc));
+
+  rc = ksba_cert_hash (cert, 0, HASH_FNC, md);
+  if (rc)
+    {
+      log_error (_("oops: ksba_cert_hash failed: %s\n"), gpg_strerror (rc));
+      memset (digest, 0xff, 20); /* Use a dummy value. */
+    }
+  else
+    {
+      gcry_md_final (md);
+      memcpy (digest, gcry_md_read (md, GCRY_MD_SHA1), 20);
+    }
+  gcry_md_close (md);
+  buf = xmalloc (61);
+  *buf = 0;
+  for (i=0; i < 20; i++ )
+    sprintf (buf+strlen(buf), "%02X:", digest[i]);
+  buf[strlen(buf)-1] = 0; /* Remove railing colon. */
+  return buf;
+}
+
 
 /* Dump the serial number SERIALNO to the log stream.  */
 void
Index: dirmngr/src/misc.h
diff -u dirmngr/src/misc.h:1.9 dirmngr/src/misc.h:1.10
--- dirmngr/src/misc.h:1.9	Tue Nov 23 14:20:44 2004
+++ dirmngr/src/misc.h	Fri Dec  3 15:42:36 2004
@@ -84,6 +84,9 @@
 /* Return an allocated hex-string with the SHA-1 fingerprint of
    CERT. */
 char *get_fingerprint_hexstring (ksba_cert_t cert);
+/* Return an allocated hex-string with the SHA-1 fingerprint of
+   CERT.  This version inserts the usual colons. */
+char *get_fingerprint_hexstring_colon (ksba_cert_t cert);
 
 
 /* Dump the serial number SERIALNO to the log stream.  */
Index: dirmngr/src/ocsp.c
diff -u dirmngr/src/ocsp.c:1.12 dirmngr/src/ocsp.c:1.13
--- dirmngr/src/ocsp.c:1.12	Wed Nov 24 15:44:01 2004
+++ dirmngr/src/ocsp.c	Fri Dec  3 15:42:36 2004
@@ -348,7 +348,9 @@
     {
       /* We should use the default OCSP reponder's certificate.  Get
          it from the fingerprint. */
-      cert = get_cert_local (ctrl, signer_fpr);
+      cert = get_cert_byhexfpr (signer_fpr);
+      if (!cert)
+        cert = get_cert_local (ctrl, signer_fpr);
       if (cert)
         {
           err = check_signature_core (ctrl, cert, s_sig, s_hash);
@@ -400,6 +402,7 @@
   gcry_sexp_t s_sig = NULL;
   ksba_isotime_t current_time;
   ksba_isotime_t this_update, next_update, revocation_time, produced_at;
+  ksba_isotime_t tmp_time;
   ksba_status_t status;
   ksba_crl_reason_t reason;
   char *url_buffer = NULL;
@@ -589,16 +592,19 @@
   if (*next_update && strcmp (next_update, current_time) < 0 )
     {
       log_error (_("OCSP responder returned an too old status\n"));
+      log_info ("now: %s  next_update: %s\n", current_time, next_update);
       if (!err)
         err = gpg_error (GPG_ERR_TIME_CONFLICT);
     }
   /* Check that THIS_UPDATE is not too far back in the past.  We
      currently use 3 hours (the extra 10 minutes are for the time
      adjust above). */
+  copy_time (tmp_time, this_update);
   add_isotime (this_update, 3 * 60 * 60 + 10 * 60);
   if (!*this_update || strcmp (this_update, current_time) < 0 )
     {
       log_error (_("OCSP responder returned a non-current status\n"));
+      log_info ("now: %s  this_update: %s\n", current_time, tmp_time);
       if (!err)
         err = gpg_error (GPG_ERR_TIME_CONFLICT);
     }
Index: dirmngr/src/server.c
diff -u dirmngr/src/server.c:1.47 dirmngr/src/server.c:1.48
--- dirmngr/src/server.c:1.47	Tue Nov 23 14:20:44 2004
+++ dirmngr/src/server.c	Fri Dec  3 15:42:36 2004
@@ -696,7 +696,7 @@
    that FILENAME should be given with an absolute path because
    Dirmngrs cwd is not known.  This command is usually used by gpgsm
    using the invocation "gpgsm --call-dirmngr loadcrl <filename>".  A
-   direct onvocation of Dirmngr is not useful because gpgsm might need
+   direct invocation of Dirmngr is not useful because gpgsm might need
    to callback gpgsm to ask for the CA's certificate.
 */
 




More information about the Gnupg-commits mailing list