summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>1998-02-17 21:48:52 +0100
committerWerner Koch <wk@gnupg.org>1998-02-17 21:48:52 +0100
commitc8bb57d05d1b237e16f93d95a4df5a1d343c4c5a (patch)
tree7692d6a234d6c22528ffce134ad0f6c904eaa91f
parentremoved password from key two (diff)
downloadgnupg2-c8bb57d05d1b237e16f93d95a4df5a1d343c4c5a.tar.xz
gnupg2-c8bb57d05d1b237e16f93d95a4df5a1d343c4c5a.zip
import works
-rw-r--r--README33
-rw-r--r--g10/ChangeLog34
-rw-r--r--g10/Makefile.am2
-rw-r--r--g10/OPTIONS9
-rw-r--r--g10/armor.c5
-rw-r--r--g10/free-packet.c43
-rw-r--r--g10/g10.c24
-rw-r--r--g10/g10maint.c38
-rw-r--r--g10/getkey.c4
-rw-r--r--g10/import.c293
-rw-r--r--g10/kbnode.c76
-rw-r--r--g10/keydb.h2
-rw-r--r--g10/keygen.c4
-rw-r--r--g10/main.h1
-rw-r--r--g10/mainproc.c109
-rw-r--r--g10/options.h2
-rw-r--r--g10/packet.h2
-rw-r--r--g10/pubring.asc38
-rw-r--r--g10/pubring.g10bin3017 -> 0 bytes
-rw-r--r--g10/ringedit.c28
-rw-r--r--g10/sign.c12
-rw-r--r--g10/trustdb.c24
-rw-r--r--mpi/m68k/distfiles6
-rw-r--r--mpi/m68k/mc68020/distfiles3
-rw-r--r--mpi/m68k/mc68020/mpih-mul1.S97
-rw-r--r--mpi/m68k/mc68020/mpih-mul2.S87
-rw-r--r--mpi/m68k/mc68020/mpih-mul3.S89
-rw-r--r--mpi/m68k/mpih-add1.S85
-rw-r--r--mpi/m68k/mpih-shift.S286
-rw-r--r--mpi/m68k/mpih-sub1.S85
-rw-r--r--mpi/mpi-inv.c8
-rw-r--r--util/ChangeLog4
-rw-r--r--util/memory.c12
33 files changed, 1404 insertions, 141 deletions
diff --git a/README b/README
index f5dc7a82e..52e6e1426 100644
--- a/README
+++ b/README
@@ -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;
+}
+
+
diff --git a/g10/g10.c b/g10/g10.c
index fae08fc33..f9ae0fc69 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -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
deleted file mode 100644
index f458371d4..000000000
--- a/g10/pubring.g10
+++ /dev/null
Binary files differ
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)
{