diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 17 | ||||
-rw-r--r-- | g10/armor.c | 15 | ||||
-rw-r--r-- | g10/export.c | 18 | ||||
-rw-r--r-- | g10/g10.c | 6 | ||||
-rw-r--r-- | g10/getkey.c | 8 | ||||
-rw-r--r-- | g10/import.c | 190 | ||||
-rw-r--r-- | g10/mainproc.c | 32 | ||||
-rw-r--r-- | g10/options.h | 3 | ||||
-rw-r--r-- | g10/packet.h | 3 | ||||
-rw-r--r-- | g10/plaintext.c | 66 | ||||
-rw-r--r-- | g10/sign.c | 44 | ||||
-rw-r--r-- | g10/textfilter.c | 5 |
12 files changed, 264 insertions, 143 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index 664d378bb..7525c1818 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,20 @@ +Wed Jul 8 10:45:28 1998 Werner Koch ([email protected]) + + * plaintext.c (special_md_putc): New. + (handle_plaintext): add clearsig argument + * mainproc.c (proc_plaintext): detection of clearsig + * sign.c (write_dased_escaped): Changed clearsig format + +Tue Jul 7 18:56:19 1998 Werner Koch ([email protected]) + + * armor.c (find_header): Now makes sure that there is only one + empty line for clearsigs, as this is what OP now says. + +Mon Jul 6 13:09:07 1998 Werner Koch ([email protected]) + + * g10.c (main): New option default-secret-key + * getkey.c (get_seckey_byname): support for this option. + Mon Jul 6 09:03:49 1998 Werner Koch ([email protected]) * getkey.c (add_keyring): Keyrings are now added to end of the diff --git a/g10/armor.c b/g10/armor.c index 1dd028afc..46151eae8 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -380,16 +380,13 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, state = fhdrEOF; break; - case fhdrWAITClearsig: /* skip all empty lines (for clearsig) */ + case fhdrWAITClearsig: /* skip the empty line (for clearsig) */ c = 0; for(n=0; n < buflen && (c=iobuf_get2(a)) != -1 && c != '\n'; ) buf[n++] = c; if( n < buflen || c == '\n' ) { buf[n] = 0; - if( !n || (buf[0]=='\r' && !buf[1]) ) /* empty line */ - ; - else - state = fhdrCHECKDashEscaped3; + state = fhdrCHECKDashEscaped3; } else { /* fixme: we should check whether this line continues @@ -590,6 +587,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, buf[1] = '\n'; n = 2; } + } @@ -715,13 +713,6 @@ fake_packet( armor_filter_context_t *afx, IOBUF a, break; case fhdrENDClearsig: - /* FIXME: this is wrong: Only the last CRLF should - * not be included in the hash, muts rewrite the FSM again - * This proble does only occur if the last line does not end - * in with a LF? - */ - if( emplines ) - emplines--; /* don't count the last one */ state = fhdrENDClearsigHelp; afx->helplen = n; break; diff --git a/g10/export.c b/g10/export.c index 68e83a268..2c824d2b0 100644 --- a/g10/export.c +++ b/g10/export.c @@ -125,6 +125,24 @@ do_export( STRLIST users, int secret ) /* and write it */ for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) { + if( opt.do_not_export_rsa ) { + int algo; + switch( node->pkt->pkttype ) { + /* note: we can� do this for subkeys here */ + case PKT_PUBLIC_KEY: + algo = node->pkt->pkt.public_key->pubkey_algo; + break; + case PKT_SECRET_KEY: + algo = node->pkt->pkt.secret_key->pubkey_algo; + break; + case PKT_SIGNATURE: + algo = node->pkt->pkt.signature->pubkey_algo; + break; + default: algo = 0; + } + if( is_RSA(algo) ) + continue; + } if( (rc = build_packet( out, node->pkt )) ) { log_error("build_packet(%d) failed: %s\n", node->pkt->pkttype, g10_errstr(rc) ); @@ -76,6 +76,7 @@ static ARGPARSE_OPTS opts[] = { #endif { 537, "export" , 0, N_("export keys") }, { 563, "export-secret-keys" , 0, "@" }, + { 565, "do-not-export-rsa", 0, "@" }, { 530, "import", 0 , N_("import/merge keys")}, { 521, "list-packets",0,N_("list only the sequence of packets")}, #ifdef IS_G10MAINT @@ -105,6 +106,7 @@ static ARGPARSE_OPTS opts[] = { { 502, "no", 0, N_("assume no on most questions")}, { 509, "keyring" ,2, N_("add this keyring to the list of keyrings")}, { 517, "secret-keyring" ,2, N_("add this secret keyring to the list")}, + { 541, "default-key" ,2, N_("|NAME|use NAME as default secret key")}, { 518, "options" , 2, N_("read options from file")}, { 510, "debug" ,4|16, N_("set debugging flags")}, @@ -168,8 +170,6 @@ static ARGPARSE_OPTS opts[] = { {0} }; -/* (Free numbers: 541) */ - enum cmd_values { aNull = 0, aSym, aStore, aEncr, aKeygen, aSign, aSignEncr, @@ -575,6 +575,7 @@ main( int argc, char **argv ) case 536: opt.marginals_needed = pargs.r.ret_int; break; case 537: set_cmd( &cmd, aExport); break; case 538: trustdb_name = pargs.r.ret_str; break; + case 541: opt.def_secret_key = pargs.r.ret_str; break; case 543: break; /* no-options */ case 544: opt.homedir = pargs.r.ret_str; break; case 545: opt.batch = 0; break; @@ -591,6 +592,7 @@ main( int argc, char **argv ) case 561: opt.rfc1991 = 1; break; case 562: opt.emulate_bugs |= 1; break; case 563: set_cmd( &cmd, aExportSecret); break; + case 565: opt.do_not_export_rsa = 1; break; default : errors++; pargs.err = configfp? 1:2; break; } } diff --git a/g10/getkey.c b/g10/getkey.c index 0c69efb0b..c51e54bd9 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -532,8 +532,12 @@ get_seckey_byname( PKT_secret_key *sk, const char *name, int unprotect ) { int rc; - rc = name ? key_byname( 1, NULL, sk, name ) - : lookup_sk( sk, 15, NULL, NULL ); + if( !name && opt.def_secret_key && *opt.def_secret_key ) + rc = key_byname( 1, NULL, sk, opt.def_secret_key ); + else if( !name ) /* use the first one as default key */ + rc = lookup_sk( sk, 15, NULL, NULL ); + else + rc = key_byname( 1, NULL, sk, name ); if( !rc && unprotect ) rc = check_secret_key( sk ); diff --git a/g10/import.c b/g10/import.c index 3ed6b96bb..d32852cf0 100644 --- a/g10/import.c +++ b/g10/import.c @@ -33,6 +33,7 @@ #include "util.h" #include "trustdb.h" #include "main.h" +#include "i18n.h" static int read_block( IOBUF a, compress_filter_context_t *cfx, @@ -101,7 +102,7 @@ import_keys( const char *fname ) if( !fname ) fname = "[stdin]"; if( !inp ) { - log_error("%s: can't open file: %s\n", fname, strerror(errno) ); + log_error_f(fname, _("can't open file: %s\n"), strerror(errno) ); return G10ERR_OPEN_FILE; } @@ -116,9 +117,10 @@ import_keys( const char *fname ) else if( keyblock->pkt->pkttype == PKT_SIGNATURE && keyblock->pkt->pkt.signature->sig_class == 0x20 ) rc = import_revoke_cert( fname, keyblock ); - else - log_info("%s: skipping block of type %d\n", - fname, keyblock->pkt->pkttype ); + else { + log_info_f(fname, _("skipping block of type %d\n"), + keyblock->pkt->pkttype ); + } release_kbnode(keyblock); if( rc ) break; @@ -126,7 +128,7 @@ import_keys( const char *fname ) if( rc == -1 ) rc = 0; else if( rc && rc != G10ERR_INV_KEYRING ) - log_error("%s: read error: %s\n", fname, g10_errstr(rc)); + log_error_f( fname, _("read error: %s\n"), g10_errstr(rc)); iobuf_close(inp); return rc; @@ -255,7 +257,7 @@ import_one( const char *fname, KBNODE keyblock ) uidnode = find_next_kbnode( keyblock, PKT_USER_ID ); if( opt.verbose ) { - log_info("%s: pub %4u%c/%08lX %s ", fname, + log_info_f( fname, "pub %4u%c/%08lX %s ", nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), (ulong)keyid[1], datestr_from_pk(pk) ); @@ -265,7 +267,7 @@ import_one( const char *fname, KBNODE keyblock ) putc('\n', stderr); } if( !uidnode ) { - log_error("%s: No user id for key %08lX\n", fname, (ulong)keyid[1]); + log_error_f(fname, _("key %08lX: no user id\n"), (ulong)keyid[1]); return 0; } @@ -275,8 +277,8 @@ import_one( const char *fname, KBNODE keyblock ) return rc== -1? 0:rc; if( !delete_inv_parts( fname, keyblock, keyid ) ) { - log_info("%s: key %08lX, no valid user ids\n", - fname, (ulong)keyid[1]); + log_info_f( fname, _("key %08lX: no valid user ids\n"), + (ulong)keyid[1]); return 0; } @@ -284,27 +286,27 @@ import_one( const char *fname, KBNODE keyblock ) pk_orig = m_alloc_clear( sizeof *pk_orig ); rc = get_pubkey( pk_orig, keyid ); if( rc && rc != G10ERR_NO_PUBKEY ) { - log_error("%s: key %08lX, public key not found: %s\n", - fname, (ulong)keyid[1], g10_errstr(rc)); + log_error_f( fname, _("key %08lX: public key not found: %s\n"), + (ulong)keyid[1], g10_errstr(rc)); } else if( rc ) { /* insert this key */ /* get default resource */ if( get_keyblock_handle( NULL, 0, &kbpos ) ) { - log_error("no default public keyring\n"); + log_error(_("no default public keyring\n")); return G10ERR_GENERAL; } if( opt.verbose > 1 ) - log_info("%s: writing to '%s'\n", - fname, keyblock_resource_name(&kbpos) ); + log_info_f( fname, _("writing to '%s'\n"), + keyblock_resource_name(&kbpos) ); if( (rc=lock_keyblock( &kbpos )) ) - log_error("can't lock public keyring '%s': %s\n", - keyblock_resource_name(&kbpos), g10_errstr(rc) ); + log_error_f( keyblock_resource_name(&kbpos), + _("can't lock public keyring: %s\n"), g10_errstr(rc) ); else if( (rc=insert_keyblock( &kbpos, keyblock )) ) - log_error("%s: can't write to '%s': %s\n", fname, - keyblock_resource_name(&kbpos), g10_errstr(rc) ); + log_error_f( keyblock_resource_name(&kbpos), + _("can't write to keyring: %s\n"), g10_errstr(rc) ); unlock_keyblock( &kbpos ); /* we are ready */ - log_info("%s: key %08lX imported\n", fname, (ulong)keyid[1]); + log_info_f( fname, _("key %08lX: public key imported\n"), (ulong)keyid[1]); } else { /* merge */ int n_uids, n_sigs, n_subk; @@ -312,8 +314,8 @@ import_one( const char *fname, KBNODE keyblock ) /* Compare the original against the new key; just to be sure nothing * weird is going on */ if( cmp_public_keys( pk_orig, pk ) ) { - log_error("%s: key %08lX, doesn't match our copy\n", - fname, (ulong)keyid[1]); + log_error_f( fname, _("key %08lX: doesn't match our copy\n"), + (ulong)keyid[1]); rc = G10ERR_GENERAL; goto leave; } @@ -324,14 +326,16 @@ import_one( const char *fname, KBNODE keyblock ) /* now read the original keyblock */ rc = find_keyblock_bypk( &kbpos, pk_orig ); if( rc ) { - log_error("%s: key %08lX, can't locate original keyblock: %s\n", - fname, (ulong)keyid[1], g10_errstr(rc)); + log_error_f(fname, + _("key %08lX: can't locate original keyblock: %s\n"), + (ulong)keyid[1], g10_errstr(rc)); goto leave; } rc = read_keyblock( &kbpos, &keyblock_orig ); if( rc ) { - log_error("%s: key %08lX, can't read original keyblock: %s\n", - fname, (ulong)keyid[1], g10_errstr(rc)); + log_error_f(fname, + _("key %08lX: can't read original keyblock: %s\n"), + (ulong)keyid[1], g10_errstr(rc)); goto leave; } /* and try to merge the block */ @@ -345,37 +349,37 @@ import_one( const char *fname, KBNODE keyblock ) if( n_uids || n_sigs || n_subk ) { /* keyblock_orig has been updated; write */ if( opt.verbose > 1 ) - log_info("%s: writing to '%s'\n", - fname, keyblock_resource_name(&kbpos) ); + log_info_f(keyblock_resource_name(&kbpos), + _("writing keyblock\n")); if( (rc=lock_keyblock( &kbpos )) ) - log_error("can't lock public keyring '%s': %s\n", - keyblock_resource_name(&kbpos), g10_errstr(rc) ); + log_error_f(keyblock_resource_name(&kbpos), + _("can't lock public keyring: %s\n"), g10_errstr(rc) ); else if( (rc=update_keyblock( &kbpos, keyblock )) ) - log_error("%s: can't write to '%s': %s\n", fname, - keyblock_resource_name(&kbpos), g10_errstr(rc) ); + log_error_f( keyblock_resource_name(&kbpos), + _("can't write keyblock: %s\n"), g10_errstr(rc) ); unlock_keyblock( &kbpos ); /* we are ready */ if( n_uids == 1 ) - log_info("%s: key %08lX, 1 new user-id\n", - fname, (ulong)keyid[1]); + log_info_f(fname, _("key %08lX: 1 new user-id\n"), + (ulong)keyid[1]); else if( n_uids ) - log_info("%s: key %08lX, %d new user-ids\n", - fname, (ulong)keyid[1], n_uids ); + log_info_f(fname, _("key %08lX: %d new user-ids\n"), + (ulong)keyid[1], n_uids ); if( n_sigs == 1 ) - log_info("%s: key %08lX, 1 new signature\n", - fname, (ulong)keyid[1]); + log_info_f(fname, _("key %08lX: 1 new signature\n"), + (ulong)keyid[1]); else if( n_sigs ) - log_info("%s: key %08lX, %d new signatures\n", - fname, (ulong)keyid[1], n_sigs ); + log_info_f(fname, _("key %08lX: %d new signatures\n"), + (ulong)keyid[1], n_sigs ); if( n_subk == 1 ) - log_info("%s: key %08lX, 1 new subkey\n", - fname, (ulong)keyid[1]); + log_info_f(fname, _("key %08lX: 1 new subkey\n"), + (ulong)keyid[1]); else if( n_subk ) - log_info("%s: key %08lX, %d new subkeys\n", - fname, (ulong)keyid[1], n_subk ); + log_info_f(fname, _("key %08lX: %d new subkeys\n"), + (ulong)keyid[1], n_subk ); } else - log_info("%s: key %08lX, not changed\n", fname, (ulong)keyid[1] ); + log_info_f(fname, _("key %08lX: not changed\n"), (ulong)keyid[1] ); } leave: @@ -408,7 +412,7 @@ import_secret_one( const char *fname, KBNODE keyblock ) uidnode = find_next_kbnode( keyblock, PKT_USER_ID ); if( opt.verbose ) { - log_info("%s: sec %4u%c/%08lX %s ", fname, + log_info_f(fname, "sec %4u%c/%08lX %s ", nbits_from_sk( sk ), pubkey_letter( sk->pubkey_algo ), (ulong)keyid[1], datestr_from_sk(sk) ); @@ -418,7 +422,7 @@ import_secret_one( const char *fname, KBNODE keyblock ) putc('\n', stderr); } if( !uidnode ) { - log_error("%s: No user id for key %08lX\n", fname, (ulong)keyid[1]); + log_error_f(fname, _("key %08lX: no user id\n"), (ulong)keyid[1]); return 0; } @@ -433,25 +437,24 @@ import_secret_one( const char *fname, KBNODE keyblock ) return G10ERR_GENERAL; } if( opt.verbose > 1 ) - log_info("%s: writing to '%s'\n", - fname, keyblock_resource_name(&kbpos) ); + log_info_f(keyblock_resource_name(&kbpos), _("writing keyblock\n")); if( (rc=lock_keyblock( &kbpos )) ) - log_error("can't lock secret keyring '%s': %s\n", - keyblock_resource_name(&kbpos), g10_errstr(rc) ); + log_error_f( keyblock_resource_name(&kbpos), + _("can't lock secret keyring: %s\n"), g10_errstr(rc) ); else if( (rc=insert_keyblock( &kbpos, keyblock )) ) - log_error("%s: can't write to '%s': %s\n", fname, - keyblock_resource_name(&kbpos), g10_errstr(rc) ); + log_error_f(keyblock_resource_name(&kbpos), + _("can't write keyring\n"), g10_errstr(rc) ); unlock_keyblock( &kbpos ); /* we are ready */ - log_info("%s: key %08lX imported\n", fname, (ulong)keyid[1]); + log_info_f(fname, _("key %08lX: secret key imported\n"), (ulong)keyid[1]); } else if( !rc ) { /* we can't merge secret keys */ - log_error("%s: key %08lX already in secret keyring\n", - fname, (ulong)keyid[1]); + log_error_f(fname, _("key %08lX: already in secret keyring\n"), + (ulong)keyid[1]); } else - log_error("%s: key %08lX, secret key not found: %s\n", - fname, (ulong)keyid[1], g10_errstr(rc)); + log_error_f(fname, _("key %08lX: secret key not found: %s\n"), + (ulong)keyid[1], g10_errstr(rc)); release_kbnode( keyblock_orig ); return rc; @@ -480,29 +483,30 @@ import_revoke_cert( const char *fname, KBNODE node ) pk = m_alloc_clear( sizeof *pk ); rc = get_pubkey( pk, keyid ); if( rc == G10ERR_NO_PUBKEY ) { - log_info("%s: key %08lX, no public key - " - "can't apply revocation certificate\n", - fname, (ulong)keyid[1]); + log_info_f(fname, _("key %08lX: no public key - " + "can't apply revocation certificate\n"), (ulong)keyid[1]); rc = 0; goto leave; } else if( rc ) { - log_error("%s: key %08lX, public key not found: %s\n", - fname, (ulong)keyid[1], g10_errstr(rc)); + log_error_f(fname, _("key %08lX: public key not found: %s\n"), + (ulong)keyid[1], g10_errstr(rc)); goto leave; } /* read the original keyblock */ rc = find_keyblock_bypk( &kbpos, pk ); if( rc ) { - log_error("%s: key %08lX, can't locate original keyblock: %s\n", - fname, (ulong)keyid[1], g10_errstr(rc)); + log_error_f(fname, + _("key %08lX: can't locate original keyblock: %s\n"), + (ulong)keyid[1], g10_errstr(rc)); goto leave; } rc = read_keyblock( &kbpos, &keyblock ); if( rc ) { - log_error("%s: key %08lX, can't read original keyblock: %s\n", - fname, (ulong)keyid[1], g10_errstr(rc)); + log_error_f(fname, + _("key %08lX: can't read original keyblock: %s\n"), + (ulong)keyid[1], g10_errstr(rc)); goto leave; } @@ -512,9 +516,8 @@ import_revoke_cert( const char *fname, KBNODE node ) * special case. */ rc = check_key_signature( keyblock, node, NULL); if( rc ) { - log_error("%s: key %08lX, invalid revocation certificate" - ": %s - rejected\n", - fname, (ulong)keyid[1], g10_errstr(rc)); + log_error_f(fname, _("key %08lX: invalid revocation certificate" + ": %s - rejected\n"), (ulong)keyid[1], g10_errstr(rc)); } @@ -537,18 +540,17 @@ import_revoke_cert( const char *fname, KBNODE node ) /* and write the keyblock back */ if( opt.verbose > 1 ) - log_info("%s: writing to '%s'\n", - fname, keyblock_resource_name(&kbpos) ); + log_info_f( keyblock_resource_name(&kbpos), _("writing keyblock\n")); if( (rc=lock_keyblock( &kbpos )) ) - log_error("can't lock public keyring '%s': %s\n", - keyblock_resource_name(&kbpos), g10_errstr(rc) ); + log_error_f( keyblock_resource_name(&kbpos), + _("can't lock public keyring: %s\n"), g10_errstr(rc) ); else if( (rc=update_keyblock( &kbpos, keyblock )) ) - log_error("%s: can't write to '%s': %s\n", fname, - keyblock_resource_name(&kbpos), g10_errstr(rc) ); + log_error_f(keyblock_resource_name(&kbpos), + _("can't write keyblock: %s\n"), g10_errstr(rc) ); unlock_keyblock( &kbpos ); /* we are ready */ - log_info("%s: key %08lX, added revocation certificate\n", - fname, (ulong)keyid[1]); + log_info_f(fname, _("key %08lX: revocation certificate imported\n"), + (ulong)keyid[1]); leave: release_kbnode( keyblock ); @@ -577,16 +579,16 @@ chk_self_sigs( const char *fname, KBNODE keyblock, if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { unode = find_prev_kbnode( keyblock, n, PKT_USER_ID ); if( !unode ) { - log_error("%s: key %08lX, no user-id for signature\n", - fname, (ulong)keyid[1]); + log_error_f(fname, _("key %08lX: no user-id for signature\n"), + (ulong)keyid[1]); return -1; /* the complete keyblock is invalid */ } rc = check_key_signature( keyblock, n, NULL); if( rc ) { - log_error( rc == G10ERR_PUBKEY_ALGO ? - "%s: key %08lX, unsupported public key algorithm\n": - "%s: key %08lX, invalid self-signature\n", - fname, (ulong)keyid[1]); + log_error_f( fname, rc == G10ERR_PUBKEY_ALGO ? + _("key %08lX: unsupported public key algorithm\n"): + _("key %08lX: invalid self-signature\n"), + (ulong)keyid[1]); unode->flag |= 2; /* mark as invalid */ } @@ -614,8 +616,8 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid ) uid_seen = 1; if( (node->flag & 2) || !(node->flag & 1) ) { if( opt.verbose ) { - log_info("%s: key %08lX, removed userid '", - fname, (ulong)keyid[1]); + log_info_f(fname, _("key %08lX: skipped userid '"), + (ulong)keyid[1]); print_string( stderr, node->pkt->pkt.user_id->name, node->pkt->pkt.user_id->len, 0 ); fputs("'\n", stderr ); @@ -637,15 +639,15 @@ 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("%s: key %08lX, revocation certificate at wrong " - "place - removed\n", fname, (ulong)keyid[1]); + log_error_f(fname, _("key %08lX: revocation certificate at wrong " + "place - skipped\n"), fname, (ulong)keyid[1]); delete_kbnode( node ); } else { int rc = check_key_signature( keyblock, node, NULL); if( rc ) { - log_error("%s: key %08lX, invalid revocation certificate" - ": %s - removed\n", + log_error_f(fname, _("key %08lX: invalid revocation certificate" + ": %s - skipped\n"), fname, (ulong)keyid[1], g10_errstr(rc)); delete_kbnode( node ); } @@ -706,8 +708,8 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock, insert_kbnode( keyblock_orig, n2, 0 ); n2->flag |= 1; node->flag |= 1; - log_info("%s: key %08lX, added revocation certificate\n", - fname, (ulong)keyid[1]); + log_info_f(fname, _("key %08lX: revocation certificate added\n"), + (ulong)keyid[1]); } } } @@ -769,7 +771,7 @@ append_uid( KBNODE keyblock, KBNODE node, int *n_sigs, assert(node->pkt->pkttype == PKT_USER_ID ); /* at lease a self signature comes next to the user-id */ if( node->next->pkt->pkttype == PKT_USER_ID ) { - log_error("%s: key %08lX, our copy has no self-signature\n", + log_error_f(fname, _("key %08lX: our copy has no self-signature\n"), fname, (ulong)keyid[1]); return G10ERR_GENERAL; } @@ -805,8 +807,8 @@ merge_sigs( KBNODE dst, KBNODE src, int *n_sigs, /* at least a self signature comes next to the user-ids */ assert(src->next->pkt->pkttype != PKT_USER_ID ); if( dst->next->pkt->pkttype == PKT_USER_ID ) { - log_error("%s: key %08lX, our copy has no self-signature\n", - fname, (ulong)keyid[1]); + log_error_f(fname, _("key %08lX: our copy has no self-signature\n"), + (ulong)keyid[1]); return 0; } diff --git a/g10/mainproc.c b/g10/mainproc.c index f01380e00..b73d49bd1 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -232,22 +232,34 @@ static void proc_plaintext( CTX c, PACKET *pkt ) { PKT_plaintext *pt = pkt->pkt.plaintext; - int any, rc; + int any, clearsig, rc; KBNODE n; if( opt.verbose ) log_info("original file name='%.*s'\n", pt->namelen, pt->name); free_md_filter_context( &c->mfx ); - /* fixme: look at the sigclass to check whether we should use the - * textmode filter (sigclass 0x01) - */ c->mfx.md = md_open( 0, 0); - any = 0; + /* fixme: we may need to push the textfilter if we have sigclass 1 + * and no armoring - Not yet tested */ + any = clearsig = 0; for(n=c->list; n; n = n->next ) { - if( n->pkt->pkttype == PKT_ONEPASS_SIG - && n->pkt->pkt.onepass_sig->digest_algo ) { - md_enable( c->mfx.md, n->pkt->pkt.onepass_sig->digest_algo ); - any = 1; + if( n->pkt->pkttype == PKT_ONEPASS_SIG ) { + if( n->pkt->pkt.onepass_sig->digest_algo ) { + md_enable( c->mfx.md, n->pkt->pkt.onepass_sig->digest_algo ); + any = 1; + } + /* Check whether this is a cleartext signature. We assume that + * we have one if the sig_class is 1 and the keyid is 0, that + * are the faked packets produced by armor.c. There is a + * possibility that this fails, but there is no other easy way + * to do it. (We could use a special packet type to indicate + * this, but this may also be faked - it simply can't be verified + * and is _no_ security issue) + */ + if( n->pkt->pkt.onepass_sig->sig_class == 0x01 + && !n->pkt->pkt.onepass_sig->keyid[0] + && !n->pkt->pkt.onepass_sig->keyid[1] ) + clearsig = 1; } } if( !any ) { /* no onepass sig packet: enable all algos */ @@ -260,7 +272,7 @@ proc_plaintext( CTX c, PACKET *pkt ) if( c->mfx.md->list ) m_check( c->mfx.md->list ); } - rc = handle_plaintext( pt, &c->mfx, c->sigs_only ); + rc = handle_plaintext( pt, &c->mfx, c->sigs_only, clearsig ); if( rc ) log_error( "handle plaintext failed: %s\n", g10_errstr(rc)); if( c->mfx.md ) { diff --git a/g10/options.h b/g10/options.h index 8ad0a4205..0929be328 100644 --- a/g10/options.h +++ b/g10/options.h @@ -37,9 +37,10 @@ struct { int no_armor; int list_packets; /* list-packets mode */ int def_cipher_algo; - int reserved; + int do_not_export_rsa; int def_digest_algo; int def_compress_algo; + const char *def_secret_key; int no_comment; int marginals_needed; int completes_needed; diff --git a/g10/packet.h b/g10/packet.h index edca2a4e9..9c8a8547d 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -282,7 +282,8 @@ int decrypt_data( PKT_encrypted *ed, DEK *dek ); int encrypt_data( PKT_encrypted *ed, DEK *dek ); /*-- plaintext.c --*/ -int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,int nooutput); +int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, + int nooutput, int clearsig ); int ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname ); /*-- comment.c --*/ diff --git a/g10/plaintext.c b/g10/plaintext.c index 161db58d4..8d7b2a97e 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -34,19 +34,61 @@ /**************** + * Defer the last CR,LF + */ +static void +special_md_putc( MD_HANDLE md, int c, int *state ) +{ + if( c == -1 ) { /* flush */ + if( *state == 1 ) { + md_putc(md, '\r'); + } + *state = 0; + return; + } + again: + switch( *state ) { + case 0: + if( c == '\r' ) + *state = 1; + else + md_putc(md, c ); + break; + case 1: + if( c == '\n' ) + *state = 2; + else { + md_putc(md, '\r'); + *state = 0; + goto again; + } + break; + case 2: + md_putc(md, '\r'); + md_putc(md, '\n'); + *state = 0; + goto again; + default: BUG(); + } +} + + +/**************** * Handle a plaintext packet. If MFX is not NULL, update the MDs * Note: we should use the filter stuff here, but we have to add some * easy mimic to set a read limit, so we calculate only the * bytes from the plaintext. */ int -handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, int nooutput ) +handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, + int nooutput, int clearsig ) { char *fname = NULL; FILE *fp = NULL; int rc = 0; int c; int convert = pt->mode == 't'; + int special_state = 0; /* create the filename as C string */ if( nooutput ) @@ -86,10 +128,14 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, int nooutput ) rc = G10ERR_READ_FILE; goto leave; } - if( mfx->md ) - md_putc(mfx->md, c ); + if( mfx->md ) { + if( convert && clearsig ) + special_md_putc(mfx->md, c, &special_state ); + else + md_putc(mfx->md, c ); + } if( convert && c == '\r' ) - continue; /* FIXME: this hack is too simple */ + continue; /* fixme: this hack might be too simple */ if( fp ) { if( putc( c, fp ) == EOF ) { log_error("Error writing to '%s': %s\n", @@ -102,10 +148,14 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, int nooutput ) } else { while( (c = iobuf_get(pt->buf)) != -1 ) { - if( mfx->md ) - md_putc(mfx->md, c ); + if( mfx->md ) { + if( convert && clearsig ) + special_md_putc(mfx->md, c, &special_state ); + else + md_putc(mfx->md, c ); + } if( convert && c == '\r' ) - continue; /* FIXME: this hack is too simple */ + continue; /* fixme: this hack might be too simple */ if( fp ) { if( putc( c, fp ) == EOF ) { log_error("Error writing to '%s': %s\n", @@ -117,6 +167,8 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, int nooutput ) } iobuf_clear_eof(pt->buf); } + if( mfx->md && convert && clearsig ) + special_md_putc(mfx->md, -1, &special_state ); /* flush */ if( fp && fp != stdout && fclose(fp) ) { log_error("Error closing '%s': %s\n", fname, strerror(errno) ); diff --git a/g10/sign.c b/g10/sign.c index 7dffba314..14dfe417e 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -416,14 +416,14 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, /**************** - * note: we do not count empty lines at the beginning + * Note: We do not calculate the hash over the last CR,LF */ static int write_dash_escaped( IOBUF inp, IOBUF out, MD_HANDLE md ) { int c; int lastlf = 1; - int skip_empty = 1; + int state = 0; while( (c = iobuf_get(inp)) != -1 ) { /* Note: We don't escape "From " because the MUA should cope with it */ @@ -431,21 +431,41 @@ write_dash_escaped( IOBUF inp, IOBUF out, MD_HANDLE md ) if( c == '-' ) { iobuf_put( out, c ); iobuf_put( out, ' ' ); - skip_empty = 0; } - else if( skip_empty && c == '\r' ) - skip_empty = 2; - else - skip_empty = 0; } - if( !skip_empty ) - md_putc(md, c ); + again: + switch( state ) { + case 0: + if( c == '\r' ) + state = 1; + else + md_putc(md, c ); + break; + case 1: + if( c == '\n' ) + state = 2; + else { + md_putc(md, '\r'); + state = 0; + goto again; + } + break; + case 2: + md_putc(md, '\r'); + md_putc(md, '\n'); + state = 0; + goto again; + default: BUG(); + } iobuf_put( out, c ); lastlf = c == '\n'; - if( skip_empty == 2 ) - skip_empty = lastlf ? 0 : 1; } + if( state == 1 ) + md_putc(md, '\r'); + if( !lastlf ) + iobuf_put( out, '\n' ); + return 0; /* fixme: add error handling */ } @@ -537,13 +557,11 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) PKT_secret_key *sk = sk_rover->sk; md_enable(textmd, hash_for(sk->pubkey_algo)); } - iobuf_push_filter( inp, text_filter, &tfx ); rc = write_dash_escaped( inp, out, textmd ); if( rc ) goto leave; - iobuf_writestr(out, "\n" ); afx.what = 2; iobuf_push_filter( out, armor_filter, &afx ); diff --git a/g10/textfilter.c b/g10/textfilter.c index c42624eff..804b48505 100644 --- a/g10/textfilter.c +++ b/g10/textfilter.c @@ -51,8 +51,11 @@ read_line( byte *buf, size_t *r_buflen, IOBUF a ) for(c=0, n=0; n < buflen && (c=iobuf_get2(a)) != -1 && c != '\n'; ) buf[n++] = c; buf[n] = 0; - if( c == -1 ) + if( c == -1 ) { rc = -1; + if( !n || buf[n-1] != '\n' ) + no_lf = 1; + } else if( c != '\n' ) { IOBUF b = iobuf_temp(); while( (c=iobuf_get2(a)) != -1 && c != '\n' ) { |