sm: Fix certificate lookup in dirmngr cache.
[gnupg.git] / sm / sign.c
index 2ab8b42..08eebb7 100644 (file)
--- a/sm/sign.c
+++ b/sm/sign.c
@@ -1,5 +1,6 @@
 /* sign.c - Sign a message
- *     Copyright (C) 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003, 2008,
+ *               2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -22,7 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <unistd.h> 
+#include <unistd.h>
 #include <time.h>
 #include <assert.h>
 
 static int
 hash_data (int fd, gcry_md_hd_t md)
 {
-  FILE *fp;
+  estream_t fp;
   char buffer[4096];
   int nread;
   int rc = 0;
 
-  fp = fdopen ( dup (fd), "rb");
+  fp = es_fdopen_nc (fd, "rb");
   if (!fp)
     {
       log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
       return -1;
     }
 
-  do 
+  do
     {
-      nread = fread (buffer, 1, DIM(buffer), fp);
+      nread = es_fread (buffer, 1, DIM(buffer), fp);
       gcry_md_write (md, buffer, nread);
     }
   while (nread);
-  if (ferror (fp))
+  if (es_ferror (fp))
     {
       log_error ("read error on fd %d: %s\n", fd, strerror (errno));
       rc = -1;
     }
-  fclose (fp);
+  es_fclose (fp);
   return rc;
 }
 
+
 static int
 hash_and_copy_data (int fd, gcry_md_hd_t md, ksba_writer_t writer)
 {
   gpg_error_t err;
-  FILE *fp;
+  estream_t fp;
   char buffer[4096];
   int nread;
   int rc = 0;
   int any = 0;
 
-  fp = fdopen ( dup (fd), "rb");
+  fp = es_fdopen_nc (fd, "rb");
   if (!fp)
     {
-      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
+      gpg_error_t tmperr = gpg_error_from_syserror ();
       log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
       return tmperr;
     }
 
-  do 
+  do
     {
-      nread = fread (buffer, 1, DIM(buffer), fp);
+      nread = es_fread (buffer, 1, DIM(buffer), fp);
       if (nread)
         {
           any = 1;
@@ -99,18 +101,18 @@ hash_and_copy_data (int fd, gcry_md_hd_t md, ksba_writer_t writer)
         }
     }
   while (nread && !rc);
-  if (ferror (fp))
+  if (es_ferror (fp))
     {
-      rc = gpg_error (gpg_err_code_from_errno (errno));
+      rc = gpg_error_from_syserror ();
       log_error ("read error on fd %d: %s\n", fd, strerror (errno));
     }
-  fclose (fp);
+  es_fclose (fp);
   if (!any)
     {
       /* We can't allow to sign an empty message because it does not
-         make much sense and more seriously, ksba-cms_build has
+         make much sense and more seriously, ksba_cms_build has
          already written the tag for data and now expects an octet
-         string but an octet string of zeize 0 is illegal. */
+         string and an octet string of size 0 is illegal.  */
       log_error ("cannot sign an empty message\n");
       rc = gpg_error (GPG_ERR_NO_DATA);
     }
@@ -152,7 +154,7 @@ gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert)
   do
     {
       rc = keydb_get_cert (hd, &cert);
-      if (rc) 
+      if (rc)
         {
           log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
           keydb_release (hd);
@@ -175,13 +177,13 @@ gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert)
             }
         }
 
-      ksba_cert_release (cert); 
+      ksba_cert_release (cert);
       cert = NULL;
     }
   while (!(rc = keydb_search_next (hd)));
   if (rc && rc != -1)
     log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
-  
+
   ksba_cert_release (cert);
   keydb_release (hd);
   return rc;
@@ -209,7 +211,7 @@ get_default_signer (ctrl_t ctrl)
       return cert;
     }
 
