diff options
author | Werner Koch <wk@gnupg.org> | 1998-02-17 21:48:52 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 1998-02-17 21:48:52 +0100 |
commit | c8bb57d05d1b237e16f93d95a4df5a1d343c4c5a (patch) | |
tree | 7692d6a234d6c22528ffce134ad0f6c904eaa91f | |
parent | removed password from key two (diff) | |
download | gnupg2-c8bb57d05d1b237e16f93d95a4df5a1d343c4c5a.tar.xz gnupg2-c8bb57d05d1b237e16f93d95a4df5a1d343c4c5a.zip |
import works
-rw-r--r-- | README | 33 | ||||
-rw-r--r-- | g10/ChangeLog | 34 | ||||
-rw-r--r-- | g10/Makefile.am | 2 | ||||
-rw-r--r-- | g10/OPTIONS | 9 | ||||
-rw-r--r-- | g10/armor.c | 5 | ||||
-rw-r--r-- | g10/free-packet.c | 43 | ||||
-rw-r--r-- | g10/g10.c | 24 | ||||
-rw-r--r-- | g10/g10maint.c | 38 | ||||
-rw-r--r-- | g10/getkey.c | 4 | ||||
-rw-r--r-- | g10/import.c | 293 | ||||
-rw-r--r-- | g10/kbnode.c | 76 | ||||
-rw-r--r-- | g10/keydb.h | 2 | ||||
-rw-r--r-- | g10/keygen.c | 4 | ||||
-rw-r--r-- | g10/main.h | 1 | ||||
-rw-r--r-- | g10/mainproc.c | 109 | ||||
-rw-r--r-- | g10/options.h | 2 | ||||
-rw-r--r-- | g10/packet.h | 2 | ||||
-rw-r--r-- | g10/pubring.asc | 38 | ||||
-rw-r--r-- | g10/pubring.g10 | bin | 3017 -> 0 bytes | |||
-rw-r--r-- | g10/ringedit.c | 28 | ||||
-rw-r--r-- | g10/sign.c | 12 | ||||
-rw-r--r-- | g10/trustdb.c | 24 | ||||
-rw-r--r-- | mpi/m68k/distfiles | 6 | ||||
-rw-r--r-- | mpi/m68k/mc68020/distfiles | 3 | ||||
-rw-r--r-- | mpi/m68k/mc68020/mpih-mul1.S | 97 | ||||
-rw-r--r-- | mpi/m68k/mc68020/mpih-mul2.S | 87 | ||||
-rw-r--r-- | mpi/m68k/mc68020/mpih-mul3.S | 89 | ||||
-rw-r--r-- | mpi/m68k/mpih-add1.S | 85 | ||||
-rw-r--r-- | mpi/m68k/mpih-shift.S | 286 | ||||
-rw-r--r-- | mpi/m68k/mpih-sub1.S | 85 | ||||
-rw-r--r-- | mpi/mpi-inv.c | 8 | ||||
-rw-r--r-- | util/ChangeLog | 4 | ||||
-rw-r--r-- | util/memory.c | 12 |
33 files changed, 1404 insertions, 141 deletions
@@ -109,6 +109,15 @@ 8) Continue with step 4 if we did not find a prime in step 7. 9) Find a generator for that prime. + You should make a revocation certificate in cases someone gets + knowledge of your secret key or you forgot your passphrase: + + g10 --gen-revoke your_user_id + + Run this command and store it away; output is always ASCII armored, + so that you can print it and (hopefully never) re-create it if + your electronic media fails. + You can sign a key with this command: @@ -125,7 +134,9 @@ wether you want to sign this key. You may remove a signature at any time using the option "--edit-sig", - which asks for the sigs to remove. + which asks for the sigs to remove. Self-signatures are not removable. + + Sign @@ -172,6 +183,26 @@ Ditto, but sign the file with the user id "Suttner" + Keyring Management + ------------------ + To export your complete keyring(s) do this: + + g10 --export + + To export only some user ids do this: + + g10 --export userids + + Use "-a" or "--armor" to create ASCII armored output. + + Importing keys is done with the option, you guessed it, "--import": + + g10 --import [filenames] + + New keys are appended to the default keyring and already existing + keys are merged. Keys without a self-signature are ignored. + + How to Specify a UserID ----------------------- There are several ways to specify a userID, here are some examples: diff --git a/g10/ChangeLog b/g10/ChangeLog index 4e1cf4329..414b051f0 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,37 @@ +Tue Feb 17 21:24:17 1998 Werner Koch (wk@isil.d.shuttle.de) + + * armor.c : Add header lines "...ARMORED FILE .." + * dearmor.c (enarmor_file): New. + * g10maint.c (main): New option "--enarmor" + +Tue Feb 17 19:03:33 1998 Werner Koch (wk@isil.d.shuttle.de) + + * mainproc.c : Changed a lot, because the packets are now stored + a simple linlked list and not anymore in a complicatd tree structure. + +Tue Feb 17 10:14:48 1998 Werner Koch (wk@isil.d.shuttle.de) + + * free_packet.c (cmp_public_certs): New. + (cmp_user_ids): New. + + * kbnode.c (clone_kbnode): New. + (release_kbnode): Add clone support. + + * ringedit.c (find_keyblock_bypkc): New. + + * sign.c (remove_keysigs): Self signatures are now skipped, + changed arguments and all callers. + + * import.c : Add functionality. + +Tue Feb 17 09:31:40 1998 Werner Koch (wk@isil.d.shuttle.de) + + * options.h (homedir): New option. + * g10.c, g10maint.c, getkey.c, keygen.c, trustdb.c (opt.homedir): New. + + * trustdb.c (init_trustdb): mkdir for hoem directory + (sign_private_data): Renamed "sig" to "g10.sig" + Mon Feb 16 20:02:03 1998 Werner Koch (wk@isil.d.shuttle.de) * kbnode.c (commit_kbnode): New. diff --git a/g10/Makefile.am b/g10/Makefile.am index e200fcd1d..44cc3ae94 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -1,7 +1,7 @@ ## Process this file with automake to produce Makefile.in INCLUDES = -I$(top_srcdir)/include -EXTRA_DIST = OPTIONS pubring.g10 +EXTRA_DIST = OPTIONS pubring.asc needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a bin_PROGRAMS = g10 g10maint diff --git a/g10/OPTIONS b/g10/OPTIONS index 37c6ec485..c4e6afde0 100644 --- a/g10/OPTIONS +++ b/g10/OPTIONS @@ -132,6 +132,9 @@ armor batch # batch mode: never ask +no-batch +# disables batch + cache-all # hold everything in memory @@ -152,6 +155,8 @@ detach-sign dry-run # don't make any changes +homedir dirname +# Set the name of the home directory which defaults to "~/.g10". keyring filename # add this filename to the list of keyrings. @@ -180,6 +185,10 @@ no-verbose options filename # Ignored in option files. +no-options +# same as --options /dev/null. This option is detected +# before an attempt to open an option file + output filename # use filename for output diff --git a/g10/armor.c b/g10/armor.c index 17dc444b8..03a393b35 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -87,12 +87,15 @@ static char *head_strings[] = { "BEGIN PGP PUBLIC KEY BLOCK", "BEGIN PGP SIGNATURE", "BEGIN PGP SIGNED MESSAGE", + "BEGIN PGP ARMORED FILE", NULL }; static char *tail_strings[] = { "END PGP MESSAGE", "END PGP PUBLIC KEY BLOCK", "END PGP SIGNATURE", + "END dummy", + "END PGP ARMORED FILE", NULL }; @@ -248,7 +251,7 @@ static fhdr_state_t find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, IOBUF a, size_t n, unsigned *r_empty) { - int c, i; + int c=0, i; const char *s; byte *p; size_t buflen; diff --git a/g10/free-packet.c b/g10/free-packet.c index 949af1099..f2467a78b 100644 --- a/g10/free-packet.c +++ b/g10/free-packet.c @@ -275,6 +275,37 @@ free_packet( PACKET *pkt ) * Returns 0 if they match. */ int +cmp_public_certs( PKT_public_cert *a, PKT_public_cert *b ) +{ + if( a->timestamp != b->timestamp ) + return -1; + if( a->valid_days != b->valid_days ) + return -1; + if( a->pubkey_algo != b->pubkey_algo ) + return -1; + + if( a->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { + if( mpi_cmp( a->d.elg.p , b->d.elg.p ) ) + return -1; + if( mpi_cmp( a->d.elg.g , b->d.elg.g ) ) + return -1; + if( mpi_cmp( a->d.elg.y , b->d.elg.y ) ) + return -1; + } + else if( a->pubkey_algo == PUBKEY_ALGO_RSA ) { + if( mpi_cmp( a->d.rsa.rsa_n , b->d.rsa.rsa_n ) ) + return -1; + if( mpi_cmp( a->d.rsa.rsa_e , b->d.rsa.rsa_e ) ) + return -1; + } + + return 0; +} + +/**************** + * Returns 0 if they match. + */ +int cmp_public_secret_cert( PKT_public_cert *pkc, PKT_secret_cert *skc ) { if( pkc->timestamp != skc->timestamp ) @@ -302,3 +333,15 @@ cmp_public_secret_cert( PKT_public_cert *pkc, PKT_secret_cert *skc ) return 0; } +int +cmp_user_ids( PKT_user_id *a, PKT_user_id *b ) +{ + int res; + + res = a->len - b->len; + if( !res ) + res = memcmp( a->name, b->name, a->len ); + return res; +} + + @@ -109,7 +109,9 @@ static ARGPARSE_OPTS opts[] = { { 522, "no-greeting", 0, "\r" }, { 523, "passphrase-fd",1, "\r" }, { 541, "no-operation", 0, "\r" }, /* used by regression tests */ - + { 543, "no-options", 0, "\r" }, /* shortcut for --options /dev/null */ + { 544, "homedir", 2, "\r" }, /* defaults to "~/.g10" */ + { 545, "no-batch", 0, "\r" }, {0} }; @@ -324,6 +326,7 @@ main( int argc, char **argv ) opt.def_digest_algo = DIGEST_ALGO_RMD160; opt.completes_needed = 1; opt.marginals_needed = 3; + opt.homedir = "~/.g10"; /* check wether we have a config file on the commandline */ orig_argc = argc; @@ -340,10 +343,14 @@ main( int argc, char **argv ) */ default_config = 0; } + else if( pargs.r_opt == 543 ) + default_config = 0; /* --no-options */ + else if( pargs.r_opt == 544 ) + opt.homedir = pargs.r.ret_str; } if( default_config ) - configname = make_filename("~/.g10", "options", NULL ); + configname = make_filename(opt.homedir, "options", NULL ); argc = orig_argc; argv = orig_argv; @@ -357,7 +364,8 @@ main( int argc, char **argv ) if( !configfp ) { if( default_config ) { if( parse_debug ) - log_info(_("note: no default option file '%s'\n"), configname ); + log_info(_("note: no default option file '%s'\n"), + configname ); } else { log_error(_("option file '%s': %s\n"), @@ -447,6 +455,9 @@ main( int argc, char **argv ) case 540: secmem_set_flags( secmem_get_flags() | 1 ); break; case 541: set_cmd( &cmd, aNOP); break; case 542: set_cmd( &cmd, aGenRevoke); break; + case 543: break; /* no-options */ + case 544: opt.homedir = pargs.r.ret_str; break; + case 545: opt.batch = 0; break; default : errors++; pargs.err = configfp? 1:2; break; } } @@ -652,8 +663,11 @@ main( int argc, char **argv ) break; case aImport: - if( !argc ) - wrong_args(_("nyi")); + if( !argc ) { + rc = import_pubkeys( NULL ); + if( rc ) + log_error("import failed: %s\n", g10_errstr(rc) ); + } for( ; argc; argc--, argv++ ) { rc = import_pubkeys( *argv ); if( rc ) diff --git a/g10/g10maint.c b/g10/g10maint.c index 618acc8fa..c743bf9a3 100644 --- a/g10/g10maint.c +++ b/g10/g10maint.c @@ -43,7 +43,7 @@ enum cmd_values { aNull = 0, aPrimegen, aPrintMDs, aListPackets, aKMode, aKModeC, - aListTrustDB, aListTrustPath, aDeArmor, + aListTrustDB, aListTrustPath, aDeArmor, aEnArmor, aTest }; @@ -219,7 +219,12 @@ main( int argc, char **argv ) { 535, "completes-needed", 1, N_("(default is 1)")}, { 536, "marginals-needed", 1, N_("(default is 3)")}, { 538, "trustdb-name", 2, "\r" }, - { 540, "dearmor", 0, N_("De-Armor a file or stdin") }, + { 540, "no-secmem-warning", 0, "\r" }, /* dummy */ + { 543, "no-options", 0, "\r" }, /* shortcut for --options /dev/null */ + { 544, "homedir", 2, "\r" }, /* defaults to "~/.g10" */ + { 545, "no-batch", 0, "\r" }, + { 546, "dearmor", 0, N_("De-Armor a file or stdin") }, + { 547, "enarmor", 0, N_("En-Armor a file or stdin") }, {0} }; ARGPARSE_ARGS pargs; @@ -245,6 +250,7 @@ main( int argc, char **argv ) secmem_init( 0 ); /* disable use of secmem */ + log_set_name("g10maint"); i18n_init(); opt.compress = -1; /* defaults to standard compress level */ opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH; @@ -252,6 +258,7 @@ main( int argc, char **argv ) opt.def_digest_algo = DIGEST_ALGO_RMD160; opt.completes_needed = 1; opt.marginals_needed = 3; + opt.homedir = "~/.g10"; /* check wether we have a config file on the commandline */ orig_argc = argc; @@ -268,10 +275,14 @@ main( int argc, char **argv ) */ default_config = 0; } + else if( pargs.r_opt == 543 ) + default_config = 0; /* --no-options */ + else if( pargs.r_opt == 544 ) + opt.homedir = pargs.r.ret_str; } if( default_config ) - configname = make_filename("~/.g10", "options", NULL ); + configname = make_filename(opt.homedir, "options", NULL ); argc = orig_argc; argv = orig_argv; @@ -349,7 +360,12 @@ main( int argc, char **argv ) case 535: opt.completes_needed = pargs.r.ret_int; break; case 536: opt.marginals_needed = pargs.r.ret_int; break; case 538: trustdb_name = pargs.r.ret_str; break; - case 540: set_cmd( &cmd, aDeArmor); break; + case 540: break; /*dummy*/ + case 543: break; /* no-options */ + case 544: opt.homedir = pargs.r.ret_str; break; + case 545: opt.batch = 0; break; + case 546: set_cmd( &cmd, aDeArmor); break; + case 547: set_cmd( &cmd, aEnArmor); break; default : errors++; pargs.err = configfp? 1:2; break; } } @@ -407,12 +423,12 @@ main( int argc, char **argv ) } if( !sec_nrings || default_keyring ) { /* add default secret rings */ - char *p = make_filename("~/.g10", "secring.g10", NULL ); + char *p = make_filename(opt.homedir, "secring.g10", NULL ); add_secret_keyring(p); m_free(p); } if( !nrings || default_keyring ) { /* add default ring */ - char *p = make_filename("~/.g10", "pubring.g10", NULL ); + char *p = make_filename(opt.homedir, "pubring.g10", NULL ); add_keyring(p); m_free(p); } @@ -435,6 +451,8 @@ main( int argc, char **argv ) switch( cmd ) { case aPrimegen: case aPrintMDs: + case aDeArmor: + case aEnArmor: break; case aListTrustDB: rc = init_trustdb( argc? 1:0, trustdb_name ); break; default: rc = init_trustdb(1, trustdb_name ); break; @@ -484,6 +502,14 @@ main( int argc, char **argv ) log_error(_("dearmoring failed: %s\n"), g10_errstr(rc)); break; + case aEnArmor: + if( argc > 1 ) + wrong_args("--enarmor [file]"); + rc = enarmor_file( argc? *argv: NULL ); + if( rc ) + log_error(_("enarmoring failed: %s\n"), g10_errstr(rc)); + break; + case aPrimegen: if( argc == 1 ) { diff --git a/g10/getkey.c b/g10/getkey.c index 8f92f0a45..e58b0f813 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -89,7 +89,7 @@ add_keyring( const char *name ) if( strchr(name, '/') ) p = make_filename(name, NULL); else - p = make_filename("~/.g10", name, NULL); + p = make_filename(opt.homedir, name, NULL); sl = m_alloc( sizeof *sl + strlen(p) ); strcpy(sl->d, p ); m_free(p); @@ -139,7 +139,7 @@ add_secret_keyring( const char *name ) if( strchr(name, '/') ) p = make_filename(name, NULL); else - p = make_filename("~/.g10", name, NULL); + p = make_filename(opt.homedir, name, NULL); sl = m_alloc( sizeof *sl + strlen(p) ); strcpy(sl->d, p ); m_free(p); diff --git a/g10/import.c b/g10/import.c index ce2655bfb..43e64239f 100644 --- a/g10/import.c +++ b/g10/import.c @@ -41,6 +41,12 @@ static int import_one( const char *fname, KBNODE keyblock ); static int chk_self_sigs( const char *fname, KBNODE keyblock, PKT_public_cert *pkc, u32 *keyid ); static int delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid ); +static int merge_blocks( const char *fname, KBNODE keyblock_orig, + KBNODE keyblock, u32 *keyid, int *n_uids, int *n_sigs ); +static int append_uid( KBNODE keyblock, KBNODE node, int *n_sigs, + const char *fname, u32 *keyid ); +static int merge_sigs( KBNODE dst, KBNODE src, int *n_sigs, + const char *fname, u32 *keyid ); /**************** @@ -131,12 +137,15 @@ read_block( IOBUF a, compress_filter_context_t *cfx, int rc; PACKET *pkt; KBNODE root = NULL; - int in_cert = 0; + int in_cert; if( *pending_pkt ) { root = new_kbnode( *pending_pkt ); *pending_pkt = NULL; + in_cert = 1; } + else + in_cert = 0; pkt = m_alloc( sizeof *pkt ); init_packet(pkt); while( (rc=parse_packet(a, pkt)) != -1 ) { @@ -165,6 +174,7 @@ read_block( IOBUF a, compress_filter_context_t *cfx, init_packet(pkt); break; + case PKT_PUBLIC_CERT: case PKT_SECRET_CERT: if( in_cert ) { /* store this packet */ @@ -174,11 +184,13 @@ read_block( IOBUF a, compress_filter_context_t *cfx, } in_cert = 1; default: - if( !root ) - root = new_kbnode( pkt ); - else - add_kbnode( root, new_kbnode( pkt ) ); - pkt = m_alloc( sizeof *pkt ); + if( in_cert ) { + if( !root ) + root = new_kbnode( pkt ); + else + add_kbnode( root, new_kbnode( pkt ) ); + pkt = m_alloc( sizeof *pkt ); + } init_packet(pkt); break; } @@ -209,6 +221,7 @@ import_one( const char *fname, KBNODE keyblock ) PKT_public_cert *pkc; PKT_public_cert *pkc_orig; KBNODE node, uidnode; + KBNODE keyblock_orig = NULL; KBPOS kbpos; u32 keyid[2]; int rc = 0; @@ -243,20 +256,21 @@ import_one( const char *fname, KBNODE keyblock ) rc = chk_self_sigs( fname, keyblock , pkc, keyid ); if( rc ) return rc== -1? 0:rc; + if( !delete_inv_parts( fname, keyblock, keyid ) ) { - log_info("%s: key %08lX, no valid user ids left over\n", + log_info("%s: key %08lX, no valid user ids\n", fname, (ulong)keyid[1]); return 0; } /* do we have this key already in one of our pubrings ? */ - pkc_orig = m_alloc( sizeof *pkc_orig ); + pkc_orig = m_alloc_clear( sizeof *pkc_orig ); rc = get_pubkey( pkc_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)); } - else if( rc ) { /* inset this key */ + else if( rc ) { /* insert this key */ /* get default resource */ if( get_keyblock_handle( NULL, 0, &kbpos ) ) { log_error("no default public keyring\n"); @@ -273,31 +287,80 @@ import_one( const char *fname, KBNODE keyblock ) keyblock_resource_name(&kbpos), g10_errstr(rc) ); unlock_keyblock( &kbpos ); /* we are ready */ - if( opt.verbose ) - log_info("%s: key %08lX imported\n", fname, (ulong)keyid[1]); + log_info("%s: key %08lX imported\n", fname, (ulong)keyid[1]); } - else { - /* merge - * o Compare the key and the self-signatures of the new and the one in - * our keyring. If they are different something weird is going on; - * ask what to do. - * o See wether we have only non-self-signature on one user id; if not - * ask the user what to do. - * o compare the signatures: If we already have this signature, check - * that they compare okay; if not, issue a warning and ask the user. - * (consider to look at the timestamp and use the newest?) - * o Simply add the signature. Can't verify here because we may not have - * the signatures public key yet; verification is done when putting it - * into the trustdb, which is done automagically as soon as this pubkey - * is used. - */ - log_error("nyi\n"); + else { /* merge */ + int n_uids, n_sigs; + + /* Compare the original against the new key; just to be sure nothing + * weird is going on */ + if( cmp_public_certs( pkc_orig, pkc ) ) { + log_error("%s: key %08lX, doesn't match our copy\n", + fname, (ulong)keyid[1]); + rc = G10ERR_GENERAL; + goto leave; + } + + /* See wether we have only non-self-signature on one user id; if not + * ask the user what to do. <--- fixme */ + + /* now read the original keyblock */ + rc = find_keyblock_bypkc( &kbpos, pkc_orig ); + if( rc ) { + log_error("%s: key %08lX, can't locate original keyblock: %s\n", + fname, (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)); + goto leave; + } + /* and try to merge the block */ + clear_kbnode_flags( keyblock_orig ); + clear_kbnode_flags( keyblock ); + n_uids = n_sigs = 0; + rc = merge_blocks( fname, keyblock_orig, keyblock, + keyid, &n_uids, &n_sigs ); + if( rc ) + goto leave; + if( n_uids || n_sigs ) { /* keyblock_orig has been updated; write */ + if( opt.verbose > 1 ) + log_info("%s: writing to '%s'\n", + fname, 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) ); + 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) ); + unlock_keyblock( &kbpos ); + /* we are ready */ + if( n_uids == 1 ) + log_info("%s: key %08lX, 1 new user-id\n", + fname, (ulong)keyid[1]); + else if( n_uids ) + log_info("%s: key %08lX, %d new user-ids\n", + fname, (ulong)keyid[1], n_uids ); + if( n_sigs == 1 ) + log_info("%s: key %08lX, 1 new signature\n", + fname, (ulong)keyid[1]); + else if( n_sigs ) + log_info("%s: key %08lX, %d new signatures\n", + fname, (ulong)keyid[1], n_sigs ); + } + else + log_info("%s: key %08lX, not changed\n", fname, (ulong)keyid[1] ); } + leave: + release_kbnode( keyblock_orig ); free_public_cert( pkc_orig ); return rc; } + /**************** * loop over the keyblock an check all self signatures. * Mark all user-ids with a self-signature by setting flag bit 0. @@ -335,7 +398,10 @@ chk_self_sigs( const char *fname, KBNODE keyblock, } /**************** - * delete all parts which are invalid. + * delete all parts which are invalidand those signatures whos + * public key algorithm is not availabe in this implemenation; + * but consider RSA as valid, because parse/build_packets knows + * about it. * returns: true if at least one valid user-id is left over. */ static int @@ -347,11 +413,13 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid ) for(node=keyblock->next; node; node = node->next ) { if( node->pkt->pkttype == PKT_USER_ID ) { if( (node->flag & 2) || !(node->flag & 1) ) { - log_info("%s: key %08lX, removed userid '", + if( opt.verbose ) { + log_info("%s: key %08lX, removed userid '", fname, (ulong)keyid[1]); - print_string( stderr, node->pkt->pkt.user_id->name, + print_string( stderr, node->pkt->pkt.user_id->name, node->pkt->pkt.user_id->len ); - fputs("'\n", stderr ); + fputs("'\n", stderr ); + } delete_kbnode( node ); /* the user-id */ /* and all following packets up to the next user-id */ while( node->next && node->next->pkt->pkttype != PKT_USER_ID ){ @@ -362,10 +430,169 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid ) else nvalid++; } + else if( node->pkt->pkttype == PKT_SIGNATURE + && check_pubkey_algo( node->pkt->pkt.signature->pubkey_algo) + && node->pkt->pkt.signature->pubkey_algo != PUBKEY_ALGO_RSA ) + delete_kbnode( node ); /* build_packet() can't handle this */ } - /* note: because keyblock is the public key, ist is never marked - * for deletion and so the keyblock cannot chnage */ + /* note: because keyblock is the public key, it is never marked + * for deletion and so keyblock cannot change */ commit_kbnode( &keyblock ); return nvalid; } + + +/**************** + * compare and merge the blocks + * + * o compare the signatures: If we already have this signature, check + * that they compare okay; if not, issue a warning and ask the user. + * FIXME: add the check, that we don` have duplicate signatures and the + * warning in cases that the old/new signatures don't match. + * o Simply add the signature. Can't verify here because we may not have + * the signatures public key yet; verification is done when putting it + * into the trustdb, which is done automagically as soon as this pubkey + * is used. + * Note: We indicate newly inserted packets with flag bit 0 + */ +static int +merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock, + u32 *keyid, int *n_uids, int *n_sigs ) +{ + KBNODE node_orig, node; + int rc; + + /* first, try to merge new ones in */ + for(node_orig=keyblock_orig->next; node_orig; node_orig=node_orig->next ) { + if( !(node_orig->flag & 1) && node_orig->pkt->pkttype == PKT_USER_ID) { + /* find the user id in the imported keyblock */ + for(node=keyblock->next; node; node=node->next ) + if( !(node->flag & 1) + && node->pkt->pkttype == PKT_USER_ID + && !cmp_user_ids( node_orig->pkt->pkt.user_id, + node->pkt->pkt.user_id ) ) + break; + if( node ) { /* found: merge */ + rc = merge_sigs( node_orig, node, n_sigs, fname, keyid ); + if( rc ) + return rc; + } + } + } + + /* second, add new user-ids */ + for(node=keyblock->next; node; node=node->next ) { + if( !(node->flag & 1) && node->pkt->pkttype == PKT_USER_ID) { + /* do we have this in the original keyblock */ + for(node_orig=keyblock_orig->next; node_orig; + node_orig=node_orig->next ) + if( !(node_orig->flag & 1) + && node_orig->pkt->pkttype == PKT_USER_ID + && cmp_user_ids( node_orig->pkt->pkt.user_id, + node->pkt->pkt.user_id ) ) + break; + if( !node ) { /* this is a new user id: append */ + rc = append_uid( keyblock_orig, node, n_sigs, fname, keyid); + if( rc ) + return rc; + ++*n_uids; + } + } + } + + return 0; +} + + +/**************** + * append the userid starting with NODE and all signatures to KEYBLOCK. + * Mark all new and copied packets by setting flag bit 0. + */ +static int +append_uid( KBNODE keyblock, KBNODE node, int *n_sigs, + const char *fname, u32 *keyid ) +{ + KBNODE n; + + 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", + fname, (ulong)keyid[1]); + return G10ERR_GENERAL; + } + + for( ;node && node->pkt->pkttype != PKT_USER_ID; node = node->next ) { + /* we add a clone to the original keyblock, because this + * one is released first */ + n = clone_kbnode(node); + add_kbnode( keyblock, n ); + node->flag |= 1; + n->flag |= 1; + if( n->pkt->pkttype == PKT_SIGNATURE ) + ++*n_sigs; + } + + return 0; +} + + +/**************** + * Merge the sigs from SRC onto DST. SRC and DST are both a PKT_USER_ID. + * (how should we handle comment packets here?) + */ +static int +merge_sigs( KBNODE dst, KBNODE src, int *n_sigs, + const char *fname, u32 *keyid ) +{ + KBNODE n, n2; + int found=0; + + assert(dst->pkt->pkttype == PKT_USER_ID ); + assert(src->pkt->pkttype == PKT_USER_ID ); + /* 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]); + return 0; + } + + + for(n=src->next; n && n->pkt->pkttype != PKT_USER_ID; n = n->next ) { + if( n->pkt->pkttype != PKT_SIGNATURE ) + continue; + found = 0; + for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next) + if( n2->pkt->pkttype == PKT_SIGNATURE + && n->pkt->pkt.signature->keyid[0] + == n2->pkt->pkt.signature->keyid[0] + && n->pkt->pkt.signature->keyid[1] + == n2->pkt->pkt.signature->keyid[1] ) { + found++; + break; + } + + if( found ) { /* we already have this signature */ + /* Hmmm: should we compare the timestamp etc? + * but then we have first to see wether this signature is valid + * - or - simply add it in such a case and let trustdb logic + * decide wether to remove the old one + */ + continue; + } + + /* This signature is new, append N to DST it. + * We add a clone to the original keyblock, because this + * one is released first */ + n2 = clone_kbnode(n); + insert_kbnode( dst, n2, PKT_USER_ID ); + n2->flag |= 1; + n->flag |= 1; + ++*n_sigs; + } + + return 0; +} + diff --git a/g10/kbnode.c b/g10/kbnode.c index c28748b6e..3137e6191 100644 --- a/g10/kbnode.c +++ b/g10/kbnode.c @@ -37,7 +37,19 @@ new_kbnode( PACKET *pkt ) n->next = NULL; n->pkt = pkt; n->flag = 0; - n->private_flag=0; /* kludge to delete a node */ + n->private_flag=0; + return n; +} + + +KBNODE +clone_kbnode( KBNODE node ) +{ + KBNODE n = m_alloc( sizeof *n ); + n->next = NULL; + n->pkt = node->pkt; + n->private_flag |= 2; /* mark cloned */ + n->flag = 0; return n; } @@ -49,7 +61,8 @@ release_kbnode( KBNODE n ) while( n ) { n2 = n->next; - free_packet( n->pkt ); + if( !(n->private_flag & 2) ) + free_packet( n->pkt ); m_free( n ); n = n2; } @@ -66,6 +79,7 @@ delete_kbnode( KBNODE node ) node->private_flag |= 1; } + /**************** * Append NODE to ROOT, ROOT must exist! */ @@ -206,19 +220,67 @@ clear_kbnode_flags( KBNODE n ) int commit_kbnode( KBNODE *root ) { - KBNODE n, n2; + KBNODE n, nl; int changed = 0; - for(n=*root; n; n = n2 ) { - n2 = n->next; + for( n = *root, nl=NULL; n; n = nl->next ) { if( (n->private_flag & 1) ) { if( n == *root ) - *root = n2; - free_packet( n->pkt ); + *root = nl = n->next; + else + nl->next = n->next; + if( !(n->private_flag & 2) ) + free_packet( n->pkt ); m_free( n ); changed = 1; } + else + nl = n; } return changed; } + +void +dump_kbnode( KBNODE node ) +{ + for(; node; node = node->next ) { + const char *s; + switch( node->pkt->pkttype ) { + case 0: s="empty"; break; + case PKT_PUBLIC_CERT: s="public-key"; break; + case PKT_SECRET_CERT: s="secret-key"; break; + case PKT_SECKEY_SUBCERT: s= "secret-subkey"; break; + case PKT_PUBKEY_ENC: s="public-enc"; break; + case PKT_SIGNATURE: s="signature"; break; + case PKT_ONEPASS_SIG: s="onepass-sig"; break; + case PKT_USER_ID: s="user-id"; break; + case PKT_PUBKEY_SUBCERT: s="public-subkey"; break; + case PKT_COMMENT: s="comment"; break; + case PKT_RING_TRUST: s="trust"; break; + case PKT_PLAINTEXT: s="plaintext"; break; + case PKT_COMPRESSED: s="compressed"; break; + case PKT_ENCRYPTED: s="encrypted"; break; + default: s="unknown"; break; + } + fprintf(stderr, "node %p %02x/%02x type=%s", + node, node->flag, node->private_flag, s); + if( node->pkt->pkttype == PKT_USER_ID ) { + fputs(" \"", stderr); + print_string( stderr, node->pkt->pkt.user_id->name, + node->pkt->pkt.user_id->len ); + fputs("\"\n", stderr); + } + else if( node->pkt->pkttype == PKT_SIGNATURE ) { + fprintf(stderr, " keyid=%08lX\n", + (ulong)node->pkt->pkt.signature->keyid[1] ); + } + else if( node->pkt->pkttype == PKT_PUBLIC_CERT ) { + fprintf(stderr, " keyid=%08lX\n", (ulong) + keyid_from_pkc( node->pkt->pkt.public_cert, NULL )); + } + else + fputs("\n", stderr); + } +} + diff --git a/g10/keydb.h b/g10/keydb.h index 643632a40..eff603a04 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -127,6 +127,7 @@ byte *fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len ); /*-- kbnode.c --*/ KBNODE new_kbnode( PACKET *pkt ); +KBNODE clone_kbnode( KBNODE node ); void release_kbnode( KBNODE n ); void delete_kbnode( KBNODE node ); void add_kbnode( KBNODE root, KBNODE node ); @@ -144,6 +145,7 @@ const char *keyblock_resource_name( KBPOS *kbpos ); int get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos ); int find_keyblock( PUBKEY_FIND_INFO info, KBPOS *kbpos ); int find_keyblock_byname( KBPOS *kbpos, const char *username ); +int find_keyblock_bypkc( KBPOS *kbpos, PKT_public_cert *pkc ); int find_secret_keyblock_byname( KBPOS *kbpos, const char *username ); int lock_keyblock( KBPOS *kbpos ); void unlock_keyblock( KBPOS *kbpos ); diff --git a/g10/keygen.c b/g10/keygen.c index 89fd852e1..f0cbda3d0 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -526,8 +526,8 @@ generate_keypair() /* now check wether we a are allowed to write to the keyrings */ - pub_fname = make_filename("~/.g10", "pubring.g10", NULL ); - sec_fname = make_filename("~/.g10", "secring.g10", NULL ); + pub_fname = make_filename(opt.homedir, "pubring.g10", NULL ); + sec_fname = make_filename(opt.homedir, "secring.g10", NULL ); if( opt.verbose ) { tty_printf(_("writing public certificate to '%s'\n"), pub_fname ); tty_printf(_("writing secret certificate to '%s'\n"), sec_fname ); diff --git a/g10/main.h b/g10/main.h index 8761a1c59..2990ef872 100644 --- a/g10/main.h +++ b/g10/main.h @@ -91,6 +91,7 @@ int import_pubkeys( const char *filename ); int export_pubkeys( STRLIST users ); /* dearmor.c --*/ int dearmor_file( const char *fname ); +int enarmor_file( const char *fname ); /*-- revoke.c --*/ int gen_revoke( const char *uname ); diff --git a/g10/mainproc.c b/g10/mainproc.c index 7e19f12c1..f2b50ac9d 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -47,7 +47,7 @@ typedef struct { md_filter_context_t mfx; DEK *dek; int last_was_pubkey_enc; - KBNODE cert; /* the current certificate / or signature */ + KBNODE list; /* the current list of packets */ int have_data; IOBUF iobuf; /* used to get the filename etc. */ } *CTX; @@ -59,13 +59,13 @@ static void proc_tree( CTX c, KBNODE node ); static void -release_cert( CTX c ) +release_list( CTX c ) { - if( !c->cert ) + if( !c->list ) return; - proc_tree(c, c->cert ); - release_kbnode( c->cert ); - c->cert = NULL; + proc_tree(c, c->list ); + release_kbnode( c->list ); + c->list = NULL; } @@ -74,17 +74,15 @@ add_onepass_sig( CTX c, PACKET *pkt ) { KBNODE node; - if( c->cert ) { /* add another packet */ - if( c->cert->pkt->pkttype != PKT_ONEPASS_SIG ) { + if( c->list ) { /* add another packet */ + if( c->list->pkt->pkttype != PKT_ONEPASS_SIG ) { log_error("add_onepass_sig: another packet is in the way\n"); - release_cert( c ); + release_list( c ); } - node = new_kbnode( pkt ); - node->next = c->cert; - c->cert = node; + add_kbnode( c->list, new_kbnode( pkt )); } else /* insert the first one */ - c->cert = node = new_kbnode( pkt ); + c->list = node = new_kbnode( pkt ); return 1; } @@ -93,16 +91,16 @@ add_onepass_sig( CTX c, PACKET *pkt ) static int add_public_cert( CTX c, PACKET *pkt ) { - release_cert( c ); - c->cert = new_kbnode( pkt ); + release_list( c ); + c->list = new_kbnode( pkt ); return 1; } static int add_secret_cert( CTX c, PACKET *pkt ) { - release_cert( c ); - c->cert = new_kbnode( pkt ); + release_list( c ); + c->list = new_kbnode( pkt ); return 1; } @@ -110,24 +108,11 @@ add_secret_cert( CTX c, PACKET *pkt ) static int add_user_id( CTX c, PACKET *pkt ) { - KBNODE node, n1; - - if( !c->cert ) { + if( !c->list ) { log_error("orphaned user id\n" ); return 0; } - /* goto the last certificate */ - for(n1=c->cert; n1->next; n1 = n1->next ) - ; - assert( n1->pkt ); - if( n1->pkt->pkttype != PKT_PUBLIC_CERT - && n1->pkt->pkttype != PKT_SECRET_CERT ) { - log_error("invalid parent type %d for userid\n", n1->pkt->pkttype ); - return 0; - } - /* add a new user id node at the end */ - node = new_kbnode( pkt ); - add_kbnode( n1, node ); + add_kbnode( c->list, new_kbnode( pkt ) ); return 1; } @@ -137,7 +122,7 @@ add_signature( CTX c, PACKET *pkt ) { KBNODE node; - if( pkt->pkttype == PKT_SIGNATURE && !c->cert ) { + if( pkt->pkttype == PKT_SIGNATURE && !c->list ) { /* This is the first signature for a following datafile. * G10 does not write such packets, instead it always uses * onepass-sig packets. The drawback of PGP's method @@ -145,23 +130,17 @@ add_signature( CTX c, PACKET *pkt ) * that it is not possible to make a signature from data read * from stdin. (Anyway, G10 is able to read these stuff) */ node = new_kbnode( pkt ); - c->cert = node; + c->list = node; return 1; } - else if( !c->cert ) + else if( !c->list ) return 0; /* oops (invalid packet sequence)*/ - else if( !c->cert->pkt ) + else if( !c->list->pkt ) BUG(); /* so nicht */ - else if( c->cert->pkt->pkttype == PKT_ONEPASS_SIG ) { - /* The root is a onepass signature: we are signing data */ - node = new_kbnode( pkt ); - add_kbnode( c->cert, node ); - return 1; - } /* add a new signature node id at the end */ node = new_kbnode( pkt ); - add_kbnode( c->cert, node ); + add_kbnode( c->list, node ); return 1; } @@ -304,12 +283,12 @@ do_check_sig( CTX c, KBNODE node ) md = md_copy( c->mfx.md ); } else if( (sig->sig_class&~3) == 0x10 ) { /* classes 0x10 .. 0x13 */ - if( c->cert->pkt->pkttype == PKT_PUBLIC_CERT ) { - KBNODE n1 = find_prev_kbnode( c->cert, node, PKT_USER_ID ); + if( c->list->pkt->pkttype == PKT_PUBLIC_CERT ) { + KBNODE n1 = find_prev_kbnode( c->list, node, PKT_USER_ID ); if( n1 ) { - if( c->cert->pkt->pkt.public_cert->mfx.md ) - md = md_copy( c->cert->pkt->pkt.public_cert->mfx.md ); + if( c->list->pkt->pkt.public_cert->mfx.md ) + md = md_copy( c->list->pkt->pkt.public_cert->mfx.md ); else BUG(); md_write( md, n1->pkt->pkt.user_id->name, n1->pkt->pkt.user_id->len); @@ -394,15 +373,24 @@ list_node( CTX c, KBNODE node ) (ulong)keyid_from_pkc( pkc, NULL ), datestr_from_pkc( pkc ) ); /* and now list all userids with their signatures */ - while( (node = find_next_kbnode(node, PKT_USER_ID)) ) { - if( any ) - printf( "%*s", 31, "" ); - print_userid( node->pkt ); - putchar('\n'); - if( opt.fingerprint && !any ) - print_fingerprint( pkc, NULL ); - list_node(c, node ); - any=1; + for( node = node->next; node; node = node->next ) { + if( node->pkt->pkttype == PKT_USER_ID ) { + KBNODE n; + + if( any ) + printf( "%*s", 31, "" ); + print_userid( node->pkt ); + putchar('\n'); + if( opt.fingerprint && !any ) + print_fingerprint( pkc, NULL ); + for( n=node->next; n; n = n->next ) { + if( n->pkt->pkttype == PKT_USER_ID ) + break; + if( n->pkt->pkttype == PKT_SIGNATURE ) + list_node(c, n ); + } + any=1; + } } if( !any ) printf("ERROR: no user id!\n"); @@ -425,14 +413,9 @@ list_node( CTX c, KBNODE node ) if( !any ) printf("ERROR: no user id!\n"); } - else if( node->pkt->pkttype == PKT_USER_ID ) { - /* list everything under this user id */ - while( (node = find_next_kbnode(node, 0 )) ) - list_node(c, node ); - } else if( node->pkt->pkttype == PKT_SIGNATURE ) { PKT_signature *sig = node->pkt->pkt.signature; - int rc2; + int rc2=0; size_t n; char *p; int sigrc = ' '; @@ -527,7 +510,7 @@ proc_packets( IOBUF a ) free_packet(pkt); } - release_cert( c ); + release_list( c ); m_free(c->dek); free_packet( pkt ); m_free( pkt ); diff --git a/g10/options.h b/g10/options.h index 89388f14e..48c6bee21 100644 --- a/g10/options.h +++ b/g10/options.h @@ -42,7 +42,7 @@ struct { int no_comment; int marginals_needed; int completes_needed; - int reserved12; + const char *homedir; int reserved13; int reserved14; int reserved15; diff --git a/g10/packet.h b/g10/packet.h index d0bb3c499..98015a365 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -243,7 +243,9 @@ void free_comment( PKT_comment *rem ); void free_packet( PACKET *pkt ); PKT_public_cert *copy_public_cert( PKT_public_cert *d, PKT_public_cert *s ); PKT_secret_cert *copy_secret_cert( PKT_secret_cert *d, PKT_secret_cert *s ); +int cmp_public_certs( PKT_public_cert *a, PKT_public_cert *b ); int cmp_public_secret_cert( PKT_public_cert *pkc, PKT_secret_cert *skc ); +int cmp_user_ids( PKT_user_id *a, PKT_user_id *b ); /*-- sig-check.c --*/ diff --git a/g10/pubring.asc b/g10/pubring.asc new file mode 100644 index 000000000..436d1b56b --- /dev/null +++ b/g10/pubring.asc @@ -0,0 +1,38 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: G10 v0.2.6a (Linux) +Comment: This is an alpha version! + +owJ4nAHfBiD5mQFXAzTfJWgAABAFINbugE0d8vCiHfqvhnoptnqKVW0wf+wbDEgKR7puSi4NK0Og +tq0NGF9drJozFMFQcBQ3JZwfFtzhn1uxQZIgAn3FbA+eFM0yIzoPBg6ZBwghyXAjRn53m2kKadtj +Lw/MmvsSejhW9cAuGgQ+l3AnqGGr/FVf8UOYjONe/tQSkzBatwyDqlqo4aR53jtXSHyCs3HIBkb2 +Z9pJ7QgDRbpHTkyZ+V/nAAMFBSCtiXNEQmGdslpqMUgwjG2YS0r+kkLnHyBnYEidgT1DlveJ2Uam +KXBzE03t8eP4BCHazC6YYtlLK0u73bzE93qlcqzmWqD29X/s3Ph0cfGNyftzIVyMq/ltzvA0WuWo ++DMVkiLfqywfkmWY1jPesyHXZ+BzFz55Hj7JQdrJbj4Z8OvSFN8YeJ1c4bxdyUebswyH75mbSTc+ +gXvmKKVoEHLhduKXqLQiV2VybmVyIEtvY2ggPHdrQGlzaWwuZC5zaHV0dGxlLmRlPokBXwMFEzTf +JWgDbxG4/z6qCxADG0kFHjyJ/JQso57RBJhyP/C85qoEfs26dLClZQNmuy1kTt7Ua4Jrgi2T0mh/ ++psyo90uCatdoQ4/BCPkEAQiTuttyoqCBejL9VI9NFw9drbMrv9YCJDrGJ60Cz1J4cZsMrQdmv+k +H3odr0pHJSyeoWVh6uWWCdcf56tPhOvfn704pAMekiFyYYCRoEquYNBNYqbPGdyPa1wxqChoJ0ER +fJQr1zpwz9aiBR9gheP48OUeNLqcDMRt+HIkerRLbS4Er7xFA1OzOPQ5GaYv1kIimeTibqzzJqg6 +KXT2IWmMaO/mOHcAhUX2HNwEPvQI7OhZXl2Fba0vcWeIz0iLY+72jUTdZuN1naHyLdsj4Zhz6Iuz +QorfRlYSqa05HSAgVeZXY2UAbSWNAL3tMwZl1NB0yU3ClHk16yaJaeCOL6/tWMUBBPQbqu3Q5hrr +yYFA8YjXAwUQNN8mPOETl2Ph2BJ1EAM3QwL9FC95f+80m1FzlMYUJYpqVPLOF7D2tP9/BzX1bskI +Z0HRyVNFgDgZLhJ3IumtFwo/Pas5lg9VTQzki8fI47nlHUFFi5p6w0fBQKj8cObx3wmYfomCbjvj +dFA6RIwq6jxlAv4zOktjAyFzGOEwAibaVFC4yerQYSsZOLTTadhKWaPcPK4k0ueuT7afyEde9u8q ++9Z4g+21RkYRy3K7Kav29Mdkum66VWfEHXcV/cKpUJKfSOUsTBuvT6H59ldipKjGA5iYzwM03yX9 +AAAQAwDrovWGUv7oGFqpZv7U4+I1RbynmO/aVPkv+PAuww8qreqEAeNSjrn8IbqOz9sTBxt6vE8V +QAQPL0KCY6vDxNluoDsc0h020AxGomJ/u7fVNBpaeyMVmmYdwuJBm+5l/18AAwUDAL5RBdBDaMxQ +4KvCKf1LzbSjYUa/xYe8KD9rVAQn8gN6BHZZVUTQnvysQvu3RUmTahWMnLPGIN8xlqnUNYTKrDid +9QJftOjyMu8I0eBwQ55uURk8eOjOtBw6zrDDz3uydLQYd2VybmVyIDxkZDlqbkBhbXNhdC5vcmc+ +iNcDBRM03yX94ROXY+HYEnUQA/WdAwCPzC6dmLB4Gojgq9kgdi7gjNWgkSiMh1lNOa4zYmXrPmLr +Pak5SS1UlgxqQ7bWAONGz3GPH+86krj43EbWbtTP5f6uyNUhVDo3rfG2MVB+EpU6DX9mCosbSHa/ +UJw62ykDAJjbBaX3K7eGv83Zx36KeeD8adwU6a11NbpJi84pVJOr3TQ7pJAL3A8odXO6PrBZn8t7 +7wvf3aVMSW9NKZ7sta/BJHTwm/7nr9TjI5pwcmD0cOuX2IZjXi/6o65a/erF6okBXwMFEDTfJl4D +bxG4/z6qCxAD89QFHjBcJGk53igKPrMfpdfO8m6zCWAWSEyE/F/H1TTHr6CWo0H0Z7P7LIMMj/AH +u95plOX+ajCaEUofoAaNM1pJMB7DLpkZR1j+Qy64IpnFRVGP90Vnqmbw7wUufONWsLf6iKx76ZkS +ZS5Gg/KTbLle6/6vFfHjI1Mu85hmCyEZsTs6AHL3rROuJRUt951TeoOKHUSMo/ZDQfya+BlmbUbj +NaEp0qr2BR4ypoz5jQSiQPUFN3I0RLRzR6bS+a1pUVucNMXQuu5GsvJpQW47DznFDDteZcpf+Qai +KKcMfpUtbWOIIlWhMAtIAodBJxCqrgGWbVGEkGtcrK7IW8NUDfpe/+KLcFzvx2XPo8+RHWrTlgf1 +RhEXdNx2up7gbuiHf+CD8kABzkINfmdYizmD1/JE8+DO8gCMopcY2hYmStG4E2lUCq79qCCBeORg +5AyKSNo= +=Cg4U +-----END PGP PUBLIC KEY BLOCK----- diff --git a/g10/pubring.g10 b/g10/pubring.g10 Binary files differdeleted file mode 100644 index f458371d4..000000000 --- a/g10/pubring.g10 +++ /dev/null diff --git a/g10/ringedit.c b/g10/ringedit.c index 6d3fc14bb..95f0ef65a 100644 --- a/g10/ringedit.c +++ b/g10/ringedit.c @@ -176,6 +176,7 @@ find_keyblock( PUBKEY_FIND_INFO info, KBPOS *kbpos ) rc = keyring_search2( info, kbpos, resource_table[i].fname ); if( !rc ) { kbpos->resno = i; + kbpos->fp = NULL; return 0; } if( rc != -1 ) { @@ -213,6 +214,7 @@ search( PACKET *pkt, KBPOS *kbpos, int secret ) rc = keyring_search( pkt, kbpos, resource_table[i].iobuf ); if( !rc ) { kbpos->resno = i; + kbpos->fp = NULL; return 0; } if( rc != -1 ) { @@ -251,6 +253,25 @@ find_keyblock_byname( KBPOS *kbpos, const char *username ) return rc; } + +/**************** + * Combined function to search for a key and get the position + * of the keyblock. + */ +int +find_keyblock_bypkc( KBPOS *kbpos, PKT_public_cert *pkc ) +{ + PACKET pkt; + int rc; + + init_packet( &pkt ); + pkt.pkttype = PKT_PUBLIC_CERT; + pkt.pkt.public_cert = pkc; + rc = search( &pkt, kbpos, 0 ); + return rc; +} + + /**************** * Combined function to search for a username and get the position * of the keyblock. This function does not unprotect the secret key. @@ -277,6 +298,7 @@ find_secret_keyblock_byname( KBPOS *kbpos, const char *username ) } + /**************** * Lock the keyblock; wait until it's available * This function may change the internal data in kbpos, in cases @@ -461,7 +483,7 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf ) save_mode = set_packet_list_mode(0); if( iobuf_seek( iobuf, 0 ) ) { - log_error("can't rewind keyring file: %s\n", g10_errstr(rc)); + log_error("can't rewind keyring file\n"); rc = G10ERR_KEYRING_OPEN; goto leave; } @@ -595,7 +617,7 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root ) } if( iobuf_seek( a, kbpos->offset ) ) { - log_error("can't seek to %lu: %s\n", kbpos->offset, g10_errstr(rc)); + log_error("can't seek to %lu\n", kbpos->offset); iobuf_close(a); return G10ERR_KEYRING_OPEN; } @@ -724,7 +746,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) { RESTBL *rentry; IOBUF fp, newfp; - int rc; + int rc=0; char *bakfname = NULL; char *tmpfname = NULL; diff --git a/g10/sign.c b/g10/sign.c index 6040f4caf..2bf3045fc 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -573,7 +573,7 @@ check_all_keysigs( KBNODE keyblock ) * Ask and remove invalid signatures are to be removed. */ static int -remove_keysigs( KBNODE keyblock, int all ) +remove_keysigs( KBNODE keyblock, u32 *keyid, int all ) { KBNODE kbctx; KBNODE node; @@ -588,7 +588,7 @@ remove_keysigs( KBNODE keyblock, int all ) && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) { PKT_signature *sig = node->pkt->pkt.signature; - if( all ) { + if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { /* fixme: skip self-sig */ } @@ -609,6 +609,10 @@ remove_keysigs( KBNODE keyblock, int all ) tty_printf("Public key not available.\n"); else if( node->flag & 4 ) tty_printf("The signature could not be checked!\n"); + + if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) + continue; /* do not remove self-signatures */ + answer = tty_get("\nRemove this signature? "); tty_kill_prompt(); if( answer_is_yes(answer) ) { @@ -709,7 +713,7 @@ sign_key( const char *username, STRLIST locusr ) answer = tty_get("To you want to remove some of the invalid sigs? "); tty_kill_prompt(); if( answer_is_yes(answer) ) - remove_keysigs( keyblock, 0 ); + remove_keysigs( keyblock, pkc_keyid, 0 ); m_free(answer); } } @@ -833,7 +837,7 @@ edit_keysigs( const char *username ) clear_kbnode_flags( keyblock ); check_all_keysigs( keyblock ); - if( remove_keysigs( keyblock, 1 ) ) { + if( remove_keysigs( keyblock, pkc_keyid, 1 ) ) { rc = update_keyblock( &kbpos, keyblock ); if( rc ) { log_error("update_keyblock failed: %s\n", g10_errstr(rc) ); diff --git a/g10/trustdb.c b/g10/trustdb.c index 466dd7982..0c2620a95 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -22,10 +22,12 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> #include <errno.h> #include <assert.h> +#include <sys/stat.h> +#include <sys/types.h> #include <fcntl.h> +#include <unistd.h> #include "errors.h" #include "iobuf.h" @@ -1490,15 +1492,25 @@ init_trustdb( int level, const char *dbname ) if( !level || level==1 ) { char *fname = dbname? m_strdup( dbname ) - : make_filename("~/.g10", "trustdb.g10", NULL ); + : make_filename(opt.homedir, "trustdb.g10", NULL ); if( access( fname, R_OK ) ) { if( errno != ENOENT ) { log_error("can't access %s: %s\n", fname, strerror(errno) ); m_free(fname); return G10ERR_TRUSTDB; } - if( level ) + if( level ) { + char *p = strrchr( fname, '/' ); + assert(p); + *p = 0; + if( access( fname, F_OK ) ) { + if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) ) + log_fatal("can't create directory '%s': %s\n", + fname, strerror(errno) ); + } + *p = '/'; create_db( fname ); + } } m_free(db_name); db_name = fname; @@ -1944,7 +1956,7 @@ int verify_private_data() { int rc = 0; - char *sigfile = make_filename("~/.g10", "sig", NULL ); + char *sigfile = make_filename(opt.homedir, "g10.sig", NULL ); if( access( sigfile, R_OK ) ) { if( errno != ENOENT ) { @@ -1972,8 +1984,8 @@ int sign_private_data() { int rc; - char *sigfile = make_filename("~/.g10", "sig", NULL ); - char *secring = make_filename("~/.g10", "secring.g10", NULL ); + char *sigfile = make_filename(opt.homedir, "g10.sig", NULL ); + char *secring = make_filename(opt.homedir, "secring.g10", NULL ); STRLIST list = NULL; add_to_strlist( &list, db_name ); diff --git a/mpi/m68k/distfiles b/mpi/m68k/distfiles index 88494d955..4693a209f 100644 --- a/mpi/m68k/distfiles +++ b/mpi/m68k/distfiles @@ -1 +1,7 @@ syntax.h +mpih-lshift.S +mpih-add1.S +mpih-sub1.S + + + diff --git a/mpi/m68k/mc68020/distfiles b/mpi/m68k/mc68020/distfiles index e69de29bb..fc7df9fa3 100644 --- a/mpi/m68k/mc68020/distfiles +++ b/mpi/m68k/mc68020/distfiles @@ -0,0 +1,3 @@ +mpih-mul1.S +mpih-mul2.S +mpih-mul3.S diff --git a/mpi/m68k/mc68020/mpih-mul1.S b/mpi/m68k/mc68020/mpih-mul1.S new file mode 100644 index 000000000..16a52a229 --- /dev/null +++ b/mpi/m68k/mc68020/mpih-mul1.S @@ -0,0 +1,97 @@ +/* mc68020 __mpn_mul_1 -- Multiply a limb vector with a limb and store + the result in a second limb vector. + +Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + + + +#include "sysdep.h" +#include "asm-syntax.h" + + +/******************* + * mpi_limb_t + * mpihelp_mul_1( mpi_ptr_t res_ptr, (sp + 4) + * mpi_ptr_t s1_ptr, (sp + 8) + * mpi_size_t s1_size, (sp + 12) + * mpi_limb_t s2_limb) (sp + 16) + */ + + + TEXT + ALIGN + GLOBL C_SYMBOL_NAME(mpihelp_mul_1) + +C_SYMBOL_NAME(mpihelp_mul_1:) +PROLOG(mpihelp_mul_1) + +#define res_ptr a0 +#define s1_ptr a1 +#define s1_size d2 +#define s2_limb d4 + +/* Save used registers on the stack. */ + moveml R(d2)-R(d4),MEM_PREDEC(sp) +#if 0 + movel R(d2),MEM_PREDEC(sp) + movel R(d3),MEM_PREDEC(sp) + movel R(d4),MEM_PREDEC(sp) +#endif + +/* Copy the arguments to registers. Better use movem? */ + movel MEM_DISP(sp,16),R(res_ptr) + movel MEM_DISP(sp,20),R(s1_ptr) + movel MEM_DISP(sp,24),R(s1_size) + movel MEM_DISP(sp,28),R(s2_limb) + + eorw #1,R(s1_size) + clrl R(d1) + lsrl #1,R(s1_size) + bcc L(L1) + subql #1,R(s1_size) + subl R(d0),R(d0) /* (d0,cy) <= (0,0) */ + +L(Loop:) + movel MEM_POSTINC(s1_ptr),R(d3) + mulul R(s2_limb),R(d1):R(d3) + addxl R(d0),R(d3) + movel R(d3),MEM_POSTINC(res_ptr) +L(L1:) movel MEM_POSTINC(s1_ptr),R(d3) + mulul R(s2_limb),R(d0):R(d3) + addxl R(d1),R(d3) + movel R(d3),MEM_POSTINC(res_ptr) + + dbf R(s1_size),L(Loop) + clrl R(d3) + addxl R(d3),R(d0) + subl #0x10000,R(s1_size) + bcc L(Loop) + +/* Restore used registers from stack frame. */ + moveml MEM_POSTINC(sp),R(d2)-R(d4) +#if 0 + movel MEM_POSTINC(sp),R(d4) + movel MEM_POSTINC(sp),R(d3) + movel MEM_POSTINC(sp),R(d2) +#endif + rts +EPILOG(mpihelp_mul_1) + + diff --git a/mpi/m68k/mc68020/mpih-mul2.S b/mpi/m68k/mc68020/mpih-mul2.S new file mode 100644 index 000000000..8cbbc5480 --- /dev/null +++ b/mpi/m68k/mc68020/mpih-mul2.S @@ -0,0 +1,87 @@ +/* mc68020 __mpn_addmul_1 -- Multiply a limb vector with a limb and add + the result to a second limb vector. + +Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + + +#include "sysdep.h" +#include "asm-syntax.h" + +/******************* + * mpi_limb_t + * mpihelp_addmul_1( mpi_ptr_t res_ptr, (sp + 4) + * mpi_ptr_t s1_ptr, (sp + 8) + * mpi_size_t s1_size, (sp + 12) + * mpi_limb_t s2_limb) (sp + 16) + */ + + + TEXT + ALIGN + GLOBL C_SYMBOL_NAME(mpihelp_addmul_1) + +C_SYMBOL_NAME(mpihelp_addmul_1:) +PROLOG(mpihelp_addmul_1) + +#define res_ptr a0 +#define s1_ptr a1 +#define s1_size d2 +#define s2_limb d4 + +/* Save used registers on the stack. */ + moveml R(d2)-R(d5),MEM_PREDEC(sp) + +/* Copy the arguments to registers. Better use movem? */ + movel MEM_DISP(sp,20),R(res_ptr) + movel MEM_DISP(sp,24),R(s1_ptr) + movel MEM_DISP(sp,28),R(s1_size) + movel MEM_DISP(sp,32),R(s2_limb) + + eorw #1,R(s1_size) + clrl R(d1) + clrl R(d5) + lsrl #1,R(s1_size) + bcc L(L1) + subql #1,R(s1_size) + subl R(d0),R(d0) /* (d0,cy) <= (0,0) */ + +L(Loop:) + movel MEM_POSTINC(s1_ptr),R(d3) + mulul R(s2_limb),R(d1):R(d3) + addxl R(d0),R(d3) + addxl R(d5),R(d1) + addl R(d3),MEM_POSTINC(res_ptr) +L(L1:) movel MEM_POSTINC(s1_ptr),R(d3) + mulul R(s2_limb),R(d0):R(d3) + addxl R(d1),R(d3) + addxl R(d5),R(d0) + addl R(d3),MEM_POSTINC(res_ptr) + + dbf R(s1_size),L(Loop) + addxl R(d5),R(d0) + subl #0x10000,R(s1_size) + bcc L(Loop) + +/* Restore used registers from stack frame. */ + moveml MEM_POSTINC(sp),R(d2)-R(d5) + + rts +EPILOG(mpihelp_addmul_1) + diff --git a/mpi/m68k/mc68020/mpih-mul3.S b/mpi/m68k/mc68020/mpih-mul3.S new file mode 100644 index 000000000..8e28ce456 --- /dev/null +++ b/mpi/m68k/mc68020/mpih-mul3.S @@ -0,0 +1,89 @@ +/* mc68020 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract + the result from a second limb vector. + +Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + + + +#include "sysdep.h" +#include "asm-syntax.h" + +/******************* + * mpi_limb_t + * mpihelp_submul_1( mpi_ptr_t res_ptr, (sp + 4) + * mpi_ptr_t s1_ptr, (sp + 8) + * mpi_size_t s1_size, (sp + 12) + * mpi_limb_t s2_limb) (sp + 16) + */ + + + TEXT + ALIGN + GLOBL C_SYMBOL_NAME(mpihelp_submul_1) + +C_SYMBOL_NAME(mpihelp_submul_1:) +PROLOG(mpihelp_submul_1) + +#define res_ptr a0 +#define s1_ptr a1 +#define s1_size d2 +#define s2_limb d4 + +/* Save used registers on the stack. */ + moveml R(d2)-R(d5),MEM_PREDEC(sp) + +/* Copy the arguments to registers. Better use movem? */ + movel MEM_DISP(sp,20),R(res_ptr) + movel MEM_DISP(sp,24),R(s1_ptr) + movel MEM_DISP(sp,28),R(s1_size) + movel MEM_DISP(sp,32),R(s2_limb) + + eorw #1,R(s1_size) + clrl R(d1) + clrl R(d5) + lsrl #1,R(s1_size) + bcc L(L1) + subql #1,R(s1_size) + subl R(d0),R(d0) /* (d0,cy) <= (0,0) */ + +L(Loop:) + movel MEM_POSTINC(s1_ptr),R(d3) + mulul R(s2_limb),R(d1):R(d3) + addxl R(d0),R(d3) + addxl R(d5),R(d1) + subl R(d3),MEM_POSTINC(res_ptr) +L(L1:) movel MEM_POSTINC(s1_ptr),R(d3) + mulul R(s2_limb),R(d0):R(d3) + addxl R(d1),R(d3) + addxl R(d5),R(d0) + subl R(d3),MEM_POSTINC(res_ptr) + + dbf R(s1_size),L(Loop) + addxl R(d5),R(d0) + subl #0x10000,R(s1_size) + bcc L(Loop) + +/* Restore used registers from stack frame. */ + moveml MEM_POSTINC(sp),R(d2)-R(d5) + + rts +EPILOG(mpihelp_submul_1) + + diff --git a/mpi/m68k/mpih-add1.S b/mpi/m68k/mpih-add1.S new file mode 100644 index 000000000..b3812c787 --- /dev/null +++ b/mpi/m68k/mpih-add1.S @@ -0,0 +1,85 @@ +/* mc68020 __mpn_add_n -- Add two limb vectors of the same length > 0 and store + sum in a third limb vector. + +Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + + +#include "sysdep.h" +#include "asm-syntax.h" + + +/******************* + * mpi_limb_t + * mpihelp_add_n( mpi_ptr_t res_ptr, (sp + 4) + * mpi_ptr_t s1_ptr, (sp + 8) + * mpi_ptr_t s2_ptr, (sp + 16) + * mpi_size_t size) (sp + 12) + */ + + + TEXT + ALIGN + GLOBL C_SYMBOL_NAME(mpihelp_add_n) + +C_SYMBOL_NAME(mpihelp_add_n:) +PROLOG(mpihelp_add_n) + /* Save used registers on the stack. */ + movel R(d2),MEM_PREDEC(sp) + movel R(a2),MEM_PREDEC(sp) + + /* Copy the arguments to registers. Better use movem? */ + movel MEM_DISP(sp,12),R(a2) + movel MEM_DISP(sp,16),R(a0) + movel MEM_DISP(sp,20),R(a1) + movel MEM_DISP(sp,24),R(d2) + + eorw #1,R(d2) + lsrl #1,R(d2) + bcc L(L1) + subql #1,R(d2) /* clears cy as side effect */ + +L(Loop:) + movel MEM_POSTINC(a0),R(d0) + movel MEM_POSTINC(a1),R(d1) + addxl R(d1),R(d0) + movel R(d0),MEM_POSTINC(a2) +L(L1:) movel MEM_POSTINC(a0),R(d0) + movel MEM_POSTINC(a1),R(d1) + addxl R(d1),R(d0) + movel R(d0),MEM_POSTINC(a2) + + dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */ + subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */ + subl #0x10000,R(d2) + bcs L(L2) + addl R(d0),R(d0) /* restore cy */ + bra L(Loop) + +L(L2:) + negl R(d0) + + /* Restore used registers from stack frame. */ + movel MEM_POSTINC(sp),R(a2) + movel MEM_POSTINC(sp),R(d2) + + rts +EPILOG(mpihelp_add_n) + + diff --git a/mpi/m68k/mpih-shift.S b/mpi/m68k/mpih-shift.S new file mode 100644 index 000000000..a9208745e --- /dev/null +++ b/mpi/m68k/mpih-shift.S @@ -0,0 +1,286 @@ +/* mc68020 __mpn_lshift -- Shift left a low-level natural-number integer. + +Copyright (C) 1996 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + +/******************* + * mpi_limb_t + * mpihelp_lshift( mpi_ptr_t wp, (sp + 4) + * mpi_ptr_t up, (sp + 8) + * mpi_size_t usize, (sp + 12) + * unsigned cnt) (sp + 16) + */ + +#define res_ptr a1 +#define s_ptr a0 +#define s_size d6 +#define cnt d4 + + TEXT + ALIGN + GLOBL C_SYMBOL_NAME(mpihelp_lshift) + +C_SYMBOL_NAME(mpihelp_lshift:) +PROLOG(mpihelp_lshift) + + /* Save used registers on the stack. */ + moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp) + + /* Copy the arguments to registers. */ + movel MEM_DISP(sp,28),R(res_ptr) + movel MEM_DISP(sp,32),R(s_ptr) + movel MEM_DISP(sp,36),R(s_size) + movel MEM_DISP(sp,40),R(cnt) + + moveql #1,R(d5) + cmpl R(d5),R(cnt) + bne L(Lnormal) + cmpl R(s_ptr),R(res_ptr) + bls L(Lspecial) /* jump if s_ptr >= res_ptr */ +#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) + lea MEM_INDX1(s_ptr,s_size,l,4),R(a2) +#else /* not mc68020 */ + movel R(s_size),R(d0) + asll #2,R(d0) + lea MEM_INDX(s_ptr,d0,l),R(a2) +#endif + cmpl R(res_ptr),R(a2) + bls L(Lspecial) /* jump if res_ptr >= s_ptr + s_size */ + +L(Lnormal:) + moveql #32,R(d5) + subl R(cnt),R(d5) + +#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) + lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr) + lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr) +#else /* not mc68000 */ + movel R(s_size),R(d0) + asll #2,R(d0) + addl R(s_size),R(s_ptr) + addl R(s_size),R(res_ptr) +#endif + movel MEM_PREDEC(s_ptr),R(d2) + movel R(d2),R(d0) + lsrl R(d5),R(d0) /* compute carry limb */ + + lsll R(cnt),R(d2) + movel R(d2),R(d1) + subql #1,R(s_size) + beq L(Lend) + lsrl #1,R(s_size) + bcs L(L1) + subql #1,R(s_size) + +L(Loop:) + movel MEM_PREDEC(s_ptr),R(d2) + movel R(d2),R(d3) + lsrl R(d5),R(d3) + orl R(d3),R(d1) + movel R(d1),MEM_PREDEC(res_ptr) + lsll R(cnt),R(d2) +L(L1:) + movel MEM_PREDEC(s_ptr),R(d1) + movel R(d1),R(d3) + lsrl R(d5),R(d3) + orl R(d3),R(d2) + movel R(d2),MEM_PREDEC(res_ptr) + lsll R(cnt),R(d1) + + dbf R(s_size),L(Loop) + subl #0x10000,R(s_size) + bcc L(Loop) + +L(Lend:) + movel R(d1),MEM_PREDEC(res_ptr) /* store least significant limb */ + +/* Restore used registers from stack frame. */ + moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) + rts + +/* We loop from least significant end of the arrays, which is only + permissable if the source and destination don't overlap, since the + function is documented to work for overlapping source and destination. */ + +L(Lspecial:) + clrl R(d0) /* initialize carry */ + eorw #1,R(s_size) + lsrl #1,R(s_size) + bcc L(LL1) + subql #1,R(s_size) + +L(LLoop:) + movel MEM_POSTINC(s_ptr),R(d2) + addxl R(d2),R(d2) + movel R(d2),MEM_POSTINC(res_ptr) +L(LL1:) + movel MEM_POSTINC(s_ptr),R(d2) + addxl R(d2),R(d2) + movel R(d2),MEM_POSTINC(res_ptr) + + dbf R(s_size),L(LLoop) + addxl R(d0),R(d0) /* save cy in lsb */ + subl #0x10000,R(s_size) + bcs L(LLend) + lsrl #1,R(d0) /* restore cy */ + bra L(LLoop) + +L(LLend:) +/* Restore used registers from stack frame. */ + moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) + rts +EPILOG(mpihelp_lshift) + + + + +/******************* + * mpi_limb_t + * mpihelp_rshift( mpi_ptr_t wp, (sp + 4) + * mpi_ptr_t up, (sp + 8) + * mpi_size_t usize, (sp + 12) + * unsigned cnt) (sp + 16) + */ + +#define res_ptr a1 +#define s_ptr a0 +#define s_size d6 +#define cnt d4 + + TEXT + ALIGN + GLOBL C_SYMBOL_NAME(mpihelp_rshift) + +C_SYMBOL_NAME(mpihelp_rshift:) +PROLOG(mpihelp_rshift) + /* Save used registers on the stack. */ + moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp) + + /* Copy the arguments to registers. */ + movel MEM_DISP(sp,28),R(res_ptr) + movel MEM_DISP(sp,32),R(s_ptr) + movel MEM_DISP(sp,36),R(s_size) + movel MEM_DISP(sp,40),R(cnt) + + moveql #1,R(d5) + cmpl R(d5),R(cnt) + bne L(Rnormal) + cmpl R(res_ptr),R(s_ptr) + bls L(Lspecial) /* jump if res_ptr >= s_ptr */ +#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) + lea MEM_INDX1(res_ptr,s_size,l,4),R(a2) +#else /* not mc68020 */ + movel R(s_size),R(d0) + asll #2,R(d0) + lea MEM_INDX(res_ptr,d0,l),R(a2) +#endif + cmpl R(s_ptr),R(a2) + bls L(Lspecial) /* jump if s_ptr >= res_ptr + s_size */ + +L(Rnormal:) + moveql #32,R(d5) + subl R(cnt),R(d5) + movel MEM_POSTINC(s_ptr),R(d2) + movel R(d2),R(d0) + lsll R(d5),R(d0) /* compute carry limb */ + + lsrl R(cnt),R(d2) + movel R(d2),R(d1) + subql #1,R(s_size) + beq L(Rend) + lsrl #1,R(s_size) + bcs L(R1) + subql #1,R(s_size) + +L(Roop:) + movel MEM_POSTINC(s_ptr),R(d2) + movel R(d2),R(d3) + lsll R(d5),R(d3) + orl R(d3),R(d1) + movel R(d1),MEM_POSTINC(res_ptr) + lsrl R(cnt),R(d2) +L(R1:) + movel MEM_POSTINC(s_ptr),R(d1) + movel R(d1),R(d3) + lsll R(d5),R(d3) + orl R(d3),R(d2) + movel R(d2),MEM_POSTINC(res_ptr) + lsrl R(cnt),R(d1) + + dbf R(s_size),L(Roop) + subl #0x10000,R(s_size) + bcc L(Roop) + +L(Rend:) + movel R(d1),MEM(res_ptr) /* store most significant limb */ + +/* Restore used registers from stack frame. */ + moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) + rts + +/* We loop from most significant end of the arrays, which is only + permissable if the source and destination don't overlap, since the + function is documented to work for overlapping source and destination. */ + +L(Lspecial:) +#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) + lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr) + lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr) +#else /* not mc68000 */ + movel R(s_size),R(d0) + asll #2,R(d0) + addl R(s_size),R(s_ptr) + addl R(s_size),R(res_ptr) +#endif + + clrl R(d0) /* initialize carry */ + eorw #1,R(s_size) + lsrl #1,R(s_size) + bcc L(LR1) + subql #1,R(s_size) + +L(LRoop:) + movel MEM_PREDEC(s_ptr),R(d2) + roxrl #1,R(d2) + movel R(d2),MEM_PREDEC(res_ptr) +L(LR1:) + movel MEM_PREDEC(s_ptr),R(d2) + roxrl #1,R(d2) + movel R(d2),MEM_PREDEC(res_ptr) + + dbf R(s_size),L(LRoop) + roxrl #1,R(d0) /* save cy in msb */ + subl #0x10000,R(s_size) + bcs L(LRend) + addl R(d0),R(d0) /* restore cy */ + bra L(LRoop) + +L(LRend:) +/* Restore used registers from stack frame. */ + moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) + rts +EPILOG(mpihelp_rshift) + + + + diff --git a/mpi/m68k/mpih-sub1.S b/mpi/m68k/mpih-sub1.S new file mode 100644 index 000000000..8d8ef0b41 --- /dev/null +++ b/mpi/m68k/mpih-sub1.S @@ -0,0 +1,85 @@ +/* mc68020 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and + store difference in a third limb vector. + +Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + + +#include "sysdep.h" +#include "asm-syntax.h" + + +/******************* + * mpi_limb_t + * mpihelp_sub_n( mpi_ptr_t res_ptr, (sp + 4) + * mpi_ptr_t s1_ptr, (sp + 8) + * mpi_ptr_t s2_ptr, (sp + 16) + * mpi_size_t size) (sp + 12) + */ + + + TEXT + ALIGN + GLOBL C_SYMBOL_NAME(mpihelp_sub_n) + +C_SYMBOL_NAME(mpihelp_sub_n:) +PROLOG(mpihelp_sub_n) +/* Save used registers on the stack. */ + movel R(d2),MEM_PREDEC(sp) + movel R(a2),MEM_PREDEC(sp) + +/* Copy the arguments to registers. Better use movem? */ + movel MEM_DISP(sp,12),R(a2) + movel MEM_DISP(sp,16),R(a0) + movel MEM_DISP(sp,20),R(a1) + movel MEM_DISP(sp,24),R(d2) + + eorw #1,R(d2) + lsrl #1,R(d2) + bcc L(L1) + subql #1,R(d2) /* clears cy as side effect */ + +L(Loop:) + movel MEM_POSTINC(a0),R(d0) + movel MEM_POSTINC(a1),R(d1) + subxl R(d1),R(d0) + movel R(d0),MEM_POSTINC(a2) +L(L1:) movel MEM_POSTINC(a0),R(d0) + movel MEM_POSTINC(a1),R(d1) + subxl R(d1),R(d0) + movel R(d0),MEM_POSTINC(a2) + + dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */ + subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */ + subl #0x10000,R(d2) + bcs L(L2) + addl R(d0),R(d0) /* restore cy */ + bra L(Loop) + +L(L2:) + negl R(d0) + +/* Restore used registers from stack frame. */ + movel MEM_POSTINC(sp),R(a2) + movel MEM_POSTINC(sp),R(d2) + + rts +EPILOG(mpihelp_sub_n) + + diff --git a/mpi/mpi-inv.c b/mpi/mpi-inv.c index 53ef356b3..dcded3e58 100644 --- a/mpi/mpi-inv.c +++ b/mpi/mpi-inv.c @@ -44,10 +44,10 @@ mpi_invm( MPI x, MPI a, MPI n ) v1 = mpi_alloc_set_ui(0); v2 = mpi_alloc_set_ui(1); v3 = mpi_copy(v); - q = mpi_alloc( mpi_get_nlimbs(u) ); - t1 = mpi_alloc( mpi_get_nlimbs(u) ); - t2 = mpi_alloc( mpi_get_nlimbs(u) ); - t3 = mpi_alloc( mpi_get_nlimbs(u) ); + q = mpi_alloc( mpi_get_nlimbs(u)+1 ); + t1 = mpi_alloc( mpi_get_nlimbs(u)+1 ); + t2 = mpi_alloc( mpi_get_nlimbs(u)+1 ); + t3 = mpi_alloc( mpi_get_nlimbs(u)+1 ); while( mpi_cmp_ui( v3, 0 ) ) { mpi_fdiv_q( q, u3, v3 ); mpi_mul(t1, v1, q); mpi_mul(t2, v2, q); mpi_mul(t3, v3, q); diff --git a/util/ChangeLog b/util/ChangeLog index 770fe9e90..a6d2a340c 100644 --- a/util/ChangeLog +++ b/util/ChangeLog @@ -1,3 +1,7 @@ +Tue Feb 17 19:43:44 1998 Werner Koch (wk@isil.d.shuttle.de) + + * memory.c (dump_table_at_exit): New. + Mon Feb 16 10:07:28 1998 Werner Koch (wk@isil.d.shuttle.de) * argparse.c (show_version, show_help, default_strusage): Changed diff --git a/util/memory.c b/util/memory.c index cd4dc815d..6633b94a6 100644 --- a/util/memory.c +++ b/util/memory.c @@ -101,6 +101,7 @@ static unsigned memtbl_size; /* number of allocated entries */ static unsigned memtbl_len; /* number of used entries */ static struct memtbl_entry *memtbl_unused;/* to keep track of unused entries */ +static void dump_table_at_exit(void); static void dump_table(void); static void check_allmem( const char *info ); @@ -135,8 +136,7 @@ add_entry( byte *p, unsigned n, int mode, const char *info, const char *by ) membug("memory debug table malloc failed\n"); index = 0; memtbl_len = 1; - if( DBG_MEMSTAT ) - atexit( dump_table ); + atexit( dump_table_at_exit ); } else { /* realloc */ unsigned n = memtbl_size / 4; /* enlarge by 25% */ @@ -264,6 +264,14 @@ dump_entry(struct memtbl_entry *e ) } + +static void +dump_table_at_exit( void) +{ + if( DBG_MEMSTAT ) + dump_table(); +} + static void dump_table( void) { |