* build-packet.c (build_sig_subpkt): Comments.
authorDavid Shaw <dshaw@jabberwocky.com>
Wed, 30 Apr 2003 05:33:52 +0000 (05:33 +0000)
committerDavid Shaw <dshaw@jabberwocky.com>
Wed, 30 Apr 2003 05:33:52 +0000 (05:33 +0000)
* exec.c (exec_write): Cast NULL to void* to properly terminate varargs
list.

* keyedit.c (show_key_with_all_names): Just for safety, catch an invalid
pk algorithm.

* sign.c (make_keysig_packet): Crucial that the call to mksubpkt comes
LAST before the calls to finalize the sig as that makes it possible for
the mksubpkt function to get a reliable pointer to the subpacket area.

* pkclist.c (do_we_trust_pre): If an untrusted key was chosen by a
particular user ID, use that ID as the one to ask about when prompting
whether to use the key anyway. (build_pk_list): Similar change here when
adding keys to the recipient list.

* trustdb.c (update_validity): Fix bug that prevented more than one
validity record per trust record. (get_validity): When retrieving validity
for a (user) supplied user ID, return the validity for that user ID only,
and do not fall back to the general key validity. (validate_one_keyblock):
Some commentary on whether non-self-signed user IDs belong in the web of
trust (arguably, they do).

g10/ChangeLog
g10/build-packet.c
g10/exec.c
g10/keyedit.c
g10/pkclist.c
g10/sign.c
g10/trustdb.c

index d80849f..e7398ef 100644 (file)
@@ -1,3 +1,33 @@
+2003-04-30  David Shaw  <dshaw@jabberwocky.com>
+
+       * build-packet.c (build_sig_subpkt): Comments.
+
+       * exec.c (exec_write): Cast NULL to void* to properly terminate
+       varargs list.
+
+       * keyedit.c (show_key_with_all_names): Just for safety, catch an
+       invalid pk algorithm.
+
+       * sign.c (make_keysig_packet): Crucial that the call to mksubpkt
+       comes LAST before the calls to finalize the sig as that makes it
+       possible for the mksubpkt function to get a reliable pointer to
+       the subpacket area.
+
+       * pkclist.c (do_we_trust_pre): If an untrusted key was chosen by a
+       particular user ID, use that ID as the one to ask about when
+       prompting whether to use the key anyway.
+       (build_pk_list): Similar change here when adding keys to the
+       recipient list.
+
+       * trustdb.c (update_validity): Fix bug that prevented more than
+       one validity record per trust record.
+       (get_validity): When retrieving validity for a (user) supplied
+       user ID, return the validity for that user ID only, and do not
+       fall back to the general key validity.
+       (validate_one_keyblock): Some commentary on whether
+       non-self-signed user IDs belong in the web of trust (arguably,
+       they do).
+
 2003-04-27  David Shaw  <dshaw@jabberwocky.com>
 
        * g10.c (main): Add --no-textmode.
 2003-04-27  David Shaw  <dshaw@jabberwocky.com>
 
        * g10.c (main): Add --no-textmode.
index 92e357f..3fec9a8 100644 (file)
@@ -794,6 +794,10 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
       case SIGSUBPKT_PRIV_VERIFY_CACHE: /*(obsolete)*/
        BUG();
        break;
       case SIGSUBPKT_PRIV_VERIFY_CACHE: /*(obsolete)*/
        BUG();
        break;
+       /* The issuer being unhashed is a historical oddity.  It
+          should work equally as well hashed.  Of course, if even an
+          unhashed issuer is tampered with, it makes it awfully hard
+          to verify the sig... */
       case SIGSUBPKT_ISSUER:
         hashed = 0;
         break;
       case SIGSUBPKT_ISSUER:
         hashed = 0;
         break;
index fd592e8..0278438 100644 (file)
@@ -417,14 +417,14 @@ int exec_write(struct exec_info **info,const char *program,
              if(DBG_EXTPROG)
                log_debug("execlp: %s\n",program);
 
              if(DBG_EXTPROG)
                log_debug("execlp: %s\n",program);
 
-             execlp(program,program,NULL);
+             execlp(program,program,(void *)NULL);
            }
          else
            {
              if(DBG_EXTPROG)
                log_debug("execlp: %s -c %s\n",shell,(*info)->command);
 
            }
          else
            {
              if(DBG_EXTPROG)
                log_debug("execlp: %s -c %s\n",shell,(*info)->command);
 
-             execlp(shell,shell,"-c",(*info)->command,NULL);
+             execlp(shell,shell,"-c",(*info)->command,(void *)NULL);
            }
 
          /* If we get this far the exec failed.  Clean up and return. */
            }
 
          /* If we get this far the exec failed.  Clean up and return. */
