* packet.h, main.h, sig-check.c (signature_check2, check_key_signature2,
[gnupg.git] / g10 / mainproc.c
index a801f5e..0bd1a56 100644 (file)
@@ -722,9 +722,9 @@ do_check_sig( CTX c, KBNODE node, int *is_selfsig, int *is_expkey )
     }
     else
        return G10ERR_SIG_CLASS;
-    rc = signature_check2( sig, md, &dummy, is_expkey );
+    rc = signature_check2( sig, md, &dummy, is_expkey, NULL );
     if( rc == G10ERR_BAD_SIGN && md2 )
-       rc = signature_check2( sig, md2, &dummy, is_expkey );
+       rc = signature_check2( sig, md2, &dummy, is_expkey, NULL );
     md_close(md);
     md_close(md2);
 
@@ -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
  */
@@ -1324,6 +1278,28 @@ check_sig_and_print( CTX c, KBNODE node )
        if( keyserver_import_keyid ( sig->keyid )==0 )
            rc = do_check_sig(c, node, NULL, &is_expkey );
     }
+
+    /* If the key still isn't found, try to inform the user where it
+       can be found. */
+
+    if(rc==G10ERR_NO_PUBKEY && opt.verify_options&VERIFY_SHOW_KEYSERVER)
+      {
+       const byte *p;
+       int seq=0;
+       size_t n;
+
+       while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&n,&seq,NULL)))
+         {
+           /* According to my favorite copy editor, in English
+              grammar, you say "at" if the key is located on a web
+              page, but "from" if it is located on a keyserver.  I'm
+              not going to even try to make two strings here :) */
+           log_info(_("Key available at: ") );
+           print_string( log_stream(), p, n, 0 );
+           putc( '\n', log_stream() );
+         }
+      }
+
     if( !rc || rc == G10ERR_BAD_SIGN ) {
        KBNODE un, keyblock;
        int count=0, statno;
@@ -1433,7 +1409,7 @@ check_sig_and_print( CTX c, KBNODE node )
                  {
                    dump_attribs(un->pkt->pkt.user_id,pk,NULL);
 
-                   if(opt.show_photos)
+                   if(opt.verify_options&VERIFY_SHOW_PHOTOS)
                      show_photos(un->pkt->pkt.user_id->attribs,
                                  un->pkt->pkt.user_id->numattribs,pk,NULL);
                  }
@@ -1447,7 +1423,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 */
@@ -1625,6 +1611,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"),
@@ -1686,8 +1696,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);