gpg: Remove all assert.h and s/assert/log_assert/.
[gnupg.git] / g10 / mainproc.c
index c90b9e3..d56790b 100644 (file)
@@ -22,7 +22,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <assert.h>
 #include <time.h>
 
 #include "gpg.h"
@@ -106,7 +105,7 @@ struct mainproc_context
 
 
 /*** Local prototypes.  ***/
-static int do_proc_packets (CTX c, iobuf_t a);
+static int do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a);
 static void list_node (CTX c, kbnode_t node);
 static void proc_tree (CTX c, kbnode_t node);
 static int literals_seen;
@@ -366,7 +365,7 @@ proc_symkey_enc (CTX c, PACKET *pkt)
 
 
 static void
-proc_pubkey_enc (CTX c, PACKET *pkt)
+proc_pubkey_enc (ctrl_t ctrl, CTX c, PACKET *pkt)
 {
   PKT_pubkey_enc *enc;
   int result = 0;
@@ -387,7 +386,7 @@ proc_pubkey_enc (CTX c, PACKET *pkt)
          to the Libgcrypt defined one.  This is due a chicken-egg
          problem: We need to have code in Libgcrypt for a new
          algorithm so to implement a proposed new algorithm before the
-         IANA will finally assign an OpenPGP indentifier.  */
+         IANA will finally assign an OpenPGP identifier.  */
       snprintf (buf, sizeof buf, "%08lX%08lX %d 0",
                (ulong)enc->keyid[0], (ulong)enc->keyid[1], enc->pubkey_algo);
       write_status_text (STATUS_ENC_TO, buf);
@@ -428,7 +427,7 @@ proc_pubkey_enc (CTX c, PACKET *pkt)
           else
             {
               c->dek = xmalloc_secure_clear (sizeof *c->dek);
-              if ((result = get_session_key (enc, c->dek)))
+              if ((result = get_session_key (ctrl, enc, c->dek)))
                 {
                   /* Error: Delete the DEK. */
                   xfree (c->dek);
@@ -607,6 +606,22 @@ proc_encrypted (CTX c, PACKET *pkt)
 
   if (result == -1)
     ;
+  else if (!result
+           && !opt.ignore_mdc_error
+           && !pkt->pkt.encrypted->mdc_method
+           && openpgp_cipher_get_algo_blklen (c->dek->algo) != 8
+           && c->dek->algo != CIPHER_ALGO_TWOFISH)
+    {
+      /* The message has been decrypted but has no MDC despite that a
+         modern cipher (blocklength != 64 bit, except for Twofish) is
+         used and the option to ignore MDC errors is not used: To
+         avoid attacks changing an MDC message to a non-MDC message,
+         we fail here.  */
+      log_error (_("WARNING: message was not integrity protected\n"));
+      if (opt.verbose > 1)
+        log_info ("decryption forced to fail\n");
+      write_status (STATUS_DECRYPTION_FAILED);
+    }
   else if (!result || (gpg_err_code (result) == GPG_ERR_BAD_SIGNATURE
                        && opt.ignore_mdc_error))
     {
@@ -630,8 +645,9 @@ proc_encrypted (CTX c, PACKET *pkt)
       if (gpg_err_code (result) == GPG_ERR_BAD_KEY
           && *c->dek->s2k_cacheid != '\0')
         {
-          log_debug (_("cleared passphrase cached with ID: %s\n"),
-                     c->dek->s2k_cacheid);
+          if (opt.debug)
+            log_debug ("cleared passphrase cached with ID: %s\n",
+                       c->dek->s2k_cacheid);
           passphrase_clear_cache (NULL, c->dek->s2k_cacheid, 0);
         }
       glo_ctrl.lasterr = result;
@@ -835,9 +851,10 @@ do_check_sig (CTX c, kbnode_t node, int *is_selfsig,
   PKT_signature *sig;
   gcry_md_hd_t md = NULL;
   gcry_md_hd_t md2 = NULL;
+  gcry_md_hd_t md_good = NULL;
   int algo, rc;
 
-  assert (node->pkt->pkttype == PKT_SIGNATURE);
+  log_assert (node->pkt->pkttype == PKT_SIGNATURE);
   if (is_selfsig)
     *is_selfsig = 0;
   sig = node->pkt->pkt.signature;
@@ -856,7 +873,7 @@ do_check_sig (CTX c, kbnode_t node, int *is_selfsig,
         }
       else /* detached signature */
         {
-          /* signature_check() will enable the md. */
+          /* check_signature() will enable the md. */
           if (gcry_md_open (&md, 0, 0 ))
             BUG ();
         }
@@ -875,7 +892,7 @@ do_check_sig (CTX c, kbnode_t node, int *is_selfsig,
       else /* detached signature */
         {
           log_debug ("Do we really need this here?");
-          /* signature_check() will enable the md*/
+          /* check_signature() will enable the md*/
           if (gcry_md_open (&md, 0, 0 ))
             BUG ();
           if (gcry_md_open (&md2, 0, 0 ))
@@ -909,9 +926,24 @@ do_check_sig (CTX c, kbnode_t node, int *is_selfsig,
   else
     return GPG_ERR_SIG_CLASS;
 
-  rc = signature_check2 (sig, md, NULL, is_expkey, is_revkey, NULL);
-  if (gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE && md2)
-    rc = signature_check2 (sig, md2, NULL, is_expkey, is_revkey, NULL);
+  /* We only get here if we are checking the signature of a binary
+     (0x00) or text document (0x01).  */
+  rc = check_signature2 (sig, md, NULL, is_expkey, is_revkey, NULL);
+  if (! rc)
+    md_good = md;
+  else if (gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE && md2)
+    {
+      rc = check_signature2 (sig, md2, NULL, is_expkey, is_revkey, NULL);
+      if (! rc)
+       md_good = md2;
+    }
+
+  if (md_good)
+    {
+      unsigned char *buffer = gcry_md_read (md_good, 0);
+      sig->digest_len = gcry_md_get_algo_dlen (map_md_openpgp_to_gcry (algo));
+      memcpy (sig->digest, buffer, sig->digest_len);
+    }
 
   gcry_md_close (md);
   gcry_md_close (md2);
@@ -1031,7 +1063,9 @@ list_node (CTX c, kbnode_t node)
                     es_printf ("%s:::::::::",
                                node->pkt->pkt.user_id->attrib_data?"uat":"uid");
                   else
-                    es_printf ("uid%*s", 28, "" );
+                    es_printf ("uid%*s",
+                               (int)keystrlen ()+(opt.legacy_list_mode? 9:11),
+                               "" );
                   print_userid (node->pkt);
                   if (opt.with_colons)
                     es_putc (':', es_stdout);
@@ -1057,7 +1091,7 @@ list_node (CTX c, kbnode_t node)
     {
 
       log_debug ("FIXME: No way to print secret key packets here\n");
-      /* fixme: We may use a fucntion to turn a secret key packet into
+      /* fixme: We may use a function to turn a secret key packet into
          a public key one and use that here.  */
     }
   else if (node->pkt->pkttype == PKT_SIGNATURE)
@@ -1161,7 +1195,7 @@ proc_packets (ctrl_t ctrl, void *anchor, iobuf_t a )
 
   c->ctrl = ctrl;
   c->anchor = anchor;
-  rc = do_proc_packets (c, a);
+  rc = do_proc_packets (ctrl, c, a);
   xfree (c);
 
   return rc;
@@ -1184,7 +1218,7 @@ proc_signature_packets (ctrl_t ctrl, void *anchor, iobuf_t a,
   c->signed_data.used = !!signedfiles;
 
   c->sigfilename = sigfilename;
-  rc = do_proc_packets ( c, a );
+  rc = do_proc_packets (ctrl, c, a);
 
   /* If we have not encountered any signature we print an error
      messages, send a NODATA status back and return an error code.
@@ -1227,7 +1261,7 @@ proc_signature_packets_by_fd (ctrl_t ctrl,
   c->signed_data.data_names = NULL;
   c->signed_data.used = (signed_data_fd != -1);
 
-  rc = do_proc_packets ( c, a );
+  rc = do_proc_packets (ctrl, c, a);
 
   /* If we have not encountered any signature we print an error
      messages, send a NODATA status back and return an error code.
@@ -1260,7 +1294,7 @@ proc_encryption_packets (ctrl_t ctrl, void *anchor, iobuf_t a )
   c->ctrl = ctrl;
   c->anchor = anchor;
   c->encrypt_only = 1;
-  rc = do_proc_packets (c, a);
+  rc = do_proc_packets (ctrl, c, a);
   xfree (c);
   return rc;
 }
@@ -1286,7 +1320,7 @@ check_nesting (CTX c)
 
 
 static int
-do_proc_packets (CTX c, iobuf_t a)
+do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a)
 {
   PACKET *pkt;
   int rc = 0;
@@ -1318,7 +1352,7 @@ do_proc_packets (CTX c, iobuf_t a)
         {
           switch (pkt->pkttype)
             {
-            case PKT_PUBKEY_ENC:    proc_pubkey_enc (c, pkt); break;
+            case PKT_PUBKEY_ENC:    proc_pubkey_enc (ctrl, c, pkt); break;
             case PKT_SYMKEY_ENC:    proc_symkey_enc (c, pkt); break;
             case PKT_ENCRYPTED:
             case PKT_ENCRYPTED_MDC: proc_encrypted (c, pkt); break;
@@ -1362,7 +1396,7 @@ do_proc_packets (CTX c, iobuf_t a)
 
             case PKT_SIGNATURE:   newpkt = add_signature (c, pkt); break;
             case PKT_SYMKEY_ENC:  proc_symkey_enc (c, pkt); break;
-            case PKT_PUBKEY_ENC:  proc_pubkey_enc (c, pkt); break;
+            case PKT_PUBKEY_ENC:  proc_pubkey_enc (ctrl, c, pkt); break;
             case PKT_ENCRYPTED:
             case PKT_ENCRYPTED_MDC: proc_encrypted (c, pkt); break;
             case PKT_PLAINTEXT:   proc_plaintext (c, pkt); break;
@@ -1388,7 +1422,7 @@ do_proc_packets (CTX c, iobuf_t a)
               break;
             case PKT_USER_ID:     newpkt = add_user_id (c, pkt); break;
             case PKT_SIGNATURE:   newpkt = add_signature (c, pkt); break;
-            case PKT_PUBKEY_ENC:  proc_pubkey_enc (c, pkt); break;
+            case PKT_PUBKEY_ENC:  proc_pubkey_enc (ctrl, c, pkt); break;
             case PKT_SYMKEY_ENC:  proc_symkey_enc (c, pkt); break;
             case PKT_ENCRYPTED:
             case PKT_ENCRYPTED_MDC: proc_encrypted (c, pkt); break;
@@ -1408,7 +1442,7 @@ do_proc_packets (CTX c, iobuf_t a)
        * I used it.  Adding the MDC check here is a hack.
        * The right solution is to initiate another context for encrypted
        * packet and not to reuse the current one ...  It works right
-       * when there is a compression packet inbetween which adds just
+       * when there is a compression packet between which adds just
        * an extra layer.
        * Hmmm: Rewrite this whole module here??
        */
@@ -1488,7 +1522,7 @@ pka_uri_from_sig (CTX c, PKT_signature *sig)
 {
   if (!sig->flags.pka_tried)
     {
-      assert (!sig->pka_info);
+      log_assert (!sig->pka_info);
       sig->flags.pka_tried = 1;
       sig->pka_info = get_pka_address (sig);
       if (sig->pka_info)
@@ -1602,7 +1636,7 @@ check_sig_and_print (CTX c, kbnode_t node)
 /*     dump_kbnode (c->list); */
 
     n = c->list;
-    assert (n);
+    log_assert (n);
     if ( n->pkt->pkttype == PKT_SIGNATURE )
       {
         /* This is either "S{1,n}" case (detached signature) or
@@ -1768,8 +1802,8 @@ check_sig_and_print (CTX c, kbnode_t node)
        no information from the DNS PKA, this is a third try. */
 
   if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
-      && opt.keyserver
-      && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE))
+      && (opt.keyserver_options.options&KEYSERVER_AUTO_KEY_RETRIEVE)
+      && keyserver_any_configured (c->ctrl))
     {
       int res;
 
@@ -1804,7 +1838,8 @@ check_sig_and_print (CTX c, kbnode_t node)
       snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX [uncertain] ",
                 (ulong)sig->keyid[0], (ulong)sig->keyid[1]);
 
-      /* Find and print the primary user ID.  */
+      /* Find and print the primary user ID along with the
+         "Good|Expired|Bad signature" line.  */
       for (un=keyblock; un; un = un->next)
         {
           int valid;
@@ -1828,11 +1863,17 @@ check_sig_and_print (CTX c, kbnode_t node)
           if (un->pkt->pkt.user_id->attrib_data)
             continue;
 
-          assert (pk);
+          log_assert (pk);
 
-          /* Get it before we print anything to avoid interrupting the
-             output with the "please do a --check-trustdb" line. */
-          valid = get_validity (pk, un->pkt->pkt.user_id);
+         /* Since this is just informational, don't actually ask the
+            user to update any trust information.  (Note: we register
+            the signature later.)  Because print_good_bad_signature
+            does not print a LF we need to compute the validity
+            before calling that function.  */
+          if ((opt.verify_options & VERIFY_SHOW_UID_VALIDITY))
+            valid = get_validity (pk, un->pkt->pkt.user_id, NULL, 0);
+          else
+            valid = 0; /* Not used.  */
 
           keyid_str[17] = 0; /* cut off the "[uncertain]" part */
 
@@ -1843,11 +1884,17 @@ check_sig_and_print (CTX c, kbnode_t node)
           else
             log_printf ("\n");
 
+          /* Get a string description of the algo for informational
+             output we want to print later.  It is convenient to do it
+             here because we already have the right public key. */
           pubkey_string (pk, pkstrbuf, sizeof pkstrbuf);
           count++;
        }
 
-      if (!count)  /* Just in case that we have no valid textual userid */
+      /* In case we did not found a valid valid textual userid above
+         we print the first user id packet or a "[?]" instead along
+         with the "Good|Expired|Bad signature" line.  */
+      if (!count)
         {
           /* Try for an invalid textual userid */
           for (un=keyblock; un; un = un->next)
@@ -1892,11 +1939,12 @@ check_sig_and_print (CTX c, kbnode_t node)
                    || un->pkt->pkt.user_id->is_expired)
                   && !(opt.verify_options & VERIFY_SHOW_UNUSABLE_UIDS))
                 continue;
-              /* Only skip textual primaries */
+              /* Skip textual primary user ids which we printed above. */
               if (un->pkt->pkt.user_id->is_primary
                   && !un->pkt->pkt.user_id->attrib_data )
                 continue;
 
+              /* If this user id has attribute data, print that.  */
               if (un->pkt->pkt.user_id->attrib_data)
                 {
                   dump_attribs (un->pkt->pkt.user_id, pk);
@@ -1921,8 +1969,11 @@ check_sig_and_print (CTX c, kbnode_t node)
                   else if (un->pkt->pkt.user_id->is_expired)
                     valid = _("expired");
                   else
+                   /* Since this is just informational, don't
+                      actually ask the user to update any trust
+                      information.  */
                     valid = (trust_value_to_string
-                             (get_validity (pk, un->pkt->pkt.user_id)));
+                             (get_validity (pk, un->pkt->pkt.user_id, sig, 0)));
                   log_printf (" [%s]\n",valid);
                 }
               else
@@ -1931,6 +1982,7 @@ check_sig_and_print (CTX c, kbnode_t node)
        }
       release_kbnode( keyblock );
 
+      /* For good signatures print notation data.  */
       if (!rc)
         {
           if ((opt.verify_options & VERIFY_SHOW_POLICY_URLS))
@@ -1952,9 +2004,9 @@ check_sig_and_print (CTX c, kbnode_t node)
             show_notation (sig, 0, 2, 0);
         }
 
+      /* For good signatures print the VALIDSIG status line.  */
       if (!rc && is_status_enabled ())
         {
-          /* Print a status response with the fingerprint. */
           PKT_public_key *vpk = xmalloc_clear (sizeof *vpk);
 
           if (!get_pubkey (vpk, sig->keyid))
@@ -2002,6 +2054,9 @@ check_sig_and_print (CTX c, kbnode_t node)
           free_public_key (vpk);
        }
 
+      /* For good signatures compute and print the trust information.
+         Note that in the Tofu trust model this may ask the user on
+         how to resolve a conflict.  */
       if (!rc)
         {
           if ((opt.verify_options & VERIFY_PKA_LOOKUPS))
@@ -2009,6 +2064,7 @@ check_sig_and_print (CTX c, kbnode_t node)
           rc = check_signatures_trust (sig);
         }
 
+      /* Print extra information about the signature.  */
       if (sig->flags.expired)
         {
           log_info (_("Signature expired %s\n"), asctimestamp(sig->expiredate));
@@ -2025,6 +2081,7 @@ check_sig_and_print (CTX c, kbnode_t node)
                   *pkstrbuf?_(", key algorithm "):"",
                   pkstrbuf);
 
+      /* Print final warnings.  */
       if (!rc && !c->signed_data.used)
         {
           /* Signature is basically good but we test whether the