@@ -617,4 +617,3 @@ int exec_finish(struct exec_info *info)
   return ret;
 }
 #endif /* ! NO_EXEC */
   return ret;
 }
 #endif /* ! NO_EXEC */
-
index 0324b40..333552c 100644 (file)
@@ -1983,13 +1983,15 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
                     for(i=0;i<pk->numrevkeys;i++) {
                         u32 r_keyid[2];
                         char *user;
                     for(i=0;i<pk->numrevkeys;i++) {
                         u32 r_keyid[2];
                         char *user;
-           
+                       const char *algo=
+                         pubkey_algo_to_string(pk->revkey[i].algid);
+
                         keyid_from_fingerprint(pk->revkey[i].fpr,
                                                MAX_FINGERPRINT_LEN,r_keyid);
                         
                         user=get_user_id_string (r_keyid);
                         tty_printf (_("This key may be revoked by %s key "),
                         keyid_from_fingerprint(pk->revkey[i].fpr,
                                                MAX_FINGERPRINT_LEN,r_keyid);
                         
                         user=get_user_id_string (r_keyid);
                         tty_printf (_("This key may be revoked by %s key "),
-                                 pubkey_algo_to_string (pk->revkey[i].algid));
+                                   algo?algo:"?");
                         tty_print_utf8_string (user, strlen (user));
                         if ((pk->revkey[i].class&0x40))
                           tty_printf (_(" (sensitive)"));
                         tty_print_utf8_string (user, strlen (user));
                         if ((pk->revkey[i].class&0x40))
                           tty_printf (_(" (sensitive)"));
index 99f98b3..671fe20 100644 (file)
@@ -542,17 +542,23 @@ do_we_trust_pre( PKT_public_key *pk, unsigned int trustlevel )
        return 0;
 
     if( !opt.batch && !rc ) {
        return 0;
 
     if( !opt.batch && !rc ) {
-       char *p;
        u32 keyid[2];
        u32 keyid[2];
-       size_t n;
 
        keyid_from_pk( pk, keyid);
        tty_printf( "%4u%c/%08lX %s \"",
                  nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
                  (ulong)keyid[1], datestr_from_pk( pk ) );
 
        keyid_from_pk( pk, keyid);
        tty_printf( "%4u%c/%08lX %s \"",
                  nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
                  (ulong)keyid[1], datestr_from_pk( pk ) );
-       p = get_user_id( keyid, &n );
-       tty_print_utf8_string( p, n ),
-       m_free(p);
+       /* If the pk was chosen by a particular user ID, this is the
+          one to ask about. */
+       if(pk->user_id)
+         tty_print_utf8_string(pk->user_id->name,pk->user_id->len);
+       else
+         {
+           size_t n;
+           char *p = get_user_id( keyid, &n );
+           tty_print_utf8_string( p, n );
+           m_free(p);
+         }
        tty_printf("\"\n");
         print_fingerprint (pk, NULL, 2);
        tty_printf("\n");
        tty_printf("\"\n");
         print_fingerprint (pk, NULL, 2);
        tty_printf("\n");
@@ -932,8 +938,8 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use )
                }
                else {
                    int trustlevel;
                }
                else {
                    int trustlevel;
-
-                   trustlevel = get_validity (pk, NULL);
+                   
+                   trustlevel = get_validity (pk, pk->user_id);
                    if( (trustlevel & TRUST_FLAG_DISABLED) ) {
                        tty_printf(_("Public key is disabled.\n") );
                    }
                    if( (trustlevel & TRUST_FLAG_DISABLED) ) {
                        tty_printf(_("Public key is disabled.\n") );
                    }
@@ -946,8 +952,6 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use )
                        }
                        else {
                            PK_LIST r;
                        }
                        else {
                            PK_LIST r;
-                           char *p;
-                           size_t n;
                            u32 keyid[2];
 
                            keyid_from_pk( pk, keyid);
                            u32 keyid[2];
 
                            keyid_from_pk( pk, keyid);
@@ -956,9 +960,16 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use )
                                       pubkey_letter( pk->pubkey_algo ),
                                       (ulong)keyid[1],
                                       datestr_from_pk( pk ) );
                                       pubkey_letter( pk->pubkey_algo ),
                                       (ulong)keyid[1],
                                       datestr_from_pk( pk ) );