-  rc = classify_user_id (opt.local_user, &desc);
+  rc = classify_user_id (opt.local_user, &desc, 0);
   if (rc)
     {
       log_error ("failed to find default signer: %s\n", gpg_strerror (rc));
@@ -225,7 +227,7 @@ get_default_signer (ctrl_t ctrl)
     {
       log_debug ("failed to find default certificate: rc=%d\n", rc);
     }
-  else 
+  else
     {
       rc = keydb_get_cert (kh, &cert);
       if (rc)
@@ -241,7 +243,7 @@ get_default_signer (ctrl_t ctrl)
 /* Depending on the options in CTRL add the certificate CERT as well as
    other certificate up in the chain to the Root-CA to the CMS
    object. */
-static int 
+static int
 add_certificate_list (ctrl_t ctrl, ksba_cms_t cms, ksba_cert_t cert)
 {
   gpg_error_t err;
@@ -302,7 +304,7 @@ add_certificate_list (ctrl_t ctrl, ksba_cms_t cms, ksba_cert_t cert)
 
 
 \f
-/* Perform a sign operation.  
+/* Perform a sign operation.
 
    Sign the data received on DATA-FD in embedded mode or in detached
    mode when DETACHED is true.  Write the signature to OUT_FP.  The
@@ -310,7 +312,7 @@ add_certificate_list (ctrl_t ctrl, ksba_cms_t cms, ksba_cert_t cert)
    be used if the value of this argument is NULL. */
 int
 gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
-            int data_fd, int detached, FILE *out_fp)
+            int data_fd, int detached, estream_t out_fp)
 {
   int i, rc;
   gpg_error_t err;
@@ -332,13 +334,13 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
   kh = keydb_new (0);
   if (!kh)
     {
-      log_error (_("failed to allocated keyDB handle\n"));
+      log_error (_("failed to allocate keyDB handle\n"));
       rc = gpg_error (GPG_ERR_GENERAL);
       goto leave;
     }
 
   ctrl->pem_name = "SIGNED MESSAGE";
-  rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, NULL, &writer);
+  rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
   if (rc)
     {
       log_error ("can't create writer: %s\n", gpg_strerror (rc));
@@ -380,7 +382,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
       if (!cert)
         {
           log_error ("no default signer found\n");
-          gpgsm_status2 (ctrl, STATUS_INV_SGNR, 
+          gpgsm_status2 (ctrl, STATUS_INV_SGNR,
                          get_inv_recpsgnr_code (GPG_ERR_NO_SECKEY), NULL);
           rc = gpg_error (GPG_ERR_GENERAL);
           goto leave;
@@ -396,7 +398,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
           char *tmpfpr;
 
           tmpfpr = gpgsm_get_fingerprint_hexstring (cert, 0);
-          gpgsm_status2 (ctrl, STATUS_INV_SGNR, 
+          gpgsm_status2 (ctrl, STATUS_INV_SGNR,
                          get_inv_recpsgnr_code (rc), tmpfpr, NULL);
           xfree (tmpfpr);
           goto leave;
@@ -442,13 +444,13 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
         case GCRY_MD_SHA384: oid = "2.16.840.1.101.3.4.2.2"; break;
         case GCRY_MD_SHA512: oid = "2.16.840.1.101.3.4.2.3"; break;
 /*         case GCRY_MD_WHIRLPOOL: oid = "No OID yet"; break; */
-              
+
         case GCRY_MD_MD5:  /* We don't want to use MD5.  */
         case 0:            /* No algorithm found in cert.  */
         default:           /* Other algorithms.  */
           log_info (_("hash algorithm %d (%s) for signer %d not supported;"
                       " using %s\n"),
-                    cl->hash_algo, oid? oid: "?", i, 
+                    cl->hash_algo, oid? oid: "?", i,
                     gcry_md_algo_name (GCRY_MD_SHA1));
           cl->hash_algo = GCRY_MD_SHA1;
           oid = "1.3.14.3.2.26";
@@ -460,7 +462,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
   if (opt.verbose)
     {
       for (i=0, cl=signerlist; cl; cl = cl->next, i++)
-        log_info (_("hash algorithm used for signer %d: %s (%s)\n"), 
+        log_info (_("hash algorithm used for signer %d: %s (%s)\n"),
                   i, gcry_md_algo_name (cl->hash_algo), cl->hash_algo_oid);
     }
 
@@ -471,7 +473,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
       rc = gpgsm_cert_use_sign_p (cl->cert);
       if (rc)
         goto leave;
-      
+
       err = ksba_cms_add_signer (cms, cl->cert);
       if (err)
         {
@@ -501,31 +503,34 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
   /* Check whether one of the certificates is qualified.  Note that we
      already validated the certificate and thus the user data stored
      flag must be available. */
-  for (cl=signerlist; cl; cl = cl->next)
+  if (!opt.no_chain_validation)
     {
-      size_t buflen;
-      char buffer[1];
-      
-      err = ksba_cert_get_user_data (cl->cert, "is_qualified", 
-                                     &buffer, sizeof (buffer), &buflen);
-      if (err || !buflen)
+      for (cl=signerlist; cl; cl = cl->next)
         {
-          log_error (_("checking for qualified certificate failed: %s\n"),
-                     gpg_strerror (err)); 
-          rc = err;
-          goto leave;
-        }
-      if (*buffer)
-        err = gpgsm_qualified_consent (ctrl, cl->cert);
-      else
-        err = gpgsm_not_qualified_warning (ctrl, cl->cert);
-      if (err)
-        {
-          rc = err;
-          goto leave;
+          size_t buflen;
+          char buffer[1];
+
+          err = ksba_cert_get_user_data (cl->cert, "is_qualified",
+                                         &buffer, sizeof (buffer), &buflen);
+          if (err || !buflen)
+            {
+              log_error (_("checking for qualified certificate failed: %s\n"),
+                         gpg_strerror (err));
+              rc = err;
+              goto leave;
+            }
+          if (*buffer)
+            err = gpgsm_qualified_consent (ctrl, cl->cert);
+          else
+            err = gpgsm_not_qualified_warning (ctrl, cl->cert);
+          if (err)
+            {
+              rc = err;
+              goto leave;
+            }
         }
     }
-  
+
   /* Prepare hashing (actually we are figuring out what we have set
      above). */
   rc = gcry_md_open (&data_md, 0, 0);
@@ -535,14 +540,14 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
       goto leave;
     }
   if (DBG_HASHING)
-    gcry_md_start_debug (data_md, "sign.data");
+    gcry_md_debug (data_md, "sign.data");
 
   for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++)
     {
       algo = gcry_md_map_name (algoid);
       if (!algo)
         {
-          log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
+          log_error ("unknown hash algorithm '%s'\n", algoid? algoid:"?");
           rc = gpg_error (GPG_ERR_BUG);
           goto leave;
         }
@@ -614,7 +619,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
 
 
   /* Main building loop. */
-  do 
+  do
     {
       err = ksba_cms_build (cms, &stopreason);
       if (err)
@@ -625,7 +630,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
         }
 
       if (stopreason == KSBA_SR_BEGIN_DATA)
-        { 
+        {
           /* Hash the data and store the message digest. */
           unsigned char *digest;
           size_t digest_len;
@@ -658,7 +663,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
             }
         }
       else if (stopreason == KSBA_SR_NEED_SIG)
-        { 
+        {
           /* Compute the signature for all signers.  */
           gcry_md_hd_t md;
 
@@ -669,7 +674,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
               goto leave;
             }
           if (DBG_HASHING)
-            gcry_md_start_debug (md, "sign.attr");
+            gcry_md_debug (md, "sign.attr");
           ksba_cms_set_hash_function (cms, HASH_FNC, md);
           for (cl=signerlist,signer=0; cl; cl = cl->next, signer++)
             {
@@ -685,7 +690,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
                 for (cl_tmp=signerlist; cl_tmp; cl_tmp = cl_tmp->next)
                   {
                     gcry_md_enable (md, cl_tmp->hash_algo);
-                    audit_log_i (ctrl->audit, AUDIT_ATTR_HASH_ALGO, 
+                    audit_log_i (ctrl->audit, AUDIT_ATTR_HASH_ALGO,
                                  cl_tmp->hash_algo);
                   }
               }
@@ -698,7 +703,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
                   gcry_md_close (md);
                   goto leave;
                 }
-            
+
               rc = gpgsm_create_cms_signature (ctrl, cl->cert,
                                                md, cl->hash_algo, &sigval);
               if (rc)
@@ -733,8 +738,8 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
                 int pkalgo = gpgsm_get_key_algo_info (cl->cert, NULL);
                 buf = xtryasprintf ("%c %d %d 00 %s %s",
                                     detached? 'D':'S',
-                                    pkalgo, 
-                                    cl->hash_algo, 
+                                    pkalgo,
+                                    cl->hash_algo,
                                     signed_at,
                                     fpr);
                 if (!buf)
@@ -753,10 +758,10 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
           gcry_md_close (md);
         }
     }
-  while (stopreason != KSBA_SR_READY);   
+  while (stopreason != KSBA_SR_READY);
 
   rc = gpgsm_finish_writer (b64writer);
-  if (rc) 
+  if (rc)
     {
       log_error ("write failed: %s\n", gpg_strerror (rc));
       goto leave;
@@ -774,7 +779,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
     gpgsm_release_certlist (signerlist);
   ksba_cms_release (cms);
   gpgsm_destroy_writer (b64writer);
-  keydb_release (kh); 
+  keydb_release (kh);
   gcry_md_close (data_md);
   return rc;
 }