Inadvertently left out of the 2003-06-01 checkin
[gnupg.git] / g10 / mainproc.c
index 0fc3a85..ec812d7 100644 (file)
@@ -1,5 +1,5 @@
 /* mainproc.c - handle packets
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -292,7 +292,7 @@ proc_symkey_enc( CTX c, PACKET *pkt )
        c->last_was_session_key = 2;
        if ( opt.list_only )
            goto leave;
-       c->dek = passphrase_to_dek( NULL, 0, algo, &enc->s2k, 0, NULL );
+       c->dek = passphrase_to_dek( NULL, 0, algo, &enc->s2k, 0, NULL, NULL );
         if (c->dek)
             c->dek->algo_info_printed = 1;
         if ( c->dek && enc->seskeylen )
@@ -477,7 +477,7 @@ proc_encrypted( CTX c, PACKET *pkt )
         }
         else {
             algo = CIPHER_ALGO_IDEA;
-            if (!opt.def_digest_algo) {
+            if (!opt.s2k_digest_algo) {
                 /* If no digest is given we assume MD5 */
                 s2kbuf.mode = 0;
                 s2kbuf.hash_algo = DIGEST_ALGO_MD5;
@@ -486,7 +486,7 @@ proc_encrypted( CTX c, PACKET *pkt )
             log_info (_("assuming %s encrypted data\n"), "IDEA");
         }
 
-       c->dek = passphrase_to_dek ( NULL, 0, algo, s2k, 0, NULL );
+       c->dek = passphrase_to_dek ( NULL, 0, algo, s2k, 0, NULL, NULL );
         if (c->dek)
             c->dek->algo_info_printed = 1;
     }
@@ -505,7 +505,7 @@ proc_encrypted( CTX c, PACKET *pkt )
        if( pkt->pkt.encrypted->mdc_method && !result )
            write_status( STATUS_GOODMDC );
        else if(!opt.no_mdc_warn)
-           log_info ("WARNING: message was not integrity protected\n");
+           log_info (_("WARNING: message was not integrity protected\n"));
     }
     else if( result == G10ERR_BAD_SIGN ) {
        log_error(_("WARNING: encrypted message has been manipulated!\n"));
@@ -757,52 +757,6 @@ print_userid( PACKET *pkt )
 }
 
 
-static void
-print_notation_data( PKT_signature *sig )
-{
-    size_t n, n1, n2;
-    const byte *p;
-    int seq = 0;
-
-    while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,&n,&seq,NULL))) {
-       if( n < 8 ) {
-           log_info(_("WARNING: invalid notation data found\n"));
-           return;
-       }
-       if( !(*p & 0x80) )
-           return; /* not human readable */
-       n1 = (p[4] << 8) | p[5];
-       n2 = (p[6] << 8) | p[7];
-       p += 8;
-       if( 8+n1+n2 != n ) {
-           log_info(_("WARNING: invalid notation data found\n"));
-           return;
-       }
-       log_info(_("Notation: ") );
-       print_string( log_stream(), p, n1, 0 );
-       putc( '=', log_stream() );
-       print_string( log_stream(), p+n1, n2, 0 );
-       putc( '\n', log_stream() );
-        write_status_buffer ( STATUS_NOTATION_NAME, p   , n1, 0 );
-        write_status_buffer ( STATUS_NOTATION_DATA, p+n1, n2, 50 );
-    }
-
-    seq=0;
-
-    while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,&n,&seq,NULL))) {
-       log_info(_("Policy: ") );
-       print_string( log_stream(), p, n, 0 );
-       putc( '\n', log_stream() );
-        write_status_buffer ( STATUS_POLICY_URL, p, n, 0 );
-    }
-
-    /* Now check whether the key of this signature has some
-     * notation data */
-
-    /* TODO */
-}
-
-
 /****************
  * List the certificate in a user friendly way
  */
@@ -1019,9 +973,19 @@ list_node( CTX c, KBNODE node )
            putchar(':');
            if( sigrc != ' ' )
                putchar(sigrc);
