aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/Makefile.am1
-rw-r--r--g10/Makefile.in10
-rw-r--r--g10/compress.c2
-rw-r--r--g10/encode.c4
-rw-r--r--g10/filter.h15
-rw-r--r--g10/g10.c5
-rw-r--r--g10/keygen.c36
-rw-r--r--g10/main.h3
-rw-r--r--g10/mainproc.c21
-rw-r--r--g10/openfile.c33
-rw-r--r--g10/options.h2
-rw-r--r--g10/packet.h2
-rw-r--r--g10/plaintext.c42
-rw-r--r--g10/textfilter.c106
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*/
diff --git a/g10/g10.c b/g10/g10.c
index a8a278997..9a1966d02 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -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;
+}
+
+
+