Help dirmngr to use supplied trust anchors.
authorWerner Koch <wk@gnupg.org>
Tue, 21 Oct 2008 15:03:51 +0000 (15:03 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 21 Oct 2008 15:03:51 +0000 (15:03 +0000)
sm/ChangeLog
sm/call-agent.c
sm/call-dirmngr.c
sm/certchain.c
sm/gpgsm.h
sm/keylist.c

index 2404c72..2c178ca 100644 (file)
@@ -1,3 +1,12 @@
+2008-10-21  Werner Koch  <wk@g10code.com>
+
+       * call-dirmngr.c (inq_certificate_parm_s): Add field CTRL.
+       (gpgsm_dirmngr_isvalid): Supply a value for that field.
+       (inq_certificate): Add inquiry ISTRUSTED.
+
+       * call-agent.c (gpgsm_agent_istrusted): Add new optional arg
+       HEXFPR.  Changed all callers.
+
 2008-10-20  Werner Koch  <wk@g10code.com>
 
        * keydb.c (keydb_locate_writable): Mark unused arg.
index bca44d2..0add44a 100644 (file)
@@ -560,31 +560,45 @@ istrusted_status_cb (void *opaque, const char *line)
 
 
 /* Ask the agent whether the certificate is in the list of trusted
-   keys.  ROOTCA_FLAGS is guaranteed to be cleared on error. */
+   keys.  The certificate is either specified by the CERT object or by
+   the fingerprint HEXFPR.  ROOTCA_FLAGS is guaranteed to be cleared
+   on error. */
 int
-gpgsm_agent_istrusted (ctrl_t ctrl, ksba_cert_t cert,
+gpgsm_agent_istrusted (ctrl_t ctrl, ksba_cert_t cert, const char *hexfpr,
                        struct rootca_flags_s *rootca_flags)
 {
   int rc;
-  char *fpr;
   char line[ASSUAN_LINELENGTH];
 
   memset (rootca_flags, 0, sizeof *rootca_flags);
 
+  if (cert && hexfpr)
+    return gpg_error (GPG_ERR_INV_ARG);
+
   rc = start_agent (ctrl);
   if (rc)
     return rc;
 
-  fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
-  if (!fpr)
+  if (hexfpr)
     {
-      log_error ("error getting the fingerprint\n");
-      return gpg_error (GPG_ERR_GENERAL);
+      snprintf (line, DIM(line)-1, "ISTRUSTED %s", hexfpr);
+      line[DIM(line)-1] = 0;
     }
+  else
+    {
+      char *fpr;
 
-  snprintf (line, DIM(line)-1, "ISTRUSTED %s", fpr);
-  line[DIM(line)-1] = 0;
-  xfree (fpr);
+      fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
+      if (!fpr)
+        {
+          log_error ("error getting the fingerprint\n");
+          return gpg_error (GPG_ERR_GENERAL);
+        }
+      
+      snprintf (line, DIM(line)-1, "ISTRUSTED %s", fpr);
+      line[DIM(line)-1] = 0;
+      xfree (fpr);
+    }
 
   rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
                         istrusted_status_cb, rootca_flags);
index 20017dd..914fdd0 100644 (file)
@@ -55,6 +55,7 @@ static int dirmngr2_ctx_locked;
 static int force_pipe_server = 0;
 
 struct inq_certificate_parm_s {
+  ctrl_t ctrl;
   assuan_context_t ctx;
   ksba_cert_t cert;
   ksba_cert_t issuer_cert;
@@ -408,6 +409,33 @@ inq_certificate (void *opaque, const char *line)
       line += 14;
       issuer_mode = 1;
     }
+  else if (!strncmp (line, "ISTRUSTED", 9) && (line[9]==' ' || !line[9]))
+    {
+      /* The server is asking us whether the certificate is a trusted
+         root certificate.  */
+      const char *s;
+      size_t n;
+      char fpr[41];
+      struct rootca_flags_s rootca_flags;
+
+      line += 9;
+      while (*line == ' ')
+        line++;
+
+      for (s=line,n=0; hexdigitp (s); s++, n++)
+        ;
+      if (*s || n != 40)
+        return gpg_error (GPG_ERR_ASS_PARAMETER);
+      for (s=line, n=0; n < 40; s++, n++)
+        fpr[n] = (*s >= 'a')? (*s & 0xdf): *s;
+      fpr[n] = 0;
+      
+      if (!gpgsm_agent_istrusted (parm->ctrl, NULL, fpr, &rootca_flags))
+        rc = assuan_send_data (parm->ctx, "1", 1);
+      else
+        rc = 0;
+      return rc;
+    }
   else
     {
       log_error ("unsupported inquiry `%s'\n", line);
@@ -555,6 +583,7 @@ gpgsm_dirmngr_isvalid (ctrl_t ctrl,
     }
 
   parm.ctx = dirmngr_ctx;
+  parm.ctrl = ctrl;
   parm.cert = cert;
   parm.issuer_cert = issuer_cert;
 
index 2d81dbf..fbff7c0 100644 (file)
@@ -1284,7 +1284,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
              We used to do this only later but changed it to call the
              check right here so that we can access special flags
              associated with that specific root certificate.  */
-          istrusted_rc = gpgsm_agent_istrusted (ctrl, subject_cert,
+          istrusted_rc = gpgsm_agent_istrusted (ctrl, subject_cert, NULL,
                                                 rootca_flags);
           audit_log_cert (ctrl->audit, AUDIT_ROOT_TRUSTED,
                           subject_cert, istrusted_rc);
@@ -1565,7 +1565,7 @@ do_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t checktime_arg,
                performance reasons. */
             if (is_root)
               {
-                istrusted_rc = gpgsm_agent_istrusted (ctrl, issuer_cert,
+                istrusted_rc = gpgsm_agent_istrusted (ctrl, issuer_cert, NULL,
                                                       rootca_flags);
                 if (!istrusted_rc && rootca_flags->relax)
                   {
index 278c6e5..0ee557f 100644 (file)
@@ -386,7 +386,7 @@ int gpgsm_agent_genkey (ctrl_t ctrl,
                         ksba_const_sexp_t keyparms, ksba_sexp_t *r_pubkey);
 int gpgsm_agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip,
                          ksba_sexp_t *r_pubkey);
-int gpgsm_agent_istrusted (ctrl_t ctrl, ksba_cert_t cert,
+int gpgsm_agent_istrusted (ctrl_t ctrl, ksba_cert_t cert, const char *hexfpr,
                            struct rootca_flags_s *rootca_flags);
 int gpgsm_agent_havekey (ctrl_t ctrl, const char *hexkeygrip);
 int gpgsm_agent_marktrusted (ctrl_t ctrl, ksba_cert_t cert);
index 2af4749..1e77bfc 100644 (file)
@@ -429,7 +429,7 @@ list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
     {
       struct rootca_flags_s dummy_flags;
 
-      rc = gpgsm_agent_istrusted (ctrl, cert, &dummy_flags);
+      rc = gpgsm_agent_istrusted (ctrl, cert, NULL, &dummy_flags);
       if (!rc)
         *truststring = 'u';  /* Yes, we trust this one (ultimately). */
       else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)