dirmngr: Add support for hkps keyservers.
authorWerner Koch <wk@gnupg.org>
Mon, 5 May 2014 14:09:45 +0000 (16:09 +0200)
committerWerner Koch <wk@gnupg.org>
Mon, 5 May 2014 14:23:37 +0000 (16:23 +0200)
* dirmngr/dirmngr.c: Include gnutls.h.
(opts): Add --gnutls-debug and --hkp-cacert.
(opt_gnutls_debug, my_gnutls_log): New.
(set_debug): Set gnutls log level.
(parse_rereadable_options): Register a CA file.
(main): Init GNUTLS.
* dirmngr/ks-engine-hkp.c (ks_hkp_help): Support hkps.
(send_request): Ditto.

dirmngr/dirmngr.c
dirmngr/ks-engine-hkp.c
dirmngr/sks-keyservers.netCA.pem [new file with mode: 0644]
doc/dirmngr.texi
doc/gpg.texi

index 81da029..8f85e48 100644 (file)
@@ -40,6 +40,9 @@
 # include <signal.h>
 #endif
 #include <npth.h>
+#ifdef HTTP_USE_GNUTLS
+# include <gnutls/gnutls.h>
+#endif /*HTTP_USE_GNUTLS*/
 
 
 #define JNLIB_NEED_LOG_LOGV
@@ -92,6 +95,7 @@ enum cmd_and_opt_values {
   oDebugAll,
   oDebugWait,
   oDebugLevel,
+  oGnutlsDebug,
   oNoGreeting,
   oNoOptions,
   oHomedir,
@@ -116,6 +120,7 @@ enum cmd_and_opt_values {
   oOCSPMaxPeriod,
   oOCSPCurrentPeriod,
   oMaxReplies,
+  oHkpCaCert,
   oFakedSystemTime,
   oForce,
   oAllowOCSP,
@@ -195,11 +200,16 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_i (oMaxReplies, "max-replies",
                 N_("|N|do not return more than N items in one query")),
 
+  ARGPARSE_s_s (oHkpCaCert, "hkp-cacert",
+                N_("|FILE|use the CA certifciates in FILE for HKP over TLS")),
+
+
   ARGPARSE_s_s (oSocketName, "socket-name", "@"),  /* Only for debugging.  */
 
   ARGPARSE_s_u (oFakedSystemTime, "faked-system-time", "@"), /*(epoch time)*/
   ARGPARSE_p_u (oDebug,    "debug", "@"),
   ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
+  ARGPARSE_s_i (oGnutlsDebug, "gnutls-debug", "@"),
   ARGPARSE_s_i (oDebugWait, "debug-wait", "@"),
   ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"),
   ARGPARSE_s_s (oHomedir, "homedir", "@"),
@@ -234,6 +244,9 @@ static char *current_logfile;
 /* Helper to implement --debug-level. */
 static const char *debug_level;
 
+/* Helper to set the GNUTLS log level.  */
+static int opt_gnutls_debug = -1;
+
 /* Flag indicating that a shutdown has been requested.  */
 static volatile int shutdown_pending;
 
@@ -331,6 +344,20 @@ my_ksba_hash_buffer (void *arg, const char *oid,
 }
 
 
+/* GNUTLS log function callback.  */
+static void
+my_gnutls_log (int level, const char *text)
+{
+  int n;
+
+  n = strlen (text);
+  while (n && text[n-1] == '\n')
+    n--;
+
+  log_debug ("gnutls:L%d: %.*s\n", level, n, text);
+}
+
+
 /* Setup the debugging.  With a LEVEL of NULL only the active debug
    flags are propagated to the subsystems.  With LEVEL set, a specific
    set of debug flags is set; thus overriding all flags already
@@ -382,6 +409,14 @@ set_debug (void)
 
   if (opt.debug & DBG_CRYPTO_VALUE )
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
+
+#ifdef HTTP_USE_GNUTLS
+  if (opt_gnutls_debug >= 0)
+    {
+      gnutls_global_set_log_function (my_gnutls_log);
+      gnutls_global_set_log_level (opt_gnutls_debug);
+    }
+#endif /*HTTP_USE_GNUTLS*/
 }
 
 
@@ -439,6 +474,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
           opt.ocsp_signer = tmp;
         }
       FREE_STRLIST (opt.ignored_cert_extensions);
