gpgtar: Improve error messages.
[gnupg.git] / sm / sign.c
index 0f83db6..24ecad3 100644 (file)
--- a/sm/sign.c
+++ b/sm/sign.c
@@ -15,7 +15,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
@@ -32,7 +32,7 @@
 #include <ksba.h>
 
 #include "keydb.h"
-#include "i18n.h"
+#include "../common/i18n.h"
 
 
 /* Hash the data and return if something was hashed.  Return -1 on error.  */
@@ -109,7 +109,7 @@ hash_and_copy_data (int fd, gcry_md_hd_t md, ksba_writer_t writer)
   es_fclose (fp);
   if (!any)
     {
-      /* We can't allow to sign an empty message because it does not
+      /* We can't allow signing an empty message because it does not
          make much sense and more seriously, ksba_cms_build has
          already written the tag for data and now expects an octet
          string and an octet string of size 0 is illegal.  */
@@ -141,10 +141,10 @@ gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert)
   int rc;
   char *p;
 
-  hd = keydb_new (0);
+  hd = keydb_new ();
   if (!hd)
     return gpg_error (GPG_ERR_GENERAL);
-  rc = keydb_search_first (hd);
+  rc = keydb_search_first (ctrl, hd);
   if (rc)
     {
       keydb_release (hd);
@@ -180,7 +180,7 @@ gpgsm_get_default_cert (ctrl_t ctrl, ksba_cert_t *r_cert)
       ksba_cert_release (cert);
       cert = NULL;
     }
-  while (!(rc = keydb_search_next (hd)));
+  while (!(rc = keydb_search_next (ctrl, hd)));
   if (rc && rc != -1)
     log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
 
@@ -211,18 +211,18 @@ 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));
       return NULL;
     }
 
-  kh = keydb_new (0);
+  kh = keydb_new ();
   if (!kh)
     return NULL;
 
-  rc = keydb_search (kh, &desc, 1);
+  rc = keydb_search (ctrl, kh, &desc, 1);
   if (rc)
     {
       log_debug ("failed to find default certificate: rc=%d\n", rc);
@@ -316,7 +316,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
 {
   int i, rc;
   gpg_error_t err;
-  Base64Context b64writer = NULL;
+  gnupg_ksba_io_t b64writer = NULL;
   ksba_writer_t writer;
   ksba_cms_t cms = NULL;
   ksba_stop_reason_t stopreason;
@@ -331,16 +331,30 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
 
   audit_set_type (ctrl->audit, AUDIT_TYPE_SIGN);
 
-  kh = keydb_new (0);
+  kh = keydb_new ();
   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;
     }
 
+  if (!gnupg_rng_is_compliant (opt.compliance))
+    {
+      rc = gpg_error (GPG_ERR_FORBIDDEN);
+      log_error (_("%s is not compliant with %s mode\n"),
+                 "RNG",
+                 gnupg_compliance_option_string (opt.compliance));
+      gpgsm_status_with_error (ctrl, STATUS_ERROR,
+                               "random-compliance", rc);
+      goto leave;
+    }
+
   ctrl->pem_name = "SIGNED MESSAGE";
-  rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
+  rc = gnupg_ksba_create_writer
+    (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0)
+                  | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)),
+     ctrl->pem_name, out_fp, &writer);
   if (rc)
     {
       log_error ("can't create writer: %s\n", gpg_strerror (rc));
@@ -388,7 +402,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
           goto leave;
         }
 
-      /* Although we don't check for ambigious specification we will
+      /* Although we don't check for ambiguous specification we will
          check that the signer's certificate is usable and valid.  */
       rc = gpgsm_cert_use_sign_p (cert);
       if (!rc)
@@ -457,6 +471,35 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
           break;
         }
       cl->hash_algo_oid = oid;
+
+      /* Check compliance.  */
+      if (! gnupg_digest_is_allowed (opt.compliance, 1, cl->hash_algo))
+        {
+          log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
+                     gcry_md_algo_name (cl->hash_algo),
+                     gnupg_compliance_option_string (opt.compliance));
+          err = gpg_error (GPG_ERR_DIGEST_ALGO);
+          goto leave;
+        }
+
+      {
+        unsigned int nbits;
+        int pk_algo = gpgsm_get_key_algo_info (cl->cert, &nbits);
+
+        if (! gnupg_pk_is_allowed (opt.compliance, PK_USE_SIGNING, pk_algo,
+                                   NULL, nbits, NULL))
+          {
+            char  kidstr[10+1];
+
+            snprintf (kidstr, sizeof kidstr, "0x%08lX",
+                      gpgsm_get_short_fingerprint (cl->cert, NULL));
+            log_error (_("key %s may not be used for signing in %s mode\n"),
+                       kidstr,
+                       gnupg_compliance_option_string (opt.compliance));
+            err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+            goto leave;
+          }
+      }
     }
 
   if (opt.verbose)
@@ -540,14 +583,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;
         }
@@ -674,7 +717,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++)
             {
@@ -760,7 +803,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
     }
   while (stopreason != KSBA_SR_READY);
 
-  rc = gpgsm_finish_writer (b64writer);
+  rc = gnupg_ksba_finish_writer (b64writer);
   if (rc)
     {
       log_error ("write failed: %s\n", gpg_strerror (rc));
@@ -778,7 +821,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
   if (release_signerlist)
     gpgsm_release_certlist (signerlist);
   ksba_cms_release (cms);
-  gpgsm_destroy_writer (b64writer);
+  gnupg_ksba_destroy_writer (b64writer);
   keydb_release (kh);
   gcry_md_close (data_md);
   return rc;