Revert commit 4654384fe7a4dcee113dacf27c398b13dea5d0be.
[gnupg.git] / g10 / pkclist.c
index e783ae4..d7e78cb 100644 (file)
@@ -37,6 +37,7 @@
 #include "status.h"
 #include "photoid.h"
 #include "i18n.h"
+#include "tofu.h"
 
 #define CONTROL_D ('D' - 'A' + 1)
 
@@ -112,7 +113,7 @@ do_show_revocation_reason( PKT_signature *sig )
 void
 show_revocation_reason( PKT_public_key *pk, int mode )
 {
-    /* Hmmm, this is not so easy becuase we have to duplicate the code
+    /* Hmmm, this is not so easy because we have to duplicate the code
      * used in the trustbd to calculate the keyflags.  We need to find
      * a clean way to check revocation certificates on keys and
      * signatures.  And there should be no duplicate code.  Because we
@@ -127,7 +128,7 @@ show_revocation_reason( PKT_public_key *pk, int mode )
 
     /* get the keyblock */
     fingerprint_from_pk( pk, fingerprint, &fingerlen );
-    rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
+    rc = get_pubkey_byfprint(NULL, &keyblock, fingerprint, fingerlen);
     if( rc ) { /* that should never happen */
        log_debug( "failed to get the keyblock\n");
        return;
@@ -507,20 +508,20 @@ do_we_trust_pre( PKT_public_key *pk, unsigned int trustlevel )
 
 /****************
  * Check whether we can trust this signature.
- * Returns: Error if we shall not trust this signatures.
+ * Returns an error code if we should not trust this signature.
  */
 int
 check_signatures_trust( PKT_signature *sig )
 {
   PKT_public_key *pk = xmalloc_clear( sizeof *pk );
-  unsigned int trustlevel;
+  unsigned int trustlevel = TRUST_UNKNOWN;
   int rc=0;
 
   rc = get_pubkey( pk, sig->keyid );
   if (rc)
     { /* this should not happen */
       log_error("Ooops; the key vanished  - can't check the trust\n");
-      rc = G10ERR_NO_PUBKEY;
+      rc = GPG_ERR_NO_PUBKEY;
       goto leave;
     }
 
@@ -537,7 +538,7 @@ check_signatures_trust( PKT_signature *sig )
     log_info(_("WARNING: this key might be revoked (revocation key"
               " not present)\n"));
 
-  trustlevel = get_validity (pk, NULL);
+  trustlevel = get_validity (pk, NULL, sig, 1);
 
   if ( (trustlevel & TRUST_FLAG_REVOKED) )
     {
@@ -701,7 +702,7 @@ key_present_in_pk_list(PK_LIST pk_list, PKT_public_key *pk)
  * Return a malloced string with a default recipient if there is any
  */
 static char *
-default_recipient(void)
+default_recipient(ctrl_t ctrl)
 {
     PKT_public_key *pk;
     byte fpr[MAX_FINGERPRINT_LEN+1];
@@ -714,7 +715,7 @@ default_recipient(void)
     if( !opt.def_recipient_self )
        return NULL;
     pk = xmalloc_clear( sizeof *pk );
-    i = get_seckey_byname (pk, NULL);
+    i = get_seckey_default (ctrl, pk);
     if( i ) {
        free_public_key( pk );
        return NULL;
@@ -805,7 +806,7 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
       int code;
 
       /* Key not found or other error. */
-      log_error (_("%s: skipped: %s\n"), name, g10_errstr(rc) );
+      log_error (_("%s: skipped: %s\n"), name, gpg_strerror (rc) );
       switch (gpg_err_code (rc))
         {
         case GPG_ERR_NO_SECKEY:
@@ -823,20 +824,20 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
     {
       /* Key found but not usable for us (e.g. sign-only key). */
       send_status_inv_recp (3, name); /* Wrong key usage */
-      log_error (_("%s: skipped: %s\n"), name, g10_errstr(rc) );
+      log_error (_("%s: skipped: %s\n"), name, gpg_strerror (rc) );
       free_public_key (pk);
       return rc;
     }
 
   /* Key found and usable.  Check validity. */
-  trustlevel = get_validity (pk, pk->user_id);
+  trustlevel = get_validity (pk, pk->user_id, NULL, 1);
   if ( (trustlevel & TRUST_FLAG_DISABLED) )
     {
       /* Key has been disabled. */
       send_status_inv_recp (13, name);
       log_info (_("%s: skipped: public key is disabled\n"), name);
       free_public_key (pk);
-      return G10ERR_UNU_PUBKEY;
+      return GPG_ERR_UNUSABLE_PUBKEY;
     }
 
   if ( !do_we_trust_pre (pk, trustlevel) )
@@ -844,7 +845,7 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
       /* We don't trust this key.  */
       send_status_inv_recp (10, name);
       free_public_key (pk);
-      return G10ERR_UNU_PUBKEY;
+      return GPG_ERR_UNUSABLE_PUBKEY;
     }
   /* Note: do_we_trust may have changed the trustlevel. */
 
@@ -889,18 +890,15 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use,
    value but not very useful.  Group expansion is done on these names;
    they may be in any of the user Id formats we can handle.  The flags
    bits for each string in the string list are used for:
-     Bit 0: This is an encrypt-to recipient.
-     Bit 1: This is a hidden recipient.
-
-   USE is the desired use for the key - usually PUBKEY_USAGE_ENC.
+     Bit 0 (PK_LIST_ENCRYPT_TO): This is an encrypt-to recipient.
+     Bit 1 (PK_LIST_HIDDEN)    : This is a hidden recipient.
 
    On success a list of keys is stored at the address RET_PK_LIST; the
    caller must free this list.  On error the value at this address is
    not changed.
  */
 int
-build_pk_list (ctrl_t ctrl,
-               strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
+build_pk_list (ctrl_t ctrl, strlist_t rcpts, PK_LIST *ret_pk_list)
 {
   PK_LIST pk_list = NULL;
   PKT_public_key *pk=NULL;
@@ -916,11 +914,65 @@ build_pk_list (ctrl_t ctrl,
   else
     remusr = rcpts;
 
+  /* XXX: Change this function to use get_pubkeys instead of
+     get_pubkey_byname to detect ambiguous key specifications and warn
+     about duplicate keyblocks.  For ambiguous key specifications on
+     the command line or provided interactively, prompt the user to
+     select the best key.  If a key specification is ambiguous and we
+     are in batch mode, die.  */
+
+  if (opt.encrypt_to_default_key)
+    {
+      static int warned;
+
+      const char *default_key = parse_def_secret_key (ctrl);
+      if (default_key)
+        {
+          PK_LIST r = xmalloc_clear (sizeof *r);
+
+          r->pk = xmalloc_clear (sizeof *r->pk);
+          r->pk->req_usage = PUBKEY_USAGE_ENC;
+
+          rc = get_pubkey_byname (ctrl, NULL, r->pk, default_key,
+                                   NULL, NULL, 0, 1);
+          if (rc)
+            {
+              xfree (r->pk);
+              xfree (r);
+
+              log_error (_("Can't encrypt to '%s'.\n"), default_key);
+              if (!opt.quiet)
+                log_info (_("(check argument of option '%s')\n"),
+                          "--default-key");
+            }
+          else
+            {
+              r->next = pk_list;
+              r->flags = 0;
+              pk_list = r;
+            }
+        }
+      else if (opt.def_secret_key)
+        {
+          if (! warned)
+            log_info (_("option '%s' given, but no valid default keys given\n"),
+                      "--encrypt-to-default-key");
+          warned = 1;
+        }
+      else
+        {
+          if (! warned)
+            log_info (_("option '%s' given, but option '%s' not given\n"),
+                      "--encrypt-to-default-key", "--default-key");
+          warned = 1;
+        }
+    }
+
   /* Check whether there are any recipients in the list and build the
    * list of the encrypt-to ones (we always trust them). */
   for ( rov = remusr; rov; rov = rov->next )
     {
-      if ( !(rov->flags & 1) )
+      if ( !(rov->flags & PK_LIST_ENCRYPT_TO) )
         {
           /* This is a regular recipient; i.e. not an encrypt-to
              one. */
@@ -928,7 +980,7 @@ build_pk_list (ctrl_t ctrl,
 
           /* Hidden recipients are not allowed while in PGP mode,
              issue a warning and switch into GnuPG mode. */
-          if ((rov->flags&2) && (PGP2 || PGP6 || PGP7 || PGP8))
+          if ((rov->flags & PK_LIST_HIDDEN) && (PGP6 || PGP7 || PGP8))
             {
               log_info(_("you may not use %s while in %s mode\n"),
                        "--hidden-recipient",
@@ -937,12 +989,12 @@ build_pk_list (ctrl_t ctrl,
               compliance_failure();
             }
         }
-      else if ( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to )
+      else if (!opt.no_encrypt_to)
         {
-          /* Encryption has been requested and --encrypt-to has not
-             been disabled.  Check this encrypt-to key. */
+          /* --encrypt-to has not been disabled.  Check this
+             encrypt-to key. */
           pk = xmalloc_clear( sizeof *pk );
-          pk->req_usage = use;
+          pk->req_usage = PUBKEY_USAGE_ENC;
 
           /* We explicitly allow encrypt-to to an disabled key; thus
              we pass 1 for the second last argument and 1 as the last
@@ -951,11 +1003,12 @@ build_pk_list (ctrl_t ctrl,
                                         NULL, pk, rov->d, NULL, NULL, 1, 1)) )
             {
               free_public_key ( pk ); pk = NULL;
-              log_error (_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
+              log_error (_("%s: skipped: %s\n"), rov->d, gpg_strerror (rc) );
               send_status_inv_recp (0, rov->d);
               goto fail;
             }
-          else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) )
+          else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo,
+                                                PUBKEY_USAGE_ENC)) )
             {
               /* Skip the actual key if the key is already present
                * in the list.  Add it to our list if not. */
@@ -972,13 +1025,13 @@ build_pk_list (ctrl_t ctrl,
                   r = xmalloc( sizeof *r );
                   r->pk = pk; pk = NULL;
                   r->next = pk_list;
-                  r->flags = (rov->flags&2)?1:0;
+                  r->flags = (rov->flags&PK_LIST_HIDDEN)?1:0;
                   pk_list = r;
 
                   /* Hidden encrypt-to recipients are not allowed while
                      in PGP mode, issue a warning and switch into
                      GnuPG mode. */
-                  if ((r->flags&1) && (PGP2 || PGP6 || PGP7 || PGP8))
+                  if ((r->flags&PK_LIST_ENCRYPT_TO) && (PGP6 || PGP7 || PGP8))
                     {
                       log_info(_("you may not use %s while in %s mode\n"),
                                "--hidden-encrypt-to",
@@ -992,7 +1045,7 @@ build_pk_list (ctrl_t ctrl,
             {
               /* The public key is not usable for encryption. */
               free_public_key( pk ); pk = NULL;
-              log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
+              log_error(_("%s: skipped: %s\n"), rov->d, gpg_strerror (rc) );
               send_status_inv_recp (3, rov->d); /* Wrong key usage */
               goto fail;
             }
@@ -1009,7 +1062,7 @@ build_pk_list (ctrl_t ctrl,
 
       if (pk_list)
         any_recipients = 1;
-      def_rec = default_recipient();
+      def_rec = default_recipient(ctrl);
       have_def_rec = !!def_rec;
       if ( !have_def_rec )
         tty_printf(_("You did not specify a user ID. (you may use \"-r\")\n"));
@@ -1075,7 +1128,7 @@ build_pk_list (ctrl_t ctrl,
             }
 
           /* Do group expand here too.  The trick here is to continue
-             the loop if any expansion occured.  The code above will
+             the loop if any expansion occurred.  The code above will
              then list all expanded keys. */
           if (expand_id(answer,&backlog,0))
             continue;
@@ -1083,11 +1136,12 @@ build_pk_list (ctrl_t ctrl,
           /* Get and check key for the current name. */
           free_public_key (pk);
           pk = xmalloc_clear( sizeof *pk );
-          pk->req_usage = use;
+          pk->req_usage = PUBKEY_USAGE_ENC;
           rc = get_pubkey_byname (ctrl, NULL, pk, answer, NULL, NULL, 0, 0 );
           if (rc)
             tty_printf(_("No such user ID.\n"));
-          else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) )
+          else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo,
+                                                PUBKEY_USAGE_ENC)) )
             {
               if ( have_def_rec )
                 {
@@ -1114,7 +1168,7 @@ build_pk_list (ctrl_t ctrl,
                 { /* Check validity of this key. */
                   int trustlevel;
 
-                  trustlevel = get_validity (pk, pk->user_id);
+                  trustlevel = get_validity (pk, pk->user_id, NULL, 1);
                   if ( (trustlevel & TRUST_FLAG_DISABLED) )
                     {
                       tty_printf (_("Public key is disabled.\n") );
@@ -1152,18 +1206,19 @@ build_pk_list (ctrl_t ctrl,
           pk = NULL;
         }
     }
-  else if ( !any_recipients && (def_rec = default_recipient()) )
+  else if ( !any_recipients && (def_rec = default_recipient(ctrl)) )
     {
       /* We are in batch mode and have only a default recipient. */
       pk = xmalloc_clear( sizeof *pk );
-      pk->req_usage = use;
+      pk->req_usage = PUBKEY_USAGE_ENC;
 
       /* The default recipient is allowed to be disabled; thus pass 1
          as second last argument.  We also don't want an AKL. */
       rc = get_pubkey_byname (ctrl, NULL, pk, def_rec, NULL, NULL, 1, 1);
       if (rc)
         log_error(_("unknown default recipient \"%s\"\n"), def_rec );
-      else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use)) )
+      else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo,
+                                           PUBKEY_USAGE_ENC)) )
         {
           /* Mark any_recipients here since the default recipient
              would have been used if it wasn't already there.  It
@@ -1195,10 +1250,11 @@ build_pk_list (ctrl_t ctrl,
       any_recipients = 0;
       for (; remusr; remusr = remusr->next )
         {
-          if ( (remusr->flags & 1) )
+          if ( (remusr->flags & PK_LIST_ENCRYPT_TO) )
             continue; /* encrypt-to keys are already handled. */
 
-          rc = find_and_check_key (ctrl, remusr->d, use, !!(remusr->flags&2),
+          rc = find_and_check_key (ctrl, remusr->d, PUBKEY_USAGE_ENC,
+                                   !!(remusr->flags&PK_LIST_HIDDEN),
                                    &pk_list);
           if (rc)
             goto fail;
@@ -1210,7 +1266,7 @@ build_pk_list (ctrl_t ctrl,
     {
       log_error(_("no valid addressees\n"));
       write_status_text (STATUS_NO_RECP, "0");
-      rc = G10ERR_NO_USER_ID;
+      rc = GPG_ERR_NO_USER_ID;
     }
 
  fail:
@@ -1344,10 +1400,7 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype,
             dropped from 4880 but is still relevant to GPG's 1991
             support.  All this doesn't mean IDEA is actually
             available, of course. */
-         if(PGP2 && pkr->pk->version<4 && pkr->pk->selfsigversion<4)
-           implicit=CIPHER_ALGO_IDEA;
-         else
-           implicit=CIPHER_ALGO_3DES;
+          implicit=CIPHER_ALGO_3DES;
 
          break;
 
@@ -1359,12 +1412,7 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype,
             mode, and that's the only time PREFTYPE_HASH is used
             anyway. -dms */
 
-         /* MD5 is there for v3 keys with v3 selfsigs when --pgp2 is
-            on. */
-         if(PGP2 && pkr->pk->version<4 && pkr->pk->selfsigversion<4)
-           implicit=DIGEST_ALGO_MD5;
-         else
-           implicit=DIGEST_ALGO_SHA1;
+          implicit=DIGEST_ALGO_SHA1;
 
          break;