+      http_register_tls_ca (NULL);
       return 1;
     }
 
@@ -449,6 +485,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
     case oDebug:   opt.debug |= pargs->r.ret_ulong; break;
     case oDebugAll: opt.debug = ~0; break;
     case oDebugLevel: debug_level = pargs->r.ret_str; break;
+    case oGnutlsDebug: opt_gnutls_debug = pargs->r.ret_int; break;
 
     case oLogFile:
       if (!reread)
@@ -490,6 +527,10 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
 
     case oMaxReplies: opt.max_replies = pargs->r.ret_int; break;
 
+    case oHkpCaCert:
+      http_register_tls_ca (pargs->r.ret_str);
+      break;
+
     case oIgnoreCertExtension:
       add_to_strlist (&opt.ignored_cert_extensions, pargs->r.ret_str);
       break;
@@ -628,6 +669,12 @@ main (int argc, char **argv)
   ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
   ksba_set_hash_buffer_function (my_ksba_hash_buffer, NULL);
 
+  /* Init GNUTLS.  */
+#ifdef HTTP_USE_GNUTLS
+  rc = gnutls_global_init ();
+  if (rc)
+    log_fatal ("gnutls_global_init failed: %s\n", gnutls_strerror (rc));
+#endif /*HTTP_USE_GNUTLS*/
 
   /* Init Assuan. */
   malloc_hooks.malloc = gcry_malloc;
index fa616a0..c115cf5 100644 (file)
@@ -628,12 +628,14 @@ ks_hkp_help (ctrl_t ctrl, parsed_uri_t uri)
   const char const data[] =
     "Handler for HKP URLs:\n"
     "  hkp://\n"
+    "  hkps://\n"
     "Supported methods: search, get, put\n";
   gpg_error_t err;
 
   if (!uri)
-    err = ks_print_help (ctrl, "  hkp");
-  else if (uri->is_http && !strcmp (uri->scheme, "hkp"))
+    err = ks_print_help (ctrl, "  hkp\n  hkps");
+  else if (uri->is_http && (!strcmp (uri->scheme, "hkp")
+                            || !strcmp (uri->scheme, "hkps")))
     err = ks_print_help (ctrl, data);
   else
     err = 0;
