aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/Makefile.am6
-rw-r--r--g10/Makefile.in6
-rw-r--r--g10/armor.c76
-rw-r--r--g10/comment.c27
-rw-r--r--g10/g10.c18
-rw-r--r--g10/g10maint.c12
-rw-r--r--g10/keygen.c9
-rw-r--r--g10/keyid.c10
-rw-r--r--g10/main.h1
-rw-r--r--g10/parse-packet.c4
-rw-r--r--g10/plaintext.c6
-rw-r--r--g10/pubring.g10bin0 -> 3017 bytes
-rw-r--r--g10/sign.c27
13 files changed, 168 insertions, 34 deletions
diff --git a/g10/Makefile.am b/g10/Makefile.am
index b0a2e9293..5bb3db24b 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -1,7 +1,7 @@
## Process this file with automake to produce Makefile.in
-INCLUDES = -I.. -I$(top_srcdir)/include
-EXTRA_DIST = OPTIONS
+INCLUDES = -I$(top_srcdir)/include
+EXTRA_DIST = OPTIONS pubring.g10
needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a
bin_PROGRAMS = g10 g10maint
@@ -55,7 +55,7 @@ g10_SOURCES = g10.c \
g10maint_SOURCES = g10maint.c \
$(common_source)
-LDADD = $(needed_libs)
+LDADD = @INTLLIBS@ $(needed_libs)
$(PROGRAMS): $(needed_libs)
diff --git a/g10/Makefile.in b/g10/Makefile.in
index 808d99fdb..6bcb29e40 100644
--- a/g10/Makefile.in
+++ b/g10/Makefile.in
@@ -86,8 +86,8 @@ POSUB = @POSUB@
RANLIB = @RANLIB@
VERSION = @VERSION@
-INCLUDES = -I.. -I$(top_srcdir)/include
-EXTRA_DIST = OPTIONS
+INCLUDES = -I$(top_srcdir)/include
+EXTRA_DIST = OPTIONS pubring.g10
needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a
bin_PROGRAMS = g10 g10maint
@@ -140,7 +140,7 @@ g10_SOURCES = g10.c \
g10maint_SOURCES = g10maint.c \
$(common_source)
-LDADD = $(needed_libs)
+LDADD = @INTLLIBS@ $(needed_libs)
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES =
diff --git a/g10/armor.c b/g10/armor.c
index e397346cc..37e37e726 100644
--- a/g10/armor.c
+++ b/g10/armor.c
@@ -172,6 +172,52 @@ invalid_armor(void)
/****************
+ * check wether the armor header is valid on a signed message.
+ * this is for security reasons: the header lines are not included in the
+ * hash and by using some creative formatting rules, Mallory could fake
+ * any text at the beginning of a document; assuming it is read with
+ * a simple viewer. We do only allow the Hash Header.
+ */
+static int
+parse_hash_header( const char *line )
+{
+ const char *s, *s2;
+ unsigned found = 0;
+
+ if( strlen(line) < 6 || strlen(line) > 60 )
+ return 0; /* too short or too long */
+ if( memcmp( line, "Hash:", 5 ) )
+ return 0; /* invalid header */
+ s = line+5;
+ for(s=line+5;;s=s2) {
+ for(; *s && (*s==' ' || *s == '\t'); s++ )
+ ;
+ if( !*s )
+ break;
+ for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ )
+ ;
+ if( !strncmp( s, "RIPEMD160", s2-s ) )
+ found |= 1;
+ else if( !strncmp( s, "SHA1", s2-s ) )
+ found |= 2;
+ else if( !strncmp( s, "MD5", s2-s ) )
+ found |= 4;
+ else if( !strncmp( s, "MD2", s2-s ) )
+ found |= 8;
+ else
+ return 0;
+ for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
+ ;
+ if( *s2 && *s2 != ',' )
+ return 0;
+ if( *s2 )
+ s2++;
+ }
+ return found;
+}
+
+
+/****************
* parse an ascii armor.
* Returns: the state,
* the remaining bytes in BUF are returned in RBUFLEN.
@@ -197,15 +243,17 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
do {
switch( state ) {
case fhdrHASArmor:
- /* read 28 bytes, which is the bare minimum for a BEGIN...
- * and check wether this has a Armor. */
+ /* read at least the first byte to check wether it is armored
+ * or not */
c = 0;
for(n=0; n < 28 && (c=iobuf_get2(a)) != -1 && c != '\n'; )
buf[n++] = c;
- if( n < 28 || c == -1 )
+ if( !n || c == -1 )
state = fhdrNOArmor; /* too short */
else if( !is_armored( buf ) )
state = fhdrNOArmor;
+ else if( c == '\n' )
+ state = fhdrCHECKBegin;
else
state = fhdrINITCont;
break;
@@ -243,7 +291,12 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
log_debug("armor header: ");
print_string( stderr, buf, n );
putc('\n', stderr);
- state = fhdrWAITHeader;
+ if( clearsig && !parse_hash_header( buf ) ) {
+ log_error("invalid clearsig header\n");
+ state = fhdrERROR;
+ }
+ else
+ state = fhdrWAITHeader;
}
else
state = fhdrCHECKDashEscaped3;
@@ -605,7 +658,6 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
break;
case fhdrENDClearsig:
- log_debug("endclearsig: emplines=%u n=%u\n", emplines, n );
assert( emplines );
emplines--; /* don't count the last one */
state = fhdrENDClearsigHelp;
@@ -760,12 +812,14 @@ armor_filter( void *opaque, int control,
int idx, idx2;
size_t n=0;
u32 crc;
+ #if 1
static FILE *fp ;
if( !fp ) {
fp = fopen("armor.out", "w");
assert(fp);
}
+ #endif
if( DBG_FILTER )
log_debug("armor-filter: control: %d\n", control );
@@ -794,8 +848,14 @@ armor_filter( void *opaque, int control,
rc = fake_packet( afx, a, &n, buf, size );
else if( !afx->inp_checked ) {
rc = check_input( afx, a );
- if( afx->inp_bypass )
- ;
+ if( afx->inp_bypass ) {
+ for( n=0; n < size && n < afx->helplen; n++ )
+ buf[n] = afx->helpbuf[n];
+ if( !n )
+ rc = -1;
+ assert( n == afx->helplen );
+ afx->helplen = 0;
+ }
else if( afx->faked ) {
/* the buffer is at least 30 bytes long, so it
* is easy to construct the packets */
@@ -824,9 +884,11 @@ armor_filter( void *opaque, int control,
}
else
rc = radix64_read( afx, a, &n, buf, size );
+ #if 1
if( n )
if( fwrite(buf, n, 1, fp ) != 1 )
BUG();
+ #endif
*ret_len = n;
}
else if( control == IOBUFCTRL_FLUSH ) {
diff --git a/g10/comment.c b/g10/comment.c
index 00bbac7dd..ce2e6cc4c 100644
--- a/g10/comment.c
+++ b/g10/comment.c
@@ -69,3 +69,30 @@ make_comment_node( const char *s )
}
+KBNODE
+make_mpi_comment_node( const char *s, MPI a )
+{
+ PACKET *pkt;
+ byte *buf, *p, *pp;
+ unsigned n1, nb1;
+ size_t n = strlen(s);
+
+ nb1 = mpi_get_nbits( a );
+ p = buf = mpi_get_buffer( a, &n1, NULL );
+ for( ; !*p && n1; p++, n1-- ) /* skip leading null bytes */
+ ;
+
+ pkt = m_alloc_clear( sizeof *pkt );
+ pkt->pkttype = PKT_COMMENT;
+ pkt->pkt.comment = m_alloc( sizeof *pkt->pkt.comment + n + 2 + n1 );
+ pkt->pkt.comment->len = n+1+2+n1;
+ pp = pkt->pkt.comment->data;
+ memcpy(pp, s, n+1);
+ pp[n+1] = nb1 >> 8;
+ pp[n+2] = nb1 ;
+ memcpy(pp+n+3, p, n1 );
+ m_free(buf);
+ return new_kbnode( pkt );
+}
+
+
diff --git a/g10/g10.c b/g10/g10.c
index b64896912..410aeaaf3 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -101,8 +101,12 @@ strusage( int level )
static void
i18n_init(void)
{
- #ifdef ENABLE_NLS
- setlocale( LC_MESSAGES, "" );
+ #ifdef HAVE_LIBINTL
+ #ifdef HAVE_LC_MESSAGES
+ setlocale( LC_MESSAGES, "" );
+ #else
+ setlocale( LC_ALL, "" );
+ #endif
bindtextdomain( PACKAGE, G10_LOCALEDIR );
textdomain( PACKAGE );
#endif
@@ -235,8 +239,10 @@ main( int argc, char **argv )
enum cmd_values cmd = 0;
const char *trustdb_name = NULL;
-
- secmem_init( 16384 );
+ /* Please note that we may running SUID(ROOT), so be very CAREFUL
+ * when adding any stuff between here and the call to
+ * secmem_init() somewhere after the option parsing
+ */
i18n_init();
opt.compress = -1; /* defaults to standard compress level */
@@ -397,6 +403,10 @@ main( int argc, char **argv )
if( errors )
g10_exit(2);
+ /* initialize the secure memory. */
+ secmem_init( 16384 );
+ /* Okay, we are now working under our real uid */
+
write_status( STATUS_ENTER );
set_debug();
diff --git a/g10/g10maint.c b/g10/g10maint.c
index a6ba7dc63..4352045c1 100644
--- a/g10/g10maint.c
+++ b/g10/g10maint.c
@@ -101,8 +101,12 @@ strusage( int level )
static void
i18n_init(void)
{
- #ifdef ENABLE_NLS
- setlocale( LC_MESSAGES, "" );
+ #ifdef HAVE_LIBINTL
+ #ifdef HAVE_LC_MESSAGES
+ setlocale( LC_MESSAGES, "" );
+ #else
+ setlocale( LC_ALL, "" );
+ #endif
bindtextdomain( PACKAGE, G10_LOCALEDIR );
textdomain( PACKAGE );
#endif
@@ -449,13 +453,13 @@ main( int argc, char **argv )
}
else if( argc == 2 ) {
mpi_print( stdout, generate_elg_prime( atoi(argv[0]),
- atoi(argv[1]), NULL ), 1);
+ atoi(argv[1]), NULL,NULL ), 1);
putchar('\n');
}
else if( argc == 3 ) {
MPI g = mpi_alloc(1);
mpi_print( stdout, generate_elg_prime( atoi(argv[0]),
- atoi(argv[1]), g ), 1);
+ atoi(argv[1]), g, NULL ), 1);
printf("\nGenerator: ");
mpi_print( stdout, g, 1 );
putchar('\n');
diff --git a/g10/keygen.c b/g10/keygen.c
index a817463db..d73573cb1 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -145,13 +145,15 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
PKT_secret_cert **ret_skc )
{
int rc;
+ int i;
PACKET *pkt;
PKT_secret_cert *skc;
PKT_public_cert *pkc;
ELG_public_key pk;
ELG_secret_key sk;
+ MPI *factors;
- elg_generate( &pk, &sk, nbits );
+ elg_generate( &pk, &sk, nbits, &factors );
skc = m_alloc_clear( sizeof *skc );
pkc = m_alloc_clear( sizeof *pkc );
@@ -190,10 +192,15 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
pkt->pkt.public_cert = pkc;
add_kbnode(pub_root, new_kbnode( pkt ));
+ /* don't know wether it make sense to have the factors, so for now
+ * we store them in the secret keyring (but they are of secret) */
pkt = m_alloc_clear(sizeof *pkt);
pkt->pkttype = PKT_SECRET_CERT;
pkt->pkt.secret_cert = skc;
add_kbnode(sec_root, new_kbnode( pkt ));
+ for(i=0; factors[i]; i++ )
+ add_kbnode( sec_root,
+ make_mpi_comment_node("#:ELG_factor:", factors[i] ));
return 0;
}
diff --git a/g10/keyid.c b/g10/keyid.c
index 5d5a043c5..6e7b120e6 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -59,14 +59,18 @@ v3_elg_fingerprint_md( PKT_public_cert *pkc )
byte *buf1, *buf2, *buf3;
byte *p1, *p2, *p3;
unsigned n1, n2, n3;
+ unsigned nb1, nb2, nb3;
unsigned n;
+ nb1 = mpi_get_nbits(pkc->d.elg.p);
p1 = buf1 = mpi_get_buffer( pkc->d.elg.p, &n1, NULL );
for( ; !*p1 && n1; p1++, n1-- ) /* skip leading null bytes */
;
+ nb2 = mpi_get_nbits(pkc->d.elg.g);
p2 = buf2 = mpi_get_buffer( pkc->d.elg.g, &n2, NULL );
for( ; !*p2 && n2; p2++, n2-- ) /* skip leading null bytes */
;
+ nb3 = mpi_get_nbits(pkc->d.elg.y);
p3 = buf3 = mpi_get_buffer( pkc->d.elg.y, &n3, NULL );
for( ; !*p3 && n3; p3++, n3-- ) /* skip leading null bytes */
;
@@ -90,9 +94,9 @@ v3_elg_fingerprint_md( PKT_public_cert *pkc )
md_putc( md, a );
}
md_putc( md, pkc->pubkey_algo );
- md_putc( md, n1>>8); md_putc( md, n1 ); md_write( md, p1, n1 );
- md_putc( md, n2>>8); md_putc( md, n2 ); md_write( md, p2, n2 );
- md_putc( md, n3>>8); md_putc( md, n3 ); md_write( md, p3, n3 );
+ md_putc( md, nb1>>8); md_putc( md, nb1 ); md_write( md, p1, n1 );
+ md_putc( md, nb2>>8); md_putc( md, nb2 ); md_write( md, p2, n2 );
+ md_putc( md, nb3>>8); md_putc( md, nb3 ); md_write( md, p3, n3 );
m_free(buf1);
m_free(buf2);
m_free(buf3);
diff --git a/g10/main.h b/g10/main.h
index 67091e7b4..55b99cef1 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -76,6 +76,7 @@ MPI encode_md_value( MD_HANDLE md, unsigned nbits );
/*-- comment.c --*/
KBNODE make_comment_node( const char *s );
+KBNODE make_mpi_comment_node( const char *s, MPI a );
/*-- elg.c --*/
void g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index f364d3b7b..c49b6f513 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -714,7 +714,7 @@ parse_subkey( IOBUF inp, int pkttype, unsigned long pktlen )
version = iobuf_get_noeof(inp); pktlen--;
if( pkttype == PKT_PUBKEY_SUBCERT && version == '#' ) {
/* early versions of G10 use old comments packets; luckily all those
- * comments are are started by a hash */
+ * comments are started by a hash */
if( list_mode ) {
printf(":old comment packet: \"" );
for( ; pktlen; pktlen-- ) {
@@ -829,8 +829,6 @@ parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
pktlen = 0;
if( list_mode ) {
- /* a value if 'c' is used by armor to indicate a faked packet
- * it should be considered as 't' */
printf(":literal data packet:\n"
"\tmode %c, created %lu, name=\"",
mode >= ' ' && mode <'z'? mode : '?',
diff --git a/g10/plaintext.c b/g10/plaintext.c
index ea43a1e6f..196da81f4 100644
--- a/g10/plaintext.c
+++ b/g10/plaintext.c
@@ -45,6 +45,10 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
FILE *fp = NULL;
int rc = 0;
int c;
+static FILE *abc;
+if( !abc )
+ abc=fopen("plaintext.out", "wb");
+if( !abc ) BUG();
/* create the filename as C string */
if( opt.outfile ) {
@@ -78,6 +82,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
rc = G10ERR_READ_FILE;
goto leave;
}
+ putc( c, abc );
if( mfx->md )
md_putc(mfx->md, c );
if( putc( c, fp ) == EOF ) {
@@ -89,6 +94,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
}
else {
while( (c = iobuf_get(pt->buf)) != -1 ) {
+ putc( c, abc );
if( mfx->md )
md_putc(mfx->md, c );
if( putc( c, fp ) == EOF ) {
diff --git a/g10/pubring.g10 b/g10/pubring.g10
new file mode 100644
index 000000000..f458371d4
--- /dev/null
+++ b/g10/pubring.g10
Binary files differ
diff --git a/g10/sign.c b/g10/sign.c
index 010c6bcc3..883a8d4f1 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -144,7 +144,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
}
/* prepare to calculate the MD over the input */
- if( opt.textmode && opt.armor && !outfile )
+ if( opt.textmode && !outfile )
iobuf_push_filter( inp, text_filter, &tfx );
mfx.md = md_open(DIGEST_ALGO_RMD160, 0);
if( !multifile )
@@ -301,22 +301,36 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
+/****************
+ * note: we do not count empty lines at the beginning
+ */
static int
write_dash_escaped( IOBUF inp, IOBUF out, MD_HANDLE md )
{
int c;
int lastlf = 1;
+ int skip_empty = 1;
while( (c = iobuf_get(inp)) != -1 ) {
/* Note: We don't escape "From " because the MUA should cope with it */
- if( lastlf && c == '-' ) {
- iobuf_put( out, c );
- iobuf_put( out, ' ' );
+ if( lastlf ) {
+ if( c == '-' ) {
+ iobuf_put( out, c );
+ iobuf_put( out, ' ' );
+ skip_empty = 0;
+ }
+ else if( skip_empty && c == '\r' )
+ skip_empty = 2;
+ else
+ skip_empty = 0;
}
- md_putc(md, c );
+ if( !skip_empty )
+ md_putc(md, c );
iobuf_put( out, c );
lastlf = c == '\n';
+ if( skip_empty == 2 )
+ skip_empty = lastlf ? 0 : 1;
}
return 0; /* fixme: add error handling */
}
@@ -368,7 +382,8 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
goto leave;
}
- iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----\n\n" );
+ iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----\n"
+ "Hash: RIPEMD160\n\n" );
textmd = md_open(DIGEST_ALGO_RMD160, 0);
iobuf_push_filter( inp, text_filter, &tfx );