*** empty log message ***
authorWerner Koch <wk@gnupg.org>
Fri, 30 Jan 1998 16:23:16 +0000 (16:23 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 30 Jan 1998 16:23:16 +0000 (16:23 +0000)
NEWS
g10/Makefile.am
g10/Makefile.in
g10/OPTIONS
g10/free-packet.c
g10/g10.c
g10/mainproc.c
g10/packet.h
g10/status.c [new file with mode: 0644]
g10/status.h [new file with mode: 0644]
mpi/mpicoder.c

diff --git a/NEWS b/NEWS
index ba17e96..41d9b4f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,7 @@
 
+    * added option "--status-fd": see g10/OPTIONS
+
+
     * We have secure memeory on systems which support mlock().
       It is not complete yet, because we do not have signal handler
       which does a cleanup in very case.
index 154ffe6..e83e63a 100644 (file)
@@ -43,6 +43,8 @@ g10_SOURCES = g10.c           \
              import.c          \
              export.c          \
              comment.c         \
+             status.c          \
+             status.h          \
              sig-check.c
 
 
index a11c89a..d8b0672 100644 (file)
@@ -81,6 +81,8 @@ g10_SOURCES = g10.c           \
              import.c          \
              export.c          \
              comment.c         \
+             status.c          \
+             status.h          \
              sig-check.c
 
 LDADD = -L ../cipher -L ../mpi -L ../util \
@@ -107,7 +109,7 @@ free-packet.o getkey.o pkclist.o skclist.o ringedit.o kbnode.o keygen.o \
 mainproc.o armor.o mdfilter.o textfilter.o cipher.o elg.o rsa.o \
 openfile.o keyid.o trustdb.o parse-packet.o passphrase.o plaintext.o \
 pubkey-enc.o seckey-cert.o seskey.o sign.o import.o export.o comment.o \
-sig-check.o
+status.o sig-check.o
 EXTRA_g10_SOURCES =
 g10_LDADD = $(LDADD)
 DIST_COMMON = Makefile.am Makefile.in
@@ -137,7 +139,8 @@ $(srcdir)/.deps/pubkey-enc.P $(srcdir)/.deps/ringedit.P \
 $(srcdir)/.deps/rsa.P $(srcdir)/.deps/seckey-cert.P \
 $(srcdir)/.deps/seskey.P $(srcdir)/.deps/sig-check.P \
 $(srcdir)/.deps/sign.P $(srcdir)/.deps/skclist.P \
-$(srcdir)/.deps/textfilter.P $(srcdir)/.deps/trustdb.P
+$(srcdir)/.deps/status.P $(srcdir)/.deps/textfilter.P \
+$(srcdir)/.deps/trustdb.P
 SOURCES = $(g10_SOURCES)
 OBJECTS = $(g10_OBJECTS)
 
index ed91fcf..4f21a9e 100644 (file)
@@ -192,6 +192,13 @@ remote-user
 secret-keyring filename
 # add filename to the list of secret keyrings
 
+status-fd n
+# Write status informations to this file descriptor. If this option
+# is not used, no status information is writte.  This option is for the
+# sake of a calling programm (e.g. a MUA) to ease up parsing of output
+# and providing a defined set of status messages.
+# FIXME: use a format ala "100 Blabla"?
+
 verbose
 # Give more informations suring processing. If used 2 times, the input data
 # is listed in detail.
index e2efa5a..949af10 100644 (file)
@@ -56,6 +56,25 @@ free_seckey_enc( PKT_signature *enc )
     m_free(enc);
 }
 