@@ -747,6 +749,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
               estream_t *r_fp)
 {
   gpg_error_t err;
+  http_session_t session = NULL;
   http_t http = NULL;
   int redirects_left = MAX_REDIRECTS;
   estream_t fp = NULL;
@@ -754,6 +757,10 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
 
   *r_fp = NULL;
 
+  err = http_session_new (&session, NULL);
+  if (err)
+    goto leave;
+
  once_more:
   err = http_open (&http,
                    post_cb? HTTP_REQ_POST : HTTP_REQ_GET,
@@ -761,7 +768,8 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
                    /* fixme: AUTH */ NULL,
                    httpflags,
                    /* fixme: proxy*/ NULL,
-                   NULL, NULL,
+                   session,
+                   NULL,
                    /*FIXME curl->srvtag*/NULL);
   if (!err)
     {
@@ -798,6 +806,13 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
       goto leave;
     }
 
+  if (http_get_tls_info (http, NULL))
+    {
+      /* Update the httpflags so that a redirect won't fallback to an
+         unencrypted connection.  */
+      httpflags |= HTTP_FLAG_FORCE_TLS;
+    }
+
   switch (http_get_status_code (http))
     {
     case 200:
@@ -806,6 +821,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
 
     case 301:
     case 302:
+    case 307:
       {
         const char *s = http_get_header (http, "Location");
 
@@ -837,6 +853,10 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
       goto leave;
     }
 
+  /* FIXME: We should register a permanent redirection and whether a
+     host has ever used TLS so that future calls will always use
+     TLS. */
+
   fp = http_get_read_ptr (http);
   if (!fp)
     {
@@ -851,6 +871,7 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
 
  leave:
   http_close (http, 0);
+  http_session_release (session);
   xfree (request_buffer);
   return err;
 }
diff --git a/dirmngr/sks-keyservers.netCA.pem b/dirmngr/sks-keyservers.netCA.pem
new file mode 100644 (file)
index 0000000..24a2ad2
--- /dev/null
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFizCCA3OgAwIBAgIJAK9zyLTPn4CPMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNV
+BAYTAk5PMQ0wCwYDVQQIDARPc2xvMR4wHAYDVQQKDBVza3Mta2V5c2VydmVycy5u
+ZXQgQ0ExHjAcBgNVBAMMFXNrcy1rZXlzZXJ2ZXJzLm5ldCBDQTAeFw0xMjEwMDkw
+MDMzMzdaFw0yMjEwMDcwMDMzMzdaMFwxCzAJBgNVBAYTAk5PMQ0wCwYDVQQIDARP
+c2xvMR4wHAYDVQQKDBVza3Mta2V5c2VydmVycy5uZXQgQ0ExHjAcBgNVBAMMFXNr
+cy1rZXlzZXJ2ZXJzLm5ldCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
+ggIBANdsWy4PXWNUCkS3L//nrd0GqN3dVwoBGZ6w94Tw2jPDPifegwxQozFXkG6I
+6A4TK1CJLXPvfz0UP0aBYyPmTNadDinaB9T4jIwd4rnxl+59GiEmqkN3IfPsv5Jj
+MkKUmJnvOT0DEVlEaO1UZIwx5WpfprB3mR81/qm4XkAgmYrmgnLXd/pJDAMk7y1F
+45b5zWofiD5l677lplcIPRbFhpJ6kDTODXh/XEdtF71EAeaOdEGOvyGDmCO0GWqS
+FDkMMPTlieLA/0rgFTcz4xwUYj/cD5e0ZBuSkYsYFAU3hd1cGfBue0cPZaQH2HYx
+Qk4zXD8S3F4690fRhr+tki5gyG6JDR67aKp3BIGLqm7f45WkX1hYp+YXywmEziM4
+aSbGYhx8hoFGfq9UcfPEvp2aoc8u5sdqjDslhyUzM1v3m3ZGbhwEOnVjljY6JJLx
+MxagxnZZSAY424ZZ3t71E/Mn27dm2w+xFRuoy8JEjv1d+BT3eChM5KaNwrj0IO/y
+u8kFIgWYA1vZ/15qMT+tyJTfyrNVV/7Df7TNeWyNqjJ5rBmt0M6NpHG7CrUSkBy9
+p8JhimgjP5r0FlEkgg+lyD+V79H98gQfVgP3pbJICz0SpBQf2F/2tyS4rLm+49rP
+fcOajiXEuyhpcmzgusAj/1FjrtlynH1r9mnNaX4e+rLWzvU5AgMBAAGjUDBOMB0G
+A1UdDgQWBBTkwyoJFGfYTVISTpM8E+igjdq28zAfBgNVHSMEGDAWgBTkwyoJFGfY
+TVISTpM8E+igjdq28zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQAR
+OXnYwu3g1ZjHyley3fZI5aLPsaE17cOImVTehC8DcIphm2HOMR/hYTTL+V0G4P+u
+gH+6xeRLKSHMHZTtSBIa6GDL03434y9CBuwGvAFCMU2GV8w92/Z7apkAhdLToZA/
+X/iWP2jeaVJhxgEcH8uPrnSlqoPBcKC9PrgUzQYfSZJkLmB+3jEa3HKruy1abJP5
+gAdQvwvcPpvYRnIzUc9fZODsVmlHVFBCl2dlu/iHh2h4GmL4Da2rRkUMlbVTdioB
+UYIvMycdOkpH5wJftzw7cpjsudGas0PARDXCFfGyKhwBRFY7Xp7lbjtU5Rz0Gc04
+lPrhDf0pFE98Aw4jJRpFeWMjpXUEaG1cq7D641RpgcMfPFvOHY47rvDTS7XJOaUT
+BwRjmDt896s6vMDcaG/uXJbQjuzmmx3W2Idyh3s5SI0GTHb0IwMKYb4eBUIpQOnB
+cE77VnCYqKvN1NVYAqhWjXbY7XasZvszCRcOG+W3FqNaHOK/n/0ueb0uijdLan+U
+f4p1bjbAox8eAOQS/8a3bzkJzdyBNUKGx1BIK2IBL9bn/HravSDOiNRSnZ/R3l9G
+ZauX0tu7IIDlRCILXSyeazu0aj/vdT3YFQXPcvt5Fkf5wiNTo53f72/jYEJd6qph
+WrpoKqrwGwTpRUCMhYIUt65hsTxCiJJ5nKe39h46sg==
+-----END CERTIFICATE-----
index e626487..7b2f92c 100644 (file)
@@ -18,7 +18,7 @@
 @mansect synopsis
 @ifset manverb
 .B  dirmngr
-.RI [ options ]  
+.RI [ options ]
 .I command
 .RI [ args ]
 @end ifset
@@ -32,7 +32,7 @@ system daemon through the @command{dirmngr-client} tool.
 
 If @command{dirmngr} is started in system daemon mode, it uses a
 directory layout as common for system daemons and does not make use of
-the default @file{~/.gnupg} directory.  
+the default @file{~/.gnupg} directory.
 
 
 @manpause
@@ -175,7 +175,7 @@ numeric value or by a keyword:
 @item none
 No debugging at all.  A value of less than 1 may be used instead of
 the keyword.
-@item basic  
+@item basic
 Some basic debug messages.  A value between 1 and 2 may be used
 instead of the keyword.
 @item advanced
@@ -204,6 +204,10 @@ usual C-Syntax.
 @opindex debug-all
 Same as @code{--debug=0xffffffff}
 
+@item --gnutls-debug @var{level}
+@opindex gnutls-debug
+Enable debugging of GNUTLS at @var{level}.
+
 @item --debug-wait @var{n}
 @opindex debug-wait
 When running in server mode, wait @var{n} seconds before entering the
@@ -247,12 +251,12 @@ scheme are ignored when looking for a suitable DP.
 @item --ignore-ldap-dp
 @opindex ignore-ldap-dp
 This is similar to @option{--ignore-http-dp} but ignores entries using
-the @acronym{LDAP} scheme.  Both options may be combined resulting in 
+the @acronym{LDAP} scheme.  Both options may be combined resulting in
 ignoring DPs entirely.
 
 @item --ignore-ocsp-service-url
 @opindex ignore-ocsp-service-url
-Ignore all OCSP URLs contained in the certificate.  The effect is to 
+Ignore all OCSP URLs contained in the certificate.  The effect is to
 force the use of the default responder.
 
 @item --honor-http-proxy
@@ -284,7 +288,7 @@ configured LDAP server if the connection using the "proxy" failed.
 @item --ldapserverlist-file @var{file}
 @opindex ldapserverlist-file
 Read the list of LDAP servers to consult for CRLs and certificates from
-file instead of the default per-user ldap server list file. The default 
+file instead of the default per-user ldap server list file. The default
 value for @var{file} is @file{dirmngr_ldapservers.conf} or
 @file{ldapservers.conf} when running in @option{--daemon} mode.
 
@@ -328,7 +332,7 @@ Note: The current version of dirmngr has this option disabled by default.
 
 @item --allow-ocsp
 @opindex allow-ocsp
-This option enables OCSP support if requested by the client.  
+This option enables OCSP support if requested by the client.
 
 OCSP requests are rejected by default because they may violate the
 privacy of the user; for example it is possible to track the time when
@@ -395,10 +399,17 @@ won't be rejected due to an unknown critical extension.  Use this
 option with care because extensions are usually flagged as critical
 for a reason.
 
+@item --hkp-cacert @var{file}
+Use the root certificates in @var{file} for verification of the TLS
+certificates used with @code{hkps} (keyserver access over TLS).  If
+the file is in PEM format a suffix of @code{.pem} is expected for
+@var{file}.  This option may be given multiple times to add more
+root certificates.
+
 @end table
 
 
-@c 
+@c
 @c Dirmngr Configuration
 @c
 @mansect files
@@ -472,7 +483,7 @@ Please ignore the output; it is not needed anymore.  Check the log file
 to see whether all trusted root certificates have been loaded correctly.
 
 
-@c 
+@c
 @c Dirmngr Signals
 @c
 @mansect signals
@@ -480,7 +491,7 @@ to see whether all trusted root certificates have been loaded correctly.
 @section Use of signals.
 
 A running @command{dirmngr} may be controlled by signals, i.e. using
-the @command{kill} command to send a signal to the process. 
+the @command{kill} command to send a signal to the process.
 
 Here is a list of supported signals:
 
@@ -522,7 +533,7 @@ This prints some caching statistics to the log file.
 Dirmngr is supposed to be used as a system wide daemon, it should be
 started like:
 
-@example 
+@example
   dirmngr --daemon
 @end example
 
@@ -613,7 +624,7 @@ local lookup will be done in this case.
 
 Check whether the certificate described by the @var{certid} has been
 revoked.  Due to caching, the Dirmngr is able to answer immediately in
-most cases.  
+most cases.
 
 The @var{certid} is a hex encoded string consisting of two parts,
 delimited by a single dot.  The first part is the SHA-1 hash of the
@@ -642,7 +653,7 @@ us that it has been revoked.
 
 @item GPG_ERR_NO_CRL_KNOWN
 No CRL is known for this certificate or the CRL is not valid or out of
-date. 
+date.
 
 @item GPG_ERR_NO_DATA
 The OCSP responder returned an ``unknown'' status.  This means that it
@@ -690,7 +701,7 @@ given or the certificate is not know, the function inquires the
 certificate using:
 
 @example
-  S: INQUIRE TARGETCERT 
+  S: INQUIRE TARGETCERT
   C: D <DER encoded certificate>
   C: END
 @end example
@@ -720,7 +731,7 @@ certificate is not known by Dirmngr, the function inquires the
 certificate using:
 
 @example
-  S: INQUIRE TARGETCERT 
+  S: INQUIRE TARGETCERT
   C: D <DER encoded certificate>
   C: END
 @end example
@@ -751,13 +762,13 @@ helpful for debugging.  To get the actual certificate, this command
 immediately inquires it using
 
 @example
-  S: INQUIRE TARGETCERT 
+  S: INQUIRE TARGETCERT
   C: D <DER encoded certificate>
   C: END
 @end example
 
 Thus the caller is expected to return the certificate for the request
-as a binary blob. 
+as a binary blob.
 
 @noindent
 The return code is 0 for success; i.e. the certificate has not been
@@ -771,45 +782,45 @@ internally by dirmngr.  This command is only useful for debugging.  To
 get the actual certificate, this command immediately inquires it using
 
 @example
-  S: INQUIRE TARGETCERT 
+  S: INQUIRE TARGETCERT
   C: D <DER encoded certificate>
   C: END
 @end example
 
 Thus the caller is expected to return the certificate for the request
-as a binary blob. 
+as a binary blob.
 
 
 @mansect see also
 @ifset isman
-@command{gpgsm}(1), 
+@command{gpgsm}(1),
 @command{dirmngr-client}(1)
 @end ifset
 @include see-also-note.texi
 
-@c 
+@c
 @c !!! UNDER CONSTRUCTION !!!
-@c 
-@c 
+@c
+@c
 @c @section Verifying a Certificate
-@c 
+@c
 @c There are several ways to request services from Dirmngr.  Almost all of
 @c them are done using the Assuan protocol.  What we describe here is the
 @c Assuan command CHECKCRL as used for example by the dirmnr-client tool if
 @c invoked as
-@c 
+@c
 @c @example
 @c   dirmngr-client foo.crt
 @c @end example
-@c 
+@c
 @c This command will send an Assuan request to an already running Dirmngr
 @c instance.  foo.crt is expected to be a standard X.509 certificate and
 @c dirmngr will receive the Assuan command
-@c 
+@c
 @c @example
 @c    CHECKCRL @var [{fingerprint}]
 @c @end example
-@c 
+@c
 @c @var{fingerprint} is optional and expected to be the SHA-1 has of the
 @c DER encoding of the certificate under question.  It is to be HEX
 @c encoded.  The rationale for sending the fingerprint is that it allows
@@ -817,15 +828,15 @@ as a binary blob.
 @c this is not the case and no certificate has been found in dirmngr's
 @c internal certificate storage, dirmngr will request the certificate using
 @c the Assuan inquiry
-@c 
+@c
 @c @example
 @c       INQUIRE TARGETCERT
 @c @end example
-@c 
+@c
 @c The caller (in our example dirmngr-client) is then expected to return
 @c the certificate for the request (which should match @var{fingerprint})
 @c as a binary blob.
-@c 
+@c
 @c Dirmngr now passes control to @code{crl_cache_cert_isvalid}.  This
 @c function checks whether a CRL item exists for target certificate.  These
 @c CRL items are kept in a database of already loaded and verified CRLs.
@@ -837,25 +848,25 @@ as a binary blob.
 @c listed in the CRL or @code{GPG_ERR_NO_CRL_KNOWN} in cases where no CRL or no
 @c information is available.  The first two codes are immediatly returned to
 @c the caller and the processing of this request has been done.
-@c 
+@c
 @c Only the @code{GPG_ERR_NO_CRL_KNOWN} needs more attention: Dirmngr now
 @c calls @code{clr_cache_reload_crl} and if this succeeds calls
 @c @code{crl_cache_cert_isvald) once more.  All further errors are
 @c immediately returned to the caller.
-@c 
+@c
 @c @code{crl_cache_reload_crl} is the actual heart of the CRL management.
 @c It locates the corresponding CRL for the target certificate, reads and
 @c verifies this CRL and stores it in the CRL cache.  It works like this:
-@c 
+@c
 @c * Loop over all crlDPs in the target certificate.
 @c     * If the crlDP is invalid immediately terminate the loop.
 @c     * Loop over all names in the current crlDP.
-@c         * If the URL scheme is unknown or not enabled 
+@c         * If the URL scheme is unknown or not enabled
 @c           (--ignore-http-dp, --ignore-ldap-dp) continues with
 @c           the next name.
 @c         * @code{crl_fetch} is called to actually retrieve the CRL.
 @c           In case of problems this name is ignore and we continue with
-@c           the next name.  Note that @code{crl_fetch} does only return 
+@c           the next name.  Note that @code{crl_fetch} does only return
 @c           a descriptor for the CRL for further reading so does the CRL
 @c           does not yet end up in memory.
 @c         * @code{crl_cache_insert} is called with that descriptor to
@@ -873,16 +884,16 @@ as a binary blob.
 @c     * @code(crl_cache_insert) is then used to actually insert the CRL
 @c       into the cache.  If this failed we give up immediatley without
 @c       checking the rest of the servers from the first step.
-@c * Ready. 
-@c 
-@c 
+@c * Ready.
+@c
+@c
 @c The @code{crl_cache_insert} function takes care of reading the bulk of
 @c the CRL, parsing it and checking the signature.  It works like this: A
 @c new database file is created using a temporary file name.  The CRL
 @c parsing machinery is started and all items of the CRL are put into
 @c this database file.  At the end the issuer certificate of the CRL
 @c needs to be retrieved.  Three cases are to be distinguished:
-@c 
+@c
 @c  a) An authorityKeyIdentifier with an issuer and serialno exits: The
 @c     certificate is retrieved using @code{find_cert_bysn}.  If
 @c     the certificate is in the certificate cache, it is directly
@@ -899,7 +910,7 @@ as a binary blob.
 @c     certificate to match the requested issuer and seriano (This is
 @c     needed because the LDAP layer may return several certificates as
 @c     LDAP as no standard way to retrieve by serial number).
-@c 
+@c
 @c  b) An authorityKeyIdentifier with a key ID exists: The certificate is
 @c     retrieved using @code{find_cert_bysubject}.  If the certificate is
 @c     in the certificate cache, it is directly returned.  Then the
