See ChangeLog: Thu Jan 7 18:00:58 CET 1999 Werner Koch

This commit is contained in:
Werner Koch 1999-01-07 17:05:48 +00:00
parent e3e8d9b92f
commit 7d0efec7cf
31 changed files with 621 additions and 223 deletions

7
NEWS
View File

@ -1,6 +1,13 @@
* Polish language support.
* When querying the passphrase, the key ID of the primary key is
displayed along with the one of the used secondary key.
* Fixed a bug occurring when decrypting pgp 5 encrypted messages,
fixed an infinite loop bug in the 3DES code and in the code
which looks for trusted signatures.
Noteworthy changes in version 0.9.0
-----------------------------------

11
TODO
View File

@ -22,8 +22,8 @@ Important
* print a warning when a revoked/expired secret key is used.
* display trhe primary keyID in passphrase.c in addition to the
one for the requested key.
* Allow the use of a the faked RNG onyl for keys which are
flagged as INSECURE.
Needed
@ -35,6 +35,12 @@ Needed
encrypt this all) - We need an identifier for Twofish to put this
one into the cipher preferences.
* The -export-dynamic flag to ld works only for FreeBSD 3.0. It does
not exist on FreeBSD's 2.2.x version of ld.
Also, on my FreeBSD 2.2-stable box, i simply removed the
-Wl,-export-dynamic flag from my Makefile and it linked and seems to
be working OK so far.
Minor Bugs
----------
@ -51,3 +57,4 @@ Nice to have
* change the fake_data stuff to mpi_set_opaque
* rewrite the ugly armor code.

View File

@ -1,3 +1,8 @@
Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* md.c (md_stop_debug): Do a flush first.
(md_open): size of buffer now depends on the secure parameter
Sun Jan 3 15:28:44 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* rndunix.c (start_gatherer): Fixed stupid ==/= bug

View File

@ -25,6 +25,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "util.h"
#include "cipher.h"
#include "errors.h"
@ -208,8 +209,18 @@ MD_HANDLE
md_open( int algo, int secure )
{
MD_HANDLE hd;
hd = secure ? m_alloc_secure_clear( sizeof *hd )
: m_alloc_clear( sizeof *hd );
int bufsize;
if( secure ) {
bufsize = 512 - sizeof( *hd );
hd = m_alloc_secure_clear( sizeof *hd + bufsize );
}
else {
bufsize = 1024 - sizeof( *hd );
hd = m_alloc_clear( sizeof *hd + bufsize );
}
hd->bufsize = bufsize+1; /* hd has already one byte allocated */
hd->secure = secure;
if( algo )
md_enable( hd, algo );
@ -252,9 +263,11 @@ md_copy( MD_HANDLE a )
MD_HANDLE b;
struct md_digest_list_s *ar, *br;
b = a->secure ? m_alloc_secure( sizeof *b )
: m_alloc( sizeof *b );
memcpy( b, a, sizeof *a );
if( a->bufcount )
md_write( a, NULL, 0 );
b = a->secure ? m_alloc_secure( sizeof *b + a->bufsize - 1 )
: m_alloc( sizeof *b + a->bufsize - 1 );
memcpy( b, a, sizeof *a + a->bufsize - 1 );
b->list = NULL;
b->debug = NULL;
/* and now copy the complete list of algorithms */
@ -266,6 +279,9 @@ md_copy( MD_HANDLE a )
br->next = b->list;
b->list = br;
}
if( a->debug )
md_start_debug( b, "unknown" );
return b;
}
@ -490,6 +506,8 @@ void
md_stop_debug( MD_HANDLE md )
{
if( md->debug ) {
if( md->bufcount )
md_write( md, NULL, 0 );
fclose(md->debug);
md->debug = NULL;
}

View File

@ -106,6 +106,8 @@ case "${target}" in
CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
fi
;;
m68k-atari-mint)
;;
*)
;;
esac

View File

@ -399,10 +399,10 @@ B<--s2k-mode> I<number>
B<--compress-algo> I<number>
Use compress algorithm I<number>. Default is I<2> which is
RFC1950 compression; you may use I<1> to use the old zlib
version which is used by PGP. This is only used for
new messages. The default algorithm may give better
version which is used by PGP.
The default algorithm may give better
results because the window size is not limited to 8K.
If this is not used the OpenPGP behaviour is used; i.e.
If this is not used the OpenPGP behavior is used; i.e.
the compression algorith is selected from the preferences.
B<--digest-algo> I<name>
@ -418,7 +418,7 @@ B<--throw-keyid>
process because all available secret keys are tried.
B<--not-dash-escaped>
This option changes the behaviour of cleartext signature
This option changes the behavior of cleartext signature
so that they can be used for patch files. You should not
send such an armored file via email because all spaces
and line endings are hashed too. You can not use this

View File

@ -1,3 +1,23 @@
Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* pkclist.c (add_ownertrust): Fixed return value.
* encr-data.c (decrypt_data): Disabled iobuf_set_limit and
iobuf_pop_filter stuff.
* compress.c (handle_compressed): Disabled iobuf_pop_filter.
* packet.h (PKT_secret_key): Add is_primary flag.
* parse-packet.c (parse_key): Set this flag.
* passphrase.c (passphrase_to_dek): Kludge to print the primary
keyid - changed the API: keyid must now hold 2 keyids.
* getkey.c (get_primary_seckey): New.
* seckey-cert.c (do_check): pass primary keyid to passphrase query
* tbdio.c (open_db): removed the atexit
(tdbio_set_dbname): and moved it to here.
* armor.c: Rewrote large parts.
Tue Dec 29 19:55:38 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* revoke.c (gen_revoke): Removed compression.

