diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/Makefile.am | 1 | ||||
-rw-r--r-- | g10/Makefile.in | 10 | ||||
-rw-r--r-- | g10/compress.c | 2 | ||||
-rw-r--r-- | g10/encode.c | 4 | ||||
-rw-r--r-- | g10/filter.h | 15 | ||||
-rw-r--r-- | g10/g10.c | 5 | ||||
-rw-r--r-- | g10/keygen.c | 36 | ||||
-rw-r--r-- | g10/main.h | 3 | ||||
-rw-r--r-- | g10/mainproc.c | 21 | ||||
-rw-r--r-- | g10/openfile.c | 33 | ||||
-rw-r--r-- | g10/options.h | 2 | ||||
-rw-r--r-- | g10/packet.h | 2 | ||||
-rw-r--r-- | g10/plaintext.c | 42 | ||||
-rw-r--r-- | g10/textfilter.c | 106 |
14 files changed, 232 insertions, 50 deletions
diff --git a/g10/Makefile.am b/g10/Makefile.am index e13459e97..ee22d2ed9 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -21,6 +21,7 @@ g10_SOURCES = g10.c \ mainproc.c \ armor.c \ mdfilter.c \ + textfilter.c \ cipher.c \ options.h \ openfile.c \ diff --git a/g10/Makefile.in b/g10/Makefile.in index 6ce262c02..b77793783 100644 --- a/g10/Makefile.in +++ b/g10/Makefile.in @@ -59,6 +59,7 @@ g10_SOURCES = g10.c \ mainproc.c \ armor.c \ mdfilter.c \ + textfilter.c \ cipher.c \ options.h \ openfile.c \ @@ -94,9 +95,9 @@ COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) LINK = $(CC) $(LDFLAGS) -o $@ g10_OBJECTS = g10.o build-packet.o compress.o encode.o encr-data.o \ free-packet.o getkey.o ringedit.o kbnode.o keygen.o mainproc.o armor.o \ -mdfilter.o cipher.o openfile.o keyid.o parse-packet.o passphrase.o \ -plaintext.o pubkey-enc.o seckey-cert.o seskey.o sign.o comment.o \ -sig-check.o +mdfilter.o textfilter.o cipher.o openfile.o keyid.o parse-packet.o \ +passphrase.o plaintext.o pubkey-enc.o seckey-cert.o seskey.o sign.o \ +comment.o sig-check.o EXTRA_g10_SOURCES = g10_LDADD = $(LDADD) DIST_COMMON = Makefile.am Makefile.in @@ -122,7 +123,8 @@ $(srcdir)/.deps/openfile.P $(srcdir)/.deps/parse-packet.P \ $(srcdir)/.deps/passphrase.P $(srcdir)/.deps/plaintext.P \ $(srcdir)/.deps/pubkey-enc.P $(srcdir)/.deps/ringedit.P \ $(srcdir)/.deps/seckey-cert.P $(srcdir)/.deps/seskey.P \ -$(srcdir)/.deps/sig-check.P $(srcdir)/.deps/sign.P +$(srcdir)/.deps/sig-check.P $(srcdir)/.deps/sign.P \ +$(srcdir)/.deps/textfilter.P SOURCES = $(g10_SOURCES) OBJECTS = $(g10_OBJECTS) diff --git a/g10/compress.c b/g10/compress.c index 2b10c983b..0502b3637 100644 --- a/g10/compress.c +++ b/g10/compress.c @@ -154,7 +154,7 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs, log_debug("inflate returned: avail_in=%u, avail_out=%u, zrc=%d\n", (unsigned)zs->avail_in, (unsigned)zs->avail_out, zrc); if( zrc == Z_STREAM_END ) - rc = -1; /* eof */ + rc = -1; /* eof FIXME: return remaining bytes until EOF */ else if( zrc != Z_OK ) { if( zs->msg ) log_fatal("zlib inflate problem: %s\n", zs->msg ); diff --git a/g10/encode.c b/g10/encode.c index 53d03c038..b3d97d8b5 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -97,7 +97,7 @@ encode_simple( const char *filename, int mode ) } } - if( !(out = open_outfile( filename )) ) { + if( !(out = open_outfile( filename, opt.armor? 1:0 )) ) { iobuf_close(inp); m_free(cfx.dek); return G10ERR_CREATE_FILE; /* or user said: do not overwrite */ @@ -190,7 +190,7 @@ encode_crypt( const char *filename, STRLIST remusr ) else if( opt.verbose ) log_error("reding from '%s'\n", filename? filename: "[stdin]"); - if( !(out = open_outfile( filename )) ) { + if( !(out = open_outfile( filename, opt.armor? 1:0 )) ) { iobuf_close(inp); free_strlist(local_remusr); return G10ERR_CREATE_FILE; /* or user said: do not overwrite */ diff --git a/g10/filter.h b/g10/filter.h index 72029c61f..69f5174d4 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -35,6 +35,10 @@ typedef struct { byte radbuf[4]; int idx, idx2; u32 crc; + byte helpbuf[100]; + int helpidx, helplen; + int last_c; + int fake; int inp_checked; /* set if inp has been checked */ int inp_bypass; /* set if the input is not armored */ int inp_eof; @@ -60,6 +64,13 @@ typedef struct { } cipher_filter_context_t; +typedef struct { + size_t linesize; + byte *line; + size_t linelen; + size_t pos; + int eof; +} text_filter_context_t; /*-- mdfilter.c --*/ int md_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len); @@ -77,6 +88,10 @@ int compress_filter( void *opaque, int control, int cipher_filter( void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len); +/*-- textfilter.c --*/ +int text_filter( void *opaque, int control, + IOBUF chain, byte *buf, size_t *ret_len); + #endif /*G10_FILTER_H*/ @@ -116,6 +116,7 @@ main( int argc, char **argv ) { 508, "check-key" ,0, "check signatures on a key in the keyring" }, { 509, "keyring" ,2, "add this keyring to the list of keyrings" }, { 's', "sign", 0, "make a signature"}, + { 't', "textmode", 0, "use canonical text mode"}, { 'b', "detach-sign", 0, "make a detached signature"}, { 'e', "encrypt", 0, "encrypt data" }, { 'd', "decrypt", 0, "decrypt data (default)" }, @@ -140,7 +141,7 @@ main( int argc, char **argv ) IOBUF a; int rc; enum { aNull, aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr, - aTest, aPrintMDs, aSignKey, + aTest, aPrintMDs, aSignKey, aClearsig } action = aNull; int orig_argc; char **orig_argv; @@ -219,6 +220,7 @@ main( int argc, char **argv ) case 'b': detached_sig = 1; /* fall trough */ case 's': action = action == aEncr? aSignEncr : aSign; break; + case 't': action = aClearsig; break; case 'l': /* store the local users */ sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str)); strcpy(sl->d, pargs.r.ret_str); @@ -329,7 +331,6 @@ main( int argc, char **argv ) log_error("sign_file('%s'): %s\n", fname_print, g10_errstr(rc) ); break; - case aSignEncr: /* sign and encrypt the given file */ log_fatal("signing and encryption is not yet implemented\n"); usage(1); /* FIXME */ diff --git a/g10/keygen.c b/g10/keygen.c index 2582f9b47..43924395c 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -38,7 +38,9 @@ #define TEST_UID "Karl Test" #endif - +#if defined(HAVE_RSA_CIPHER) && 0 + #define ENABLE_RSA_KEYGEN 1 +#endif static u16 @@ -197,7 +199,7 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, -#ifdef HAVE_RSA_CIPHER +#ifdef ENABLE_RSA_KEYGEN static int gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek, PKT_public_cert **ret_pkc, PKT_secret_cert **ret_skc ) @@ -271,7 +273,7 @@ gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek, free_packet(&pkt2); return rc; } -#endif /*HAVE_RSA_CIPHER*/ +#endif /*ENABLE_RSA_KEYGEN*/ static int @@ -310,10 +312,10 @@ generate_keypair() tty_printf("Please select the algorithm to use:\n" " (1) ElGamal is the suggested one.\n" - #ifdef HAVE_RSA_CIPHER - " (2) RSA cannot be used in the U.S.\n" + " (2) DSA can only be used for signatures.\n" + #ifdef ENABLE_RSA_KEYGEN + " (3) RSA cannot be used in the U.S.\n" #endif - " (3) DSA can only be used for signatures.\n" ); #endif @@ -321,11 +323,11 @@ generate_keypair() #ifdef TEST_ALGO algo = TEST_ALGO; #else - answer = tty_get("Your selection? (1" - #ifdef HAVE_RSA_CIPHER - ",2" + answer = tty_get("Your selection? (1,2" + #ifdef ENABLE_RSA_KEYGEN + ",3" #endif - ",3) "); + ") "); tty_kill_prompt(); algo = *answer? atoi(answer): 1; m_free(answer); @@ -335,18 +337,18 @@ generate_keypair() algo_name = "ElGamal"; break; } - #ifdef HAVE_RSA_CIPHER else if( algo == 2 ) { + algo = PUBKEY_ALGO_DSA; + algo_name = "DSA"; + tty_printf("Sorry; DSA is not yet supported.\n"); + } + #ifdef ENABLE_RSA_KEYGEN + else if( algo == 3 ) { algo = PUBKEY_ALGO_RSA; algo_name = "RSA"; break; } #endif - else if( algo == 3 ) { - algo = PUBKEY_ALGO_DSA; - algo_name = "DSA"; - tty_printf("Sorry; DSA is not yet supported.\n"); - } } @@ -479,7 +481,7 @@ generate_keypair() if( algo == PUBKEY_ALGO_ELGAMAL ) rc = gen_elg(nbits, pub_root, sec_root, dek, &skc ); - #ifdef HAVE_RSA_CIPHER + #ifdef ENABLE_RSA_KEYGEN else if( algo == PUBKEY_ALGO_RSA ) rc = gen_rsa(nbits, pub_io, sec_io, dek, &skc ); #endif diff --git a/g10/main.h b/g10/main.h index 0d769c8b0..a8d28af79 100644 --- a/g10/main.h +++ b/g10/main.h @@ -45,7 +45,8 @@ void generate_keypair(void); /*-- openfile.c --*/ int overwrite_filep( const char *fname ); -IOBUF open_outfile( const char *fname ); +IOBUF open_outfile( const char *fname, int mode ); +IOBUF open_sigfile( const char *iname ); /*-- seskey.c --*/ void make_session_key( DEK *dek ); diff --git a/g10/mainproc.c b/g10/mainproc.c index 8bee0de09..338ce3d2d 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -49,6 +49,7 @@ typedef struct { int opt_list; KBNODE cert; /* the current certificate */ int have_data; + IOBUF iobuf; /* used to get the filename etc. */ } *CTX; @@ -259,8 +260,11 @@ proc_plaintext( CTX c, PACKET *pkt ) printf("txt: plain text data name='%.*s'\n", pt->namelen, pt->name); free_md_filter_context( &c->mfx ); - /* fixme: take the digest algo to use from the - * onepass_sig packet (if we have these) */ + /* fixme: take the digest algo(s) to use from the + * onepass_sig packet (if we have these) + * And look at the sigclass to check wether we should use the + * textmode filter (sigclass 0x01) + */ c->mfx.md = md_open(DIGEST_ALGO_RMD160, 0); result = handle_plaintext( pt, &c->mfx ); if( !result ) @@ -463,8 +467,9 @@ list_node( CTX c, KBNODE node ) if( !opt.list_sigs ) return; + fputs("sig", stdout); if( opt.check_sigs ) { - + fflush(stdout); switch( (rc2=do_check_sig( c, node )) ) { case 0: sigrc = '!'; break; case G10ERR_BAD_SIGN: sigrc = '-'; break; @@ -472,7 +477,7 @@ list_node( CTX c, KBNODE node ) default: sigrc = '%'; break; } } - printf("sig%c %08lX %s ", + printf("%c %08lX %s ", sigrc, sig->keyid[1], datestr_from_sig(sig)); if( sigrc == '%' ) printf("[%s] ", g10_errstr(rc2) ); @@ -501,6 +506,7 @@ proc_packets( IOBUF a ) int newpkt; c->opt_list = 1; + c->iobuf = a; init_packet(pkt); while( (rc=parse_packet(a, pkt)) != -1 ) { /* cleanup if we have an illegal data structure */ @@ -511,6 +517,8 @@ proc_packets( IOBUF a ) if( rc ) { free_packet(pkt); + if( rc == G10ERR_INVALID_PACKET ) + break; continue; } newpkt = -1; @@ -559,7 +567,7 @@ print_keyid( FILE *fp, u32 *keyid ) } /**************** - * Preocess the tree which starts at node + * Process the tree which starts at node */ static void proc_tree( CTX c, KBNODE node ) @@ -582,7 +590,8 @@ proc_tree( CTX c, KBNODE node ) /* 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); - rc = ask_for_detached_datafile( &c->mfx ); + 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; diff --git a/g10/openfile.c b/g10/openfile.c index 4b7331dcd..388c9bfa7 100644 --- a/g10/openfile.c +++ b/g10/openfile.c @@ -23,6 +23,7 @@ #include <stdlib.h> #include <string.h> #include <assert.h> +#include <errno.h> #include <unistd.h> #include "util.h" #include "memory.h" @@ -80,9 +81,12 @@ overwrite_filep( const char *fname ) /**************** * Make an output filename for the inputfile INAME. * Returns an IOBUF + * Mode 0 = use ".g10" + * 1 = use ".asc" + * 2 = use ".sig" */ IOBUF -open_outfile( const char *iname ) +open_outfile( const char *iname, int mode ) { IOBUF a = NULL; int rc; @@ -101,7 +105,8 @@ open_outfile( const char *iname ) name = opt.outfile; else { buf = m_alloc(strlen(iname)+4+1); - strcpy(stpcpy(buf,iname), ".g10"); + strcpy(stpcpy(buf,iname), mode==1 ? ".asc" : + mode==2 ? ".sig" : ".g10"); name = buf; } if( !(rc=overwrite_filep( name )) ) { @@ -117,3 +122,27 @@ open_outfile( const char *iname ) return a; } + +/**************** + * Try to open a file without the extension ".sig" + * Return NULL if such a file is not available. + */ +IOBUF +open_sigfile( const char *iname ) +{ + IOBUF a = NULL; + size_t len; + + if( iname ) { + len = strlen(iname); + if( len > 4 && !strcmp(iname + len - 4, ".sig") ) { + char *buf; + buf = m_strdup(iname); + buf[len-4] = 0 ; + a = iobuf_open( buf ); + m_free(buf); + } + } + return a; +} + diff --git a/g10/options.h b/g10/options.h index 8338404ea..c1aea3f95 100644 --- a/g10/options.h +++ b/g10/options.h @@ -26,7 +26,7 @@ struct { int armor; int compress; char *outfile; - int reserved0; + int textmode; int batch; /* run in batch mode */ int answer_yes; /* answer yes on most questions */ int answer_no; /* answer no on most questions */ diff --git a/g10/packet.h b/g10/packet.h index 609bf8853..f7dbf9734 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -252,7 +252,7 @@ int encrypt_data( PKT_encrypted *ed, DEK *dek ); /*-- plaintext.c --*/ int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx ); -int ask_for_detached_datafile( md_filter_context_t *mfx ); +int ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname ); /*-- comment.c --*/ int write_comment( IOBUF out, const char *s ); diff --git a/g10/plaintext.c b/g10/plaintext.c index 831a81089..114db1df0 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -29,6 +29,7 @@ #include "packet.h" #include "ttyio.h" #include "filter.h" +#include "main.h" /**************** @@ -124,27 +125,42 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx ) /**************** * Ask for the detached datafile and calculate the digest from it. + * INFILE is the name of the input file. */ int -ask_for_detached_datafile( md_filter_context_t *mfx ) +ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname ) { - char *answer; - FILE *fp; + char *answer = NULL; + IOBUF fp; int rc = 0; int c; - tty_printf("Detached signature.\n"); - answer = tty_get("Please enter name of data file: "); - tty_kill_prompt(); - - fp = fopen(answer,"rb"); + fp = open_sigfile( inname ); /* open default file */ if( !fp ) { - log_error("can't open '%s': %s\n", answer, strerror(errno) ); - rc = G10ERR_READ_FILE; - goto leave; + int any=0; + tty_printf("Detached signature.\n"); + do { + m_free(answer); + answer = tty_get("Please enter name of data file: "); + tty_kill_prompt(); + if( any && !*answer ) { + rc = G10ERR_READ_FILE; + goto leave; + } + fp = iobuf_open(answer); + if( !fp && errno == ENOENT ) { + tty_printf("No such file, try again or hit enter to quit.\n"); + any++; + } + else if( !fp ) { + log_error("can't open '%s': %s\n", answer, strerror(errno) ); + rc = G10ERR_READ_FILE; + goto leave; + } + } while( !fp ); } - while( (c = getc(fp)) != EOF ) { + while( (c = iobuf_get(fp)) != -1 ) { if( mfx->md ) md_putchar(mfx->md, c ); if( mfx->rmd160 ) @@ -152,7 +168,7 @@ ask_for_detached_datafile( md_filter_context_t *mfx ) if( mfx->md5 ) md5_putchar(mfx->md5, c ); } - fclose(fp); + iobuf_close(fp); leave: m_free(answer); diff --git a/g10/textfilter.c b/g10/textfilter.c new file mode 100644 index 000000000..e57b429e8 --- /dev/null +++ b/g10/textfilter.c @@ -0,0 +1,106 @@ +/* textfilter.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 <string.h> +#include <errno.h> +#include <assert.h> + +#include "errors.h" +#include "iobuf.h" +#include "memory.h" +#include "util.h" +#include "filter.h" + + +/**************** + * The filter is used to make canonical text: Lines are terminated by + * CR, LF, trailing white spaces are removed. + */ +int +text_filter( void *opaque, int control, + IOBUF a, byte *buf, size_t *ret_len) +{ + size_t size = *ret_len; + text_filter_context_t *tfx = opaque; + int i, c, rc=0; + byte *p; + + if( control == IOBUFCTRL_UNDERFLOW ) { + for(i=0; i < size; i++ ) { + if( !tfx->linelen && !tfx->eof ) { /* read a complete line */ + for(;;) { + if( (c = iobuf_get(a)) == -1 ) { + tfx->eof=1; + break; + } + if( c == '\n' ) + break; + if( tfx->linelen >= tfx->linesize ) { + tfx->linesize += 500; + tfx->line = m_realloc( tfx->line, tfx->linesize ); + } + tfx->line[tfx->linelen++] = c; + } + /* remove trailing white spaces */ + p = tfx->line + tfx->linelen - 1; + for( ; p >= tfx->line; p--, tfx->linelen-- ) { + if( *p != ' ' && *p == '\t' && *p != '\r' ) + break; + } + if( tfx->linelen+2 >= tfx->linesize ) { + tfx->linesize += 10; + tfx->line = m_realloc( tfx->line, tfx->linesize ); + } + tfx->line[tfx->linelen++] = '\r'; + tfx->line[tfx->linelen++] = '\n'; + tfx->pos=0; + } + if( tfx->pos < tfx->linelen ) + buf[i] = tfx->line[tfx->pos++]; + else if( tfx->eof ) + break; + else + tfx->linelen = 0; + } + if( !i ) + rc = -1; + *ret_len = i; + } + else if( control == IOBUFCTRL_INIT ) { + tfx->linesize = 500; + tfx->line = m_alloc(tfx->linesize); + tfx->linelen = 0; + tfx->pos = 0; + tfx->eof = 0; + } + else if( control == IOBUFCTRL_FREE ) { + m_free( tfx->line ); + tfx->line = NULL; + } + else if( control == IOBUFCTRL_DESC ) + *(char**)buf = "text_filter"; + return rc; +} + + + |