@@ -913,7 +924,7 @@ as a binary blob.
 @c     external resources.  This is done using the @code{ca_cert_fetch}
 @c     and @code{fetch_next_ksba_cert} and comparing the returned
 @c     certificate to match the requested subject and key ID.
-@c 
+@c
 @c  c) No authorityKeyIdentifier exits: The certificate is retrieved
 @c     using @code{find_cert_bysubject} without the key ID argument.  If
 @c     the certificate is in the certificate cache the first one with a
@@ -930,12 +941,12 @@ as a binary blob.
 @c     and @code{fetch_next_ksba_cert} and comparing the returned
 @c     certificate to match the requested subject; the first certificate
 @c     with a matching subject is then returned.
-@c 
+@c
 @c If no certificate was found, the function returns with the error
 @c GPG_ERR_MISSING_CERT.  Now the signature is verified.  If this fails,
 @c the erro is returned.  On success the @code{validate_cert_chain} is
-@c used to verify that the certificate is actually valid. 
-@c 
+@c used to verify that the certificate is actually valid.
+@c
 @c Here we may encounter a recursive situation:
 @c @code{validate_cert_chain} needs to look at other certificates and
 @c also at CRLs to check whether tehse other certificates and well, the
@@ -944,7 +955,7 @@ as a binary blob.
 @c are currently processing. This would be a catch-22 and may indicate a
 @c broken PKI.  However, due to overlapping expiring times and imprecise
 @c clocks thsi may actually happen.
