Make public key data structure easier to read.
authorWerner Koch <wk@gnupg.org>
Wed, 20 Oct 2010 11:33:50 +0000 (11:33 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 20 Oct 2010 11:33:50 +0000 (11:33 +0000)
Check vor v1 card while signing.

18 files changed:
g10/ChangeLog
g10/free-packet.c
g10/getkey.c
g10/kbnode.c
g10/keyedit.c
g10/keyid.c
g10/keylist.c
g10/keyserver.c
g10/mainproc.c
g10/misc.c
g10/packet.h
g10/parse-packet.c
g10/pkclist.c
g10/pubkey-enc.c
g10/seckey-cert.c
g10/sig-check.c
g10/sign.c
g10/trustdb.c

index d9c4f12..d475d6e 100644 (file)
@@ -1,3 +1,28 @@
+2010-10-20  Werner Koch  <wk@g10code.com>
+
+       * packet.h (PKT_public_key): s/mdc_feature/flags.mdc/.  Change all
+       users.
+       (PKT_public_key): Split is_disabled into flags.disabled_valid and
+       flags.disabled.  Change all users.
+       (pk_is_disabled): Adjust for change.
+       (PKT_public_key): s/is_primary/flags.primary/. Change all users.
+       (PKT_public_key): s/is_revoked/flags.revoked/. Change all users.
+       (PKT_public_key): s/maybe_revoked/flags.maybe_revoked/. Change all
+       users.
+       (PKT_public_key): s/is_valid/flags.valid/. Change all users.
+       (PKT_public_key): s/dont_cache/flags.dont_cache/. Change all users.
+       (PKT_public_key): s/backsig/flags.backsig/. Change all users.
+
+       * sign.c (openpgp_card_v1_p): New.
+       (hash_for): Re-implement test for v1 cards.
+       * packet.h (PKT_public_key): Add field serialno and
+       flags.serialno_valid.
+       * free-packet.c (release_public_key_parts): Free serialno.
+
+       * parse-packet.c (parse_key): Cast -1 to size_t.
+       * trustdb.c (validate_keys): Cast -1 to size_t.  Suggested by
+       Steven M. Schweda.
+
 2010-10-18  Werner Koch  <wk@g10code.com>
 
        * call-agent.c (agent_scd_pksign): Replace sprintf by bin2hex.
index 5c4a0fc..3b18656 100644 (file)
@@ -112,7 +112,11 @@ release_public_key_parts (PKT_public_key *pk)
       pk->revkey=NULL;
       pk->numrevkeys=0;
     }
-
+  if (pk->serialno)
+    {
+      xfree (pk->serialno);
+      pk->serialno = NULL;
+    }
 }
 
 
index ad7e71c..f114920 100644 (file)
@@ -134,7 +134,7 @@ cache_public_key (PKT_public_key * pk)
   if (pk_cache_disabled)
     return;
 
-  if (pk->dont_cache)
+  if (pk->flags.dont_cache)
     return;
 
   if (is_ELGAMAL (pk->pubkey_algo)
@@ -1411,6 +1411,8 @@ sig_to_revoke_info (PKT_signature * sig, struct revoke_info *rinfo)
   rinfo->keyid[1] = sig->keyid[1];
 }
 
+
+/* Note that R_REVOKED may be set to 0, 1 or 2.  */
 static void
 merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
                     struct revoke_info *rinfo)
@@ -1571,7 +1573,7 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
 
       /* Mark that key as valid: One direct key signature should
        * render a key as valid.  */
-      pk->is_valid = 1;
+      pk->flags.valid = 1;
     }
 
   /* Pass 1.5: Look for key revocation signatures that were not made
@@ -1599,7 +1601,7 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
                    break;
                  }
                else if (rc == G10ERR_NO_PUBKEY)
-                 pk->maybe_revoked = 1;
+                 pk->flags.maybe_revoked = 1;
 
                /* A failure here means the sig did not verify, was
                   not issued by a revocation key, or a revocation
@@ -1623,7 +1625,7 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
          if (uidnode && signode)
            {
              fixup_uidnode (uidnode, signode, keytimestamp);
-             pk->is_valid = 1;
+             pk->flags.valid = 1;
            }
          uidnode = k;
          signode = NULL;
@@ -1659,22 +1661,22 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
   if (uidnode && signode)
     {
       fixup_uidnode (uidnode, signode, keytimestamp);
-      pk->is_valid = 1;
+      pk->flags.valid = 1;
     }
 
   /* If the key isn't valid yet, and we have
      --allow-non-selfsigned-uid set, then force it valid. */
