aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog20
-rw-r--r--g10/armor.c420
-rw-r--r--g10/compress.c2
-rw-r--r--g10/encr-data.c4
-rw-r--r--g10/filter.h39
-rw-r--r--g10/getkey.c10
-rw-r--r--g10/keydb.h1
-rw-r--r--g10/packet.h1
-rw-r--r--g10/parse-packet.c1
-rw-r--r--g10/passphrase.c13
-rw-r--r--g10/pkclist.c2
-rw-r--r--g10/plaintext.c9
-rw-r--r--g10/seckey-cert.c9
-rw-r--r--g10/sig-check.c1
-rw-r--r--g10/tdbio.c23
15 files changed, 405 insertions, 150 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 69c109209..532fa472b 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,23 @@
+Thu Jan 7 18:00:58 CET 1999 Werner Koch <[email protected]>
+
+ * 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 <[email protected]>
* revoke.c (gen_revoke): Removed compression.
diff --git a/g10/armor.c b/g10/armor.c
index cddddf031..be0e69bf0 100644
--- a/g10/armor.c
+++ b/g10/armor.c
@@ -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;
+
+ /* 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;
+ return 0;
+ }
- if( state != fhdrENDClearsig )
- state = fhdrHASArmor;
+ if( !len ) {
+ return -1; /* eof */
+ }
- 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:
+ /* (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;
- afx->helplen = n;
- break;
+ return 0;
+ }
- case fhdrERROR:
- invalid_armor();
- break;
+ /* 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;
+ }
+ }
- 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;
- afx->faked = 1;
- break;
- case fhdrTEXT:
- afx->helplen = n;
- afx->helpidx = 0;
+ if( rc )
+ invalid_armor();
+ else if( afx->in_cleartext ) {
+ afx->faked = 1;
+ }
+ 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;
- 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( 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;
}
- if( state == fhdrEOF ) {
- rc = -1;
+
+ /* 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;
}
- /* 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;
-
- 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( !maxlen )
+ afx->truncated++;
+ afx->buffer_len = trim_trailing_spaces( afx->buffer, afx->buffer_len );
+ p = afx->buffer;
+ n = afx->buffer_len;
+
+ 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";
diff --git a/g10/compress.c b/g10/compress.c
index 31cc4c500..5aad678d6 100644
--- a/g10/compress.c
+++ b/g10/compress.c
@@ -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
diff --git a/g10/encr-data.c b/g10/encr-data.c
index 06c686ba3..d44d6c245 100644
--- a/g10/encr-data.c
+++ b/g10/encr-data.c
@@ -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;
diff --git a/g10/filter.h b/g10/filter.h
index 75d629e68..46e3f8a54 100644
--- a/g10/filter.h
+++ b/g10/filter.h
@@ -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;
diff --git a/g10/getkey.c b/g10/getkey.c
index 6715e0d59..aa2a8ce34 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -627,6 +627,16 @@ get_seckey( PKT_secret_key *sk, u32 *keyid )
}
/****************
+ * 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
* G10ERR_NO_SECKEY := not availabe
diff --git a/g10/keydb.h b/g10/keydb.h
index 1d1c6c26c..4a18b7ea0 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -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,
diff --git a/g10/packet.h b/g10/packet.h
index 1f5f57416..06fb92e8f 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -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 */
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 5bee45b32..3acce404b 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -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 */
}
diff --git a/g10/passphrase.c b/g10/passphrase.c
index 7f975b840..785d21df5 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -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 );
}
diff --git a/g10/pkclist.c b/g10/pkclist.c
index 6c08a6a45..f579fc37f 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -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;
}
/****************
diff --git a/g10/plaintext.c b/g10/plaintext.c
index ab750e444..c5c6685f4 100644
--- a/g10/plaintext.c
+++ b/g10/plaintext.c
@@ -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) ) {
diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c
index 6adfafdf4..5edebf782 100644
--- a/g10/seckey-cert.c
+++ b/g10/seckey-cert.c
@@ -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,
diff --git a/g10/sig-check.c b/g10/sig-check.c
index 355f6cdef..2e9fd47eb 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -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,
diff --git a/g10/tdbio.c b/g10/tdbio.c
index 094f23c87..b69d6c3f0 100644
--- a/g10/tdbio.c
+++ b/g10/tdbio.c
@@ -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 );
}