-@c     
+@c
 @c For historical reasons the Assuan command ISVALID is a bit different
 @c to CHECKCRL but this is mainly due to different calling conventions.
 @c In the end the same fucntionality is used, albeit hidden by a couple
@@ -952,44 +963,44 @@ as a binary blob.
 @c ingetrages OCSP checking depending on options are the way it is
 @c called.  GPGSM still uses this command but might eventuall switch over
 @c to CHECKCRL and CHECKOCSP so that ISVALID can be retired.
-@c   
-@c 
+@c
+@c
 @c @section Validating a certificate
-@c 
+@c
 @c We describe here how the internal function @code{validate_cert_chain}
 @c works. Note that mainly testing purposes this functionality may be
 @c called directly using @cmd{dirmngr-client --validate @file{foo.crt}}.
-@c 
+@c
 @c For backward compatibility this function returns success if Dirmngr is
 @c not used as a system daemon.  Thus not validating the certicates at
 @c all. FIXME:  This is definitely not correct and should be fixed ASAP.
-@c 
+@c
 @c The function takes the target certificate and a mode argument as
 @c parameters and returns an error code and optionally the closes
 @c expiration time of all certificates in the chain.
-@c 
+@c
 @c We first check that the certificate may be used for the requested
 @c purpose (i.e. OCSP or CRL signing).  If this is not the case
 @c GPG_ERR_WRONG_KEY_USAGE is returned.