-  if (!pk->is_valid && opt.allow_non_selfsigned_uid)
+  if (!pk->flags.valid && opt.allow_non_selfsigned_uid)
     {
       if (opt.verbose)
        log_info (_("Invalid key %s made valid by"
                    " --allow-non-selfsigned-uid\n"), keystr_from_pk (pk));
-      pk->is_valid = 1;
+      pk->flags.valid = 1;
     }
 
   /* The key STILL isn't valid, so try and find an ultimately
      trusted signature. */
-  if (!pk->is_valid)
+  if (!pk->flags.valid)
     {
       uidnode = NULL;
 
@@ -1705,7 +1707,7 @@ merge_selfsigs_main (KBNODE keyblock, int *r_revoked,
                      && get_ownertrust (ultimate_pk) == TRUST_ULTIMATE)
                    {
                      free_public_key (ultimate_pk);
-                     pk->is_valid = 1;
+                     pk->flags.valid = 1;
                      break;
                    }
 
@@ -1942,7 +1944,7 @@ merge_selfsigs_subkey (KBNODE keyblock, KBNODE subnode)
   subpk = subnode->pkt->pkt.public_key;
   keytimestamp = subpk->timestamp;
 
-  subpk->is_valid = 0;
+  subpk->flags.valid = 0;
   subpk->main_keyid[0] = mainpk->main_keyid[0];
   subpk->main_keyid[1] = mainpk->main_keyid[1];
 
@@ -1969,7 +1971,7 @@ merge_selfsigs_subkey (KBNODE keyblock, KBNODE subnode)
                     subkeys rather than re-sign old ones as the
                     problem is in the distribution.  Plus, PGP (7)
                     does this the same way.  */
-                 subpk->is_revoked = 1;
+                 subpk->flags.revoked = 1;
                  sig_to_revoke_info (sig, &subpk->revoked);
                  /* Although we could stop now, we continue to
                   * figure out other information like the old expiration
@@ -2025,10 +2027,10 @@ merge_selfsigs_subkey (KBNODE keyblock, KBNODE subnode)
   if (openpgp_pk_test_algo (subpk->pubkey_algo))
     return;
 
-  subpk->is_valid = 1;
+  subpk->flags.valid = 1;
 
   /* Find the most recent 0x19 embedded signature on our self-sig. */
-  if (subpk->backsig == 0)
+  if (!subpk->flags.backsig)
     {
       int seq = 0;
       size_t n;
@@ -2093,9 +2095,9 @@ merge_selfsigs_subkey (KBNODE keyblock, KBNODE subnode)
 
          /* 2==valid, 1==invalid, 0==didn't check */
          if (check_backsig (mainpk, subpk, backsig) == 0)
-           subpk->backsig = 2;
+           subpk->flags.backsig = 2;
          else
-           subpk->backsig = 1;
+           subpk->flags.backsig = 1;
 
          free_seckey_enc (backsig);
        }
@@ -2123,7 +2125,7 @@ merge_selfsigs (KBNODE keyblock)
   struct revoke_info rinfo;
   PKT_public_key *main_pk;
   prefitem_t *prefs;
-  int mdc_feature;
+  unsigned int mdc_feature;
 
   if (keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
     {
@@ -2151,7 +2153,7 @@ merge_selfsigs (KBNODE keyblock)
     }
 
   main_pk = keyblock->pkt->pkt.public_key;
-  if (revoked || main_pk->has_expired || !main_pk->is_valid)
+  if (revoked || main_pk->has_expired || !main_pk->flags.valid)
     {
       /* If the primary key is revoked, expired, or invalid we
        * better set the appropriate flags on that key and all
@@ -2162,11 +2164,11 @@ merge_selfsigs (KBNODE keyblock)
              || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
            {
              PKT_public_key *pk = k->pkt->pkt.public_key;
-             if (!main_pk->is_valid)
-               pk->is_valid = 0;
-             if (revoked && !pk->is_revoked)
+             if (!main_pk->flags.valid)
+               pk->flags.valid = 0;
+             if (revoked && !pk->flags.revoked)
                {
-                 pk->is_revoked = revoked;
+                 pk->flags.revoked = revoked;
                  memcpy (&pk->revoked, &rinfo, sizeof (rinfo));
                }
              if (main_pk->has_expired)
@@ -2206,7 +2208,7 @@ merge_selfsigs (KBNODE keyblock)
          if (pk->prefs)
            xfree (pk->prefs);
          pk->prefs = copy_prefs (prefs);
-         pk->mdc_feature = mdc_feature;
+         pk->flags.mdc = mdc_feature;
        }
     }
 }
@@ -2313,13 +2315,13 @@ finish_lookup (GETKEY_CTX ctx)
          if (DBG_CACHE)
            log_debug ("\tchecking subkey %08lX\n",
                       (ulong) keyid_from_pk (pk, NULL));
-         if (!pk->is_valid)
+         if (!pk->flags.valid)
            {
              if (DBG_CACHE)
                log_debug ("\tsubkey not valid\n");
              continue;
            }
-         if (pk->is_revoked)
+         if (pk->flags.revoked)
            {
              if (DBG_CACHE)
                log_debug ("\tsubkey has been revoked\n");
@@ -2368,12 +2370,12 @@ finish_lookup (GETKEY_CTX ctx)
       if (DBG_CACHE && !foundk && !req_prim)
        log_debug ("\tno suitable subkeys found - trying primary\n");
       pk = keyblock->pkt->pkt.public_key;
-      if (!pk->is_valid)
+      if (!pk->flags.valid)
        {
          if (DBG_CACHE)
            log_debug ("\tprimary key not valid\n");
        }
-      else if (pk->is_revoked)
+      else if (pk->flags.revoked)
        {
          if (DBG_CACHE)
            log_debug ("\tprimary key has been revoked\n");
index f481c9f..7309af1 100644 (file)
@@ -396,9 +396,9 @@ dump_kbnode (KBNODE node)
                       (ulong)keyid_from_pk( pk, NULL ),
                       pk->pubkey_algo, pk->pubkey_usage,
                       pk->has_expired? 'e':'.',  
-                      pk->is_revoked?  'r':'.',  
-                      pk->is_valid?    'v':'.',
-                      pk->mdc_feature? 'm':'.');
+                      pk->flags.revoked? 'r':'.',  
+                      pk->flags.valid?    'v':'.',
+                      pk->flags.mdc?   'm':'.');
         }
       
       log_flush ();
index 5b4c60a..1686fa6 100644 (file)
@@ -1807,7 +1807,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
          {
            int localsig = 0, nonrevokesig = 0, trustsig = 0, interactive = 0;
 
-           if (pk->is_revoked)
+           if (pk->flags.revoked)
              {
                tty_printf (_("Key is revoked."));
 
@@ -2651,9 +2651,9 @@ show_key_with_all_names_colon (KBNODE keyblock)
 
          fputs (node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub:" : "sub:",
                 stdout);
-         if (!pk->is_valid)
+         if (!pk->flags.valid)
            putchar ('i');
-         else if (pk->is_revoked)
+         else if (pk->flags.revoked)
            putchar ('r');
          else if (pk->has_expired)
            putchar ('e');
@@ -2882,7 +2882,7 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
              primary = pk;
            }
 
-         if (pk->is_revoked)
+         if (pk->flags.revoked)
            {
              char *user = get_user_id_string_native (pk->revoked.keyid);
               tty_printf (_("The following key was revoked on"
@@ -2933,7 +2933,7 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
 
          tty_printf (_("created: %s"), datestr_from_pk (pk));
          tty_printf ("  ");
-         if (pk->is_revoked)
+         if (pk->flags.revoked)
            tty_printf (_("revoked: %s"), revokestr_from_pk (pk));
          else if (pk->has_expired)
            tty_printf (_("expired: %s"), expirestr_from_pk (pk));
@@ -3754,7 +3754,7 @@ menu_backsign (KBNODE pub_keyblock)
        {
          if (node->pkt->pkt.public_key->pubkey_usage & PUBKEY_USAGE_SIG)
            {
-             if (node->pkt->pkt.public_key->backsig)
+             if (node->pkt->pkt.public_key->flags.backsig)
                tty_printf (_
                            ("signing subkey %s is already cross-certified\n"),
                            keystr_from_pk (node->pkt->pkt.public_key));
@@ -5028,7 +5028,7 @@ menu_revkey (KBNODE pub_keyblock)
   PACKET *pkt;
   PKT_signature *sig;
 
-  if (pk->is_revoked)
+  if (pk->flags.revoked)
     {
       tty_printf (_("Key %s is already revoked.\n"), keystr_from_pk (pk));
       return 0;
@@ -5089,7 +5089,7 @@ menu_revsubkey (KBNODE pub_keyblock)
          PKT_public_key *subpk = node->pkt->pkt.public_key;
          struct sign_attrib attrib;
 
-         if (subpk->is_revoked)
+         if (subpk->flags.revoked)
            {
              tty_printf (_("Subkey %s is already revoked.\n"),
                          keystr_from_pk (subpk));
index a11769d..1284287 100644 (file)
@@ -446,6 +446,10 @@ mk_datestr (char *buffer, time_t atime)
 {
   struct tm *tp;
 
+  /* Note: VMS uses an unsigned time_t thus the compiler yields a
+     warning here.  You may ignore this warning or def out this test
+     for VMS.  The proper way to handle this would be a configure test
+     to a detect properly implemented unsigned time_t.  */
   if ( atime < 0 ) /* 32 bit time_t and after 2038-01-19 */
     strcpy (buffer, "????" "-??" "-??"); /* mark this as invalid */
   else 
index e8440f7..de449e0 100644 (file)
@@ -601,7 +601,7 @@ print_capabilities (PKT_public_key *pk, KBNODE keyblock)
   if (use & PUBKEY_USAGE_SIG)
     {
       es_putc ('s', es_stdout);
-      if (pk->is_primary)
+      if (pk->flags.primary)
         {
           es_putc ('c', es_stdout);
           /* The PUBKEY_USAGE_CERT flag was introduced later and we
@@ -631,17 +631,17 @@ print_capabilities (PKT_public_key *pk, KBNODE keyblock)
            {
              pk = k->pkt->pkt.public_key;
 
-             if (pk->is_primary)
+             if (pk->flags.primary)
                disabled = pk_is_disabled (pk);
 
-             if (pk->is_valid && !pk->is_revoked && !pk->has_expired)
+             if (pk->flags.valid && !pk->flags.revoked && !pk->has_expired)
                {
                  if (pk->pubkey_usage & PUBKEY_USAGE_ENC)
                    enc = 1;
                  if (pk->pubkey_usage & PUBKEY_USAGE_SIG)
                    {
                      sign = 1;
-                     if (pk->is_primary)
+                     if (pk->flags.primary)
                        cert = 1;
                    }
                  if (pk->pubkey_usage & PUBKEY_USAGE_CERT)
@@ -805,7 +805,7 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
           nbits_from_pk (pk), pubkey_letter (pk->pubkey_algo),
           keystr_from_pk (pk), datestr_from_pk (pk));
 
-  if (pk->is_revoked)
+  if (pk->flags.revoked)
     {
       es_fprintf (es_stdout, " [");
       es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk));
@@ -895,7 +895,7 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
        {
          PKT_public_key *pk2 = node->pkt->pkt.public_key;
 
-         if ((pk2->is_revoked || pk2->has_expired)
+         if ((pk2->flags.revoked || pk2->has_expired)
              && !(opt.list_options & LIST_SHOW_UNUSABLE_SUBKEYS))
            {
              skip_sigs = 1;
@@ -928,7 +928,7 @@ list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
                   s2k_char,
                  nbits_from_pk (pk2), pubkey_letter (pk2->pubkey_algo),
                  keystr_from_pk (pk2), datestr_from_pk (pk2));
-         if (pk2->is_revoked)
+         if (pk2->flags.revoked)
            {
              es_fprintf (es_stdout, " [");
              es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk2));
@@ -1131,9 +1131,9 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
 
   keyid_from_pk (pk, keyid);
   es_fputs (secret? "sec:":"pub:", es_stdout);
-  if (!pk->is_valid)
+  if (!pk->flags.valid)
     es_putc ('i', es_stdout);
-  else if (pk->is_revoked)
+  else if (pk->flags.revoked)
     es_putc ('r', es_stdout);
   else if (pk->has_expired)
     es_putc ('e', es_stdout);
@@ -1193,7 +1193,7 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
          if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL)
            dump_attribs (node->pkt->pkt.user_id, pk);
          /*
-          * Fixme: We need a is_valid flag here too 
+          * Fixme: We need a valid flag here too 
           */
          str = uid->attrib_data ? "uat" : "uid";
          if (uid->is_revoked)
@@ -1251,9 +1251,9 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
 
          keyid_from_pk (pk2, keyid2);
          es_fputs (secret? "ssb:":"sub:", es_stdout);
-         if (!pk2->is_valid)
+         if (!pk2->flags.valid)
            es_putc ('i', es_stdout);
-         else if (pk2->is_revoked)
+         else if (pk2->flags.revoked)
            es_putc ('r', es_stdout);
          else if (pk2->has_expired)
            es_putc ('e', es_stdout);
index 730c52f..422e62e 100644 (file)
@@ -1282,7 +1282,7 @@ keyserver_spawn (ctrl_t ctrl,
                                  pk->timestamp,
                                  pk->expiredate);
 
-                         if(pk->is_revoked)
+                         if(pk->flags.revoked)
                            fprintf(spawn->tochild,"r");
                          if(pk->has_expired)
                            fprintf(spawn->tochild,"e");
index c2c7aba..72cefce 100644 (file)
@@ -1002,7 +1002,7 @@ list_node( CTX c, KBNODE node )
        else
          {
            /* of subkey */
-           if( pk->is_revoked )
+           if( pk->flags.revoked )
              {
                printf(" [");
                printf(_("revoked: %s"),revokestr_from_pk(pk));
@@ -1930,7 +1930,7 @@ check_sig_and_print( CTX c, KBNODE node )
                        sig->version,sig->pubkey_algo,sig->digest_algo,
                        sig->sig_class);
                 bufp = bufp + strlen (bufp);
-                if (!vpk->is_primary) {
+                if (!vpk->flags.primary) {
                    u32 akid[2];
  
                    akid[0] = vpk->main_keyid[0];
index e3bebdd..cbbba9b 100644 (file)
@@ -657,7 +657,7 @@ pct_expando(const char *string,struct expando_args *args)
 
                if((*(ch+1))=='p' && args->pksk)
                  {
-                   if(args->pksk->is_primary)
+                   if(args->pksk->flags.primary)
                      fingerprint_from_pk (args->pksk, array, &len);
                    else if (args->pksk->main_keyid[0]
                              || args->pksk->main_keyid[1])
index 643cc5b..a1d490e 100644 (file)
@@ -235,48 +235,61 @@ struct seckey_info
  * elements; the extra secret key information are stored in the
  * SECKEY_INFO field.
  */
-typedef struct {
-    u32     timestamp;     /* key made */
-    u32     expiredate;     /* expires at this date or 0 if not at all */
-    u32     max_expiredate; /* must not expire past this date */
-    struct revoke_info revoked;
-    byte    hdrbytes;      /* number of header bytes */
-    byte    version;
-    byte    selfsigversion; /* highest version of all of the self-sigs */
-    byte    pubkey_algo;    /* algorithm used for public key scheme */
-    byte    pubkey_usage;   /* for now only used to pass it to getkey() */
-    byte    req_usage;      /* hack to pass a request to getkey() */
-    byte    req_algo;       /* Ditto */
-    u32     has_expired;    /* set to the expiration date if expired */ 
-    int     is_revoked;     /* key has been revoked, 1 if by the
-                              owner, 2 if by a designated revoker */
-    int     maybe_revoked;  /* a designated revocation is present, but
-                              without the key to check it */
-    int     is_valid;       /* key (especially subkey) is valid */
-    int     dont_cache;     /* do not cache this */
-    byte    backsig;        /* 0=none, 1=bad, 2=good */
-    u32     main_keyid[2];  /* keyid of the primary key */
-    u32     keyid[2];      /* calculated by keyid_from_pk() */
-    byte    is_primary;
-    byte    is_disabled;    /* 0 for unset, 1 for enabled, 2 for disabled. */
-    prefitem_t *prefs;      /* list of preferences (may be NULL) */
-    int     mdc_feature;    /* mdc feature set */
-    PKT_user_id *user_id;   /* if != NULL: found by that uid */
-    struct revocation_key *revkey;
-    int     numrevkeys;
-    u32     trust_timestamp;
-    byte    trust_depth;
-    byte    trust_value;
-    const byte *trust_regexp;
-    struct seckey_info *seckey_info;  /* If not NULL this malloced
-                                         structure describes a secret
-                                         key.  */
-    gcry_mpi_t  pkey[PUBKEY_MAX_NSKEY]; /* Right, NSKEY elements.  */
+typedef struct
+{
+  u32     timestamp;       /* key made */
+  u32     expiredate;     /* expires at this date or 0 if not at all */
+  u32     max_expiredate; /* must not expire past this date */
+  struct revoke_info revoked;
+  byte    hdrbytes;        /* number of header bytes */
+  byte    version;
+  byte    selfsigversion; /* highest version of all of the self-sigs */
+  byte    pubkey_algo;    /* algorithm used for public key scheme */
+  byte    pubkey_usage;   /* for now only used to pass it to getkey() */
+  byte    req_usage;      /* hack to pass a request to getkey() */
+  byte    req_algo;       /* Ditto */
+  u32     has_expired;    /* set to the expiration date if expired */ 
+  u32     main_keyid[2];  /* keyid of the primary key */
+  u32     keyid[2];        /* calculated by keyid_from_pk() */
+  prefitem_t *prefs;      /* list of preferences (may be NULL) */
+  struct
+  {
+    unsigned int mdc:1;           /* MDC feature set.  */
+    unsigned int disabled_valid:1;/* The next flag is valid.  */
+    unsigned int disabled:1;      /* The key has been disabled.  */
+    unsigned int primary:1;       /* This is a primary key.  */ 
+    unsigned int revoked:2;       /* Key has been revoked.
+                                     1 = revoked by the owner
+                                     2 = revoked by designated revoker.  */
+    unsigned int maybe_revoked:1; /* A designated revocation is
+                                     present, but without the key to
+                                     check it.  */
+    unsigned int valid:1;         /* Key (especially subkey) is valid.  */
+    unsigned int dont_cache:1;    /* Do not cache this key.  */
+    unsigned int backsig:2;       /* 0=none, 1=bad, 2=good.  */
+    unsigned int serialno_valid:1;/* SERIALNO below is valid.  */
+  } flags;
+  PKT_user_id *user_id;   /* If != NULL: found by that uid. */
+  struct revocation_key *revkey;
+  int     numrevkeys;
+  u32     trust_timestamp;
+  byte    trust_depth;
+  byte    trust_value;
+  const byte *trust_regexp;
+  char    *serialno;      /* Malloced hex string or NULL if it is
+                             likely not on a card.  See also
+                             flags.serialno_valid.  */  
+  struct seckey_info *seckey_info;  /* If not NULL this malloced
+                                       structure describes a secret
+                                       key.  */
+  gcry_mpi_t  pkey[PUBKEY_MAX_NSKEY]; /* Right, NSKEY elements.  */
 } PKT_public_key;
 
 /* Evaluates as true if the pk is disabled, and false if it isn't.  If
    there is no disable value cached, fill one in. */
-#define pk_is_disabled(a) (((a)->is_disabled)?((a)->is_disabled==2):(cache_disabled_value((a))))
+#define pk_is_disabled(a)                                       \
+  (((a)->flags.disabled_valid)?                                 \
+   ((a)->flags.disabled):(cache_disabled_value((a))))
 
 
 typedef struct {
index 89d6f59..3714739 100644 (file)
@@ -1901,7 +1901,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
   pk->max_expiredate = max_expiredate;
   pk->hdrbytes = hdrlen;
   pk->version = version;
-  pk->is_primary = (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY);
+  pk->flags.primary = (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY);
   pk->pubkey_algo = algorithm;
 
   nskey = pubkey_get_nskey (algorithm);
@@ -2085,7 +2085,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
                    }
                  snlen = iobuf_get (inp);
                  pktlen--;
-                 if (pktlen < snlen || snlen == -1)
+                 if (pktlen < snlen || snlen == (size_t)(-1))
                    {
                      err = gpg_error (GPG_ERR_INV_PACKET);
                      goto leave;
index f76c186..da33159 100644 (file)
@@ -527,7 +527,7 @@ check_signatures_trust( PKT_signature *sig )
       goto leave;
     }
 
-  if(pk->maybe_revoked && !pk->is_revoked)
+  if(pk->flags.maybe_revoked && !pk->flags.revoked)
     log_info(_("WARNING: this key might be revoked (revocation key"
               " not present)\n"));
 
@@ -536,7 +536,7 @@ check_signatures_trust( PKT_signature *sig )
   if ( (trustlevel & TRUST_FLAG_REVOKED) ) 
     {
       write_status( STATUS_KEYREVOKED );
-      if(pk->is_revoked==2)
+      if(pk->flags.revoked == 2)
        log_info(_("WARNING: This key has been revoked by its"
                   " designated revoker!\n"));
       else
@@ -1491,7 +1491,7 @@ select_mdc_from_pklist (PK_LIST pk_list)
       if (pkr->pk->user_id) /* selected by user ID */
         mdc = pkr->pk->user_id->flags.mdc;
       else
-        mdc = pkr->pk->mdc_feature;
+        mdc = pkr->pk->flags.mdc;
       if (!mdc)
         return 0;  /* At least one recipient does not support it. */
     }
@@ -1512,7 +1512,7 @@ warn_missing_mdc_from_pklist (PK_LIST pk_list)
       if (pkr->pk->user_id) /* selected by user ID */
         mdc = pkr->pk->user_id->flags.mdc;
       else
-        mdc = pkr->pk->mdc_feature;
+        mdc = pkr->pk->flags.mdc;
       if (!mdc)
         log_info (_("Note: key %s has no %s feature\n"),
                   keystr_from_pk (pkr->pk), "MDC");
index 770e4fb..312b591 100644 (file)
@@ -313,7 +313,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
           }
       }
 
-    if (pk && pk->is_revoked)
+    if (pk && pk->flags.revoked)
       {
         log_info (_("NOTE: key has been revoked"));
         log_printf ("\n");
index 25f62a6..6fe5e67 100644 (file)
@@ -76,10 +76,11 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
          }
        keyid_from_sk( sk, keyid );
        keyid[2] = keyid[3] = 0;
-       if( !sk->is_primary ) {
+       if (!sk->flags.primary)
+          {
             keyid[2] = sk->main_keyid[0];
             keyid[3] = sk->main_keyid[1];
-       }
+          }
        dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo,
                                 &sk->protect.s2k, mode,
                                  tryagain_text, canceled );
@@ -269,6 +270,7 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
 int
 is_secret_key_protected (PKT_public_key *pk)
 {
+#warning do we need this
   return 0; /* FIXME:  use agent_get_keyinfo?*/
     /* return sk->is_protected? */
     /*            sk->protect.s2k.mode == 1002? -2 : */
index a24890f..9dee55d 100644 (file)
@@ -82,7 +82,7 @@ signature_check2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate,
       }
     else if( get_pubkey( pk, sig->keyid ) )
        rc = G10ERR_NO_PUBKEY;
-    else if(!pk->is_valid && !pk->is_primary)
+    else if(!pk->flags.valid && !pk->flags.primary)
         rc=G10ERR_BAD_PUBKEY; /* you cannot have a good sig from an
                                 invalid subkey */
     else
@@ -98,9 +98,9 @@ signature_check2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate,
           them as their own.  The attacker couldn't actually use the
           subkey, but they could try and claim ownership of any
           signaures issued by it. */
-       if(rc==0 && !pk->is_primary && pk->backsig<2)
+       if(rc==0 && !pk->flags.primary && pk->flags.backsig < 2)
          {
-           if(pk->backsig==0)
+           if (!pk->flags.backsig)
              {
                log_info(_("WARNING: signing subkey %s is not"
                           " cross-certified\n"),keystr_from_pk(pk));
@@ -112,7 +112,7 @@ signature_check2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate,
                if(opt.flags.require_cross_cert)
                  rc=G10ERR_GENERAL;
              }
-           else if(pk->backsig==1)
+           else if(pk->flags.backsig == 1)
              {
                log_info(_("WARNING: signing subkey %s has an invalid"
                           " cross-certification\n"),keystr_from_pk(pk));
@@ -246,7 +246,7 @@ do_check_messages( PKT_public_key *pk, PKT_signature *sig,
          *r_expired = 1;
     }
 
-    if (pk->is_revoked)
+    if (pk->flags.revoked)
       {
         if (opt.verbose)
          log_info (_("NOTE: signature key %s has been revoked\n"),
@@ -412,13 +412,12 @@ check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
   assert(IS_KEY_REV(sig));
   assert((sig->keyid[0]!=pk->keyid[0]) || (sig->keyid[0]!=pk->keyid[1]));
 
-  if(busy)
+  if (busy)
     {
-      /* return an error (i.e. not revoked), but mark the pk as
+      /* Return an error (i.e. not revoked), but mark the pk as
          uncacheable as we don't really know its revocation status
-         until it is checked directly. */
-
-      pk->dont_cache=1;
+         until it is checked directly.  */
+      pk->flags.dont_cache = 1;
       return rc;
     }
 
index 2a022e1..5c00424 100644 (file)
@@ -360,6 +360,48 @@ complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md,
 }
 
 
+/* Return true if the key seems to be on a version 1 OpenPGP card.
+   This works by asking the agent and may fail if the card has not yet
+   been used with the agent.  */
+static int
+openpgp_card_v1_p (PKT_public_key *pk)
+{
+  gpg_error_t err;
+  int result;
+
+  /* Shortcut if we are not using RSA: The v1 cards only support RSA
+     thus there is no point in looking any further.  */
+  if (!is_RSA (pk->pubkey_algo))
+    return 0;
+
+  if (!pk->flags.serialno_valid)
+    {
+      char *hexgrip;
+
+      err = hexkeygrip_from_pk (pk, &hexgrip);
+      if (err)
+        {
+          log_error ("error computing a keygrip: %s\n", gpg_strerror (err));
+          return 0; /* Ooops.  */
+        }
+
+      xfree (pk->serialno);
+      agent_get_keyinfo (NULL, hexgrip, &pk->serialno);
+      xfree (hexgrip);
+      pk->flags.serialno_valid = 1;
+    }
+
+  if (!pk->serialno)
+    result = 0; /* Error from a past agent_get_keyinfo or no card.  */
+  else
+    {
+      /* The version number of the card is included in the serialno.  */
+      result = !strncmp (pk->serialno, "D2760001240101", 14);
+    }
+  return result;
+}
+
+
 
 static int
 match_dsa_hash (unsigned int qbytes)
@@ -440,10 +482,7 @@ hash_for (PKT_public_key *pk)
 
       return match_dsa_hash(qbytes);
     }
-  else if (0 
-           /* FIXME: call agent sk->is_protected && sk->protect.s2k.mode == 1002
-           && sk->protect.ivlen == 16
-           && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01\x01", 7)*/)
+  else if (openpgp_card_v1_p (pk))
     {
       /* The sk lives on a smartcard, and old smartcards only handle
         SHA-1 and RIPEMD/160.  Newer smartcards (v2.0) don't have
@@ -851,7 +890,7 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr,
       gcry_md_start_debug (mfx.md, "sign");
 
     /* If we're encrypting and signing, it is reasonable to pick the
-       hash algorithm to use out of the recepient key prefs.  This is
+       hash algorithm to use out of the recipient key prefs.  This is
        best effort only, as in a DSA2 and smartcard world there are
        cases where we cannot please everyone with a single hash (DSA2
        wants >160 and smartcards want =160).  In the future this could
index 7226fe4..dbd593a 100644 (file)
@@ -520,7 +520,7 @@ uid_trust_string_fixed(PKT_public_key *key,PKT_user_id *uid)
 {
   if(!key && !uid)
     return _("10 translator see trustdb.c:uid_trust_string_fixed");
-  else if(uid->is_revoked || (key && key->is_revoked))
+  else if(uid->is_revoked || (key && key->flags.revoked))
     return                         _("[ revoked]");
   else if(uid->is_expired)
     return                         _("[ expired]");
@@ -994,16 +994,17 @@ update_validity (PKT_public_key *pk, PKT_user_id *uid,
  *********  Query trustdb values  **************
  ***********************************************/
 
-/* Return true if key is disabled */
+/* Return true if key is disabled.  Note that this is usually used via
+   the pk_is_disabled macro.  */
 int
-cache_disabled_value(PKT_public_key *pk)
+cache_disabled_value (PKT_public_key *pk)
 {
   int rc;
   TRUSTREC trec;
-  int disabled=0;
+  int disabled = 0;
 
-  if(pk->is_disabled)
-    return (pk->is_disabled==2);
+  if (pk->flags.disabled_valid)
+    return pk->flags.disabled;
 
   init_trustdb();
 
@@ -1016,15 +1017,13 @@ cache_disabled_value(PKT_public_key *pk)
   if (rc == -1) /* no record found, so assume not disabled */
     goto leave;
  
-  if(trec.r.trust.ownertrust & TRUST_FLAG_DISABLED)
-    disabled=1;
+  if (trec.r.trust.ownertrust & TRUST_FLAG_DISABLED)
+    disabled = 1;
  
   /* Cache it for later so we don't need to look at the trustdb every
      time */
-  if(disabled)
-    pk->is_disabled=2;
-  else
-    pk->is_disabled=1;
+  pk->flags.disabled = disabled;
+  pk->flags.disabled_valid = 1;
 
  leave:
    return disabled;
@@ -1151,16 +1150,17 @@ get_validity (PKT_public_key *pk, PKT_user_id *uid)
   if ( (trec.r.trust.ownertrust & TRUST_FLAG_DISABLED) )
     {
       validity |= TRUST_FLAG_DISABLED;
-      pk->is_disabled=2;
+      pk->flags.disabled = 1;
     }
   else
-    pk->is_disabled=1;
+    pk->flags.disabled = 0;
+  pk->flags.disabled_valid = 1;
 
  leave:
   /* set some flags direct from the key */
-  if (main_pk->is_revoked)
+  if (main_pk->flags.revoked)
     validity |= TRUST_FLAG_REVOKED;
-  if (main_pk != pk && pk->is_revoked)
+  if (main_pk != pk && pk->flags.revoked)
     validity |= TRUST_FLAG_SUB_REVOKED;
   /* Note: expiration is a trust value and not a flag - don't know why
    * I initially designed it that way */
@@ -2145,7 +2145,7 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
       merge_keys_and_selfsig (keyblock); 
       clear_kbnode_flags (keyblock);
       pk = keyblock->pkt->pkt.public_key;
-      if (pk->has_expired || pk->is_revoked)
+      if (pk->has_expired || pk->flags.revoked)
         {
           /* it does not make sense to look further at those keys */
           mark_keyblock_seen (full_trust, keyblock);
@@ -2355,7 +2355,7 @@ validate_keys (int interactive)
            {
              k->ownertrust = ask_ownertrust (k->kid,min);
 
-             if (k->ownertrust == -1)
+             if (k->ownertrust == (unsigned int)(-1))
                {
                  quit=1;
                  goto leave;