diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 20 | ||||
-rw-r--r-- | g10/armor.c | 420 | ||||
-rw-r--r-- | g10/compress.c | 2 | ||||
-rw-r--r-- | g10/encr-data.c | 4 | ||||
-rw-r--r-- | g10/filter.h | 39 | ||||
-rw-r--r-- | g10/getkey.c | 10 | ||||
-rw-r--r-- | g10/keydb.h | 1 | ||||
-rw-r--r-- | g10/packet.h | 1 | ||||
-rw-r--r-- | g10/parse-packet.c | 1 | ||||
-rw-r--r-- | g10/passphrase.c | 13 | ||||
-rw-r--r-- | g10/pkclist.c | 2 | ||||
-rw-r--r-- | g10/plaintext.c | 9 | ||||
-rw-r--r-- | g10/seckey-cert.c | 9 | ||||
-rw-r--r-- | g10/sig-check.c | 1 | ||||
-rw-r--r-- | g10/tdbio.c | 23 |
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 ); } |