-@c 
+@c
 @c The next step is to find the trust anchor (root certificate) and to
 @c assemble the chain in memory: Starting with the target certificate,
 @c the expiration time is checked against the current date, unknown
 @c critical extensions are detected and certificate policies are matched
 @c (We only allow 2.289.9.9 but I have no clue about that OID and from
 @c where I got it - it does not even seem to be assigned - debug cruft?).
-@c 
+@c
 @c Now if this certificate is a self-signed one, we have reached the
 @c trust anchor.  In this case we check that the signature is good, the
 @c certificate is allowed to act as a CA, that it is a trusted one (by
 @c checking whether it is has been put into the trusted-certs
 @c configuration directory) and finally prepend into to our list
 @c representing the certificate chain.  This steps ends then.
-@c 
+@c
 @c If it is not a self-signed certificate, we check that the chain won't
 @c get too long (current limit is 100), if this is the case we terminate
 @c with the error GPG_ERR_BAD_CERT_CHAIN.
-@c 
+@c
 @c Now the issuer's certificate is looked up: If an
 @c authorityKeyIdentifier is available, this one is used to locate the
 @c certificate either using issuer and serialnumber or subject DN
@@ -1002,7 +1013,7 @@ as a binary blob.
 @c that a matching certificate has explicitly been put into the
 @c certificate cache.  If the issuer's certificate could not be found,
 @c the validation terminates with the error code @code{GPG_ERR_MISSING_CERT}.