View File

@ -1,5 +1,5 @@
/* armor.c - Armor flter
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998,1999 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -37,6 +37,8 @@
#include "i18n.h"
#define MAX_LINELEN 20000
#define CRCINIT 0xB704CE
#define CRCPOLY 0X864CFB
#define CRCUPDATE(a,c) do { \
@ -86,6 +88,7 @@ typedef enum {
/* if we encounter this armor string with this index, go
* into a mode which fakes packets and wait for the next armor */
#define BEGIN_SIGNATURE 2
#define BEGIN_SIGNED_MSG_IDX 3
static char *head_strings[] = {
"BEGIN PGP MESSAGE",
@ -109,12 +112,6 @@ static char *tail_strings[] = {
};
static fhdr_state_t find_header( fhdr_state_t state,
byte *buf, size_t *r_buflen,
IOBUF a, size_t n,
unsigned *r_empty, int *r_hashes,
int only_keyblocks, int *not_dashed );
static void
initialize(void)
@ -153,7 +150,7 @@ initialize(void)
* Returns: True if it seems to be armored
*/
static int
is_armored( byte *buf )
is_armored( const byte *buf )
{
int ctb, pkttype;
@ -256,6 +253,8 @@ parse_hash_header( const char *line )
}
#if 0 /* old code */
/****************
* parse an ascii armor.
* Returns: the state,
@ -656,10 +655,125 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
}
}
fprintf(stderr,"ARMOR READ (state=%d): %.*s", state, n, buf );
*r_buflen = n;
*r_empty = empty;
return state;
}
#endif
static unsigned
trim_trailing_spaces( byte *line, unsigned len )
{
byte *p, *mark;
unsigned n;
for(mark=NULL, p=line, n=0; n < len; n++, p++ ) {
if( strchr(" \t\r\n", *p ) ) {
if( !mark )
mark = p;
}
else
mark = NULL;
}
if( mark ) {
*mark = 0;
return mark - line;
}
return len;
}
/****************
* Check whether this is a armor line.
* returns: -1 if it is not a armor header or the index number of the
* armor header.
*/
static int
is_armor_header( byte *line, unsigned len )
{
const char *s;
byte *save_p, *p;
int save_c;
int i;
if( len < 15 )
return -1; /* too short */
if( memcmp( line, "-----", 5 ) )
return -1; /* no */
p = strstr( line+5, "-----");
if( !p )
return -1;
save_p = p;
p += 5;
if( *p == '\r' )
p++;
if( *p == '\n' )
p++;
if( *p )
return -1; /* garbage after dashes */
save_c = *save_p; *save_p = 0;
p = line+5;
for(i=0; (s=head_strings[i]); i++ )
if( !strcmp(s, p) )
break;
*save_p = save_c;
if( !s )
return -1; /* unknown armor line */
if( opt.verbose > 1 )
log_info(_("armor: %s\n"), head_strings[i]);
return i;
}
/****************
* Parse a header lines
* Return 0: Empty line (end of header lines)
* -1: invalid header line
* >0: Good header line
*/
static int
parse_header_line( armor_filter_context_t *afx, byte *line, unsigned len )
{
byte *p;
int hashes=0;
if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
return 0; /* empty line */
len = trim_trailing_spaces( line, len );
p = strchr( line, ':');
if( !p || !p[1] ) {
log_error(_("invalid armor header: "));
print_string( stderr, line, len, 0 );
putc('\n', stderr);
return -1;
}
if( opt.verbose ) {
log_info(_("armor header: "));
print_string( stderr, line, len, 0 );
putc('\n', stderr);
}
if( afx->in_cleartext ) {
if( (hashes=parse_hash_header( line )) )
afx->hashes |= hashes;
else if( strlen(line) > 15 && !memcmp( line, "NotDashEscaped:", 15 ) )
afx->not_dash_escaped = 1;
else {
log_error(_("invalid clearsig header\n"));
return -1;
}
}
return 1;
}
/* figure out whether the data is armored or not */
@ -667,73 +781,119 @@ static int
check_input( armor_filter_context_t *afx, IOBUF a )
{
int rc = 0;
int i;
size_t n;
fhdr_state_t state = afx->parse_state;
unsigned emplines;
byte *line;
unsigned len;
unsigned maxlen;
int hdr_line = -1;
if( state != fhdrENDClearsig )
state = fhdrHASArmor;
n = DIM(afx->helpbuf);
state = find_header( state, afx->helpbuf, &n, a,
afx->helplen, &emplines, &afx->hashes,
afx->only_keyblocks, &afx->not_dash_escaped );
switch( state ) {
case fhdrNOArmor:
/* read the first line to see whether this is armored data */
maxlen = MAX_LINELEN;
len = afx->buffer_len = iobuf_read_line( a, &afx->buffer,
&afx->buffer_size, &maxlen );
line = afx->buffer;
if( !maxlen ) {
/* line has been truncated: assume not armored */
afx->inp_checked = 1;
afx->inp_bypass = 1;
afx->helplen = n;
break;
return 0;
}
case fhdrERROR:
if( !len ) {
return -1; /* eof */
}
/* (the line is always a C string but maybe longer) */
if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
;
else if( !is_armored( line ) ) {
afx->inp_checked = 1;
afx->inp_bypass = 1;
return 0;
}
/* find the armor header */
while(len) {
i = is_armor_header( line, len );
if( i >= 0 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
hdr_line = i;
if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
if( afx->in_cleartext ) {
log_error(_("nested clear text signatures\n"));
rc = G10ERR_INVALID_ARMOR;
}
afx->in_cleartext = 1;
}
break;
}
/* read the next line (skip all truncated lines) */
do {
maxlen = MAX_LINELEN;
afx->buffer_len = iobuf_read_line( a, &afx->buffer,
&afx->buffer_size, &maxlen );
line = afx->buffer;
len = afx->buffer_len;
} while( !maxlen );
}
/* parse the header lines */
while(len) {
/* read the next line (skip all truncated lines) */
do {
maxlen = MAX_LINELEN;
afx->buffer_len = iobuf_read_line( a, &afx->buffer,
&afx->buffer_size, &maxlen );
line = afx->buffer;
len = afx->buffer_len;
} while( !maxlen );
i = parse_header_line( afx, line, len );
if( i <= 0 ) {
if( i )
rc = G10ERR_INVALID_ARMOR;
break;
}
}
if( rc )
invalid_armor();
break;
case fhdrEOF:
rc = -1;
break;
case fhdrNullClearsig:
case fhdrCLEARSIG: /* start fake package mode (for clear signatures) */
case fhdrREADClearsigNext:
case fhdrCLEARSIGSimple:
case fhdrCLEARSIGSimpleNext:
afx->helplen = n;
afx->helpidx = 0;
else if( afx->in_cleartext ) {
afx->faked = 1;
break;
case fhdrTEXT:
afx->helplen = n;
afx->helpidx = 0;
}
else {
afx->inp_checked = 1;
afx->crc = CRCINIT;
afx->idx = 0;
afx->radbuf[0] = 0;
break;
default: BUG();
}
afx->parse_state = state;
return rc;
}
/* fake a literal data packet and wait for an armor line */
/****************
* Fake a literal data packet and wait for the next armor line
* fixme: empty line handling and null length clear text signature are
* not implemented/checked.
*/
static int
fake_packet( armor_filter_context_t *afx, IOBUF a,
size_t *retn, byte *buf, size_t size )
{
int rc = 0;
size_t len = 0;
size_t n, nn;
fhdr_state_t state = afx->parse_state;
unsigned emplines = afx->empty;
int lastline = 0;
unsigned maxlen, n;
byte *p;
len = 2; /* reserve 2 bytes for the length header */
size -= 3; /* and 1 for empline handling and 2 for the term header */
/* or the appended CR,LF */
while( !rc && len < size ) {
if( emplines ) {
while( emplines && len < size ) {
@ -743,70 +903,98 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
}
continue;
}
if( state == fhdrENDClearsigHelp ) {
state = fhdrENDClearsig;
afx->faked = 0;
rc = -1;
if( afx->faked == 1 )
afx->faked++; /* skip the first (empty) line */
else {
while( len < size && afx->buffer_pos < afx->buffer_len )
buf[len++] = afx->buffer[afx->buffer_pos++];
buf[len++] = '\r';
buf[len++] = '\n';
if( len >= size )
continue;
}
/* read the next line */
maxlen = MAX_LINELEN;
afx->buffer_pos = 0;
afx->buffer_len = iobuf_read_line( a, &afx->buffer,
&afx->buffer_size, &maxlen );
if( !afx->buffer_len ) {
rc = -1; /* eof */
continue;
}
if( state != fhdrNullClearsig
&& afx->helpidx < afx->helplen ) { /* flush the last buffer */
n = afx->helplen;
for(nn=afx->helpidx; len < size && nn < n ; nn++ )
buf[len++] = afx->helpbuf[nn];
afx->helpidx = nn;
continue;
}
if( state == fhdrEOF ) {
rc = -1;
continue;
}
/* read a new one */
n = DIM(afx->helpbuf);
afx->helpidx = 0;
state = find_header( state, afx->helpbuf, &n, a,
state == fhdrNullClearsig? afx->helplen:0,
&emplines, &afx->hashes,
afx->only_keyblocks,
&afx->not_dash_escaped );
switch( state) {
case fhdrERROR:
invalid_armor();
break;
if( !maxlen )
afx->truncated++;
afx->buffer_len = trim_trailing_spaces( afx->buffer, afx->buffer_len );
p = afx->buffer;
n = afx->buffer_len;
case fhdrEOF:
rc = -1;
break;
case fhdrCLEARSIG:
BUG();
case fhdrREADClearsig:
case fhdrREADClearsigNext:
case fhdrCLEARSIGSimple:
case fhdrCLEARSIGSimpleNext:
afx->helplen = n;
break;
case fhdrENDClearsig:
state = fhdrENDClearsigHelp;
afx->helplen = n;
break;
default: BUG();
if( n > 2 && *p == '-' ) {
/* check for dash escaped or armor header */
if( p[1] == ' ' && !afx->not_dash_escaped ) {
/* issue a warning if it is not regular encoded */
if( p[2] != '-' && !( n > 6 && !memcmp(p+2, "From ", 5))) {
log_info(_("invalid dash escaped line: "));
print_string( stderr, p, n, 0 );
putc('\n', stderr);
}
afx->buffer_pos = 2; /* skip */
}
else if( n >= 15 && p[1] == '-' && p[2] == '-' && p[3] == '-' ) {
if( is_armor_header( p, n ) != BEGIN_SIGNATURE ) {
log_info(_("unexpected armor:"));
print_string( stderr, p, n, 0 );
putc('\n', stderr);
}
lastline = 1;
assert( len >= 4 );
len -= 2; /* remove the last CR,LF */
rc = -1;
}
}
}
buf[0] = (len-2) >> 8;
buf[1] = (len-2);
if( state == fhdrENDClearsig ) { /* write last (ending) length header */
if( buf[0] || buf[1] ) { /* write only if length of text is > 0 */
if( lastline ) { /* write last (ending) length header */
if( buf[0] && buf[1] ) { /* only if we have some text */
buf[len++] = 0;
buf[len++] = 0;
}
rc = 0;
afx->faked = 0;
afx->in_cleartext = 0;
/* and now read the header lines */
afx->buffer_pos = 0;
for(;;) {
int i;
/* read the next line (skip all truncated lines) */
do {
maxlen = MAX_LINELEN;
afx->buffer_len = iobuf_read_line( a, &afx->buffer,
&afx->buffer_size, &maxlen );
} while( !maxlen );
p = afx->buffer;
n = afx->buffer_len;
if( !n ) {
rc = -1;
break; /* eof */
}
i = parse_header_line( afx, p , n );
if( i <= 0 ) {
if( i )
invalid_armor();
break;
}
}
afx->inp_checked = 1;
afx->crc = CRCINIT;
afx->idx = 0;
afx->radbuf[0] = 0;
}
afx->parse_state = state;
afx->empty = emplines;
*retn = len;
return rc;
@ -830,9 +1018,7 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
idx = afx->idx;
val = afx->radbuf[0];
for( n=0; n < size; ) {
if( afx->helpidx < afx->helplen )
c = afx->helpbuf[afx->helpidx++];
else if( (c=iobuf_get(a)) == -1 )
if( (c=iobuf_get(a)) == -1 )
break;
if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
continue;
@ -864,11 +1050,8 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
afx->any_data = 1;
afx->inp_checked=0;
afx->faked = 0;
afx->parse_state = 0;
for(;;) { /* skip lf and pad characters */
if( afx->helpidx < afx->helplen )
c = afx->helpbuf[afx->helpidx++];
else if( (c=iobuf_get(a)) == -1 )
if( (c=iobuf_get(a)) == -1 )
break;
if( c == '\n' || c == ' ' || c == '\r'
|| c == '\t' || c == '=' )
@ -889,9 +1072,7 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
case 2: val |= (c>>2)&15; mycrc |= val << 8;val=(c<<6)&0xc0;break;
case 3: val |= c&0x3f; mycrc |= val; break;
}
if( afx->helpidx < afx->helplen )
c = afx->helpbuf[afx->helpidx++];
else if( (c=iobuf_get(a)) == -1 )
if( (c=iobuf_get(a)) == -1 )
break;
} while( ++idx < 4 );
if( c == -1 ) {
@ -913,9 +1094,7 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
for(rc=0;!rc;) {
rc = 0 /*check_trailer( &fhdr, c )*/;
if( !rc ) {
if( afx->helpidx < afx->helplen )
c = afx->helpbuf[afx->helpidx++];
else if( (c=iobuf_get(a)) == -1 )
if( (c=iobuf_get(a)) == -1 )
rc = 2;
}
}
@ -955,7 +1134,7 @@ armor_filter( void *opaque, int control,
int idx, idx2;
size_t n=0;
u32 crc;
#if 0
#if 1
static FILE *fp ;
if( !fp ) {
@ -967,7 +1146,14 @@ armor_filter( void *opaque, int control,
if( DBG_FILTER )
log_debug("armor-filter: control: %d\n", control );
if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) {
for( n=0; n < size; n++ ) {
n = 0;
if( afx->buffer_len ) {
for(; n < size && afx->buffer_pos < afx->buffer_len; n++ )
buf[n++] = afx->buffer[afx->buffer_pos++];
if( afx->buffer_pos >= afx->buffer_len )
afx->buffer_len = 0;
}
for(; n < size; n++ ) {
if( (c=iobuf_get(a)) == -1 )
break;
buf[n] = c & 0xff;
@ -985,12 +1171,12 @@ armor_filter( void *opaque, int control,
else if( !afx->inp_checked ) {
rc = check_input( afx, a );
if( afx->inp_bypass ) {
for( n=0; n < size && n < afx->helplen; n++ )
buf[n] = afx->helpbuf[n];
for(n=0; n < size && afx->buffer_pos < afx->buffer_len; n++ )
buf[n++] = afx->buffer[afx->buffer_pos++];
if( afx->buffer_pos >= afx->buffer_len )
afx->buffer_len = 0;
if( !n )
rc = -1;
assert( n == afx->helplen );
afx->helplen = 0;
}
else if( afx->faked ) {
unsigned hashes = afx->hashes;
@ -1046,7 +1232,7 @@ armor_filter( void *opaque, int control,
}
else
rc = radix64_read( afx, a, &n, buf, size );
#if 0
#if 1
if( n )
if( fwrite(buf, n, 1, fp ) != 1 )
BUG();
@ -1181,6 +1367,8 @@ armor_filter( void *opaque, int control,
}
else if( !afx->any_data && !afx->inp_bypass )
log_error(_("no valid OpenPGP data found.\n"));
m_free( afx->buffer );
afx->buffer = NULL;
}
else if( control == IOBUFCTRL_DESC )
*(char**)buf = "armor_filter";

View File

@ -266,8 +266,8 @@ handle_compressed( PKT_compressed *cd,
rc = callback(cd->buf, passthru );
else
rc = proc_packets(cd->buf);
iobuf_pop_filter( cd->buf, compress_filter, &cfx );
#if 0
iobuf_pop_filter( cd->buf, compress_filter, &cfx );
if( cd->len )
iobuf_set_limit( cd->buf, 0 ); /* disable the readlimit */
else

View File

@ -79,7 +79,7 @@ decrypt_data( PKT_encrypted *ed, DEK *dek )
cipher_setiv( dfx.cipher_hd, NULL );
if( ed->len ) {
iobuf_set_limit( ed->buf, ed->len );
/*iobuf_set_limit( ed->buf, ed->len );*/
for(i=0; i < (blocksize+2) && ed->len; i++, ed->len-- )
temp[i] = iobuf_get(ed->buf);
@ -100,11 +100,13 @@ decrypt_data( PKT_encrypted *ed, DEK *dek )
}
iobuf_push_filter( ed->buf, decode_filter, &dfx );
proc_packets(ed->buf);
#if 0
iobuf_pop_filter( ed->buf, decode_filter, &dfx );
if( ed->len )
iobuf_set_limit( ed->buf, 0 ); /* disable the readlimit */
else
iobuf_clear_eof( ed->buf );
#endif
ed->buf = NULL;
cipher_close(dfx.cipher_hd);
return 0;

View File

@ -29,23 +29,32 @@ typedef struct {
} md_filter_context_t;
typedef struct {
int status;
int what;
int only_keyblocks; /* skip all headers but ".... key block" */
/* these fields may be initialized */
int what; /* what kind of armor headers to write */
int only_keyblocks; /* skip all headers but ".... key block" */
const char *hdrlines; /* write these headerlines */
/* the following fields must be initialized to zero */
int inp_checked; /* set if the input has been checked */
int inp_bypass; /* set if the input is not armored */
int in_cleartext; /* clear text message */
int not_dash_escaped; /* clear text is not dash escaped */
int hashes; /* detected hash algorithms */
int faked; /* we are faking a literal data packet */
int truncated; /* number of truncated lines */
byte *buffer; /* malloced buffer */
unsigned buffer_size; /* and size of this buffer */
unsigned buffer_len; /* used length of the buffer */
unsigned buffer_pos; /* read position */
byte radbuf[4];
int idx, idx2;
int idx, idx2;
u32 crc;
byte helpbuf[100];
int helpidx, helplen;
unsigned empty; /* empty line counter */
int hashes; /* detected hash algorithms */
int faked;
int parse_state;
int inp_checked; /* set if inp has been checked */
int inp_bypass; /* set if the input is not armored */
int any_data;
const char *hdrlines;
int not_dash_escaped;
int status; /* an internal state flag */
int any_data; /* any valid armored data seen */
unsigned empty; /* empty line counter USED??? */
} armor_filter_context_t;

View File

@ -626,6 +626,16 @@ get_seckey( PKT_secret_key *sk, u32 *keyid )
return rc;
}
/****************
* Get the primary secret key and store it into sk
* Note: This function does not unprotect the key!
*/
int
get_primary_seckey( PKT_secret_key *sk, u32 *keyid )
{
return lookup_sk( sk, 11, keyid, NULL, 1 );
}
/****************
* Check whether the secret key is available
* Returns: 0 := key is available

View File

@ -138,6 +138,7 @@ int get_pubkey_byname( GETKEY_CTX *rx, PKT_public_key *pk,
int get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock );
void get_pubkey_end( GETKEY_CTX ctx );
int get_seckey( PKT_secret_key *sk, u32 *keyid );
int get_primary_seckey( PKT_secret_key *sk, u32 *keyid );
int get_pubkey_byfprint( PKT_public_key *pk, const byte *fprint,
size_t fprint_len );
int get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint,

View File

@ -131,6 +131,7 @@ typedef struct {
byte version;
byte pubkey_algo; /* algorithm used for public key scheme */
byte pubkey_usage;
byte is_primary;
byte is_protected; /* The secret info is protected and must */
/* be decrypted before use, the protected */
/* MPIs are simply (void*) pointers to memory */

View File

@ -1201,6 +1201,7 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
sk->expiredate = expiredate;
sk->hdrbytes = hdrlen;
sk->version = version;
sk->is_primary = pkttype == PKT_SECRET_KEY;
sk->pubkey_algo = algorithm;
sk->pubkey_usage = 0; /* not yet used */
}

View File

@ -147,16 +147,25 @@ passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode )
if( !get_pubkey( pk, keyid ) ) {
const char *s = pubkey_algo_to_string( pk->pubkey_algo );
tty_printf( _("(%u-bit %s key, ID %08lX, created %s)\n"),
tty_printf( _("%u-bit %s key, ID %08lX, created %s"),
nbits_from_pk( pk ), s?s:"?", (ulong)keyid[1],
strtimestamp(pk->timestamp) );
if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
&& keyid[1] != keyid[3] )
tty_printf( _(" (main key ID %08lX)"), (ulong)keyid[3] );
tty_printf("\n");
}
tty_printf("\n");
free_public_key( pk );
}
else if( keyid && !next_pw ) {
char buf[20];
char buf[50];
sprintf( buf, "%08lX%08lX", (ulong)keyid[0], (ulong)keyid[1] );
if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
&& keyid[1] != keyid[3] )
sprintf( buf+strlen(buf), " %08lX%08lX",
(ulong)keyid[2], (ulong)keyid[3] );
write_status_text( STATUS_NEED_PASSPHRASE, buf );
}

View File

@ -264,7 +264,7 @@ _("Could not find a valid trust path to the key. Let's see whether we\n"
else if( !changed )
tty_printf(_("No trust values changed.\n\n") );
return any? 0:-1;
return changed? 0:-1;
}
/****************

View File

@ -23,6 +23,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "util.h"
#include "memory.h"
#include "options.h"
@ -137,7 +138,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
goto leave;
}
if( mfx->md ) {
if( convert && clearsig )
if( 0 && convert && clearsig )
special_md_putc(mfx->md, c, &special_state );
else
md_putc(mfx->md, c );
@ -157,7 +158,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
else {
while( (c = iobuf_get(pt->buf)) != -1 ) {
if( mfx->md ) {
if( convert && clearsig )
if( 0 && convert && clearsig )
special_md_putc(mfx->md, c, &special_state );
else
md_putc(mfx->md, c );
@ -173,9 +174,9 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
}
}
}
iobuf_clear_eof(pt->buf);
pt->buf = NULL;
}
if( mfx->md && convert && clearsig )
if( 0 && mfx->md && convert && clearsig )
special_md_putc(mfx->md, -1, &special_state ); /* flush */
if( fp && fp != stdout && fclose(fp) ) {

View File

@ -44,7 +44,7 @@ do_check( PKT_secret_key *sk )
if( sk->is_protected ) { /* remove the protection */
DEK *dek = NULL;
u32 keyid[2];
u32 keyid[4]; /* 4! because we need two of them */
CIPHER_HANDLE cipher_hd=NULL;
PKT_secret_key *save_sk;
char save_iv[8];
@ -58,6 +58,13 @@ do_check( PKT_secret_key *sk )
return G10ERR_CIPHER_ALGO;
}
keyid_from_sk( sk, keyid );
keyid[2] = keyid[3] = 0;
if( !sk->is_primary ) {
PKT_secret_key *sk2 = m_alloc_clear( sizeof *sk2 );
if( !get_primary_seckey( sk2, keyid ) )
keyid_from_sk( sk2, keyid+2 );
free_secret_key( sk2 );
}
dek = passphrase_to_dek( keyid, sk->protect.algo,
&sk->protect.s2k, 0 );
cipher_hd = cipher_open( sk->protect.algo,

View File

@ -217,6 +217,7 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest )
result = encode_md_value( pk->pubkey_algo, digest, sig->digest_algo,
mpi_get_nbits(pk->pkey[0]));
ctx.sig = sig;
ctx.md = digest;
rc = pubkey_verify( pk->pubkey_algo, result, sig->data, pk->pkey,

View File

@ -389,11 +389,25 @@ tdbio_cancel_transaction()
**************** cached I/O functions ******************
********************************************************/
static void
cleanup(void)
{
if( lockname ) {
release_dotlock(lockname);
lockname = NULL;
}
}
int
tdbio_set_dbname( const char *new_dbname, int create )
{
char *fname;
static int initialized = 0;
if( !initialized ) {
atexit( cleanup );
initialized = 1;
}
fname = new_dbname? m_strdup( new_dbname )
: make_filename(opt.homedir, "trustdb.gpg", NULL );
@ -480,14 +494,6 @@ tdbio_get_dbname()
}
static void
cleanup(void)
{
if( lockname ) {
release_dotlock(lockname);
lockname = NULL;
}
}
static void
open_db()
@ -504,7 +510,6 @@ open_db()
log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
log_fatal( _("%s: invalid trustdb\n"), db_name );
atexit( cleanup );
}

View File

@ -1,3 +1,7 @@
Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* cipher.h (MD_BUFFER_SIZE): Removed.
Mon Dec 14 21:18:49 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* types.h: fix for SUNPRO_C

View File

@ -75,15 +75,13 @@ struct cipher_handle_s { char does_not_matter[1]; };
#define CIPHER_MODE_AUTO_CFB 4
#define CIPHER_MODE_DUMMY 5 /* used with algo DUMMY for no encryption */
#define MD_BUFFER_SIZE 512
typedef struct {
byte buffer[MD_BUFFER_SIZE];
int bufcount;
int secure;
FILE *debug;
struct md_digest_list_s *list;
int bufcount;
int bufsize;
byte buffer[1];
} *MD_HANDLE;
@ -118,9 +116,9 @@ const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen );
void md_start_debug( MD_HANDLE a, const char *suffix );
void md_stop_debug( MD_HANDLE a );
#define md_is_secure(a) ((a)->secure)
#define md_putc(h,c) \
#define md_putc(h,c) \
do { \
if( (h)->bufcount == MD_BUFFER_SIZE ) \
if( (h)->bufcount == (h)->bufsize ) \
md_write( (h), NULL, 0 ); \
(h)->buffer[(h)->bufcount++] = (c) & 0xff; \
} while(0)

View File

@ -158,6 +158,7 @@ void mpi_putbyte( MPI a, unsigned index, int value );
unsigned mpi_trailing_zeros( MPI a );
/*-- mpi-bit.c --*/
void mpi_normalize( MPI a );
unsigned mpi_get_nbits( MPI a );
int mpi_test_bit( MPI a, unsigned n );
void mpi_set_bit( MPI a, unsigned n );

View File

@ -1,3 +1,10 @@
Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* mpi-bit.c (mpi_normalize): New.
(mpi_get_nbits): Normalize the MPI.
* mpi-bit.c (mpi_cmp): Normalize the MPI before the compare.
Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* config.links: Moved the case for powerpc*linux

View File

@ -48,7 +48,19 @@ __clz_tab[] =
#define A_LIMB_1 ((mpi_limb_t)1)
/****************
* Sometimes we have MSL (most significant limbs) which are 0;
* this is for some reasons not good, so this function removes them.
*/
void
mpi_normalize( MPI a )
{
if( mpi_is_protected(a) )
return;
for( ; a->nlimbs && !a->d[a->nlimbs-1]; a->nlimbs-- )
;
}
@ -67,6 +79,7 @@ mpi_get_nbits( MPI a )
return n;
}
mpi_normalize( a );
if( a->nlimbs ) {
mpi_limb_t alimb = a->d[a->nlimbs-1];
if( alimb )

View File

@ -46,27 +46,28 @@ mpi_cmp_ui( MPI u, unsigned long v )
int
mpi_cmp( MPI u, MPI v )
{
mpi_size_t usize = u->nlimbs;
mpi_size_t vsize = v->nlimbs;
mpi_size_t usize, vsize;
int cmp;
/* FIXME: are the numbers always normalized? */
mpi_normalize( u );
mpi_normalize( v );
usize = u->nlimbs;
vsize = v->nlimbs;
if( !u->sign && v->sign )
return 1;
else if( u->sign && !v->sign )
if( u->sign && !v->sign )
return -1;
else if( usize != vsize && !u->sign && !v->sign )
if( usize != vsize && !u->sign && !v->sign )
return usize - vsize;
else if( usize != vsize && u->sign && v->sign )
if( usize != vsize && u->sign && v->sign )
return vsize + usize;
else if( !usize )
if( !usize )
return 0;
else if( !(cmp=mpihelp_cmp( u->d, v->d, usize )) )
if( !(cmp=mpihelp_cmp( u->d, v->d, usize )) )
return 0;
else if( (cmp < 0?1:0) == (u->sign?1:0))
if( (cmp < 0?1:0) == (u->sign?1:0))
return 1;
else
return -1;
return -1;
}

View File

@ -513,7 +513,7 @@ msgstr "|N|Die Komprimierverfahren N benutzen"
#: g10/g10.c:254
msgid "throw keyid field of encrypted packets"
msgstr "entferne die AbsenderI-ID verschlüsselter Pakete"
msgstr "entferne die Absender-ID verschlüsselter Pakete"
#: g10/g10.c:262
msgid ""

View File

@ -1,3 +1,11 @@
Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* iobuf.c (iobuf_clear_eof): Removed.
(underflow): Changed the eof handling.
(iobuf_pop_filter): Made static and renamed to pop_filter.
* iobuf.c (iobuf_read_line): New.
Sun Jan 3 15:28:44 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* dotlock.c (make_dotlock): print another informal message.

View File

@ -1,5 +1,5 @@
/* [argparse.c wk 17.06.97] Argument Parser for option handling
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998,1999 Free Software Foundation, Inc.
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
@ -873,7 +873,7 @@ default_strusage( int level )
switch( level ) {
case 11: p = "foo"; break;
case 13: p = "0.0"; break;
case 14: p = "Copyright (C) 1998 Free Software Foundation, Inc."; break;
case 14: p = "Copyright (C) 1999 Free Software Foundation, Inc."; break;
case 15: p =
"This program comes with ABSOLUTELY NO WARRANTY.\n"
"This is free software, and you are welcome to redistribute it\n"

View File

@ -1,5 +1,5 @@
/* iobuf.c - file handling
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998,1999 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -434,7 +434,7 @@ iobuf_close( IOBUF a )
if( a && a->directfp ) {
fclose( a->directfp );
if( DBG_IOBUF )
log_debug("iobuf-close -> %p\n", a->directfp );
log_debug("iobuf_close -> %p\n", a->directfp );
return 0;
}
@ -722,9 +722,10 @@ iobuf_push_filter( IOBUF a,
/****************
* Remove an i/o filter.
* Only needed for iobuf_seek?
*/
int
iobuf_pop_filter( IOBUF a, int (*f)(void *opaque, int control,
static int
pop_filter( IOBUF a, int (*f)(void *opaque, int control,
IOBUF chain, byte *buf, size_t *len), void *ov )
{
IOBUF b;
@ -798,16 +799,26 @@ underflow(IOBUF a)
size_t len;
int rc;
/*log_debug("iobuf-%d.%d: underflow: start=%lu len=%lu\n",
a->no, a->subno, (ulong)a->d.start, (ulong)a->d.len );*/
assert( a->d.start == a->d.len );
if( a->usage == 3 )
return -1; /* EOF because a temp buffer can't do an underflow */
if( a->filter_eof ) {
if( a->chain ) {
IOBUF b = a->chain;
m_free(a->d.buf);
memcpy(a, b, sizeof *a);
m_free(b);
if( DBG_IOBUF )
log_debug("iobuf-%d.%d: popped filter in underflow\n",
a->no, a->subno );
}
else
a->filter_eof = 0;
if( DBG_IOBUF )
log_debug("iobuf-%d.%d: filter eof\n", a->no, a->subno );
return -1;
log_debug("iobuf-%d.%d: underflow: eof (due to filter eof)\n",
a->no, a->subno );
return -1; /* return one(!) EOF */
}
if( a->error ) {
if( DBG_IOBUF )
@ -822,8 +833,6 @@ underflow(IOBUF a)
if( len < a->d.size ) {
if( ferror(fp) )
a->error = 1;
else if( feof( fp ) )
a->filter_eof = 1;
}
a->d.len = len;
a->d.start = 0;
@ -835,47 +844,48 @@ underflow(IOBUF a)
len = a->d.size;
rc = a->filter( a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
a->d.buf, &len );
if( DBG_IOBUF )
log_debug("iobuf-%d.%d: underflow: req=%lu got=%lu rc=%d\n",
a->no, a->subno, (ulong)a->d.size, (ulong)len, rc );
if( a->usage == 1 && rc == -1 ) { /* EOF: we can remove the filter */
size_t dummy_len;
/* and tell the filter to free it self */
if( a->filter != file_filter ) {
if( (rc = a->filter(a->filter_ov, IOBUFCTRL_FREE, a->chain,
NULL, &dummy_len)) )
log_error("IOBUFCTRL_FREE failed: %s\n", g10_errstr(rc) );
a->filter = NULL;
a->desc = NULL;
a->filter_ov = NULL;
}
/* and tell the filter to free itself */
if( (rc = a->filter(a->filter_ov, IOBUFCTRL_FREE, a->chain,
NULL, &dummy_len)) )
log_error("IOBUFCTRL_FREE failed: %s\n", g10_errstr(rc) );
a->filter = NULL;
a->desc = NULL;
a->filter_ov = NULL;
a->filter_eof = 1;
if( !len && a->chain ) {
IOBUF b = a->chain;
m_free(a->d.buf);
memcpy(a,b, sizeof *a);
m_free(b);
if( DBG_IOBUF )
log_debug("iobuf-%d.%d: popped filter in underflow (!len)\n",
a->no, a->subno );
}
}
else if( rc )
a->error = 1;
if( !len )
if( !len ) {
if( DBG_IOBUF )
log_debug("iobuf-%d.%d: underflow: eof\n", a->no, a->subno );
return -1;
}
a->d.len = len;
a->d.start = 0;
return a->d.buf[a->d.start++];
}
else
else {
if( DBG_IOBUF )
log_debug("iobuf-%d.%d: underflow: eof (no filter)\n",
a->no, a->subno );
return -1; /* no filter; return EOF */
}
void
iobuf_clear_eof(IOBUF a)
{
if( a->directfp )
return;
assert(a->usage == 1);
if( a->filter )
log_info("iobuf-%d.%d: clear_eof `%s' with enabled filter\n", a->no, a->subno, a->desc );
if( !a->filter_eof )
log_info("iobuf-%d.%d: clear_eof `%s' with no EOF pending\n", a->no, a->subno, a->desc );
iobuf_pop_filter(a, NULL, NULL);
}
}
@ -1209,8 +1219,10 @@ iobuf_seek( IOBUF a, ulong newpos )
a->ntotal = newpos;
a->error = 0;
/* remove filters, but the last */
if( a->chain )
log_debug("pop_filter called in iobuf_seek - please report\n");
while( a->chain )
iobuf_pop_filter( a, a->filter, NULL );
pop_filter( a, a->filter, NULL );
return 0;
}
@ -1263,7 +1275,8 @@ iobuf_set_block_mode( IOBUF a, size_t n )
assert( a->usage == 1 || a->usage == 2 );
ctx->usage = a->usage;
if( !n ) {
iobuf_pop_filter(a, block_filter, NULL );
log_debug("pop_filter called in set_block_mode - please report\n");
pop_filter(a, block_filter, NULL );
}
else {
ctx->size = n; /* only needed for usage 2 */
@ -1283,7 +1296,8 @@ iobuf_set_partial_block_mode( IOBUF a, size_t len )
assert( a->usage == 1 || a->usage == 2 );
ctx->usage = a->usage;
if( !len ) {
iobuf_pop_filter(a, block_filter, NULL );
log_debug("pop_filter called in set_partial_block_mode - please report\n");
pop_filter(a, block_filter, NULL );
}
else {
ctx->partial = 1;
@ -1307,4 +1321,62 @@ iobuf_in_block_mode( IOBUF a )
}
/****************
* Same as fgets() but if the buffer is too short a larger one will
* be allocated up to some limit *max_length.
* A line is considered a byte stream ending in a LF.
* Returns the length of the line. EOF is indicated by a line of
* length zero. The last LF may be missing due to an EOF.
* is max_length is zero on return, the line has been truncated.
*
* Note: The buffer is allocated with enough space to append a CR,LF,EOL
*/
unsigned
iobuf_read_line( IOBUF a, byte **addr_of_buffer,
unsigned *length_of_buffer, unsigned *max_length )
{
int c;
char *buffer = *addr_of_buffer;
unsigned length = *length_of_buffer;
unsigned nbytes = 0;
unsigned maxlen = *max_length;
char *p;
if( !buffer ) { /* must allocate a new buffer */
length = 256;
buffer = m_alloc( length );
*addr_of_buffer = buffer;
*length_of_buffer = length;
}
length -= 3; /* reserve 3 bytes (cr,lf,eol) */
p = buffer;
while( (c=iobuf_get(a)) != -1 ) {
if( nbytes == length ) { /* increase the buffer */
if( length > maxlen ) { /* this is out limit */
/* skip the rest of the line */
while( c != '\n' && (c=iobuf_get(a)) != -1 )
;
*p++ = '\n'; /* always append a LF (we have reserved space) */
nbytes++;
*max_length = 0; /* indicate truncation */
break;
}
length += 3; /* correct for the reserved byte */
length += length < 1024? 256 : 1024;
buffer = m_realloc( buffer, length );
*addr_of_buffer = buffer;
*length_of_buffer = length;
length -= 3; /* and reserve again */
p = buffer + nbytes;
}
*p++ = c;
nbytes++;
if( c == '\n' )
break;
}
*p = 0; /* make sure the line is a string */
return nbytes;
}