+
+/****************
+ * Return the digest algorith from the signature packet.
+ * We need this function because the digeste algo depends on the
+ * used pubkey algorithm.
+ */
+int
+digest_algo_from_sig( PKT_signature *sig )
+{
+    switch( sig->pubkey_algo ) {
+      case PUBKEY_ALGO_ELGAMAL: return sig->d.elg.digest_algo;
+      case PUBKEY_ALGO_RSA:    return sig->d.rsa.digest_algo;
+      default: return 0;
+    }
+}
+
+
+
+
 void
 release_public_cert_parts( PKT_public_cert *cert )
 {
index cab9dc3..9b593e0 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -38,6 +38,7 @@
 #include "trustdb.h"
 #include "ttyio.h"
 #include "i18n.h"
+#include "status.h"
 
 
 enum cmd_values { aNull = 0,
@@ -187,7 +188,7 @@ main( int argc, char **argv )
     { 'k', NULL      , 0, N_("list keys")},
     { 510, "debug"     ,4|16, N_("set debugging flags")},
     { 511, "debug-all" ,0, N_("enable full debugging")},
- /* { 512 unused */
+    { 512, "status-fd" ,1, N_("write status info to this fd") },
     { 513, "gen-prime" , 0, "\r" },
     { 514, "test"      , 0, "\r" },
     { 515, "fingerprint", 0, N_("show the fingerprints")},
@@ -329,7 +330,7 @@ main( int argc, char **argv )
          case 509: add_keyring(pargs.r.ret_str); nrings++; break;
          case 510: opt.debug |= pargs.r.ret_ulong; break;
          case 511: opt.debug = ~0; break;
-       /*  case 512: */
+         case 512: set_status_fd( pargs.r.ret_int ); break;
          case 513: set_cmd( &cmd, aPrimegen); break;
          case 514: set_cmd( &cmd, aTest); break;
          case 515: opt.fingerprint = 1; break;
@@ -401,6 +402,7 @@ main( int argc, char **argv )
     if( errors )
        g10_exit(2);
 
+    write_status( STATUS_ENTER );
 
     set_debug();
     if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
@@ -685,7 +687,9 @@ g10_exit( int rc )
     if( opt.verbose )
        secmem_dump_stats();
     secmem_term();
-    exit( rc? rc : log_get_errorcount(0)? 2:0 );
+    rc = rc? rc : log_get_errorcount(0)? 2:0;
+    write_status( STATUS_LEAVE );
+    exit(rc );
 }
 
 
index 35a4493..607d712 100644 (file)
@@ -33,6 +33,7 @@
 #include "filter.h"
 #include "cipher.h"
 #include "main.h"
+#include "status.h"
 
 
 /****************
@@ -46,7 +47,7 @@ typedef struct {
     md_filter_context_t mfx;
     DEK *dek;
     int last_was_pubkey_enc;
-    KBNODE cert;     /* the current certificate */
+    KBNODE cert;     /* the current certificate / or signature */
     int have_data;
     IOBUF iobuf;    /* used to get the filename etc. */
 } *CTX;