-@c 
+@c
 @c If the issuer's certificate has been found, the signature of the
 @c actual certificate is checked and in case this fails the error
 @c #code{GPG_ERR_BAD_CERT_CHAIN} is returned.  If the signature checks out, the
@@ -1011,13 +1022,13 @@ as a binary blob.
 @c certificate signing).  Then the certificate is prepended to our list
 @c representing the certificate chain.  Finally the loop is continued now
 @c with the issuer's certificate as the current certificate.
-@c 
+@c
 @c After the end of the loop and if no error as been encountered
 @c (i.e. the certificate chain has been assempled correctly), a check is
 @c done whether any certificate expired or a critical policy has not been
 @c met.  In any of these cases the validation terminates with an
-@c appropriate error. 
-@c 
+@c appropriate error.
+@c
 @c Finally the function @code{check_revocations} is called to verify no
 @c certificate in the assempled chain has been revoked: This is an
 @c recursive process because a CRL has to be checked for each certificate
@@ -1025,16 +1036,16 @@ as a binary blob.
 @c that it is trusted and we avoid checking a CRL here due to common
 @c setup problems and the assumption that a revoked root certifcate has
 @c been removed from the list of trusted certificates.
-@c 
-@c 
-@c 
-@c 
+@c
+@c
+@c
+@c
 @c @section Looking up certificates through LDAP.