-                           p = get_user_id( keyid, &n );
-                           tty_print_utf8_string( p, n );
-                           m_free(p);
+                           if(pk->user_id)
+                             tty_print_utf8_string(pk->user_id->name,
+                                                   pk->user_id->len);
+                           else
+                             {
+                               size_t n;
+                               char *p = get_user_id( keyid, &n );
+                               tty_print_utf8_string( p, n );
+                               m_free(p);
+                             }
                            tty_printf("\"\n");
 
                            r = m_alloc( sizeof *r );
                            tty_printf("\"\n");
 
                            r = m_alloc( sizeof *r );
@@ -1028,7 +1039,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use )
            else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
                int trustlevel;
 
            else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
                int trustlevel;
 
-               trustlevel = get_validity (pk, NULL);
+               trustlevel = get_validity (pk, pk->user_id);
                if( (trustlevel & TRUST_FLAG_DISABLED) ) {
                    free_public_key(pk); pk = NULL;
                    log_info(_("%s: skipped: public key is disabled\n"),
                if( (trustlevel & TRUST_FLAG_DISABLED) ) {
                    free_public_key(pk); pk = NULL;
                    log_info(_("%s: skipped: public key is disabled\n"),
index 2b56240..8311bdb 100644 (file)
@@ -1251,12 +1251,15 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
     sig->sig_class = sigclass;
     if( sig->version >= 4 )
        build_sig_subpkt_from_sig( sig );
     sig->sig_class = sigclass;
     if( sig->version >= 4 )
        build_sig_subpkt_from_sig( sig );
+    mk_notation_and_policy( sig, pk, sk );
 
 
+    /* Crucial that the call to mksubpkt comes LAST before the calls
+       to finalize the sig as that makes it possible for the mksubpkt
+       function to get a reliable pointer to the subpacket area. */
     if( sig->version >= 4 && mksubpkt )
        rc = (*mksubpkt)( sig, opaque );
 
     if( !rc ) {
     if( sig->version >= 4 && mksubpkt )
        rc = (*mksubpkt)( sig, opaque );
 
     if( !rc ) {
-       mk_notation_and_policy( sig, pk, sk );
         hash_sigversion_to_magic (md, sig);
        md_final(md);
 
         hash_sigversion_to_magic (md, sig);
        md_final(md);
 
index c976876..b3aa436 100644 (file)
@@ -873,13 +873,13 @@ update_validity (PKT_public_key *pk, PKT_user_id *uid,
       vrec.rectype = RECTYPE_VALID;
       memcpy (vrec.r.valid.namehash, uid->namehash, 20);
       vrec.r.valid.next = trec.r.trust.validlist;
       vrec.rectype = RECTYPE_VALID;
       memcpy (vrec.r.valid.namehash, uid->namehash, 20);
       vrec.r.valid.next = trec.r.trust.validlist;
+      trec.r.trust.validlist = vrec.recnum;
     }
   vrec.r.valid.validity = validity;
   vrec.r.valid.full_count = uid->help_full_count;
   vrec.r.valid.marginal_count = uid->help_marginal_count;
   write_record (&vrec);
   trec.r.trust.depth = depth;
     }
   vrec.r.valid.validity = validity;
   vrec.r.valid.full_count = uid->help_full_count;
   vrec.r.valid.marginal_count = uid->help_marginal_count;
   write_record (&vrec);
   trec.r.trust.depth = depth;
-  trec.r.trust.validlist = vrec.recnum;
   write_record (&trec);
 }
 
   write_record (&trec);
 }
 
@@ -985,7 +985,7 @@ get_validity (PKT_public_key *pk, PKT_user_id *uid)
 
   if(uid)
     namehash_from_uid(uid);
 
   if(uid)
     namehash_from_uid(uid);
-  
+
   init_trustdb ();
   if (!did_nextcheck
       && (opt.trust_model==TM_CLASSIC || opt.trust_model==TM_OPENPGP))
   init_trustdb ();
   if (!did_nextcheck
       && (opt.trust_model==TM_CLASSIC || opt.trust_model==TM_OPENPGP))
@@ -1043,16 +1043,30 @@ get_validity (PKT_public_key *pk, PKT_user_id *uid)
   while (recno)
     {
       read_record (recno, &vrec, RECTYPE_VALID);
   while (recno)
     {
       read_record (recno, &vrec, RECTYPE_VALID);
-      if ( validity < (vrec.r.valid.validity & TRUST_MASK) )
-        validity = (vrec.r.valid.validity & TRUST_MASK);
-      if ( uid && !memcmp (vrec.r.valid.namehash, uid->namehash, 20) )
-        break;
+
+      if(uid)
+       {
+         /* If a user ID is given we return the validity for that
+            user ID ONLY.  If the namehash is not found, then there
+            is no validity at all (i.e. the user ID wasn't
+            signed). */
+         if(memcmp(vrec.r.valid.namehash,uid->namehash,20)==0)
+           {
+             validity=(vrec.r.valid.validity & TRUST_MASK);
+             break;
+           }
+       }
+      else
+       {
+         /* If no namehash is given, we take the maximum validity
+            over all user IDs */
+         if ( validity < (vrec.r.valid.validity & TRUST_MASK) )
+           validity = (vrec.r.valid.validity & TRUST_MASK);
+       }
+
       recno = vrec.r.valid.next;
     }
   
       recno = vrec.r.valid.next;
     }
   
-  if (recno) /* okay, use the user ID associated one */
-    validity = (vrec.r.valid.validity & TRUST_MASK);
-
   if ( (trec.r.trust.ownertrust & TRUST_FLAG_DISABLED) )
     validity |= TRUST_FLAG_DISABLED;
 
   if ( (trec.r.trust.ownertrust & TRUST_FLAG_DISABLED) )
     validity |= TRUST_FLAG_DISABLED;
 
@@ -1528,6 +1542,16 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist,
   keyid_from_pk(pk, main_kid);
   for (node=kb; node; node = node->next)
     {
   keyid_from_pk(pk, main_kid);
   for (node=kb; node; node = node->next)
     {
+      /* A bit of discussion here: is it better for the web of trust
+        to be built among only self-signed uids?  On the one hand, a
+        self-signed uid is a statement that the key owner definitely
+        intended that uid to be there, but on the other hand, a
+        signed (but not self-signed) uid does carry trust, of a sort,
+        even if it is a statement being made by people other than the
+        key owner "through" the uids on the key owner's key.  I'm
+        going with the latter. -dshaw */
+
+      /* && node->pkt->pkt.user_id->created) */
       if (node->pkt->pkttype == PKT_USER_ID)
         {
           if (uidnode && issigned)
       if (node->pkt->pkttype == PKT_USER_ID)
         {
           if (uidnode && issigned)
@@ -1542,13 +1566,19 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist,
             }
           uidnode = node;
          uid=uidnode->pkt->pkt.user_id;
             }
           uidnode = node;
          uid=uidnode->pkt->pkt.user_id;
+#if 0
+         /* If the selfsig is going to expire...  This is disabled as
+            we do count un-self-signed uids in the web of trust. */
+         if(uid->expiredate && uid->expiredate<*next_expire)
+           *next_expire = uid->expiredate;
+#endif
           issigned = 0;
          get_validity_counts(pk,uid);
           mark_usable_uid_certs (kb, uidnode, main_kid, klist, 
                                  curtime, next_expire);
         }
           issigned = 0;
          get_validity_counts(pk,uid);
           mark_usable_uid_certs (kb, uidnode, main_kid, klist, 
                                  curtime, next_expire);
         }
-      else if (node->pkt->pkttype == PKT_SIGNATURE 
-               && (node->flag & (1<<8)) && uid)
+      else if (node->pkt->pkttype == PKT_SIGNATURE
+              && (node->flag & (1<<8)) && uid)
         {
          /* Note that we are only seeing unrevoked sigs here */
           PKT_signature *sig = node->pkt->pkt.signature;
         {
          /* Note that we are only seeing unrevoked sigs here */
           PKT_signature *sig = node->pkt->pkt.signature;