@@ -74,7 +75,6 @@ add_onepass_sig( CTX c, PACKET *pkt )
     KBNODE node;
 
     if( c->cert ) { /* add another packet */
-
        if( c->cert->pkt->pkttype != PKT_ONEPASS_SIG ) {
           log_error("add_onepass_sig: another packet is in the way\n");
           release_cert( c );
@@ -143,29 +143,36 @@ add_signature( CTX c, PACKET *pkt )
 {
     KBNODE node, n1, n2;
 
-    if( !c->cert ) {
-       /* orphaned signature (no certificate)
-        * this is the first signature for a following datafile
-        */
-       return 0;
+    if( pkt->pkttype == PKT_SIGNATURE && !c->cert ) {
+       /* This is the first signature for a following datafile.
+        * G10 does not write such packets, instead it always uses
+        * onepass-sig packets.  The drawback of PGP's method
+        * of writing prepending the signtaure to the data is,
+        * that it is not possible to make a signature from data
+        * read from stdin.  But we are able to read these stuff. */
+       node = new_kbnode( pkt );
+       node->next = c->cert;
+       c->cert = node;
+       return 1;
     }
-    assert( c->cert->pkt );
-    if( c->cert->pkt->pkttype == PKT_ONEPASS_SIG ) {
+    else if( !c->cert )
+       return 0;
+    else if( !c->cert->pkt )
+       BUG();
+    else if( c->cert->pkt->pkttype == PKT_ONEPASS_SIG ) {
        /* The root is a onepass signature, so we are signing data
         * The childs direct under the root are the signatures
-        * (there is no need to keep the correct sequence of packets)
-        */
+        * (there is no need to keep the correct sequence of packets) */
        node = new_kbnode( pkt );
        node->next = c->cert->child;
        c->cert->child = node;
        return 1;
     }
-
-
-    if( !c->cert->child ) {
+    else if( !c->cert->child ) {
        log_error("orphaned signature (no userid)\n" );
        return 0;
     }
+
     /* goto the last user id */
     for(n1=c->cert->child; n1->next; n1 = n1->next )
        ;
@@ -564,6 +571,38 @@ print_keyid( FILE *fp, u32 *keyid )
     m_free(p);
 }
 
+
+
+static int
+check_sig_and_print( CTX c, KBNODE node )
+{
+    PKT_signature *sig = node->pkt->pkt.signature;
+    int rc;
+
+    rc = do_check_sig(c, node );
+    if( !rc ) {
+       write_status( STATUS_GOODSIG );
+       log_info("Good signature from ");
+       print_keyid( stderr, sig->keyid );
+       putc('\n', stderr);
+    }
+    else if( rc == G10ERR_BAD_SIGN ) {
+       write_status( STATUS_BADSIG );
+       log_error("BAD signature from ");
+       print_keyid( stderr, sig->keyid );
+       putc('\n', stderr);
+       if( opt.batch )
+           g10_exit(1);
+    }
+    else {
+       write_status( STATUS_ERRSIG );
+       log_error("Can't check signature made by %08lX: %s\n",
+                  sig->keyid[1], g10_errstr(rc) );
+    }
+    return rc;
+}
+
+
 /****************
  * Process the tree which starts at node
  */
@@ -588,9 +627,13 @@ proc_tree( CTX c, KBNODE node )
        else {  /* check all signatures */
            if( !c->have_data ) {
                free_md_filter_context( &c->mfx );
-               /* fixme: take the digest algo to use from the
-                * onepass_sig packet (if we have these) */
-               c->mfx.md = md_open(DIGEST_ALGO_RMD160, 0);
+               /* prepare to create all requested message digests */
+               c->mfx.md = md_open(0, 0);
+               for(n1=node->child; n1; n1 = n1->next ) {
+                   md_enable( c->mfx.md,
+                              digest_algo_from_sig(n1->pkt->pkt.signature));
+               }
+               /* ask for file and hash it */
                rc = ask_for_detached_datafile( &c->mfx,
                                                iobuf_get_fname(c->iobuf));
                if( rc ) {
@@ -599,30 +642,26 @@ proc_tree( CTX c, KBNODE node )
                }
            }
 
-           for(n1=node->child; n1; n1 = n1->next ) {
-               PKT_signature *sig = n1->pkt->pkt.signature;
-
-               rc = do_check_sig(c, n1 );
-               if( !rc ) {
-                   log_info("Good signature from ");
-                   print_keyid( stderr, sig->keyid );
-                   putc('\n', stderr);
-               }
-               else if( rc == G10ERR_BAD_SIGN ) {
-                   log_error("BAD signature from ");
-                   print_keyid( stderr, sig->keyid );
-                   putc('\n', stderr);
-                   if( opt.batch )
-                       g10_exit(1);
-               }
-               else
-                   log_error("Can't check signature made by %08lX: %s\n",
-                              sig->keyid[1], g10_errstr(rc) );
-           }
+           for(n1=node->child; n1; n1 = n1->next )
+               check_sig_and_print( c, n1 );
        }
     }
     else if( node->pkt->pkttype == PKT_SIGNATURE ) {
+       PKT_signature *sig = node->pkt->pkt.signature;
+
        log_info("proc_tree: old style signature\n");
+       if( !c->have_data ) {
+           free_md_filter_context( &c->mfx );
+           c->mfx.md = md_open(digest_algo_from_sig(sig), 0);
+           rc = ask_for_detached_datafile( &c->mfx,
+                                           iobuf_get_fname(c->iobuf));
+           if( rc ) {
+               log_error("can't hash datafile: %s\n", g10_errstr(rc));
+               return;
+           }
+       }
+
+       check_sig_and_print( c, node );
     }
     else
        log_error("proc_tree: invalid root packet\n");
index 2856952..8d3018d 100644 (file)
@@ -230,6 +230,7 @@ void hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc );
 /*-- free-packet.c --*/
 void free_pubkey_enc( PKT_pubkey_enc *enc );
 void free_seckey_enc( PKT_signature *enc );
+int  digest_algo_from_sig( PKT_signature *sig );
 void release_public_cert_parts( PKT_public_cert *cert );
 void free_public_cert( PKT_public_cert *cert );
 void release_secret_cert_parts( PKT_secret_cert *cert );
diff --git a/g10/status.c b/g10/status.c
new file mode 100644 (file)
index 0000000..6c660b7
--- /dev/null
@@ -0,0 +1,57 @@
+/* status.c
+ *     Copyright (c) 1997 by Werner Koch (dd9jn)
+ *
+ * This file is part of G10.
+ *
+ * G10 is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * G10 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "status.h"
+
+static int fd = -1;
+
+void
+set_status_fd( int newfd )
+{
+    fd = newfd;
+}
+
+
+void
+write_status( int no )
+{
+    const char *s;
+
+    if( fd == -1 )
+       return;  /* not enabled */
+
+    switch( no ) {
+      case STATUS_ENTER  : s = "ENTER\n"; break;
+      case STATUS_LEAVE  : s = "LEAVE\n"; break;
+      case STATUS_ABORT  : s = "ABORT\n"; break;
+      case STATUS_GOODSIG: s = "GOODSIG\n"; break;
+      case STATUS_BADSIG : s = "BADSIG\n"; break;
+      case STATUS_ERRSIG : s = "ERRSIG\n"; break;
+      default: s = "?\n"; break;
+    }
+
+    write( fd, s, strlen(s) );
+
+}
+
diff --git a/g10/status.h b/g10/status.h
new file mode 100644 (file)
index 0000000..55eef32
--- /dev/null
@@ -0,0 +1,41 @@
+/* status.h
+ *     Copyright (c) 1997 by Werner Koch (dd9jn)
+ *
+ * This file is part of G10.
+ *
+ * G10 is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * G10 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#ifndef G10_STATUS_H
+#define G10_STATUS_H
+
+
+#define STATUS_ENTER    1
+#define STATUS_LEAVE    2
+#define STATUS_ABORT    3
+
+#define STATUS_GOODSIG  4
+#define STATUS_BADSIG   5
+#define STATUS_ERRSIG   6
+
+
+
+
+
+/*-- status.c --*/
+void set_status_fd( int fd );
+void write_status( int no );
+
+
+#endif /*G10_STATUS_H*/
index 7558399..b371fa6 100644 (file)
@@ -244,14 +244,21 @@ mpi_print( FILE *fp, MPI a, int mode )
 u32
 mpi_get_keyid( MPI a, u32 *keyid )
 {
-#if BYTES_PER_MPI_LIMB != 4
-  #error Make this function work with other LIMB sizes
-#endif
+#if BYTES_PER_MPI_LIMB == 4
     if( keyid ) {
        keyid[0] = a->nlimbs >= 2? a->d[1] : 0;
        keyid[1] = a->nlimbs >= 1? a->d[0] : 0;
     }
     return a->nlimbs >= 1? a->d[0] : 0;
+#elif BYTES_PER_MPI_LIMB == 8
+    if( keyid ) {
+       keyid[0] = a->nlimbs? (u32)(a->d[0] >> 32) : 0;
+       keyid[1] = a->nlimbs? (u32)(a->d[0] & 0xffffffff) : 0;
+    }
+    return a->nlimbs? (u32)(a->d[0] & 0xffffffff) : 0;
+#else
+  #error Make this function work with other LIMB sizes
+#endif
 }