-@c 
+@c
 @c This describes the LDAP layer to retrieve certificates.
 @c the functions @code{ca_cert_fetch} and @code{fetch_next_ksba_cert} are
 @c used for this.  The first one starts a search and the second one is
 @c used to retrieve certificate after certificate.
-@c 
+@c
+
 
-  
index 1a81010..bc12cbc 100644 (file)
@@ -1630,16 +1630,29 @@ are available for all keyserver types, some common options are:
   program uses internally (libcurl, openldap, etc).
 
   @item check-cert
+@ifset gpgtwoone
+  This option has no more function since GnuPG 2.1.  Use the
+  @code{dirmngr} configuration options instead.
+@end ifset
+@ifclear gpgtwoone
   Enable certificate checking if the keyserver presents one (for hkps or
   ldaps).  Defaults to on.
+@end ifclear
 
   @item ca-cert-file
+@ifset gpgtwoone
+  This option has no more function since GnuPG 2.1.  Use the
+  @code{dirmngr} configuration options instead.
+@end ifset
+@ifclear gpgtwoone
   Provide a certificate store to override the system default.  Only
   necessary if check-cert is enabled, and the keyserver is using a
   certificate that is not present in a system default certificate list.
 
   Note that depending on the SSL library that the keyserver helper is
   built with, this may actually be a directory or a file.
+@end ifclear
+
 @end table
 
 @item --completes-needed @code{n}