-           printf("::%d:%08lX%08lX:%s::::", sig->pubkey_algo,
-                                            (ulong)sig->keyid[0],
-                      (ulong)sig->keyid[1], colon_datestr_from_sig(sig));
+           printf("::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
+                  (ulong)sig->keyid[0], (ulong)sig->keyid[1],
+                  colon_datestr_from_sig(sig),
+                  colon_expirestr_from_sig(sig));
+
+           if(sig->trust_depth || sig->trust_value)
+             printf("%d %d",sig->trust_depth,sig->trust_value);
+           printf(":");
+
+           if(sig->trust_regexp)
+             print_string(stdout,sig->trust_regexp,
+                          strlen(sig->trust_regexp),':');
+           printf(":");
        }
        else
            printf("%c       %08lX %s   ",
@@ -1303,8 +1267,6 @@ check_sig_and_print( CTX c, KBNODE node )
             }
         }
     }
-    
-
 
     tstr = asctimestamp(sig->timestamp);
     astr = pubkey_algo_to_string( sig->pubkey_algo );
@@ -1382,7 +1344,7 @@ check_sig_and_print( CTX c, KBNODE node )
                }
            }
 
-            if (opt.always_trust || !un)
+            if (opt.trust_model==TM_ALWAYS || !un)
                 keyid_str[17] = 0; /* cut off the "[uncertain]" part */
 
             write_status_text_and_buffer (statno, keyid_str,
@@ -1393,7 +1355,7 @@ check_sig_and_print( CTX c, KBNODE node )
             log_info(rc? _("BAD signature from \"")
                        : sig->flags.expired ? _("Expired signature from \"")
                       : _("Good signature from \""));
-            if (!opt.always_trust && un) {
+            if (opt.trust_model!=TM_ALWAYS && un) {
                 fputs(_("[uncertain]"), log_stream() );
                 putc(' ', log_stream() );
             }
@@ -1421,9 +1383,14 @@ check_sig_and_print( CTX c, KBNODE node )
                     !un->pkt->pkt.user_id->attrib_data )
                    continue;
 
-               if(opt.show_photos && un->pkt->pkt.user_id->attrib_data)
-                 show_photos(un->pkt->pkt.user_id->attribs,
-                             un->pkt->pkt.user_id->numattribs,pk,NULL);
+               if(un->pkt->pkt.user_id->attrib_data)
+                 {
+                   dump_attribs(un->pkt->pkt.user_id,pk,NULL);
+
+                   if(opt.verify_options&VERIFY_SHOW_PHOTOS)
+                     show_photos(un->pkt->pkt.user_id->attribs,
+                                 un->pkt->pkt.user_id->numattribs,pk,NULL);
+                 }
 
                log_info(    _("                aka \""));
                 print_utf8_string( log_stream(), un->pkt->pkt.user_id->name,
@@ -1434,7 +1401,17 @@ check_sig_and_print( CTX c, KBNODE node )
        release_kbnode( keyblock );
 
        if( !rc )
-           print_notation_data( sig );
+         {
+           if(opt.verify_options&VERIFY_SHOW_POLICY)
+             show_policy_url(sig,0,1);
+           else
+             show_policy_url(sig,0,2);
+
+           if(opt.verify_options&VERIFY_SHOW_NOTATION)
+             show_notation(sig,0,1);
+           else
+             show_notation(sig,0,2);
+         }
 
        if( !rc && is_status_enabled() ) {
            /* print a status response with the fingerprint */
@@ -1442,17 +1419,42 @@ check_sig_and_print( CTX c, KBNODE node )
 
            if( !get_pubkey( pk, sig->keyid ) ) {
                byte array[MAX_FINGERPRINT_LEN], *p;
-               char buf[MAX_FINGERPRINT_LEN*2+72];
+               char buf[MAX_FINGERPRINT_LEN*4+90], *bufp;
                size_t i, n;
 
+                bufp = buf;
                fingerprint_from_pk( pk, array, &n );
                p = array;
-               for(i=0; i < n ; i++, p++ )
-                   sprintf(buf+2*i, "%02X", *p );
-               sprintf(buf+strlen(buf), " %s %lu %lu",
-                                        strtimestamp( sig->timestamp ),
-                                        (ulong)sig->timestamp,
-                                        (ulong)sig->expiredate );
+               for(i=0; i < n ; i++, p++, bufp += 2)
+                    sprintf(bufp, "%02X", *p );
+               /* TODO: Replace the reserved '0' in the field below
+                  with bits for status flags (policy url, notation,
+                  etc.).  Remember to make the buffer larger to
+                  match! */
+               sprintf(bufp, " %s %lu %lu %d 0 %d %d %02X ",
+                        strtimestamp( sig->timestamp ),
+                        (ulong)sig->timestamp,(ulong)sig->expiredate,
+                       sig->version,sig->pubkey_algo,sig->digest_algo,
+                       sig->sig_class);
+                bufp = bufp + strlen (bufp);
+                if (!pk->is_primary) {
+                   u32 akid[2];
+                   akid[0] = pk->main_keyid[0];
+                   akid[1] = pk->main_keyid[1];
+                   free_public_key (pk);
+                   pk = m_alloc_clear( sizeof *pk );
+                   if (get_pubkey (pk, akid)) {
+                     /* impossible error, we simply return a zeroed out fpr */
+                     n = MAX_FINGERPRINT_LEN < 20? MAX_FINGERPRINT_LEN : 20;
+                     memset (array, 0, n);
+                   }
+                   else
+                     fingerprint_from_pk( pk, array, &n );
+                }
+               p = array;
+               for(i=0; i < n ; i++, p++, bufp += 2)
+                    sprintf(bufp, "%02X", *p );
                write_status_text( STATUS_VALIDSIG, buf );
            }
            free_public_key( pk );
@@ -1463,11 +1465,18 @@ check_sig_and_print( CTX c, KBNODE node )
 
        if(sig->flags.expired)
          {
-           log_info("Signature expired %s\n",asctimestamp(sig->expiredate));
+           log_info(_("Signature expired %s\n"),
+                    asctimestamp(sig->expiredate));
            rc=G10ERR_GENERAL; /* need a better error here? */
          }
        else if(sig->expiredate)
-         log_info("Signature expires %s\n",asctimestamp(sig->expiredate));
+         log_info(_("Signature expires %s\n"),asctimestamp(sig->expiredate));
+
+       if(opt.verbose)
+         log_info(_("%s signature, digest algorithm %s\n"),
+                  sig->sig_class==0x00?_("binary"):
+                  sig->sig_class==0x01?_("textmode"):_("unknown"),
+                  digest_algo_to_string(sig->digest_algo));
 
        if( rc )
            g10_errors_seen = 1;
@@ -1580,6 +1589,30 @@ proc_tree( CTX c, KBNODE node )
     }
     else if( node->pkt->pkttype == PKT_SIGNATURE ) {
        PKT_signature *sig = node->pkt->pkt.signature;
+       int multiple_ok=1;
+
+       n1=find_next_kbnode(node, PKT_SIGNATURE);
+       if(n1)
+         {
+           byte class=sig->sig_class;
+           byte hash=sig->digest_algo;
+
+           for(; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE)))
+             {
+               /* We can't currently handle multiple signatures of
+                  different classes or digests (we'd pretty much have
+                  to run a different hash context for each), but if
+                  they are all the same, make an exception. */
+               if(n1->pkt->pkt.signature->sig_class!=class
+                  || n1->pkt->pkt.signature->digest_algo!=hash)
+                 {
+                   multiple_ok=0;
+                   log_info(_("WARNING: multiple signatures detected.  "
+                              "Only the first will be checked.\n"));
+                   break;
+                 }
+             }
+         }
 
        if( sig->sig_class != 0x00 && sig->sig_class != 0x01 )
            log_info(_("standalone signature of class 0x%02x\n"),
@@ -1602,7 +1635,7 @@ proc_tree( CTX c, KBNODE node )
                 * signature has been created in textmode */
                c->mfx.md2 = md_open( sig->digest_algo, 0 );
            }
-         #if 0 /* workaround disabled */
+#if 0 /* workaround disabled */
            /* Here we have another hack to work around a pgp 2 bug
             * It works by not using the textmode for detached signatures;
             * this will let the first signature check (on md) fail
@@ -1611,7 +1644,7 @@ proc_tree( CTX c, KBNODE node )
             * hack but it may help in some cases (and break others)
             */
                    /*  c->mfx.md2? 0 :(sig->sig_class == 0x01) */
-         #endif
+#endif
             if ( DBG_HASHING ) {
                 md_start_debug( c->mfx.md, "verify" );
                 if ( c->mfx.md2  )
@@ -1641,8 +1674,11 @@ proc_tree( CTX c, KBNODE node )
        else if (!opt.quiet)
            log_info(_("old style (PGP 2.x) signature\n"));
 
-       for( n1 = node; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )) )
+       if(multiple_ok)
+         for( n1 = node; n1; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )) )
            check_sig_and_print( c, n1 );
+       else
+         check_sig_and_print( c, node );
     }
     else {
         dump_kbnode (c->list);
@@ -1650,7 +1686,3 @@ proc_tree( CTX c, KBNODE node )
         dump_kbnode (node);
     }
 }
-
-
-
-