diff --git a/NEWS b/NEWS index b942af624..86835f12e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,18 @@ +Noteworthy changes in version 0.3.1 +----------------------------------- + * Partial headers are now written in the OpenPGP format if + a key in a v4 packet is used. + + * Removed some unused options, removed the gnupg.sig stuff. + + * Key lookup by name now returns a key which can be used for + the desired action. + + * New options --list-ownertrust (gpgm) to make a backup copy + of the ownertrust values you assigned. + + * clear signature headers are now in compliance with OpenPGP. + Noteworthy changes in version 0.3.0 ----------------------------------- diff --git a/TODO b/TODO index 50d799ad5..aa723cc58 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,13 @@ - * add writing of partial headers conforming to OpenPGP - util/iobuf.c:block_filter + * add option --restore-ownertrust * add options: --default-signature-user, --default-encryption-user + * Change the formatting of log_xxxx to GNU standards + ("name:filename:line: text") + + * add a way to delete subkeys (in edit-keys?) + * make preferences work * rewrite --list-packets or put it into another tool. @@ -15,7 +19,9 @@ * add readline support. Must enhance libreadline - Anyone? - * Burn the buffers used by fopen(), or use read(2). + * Burn the buffers used by fopen(), or use read(2). Does this + really make sense? + * enable a SIGSEGV handler while using zlib functions diff --git a/checks/Makefile.am b/checks/Makefile.am index 8787bc032..ae09b207b 100644 --- a/checks/Makefile.am +++ b/checks/Makefile.am @@ -12,7 +12,7 @@ TESTS = version.test mds.test \ conventional.test -TEST_FILES = pubring.asc secring.asc gnupg.asc plain-1 plain-2 plain-3o.asc \ +TEST_FILES = pubring.asc secring.asc plain-1 plain-2 plain-3o.asc \ plain-1.asc plain-2.asc plain-3.asc plain-1-pgp.asc \ pubring.pkr.asc secring.skr.asc @@ -23,17 +23,14 @@ CLEANFILES = prepared.stamp x y z out err $(DATA_FILES) check: prepared.stamp -prepared.stamp: pubring.gpg secring.gpg gnupg.sig plain-3 \ +prepared.stamp: pubring.gpg secring.gpg plain-3 \ pubring.pkr secring.skr $(DATA_FILES) - @echo "def" | ../g10/gpg --homedir . -v --no-operation; \ echo timestamp >./prepared.stamp pubring.gpg: pubring.asc ../g10/gpgm --yes --dearmor -o pubring.gpg pubring.asc secring.gpg: secring.asc ../g10/gpgm --yes --dearmor -o secring.gpg secring.asc -gnupg.sig: gnupg.asc - ../g10/gpgm --yes --dearmor -o gnupg.sig gnupg.asc plain-3: plain-3o.asc ../g10/gpgm --yes --dearmor -o plain-3 plain-3o.asc pubring.pkr: pubring.pkr.asc diff --git a/checks/gnupg.asc b/checks/gnupg.asc deleted file mode 100644 index 54f9824d6..000000000 --- a/checks/gnupg.asc +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN PGP ARMORED FILE----- -Version: GNUPG v0.2.7b (Linux) -Comment: This is an alpha version! -Comment: Use "g10maint --dearmor" for unpacking - -0CEjY3JlYXRlZCBieSBHTlVQRyB2MC4yLjdiIChMaW51eCmQDQMAAxDlaCrLPviEowGI1wMFADTy -2TnlaCrLPviEoxADgEwC/jmq4S8mH3ulVqOyszVXwLaOGwtNdQMc+q5yOTiGTme6tLrYshsXDrG0 -qEeLEny8gqPpuUSH0Qht5V45sD8EfYBqptoxYiwpHlQcghrEUqGgo+QgXffPcrlbGINs576mugMA -mj/y4wOgoeJmc8WWNEnx+LehCZE1OaLpV5IWHigefsVLLv7jcQ2j80yxdCllqzvQTPQN+tlVoGei -yoC4BF2wzoG8sWJ0B9xFkQ/WV0jh1vpWiSfnZU1yhVkRNMk7SodM -=Ehf8 ------END PGP ARMORED FILE----- diff --git a/cipher/dsa.c b/cipher/dsa.c index 46484c1e9..107ed71c2 100644 --- a/cipher/dsa.c +++ b/cipher/dsa.c @@ -405,7 +405,7 @@ dsa_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig, *nsig = 2; switch( algo ) { - case PUBKEY_ALGO_DSA: *usage = 1; return "DSA"; + case PUBKEY_ALGO_DSA: *usage = PUBKEY_USAGE_SIG; return "DSA"; default: *usage = 0; return NULL; } } diff --git a/cipher/elgamal.c b/cipher/elgamal.c index bcaaa20ba..9b9981da1 100644 --- a/cipher/elgamal.c +++ b/cipher/elgamal.c @@ -510,8 +510,8 @@ elg_get_nbits( int algo, MPI *pkey ) * the ALGO is invalid. * Usage: Bit 0 set : allows signing * 1 set : allows encryption - * NOTE: This function allows signing also for ELG-E, chich is not - * okay but a bad hack to allow to work with olf gpg keys. The real check + * NOTE: This function allows signing also for ELG-E, which is not + * okay but a bad hack to allow to work with old gpg keys. The real check * is done in the gnupg ocde depending on the packet version. */ const char * @@ -524,8 +524,12 @@ elg_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig, *nsig = 2; switch( algo ) { - case PUBKEY_ALGO_ELGAMAL: *usage = 2|1; return "ELG"; - case PUBKEY_ALGO_ELGAMAL_E: *usage = 2|1; return "ELG-E"; + case PUBKEY_ALGO_ELGAMAL: + *usage = PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC; + return "ELG"; + case PUBKEY_ALGO_ELGAMAL_E: + *usage = PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC; + return "ELG-E"; default: *usage = 0; return NULL; } } diff --git a/cipher/pubkey.c b/cipher/pubkey.c index f59996c4d..a78f788c0 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -282,9 +282,11 @@ check_pubkey_algo2( int algo, unsigned usage ) do { for(i=0; pubkey_table[i].name; i++ ) if( pubkey_table[i].algo == algo ) { - if( (usage & 1) && !(pubkey_table[i].usage & 1) ) + if( (usage & PUBKEY_USAGE_SIG) + && !(pubkey_table[i].usage & PUBKEY_USAGE_SIG) ) return G10ERR_WR_PUBKEY_ALGO; - if( (usage & 2) && !(pubkey_table[i].usage & 2) ) + if( (usage & PUBKEY_USAGE_ENC) + && !(pubkey_table[i].usage & PUBKEY_USAGE_ENC) ) return G10ERR_WR_PUBKEY_ALGO; return 0; /* okay */ } diff --git a/doc/DETAILS b/doc/DETAILS index a9f04090f..e315bf550 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -71,7 +71,7 @@ Record type 1: 1 byte completes needed 1 byte max. cert depth If any of this 3 values are changed, all cache records - muts be invalidated. + must be invalidated. 9 bytes reserved @@ -88,7 +88,9 @@ Record type 2: (directory record) 1 u32 cache record 1 u32 sigrecord 1 byte No signatures flag (used to avoid duplicate building). - 13 byte reserved + 3 byte reserved + 1 u32 preference record + 6 byte reserved Record type 3: @@ -124,7 +126,7 @@ Record type 4: (cache record) 20 bytes rmd160 hash value over the complete keyblock This is used to detect any changes of the keyblock with all CTBs and lengths headers. Calculation is easy if the keyblock - is optained from a keyserved: simply create the hash from all + is optained from a keyserver: simply create the hash from all received data bytes. 1 byte number of untrusted signatures. @@ -162,7 +164,7 @@ Record Type 6 (hash table) used directly as hash values. (They can be considered as strong random numbers.) What we use is a dynamic multilevel architecture, which combines - Hashtables, record lists, and linked lists. + hashtables, record lists, and linked lists. This record is a hashtable of 256 entries; a special property is that all these records are stored consecutively to make one @@ -207,7 +209,6 @@ Record type 7 (hash list) - Packet Headers =============== diff --git a/doc/gpg.1pod b/doc/gpg.1pod index 9fe18c5ec..8a67dfb09 100644 --- a/doc/gpg.1pod +++ b/doc/gpg.1pod @@ -5,10 +5,14 @@ gpg - GNU Privacy Guard =head1 SYNOPSIS B [--homedir name] [--options file] [options] command [args] +B [--homedir name] [--options file] [options] command [args] =head1 DESCRIPTION -This is the main program for the GNUPG system. +B is the main program for the GNUPG system. B is a maintenance +tool which has some commands B does not have; it is there because +it does not handle sensitive data ans therefore has no need to allocate +secure memory. =head1 COMMANDS @@ -91,6 +95,11 @@ B<--gen-key> Generate a new key pair. This command can only be used interactive. +B<--add-key> I + Add a subkey to an already existing key. This + command is similiar to B<--gen-key> but a primary + key must already exit. + B<--sign-key> I Make a signature on key of user I. This looks for the key, displays the key and checks @@ -130,6 +139,9 @@ B<--export> [I] B<--import> import/merge keys +B<--list-ownertrust> + List the assigned ownertrust values in ascii format for + backup purposes [B only]. =head1 OPTIONS @@ -246,11 +258,6 @@ B<--cipher-algo> I with the option B<--verbose> yields a list of supported algorithms. -B<--pubkey-algo> I - Use I as puplic key algorithm. Running the program - with the option B<--verbose> yields a list of supported - algorithms. - B<--digest-algo> I Use I as message digest algorithm. Running the program with the option B<--verbose> yields a list of diff --git a/g10/ChangeLog b/g10/ChangeLog index 7094ed601..664d378bb 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,41 @@ +Mon Jul 6 09:03:49 1998 Werner Koch (wk@isil.d.shuttle.de) + + * getkey.c (add_keyring): Keyrings are now added to end of the + list of keyrings. The first added keyringwill be created. + (add_secret_keyring): Likewise. + + * ringedit.c (add_keyblock_resource): Files are created here. + + * g10.c (aNOP): Removed + + * getkey.c (lookup): Add checking of usage for name lookups + * packet.h (pubkey_usage): Add a field which may be used to store + usage capabilities. + * pkclist.c (build_pk_list): getkey now called with usage arg. + * skclist.c (build_sk_list): Ditto. + + * sign.c (clearsign_file): Fixed "Hash:" headers + +Sat Jul 4 13:33:31 1998 Werner Koch (wk@isil.d.shuttle.de) + + * trustdb.c (list_ownertrust): New. + * g10.c (aListOwnerTrust): New. + + * g10.c (def_pubkey_algo): Removed. + + * trustdb.c (verify_private_data): Removed and also the call to it. + (sign_private_data): Removed. + +Fri Jul 3 13:26:10 1998 Werner Koch (wk@isil.d.shuttle.de) + + * g10.c (aEditKey): was aEditSig. Changed usage msg. + + * keyedit.c: Done some i18n stuff. + + * g10.c (do_not_use_RSA): New. + * sign.c (do_sign): Add call to above function. + * encode.c (write_pubkey_enc_from_list): Ditto. + Thu Jul 2 21:01:25 1998 Werner Koch (wk@isil.d.shuttle.de) * parse-packet.c: Now is able sto store data of unknown diff --git a/g10/Makefile.am b/g10/Makefile.am index 579ec6075..c64055423 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -32,6 +32,8 @@ common_source = \ keyid.c \ trustdb.c \ trustdb.h \ + pref.h \ + pref.c \ packet.h \ parse-packet.c \ passphrase.c \ diff --git a/g10/armor.c b/g10/armor.c index 7fe2f8172..1dd028afc 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -325,7 +325,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, if( n < buflen || c == '\n' ) { if( n && buf[0] != '\r') { /* maybe a header */ if( strchr( buf, ':') ) { /* yes */ - int hashes; + int hashes=0; if( buf[n-1] == '\r' ) buf[--n] = 0; if( opt.verbose ) { @@ -822,13 +822,19 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn, else if( (c=iobuf_get(a)) == -1 ) break; } while( ++idx < 4 ); - if( c == -1 ) + if( c == -1 ) { log_error("premature eof (in CRC)\n"); - else if( idx != 4 ) + rc = G10ERR_INVALID_ARMOR; + } + else if( idx != 4 ) { log_error("malformed CRC\n"); - else if( mycrc != afx->crc ) + rc = G10ERR_INVALID_ARMOR; + } + else if( mycrc != afx->crc ) { log_error("CRC error; %06lx - %06lx\n", (ulong)afx->crc, (ulong)mycrc); + rc = G10ERR_INVALID_ARMOR; + } else { rc = 0; #if 0 @@ -843,10 +849,14 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn, } if( rc == -1 ) rc = 0; - else if( rc == 2 ) + else if( rc == 2 ) { log_error("premature eof (in Trailer)\n"); - else + rc = G10ERR_INVALID_ARMOR; + } + else { log_error("error in trailer line\n"); + rc = G10ERR_INVALID_ARMOR; + } #endif } } @@ -988,7 +998,8 @@ armor_filter( void *opaque, int control, iobuf_writestr(a, "-----\n"); iobuf_writestr(a, "Version: GNUPG v" VERSION " (" PRINTABLE_OS_NAME ")\n"); - iobuf_writestr(a, "Comment: This is an alpha version!\n"); + iobuf_writestr(a, + "Comment: Get GNUPG from ftp://ftp.guug.de/pub/gcrypt/\n"); if( afx->hdrlines ) iobuf_writestr(a, afx->hdrlines); iobuf_put(a, '\n'); diff --git a/g10/build-packet.c b/g10/build-packet.c index b8acc577e..ae5e08f15 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -281,7 +281,7 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk ) iobuf_put(a, sk->pubkey_algo ); nskey = pubkey_get_nskey( sk->pubkey_algo ); npkey = pubkey_get_npkey( sk->pubkey_algo ); - if( npkey ) { + if( !npkey ) { write_fake_data( a, sk->skey[0] ); goto leave; } diff --git a/g10/cipher.c b/g10/cipher.c index b975d26f1..0891d52fb 100644 --- a/g10/cipher.c +++ b/g10/cipher.c @@ -46,6 +46,7 @@ write_header( cipher_filter_context_t *cfx, IOBUF a ) memset( &ed, 0, sizeof ed ); ed.len = cfx->datalen; + ed.new_ctb = !ed.len && !opt.rfc1991; init_packet( &pkt ); pkt.pkttype = PKT_ENCRYPTED; pkt.pkt.encrypted = &ed; @@ -88,13 +89,7 @@ cipher_filter( void *opaque, int control, rc = G10ERR_WRITE_FILE; } else if( control == IOBUFCTRL_FREE ) { - #if 0 - if( cfx->new_partial && cfx->cfx->la_buffer ) { - - } - #endif cipher_close(cfx->cipher_hd); - m_free(cfx->la_buffer); cfx->la_buffer = NULL; } else if( control == IOBUFCTRL_DESC ) { *(char**)buf = "cipher_filter"; diff --git a/g10/encode.c b/g10/encode.c index 2cc2f10c3..969e9afee 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -34,6 +34,7 @@ #include "util.h" #include "main.h" #include "filter.h" +#include "i18n.h" static int encode_simple( const char *filename, int mode ); @@ -81,7 +82,7 @@ encode_simple( const char *filename, int mode ) /* prepare iobufs */ if( !(inp = iobuf_open(filename)) ) { - log_error("can't open %s: %s\n", filename? filename: "[stdin]", + log_error(_("%s: can't open: %s\n"), filename? filename: "[stdin]", strerror(errno) ); return G10ERR_OPEN_FILE; } @@ -98,7 +99,7 @@ encode_simple( const char *filename, int mode ) m_free(cfx.dek); m_free(s2k); iobuf_close(inp); - log_error("error creating passphrase: %s\n", g10_errstr(rc) ); + log_error(_("error creating passphrase: %s\n"), g10_errstr(rc) ); return rc; } } @@ -134,7 +135,7 @@ encode_simple( const char *filename, int mode ) pt->namelen = strlen(filename); memcpy(pt->name, filename, pt->namelen ); if( !(filesize = iobuf_get_filelength(inp)) ) - log_info("warning: '%s' is an empty file\n", filename ); + log_info(_("%s: warning: empty file\n"), filename ); } else { /* no filename */ pt = m_alloc( sizeof *pt - 1 ); @@ -191,18 +192,18 @@ encode_crypt( const char *filename, STRLIST remusr ) memset( &afx, 0, sizeof afx); memset( &zfx, 0, sizeof zfx); - if( (rc=build_pk_list( remusr, &pk_list, 2)) ) + if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) ) return rc; /* prepare iobufs */ if( !(inp = iobuf_open(filename)) ) { - log_error("can't open %s: %s\n", filename? filename: "[stdin]", + log_error(_("can't open %s: %s\n"), filename? filename: "[stdin]", strerror(errno) ); rc = G10ERR_OPEN_FILE; goto leave; } else if( opt.verbose ) - log_info("reading from '%s'\n", filename? filename: "[stdin]"); + log_info(_("reading from '%s'\n"), filename? filename: "[stdin]"); if( !(out = open_outfile( filename, opt.armor? 1:0 )) ) { rc = G10ERR_CREATE_FILE; /* or user said: do not overwrite */ @@ -232,7 +233,7 @@ encode_crypt( const char *filename, STRLIST remusr ) pt->namelen = strlen(filename); memcpy(pt->name, filename, pt->namelen ); if( !(filesize = iobuf_get_filelength(inp)) ) - log_info("warning: '%s' is an empty file\n", filename ); + log_info(_("%s: warning: empty file\n"), filename ); } else { /* no filename */ pt = m_alloc( sizeof *pt - 1 ); @@ -242,6 +243,7 @@ encode_crypt( const char *filename, STRLIST remusr ) pt->timestamp = make_timestamp(); pt->mode = 'b'; pt->len = filesize; + pt->new_ctb = !pt->len && !opt.rfc1991; pt->buf = inp; init_packet(&pkt); pkt.pkttype = PKT_PLAINTEXT; @@ -332,6 +334,8 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out ) MPI frame; pk = pk_list->pk; + if( is_RSA(pk->pubkey_algo) ) + do_not_use_RSA(); enc = m_alloc_clear( sizeof *enc ); enc->pubkey_algo = pk->pubkey_algo; keyid_from_pk( pk, enc->keyid ); @@ -344,7 +348,7 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out ) else { if( opt.verbose ) { char *ustr = get_user_id_string( enc->keyid ); - log_info("%s encrypted for: %s\n", + log_info(_("%s encrypted for: %s\n"), pubkey_algo_to_string(enc->pubkey_algo), ustr ); m_free(ustr); } diff --git a/g10/filter.h b/g10/filter.h index 108e64c0e..2dc8a3e87 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -61,9 +61,6 @@ typedef struct { typedef struct { DEK *dek; u32 datalen; - int new_partial; /* use Openpgp partial packets header */ - char *la_buffer; /* help buffer for OP partial stuff */ - size_t la_buflen; /* and its used length */ CIPHER_HANDLE cipher_hd; int header; } cipher_filter_context_t; diff --git a/g10/g10.c b/g10/g10.c index 4b1e696e2..07857d4a4 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -79,6 +79,7 @@ static ARGPARSE_OPTS opts[] = { { 530, "import", 0 , N_("import/merge keys")}, { 521, "list-packets",0,N_("list only the sequence of packets")}, #ifdef IS_G10MAINT + { 564, "list-ownertrust", 0, "list the ownertrust values"}, { 546, "dearmor", 0, N_("De-Armor a file or stdin") }, { 547, "enarmor", 0, N_("En-Armor a file or stdin") }, { 555, "print-md" , 0, N_("|algo [files]|print message digests")}, @@ -116,12 +117,10 @@ static ARGPARSE_OPTS opts[] = { { 561, "rfc1991", 0, N_("emulate the mode described in RFC1991")}, #ifdef IS_G10 { 527, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")}, - { 528, "pubkey-algo", 2 , N_("|NAME|use public key algorithm NAME")}, { 529, "digest-algo", 2 , N_("|NAME|use message digest algorithm NAME")}, { 556, "compress-algo", 1 , N_("|N|use compress algorithm N")}, #else /* some dummies */ { 527, "cipher-algo", 2 , "@"}, - { 528, "pubkey-algo", 2 , "@"}, { 529, "digest-algo", 2 , "@"}, { 556, "compress-algo", 1 , "@"}, #endif @@ -138,6 +137,7 @@ static ARGPARSE_OPTS opts[] = { /* hidden options */ #ifdef IS_G10MAINT { 514, "test" , 0, "@" }, + { 564, "list-ownertrust",0 , "@"}, { 531, "list-trustdb",0 , "@"}, { 533, "list-trust-path",0, "@"}, #endif @@ -154,7 +154,6 @@ static ARGPARSE_OPTS opts[] = { { 519, "no-armor", 0, "@"}, { 520, "no-default-keyring", 0, "@" }, { 522, "no-greeting", 0, "@" }, - { 541, "no-operation", 0, "@" }, /* used by regression tests */ { 543, "no-options", 0, "@" }, /* shortcut for --options /dev/null */ { 544, "homedir", 2, "@" }, /* defaults to "~/.gnupg" */ { 545, "no-batch", 0, "@" }, @@ -169,18 +168,19 @@ static ARGPARSE_OPTS opts[] = { {0} }; - +/* (Free numbers: 541) */ enum cmd_values { aNull = 0, aSym, aStore, aEncr, aKeygen, aSign, aSignEncr, - aSignKey, aClearsign, aListPackets, aEditSig, aDeleteKey, aDeleteSecretKey, + aSignKey, aClearsign, aListPackets, aEditKey, aDeleteKey, aDeleteSecretKey, aKMode, aKModeC, aChangePass, aImport, aVerify, aDecrypt, aListKeys, aListSigs, aKeyadd, aListSecretKeys, aExport, aExportSecret, aCheckKeys, aGenRevoke, aPrimegen, aPrintMD, aPrintMDs, - aListTrustDB, aListTrustPath, aDeArmor, aEnArmor, aGenRandom, aTest, -aNOP }; + aListTrustDB, aListTrustPath, aListOwnerTrust, + aDeArmor, aEnArmor, aGenRandom, +aTest }; static char *build_list( const char *text, @@ -358,8 +358,6 @@ check_opts(void) { if( !opt.def_cipher_algo || check_cipher_algo(opt.def_cipher_algo) ) log_error(_("selected cipher algorithm is invalid\n")); - if( !opt.def_pubkey_algo || check_pubkey_algo(opt.def_pubkey_algo) ) - log_error(_("selected pubkey algorithm is invalid\n")); if( opt.def_digest_algo && check_digest_algo(opt.def_digest_algo) ) log_error(_("selected digest algorithm is invalid\n")); if( opt.def_compress_algo < 1 || opt.def_compress_algo > 2 ) @@ -414,7 +412,6 @@ main( int argc, char **argv ) opt.compress = -1; /* defaults to standard compress level */ /* fixme: set the next two to zero and decide where used */ opt.def_cipher_algo = DEFAULT_CIPHER_ALGO; - opt.def_pubkey_algo = DEFAULT_PUBKEY_ALGO; opt.def_digest_algo = 0; opt.def_compress_algo = 2; opt.completes_needed = 1; @@ -510,14 +507,11 @@ main( int argc, char **argv ) case 506: set_cmd( &cmd, aSignKey); break; case 507: set_cmd( &cmd, aStore); break; case 523: set_passphrase_fd( pargs.r.ret_int ); break; - case 524: set_cmd( &cmd, aEditSig); break; + case 524: set_cmd( &cmd, aEditKey); break; case 525: set_cmd( &cmd, aChangePass); break; case 527: opt.def_cipher_algo = string_to_cipher_algo(pargs.r.ret_str); break; - case 528: - opt.def_pubkey_algo = string_to_pubkey_algo(pargs.r.ret_str); - break; case 529: opt.def_digest_algo = string_to_digest_algo(pargs.r.ret_str); break; @@ -527,7 +521,6 @@ main( int argc, char **argv ) case 550: set_cmd( &cmd, aVerify); break; #else case 527: - case 528: case 529: break; #endif /* !IS_G10 */ @@ -543,6 +536,7 @@ main( int argc, char **argv ) case 547: set_cmd( &cmd, aEnArmor); break; case 548: set_cmd( &cmd, aGenRandom); break; case 555: set_cmd( &cmd, aPrintMD); break; + case 564: set_cmd( &cmd, aListOwnerTrust); break; #endif /* IS_G10MAINT */ case 'o': opt.outfile = pargs.r.ret_str; break; @@ -581,7 +575,6 @@ 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: set_cmd( &cmd, aNOP); break; case 543: break; /* no-options */ case 544: opt.homedir = pargs.r.ret_str; break; case 545: opt.batch = 0; break; @@ -692,6 +685,7 @@ main( int argc, char **argv ) if( opt.with_colons ) /* need this to list the trust */ rc = init_trustdb(1, trustdb_name ); break; + case aListOwnerTrust: rc = init_trustdb( 0, trustdb_name ); break; case aListTrustDB: rc = init_trustdb( argc? 1:0, trustdb_name ); break; default: rc = init_trustdb(1, trustdb_name ); break; } @@ -784,9 +778,9 @@ main( int argc, char **argv ) log_error("%s: sign key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) ); break; - case aEditSig: /* Edit a key signature */ + case aEditKey: /* Edit a key signature */ if( argc != 1 ) - wrong_args(_("--edit-sig username")); + wrong_args(_("--edit-key username")); /* note: fname is the user id! */ if( (rc = edit_keysigs(fname)) ) log_error("%s: edit signature failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) ); @@ -1003,12 +997,15 @@ main( int argc, char **argv ) list_trust_path( atoi(*argv), argv[1] ); break; + case aListOwnerTrust: + if( argc ) + wrong_args("--list-ownertrust"); + list_ownertrust(); + break; + #endif /* IS_G10MAINT */ - case aNOP: - break; - case aListPackets: opt.list_packets=1; default: @@ -1053,6 +1050,20 @@ g10_exit( int rc ) exit(rc ); } + +void +do_not_use_RSA() +{ + static int did_rsa_note = 0; + + if( !did_rsa_note ) { + did_rsa_note = 1; + log_info(_("RSA keys are depreciated; please consider " + "creating a new key and use this key in the future\n")); + } +} + + #ifdef IS_G10MAINT static void print_hex( byte *p, size_t n ) @@ -1159,41 +1170,6 @@ print_mds( const char *fname, int algo ) static void do_test(int times) { - MPI base[4]; - MPI exp[4]; - MPI t1 = mpi_alloc(50); - MPI t2 = mpi_alloc(50); - MPI t3 = mpi_alloc(50); - MPI tmp= mpi_alloc(50); - MPI m = mpi_alloc(50); - MPI res = mpi_alloc(50); - - mpi_fromstr( m, "0x10000000000000000000000000" ); - base[0] = mpi_alloc_set_ui( 3 ); - mpi_fromstr( base[0], "0x145984358945989898495ffdd13" ); - base[1] = mpi_alloc_set_ui( 5 ); - mpi_fromstr( base[1], "0x000effff9999000000001100001" ); - base[2] = mpi_alloc_set_ui( 2 ); - mpi_fromstr( base[2], "0x499eeeaaaaa0444444545466672" ); - base[3] = NULL; - exp[0] = mpi_alloc_set_ui( 30 ); - exp[1] = mpi_alloc_set_ui( 10 ); - mpi_fromstr( exp[1], "0x3457878888888888aabbbccccc1" ); - exp[2] = mpi_alloc_set_ui( 24 ); - exp[3] = NULL; - - mpi_powm( t1, base[0], exp[0], m ); - mpi_powm( t2, base[1], exp[1], m ); - mpi_powm( t3, base[2], exp[2], m ); - mpi_mulm( tmp, t1, t2, m ); - mpi_mulm( t1, tmp, t3, m ); - log_mpidump("X=", t1 ); - - - mpi_mulpowm( res, base, exp, m ); - log_mpidump("X=", res ); - - m_check(NULL); } #endif /* IS_G10MAINT */ diff --git a/g10/getkey.c b/g10/getkey.c index b88b926e0..0c69efb0b 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -76,12 +76,15 @@ static int lookup_sk( PKT_secret_key *sk, int mode, u32 *keyid, const char *name ); /* note this function may be called before secure memory is - * available */ + * available + * The first keyring which is added by this function is + * created if it does not exist. + */ void add_keyring( const char *name ) { STRLIST sl; - int rc; + int rc, force = !keyrings; if( *name != '/' ) { /* do tilde expansion etc */ char *p ; @@ -90,22 +93,17 @@ add_keyring( const char *name ) p = make_filename(name, NULL); else p = make_filename(opt.homedir, name, NULL); - sl = m_alloc( sizeof *sl + strlen(p) ); - strcpy(sl->d, p ); + sl = append_to_strlist( &keyrings, p ); m_free(p); } - else { - sl = m_alloc( sizeof *sl + strlen(name) ); - strcpy(sl->d, name ); - } - sl->next = keyrings; - keyrings = sl; + else + sl = append_to_strlist( &keyrings, name ); /* fixme: We should remove much out of this module and * combine it with the keyblock stuff from ringedit.c * For now we will simple add the filename as keyblock resource */ - rc = add_keyblock_resource( sl->d, 0, 0 ); + rc = add_keyblock_resource( sl->d, force, 0 ); if( rc ) log_error("keyblock resource '%s': %s\n", sl->d, g10_errstr(rc) ); } @@ -139,7 +137,7 @@ void add_secret_keyring( const char *name ) { STRLIST sl; - int rc; + int rc, force = !secret_keyrings; if( *name != '/' ) { /* do tilde expansion etc */ char *p ; @@ -148,22 +146,17 @@ add_secret_keyring( const char *name ) p = make_filename(name, NULL); else p = make_filename(opt.homedir, name, NULL); - sl = m_alloc( sizeof *sl + strlen(p) ); - strcpy(sl->d, p ); + sl = append_to_strlist( &secret_keyrings, p ); m_free(p); } - else { - sl = m_alloc( sizeof *sl + strlen(name) ); - strcpy(sl->d, name ); - } - sl->next = secret_keyrings; - secret_keyrings = sl; + else + sl = append_to_strlist( &secret_keyrings, name ); /* fixme: We should remove much out of this module and * combine it with the keyblock stuff from ringedit.c * For now we will simple add the filename as keyblock resource */ - rc = add_keyblock_resource( sl->d, 0, 1 ); + rc = add_keyblock_resource( sl->d, force, 1 ); if( rc ) log_error("secret keyblock resource '%s': %s\n", sl->d, g10_errstr(rc)); } @@ -648,6 +641,7 @@ add_stuff_from_selfsig( KBNODE keyblock, KBNODE knode ) } } + /**************** * Lookup a key by scanning all keyrings * mode 1 = lookup by NAME (exact) @@ -696,7 +690,12 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid, || kk->pkt->pkttype == PKT_PUBLIC_SUBKEY ) && ( !pk->pubkey_algo || pk->pubkey_algo - == kk->pkt->pkt.public_key->pubkey_algo)) + == kk->pkt->pkt.public_key->pubkey_algo) + && ( !pk->pubkey_usage + || !check_pubkey_algo2( + kk->pkt->pkt.public_key->pubkey_algo, + pk->pubkey_usage )) + ) break; if( kk ) { u32 aki[2]; @@ -711,6 +710,9 @@ 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], diff --git a/g10/gpgd.c b/g10/gpgd.c index 34158b7f9..da7a990dc 100644 --- a/g10/gpgd.c +++ b/g10/gpgd.c @@ -249,6 +249,18 @@ g10_exit( int rc ) exit(rc ); } +void +do_not_use_RSA() +{ + static int did_rsa_note = 0; + + if( !did_rsa_note ) { + did_rsa_note = 1; + log_info("RSA keys are depreciated; please consider " + "creating a new key and use this key in the future\n"); + } +} + static void become_daemon() diff --git a/g10/import.c b/g10/import.c index 1467f092f..3ed6b96bb 100644 --- a/g10/import.c +++ b/g10/import.c @@ -125,7 +125,7 @@ import_keys( const char *fname ) } if( rc == -1 ) rc = 0; - else if( rc ) + else if( rc && rc != G10ERR_INV_KEYRING ) log_error("%s: read error: %s\n", fname, g10_errstr(rc)); iobuf_close(inp); diff --git a/g10/keyedit.c b/g10/keyedit.c index 3851b5c06..ee50a7880 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -75,8 +75,9 @@ sign_it_p( PKT_public_key *pk, PKT_user_id *uid ) char *answer; int yes; - tty_printf("\nAre you really sure that you want to sign this key:\n\n" - "%4u%c/%08lX %s ", + tty_printf("\n"); + tty_printf(_("Are you really sure that you want to sign this key:\n\n")); + tty_printf("pub %4u%c/%08lX %s ", nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), (ulong)keyid_from_pk( pk, NULL ), @@ -85,7 +86,7 @@ sign_it_p( PKT_public_key *pk, PKT_user_id *uid ) tty_printf("\n"); show_fingerprint(pk); tty_printf("\n"); - answer = tty_get("Sign this key? "); + answer = tty_get(_("Sign this key? ")); tty_kill_prompt(); yes = answer_is_yes(answer); m_free(answer); @@ -141,11 +142,11 @@ check_all_keysigs( KBNODE keyblock ) } } if( inv_sigs ) - tty_printf("%d bad signatures\n", inv_sigs ); + tty_printf(_("%d bad signatures\n"), inv_sigs ); if( no_key ) - tty_printf("No public key for %d signatures\n", no_key ); + tty_printf(_("No public key for %d signatures\n"), no_key ); if( oth_err ) - tty_printf("%d signatures not checked due to errors\n", oth_err ); + tty_printf(_("%d signatures not checked due to errors\n"), oth_err ); return inv_sigs || no_key || oth_err; } @@ -172,7 +173,7 @@ remove_keysigs( KBNODE keyblock, u32 *keyid, int all ) tty_printf("\n \"%08lX %s ", sig->keyid[1], datestr_from_sig(sig)); if( node->flag & 6 ) - tty_printf("[User name not available] "); + tty_printf(_("[User name not available] ")); else { size_t n; char *p = get_user_id( sig->keyid, &n ); @@ -181,18 +182,19 @@ remove_keysigs( KBNODE keyblock, u32 *keyid, int all ) } tty_printf("\"\n"); if( node->flag & 1 ) - tty_printf("This is a BAD signature!\n"); + tty_printf(_("This is a BAD signature!\n")); else if( node->flag & 2 ) - tty_printf("Public key not available.\n"); + tty_printf(_("Public key not available.\n")); else if( node->flag & 4 ) - tty_printf("The signature could not be checked!\n"); + tty_printf(_("The signature could not be checked!\n")); if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { - tty_printf("Skipped self-signature\n"); + tty_printf(_("Skipped self-signature\n")); continue; /* do not remove self-signatures */ } - answer = tty_get("\nRemove this signature? "); + tty_printf("\n"); + answer = tty_get(_("Remove this signature? ")); tty_kill_prompt(); if( answer_is_yes(answer) ) { node->flag |= 128; /* use bit 7 to mark this node */ @@ -204,7 +206,7 @@ remove_keysigs( KBNODE keyblock, u32 *keyid, int all ) if( !count ) return 0; /* nothing to remove */ - answer = tty_get("Do you really want to remove the selected signatures? "); + answer = tty_get(_("Do you really want to remove the selected signatures? ")); tty_kill_prompt(); yes = answer_is_yes(answer); m_free(answer); @@ -245,7 +247,7 @@ sign_key( const char *username, STRLIST locusr ) /* search the userid */ rc = find_keyblock_byname( &kbpos, username ); if( rc ) { - log_error("user '%s' not found\n", username ); + log_error(_("%s: user not found\n"), username ); goto leave; } @@ -272,7 +274,7 @@ sign_key( const char *username, STRLIST locusr ) pk = node->pkt->pkt.public_key; keyid_from_pk( pk, pk_keyid ); - log_info("Checking signatures of this public key certificate:\n"); + tty_printf(_("Checking signatures of this public key certificate:\n")); tty_printf("pub %4u%c/%08lX %s ", nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), @@ -289,7 +291,8 @@ sign_key( const char *username, STRLIST locusr ) if( check_all_keysigs( keyblock ) ) { if( !opt.batch ) { /* ask whether we really should do anything */ - answer = tty_get("To you want to remove some of the invalid sigs? "); + answer = tty_get( + _("To you want to remove some of the invalid sigs? ")); tty_kill_prompt(); if( answer_is_yes(answer) ) remove_keysigs( keyblock, pk_keyid, 0 ); @@ -309,7 +312,7 @@ sign_key( const char *username, STRLIST locusr ) && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) { if( akeyid[0] == node->pkt->pkt.signature->keyid[0] && akeyid[1] == node->pkt->pkt.signature->keyid[1] ) { - log_info("Already signed by keyid %08lX\n", + log_info(_("Already signed by keyid %08lX\n"), (ulong)akeyid[1] ); sk_rover->mark = 0; } @@ -321,7 +324,7 @@ sign_key( const char *username, STRLIST locusr ) break; } if( !sk_rover ) { - log_info("Nothing to sign\n"); + log_info(_("Nothing to sign\n")); goto leave; } @@ -390,7 +393,7 @@ edit_keysigs( const char *username ) /* search the userid */ rc = find_keyblock_byname( &kbpos, username ); if( rc ) { - log_error("%s: user not found\n", username ); + log_error(_("%s: user not found\n"), username ); goto leave; } @@ -411,7 +414,7 @@ edit_keysigs( const char *username ) pk = node->pkt->pkt.public_key; keyid_from_pk( pk, pk_keyid ); - log_info("Checking signatures of this public key certificate:\n"); + tty_printf(_("Checking signatures of this public key certificate:\n")); tty_printf("pub %4u%c/%08lX %s ", nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), @@ -459,7 +462,7 @@ delete_key( const char *username, int secret ) rc = secret? find_secret_keyblock_byname( &kbpos, username ) : find_keyblock_byname( &kbpos, username ); if( rc ) { - log_error("%s: user not found\n", username ); + log_error(_("%s: user not found\n"), username ); goto leave; } @@ -622,10 +625,10 @@ change_passphrase( const char *username ) rc = G10ERR_PUBKEY_ALGO; break; case 0: - tty_printf("This key is not protected.\n"); + tty_printf(_("This key is not protected.\n")); break; default: - tty_printf("Key is protected.\n"); + tty_printf(_("Key is protected.\n")); rc = check_secret_key( sk ); if( !rc ) passphrase = get_last_passphrase(); @@ -644,7 +647,7 @@ change_passphrase( const char *username ) } if( rc ) - tty_printf("Can't edit this key: %s\n", g10_errstr(rc)); + tty_printf(_("Can't edit this key: %s\n"), g10_errstr(rc)); else { DEK *dek = NULL; STRING2KEY *s2k = m_alloc_secure( sizeof *s2k ); diff --git a/g10/main.h b/g10/main.h index 03150d37f..dcba0488f 100644 --- a/g10/main.h +++ b/g10/main.h @@ -43,6 +43,7 @@ typedef struct { #else void g10_exit(int rc); #endif +void do_not_use_RSA(void); /*-- misc.c --*/ void trap_unaligned(void); diff --git a/g10/options.h b/g10/options.h index 1e34ced08..8ad0a4205 100644 --- a/g10/options.h +++ b/g10/options.h @@ -37,7 +37,7 @@ struct { int no_armor; int list_packets; /* list-packets mode */ int def_cipher_algo; - int def_pubkey_algo; + int reserved; int def_digest_algo; int def_compress_algo; int no_comment; diff --git a/g10/packet.h b/g10/packet.h index 4524328c6..edca2a4e9 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -109,6 +109,7 @@ typedef struct { byte hdrbytes; /* number of header bytes */ byte version; byte pubkey_algo; /* algorithm used for public key scheme */ + byte pubkey_usage; /* for now only used to pass it to getkey() */ ulong local_id; /* internal use, valid if > 0 */ MPI pkey[PUBKEY_MAX_NPKEY]; } PKT_public_key; @@ -119,6 +120,7 @@ typedef struct { byte hdrbytes; /* number of header bytes */ byte version; byte pubkey_algo; /* algorithm used for public key scheme */ + byte pubkey_usage; 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 20afd4163..ab1e6cdf8 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -203,7 +203,7 @@ static int parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, int *skip, IOBUF out, int do_skip ) { - int rc, c, ctb, pkttype, lenbytes; + int rc=0, c, ctb, pkttype, lenbytes; unsigned long pktlen; byte hdr[8]; int hdrlen; @@ -213,13 +213,16 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, assert( !pkt->pkt.generic ); if( retpos ) *retpos = iobuf_tell(inp); - if( (ctb = iobuf_get(inp)) == -1 ) - return -1; + if( (ctb = iobuf_get(inp)) == -1 ) { + rc = -1; + goto leave; + } hdrlen=0; hdr[hdrlen++] = ctb; if( !(ctb & 0x80) ) { log_error("%s: invalid packet (ctb=%02x)\n", iobuf_where(inp), ctb ); - return G10ERR_INVALID_PACKET; + rc = G10ERR_INVALID_PACKET; + goto leave; } pktlen = 0; new_ctb = !!(ctb & 0x40); @@ -227,7 +230,8 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, pkttype = ctb & 0x3f; if( (c = iobuf_get(inp)) == -1 ) { log_error("%s: 1st length byte missing\n", iobuf_where(inp) ); - return G10ERR_INVALID_PACKET; + rc = G10ERR_INVALID_PACKET; + goto leave; } hdr[hdrlen++] = c; if( c < 192 ) @@ -236,7 +240,8 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, pktlen = (c - 192) * 256; if( (c = iobuf_get(inp)) == -1 ) { log_error("%s: 2nd length byte missing\n", iobuf_where(inp) ); - return G10ERR_INVALID_PACKET; + rc = G10ERR_INVALID_PACKET; + goto leave; } hdr[hdrlen++] = c; pktlen += c + 192; @@ -247,7 +252,8 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 8; if( (c = iobuf_get(inp)) == -1 ) { log_error("%s: 4 byte length invalid\n", iobuf_where(inp) ); - return G10ERR_INVALID_PACKET; + rc = G10ERR_INVALID_PACKET; + goto leave; } pktlen |= (hdr[hdrlen++] = c ); } @@ -277,13 +283,14 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, rc = G10ERR_WRITE_FILE; else rc = copy_packet(inp, out, pkttype, pktlen ); - return rc; + goto leave; } if( do_skip || !pkttype || (reqtype && pkttype != reqtype) ) { skip_packet(inp, pkttype, pktlen); *skip = 1; - return 0; + rc = 0; + goto leave; } if( DBG_PACKET ) @@ -341,6 +348,9 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, break; } + leave: + if( rc == -1 && iobuf_error(inp) ) + rc = G10ERR_INV_KEYRING; return rc; } @@ -925,6 +935,7 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen, sk->hdrbytes = hdrlen; sk->version = version; sk->pubkey_algo = algorithm; + sk->pubkey_usage = 0; /* not yet used */ } else { PKT_public_key *pk = pkt->pkt.public_key; @@ -934,6 +945,7 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen, pk->hdrbytes = hdrlen; pk->version = version; pk->pubkey_algo = algorithm; + pk->pubkey_usage = 0; /* not yet used */ } nskey = pubkey_get_nskey( algorithm ); npkey = pubkey_get_npkey( algorithm ); diff --git a/g10/pkclist.c b/g10/pkclist.c index 3babb2997..e20fe8503 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -317,9 +317,10 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned usage ) if( pk ) free_public_key( pk ); pk = m_alloc_clear( sizeof *pk ); + pk->pubkey_usage = usage; rc = get_pubkey_byname( pk, answer ); if( rc ) - tty_printf("No such user ID.\n"); + tty_printf(_("No such user ID.\n")); else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, usage)) ) { int trustlevel; @@ -350,9 +351,10 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned usage ) for(; remusr; remusr = remusr->next ) { pk = m_alloc_clear( sizeof *pk ); + pk->pubkey_usage = usage; if( (rc = get_pubkey_byname( pk, remusr->d )) ) { free_public_key( pk ); pk = NULL; - log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) ); + log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) ); } else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, usage )) ) { int trustlevel; @@ -360,7 +362,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned usage ) rc = check_trust( pk, &trustlevel ); if( rc ) { free_public_key( pk ); pk = NULL; - log_error("error checking pk of '%s': %s\n", + log_error(_("%s: error checking key: %s\n"), remusr->d, g10_errstr(rc) ); } else if( do_we_trust_pre( pk, trustlevel ) ) { @@ -379,14 +381,14 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned usage ) } else { free_public_key( pk ); pk = NULL; - log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) ); + log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) ); } } } if( !rc && !pk_list ) { - log_error("no valid addressees\n"); + log_error(_("no valid addressees\n")); rc = G10ERR_NO_USER_ID; } diff --git a/g10/pref.c b/g10/pref.c new file mode 100644 index 000000000..342696907 --- /dev/null +++ b/g10/pref.c @@ -0,0 +1,81 @@ +/* pref.c + * Copyright (C) 1998 Free Software Foundation, Inc. + * + * This file is part of GNUPG. + * + * GNUPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GNUPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#define DEFINES_PREF_LIST 1 +#include +#include +#include +#include +#include +#include + +#include "errors.h" +#include "memory.h" +#include "util.h" +#include "ttyio.h" +#include "i18n.h" +#include "pref.h" + + +#define N_CIPHERS 3 +#define N_DIGESTS 4 +#define N_COMPRS 3 + +struct pref_list_s { + PREF_LIST *extend; /* if we need more, we link them together */ + byte cipher[N_CIPHERS]; /* cipher algos */ + byte digest[N_DIGESTS]; /* digest algos */ + byte compr [N_COMPRS ]; /* compress algos (a 255 denotes no compression)*/ +}; + + +#if 0 +PREF_LIST +new_pref_list() +{ + return m_alloc_clear( sizeof(*PREF_LIST) ); +} + +void +release_pref_list( PREF_LIST pref ) +{ + while( pref ) { + PREF_LIST tmp = pref->extend; + m_free( pref ); + pref = tmp; + } +} + +PREF_LIST +copy_pref_list( PREF_LIST s ) +{ + PREF_LIST ss, ss, d = new_pref_list(); + *d = *s; + for( ss = s->extend; ss; ss = ss->extend ) { + + WORK WORK WORK + d->extend = new_pref_list(); + + *d->extend = *ss; + } + return d; +} +#endif + diff --git a/g10/pref.h b/g10/pref.h new file mode 100644 index 000000000..ec173c90b --- /dev/null +++ b/g10/pref.h @@ -0,0 +1,42 @@ +/* pref.h + * Copyright (C) 1998 Free Software Foundation, Inc. + * + * This file is part of GNUPG. + * + * GNUPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GNUPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef G10_PREF_H +#define G10_PREF_H 1 + +/* a structure to hold information abopu preferred algorithms */ +typedef struct pref_list_s *PREF_LIST; +#ifndef DEFINES_PREF_LIST +struct pref_list_s { char preference_stuff[1]; }; +#endif + + +PREF_LIST new_pref_list(void); +void release_pref_list( PREF_LIST pref ); + + + + + + + + + +#endif /*G10_PREF_H*/ diff --git a/g10/ringedit.c b/g10/ringedit.c index 876247000..58eb6d6d9 100644 --- a/g10/ringedit.c +++ b/g10/ringedit.c @@ -117,6 +117,17 @@ add_keyblock_resource( const char *filename, int force, int secret ) if( !iobuf && !force ) return G10ERR_OPEN_FILE; #endif + + if( !iobuf ) { + iobuf = iobuf_create( filename ); + if( !iobuf ) { + log_error("%s: can't create: %s\n", filename, strerror(errno)); + return G10ERR_OPEN_FILE; + } + else + log_info("%s: keyring created\n", filename ); + } + resource_table[i].used = 1; resource_table[i].secret = !!secret; resource_table[i].fname = m_strdup(filename); @@ -726,6 +737,8 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) log_error("%s: can't create: %s\n", rentry->fname, strerror(errno)); return G10ERR_OPEN_FILE; } + else + log_info("%s: keyring created\n", rentry->fname ); kbctx=NULL; while( (node = walk_kbnode( root, &kbctx, 0 )) ) { diff --git a/g10/sign.c b/g10/sign.c index 116e74b73..7dffba314 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -46,6 +46,9 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig, byte *dp; int rc; + if( is_RSA(sk->pubkey_algo) ) + do_not_use_RSA(); + if( !digest_algo ) digest_algo = md_get_algo(md); @@ -166,12 +169,12 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, if( fname && filenames->next && (!detached || encrypt) ) log_bug("multiple files can only be detached signed"); - if( (rc=build_sk_list( locusr, &sk_list, 1, 1 )) ) + if( (rc=build_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) ) goto leave; if( !old_style ) old_style = only_old_style( sk_list ); if( encrypt ) { - if( (rc=build_pk_list( remusr, &pk_list, 2 )) ) + if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )) ) goto leave; } @@ -314,6 +317,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, pt->timestamp = make_timestamp(); pt->mode = opt.textmode && !outfile ? 't':'b'; pt->len = filesize; + pt->new_ctb = !pt->len && !opt.rfc1991; pt->buf = inp; pkt.pkttype = PKT_PLAINTEXT; pkt.pkt.plaintext = pt; @@ -461,12 +465,13 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) SK_LIST sk_list = NULL; SK_LIST sk_rover = NULL; int old_style = opt.rfc1991; + int only_md5 = 0; memset( &afx, 0, sizeof afx); memset( &tfx, 0, sizeof tfx); init_packet( &pkt ); - if( (rc=build_sk_list( locusr, &sk_list, 1, 1 )) ) + if( (rc=build_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) ) goto leave; if( !old_style ) old_style = only_old_style( sk_list ); @@ -493,18 +498,36 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) goto leave; } - /* FIXME: This stuff is not correct if multiple hash algos are used*/ iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----\n" ); - if( old_style - || (opt.def_digest_algo?opt.def_digest_algo:DEFAULT_DIGEST_ALGO) - == DIGEST_ALGO_MD5 ) + + for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { + PKT_secret_key *sk = sk_rover->sk; + if( hash_for(sk->pubkey_algo) == DIGEST_ALGO_MD5 ) + only_md5 = 1; + else { + only_md5 = 0; + break; + } + } + + if( old_style || only_md5 ) iobuf_writestr(out, "\n" ); else { - const char *s = digest_algo_to_string(opt.def_digest_algo? - opt.def_digest_algo:DEFAULT_DIGEST_ALGO); - assert(s); + const char *s; + int any = 0; + iobuf_writestr(out, "Hash: " ); - iobuf_writestr(out, s ); + for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { + PKT_secret_key *sk = sk_rover->sk; + s = digest_algo_to_string( hash_for(sk->pubkey_algo) ); + if( s ) { + if( any ) + iobuf_put(out, ',' ); + iobuf_writestr(out, s ); + any = 1; + } + } + assert(any); iobuf_writestr(out, "\n\n" ); } diff --git a/g10/skclist.c b/g10/skclist.c index 7082a2caa..efd97f3d1 100644 --- a/g10/skclist.c +++ b/g10/skclist.c @@ -56,13 +56,14 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock, PKT_secret_key *sk; sk = m_alloc_clear( sizeof *sk ); + sk->pubkey_usage = usage; if( (rc = get_seckey_byname( sk, NULL, unlock )) ) { free_secret_key( sk ); sk = NULL; log_error("no default secret key: %s\n", g10_errstr(rc) ); } else if( !(rc=check_pubkey_algo2(sk->pubkey_algo, usage)) ) { SK_LIST r; - if( sk->version == 4 && (usage & 1) + if( sk->version == 4 && (usage & PUBKEY_USAGE_SIG) && sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) { log_error("this is a PGP generated " "ElGamal key which is NOT secure for signatures!\n"); @@ -86,13 +87,14 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock, PKT_secret_key *sk; sk = m_alloc_clear( sizeof *sk ); + sk->pubkey_usage = usage; if( (rc = get_seckey_byname( sk, locusr->d, unlock )) ) { free_secret_key( sk ); sk = NULL; log_error("skipped '%s': %s\n", locusr->d, g10_errstr(rc) ); } else if( !(rc=check_pubkey_algo2(sk->pubkey_algo, usage)) ) { SK_LIST r; - if( sk->version == 4 && (usage & 1) + if( sk->version == 4 && (usage & PUBKEY_USAGE_SIG) && sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) { log_info("skipped '%s': this is a PGP generated " "ElGamal key which is not secure for signatures!\n", diff --git a/g10/trustdb.c b/g10/trustdb.c index e9264c69e..4ca177c1d 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1540,18 +1540,13 @@ init_trustdb( int level, const char *dbname ) if( !level ) return 0; - /* we can verify a signature about our local data (secring and trustdb) - * in ~/.gnupg/ here */ - rc = verify_private_data(); - if( !rc ) { - /* verify that our own keys are in the trustDB - * or move them to the trustdb. */ - rc = verify_own_keys(); + /* verify that our own keys are in the trustDB + * or move them to the trustdb. */ + rc = verify_own_keys(); - /* should we check whether there is no other ultimately trusted - * key in the database? */ + /* should we check whether there is no other ultimately trusted + * key in the database? */ - } } else BUG(); @@ -1593,6 +1588,27 @@ list_trustdb( const char *username ) } } +/**************** + * make a list of all owner trust value. + */ +void +list_ownertrust() +{ + TRUSTREC rec; + ulong recnum; + int i; + byte *p; + + for(recnum=0; !read_record( recnum, &rec, 0); recnum++ ) { + if( rec.rectype == RECTYPE_KEY ) { + p = rec.r.key.fingerprint; + for(i=0; i < rec.r.key.fingerprint_len; i++, p++ ) + printf("%02X", *p ); + printf(":%u:\n", (unsigned)rec.r.key.ownertrust ); + } + } +} + void list_trust_path( int max_depth, const char *username ) { @@ -2012,50 +2028,3 @@ update_no_sigs( ulong lid, int no_sigs ) } -int -verify_private_data() -{ - int rc = 0; - char *sigfile = make_filename(opt.homedir, "gnupg.sig", NULL ); - - if( access( sigfile, R_OK ) ) { - if( errno != ENOENT ) { - log_error("can't access %s: %s\n", sigfile, strerror(errno) ); - rc = G10ERR_TRUSTDB; - goto leave; - } - log_info("private data signature missing; creating ...\n"); - rc = sign_private_data(); - if( rc ) { - log_error("error creating %s: %s\n", sigfile, g10_errstr(rc) ); - goto leave; - } - } - - /* FIXME: verify this signature */ - - leave: - m_free(sigfile); - return rc; -} - - -int -sign_private_data() -{ - int rc; - char *sigfile = make_filename(opt.homedir, "gnupg.sig", NULL ); - char *secring = make_filename(opt.homedir, "secring.gpg", NULL ); - STRLIST list = NULL; - - add_to_strlist( &list, db_name ); - add_to_strlist( &list, secring ); - - rc = sign_file( list, 1, NULL, 0, NULL, sigfile); - - m_free(sigfile); - m_free(secring); - free_strlist(list); - return rc; -} - diff --git a/g10/trustdb.h b/g10/trustdb.h index e4d74e411..705ffaf80 100644 --- a/g10/trustdb.h +++ b/g10/trustdb.h @@ -38,6 +38,7 @@ /*-- trustdb.c --*/ void list_trustdb(const char *username); void list_trust_path( int max_depth, const char *username ); +void list_ownertrust(void); int init_trustdb( int level, const char *dbname ); int check_trust( PKT_public_key *pk, unsigned *r_trustlevel ); int query_trust_info( PKT_public_key *pk ); @@ -47,7 +48,5 @@ int keyid_from_trustdb( ulong lid, u32 *keyid ); int query_trust_record( PKT_public_key *pk ); int insert_trust_record( PKT_public_key *pk ); int update_ownertrust( ulong lid, unsigned new_trust ); -int verify_private_data(void); -int sign_private_data(void); #endif /*G10_TRUSTDB_H*/ diff --git a/include/ChangeLog b/include/ChangeLog index 0df9e6836..b59c6393c 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,12 @@ +Mon Jul 6 10:41:55 1998 Werner Koch (wk@isil.d.shuttle.de) + + * cipher.h (PUBKEY_USAGE_): New. + +Mon Jul 6 09:49:51 1998 Werner Koch (wk@isil.d.shuttle.de) + + * iobuf.h (iobuf_set_error): New. + (iobuf_error): New. + Sat Jun 13 17:31:32 1998 Werner Koch (wk@isil.d.shuttle.de) * g10lib.h: New as interface for the g10lib. diff --git a/include/errors.h b/include/errors.h index f2ec2073b..1633478c1 100644 --- a/include/errors.h +++ b/include/errors.h @@ -34,7 +34,7 @@ #define G10ERR_CIPHER_ALGO 12 /* Unknown cipher algorithm */ #define G10ERR_KEYRING_OPEN 13 #define G10ERR_INVALID_PACKET 14 -#define G10ERR_BAD_RING 15 +#define G10ERR_INVALID_ARMOR 15 #define G10ERR_NO_USER_ID 16 #define G10ERR_NO_SECKEY 17 /* secret key not available */ #define G10ERR_WRONG_SECKEY 18 /* wrong seckey used */ diff --git a/include/iobuf.h b/include/iobuf.h index 7fd4f7bd1..c84254d73 100644 --- a/include/iobuf.h +++ b/include/iobuf.h @@ -48,6 +48,7 @@ struct iobuf_struct { byte *buf; } d; int filter_eof; + int error; int (*filter)( void *opaque, int control, IOBUF chain, byte *buf, size_t *len); void *filter_ov; /* value for opaque */ @@ -81,6 +82,8 @@ int iobuf_pop_filter( IOBUF a, int (*f)(void *opaque, int control, IOBUF chain, byte *buf, size_t *len), void *ov ); int iobuf_flush(IOBUF a); void iobuf_clear_eof(IOBUF a); +#define iobuf_set_error(a) do { (a)->error = 1; } while(0) +#define iobuf_error(a) ((a)->error) void iobuf_set_limit( IOBUF a, unsigned long nlimit ); diff --git a/include/util.h b/include/util.h index 24fea1260..032f0adfb 100644 --- a/include/util.h +++ b/include/util.h @@ -126,7 +126,8 @@ int answer_is_yes( const char *s ); /*-- strgutil.c --*/ void free_strlist( STRLIST sl ); #define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0) -void add_to_strlist( STRLIST *list, const char *string ); +STRLIST add_to_strlist( STRLIST *list, const char *string ); +STRLIST append_to_strlist( STRLIST *list, const char *string ); STRLIST strlist_prev( STRLIST head, STRLIST node ); STRLIST strlist_last( STRLIST node ); int memicmp( const char *a, const char *b, size_t n ); diff --git a/mpi/ChangeLog b/mpi/ChangeLog index a52381d05..babbabdf9 100644 --- a/mpi/ChangeLog +++ b/mpi/ChangeLog @@ -1,3 +1,9 @@ +Sat Jul 4 10:11:11 1998 Werner Koch (wk@isil.d.shuttle.de) + + * mpiutil.c (mpi_clear): Reset flags. + (mpi_set): Ditto. + (mpi_alloc_secure): Set flag to 1 and not ored the 1 in, tsss.. + Fri Jun 26 11:19:06 1998 Werner Koch (wk@isil.d.shuttle.de) * mpiutil.c (mpi_alloc): set nbits to 0. diff --git a/mpi/mpi-inv.c b/mpi/mpi-inv.c index 2cea72811..25efbd979 100644 --- a/mpi/mpi-inv.c +++ b/mpi/mpi-inv.c @@ -167,6 +167,7 @@ mpi_invm( MPI x, MPI a, MPI n ) u = mpi_copy(a); v = mpi_copy(n); + for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) { mpi_rshift(u, u, 1); mpi_rshift(v, v, 1); diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c index 231e5d578..c9af50561 100644 --- a/mpi/mpiutil.c +++ b/mpi/mpiutil.c @@ -94,7 +94,7 @@ mpi_alloc_secure( unsigned nlimbs ) a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL; #endif a->alloced = nlimbs; - a->flags |= 1; + a->flags = 1; a->nlimbs = 0; a->sign = 0; a->nbits = 0; @@ -178,6 +178,7 @@ mpi_clear( MPI a ) { a->nlimbs = 0; a->nbits = 0; + a->flags = 0; } @@ -197,7 +198,8 @@ mpi_free( MPI a ) #else mpi_free_limb_space(a->d); #endif - + if( a->flags & ~3 ) + log_bug("invalid flag value in mpi\n"); m_free(a); } @@ -231,7 +233,7 @@ mpi_set_secure( MPI a ) /**************** - * Note: This copy function shpould not interpret the MPI + * Note: This copy function should not interpret the MPI * but copy it transparently. */ MPI @@ -278,6 +280,7 @@ mpi_set( MPI w, MPI u) MPN_COPY( wp, up, usize ); w->nlimbs = usize; w->nbits = u->nbits; + w->flags = u->flags; w->sign = usign; } @@ -290,6 +293,7 @@ mpi_set_ui( MPI w, unsigned long u) w->nlimbs = u? 1:0; w->sign = 0; w->nbits = 0; + w->flags = 0; } diff --git a/tools/mk-tdata b/tools/mk-tdata index 85e567d45..3b9e1c016 100755 Binary files a/tools/mk-tdata and b/tools/mk-tdata differ diff --git a/util/ChangeLog b/util/ChangeLog index 76e85131d..5baefcc20 100644 --- a/util/ChangeLog +++ b/util/ChangeLog @@ -1,3 +1,7 @@ +Mon Jul 6 09:03:49 1998 Werner Koch (wk@isil.d.shuttle.de) + + * strgutil.c (append_to_strlist): New. + Thu Jul 2 15:55:44 1998 Werner Koch (wk@isil.d.shuttle.de) * iobuf.c (block_filter): Add writing of OP partial length headers. diff --git a/util/errors.c b/util/errors.c index b71ff4f49..6b72576b5 100644 --- a/util/errors.c +++ b/util/errors.c @@ -64,7 +64,7 @@ g10_errstr( int err ) X(CIPHER_ALGO ,"Unknown cipher algorithm") X(KEYRING_OPEN ,"Can't open the keyring") X(INVALID_PACKET ,"Invalid packet") - X(BAD_RING ,"Broken keyring") + X(INVALID_ARMOR ,"Invalid armor") X(NO_USER_ID ,"No such user id") X(NO_SECKEY ,"Secret key not available") X(WRONG_SECKEY ,"Wrong secret key used") @@ -80,6 +80,9 @@ g10_errstr( int err ) X(NI_CIPHER ,"Unimplemented cipher algorithm") X(SIG_CLASS ,"Unknown signature class") X(TRUSTDB ,"Trust database error") + X(BAD_MPI ,"Bad MPI") + X(RESOURCE_LIMIT ,"Resource limit") + X(INV_KEYRING ,"Invalid keyring") X(BAD_CERT ,"Bad certificate") X(INV_USER_ID ,"Malformed user id") X(CLOSE_FILE ,"File close error") diff --git a/util/iobuf.c b/util/iobuf.c index 7be3431bc..bd69322b9 100644 --- a/util/iobuf.c +++ b/util/iobuf.c @@ -739,6 +739,11 @@ underflow(IOBUF a) log_debug("iobuf-%d.%d: filter eof\n", a->no, a->subno ); return -1; } + if( a->error ) { + if( DBG_IOBUF ) + log_debug("iobuf-%d.%d: error\n", a->no, a->subno ); + return -1; + } if( a->filter ) { len = a->d.size; @@ -758,6 +763,8 @@ underflow(IOBUF a) } a->filter_eof = 1; } + else if( rc ) + a->error = 1; if( !len ) return -1; @@ -802,6 +809,8 @@ iobuf_flush(IOBUF a) log_info("iobuf_flush did not write all!\n"); rc = G10ERR_WRITE_FILE; } + else if( rc ) + a->error = 1; a->d.len = 0; return rc; @@ -1058,6 +1067,7 @@ iobuf_seek( IOBUF a, ulong newpos ) a->nbytes = 0; a->nlimit = 0; a->ntotal = newpos; + a->error = 0; /* remove filters, but the last */ while( a->chain ) iobuf_pop_filter( a, a->filter, NULL ); diff --git a/util/strgutil.c b/util/strgutil.c index c6c8f5a65..d19ba6e54 100644 --- a/util/strgutil.c +++ b/util/strgutil.c @@ -39,7 +39,7 @@ free_strlist( STRLIST sl ) } -void +STRLIST add_to_strlist( STRLIST *list, const char *string ) { STRLIST sl; @@ -48,6 +48,25 @@ add_to_strlist( STRLIST *list, const char *string ) strcpy(sl->d, string); sl->next = *list; *list = sl; + return sl; +} + +STRLIST +append_to_strlist( STRLIST *list, const char *string ) +{ + STRLIST r, sl; + + sl = m_alloc( sizeof *sl + strlen(string)); + strcpy(sl->d, string); + sl->next = NULL; + if( !*list ) + *list = sl; + else { + for( r = *list; r->next; r = r->next ) + ; + r->next = sl; + } + return sl; }