diff options
author | Werner Koch <wk@gnupg.org> | 1998-09-28 21:25:31 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 1998-09-28 21:25:31 +0200 |
commit | 41fa8a3345aecf9b85c1eebb33f9b961a558db1c (patch) | |
tree | 4f5745dc77207f40dabd7f9a176b7255e8994223 /g10 | |
parent | . (diff) | |
download | gnupg2-41fa8a3345aecf9b85c1eebb33f9b961a558db1c.tar.xz gnupg2-41fa8a3345aecf9b85c1eebb33f9b961a558db1c.zip |
*** empty log message ***
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 94 | ||||
-rw-r--r-- | g10/Makefile.am | 2 | ||||
-rw-r--r-- | g10/OPTIONS | 2 | ||||
-rw-r--r-- | g10/armor.c | 48 | ||||
-rw-r--r-- | g10/encode.c | 16 | ||||
-rw-r--r-- | g10/filter.h | 2 | ||||
-rw-r--r-- | g10/g10.c | 116 | ||||
-rw-r--r-- | g10/getkey.c | 27 | ||||
-rw-r--r-- | g10/gpgd.c | 9 | ||||
-rw-r--r-- | g10/import.c | 15 | ||||
-rw-r--r-- | g10/keydb.h | 4 | ||||
-rw-r--r-- | g10/keyedit.c | 12 | ||||
-rw-r--r-- | g10/keygen.c | 12 | ||||
-rw-r--r-- | g10/ks-proto.c | 299 | ||||
-rw-r--r-- | g10/mainproc.c | 4 | ||||
-rw-r--r-- | g10/options.h | 3 | ||||
-rw-r--r-- | g10/parse-packet.c | 3 | ||||
-rw-r--r-- | g10/passphrase.c | 138 | ||||
-rw-r--r-- | g10/pkclist.c | 16 | ||||
-rw-r--r-- | g10/seckey-cert.c | 2 | ||||
-rw-r--r-- | g10/sig-check.c | 4 | ||||
-rw-r--r-- | g10/status.c | 17 | ||||
-rw-r--r-- | g10/trustdb.c | 24 |
23 files changed, 453 insertions, 416 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index 84ebb78bd..e767f75be 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,21 +1,67 @@ -Fri Sep 18 16:50:32 1998 Werner Koch (wk@(none)) +Mon Sep 28 12:57:12 1998 Werner Koch (wk@isil.d.shuttle.de) + + * g10.c (verify_own_keys): Add warning if a key is not protected. + + * passphrase (hash_passphrase): Fixed iterated+salted mode and + setup for keysizes > hashsize. + + * g10.c (main): New options: --s2k-{cipher,digest,mode}. + +Fri Sep 25 09:34:23 1998 Werner Koch (wk@isil.d.shuttle.de) + + * g10.c: Chnaged some help texts. + +Tue Sep 22 19:34:39 1998 Werner Koch (wk@isil.d.shuttle.de) + + * passphrase.c (read_passphrase_from_fd): fixed bug for long + passphrases. + +Mon Sep 21 11:28:05 1998 Werner Koch (wk@(none)) + + * getkey.c (lookup): Add code to use the sub key if the primary one + does not match the usage. + + * armor.c (armor_filter): New error message: no valid data found. + (radix64_read): Changes to support multiple messages. + (i18n.h): New. + * mainproc.c (add_onepass_sig): bug fix. + +Mon Sep 21 08:03:16 1998 Werner Koch (wk@isil.d.shuttle.de) + + * pkclist.c (do_we_trust): Add keyid to most messages. + + * passphrase.c (read_passphrase_from_fd): New. + (have_static_passphrase): New + (get_passphrase_fd): Removed. + (set_passphrase_fd): Removed. + * g10.c (main): passphrase is now read here. + + * keyedit.c (keyedit_menu): "help" texts should now translate fine. + +Mon Sep 21 06:40:02 1998 Werner Koch (wk@isil.d.shuttle.de) + + * encode.c (encode_simple): Now disables compression + when --rfc1991 is used. + (encode_crypt): Ditto. + +Fri Sep 18 16:50:32 1998 Werner Koch (wk@isil.d.shuttle.de) * getkey.c (merge_key_and_selfsig): New. -Fri Sep 18 10:20:11 1998 Werner Koch (wk@(none)) +Fri Sep 18 10:20:11 1998 Werner Koch (wk@isil.d.shuttle.de) - * pkclist.c (select_algo_from_prefs): Removed 3DEs kludge. + * pkclist.c (select_algo_from_prefs): Removed 3DES kludge. * seskey.c (make_session_key): Fixed SERIOUS bug introduced by adding the weak key detection code. * sign.c (sign_file): Changed aremor header in certain cases. -Tue Sep 15 17:52:55 1998 Werner Koch (wk@(none)) +Tue Sep 15 17:52:55 1998 Werner Koch (wk@isil.d.shuttle.de) * mainproc.c (check_sig_and_print): Replaced ascime by asctimestamp. -Mon Sep 14 11:40:52 1998 Werner Koch (wk@(none)) +Mon Sep 14 11:40:52 1998 Werner Koch (wk@isil.d.shuttle.de) * seskey.c (make_session_key): Now detects weak keys. @@ -24,17 +70,17 @@ Mon Sep 14 11:40:52 1998 Werner Koch (wk@(none)) * plaintext.c (handle_plaintext): Does no anymore suppress CR from cleartext signed messages. -Sun Sep 13 12:54:29 1998 Werner Koch (wk@(none)) +Sun Sep 13 12:54:29 1998 Werner Koch (wk@isil.d.shuttle.de) * trustdb.c (insert_trust_record): Fixed a stupid bug in the free liunked list loops. -Sat Sep 12 15:49:16 1998 Werner Koch (wk@(none)) +Sat Sep 12 15:49:16 1998 Werner Koch (wk@isil.d.shuttle.de) * status.c (remove_shmid): New. (init_shm_comprocess): Now sets permission to the real uid. -Wed Sep 9 11:15:03 1998 Werner Koch (wk@(none)) +Wed Sep 9 11:15:03 1998 Werner Koch (wk@isil.d.shuttle.de) * packet.h (PKT_pubkey_enc): New flah throw_keyid, and add logic to implement it. @@ -42,11 +88,11 @@ Wed Sep 9 11:15:03 1998 Werner Koch (wk@(none)) * getkey.c (enum_secret_keys): Add new ar and changed all callers. -Tue Sep 8 20:04:09 1998 Werner Koch (wk@(none)) +Tue Sep 8 20:04:09 1998 Werner Koch (wk@isil.d.shuttle.de) * delkey.c (delete_key): Moved from keyedit.c. -Mon Sep 7 16:37:52 1998 Werner Koch (wk@(none)) +Mon Sep 7 16:37:52 1998 Werner Koch (wk@isil.d.shuttle.de) * build-packet.c (calc_length_header): New arg new_ctb to correctly calculate the length of new style packets. @@ -55,7 +101,7 @@ Mon Sep 7 16:37:52 1998 Werner Koch (wk@(none)) * pkclist.c (select_algo_from_prefs): 3DEs substitute is now CAST5. -Tue Aug 11 17:54:50 1998 Werner Koch (wk@(none)) +Tue Aug 11 17:54:50 1998 Werner Koch (wk@isil.d.shuttle.de) * build-packet.c (do_secret_key): Fixed handling of old keys. @@ -63,7 +109,7 @@ Tue Aug 11 17:54:50 1998 Werner Koch (wk@(none)) * openfile.c (open_outfile): Changed arguments and all callers. -Tue Aug 11 09:14:35 1998 Werner Koch (wk@(none)) +Tue Aug 11 09:14:35 1998 Werner Koch (wk@isil.d.shuttle.de) * encode.c (encode_simple): Applied option set-filename and comment. (encode_crypt): Ditto. @@ -87,7 +133,7 @@ Tue Aug 11 09:14:35 1998 Werner Koch (wk@(none)) * status.c (cpr_get_answer_is_yes): add display_help. -Mon Aug 10 10:11:28 1998 Werner Koch (wk@(none)) +Mon Aug 10 10:11:28 1998 Werner Koch (wk@isil.d.shuttle.de) * getkey.c (lookup_sk): Now always returns the primary if arg primary is true. @@ -96,15 +142,15 @@ Mon Aug 10 10:11:28 1998 Werner Koch (wk@(none)) (get_seckey_byname): Ditto. -Mon Aug 10 08:34:03 1998 Werner Koch (wk@(none)) +Mon Aug 10 08:34:03 1998 Werner Koch (wk@isil.d.shuttle.de) * keyid.c (pubkey_letter): ELG_E is now a small g. -Sat Aug 8 17:26:12 1998 Werner Koch (wk@(none)) +Sat Aug 8 17:26:12 1998 Werner Koch (wk@isil.d.shuttle.de) * openfile (overwrite_filep): Changed semantics and all callers. -Sat Aug 8 12:17:07 1998 Werner Koch (wk@(none)) +Sat Aug 8 12:17:07 1998 Werner Koch (wk@isil.d.shuttle.de) * status.c (display_help): New. @@ -118,7 +164,7 @@ Thu Aug 6 07:34:56 1998 Werner Koch,mobil,,, (wk@tobold) secret keyrings and add additional warning in case of a failed secret keyring operation. -Wed Aug 5 11:54:37 1998 Werner Koch (wk@(none)) +Wed Aug 5 11:54:37 1998 Werner Koch (wk@isil.d.shuttle.de) * g10.c (check_opts): Moved to main. Changed def_cipher_algo semantics and chnaged all users. @@ -131,7 +177,7 @@ Wed Aug 5 11:54:37 1998 Werner Koch (wk@(none)) * build-packet.c (do_secret_key): Ditto. (do_symkey_enc): Ditto. -Tue Aug 4 08:59:10 1998 Werner Koch (wk@(none)) +Tue Aug 4 08:59:10 1998 Werner Koch (wk@isil.d.shuttle.de) * getkey.c (enum_secret_keys): Now returns only primary keys. @@ -142,36 +188,36 @@ Tue Aug 4 08:59:10 1998 Werner Koch (wk@(none)) * sign.c (sign_file): one-pass sigs are now emiited reverse. Preference data is considered when selecting the compress algo. -Wed Jul 29 12:53:03 1998 Werner Koch (wk@(none)) +Wed Jul 29 12:53:03 1998 Werner Koch (wk@isil.d.shuttle.de) * free-packet.c (copy_signature): New. * keygen.c (generate_subkeypair): rewritten * g10.c (aKeyadd): Removed option --add-key -Mon Jul 27 10:37:28 1998 Werner Koch (wk@(none)) +Mon Jul 27 10:37:28 1998 Werner Koch (wk@isil.d.shuttle.de) * seckey-cert.c (do_check): Additional check on cipher blocksize. (protect_secret_key): Ditto. * encr-data.c: Support for other blocksizes. * cipher.c (write_header): Ditto. -Fri Jul 24 16:47:59 1998 Werner Koch (wk@(none)) +Fri Jul 24 16:47:59 1998 Werner Koch (wk@isil.d.shuttle.de) * kbnode.c (insert_kbnode): Changed semantics and all callers. * keyedit.c : More or less a complete rewrite -Wed Jul 22 17:10:04 1998 Werner Koch (wk@(none)) +Wed Jul 22 17:10:04 1998 Werner Koch (wk@isil.d.shuttle.de) * build-packet.c (write_sign_packet_header): New. -Tue Jul 21 14:37:09 1998 Werner Koch (wk@(none)) +Tue Jul 21 14:37:09 1998 Werner Koch (wk@isil.d.shuttle.de) * import.c (import_one): Now creates a trustdb record. * g10.c (main): New command --check-trustdb -Mon Jul 20 11:15:07 1998 Werner Koch (wk@(none)) +Mon Jul 20 11:15:07 1998 Werner Koch (wk@isil.d.shuttle.de) * genkey.c (generate_keypair): Default key is now DSA with encryption only ElGamal subkey. diff --git a/g10/Makefile.am b/g10/Makefile.am index c6d5b135e..b38037d28 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -71,6 +71,8 @@ gpgm_SOURCES = dearmor.c \ #gpgd_SOURCES = gpgd.c \ # ks-proto.h \ # ks-proto.c \ +# ks-db.c \ +# ks-db.h \ # $(common_source) diff --git a/g10/OPTIONS b/g10/OPTIONS index 9555ce06a..4ec4192e3 100644 --- a/g10/OPTIONS +++ b/g10/OPTIONS @@ -49,7 +49,7 @@ compress-sigs run-as-shm-coprocess [request-locked-shm-size] # very special :-) # You will have to use "--status-fd" too - +# Note: This option dioes only work if given on the command line. set-filename <name> # Set <name> as the filename into the plaintext packet diff --git a/g10/armor.c b/g10/armor.c index 38e1b190d..c72526a98 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -34,6 +34,7 @@ #include "options.h" #include "main.h" #include "status.h" +#include "i18n.h" #define CRCINIT 0xB704CE @@ -51,7 +52,7 @@ static int is_initialized; typedef enum { - fhdrHASArmor, + fhdrHASArmor = 0, fhdrNOArmor, fhdrINIT, fhdrINITCont, @@ -331,12 +332,12 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, if( buf[n-1] == '\r' ) buf[--n] = 0; if( opt.verbose ) { - log_info("armor header: "); + log_info(_("armor header: ")); print_string( stderr, buf, n, 0 ); putc('\n', stderr); } if( clearsig && !(hashes=parse_hash_header( buf )) ) { - log_error("invalid clearsig header\n"); + log_error(_("invalid clearsig header\n")); state = fhdrERROR; } else { @@ -362,7 +363,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, } } else { - log_error("invalid armor header: "); + log_error(_("invalid armor header: ")); print_string( stderr, buf, n, 0 ); putc('\n', stderr); state = fhdrERROR; @@ -371,7 +372,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, else if( c != -1 ) { if( strchr( buf, ':') ) { /* buffer to short, but this is okay*/ if( opt.verbose ) { - log_info("armor header: "); + log_info(_("armor header: ")); print_string( stderr, buf, n, 0 ); fputs("[...]\n", stderr); /* indicate it is truncated */ } @@ -436,7 +437,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, if( hdr_line == BEGIN_SIGNED_MSG_IDX ) clearsig = 1; if( opt.verbose > 1 ) - log_info("armor: %s\n", head_strings[hdr_line]); + log_info(_("armor: %s\n"), head_strings[hdr_line]); break; case fhdrCLEARSIG: @@ -480,7 +481,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, fhdrREADClearsig : fhdrTESTSpaces; } else { - log_error("invalid dash escaped line: "); + log_error(_("invalid dash escaped line: ")); print_string( stderr, buf, n, 0 ); putc('\n', stderr); state = fhdrERROR; @@ -549,7 +550,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, } break; case fhdrERRORShow: - log_error("invalid clear text header: "); + log_error(_("invalid clear text header: ")); print_string( stderr, buf, n, 0 ); putc('\n', stderr); state = fhdrERROR; @@ -779,7 +780,7 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn, break; } else if( (c = asctobin[(c2=c)]) == 255 ) { - log_error("invalid radix64 character %02x skipped\n", c2); + log_error(_("invalid radix64 character %02x skipped\n"), c2); continue; } switch(idx) { @@ -797,7 +798,10 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn, afx->idx = idx; afx->radbuf[0] = val; if( checkcrc ) { - afx->inp_eof = 1; /*assume eof */ + 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++]; @@ -809,7 +813,7 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn, break; } if( c == -1 ) - log_error("premature eof (no CRC)\n"); + log_error(_("premature eof (no CRC)\n")); else { u32 mycrc = 0; idx = 0; @@ -828,15 +832,15 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn, break; } while( ++idx < 4 ); if( c == -1 ) { - log_error("premature eof (in CRC)\n"); + log_error(_("premature eof (in CRC)\n")); rc = G10ERR_INVALID_ARMOR; } else if( idx != 4 ) { - log_error("malformed CRC\n"); + log_error(_("malformed CRC\n")); rc = G10ERR_INVALID_ARMOR; } else if( mycrc != afx->crc ) { - log_error("CRC error; %06lx - %06lx\n", + log_error(_("CRC error; %06lx - %06lx\n"), (ulong)afx->crc, (ulong)mycrc); rc = G10ERR_INVALID_ARMOR; } @@ -855,11 +859,11 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn, if( rc == -1 ) rc = 0; else if( rc == 2 ) { - log_error("premature eof (in Trailer)\n"); + log_error(_("premature eof (in Trailer)\n")); rc = G10ERR_INVALID_ARMOR; } else { - log_error("error in trailer line\n"); + log_error(_("error in trailer line\n")); rc = G10ERR_INVALID_ARMOR; } #endif @@ -874,7 +878,6 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn, return rc; } - /**************** * This filter is used to handle the armor stuff */ @@ -914,13 +917,6 @@ armor_filter( void *opaque, int control, if( size < 15+(4*15) ) /* need space for up to 4 onepass_sigs */ BUG(); /* supplied buffer too short */ - if( afx->inp_eof ) { - *ret_len = 0; - if( DBG_FILTER ) - log_debug("armor-filter: eof due to inp_eof flag\n" ); - return -1; - } - if( afx->faked ) rc = fake_packet( afx, a, &n, buf, size ); else if( !afx->inp_checked ) { @@ -1021,7 +1017,7 @@ armor_filter( void *opaque, int control, } else iobuf_writestr(a, - "Comment: Get GNUPG from ftp://ftp.guug.de/pub/gcrypt/\n"); + "Comment: For info finger gcrypt@ftp.guug.de\n"); if( afx->hdrlines ) iobuf_writestr(a, afx->hdrlines); iobuf_put(a, '\n'); @@ -1120,6 +1116,8 @@ armor_filter( void *opaque, int control, iobuf_writestr(a, tail_strings[afx->what] ); iobuf_writestr(a, "-----\n"); } + else if( !afx->any_data && !afx->inp_bypass ) + log_error(_("no valid RFC1991 or OpenPGP data found.\n")); } else if( control == IOBUFCTRL_DESC ) *(char**)buf = "armor_filter"; diff --git a/g10/encode.c b/g10/encode.c index ae8b26116..bc4742607 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -76,6 +76,7 @@ encode_simple( const char *filename, int mode ) cipher_filter_context_t cfx; armor_filter_context_t afx; compress_filter_context_t zfx; + int do_compress = opt.compress && !opt.rfc1991; memset( &cfx, 0, sizeof cfx); memset( &afx, 0, sizeof afx); @@ -92,12 +93,12 @@ encode_simple( const char *filename, int mode ) cfx.dek = NULL; if( mode ) { s2k = m_alloc_clear( sizeof *s2k ); - s2k->mode = opt.rfc1991? 0:1; + s2k->mode = opt.rfc1991? 0:opt.s2k_mode; s2k->hash_algo = opt.def_digest_algo ? opt.def_digest_algo - : DEFAULT_DIGEST_ALGO; + : opt.s2k_digest_algo; cfx.dek = passphrase_to_dek( NULL, opt.def_cipher_algo ? opt.def_cipher_algo - : DEFAULT_CIPHER_ALGO , s2k, 2 ); + : opt.s2k_cipher_algo , s2k, 2 ); if( !cfx.dek || !cfx.dek->keylen ) { rc = G10ERR_PASSPHRASE; m_free(cfx.dek); @@ -158,13 +159,13 @@ encode_simple( const char *filename, int mode ) pt->buf = inp; pkt.pkttype = PKT_PLAINTEXT; pkt.pkt.plaintext = pt; - cfx.datalen = filesize && !opt.compress ? calc_packet_length( &pkt ) : 0; + cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0; /* register the cipher filter */ if( mode ) iobuf_push_filter( out, cipher_filter, &cfx ); /* register the compress filter */ - if( opt.compress ) + if( do_compress ) iobuf_push_filter( out, compress_filter, &zfx ); /* do the work */ @@ -197,6 +198,7 @@ encode_crypt( const char *filename, STRLIST remusr ) armor_filter_context_t afx; compress_filter_context_t zfx; PK_LIST pk_list; + int do_compress = opt.compress && !opt.rfc1991; memset( &cfx, 0, sizeof cfx); memset( &afx, 0, sizeof afx); @@ -270,12 +272,12 @@ encode_crypt( const char *filename, STRLIST remusr ) pt->buf = inp; pkt.pkttype = PKT_PLAINTEXT; pkt.pkt.plaintext = pt; - cfx.datalen = filesize && !opt.compress? calc_packet_length( &pkt ) : 0; + cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0; /* register the cipher filter */ iobuf_push_filter( out, cipher_filter, &cfx ); /* register the compress filter */ - if( opt.compress ) { + if( do_compress ) { int compr_algo = select_algo_from_prefs( pk_list, PREFTYPE_COMPR ); if( !compr_algo ) ; /* don't use compression */ diff --git a/g10/filter.h b/g10/filter.h index 2dc8a3e87..d48b75627 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -42,7 +42,7 @@ typedef struct { int parse_state; int inp_checked; /* set if inp has been checked */ int inp_bypass; /* set if the input is not armored */ - int inp_eof; + int any_data; const char *hdrlines; } armor_filter_context_t; @@ -135,6 +135,9 @@ enum cmd_and_opt_values { aNull = 0, oSetFilename, oComment, oThrowKeyid, + oS2KMode, + oS2KDigest, + oS2KCipher, aTest }; @@ -212,6 +215,11 @@ static ARGPARSE_OPTS opts[] = { { oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")}, { oLoadExtension, "load-extension" ,2, N_("|file|load extension module")}, { oRFC1991, "rfc1991", 0, N_("emulate the mode described in RFC1991")}, + { oS2KMode, "s2k-mode", 1, N_("|N| use passphrase mode N")}, + { oS2KDigest, "s2k-digest-algo",2, + N_("|NAME| use message digest algorithm NAME for passphrases")}, + { oS2KCipher, "s2k-cipher-algo",2, + N_("|NAME| use cipher algorithm NAME for passphrases")}, #ifdef IS_G10 { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")}, { oDigestAlgo, "digest-algo", 2 , N_("|NAME|use message digest algorithm NAME")}, @@ -226,10 +234,10 @@ static ARGPARSE_OPTS opts[] = { #ifdef IS_G10 { 302, NULL, 0, N_("@\nExamples:\n\n" " -se -r Bob [file] sign and encrypt for user Bob\n" - " -sat [file] make a clear text signature\n" - " -sb [file] make a detached signature\n" - " -k [userid] show keys\n" - " -kc [userid] show fingerprint\n" ) }, + " --clearsign [file] make a clear text signature\n" + " --detach-sign [file] make a detached signature\n" + " --list-keys [names] show keys\n" + " --fingerprint [names] show fingerprints\n" ) }, #endif /* hidden options */ @@ -472,11 +480,15 @@ main( int argc, char **argv ) const char *trustdb_name = NULL; char *def_cipher_string = NULL; char *def_digest_string = NULL; + char *s2k_cipher_string = NULL; + char *s2k_digest_string = NULL; + int pwfd = -1; #ifdef USE_SHM_COPROCESSING ulong requested_shm_size=0; #endif trap_unaligned(); + secmem_set_flags( secmem_get_flags() | 2 ); /* suspend warnings */ #ifdef IS_G10MAINT secmem_init( 0 ); /* disable use of secmem */ maybe_setuid = 0; @@ -497,6 +509,9 @@ main( int argc, char **argv ) opt.def_cipher_algo = 0; opt.def_digest_algo = 0; opt.def_compress_algo = 2; + opt.s2k_mode = 1; /* salted */ + opt.s2k_digest_algo = DIGEST_ALGO_RMD160; + opt.s2k_cipher_algo = CIPHER_ALGO_BLOWFISH; opt.completes_needed = 1; opt.marginals_needed = 3; opt.homedir = getenv("GNUPGHOME"); @@ -527,8 +542,34 @@ main( int argc, char **argv ) default_config = 0; /* --no-options */ else if( pargs.r_opt == oHomedir ) opt.homedir = pargs.r.ret_str; + #ifdef USE_SHM_COPROCESSING + else if( pargs.r_opt == oRunAsShmCP ) { + /* does not make sense in a options file, we do it here, + * so that we are the able to drop setuid as soon as possible */ + opt.shm_coprocess = 1; + requested_shm_size = pargs.r.ret_ulong; + } + #endif } + + #ifdef USE_SHM_COPROCESSING + if( opt.shm_coprocess ) { + #ifdef IS_G10 + init_shm_coprocessing(requested_shm_size, 1 ); + #else + init_shm_coprocessing(requested_shm_size, 0 ); + #endif + } + #endif + #ifdef IS_G10 + /* initialize the secure memory. */ + secmem_init( 16384 ); + maybe_setuid = 0; + /* Okay, we are now working under our real uid */ + #endif + + if( default_config ) configname = make_filename(opt.homedir, "options", NULL ); @@ -550,7 +591,7 @@ main( int argc, char **argv ) else { log_error(_("option file '%s': %s\n"), configname, strerror(errno) ); - g10_exit(1); + g10_exit(2); } m_free(configname); configname = NULL; } @@ -654,16 +695,18 @@ main( int argc, char **argv ) case oDoNotExportRSA: opt.do_not_export_rsa = 1; break; case oCompressSigs: opt.compress_sigs = 1; break; case oRunAsShmCP: - #ifdef USE_SHM_COPROCESSING - opt.shm_coprocess = 1; - requested_shm_size = pargs.r.ret_ulong; - #else + #ifndef USE_SHM_COPROCESSING + /* not possible in the option file, + * but we print the warning here anyway */ log_error("shared memory coprocessing is not available\n"); #endif break; case oSetFilename: opt.set_filename = pargs.r.ret_str; break; case oComment: opt.comment_string = pargs.r.ret_str; break; case oThrowKeyid: opt.throw_keyid = 1; break; + case oS2KMode: opt.s2k_mode = pargs.r.ret_int; break; + case oS2KDigest: s2k_digest_string = m_strdup(pargs.r.ret_str); break; + case oS2KCipher: s2k_cipher_string = m_strdup(pargs.r.ret_str); break; #ifdef IS_G10 case oRemote: /* store the remote users */ @@ -680,7 +723,7 @@ main( int argc, char **argv ) locusr = sl; break; case oCompress: opt.compress = pargs.r.ret_int; break; - case oPasswdFD: set_passphrase_fd( pargs.r.ret_int ); break; + case oPasswdFD: pwfd = pargs.r.ret_int; break; case oCipherAlgo: def_cipher_string = m_strdup(pargs.r.ret_str); break; case oDigestAlgo: def_digest_string = m_strdup(pargs.r.ret_str); break; case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break; @@ -709,22 +752,7 @@ main( int argc, char **argv ) tty_printf("%s\n", strusage(15) ); } - #ifdef USE_SHM_COPROCESSING - if( opt.shm_coprocess ) { - #ifdef IS_G10 - init_shm_coprocessing(requested_shm_size, 1 ); - #else - init_shm_coprocessing(requested_shm_size, 0 ); - #endif - } - #endif - #ifdef IS_G10 - /* initialize the secure memory. */ - secmem_init( 16384 ); - maybe_setuid = 0; - /* Okay, we are now working under our real uid */ - #endif - + secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */ set_debug(); @@ -742,12 +770,29 @@ main( int argc, char **argv ) if( check_digest_algo(opt.def_digest_algo) ) log_error(_("selected digest algorithm is invalid\n")); } + if( s2k_cipher_string ) { + opt.s2k_cipher_algo = string_to_cipher_algo(s2k_cipher_string); + m_free(s2k_cipher_string); s2k_cipher_string = NULL; + if( check_cipher_algo(opt.s2k_cipher_algo) ) + log_error(_("selected cipher algorithm is invalid\n")); + } + if( s2k_digest_string ) { + opt.s2k_digest_algo = string_to_digest_algo(s2k_digest_string); + m_free(s2k_digest_string); s2k_digest_string = NULL; + if( check_digest_algo(opt.s2k_digest_algo) ) + log_error(_("selected digest algorithm is invalid\n")); + } if( opt.def_compress_algo < 1 || opt.def_compress_algo > 2 ) log_error(_("compress algorithm must be in range %d..%d\n"), 1, 2); if( opt.completes_needed < 1 ) log_error(_("completes-needed must be greater than 0\n")); if( opt.marginals_needed < 2 ) log_error(_("marginals-needed must be greater than 1\n")); + switch( opt.s2k_mode ) { + case 0: case 1: case 3: break; + default: + log_error(_("invalid S2K mode; must be 0, 1 or 3\n")); + } if( log_get_errorcount(0) ) g10_exit(2); @@ -795,20 +840,11 @@ main( int argc, char **argv ) FREE_STRLIST(nrings); FREE_STRLIST(sec_nrings); - if( argc ) - fname = *argv; - else { - fname = NULL; - if( get_passphrase_fd() == 0 ) { - /* reading data and passphrase from stdin: - * we assume the first line is the passphrase, so - * we should read it now. - * - * We should do it here, but for now it is not needed. - * Anyway, this password scheme is not quite good - */ - } - } + + if( pwfd != -1 ) /* read the passphrase now. */ + read_passphrase_from_fd( pwfd ); + + fname = argc? *argv : NULL; switch( cmd ) { case aPrimegen: diff --git a/g10/getkey.c b/g10/getkey.c index f9f4c9f43..eed62e916 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -31,6 +31,7 @@ #include "keydb.h" #include "options.h" #include "main.h" +#include "i18n.h" #define MAX_PK_CACHE_ENTRIES 500 @@ -789,9 +790,6 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid, } } else { /* keyid or fingerprint lookup */ - /* No need to compare the usage here, as we already have the - * keyid to use - */ if( DBG_CACHE && (mode== 10 || mode==11) ) { log_debug("lookup keyid=%08lx%08lx req_algo=%d mode=%d\n", (ulong)keyid[0], (ulong)keyid[1], @@ -867,6 +865,29 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid, merge_one_pk_and_selfsig( keyblock, keyblock ); } else { + if( primary && pk->pubkey_usage + && check_pubkey_algo2( k->pkt->pkt.public_key->pubkey_algo, + pk->pubkey_usage ) == G10ERR_WR_PUBKEY_ALGO ) { + /* if the usage is not correct, try to use a subkey */ + KBNODE save_k = k; + + for( ; k; k = k->next ) { + if( k->pkt->pkttype == PKT_PUBLIC_SUBKEY + && !check_pubkey_algo2( + k->pkt->pkt.public_key->pubkey_algo, + pk->pubkey_usage ) ) + break; + } + if( !k ) + k = save_k; + else + log_info(_("using secondary key %08lX " + "instead of primary key %08lX\n"), + (ulong)keyid_from_pk( k->pkt->pkt.public_key, NULL), + (ulong)keyid_from_pk( save_k->pkt->pkt.public_key, NULL) + ); + } + copy_public_key_new_namehash( pk, k->pkt->pkt.public_key, use_namehash? namehash:NULL); merge_one_pk_and_selfsig( keyblock, k ); diff --git a/g10/gpgd.c b/g10/gpgd.c index da7a990dc..ce92c95d7 100644 --- a/g10/gpgd.c +++ b/g10/gpgd.c @@ -18,6 +18,15 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +/**************** + * This is a spinning server for most purposes, the server does only + * fork for updates (which may require signature checks and lengthy DB + * operations). + * + * see ks-proto.c for the used protocol. + * see ks-db.c for the layout of the database. + */ + #include <config.h> #include <stdio.h> #include <errno.h> diff --git a/g10/import.c b/g10/import.c index 7ef916d27..12a2a099d 100644 --- a/g10/import.c +++ b/g10/import.c @@ -459,7 +459,7 @@ import_secret_one( const char *fname, KBNODE keyblock ) _("can't lock secret keyring: %s\n"), g10_errstr(rc) ); else if( (rc=insert_keyblock( &kbpos, keyblock )) ) log_error_f(keyblock_resource_name(&kbpos), - _("can't write keyring\n"), g10_errstr(rc) ); + _("can't write keyring: %s\n"), g10_errstr(rc) ); unlock_keyblock( &kbpos ); /* we are ready */ log_info_f(fname, _("key %08lX: secret key imported\n"), (ulong)keyid[1]); @@ -655,16 +655,17 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid ) else if( node->pkt->pkttype == PKT_SIGNATURE && node->pkt->pkt.signature->sig_class == 0x20 ) { if( uid_seen ) { - log_error_f(fname, _("key %08lX: revocation certificate at wrong " - "place - skipped\n"), fname, (ulong)keyid[1]); + log_error_f(fname, _("key %08lX: revocation certificate " + "at wrong place - skipped\n"), + (ulong)keyid[1]); delete_kbnode( node ); } else { int rc = check_key_signature( keyblock, node, NULL); if( rc ) { - log_error_f(fname, _("key %08lX: invalid revocation certificate" - ": %s - skipped\n"), - fname, (ulong)keyid[1], g10_errstr(rc)); + log_error_f(fname, _("key %08lX: invalid revocation " + "certificate: %s - skipped\n"), + (ulong)keyid[1], g10_errstr(rc)); delete_kbnode( node ); } } @@ -788,7 +789,7 @@ append_uid( KBNODE keyblock, KBNODE node, int *n_sigs, /* at lease a self signature comes next to the user-id */ if( node->next->pkt->pkttype == PKT_USER_ID ) { log_error_f(fname, _("key %08lX: our copy has no self-signature\n"), - fname, (ulong)keyid[1]); + (ulong)keyid[1]); return G10ERR_GENERAL; } diff --git a/g10/keydb.h b/g10/keydb.h index c16dc4b80..c7fb26db1 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -99,8 +99,8 @@ int build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock, unsigned usage ); /*-- passphrase.h --*/ -void set_passphrase_fd( int fd ); -int get_passphrase_fd(void); +int have_static_passphrase(void); +void read_passphrase_from_fd( int fd ); DEK *passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode); void set_next_passphrase( const char *s ); char *get_last_passphrase(void); diff --git a/g10/keyedit.c b/g10/keyedit.c index 13fa24c8c..9387a762e 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -199,7 +199,6 @@ check_all_keysigs( KBNODE keyblock, int only_selected ) } - /**************** * Loop over all locusr and and sign the uids after asking. * If no user id is marked, all user ids will be signed; @@ -259,10 +258,9 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified ) (ulong)sk_keyid[1] ); continue; } - /* Ask whether we realy should sign these user id(s) */ + /* Ask whether we really should sign these user id(s) */ tty_printf("\n"); show_key_with_all_names( keyblock, 1, 1, 0, 0 ); - tty_printf("\n"); tty_printf(_( "Are you really sure that you want to sign this key\n" "with your key: \"")); @@ -372,9 +370,9 @@ change_passphrase( KBNODE keyblock ) set_next_passphrase( NULL ); for(;;) { - s2k->mode = 1; - s2k->hash_algo = DIGEST_ALGO_RMD160; - dek = passphrase_to_dek( NULL, CIPHER_ALGO_BLOWFISH, s2k, 2 ); + s2k->mode = opt.s2k_mode; + s2k->hash_algo = opt.s2k_digest_algo; + dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 ); if( !dek ) { tty_printf(_("passphrase not correctly repeated; try again.\n")); } @@ -556,7 +554,7 @@ keyedit_menu( const char *username, STRLIST locusr ) if( cmds[i].need_sk && !sec_keyblock ) ; /* skip if we do not have the secret key */ else if( cmds[i].desc ) - tty_printf("%-10s %s\n", cmds[i].name, cmds[i].desc ); + tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) ); } break; diff --git a/g10/keygen.c b/g10/keygen.c index 47a24b2ae..1d1cdbfc2 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -687,9 +687,9 @@ ask_passphrase( STRING2KEY **ret_s2k ) s2k = m_alloc_secure( sizeof *s2k ); for(;;) { - s2k->mode = 1; - s2k->hash_algo = DIGEST_ALGO_RMD160; - dek = passphrase_to_dek( NULL, CIPHER_ALGO_BLOWFISH, s2k, 2 ); + s2k->mode = opt.s2k_mode; + s2k->hash_algo = opt.s2k_digest_algo; + dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 ); if( !dek ) { tty_printf(_("passphrase not correctly repeated; try again.\n")); } @@ -970,10 +970,10 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock ) if( passphrase ) { s2k = m_alloc_secure( sizeof *s2k ); - s2k->mode = 1; - s2k->hash_algo = DIGEST_ALGO_RMD160; + s2k->mode = opt.s2k_mode; + s2k->hash_algo = opt.s2k_digest_algo; set_next_passphrase( passphrase ); - dek = passphrase_to_dek( NULL, CIPHER_ALGO_BLOWFISH, s2k, 2 ); + dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 ); } rc = do_create( algo, nbits, pub_keyblock, sec_keyblock, diff --git a/g10/ks-proto.c b/g10/ks-proto.c index b862357fb..b5109f2ad 100644 --- a/g10/ks-proto.c +++ b/g10/ks-proto.c @@ -42,245 +42,114 @@ * X-Key-MTime: <last modification time> * X-Key-LID: <local_key_id_used_for_update_etc> * [fixme: is X-.... allowed?] + * */ #include <config.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <errno.h> +#include <ctype.h> #include "util.h" #include "ks-proto.h" -#if 0 -/**************** - * Read a protocol line - */ -static int -read_line( FILE *fp ) -{ - return -1; -} - - - - -/**************** - * Send a HKP request - */ -int -hkp_request( int operation, const char *user_id ) -{ - -} - - - - - -/************************************************ - ******* client communication stuff ************ - ************************************************/ - -/**************** - * Initialisieren des clients - * Es wird ein Handle zurückgegeben oder -1 bei einem fehler. - * z.Z. ist nut eine Verbindung gleichzeitig möglich. - * Wenn einer serverpid von 0 angegeben wird, so wird diese - * der environment variabeln ATEXDB_PID entnommen. - */ - -int -hkp_open( const char *serverurl ) -{ - const char *s; - - s = SERVER_NAME_TEMPLATE; - client.serv_name = xmalloc(strlen(s) + 10 ); - sprintf(client.serv_name,s, serverpid ); - if( opt.verbose ) - Info("Using unix domain stream '%s'", client.serv_name ); - - memset( &client.serv_addr, 0, sizeof client.serv_addr ); - client.serv_addr.sun_family = AF_UNIX; - strcpy( client.serv_addr.sun_path, client.serv_name ); - client.serv_addr_len = strlen(client.serv_addr.sun_path) - + sizeof client.serv_addr.sun_family; - - client.sockfd = -1; - if( DoCheckVersion() ) - return -1; - return 0; -} - - -static int -DoConnect() -{ - if( client.sockfd != -1 ) - DoDisconnect(); - if( (client.sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ) { - Error(1000,"can't open unix domain socket"); - return 1; - } - if( connect(client.sockfd, (struct sockaddr*)&client.serv_addr, - client.serv_addr_len) == -1 ) { - Error(1000,"can't connect to '%s'",client.serv_addr.sun_path); - return 1; - } - - return 0; /* okay */ -} - -static int -DoDisconnect() -{ - if( client.sockfd != -1 ) { - close(client.sockfd); - client.sockfd = -1; - } - return 0; /* okay */ -} -/**************** - * NBYTES auf den aktuellen stream schreiben. - */ static int -DoWrite( void *buf, size_t nbytes ) +do_read( int fd, char *buffer, size_t bufsize, int *ret_nread ) { - size_t nleft = nbytes; - ssize_t nwritten; - - while( nleft > 0 ) { - /* FIXME: add EINTR handling */ - nwritten = write(client.sockfd, buf, nleft); - if( nwritten < 0 ) { - Error(1000,"error writing to server"); + int n; + fd_set rfds; + struct timeval tv; + int rc; + + *ret_nread = 0; + do { + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + tv.tv_sec = 1; + tv.tv_usec = 0; + if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) + return 0; /* timeout */ + if( rc == -1 ) { + log_error("select() error: %s\n", strerror(errno)); return -1; } - nleft -= nwritten; - buf = (char*)buf + nwritten; - } - return 0; -} - -static int -DoWriteStr( const char *s ) -{ - return DoWrite((char *)s, strlen(s) ); -} - - -static int -DoRead( void *buf, size_t buflen, size_t *ret_nread, int stop) -{ - size_t nleft = buflen; - int nread; - char *p; - - p = buf; - while( nleft > 0 ) { - /* FIXME: add EINTR handling */ - nread = read(client.sockfd, buf, stop? 1 : nleft); - if( nread < 0 ) { - Error(1000,"error reading from server"); - return -1; - } - else if( !nread ) - break; /* EOF */ - nleft -= nread; - buf = (char*)buf + nread; - if( stop ) - for(; p < (char*)buf ; p++ ) - if( *p == '\n' ) - goto leave; - } - leave: - if( ret_nread ) - *ret_nread = buflen - nleft; - return 0; -} - -/**************** - * Like DoRead(), but append the received data to the given strgbuf. - * read a maximum of nbytes; - */ -static int -DoReadIntoStrgbuf( strgbuf_t *strgbuf, size_t nbytes, size_t *ret_nread) -{ - size_t ntotal, nleft; - int nread; - byte *p, buffer[1000]; - ntotal = 0; - nleft = nbytes; - while( nleft ) { - nread = read(client.sockfd, buffer, - nleft > DIM(buffer)? DIM(buffer) : nleft); - if( nread < 0 ) { - Error(1000,"error reading from server"); + do { + n = read(fd, buffer, bufsize ); + if( n >= 0 && n > bufsize ) + log_bug("bogus read from fd %d (n=%d)\n", fd, n ); + } while( n == -1 && errno == EINTR ); + if( n == -1 ) { + log_error("read error on fd %d: %s\n", fd, strerror(errno) ); return -1; } - else if( !nread ) - break; /* EOF */ - nleft -= nread; - ntotal += nread; - /* ab in den stringbuffer */ - for(p=buffer; nread; nread--, p++ ) - PutStrgbuf(strgbuf, *p ); - } - - if( ret_nread ) - *ret_nread = ntotal; + } while( !n ); + *ret_nread = n; return 0; } -/**************** - * In retval wird das numerische argument nach OK zurückgegeben - */ -static int -DoRequest( char *request, long *retval ) -{ - if( DoWrite(request, strlen(request)) ) - return -1; - return DoWaitReply( retval ); -} - -static int -DoWaitReply( long *retval ) +int +ks_get_request( int fd, KS_TRANS *req ) { - char *p, buf[200]; /* enough room for messages */ - size_t nread; + char *p, *p2, buf[500]; + int nread, n; + int state = 0; + + req->err = 0; + req->data = NULL; + while( !do_read( fd, buf, DIM(buf)-1, &nread ) { + p = buf; + if( !state ) { + /* replace the trailing LF with a 0 */ + for(p2=p,n=0; n < nread && *p2 != '\n'; p2++ ) + ; + if( *p2 != '\n' ) { + req->err = KS_ERR_REQ_TOO_LONG; + break; + } + *p2++ = 0; + n++; + + /* now look at the request. Note that the isspace() will work + * because there is still a CR before the 0 */ + if( (p[0] == 'G' || p[0] == 'g') + && (p[1] == 'E' || p[1] == 'e') + && (p[2] == 'T' || p[2] == 't') && isspace( p[3] ) ) { + req->cmd = KS_REQ_GET; + p += 4; + } + else if( (p[0] == 'H' || p[0] == 'h') + && (p[1] == 'E' || p[1] == 'e') + && (p[2] == 'A' || p[2] == 'a') + && (p[3] == 'D' || p[3] == 'd') && isspace( p[4] ) ) { + req->cmd = KS_REQ_HEAD; + p += 5; + } + else if( (p[0] == 'H' || p[0] == 'h') + && (p[1] == 'E' || p[1] == 'e') + && (p[2] == 'L' || p[2] == 'l') + && (p[3] == 'P' || p[3] == 'p') && isspace( p[4] ) ) { + req->cmd = KS_REQ_HELP; + p += 5; + } + else + req->cmd = KS_REQ_UNKNOWN; + /* skip spaces, store args and remaining data */ + while( *p == ' ' || *p == '\t' ) + p++; + /* fixme: remove trailing blanks from args */ + req->args = p; + p = p2; /* p now points to the remaining n bytes in the buffer */ + state = 1; + } + if( state == 1 ) { + /* read the option lines */ + } - /* read but stop at the first newline */ - if( DoRead(buf, DIM(buf)-2, &nread, 1 ) ) - return -1; - buf[DIM(buf)-1] = 0; - /* fixme: should check, that we have the linefeed and otherwise - * perform a dummy read */ - if( p = strchr(buf, '\n') ) - *p = 0; - if( *buf == 'O' && buf[1] == 'K' && (buf[2]==' ' || !buf[2]) ) { - if( retval ) - *retval = buf[2]? strtol(buf+3, NULL, 10 ):0; - return 0; } - Error(0, "Server replied: %.60s", buf ); - return -1; } - - - - - - - - - - -#endif - - - diff --git a/g10/mainproc.c b/g10/mainproc.c index 1e8af7e21..bcbc4bd92 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -88,8 +88,10 @@ add_onepass_sig( CTX c, PACKET *pkt ) if( c->list->pkt->pkttype != PKT_ONEPASS_SIG ) { log_error("add_onepass_sig: another packet is in the way\n"); release_list( c ); + c->list = new_kbnode( pkt ); } - add_kbnode( c->list, new_kbnode( pkt )); + else + add_kbnode( c->list, new_kbnode( pkt )); } else /* insert the first one */ c->list = node = new_kbnode( pkt ); diff --git a/g10/options.h b/g10/options.h index a4b4167c4..d674ada12 100644 --- a/g10/options.h +++ b/g10/options.h @@ -55,6 +55,9 @@ struct { const char *set_filename; const char *comment_string; int throw_keyid; + int s2k_mode; + int s2k_digest_algo; + int s2k_cipher_algo; } opt; diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 2601e1571..1cd14acfb 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1068,6 +1068,9 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen, } sk->protect.s2k.count = iobuf_get(inp); pktlen--; + if( list_mode ) + printf("\tprotect count: %lu\n", + (ulong)sk->protect.s2k.count); } } else { /* old version; no S2K, so we set mode to 0, hash MD5 */ diff --git a/g10/passphrase.c b/g10/passphrase.c index 7dbaeb466..2e649119d 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -34,22 +34,16 @@ #include "i18n.h" #include "status.h" -static int pwfd = -1; +static char *fd_passwd = NULL; static char *next_pw = NULL; static char *last_pw = NULL; static void hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create ); -void -set_passphrase_fd( int fd ) -{ - pwfd = fd; -} - int -get_passphrase_fd() +have_static_passphrase() { - return pwfd; + return !!fd_passwd; } /**************** @@ -81,6 +75,36 @@ get_last_passphrase() } +void +read_passphrase_from_fd( int fd ) +{ + int i, len; + char *pw; + + if( !opt.batch ) + tty_printf("Reading passphrase from file descriptor %d ...", fd ); + for( pw = NULL, i = len = 100; ; i++ ) { + if( i >= len-1 ) { + char *pw2 = pw; + len += 100; + pw = m_alloc_secure( len ); + if( pw2 ) + memcpy(pw, pw2, i ); + else + i=0; + } + if( read( fd, pw+i, 1) != 1 || pw[i] == '\n' ) + break; + } + pw[i] = 0; + if( !opt.batch ) + tty_printf("\b\b\b \n" ); + + m_free( fd_passwd ); + fd_passwd = pw; +} + + /**************** * Get a passphrase for the secret key with KEYID, display TEXT * if the user needs to enter the passphrase. @@ -140,26 +164,9 @@ passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode ) pw = next_pw; next_pw = NULL; } - else if( pwfd != -1 ) { /* read the passphrase from the file */ - int i, len; - - if( !opt.batch ) - tty_printf("Reading from file descriptor %d ...", pwfd ); - for( pw = NULL, i = len = 100; ; i++ ) { - if( i >= len-1 ) { - char *pw2 = pw; - len += 100; - pw = m_alloc_secure( len ); - if( pw2 ) - memcpy(pw, pw2, i ); - i=0; - } - if( read( pwfd, pw+i, 1) != 1 || pw[i] == '\n' ) - break; - } - pw[i] = 0; - if( !opt.batch ) - tty_printf("\b\b\b \n" ); + else if( fd_passwd ) { + pw = m_alloc_secure( strlen(fd_passwd)+1 ); + strcpy( pw, fd_passwd ); } else if( opt.batch ) log_fatal("Can't query password in batchmode\n"); @@ -192,54 +199,69 @@ passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode ) /**************** * Hash a passphrase using the supplied s2k. If create is true, create - * a new salt or whatelse must be filled into the s2k for a new key. + * a new salt or what else must be filled into the s2k for a new key. * always needs: dek->algo, s2k->mode, s2k->hash_algo. */ static void hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create ) { MD_HANDLE md; + int pass, i; + int used = 0; + int pwlen = strlen(pw); assert( s2k->hash_algo ); - dek->keylen = 0; + dek->keylen = cipher_get_keylen( dek->algo ) / 8; + if( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) ) + BUG(); + md = md_open( s2k->hash_algo, 1); - if( s2k->mode == 1 || s2k->mode == 3 ) { - ulong count = 0; - int len = strlen(pw); - int len2 = len + 8; + for(pass=0; used < dek->keylen ; pass++ ) { + if( pass ) { + md_reset(md); + for(i=0; i < pass; i++ ) /* preset the hash context */ + md_putc(md, 0 ); + } - if( create ) - randomize_buffer(s2k->salt, 8, 1); + if( s2k->mode == 1 || s2k->mode == 3 ) { + int len2 = pwlen + 8; + ulong count = len2; - if( s2k->mode == 3 ) { - count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6); - log_debug("s2k iteration count=%lu\n", count ); - } - for(;;) { - md_write( md, s2k->salt, 8 ); - md_write( md, pw, len ); - if( count <= len2 ) - break; - count -= len2; - } - if( count ) { - if( count < 8 ) { - md_write( md, s2k->salt, count ); + if( create && !pass ) { + randomize_buffer(s2k->salt, 8, 1); + if( s2k->mode == 3 ) + s2k->count = 96; /* = 56536 */ } + + if( s2k->mode == 3 ) { + count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6); + if( count < len2 ) + count = len2; + } + /* a little bit complicated because we need a ulong for count */ + while( count > len2 ) { /* maybe iterated+salted */ + md_write( md, s2k->salt, 8 ); + md_write( md, pw, pwlen ); + count -= len2; + } + if( count < 8 ) + md_write( md, s2k->salt, count ); else { md_write( md, s2k->salt, 8 ); count -= 8; - assert( count <= len ); + assert( count >= 0 ); md_write( md, pw, count ); } } + else + md_write( md, pw, pwlen ); + md_final( md ); + i = md_digest_length( s2k->hash_algo ); + if( i > dek->keylen - used ) + i = dek->keylen - used; + memcpy( dek->key+used, md_read(md, s2k->hash_algo), i ); + used += i; } - else - md_write( md, pw, strlen(pw) ); - md_final( md ); - dek->keylen = cipher_get_keylen( dek->algo ) / 8; - assert(dek->keylen > 0 && dek->keylen <= DIM(dek->key) ); - memcpy( dek->key, md_read(md,0), dek->keylen ); md_close(md); } diff --git a/g10/pkclist.c b/g10/pkclist.c index 4f52eebb7..272a861b7 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -182,7 +182,8 @@ do_we_trust( PKT_public_key *pk, int trustlevel ) int rc; if( (trustlevel & TRUST_FLAG_REVOKED) ) { - log_info("key has been revoked!\n"); + log_info("%08lX: key has been revoked!\n", + (ulong)keyid_from_pk( pk, NULL) ); if( opt.batch ) return 0; @@ -209,12 +210,13 @@ do_we_trust( PKT_public_key *pk, int trustlevel ) return do_we_trust( pk, trustlevel ); case TRUST_EXPIRED: - log_info("key has expired\n"); + log_info("%08lX: key has expired\n", (ulong)keyid_from_pk( pk, NULL) ); return 0; /* no */ case TRUST_UNDEFINED: if( opt.batch || opt.answer_no ) - log_info("no info to calculate a trust probability\n"); + log_info("%08lX: no info to calculate a trust probability\n", + (ulong)keyid_from_pk( pk, NULL) ); else { rc = add_ownertrust( pk ); if( !rc ) { @@ -229,12 +231,14 @@ do_we_trust( PKT_public_key *pk, int trustlevel ) return 0; case TRUST_NEVER: - log_info("We do NOT trust this key\n"); + log_info("%08lX: We do NOT trust this key\n", + (ulong)keyid_from_pk( pk, NULL) ); return 0; /* no */ case TRUST_MARGINAL: - log_info("I'm not sure whether this key really belongs to the owner\n" - "but I proceed anyway\n"); + log_info("%08lX: I'm not sure whether this key really belongs to the owner\n" + "but I proceed anyway\n", + (ulong)keyid_from_pk( pk, NULL) ); return 1; /* yes */ case TRUST_FULLY: diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c index 9253b8ce1..d43f8619d 100644 --- a/g10/seckey-cert.c +++ b/g10/seckey-cert.c @@ -168,7 +168,7 @@ check_secret_key( PKT_secret_key *sk, int n ) if( i ) log_error(_("Invalid passphrase; please try again ...\n")); rc = do_check( sk ); - if( get_passphrase_fd() != -1 ) + if( have_static_passphrase() ) break; } diff --git a/g10/sig-check.c b/g10/sig-check.c index 1dda44529..5e6873f9d 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -152,8 +152,8 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest ) u32 cur_time; if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) { - log_info("this is a PGP generated " - "ElGamal key which is NOT secure for signatures!\n"); + log_info(_("this is a PGP generated " + "ElGamal key which is NOT secure for signatures!\n")); return G10ERR_PUBKEY_ALGO; } diff --git a/g10/status.c b/g10/status.c index 7cb2f5c5d..97b4fba97 100644 --- a/g10/status.c +++ b/g10/status.c @@ -31,6 +31,9 @@ #ifdef HAVE_SYS_SHM_H #include <sys/shm.h> #endif + #if defined(HAVE_MLOCK) + #include <sys/mman.h> + #endif #endif #include "util.h" #include "status.h" @@ -142,11 +145,21 @@ init_shm_coprocessing ( ulong requested_shm_size, int lock_mem ) log_info("mapped %uk shared memory at %p, id=%d\n", (unsigned)shm_size/1024, shm_area, shm_id ); if( lock_mem ) { + #ifdef IPC_HAVE_SHM_LOCK if ( shmctl (shm_id, SHM_LOCK, 0) ) - log_info("Locking shared memory %d failed: %s\n", + log_info("locking shared memory %d failed: %s\n", shm_id, strerror(errno)); else shm_is_locked = 1; + #elif defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK) + if ( mlock (shm_area, shm_size) ) + log_info("locking shared memory %d failed: %s\n", + shm_id, strerror(errno)); + else + shm_is_locked = 1; + #else + log_info("Locking shared memory %d failed: No way to do it\n", shm_id ); + #endif } @@ -225,7 +238,7 @@ do_shm_get( const char *keyword, int hidden, int bool ) static void display_help( const char *keyword ) { - char *p; + const char *p; int hint = 0; tty_kill_prompt(); diff --git a/g10/trustdb.c b/g10/trustdb.c index bce0df0c9..b36c176ae 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -105,7 +105,7 @@ static TRUST_SEG_LIST last_trust_web_tslist; #define HEXTOBIN(a) ( (a) >= '0' && (a) <= '9' ? ((a)-'0') : \ (a) >= 'A' && (a) <= 'F' ? ((a)-'A'+10) : ((a)-'a'+10)) - + /********************************************** ************* list helpers ******************* **********************************************/ @@ -239,6 +239,8 @@ keyid_from_lid( ulong lid, u32 *keyid ) return 0; } + + /**************** * Walk through the signatures of a public key. * The caller must provide a context structure, with all fields set @@ -333,7 +335,7 @@ walk_sigrecs( SIGREC_CONTEXT *c, int create ) - + /*********************************************** ************* Trust stuff ****************** ***********************************************/ @@ -357,6 +359,10 @@ verify_own_keys() if( DBG_TRUST ) log_debug("key %08lX: checking secret key\n", (ulong)keyid[1] ); + if( is_secret_key_protected( sk ) < 1 ) + log_info("note: secret key %08lX is NOT protected.\n", + (ulong)keyid[1] ); + /* see whether we can access the public key of this secret key */ memset( pk, 0, sizeof *pk ); rc = get_pubkey( pk, keyid ); @@ -1204,7 +1210,7 @@ do_check( TRUSTREC *dr, unsigned *trustlevel ) return 0; } - + /*********************************************** **************** API ************************ ***********************************************/ @@ -1564,6 +1570,8 @@ check_trustdb( const char *username ) } } + + /**************** * Get the trustlevel for this PK. * Note: This does not ask any questions @@ -1612,11 +1620,11 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel ) rc = insert_trust_record( pk ); if( rc ) { log_error(_("key %08lX: insert trust record failed: %s\n"), - keyid[1], g10_errstr(rc)); + (ulong)keyid[1], g10_errstr(rc)); goto leave; } log_info(_("key %08lX.%lu: inserted into trustdb\n"), - keyid[1], pk->local_id ); + (ulong)keyid[1], pk->local_id ); /* and re-read the dir record */ if( tdbio_read_record( pk->local_id, &rec, RECTYPE_DIR ) ) { log_error("check_trust: reread dir record failed\n"); @@ -1628,14 +1636,14 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel ) if( pk->timestamp > cur_time ) { log_info(_("key %08lX.%lu: created in future " "(time warp or clock problem)\n"), - keyid[1], pk->local_id ); + (ulong)keyid[1], pk->local_id ); return G10ERR_TIME_CONFLICT; } if( pk->valid_days && add_days_to_timestamp(pk->timestamp, pk->valid_days) < cur_time ) { log_info(_("key %08lX.%lu: expired at %s\n"), - keyid[1], pk->local_id, + (ulong)keyid[1], pk->local_id, asctimestamp( add_days_to_timestamp(pk->timestamp, pk->valid_days))); trustlevel = TRUST_EXPIRED; @@ -1644,7 +1652,7 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel ) rc = do_check( &rec, &trustlevel ); if( rc ) { log_error(_("key %08lX.%lu: trust check failed: %s\n"), - keyid[1], pk->local_id, g10_errstr(rc)); + (ulong)keyid[1], pk->local_id, g10_errstr(rc)); return rc; } } |